blob: 1a9c185bb6dc1b5f5b772e52a59990b358e9f358 [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. */
149} global_ssl = {
150#ifdef LISTEN_DEFAULT_CIPHERS
151 .listen_default_ciphers = LISTEN_DEFAULT_CIPHERS,
152#endif
153#ifdef CONNECT_DEFAULT_CIPHERS
154 .connect_default_ciphers = CONNECT_DEFAULT_CIPHERS,
155#endif
156 .listen_default_ssloptions = BC_SSL_O_NONE,
157 .connect_default_ssloptions = SRV_SSL_O_NONE,
158
159#ifdef DEFAULT_SSL_MAX_RECORD
160 .max_record = DEFAULT_SSL_MAX_RECORD,
161#endif
162 .default_dh_param = SSL_DEFAULT_DH_PARAM,
163 .ctx_cache = DEFAULT_SSL_CTX_CACHE,
164};
165
166
Nenad Merdanovic200b0fa2015-05-09 08:46:01 +0200167#if (defined SSL_CTRL_SET_TLSEXT_TICKET_KEY_CB && TLS_TICKETS_NO > 0)
168struct list tlskeys_reference = LIST_HEAD_INIT(tlskeys_reference);
169#endif
170
Remi Gacogne8de54152014-07-15 11:36:40 +0200171#ifndef OPENSSL_NO_DH
Remi Gacogne4f902b82015-05-28 16:23:00 +0200172static int ssl_dh_ptr_index = -1;
Remi Gacogne47783ef2015-05-29 15:53:22 +0200173static DH *global_dh = NULL;
Remi Gacogne8de54152014-07-15 11:36:40 +0200174static DH *local_dh_1024 = NULL;
175static DH *local_dh_2048 = NULL;
176static DH *local_dh_4096 = NULL;
Remi Gacogne8de54152014-07-15 11:36:40 +0200177#endif /* OPENSSL_NO_DH */
178
Emmanuel Hocdetfdec7892017-01-13 17:48:18 +0100179#if (defined SSL_CTRL_SET_TLSEXT_HOSTNAME && !defined SSL_NO_GENERATE_CERTIFICATES)
Christopher Faulet31af49d2015-06-09 17:29:50 +0200180/* X509V3 Extensions that will be added on generated certificates */
181#define X509V3_EXT_SIZE 5
182static char *x509v3_ext_names[X509V3_EXT_SIZE] = {
183 "basicConstraints",
184 "nsComment",
185 "subjectKeyIdentifier",
186 "authorityKeyIdentifier",
187 "keyUsage",
188};
189static char *x509v3_ext_values[X509V3_EXT_SIZE] = {
190 "CA:FALSE",
191 "\"OpenSSL Generated Certificate\"",
192 "hash",
193 "keyid,issuer:always",
194 "nonRepudiation,digitalSignature,keyEncipherment"
195};
Christopher Faulet31af49d2015-06-09 17:29:50 +0200196/* LRU cache to store generated certificate */
197static struct lru64_head *ssl_ctx_lru_tree = NULL;
198static unsigned int ssl_ctx_lru_seed = 0;
Willy Tarreauc8ad3be2015-06-17 15:48:26 +0200199#endif // SSL_CTRL_SET_TLSEXT_HOSTNAME
200
Emmanuel Hocdetfdec7892017-01-13 17:48:18 +0100201static struct ssl_bind_kw ssl_bind_kws[];
202
yanbzhube2774d2015-12-10 15:07:30 -0500203#if OPENSSL_VERSION_NUMBER >= 0x1000200fL
204/* The order here matters for picking a default context,
205 * keep the most common keytype at the bottom of the list
206 */
207const char *SSL_SOCK_KEYTYPE_NAMES[] = {
208 "dsa",
209 "ecdsa",
210 "rsa"
211};
212#define SSL_SOCK_NUM_KEYTYPES 3
Willy Tarreau30da7ad2015-12-14 11:28:33 +0100213#else
214#define SSL_SOCK_NUM_KEYTYPES 1
yanbzhube2774d2015-12-10 15:07:30 -0500215#endif
216
Emmanuel Hocdetfdec7892017-01-13 17:48:18 +0100217/*
218 * This function gives the detail of the SSL error. It is used only
219 * if the debug mode and the verbose mode are activated. It dump all
220 * the SSL error until the stack was empty.
221 */
222static forceinline void ssl_sock_dump_errors(struct connection *conn)
223{
224 unsigned long ret;
225
226 if (unlikely(global.mode & MODE_DEBUG)) {
227 while(1) {
228 ret = ERR_get_error();
229 if (ret == 0)
230 return;
231 fprintf(stderr, "fd[%04x] OpenSSL error[0x%lx] %s: %s\n",
232 (unsigned short)conn->t.sock.fd, ret,
233 ERR_func_error_string(ret), ERR_reason_error_string(ret));
234 }
235 }
236}
237
Willy Tarreauc8ad3be2015-06-17 15:48:26 +0200238#if (defined SSL_CTRL_SET_TLSEXT_STATUS_REQ_CB && !defined OPENSSL_NO_OCSP)
yanbzhube2774d2015-12-10 15:07:30 -0500239/*
240 * struct alignment works here such that the key.key is the same as key_data
241 * Do not change the placement of key_data
242 */
Willy Tarreauc8ad3be2015-06-17 15:48:26 +0200243struct certificate_ocsp {
244 struct ebmb_node key;
245 unsigned char key_data[OCSP_MAX_CERTID_ASN1_LENGTH];
246 struct chunk response;
247 long expire;
248};
Christopher Faulet31af49d2015-06-09 17:29:50 +0200249
yanbzhube2774d2015-12-10 15:07:30 -0500250struct ocsp_cbk_arg {
251 int is_single;
252 int single_kt;
253 union {
254 struct certificate_ocsp *s_ocsp;
255 /*
256 * m_ocsp will have multiple entries dependent on key type
257 * Entry 0 - DSA
258 * Entry 1 - ECDSA
259 * Entry 2 - RSA
260 */
261 struct certificate_ocsp *m_ocsp[SSL_SOCK_NUM_KEYTYPES];
262 };
263};
264
Emeric Brun4f3c87a2014-06-20 15:46:13 +0200265/*
266 * This function returns the number of seconds elapsed
267 * since the Epoch, 1970-01-01 00:00:00 +0000 (UTC) and the
268 * date presented un ASN1_GENERALIZEDTIME.
269 *
270 * In parsing error case, it returns -1.
271 */
272static long asn1_generalizedtime_to_epoch(ASN1_GENERALIZEDTIME *d)
273{
274 long epoch;
275 char *p, *end;
276 const unsigned short month_offset[12] = {
277 0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334
278 };
279 int year, month;
280
281 if (!d || (d->type != V_ASN1_GENERALIZEDTIME)) return -1;
282
283 p = (char *)d->data;
284 end = p + d->length;
285
286 if (end - p < 4) return -1;
287 year = 1000 * (p[0] - '0') + 100 * (p[1] - '0') + 10 * (p[2] - '0') + p[3] - '0';
288 p += 4;
289 if (end - p < 2) return -1;
290 month = 10 * (p[0] - '0') + p[1] - '0';
291 if (month < 1 || month > 12) return -1;
292 /* Compute the number of seconds since 1 jan 1970 and the beginning of current month
293 We consider leap years and the current month (<marsh or not) */
294 epoch = ( ((year - 1970) * 365)
295 + ((year - (month < 3)) / 4 - (year - (month < 3)) / 100 + (year - (month < 3)) / 400)
296 - ((1970 - 1) / 4 - (1970 - 1) / 100 + (1970 - 1) / 400)
297 + month_offset[month-1]
298 ) * 24 * 60 * 60;
299 p += 2;
300 if (end - p < 2) return -1;
301 /* Add the number of seconds of completed days of current month */
302 epoch += (10 * (p[0] - '0') + p[1] - '0' - 1) * 24 * 60 * 60;
303 p += 2;
304 if (end - p < 2) return -1;
305 /* Add the completed hours of the current day */
306 epoch += (10 * (p[0] - '0') + p[1] - '0') * 60 * 60;
307 p += 2;
308 if (end - p < 2) return -1;
309 /* Add the completed minutes of the current hour */
310 epoch += (10 * (p[0] - '0') + p[1] - '0') * 60;
311 p += 2;
312 if (p == end) return -1;
313 /* Test if there is available seconds */
314 if (p[0] < '0' || p[0] > '9')
315 goto nosec;
316 if (end - p < 2) return -1;
317 /* Add the seconds of the current minute */
318 epoch += 10 * (p[0] - '0') + p[1] - '0';
319 p += 2;
320 if (p == end) return -1;
321 /* Ignore seconds float part if present */
322 if (p[0] == '.') {
323 do {
324 if (++p == end) return -1;
325 } while (p[0] >= '0' && p[0] <= '9');
326 }
327
328nosec:
329 if (p[0] == 'Z') {
330 if (end - p != 1) return -1;
331 return epoch;
332 }
333 else if (p[0] == '+') {
334 if (end - p != 5) return -1;
335 /* Apply timezone offset */
336 return epoch - ((10 * (p[1] - '0') + p[2] - '0') * 60 + (10 * (p[3] - '0') + p[4] - '0')) * 60;
337 }
338 else if (p[0] == '-') {
339 if (end - p != 5) return -1;
340 /* Apply timezone offset */
341 return epoch + ((10 * (p[1] - '0') + p[2] - '0') * 60 + (10 * (p[3] - '0') + p[4] - '0')) * 60;
342 }
343
344 return -1;
345}
346
Emeric Brun1d3865b2014-06-20 15:37:32 +0200347static struct eb_root cert_ocsp_tree = EB_ROOT_UNIQUE;
Emeric Brun4147b2e2014-06-16 18:36:30 +0200348
349/* This function starts to check if the OCSP response (in DER format) contained
350 * in chunk 'ocsp_response' is valid (else exits on error).
351 * If 'cid' is not NULL, it will be compared to the OCSP certificate ID
352 * contained in the OCSP Response and exits on error if no match.
353 * If it's a valid OCSP Response:
354 * If 'ocsp' is not NULL, the chunk is copied in the OCSP response's container
355 * pointed by 'ocsp'.
356 * If 'ocsp' is NULL, the function looks up into the OCSP response's
357 * containers tree (using as index the ASN1 form of the OCSP Certificate ID extracted
358 * from the response) and exits on error if not found. Finally, If an OCSP response is
359 * already present in the container, it will be overwritten.
360 *
361 * Note: OCSP response containing more than one OCSP Single response is not
362 * considered valid.
363 *
364 * Returns 0 on success, 1 in error case.
365 */
366static int ssl_sock_load_ocsp_response(struct chunk *ocsp_response, struct certificate_ocsp *ocsp, OCSP_CERTID *cid, char **err)
367{
368 OCSP_RESPONSE *resp;
369 OCSP_BASICRESP *bs = NULL;
370 OCSP_SINGLERESP *sr;
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +0200371 OCSP_CERTID *id;
Emeric Brun4147b2e2014-06-16 18:36:30 +0200372 unsigned char *p = (unsigned char *)ocsp_response->str;
373 int rc , count_sr;
Emeric Brun13a6b482014-06-20 15:44:34 +0200374 ASN1_GENERALIZEDTIME *revtime, *thisupd, *nextupd = NULL;
Emeric Brun4147b2e2014-06-16 18:36:30 +0200375 int reason;
376 int ret = 1;
377
378 resp = d2i_OCSP_RESPONSE(NULL, (const unsigned char **)&p, ocsp_response->len);
379 if (!resp) {
380 memprintf(err, "Unable to parse OCSP response");
381 goto out;
382 }
383
384 rc = OCSP_response_status(resp);
385 if (rc != OCSP_RESPONSE_STATUS_SUCCESSFUL) {
386 memprintf(err, "OCSP response status not successful");
387 goto out;
388 }
389
390 bs = OCSP_response_get1_basic(resp);
391 if (!bs) {
392 memprintf(err, "Failed to get basic response from OCSP Response");
393 goto out;
394 }
395
396 count_sr = OCSP_resp_count(bs);
397 if (count_sr > 1) {
398 memprintf(err, "OCSP response ignored because contains multiple single responses (%d)", count_sr);
399 goto out;
400 }
401
402 sr = OCSP_resp_get0(bs, 0);
403 if (!sr) {
404 memprintf(err, "Failed to get OCSP single response");
405 goto out;
406 }
407
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +0200408 id = (OCSP_CERTID*)OCSP_SINGLERESP_get0_id(sr);
409
Emeric Brun4147b2e2014-06-16 18:36:30 +0200410 rc = OCSP_single_get0_status(sr, &reason, &revtime, &thisupd, &nextupd);
411 if (rc != V_OCSP_CERTSTATUS_GOOD) {
412 memprintf(err, "OCSP single response: certificate status not good");
413 goto out;
414 }
415
Emeric Brun13a6b482014-06-20 15:44:34 +0200416 if (!nextupd) {
417 memprintf(err, "OCSP single response: missing nextupdate");
418 goto out;
419 }
420
Emeric Brunc8b27b62014-06-19 14:16:17 +0200421 rc = OCSP_check_validity(thisupd, nextupd, OCSP_MAX_RESPONSE_TIME_SKEW, -1);
Emeric Brun4147b2e2014-06-16 18:36:30 +0200422 if (!rc) {
423 memprintf(err, "OCSP single response: no longer valid.");
424 goto out;
425 }
426
427 if (cid) {
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +0200428 if (OCSP_id_cmp(id, cid)) {
Emeric Brun4147b2e2014-06-16 18:36:30 +0200429 memprintf(err, "OCSP single response: Certificate ID does not match certificate and issuer");
430 goto out;
431 }
432 }
433
434 if (!ocsp) {
435 unsigned char key[OCSP_MAX_CERTID_ASN1_LENGTH];
436 unsigned char *p;
437
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +0200438 rc = i2d_OCSP_CERTID(id, NULL);
Emeric Brun4147b2e2014-06-16 18:36:30 +0200439 if (!rc) {
440 memprintf(err, "OCSP single response: Unable to encode Certificate ID");
441 goto out;
442 }
443
444 if (rc > OCSP_MAX_CERTID_ASN1_LENGTH) {
445 memprintf(err, "OCSP single response: Certificate ID too long");
446 goto out;
447 }
448
449 p = key;
450 memset(key, 0, OCSP_MAX_CERTID_ASN1_LENGTH);
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +0200451 i2d_OCSP_CERTID(id, &p);
Emeric Brun4147b2e2014-06-16 18:36:30 +0200452 ocsp = (struct certificate_ocsp *)ebmb_lookup(&cert_ocsp_tree, key, OCSP_MAX_CERTID_ASN1_LENGTH);
453 if (!ocsp) {
454 memprintf(err, "OCSP single response: Certificate ID does not match any certificate or issuer");
455 goto out;
456 }
457 }
458
459 /* According to comments on "chunk_dup", the
460 previous chunk buffer will be freed */
461 if (!chunk_dup(&ocsp->response, ocsp_response)) {
462 memprintf(err, "OCSP response: Memory allocation error");
463 goto out;
464 }
465
Emeric Brun4f3c87a2014-06-20 15:46:13 +0200466 ocsp->expire = asn1_generalizedtime_to_epoch(nextupd) - OCSP_MAX_RESPONSE_TIME_SKEW;
467
Emeric Brun4147b2e2014-06-16 18:36:30 +0200468 ret = 0;
469out:
470 if (bs)
471 OCSP_BASICRESP_free(bs);
472
473 if (resp)
474 OCSP_RESPONSE_free(resp);
475
476 return ret;
477}
478/*
479 * External function use to update the OCSP response in the OCSP response's
480 * containers tree. The chunk 'ocsp_response' must contain the OCSP response
481 * to update in DER format.
482 *
483 * Returns 0 on success, 1 in error case.
484 */
485int ssl_sock_update_ocsp_response(struct chunk *ocsp_response, char **err)
486{
487 return ssl_sock_load_ocsp_response(ocsp_response, NULL, NULL, err);
488}
489
490/*
491 * This function load the OCSP Resonse in DER format contained in file at
492 * path 'ocsp_path' and call 'ssl_sock_load_ocsp_response'
493 *
494 * Returns 0 on success, 1 in error case.
495 */
496static int ssl_sock_load_ocsp_response_from_file(const char *ocsp_path, struct certificate_ocsp *ocsp, OCSP_CERTID *cid, char **err)
497{
498 int fd = -1;
499 int r = 0;
500 int ret = 1;
501
502 fd = open(ocsp_path, O_RDONLY);
503 if (fd == -1) {
504 memprintf(err, "Error opening OCSP response file");
505 goto end;
506 }
507
508 trash.len = 0;
509 while (trash.len < trash.size) {
510 r = read(fd, trash.str + trash.len, trash.size - trash.len);
511 if (r < 0) {
512 if (errno == EINTR)
513 continue;
514
515 memprintf(err, "Error reading OCSP response from file");
516 goto end;
517 }
518 else if (r == 0) {
519 break;
520 }
521 trash.len += r;
522 }
523
524 close(fd);
525 fd = -1;
526
527 ret = ssl_sock_load_ocsp_response(&trash, ocsp, cid, err);
528end:
529 if (fd != -1)
530 close(fd);
531
532 return ret;
533}
Emmanuel Hocdetfdec7892017-01-13 17:48:18 +0100534#endif
Emeric Brun4147b2e2014-06-16 18:36:30 +0200535
Nenad Merdanovic05552d42015-02-27 19:56:49 +0100536#if (defined SSL_CTRL_SET_TLSEXT_TICKET_KEY_CB && TLS_TICKETS_NO > 0)
537static 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)
538{
539 struct tls_sess_key *keys;
540 struct connection *conn;
541 int head;
542 int i;
543
Vincent Bernat3c2f2f22016-04-03 13:48:42 +0200544 conn = SSL_get_app_data(s);
Nenad Merdanovic146defa2015-05-09 08:46:00 +0200545 keys = objt_listener(conn->target)->bind_conf->keys_ref->tlskeys;
546 head = objt_listener(conn->target)->bind_conf->keys_ref->tls_ticket_enc_index;
Nenad Merdanovic05552d42015-02-27 19:56:49 +0100547
548 if (enc) {
549 memcpy(key_name, keys[head].name, 16);
550
551 if(!RAND_pseudo_bytes(iv, EVP_MAX_IV_LENGTH))
552 return -1;
553
554 if(!EVP_EncryptInit_ex(ectx, EVP_aes_128_cbc(), NULL, keys[head].aes_key, iv))
555 return -1;
556
557 HMAC_Init_ex(hctx, keys[head].hmac_key, 16, HASH_FUNCT(), NULL);
558
559 return 1;
560 } else {
561 for (i = 0; i < TLS_TICKETS_NO; i++) {
562 if (!memcmp(key_name, keys[(head + i) % TLS_TICKETS_NO].name, 16))
563 goto found;
564 }
565 return 0;
566
567 found:
568 HMAC_Init_ex(hctx, keys[(head + i) % TLS_TICKETS_NO].hmac_key, 16, HASH_FUNCT(), NULL);
569 if(!EVP_DecryptInit_ex(ectx, EVP_aes_128_cbc(), NULL, keys[(head + i) % TLS_TICKETS_NO].aes_key, iv))
570 return -1;
571 /* 2 for key renewal, 1 if current key is still valid */
572 return i ? 2 : 1;
573 }
Nenad Merdanovic200b0fa2015-05-09 08:46:01 +0200574}
575
576struct tls_keys_ref *tlskeys_ref_lookup(const char *filename)
577{
578 struct tls_keys_ref *ref;
579
580 list_for_each_entry(ref, &tlskeys_reference, list)
581 if (ref->filename && strcmp(filename, ref->filename) == 0)
582 return ref;
583 return NULL;
584}
585
586struct tls_keys_ref *tlskeys_ref_lookupid(int unique_id)
587{
588 struct tls_keys_ref *ref;
589
590 list_for_each_entry(ref, &tlskeys_reference, list)
591 if (ref->unique_id == unique_id)
592 return ref;
593 return NULL;
594}
595
596int ssl_sock_update_tlskey(char *filename, struct chunk *tlskey, char **err) {
597 struct tls_keys_ref *ref = tlskeys_ref_lookup(filename);
598
599 if(!ref) {
600 memprintf(err, "Unable to locate the referenced filename: %s", filename);
601 return 1;
602 }
603
Pradeep Jindalcc79b002015-08-20 18:25:17 +0530604 memcpy((char *) (ref->tlskeys + ((ref->tls_ticket_enc_index + 2) % TLS_TICKETS_NO)), tlskey->str, tlskey->len);
605 ref->tls_ticket_enc_index = (ref->tls_ticket_enc_index + 1) % TLS_TICKETS_NO;
Nenad Merdanovic200b0fa2015-05-09 08:46:01 +0200606
607 return 0;
Nenad Merdanovic05552d42015-02-27 19:56:49 +0100608}
Nenad Merdanovic200b0fa2015-05-09 08:46:01 +0200609
610/* This function finalize the configuration parsing. Its set all the
Willy Tarreaud1c57502016-12-22 22:46:15 +0100611 * automatic ids. It's called just after the basic checks. It returns
612 * 0 on success otherwise ERR_*.
Nenad Merdanovic200b0fa2015-05-09 08:46:01 +0200613 */
Willy Tarreaud1c57502016-12-22 22:46:15 +0100614static int tlskeys_finalize_config(void)
Nenad Merdanovic200b0fa2015-05-09 08:46:01 +0200615{
616 int i = 0;
617 struct tls_keys_ref *ref, *ref2, *ref3;
618 struct list tkr = LIST_HEAD_INIT(tkr);
619
620 list_for_each_entry(ref, &tlskeys_reference, list) {
621 if (ref->unique_id == -1) {
622 /* Look for the first free id. */
623 while (1) {
624 list_for_each_entry(ref2, &tlskeys_reference, list) {
625 if (ref2->unique_id == i) {
626 i++;
627 break;
628 }
629 }
630 if (&ref2->list == &tlskeys_reference)
631 break;
632 }
633
634 /* Uses the unique id and increment it for the next entry. */
635 ref->unique_id = i;
636 i++;
637 }
638 }
639
640 /* This sort the reference list by id. */
641 list_for_each_entry_safe(ref, ref2, &tlskeys_reference, list) {
642 LIST_DEL(&ref->list);
643 list_for_each_entry(ref3, &tkr, list) {
644 if (ref->unique_id < ref3->unique_id) {
645 LIST_ADDQ(&ref3->list, &ref->list);
646 break;
647 }
648 }
649 if (&ref3->list == &tkr)
650 LIST_ADDQ(&tkr, &ref->list);
651 }
652
653 /* swap root */
654 LIST_ADD(&tkr, &tlskeys_reference);
655 LIST_DEL(&tkr);
Willy Tarreaud1c57502016-12-22 22:46:15 +0100656 return 0;
Nenad Merdanovic200b0fa2015-05-09 08:46:01 +0200657}
Nenad Merdanovic05552d42015-02-27 19:56:49 +0100658#endif /* SSL_CTRL_SET_TLSEXT_TICKET_KEY_CB */
659
Emmanuel Hocdetfdec7892017-01-13 17:48:18 +0100660#ifndef OPENSSL_NO_OCSP
yanbzhube2774d2015-12-10 15:07:30 -0500661int ssl_sock_get_ocsp_arg_kt_index(int evp_keytype)
662{
663 switch (evp_keytype) {
664 case EVP_PKEY_RSA:
665 return 2;
666 case EVP_PKEY_DSA:
667 return 0;
668 case EVP_PKEY_EC:
669 return 1;
670 }
671
672 return -1;
673}
674
Emeric Brun4147b2e2014-06-16 18:36:30 +0200675/*
676 * Callback used to set OCSP status extension content in server hello.
677 */
678int ssl_sock_ocsp_stapling_cbk(SSL *ssl, void *arg)
679{
yanbzhube2774d2015-12-10 15:07:30 -0500680 struct certificate_ocsp *ocsp;
681 struct ocsp_cbk_arg *ocsp_arg;
682 char *ssl_buf;
683 EVP_PKEY *ssl_pkey;
684 int key_type;
685 int index;
686
Vincent Bernat3c2f2f22016-04-03 13:48:42 +0200687 ocsp_arg = arg;
yanbzhube2774d2015-12-10 15:07:30 -0500688
689 ssl_pkey = SSL_get_privatekey(ssl);
690 if (!ssl_pkey)
691 return SSL_TLSEXT_ERR_NOACK;
692
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +0200693 key_type = EVP_PKEY_base_id(ssl_pkey);
yanbzhube2774d2015-12-10 15:07:30 -0500694
695 if (ocsp_arg->is_single && ocsp_arg->single_kt == key_type)
696 ocsp = ocsp_arg->s_ocsp;
697 else {
698 /* For multiple certs per context, we have to find the correct OCSP response based on
699 * the certificate type
700 */
701 index = ssl_sock_get_ocsp_arg_kt_index(key_type);
702
703 if (index < 0)
704 return SSL_TLSEXT_ERR_NOACK;
705
706 ocsp = ocsp_arg->m_ocsp[index];
707
708 }
Emeric Brun4147b2e2014-06-16 18:36:30 +0200709
710 if (!ocsp ||
711 !ocsp->response.str ||
Emeric Brun4f3c87a2014-06-20 15:46:13 +0200712 !ocsp->response.len ||
713 (ocsp->expire < now.tv_sec))
Emeric Brun4147b2e2014-06-16 18:36:30 +0200714 return SSL_TLSEXT_ERR_NOACK;
715
716 ssl_buf = OPENSSL_malloc(ocsp->response.len);
717 if (!ssl_buf)
718 return SSL_TLSEXT_ERR_NOACK;
719
720 memcpy(ssl_buf, ocsp->response.str, ocsp->response.len);
721 SSL_set_tlsext_status_ocsp_resp(ssl, ssl_buf, ocsp->response.len);
722
723 return SSL_TLSEXT_ERR_OK;
724}
725
726/*
727 * This function enables the handling of OCSP status extension on 'ctx' if a
728 * file name 'cert_path' suffixed using ".ocsp" is present.
729 * To enable OCSP status extension, the issuer's certificate is mandatory.
730 * It should be present in the certificate's extra chain builded from file
731 * 'cert_path'. If not found, the issuer certificate is loaded from a file
732 * named 'cert_path' suffixed using '.issuer'.
733 *
734 * In addition, ".ocsp" file content is loaded as a DER format of an OCSP
735 * response. If file is empty or content is not a valid OCSP response,
736 * OCSP status extension is enabled but OCSP response is ignored (a warning
737 * is displayed).
738 *
739 * Returns 1 if no ".ocsp" file found, 0 if OCSP status extension is
740 * succesfully enabled, or -1 in other error case.
741 */
742static int ssl_sock_load_ocsp(SSL_CTX *ctx, const char *cert_path)
743{
744
745 BIO *in = NULL;
746 X509 *x, *xi = NULL, *issuer = NULL;
747 STACK_OF(X509) *chain = NULL;
748 OCSP_CERTID *cid = NULL;
749 SSL *ssl;
750 char ocsp_path[MAXPATHLEN+1];
751 int i, ret = -1;
752 struct stat st;
753 struct certificate_ocsp *ocsp = NULL, *iocsp;
754 char *warn = NULL;
755 unsigned char *p;
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +0200756 pem_password_cb *passwd_cb;
757 void *passwd_cb_userdata;
758 void (*callback) (void);
Emeric Brun4147b2e2014-06-16 18:36:30 +0200759
760 snprintf(ocsp_path, MAXPATHLEN+1, "%s.ocsp", cert_path);
761
762 if (stat(ocsp_path, &st))
763 return 1;
764
765 ssl = SSL_new(ctx);
766 if (!ssl)
767 goto out;
768
769 x = SSL_get_certificate(ssl);
770 if (!x)
771 goto out;
772
773 /* Try to lookup for issuer in certificate extra chain */
774#ifdef SSL_CTRL_GET_EXTRA_CHAIN_CERTS
775 SSL_CTX_get_extra_chain_certs(ctx, &chain);
776#else
777 chain = ctx->extra_certs;
778#endif
779 for (i = 0; i < sk_X509_num(chain); i++) {
780 issuer = sk_X509_value(chain, i);
781 if (X509_check_issued(issuer, x) == X509_V_OK)
782 break;
783 else
784 issuer = NULL;
785 }
786
787 /* If not found try to load issuer from a suffixed file */
788 if (!issuer) {
789 char issuer_path[MAXPATHLEN+1];
790
791 in = BIO_new(BIO_s_file());
792 if (!in)
793 goto out;
794
795 snprintf(issuer_path, MAXPATHLEN+1, "%s.issuer", cert_path);
796 if (BIO_read_filename(in, issuer_path) <= 0)
797 goto out;
798
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +0200799 passwd_cb = SSL_CTX_get_default_passwd_cb(ctx);
800 passwd_cb_userdata = SSL_CTX_get_default_passwd_cb_userdata(ctx);
801
802 xi = PEM_read_bio_X509_AUX(in, NULL, passwd_cb, passwd_cb_userdata);
Emeric Brun4147b2e2014-06-16 18:36:30 +0200803 if (!xi)
804 goto out;
805
806 if (X509_check_issued(xi, x) != X509_V_OK)
807 goto out;
808
809 issuer = xi;
810 }
811
812 cid = OCSP_cert_to_id(0, x, issuer);
813 if (!cid)
814 goto out;
815
816 i = i2d_OCSP_CERTID(cid, NULL);
817 if (!i || (i > OCSP_MAX_CERTID_ASN1_LENGTH))
818 goto out;
819
Vincent Bernat02779b62016-04-03 13:48:43 +0200820 ocsp = calloc(1, sizeof(*ocsp));
Emeric Brun4147b2e2014-06-16 18:36:30 +0200821 if (!ocsp)
822 goto out;
823
824 p = ocsp->key_data;
825 i2d_OCSP_CERTID(cid, &p);
826
827 iocsp = (struct certificate_ocsp *)ebmb_insert(&cert_ocsp_tree, &ocsp->key, OCSP_MAX_CERTID_ASN1_LENGTH);
828 if (iocsp == ocsp)
829 ocsp = NULL;
830
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +0200831#ifndef SSL_CTX_get_tlsext_status_cb
832# define SSL_CTX_get_tlsext_status_cb(ctx, cb) \
833 *cb = (void (*) (void))ctx->tlsext_status_cb;
834#endif
835 SSL_CTX_get_tlsext_status_cb(ctx, &callback);
836
837 if (!callback) {
Vincent Bernat02779b62016-04-03 13:48:43 +0200838 struct ocsp_cbk_arg *cb_arg = calloc(1, sizeof(*cb_arg));
Emmanuel Hocdetb7a4c342017-01-06 12:57:46 +0100839 EVP_PKEY *pkey;
yanbzhube2774d2015-12-10 15:07:30 -0500840
841 cb_arg->is_single = 1;
842 cb_arg->s_ocsp = iocsp;
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +0200843
Emmanuel Hocdetb7a4c342017-01-06 12:57:46 +0100844 pkey = X509_get_pubkey(x);
845 cb_arg->single_kt = EVP_PKEY_base_id(pkey);
846 EVP_PKEY_free(pkey);
yanbzhube2774d2015-12-10 15:07:30 -0500847
848 SSL_CTX_set_tlsext_status_cb(ctx, ssl_sock_ocsp_stapling_cbk);
849 SSL_CTX_set_tlsext_status_arg(ctx, cb_arg);
850 } else {
851 /*
852 * If the ctx has a status CB, then we have previously set an OCSP staple for this ctx
853 * Update that cb_arg with the new cert's staple
854 */
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +0200855 struct ocsp_cbk_arg *cb_arg;
yanbzhube2774d2015-12-10 15:07:30 -0500856 struct certificate_ocsp *tmp_ocsp;
857 int index;
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +0200858 int key_type;
Emmanuel Hocdetb7a4c342017-01-06 12:57:46 +0100859 EVP_PKEY *pkey;
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +0200860
861#ifdef SSL_CTX_get_tlsext_status_arg
862 SSL_CTX_ctrl(ctx, SSL_CTRL_GET_TLSEXT_STATUS_REQ_CB_ARG, 0, &cb_arg);
863#else
864 cb_arg = ctx->tlsext_status_arg;
865#endif
yanbzhube2774d2015-12-10 15:07:30 -0500866
867 /*
868 * The following few lines will convert cb_arg from a single ocsp to multi ocsp
869 * the order of operations below matter, take care when changing it
870 */
871 tmp_ocsp = cb_arg->s_ocsp;
872 index = ssl_sock_get_ocsp_arg_kt_index(cb_arg->single_kt);
873 cb_arg->s_ocsp = NULL;
874 cb_arg->m_ocsp[index] = tmp_ocsp;
875 cb_arg->is_single = 0;
876 cb_arg->single_kt = 0;
877
Emmanuel Hocdetb7a4c342017-01-06 12:57:46 +0100878 pkey = X509_get_pubkey(x);
879 key_type = EVP_PKEY_base_id(pkey);
880 EVP_PKEY_free(pkey);
881
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +0200882 index = ssl_sock_get_ocsp_arg_kt_index(key_type);
yanbzhube2774d2015-12-10 15:07:30 -0500883 if (index >= 0 && !cb_arg->m_ocsp[index])
884 cb_arg->m_ocsp[index] = iocsp;
885
886 }
Emeric Brun4147b2e2014-06-16 18:36:30 +0200887
888 ret = 0;
889
890 warn = NULL;
891 if (ssl_sock_load_ocsp_response_from_file(ocsp_path, iocsp, cid, &warn)) {
892 memprintf(&warn, "Loading '%s': %s. Content will be ignored", ocsp_path, warn ? warn : "failure");
893 Warning("%s.\n", warn);
894 }
895
896out:
897 if (ssl)
898 SSL_free(ssl);
899
900 if (in)
901 BIO_free(in);
902
903 if (xi)
904 X509_free(xi);
905
906 if (cid)
907 OCSP_CERTID_free(cid);
908
909 if (ocsp)
910 free(ocsp);
911
912 if (warn)
913 free(warn);
914
915
916 return ret;
917}
918
919#endif
920
Daniel Jakots54ffb912015-11-06 20:02:41 +0100921#if (OPENSSL_VERSION_NUMBER >= 0x1000200fL && !defined OPENSSL_NO_TLSEXT && !defined OPENSSL_IS_BORINGSSL && !defined LIBRESSL_VERSION_NUMBER)
Janusz Dziemidowicz2c701b52015-03-07 23:03:59 +0100922
923#define CT_EXTENSION_TYPE 18
924
925static int sctl_ex_index = -1;
926
927/*
928 * Try to parse Signed Certificate Timestamp List structure. This function
929 * makes only basic test if the data seems like SCTL. No signature validation
930 * is performed.
931 */
932static int ssl_sock_parse_sctl(struct chunk *sctl)
933{
934 int ret = 1;
935 int len, pos, sct_len;
936 unsigned char *data;
937
938 if (sctl->len < 2)
939 goto out;
940
941 data = (unsigned char *)sctl->str;
942 len = (data[0] << 8) | data[1];
943
944 if (len + 2 != sctl->len)
945 goto out;
946
947 data = data + 2;
948 pos = 0;
949 while (pos < len) {
950 if (len - pos < 2)
951 goto out;
952
953 sct_len = (data[pos] << 8) | data[pos + 1];
954 if (pos + sct_len + 2 > len)
955 goto out;
956
957 pos += sct_len + 2;
958 }
959
960 ret = 0;
961
962out:
963 return ret;
964}
965
966static int ssl_sock_load_sctl_from_file(const char *sctl_path, struct chunk **sctl)
967{
968 int fd = -1;
969 int r = 0;
970 int ret = 1;
971
972 *sctl = NULL;
973
974 fd = open(sctl_path, O_RDONLY);
975 if (fd == -1)
976 goto end;
977
978 trash.len = 0;
979 while (trash.len < trash.size) {
980 r = read(fd, trash.str + trash.len, trash.size - trash.len);
981 if (r < 0) {
982 if (errno == EINTR)
983 continue;
984
985 goto end;
986 }
987 else if (r == 0) {
988 break;
989 }
990 trash.len += r;
991 }
992
993 ret = ssl_sock_parse_sctl(&trash);
994 if (ret)
995 goto end;
996
Vincent Bernat02779b62016-04-03 13:48:43 +0200997 *sctl = calloc(1, sizeof(**sctl));
Janusz Dziemidowicz2c701b52015-03-07 23:03:59 +0100998 if (!chunk_dup(*sctl, &trash)) {
999 free(*sctl);
1000 *sctl = NULL;
1001 goto end;
1002 }
1003
1004end:
1005 if (fd != -1)
1006 close(fd);
1007
1008 return ret;
1009}
1010
1011int ssl_sock_sctl_add_cbk(SSL *ssl, unsigned ext_type, const unsigned char **out, size_t *outlen, int *al, void *add_arg)
1012{
Vincent Bernat3c2f2f22016-04-03 13:48:42 +02001013 struct chunk *sctl = add_arg;
Janusz Dziemidowicz2c701b52015-03-07 23:03:59 +01001014
1015 *out = (unsigned char *)sctl->str;
1016 *outlen = sctl->len;
1017
1018 return 1;
1019}
1020
1021int ssl_sock_sctl_parse_cbk(SSL *s, unsigned int ext_type, const unsigned char *in, size_t inlen, int *al, void *parse_arg)
1022{
1023 return 1;
1024}
1025
1026static int ssl_sock_load_sctl(SSL_CTX *ctx, const char *cert_path)
1027{
1028 char sctl_path[MAXPATHLEN+1];
1029 int ret = -1;
1030 struct stat st;
1031 struct chunk *sctl = NULL;
1032
1033 snprintf(sctl_path, MAXPATHLEN+1, "%s.sctl", cert_path);
1034
1035 if (stat(sctl_path, &st))
1036 return 1;
1037
1038 if (ssl_sock_load_sctl_from_file(sctl_path, &sctl))
1039 goto out;
1040
1041 if (!SSL_CTX_add_server_custom_ext(ctx, CT_EXTENSION_TYPE, ssl_sock_sctl_add_cbk, NULL, sctl, ssl_sock_sctl_parse_cbk, NULL)) {
1042 free(sctl);
1043 goto out;
1044 }
1045
1046 SSL_CTX_set_ex_data(ctx, sctl_ex_index, sctl);
1047
1048 ret = 0;
1049
1050out:
1051 return ret;
1052}
1053
1054#endif
1055
Emeric Brune1f38db2012-09-03 20:36:47 +02001056void ssl_sock_infocbk(const SSL *ssl, int where, int ret)
1057{
Vincent Bernat3c2f2f22016-04-03 13:48:42 +02001058 struct connection *conn = SSL_get_app_data(ssl);
Emeric Brund8b2bb52014-01-28 15:43:53 +01001059 BIO *write_bio;
Willy Tarreau622317d2015-02-27 16:36:16 +01001060 (void)ret; /* shut gcc stupid warning */
Emeric Brune1f38db2012-09-03 20:36:47 +02001061
1062 if (where & SSL_CB_HANDSHAKE_START) {
1063 /* Disable renegotiation (CVE-2009-3555) */
Willy Tarreau20879a02012-12-03 16:32:10 +01001064 if (conn->flags & CO_FL_CONNECTED) {
Emeric Brune1f38db2012-09-03 20:36:47 +02001065 conn->flags |= CO_FL_ERROR;
Willy Tarreau20879a02012-12-03 16:32:10 +01001066 conn->err_code = CO_ER_SSL_RENEG;
1067 }
Emeric Brune1f38db2012-09-03 20:36:47 +02001068 }
Emeric Brund8b2bb52014-01-28 15:43:53 +01001069
1070 if ((where & SSL_CB_ACCEPT_LOOP) == SSL_CB_ACCEPT_LOOP) {
1071 if (!(conn->xprt_st & SSL_SOCK_ST_FL_16K_WBFSIZE)) {
1072 /* Long certificate chains optimz
1073 If write and read bios are differents, we
1074 consider that the buffering was activated,
1075 so we rise the output buffer size from 4k
1076 to 16k */
1077 write_bio = SSL_get_wbio(ssl);
1078 if (write_bio != SSL_get_rbio(ssl)) {
1079 BIO_set_write_buffer_size(write_bio, 16384);
1080 conn->xprt_st |= SSL_SOCK_ST_FL_16K_WBFSIZE;
1081 }
1082 }
1083 }
Emeric Brunfc0421f2012-09-07 17:30:07 +02001084}
1085
Emeric Brune64aef12012-09-21 13:15:06 +02001086/* Callback is called for each certificate of the chain during a verify
1087 ok is set to 1 if preverify detect no error on current certificate.
1088 Returns 0 to break the handshake, 1 otherwise. */
Evan Broderbe554312013-06-27 00:05:25 -07001089int ssl_sock_bind_verifycbk(int ok, X509_STORE_CTX *x_store)
Emeric Brune64aef12012-09-21 13:15:06 +02001090{
1091 SSL *ssl;
1092 struct connection *conn;
Emeric Brun81c00f02012-09-21 14:31:21 +02001093 int err, depth;
Emeric Brune64aef12012-09-21 13:15:06 +02001094
1095 ssl = X509_STORE_CTX_get_ex_data(x_store, SSL_get_ex_data_X509_STORE_CTX_idx());
Vincent Bernat3c2f2f22016-04-03 13:48:42 +02001096 conn = SSL_get_app_data(ssl);
Emeric Brune64aef12012-09-21 13:15:06 +02001097
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02001098 conn->xprt_st |= SSL_SOCK_ST_FL_VERIFY_DONE;
Emeric Brune64aef12012-09-21 13:15:06 +02001099
Emeric Brun81c00f02012-09-21 14:31:21 +02001100 if (ok) /* no errors */
1101 return ok;
1102
1103 depth = X509_STORE_CTX_get_error_depth(x_store);
1104 err = X509_STORE_CTX_get_error(x_store);
1105
1106 /* check if CA error needs to be ignored */
1107 if (depth > 0) {
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02001108 if (!SSL_SOCK_ST_TO_CA_ERROR(conn->xprt_st)) {
1109 conn->xprt_st |= SSL_SOCK_CA_ERROR_TO_ST(err);
1110 conn->xprt_st |= SSL_SOCK_CAEDEPTH_TO_ST(depth);
Emeric Brunf282a812012-09-21 15:27:54 +02001111 }
1112
Emeric Brun1eb20ef2012-12-03 13:24:29 +01001113 if (objt_listener(conn->target)->bind_conf->ca_ignerr & (1ULL << err)) {
Thierry FOURNIER / OZON.IO8b068c22016-10-10 11:59:50 +02001114 ssl_sock_dump_errors(conn);
Emeric Brun1eb20ef2012-12-03 13:24:29 +01001115 ERR_clear_error();
Emeric Brun81c00f02012-09-21 14:31:21 +02001116 return 1;
Emeric Brun1eb20ef2012-12-03 13:24:29 +01001117 }
Emeric Brun81c00f02012-09-21 14:31:21 +02001118
Willy Tarreau20879a02012-12-03 16:32:10 +01001119 conn->err_code = CO_ER_SSL_CA_FAIL;
Emeric Brun81c00f02012-09-21 14:31:21 +02001120 return 0;
1121 }
1122
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02001123 if (!SSL_SOCK_ST_TO_CRTERROR(conn->xprt_st))
1124 conn->xprt_st |= SSL_SOCK_CRTERROR_TO_ST(err);
Emeric Brunf282a812012-09-21 15:27:54 +02001125
Emeric Brun81c00f02012-09-21 14:31:21 +02001126 /* check if certificate error needs to be ignored */
Emeric Brun1eb20ef2012-12-03 13:24:29 +01001127 if (objt_listener(conn->target)->bind_conf->crt_ignerr & (1ULL << err)) {
Thierry FOURNIER / OZON.IO8b068c22016-10-10 11:59:50 +02001128 ssl_sock_dump_errors(conn);
Emeric Brun1eb20ef2012-12-03 13:24:29 +01001129 ERR_clear_error();
Emeric Brun81c00f02012-09-21 14:31:21 +02001130 return 1;
Emeric Brun1eb20ef2012-12-03 13:24:29 +01001131 }
Emeric Brun81c00f02012-09-21 14:31:21 +02001132
Willy Tarreau20879a02012-12-03 16:32:10 +01001133 conn->err_code = CO_ER_SSL_CRT_FAIL;
Emeric Brun81c00f02012-09-21 14:31:21 +02001134 return 0;
Emeric Brune64aef12012-09-21 13:15:06 +02001135}
1136
Emeric Brun29f037d2014-04-25 19:05:36 +02001137/* Callback is called for ssl protocol analyse */
1138void ssl_sock_msgcbk(int write_p, int version, int content_type, const void *buf, size_t len, SSL *ssl, void *arg)
1139{
Emeric Brun29f037d2014-04-25 19:05:36 +02001140#ifdef TLS1_RT_HEARTBEAT
1141 /* test heartbeat received (write_p is set to 0
1142 for a received record) */
Willy Tarreauf51c6982014-04-25 20:02:39 +02001143 if ((content_type == TLS1_RT_HEARTBEAT) && (write_p == 0)) {
Vincent Bernat3c2f2f22016-04-03 13:48:42 +02001144 struct connection *conn = SSL_get_app_data(ssl);
Willy Tarreauf51c6982014-04-25 20:02:39 +02001145 const unsigned char *p = buf;
1146 unsigned int payload;
1147
Emeric Brun29f037d2014-04-25 19:05:36 +02001148 conn->xprt_st |= SSL_SOCK_RECV_HEARTBEAT;
Willy Tarreauf51c6982014-04-25 20:02:39 +02001149
1150 /* Check if this is a CVE-2014-0160 exploitation attempt. */
1151 if (*p != TLS1_HB_REQUEST)
1152 return;
1153
Willy Tarreauaeed6722014-04-25 23:59:58 +02001154 if (len < 1 + 2 + 16) /* 1 type + 2 size + 0 payload + 16 padding */
Willy Tarreauf51c6982014-04-25 20:02:39 +02001155 goto kill_it;
1156
1157 payload = (p[1] * 256) + p[2];
Willy Tarreau3b2fdb62014-04-25 23:44:22 +02001158 if (3 + payload + 16 <= len)
Willy Tarreauf51c6982014-04-25 20:02:39 +02001159 return; /* OK no problem */
Willy Tarreauaeed6722014-04-25 23:59:58 +02001160 kill_it:
Willy Tarreau3b2fdb62014-04-25 23:44:22 +02001161 /* We have a clear heartbleed attack (CVE-2014-0160), the
1162 * advertised payload is larger than the advertised packet
1163 * length, so we have garbage in the buffer between the
1164 * payload and the end of the buffer (p+len). We can't know
1165 * if the SSL stack is patched, and we don't know if we can
1166 * safely wipe out the area between p+3+len and payload.
1167 * So instead, we prevent the response from being sent by
1168 * setting the max_send_fragment to 0 and we report an SSL
1169 * error, which will kill this connection. It will be reported
1170 * above as SSL_ERROR_SSL while an other handshake failure with
Willy Tarreauf51c6982014-04-25 20:02:39 +02001171 * a heartbeat message will be reported as SSL_ERROR_SYSCALL.
1172 */
Willy Tarreau3b2fdb62014-04-25 23:44:22 +02001173 ssl->max_send_fragment = 0;
Willy Tarreauf51c6982014-04-25 20:02:39 +02001174 SSLerr(SSL_F_TLS1_HEARTBEAT, SSL_R_SSL_HANDSHAKE_FAILURE);
1175 return;
1176 }
Emeric Brun29f037d2014-04-25 19:05:36 +02001177#endif
1178}
1179
Willy Tarreau6c9a3d52012-10-18 18:57:14 +02001180#ifdef OPENSSL_NPN_NEGOTIATED
1181/* This callback is used so that the server advertises the list of
1182 * negociable protocols for NPN.
1183 */
1184static int ssl_sock_advertise_npn_protos(SSL *s, const unsigned char **data,
1185 unsigned int *len, void *arg)
1186{
Emmanuel Hocdet98263292016-12-29 18:26:15 +01001187 struct ssl_bind_conf *conf = arg;
Willy Tarreau6c9a3d52012-10-18 18:57:14 +02001188
1189 *data = (const unsigned char *)conf->npn_str;
1190 *len = conf->npn_len;
1191 return SSL_TLSEXT_ERR_OK;
1192}
1193#endif
1194
Dirkjan Bussink48f1c4e2014-02-13 12:29:42 +01001195#ifdef TLSEXT_TYPE_application_layer_protocol_negotiation
Willy Tarreauab861d32013-04-02 02:30:41 +02001196/* This callback is used so that the server advertises the list of
1197 * negociable protocols for ALPN.
1198 */
Dirkjan Bussink48f1c4e2014-02-13 12:29:42 +01001199static int ssl_sock_advertise_alpn_protos(SSL *s, const unsigned char **out,
1200 unsigned char *outlen,
1201 const unsigned char *server,
1202 unsigned int server_len, void *arg)
Willy Tarreauab861d32013-04-02 02:30:41 +02001203{
Emmanuel Hocdet98263292016-12-29 18:26:15 +01001204 struct ssl_bind_conf *conf = arg;
Willy Tarreauab861d32013-04-02 02:30:41 +02001205
Dirkjan Bussink48f1c4e2014-02-13 12:29:42 +01001206 if (SSL_select_next_proto((unsigned char**) out, outlen, (const unsigned char *)conf->alpn_str,
1207 conf->alpn_len, server, server_len) != OPENSSL_NPN_NEGOTIATED) {
1208 return SSL_TLSEXT_ERR_NOACK;
1209 }
Willy Tarreauab861d32013-04-02 02:30:41 +02001210 return SSL_TLSEXT_ERR_OK;
1211}
1212#endif
1213
Willy Tarreauc8ad3be2015-06-17 15:48:26 +02001214#ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME
Emmanuel Hocdetfdec7892017-01-13 17:48:18 +01001215#ifndef SSL_NO_GENERATE_CERTIFICATES
Christopher Faulet85b5a1a2015-10-09 11:46:32 +02001216static DH *ssl_get_tmp_dh(SSL *ssl, int export, int keylen);
1217
Christopher Faulet30548802015-06-11 13:39:32 +02001218/* Create a X509 certificate with the specified servername and serial. This
1219 * function returns a SSL_CTX object or NULL if an error occurs. */
Christopher Faulet7969a332015-10-09 11:15:03 +02001220static SSL_CTX *
Christopher Faulet635c0ad2015-11-12 11:35:51 +01001221ssl_sock_do_create_cert(const char *servername, struct bind_conf *bind_conf, SSL *ssl)
Christopher Faulet31af49d2015-06-09 17:29:50 +02001222{
Christopher Faulet635c0ad2015-11-12 11:35:51 +01001223 static unsigned int serial = 0;
1224
Christopher Faulet7969a332015-10-09 11:15:03 +02001225 X509 *cacert = bind_conf->ca_sign_cert;
1226 EVP_PKEY *capkey = bind_conf->ca_sign_pkey;
Christopher Faulet31af49d2015-06-09 17:29:50 +02001227 SSL_CTX *ssl_ctx = NULL;
1228 X509 *newcrt = NULL;
1229 EVP_PKEY *pkey = NULL;
Christopher Faulet31af49d2015-06-09 17:29:50 +02001230 X509_NAME *name;
1231 const EVP_MD *digest;
1232 X509V3_CTX ctx;
1233 unsigned int i;
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02001234 int key_type;
Christopher Faulet31af49d2015-06-09 17:29:50 +02001235
Christopher Faulet7969a332015-10-09 11:15:03 +02001236 /* Get the private key of the defautl certificate and use it */
1237 if (!(pkey = SSL_get_privatekey(ssl)))
Christopher Faulet31af49d2015-06-09 17:29:50 +02001238 goto mkcert_error;
1239
1240 /* Create the certificate */
1241 if (!(newcrt = X509_new()))
1242 goto mkcert_error;
1243
1244 /* Set version number for the certificate (X509v3) and the serial
1245 * number */
1246 if (X509_set_version(newcrt, 2L) != 1)
1247 goto mkcert_error;
Christopher Faulet635c0ad2015-11-12 11:35:51 +01001248 if (!serial)
1249 serial = now_ms;
1250 ASN1_INTEGER_set(X509_get_serialNumber(newcrt), serial++);
Christopher Faulet31af49d2015-06-09 17:29:50 +02001251
1252 /* Set duration for the certificate */
1253 if (!X509_gmtime_adj(X509_get_notBefore(newcrt), (long)-60*60*24) ||
1254 !X509_gmtime_adj(X509_get_notAfter(newcrt),(long)60*60*24*365))
1255 goto mkcert_error;
1256
1257 /* set public key in the certificate */
1258 if (X509_set_pubkey(newcrt, pkey) != 1)
1259 goto mkcert_error;
1260
1261 /* Set issuer name from the CA */
1262 if (!(name = X509_get_subject_name(cacert)))
1263 goto mkcert_error;
1264 if (X509_set_issuer_name(newcrt, name) != 1)
1265 goto mkcert_error;
1266
1267 /* Set the subject name using the same, but the CN */
1268 name = X509_NAME_dup(name);
1269 if (X509_NAME_add_entry_by_txt(name, "CN", MBSTRING_ASC,
1270 (const unsigned char *)servername,
1271 -1, -1, 0) != 1) {
1272 X509_NAME_free(name);
1273 goto mkcert_error;
1274 }
1275 if (X509_set_subject_name(newcrt, name) != 1) {
1276 X509_NAME_free(name);
1277 goto mkcert_error;
1278 }
1279 X509_NAME_free(name);
1280
1281 /* Add x509v3 extensions as specified */
1282 X509V3_set_ctx(&ctx, cacert, newcrt, NULL, NULL, 0);
1283 for (i = 0; i < X509V3_EXT_SIZE; i++) {
1284 X509_EXTENSION *ext;
1285
1286 if (!(ext = X509V3_EXT_conf(NULL, &ctx, x509v3_ext_names[i], x509v3_ext_values[i])))
1287 goto mkcert_error;
1288 if (!X509_add_ext(newcrt, ext, -1)) {
1289 X509_EXTENSION_free(ext);
1290 goto mkcert_error;
1291 }
1292 X509_EXTENSION_free(ext);
1293 }
1294
1295 /* Sign the certificate with the CA private key */
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02001296
1297 key_type = EVP_PKEY_base_id(capkey);
1298
1299 if (key_type == EVP_PKEY_DSA)
1300 digest = EVP_sha1();
1301 else if (key_type == EVP_PKEY_RSA)
Christopher Faulet31af49d2015-06-09 17:29:50 +02001302 digest = EVP_sha256();
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02001303 else if (key_type == EVP_PKEY_EC)
Christopher Faulet7969a332015-10-09 11:15:03 +02001304 digest = EVP_sha256();
1305 else {
Christopher Faulete7db2162015-10-19 13:59:24 +02001306#if (OPENSSL_VERSION_NUMBER >= 0x1000000fL)
Christopher Faulet7969a332015-10-09 11:15:03 +02001307 int nid;
1308
1309 if (EVP_PKEY_get_default_digest_nid(capkey, &nid) <= 0)
1310 goto mkcert_error;
1311 if (!(digest = EVP_get_digestbynid(nid)))
1312 goto mkcert_error;
Christopher Faulete7db2162015-10-19 13:59:24 +02001313#else
1314 goto mkcert_error;
1315#endif
Christopher Faulet7969a332015-10-09 11:15:03 +02001316 }
1317
Christopher Faulet31af49d2015-06-09 17:29:50 +02001318 if (!(X509_sign(newcrt, capkey, digest)))
1319 goto mkcert_error;
1320
1321 /* Create and set the new SSL_CTX */
1322 if (!(ssl_ctx = SSL_CTX_new(SSLv23_server_method())))
1323 goto mkcert_error;
1324 if (!SSL_CTX_use_PrivateKey(ssl_ctx, pkey))
1325 goto mkcert_error;
1326 if (!SSL_CTX_use_certificate(ssl_ctx, newcrt))
1327 goto mkcert_error;
1328 if (!SSL_CTX_check_private_key(ssl_ctx))
1329 goto mkcert_error;
1330
1331 if (newcrt) X509_free(newcrt);
Christopher Faulet7969a332015-10-09 11:15:03 +02001332
Christopher Faulet85b5a1a2015-10-09 11:46:32 +02001333 SSL_CTX_set_tmp_dh_callback(ssl_ctx, ssl_get_tmp_dh);
1334#if defined(SSL_CTX_set_tmp_ecdh) && !defined(OPENSSL_NO_ECDH)
1335 {
Emmanuel Hocdet98263292016-12-29 18:26:15 +01001336 const char *ecdhe = (bind_conf->ssl_conf.ecdhe ? bind_conf->ssl_conf.ecdhe : ECDHE_DEFAULT_CURVE);
Christopher Faulet85b5a1a2015-10-09 11:46:32 +02001337 EC_KEY *ecc;
1338 int nid;
1339
1340 if ((nid = OBJ_sn2nid(ecdhe)) == NID_undef)
1341 goto end;
1342 if (!(ecc = EC_KEY_new_by_curve_name(nid)))
1343 goto end;
1344 SSL_CTX_set_tmp_ecdh(ssl_ctx, ecc);
1345 EC_KEY_free(ecc);
1346 }
1347#endif
1348 end:
Christopher Faulet31af49d2015-06-09 17:29:50 +02001349 return ssl_ctx;
1350
1351 mkcert_error:
1352 if (ssl_ctx) SSL_CTX_free(ssl_ctx);
1353 if (newcrt) X509_free(newcrt);
Christopher Faulet31af49d2015-06-09 17:29:50 +02001354 return NULL;
1355}
1356
Christopher Faulet7969a332015-10-09 11:15:03 +02001357SSL_CTX *
Christopher Faulet635c0ad2015-11-12 11:35:51 +01001358ssl_sock_create_cert(struct connection *conn, const char *servername, unsigned int key)
Christopher Faulet7969a332015-10-09 11:15:03 +02001359{
1360 struct bind_conf *bind_conf = objt_listener(conn->target)->bind_conf;
Christopher Faulet635c0ad2015-11-12 11:35:51 +01001361
1362 return ssl_sock_do_create_cert(servername, bind_conf, conn->xprt_ctx);
Christopher Faulet7969a332015-10-09 11:15:03 +02001363}
1364
Christopher Faulet30548802015-06-11 13:39:32 +02001365/* Do a lookup for a certificate in the LRU cache used to store generated
1366 * certificates. */
1367SSL_CTX *
Christopher Faulet635c0ad2015-11-12 11:35:51 +01001368ssl_sock_get_generated_cert(unsigned int key, struct bind_conf *bind_conf)
Christopher Faulet30548802015-06-11 13:39:32 +02001369{
1370 struct lru64 *lru = NULL;
1371
1372 if (ssl_ctx_lru_tree) {
Christopher Faulet635c0ad2015-11-12 11:35:51 +01001373 lru = lru64_lookup(key, ssl_ctx_lru_tree, bind_conf->ca_sign_cert, 0);
Christopher Faulet30548802015-06-11 13:39:32 +02001374 if (lru && lru->domain)
1375 return (SSL_CTX *)lru->data;
1376 }
1377 return NULL;
1378}
1379
Christopher Fauletd2cab922015-07-28 16:03:47 +02001380/* Set a certificate int the LRU cache used to store generated
1381 * certificate. Return 0 on success, otherwise -1 */
1382int
Christopher Faulet635c0ad2015-11-12 11:35:51 +01001383ssl_sock_set_generated_cert(SSL_CTX *ssl_ctx, unsigned int key, struct bind_conf *bind_conf)
Christopher Faulet30548802015-06-11 13:39:32 +02001384{
1385 struct lru64 *lru = NULL;
1386
1387 if (ssl_ctx_lru_tree) {
Christopher Faulet635c0ad2015-11-12 11:35:51 +01001388 lru = lru64_get(key, ssl_ctx_lru_tree, bind_conf->ca_sign_cert, 0);
Christopher Faulet30548802015-06-11 13:39:32 +02001389 if (!lru)
Christopher Fauletd2cab922015-07-28 16:03:47 +02001390 return -1;
Christopher Faulet30548802015-06-11 13:39:32 +02001391 if (lru->domain && lru->data)
1392 lru->free((SSL_CTX *)lru->data);
Christopher Faulet7969a332015-10-09 11:15:03 +02001393 lru64_commit(lru, ssl_ctx, bind_conf->ca_sign_cert, 0, (void (*)(void *))SSL_CTX_free);
Christopher Fauletd2cab922015-07-28 16:03:47 +02001394 return 0;
Christopher Faulet30548802015-06-11 13:39:32 +02001395 }
Christopher Fauletd2cab922015-07-28 16:03:47 +02001396 return -1;
Christopher Faulet30548802015-06-11 13:39:32 +02001397}
1398
Christopher Faulet635c0ad2015-11-12 11:35:51 +01001399/* Compute the key of the certificate. */
Christopher Faulet30548802015-06-11 13:39:32 +02001400unsigned int
Christopher Faulet635c0ad2015-11-12 11:35:51 +01001401ssl_sock_generated_cert_key(const void *data, size_t len)
Christopher Faulet30548802015-06-11 13:39:32 +02001402{
1403 return XXH32(data, len, ssl_ctx_lru_seed);
1404}
1405
Willy Tarreau2f63ef42015-10-20 15:16:01 +02001406/* Generate a cert and immediately assign it to the SSL session so that the cert's
1407 * refcount is maintained regardless of the cert's presence in the LRU cache.
1408 */
Christopher Faulet31af49d2015-06-09 17:29:50 +02001409static SSL_CTX *
Christopher Faulet7969a332015-10-09 11:15:03 +02001410ssl_sock_generate_certificate(const char *servername, struct bind_conf *bind_conf, SSL *ssl)
Christopher Faulet31af49d2015-06-09 17:29:50 +02001411{
1412 X509 *cacert = bind_conf->ca_sign_cert;
Christopher Faulet31af49d2015-06-09 17:29:50 +02001413 SSL_CTX *ssl_ctx = NULL;
1414 struct lru64 *lru = NULL;
Christopher Faulet635c0ad2015-11-12 11:35:51 +01001415 unsigned int key;
Christopher Faulet31af49d2015-06-09 17:29:50 +02001416
Christopher Faulet635c0ad2015-11-12 11:35:51 +01001417 key = ssl_sock_generated_cert_key(servername, strlen(servername));
Christopher Faulet31af49d2015-06-09 17:29:50 +02001418 if (ssl_ctx_lru_tree) {
Christopher Faulet635c0ad2015-11-12 11:35:51 +01001419 lru = lru64_get(key, ssl_ctx_lru_tree, cacert, 0);
Christopher Faulet31af49d2015-06-09 17:29:50 +02001420 if (lru && lru->domain)
1421 ssl_ctx = (SSL_CTX *)lru->data;
Christopher Fauletd2cab922015-07-28 16:03:47 +02001422 if (!ssl_ctx && lru) {
Christopher Faulet635c0ad2015-11-12 11:35:51 +01001423 ssl_ctx = ssl_sock_do_create_cert(servername, bind_conf, ssl);
Christopher Faulet31af49d2015-06-09 17:29:50 +02001424 lru64_commit(lru, ssl_ctx, cacert, 0, (void (*)(void *))SSL_CTX_free);
Christopher Fauletd2cab922015-07-28 16:03:47 +02001425 }
Willy Tarreau2f63ef42015-10-20 15:16:01 +02001426 SSL_set_SSL_CTX(ssl, ssl_ctx);
Christopher Faulet31af49d2015-06-09 17:29:50 +02001427 }
Willy Tarreau2f63ef42015-10-20 15:16:01 +02001428 else {
Christopher Faulet635c0ad2015-11-12 11:35:51 +01001429 ssl_ctx = ssl_sock_do_create_cert(servername, bind_conf, ssl);
Willy Tarreau2f63ef42015-10-20 15:16:01 +02001430 SSL_set_SSL_CTX(ssl, ssl_ctx);
1431 /* No LRU cache, this CTX will be released as soon as the session dies */
1432 SSL_CTX_free(ssl_ctx);
1433 }
Christopher Faulet31af49d2015-06-09 17:29:50 +02001434 return ssl_ctx;
1435}
Emmanuel Hocdetfdec7892017-01-13 17:48:18 +01001436#endif /* !defined SSL_NO_GENERATE_CERTIFICATES */
Christopher Faulet31af49d2015-06-09 17:29:50 +02001437
Emmanuel Hocdet530141f2017-03-01 18:54:56 +01001438static void ssl_sock_switchctx_set(SSL *ssl, SSL_CTX *ctx)
1439{
1440 SSL_set_verify(ssl, SSL_CTX_get_verify_mode(ctx), ssl_sock_bind_verifycbk);
1441 SSL_set_client_CA_list(ssl, SSL_dup_CA_list(SSL_CTX_get_client_CA_list(ctx)));
1442 SSL_set_SSL_CTX(ssl, ctx);
1443}
1444
Emmanuel Hocdet05942112017-02-20 16:11:50 +01001445#ifdef OPENSSL_IS_BORINGSSL
1446
1447static int ssl_sock_switchctx_err_cbk(SSL *ssl, int *al, void *priv)
1448{
1449 (void)al; /* shut gcc stupid warning */
1450 (void)priv;
1451
1452 if (!SSL_get_servername(ssl, TLSEXT_NAMETYPE_host_name))
1453 return SSL_TLSEXT_ERR_NOACK;
1454 return SSL_TLSEXT_ERR_OK;
1455}
1456
1457static int ssl_sock_switchctx_cbk(const struct ssl_early_callback_ctx *ctx)
1458{
1459 struct connection *conn;
1460 struct bind_conf *s;
1461 const uint8_t *extension_data;
1462 size_t extension_len;
1463 CBS extension, cipher_suites, server_name_list, host_name, sig_algs;
1464 const SSL_CIPHER *cipher;
1465 uint16_t cipher_suite;
1466 uint8_t name_type, hash, sign;
1467 int has_rsa = 0, has_ecdsa = 0, has_ecdsa_sig = 0;
1468
1469 char *wildp = NULL;
1470 const uint8_t *servername;
1471 struct ebmb_node *node, *n, *node_ecdsa = NULL, *node_rsa = NULL, *node_anonymous = NULL;
1472 int i;
1473
1474 conn = SSL_get_app_data(ctx->ssl);
1475 s = objt_listener(conn->target)->bind_conf;
1476
1477 if (SSL_early_callback_ctx_extension_get(ctx, TLSEXT_TYPE_server_name,
1478 &extension_data, &extension_len)) {
1479 CBS_init(&extension, extension_data, extension_len);
1480
1481 if (!CBS_get_u16_length_prefixed(&extension, &server_name_list)
1482 || !CBS_get_u8(&server_name_list, &name_type)
1483 /* Although the server_name extension was intended to be extensible to
1484 * new name types and multiple names, OpenSSL 1.0.x had a bug which meant
1485 * different name types will cause an error. Further, RFC 4366 originally
1486 * defined syntax inextensibly. RFC 6066 corrected this mistake, but
1487 * adding new name types is no longer feasible.
1488 *
1489 * Act as if the extensibility does not exist to simplify parsing. */
1490 || !CBS_get_u16_length_prefixed(&server_name_list, &host_name)
1491 || CBS_len(&server_name_list) != 0
1492 || CBS_len(&extension) != 0
1493 || name_type != TLSEXT_NAMETYPE_host_name
1494 || CBS_len(&host_name) == 0
1495 || CBS_len(&host_name) > TLSEXT_MAXLEN_host_name
1496 || CBS_contains_zero_byte(&host_name)) {
1497 goto abort;
1498 }
1499 } else {
1500 /* without SNI extension, is the default_ctx (need SSL_TLSEXT_ERR_NOACK) */
1501 if (!s->strict_sni)
1502 return 1;
1503 goto abort;
1504 }
1505
1506 /* extract/check clientHello informations */
1507 if (SSL_early_callback_ctx_extension_get(ctx, TLSEXT_TYPE_signature_algorithms, &extension_data, &extension_len)) {
1508 CBS_init(&extension, extension_data, extension_len);
1509
1510 if (!CBS_get_u16_length_prefixed(&extension, &sig_algs)
1511 || CBS_len(&sig_algs) == 0
1512 || CBS_len(&extension) != 0) {
1513 goto abort;
1514 }
1515 if (CBS_len(&sig_algs) % 2 != 0) {
1516 goto abort;
1517 }
1518 while (CBS_len(&sig_algs) != 0) {
1519 if (!CBS_get_u8(&sig_algs, &hash)
1520 || !CBS_get_u8(&sig_algs, &sign)) {
1521 goto abort;
1522 }
1523 switch (sign) {
1524 case TLSEXT_signature_rsa:
1525 has_rsa = 1;
1526 break;
1527 case TLSEXT_signature_ecdsa:
1528 has_ecdsa_sig = 1;
1529 break;
1530 default:
1531 continue;
1532 }
1533 if (has_ecdsa_sig && has_rsa)
1534 break;
1535 }
1536 } else {
1537 /* without TLSEXT_TYPE_signature_algorithms extension (< TLS 1.2) */
1538 has_rsa = 1;
1539 }
1540 if (has_ecdsa_sig) { /* in very rare case: has ecdsa sign but not a ECDSA cipher */
1541 CBS_init(&cipher_suites, ctx->cipher_suites, ctx->cipher_suites_len);
1542
1543 while (CBS_len(&cipher_suites) != 0) {
1544 if (!CBS_get_u16(&cipher_suites, &cipher_suite)) {
1545 goto abort;
1546 }
1547 cipher = SSL_get_cipher_by_value(cipher_suite);
1548 if (cipher && SSL_CIPHER_is_ECDSA(cipher)) {
1549 has_ecdsa = 1;
1550 break;
1551 }
1552 }
1553 }
1554
1555 servername = CBS_data(&host_name);
1556 for (i = 0; i < trash.size && i < CBS_len(&host_name); i++) {
1557 trash.str[i] = tolower(servername[i]);
1558 if (!wildp && (trash.str[i] == '.'))
1559 wildp = &trash.str[i];
1560 }
1561 trash.str[i] = 0;
1562
1563 /* lookup in full qualified names */
1564 node = ebst_lookup(&s->sni_ctx, trash.str);
1565
1566 /* lookup a not neg filter */
1567 for (n = node; n; n = ebmb_next_dup(n)) {
1568 if (!container_of(n, struct sni_ctx, name)->neg) {
1569 switch(container_of(n, struct sni_ctx, name)->key_sig) {
1570 case TLSEXT_signature_ecdsa:
1571 if (has_ecdsa) {
1572 node_ecdsa = n;
1573 goto find_one;
1574 }
1575 break;
1576 case TLSEXT_signature_rsa:
1577 if (has_rsa && !node_rsa) {
1578 node_rsa = n;
1579 if (!has_ecdsa)
1580 goto find_one;
1581 }
1582 break;
1583 default: /* TLSEXT_signature_anonymous */
1584 if (!node_anonymous)
1585 node_anonymous = n;
1586 break;
1587 }
1588 }
1589 }
1590 if (wildp) {
1591 /* lookup in wildcards names */
1592 node = ebst_lookup(&s->sni_w_ctx, wildp);
1593 for (n = node; n; n = ebmb_next_dup(n)) {
1594 if (!container_of(n, struct sni_ctx, name)->neg) {
1595 switch(container_of(n, struct sni_ctx, name)->key_sig) {
1596 case TLSEXT_signature_ecdsa:
1597 if (has_ecdsa) {
1598 node_ecdsa = n;
1599 goto find_one;
1600 }
1601 break;
1602 case TLSEXT_signature_rsa:
1603 if (has_rsa && !node_rsa) {
1604 node_rsa = n;
1605 if (!has_ecdsa)
1606 goto find_one;
1607 }
1608 break;
1609 default: /* TLSEXT_signature_anonymous */
1610 if (!node_anonymous)
1611 node_anonymous = n;
1612 break;
1613 }
1614 }
1615 }
1616 }
1617 find_one:
1618 /* select by key_signature priority order */
1619 node = node_ecdsa ? node_ecdsa : (node_rsa ? node_rsa : node_anonymous);
1620
1621 if (node) {
1622 /* switch ctx */
Emmanuel Hocdet530141f2017-03-01 18:54:56 +01001623 ssl_sock_switchctx_set(ctx->ssl, container_of(node, struct sni_ctx, name)->ctx);
Emmanuel Hocdet05942112017-02-20 16:11:50 +01001624 return 1;
1625 }
1626 if (!s->strict_sni)
1627 /* no certificate match, is the default_ctx */
1628 /* the client will alert (was SSL_TLSEXT_ERR_ALERT_WARNING, ignored by Boring) */
1629 return 1;
1630 abort:
1631 /* abort handshake (was SSL_TLSEXT_ERR_ALERT_FATAL) */
1632 conn->err_code = CO_ER_SSL_HANDSHAKE;
1633 return -1;
1634}
1635
1636#else /* OPENSSL_IS_BORINGSSL */
1637
Emeric Brunfc0421f2012-09-07 17:30:07 +02001638/* Sets the SSL ctx of <ssl> to match the advertised server name. Returns a
1639 * warning when no match is found, which implies the default (first) cert
1640 * will keep being used.
1641 */
Emmanuel Hocdetfdec7892017-01-13 17:48:18 +01001642static int ssl_sock_switchctx_cbk(SSL *ssl, int *al, void *priv)
Emeric Brunfc0421f2012-09-07 17:30:07 +02001643{
1644 const char *servername;
1645 const char *wildp = NULL;
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +02001646 struct ebmb_node *node, *n;
Emmanuel Hocdetfdec7892017-01-13 17:48:18 +01001647 struct bind_conf *s = priv;
Emeric Brunfc0421f2012-09-07 17:30:07 +02001648 int i;
1649 (void)al; /* shut gcc stupid warning */
1650
1651 servername = SSL_get_servername(ssl, TLSEXT_NAMETYPE_host_name);
Emmanuel Hocdet65623372013-01-24 17:17:15 +01001652 if (!servername) {
Emmanuel Hocdetfdec7892017-01-13 17:48:18 +01001653#if (!defined SSL_NO_GENERATE_CERTIFICATES)
Willy Tarreauf6721452015-07-07 18:04:38 +02001654 if (s->generate_certs) {
Vincent Bernat3c2f2f22016-04-03 13:48:42 +02001655 struct connection *conn = SSL_get_app_data(ssl);
Christopher Faulet635c0ad2015-11-12 11:35:51 +01001656 unsigned int key;
Willy Tarreauf6721452015-07-07 18:04:38 +02001657 SSL_CTX *ctx;
Christopher Faulet30548802015-06-11 13:39:32 +02001658
Willy Tarreauf6721452015-07-07 18:04:38 +02001659 conn_get_to_addr(conn);
1660 if (conn->flags & CO_FL_ADDR_TO_SET) {
Christopher Faulet635c0ad2015-11-12 11:35:51 +01001661 key = ssl_sock_generated_cert_key(&conn->addr.to, get_addr_len(&conn->addr.to));
1662 ctx = ssl_sock_get_generated_cert(key, s);
Willy Tarreauf6721452015-07-07 18:04:38 +02001663 if (ctx) {
1664 /* switch ctx */
1665 SSL_set_SSL_CTX(ssl, ctx);
1666 return SSL_TLSEXT_ERR_OK;
1667 }
Christopher Faulet30548802015-06-11 13:39:32 +02001668 }
1669 }
Emmanuel Hocdetfdec7892017-01-13 17:48:18 +01001670#endif
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +02001671 return (s->strict_sni ?
1672 SSL_TLSEXT_ERR_ALERT_FATAL :
Emmanuel Hocdet79274e22013-05-31 12:47:44 +02001673 SSL_TLSEXT_ERR_NOACK);
Emmanuel Hocdet65623372013-01-24 17:17:15 +01001674 }
Emeric Brunfc0421f2012-09-07 17:30:07 +02001675
Willy Tarreau19d14ef2012-10-29 16:51:55 +01001676 for (i = 0; i < trash.size; i++) {
Emeric Brunfc0421f2012-09-07 17:30:07 +02001677 if (!servername[i])
1678 break;
Willy Tarreau19d14ef2012-10-29 16:51:55 +01001679 trash.str[i] = tolower(servername[i]);
1680 if (!wildp && (trash.str[i] == '.'))
1681 wildp = &trash.str[i];
Emeric Brunfc0421f2012-09-07 17:30:07 +02001682 }
Willy Tarreau19d14ef2012-10-29 16:51:55 +01001683 trash.str[i] = 0;
Emeric Brunfc0421f2012-09-07 17:30:07 +02001684
1685 /* lookup in full qualified names */
Willy Tarreau19d14ef2012-10-29 16:51:55 +01001686 node = ebst_lookup(&s->sni_ctx, trash.str);
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +02001687
1688 /* lookup a not neg filter */
1689 for (n = node; n; n = ebmb_next_dup(n)) {
1690 if (!container_of(n, struct sni_ctx, name)->neg) {
1691 node = n;
1692 break;
Emmanuel Hocdet65623372013-01-24 17:17:15 +01001693 }
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +02001694 }
1695 if (!node && wildp) {
1696 /* lookup in wildcards names */
Emeric Brunfc0421f2012-09-07 17:30:07 +02001697 node = ebst_lookup(&s->sni_w_ctx, wildp);
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +02001698 }
1699 if (!node || container_of(node, struct sni_ctx, name)->neg) {
Emmanuel Hocdetfdec7892017-01-13 17:48:18 +01001700#if (!defined SSL_NO_GENERATE_CERTIFICATES)
Christopher Faulet31af49d2015-06-09 17:29:50 +02001701 SSL_CTX *ctx;
Christopher Faulet31af49d2015-06-09 17:29:50 +02001702 if (s->generate_certs &&
Christopher Faulet7969a332015-10-09 11:15:03 +02001703 (ctx = ssl_sock_generate_certificate(servername, s, ssl))) {
Christopher Faulet31af49d2015-06-09 17:29:50 +02001704 /* switch ctx */
Christopher Faulet31af49d2015-06-09 17:29:50 +02001705 return SSL_TLSEXT_ERR_OK;
1706 }
Emmanuel Hocdetfdec7892017-01-13 17:48:18 +01001707#endif
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +02001708 return (s->strict_sni ?
1709 SSL_TLSEXT_ERR_ALERT_FATAL :
1710 SSL_TLSEXT_ERR_ALERT_WARNING);
Emeric Brunfc0421f2012-09-07 17:30:07 +02001711 }
1712
1713 /* switch ctx */
Emmanuel Hocdet530141f2017-03-01 18:54:56 +01001714 ssl_sock_switchctx_set(ssl, container_of(node, struct sni_ctx, name)->ctx);
Emeric Brunfc0421f2012-09-07 17:30:07 +02001715 return SSL_TLSEXT_ERR_OK;
1716}
Emmanuel Hocdet05942112017-02-20 16:11:50 +01001717#endif /* (!) OPENSSL_IS_BORINGSSL */
Emeric Brunfc0421f2012-09-07 17:30:07 +02001718#endif /* SSL_CTRL_SET_TLSEXT_HOSTNAME */
1719
Emeric Bruna4bcd9a2012-09-20 16:19:02 +02001720#ifndef OPENSSL_NO_DH
Remi Gacognef46cd6e2014-06-12 14:58:40 +02001721
1722static DH * ssl_get_dh_1024(void)
1723{
Remi Gacogned3a341a2015-05-29 16:26:17 +02001724 static unsigned char dh1024_p[]={
1725 0xFA,0xF9,0x2A,0x22,0x2A,0xA7,0x7F,0xE1,0x67,0x4E,0x53,0xF7,
1726 0x56,0x13,0xC3,0xB1,0xE3,0x29,0x6B,0x66,0x31,0x6A,0x7F,0xB3,
1727 0xC2,0x68,0x6B,0xCB,0x1D,0x57,0x39,0x1D,0x1F,0xFF,0x1C,0xC9,
1728 0xA6,0xA4,0x98,0x82,0x31,0x5D,0x25,0xFF,0x8A,0xE0,0x73,0x96,
1729 0x81,0xC8,0x83,0x79,0xC1,0x5A,0x04,0xF8,0x37,0x0D,0xA8,0x3D,
1730 0xAE,0x74,0xBC,0xDB,0xB6,0xA4,0x75,0xD9,0x71,0x8A,0xA0,0x17,
1731 0x9E,0x2D,0xC8,0xA8,0xDF,0x2C,0x5F,0x82,0x95,0xF8,0x92,0x9B,
1732 0xA7,0x33,0x5F,0x89,0x71,0xC8,0x2D,0x6B,0x18,0x86,0xC4,0x94,
1733 0x22,0xA5,0x52,0x8D,0xF6,0xF6,0xD2,0x37,0x92,0x0F,0xA5,0xCC,
1734 0xDB,0x7B,0x1D,0x3D,0xA1,0x31,0xB7,0x80,0x8F,0x0B,0x67,0x5E,
1735 0x36,0xA5,0x60,0x0C,0xF1,0x95,0x33,0x8B,
1736 };
1737 static unsigned char dh1024_g[]={
1738 0x02,
1739 };
1740
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02001741 BIGNUM *p;
1742 BIGNUM *g;
Remi Gacognef46cd6e2014-06-12 14:58:40 +02001743 DH *dh = DH_new();
1744 if (dh) {
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02001745 p = BN_bin2bn(dh1024_p, sizeof dh1024_p, NULL);
1746 g = BN_bin2bn(dh1024_g, sizeof dh1024_g, NULL);
Remi Gacogned3a341a2015-05-29 16:26:17 +02001747
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02001748 if (!p || !g) {
Remi Gacognef46cd6e2014-06-12 14:58:40 +02001749 DH_free(dh);
1750 dh = NULL;
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02001751 } else {
1752 DH_set0_pqg(dh, p, NULL, g);
Remi Gacognef46cd6e2014-06-12 14:58:40 +02001753 }
1754 }
1755 return dh;
1756}
1757
1758static DH *ssl_get_dh_2048(void)
1759{
Remi Gacogned3a341a2015-05-29 16:26:17 +02001760 static unsigned char dh2048_p[]={
1761 0xEC,0x86,0xF8,0x70,0xA0,0x33,0x16,0xEC,0x05,0x1A,0x73,0x59,
1762 0xCD,0x1F,0x8B,0xF8,0x29,0xE4,0xD2,0xCF,0x52,0xDD,0xC2,0x24,
1763 0x8D,0xB5,0x38,0x9A,0xFB,0x5C,0xA4,0xE4,0xB2,0xDA,0xCE,0x66,
1764 0x50,0x74,0xA6,0x85,0x4D,0x4B,0x1D,0x30,0xB8,0x2B,0xF3,0x10,
1765 0xE9,0xA7,0x2D,0x05,0x71,0xE7,0x81,0xDF,0x8B,0x59,0x52,0x3B,
1766 0x5F,0x43,0x0B,0x68,0xF1,0xDB,0x07,0xBE,0x08,0x6B,0x1B,0x23,
1767 0xEE,0x4D,0xCC,0x9E,0x0E,0x43,0xA0,0x1E,0xDF,0x43,0x8C,0xEC,
1768 0xBE,0xBE,0x90,0xB4,0x51,0x54,0xB9,0x2F,0x7B,0x64,0x76,0x4E,
1769 0x5D,0xD4,0x2E,0xAE,0xC2,0x9E,0xAE,0x51,0x43,0x59,0xC7,0x77,
1770 0x9C,0x50,0x3C,0x0E,0xED,0x73,0x04,0x5F,0xF1,0x4C,0x76,0x2A,
1771 0xD8,0xF8,0xCF,0xFC,0x34,0x40,0xD1,0xB4,0x42,0x61,0x84,0x66,
1772 0x42,0x39,0x04,0xF8,0x68,0xB2,0x62,0xD7,0x55,0xED,0x1B,0x74,
1773 0x75,0x91,0xE0,0xC5,0x69,0xC1,0x31,0x5C,0xDB,0x7B,0x44,0x2E,
1774 0xCE,0x84,0x58,0x0D,0x1E,0x66,0x0C,0xC8,0x44,0x9E,0xFD,0x40,
1775 0x08,0x67,0x5D,0xFB,0xA7,0x76,0x8F,0x00,0x11,0x87,0xE9,0x93,
1776 0xF9,0x7D,0xC4,0xBC,0x74,0x55,0x20,0xD4,0x4A,0x41,0x2F,0x43,
1777 0x42,0x1A,0xC1,0xF2,0x97,0x17,0x49,0x27,0x37,0x6B,0x2F,0x88,
1778 0x7E,0x1C,0xA0,0xA1,0x89,0x92,0x27,0xD9,0x56,0x5A,0x71,0xC1,
1779 0x56,0x37,0x7E,0x3A,0x9D,0x05,0xE7,0xEE,0x5D,0x8F,0x82,0x17,
1780 0xBC,0xE9,0xC2,0x93,0x30,0x82,0xF9,0xF4,0xC9,0xAE,0x49,0xDB,
1781 0xD0,0x54,0xB4,0xD9,0x75,0x4D,0xFA,0x06,0xB8,0xD6,0x38,0x41,
1782 0xB7,0x1F,0x77,0xF3,
1783 };
1784 static unsigned char dh2048_g[]={
1785 0x02,
1786 };
1787
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02001788 BIGNUM *p;
1789 BIGNUM *g;
Remi Gacognef46cd6e2014-06-12 14:58:40 +02001790 DH *dh = DH_new();
1791 if (dh) {
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02001792 p = BN_bin2bn(dh2048_p, sizeof dh2048_p, NULL);
1793 g = BN_bin2bn(dh2048_g, sizeof dh2048_g, NULL);
Remi Gacogned3a341a2015-05-29 16:26:17 +02001794
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02001795 if (!p || !g) {
Remi Gacognef46cd6e2014-06-12 14:58:40 +02001796 DH_free(dh);
1797 dh = NULL;
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02001798 } else {
1799 DH_set0_pqg(dh, p, NULL, g);
Remi Gacognef46cd6e2014-06-12 14:58:40 +02001800 }
1801 }
1802 return dh;
1803}
1804
1805static DH *ssl_get_dh_4096(void)
1806{
Remi Gacogned3a341a2015-05-29 16:26:17 +02001807 static unsigned char dh4096_p[]={
1808 0xDE,0x16,0x94,0xCD,0x99,0x58,0x07,0xF1,0xF7,0x32,0x96,0x11,
1809 0x04,0x82,0xD4,0x84,0x72,0x80,0x99,0x06,0xCA,0xF0,0xA3,0x68,
1810 0x07,0xCE,0x64,0x50,0xE7,0x74,0x45,0x20,0x80,0x5E,0x4D,0xAD,
1811 0xA5,0xB6,0xED,0xFA,0x80,0x6C,0x3B,0x35,0xC4,0x9A,0x14,0x6B,
1812 0x32,0xBB,0xFD,0x1F,0x17,0x8E,0xB7,0x1F,0xD6,0xFA,0x3F,0x7B,
1813 0xEE,0x16,0xA5,0x62,0x33,0x0D,0xED,0xBC,0x4E,0x58,0xE5,0x47,
1814 0x4D,0xE9,0xAB,0x8E,0x38,0xD3,0x6E,0x90,0x57,0xE3,0x22,0x15,
1815 0x33,0xBD,0xF6,0x43,0x45,0xB5,0x10,0x0A,0xBE,0x2C,0xB4,0x35,
1816 0xB8,0x53,0x8D,0xAD,0xFB,0xA7,0x1F,0x85,0x58,0x41,0x7A,0x79,
1817 0x20,0x68,0xB3,0xE1,0x3D,0x08,0x76,0xBF,0x86,0x0D,0x49,0xE3,
1818 0x82,0x71,0x8C,0xB4,0x8D,0x81,0x84,0xD4,0xE7,0xBE,0x91,0xDC,
1819 0x26,0x39,0x48,0x0F,0x35,0xC4,0xCA,0x65,0xE3,0x40,0x93,0x52,
1820 0x76,0x58,0x7D,0xDD,0x51,0x75,0xDC,0x69,0x61,0xBF,0x47,0x2C,
1821 0x16,0x68,0x2D,0xC9,0x29,0xD3,0xE6,0xC0,0x99,0x48,0xA0,0x9A,
1822 0xC8,0x78,0xC0,0x6D,0x81,0x67,0x12,0x61,0x3F,0x71,0xBA,0x41,
1823 0x1F,0x6C,0x89,0x44,0x03,0xBA,0x3B,0x39,0x60,0xAA,0x28,0x55,
1824 0x59,0xAE,0xB8,0xFA,0xCB,0x6F,0xA5,0x1A,0xF7,0x2B,0xDD,0x52,
1825 0x8A,0x8B,0xE2,0x71,0xA6,0x5E,0x7E,0xD8,0x2E,0x18,0xE0,0x66,
1826 0xDF,0xDD,0x22,0x21,0x99,0x52,0x73,0xA6,0x33,0x20,0x65,0x0E,
1827 0x53,0xE7,0x6B,0x9B,0xC5,0xA3,0x2F,0x97,0x65,0x76,0xD3,0x47,
1828 0x23,0x77,0x12,0xB6,0x11,0x7B,0x24,0xED,0xF1,0xEF,0xC0,0xE2,
1829 0xA3,0x7E,0x67,0x05,0x3E,0x96,0x4D,0x45,0xC2,0x18,0xD1,0x73,
1830 0x9E,0x07,0xF3,0x81,0x6E,0x52,0x63,0xF6,0x20,0x76,0xB9,0x13,
1831 0xD2,0x65,0x30,0x18,0x16,0x09,0x16,0x9E,0x8F,0xF1,0xD2,0x10,
1832 0x5A,0xD3,0xD4,0xAF,0x16,0x61,0xDA,0x55,0x2E,0x18,0x5E,0x14,
1833 0x08,0x54,0x2E,0x2A,0x25,0xA2,0x1A,0x9B,0x8B,0x32,0xA9,0xFD,
1834 0xC2,0x48,0x96,0xE1,0x80,0xCA,0xE9,0x22,0x17,0xBB,0xCE,0x3E,
1835 0x9E,0xED,0xC7,0xF1,0x1F,0xEC,0x17,0x21,0xDC,0x7B,0x82,0x48,
1836 0x8E,0xBB,0x4B,0x9D,0x5B,0x04,0x04,0xDA,0xDB,0x39,0xDF,0x01,
1837 0x40,0xC3,0xAA,0x26,0x23,0x89,0x75,0xC6,0x0B,0xD0,0xA2,0x60,
1838 0x6A,0xF1,0xCC,0x65,0x18,0x98,0x1B,0x52,0xD2,0x74,0x61,0xCC,
1839 0xBD,0x60,0xAE,0xA3,0xA0,0x66,0x6A,0x16,0x34,0x92,0x3F,0x41,
1840 0x40,0x31,0x29,0xC0,0x2C,0x63,0xB2,0x07,0x8D,0xEB,0x94,0xB8,
1841 0xE8,0x47,0x92,0x52,0x93,0x6A,0x1B,0x7E,0x1A,0x61,0xB3,0x1B,
1842 0xF0,0xD6,0x72,0x9B,0xF1,0xB0,0xAF,0xBF,0x3E,0x65,0xEF,0x23,
1843 0x1D,0x6F,0xFF,0x70,0xCD,0x8A,0x4C,0x8A,0xA0,0x72,0x9D,0xBE,
1844 0xD4,0xBB,0x24,0x47,0x4A,0x68,0xB5,0xF5,0xC6,0xD5,0x7A,0xCD,
1845 0xCA,0x06,0x41,0x07,0xAD,0xC2,0x1E,0xE6,0x54,0xA7,0xAD,0x03,
1846 0xD9,0x12,0xC1,0x9C,0x13,0xB1,0xC9,0x0A,0x43,0x8E,0x1E,0x08,
1847 0xCE,0x50,0x82,0x73,0x5F,0xA7,0x55,0x1D,0xD9,0x59,0xAC,0xB5,
1848 0xEA,0x02,0x7F,0x6C,0x5B,0x74,0x96,0x98,0x67,0x24,0xA3,0x0F,
1849 0x15,0xFC,0xA9,0x7D,0x3E,0x67,0xD1,0x70,0xF8,0x97,0xF3,0x67,
1850 0xC5,0x8C,0x88,0x44,0x08,0x02,0xC7,0x2B,
Remi Gacognef46cd6e2014-06-12 14:58:40 +02001851 };
Remi Gacogned3a341a2015-05-29 16:26:17 +02001852 static unsigned char dh4096_g[]={
1853 0x02,
1854 };
Remi Gacognef46cd6e2014-06-12 14:58:40 +02001855
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02001856 BIGNUM *p;
1857 BIGNUM *g;
Remi Gacognef46cd6e2014-06-12 14:58:40 +02001858 DH *dh = DH_new();
1859 if (dh) {
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02001860 p = BN_bin2bn(dh4096_p, sizeof dh4096_p, NULL);
1861 g = BN_bin2bn(dh4096_g, sizeof dh4096_g, NULL);
Remi Gacogned3a341a2015-05-29 16:26:17 +02001862
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02001863 if (!p || !g) {
Remi Gacognef46cd6e2014-06-12 14:58:40 +02001864 DH_free(dh);
1865 dh = NULL;
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02001866 } else {
1867 DH_set0_pqg(dh, p, NULL, g);
Remi Gacognef46cd6e2014-06-12 14:58:40 +02001868 }
1869 }
1870 return dh;
1871}
1872
1873/* Returns Diffie-Hellman parameters matching the private key length
Willy Tarreauef934602016-12-22 23:12:01 +01001874 but not exceeding global_ssl.default_dh_param */
Remi Gacognef46cd6e2014-06-12 14:58:40 +02001875static DH *ssl_get_tmp_dh(SSL *ssl, int export, int keylen)
1876{
1877 DH *dh = NULL;
1878 EVP_PKEY *pkey = SSL_get_privatekey(ssl);
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02001879 int type;
1880
1881 type = pkey ? EVP_PKEY_base_id(pkey) : EVP_PKEY_NONE;
Remi Gacognef46cd6e2014-06-12 14:58:40 +02001882
1883 /* The keylen supplied by OpenSSL can only be 512 or 1024.
1884 See ssl3_send_server_key_exchange() in ssl/s3_srvr.c
1885 */
1886 if (type == EVP_PKEY_RSA || type == EVP_PKEY_DSA) {
1887 keylen = EVP_PKEY_bits(pkey);
1888 }
1889
Willy Tarreauef934602016-12-22 23:12:01 +01001890 if (keylen > global_ssl.default_dh_param) {
1891 keylen = global_ssl.default_dh_param;
Remi Gacognef46cd6e2014-06-12 14:58:40 +02001892 }
1893
Remi Gacogned3a341a2015-05-29 16:26:17 +02001894 if (keylen >= 4096) {
Remi Gacogne8de54152014-07-15 11:36:40 +02001895 dh = local_dh_4096;
Remi Gacognef46cd6e2014-06-12 14:58:40 +02001896 }
1897 else if (keylen >= 2048) {
Remi Gacogne8de54152014-07-15 11:36:40 +02001898 dh = local_dh_2048;
Remi Gacognef46cd6e2014-06-12 14:58:40 +02001899 }
1900 else {
Remi Gacogne8de54152014-07-15 11:36:40 +02001901 dh = local_dh_1024;
Remi Gacognef46cd6e2014-06-12 14:58:40 +02001902 }
1903
1904 return dh;
1905}
1906
Remi Gacogne47783ef2015-05-29 15:53:22 +02001907static DH * ssl_sock_get_dh_from_file(const char *filename)
Emeric Bruna4bcd9a2012-09-20 16:19:02 +02001908{
Emeric Bruna4bcd9a2012-09-20 16:19:02 +02001909 DH *dh = NULL;
Remi Gacogne47783ef2015-05-29 15:53:22 +02001910 BIO *in = BIO_new(BIO_s_file());
Emeric Bruna4bcd9a2012-09-20 16:19:02 +02001911
Emeric Bruna4bcd9a2012-09-20 16:19:02 +02001912 if (in == NULL)
1913 goto end;
1914
Remi Gacogne47783ef2015-05-29 15:53:22 +02001915 if (BIO_read_filename(in, filename) <= 0)
Emeric Bruna4bcd9a2012-09-20 16:19:02 +02001916 goto end;
1917
Remi Gacogne47783ef2015-05-29 15:53:22 +02001918 dh = PEM_read_bio_DHparams(in, NULL, NULL, NULL);
1919
1920end:
1921 if (in)
1922 BIO_free(in);
1923
1924 return dh;
1925}
1926
1927int ssl_sock_load_global_dh_param_from_file(const char *filename)
1928{
1929 global_dh = ssl_sock_get_dh_from_file(filename);
1930
1931 if (global_dh) {
1932 return 0;
1933 }
1934
1935 return -1;
1936}
1937
1938/* Loads Diffie-Hellman parameter from a file. Returns 1 if loaded, else -1
1939 if an error occured, and 0 if parameter not found. */
1940int ssl_sock_load_dh_params(SSL_CTX *ctx, const char *file)
1941{
1942 int ret = -1;
1943 DH *dh = ssl_sock_get_dh_from_file(file);
1944
Remi Gacognef46cd6e2014-06-12 14:58:40 +02001945 if (dh) {
1946 ret = 1;
1947 SSL_CTX_set_tmp_dh(ctx, dh);
Remi Gacogne4f902b82015-05-28 16:23:00 +02001948
1949 if (ssl_dh_ptr_index >= 0) {
1950 /* store a pointer to the DH params to avoid complaining about
1951 ssl-default-dh-param not being set for this SSL_CTX */
1952 SSL_CTX_set_ex_data(ctx, ssl_dh_ptr_index, dh);
1953 }
Remi Gacognef46cd6e2014-06-12 14:58:40 +02001954 }
Remi Gacogne47783ef2015-05-29 15:53:22 +02001955 else if (global_dh) {
1956 SSL_CTX_set_tmp_dh(ctx, global_dh);
1957 ret = 0; /* DH params not found */
1958 }
Remi Gacognef46cd6e2014-06-12 14:58:40 +02001959 else {
Emeric Brun41fdb3c2013-04-26 11:05:44 +02001960 /* Clear openssl global errors stack */
1961 ERR_clear_error();
1962
Willy Tarreauef934602016-12-22 23:12:01 +01001963 if (global_ssl.default_dh_param <= 1024) {
Remi Gacognef46cd6e2014-06-12 14:58:40 +02001964 /* we are limited to DH parameter of 1024 bits anyway */
Remi Gacognec7e12632016-07-02 16:26:10 +02001965 if (local_dh_1024 == NULL)
1966 local_dh_1024 = ssl_get_dh_1024();
1967
Remi Gacogne8de54152014-07-15 11:36:40 +02001968 if (local_dh_1024 == NULL)
Remi Gacognef46cd6e2014-06-12 14:58:40 +02001969 goto end;
Willy Tarreau6e774b42014-04-25 21:35:23 +02001970
Remi Gacogne8de54152014-07-15 11:36:40 +02001971 SSL_CTX_set_tmp_dh(ctx, local_dh_1024);
Remi Gacognef46cd6e2014-06-12 14:58:40 +02001972 }
1973 else {
1974 SSL_CTX_set_tmp_dh_callback(ctx, ssl_get_tmp_dh);
1975 }
Willy Tarreau6e774b42014-04-25 21:35:23 +02001976
Emeric Brun41fdb3c2013-04-26 11:05:44 +02001977 ret = 0; /* DH params not found */
Emeric Bruna4bcd9a2012-09-20 16:19:02 +02001978 }
Emeric Brun644cde02012-12-14 11:21:13 +01001979
Emeric Bruna4bcd9a2012-09-20 16:19:02 +02001980end:
1981 if (dh)
1982 DH_free(dh);
1983
Emeric Bruna4bcd9a2012-09-20 16:19:02 +02001984 return ret;
1985}
1986#endif
1987
Emmanuel Hocdet05942112017-02-20 16:11:50 +01001988static int ssl_sock_add_cert_sni(SSL_CTX *ctx, struct bind_conf *s, struct ssl_bind_conf *conf,
1989 uint8_t key_sig, char *name, int order)
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01001990{
1991 struct sni_ctx *sc;
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +02001992 int wild = 0, neg = 0;
Thierry FOURNIER / OZON.IO07c3d782016-10-06 10:56:48 +02001993 struct ebmb_node *node;
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01001994
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +02001995 if (*name == '!') {
1996 neg = 1;
1997 name++;
1998 }
1999 if (*name == '*') {
2000 wild = 1;
2001 name++;
2002 }
2003 /* !* filter is a nop */
2004 if (neg && wild)
2005 return order;
2006 if (*name) {
2007 int j, len;
2008 len = strlen(name);
Thierry FOURNIER / OZON.IO07c3d782016-10-06 10:56:48 +02002009 for (j = 0; j < len && j < trash.size; j++)
2010 trash.str[j] = tolower(name[j]);
2011 if (j >= trash.size)
2012 return order;
2013 trash.str[j] = 0;
2014
2015 /* Check for duplicates. */
2016 if (wild)
2017 node = ebst_lookup(&s->sni_w_ctx, trash.str);
2018 else
2019 node = ebst_lookup(&s->sni_ctx, trash.str);
2020 for (; node; node = ebmb_next_dup(node)) {
2021 sc = ebmb_entry(node, struct sni_ctx, name);
Emmanuel Hocdet05942112017-02-20 16:11:50 +01002022 if (sc->ctx == ctx && sc->conf == conf &&
2023 sc->key_sig == key_sig && sc->neg == neg)
Thierry FOURNIER / OZON.IO07c3d782016-10-06 10:56:48 +02002024 return order;
2025 }
2026
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01002027 sc = malloc(sizeof(struct sni_ctx) + len + 1);
Thierry FOURNIER / OZON.IO7a3bd3b2016-10-06 10:35:29 +02002028 if (!sc)
2029 return order;
Thierry FOURNIER / OZON.IO07c3d782016-10-06 10:56:48 +02002030 memcpy(sc->name.key, trash.str, len + 1);
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01002031 sc->ctx = ctx;
Emmanuel Hocdet98263292016-12-29 18:26:15 +01002032 sc->conf = conf;
Emmanuel Hocdet05942112017-02-20 16:11:50 +01002033 sc->key_sig = key_sig;
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +02002034 sc->order = order++;
2035 sc->neg = neg;
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01002036 if (wild)
2037 ebst_insert(&s->sni_w_ctx, &sc->name);
2038 else
2039 ebst_insert(&s->sni_ctx, &sc->name);
2040 }
2041 return order;
2042}
2043
yanbzhu488a4d22015-12-01 15:16:07 -05002044
2045/* The following code is used for loading multiple crt files into
2046 * SSL_CTX's based on CN/SAN
2047 */
Luca Pizzamiglio578b1692016-12-12 10:56:56 +01002048#if OPENSSL_VERSION_NUMBER >= 0x1000200fL && !defined(LIBRESSL_VERSION_NUMBER)
yanbzhu488a4d22015-12-01 15:16:07 -05002049/* This is used to preload the certifcate, private key
2050 * and Cert Chain of a file passed in via the crt
2051 * argument
2052 *
2053 * This way, we do not have to read the file multiple times
2054 */
2055struct cert_key_and_chain {
2056 X509 *cert;
2057 EVP_PKEY *key;
2058 unsigned int num_chain_certs;
2059 /* This is an array of X509 pointers */
2060 X509 **chain_certs;
2061};
2062
yanbzhu08ce6ab2015-12-02 13:01:29 -05002063#define SSL_SOCK_POSSIBLE_KT_COMBOS (1<<(SSL_SOCK_NUM_KEYTYPES))
2064
2065struct key_combo_ctx {
2066 SSL_CTX *ctx;
2067 int order;
2068};
2069
2070/* Map used for processing multiple keypairs for a single purpose
2071 *
2072 * This maps CN/SNI name to certificate type
2073 */
2074struct sni_keytype {
2075 int keytypes; /* BITMASK for keytypes */
2076 struct ebmb_node name; /* node holding the servername value */
2077};
2078
2079
yanbzhu488a4d22015-12-01 15:16:07 -05002080/* Frees the contents of a cert_key_and_chain
2081 */
2082static void ssl_sock_free_cert_key_and_chain_contents(struct cert_key_and_chain *ckch)
2083{
2084 int i;
2085
2086 if (!ckch)
2087 return;
2088
2089 /* Free the certificate and set pointer to NULL */
2090 if (ckch->cert)
2091 X509_free(ckch->cert);
2092 ckch->cert = NULL;
2093
2094 /* Free the key and set pointer to NULL */
2095 if (ckch->key)
2096 EVP_PKEY_free(ckch->key);
2097 ckch->key = NULL;
2098
2099 /* Free each certificate in the chain */
2100 for (i = 0; i < ckch->num_chain_certs; i++) {
2101 if (ckch->chain_certs[i])
2102 X509_free(ckch->chain_certs[i]);
2103 }
2104
2105 /* Free the chain obj itself and set to NULL */
2106 if (ckch->num_chain_certs > 0) {
2107 free(ckch->chain_certs);
2108 ckch->num_chain_certs = 0;
2109 ckch->chain_certs = NULL;
2110 }
2111
2112}
2113
2114/* checks if a key and cert exists in the ckch
2115 */
2116static int ssl_sock_is_ckch_valid(struct cert_key_and_chain *ckch)
2117{
2118 return (ckch->cert != NULL && ckch->key != NULL);
2119}
2120
2121
2122/* Loads the contents of a crt file (path) into a cert_key_and_chain
2123 * This allows us to carry the contents of the file without having to
2124 * read the file multiple times.
2125 *
2126 * returns:
2127 * 0 on Success
2128 * 1 on SSL Failure
2129 * 2 on file not found
2130 */
2131static int ssl_sock_load_crt_file_into_ckch(const char *path, struct cert_key_and_chain *ckch, char **err)
2132{
2133
2134 BIO *in;
2135 X509 *ca = NULL;
2136 int ret = 1;
2137
2138 ssl_sock_free_cert_key_and_chain_contents(ckch);
2139
2140 in = BIO_new(BIO_s_file());
2141 if (in == NULL)
2142 goto end;
2143
2144 if (BIO_read_filename(in, path) <= 0)
2145 goto end;
2146
yanbzhu488a4d22015-12-01 15:16:07 -05002147 /* Read Private Key */
2148 ckch->key = PEM_read_bio_PrivateKey(in, NULL, NULL, NULL);
2149 if (ckch->key == NULL) {
2150 memprintf(err, "%sunable to load private key from file '%s'.\n",
2151 err && *err ? *err : "", path);
2152 goto end;
2153 }
2154
Willy Tarreaubb137a82016-04-06 19:02:38 +02002155 /* Seek back to beginning of file */
Thierry FOURNIER / OZON.IOd44ea3f2016-10-14 00:49:21 +02002156 if (BIO_reset(in) == -1) {
2157 memprintf(err, "%san error occurred while reading the file '%s'.\n",
2158 err && *err ? *err : "", path);
2159 goto end;
2160 }
Willy Tarreaubb137a82016-04-06 19:02:38 +02002161
2162 /* Read Certificate */
2163 ckch->cert = PEM_read_bio_X509_AUX(in, NULL, NULL, NULL);
2164 if (ckch->cert == NULL) {
2165 memprintf(err, "%sunable to load certificate from file '%s'.\n",
2166 err && *err ? *err : "", path);
2167 goto end;
2168 }
2169
yanbzhu488a4d22015-12-01 15:16:07 -05002170 /* Read Certificate Chain */
2171 while ((ca = PEM_read_bio_X509(in, NULL, NULL, NULL))) {
2172 /* Grow the chain certs */
2173 ckch->num_chain_certs++;
2174 ckch->chain_certs = realloc(ckch->chain_certs, (ckch->num_chain_certs * sizeof(X509 *)));
2175
2176 /* use - 1 here since we just incremented it above */
2177 ckch->chain_certs[ckch->num_chain_certs - 1] = ca;
2178 }
2179 ret = ERR_get_error();
2180 if (ret && (ERR_GET_LIB(ret) != ERR_LIB_PEM && ERR_GET_REASON(ret) != PEM_R_NO_START_LINE)) {
2181 memprintf(err, "%sunable to load certificate chain from file '%s'.\n",
2182 err && *err ? *err : "", path);
2183 ret = 1;
2184 goto end;
2185 }
2186
2187 ret = 0;
2188
2189end:
2190
2191 ERR_clear_error();
2192 if (in)
2193 BIO_free(in);
2194
2195 /* Something went wrong in one of the reads */
2196 if (ret != 0)
2197 ssl_sock_free_cert_key_and_chain_contents(ckch);
2198
2199 return ret;
2200}
2201
2202/* Loads the info in ckch into ctx
2203 * Currently, this does not process any information about ocsp, dhparams or
2204 * sctl
2205 * Returns
2206 * 0 on success
2207 * 1 on failure
2208 */
2209static int ssl_sock_put_ckch_into_ctx(const char *path, const struct cert_key_and_chain *ckch, SSL_CTX *ctx, char **err)
2210{
2211 int i = 0;
2212
2213 if (SSL_CTX_use_PrivateKey(ctx, ckch->key) <= 0) {
2214 memprintf(err, "%sunable to load SSL private key into SSL Context '%s'.\n",
2215 err && *err ? *err : "", path);
2216 return 1;
2217 }
2218
2219 if (!SSL_CTX_use_certificate(ctx, ckch->cert)) {
2220 memprintf(err, "%sunable to load SSL certificate into SSL Context '%s'.\n",
2221 err && *err ? *err : "", path);
2222 return 1;
2223 }
2224
yanbzhu488a4d22015-12-01 15:16:07 -05002225 /* Load all certs in the ckch into the ctx_chain for the ssl_ctx */
2226 for (i = 0; i < ckch->num_chain_certs; i++) {
2227 if (!SSL_CTX_add1_chain_cert(ctx, ckch->chain_certs[i])) {
yanbzhu08ce6ab2015-12-02 13:01:29 -05002228 memprintf(err, "%sunable to load chain certificate #%d into SSL Context '%s'. Make sure you are linking against Openssl >= 1.0.2.\n",
2229 err && *err ? *err : "", (i+1), path);
yanbzhu488a4d22015-12-01 15:16:07 -05002230 return 1;
2231 }
2232 }
2233
2234 if (SSL_CTX_check_private_key(ctx) <= 0) {
2235 memprintf(err, "%sinconsistencies between private key and certificate loaded from PEM file '%s'.\n",
2236 err && *err ? *err : "", path);
2237 return 1;
2238 }
2239
2240 return 0;
2241}
2242
yanbzhu08ce6ab2015-12-02 13:01:29 -05002243
2244static void ssl_sock_populate_sni_keytypes_hplr(const char *str, struct eb_root *sni_keytypes, int key_index)
2245{
2246 struct sni_keytype *s_kt = NULL;
2247 struct ebmb_node *node;
2248 int i;
2249
2250 for (i = 0; i < trash.size; i++) {
2251 if (!str[i])
2252 break;
2253 trash.str[i] = tolower(str[i]);
2254 }
2255 trash.str[i] = 0;
2256 node = ebst_lookup(sni_keytypes, trash.str);
2257 if (!node) {
2258 /* CN not found in tree */
2259 s_kt = malloc(sizeof(struct sni_keytype) + i + 1);
2260 /* Using memcpy here instead of strncpy.
2261 * strncpy will cause sig_abrt errors under certain versions of gcc with -O2
2262 * See: https://gcc.gnu.org/bugzilla/show_bug.cgi?id=60792
2263 */
2264 memcpy(s_kt->name.key, trash.str, i+1);
2265 s_kt->keytypes = 0;
2266 ebst_insert(sni_keytypes, &s_kt->name);
2267 } else {
2268 /* CN found in tree */
2269 s_kt = container_of(node, struct sni_keytype, name);
2270 }
2271
2272 /* Mark that this CN has the keytype of key_index via keytypes mask */
2273 s_kt->keytypes |= 1<<key_index;
2274
2275}
2276
2277
2278/* Given a path that does not exist, try to check for path.rsa, path.dsa and path.ecdsa files.
2279 * If any are found, group these files into a set of SSL_CTX*
2280 * based on shared and unique CN and SAN entries. Add these SSL_CTX* to the SNI tree.
2281 *
2282 * This will allow the user to explictly group multiple cert/keys for a single purpose
2283 *
2284 * Returns
2285 * 0 on success
2286 * 1 on failure
2287 */
Emmanuel Hocdet98263292016-12-29 18:26:15 +01002288static int ssl_sock_load_multi_cert(const char *path, struct bind_conf *bind_conf, struct ssl_bind_conf *ssl_conf,
2289 char **sni_filter, int fcount, char **err)
yanbzhu08ce6ab2015-12-02 13:01:29 -05002290{
2291 char fp[MAXPATHLEN+1] = {0};
2292 int n = 0;
2293 int i = 0;
2294 struct cert_key_and_chain certs_and_keys[SSL_SOCK_NUM_KEYTYPES] = { {0} };
2295 struct eb_root sni_keytypes_map = { {0} };
2296 struct ebmb_node *node;
2297 struct ebmb_node *next;
2298 /* Array of SSL_CTX pointers corresponding to each possible combo
2299 * of keytypes
2300 */
2301 struct key_combo_ctx key_combos[SSL_SOCK_POSSIBLE_KT_COMBOS] = { {0} };
2302 int rv = 0;
2303 X509_NAME *xname = NULL;
2304 char *str = NULL;
2305#ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME
2306 STACK_OF(GENERAL_NAME) *names = NULL;
2307#endif
2308
2309 /* Load all possible certs and keys */
2310 for (n = 0; n < SSL_SOCK_NUM_KEYTYPES; n++) {
2311 struct stat buf;
2312
2313 snprintf(fp, sizeof(fp), "%s.%s", path, SSL_SOCK_KEYTYPE_NAMES[n]);
2314 if (stat(fp, &buf) == 0) {
2315 if (ssl_sock_load_crt_file_into_ckch(fp, &certs_and_keys[n], err) == 1) {
2316 rv = 1;
2317 goto end;
2318 }
2319 }
2320 }
2321
2322 /* Process each ckch and update keytypes for each CN/SAN
2323 * for example, if CN/SAN www.a.com is associated with
2324 * certs with keytype 0 and 2, then at the end of the loop,
2325 * www.a.com will have:
2326 * keyindex = 0 | 1 | 4 = 5
2327 */
2328 for (n = 0; n < SSL_SOCK_NUM_KEYTYPES; n++) {
2329
2330 if (!ssl_sock_is_ckch_valid(&certs_and_keys[n]))
2331 continue;
2332
Emmanuel Hocdetd294aea2016-05-13 11:14:06 +02002333 if (fcount) {
Willy Tarreau24b892f2016-06-20 23:01:57 +02002334 for (i = 0; i < fcount; i++)
Emmanuel Hocdetd294aea2016-05-13 11:14:06 +02002335 ssl_sock_populate_sni_keytypes_hplr(sni_filter[i], &sni_keytypes_map, n);
2336 } else {
2337 /* A lot of the following code is OpenSSL boilerplate for processing CN's and SAN's,
2338 * so the line that contains logic is marked via comments
2339 */
2340 xname = X509_get_subject_name(certs_and_keys[n].cert);
2341 i = -1;
2342 while ((i = X509_NAME_get_index_by_NID(xname, NID_commonName, i)) != -1) {
2343 X509_NAME_ENTRY *entry = X509_NAME_get_entry(xname, i);
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02002344 ASN1_STRING *value;
2345 value = X509_NAME_ENTRY_get_data(entry);
2346 if (ASN1_STRING_to_UTF8((unsigned char **)&str, value) >= 0) {
Emmanuel Hocdetd294aea2016-05-13 11:14:06 +02002347 /* Important line is here */
2348 ssl_sock_populate_sni_keytypes_hplr(str, &sni_keytypes_map, n);
yanbzhu08ce6ab2015-12-02 13:01:29 -05002349
Emmanuel Hocdetd294aea2016-05-13 11:14:06 +02002350 OPENSSL_free(str);
2351 str = NULL;
2352 }
yanbzhu08ce6ab2015-12-02 13:01:29 -05002353 }
yanbzhu08ce6ab2015-12-02 13:01:29 -05002354
Emmanuel Hocdetd294aea2016-05-13 11:14:06 +02002355 /* Do the above logic for each SAN */
yanbzhu08ce6ab2015-12-02 13:01:29 -05002356#ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME
Emmanuel Hocdetd294aea2016-05-13 11:14:06 +02002357 names = X509_get_ext_d2i(certs_and_keys[n].cert, NID_subject_alt_name, NULL, NULL);
2358 if (names) {
2359 for (i = 0; i < sk_GENERAL_NAME_num(names); i++) {
2360 GENERAL_NAME *name = sk_GENERAL_NAME_value(names, i);
yanbzhu08ce6ab2015-12-02 13:01:29 -05002361
Emmanuel Hocdetd294aea2016-05-13 11:14:06 +02002362 if (name->type == GEN_DNS) {
2363 if (ASN1_STRING_to_UTF8((unsigned char **)&str, name->d.dNSName) >= 0) {
2364 /* Important line is here */
2365 ssl_sock_populate_sni_keytypes_hplr(str, &sni_keytypes_map, n);
yanbzhu08ce6ab2015-12-02 13:01:29 -05002366
Emmanuel Hocdetd294aea2016-05-13 11:14:06 +02002367 OPENSSL_free(str);
2368 str = NULL;
2369 }
yanbzhu08ce6ab2015-12-02 13:01:29 -05002370 }
2371 }
2372 }
2373 }
2374#endif /* SSL_CTRL_SET_TLSEXT_HOSTNAME */
2375 }
2376
2377 /* If no files found, return error */
2378 if (eb_is_empty(&sni_keytypes_map)) {
2379 memprintf(err, "%sunable to load SSL certificate file '%s' file does not exist.\n",
2380 err && *err ? *err : "", path);
2381 rv = 1;
2382 goto end;
2383 }
2384
2385 /* We now have a map of CN/SAN to keytypes that are loaded in
2386 * Iterate through the map to create the SSL_CTX's (if needed)
2387 * and add each CTX to the SNI tree
2388 *
2389 * Some math here:
2390 * There are 2^n - 1 possibile combinations, each unique
2391 * combination is denoted by the key in the map. Each key
2392 * has a value between 1 and 2^n - 1. Conveniently, the array
2393 * of SSL_CTX* is sized 2^n. So, we can simply use the i'th
2394 * entry in the array to correspond to the unique combo (key)
2395 * associated with i. This unique key combo (i) will be associated
2396 * with combos[i-1]
2397 */
2398
2399 node = ebmb_first(&sni_keytypes_map);
2400 while (node) {
2401 SSL_CTX *cur_ctx;
Bertrand Jacquin33423092016-11-13 16:37:13 +00002402 char cur_file[MAXPATHLEN+1];
yanbzhu08ce6ab2015-12-02 13:01:29 -05002403
2404 str = (char *)container_of(node, struct sni_keytype, name)->name.key;
2405 i = container_of(node, struct sni_keytype, name)->keytypes;
2406 cur_ctx = key_combos[i-1].ctx;
2407
2408 if (cur_ctx == NULL) {
2409 /* need to create SSL_CTX */
2410 cur_ctx = SSL_CTX_new(SSLv23_server_method());
2411 if (cur_ctx == NULL) {
2412 memprintf(err, "%sunable to allocate SSL context.\n",
2413 err && *err ? *err : "");
2414 rv = 1;
2415 goto end;
2416 }
2417
yanbzhube2774d2015-12-10 15:07:30 -05002418 /* Load all required certs/keys/chains/OCSPs info into SSL_CTX */
yanbzhu08ce6ab2015-12-02 13:01:29 -05002419 for (n = 0; n < SSL_SOCK_NUM_KEYTYPES; n++) {
2420 if (i & (1<<n)) {
2421 /* Key combo contains ckch[n] */
Bertrand Jacquin33423092016-11-13 16:37:13 +00002422 snprintf(cur_file, MAXPATHLEN+1, "%s.%s", path, SSL_SOCK_KEYTYPE_NAMES[n]);
2423 if (ssl_sock_put_ckch_into_ctx(cur_file, &certs_and_keys[n], cur_ctx, err) != 0) {
yanbzhu08ce6ab2015-12-02 13:01:29 -05002424 SSL_CTX_free(cur_ctx);
2425 rv = 1;
2426 goto end;
2427 }
yanbzhube2774d2015-12-10 15:07:30 -05002428
2429#if (defined SSL_CTRL_SET_TLSEXT_STATUS_REQ_CB && !defined OPENSSL_NO_OCSP)
2430 /* Load OCSP Info into context */
Bertrand Jacquin33423092016-11-13 16:37:13 +00002431 if (ssl_sock_load_ocsp(cur_ctx, cur_file) < 0) {
yanbzhube2774d2015-12-10 15:07:30 -05002432 if (err)
2433 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 +00002434 *err ? *err : "", cur_file);
yanbzhube2774d2015-12-10 15:07:30 -05002435 SSL_CTX_free(cur_ctx);
2436 rv = 1;
2437 goto end;
2438 }
2439#endif
yanbzhu08ce6ab2015-12-02 13:01:29 -05002440 }
2441 }
2442
2443 /* Load DH params into the ctx to support DHE keys */
2444#ifndef OPENSSL_NO_DH
2445 if (ssl_dh_ptr_index >= 0)
2446 SSL_CTX_set_ex_data(cur_ctx, ssl_dh_ptr_index, NULL);
2447
2448 rv = ssl_sock_load_dh_params(cur_ctx, NULL);
2449 if (rv < 0) {
2450 if (err)
2451 memprintf(err, "%sunable to load DH parameters from file '%s'.\n",
2452 *err ? *err : "", path);
2453 rv = 1;
2454 goto end;
2455 }
2456#endif
2457
2458 /* Update key_combos */
2459 key_combos[i-1].ctx = cur_ctx;
2460 }
2461
2462 /* Update SNI Tree */
Emmanuel Hocdet05942112017-02-20 16:11:50 +01002463 key_combos[i-1].order = ssl_sock_add_cert_sni(cur_ctx, bind_conf, ssl_conf,
2464 TLSEXT_signature_anonymous, str, key_combos[i-1].order);
yanbzhu08ce6ab2015-12-02 13:01:29 -05002465 node = ebmb_next(node);
2466 }
2467
2468
2469 /* Mark a default context if none exists, using the ctx that has the most shared keys */
2470 if (!bind_conf->default_ctx) {
2471 for (i = SSL_SOCK_POSSIBLE_KT_COMBOS - 1; i >= 0; i--) {
2472 if (key_combos[i].ctx) {
2473 bind_conf->default_ctx = key_combos[i].ctx;
Emmanuel Hocdet98263292016-12-29 18:26:15 +01002474 bind_conf->default_ssl_conf = ssl_conf;
yanbzhu08ce6ab2015-12-02 13:01:29 -05002475 break;
2476 }
2477 }
2478 }
2479
2480end:
2481
2482 if (names)
2483 sk_GENERAL_NAME_pop_free(names, GENERAL_NAME_free);
2484
2485 for (n = 0; n < SSL_SOCK_NUM_KEYTYPES; n++)
2486 ssl_sock_free_cert_key_and_chain_contents(&certs_and_keys[n]);
2487
2488 node = ebmb_first(&sni_keytypes_map);
2489 while (node) {
2490 next = ebmb_next(node);
2491 ebmb_delete(node);
2492 node = next;
2493 }
2494
2495 return rv;
2496}
2497#else
2498/* This is a dummy, that just logs an error and returns error */
Emmanuel Hocdet98263292016-12-29 18:26:15 +01002499static int ssl_sock_load_multi_cert(const char *path, struct bind_conf *bind_conf, struct ssl_bind_conf *ssl_conf,
2500 char **sni_filter, int fcount, char **err)
yanbzhu08ce6ab2015-12-02 13:01:29 -05002501{
2502 memprintf(err, "%sunable to stat SSL certificate from file '%s' : %s.\n",
2503 err && *err ? *err : "", path, strerror(errno));
2504 return 1;
2505}
2506
yanbzhu488a4d22015-12-01 15:16:07 -05002507#endif /* #if OPENSSL_VERSION_NUMBER >= 0x1000200fL: Support for loading multiple certs into a single SSL_CTX */
2508
Emeric Brunfc0421f2012-09-07 17:30:07 +02002509/* Loads a certificate key and CA chain from a file. Returns 0 on error, -1 if
2510 * an early error happens and the caller must call SSL_CTX_free() by itelf.
2511 */
Emmanuel Hocdet98263292016-12-29 18:26:15 +01002512static int ssl_sock_load_cert_chain_file(SSL_CTX *ctx, const char *file, struct bind_conf *s,
2513 struct ssl_bind_conf *ssl_conf, char **sni_filter, int fcount)
Emeric Brunfc0421f2012-09-07 17:30:07 +02002514{
2515 BIO *in;
2516 X509 *x = NULL, *ca;
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +02002517 int i, err;
Emeric Brunfc0421f2012-09-07 17:30:07 +02002518 int ret = -1;
2519 int order = 0;
2520 X509_NAME *xname;
2521 char *str;
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02002522 pem_password_cb *passwd_cb;
2523 void *passwd_cb_userdata;
Emmanuel Hocdet05942112017-02-20 16:11:50 +01002524 EVP_PKEY *pkey;
2525 uint8_t key_sig = TLSEXT_signature_anonymous;
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02002526
Emeric Brunfc0421f2012-09-07 17:30:07 +02002527#ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME
2528 STACK_OF(GENERAL_NAME) *names;
2529#endif
2530
2531 in = BIO_new(BIO_s_file());
2532 if (in == NULL)
2533 goto end;
2534
2535 if (BIO_read_filename(in, file) <= 0)
2536 goto end;
2537
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02002538
2539 passwd_cb = SSL_CTX_get_default_passwd_cb(ctx);
2540 passwd_cb_userdata = SSL_CTX_get_default_passwd_cb_userdata(ctx);
2541
2542 x = PEM_read_bio_X509_AUX(in, NULL, passwd_cb, passwd_cb_userdata);
Emeric Brunfc0421f2012-09-07 17:30:07 +02002543 if (x == NULL)
2544 goto end;
2545
Emmanuel Hocdet05942112017-02-20 16:11:50 +01002546 pkey = X509_get_pubkey(x);
2547 if (pkey) {
2548 switch(EVP_PKEY_base_id(pkey)) {
2549 case EVP_PKEY_RSA:
2550 key_sig = TLSEXT_signature_rsa;
2551 break;
2552 case EVP_PKEY_EC:
2553 key_sig = TLSEXT_signature_ecdsa;
2554 break;
2555 }
2556 EVP_PKEY_free(pkey);
2557 }
2558
Emeric Brun50bcecc2013-04-22 13:05:23 +02002559 if (fcount) {
2560 while (fcount--)
Emmanuel Hocdet05942112017-02-20 16:11:50 +01002561 order = ssl_sock_add_cert_sni(ctx, s, ssl_conf, key_sig, sni_filter[fcount], order);
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01002562 }
2563 else {
Emeric Brunfc0421f2012-09-07 17:30:07 +02002564#ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01002565 names = X509_get_ext_d2i(x, NID_subject_alt_name, NULL, NULL);
2566 if (names) {
2567 for (i = 0; i < sk_GENERAL_NAME_num(names); i++) {
2568 GENERAL_NAME *name = sk_GENERAL_NAME_value(names, i);
2569 if (name->type == GEN_DNS) {
2570 if (ASN1_STRING_to_UTF8((unsigned char **)&str, name->d.dNSName) >= 0) {
Emmanuel Hocdet05942112017-02-20 16:11:50 +01002571 order = ssl_sock_add_cert_sni(ctx, s, ssl_conf, key_sig, str, order);
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01002572 OPENSSL_free(str);
Emeric Brunfc0421f2012-09-07 17:30:07 +02002573 }
Emeric Brunfc0421f2012-09-07 17:30:07 +02002574 }
2575 }
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01002576 sk_GENERAL_NAME_pop_free(names, GENERAL_NAME_free);
Emeric Brunfc0421f2012-09-07 17:30:07 +02002577 }
Emeric Brunfc0421f2012-09-07 17:30:07 +02002578#endif /* SSL_CTRL_SET_TLSEXT_HOSTNAME */
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01002579 xname = X509_get_subject_name(x);
2580 i = -1;
2581 while ((i = X509_NAME_get_index_by_NID(xname, NID_commonName, i)) != -1) {
2582 X509_NAME_ENTRY *entry = X509_NAME_get_entry(xname, i);
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02002583 ASN1_STRING *value;
2584
2585 value = X509_NAME_ENTRY_get_data(entry);
2586 if (ASN1_STRING_to_UTF8((unsigned char **)&str, value) >= 0) {
Emmanuel Hocdet05942112017-02-20 16:11:50 +01002587 order = ssl_sock_add_cert_sni(ctx, s, ssl_conf, key_sig, str, order);
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01002588 OPENSSL_free(str);
Emeric Brunfc0421f2012-09-07 17:30:07 +02002589 }
Emeric Brunfc0421f2012-09-07 17:30:07 +02002590 }
2591 }
2592
2593 ret = 0; /* the caller must not free the SSL_CTX argument anymore */
2594 if (!SSL_CTX_use_certificate(ctx, x))
2595 goto end;
2596
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02002597#ifdef SSL_CTX_clear_extra_chain_certs
2598 SSL_CTX_clear_extra_chain_certs(ctx);
2599#else
Emeric Brunfc0421f2012-09-07 17:30:07 +02002600 if (ctx->extra_certs != NULL) {
2601 sk_X509_pop_free(ctx->extra_certs, X509_free);
2602 ctx->extra_certs = NULL;
2603 }
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02002604#endif
Emeric Brunfc0421f2012-09-07 17:30:07 +02002605
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02002606 while ((ca = PEM_read_bio_X509(in, NULL, passwd_cb, passwd_cb_userdata))) {
Emeric Brunfc0421f2012-09-07 17:30:07 +02002607 if (!SSL_CTX_add_extra_chain_cert(ctx, ca)) {
2608 X509_free(ca);
2609 goto end;
2610 }
2611 }
2612
2613 err = ERR_get_error();
2614 if (!err || (ERR_GET_LIB(err) == ERR_LIB_PEM && ERR_GET_REASON(err) == PEM_R_NO_START_LINE)) {
2615 /* we successfully reached the last cert in the file */
2616 ret = 1;
2617 }
2618 ERR_clear_error();
2619
2620end:
2621 if (x)
2622 X509_free(x);
2623
2624 if (in)
2625 BIO_free(in);
2626
2627 return ret;
2628}
2629
Emmanuel Hocdet98263292016-12-29 18:26:15 +01002630static int ssl_sock_load_cert_file(const char *path, struct bind_conf *bind_conf, struct ssl_bind_conf *ssl_conf,
2631 char **sni_filter, int fcount, char **err)
Emeric Brunfc0421f2012-09-07 17:30:07 +02002632{
2633 int ret;
2634 SSL_CTX *ctx;
2635
2636 ctx = SSL_CTX_new(SSLv23_server_method());
2637 if (!ctx) {
Willy Tarreaueb6cead2012-09-20 19:43:14 +02002638 memprintf(err, "%sunable to allocate SSL context for cert '%s'.\n",
2639 err && *err ? *err : "", path);
Emeric Brunfc0421f2012-09-07 17:30:07 +02002640 return 1;
2641 }
2642
2643 if (SSL_CTX_use_PrivateKey_file(ctx, path, SSL_FILETYPE_PEM) <= 0) {
Willy Tarreaueb6cead2012-09-20 19:43:14 +02002644 memprintf(err, "%sunable to load SSL private key from PEM file '%s'.\n",
2645 err && *err ? *err : "", path);
Emeric Brunfc0421f2012-09-07 17:30:07 +02002646 SSL_CTX_free(ctx);
2647 return 1;
2648 }
2649
Emmanuel Hocdet98263292016-12-29 18:26:15 +01002650 ret = ssl_sock_load_cert_chain_file(ctx, path, bind_conf, ssl_conf, sni_filter, fcount);
Emeric Brunfc0421f2012-09-07 17:30:07 +02002651 if (ret <= 0) {
Willy Tarreaueb6cead2012-09-20 19:43:14 +02002652 memprintf(err, "%sunable to load SSL certificate from PEM file '%s'.\n",
2653 err && *err ? *err : "", path);
Emeric Brunfc0421f2012-09-07 17:30:07 +02002654 if (ret < 0) /* serious error, must do that ourselves */
2655 SSL_CTX_free(ctx);
2656 return 1;
2657 }
Emeric Brun61694ab2012-10-26 13:35:33 +02002658
2659 if (SSL_CTX_check_private_key(ctx) <= 0) {
2660 memprintf(err, "%sinconsistencies between private key and certificate loaded from PEM file '%s'.\n",
2661 err && *err ? *err : "", path);
2662 return 1;
2663 }
2664
Emeric Brunfc0421f2012-09-07 17:30:07 +02002665 /* we must not free the SSL_CTX anymore below, since it's already in
2666 * the tree, so it will be discovered and cleaned in time.
2667 */
Emeric Bruna4bcd9a2012-09-20 16:19:02 +02002668#ifndef OPENSSL_NO_DH
Remi Gacogne4f902b82015-05-28 16:23:00 +02002669 /* store a NULL pointer to indicate we have not yet loaded
2670 a custom DH param file */
2671 if (ssl_dh_ptr_index >= 0) {
2672 SSL_CTX_set_ex_data(ctx, ssl_dh_ptr_index, NULL);
2673 }
2674
Emeric Bruna4bcd9a2012-09-20 16:19:02 +02002675 ret = ssl_sock_load_dh_params(ctx, path);
2676 if (ret < 0) {
2677 if (err)
2678 memprintf(err, "%sunable to load DH parameters from file '%s'.\n",
2679 *err ? *err : "", path);
2680 return 1;
2681 }
2682#endif
2683
Lukas Tribuse4e30f72014-12-09 16:32:51 +01002684#if (defined SSL_CTRL_SET_TLSEXT_STATUS_REQ_CB && !defined OPENSSL_NO_OCSP)
Emeric Brun4147b2e2014-06-16 18:36:30 +02002685 ret = ssl_sock_load_ocsp(ctx, path);
2686 if (ret < 0) {
2687 if (err)
2688 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",
2689 *err ? *err : "", path);
2690 return 1;
2691 }
2692#endif
2693
Daniel Jakots54ffb912015-11-06 20:02:41 +01002694#if (OPENSSL_VERSION_NUMBER >= 0x1000200fL && !defined OPENSSL_NO_TLSEXT && !defined OPENSSL_IS_BORINGSSL && !defined LIBRESSL_VERSION_NUMBER)
Janusz Dziemidowicz2c701b52015-03-07 23:03:59 +01002695 if (sctl_ex_index >= 0) {
2696 ret = ssl_sock_load_sctl(ctx, path);
2697 if (ret < 0) {
2698 if (err)
2699 memprintf(err, "%s '%s.sctl' is present but cannot be read or parsed'.\n",
2700 *err ? *err : "", path);
2701 return 1;
2702 }
2703 }
2704#endif
2705
Emeric Brunfc0421f2012-09-07 17:30:07 +02002706#ifndef SSL_CTRL_SET_TLSEXT_HOSTNAME
Willy Tarreau2a65ff02012-09-13 17:54:29 +02002707 if (bind_conf->default_ctx) {
Willy Tarreaueb6cead2012-09-20 19:43:14 +02002708 memprintf(err, "%sthis version of openssl cannot load multiple SSL certificates.\n",
2709 err && *err ? *err : "");
Emeric Brunfc0421f2012-09-07 17:30:07 +02002710 return 1;
2711 }
2712#endif
Emmanuel Hocdet98263292016-12-29 18:26:15 +01002713 if (!bind_conf->default_ctx) {
Willy Tarreau2a65ff02012-09-13 17:54:29 +02002714 bind_conf->default_ctx = ctx;
Emmanuel Hocdet98263292016-12-29 18:26:15 +01002715 bind_conf->default_ssl_conf = ssl_conf;
2716 }
Emeric Brunfc0421f2012-09-07 17:30:07 +02002717
2718 return 0;
2719}
2720
Willy Tarreau03209342016-12-22 17:08:28 +01002721int ssl_sock_load_cert(char *path, struct bind_conf *bind_conf, char **err)
Emeric Brunfc0421f2012-09-07 17:30:07 +02002722{
Cyril Bonté3180f7b2015-01-25 00:16:08 +01002723 struct dirent **de_list;
2724 int i, n;
Emeric Brunfc0421f2012-09-07 17:30:07 +02002725 DIR *dir;
2726 struct stat buf;
Willy Tarreauee2663b2012-12-06 11:36:59 +01002727 char *end;
2728 char fp[MAXPATHLEN+1];
Emeric Brunfc0421f2012-09-07 17:30:07 +02002729 int cfgerr = 0;
yanbzhu63ea8462015-12-09 13:35:14 -05002730#if OPENSSL_VERSION_NUMBER >= 0x1000200fL
2731 int is_bundle;
2732 int j;
2733#endif
Emeric Brunfc0421f2012-09-07 17:30:07 +02002734
yanbzhu08ce6ab2015-12-02 13:01:29 -05002735 if (stat(path, &buf) == 0) {
2736 dir = opendir(path);
2737 if (!dir)
Emmanuel Hocdet98263292016-12-29 18:26:15 +01002738 return ssl_sock_load_cert_file(path, bind_conf, NULL, NULL, 0, err);
Emeric Brunfc0421f2012-09-07 17:30:07 +02002739
yanbzhu08ce6ab2015-12-02 13:01:29 -05002740 /* strip trailing slashes, including first one */
2741 for (end = path + strlen(path) - 1; end >= path && *end == '/'; end--)
2742 *end = 0;
Emeric Brunfc0421f2012-09-07 17:30:07 +02002743
yanbzhu08ce6ab2015-12-02 13:01:29 -05002744 n = scandir(path, &de_list, 0, alphasort);
2745 if (n < 0) {
2746 memprintf(err, "%sunable to scan directory '%s' : %s.\n",
2747 err && *err ? *err : "", path, strerror(errno));
2748 cfgerr++;
2749 }
2750 else {
2751 for (i = 0; i < n; i++) {
2752 struct dirent *de = de_list[i];
Emeric Brun2aab7222014-06-18 18:15:09 +02002753
yanbzhu08ce6ab2015-12-02 13:01:29 -05002754 end = strrchr(de->d_name, '.');
2755 if (end && (!strcmp(end, ".issuer") || !strcmp(end, ".ocsp") || !strcmp(end, ".sctl")))
2756 goto ignore_entry;
Cyril Bonté3180f7b2015-01-25 00:16:08 +01002757
yanbzhu08ce6ab2015-12-02 13:01:29 -05002758 snprintf(fp, sizeof(fp), "%s/%s", path, de->d_name);
2759 if (stat(fp, &buf) != 0) {
2760 memprintf(err, "%sunable to stat SSL certificate from file '%s' : %s.\n",
2761 err && *err ? *err : "", fp, strerror(errno));
2762 cfgerr++;
2763 goto ignore_entry;
2764 }
2765 if (!S_ISREG(buf.st_mode))
2766 goto ignore_entry;
yanbzhu63ea8462015-12-09 13:35:14 -05002767
2768#if OPENSSL_VERSION_NUMBER >= 0x1000200fL
2769 is_bundle = 0;
2770 /* Check if current entry in directory is part of a multi-cert bundle */
2771
2772 if (end) {
2773 for (j = 0; j < SSL_SOCK_NUM_KEYTYPES; j++) {
2774 if (!strcmp(end + 1, SSL_SOCK_KEYTYPE_NAMES[j])) {
2775 is_bundle = 1;
2776 break;
2777 }
2778 }
2779
2780 if (is_bundle) {
2781 char dp[MAXPATHLEN+1] = {0}; /* this will be the filename w/o the keytype */
2782 int dp_len;
2783
2784 dp_len = end - de->d_name;
2785 snprintf(dp, dp_len + 1, "%s", de->d_name);
2786
2787 /* increment i and free de until we get to a non-bundle cert
2788 * Note here that we look at de_list[i + 1] before freeing de
2789 * this is important since ignore_entry will free de
2790 */
2791 while (i + 1 < n && !strncmp(de_list[i + 1]->d_name, dp, dp_len)) {
2792 free(de);
2793 i++;
2794 de = de_list[i];
2795 }
2796
2797 snprintf(fp, sizeof(fp), "%s/%s", path, dp);
Emmanuel Hocdet98263292016-12-29 18:26:15 +01002798 ssl_sock_load_multi_cert(fp, bind_conf, NULL, NULL, 0, err);
yanbzhu63ea8462015-12-09 13:35:14 -05002799
2800 /* Successfully processed the bundle */
2801 goto ignore_entry;
2802 }
2803 }
2804
2805#endif
Emmanuel Hocdet98263292016-12-29 18:26:15 +01002806 cfgerr += ssl_sock_load_cert_file(fp, bind_conf, NULL, NULL, 0, err);
yanbzhu08ce6ab2015-12-02 13:01:29 -05002807ignore_entry:
2808 free(de);
Cyril Bonté3180f7b2015-01-25 00:16:08 +01002809 }
yanbzhu08ce6ab2015-12-02 13:01:29 -05002810 free(de_list);
Emeric Brunfc0421f2012-09-07 17:30:07 +02002811 }
yanbzhu08ce6ab2015-12-02 13:01:29 -05002812 closedir(dir);
2813 return cfgerr;
Emeric Brunfc0421f2012-09-07 17:30:07 +02002814 }
yanbzhu08ce6ab2015-12-02 13:01:29 -05002815
Emmanuel Hocdet98263292016-12-29 18:26:15 +01002816 cfgerr = ssl_sock_load_multi_cert(path, bind_conf, NULL, NULL, 0, err);
yanbzhu08ce6ab2015-12-02 13:01:29 -05002817
Emeric Brunfc0421f2012-09-07 17:30:07 +02002818 return cfgerr;
2819}
2820
Thierry Fournier383085f2013-01-24 14:15:43 +01002821/* Make sure openssl opens /dev/urandom before the chroot. The work is only
2822 * done once. Zero is returned if the operation fails. No error is returned
2823 * if the random is said as not implemented, because we expect that openssl
2824 * will use another method once needed.
2825 */
2826static int ssl_initialize_random()
2827{
2828 unsigned char random;
2829 static int random_initialized = 0;
2830
2831 if (!random_initialized && RAND_bytes(&random, 1) != 0)
2832 random_initialized = 1;
2833
2834 return random_initialized;
2835}
2836
Emmanuel Hocdet98263292016-12-29 18:26:15 +01002837/* release ssl bind conf */
2838void ssl_sock_free_ssl_conf(struct ssl_bind_conf *conf)
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01002839{
Emmanuel Hocdet98263292016-12-29 18:26:15 +01002840 if (conf) {
2841#ifdef OPENSSL_NPN_NEGOTIATED
2842 free(conf->npn_str);
2843 conf->npn_str = NULL;
2844#endif
2845#ifdef TLSEXT_TYPE_application_layer_protocol_negotiation
2846 free(conf->alpn_str);
2847 conf->alpn_str = NULL;
2848#endif
2849 free(conf->ca_file);
2850 conf->ca_file = NULL;
2851 free(conf->crl_file);
2852 conf->crl_file = NULL;
2853 free(conf->ciphers);
2854 conf->ciphers = NULL;
Emmanuel Hocdete7f2b732017-01-09 16:15:54 +01002855 free(conf->curves);
2856 conf->curves = NULL;
Emmanuel Hocdet98263292016-12-29 18:26:15 +01002857 free(conf->ecdhe);
2858 conf->ecdhe = NULL;
2859 }
2860}
2861
2862int ssl_sock_load_cert_list_file(char *file, struct bind_conf *bind_conf, struct proxy *curproxy, char **err)
2863{
2864 char thisline[CRT_LINESIZE];
2865 char path[MAXPATHLEN+1];
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01002866 FILE *f;
yanbzhu1b04e5b2015-12-02 13:54:14 -05002867 struct stat buf;
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01002868 int linenum = 0;
2869 int cfgerr = 0;
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01002870
Willy Tarreauad1731d2013-04-02 17:35:58 +02002871 if ((f = fopen(file, "r")) == NULL) {
2872 memprintf(err, "cannot open file '%s' : %s", file, strerror(errno));
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01002873 return 1;
Willy Tarreauad1731d2013-04-02 17:35:58 +02002874 }
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01002875
2876 while (fgets(thisline, sizeof(thisline), f) != NULL) {
Emmanuel Hocdet98263292016-12-29 18:26:15 +01002877 int arg, newarg, cur_arg, i, ssl_b = 0, ssl_e = 0;
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01002878 char *end;
Emmanuel Hocdet98263292016-12-29 18:26:15 +01002879 char *args[MAX_CRT_ARGS + 1];
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01002880 char *line = thisline;
Emmanuel Hocdet98263292016-12-29 18:26:15 +01002881 char *crt_path;
2882 struct ssl_bind_conf *ssl_conf = NULL;
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01002883
2884 linenum++;
2885 end = line + strlen(line);
2886 if (end-line == sizeof(thisline)-1 && *(end-1) != '\n') {
2887 /* Check if we reached the limit and the last char is not \n.
2888 * Watch out for the last line without the terminating '\n'!
2889 */
Willy Tarreauad1731d2013-04-02 17:35:58 +02002890 memprintf(err, "line %d too long in file '%s', limit is %d characters",
2891 linenum, file, (int)sizeof(thisline)-1);
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01002892 cfgerr = 1;
Willy Tarreauad1731d2013-04-02 17:35:58 +02002893 break;
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01002894 }
2895
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01002896 arg = 0;
Emeric Brun50bcecc2013-04-22 13:05:23 +02002897 newarg = 1;
2898 while (*line) {
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01002899 if (*line == '#' || *line == '\n' || *line == '\r') {
2900 /* end of string, end of loop */
2901 *line = 0;
2902 break;
Emmanuel Hocdet98263292016-12-29 18:26:15 +01002903 } else if (isspace(*line)) {
Emeric Brun50bcecc2013-04-22 13:05:23 +02002904 newarg = 1;
2905 *line = 0;
Emmanuel Hocdet98263292016-12-29 18:26:15 +01002906 } else if (*line == '[') {
2907 if (ssl_b) {
2908 memprintf(err, "too many '[' on line %d in file '%s'.", linenum, file);
2909 cfgerr = 1;
2910 break;
2911 }
2912 if (!arg) {
2913 memprintf(err, "file must start with a cert on line %d in file '%s'", linenum, file);
2914 cfgerr = 1;
2915 break;
2916 }
2917 ssl_b = arg;
2918 newarg = 1;
2919 *line = 0;
2920 } else if (*line == ']') {
2921 if (ssl_e) {
2922 memprintf(err, "too many ']' on line %d in file '%s'.", linenum, file);
Emeric Brun50bcecc2013-04-22 13:05:23 +02002923 cfgerr = 1;
2924 break;
2925 }
Emmanuel Hocdet98263292016-12-29 18:26:15 +01002926 if (!ssl_b) {
2927 memprintf(err, "missing '[' in line %d in file '%s'.", linenum, file);
2928 cfgerr = 1;
2929 break;
2930 }
2931 ssl_e = arg;
2932 newarg = 1;
2933 *line = 0;
2934 } else if (newarg) {
2935 if (arg == MAX_CRT_ARGS) {
2936 memprintf(err, "too many args on line %d in file '%s'.", linenum, file);
2937 cfgerr = 1;
2938 break;
2939 }
Emeric Brun50bcecc2013-04-22 13:05:23 +02002940 newarg = 0;
2941 args[arg++] = line;
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01002942 }
Emeric Brun50bcecc2013-04-22 13:05:23 +02002943 line++;
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01002944 }
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +02002945 if (cfgerr)
2946 break;
Emmanuel Hocdet98263292016-12-29 18:26:15 +01002947 args[arg++] = line;
Willy Tarreauad1731d2013-04-02 17:35:58 +02002948
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01002949 /* empty line */
Emmanuel Hocdet98263292016-12-29 18:26:15 +01002950 if (!*args[0])
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01002951 continue;
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01002952
Emmanuel Hocdet98263292016-12-29 18:26:15 +01002953 crt_path = args[0];
2954 if (*crt_path != '/' && global_ssl.crt_base) {
2955 if ((strlen(global_ssl.crt_base) + 1 + strlen(crt_path)) > MAXPATHLEN) {
2956 memprintf(err, "'%s' : path too long on line %d in file '%s'",
2957 crt_path, linenum, file);
2958 cfgerr = 1;
2959 break;
2960 }
2961 snprintf(path, sizeof(path), "%s/%s", global_ssl.crt_base, crt_path);
2962 crt_path = path;
2963 }
2964
2965 ssl_conf = calloc(1, sizeof *ssl_conf);
2966 cur_arg = ssl_b ? ssl_b : 1;
2967 while (cur_arg < ssl_e) {
2968 newarg = 0;
2969 for (i = 0; ssl_bind_kws[i].kw != NULL; i++) {
2970 if (strcmp(ssl_bind_kws[i].kw, args[cur_arg]) == 0) {
2971 newarg = 1;
2972 cfgerr = ssl_bind_kws[i].parse(args, cur_arg, curproxy, ssl_conf, err);
2973 if (cur_arg + 1 + ssl_bind_kws[i].skip > ssl_e) {
2974 memprintf(err, "ssl args out of '[]' for %s on line %d in file '%s'",
2975 args[cur_arg], linenum, file);
2976 cfgerr = 1;
2977 }
2978 cur_arg += 1 + ssl_bind_kws[i].skip;
2979 break;
2980 }
2981 }
2982 if (!cfgerr && !newarg) {
2983 memprintf(err, "unknown ssl keyword %s on line %d in file '%s'.",
2984 args[cur_arg], linenum, file);
2985 cfgerr = 1;
2986 break;
2987 }
2988 }
2989 if (cfgerr) {
2990 ssl_sock_free_ssl_conf(ssl_conf);
2991 free(ssl_conf);
2992 ssl_conf = NULL;
2993 break;
2994 }
2995
2996 if (stat(crt_path, &buf) == 0) {
2997 cfgerr = ssl_sock_load_cert_file(crt_path, bind_conf, ssl_conf,
2998 &args[cur_arg], arg - cur_arg - 1, err);
yanbzhu1b04e5b2015-12-02 13:54:14 -05002999 } else {
Emmanuel Hocdet98263292016-12-29 18:26:15 +01003000 cfgerr = ssl_sock_load_multi_cert(crt_path, bind_conf, ssl_conf,
3001 &args[cur_arg], arg - cur_arg - 1, err);
yanbzhu1b04e5b2015-12-02 13:54:14 -05003002 }
3003
Willy Tarreauad1731d2013-04-02 17:35:58 +02003004 if (cfgerr) {
3005 memprintf(err, "error processing line %d in file '%s' : %s", linenum, file, *err);
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01003006 break;
Willy Tarreauad1731d2013-04-02 17:35:58 +02003007 }
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01003008 }
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01003009 fclose(f);
3010 return cfgerr;
3011}
3012
Emeric Brunfc0421f2012-09-07 17:30:07 +02003013#ifndef SSL_OP_CIPHER_SERVER_PREFERENCE /* needs OpenSSL >= 0.9.7 */
3014#define SSL_OP_CIPHER_SERVER_PREFERENCE 0
3015#endif
3016
3017#ifndef SSL_OP_NO_SESSION_RESUMPTION_ON_RENEGOTIATION /* needs OpenSSL >= 0.9.7 */
3018#define SSL_OP_NO_SESSION_RESUMPTION_ON_RENEGOTIATION 0
Willy Tarreau7d588ee2012-11-26 18:47:31 +01003019#define SSL_renegotiate_pending(arg) 0
Emeric Brunfc0421f2012-09-07 17:30:07 +02003020#endif
Emeric Brun2b58d042012-09-20 17:10:03 +02003021#ifndef SSL_OP_SINGLE_ECDH_USE /* needs OpenSSL >= 0.9.8 */
3022#define SSL_OP_SINGLE_ECDH_USE 0
3023#endif
Emeric Brun2d0c4822012-10-02 13:45:20 +02003024#ifndef SSL_OP_NO_TICKET /* needs OpenSSL >= 0.9.8 */
3025#define SSL_OP_NO_TICKET 0
3026#endif
Emeric Brunfc0421f2012-09-07 17:30:07 +02003027#ifndef SSL_OP_NO_COMPRESSION /* needs OpenSSL >= 0.9.9 */
3028#define SSL_OP_NO_COMPRESSION 0
3029#endif
Emeric Brunc0ff4922012-09-28 19:37:02 +02003030#ifndef SSL_OP_NO_TLSv1_1 /* needs OpenSSL >= 1.0.1 */
3031#define SSL_OP_NO_TLSv1_1 0
3032#endif
3033#ifndef SSL_OP_NO_TLSv1_2 /* needs OpenSSL >= 1.0.1 */
3034#define SSL_OP_NO_TLSv1_2 0
3035#endif
Emeric Bruna4bcd9a2012-09-20 16:19:02 +02003036#ifndef SSL_OP_SINGLE_DH_USE /* needs OpenSSL >= 0.9.6 */
3037#define SSL_OP_SINGLE_DH_USE 0
3038#endif
Emeric Brun2b58d042012-09-20 17:10:03 +02003039#ifndef SSL_OP_SINGLE_ECDH_USE /* needs OpenSSL >= 1.0.0 */
3040#define SSL_OP_SINGLE_ECDH_USE 0
3041#endif
Emeric Brunfc0421f2012-09-07 17:30:07 +02003042#ifndef SSL_MODE_RELEASE_BUFFERS /* needs OpenSSL >= 1.0.0 */
3043#define SSL_MODE_RELEASE_BUFFERS 0
3044#endif
Willy Tarreau396a1862014-11-13 14:06:52 +01003045#ifndef SSL_MODE_SMALL_BUFFERS /* needs small_records.patch */
3046#define SSL_MODE_SMALL_BUFFERS 0
3047#endif
Remi Gacognef46cd6e2014-06-12 14:58:40 +02003048
Emmanuel Hocdet98263292016-12-29 18:26:15 +01003049int ssl_sock_prepare_ctx(struct bind_conf *bind_conf, struct ssl_bind_conf *ssl_conf, SSL_CTX *ctx)
Emeric Brunfc0421f2012-09-07 17:30:07 +02003050{
Willy Tarreau03209342016-12-22 17:08:28 +01003051 struct proxy *curproxy = bind_conf->frontend;
Emeric Brunfc0421f2012-09-07 17:30:07 +02003052 int cfgerr = 0;
Emeric Brun850efd52014-01-29 12:24:34 +01003053 int verify = SSL_VERIFY_NONE;
Remi Gacogneaf5c3da2014-05-19 10:29:58 +02003054 long ssloptions =
Emeric Brunfc0421f2012-09-07 17:30:07 +02003055 SSL_OP_ALL | /* all known workarounds for bugs */
3056 SSL_OP_NO_SSLv2 |
3057 SSL_OP_NO_COMPRESSION |
Emeric Bruna4bcd9a2012-09-20 16:19:02 +02003058 SSL_OP_SINGLE_DH_USE |
Emeric Brun2b58d042012-09-20 17:10:03 +02003059 SSL_OP_SINGLE_ECDH_USE |
Emeric Brun3c4bc6e2012-10-04 18:44:19 +02003060 SSL_OP_NO_SESSION_RESUMPTION_ON_RENEGOTIATION |
3061 SSL_OP_CIPHER_SERVER_PREFERENCE;
Remi Gacogneaf5c3da2014-05-19 10:29:58 +02003062 long sslmode =
Emeric Brunfc0421f2012-09-07 17:30:07 +02003063 SSL_MODE_ENABLE_PARTIAL_WRITE |
3064 SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER |
Willy Tarreau396a1862014-11-13 14:06:52 +01003065 SSL_MODE_RELEASE_BUFFERS |
3066 SSL_MODE_SMALL_BUFFERS;
Remi Gacognef46cd6e2014-06-12 14:58:40 +02003067 STACK_OF(SSL_CIPHER) * ciphers = NULL;
Emmanuel Hocdetfdec7892017-01-13 17:48:18 +01003068 const SSL_CIPHER * cipher = NULL;
Remi Gacognec1eab8c2014-06-12 18:20:11 +02003069 char cipher_description[128];
3070 /* The description of ciphers using an Ephemeral Diffie Hellman key exchange
3071 contains " Kx=DH " or " Kx=DH(". Beware of " Kx=DH/",
3072 which is not ephemeral DH. */
3073 const char dhe_description[] = " Kx=DH ";
3074 const char dhe_export_description[] = " Kx=DH(";
Remi Gacognef46cd6e2014-06-12 14:58:40 +02003075 int idx = 0;
3076 int dhe_found = 0;
Remi Gacogne23d5d372014-10-10 17:04:26 +02003077 SSL *ssl = NULL;
Emmanuel Hocdet98263292016-12-29 18:26:15 +01003078 struct ssl_bind_conf *ssl_conf_cur;
3079 int conf_ssl_options = bind_conf->ssl_conf.ssl_options | (ssl_conf ? ssl_conf->ssl_options : 0);
3080 const char *conf_ciphers;
Emmanuel Hocdete7f2b732017-01-09 16:15:54 +01003081 const char *conf_curves = NULL;
Emeric Brunfc0421f2012-09-07 17:30:07 +02003082
Thierry Fournier383085f2013-01-24 14:15:43 +01003083 /* Make sure openssl opens /dev/urandom before the chroot */
3084 if (!ssl_initialize_random()) {
3085 Alert("OpenSSL random data generator initialization failed.\n");
3086 cfgerr++;
3087 }
3088
Emmanuel Hocdet98263292016-12-29 18:26:15 +01003089 if (conf_ssl_options & BC_SSL_O_NO_SSLV3)
Emeric Brunfc0421f2012-09-07 17:30:07 +02003090 ssloptions |= SSL_OP_NO_SSLv3;
Emmanuel Hocdet98263292016-12-29 18:26:15 +01003091 if (conf_ssl_options & BC_SSL_O_NO_TLSV10)
Emeric Brunfc0421f2012-09-07 17:30:07 +02003092 ssloptions |= SSL_OP_NO_TLSv1;
Emmanuel Hocdet98263292016-12-29 18:26:15 +01003093 if (conf_ssl_options & BC_SSL_O_NO_TLSV11)
Emeric Brunc0ff4922012-09-28 19:37:02 +02003094 ssloptions |= SSL_OP_NO_TLSv1_1;
Emmanuel Hocdet98263292016-12-29 18:26:15 +01003095 if (conf_ssl_options & BC_SSL_O_NO_TLSV12)
Emeric Brunc0ff4922012-09-28 19:37:02 +02003096 ssloptions |= SSL_OP_NO_TLSv1_2;
Emmanuel Hocdet98263292016-12-29 18:26:15 +01003097 if (conf_ssl_options & BC_SSL_O_NO_TLS_TICKETS)
Emeric Brun2d0c4822012-10-02 13:45:20 +02003098 ssloptions |= SSL_OP_NO_TICKET;
Emmanuel Hocdetfdec7892017-01-13 17:48:18 +01003099#ifndef OPENSSL_IS_BORINGSSL
Emmanuel Hocdet98263292016-12-29 18:26:15 +01003100 if (conf_ssl_options & BC_SSL_O_USE_SSLV3) {
Jérémie Courrèges-Anglas17c3f622015-07-25 16:50:52 -06003101#ifndef OPENSSL_NO_SSL3
Emeric Brun2cb7ae52012-10-05 14:14:21 +02003102 SSL_CTX_set_ssl_version(ctx, SSLv3_server_method());
Jérémie Courrèges-Anglas17c3f622015-07-25 16:50:52 -06003103#else
3104 Alert("SSLv3 support requested but unavailable.\n");
3105 cfgerr++;
3106#endif
3107 }
Emmanuel Hocdet98263292016-12-29 18:26:15 +01003108 if (conf_ssl_options & BC_SSL_O_USE_TLSV10)
Emeric Brun2cb7ae52012-10-05 14:14:21 +02003109 SSL_CTX_set_ssl_version(ctx, TLSv1_server_method());
3110#if SSL_OP_NO_TLSv1_1
Emmanuel Hocdet98263292016-12-29 18:26:15 +01003111 if (conf_ssl_options & BC_SSL_O_USE_TLSV11)
Emeric Brun2cb7ae52012-10-05 14:14:21 +02003112 SSL_CTX_set_ssl_version(ctx, TLSv1_1_server_method());
3113#endif
3114#if SSL_OP_NO_TLSv1_2
Emmanuel Hocdet98263292016-12-29 18:26:15 +01003115 if (conf_ssl_options & BC_SSL_O_USE_TLSV12)
Emeric Brun2cb7ae52012-10-05 14:14:21 +02003116 SSL_CTX_set_ssl_version(ctx, TLSv1_2_server_method());
3117#endif
Emmanuel Hocdetfdec7892017-01-13 17:48:18 +01003118#endif
Emeric Brunfc0421f2012-09-07 17:30:07 +02003119 SSL_CTX_set_options(ctx, ssloptions);
3120 SSL_CTX_set_mode(ctx, sslmode);
Emmanuel Hocdet98263292016-12-29 18:26:15 +01003121 switch ((ssl_conf && ssl_conf->verify) ? ssl_conf->verify : bind_conf->ssl_conf.verify) {
Emeric Brun850efd52014-01-29 12:24:34 +01003122 case SSL_SOCK_VERIFY_NONE:
3123 verify = SSL_VERIFY_NONE;
3124 break;
3125 case SSL_SOCK_VERIFY_OPTIONAL:
3126 verify = SSL_VERIFY_PEER;
3127 break;
3128 case SSL_SOCK_VERIFY_REQUIRED:
3129 verify = SSL_VERIFY_PEER|SSL_VERIFY_FAIL_IF_NO_PEER_CERT;
3130 break;
3131 }
3132 SSL_CTX_set_verify(ctx, verify, ssl_sock_bind_verifycbk);
3133 if (verify & SSL_VERIFY_PEER) {
Emmanuel Hocdet98263292016-12-29 18:26:15 +01003134 char *ca_file = (ssl_conf && ssl_conf->ca_file) ? ssl_conf->ca_file : bind_conf->ssl_conf.ca_file;
3135 char *crl_file = (ssl_conf && ssl_conf->crl_file) ? ssl_conf->crl_file : bind_conf->ssl_conf.crl_file;
3136 if (ca_file) {
Emeric Brund94b3fe2012-09-20 18:23:56 +02003137 /* load CAfile to verify */
Emmanuel Hocdet98263292016-12-29 18:26:15 +01003138 if (!SSL_CTX_load_verify_locations(ctx, ca_file, NULL)) {
Emeric Brund94b3fe2012-09-20 18:23:56 +02003139 Alert("Proxy '%s': unable to load CA file '%s' for bind '%s' at [%s:%d].\n",
Emmanuel Hocdet98263292016-12-29 18:26:15 +01003140 curproxy->id, ca_file, bind_conf->arg, bind_conf->file, bind_conf->line);
Emeric Brund94b3fe2012-09-20 18:23:56 +02003141 cfgerr++;
3142 }
3143 /* set CA names fo client cert request, function returns void */
Emmanuel Hocdet98263292016-12-29 18:26:15 +01003144 SSL_CTX_set_client_CA_list(ctx, SSL_load_client_CA_file(ca_file));
Emeric Brund94b3fe2012-09-20 18:23:56 +02003145 }
Emeric Brun850efd52014-01-29 12:24:34 +01003146 else {
3147 Alert("Proxy '%s': verify is enabled but no CA file specified for bind '%s' at [%s:%d].\n",
3148 curproxy->id, bind_conf->arg, bind_conf->file, bind_conf->line);
3149 cfgerr++;
3150 }
Emeric Brun051cdab2012-10-02 19:25:50 +02003151#ifdef X509_V_FLAG_CRL_CHECK
Emmanuel Hocdet98263292016-12-29 18:26:15 +01003152 if (crl_file) {
Emeric Brund94b3fe2012-09-20 18:23:56 +02003153 X509_STORE *store = SSL_CTX_get_cert_store(ctx);
3154
Emmanuel Hocdet98263292016-12-29 18:26:15 +01003155 if (!store || !X509_STORE_load_locations(store, crl_file, NULL)) {
Emeric Brund94b3fe2012-09-20 18:23:56 +02003156 Alert("Proxy '%s': unable to configure CRL file '%s' for bind '%s' at [%s:%d].\n",
Emmanuel Hocdet98263292016-12-29 18:26:15 +01003157 curproxy->id, crl_file, bind_conf->arg, bind_conf->file, bind_conf->line);
Emeric Brund94b3fe2012-09-20 18:23:56 +02003158 cfgerr++;
3159 }
Emeric Brun561e5742012-10-02 15:20:55 +02003160 else {
3161 X509_STORE_set_flags(store, X509_V_FLAG_CRL_CHECK|X509_V_FLAG_CRL_CHECK_ALL);
3162 }
Emeric Brund94b3fe2012-09-20 18:23:56 +02003163 }
Emeric Brun051cdab2012-10-02 19:25:50 +02003164#endif
Emeric Brun644cde02012-12-14 11:21:13 +01003165 ERR_clear_error();
Emeric Brund94b3fe2012-09-20 18:23:56 +02003166 }
Nenad Merdanovic05552d42015-02-27 19:56:49 +01003167#if (defined SSL_CTRL_SET_TLSEXT_TICKET_KEY_CB && TLS_TICKETS_NO > 0)
Nenad Merdanovic146defa2015-05-09 08:46:00 +02003168 if(bind_conf->keys_ref) {
Nenad Merdanovic05552d42015-02-27 19:56:49 +01003169 if (!SSL_CTX_set_tlsext_ticket_key_cb(ctx, ssl_tlsext_ticket_key_cb)) {
3170 Alert("Proxy '%s': unable to set callback for TLS ticket validation for bind '%s' at [%s:%d].\n",
3171 curproxy->id, bind_conf->arg, bind_conf->file, bind_conf->line);
3172 cfgerr++;
3173 }
3174 }
3175#endif
3176
Willy Tarreauef934602016-12-22 23:12:01 +01003177 if (global_ssl.life_time)
3178 SSL_CTX_set_timeout(ctx, global_ssl.life_time);
Emeric Brun4f65bff2012-11-16 15:11:00 +01003179
Emeric Brunfc0421f2012-09-07 17:30:07 +02003180 shared_context_set_cache(ctx);
Emmanuel Hocdet98263292016-12-29 18:26:15 +01003181 conf_ciphers = (ssl_conf && ssl_conf->ciphers) ? ssl_conf->ciphers : bind_conf->ssl_conf.ciphers;
3182 if (conf_ciphers &&
3183 !SSL_CTX_set_cipher_list(ctx, conf_ciphers)) {
Emeric Brunfc0421f2012-09-07 17:30:07 +02003184 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 +01003185 curproxy->id, conf_ciphers, bind_conf->arg, bind_conf->file, bind_conf->line);
Emeric Brunfc0421f2012-09-07 17:30:07 +02003186 cfgerr++;
3187 }
3188
Remi Gacogne47783ef2015-05-29 15:53:22 +02003189 /* If tune.ssl.default-dh-param has not been set,
3190 neither has ssl-default-dh-file and no static DH
3191 params were in the certificate file. */
Willy Tarreauef934602016-12-22 23:12:01 +01003192 if (global_ssl.default_dh_param == 0 &&
Remi Gacogne47783ef2015-05-29 15:53:22 +02003193 global_dh == NULL &&
Remi Gacogne4f902b82015-05-28 16:23:00 +02003194 (ssl_dh_ptr_index == -1 ||
3195 SSL_CTX_get_ex_data(ctx, ssl_dh_ptr_index) == NULL)) {
Lukas Tribus90132722014-08-18 00:56:33 +02003196
Remi Gacogne23d5d372014-10-10 17:04:26 +02003197 ssl = SSL_new(ctx);
Remi Gacognef46cd6e2014-06-12 14:58:40 +02003198
Remi Gacogne23d5d372014-10-10 17:04:26 +02003199 if (ssl) {
3200 ciphers = SSL_get_ciphers(ssl);
3201
3202 if (ciphers) {
3203 for (idx = 0; idx < sk_SSL_CIPHER_num(ciphers); idx++) {
3204 cipher = sk_SSL_CIPHER_value(ciphers, idx);
3205 if (SSL_CIPHER_description(cipher, cipher_description, sizeof (cipher_description)) == cipher_description) {
3206 if (strstr(cipher_description, dhe_description) != NULL ||
3207 strstr(cipher_description, dhe_export_description) != NULL) {
3208 dhe_found = 1;
3209 break;
3210 }
Remi Gacognec1eab8c2014-06-12 18:20:11 +02003211 }
Remi Gacognef46cd6e2014-06-12 14:58:40 +02003212 }
3213 }
Remi Gacogne23d5d372014-10-10 17:04:26 +02003214 SSL_free(ssl);
3215 ssl = NULL;
Lukas Tribus90132722014-08-18 00:56:33 +02003216 }
Remi Gacognef46cd6e2014-06-12 14:58:40 +02003217
Lukas Tribus90132722014-08-18 00:56:33 +02003218 if (dhe_found) {
3219 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 +02003220 }
3221
Willy Tarreauef934602016-12-22 23:12:01 +01003222 global_ssl.default_dh_param = 1024;
Remi Gacognef46cd6e2014-06-12 14:58:40 +02003223 }
Remi Gacogne8de54152014-07-15 11:36:40 +02003224
3225#ifndef OPENSSL_NO_DH
Willy Tarreauef934602016-12-22 23:12:01 +01003226 if (global_ssl.default_dh_param >= 1024) {
Remi Gacogne8de54152014-07-15 11:36:40 +02003227 if (local_dh_1024 == NULL) {
3228 local_dh_1024 = ssl_get_dh_1024();
3229 }
Willy Tarreauef934602016-12-22 23:12:01 +01003230 if (global_ssl.default_dh_param >= 2048) {
Remi Gacogne8de54152014-07-15 11:36:40 +02003231 if (local_dh_2048 == NULL) {
3232 local_dh_2048 = ssl_get_dh_2048();
3233 }
Willy Tarreauef934602016-12-22 23:12:01 +01003234 if (global_ssl.default_dh_param >= 4096) {
Remi Gacogne8de54152014-07-15 11:36:40 +02003235 if (local_dh_4096 == NULL) {
3236 local_dh_4096 = ssl_get_dh_4096();
3237 }
Remi Gacogne8de54152014-07-15 11:36:40 +02003238 }
3239 }
3240 }
3241#endif /* OPENSSL_NO_DH */
Remi Gacognef46cd6e2014-06-12 14:58:40 +02003242
Emeric Brunfc0421f2012-09-07 17:30:07 +02003243 SSL_CTX_set_info_callback(ctx, ssl_sock_infocbk);
Willy Tarreau5cbe4ef2014-05-08 22:45:11 +02003244#if OPENSSL_VERSION_NUMBER >= 0x00907000L
Emeric Brun29f037d2014-04-25 19:05:36 +02003245 SSL_CTX_set_msg_callback(ctx, ssl_sock_msgcbk);
Willy Tarreau5cbe4ef2014-05-08 22:45:11 +02003246#endif
Emeric Brun29f037d2014-04-25 19:05:36 +02003247
Willy Tarreau6c9a3d52012-10-18 18:57:14 +02003248#ifdef OPENSSL_NPN_NEGOTIATED
Emmanuel Hocdet98263292016-12-29 18:26:15 +01003249 ssl_conf_cur = NULL;
3250 if (ssl_conf && ssl_conf->npn_str)
3251 ssl_conf_cur = ssl_conf;
3252 else if (bind_conf->ssl_conf.npn_str)
3253 ssl_conf_cur = &bind_conf->ssl_conf;
3254 if (ssl_conf_cur)
3255 SSL_CTX_set_next_protos_advertised_cb(ctx, ssl_sock_advertise_npn_protos, ssl_conf_cur);
Willy Tarreau6c9a3d52012-10-18 18:57:14 +02003256#endif
Dirkjan Bussink48f1c4e2014-02-13 12:29:42 +01003257#ifdef TLSEXT_TYPE_application_layer_protocol_negotiation
Emmanuel Hocdet98263292016-12-29 18:26:15 +01003258 ssl_conf_cur = NULL;
3259 if (ssl_conf && ssl_conf->alpn_str)
3260 ssl_conf_cur = ssl_conf;
3261 else if (bind_conf->ssl_conf.alpn_str)
3262 ssl_conf_cur = &bind_conf->ssl_conf;
3263 if (ssl_conf_cur)
3264 SSL_CTX_set_alpn_select_cb(ctx, ssl_sock_advertise_alpn_protos, ssl_conf_cur);
Willy Tarreauab861d32013-04-02 02:30:41 +02003265#endif
Willy Tarreau6c9a3d52012-10-18 18:57:14 +02003266
Emeric Brunfc0421f2012-09-07 17:30:07 +02003267#ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME
Emmanuel Hocdet05942112017-02-20 16:11:50 +01003268#ifdef OPENSSL_IS_BORINGSSL
3269 SSL_CTX_set_select_certificate_cb(ctx, ssl_sock_switchctx_cbk);
3270 SSL_CTX_set_tlsext_servername_callback(ctx, ssl_sock_switchctx_err_cbk);
3271#else
Emeric Brunfc0421f2012-09-07 17:30:07 +02003272 SSL_CTX_set_tlsext_servername_callback(ctx, ssl_sock_switchctx_cbk);
Willy Tarreau2a65ff02012-09-13 17:54:29 +02003273 SSL_CTX_set_tlsext_servername_arg(ctx, bind_conf);
Emeric Brunfc0421f2012-09-07 17:30:07 +02003274#endif
Emmanuel Hocdet05942112017-02-20 16:11:50 +01003275#endif
Emmanuel Hocdete7f2b732017-01-09 16:15:54 +01003276#if OPENSSL_VERSION_NUMBER >= 0x1000200fL
3277 conf_curves = (ssl_conf && ssl_conf->curves) ? ssl_conf->curves : bind_conf->ssl_conf.curves;
3278 if (conf_curves) {
3279 if (!SSL_CTX_set1_curves_list(ctx, conf_curves)) {
3280 Alert("Proxy '%s': unable to set SSL curves list to '%s' for bind '%s' at [%s:%d].\n",
3281 curproxy->id, conf_curves, bind_conf->arg, bind_conf->file, bind_conf->line);
3282 cfgerr++;
3283 }
Emmanuel Hocdete7f2b732017-01-09 16:15:54 +01003284 else
3285 SSL_CTX_set_ecdh_auto(ctx, 1);
Emmanuel Hocdete7f2b732017-01-09 16:15:54 +01003286 }
3287#endif
Emeric Brun2b58d042012-09-20 17:10:03 +02003288#if defined(SSL_CTX_set_tmp_ecdh) && !defined(OPENSSL_NO_ECDH)
Emmanuel Hocdete7f2b732017-01-09 16:15:54 +01003289 if (!conf_curves) {
Emeric Brun2b58d042012-09-20 17:10:03 +02003290 int i;
3291 EC_KEY *ecdh;
Emmanuel Hocdet98263292016-12-29 18:26:15 +01003292 const char *ecdhe = (ssl_conf && ssl_conf->ecdhe) ? ssl_conf->ecdhe :
3293 (bind_conf->ssl_conf.ecdhe ? bind_conf->ssl_conf.ecdhe : ECDHE_DEFAULT_CURVE);
Emeric Brun2b58d042012-09-20 17:10:03 +02003294
Emmanuel Hocdet98263292016-12-29 18:26:15 +01003295 i = OBJ_sn2nid(ecdhe);
Emeric Brun2b58d042012-09-20 17:10:03 +02003296 if (!i || ((ecdh = EC_KEY_new_by_curve_name(i)) == NULL)) {
3297 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 +01003298 curproxy->id, ecdhe, bind_conf->arg, bind_conf->file, bind_conf->line);
Emeric Brun2b58d042012-09-20 17:10:03 +02003299 cfgerr++;
3300 }
3301 else {
3302 SSL_CTX_set_tmp_ecdh(ctx, ecdh);
3303 EC_KEY_free(ecdh);
3304 }
3305 }
3306#endif
3307
Emeric Brunfc0421f2012-09-07 17:30:07 +02003308 return cfgerr;
3309}
3310
Evan Broderbe554312013-06-27 00:05:25 -07003311static int ssl_sock_srv_hostcheck(const char *pattern, const char *hostname)
3312{
3313 const char *pattern_wildcard, *pattern_left_label_end, *hostname_left_label_end;
3314 size_t prefixlen, suffixlen;
3315
3316 /* Trivial case */
3317 if (strcmp(pattern, hostname) == 0)
3318 return 1;
3319
Evan Broderbe554312013-06-27 00:05:25 -07003320 /* The rest of this logic is based on RFC 6125, section 6.4.3
3321 * (http://tools.ietf.org/html/rfc6125#section-6.4.3) */
3322
Emeric Bruna848dae2013-10-08 11:27:28 +02003323 pattern_wildcard = NULL;
3324 pattern_left_label_end = pattern;
3325 while (*pattern_left_label_end != '.') {
3326 switch (*pattern_left_label_end) {
3327 case 0:
3328 /* End of label not found */
3329 return 0;
3330 case '*':
3331 /* If there is more than one wildcards */
3332 if (pattern_wildcard)
3333 return 0;
3334 pattern_wildcard = pattern_left_label_end;
3335 break;
3336 }
3337 pattern_left_label_end++;
3338 }
3339
3340 /* If it's not trivial and there is no wildcard, it can't
3341 * match */
3342 if (!pattern_wildcard)
Evan Broderbe554312013-06-27 00:05:25 -07003343 return 0;
3344
3345 /* Make sure all labels match except the leftmost */
3346 hostname_left_label_end = strchr(hostname, '.');
3347 if (!hostname_left_label_end
3348 || strcmp(pattern_left_label_end, hostname_left_label_end) != 0)
3349 return 0;
3350
3351 /* Make sure the leftmost label of the hostname is long enough
3352 * that the wildcard can match */
Emeric Brun369da852013-10-08 11:39:35 +02003353 if (hostname_left_label_end - hostname < (pattern_left_label_end - pattern) - 1)
Evan Broderbe554312013-06-27 00:05:25 -07003354 return 0;
3355
3356 /* Finally compare the string on either side of the
3357 * wildcard */
3358 prefixlen = pattern_wildcard - pattern;
3359 suffixlen = pattern_left_label_end - (pattern_wildcard + 1);
Emeric Bruna848dae2013-10-08 11:27:28 +02003360 if ((prefixlen && (memcmp(pattern, hostname, prefixlen) != 0))
3361 || (suffixlen && (memcmp(pattern_wildcard + 1, hostname_left_label_end - suffixlen, suffixlen) != 0)))
Evan Broderbe554312013-06-27 00:05:25 -07003362 return 0;
3363
3364 return 1;
3365}
3366
3367static int ssl_sock_srv_verifycbk(int ok, X509_STORE_CTX *ctx)
3368{
3369 SSL *ssl;
3370 struct connection *conn;
3371 char *servername;
3372
3373 int depth;
3374 X509 *cert;
3375 STACK_OF(GENERAL_NAME) *alt_names;
3376 int i;
3377 X509_NAME *cert_subject;
3378 char *str;
3379
3380 if (ok == 0)
3381 return ok;
3382
3383 ssl = X509_STORE_CTX_get_ex_data(ctx, SSL_get_ex_data_X509_STORE_CTX_idx());
Vincent Bernat3c2f2f22016-04-03 13:48:42 +02003384 conn = SSL_get_app_data(ssl);
Evan Broderbe554312013-06-27 00:05:25 -07003385
3386 servername = objt_server(conn->target)->ssl_ctx.verify_host;
3387
3388 /* We only need to verify the CN on the actual server cert,
3389 * not the indirect CAs */
3390 depth = X509_STORE_CTX_get_error_depth(ctx);
3391 if (depth != 0)
3392 return ok;
3393
3394 /* At this point, the cert is *not* OK unless we can find a
3395 * hostname match */
3396 ok = 0;
3397
3398 cert = X509_STORE_CTX_get_current_cert(ctx);
3399 /* It seems like this might happen if verify peer isn't set */
3400 if (!cert)
3401 return ok;
3402
3403 alt_names = X509_get_ext_d2i(cert, NID_subject_alt_name, NULL, NULL);
3404 if (alt_names) {
3405 for (i = 0; !ok && i < sk_GENERAL_NAME_num(alt_names); i++) {
3406 GENERAL_NAME *name = sk_GENERAL_NAME_value(alt_names, i);
3407 if (name->type == GEN_DNS) {
Emeric Bruna33410c2013-09-17 15:47:48 +02003408#if OPENSSL_VERSION_NUMBER < 0x00907000L
3409 if (ASN1_STRING_to_UTF8((unsigned char **)&str, name->d.ia5) >= 0) {
3410#else
Evan Broderbe554312013-06-27 00:05:25 -07003411 if (ASN1_STRING_to_UTF8((unsigned char **)&str, name->d.dNSName) >= 0) {
Emeric Bruna33410c2013-09-17 15:47:48 +02003412#endif
Evan Broderbe554312013-06-27 00:05:25 -07003413 ok = ssl_sock_srv_hostcheck(str, servername);
3414 OPENSSL_free(str);
3415 }
3416 }
3417 }
Emeric Brun4ad50a42013-09-17 15:19:54 +02003418 sk_GENERAL_NAME_pop_free(alt_names, GENERAL_NAME_free);
Evan Broderbe554312013-06-27 00:05:25 -07003419 }
3420
3421 cert_subject = X509_get_subject_name(cert);
3422 i = -1;
3423 while (!ok && (i = X509_NAME_get_index_by_NID(cert_subject, NID_commonName, i)) != -1) {
3424 X509_NAME_ENTRY *entry = X509_NAME_get_entry(cert_subject, i);
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02003425 ASN1_STRING *value;
3426 value = X509_NAME_ENTRY_get_data(entry);
3427 if (ASN1_STRING_to_UTF8((unsigned char **)&str, value) >= 0) {
Evan Broderbe554312013-06-27 00:05:25 -07003428 ok = ssl_sock_srv_hostcheck(str, servername);
3429 OPENSSL_free(str);
3430 }
3431 }
3432
3433 return ok;
3434}
3435
Emeric Brun94324a42012-10-11 14:00:19 +02003436/* prepare ssl context from servers options. Returns an error count */
Willy Tarreau03209342016-12-22 17:08:28 +01003437int ssl_sock_prepare_srv_ctx(struct server *srv)
Emeric Brun94324a42012-10-11 14:00:19 +02003438{
Willy Tarreau03209342016-12-22 17:08:28 +01003439 struct proxy *curproxy = srv->proxy;
Emeric Brun94324a42012-10-11 14:00:19 +02003440 int cfgerr = 0;
Remi Gacogneaf5c3da2014-05-19 10:29:58 +02003441 long options =
Emeric Brun94324a42012-10-11 14:00:19 +02003442 SSL_OP_ALL | /* all known workarounds for bugs */
3443 SSL_OP_NO_SSLv2 |
3444 SSL_OP_NO_COMPRESSION;
Remi Gacogneaf5c3da2014-05-19 10:29:58 +02003445 long mode =
Emeric Brun94324a42012-10-11 14:00:19 +02003446 SSL_MODE_ENABLE_PARTIAL_WRITE |
3447 SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER |
Willy Tarreau396a1862014-11-13 14:06:52 +01003448 SSL_MODE_RELEASE_BUFFERS |
3449 SSL_MODE_SMALL_BUFFERS;
Emeric Brun850efd52014-01-29 12:24:34 +01003450 int verify = SSL_VERIFY_NONE;
Emeric Brun94324a42012-10-11 14:00:19 +02003451
Thierry Fournier383085f2013-01-24 14:15:43 +01003452 /* Make sure openssl opens /dev/urandom before the chroot */
3453 if (!ssl_initialize_random()) {
3454 Alert("OpenSSL random data generator initialization failed.\n");
3455 cfgerr++;
3456 }
3457
Willy Tarreaufce03112015-01-15 21:32:40 +01003458 /* Automatic memory computations need to know we use SSL there */
3459 global.ssl_used_backend = 1;
3460
3461 /* Initiate SSL context for current server */
Emeric Brun94324a42012-10-11 14:00:19 +02003462 srv->ssl_ctx.reused_sess = NULL;
3463 if (srv->use_ssl)
3464 srv->xprt = &ssl_sock;
3465 if (srv->check.use_ssl)
Cyril Bonté9ce13112014-11-15 22:41:27 +01003466 srv->check.xprt = &ssl_sock;
Emeric Brun94324a42012-10-11 14:00:19 +02003467
3468 srv->ssl_ctx.ctx = SSL_CTX_new(SSLv23_client_method());
3469 if (!srv->ssl_ctx.ctx) {
3470 Alert("config : %s '%s', server '%s': unable to allocate ssl context.\n",
3471 proxy_type_str(curproxy), curproxy->id,
3472 srv->id);
3473 cfgerr++;
3474 return cfgerr;
3475 }
Emeric Bruna7aa3092012-10-26 12:58:00 +02003476 if (srv->ssl_ctx.client_crt) {
3477 if (SSL_CTX_use_PrivateKey_file(srv->ssl_ctx.ctx, srv->ssl_ctx.client_crt, SSL_FILETYPE_PEM) <= 0) {
3478 Alert("config : %s '%s', server '%s': unable to load SSL private key from PEM file '%s'.\n",
3479 proxy_type_str(curproxy), curproxy->id,
3480 srv->id, srv->ssl_ctx.client_crt);
3481 cfgerr++;
3482 }
3483 else if (SSL_CTX_use_certificate_chain_file(srv->ssl_ctx.ctx, srv->ssl_ctx.client_crt) <= 0) {
3484 Alert("config : %s '%s', server '%s': unable to load ssl certificate from PEM file '%s'.\n",
3485 proxy_type_str(curproxy), curproxy->id,
3486 srv->id, srv->ssl_ctx.client_crt);
3487 cfgerr++;
3488 }
3489 else if (SSL_CTX_check_private_key(srv->ssl_ctx.ctx) <= 0) {
3490 Alert("config : %s '%s', server '%s': inconsistencies between private key and certificate loaded from PEM file '%s'.\n",
3491 proxy_type_str(curproxy), curproxy->id,
3492 srv->id, srv->ssl_ctx.client_crt);
3493 cfgerr++;
3494 }
3495 }
Emeric Brun94324a42012-10-11 14:00:19 +02003496
3497 if (srv->ssl_ctx.options & SRV_SSL_O_NO_SSLV3)
3498 options |= SSL_OP_NO_SSLv3;
3499 if (srv->ssl_ctx.options & SRV_SSL_O_NO_TLSV10)
3500 options |= SSL_OP_NO_TLSv1;
3501 if (srv->ssl_ctx.options & SRV_SSL_O_NO_TLSV11)
3502 options |= SSL_OP_NO_TLSv1_1;
3503 if (srv->ssl_ctx.options & SRV_SSL_O_NO_TLSV12)
3504 options |= SSL_OP_NO_TLSv1_2;
Emeric Brunf9c5c472012-10-11 15:28:34 +02003505 if (srv->ssl_ctx.options & SRV_SSL_O_NO_TLS_TICKETS)
3506 options |= SSL_OP_NO_TICKET;
Emmanuel Hocdetfdec7892017-01-13 17:48:18 +01003507#ifndef OPENSSL_IS_BORINGSSL
Jérémie Courrèges-Anglas17c3f622015-07-25 16:50:52 -06003508 if (srv->ssl_ctx.options & SRV_SSL_O_USE_SSLV3) {
3509#ifndef OPENSSL_NO_SSL3
Emeric Brun94324a42012-10-11 14:00:19 +02003510 SSL_CTX_set_ssl_version(srv->ssl_ctx.ctx, SSLv3_client_method());
Jérémie Courrèges-Anglas17c3f622015-07-25 16:50:52 -06003511#else
Thierry FOURNIERbc965342015-08-26 08:21:26 +02003512 Alert("SSLv3 support requested but unavailable.\n");
Jérémie Courrèges-Anglas17c3f622015-07-25 16:50:52 -06003513 cfgerr++;
3514#endif
3515 }
Emeric Brun94324a42012-10-11 14:00:19 +02003516 if (srv->ssl_ctx.options & SRV_SSL_O_USE_TLSV10)
3517 SSL_CTX_set_ssl_version(srv->ssl_ctx.ctx, TLSv1_client_method());
3518#if SSL_OP_NO_TLSv1_1
3519 if (srv->ssl_ctx.options & SRV_SSL_O_USE_TLSV11)
3520 SSL_CTX_set_ssl_version(srv->ssl_ctx.ctx, TLSv1_1_client_method());
3521#endif
3522#if SSL_OP_NO_TLSv1_2
3523 if (srv->ssl_ctx.options & SRV_SSL_O_USE_TLSV12)
3524 SSL_CTX_set_ssl_version(srv->ssl_ctx.ctx, TLSv1_2_client_method());
3525#endif
Emmanuel Hocdetfdec7892017-01-13 17:48:18 +01003526#endif
Emeric Brun94324a42012-10-11 14:00:19 +02003527 SSL_CTX_set_options(srv->ssl_ctx.ctx, options);
3528 SSL_CTX_set_mode(srv->ssl_ctx.ctx, mode);
Emeric Brun850efd52014-01-29 12:24:34 +01003529
3530 if (global.ssl_server_verify == SSL_SERVER_VERIFY_REQUIRED)
3531 verify = SSL_VERIFY_PEER;
3532
3533 switch (srv->ssl_ctx.verify) {
3534 case SSL_SOCK_VERIFY_NONE:
3535 verify = SSL_VERIFY_NONE;
3536 break;
3537 case SSL_SOCK_VERIFY_REQUIRED:
3538 verify = SSL_VERIFY_PEER;
3539 break;
3540 }
Evan Broderbe554312013-06-27 00:05:25 -07003541 SSL_CTX_set_verify(srv->ssl_ctx.ctx,
Emeric Brun850efd52014-01-29 12:24:34 +01003542 verify,
Evan Broderbe554312013-06-27 00:05:25 -07003543 srv->ssl_ctx.verify_host ? ssl_sock_srv_verifycbk : NULL);
Emeric Brun850efd52014-01-29 12:24:34 +01003544 if (verify & SSL_VERIFY_PEER) {
Emeric Brunef42d922012-10-11 16:11:36 +02003545 if (srv->ssl_ctx.ca_file) {
3546 /* load CAfile to verify */
3547 if (!SSL_CTX_load_verify_locations(srv->ssl_ctx.ctx, srv->ssl_ctx.ca_file, NULL)) {
Willy Tarreau07ba08b2014-02-16 19:22:08 +01003548 Alert("Proxy '%s', server '%s' [%s:%d] unable to load CA file '%s'.\n",
Emeric Brunef42d922012-10-11 16:11:36 +02003549 curproxy->id, srv->id,
3550 srv->conf.file, srv->conf.line, srv->ssl_ctx.ca_file);
3551 cfgerr++;
3552 }
3553 }
Emeric Brun850efd52014-01-29 12:24:34 +01003554 else {
3555 if (global.ssl_server_verify == SSL_SERVER_VERIFY_REQUIRED)
Willy Tarreau07ba08b2014-02-16 19:22:08 +01003556 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 +01003557 curproxy->id, srv->id,
3558 srv->conf.file, srv->conf.line);
3559 else
Willy Tarreau07ba08b2014-02-16 19:22:08 +01003560 Alert("Proxy '%s', server '%s' [%s:%d] verify is enabled but no CA file specified.\n",
Emeric Brun850efd52014-01-29 12:24:34 +01003561 curproxy->id, srv->id,
3562 srv->conf.file, srv->conf.line);
3563 cfgerr++;
3564 }
Emeric Brunef42d922012-10-11 16:11:36 +02003565#ifdef X509_V_FLAG_CRL_CHECK
3566 if (srv->ssl_ctx.crl_file) {
3567 X509_STORE *store = SSL_CTX_get_cert_store(srv->ssl_ctx.ctx);
3568
3569 if (!store || !X509_STORE_load_locations(store, srv->ssl_ctx.crl_file, NULL)) {
Willy Tarreau07ba08b2014-02-16 19:22:08 +01003570 Alert("Proxy '%s', server '%s' [%s:%d] unable to configure CRL file '%s'.\n",
Emeric Brunef42d922012-10-11 16:11:36 +02003571 curproxy->id, srv->id,
3572 srv->conf.file, srv->conf.line, srv->ssl_ctx.crl_file);
3573 cfgerr++;
3574 }
3575 else {
3576 X509_STORE_set_flags(store, X509_V_FLAG_CRL_CHECK|X509_V_FLAG_CRL_CHECK_ALL);
3577 }
3578 }
3579#endif
3580 }
3581
Willy Tarreauef934602016-12-22 23:12:01 +01003582 if (global_ssl.life_time)
3583 SSL_CTX_set_timeout(srv->ssl_ctx.ctx, global_ssl.life_time);
Emeric Brun4f65bff2012-11-16 15:11:00 +01003584
Emeric Brun94324a42012-10-11 14:00:19 +02003585 SSL_CTX_set_session_cache_mode(srv->ssl_ctx.ctx, SSL_SESS_CACHE_OFF);
3586 if (srv->ssl_ctx.ciphers &&
3587 !SSL_CTX_set_cipher_list(srv->ssl_ctx.ctx, srv->ssl_ctx.ciphers)) {
3588 Alert("Proxy '%s', server '%s' [%s:%d] : unable to set SSL cipher list to '%s'.\n",
3589 curproxy->id, srv->id,
3590 srv->conf.file, srv->conf.line, srv->ssl_ctx.ciphers);
3591 cfgerr++;
3592 }
3593
3594 return cfgerr;
3595}
3596
Willy Tarreau2a65ff02012-09-13 17:54:29 +02003597/* Walks down the two trees in bind_conf and prepares all certs. The pointer may
Emeric Brunfc0421f2012-09-07 17:30:07 +02003598 * be NULL, in which case nothing is done. Returns the number of errors
3599 * encountered.
3600 */
Willy Tarreau03209342016-12-22 17:08:28 +01003601int ssl_sock_prepare_all_ctx(struct bind_conf *bind_conf)
Emeric Brunfc0421f2012-09-07 17:30:07 +02003602{
3603 struct ebmb_node *node;
3604 struct sni_ctx *sni;
3605 int err = 0;
3606
Willy Tarreau2a65ff02012-09-13 17:54:29 +02003607 if (!bind_conf || !bind_conf->is_ssl)
Emeric Brunfc0421f2012-09-07 17:30:07 +02003608 return 0;
3609
Willy Tarreaufce03112015-01-15 21:32:40 +01003610 /* Automatic memory computations need to know we use SSL there */
3611 global.ssl_used_frontend = 1;
3612
Emeric Brun0bed9942014-10-30 19:25:24 +01003613 if (bind_conf->default_ctx)
Emmanuel Hocdet98263292016-12-29 18:26:15 +01003614 err += ssl_sock_prepare_ctx(bind_conf, bind_conf->default_ssl_conf, bind_conf->default_ctx);
Emeric Brun0bed9942014-10-30 19:25:24 +01003615
Willy Tarreau2a65ff02012-09-13 17:54:29 +02003616 node = ebmb_first(&bind_conf->sni_ctx);
Emeric Brunfc0421f2012-09-07 17:30:07 +02003617 while (node) {
3618 sni = ebmb_entry(node, struct sni_ctx, name);
Emeric Brun0bed9942014-10-30 19:25:24 +01003619 if (!sni->order && sni->ctx != bind_conf->default_ctx)
3620 /* only initialize the CTX on its first occurrence and
3621 if it is not the default_ctx */
Emmanuel Hocdet98263292016-12-29 18:26:15 +01003622 err += ssl_sock_prepare_ctx(bind_conf, sni->conf, sni->ctx);
Emeric Brunfc0421f2012-09-07 17:30:07 +02003623 node = ebmb_next(node);
3624 }
3625
Willy Tarreau2a65ff02012-09-13 17:54:29 +02003626 node = ebmb_first(&bind_conf->sni_w_ctx);
Emeric Brunfc0421f2012-09-07 17:30:07 +02003627 while (node) {
3628 sni = ebmb_entry(node, struct sni_ctx, name);
Emeric Brun0bed9942014-10-30 19:25:24 +01003629 if (!sni->order && sni->ctx != bind_conf->default_ctx)
3630 /* only initialize the CTX on its first occurrence and
3631 if it is not the default_ctx */
Emmanuel Hocdet98263292016-12-29 18:26:15 +01003632 err += ssl_sock_prepare_ctx(bind_conf, sni->conf, sni->ctx);
Emeric Brunfc0421f2012-09-07 17:30:07 +02003633 node = ebmb_next(node);
3634 }
3635 return err;
3636}
3637
Willy Tarreau55d37912016-12-21 23:38:39 +01003638/* Prepares all the contexts for a bind_conf and allocates the shared SSL
3639 * context if needed. Returns < 0 on error, 0 on success. The warnings and
3640 * alerts are directly emitted since the rest of the stack does it below.
3641 */
3642int ssl_sock_prepare_bind_conf(struct bind_conf *bind_conf)
3643{
3644 struct proxy *px = bind_conf->frontend;
3645 int alloc_ctx;
3646 int err;
3647
3648 if (!bind_conf->is_ssl) {
3649 if (bind_conf->default_ctx) {
3650 Warning("Proxy '%s': A certificate was specified but SSL was not enabled on bind '%s' at [%s:%d] (use 'ssl').\n",
3651 px->id, bind_conf->arg, bind_conf->file, bind_conf->line);
3652 }
3653 return 0;
3654 }
3655 if (!bind_conf->default_ctx) {
3656 Alert("Proxy '%s': no SSL certificate specified for bind '%s' at [%s:%d] (use 'crt').\n",
3657 px->id, bind_conf->arg, bind_conf->file, bind_conf->line);
3658 return -1;
3659 }
3660
Willy Tarreauef934602016-12-22 23:12:01 +01003661 alloc_ctx = shared_context_init(global.tune.sslcachesize, (!global_ssl.private_cache && (global.nbproc > 1)) ? 1 : 0);
Willy Tarreau55d37912016-12-21 23:38:39 +01003662 if (alloc_ctx < 0) {
3663 if (alloc_ctx == SHCTX_E_INIT_LOCK)
3664 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");
3665 else
3666 Alert("Unable to allocate SSL session cache.\n");
3667 return -1;
3668 }
3669
3670 err = 0;
3671 /* initialize all certificate contexts */
3672 err += ssl_sock_prepare_all_ctx(bind_conf);
3673
3674 /* initialize CA variables if the certificates generation is enabled */
3675 err += ssl_sock_load_ca(bind_conf);
3676
3677 return -err;
3678}
Christopher Faulet77fe80c2015-07-29 13:02:40 +02003679
3680/* release ssl context allocated for servers. */
3681void ssl_sock_free_srv_ctx(struct server *srv)
3682{
3683 if (srv->ssl_ctx.ctx)
3684 SSL_CTX_free(srv->ssl_ctx.ctx);
3685}
3686
Willy Tarreau2a65ff02012-09-13 17:54:29 +02003687/* Walks down the two trees in bind_conf and frees all the certs. The pointer may
Emeric Brunfc0421f2012-09-07 17:30:07 +02003688 * be NULL, in which case nothing is done. The default_ctx is nullified too.
3689 */
Willy Tarreau2a65ff02012-09-13 17:54:29 +02003690void ssl_sock_free_all_ctx(struct bind_conf *bind_conf)
Emeric Brunfc0421f2012-09-07 17:30:07 +02003691{
3692 struct ebmb_node *node, *back;
3693 struct sni_ctx *sni;
3694
Willy Tarreau2a65ff02012-09-13 17:54:29 +02003695 if (!bind_conf || !bind_conf->is_ssl)
Emeric Brunfc0421f2012-09-07 17:30:07 +02003696 return;
3697
Willy Tarreau2a65ff02012-09-13 17:54:29 +02003698 node = ebmb_first(&bind_conf->sni_ctx);
Emeric Brunfc0421f2012-09-07 17:30:07 +02003699 while (node) {
3700 sni = ebmb_entry(node, struct sni_ctx, name);
3701 back = ebmb_next(node);
3702 ebmb_delete(node);
Emmanuel Hocdet98263292016-12-29 18:26:15 +01003703 if (!sni->order) { /* only free the CTX on its first occurrence */
Emeric Brunfc0421f2012-09-07 17:30:07 +02003704 SSL_CTX_free(sni->ctx);
Emmanuel Hocdet98263292016-12-29 18:26:15 +01003705 ssl_sock_free_ssl_conf(sni->conf);
3706 free(sni->conf);
3707 sni->conf = NULL;
3708 }
Emeric Brunfc0421f2012-09-07 17:30:07 +02003709 free(sni);
3710 node = back;
3711 }
3712
Willy Tarreau2a65ff02012-09-13 17:54:29 +02003713 node = ebmb_first(&bind_conf->sni_w_ctx);
Emeric Brunfc0421f2012-09-07 17:30:07 +02003714 while (node) {
3715 sni = ebmb_entry(node, struct sni_ctx, name);
3716 back = ebmb_next(node);
3717 ebmb_delete(node);
Emmanuel Hocdet98263292016-12-29 18:26:15 +01003718 if (!sni->order) { /* only free the CTX on its first occurrence */
Emeric Brunfc0421f2012-09-07 17:30:07 +02003719 SSL_CTX_free(sni->ctx);
Emmanuel Hocdet98263292016-12-29 18:26:15 +01003720 ssl_sock_free_ssl_conf(sni->conf);
3721 free(sni->conf);
3722 sni->conf = NULL;
3723 }
Emeric Brunfc0421f2012-09-07 17:30:07 +02003724 free(sni);
3725 node = back;
3726 }
3727
Willy Tarreau2a65ff02012-09-13 17:54:29 +02003728 bind_conf->default_ctx = NULL;
Emmanuel Hocdet98263292016-12-29 18:26:15 +01003729 bind_conf->default_ssl_conf = NULL;
Emeric Brune1f38db2012-09-03 20:36:47 +02003730}
3731
Willy Tarreau795cdab2016-12-22 17:30:54 +01003732/* Destroys all the contexts for a bind_conf. This is used during deinit(). */
3733void ssl_sock_destroy_bind_conf(struct bind_conf *bind_conf)
3734{
3735 ssl_sock_free_ca(bind_conf);
3736 ssl_sock_free_all_ctx(bind_conf);
Emmanuel Hocdet98263292016-12-29 18:26:15 +01003737 ssl_sock_free_ssl_conf(&bind_conf->ssl_conf);
Willy Tarreau795cdab2016-12-22 17:30:54 +01003738 free(bind_conf->ca_sign_file);
3739 free(bind_conf->ca_sign_pass);
Willy Tarreau795cdab2016-12-22 17:30:54 +01003740 if (bind_conf->keys_ref) {
3741 free(bind_conf->keys_ref->filename);
3742 free(bind_conf->keys_ref->tlskeys);
3743 LIST_DEL(&bind_conf->keys_ref->list);
3744 free(bind_conf->keys_ref);
3745 }
3746 bind_conf->keys_ref = NULL;
Willy Tarreau795cdab2016-12-22 17:30:54 +01003747 bind_conf->ca_sign_pass = NULL;
3748 bind_conf->ca_sign_file = NULL;
Willy Tarreau795cdab2016-12-22 17:30:54 +01003749}
3750
Christopher Faulet31af49d2015-06-09 17:29:50 +02003751/* Load CA cert file and private key used to generate certificates */
3752int
Willy Tarreau03209342016-12-22 17:08:28 +01003753ssl_sock_load_ca(struct bind_conf *bind_conf)
Christopher Faulet31af49d2015-06-09 17:29:50 +02003754{
Willy Tarreau03209342016-12-22 17:08:28 +01003755 struct proxy *px = bind_conf->frontend;
Christopher Faulet31af49d2015-06-09 17:29:50 +02003756 FILE *fp;
3757 X509 *cacert = NULL;
3758 EVP_PKEY *capkey = NULL;
3759 int err = 0;
3760
3761 if (!bind_conf || !bind_conf->generate_certs)
3762 return err;
3763
Emmanuel Hocdetfdec7892017-01-13 17:48:18 +01003764#if (defined SSL_CTRL_SET_TLSEXT_HOSTNAME && !defined SSL_NO_GENERATE_CERTIFICATES)
Willy Tarreauef934602016-12-22 23:12:01 +01003765 if (global_ssl.ctx_cache)
3766 ssl_ctx_lru_tree = lru64_new(global_ssl.ctx_cache);
Christopher Fauletd2cab922015-07-28 16:03:47 +02003767 ssl_ctx_lru_seed = (unsigned int)time(NULL);
Willy Tarreaua84c2672015-10-09 12:10:13 +02003768#endif
Christopher Fauletd2cab922015-07-28 16:03:47 +02003769
Christopher Faulet31af49d2015-06-09 17:29:50 +02003770 if (!bind_conf->ca_sign_file) {
3771 Alert("Proxy '%s': cannot enable certificate generation, "
3772 "no CA certificate File configured at [%s:%d].\n",
3773 px->id, bind_conf->file, bind_conf->line);
Christopher Faulet31af49d2015-06-09 17:29:50 +02003774 goto load_error;
Christopher Fauletc6f02fb2015-10-09 10:53:31 +02003775 }
Christopher Faulet31af49d2015-06-09 17:29:50 +02003776
3777 /* read in the CA certificate */
3778 if (!(fp = fopen(bind_conf->ca_sign_file, "r"))) {
3779 Alert("Proxy '%s': Failed to read CA certificate file '%s' at [%s:%d].\n",
3780 px->id, bind_conf->ca_sign_file, bind_conf->file, bind_conf->line);
Christopher Faulet31af49d2015-06-09 17:29:50 +02003781 goto load_error;
3782 }
3783 if (!(cacert = PEM_read_X509(fp, NULL, NULL, NULL))) {
3784 Alert("Proxy '%s': Failed to read CA certificate file '%s' at [%s:%d].\n",
3785 px->id, bind_conf->ca_sign_file, bind_conf->file, bind_conf->line);
Christopher Fauletc6f02fb2015-10-09 10:53:31 +02003786 goto read_error;
Christopher Faulet31af49d2015-06-09 17:29:50 +02003787 }
Christopher Fauletc6f02fb2015-10-09 10:53:31 +02003788 rewind(fp);
Christopher Faulet31af49d2015-06-09 17:29:50 +02003789 if (!(capkey = PEM_read_PrivateKey(fp, NULL, NULL, bind_conf->ca_sign_pass))) {
3790 Alert("Proxy '%s': Failed to read CA private key file '%s' at [%s:%d].\n",
3791 px->id, bind_conf->ca_sign_file, bind_conf->file, bind_conf->line);
Christopher Fauletc6f02fb2015-10-09 10:53:31 +02003792 goto read_error;
Christopher Faulet31af49d2015-06-09 17:29:50 +02003793 }
Christopher Faulet31af49d2015-06-09 17:29:50 +02003794
Christopher Fauletc6f02fb2015-10-09 10:53:31 +02003795 fclose (fp);
Christopher Faulet31af49d2015-06-09 17:29:50 +02003796 bind_conf->ca_sign_cert = cacert;
3797 bind_conf->ca_sign_pkey = capkey;
3798 return err;
3799
Christopher Fauletc6f02fb2015-10-09 10:53:31 +02003800 read_error:
3801 fclose (fp);
Christopher Faulet31af49d2015-06-09 17:29:50 +02003802 if (capkey) EVP_PKEY_free(capkey);
3803 if (cacert) X509_free(cacert);
Christopher Fauletc6f02fb2015-10-09 10:53:31 +02003804 load_error:
3805 bind_conf->generate_certs = 0;
3806 err++;
Christopher Faulet31af49d2015-06-09 17:29:50 +02003807 return err;
3808}
3809
3810/* Release CA cert and private key used to generate certificated */
3811void
3812ssl_sock_free_ca(struct bind_conf *bind_conf)
3813{
3814 if (!bind_conf)
3815 return;
3816
3817 if (bind_conf->ca_sign_pkey)
3818 EVP_PKEY_free(bind_conf->ca_sign_pkey);
3819 if (bind_conf->ca_sign_cert)
3820 X509_free(bind_conf->ca_sign_cert);
Willy Tarreau94ff03a2016-12-22 17:57:46 +01003821 bind_conf->ca_sign_pkey = NULL;
3822 bind_conf->ca_sign_cert = NULL;
Christopher Faulet31af49d2015-06-09 17:29:50 +02003823}
3824
Emeric Brun46591952012-05-18 15:47:34 +02003825/*
3826 * This function is called if SSL * context is not yet allocated. The function
3827 * is designed to be called before any other data-layer operation and sets the
3828 * handshake flag on the connection. It is safe to call it multiple times.
3829 * It returns 0 on success and -1 in error case.
3830 */
3831static int ssl_sock_init(struct connection *conn)
3832{
3833 /* already initialized */
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02003834 if (conn->xprt_ctx)
Emeric Brun46591952012-05-18 15:47:34 +02003835 return 0;
3836
Willy Tarreau3c728722014-01-23 13:50:42 +01003837 if (!conn_ctrl_ready(conn))
Willy Tarreauf79c8172013-10-21 16:30:56 +02003838 return 0;
3839
Willy Tarreau20879a02012-12-03 16:32:10 +01003840 if (global.maxsslconn && sslconns >= global.maxsslconn) {
3841 conn->err_code = CO_ER_SSL_TOO_MANY;
Willy Tarreau403edff2012-09-06 11:58:37 +02003842 return -1;
Willy Tarreau20879a02012-12-03 16:32:10 +01003843 }
Willy Tarreau403edff2012-09-06 11:58:37 +02003844
Emeric Brun46591952012-05-18 15:47:34 +02003845 /* If it is in client mode initiate SSL session
3846 in connect state otherwise accept state */
Willy Tarreau3fdb3662012-11-12 00:42:33 +01003847 if (objt_server(conn->target)) {
Willy Tarreaufba03cd2014-11-13 13:48:58 +01003848 int may_retry = 1;
3849
3850 retry_connect:
Emeric Brun46591952012-05-18 15:47:34 +02003851 /* Alloc a new SSL session ctx */
Willy Tarreau3fdb3662012-11-12 00:42:33 +01003852 conn->xprt_ctx = SSL_new(objt_server(conn->target)->ssl_ctx.ctx);
Willy Tarreau20879a02012-12-03 16:32:10 +01003853 if (!conn->xprt_ctx) {
Willy Tarreaufba03cd2014-11-13 13:48:58 +01003854 if (may_retry--) {
3855 pool_gc2();
3856 goto retry_connect;
3857 }
Willy Tarreau20879a02012-12-03 16:32:10 +01003858 conn->err_code = CO_ER_SSL_NO_MEM;
Emeric Brun46591952012-05-18 15:47:34 +02003859 return -1;
Willy Tarreau20879a02012-12-03 16:32:10 +01003860 }
Emeric Brun46591952012-05-18 15:47:34 +02003861
Emeric Brun46591952012-05-18 15:47:34 +02003862 /* set fd on SSL session context */
Emeric Brun55476152014-11-12 17:35:37 +01003863 if (!SSL_set_fd(conn->xprt_ctx, conn->t.sock.fd)) {
3864 SSL_free(conn->xprt_ctx);
3865 conn->xprt_ctx = NULL;
Willy Tarreaufba03cd2014-11-13 13:48:58 +01003866 if (may_retry--) {
3867 pool_gc2();
3868 goto retry_connect;
3869 }
Emeric Brun55476152014-11-12 17:35:37 +01003870 conn->err_code = CO_ER_SSL_NO_MEM;
3871 return -1;
3872 }
Emeric Brun46591952012-05-18 15:47:34 +02003873
Evan Broderbe554312013-06-27 00:05:25 -07003874 /* set connection pointer */
Emeric Brun55476152014-11-12 17:35:37 +01003875 if (!SSL_set_app_data(conn->xprt_ctx, conn)) {
3876 SSL_free(conn->xprt_ctx);
3877 conn->xprt_ctx = NULL;
Willy Tarreaufba03cd2014-11-13 13:48:58 +01003878 if (may_retry--) {
3879 pool_gc2();
3880 goto retry_connect;
3881 }
Emeric Brun55476152014-11-12 17:35:37 +01003882 conn->err_code = CO_ER_SSL_NO_MEM;
3883 return -1;
3884 }
3885
3886 SSL_set_connect_state(conn->xprt_ctx);
3887 if (objt_server(conn->target)->ssl_ctx.reused_sess) {
3888 if(!SSL_set_session(conn->xprt_ctx, objt_server(conn->target)->ssl_ctx.reused_sess)) {
3889 SSL_SESSION_free(objt_server(conn->target)->ssl_ctx.reused_sess);
3890 objt_server(conn->target)->ssl_ctx.reused_sess = NULL;
3891 }
3892 }
Evan Broderbe554312013-06-27 00:05:25 -07003893
Emeric Brun46591952012-05-18 15:47:34 +02003894 /* leave init state and start handshake */
Willy Tarreau05737472012-09-04 08:03:39 +02003895 conn->flags |= CO_FL_SSL_WAIT_HS | CO_FL_WAIT_L6_CONN;
Willy Tarreau403edff2012-09-06 11:58:37 +02003896
3897 sslconns++;
Willy Tarreau71b734c2014-01-28 15:19:44 +01003898 totalsslconns++;
Emeric Brun46591952012-05-18 15:47:34 +02003899 return 0;
3900 }
Willy Tarreau3fdb3662012-11-12 00:42:33 +01003901 else if (objt_listener(conn->target)) {
Willy Tarreaufba03cd2014-11-13 13:48:58 +01003902 int may_retry = 1;
3903
3904 retry_accept:
Emeric Brun46591952012-05-18 15:47:34 +02003905 /* Alloc a new SSL session ctx */
Willy Tarreau3fdb3662012-11-12 00:42:33 +01003906 conn->xprt_ctx = SSL_new(objt_listener(conn->target)->bind_conf->default_ctx);
Willy Tarreau20879a02012-12-03 16:32:10 +01003907 if (!conn->xprt_ctx) {
Willy Tarreaufba03cd2014-11-13 13:48:58 +01003908 if (may_retry--) {
3909 pool_gc2();
3910 goto retry_accept;
3911 }
Willy Tarreau20879a02012-12-03 16:32:10 +01003912 conn->err_code = CO_ER_SSL_NO_MEM;
Emeric Brun46591952012-05-18 15:47:34 +02003913 return -1;
Willy Tarreau20879a02012-12-03 16:32:10 +01003914 }
Emeric Brun46591952012-05-18 15:47:34 +02003915
Emeric Brun46591952012-05-18 15:47:34 +02003916 /* set fd on SSL session context */
Emeric Brun55476152014-11-12 17:35:37 +01003917 if (!SSL_set_fd(conn->xprt_ctx, conn->t.sock.fd)) {
3918 SSL_free(conn->xprt_ctx);
3919 conn->xprt_ctx = NULL;
Willy Tarreaufba03cd2014-11-13 13:48:58 +01003920 if (may_retry--) {
3921 pool_gc2();
3922 goto retry_accept;
3923 }
Emeric Brun55476152014-11-12 17:35:37 +01003924 conn->err_code = CO_ER_SSL_NO_MEM;
3925 return -1;
3926 }
Emeric Brun46591952012-05-18 15:47:34 +02003927
Emeric Brune1f38db2012-09-03 20:36:47 +02003928 /* set connection pointer */
Emeric Brun55476152014-11-12 17:35:37 +01003929 if (!SSL_set_app_data(conn->xprt_ctx, conn)) {
3930 SSL_free(conn->xprt_ctx);
3931 conn->xprt_ctx = NULL;
Willy Tarreaufba03cd2014-11-13 13:48:58 +01003932 if (may_retry--) {
3933 pool_gc2();
3934 goto retry_accept;
3935 }
Emeric Brun55476152014-11-12 17:35:37 +01003936 conn->err_code = CO_ER_SSL_NO_MEM;
3937 return -1;
3938 }
3939
3940 SSL_set_accept_state(conn->xprt_ctx);
Emeric Brune1f38db2012-09-03 20:36:47 +02003941
Emeric Brun46591952012-05-18 15:47:34 +02003942 /* leave init state and start handshake */
Willy Tarreau05737472012-09-04 08:03:39 +02003943 conn->flags |= CO_FL_SSL_WAIT_HS | CO_FL_WAIT_L6_CONN;
Willy Tarreau403edff2012-09-06 11:58:37 +02003944
3945 sslconns++;
Willy Tarreau71b734c2014-01-28 15:19:44 +01003946 totalsslconns++;
Emeric Brun46591952012-05-18 15:47:34 +02003947 return 0;
3948 }
3949 /* don't know how to handle such a target */
Willy Tarreau20879a02012-12-03 16:32:10 +01003950 conn->err_code = CO_ER_SSL_NO_TARGET;
Emeric Brun46591952012-05-18 15:47:34 +02003951 return -1;
3952}
3953
3954
3955/* This is the callback which is used when an SSL handshake is pending. It
3956 * updates the FD status if it wants some polling before being called again.
3957 * It returns 0 if it fails in a fatal way or needs to poll to go further,
3958 * otherwise it returns non-zero and removes itself from the connection's
3959 * flags (the bit is provided in <flag> by the caller).
3960 */
3961int ssl_sock_handshake(struct connection *conn, unsigned int flag)
3962{
3963 int ret;
3964
Willy Tarreau3c728722014-01-23 13:50:42 +01003965 if (!conn_ctrl_ready(conn))
Willy Tarreauf79c8172013-10-21 16:30:56 +02003966 return 0;
3967
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02003968 if (!conn->xprt_ctx)
Emeric Brun46591952012-05-18 15:47:34 +02003969 goto out_error;
3970
Emeric Brun674b7432012-11-08 19:21:55 +01003971 /* If we use SSL_do_handshake to process a reneg initiated by
3972 * the remote peer, it sometimes returns SSL_ERROR_SSL.
3973 * Usually SSL_write and SSL_read are used and process implicitly
3974 * the reneg handshake.
3975 * Here we use SSL_peek as a workaround for reneg.
3976 */
3977 if ((conn->flags & CO_FL_CONNECTED) && SSL_renegotiate_pending(conn->xprt_ctx)) {
3978 char c;
3979
3980 ret = SSL_peek(conn->xprt_ctx, &c, 1);
3981 if (ret <= 0) {
3982 /* handshake may have not been completed, let's find why */
3983 ret = SSL_get_error(conn->xprt_ctx, ret);
3984 if (ret == SSL_ERROR_WANT_WRITE) {
3985 /* SSL handshake needs to write, L4 connection may not be ready */
3986 __conn_sock_stop_recv(conn);
Willy Tarreaue1f50c42014-01-22 20:02:06 +01003987 __conn_sock_want_send(conn);
3988 fd_cant_send(conn->t.sock.fd);
Emeric Brun674b7432012-11-08 19:21:55 +01003989 return 0;
3990 }
3991 else if (ret == SSL_ERROR_WANT_READ) {
3992 /* handshake may have been completed but we have
3993 * no more data to read.
3994 */
3995 if (!SSL_renegotiate_pending(conn->xprt_ctx)) {
3996 ret = 1;
3997 goto reneg_ok;
3998 }
3999 /* SSL handshake needs to read, L4 connection is ready */
4000 if (conn->flags & CO_FL_WAIT_L4_CONN)
4001 conn->flags &= ~CO_FL_WAIT_L4_CONN;
4002 __conn_sock_stop_send(conn);
Willy Tarreaue1f50c42014-01-22 20:02:06 +01004003 __conn_sock_want_recv(conn);
4004 fd_cant_recv(conn->t.sock.fd);
Emeric Brun674b7432012-11-08 19:21:55 +01004005 return 0;
4006 }
4007 else if (ret == SSL_ERROR_SYSCALL) {
4008 /* if errno is null, then connection was successfully established */
4009 if (!errno && conn->flags & CO_FL_WAIT_L4_CONN)
4010 conn->flags &= ~CO_FL_WAIT_L4_CONN;
Willy Tarreau20879a02012-12-03 16:32:10 +01004011 if (!conn->err_code) {
Emmanuel Hocdetfdec7892017-01-13 17:48:18 +01004012#ifdef OPENSSL_NO_HEARTBEATS /* BoringSSL */
4013 conn->err_code = CO_ER_SSL_HANDSHAKE;
4014#else
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02004015 int empty_handshake;
Luca Pizzamiglio578b1692016-12-12 10:56:56 +01004016#if (OPENSSL_VERSION_NUMBER >= 0x1010000fL) && !defined(LIBRESSL_VERSION_NUMBER)
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02004017 OSSL_HANDSHAKE_STATE state = SSL_get_state((SSL *)conn->xprt_ctx);
4018 empty_handshake = state == TLS_ST_BEFORE;
4019#else
4020 empty_handshake = !((SSL *)conn->xprt_ctx)->packet_length;
4021#endif
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02004022 if (empty_handshake) {
Emeric Brun29f037d2014-04-25 19:05:36 +02004023 if (!errno) {
4024 if (conn->xprt_st & SSL_SOCK_RECV_HEARTBEAT)
4025 conn->err_code = CO_ER_SSL_HANDSHAKE_HB;
4026 else
4027 conn->err_code = CO_ER_SSL_EMPTY;
4028 }
4029 else {
4030 if (conn->xprt_st & SSL_SOCK_RECV_HEARTBEAT)
4031 conn->err_code = CO_ER_SSL_HANDSHAKE_HB;
4032 else
4033 conn->err_code = CO_ER_SSL_ABORT;
4034 }
4035 }
4036 else {
4037 if (conn->xprt_st & SSL_SOCK_RECV_HEARTBEAT)
4038 conn->err_code = CO_ER_SSL_HANDSHAKE_HB;
Willy Tarreau20879a02012-12-03 16:32:10 +01004039 else
Emeric Brun29f037d2014-04-25 19:05:36 +02004040 conn->err_code = CO_ER_SSL_HANDSHAKE;
4041 }
Emmanuel Hocdetfdec7892017-01-13 17:48:18 +01004042#endif
Willy Tarreau20879a02012-12-03 16:32:10 +01004043 }
Emeric Brun674b7432012-11-08 19:21:55 +01004044 goto out_error;
4045 }
4046 else {
4047 /* Fail on all other handshake errors */
4048 /* Note: OpenSSL may leave unread bytes in the socket's
4049 * buffer, causing an RST to be emitted upon close() on
4050 * TCP sockets. We first try to drain possibly pending
4051 * data to avoid this as much as possible.
4052 */
Willy Tarreaud85c4852015-03-13 00:40:28 +01004053 conn_sock_drain(conn);
Willy Tarreau20879a02012-12-03 16:32:10 +01004054 if (!conn->err_code)
Willy Tarreauf51c6982014-04-25 20:02:39 +02004055 conn->err_code = (conn->xprt_st & SSL_SOCK_RECV_HEARTBEAT) ?
4056 CO_ER_SSL_KILLED_HB : CO_ER_SSL_HANDSHAKE;
Emeric Brun674b7432012-11-08 19:21:55 +01004057 goto out_error;
4058 }
4059 }
4060 /* read some data: consider handshake completed */
4061 goto reneg_ok;
4062 }
4063
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02004064 ret = SSL_do_handshake(conn->xprt_ctx);
Emeric Brun46591952012-05-18 15:47:34 +02004065 if (ret != 1) {
4066 /* handshake did not complete, let's find why */
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02004067 ret = SSL_get_error(conn->xprt_ctx, ret);
Emeric Brun46591952012-05-18 15:47:34 +02004068
4069 if (ret == SSL_ERROR_WANT_WRITE) {
4070 /* SSL handshake needs to write, L4 connection may not be ready */
4071 __conn_sock_stop_recv(conn);
Willy Tarreaue1f50c42014-01-22 20:02:06 +01004072 __conn_sock_want_send(conn);
4073 fd_cant_send(conn->t.sock.fd);
Emeric Brun46591952012-05-18 15:47:34 +02004074 return 0;
4075 }
4076 else if (ret == SSL_ERROR_WANT_READ) {
4077 /* SSL handshake needs to read, L4 connection is ready */
4078 if (conn->flags & CO_FL_WAIT_L4_CONN)
4079 conn->flags &= ~CO_FL_WAIT_L4_CONN;
4080 __conn_sock_stop_send(conn);
Willy Tarreaue1f50c42014-01-22 20:02:06 +01004081 __conn_sock_want_recv(conn);
4082 fd_cant_recv(conn->t.sock.fd);
Emeric Brun46591952012-05-18 15:47:34 +02004083 return 0;
4084 }
Willy Tarreau89230192012-09-28 20:22:13 +02004085 else if (ret == SSL_ERROR_SYSCALL) {
4086 /* if errno is null, then connection was successfully established */
4087 if (!errno && conn->flags & CO_FL_WAIT_L4_CONN)
4088 conn->flags &= ~CO_FL_WAIT_L4_CONN;
Emmanuel Hocdetfdec7892017-01-13 17:48:18 +01004089 if (!conn->err_code) {
4090#ifdef OPENSSL_NO_HEARTBEATS /* BoringSSL */
4091 conn->err_code = CO_ER_SSL_HANDSHAKE;
4092#else
4093 int empty_handshake;
Luca Pizzamiglio578b1692016-12-12 10:56:56 +01004094#if (OPENSSL_VERSION_NUMBER >= 0x1010000fL) && !defined(LIBRESSL_VERSION_NUMBER)
Emmanuel Hocdetfdec7892017-01-13 17:48:18 +01004095 OSSL_HANDSHAKE_STATE state = SSL_get_state((SSL *)conn->xprt_ctx);
4096 empty_handshake = state == TLS_ST_BEFORE;
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02004097#else
Emmanuel Hocdetfdec7892017-01-13 17:48:18 +01004098 empty_handshake = !((SSL *)conn->xprt_ctx)->packet_length;
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02004099#endif
Emmanuel Hocdetfdec7892017-01-13 17:48:18 +01004100 if (empty_handshake) {
4101 if (!errno) {
4102 if (conn->xprt_st & SSL_SOCK_RECV_HEARTBEAT)
4103 conn->err_code = CO_ER_SSL_HANDSHAKE_HB;
4104 else
4105 conn->err_code = CO_ER_SSL_EMPTY;
4106 }
4107 else {
4108 if (conn->xprt_st & SSL_SOCK_RECV_HEARTBEAT)
4109 conn->err_code = CO_ER_SSL_HANDSHAKE_HB;
4110 else
4111 conn->err_code = CO_ER_SSL_ABORT;
4112 }
Emeric Brun29f037d2014-04-25 19:05:36 +02004113 }
4114 else {
4115 if (conn->xprt_st & SSL_SOCK_RECV_HEARTBEAT)
4116 conn->err_code = CO_ER_SSL_HANDSHAKE_HB;
4117 else
Emmanuel Hocdetfdec7892017-01-13 17:48:18 +01004118 conn->err_code = CO_ER_SSL_HANDSHAKE;
Emeric Brun29f037d2014-04-25 19:05:36 +02004119 }
Emmanuel Hocdetfdec7892017-01-13 17:48:18 +01004120#endif
Emeric Brun29f037d2014-04-25 19:05:36 +02004121 }
Willy Tarreau89230192012-09-28 20:22:13 +02004122 goto out_error;
4123 }
Emeric Brun46591952012-05-18 15:47:34 +02004124 else {
4125 /* Fail on all other handshake errors */
Willy Tarreau566dc552012-10-19 20:52:18 +02004126 /* Note: OpenSSL may leave unread bytes in the socket's
4127 * buffer, causing an RST to be emitted upon close() on
4128 * TCP sockets. We first try to drain possibly pending
4129 * data to avoid this as much as possible.
4130 */
Willy Tarreaud85c4852015-03-13 00:40:28 +01004131 conn_sock_drain(conn);
Willy Tarreau20879a02012-12-03 16:32:10 +01004132 if (!conn->err_code)
Willy Tarreauf51c6982014-04-25 20:02:39 +02004133 conn->err_code = (conn->xprt_st & SSL_SOCK_RECV_HEARTBEAT) ?
4134 CO_ER_SSL_KILLED_HB : CO_ER_SSL_HANDSHAKE;
Emeric Brun46591952012-05-18 15:47:34 +02004135 goto out_error;
4136 }
4137 }
4138
Emeric Brun674b7432012-11-08 19:21:55 +01004139reneg_ok:
Emeric Brun46591952012-05-18 15:47:34 +02004140 /* Handshake succeeded */
Willy Tarreau0c9c2722014-05-28 12:28:58 +02004141 if (!SSL_session_reused(conn->xprt_ctx)) {
4142 if (objt_server(conn->target)) {
4143 update_freq_ctr(&global.ssl_be_keys_per_sec, 1);
4144 if (global.ssl_be_keys_per_sec.curr_ctr > global.ssl_be_keys_max)
4145 global.ssl_be_keys_max = global.ssl_be_keys_per_sec.curr_ctr;
4146
Emeric Brun46591952012-05-18 15:47:34 +02004147 /* check if session was reused, if not store current session on server for reuse */
Willy Tarreau30fd4bd2016-12-22 21:54:21 +01004148 if (objt_server(conn->target)->ssl_ctx.reused_sess) {
Willy Tarreau3fdb3662012-11-12 00:42:33 +01004149 SSL_SESSION_free(objt_server(conn->target)->ssl_ctx.reused_sess);
Willy Tarreau30fd4bd2016-12-22 21:54:21 +01004150 objt_server(conn->target)->ssl_ctx.reused_sess = NULL;
4151 }
Emeric Brun46591952012-05-18 15:47:34 +02004152
Willy Tarreau2a3fb1c2015-02-05 16:47:07 +01004153 if (!(objt_server(conn->target)->ssl_ctx.options & SRV_SSL_O_NO_REUSE))
4154 objt_server(conn->target)->ssl_ctx.reused_sess = SSL_get1_session(conn->xprt_ctx);
Emeric Brun46591952012-05-18 15:47:34 +02004155 }
Willy Tarreau0c9c2722014-05-28 12:28:58 +02004156 else {
4157 update_freq_ctr(&global.ssl_fe_keys_per_sec, 1);
4158 if (global.ssl_fe_keys_per_sec.curr_ctr > global.ssl_fe_keys_max)
4159 global.ssl_fe_keys_max = global.ssl_fe_keys_per_sec.curr_ctr;
4160 }
Emeric Brun46591952012-05-18 15:47:34 +02004161 }
4162
4163 /* The connection is now established at both layers, it's time to leave */
4164 conn->flags &= ~(flag | CO_FL_WAIT_L4_CONN | CO_FL_WAIT_L6_CONN);
4165 return 1;
4166
4167 out_error:
Emeric Brun644cde02012-12-14 11:21:13 +01004168 /* Clear openssl global errors stack */
Thierry FOURNIER / OZON.IO8b068c22016-10-10 11:59:50 +02004169 ssl_sock_dump_errors(conn);
Emeric Brun644cde02012-12-14 11:21:13 +01004170 ERR_clear_error();
4171
Emeric Brun9fa89732012-10-04 17:09:56 +02004172 /* free resumed session if exists */
Willy Tarreau3fdb3662012-11-12 00:42:33 +01004173 if (objt_server(conn->target) && objt_server(conn->target)->ssl_ctx.reused_sess) {
4174 SSL_SESSION_free(objt_server(conn->target)->ssl_ctx.reused_sess);
4175 objt_server(conn->target)->ssl_ctx.reused_sess = NULL;
Emeric Brun9fa89732012-10-04 17:09:56 +02004176 }
4177
Emeric Brun46591952012-05-18 15:47:34 +02004178 /* Fail on all other handshake errors */
4179 conn->flags |= CO_FL_ERROR;
Willy Tarreau20879a02012-12-03 16:32:10 +01004180 if (!conn->err_code)
4181 conn->err_code = CO_ER_SSL_HANDSHAKE;
Emeric Brun46591952012-05-18 15:47:34 +02004182 return 0;
4183}
4184
4185/* Receive up to <count> bytes from connection <conn>'s socket and store them
Willy Tarreauabf08d92014-01-14 11:31:27 +01004186 * into buffer <buf>. Only one call to recv() is performed, unless the
Emeric Brun46591952012-05-18 15:47:34 +02004187 * buffer wraps, in which case a second call may be performed. The connection's
4188 * flags are updated with whatever special event is detected (error, read0,
4189 * empty). The caller is responsible for taking care of those events and
4190 * avoiding the call if inappropriate. The function does not call the
4191 * connection's polling update function, so the caller is responsible for this.
4192 */
4193static int ssl_sock_to_buf(struct connection *conn, struct buffer *buf, int count)
4194{
4195 int ret, done = 0;
Willy Tarreauabf08d92014-01-14 11:31:27 +01004196 int try;
Emeric Brun46591952012-05-18 15:47:34 +02004197
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02004198 if (!conn->xprt_ctx)
Emeric Brun46591952012-05-18 15:47:34 +02004199 goto out_error;
4200
4201 if (conn->flags & CO_FL_HANDSHAKE)
4202 /* a handshake was requested */
4203 return 0;
4204
Willy Tarreauabf08d92014-01-14 11:31:27 +01004205 /* let's realign the buffer to optimize I/O */
4206 if (buffer_empty(buf))
Emeric Brun46591952012-05-18 15:47:34 +02004207 buf->p = buf->data;
Emeric Brun46591952012-05-18 15:47:34 +02004208
4209 /* read the largest possible block. For this, we perform only one call
4210 * to recv() unless the buffer wraps and we exactly fill the first hunk,
4211 * in which case we accept to do it once again. A new attempt is made on
4212 * EINTR too.
4213 */
Willy Tarreau00b0fb92014-01-17 11:09:40 +01004214 while (count > 0) {
Willy Tarreauabf08d92014-01-14 11:31:27 +01004215 /* first check if we have some room after p+i */
4216 try = buf->data + buf->size - (buf->p + buf->i);
4217 /* otherwise continue between data and p-o */
4218 if (try <= 0) {
4219 try = buf->p - (buf->data + buf->o);
4220 if (try <= 0)
4221 break;
4222 }
4223 if (try > count)
4224 try = count;
4225
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02004226 ret = SSL_read(conn->xprt_ctx, bi_end(buf), try);
Emeric Brune1f38db2012-09-03 20:36:47 +02004227 if (conn->flags & CO_FL_ERROR) {
4228 /* CO_FL_ERROR may be set by ssl_sock_infocbk */
Emeric Brun644cde02012-12-14 11:21:13 +01004229 goto out_error;
Emeric Brune1f38db2012-09-03 20:36:47 +02004230 }
Emeric Brun46591952012-05-18 15:47:34 +02004231 if (ret > 0) {
4232 buf->i += ret;
4233 done += ret;
4234 if (ret < try)
4235 break;
4236 count -= ret;
Emeric Brun46591952012-05-18 15:47:34 +02004237 }
4238 else if (ret == 0) {
Emeric Brun644cde02012-12-14 11:21:13 +01004239 ret = SSL_get_error(conn->xprt_ctx, ret);
4240 if (ret != SSL_ERROR_ZERO_RETURN) {
Emeric Brun1c646862012-12-14 12:33:41 +01004241 /* error on protocol or underlying transport */
4242 if ((ret != SSL_ERROR_SYSCALL)
4243 || (errno && (errno != EAGAIN)))
4244 conn->flags |= CO_FL_ERROR;
4245
Emeric Brun644cde02012-12-14 11:21:13 +01004246 /* Clear openssl global errors stack */
Thierry FOURNIER / OZON.IO8b068c22016-10-10 11:59:50 +02004247 ssl_sock_dump_errors(conn);
Emeric Brun644cde02012-12-14 11:21:13 +01004248 ERR_clear_error();
4249 }
Emeric Brun46591952012-05-18 15:47:34 +02004250 goto read0;
4251 }
4252 else {
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02004253 ret = SSL_get_error(conn->xprt_ctx, ret);
Emeric Brun46591952012-05-18 15:47:34 +02004254 if (ret == SSL_ERROR_WANT_WRITE) {
Emeric Brun8af8dd12012-11-08 17:56:20 +01004255 /* handshake is running, and it needs to enable write */
Emeric Brun46591952012-05-18 15:47:34 +02004256 conn->flags |= CO_FL_SSL_WAIT_HS;
Emeric Brun8af8dd12012-11-08 17:56:20 +01004257 __conn_sock_want_send(conn);
Emeric Brun46591952012-05-18 15:47:34 +02004258 break;
4259 }
4260 else if (ret == SSL_ERROR_WANT_READ) {
Emeric Brun282a76a2012-11-08 18:02:56 +01004261 if (SSL_renegotiate_pending(conn->xprt_ctx)) {
4262 /* handshake is running, and it may need to re-enable read */
4263 conn->flags |= CO_FL_SSL_WAIT_HS;
4264 __conn_sock_want_recv(conn);
4265 break;
4266 }
Emeric Brun46591952012-05-18 15:47:34 +02004267 /* we need to poll for retry a read later */
Willy Tarreaue1f50c42014-01-22 20:02:06 +01004268 fd_cant_recv(conn->t.sock.fd);
Emeric Brun46591952012-05-18 15:47:34 +02004269 break;
4270 }
4271 /* otherwise it's a real error */
4272 goto out_error;
4273 }
4274 }
4275 return done;
4276
4277 read0:
4278 conn_sock_read0(conn);
4279 return done;
4280 out_error:
Emeric Brun644cde02012-12-14 11:21:13 +01004281 /* Clear openssl global errors stack */
Thierry FOURNIER / OZON.IO8b068c22016-10-10 11:59:50 +02004282 ssl_sock_dump_errors(conn);
Emeric Brun644cde02012-12-14 11:21:13 +01004283 ERR_clear_error();
4284
Emeric Brun46591952012-05-18 15:47:34 +02004285 conn->flags |= CO_FL_ERROR;
4286 return done;
4287}
4288
4289
4290/* Send all pending bytes from buffer <buf> to connection <conn>'s socket.
Willy Tarreau1049b1f2014-02-02 01:51:17 +01004291 * <flags> may contain some CO_SFL_* flags to hint the system about other
4292 * pending data for example, but this flag is ignored at the moment.
Emeric Brun46591952012-05-18 15:47:34 +02004293 * Only one call to send() is performed, unless the buffer wraps, in which case
4294 * a second call may be performed. The connection's flags are updated with
4295 * whatever special event is detected (error, empty). The caller is responsible
4296 * for taking care of those events and avoiding the call if inappropriate. The
4297 * function does not call the connection's polling update function, so the caller
4298 * is responsible for this.
4299 */
4300static int ssl_sock_from_buf(struct connection *conn, struct buffer *buf, int flags)
4301{
4302 int ret, try, done;
4303
4304 done = 0;
4305
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02004306 if (!conn->xprt_ctx)
Emeric Brun46591952012-05-18 15:47:34 +02004307 goto out_error;
4308
4309 if (conn->flags & CO_FL_HANDSHAKE)
4310 /* a handshake was requested */
4311 return 0;
4312
4313 /* send the largest possible block. For this we perform only one call
4314 * to send() unless the buffer wraps and we exactly fill the first hunk,
4315 * in which case we accept to do it once again.
4316 */
4317 while (buf->o) {
Kevin Hestercad82342013-05-30 15:12:41 -07004318 try = bo_contig_data(buf);
Willy Tarreaubfd59462013-02-21 07:46:09 +01004319
Willy Tarreau7bed9452014-02-02 02:00:24 +01004320 if (!(flags & CO_SFL_STREAMER) &&
Willy Tarreau518cedd2014-02-17 15:43:01 +01004321 !(conn->xprt_st & SSL_SOCK_SEND_UNLIMITED) &&
Willy Tarreauef934602016-12-22 23:12:01 +01004322 global_ssl.max_record && try > global_ssl.max_record) {
4323 try = global_ssl.max_record;
Willy Tarreau518cedd2014-02-17 15:43:01 +01004324 }
4325 else {
4326 /* we need to keep the information about the fact that
4327 * we're not limiting the upcoming send(), because if it
4328 * fails, we'll have to retry with at least as many data.
4329 */
4330 conn->xprt_st |= SSL_SOCK_SEND_UNLIMITED;
4331 }
Willy Tarreaubfd59462013-02-21 07:46:09 +01004332
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02004333 ret = SSL_write(conn->xprt_ctx, bo_ptr(buf), try);
Willy Tarreau518cedd2014-02-17 15:43:01 +01004334
Emeric Brune1f38db2012-09-03 20:36:47 +02004335 if (conn->flags & CO_FL_ERROR) {
4336 /* CO_FL_ERROR may be set by ssl_sock_infocbk */
Emeric Brun644cde02012-12-14 11:21:13 +01004337 goto out_error;
Emeric Brune1f38db2012-09-03 20:36:47 +02004338 }
Emeric Brun46591952012-05-18 15:47:34 +02004339 if (ret > 0) {
Willy Tarreau518cedd2014-02-17 15:43:01 +01004340 conn->xprt_st &= ~SSL_SOCK_SEND_UNLIMITED;
4341
Emeric Brun46591952012-05-18 15:47:34 +02004342 buf->o -= ret;
4343 done += ret;
4344
Willy Tarreau5fb38032012-12-16 19:39:09 +01004345 if (likely(buffer_empty(buf)))
Emeric Brun46591952012-05-18 15:47:34 +02004346 /* optimize data alignment in the buffer */
4347 buf->p = buf->data;
4348
4349 /* if the system buffer is full, don't insist */
4350 if (ret < try)
4351 break;
4352 }
4353 else {
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02004354 ret = SSL_get_error(conn->xprt_ctx, ret);
Emeric Brun46591952012-05-18 15:47:34 +02004355 if (ret == SSL_ERROR_WANT_WRITE) {
Emeric Brun282a76a2012-11-08 18:02:56 +01004356 if (SSL_renegotiate_pending(conn->xprt_ctx)) {
4357 /* handshake is running, and it may need to re-enable write */
4358 conn->flags |= CO_FL_SSL_WAIT_HS;
4359 __conn_sock_want_send(conn);
4360 break;
4361 }
Emeric Brun46591952012-05-18 15:47:34 +02004362 /* we need to poll to retry a write later */
Willy Tarreaue1f50c42014-01-22 20:02:06 +01004363 fd_cant_send(conn->t.sock.fd);
Emeric Brun46591952012-05-18 15:47:34 +02004364 break;
4365 }
4366 else if (ret == SSL_ERROR_WANT_READ) {
Emeric Brun8af8dd12012-11-08 17:56:20 +01004367 /* handshake is running, and it needs to enable read */
Emeric Brun46591952012-05-18 15:47:34 +02004368 conn->flags |= CO_FL_SSL_WAIT_HS;
Emeric Brun8af8dd12012-11-08 17:56:20 +01004369 __conn_sock_want_recv(conn);
Emeric Brun46591952012-05-18 15:47:34 +02004370 break;
4371 }
4372 goto out_error;
4373 }
4374 }
4375 return done;
4376
4377 out_error:
Emeric Brun644cde02012-12-14 11:21:13 +01004378 /* Clear openssl global errors stack */
Thierry FOURNIER / OZON.IO8b068c22016-10-10 11:59:50 +02004379 ssl_sock_dump_errors(conn);
Emeric Brun644cde02012-12-14 11:21:13 +01004380 ERR_clear_error();
4381
Emeric Brun46591952012-05-18 15:47:34 +02004382 conn->flags |= CO_FL_ERROR;
4383 return done;
4384}
4385
Emeric Brun46591952012-05-18 15:47:34 +02004386static void ssl_sock_close(struct connection *conn) {
4387
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02004388 if (conn->xprt_ctx) {
4389 SSL_free(conn->xprt_ctx);
4390 conn->xprt_ctx = NULL;
Willy Tarreau403edff2012-09-06 11:58:37 +02004391 sslconns--;
Emeric Brun46591952012-05-18 15:47:34 +02004392 }
Emeric Brun46591952012-05-18 15:47:34 +02004393}
4394
4395/* This function tries to perform a clean shutdown on an SSL connection, and in
4396 * any case, flags the connection as reusable if no handshake was in progress.
4397 */
4398static void ssl_sock_shutw(struct connection *conn, int clean)
4399{
4400 if (conn->flags & CO_FL_HANDSHAKE)
4401 return;
Emmanuel Hocdet405ff312017-01-08 14:07:39 +01004402 if (!clean)
4403 /* don't sent notify on SSL_shutdown */
Willy Tarreaue3cc3a32017-02-13 11:12:29 +01004404 SSL_set_quiet_shutdown(conn->xprt_ctx, 1);
Emeric Brun46591952012-05-18 15:47:34 +02004405 /* no handshake was in progress, try a clean ssl shutdown */
Emmanuel Hocdet405ff312017-01-08 14:07:39 +01004406 if (SSL_shutdown(conn->xprt_ctx) <= 0) {
Emeric Brun644cde02012-12-14 11:21:13 +01004407 /* Clear openssl global errors stack */
Thierry FOURNIER / OZON.IO8b068c22016-10-10 11:59:50 +02004408 ssl_sock_dump_errors(conn);
Emeric Brun644cde02012-12-14 11:21:13 +01004409 ERR_clear_error();
4410 }
Emeric Brun46591952012-05-18 15:47:34 +02004411}
4412
Willy Tarreauffc3fcd2012-10-12 20:17:54 +02004413/* used for logging, may be changed for a sample fetch later */
4414const char *ssl_sock_get_cipher_name(struct connection *conn)
4415{
4416 if (!conn->xprt && !conn->xprt_ctx)
4417 return NULL;
4418 return SSL_get_cipher_name(conn->xprt_ctx);
4419}
4420
4421/* used for logging, may be changed for a sample fetch later */
4422const char *ssl_sock_get_proto_version(struct connection *conn)
4423{
4424 if (!conn->xprt && !conn->xprt_ctx)
4425 return NULL;
4426 return SSL_get_version(conn->xprt_ctx);
4427}
4428
Willy Tarreau8d598402012-10-22 17:58:39 +02004429/* Extract a serial from a cert, and copy it to a chunk.
4430 * Returns 1 if serial is found and copied, 0 if no serial found and
4431 * -1 if output is not large enough.
4432 */
4433static int
4434ssl_sock_get_serial(X509 *crt, struct chunk *out)
4435{
4436 ASN1_INTEGER *serial;
4437
4438 serial = X509_get_serialNumber(crt);
4439 if (!serial)
4440 return 0;
4441
4442 if (out->size < serial->length)
4443 return -1;
4444
4445 memcpy(out->str, serial->data, serial->length);
4446 out->len = serial->length;
4447 return 1;
4448}
4449
Emeric Brun43e79582014-10-29 19:03:26 +01004450/* Extract a cert to der, and copy it to a chunk.
4451 * Returns 1 if cert is found and copied, 0 on der convertion failure and
4452 * -1 if output is not large enough.
4453 */
4454static int
4455ssl_sock_crt2der(X509 *crt, struct chunk *out)
4456{
4457 int len;
4458 unsigned char *p = (unsigned char *)out->str;;
4459
4460 len =i2d_X509(crt, NULL);
4461 if (len <= 0)
4462 return 1;
4463
4464 if (out->size < len)
4465 return -1;
4466
4467 i2d_X509(crt,&p);
4468 out->len = len;
4469 return 1;
4470}
4471
Emeric Brunce5ad802012-10-22 14:11:22 +02004472
4473/* Copy Date in ASN1_UTCTIME format in struct chunk out.
4474 * Returns 1 if serial is found and copied, 0 if no valid time found
4475 * and -1 if output is not large enough.
4476 */
4477static int
4478ssl_sock_get_time(ASN1_TIME *tm, struct chunk *out)
4479{
4480 if (tm->type == V_ASN1_GENERALIZEDTIME) {
4481 ASN1_GENERALIZEDTIME *gentm = (ASN1_GENERALIZEDTIME *)tm;
4482
4483 if (gentm->length < 12)
4484 return 0;
4485 if (gentm->data[0] != 0x32 || gentm->data[1] != 0x30)
4486 return 0;
4487 if (out->size < gentm->length-2)
4488 return -1;
4489
4490 memcpy(out->str, gentm->data+2, gentm->length-2);
4491 out->len = gentm->length-2;
4492 return 1;
4493 }
4494 else if (tm->type == V_ASN1_UTCTIME) {
4495 ASN1_UTCTIME *utctm = (ASN1_UTCTIME *)tm;
4496
4497 if (utctm->length < 10)
4498 return 0;
4499 if (utctm->data[0] >= 0x35)
4500 return 0;
4501 if (out->size < utctm->length)
4502 return -1;
4503
4504 memcpy(out->str, utctm->data, utctm->length);
4505 out->len = utctm->length;
4506 return 1;
4507 }
4508
4509 return 0;
4510}
4511
Emeric Brun87855892012-10-17 17:39:35 +02004512/* Extract an entry from a X509_NAME and copy its value to an output chunk.
4513 * Returns 1 if entry found, 0 if entry not found, or -1 if output not large enough.
4514 */
4515static int
4516ssl_sock_get_dn_entry(X509_NAME *a, const struct chunk *entry, int pos, struct chunk *out)
4517{
4518 X509_NAME_ENTRY *ne;
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02004519 ASN1_OBJECT *obj;
4520 ASN1_STRING *data;
4521 const unsigned char *data_ptr;
4522 int data_len;
Emeric Brun87855892012-10-17 17:39:35 +02004523 int i, j, n;
4524 int cur = 0;
4525 const char *s;
4526 char tmp[128];
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02004527 int name_count;
4528
4529 name_count = X509_NAME_entry_count(a);
Emeric Brun87855892012-10-17 17:39:35 +02004530
4531 out->len = 0;
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02004532 for (i = 0; i < name_count; i++) {
Emeric Brun87855892012-10-17 17:39:35 +02004533 if (pos < 0)
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02004534 j = (name_count-1) - i;
Emeric Brun87855892012-10-17 17:39:35 +02004535 else
4536 j = i;
4537
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02004538 ne = X509_NAME_get_entry(a, j);
4539 obj = X509_NAME_ENTRY_get_object(ne);
4540 data = X509_NAME_ENTRY_get_data(ne);
4541 data_ptr = ASN1_STRING_get0_data(data);
4542 data_len = ASN1_STRING_length(data);
4543 n = OBJ_obj2nid(obj);
Emeric Brun87855892012-10-17 17:39:35 +02004544 if ((n == NID_undef) || ((s = OBJ_nid2sn(n)) == NULL)) {
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02004545 i2t_ASN1_OBJECT(tmp, sizeof(tmp), obj);
Emeric Brun87855892012-10-17 17:39:35 +02004546 s = tmp;
4547 }
4548
4549 if (chunk_strcasecmp(entry, s) != 0)
4550 continue;
4551
4552 if (pos < 0)
4553 cur--;
4554 else
4555 cur++;
4556
4557 if (cur != pos)
4558 continue;
4559
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02004560 if (data_len > out->size)
Emeric Brun87855892012-10-17 17:39:35 +02004561 return -1;
4562
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02004563 memcpy(out->str, data_ptr, data_len);
4564 out->len = data_len;
Emeric Brun87855892012-10-17 17:39:35 +02004565 return 1;
4566 }
4567
4568 return 0;
4569
4570}
4571
4572/* Extract and format full DN from a X509_NAME and copy result into a chunk
4573 * Returns 1 if dn entries exits, 0 if no dn entry found or -1 if output is not large enough.
4574 */
4575static int
4576ssl_sock_get_dn_oneline(X509_NAME *a, struct chunk *out)
4577{
4578 X509_NAME_ENTRY *ne;
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02004579 ASN1_OBJECT *obj;
4580 ASN1_STRING *data;
4581 const unsigned char *data_ptr;
4582 int data_len;
Emeric Brun87855892012-10-17 17:39:35 +02004583 int i, n, ln;
4584 int l = 0;
4585 const char *s;
4586 char *p;
4587 char tmp[128];
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02004588 int name_count;
4589
4590
4591 name_count = X509_NAME_entry_count(a);
Emeric Brun87855892012-10-17 17:39:35 +02004592
4593 out->len = 0;
4594 p = out->str;
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02004595 for (i = 0; i < name_count; i++) {
4596 ne = X509_NAME_get_entry(a, i);
4597 obj = X509_NAME_ENTRY_get_object(ne);
4598 data = X509_NAME_ENTRY_get_data(ne);
4599 data_ptr = ASN1_STRING_get0_data(data);
4600 data_len = ASN1_STRING_length(data);
4601 n = OBJ_obj2nid(obj);
Emeric Brun87855892012-10-17 17:39:35 +02004602 if ((n == NID_undef) || ((s = OBJ_nid2sn(n)) == NULL)) {
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02004603 i2t_ASN1_OBJECT(tmp, sizeof(tmp), obj);
Emeric Brun87855892012-10-17 17:39:35 +02004604 s = tmp;
4605 }
4606 ln = strlen(s);
4607
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02004608 l += 1 + ln + 1 + data_len;
Emeric Brun87855892012-10-17 17:39:35 +02004609 if (l > out->size)
4610 return -1;
4611 out->len = l;
4612
4613 *(p++)='/';
4614 memcpy(p, s, ln);
4615 p += ln;
4616 *(p++)='=';
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02004617 memcpy(p, data_ptr, data_len);
4618 p += data_len;
Emeric Brun87855892012-10-17 17:39:35 +02004619 }
4620
4621 if (!out->len)
4622 return 0;
4623
4624 return 1;
4625}
4626
David Safb76832014-05-08 23:42:08 -04004627char *ssl_sock_get_version(struct connection *conn)
4628{
4629 if (!ssl_sock_is_ssl(conn))
4630 return NULL;
4631
4632 return (char *)SSL_get_version(conn->xprt_ctx);
4633}
4634
Willy Tarreau119a4082016-12-22 21:58:38 +01004635/* Sets advertised SNI for outgoing connections. Please set <hostname> to NULL
4636 * to disable SNI.
4637 */
Willy Tarreau63076412015-07-10 11:33:32 +02004638void ssl_sock_set_servername(struct connection *conn, const char *hostname)
4639{
4640#ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME
Willy Tarreau119a4082016-12-22 21:58:38 +01004641 char *prev_name;
4642
Willy Tarreau63076412015-07-10 11:33:32 +02004643 if (!ssl_sock_is_ssl(conn))
4644 return;
4645
Willy Tarreau119a4082016-12-22 21:58:38 +01004646 /* if the SNI changes, we must destroy the reusable context so that a
4647 * new connection will present a new SNI. As an optimization we could
4648 * later imagine having a small cache of ssl_ctx to hold a few SNI per
4649 * server.
4650 */
4651 prev_name = (char *)SSL_get_servername(conn->xprt_ctx, TLSEXT_NAMETYPE_host_name);
4652 if ((!prev_name && hostname) ||
4653 (prev_name && (!hostname || strcmp(hostname, prev_name) != 0)))
4654 SSL_set_session(conn->xprt_ctx, NULL);
4655
Willy Tarreau63076412015-07-10 11:33:32 +02004656 SSL_set_tlsext_host_name(conn->xprt_ctx, hostname);
4657#endif
4658}
4659
Emeric Brun0abf8362014-06-24 18:26:41 +02004660/* Extract peer certificate's common name into the chunk dest
4661 * Returns
4662 * the len of the extracted common name
4663 * or 0 if no CN found in DN
4664 * or -1 on error case (i.e. no peer certificate)
4665 */
4666int ssl_sock_get_remote_common_name(struct connection *conn, struct chunk *dest)
David Safb76832014-05-08 23:42:08 -04004667{
4668 X509 *crt = NULL;
4669 X509_NAME *name;
David Safb76832014-05-08 23:42:08 -04004670 const char find_cn[] = "CN";
4671 const struct chunk find_cn_chunk = {
4672 .str = (char *)&find_cn,
4673 .len = sizeof(find_cn)-1
4674 };
Emeric Brun0abf8362014-06-24 18:26:41 +02004675 int result = -1;
David Safb76832014-05-08 23:42:08 -04004676
4677 if (!ssl_sock_is_ssl(conn))
Emeric Brun0abf8362014-06-24 18:26:41 +02004678 goto out;
David Safb76832014-05-08 23:42:08 -04004679
4680 /* SSL_get_peer_certificate, it increase X509 * ref count */
4681 crt = SSL_get_peer_certificate(conn->xprt_ctx);
4682 if (!crt)
4683 goto out;
4684
4685 name = X509_get_subject_name(crt);
4686 if (!name)
4687 goto out;
David Safb76832014-05-08 23:42:08 -04004688
Emeric Brun0abf8362014-06-24 18:26:41 +02004689 result = ssl_sock_get_dn_entry(name, &find_cn_chunk, 1, dest);
4690out:
David Safb76832014-05-08 23:42:08 -04004691 if (crt)
4692 X509_free(crt);
4693
4694 return result;
4695}
4696
Dave McCowan328fb582014-07-30 10:39:13 -04004697/* returns 1 if client passed a certificate for this session, 0 if not */
4698int ssl_sock_get_cert_used_sess(struct connection *conn)
4699{
4700 X509 *crt = NULL;
4701
4702 if (!ssl_sock_is_ssl(conn))
4703 return 0;
4704
4705 /* SSL_get_peer_certificate, it increase X509 * ref count */
4706 crt = SSL_get_peer_certificate(conn->xprt_ctx);
4707 if (!crt)
4708 return 0;
4709
4710 X509_free(crt);
4711 return 1;
4712}
4713
4714/* returns 1 if client passed a certificate for this connection, 0 if not */
4715int ssl_sock_get_cert_used_conn(struct connection *conn)
David Safb76832014-05-08 23:42:08 -04004716{
4717 if (!ssl_sock_is_ssl(conn))
4718 return 0;
4719
4720 return SSL_SOCK_ST_FL_VERIFY_DONE & conn->xprt_st ? 1 : 0;
4721}
4722
4723/* returns result from SSL verify */
4724unsigned int ssl_sock_get_verify_result(struct connection *conn)
4725{
4726 if (!ssl_sock_is_ssl(conn))
4727 return (unsigned int)X509_V_ERR_APPLICATION_VERIFICATION;
4728
4729 return (unsigned int)SSL_get_verify_result(conn->xprt_ctx);
4730}
4731
Willy Tarreau7875d092012-09-10 08:20:03 +02004732/***** Below are some sample fetching functions for ACL/patterns *****/
4733
Emeric Brune64aef12012-09-21 13:15:06 +02004734/* boolean, returns true if client cert was present */
4735static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02004736smp_fetch_ssl_fc_has_crt(const struct arg *args, struct sample *smp, const char *kw, void *private)
Emeric Brune64aef12012-09-21 13:15:06 +02004737{
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004738 struct connection *conn;
4739
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02004740 conn = objt_conn(smp->sess->origin);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004741 if (!conn || conn->xprt != &ssl_sock)
Emeric Brune64aef12012-09-21 13:15:06 +02004742 return 0;
4743
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004744 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brune64aef12012-09-21 13:15:06 +02004745 smp->flags |= SMP_F_MAY_CHANGE;
4746 return 0;
4747 }
4748
4749 smp->flags = 0;
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02004750 smp->data.type = SMP_T_BOOL;
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02004751 smp->data.u.sint = SSL_SOCK_ST_FL_VERIFY_DONE & conn->xprt_st ? 1 : 0;
Emeric Brune64aef12012-09-21 13:15:06 +02004752
4753 return 1;
4754}
4755
Emeric Brun43e79582014-10-29 19:03:26 +01004756/* binary, returns a certificate in a binary chunk (der/raw).
4757 * The 5th keyword char is used to know if SSL_get_certificate or SSL_get_peer_certificate
4758 * should be use.
4759 */
4760static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02004761smp_fetch_ssl_x_der(const struct arg *args, struct sample *smp, const char *kw, void *private)
Emeric Brun43e79582014-10-29 19:03:26 +01004762{
4763 int cert_peer = (kw[4] == 'c') ? 1 : 0;
4764 X509 *crt = NULL;
4765 int ret = 0;
4766 struct chunk *smp_trash;
4767 struct connection *conn;
4768
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02004769 conn = objt_conn(smp->sess->origin);
Emeric Brun43e79582014-10-29 19:03:26 +01004770 if (!conn || conn->xprt != &ssl_sock)
4771 return 0;
4772
4773 if (!(conn->flags & CO_FL_CONNECTED)) {
4774 smp->flags |= SMP_F_MAY_CHANGE;
4775 return 0;
4776 }
4777
4778 if (cert_peer)
4779 crt = SSL_get_peer_certificate(conn->xprt_ctx);
4780 else
4781 crt = SSL_get_certificate(conn->xprt_ctx);
4782
4783 if (!crt)
4784 goto out;
4785
4786 smp_trash = get_trash_chunk();
4787 if (ssl_sock_crt2der(crt, smp_trash) <= 0)
4788 goto out;
4789
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02004790 smp->data.u.str = *smp_trash;
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02004791 smp->data.type = SMP_T_BIN;
Emeric Brun43e79582014-10-29 19:03:26 +01004792 ret = 1;
4793out:
4794 /* SSL_get_peer_certificate, it increase X509 * ref count */
4795 if (cert_peer && crt)
4796 X509_free(crt);
4797 return ret;
4798}
4799
Emeric Brunba841a12014-04-30 17:05:08 +02004800/* binary, returns serial of certificate in a binary chunk.
4801 * The 5th keyword char is used to know if SSL_get_certificate or SSL_get_peer_certificate
4802 * should be use.
4803 */
Willy Tarreau8d598402012-10-22 17:58:39 +02004804static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02004805smp_fetch_ssl_x_serial(const struct arg *args, struct sample *smp, const char *kw, void *private)
Willy Tarreau8d598402012-10-22 17:58:39 +02004806{
Emeric Brunba841a12014-04-30 17:05:08 +02004807 int cert_peer = (kw[4] == 'c') ? 1 : 0;
Willy Tarreau8d598402012-10-22 17:58:39 +02004808 X509 *crt = NULL;
4809 int ret = 0;
4810 struct chunk *smp_trash;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004811 struct connection *conn;
4812
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02004813 conn = objt_conn(smp->sess->origin);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004814 if (!conn || conn->xprt != &ssl_sock)
Willy Tarreau8d598402012-10-22 17:58:39 +02004815 return 0;
4816
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004817 if (!(conn->flags & CO_FL_CONNECTED)) {
Willy Tarreau8d598402012-10-22 17:58:39 +02004818 smp->flags |= SMP_F_MAY_CHANGE;
4819 return 0;
4820 }
4821
Emeric Brunba841a12014-04-30 17:05:08 +02004822 if (cert_peer)
4823 crt = SSL_get_peer_certificate(conn->xprt_ctx);
4824 else
4825 crt = SSL_get_certificate(conn->xprt_ctx);
4826
Willy Tarreau8d598402012-10-22 17:58:39 +02004827 if (!crt)
4828 goto out;
4829
Willy Tarreau47ca5452012-12-23 20:22:19 +01004830 smp_trash = get_trash_chunk();
Willy Tarreau8d598402012-10-22 17:58:39 +02004831 if (ssl_sock_get_serial(crt, smp_trash) <= 0)
4832 goto out;
4833
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02004834 smp->data.u.str = *smp_trash;
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02004835 smp->data.type = SMP_T_BIN;
Willy Tarreau8d598402012-10-22 17:58:39 +02004836 ret = 1;
4837out:
Emeric Brunba841a12014-04-30 17:05:08 +02004838 /* SSL_get_peer_certificate, it increase X509 * ref count */
4839 if (cert_peer && crt)
Willy Tarreau8d598402012-10-22 17:58:39 +02004840 X509_free(crt);
4841 return ret;
4842}
Emeric Brune64aef12012-09-21 13:15:06 +02004843
Emeric Brunba841a12014-04-30 17:05:08 +02004844/* binary, returns the client certificate's SHA-1 fingerprint (SHA-1 hash of DER-encoded certificate) in a binary chunk.
4845 * The 5th keyword char is used to know if SSL_get_certificate or SSL_get_peer_certificate
4846 * should be use.
4847 */
James Votha051b4a2013-05-14 20:37:59 +02004848static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02004849smp_fetch_ssl_x_sha1(const struct arg *args, struct sample *smp, const char *kw, void *private)
James Votha051b4a2013-05-14 20:37:59 +02004850{
Emeric Brunba841a12014-04-30 17:05:08 +02004851 int cert_peer = (kw[4] == 'c') ? 1 : 0;
James Votha051b4a2013-05-14 20:37:59 +02004852 X509 *crt = NULL;
4853 const EVP_MD *digest;
4854 int ret = 0;
4855 struct chunk *smp_trash;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004856 struct connection *conn;
James Votha051b4a2013-05-14 20:37:59 +02004857
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02004858 conn = objt_conn(smp->sess->origin);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004859 if (!conn || conn->xprt != &ssl_sock)
4860 return 0;
4861
4862 if (!(conn->flags & CO_FL_CONNECTED)) {
James Votha051b4a2013-05-14 20:37:59 +02004863 smp->flags |= SMP_F_MAY_CHANGE;
4864 return 0;
4865 }
4866
Emeric Brunba841a12014-04-30 17:05:08 +02004867 if (cert_peer)
4868 crt = SSL_get_peer_certificate(conn->xprt_ctx);
4869 else
4870 crt = SSL_get_certificate(conn->xprt_ctx);
James Votha051b4a2013-05-14 20:37:59 +02004871 if (!crt)
4872 goto out;
4873
4874 smp_trash = get_trash_chunk();
4875 digest = EVP_sha1();
4876 X509_digest(crt, digest, (unsigned char *)smp_trash->str, (unsigned int *)&smp_trash->len);
4877
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02004878 smp->data.u.str = *smp_trash;
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02004879 smp->data.type = SMP_T_BIN;
James Votha051b4a2013-05-14 20:37:59 +02004880 ret = 1;
4881out:
Emeric Brunba841a12014-04-30 17:05:08 +02004882 /* SSL_get_peer_certificate, it increase X509 * ref count */
4883 if (cert_peer && crt)
James Votha051b4a2013-05-14 20:37:59 +02004884 X509_free(crt);
4885 return ret;
4886}
4887
Emeric Brunba841a12014-04-30 17:05:08 +02004888/* string, returns certificate's notafter date in ASN1_UTCTIME format.
4889 * The 5th keyword char is used to know if SSL_get_certificate or SSL_get_peer_certificate
4890 * should be use.
4891 */
Emeric Brunce5ad802012-10-22 14:11:22 +02004892static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02004893smp_fetch_ssl_x_notafter(const struct arg *args, struct sample *smp, const char *kw, void *private)
Emeric Brunce5ad802012-10-22 14:11:22 +02004894{
Emeric Brunba841a12014-04-30 17:05:08 +02004895 int cert_peer = (kw[4] == 'c') ? 1 : 0;
Emeric Brunce5ad802012-10-22 14:11:22 +02004896 X509 *crt = NULL;
4897 int ret = 0;
4898 struct chunk *smp_trash;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004899 struct connection *conn;
Emeric Brunce5ad802012-10-22 14:11:22 +02004900
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02004901 conn = objt_conn(smp->sess->origin);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004902 if (!conn || conn->xprt != &ssl_sock)
4903 return 0;
4904
4905 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brunce5ad802012-10-22 14:11:22 +02004906 smp->flags |= SMP_F_MAY_CHANGE;
4907 return 0;
4908 }
4909
Emeric Brunba841a12014-04-30 17:05:08 +02004910 if (cert_peer)
4911 crt = SSL_get_peer_certificate(conn->xprt_ctx);
4912 else
4913 crt = SSL_get_certificate(conn->xprt_ctx);
Emeric Brunce5ad802012-10-22 14:11:22 +02004914 if (!crt)
4915 goto out;
4916
Willy Tarreau47ca5452012-12-23 20:22:19 +01004917 smp_trash = get_trash_chunk();
Emeric Brunce5ad802012-10-22 14:11:22 +02004918 if (ssl_sock_get_time(X509_get_notAfter(crt), smp_trash) <= 0)
4919 goto out;
4920
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02004921 smp->data.u.str = *smp_trash;
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02004922 smp->data.type = SMP_T_STR;
Emeric Brunce5ad802012-10-22 14:11:22 +02004923 ret = 1;
4924out:
Emeric Brunba841a12014-04-30 17:05:08 +02004925 /* SSL_get_peer_certificate, it increase X509 * ref count */
4926 if (cert_peer && crt)
Emeric Brunce5ad802012-10-22 14:11:22 +02004927 X509_free(crt);
4928 return ret;
4929}
4930
Emeric Brunba841a12014-04-30 17:05:08 +02004931/* string, returns a string of a formatted full dn \C=..\O=..\OU=.. \CN=.. of certificate's issuer
4932 * The 5th keyword char is used to know if SSL_get_certificate or SSL_get_peer_certificate
4933 * should be use.
4934 */
Emeric Brun87855892012-10-17 17:39:35 +02004935static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02004936smp_fetch_ssl_x_i_dn(const struct arg *args, struct sample *smp, const char *kw, void *private)
Emeric Brun87855892012-10-17 17:39:35 +02004937{
Emeric Brunba841a12014-04-30 17:05:08 +02004938 int cert_peer = (kw[4] == 'c') ? 1 : 0;
Emeric Brun87855892012-10-17 17:39:35 +02004939 X509 *crt = NULL;
4940 X509_NAME *name;
4941 int ret = 0;
4942 struct chunk *smp_trash;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004943 struct connection *conn;
Emeric Brun87855892012-10-17 17:39:35 +02004944
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02004945 conn = objt_conn(smp->sess->origin);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004946 if (!conn || conn->xprt != &ssl_sock)
4947 return 0;
4948
4949 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brun87855892012-10-17 17:39:35 +02004950 smp->flags |= SMP_F_MAY_CHANGE;
4951 return 0;
4952 }
4953
Emeric Brunba841a12014-04-30 17:05:08 +02004954 if (cert_peer)
4955 crt = SSL_get_peer_certificate(conn->xprt_ctx);
4956 else
4957 crt = SSL_get_certificate(conn->xprt_ctx);
Emeric Brun87855892012-10-17 17:39:35 +02004958 if (!crt)
4959 goto out;
4960
4961 name = X509_get_issuer_name(crt);
4962 if (!name)
4963 goto out;
4964
Willy Tarreau47ca5452012-12-23 20:22:19 +01004965 smp_trash = get_trash_chunk();
Emeric Brun87855892012-10-17 17:39:35 +02004966 if (args && args[0].type == ARGT_STR) {
4967 int pos = 1;
4968
4969 if (args[1].type == ARGT_SINT)
4970 pos = args[1].data.sint;
Emeric Brun87855892012-10-17 17:39:35 +02004971
4972 if (ssl_sock_get_dn_entry(name, &args[0].data.str, pos, smp_trash) <= 0)
4973 goto out;
4974 }
4975 else if (ssl_sock_get_dn_oneline(name, smp_trash) <= 0)
4976 goto out;
4977
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02004978 smp->data.type = SMP_T_STR;
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02004979 smp->data.u.str = *smp_trash;
Emeric Brun87855892012-10-17 17:39:35 +02004980 ret = 1;
4981out:
Emeric Brunba841a12014-04-30 17:05:08 +02004982 /* SSL_get_peer_certificate, it increase X509 * ref count */
4983 if (cert_peer && crt)
Emeric Brun87855892012-10-17 17:39:35 +02004984 X509_free(crt);
4985 return ret;
4986}
4987
Emeric Brunba841a12014-04-30 17:05:08 +02004988/* string, returns notbefore date in ASN1_UTCTIME format.
4989 * The 5th keyword char is used to know if SSL_get_certificate or SSL_get_peer_certificate
4990 * should be use.
4991 */
Emeric Brunce5ad802012-10-22 14:11:22 +02004992static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02004993smp_fetch_ssl_x_notbefore(const struct arg *args, struct sample *smp, const char *kw, void *private)
Emeric Brunce5ad802012-10-22 14:11:22 +02004994{
Emeric Brunba841a12014-04-30 17:05:08 +02004995 int cert_peer = (kw[4] == 'c') ? 1 : 0;
Emeric Brunce5ad802012-10-22 14:11:22 +02004996 X509 *crt = NULL;
4997 int ret = 0;
4998 struct chunk *smp_trash;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004999 struct connection *conn;
5000
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02005001 conn = objt_conn(smp->sess->origin);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02005002 if (!conn || conn->xprt != &ssl_sock)
Emeric Brunce5ad802012-10-22 14:11:22 +02005003 return 0;
5004
Willy Tarreaub363a1f2013-10-01 10:45:07 +02005005 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brunce5ad802012-10-22 14:11:22 +02005006 smp->flags |= SMP_F_MAY_CHANGE;
5007 return 0;
5008 }
5009
Emeric Brunba841a12014-04-30 17:05:08 +02005010 if (cert_peer)
5011 crt = SSL_get_peer_certificate(conn->xprt_ctx);
5012 else
5013 crt = SSL_get_certificate(conn->xprt_ctx);
Emeric Brunce5ad802012-10-22 14:11:22 +02005014 if (!crt)
5015 goto out;
5016
Willy Tarreau47ca5452012-12-23 20:22:19 +01005017 smp_trash = get_trash_chunk();
Emeric Brunce5ad802012-10-22 14:11:22 +02005018 if (ssl_sock_get_time(X509_get_notBefore(crt), smp_trash) <= 0)
5019 goto out;
5020
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02005021 smp->data.u.str = *smp_trash;
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02005022 smp->data.type = SMP_T_STR;
Emeric Brunce5ad802012-10-22 14:11:22 +02005023 ret = 1;
5024out:
Emeric Brunba841a12014-04-30 17:05:08 +02005025 /* SSL_get_peer_certificate, it increase X509 * ref count */
5026 if (cert_peer && crt)
Emeric Brunce5ad802012-10-22 14:11:22 +02005027 X509_free(crt);
5028 return ret;
5029}
5030
Emeric Brunba841a12014-04-30 17:05:08 +02005031/* string, returns a string of a formatted full dn \C=..\O=..\OU=.. \CN=.. of certificate's subject
5032 * The 5th keyword char is used to know if SSL_get_certificate or SSL_get_peer_certificate
5033 * should be use.
5034 */
Emeric Brun87855892012-10-17 17:39:35 +02005035static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02005036smp_fetch_ssl_x_s_dn(const struct arg *args, struct sample *smp, const char *kw, void *private)
Emeric Brun87855892012-10-17 17:39:35 +02005037{
Emeric Brunba841a12014-04-30 17:05:08 +02005038 int cert_peer = (kw[4] == 'c') ? 1 : 0;
Emeric Brun87855892012-10-17 17:39:35 +02005039 X509 *crt = NULL;
5040 X509_NAME *name;
5041 int ret = 0;
5042 struct chunk *smp_trash;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02005043 struct connection *conn;
Emeric Brun87855892012-10-17 17:39:35 +02005044
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02005045 conn = objt_conn(smp->sess->origin);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02005046 if (!conn || conn->xprt != &ssl_sock)
5047 return 0;
5048
5049 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brun87855892012-10-17 17:39:35 +02005050 smp->flags |= SMP_F_MAY_CHANGE;
5051 return 0;
5052 }
5053
Emeric Brunba841a12014-04-30 17:05:08 +02005054 if (cert_peer)
5055 crt = SSL_get_peer_certificate(conn->xprt_ctx);
5056 else
5057 crt = SSL_get_certificate(conn->xprt_ctx);
Emeric Brun87855892012-10-17 17:39:35 +02005058 if (!crt)
5059 goto out;
5060
5061 name = X509_get_subject_name(crt);
5062 if (!name)
5063 goto out;
5064
Willy Tarreau47ca5452012-12-23 20:22:19 +01005065 smp_trash = get_trash_chunk();
Emeric Brun87855892012-10-17 17:39:35 +02005066 if (args && args[0].type == ARGT_STR) {
5067 int pos = 1;
5068
5069 if (args[1].type == ARGT_SINT)
5070 pos = args[1].data.sint;
Emeric Brun87855892012-10-17 17:39:35 +02005071
5072 if (ssl_sock_get_dn_entry(name, &args[0].data.str, pos, smp_trash) <= 0)
5073 goto out;
5074 }
5075 else if (ssl_sock_get_dn_oneline(name, smp_trash) <= 0)
5076 goto out;
5077
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02005078 smp->data.type = SMP_T_STR;
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02005079 smp->data.u.str = *smp_trash;
Emeric Brun87855892012-10-17 17:39:35 +02005080 ret = 1;
5081out:
Emeric Brunba841a12014-04-30 17:05:08 +02005082 /* SSL_get_peer_certificate, it increase X509 * ref count */
5083 if (cert_peer && crt)
Emeric Brun87855892012-10-17 17:39:35 +02005084 X509_free(crt);
5085 return ret;
5086}
Emeric Brun9143d372012-12-20 15:44:16 +01005087
5088/* integer, returns true if current session use a client certificate */
5089static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02005090smp_fetch_ssl_c_used(const struct arg *args, struct sample *smp, const char *kw, void *private)
Emeric Brun9143d372012-12-20 15:44:16 +01005091{
5092 X509 *crt;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02005093 struct connection *conn;
Emeric Brun9143d372012-12-20 15:44:16 +01005094
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02005095 conn = objt_conn(smp->sess->origin);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02005096 if (!conn || conn->xprt != &ssl_sock)
5097 return 0;
5098
5099 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brun9143d372012-12-20 15:44:16 +01005100 smp->flags |= SMP_F_MAY_CHANGE;
5101 return 0;
5102 }
5103
5104 /* SSL_get_peer_certificate returns a ptr on allocated X509 struct */
Willy Tarreaub363a1f2013-10-01 10:45:07 +02005105 crt = SSL_get_peer_certificate(conn->xprt_ctx);
Emeric Brun9143d372012-12-20 15:44:16 +01005106 if (crt) {
5107 X509_free(crt);
5108 }
5109
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02005110 smp->data.type = SMP_T_BOOL;
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02005111 smp->data.u.sint = (crt != NULL);
Emeric Brun9143d372012-12-20 15:44:16 +01005112 return 1;
5113}
5114
Emeric Brunba841a12014-04-30 17:05:08 +02005115/* integer, returns the certificate version
5116 * The 5th keyword char is used to know if SSL_get_certificate or SSL_get_peer_certificate
5117 * should be use.
5118 */
Emeric Bruna7359fd2012-10-17 15:03:11 +02005119static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02005120smp_fetch_ssl_x_version(const struct arg *args, struct sample *smp, const char *kw, void *private)
Emeric Bruna7359fd2012-10-17 15:03:11 +02005121{
Emeric Brunba841a12014-04-30 17:05:08 +02005122 int cert_peer = (kw[4] == 'c') ? 1 : 0;
Emeric Bruna7359fd2012-10-17 15:03:11 +02005123 X509 *crt;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02005124 struct connection *conn;
5125
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02005126 conn = objt_conn(smp->sess->origin);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02005127 if (!conn || conn->xprt != &ssl_sock)
Emeric Bruna7359fd2012-10-17 15:03:11 +02005128 return 0;
5129
Willy Tarreaub363a1f2013-10-01 10:45:07 +02005130 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Bruna7359fd2012-10-17 15:03:11 +02005131 smp->flags |= SMP_F_MAY_CHANGE;
5132 return 0;
5133 }
5134
Emeric Brunba841a12014-04-30 17:05:08 +02005135 if (cert_peer)
5136 crt = SSL_get_peer_certificate(conn->xprt_ctx);
5137 else
5138 crt = SSL_get_certificate(conn->xprt_ctx);
Emeric Bruna7359fd2012-10-17 15:03:11 +02005139 if (!crt)
5140 return 0;
5141
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02005142 smp->data.u.sint = (unsigned int)(1 + X509_get_version(crt));
Emeric Brunba841a12014-04-30 17:05:08 +02005143 /* SSL_get_peer_certificate increase X509 * ref count */
5144 if (cert_peer)
5145 X509_free(crt);
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02005146 smp->data.type = SMP_T_SINT;
Emeric Bruna7359fd2012-10-17 15:03:11 +02005147
5148 return 1;
5149}
5150
Emeric Brunba841a12014-04-30 17:05:08 +02005151/* string, returns the certificate's signature algorithm.
5152 * The 5th keyword char is used to know if SSL_get_certificate or SSL_get_peer_certificate
5153 * should be use.
5154 */
Emeric Brun7f56e742012-10-19 18:15:40 +02005155static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02005156smp_fetch_ssl_x_sig_alg(const struct arg *args, struct sample *smp, const char *kw, void *private)
Emeric Brun7f56e742012-10-19 18:15:40 +02005157{
Emeric Brunba841a12014-04-30 17:05:08 +02005158 int cert_peer = (kw[4] == 'c') ? 1 : 0;
Emeric Brun7f56e742012-10-19 18:15:40 +02005159 X509 *crt;
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02005160 __OPENSSL_110_CONST__ ASN1_OBJECT *algorithm;
Emeric Brun7f56e742012-10-19 18:15:40 +02005161 int nid;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02005162 struct connection *conn;
Emeric Brun7f56e742012-10-19 18:15:40 +02005163
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02005164 conn = objt_conn(smp->sess->origin);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02005165 if (!conn || conn->xprt != &ssl_sock)
5166 return 0;
5167
5168 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brun7f56e742012-10-19 18:15:40 +02005169 smp->flags |= SMP_F_MAY_CHANGE;
5170 return 0;
5171 }
5172
Emeric Brunba841a12014-04-30 17:05:08 +02005173 if (cert_peer)
5174 crt = SSL_get_peer_certificate(conn->xprt_ctx);
5175 else
5176 crt = SSL_get_certificate(conn->xprt_ctx);
Emeric Brun7f56e742012-10-19 18:15:40 +02005177 if (!crt)
5178 return 0;
5179
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02005180 X509_ALGOR_get0(&algorithm, NULL, NULL, X509_get0_tbs_sigalg(crt));
5181 nid = OBJ_obj2nid(algorithm);
Emeric Brun7f56e742012-10-19 18:15:40 +02005182
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02005183 smp->data.u.str.str = (char *)OBJ_nid2sn(nid);
5184 if (!smp->data.u.str.str) {
Emeric Brunba841a12014-04-30 17:05:08 +02005185 /* SSL_get_peer_certificate increase X509 * ref count */
5186 if (cert_peer)
5187 X509_free(crt);
Emeric Brun7f56e742012-10-19 18:15:40 +02005188 return 0;
Emeric Brun9bf3ba22013-10-07 14:31:44 +02005189 }
Emeric Brun7f56e742012-10-19 18:15:40 +02005190
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02005191 smp->data.type = SMP_T_STR;
Thierry FOURNIER7654c9f2013-12-17 00:20:33 +01005192 smp->flags |= SMP_F_CONST;
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02005193 smp->data.u.str.len = strlen(smp->data.u.str.str);
Emeric Brunba841a12014-04-30 17:05:08 +02005194 /* SSL_get_peer_certificate increase X509 * ref count */
5195 if (cert_peer)
5196 X509_free(crt);
Emeric Brun7f56e742012-10-19 18:15:40 +02005197
5198 return 1;
5199}
5200
Emeric Brunba841a12014-04-30 17:05:08 +02005201/* string, returns the certificate's key algorithm.
5202 * The 5th keyword char is used to know if SSL_get_certificate or SSL_get_peer_certificate
5203 * should be use.
5204 */
Emeric Brun521a0112012-10-22 12:22:55 +02005205static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02005206smp_fetch_ssl_x_key_alg(const struct arg *args, struct sample *smp, const char *kw, void *private)
Emeric Brun521a0112012-10-22 12:22:55 +02005207{
Emeric Brunba841a12014-04-30 17:05:08 +02005208 int cert_peer = (kw[4] == 'c') ? 1 : 0;
Emeric Brun521a0112012-10-22 12:22:55 +02005209 X509 *crt;
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02005210 ASN1_OBJECT *algorithm;
Emeric Brun521a0112012-10-22 12:22:55 +02005211 int nid;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02005212 struct connection *conn;
Emeric Brun521a0112012-10-22 12:22:55 +02005213
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02005214 conn = objt_conn(smp->sess->origin);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02005215 if (!conn || conn->xprt != &ssl_sock)
5216 return 0;
5217
5218 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brun521a0112012-10-22 12:22:55 +02005219 smp->flags |= SMP_F_MAY_CHANGE;
5220 return 0;
5221 }
5222
Emeric Brunba841a12014-04-30 17:05:08 +02005223 if (cert_peer)
5224 crt = SSL_get_peer_certificate(conn->xprt_ctx);
5225 else
5226 crt = SSL_get_certificate(conn->xprt_ctx);
Emeric Brun521a0112012-10-22 12:22:55 +02005227 if (!crt)
5228 return 0;
5229
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02005230 X509_PUBKEY_get0_param(&algorithm, NULL, NULL, NULL, X509_get_X509_PUBKEY(crt));
5231 nid = OBJ_obj2nid(algorithm);
Emeric Brun521a0112012-10-22 12:22:55 +02005232
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02005233 smp->data.u.str.str = (char *)OBJ_nid2sn(nid);
5234 if (!smp->data.u.str.str) {
Emeric Brunba841a12014-04-30 17:05:08 +02005235 /* SSL_get_peer_certificate increase X509 * ref count */
5236 if (cert_peer)
5237 X509_free(crt);
Emeric Brun521a0112012-10-22 12:22:55 +02005238 return 0;
Emeric Brun9bf3ba22013-10-07 14:31:44 +02005239 }
Emeric Brun521a0112012-10-22 12:22:55 +02005240
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02005241 smp->data.type = SMP_T_STR;
Thierry FOURNIER7654c9f2013-12-17 00:20:33 +01005242 smp->flags |= SMP_F_CONST;
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02005243 smp->data.u.str.len = strlen(smp->data.u.str.str);
Emeric Brunba841a12014-04-30 17:05:08 +02005244 if (cert_peer)
5245 X509_free(crt);
Emeric Brun521a0112012-10-22 12:22:55 +02005246
5247 return 1;
5248}
5249
Emeric Brun645ae792014-04-30 14:21:06 +02005250/* boolean, returns true if front conn. transport layer is SSL.
5251 * This function is also usable on backend conn if the fetch keyword 5th
5252 * char is 'b'.
5253 */
Willy Tarreau7875d092012-09-10 08:20:03 +02005254static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02005255smp_fetch_ssl_fc(const struct arg *args, struct sample *smp, const char *kw, void *private)
Willy Tarreau7875d092012-09-10 08:20:03 +02005256{
Willy Tarreaue237fe12016-03-10 17:05:28 +01005257 struct connection *conn = objt_conn((kw[4] != 'b') ? smp->sess->origin :
5258 smp->strm ? smp->strm->si[1].end : NULL);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02005259
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02005260 smp->data.type = SMP_T_BOOL;
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02005261 smp->data.u.sint = (conn && conn->xprt == &ssl_sock);
Willy Tarreau7875d092012-09-10 08:20:03 +02005262 return 1;
5263}
5264
Emeric Brun2525b6b2012-10-18 15:59:43 +02005265/* boolean, returns true if client present a SNI */
Willy Tarreau7875d092012-09-10 08:20:03 +02005266static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02005267smp_fetch_ssl_fc_has_sni(const struct arg *args, struct sample *smp, const char *kw, void *private)
Willy Tarreau7875d092012-09-10 08:20:03 +02005268{
5269#ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02005270 struct connection *conn = objt_conn(smp->sess->origin);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02005271
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02005272 smp->data.type = SMP_T_BOOL;
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02005273 smp->data.u.sint = (conn && conn->xprt == &ssl_sock) &&
Willy Tarreaub363a1f2013-10-01 10:45:07 +02005274 conn->xprt_ctx &&
5275 SSL_get_servername(conn->xprt_ctx, TLSEXT_NAMETYPE_host_name) != NULL;
Willy Tarreau7875d092012-09-10 08:20:03 +02005276 return 1;
5277#else
5278 return 0;
5279#endif
5280}
5281
Nenad Merdanovic26ea8222015-05-18 02:28:57 +02005282/* boolean, returns true if client session has been resumed */
5283static int
5284smp_fetch_ssl_fc_is_resumed(const struct arg *args, struct sample *smp, const char *kw, void *private)
5285{
5286 struct connection *conn = objt_conn(smp->sess->origin);
5287
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02005288 smp->data.type = SMP_T_BOOL;
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02005289 smp->data.u.sint = (conn && conn->xprt == &ssl_sock) &&
Nenad Merdanovic26ea8222015-05-18 02:28:57 +02005290 conn->xprt_ctx &&
5291 SSL_session_reused(conn->xprt_ctx);
5292 return 1;
5293}
5294
Emeric Brun645ae792014-04-30 14:21:06 +02005295/* string, returns the used cipher if front conn. transport layer is SSL.
5296 * This function is also usable on backend conn if the fetch keyword 5th
5297 * char is 'b'.
5298 */
Emeric Brun589fcad2012-10-16 14:13:26 +02005299static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02005300smp_fetch_ssl_fc_cipher(const struct arg *args, struct sample *smp, const char *kw, void *private)
Emeric Brun589fcad2012-10-16 14:13:26 +02005301{
Willy Tarreaue237fe12016-03-10 17:05:28 +01005302 struct connection *conn = objt_conn((kw[4] != 'b') ? smp->sess->origin :
5303 smp->strm ? smp->strm->si[1].end : NULL);
Emeric Brun589fcad2012-10-16 14:13:26 +02005304
Willy Tarreaube508f12016-03-10 11:47:01 +01005305 smp->flags = 0;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02005306 if (!conn || !conn->xprt_ctx || conn->xprt != &ssl_sock)
Emeric Brun589fcad2012-10-16 14:13:26 +02005307 return 0;
5308
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02005309 smp->data.u.str.str = (char *)SSL_get_cipher_name(conn->xprt_ctx);
5310 if (!smp->data.u.str.str)
Emeric Brun589fcad2012-10-16 14:13:26 +02005311 return 0;
5312
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02005313 smp->data.type = SMP_T_STR;
Thierry FOURNIER7654c9f2013-12-17 00:20:33 +01005314 smp->flags |= SMP_F_CONST;
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02005315 smp->data.u.str.len = strlen(smp->data.u.str.str);
Emeric Brun589fcad2012-10-16 14:13:26 +02005316
5317 return 1;
5318}
5319
Emeric Brun645ae792014-04-30 14:21:06 +02005320/* integer, returns the algoritm's keysize if front conn. transport layer
5321 * is SSL.
5322 * This function is also usable on backend conn if the fetch keyword 5th
5323 * char is 'b'.
5324 */
Emeric Brun589fcad2012-10-16 14:13:26 +02005325static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02005326smp_fetch_ssl_fc_alg_keysize(const struct arg *args, struct sample *smp, const char *kw, void *private)
Emeric Brun589fcad2012-10-16 14:13:26 +02005327{
Willy Tarreaue237fe12016-03-10 17:05:28 +01005328 struct connection *conn = objt_conn((kw[4] != 'b') ? smp->sess->origin :
5329 smp->strm ? smp->strm->si[1].end : NULL);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02005330
Willy Tarreaue237fe12016-03-10 17:05:28 +01005331 int sint;
Willy Tarreaube508f12016-03-10 11:47:01 +01005332
Emeric Brun589fcad2012-10-16 14:13:26 +02005333 smp->flags = 0;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02005334 if (!conn || !conn->xprt_ctx || conn->xprt != &ssl_sock)
Emeric Brun589fcad2012-10-16 14:13:26 +02005335 return 0;
5336
Thierry FOURNIER07ee64e2015-07-06 23:43:03 +02005337 if (!SSL_get_cipher_bits(conn->xprt_ctx, &sint))
Willy Tarreaub363a1f2013-10-01 10:45:07 +02005338 return 0;
5339
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02005340 smp->data.u.sint = sint;
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02005341 smp->data.type = SMP_T_SINT;
Emeric Brun589fcad2012-10-16 14:13:26 +02005342
5343 return 1;
5344}
5345
Emeric Brun645ae792014-04-30 14:21:06 +02005346/* integer, returns the used keysize if front conn. transport layer is SSL.
5347 * This function is also usable on backend conn if the fetch keyword 5th
5348 * char is 'b'.
5349 */
Emeric Brun589fcad2012-10-16 14:13:26 +02005350static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02005351smp_fetch_ssl_fc_use_keysize(const struct arg *args, struct sample *smp, const char *kw, void *private)
Emeric Brun589fcad2012-10-16 14:13:26 +02005352{
Willy Tarreaue237fe12016-03-10 17:05:28 +01005353 struct connection *conn = objt_conn((kw[4] != 'b') ? smp->sess->origin :
5354 smp->strm ? smp->strm->si[1].end : NULL);
Willy Tarreaube508f12016-03-10 11:47:01 +01005355
Emeric Brun589fcad2012-10-16 14:13:26 +02005356 smp->flags = 0;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02005357 if (!conn || !conn->xprt_ctx || conn->xprt != &ssl_sock)
5358 return 0;
5359
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02005360 smp->data.u.sint = (unsigned int)SSL_get_cipher_bits(conn->xprt_ctx, NULL);
5361 if (!smp->data.u.sint)
Emeric Brun589fcad2012-10-16 14:13:26 +02005362 return 0;
5363
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02005364 smp->data.type = SMP_T_SINT;
Emeric Brun589fcad2012-10-16 14:13:26 +02005365
5366 return 1;
5367}
5368
Willy Tarreau6c9a3d52012-10-18 18:57:14 +02005369#ifdef OPENSSL_NPN_NEGOTIATED
Willy Tarreau7875d092012-09-10 08:20:03 +02005370static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02005371smp_fetch_ssl_fc_npn(const struct arg *args, struct sample *smp, const char *kw, void *private)
Willy Tarreaua33c6542012-10-15 13:19:06 +02005372{
Willy Tarreaub363a1f2013-10-01 10:45:07 +02005373 struct connection *conn;
5374
Thierry FOURNIER7654c9f2013-12-17 00:20:33 +01005375 smp->flags = SMP_F_CONST;
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02005376 smp->data.type = SMP_T_STR;
Willy Tarreaua33c6542012-10-15 13:19:06 +02005377
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02005378 conn = objt_conn(smp->sess->origin);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02005379 if (!conn || !conn->xprt_ctx || conn->xprt != &ssl_sock)
5380 return 0;
5381
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02005382 smp->data.u.str.str = NULL;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02005383 SSL_get0_next_proto_negotiated(conn->xprt_ctx,
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02005384 (const unsigned char **)&smp->data.u.str.str, (unsigned *)&smp->data.u.str.len);
Willy Tarreaua33c6542012-10-15 13:19:06 +02005385
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02005386 if (!smp->data.u.str.str)
Willy Tarreaua33c6542012-10-15 13:19:06 +02005387 return 0;
5388
5389 return 1;
Willy Tarreaua33c6542012-10-15 13:19:06 +02005390}
Willy Tarreau6c9a3d52012-10-18 18:57:14 +02005391#endif
Willy Tarreaua33c6542012-10-15 13:19:06 +02005392
Dirkjan Bussink48f1c4e2014-02-13 12:29:42 +01005393#ifdef TLSEXT_TYPE_application_layer_protocol_negotiation
Willy Tarreauab861d32013-04-02 02:30:41 +02005394static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02005395smp_fetch_ssl_fc_alpn(const struct arg *args, struct sample *smp, const char *kw, void *private)
Willy Tarreauab861d32013-04-02 02:30:41 +02005396{
Willy Tarreaub363a1f2013-10-01 10:45:07 +02005397 struct connection *conn;
5398
Thierry FOURNIER7654c9f2013-12-17 00:20:33 +01005399 smp->flags = SMP_F_CONST;
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02005400 smp->data.type = SMP_T_STR;
Willy Tarreauab861d32013-04-02 02:30:41 +02005401
Willy Tarreaue26bf052015-05-12 10:30:12 +02005402 conn = objt_conn(smp->sess->origin);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02005403 if (!conn || !conn->xprt_ctx || conn->xprt != &ssl_sock)
Willy Tarreauab861d32013-04-02 02:30:41 +02005404 return 0;
5405
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02005406 smp->data.u.str.str = NULL;
Dirkjan Bussink48f1c4e2014-02-13 12:29:42 +01005407 SSL_get0_alpn_selected(conn->xprt_ctx,
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02005408 (const unsigned char **)&smp->data.u.str.str, (unsigned *)&smp->data.u.str.len);
Willy Tarreauab861d32013-04-02 02:30:41 +02005409
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02005410 if (!smp->data.u.str.str)
Willy Tarreauab861d32013-04-02 02:30:41 +02005411 return 0;
5412
5413 return 1;
5414}
5415#endif
5416
Emeric Brun645ae792014-04-30 14:21:06 +02005417/* string, returns the used protocol if front conn. transport layer is SSL.
5418 * This function is also usable on backend conn if the fetch keyword 5th
5419 * char is 'b'.
5420 */
Willy Tarreaua33c6542012-10-15 13:19:06 +02005421static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02005422smp_fetch_ssl_fc_protocol(const struct arg *args, struct sample *smp, const char *kw, void *private)
Emeric Brun589fcad2012-10-16 14:13:26 +02005423{
Willy Tarreaue237fe12016-03-10 17:05:28 +01005424 struct connection *conn = objt_conn((kw[4] != 'b') ? smp->sess->origin :
5425 smp->strm ? smp->strm->si[1].end : NULL);
Willy Tarreaube508f12016-03-10 11:47:01 +01005426
Emeric Brun589fcad2012-10-16 14:13:26 +02005427 smp->flags = 0;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02005428 if (!conn || !conn->xprt_ctx || conn->xprt != &ssl_sock)
5429 return 0;
5430
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02005431 smp->data.u.str.str = (char *)SSL_get_version(conn->xprt_ctx);
5432 if (!smp->data.u.str.str)
Emeric Brun589fcad2012-10-16 14:13:26 +02005433 return 0;
5434
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02005435 smp->data.type = SMP_T_STR;
Thierry FOURNIER7654c9f2013-12-17 00:20:33 +01005436 smp->flags = SMP_F_CONST;
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02005437 smp->data.u.str.len = strlen(smp->data.u.str.str);
Emeric Brun589fcad2012-10-16 14:13:26 +02005438
5439 return 1;
5440}
5441
Willy Tarreau87b09662015-04-03 00:22:06 +02005442/* binary, returns the SSL stream id if front conn. transport layer is SSL.
Emeric Brun645ae792014-04-30 14:21:06 +02005443 * This function is also usable on backend conn if the fetch keyword 5th
5444 * char is 'b'.
5445 */
Emeric Brun589fcad2012-10-16 14:13:26 +02005446static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02005447smp_fetch_ssl_fc_session_id(const struct arg *args, struct sample *smp, const char *kw, void *private)
Emeric Brunfe68f682012-10-16 14:59:28 +02005448{
5449#if OPENSSL_VERSION_NUMBER > 0x0090800fL
Willy Tarreaue237fe12016-03-10 17:05:28 +01005450 struct connection *conn = objt_conn((kw[4] != 'b') ? smp->sess->origin :
5451 smp->strm ? smp->strm->si[1].end : NULL);
Emeric Brunfe68f682012-10-16 14:59:28 +02005452
Willy Tarreaue237fe12016-03-10 17:05:28 +01005453 SSL_SESSION *ssl_sess;
Willy Tarreaube508f12016-03-10 11:47:01 +01005454
Thierry FOURNIER7654c9f2013-12-17 00:20:33 +01005455 smp->flags = SMP_F_CONST;
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02005456 smp->data.type = SMP_T_BIN;
Emeric Brunfe68f682012-10-16 14:59:28 +02005457
Willy Tarreaub363a1f2013-10-01 10:45:07 +02005458 if (!conn || !conn->xprt_ctx || conn->xprt != &ssl_sock)
5459 return 0;
5460
Willy Tarreau192252e2015-04-04 01:47:55 +02005461 ssl_sess = SSL_get_session(conn->xprt_ctx);
5462 if (!ssl_sess)
Emeric Brunfe68f682012-10-16 14:59:28 +02005463 return 0;
5464
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02005465 smp->data.u.str.str = (char *)SSL_SESSION_get_id(ssl_sess, (unsigned int *)&smp->data.u.str.len);
5466 if (!smp->data.u.str.str || !smp->data.u.str.len)
Emeric Brunfe68f682012-10-16 14:59:28 +02005467 return 0;
5468
5469 return 1;
5470#else
5471 return 0;
5472#endif
5473}
5474
5475static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02005476smp_fetch_ssl_fc_sni(const struct arg *args, struct sample *smp, const char *kw, void *private)
Willy Tarreau7875d092012-09-10 08:20:03 +02005477{
5478#ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME
Willy Tarreaub363a1f2013-10-01 10:45:07 +02005479 struct connection *conn;
5480
Thierry FOURNIER7654c9f2013-12-17 00:20:33 +01005481 smp->flags = SMP_F_CONST;
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02005482 smp->data.type = SMP_T_STR;
Willy Tarreau7875d092012-09-10 08:20:03 +02005483
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02005484 conn = objt_conn(smp->sess->origin);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02005485 if (!conn || !conn->xprt_ctx || conn->xprt != &ssl_sock)
5486 return 0;
5487
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02005488 smp->data.u.str.str = (char *)SSL_get_servername(conn->xprt_ctx, TLSEXT_NAMETYPE_host_name);
5489 if (!smp->data.u.str.str)
Willy Tarreau3e394c92012-09-14 23:56:58 +02005490 return 0;
5491
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02005492 smp->data.u.str.len = strlen(smp->data.u.str.str);
Willy Tarreau7875d092012-09-10 08:20:03 +02005493 return 1;
5494#else
5495 return 0;
5496#endif
5497}
5498
David Sc1ad52e2014-04-08 18:48:47 -04005499static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02005500smp_fetch_ssl_fc_unique_id(const struct arg *args, struct sample *smp, const char *kw, void *private)
David Sc1ad52e2014-04-08 18:48:47 -04005501{
5502#if OPENSSL_VERSION_NUMBER > 0x0090800fL
Willy Tarreaue237fe12016-03-10 17:05:28 +01005503 struct connection *conn = objt_conn((kw[4] != 'b') ? smp->sess->origin :
5504 smp->strm ? smp->strm->si[1].end : NULL);
5505
David Sc1ad52e2014-04-08 18:48:47 -04005506 int finished_len;
David Sc1ad52e2014-04-08 18:48:47 -04005507 struct chunk *finished_trash;
David Sc1ad52e2014-04-08 18:48:47 -04005508
5509 smp->flags = 0;
David Sc1ad52e2014-04-08 18:48:47 -04005510 if (!conn || !conn->xprt_ctx || conn->xprt != &ssl_sock)
5511 return 0;
5512
5513 if (!(conn->flags & CO_FL_CONNECTED)) {
5514 smp->flags |= SMP_F_MAY_CHANGE;
5515 return 0;
5516 }
5517
5518 finished_trash = get_trash_chunk();
5519 if (!SSL_session_reused(conn->xprt_ctx))
5520 finished_len = SSL_get_peer_finished(conn->xprt_ctx, finished_trash->str, finished_trash->size);
5521 else
5522 finished_len = SSL_get_finished(conn->xprt_ctx, finished_trash->str, finished_trash->size);
5523
5524 if (!finished_len)
5525 return 0;
5526
Emeric Brunb73a9b02014-04-30 18:49:19 +02005527 finished_trash->len = finished_len;
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02005528 smp->data.u.str = *finished_trash;
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02005529 smp->data.type = SMP_T_BIN;
David Sc1ad52e2014-04-08 18:48:47 -04005530
5531 return 1;
5532#else
5533 return 0;
5534#endif
5535}
5536
Emeric Brun2525b6b2012-10-18 15:59:43 +02005537/* integer, returns the first verify error in CA chain of client certificate chain. */
Emeric Brunf282a812012-09-21 15:27:54 +02005538static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02005539smp_fetch_ssl_c_ca_err(const struct arg *args, struct sample *smp, const char *kw, void *private)
Emeric Brunf282a812012-09-21 15:27:54 +02005540{
Willy Tarreaub363a1f2013-10-01 10:45:07 +02005541 struct connection *conn;
5542
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02005543 conn = objt_conn(smp->sess->origin);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02005544 if (!conn || conn->xprt != &ssl_sock)
5545 return 0;
5546
5547 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brunf282a812012-09-21 15:27:54 +02005548 smp->flags = SMP_F_MAY_CHANGE;
5549 return 0;
5550 }
5551
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02005552 smp->data.type = SMP_T_SINT;
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02005553 smp->data.u.sint = (unsigned long long int)SSL_SOCK_ST_TO_CA_ERROR(conn->xprt_st);
Emeric Brunf282a812012-09-21 15:27:54 +02005554 smp->flags = 0;
5555
5556 return 1;
5557}
5558
Emeric Brun2525b6b2012-10-18 15:59:43 +02005559/* integer, returns the depth of the first verify error in CA chain of client certificate chain. */
Emeric Brunf282a812012-09-21 15:27:54 +02005560static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02005561smp_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 +02005562{
Willy Tarreaub363a1f2013-10-01 10:45:07 +02005563 struct connection *conn;
5564
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02005565 conn = objt_conn(smp->sess->origin);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02005566 if (!conn || conn->xprt != &ssl_sock)
Emeric Brunf282a812012-09-21 15:27:54 +02005567 return 0;
5568
Willy Tarreaub363a1f2013-10-01 10:45:07 +02005569 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brunf282a812012-09-21 15:27:54 +02005570 smp->flags = SMP_F_MAY_CHANGE;
5571 return 0;
5572 }
5573
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02005574 smp->data.type = SMP_T_SINT;
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02005575 smp->data.u.sint = (long long int)SSL_SOCK_ST_TO_CAEDEPTH(conn->xprt_st);
Emeric Brunf282a812012-09-21 15:27:54 +02005576 smp->flags = 0;
5577
5578 return 1;
5579}
5580
Emeric Brun2525b6b2012-10-18 15:59:43 +02005581/* integer, returns the first verify error on client certificate */
Emeric Brunf282a812012-09-21 15:27:54 +02005582static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02005583smp_fetch_ssl_c_err(const struct arg *args, struct sample *smp, const char *kw, void *private)
Emeric Brunf282a812012-09-21 15:27:54 +02005584{
Willy Tarreaub363a1f2013-10-01 10:45:07 +02005585 struct connection *conn;
5586
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02005587 conn = objt_conn(smp->sess->origin);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02005588 if (!conn || conn->xprt != &ssl_sock)
5589 return 0;
5590
5591 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brunf282a812012-09-21 15:27:54 +02005592 smp->flags = SMP_F_MAY_CHANGE;
5593 return 0;
5594 }
5595
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02005596 smp->data.type = SMP_T_SINT;
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02005597 smp->data.u.sint = (long long int)SSL_SOCK_ST_TO_CRTERROR(conn->xprt_st);
Emeric Brunf282a812012-09-21 15:27:54 +02005598 smp->flags = 0;
5599
5600 return 1;
5601}
5602
Emeric Brun2525b6b2012-10-18 15:59:43 +02005603/* integer, returns the verify result on client cert */
Emeric Brunbaf8ffb2012-09-21 15:27:20 +02005604static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02005605smp_fetch_ssl_c_verify(const struct arg *args, struct sample *smp, const char *kw, void *private)
Emeric Brunbaf8ffb2012-09-21 15:27:20 +02005606{
Willy Tarreaub363a1f2013-10-01 10:45:07 +02005607 struct connection *conn;
5608
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02005609 conn = objt_conn(smp->sess->origin);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02005610 if (!conn || conn->xprt != &ssl_sock)
5611 return 0;
5612
5613 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brunbaf8ffb2012-09-21 15:27:20 +02005614 smp->flags = SMP_F_MAY_CHANGE;
5615 return 0;
5616 }
5617
Willy Tarreaub363a1f2013-10-01 10:45:07 +02005618 if (!conn->xprt_ctx)
Emeric Brunbaf8ffb2012-09-21 15:27:20 +02005619 return 0;
5620
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02005621 smp->data.type = SMP_T_SINT;
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02005622 smp->data.u.sint = (long long int)SSL_get_verify_result(conn->xprt_ctx);
Emeric Brunbaf8ffb2012-09-21 15:27:20 +02005623 smp->flags = 0;
5624
5625 return 1;
5626}
5627
Emeric Brunfb510ea2012-10-05 12:00:26 +02005628/* parse the "ca-file" bind keyword */
Emmanuel Hocdet98263292016-12-29 18:26:15 +01005629static 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 +02005630{
5631 if (!*args[cur_arg + 1]) {
5632 if (err)
5633 memprintf(err, "'%s' : missing CAfile path", args[cur_arg]);
5634 return ERR_ALERT | ERR_FATAL;
5635 }
5636
Willy Tarreauef934602016-12-22 23:12:01 +01005637 if ((*args[cur_arg + 1] != '/') && global_ssl.ca_base)
5638 memprintf(&conf->ca_file, "%s/%s", global_ssl.ca_base, args[cur_arg + 1]);
Emeric Brunef42d922012-10-11 16:11:36 +02005639 else
5640 memprintf(&conf->ca_file, "%s", args[cur_arg + 1]);
Emeric Brunc8e8d122012-10-02 18:42:10 +02005641
Emeric Brund94b3fe2012-09-20 18:23:56 +02005642 return 0;
5643}
Emmanuel Hocdet98263292016-12-29 18:26:15 +01005644static int bind_parse_ca_file(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
5645{
5646 return ssl_bind_parse_ca_file(args, cur_arg, px, &conf->ssl_conf, err);
5647}
Emeric Brund94b3fe2012-09-20 18:23:56 +02005648
Christopher Faulet31af49d2015-06-09 17:29:50 +02005649/* parse the "ca-sign-file" bind keyword */
5650static int bind_parse_ca_sign_file(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
5651{
5652 if (!*args[cur_arg + 1]) {
5653 if (err)
5654 memprintf(err, "'%s' : missing CAfile path", args[cur_arg]);
5655 return ERR_ALERT | ERR_FATAL;
5656 }
5657
Willy Tarreauef934602016-12-22 23:12:01 +01005658 if ((*args[cur_arg + 1] != '/') && global_ssl.ca_base)
5659 memprintf(&conf->ca_sign_file, "%s/%s", global_ssl.ca_base, args[cur_arg + 1]);
Christopher Faulet31af49d2015-06-09 17:29:50 +02005660 else
5661 memprintf(&conf->ca_sign_file, "%s", args[cur_arg + 1]);
5662
5663 return 0;
5664}
5665
Bertrand Jacquinff13c062016-11-13 16:37:11 +00005666/* parse the "ca-sign-pass" bind keyword */
Christopher Faulet31af49d2015-06-09 17:29:50 +02005667static int bind_parse_ca_sign_pass(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
5668{
5669 if (!*args[cur_arg + 1]) {
5670 if (err)
5671 memprintf(err, "'%s' : missing CAkey password", args[cur_arg]);
5672 return ERR_ALERT | ERR_FATAL;
5673 }
5674 memprintf(&conf->ca_sign_pass, "%s", args[cur_arg + 1]);
5675 return 0;
5676}
5677
Willy Tarreau79eeafa2012-09-14 07:53:05 +02005678/* parse the "ciphers" bind keyword */
Emmanuel Hocdet98263292016-12-29 18:26:15 +01005679static 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 +02005680{
5681 if (!*args[cur_arg + 1]) {
Willy Tarreaueb6cead2012-09-20 19:43:14 +02005682 memprintf(err, "'%s' : missing cipher suite", args[cur_arg]);
Willy Tarreau79eeafa2012-09-14 07:53:05 +02005683 return ERR_ALERT | ERR_FATAL;
5684 }
5685
Emeric Brun76d88952012-10-05 15:47:31 +02005686 free(conf->ciphers);
Willy Tarreau4348fad2012-09-20 16:48:07 +02005687 conf->ciphers = strdup(args[cur_arg + 1]);
Willy Tarreau79eeafa2012-09-14 07:53:05 +02005688 return 0;
5689}
Emmanuel Hocdet98263292016-12-29 18:26:15 +01005690static int bind_parse_ciphers(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
5691{
5692 return ssl_bind_parse_ciphers(args, cur_arg, px, &conf->ssl_conf, err);
5693}
Willy Tarreau79eeafa2012-09-14 07:53:05 +02005694/* parse the "crt" bind keyword */
Willy Tarreau4348fad2012-09-20 16:48:07 +02005695static 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 +02005696{
Willy Tarreau38011032013-08-13 16:59:39 +02005697 char path[MAXPATHLEN];
Willy Tarreaub75d6922014-04-14 18:05:41 +02005698
Willy Tarreau79eeafa2012-09-14 07:53:05 +02005699 if (!*args[cur_arg + 1]) {
Willy Tarreaueb6cead2012-09-20 19:43:14 +02005700 memprintf(err, "'%s' : missing certificate location", args[cur_arg]);
Willy Tarreau79eeafa2012-09-14 07:53:05 +02005701 return ERR_ALERT | ERR_FATAL;
5702 }
5703
Willy Tarreauef934602016-12-22 23:12:01 +01005704 if ((*args[cur_arg + 1] != '/' ) && global_ssl.crt_base) {
5705 if ((strlen(global_ssl.crt_base) + 1 + strlen(args[cur_arg + 1]) + 1) > MAXPATHLEN) {
Emeric Brunc8e8d122012-10-02 18:42:10 +02005706 memprintf(err, "'%s' : path too long", args[cur_arg]);
5707 return ERR_ALERT | ERR_FATAL;
5708 }
Willy Tarreauef934602016-12-22 23:12:01 +01005709 snprintf(path, sizeof(path), "%s/%s", global_ssl.crt_base, args[cur_arg + 1]);
Willy Tarreau03209342016-12-22 17:08:28 +01005710 if (ssl_sock_load_cert(path, conf, err) > 0)
Emeric Brunc8e8d122012-10-02 18:42:10 +02005711 return ERR_ALERT | ERR_FATAL;
5712
5713 return 0;
5714 }
5715
Willy Tarreau03209342016-12-22 17:08:28 +01005716 if (ssl_sock_load_cert(args[cur_arg + 1], conf, err) > 0)
Willy Tarreau79eeafa2012-09-14 07:53:05 +02005717 return ERR_ALERT | ERR_FATAL;
Emeric Brund94b3fe2012-09-20 18:23:56 +02005718
5719 return 0;
5720}
5721
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01005722/* parse the "crt-list" bind keyword */
5723static int bind_parse_crt_list(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
5724{
5725 if (!*args[cur_arg + 1]) {
5726 memprintf(err, "'%s' : missing certificate location", args[cur_arg]);
5727 return ERR_ALERT | ERR_FATAL;
5728 }
5729
Emmanuel Hocdet98263292016-12-29 18:26:15 +01005730 if (ssl_sock_load_cert_list_file(args[cur_arg + 1], conf, px, err) > 0) {
Willy Tarreauad1731d2013-04-02 17:35:58 +02005731 memprintf(err, "'%s' : %s", args[cur_arg], *err);
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01005732 return ERR_ALERT | ERR_FATAL;
Willy Tarreauad1731d2013-04-02 17:35:58 +02005733 }
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01005734
5735 return 0;
5736}
5737
Emeric Brunfb510ea2012-10-05 12:00:26 +02005738/* parse the "crl-file" bind keyword */
Emmanuel Hocdet98263292016-12-29 18:26:15 +01005739static 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 +02005740{
Emeric Brun051cdab2012-10-02 19:25:50 +02005741#ifndef X509_V_FLAG_CRL_CHECK
5742 if (err)
5743 memprintf(err, "'%s' : library does not support CRL verify", args[cur_arg]);
5744 return ERR_ALERT | ERR_FATAL;
5745#else
Emeric Brund94b3fe2012-09-20 18:23:56 +02005746 if (!*args[cur_arg + 1]) {
5747 if (err)
5748 memprintf(err, "'%s' : missing CRLfile path", args[cur_arg]);
5749 return ERR_ALERT | ERR_FATAL;
5750 }
Emeric Brun2b58d042012-09-20 17:10:03 +02005751
Willy Tarreauef934602016-12-22 23:12:01 +01005752 if ((*args[cur_arg + 1] != '/') && global_ssl.ca_base)
5753 memprintf(&conf->crl_file, "%s/%s", global_ssl.ca_base, args[cur_arg + 1]);
Emeric Brunef42d922012-10-11 16:11:36 +02005754 else
5755 memprintf(&conf->crl_file, "%s", args[cur_arg + 1]);
Emeric Brunc8e8d122012-10-02 18:42:10 +02005756
Emeric Brun2b58d042012-09-20 17:10:03 +02005757 return 0;
Emeric Brun051cdab2012-10-02 19:25:50 +02005758#endif
Emeric Brun2b58d042012-09-20 17:10:03 +02005759}
Emmanuel Hocdet98263292016-12-29 18:26:15 +01005760static int bind_parse_crl_file(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
5761{
5762 return ssl_bind_parse_crl_file(args, cur_arg, px, &conf->ssl_conf, err);
5763}
Emeric Brun2b58d042012-09-20 17:10:03 +02005764
Emmanuel Hocdete7f2b732017-01-09 16:15:54 +01005765/* parse the "curves" bind keyword keyword */
5766static int ssl_bind_parse_curves(char **args, int cur_arg, struct proxy *px, struct ssl_bind_conf *conf, char **err)
5767{
5768#if OPENSSL_VERSION_NUMBER >= 0x1000200fL
5769 if (!*args[cur_arg + 1]) {
5770 if (err)
5771 memprintf(err, "'%s' : missing curve suite", args[cur_arg]);
5772 return ERR_ALERT | ERR_FATAL;
5773 }
5774 conf->curves = strdup(args[cur_arg + 1]);
5775 return 0;
5776#else
5777 if (err)
5778 memprintf(err, "'%s' : library does not support curve suite", args[cur_arg]);
5779 return ERR_ALERT | ERR_FATAL;
5780#endif
5781}
5782static int bind_parse_curves(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
5783{
5784 return ssl_bind_parse_curves(args, cur_arg, px, &conf->ssl_conf, err);
5785}
5786
Bertrand Jacquinff13c062016-11-13 16:37:11 +00005787/* parse the "ecdhe" bind keyword keyword */
Emmanuel Hocdet98263292016-12-29 18:26:15 +01005788static 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 +02005789{
5790#if OPENSSL_VERSION_NUMBER < 0x0090800fL
5791 if (err)
5792 memprintf(err, "'%s' : library does not support elliptic curve Diffie-Hellman (too old)", args[cur_arg]);
5793 return ERR_ALERT | ERR_FATAL;
5794#elif defined(OPENSSL_NO_ECDH)
5795 if (err)
5796 memprintf(err, "'%s' : library does not support elliptic curve Diffie-Hellman (disabled via OPENSSL_NO_ECDH)", args[cur_arg]);
5797 return ERR_ALERT | ERR_FATAL;
5798#else
5799 if (!*args[cur_arg + 1]) {
5800 if (err)
5801 memprintf(err, "'%s' : missing named curve", args[cur_arg]);
5802 return ERR_ALERT | ERR_FATAL;
5803 }
5804
5805 conf->ecdhe = strdup(args[cur_arg + 1]);
Willy Tarreau79eeafa2012-09-14 07:53:05 +02005806
5807 return 0;
Emeric Brun2b58d042012-09-20 17:10:03 +02005808#endif
Willy Tarreau79eeafa2012-09-14 07:53:05 +02005809}
Emmanuel Hocdet98263292016-12-29 18:26:15 +01005810static int bind_parse_ecdhe(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
5811{
5812 return ssl_bind_parse_ecdhe(args, cur_arg, px, &conf->ssl_conf, err);
5813}
Willy Tarreau79eeafa2012-09-14 07:53:05 +02005814
Bertrand Jacquinff13c062016-11-13 16:37:11 +00005815/* parse the "crt-ignore-err" and "ca-ignore-err" bind keywords */
Emeric Brun81c00f02012-09-21 14:31:21 +02005816static int bind_parse_ignore_err(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
5817{
5818 int code;
5819 char *p = args[cur_arg + 1];
5820 unsigned long long *ignerr = &conf->crt_ignerr;
5821
5822 if (!*p) {
5823 if (err)
5824 memprintf(err, "'%s' : missing error IDs list", args[cur_arg]);
5825 return ERR_ALERT | ERR_FATAL;
5826 }
5827
5828 if (strcmp(args[cur_arg], "ca-ignore-err") == 0)
5829 ignerr = &conf->ca_ignerr;
5830
5831 if (strcmp(p, "all") == 0) {
5832 *ignerr = ~0ULL;
5833 return 0;
5834 }
5835
5836 while (p) {
5837 code = atoi(p);
5838 if ((code <= 0) || (code > 63)) {
5839 if (err)
5840 memprintf(err, "'%s' : ID '%d' out of range (1..63) in error IDs list '%s'",
5841 args[cur_arg], code, args[cur_arg + 1]);
5842 return ERR_ALERT | ERR_FATAL;
5843 }
5844 *ignerr |= 1ULL << code;
5845 p = strchr(p, ',');
5846 if (p)
5847 p++;
5848 }
5849
Emeric Brun2cb7ae52012-10-05 14:14:21 +02005850 return 0;
5851}
5852
5853/* parse the "force-sslv3" bind keyword */
Emmanuel Hocdet98263292016-12-29 18:26:15 +01005854static int ssl_bind_parse_force_sslv3(char **args, int cur_arg, struct proxy *px, struct ssl_bind_conf *conf, char **err)
Emeric Brun2cb7ae52012-10-05 14:14:21 +02005855{
5856 conf->ssl_options |= BC_SSL_O_USE_SSLV3;
5857 return 0;
5858}
Emmanuel Hocdet98263292016-12-29 18:26:15 +01005859static int bind_parse_force_sslv3(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
5860{
5861 return ssl_bind_parse_force_sslv3(args, cur_arg, px, &conf->ssl_conf, err);
5862}
Emeric Brun2cb7ae52012-10-05 14:14:21 +02005863
5864/* parse the "force-tlsv10" bind keyword */
Emmanuel Hocdet98263292016-12-29 18:26:15 +01005865static int ssl_bind_parse_force_tlsv10(char **args, int cur_arg, struct proxy *px, struct ssl_bind_conf *conf, char **err)
Emeric Brun2cb7ae52012-10-05 14:14:21 +02005866{
5867 conf->ssl_options |= BC_SSL_O_USE_TLSV10;
Emeric Brun2d0c4822012-10-02 13:45:20 +02005868 return 0;
5869}
Emmanuel Hocdet98263292016-12-29 18:26:15 +01005870static int bind_parse_force_tlsv10(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
5871{
5872 return ssl_bind_parse_force_tlsv10(args, cur_arg, px, &conf->ssl_conf, err);
5873}
Emeric Brun2d0c4822012-10-02 13:45:20 +02005874
Emeric Brun2cb7ae52012-10-05 14:14:21 +02005875/* parse the "force-tlsv11" bind keyword */
Emmanuel Hocdet98263292016-12-29 18:26:15 +01005876static int ssl_bind_parse_force_tlsv11(char **args, int cur_arg, struct proxy *px, struct ssl_bind_conf *conf, char **err)
Emeric Brun2cb7ae52012-10-05 14:14:21 +02005877{
5878#if SSL_OP_NO_TLSv1_1
5879 conf->ssl_options |= BC_SSL_O_USE_TLSV11;
5880 return 0;
5881#else
5882 if (err)
5883 memprintf(err, "'%s' : library does not support protocol TLSv1.1", args[cur_arg]);
5884 return ERR_ALERT | ERR_FATAL;
5885#endif
5886}
Emmanuel Hocdet98263292016-12-29 18:26:15 +01005887static int bind_parse_force_tlsv11(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
5888{
5889 return ssl_bind_parse_force_tlsv11(args, cur_arg, px, &conf->ssl_conf, err);
5890}
Emeric Brun2cb7ae52012-10-05 14:14:21 +02005891
5892/* parse the "force-tlsv12" bind keyword */
Emmanuel Hocdet98263292016-12-29 18:26:15 +01005893static int ssl_bind_parse_force_tlsv12(char **args, int cur_arg, struct proxy *px, struct ssl_bind_conf *conf, char **err)
Emeric Brun2cb7ae52012-10-05 14:14:21 +02005894{
5895#if SSL_OP_NO_TLSv1_2
5896 conf->ssl_options |= BC_SSL_O_USE_TLSV12;
5897 return 0;
5898#else
5899 if (err)
5900 memprintf(err, "'%s' : library does not support protocol TLSv1.2", args[cur_arg]);
5901 return ERR_ALERT | ERR_FATAL;
5902#endif
5903}
Emmanuel Hocdet98263292016-12-29 18:26:15 +01005904static int bind_parse_force_tlsv12(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
5905{
5906 return ssl_bind_parse_force_tlsv12(args, cur_arg, px, &conf->ssl_conf, err);
5907}
Emeric Brun2cb7ae52012-10-05 14:14:21 +02005908
Emeric Brun2d0c4822012-10-02 13:45:20 +02005909/* parse the "no-tls-tickets" bind keyword */
Emmanuel Hocdet98263292016-12-29 18:26:15 +01005910static int ssl_bind_parse_no_tls_tickets(char **args, int cur_arg, struct proxy *px, struct ssl_bind_conf *conf, char **err)
Emeric Brun2d0c4822012-10-02 13:45:20 +02005911{
Emeric Brun89675492012-10-05 13:48:26 +02005912 conf->ssl_options |= BC_SSL_O_NO_TLS_TICKETS;
Emeric Brun81c00f02012-09-21 14:31:21 +02005913 return 0;
5914}
Emmanuel Hocdet98263292016-12-29 18:26:15 +01005915static int bind_parse_no_tls_tickets(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
5916{
5917 return ssl_bind_parse_no_tls_tickets(args, cur_arg, px, &conf->ssl_conf, err);
5918}
Emeric Brun2d0c4822012-10-02 13:45:20 +02005919
Emeric Brun9b3009b2012-10-05 11:55:06 +02005920/* parse the "no-sslv3" bind keyword */
Emmanuel Hocdet98263292016-12-29 18:26:15 +01005921static int ssl_bind_parse_no_sslv3(char **args, int cur_arg, struct proxy *px, struct ssl_bind_conf *conf, char **err)
Willy Tarreau79eeafa2012-09-14 07:53:05 +02005922{
Emeric Brun89675492012-10-05 13:48:26 +02005923 conf->ssl_options |= BC_SSL_O_NO_SSLV3;
Willy Tarreau79eeafa2012-09-14 07:53:05 +02005924 return 0;
5925}
Emmanuel Hocdet98263292016-12-29 18:26:15 +01005926static int bind_parse_no_sslv3(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
5927{
5928 return ssl_bind_parse_no_sslv3(args, cur_arg, px, &conf->ssl_conf, err);
5929}
Willy Tarreau79eeafa2012-09-14 07:53:05 +02005930
Emeric Brun9b3009b2012-10-05 11:55:06 +02005931/* parse the "no-tlsv10" bind keyword */
Emmanuel Hocdet98263292016-12-29 18:26:15 +01005932static int ssl_bind_parse_no_tlsv10(char **args, int cur_arg, struct proxy *px, struct ssl_bind_conf *conf, char **err)
Emeric Brunc0ff4922012-09-28 19:37:02 +02005933{
Emeric Brun89675492012-10-05 13:48:26 +02005934 conf->ssl_options |= BC_SSL_O_NO_TLSV10;
Emeric Brunc0ff4922012-09-28 19:37:02 +02005935 return 0;
5936}
Emmanuel Hocdet98263292016-12-29 18:26:15 +01005937static int bind_parse_no_tlsv10(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
5938{
5939 return ssl_bind_parse_no_tlsv10(args, cur_arg, px, &conf->ssl_conf, err);
5940}
Emeric Brunc0ff4922012-09-28 19:37:02 +02005941
Emeric Brun9b3009b2012-10-05 11:55:06 +02005942/* parse the "no-tlsv11" bind keyword */
Emmanuel Hocdet98263292016-12-29 18:26:15 +01005943static int ssl_bind_parse_no_tlsv11(char **args, int cur_arg, struct proxy *px, struct ssl_bind_conf *conf, char **err)
Emeric Brunc0ff4922012-09-28 19:37:02 +02005944{
Emeric Brun89675492012-10-05 13:48:26 +02005945 conf->ssl_options |= BC_SSL_O_NO_TLSV11;
Emeric Brunc0ff4922012-09-28 19:37:02 +02005946 return 0;
5947}
Emmanuel Hocdet98263292016-12-29 18:26:15 +01005948static int bind_parse_no_tlsv11(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
5949{
5950 return ssl_bind_parse_no_tlsv11(args, cur_arg, px, &conf->ssl_conf, err);
5951}
Emeric Brunc0ff4922012-09-28 19:37:02 +02005952
Emeric Brun9b3009b2012-10-05 11:55:06 +02005953/* parse the "no-tlsv12" bind keyword */
Emmanuel Hocdet98263292016-12-29 18:26:15 +01005954static int ssl_bind_parse_no_tlsv12(char **args, int cur_arg, struct proxy *px, struct ssl_bind_conf *conf, char **err)
Willy Tarreau79eeafa2012-09-14 07:53:05 +02005955{
Emeric Brun89675492012-10-05 13:48:26 +02005956 conf->ssl_options |= BC_SSL_O_NO_TLSV12;
Willy Tarreau79eeafa2012-09-14 07:53:05 +02005957 return 0;
5958}
Emmanuel Hocdet98263292016-12-29 18:26:15 +01005959static int bind_parse_no_tlsv12(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
5960{
5961 return ssl_bind_parse_no_tlsv12(args, cur_arg, px, &conf->ssl_conf, err);
5962}
Willy Tarreau79eeafa2012-09-14 07:53:05 +02005963
Willy Tarreau6c9a3d52012-10-18 18:57:14 +02005964/* parse the "npn" bind keyword */
Emmanuel Hocdet98263292016-12-29 18:26:15 +01005965static 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 +02005966{
5967#ifdef OPENSSL_NPN_NEGOTIATED
5968 char *p1, *p2;
5969
5970 if (!*args[cur_arg + 1]) {
5971 memprintf(err, "'%s' : missing the comma-delimited NPN protocol suite", args[cur_arg]);
5972 return ERR_ALERT | ERR_FATAL;
5973 }
5974
5975 free(conf->npn_str);
5976
Willy Tarreau3724da12016-02-12 17:11:12 +01005977 /* the NPN string is built as a suite of (<len> <name>)*,
5978 * so we reuse each comma to store the next <len> and need
5979 * one more for the end of the string.
5980 */
Willy Tarreau6c9a3d52012-10-18 18:57:14 +02005981 conf->npn_len = strlen(args[cur_arg + 1]) + 1;
Willy Tarreau3724da12016-02-12 17:11:12 +01005982 conf->npn_str = calloc(1, conf->npn_len + 1);
Willy Tarreau6c9a3d52012-10-18 18:57:14 +02005983 memcpy(conf->npn_str + 1, args[cur_arg + 1], conf->npn_len);
5984
5985 /* replace commas with the name length */
5986 p1 = conf->npn_str;
5987 p2 = p1 + 1;
5988 while (1) {
5989 p2 = memchr(p1 + 1, ',', conf->npn_str + conf->npn_len - (p1 + 1));
5990 if (!p2)
5991 p2 = p1 + 1 + strlen(p1 + 1);
5992
5993 if (p2 - (p1 + 1) > 255) {
5994 *p2 = '\0';
5995 memprintf(err, "'%s' : NPN protocol name too long : '%s'", args[cur_arg], p1 + 1);
5996 return ERR_ALERT | ERR_FATAL;
5997 }
5998
5999 *p1 = p2 - (p1 + 1);
6000 p1 = p2;
6001
6002 if (!*p2)
6003 break;
6004
6005 *(p2++) = '\0';
6006 }
6007 return 0;
6008#else
6009 if (err)
6010 memprintf(err, "'%s' : library does not support TLS NPN extension", args[cur_arg]);
6011 return ERR_ALERT | ERR_FATAL;
6012#endif
6013}
6014
Emmanuel Hocdet98263292016-12-29 18:26:15 +01006015static int bind_parse_npn(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
6016{
6017 return ssl_bind_parse_npn(args, cur_arg, px, &conf->ssl_conf, err);
6018}
6019
Willy Tarreauab861d32013-04-02 02:30:41 +02006020/* parse the "alpn" bind keyword */
Emmanuel Hocdet98263292016-12-29 18:26:15 +01006021static 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 +02006022{
Dirkjan Bussink48f1c4e2014-02-13 12:29:42 +01006023#ifdef TLSEXT_TYPE_application_layer_protocol_negotiation
Willy Tarreauab861d32013-04-02 02:30:41 +02006024 char *p1, *p2;
6025
6026 if (!*args[cur_arg + 1]) {
6027 memprintf(err, "'%s' : missing the comma-delimited ALPN protocol suite", args[cur_arg]);
6028 return ERR_ALERT | ERR_FATAL;
6029 }
6030
6031 free(conf->alpn_str);
6032
Marcoen Hirschbergbef60912016-02-12 17:05:24 +01006033 /* the ALPN string is built as a suite of (<len> <name>)*,
6034 * so we reuse each comma to store the next <len> and need
6035 * one more for the end of the string.
6036 */
Willy Tarreauab861d32013-04-02 02:30:41 +02006037 conf->alpn_len = strlen(args[cur_arg + 1]) + 1;
Marcoen Hirschbergbef60912016-02-12 17:05:24 +01006038 conf->alpn_str = calloc(1, conf->alpn_len + 1);
Willy Tarreauab861d32013-04-02 02:30:41 +02006039 memcpy(conf->alpn_str + 1, args[cur_arg + 1], conf->alpn_len);
6040
6041 /* replace commas with the name length */
6042 p1 = conf->alpn_str;
6043 p2 = p1 + 1;
6044 while (1) {
6045 p2 = memchr(p1 + 1, ',', conf->alpn_str + conf->alpn_len - (p1 + 1));
6046 if (!p2)
6047 p2 = p1 + 1 + strlen(p1 + 1);
6048
6049 if (p2 - (p1 + 1) > 255) {
6050 *p2 = '\0';
6051 memprintf(err, "'%s' : ALPN protocol name too long : '%s'", args[cur_arg], p1 + 1);
6052 return ERR_ALERT | ERR_FATAL;
6053 }
6054
6055 *p1 = p2 - (p1 + 1);
6056 p1 = p2;
6057
6058 if (!*p2)
6059 break;
6060
6061 *(p2++) = '\0';
6062 }
6063 return 0;
6064#else
6065 if (err)
6066 memprintf(err, "'%s' : library does not support TLS ALPN extension", args[cur_arg]);
6067 return ERR_ALERT | ERR_FATAL;
6068#endif
6069}
6070
Emmanuel Hocdet98263292016-12-29 18:26:15 +01006071static int bind_parse_alpn(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
6072{
6073 return ssl_bind_parse_alpn(args, cur_arg, px, &conf->ssl_conf, err);
6074}
6075
Willy Tarreau79eeafa2012-09-14 07:53:05 +02006076/* parse the "ssl" bind keyword */
Willy Tarreau4348fad2012-09-20 16:48:07 +02006077static 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 +02006078{
Willy Tarreau71a8c7c2016-12-21 22:04:54 +01006079 conf->xprt = &ssl_sock;
Willy Tarreau4348fad2012-09-20 16:48:07 +02006080 conf->is_ssl = 1;
Emeric Brun76d88952012-10-05 15:47:31 +02006081
Emmanuel Hocdet98263292016-12-29 18:26:15 +01006082 if (global_ssl.listen_default_ciphers && !conf->ssl_conf.ciphers)
6083 conf->ssl_conf.ciphers = strdup(global_ssl.listen_default_ciphers);
6084 conf->ssl_conf.ssl_options |= global_ssl.listen_default_ssloptions;
Emeric Brun76d88952012-10-05 15:47:31 +02006085
Willy Tarreau79eeafa2012-09-14 07:53:05 +02006086 return 0;
6087}
6088
Christopher Faulet31af49d2015-06-09 17:29:50 +02006089/* parse the "generate-certificates" bind keyword */
6090static int bind_parse_generate_certs(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
6091{
Emmanuel Hocdetfdec7892017-01-13 17:48:18 +01006092#if (defined SSL_CTRL_SET_TLSEXT_HOSTNAME && !defined SSL_NO_GENERATE_CERTIFICATES)
Christopher Faulet31af49d2015-06-09 17:29:50 +02006093 conf->generate_certs = 1;
6094#else
6095 memprintf(err, "%sthis version of openssl cannot generate SSL certificates.\n",
6096 err && *err ? *err : "");
6097#endif
6098 return 0;
6099}
6100
Emmanuel Hocdet65623372013-01-24 17:17:15 +01006101/* parse the "strict-sni" bind keyword */
6102static int bind_parse_strict_sni(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
6103{
6104 conf->strict_sni = 1;
6105 return 0;
Nenad Merdanovic05552d42015-02-27 19:56:49 +01006106}
6107
6108/* parse the "tls-ticket-keys" bind keyword */
6109static int bind_parse_tls_ticket_keys(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
6110{
6111#if (defined SSL_CTRL_SET_TLSEXT_TICKET_KEY_CB && TLS_TICKETS_NO > 0)
6112 FILE *f;
6113 int i = 0;
6114 char thisline[LINESIZE];
Nenad Merdanovic146defa2015-05-09 08:46:00 +02006115 struct tls_keys_ref *keys_ref;
Nenad Merdanovic05552d42015-02-27 19:56:49 +01006116
6117 if (!*args[cur_arg + 1]) {
6118 if (err)
6119 memprintf(err, "'%s' : missing TLS ticket keys file path", args[cur_arg]);
6120 return ERR_ALERT | ERR_FATAL;
6121 }
6122
Nenad Merdanovic200b0fa2015-05-09 08:46:01 +02006123 keys_ref = tlskeys_ref_lookup(args[cur_arg + 1]);
6124 if(keys_ref) {
6125 conf->keys_ref = keys_ref;
6126 return 0;
6127 }
6128
Vincent Bernat02779b62016-04-03 13:48:43 +02006129 keys_ref = malloc(sizeof(*keys_ref));
Nenad Merdanovic146defa2015-05-09 08:46:00 +02006130 keys_ref->tlskeys = malloc(TLS_TICKETS_NO * sizeof(struct tls_sess_key));
Nenad Merdanovic05552d42015-02-27 19:56:49 +01006131
6132 if ((f = fopen(args[cur_arg + 1], "r")) == NULL) {
6133 if (err)
6134 memprintf(err, "'%s' : unable to load ssl tickets keys file", args[cur_arg+1]);
6135 return ERR_ALERT | ERR_FATAL;
6136 }
6137
Nenad Merdanovic146defa2015-05-09 08:46:00 +02006138 keys_ref->filename = strdup(args[cur_arg + 1]);
6139
Nenad Merdanovic05552d42015-02-27 19:56:49 +01006140 while (fgets(thisline, sizeof(thisline), f) != NULL) {
6141 int len = strlen(thisline);
6142 /* Strip newline characters from the end */
6143 if(thisline[len - 1] == '\n')
6144 thisline[--len] = 0;
6145
6146 if(thisline[len - 1] == '\r')
6147 thisline[--len] = 0;
6148
Nenad Merdanovic146defa2015-05-09 08:46:00 +02006149 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 +01006150 if (err)
6151 memprintf(err, "'%s' : unable to decode base64 key on line %d", args[cur_arg+1], i + 1);
mildis16aa0152016-06-22 17:46:29 +02006152 fclose(f);
Nenad Merdanovic05552d42015-02-27 19:56:49 +01006153 return ERR_ALERT | ERR_FATAL;
6154 }
6155 i++;
6156 }
6157
6158 if (i < TLS_TICKETS_NO) {
6159 if (err)
6160 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 +02006161 fclose(f);
Nenad Merdanovic05552d42015-02-27 19:56:49 +01006162 return ERR_ALERT | ERR_FATAL;
6163 }
6164
6165 fclose(f);
6166
6167 /* Use penultimate key for encryption, handle when TLS_TICKETS_NO = 1 */
Nenad Merdanovic17891152016-03-25 22:16:57 +01006168 i -= 2;
6169 keys_ref->tls_ticket_enc_index = i < 0 ? 0 : i % TLS_TICKETS_NO;
Nenad Merdanovic200b0fa2015-05-09 08:46:01 +02006170 keys_ref->unique_id = -1;
Nenad Merdanovic146defa2015-05-09 08:46:00 +02006171 conf->keys_ref = keys_ref;
Nenad Merdanovic05552d42015-02-27 19:56:49 +01006172
Nenad Merdanovic200b0fa2015-05-09 08:46:01 +02006173 LIST_ADD(&tlskeys_reference, &keys_ref->list);
6174
Nenad Merdanovic05552d42015-02-27 19:56:49 +01006175 return 0;
6176#else
6177 if (err)
6178 memprintf(err, "'%s' : TLS ticket callback extension not supported", args[cur_arg]);
6179 return ERR_ALERT | ERR_FATAL;
6180#endif /* SSL_CTRL_SET_TLSEXT_TICKET_KEY_CB */
Emmanuel Hocdet65623372013-01-24 17:17:15 +01006181}
6182
Emeric Brund94b3fe2012-09-20 18:23:56 +02006183/* parse the "verify" bind keyword */
Emmanuel Hocdet98263292016-12-29 18:26:15 +01006184static 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 +02006185{
6186 if (!*args[cur_arg + 1]) {
6187 if (err)
6188 memprintf(err, "'%s' : missing verify method", args[cur_arg]);
6189 return ERR_ALERT | ERR_FATAL;
6190 }
6191
6192 if (strcmp(args[cur_arg + 1], "none") == 0)
Emeric Brun850efd52014-01-29 12:24:34 +01006193 conf->verify = SSL_SOCK_VERIFY_NONE;
Emeric Brund94b3fe2012-09-20 18:23:56 +02006194 else if (strcmp(args[cur_arg + 1], "optional") == 0)
Emeric Brun850efd52014-01-29 12:24:34 +01006195 conf->verify = SSL_SOCK_VERIFY_OPTIONAL;
Emeric Brund94b3fe2012-09-20 18:23:56 +02006196 else if (strcmp(args[cur_arg + 1], "required") == 0)
Emeric Brun850efd52014-01-29 12:24:34 +01006197 conf->verify = SSL_SOCK_VERIFY_REQUIRED;
Emeric Brund94b3fe2012-09-20 18:23:56 +02006198 else {
6199 if (err)
6200 memprintf(err, "'%s' : unknown verify method '%s', only 'none', 'optional', and 'required' are supported\n",
6201 args[cur_arg], args[cur_arg + 1]);
6202 return ERR_ALERT | ERR_FATAL;
6203 }
6204
6205 return 0;
6206}
Emmanuel Hocdet98263292016-12-29 18:26:15 +01006207static int bind_parse_verify(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
6208{
6209 return ssl_bind_parse_verify(args, cur_arg, px, &conf->ssl_conf, err);
6210}
Emeric Brund94b3fe2012-09-20 18:23:56 +02006211
Willy Tarreau92faadf2012-10-10 23:04:25 +02006212/************** "server" keywords ****************/
6213
Emeric Brunef42d922012-10-11 16:11:36 +02006214/* parse the "ca-file" server keyword */
6215static int srv_parse_ca_file(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
6216{
6217 if (!*args[*cur_arg + 1]) {
6218 if (err)
6219 memprintf(err, "'%s' : missing CAfile path", args[*cur_arg]);
6220 return ERR_ALERT | ERR_FATAL;
6221 }
6222
Willy Tarreauef934602016-12-22 23:12:01 +01006223 if ((*args[*cur_arg + 1] != '/') && global_ssl.ca_base)
6224 memprintf(&newsrv->ssl_ctx.ca_file, "%s/%s", global_ssl.ca_base, args[*cur_arg + 1]);
Emeric Brunef42d922012-10-11 16:11:36 +02006225 else
6226 memprintf(&newsrv->ssl_ctx.ca_file, "%s", args[*cur_arg + 1]);
6227
6228 return 0;
6229}
6230
Willy Tarreau92faadf2012-10-10 23:04:25 +02006231/* parse the "check-ssl" server keyword */
6232static int srv_parse_check_ssl(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
6233{
6234 newsrv->check.use_ssl = 1;
Willy Tarreauef934602016-12-22 23:12:01 +01006235 if (global_ssl.connect_default_ciphers && !newsrv->ssl_ctx.ciphers)
6236 newsrv->ssl_ctx.ciphers = strdup(global_ssl.connect_default_ciphers);
6237 newsrv->ssl_ctx.options |= global_ssl.connect_default_ssloptions;
Willy Tarreau92faadf2012-10-10 23:04:25 +02006238 return 0;
6239}
6240
6241/* parse the "ciphers" server keyword */
6242static int srv_parse_ciphers(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
6243{
6244 if (!*args[*cur_arg + 1]) {
6245 memprintf(err, "'%s' : missing cipher suite", args[*cur_arg]);
6246 return ERR_ALERT | ERR_FATAL;
6247 }
6248
6249 free(newsrv->ssl_ctx.ciphers);
6250 newsrv->ssl_ctx.ciphers = strdup(args[*cur_arg + 1]);
6251 return 0;
6252}
6253
Emeric Brunef42d922012-10-11 16:11:36 +02006254/* parse the "crl-file" server keyword */
6255static int srv_parse_crl_file(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
6256{
6257#ifndef X509_V_FLAG_CRL_CHECK
6258 if (err)
6259 memprintf(err, "'%s' : library does not support CRL verify", args[*cur_arg]);
6260 return ERR_ALERT | ERR_FATAL;
6261#else
6262 if (!*args[*cur_arg + 1]) {
6263 if (err)
6264 memprintf(err, "'%s' : missing CRLfile path", args[*cur_arg]);
6265 return ERR_ALERT | ERR_FATAL;
6266 }
6267
Willy Tarreauef934602016-12-22 23:12:01 +01006268 if ((*args[*cur_arg + 1] != '/') && global_ssl.ca_base)
6269 memprintf(&newsrv->ssl_ctx.crl_file, "%s/%s", global_ssl.ca_base, args[*cur_arg + 1]);
Emeric Brunef42d922012-10-11 16:11:36 +02006270 else
6271 memprintf(&newsrv->ssl_ctx.crl_file, "%s", args[*cur_arg + 1]);
6272
6273 return 0;
6274#endif
6275}
6276
Emeric Bruna7aa3092012-10-26 12:58:00 +02006277/* parse the "crt" server keyword */
6278static int srv_parse_crt(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
6279{
6280 if (!*args[*cur_arg + 1]) {
6281 if (err)
6282 memprintf(err, "'%s' : missing certificate file path", args[*cur_arg]);
6283 return ERR_ALERT | ERR_FATAL;
6284 }
6285
Willy Tarreauef934602016-12-22 23:12:01 +01006286 if ((*args[*cur_arg + 1] != '/') && global_ssl.crt_base)
6287 memprintf(&newsrv->ssl_ctx.client_crt, "%s/%s", global_ssl.ca_base, args[*cur_arg + 1]);
Emeric Bruna7aa3092012-10-26 12:58:00 +02006288 else
6289 memprintf(&newsrv->ssl_ctx.client_crt, "%s", args[*cur_arg + 1]);
6290
6291 return 0;
6292}
Emeric Brunef42d922012-10-11 16:11:36 +02006293
Willy Tarreau92faadf2012-10-10 23:04:25 +02006294/* parse the "force-sslv3" server keyword */
6295static int srv_parse_force_sslv3(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
6296{
6297 newsrv->ssl_ctx.options |= SRV_SSL_O_USE_SSLV3;
6298 return 0;
6299}
6300
6301/* parse the "force-tlsv10" server keyword */
6302static int srv_parse_force_tlsv10(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
6303{
6304 newsrv->ssl_ctx.options |= SRV_SSL_O_USE_TLSV10;
6305 return 0;
6306}
6307
6308/* parse the "force-tlsv11" server keyword */
6309static int srv_parse_force_tlsv11(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
6310{
6311#if SSL_OP_NO_TLSv1_1
6312 newsrv->ssl_ctx.options |= SRV_SSL_O_USE_TLSV11;
6313 return 0;
6314#else
6315 if (err)
6316 memprintf(err, "'%s' : library does not support protocol TLSv1.1", args[*cur_arg]);
6317 return ERR_ALERT | ERR_FATAL;
6318#endif
6319}
6320
6321/* parse the "force-tlsv12" server keyword */
6322static int srv_parse_force_tlsv12(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
6323{
6324#if SSL_OP_NO_TLSv1_2
6325 newsrv->ssl_ctx.options |= SRV_SSL_O_USE_TLSV12;
6326 return 0;
6327#else
6328 if (err)
6329 memprintf(err, "'%s' : library does not support protocol TLSv1.2", args[*cur_arg]);
6330 return ERR_ALERT | ERR_FATAL;
6331#endif
6332}
6333
Willy Tarreau2a3fb1c2015-02-05 16:47:07 +01006334/* parse the "no-ssl-reuse" server keyword */
6335static int srv_parse_no_ssl_reuse(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
6336{
6337 newsrv->ssl_ctx.options |= SRV_SSL_O_NO_REUSE;
6338 return 0;
6339}
6340
Willy Tarreau92faadf2012-10-10 23:04:25 +02006341/* parse the "no-sslv3" server keyword */
6342static int srv_parse_no_sslv3(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
6343{
6344 newsrv->ssl_ctx.options |= SRV_SSL_O_NO_SSLV3;
6345 return 0;
6346}
6347
6348/* parse the "no-tlsv10" server keyword */
6349static int srv_parse_no_tlsv10(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
6350{
6351 newsrv->ssl_ctx.options |= SRV_SSL_O_NO_TLSV10;
6352 return 0;
6353}
6354
6355/* parse the "no-tlsv11" server keyword */
6356static int srv_parse_no_tlsv11(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
6357{
6358 newsrv->ssl_ctx.options |= SRV_SSL_O_NO_TLSV11;
6359 return 0;
6360}
6361
6362/* parse the "no-tlsv12" server keyword */
6363static int srv_parse_no_tlsv12(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
6364{
6365 newsrv->ssl_ctx.options |= SRV_SSL_O_NO_TLSV12;
6366 return 0;
6367}
6368
Emeric Brunf9c5c472012-10-11 15:28:34 +02006369/* parse the "no-tls-tickets" server keyword */
6370static int srv_parse_no_tls_tickets(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
6371{
6372 newsrv->ssl_ctx.options |= SRV_SSL_O_NO_TLS_TICKETS;
6373 return 0;
6374}
David Safb76832014-05-08 23:42:08 -04006375/* parse the "send-proxy-v2-ssl" server keyword */
6376static int srv_parse_send_proxy_ssl(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
6377{
6378 newsrv->pp_opts |= SRV_PP_V2;
6379 newsrv->pp_opts |= SRV_PP_V2_SSL;
6380 return 0;
6381}
6382
6383/* parse the "send-proxy-v2-ssl-cn" server keyword */
6384static int srv_parse_send_proxy_cn(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
6385{
6386 newsrv->pp_opts |= SRV_PP_V2;
6387 newsrv->pp_opts |= SRV_PP_V2_SSL;
6388 newsrv->pp_opts |= SRV_PP_V2_SSL_CN;
6389 return 0;
6390}
Emeric Brunf9c5c472012-10-11 15:28:34 +02006391
Willy Tarreau732eac42015-07-09 11:40:25 +02006392/* parse the "sni" server keyword */
6393static int srv_parse_sni(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
6394{
6395#ifndef SSL_CTRL_SET_TLSEXT_HOSTNAME
6396 memprintf(err, "'%s' : the current SSL library doesn't support the SNI TLS extension", args[*cur_arg]);
6397 return ERR_ALERT | ERR_FATAL;
6398#else
Cyril Bonté23d19d62016-03-07 22:13:22 +01006399 int idx;
Willy Tarreau732eac42015-07-09 11:40:25 +02006400 struct sample_expr *expr;
6401
6402 if (!*args[*cur_arg + 1]) {
6403 memprintf(err, "'%s' : missing sni expression", args[*cur_arg]);
6404 return ERR_ALERT | ERR_FATAL;
6405 }
6406
Cyril Bonté23d19d62016-03-07 22:13:22 +01006407 idx = (*cur_arg) + 1;
Willy Tarreau732eac42015-07-09 11:40:25 +02006408 proxy->conf.args.ctx = ARGC_SRV;
6409
Cyril Bonté23d19d62016-03-07 22:13:22 +01006410 expr = sample_parse_expr((char **)args, &idx, px->conf.file, px->conf.line, err, &proxy->conf.args);
Willy Tarreau732eac42015-07-09 11:40:25 +02006411 if (!expr) {
6412 memprintf(err, "error detected while parsing sni expression : %s", *err);
6413 return ERR_ALERT | ERR_FATAL;
6414 }
6415
6416 if (!(expr->fetch->val & SMP_VAL_BE_SRV_CON)) {
6417 memprintf(err, "error detected while parsing sni expression : "
6418 " fetch method '%s' extracts information from '%s', none of which is available here.\n",
Cyril Bonté23d19d62016-03-07 22:13:22 +01006419 args[idx-1], sample_src_names(expr->fetch->use));
Willy Tarreau732eac42015-07-09 11:40:25 +02006420 return ERR_ALERT | ERR_FATAL;
6421 }
6422
6423 px->http_needed |= !!(expr->fetch->use & SMP_USE_HTTP_ANY);
6424 newsrv->ssl_ctx.sni = expr;
6425 return 0;
6426#endif
6427}
6428
Willy Tarreau92faadf2012-10-10 23:04:25 +02006429/* parse the "ssl" server keyword */
6430static int srv_parse_ssl(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
6431{
6432 newsrv->use_ssl = 1;
Willy Tarreauef934602016-12-22 23:12:01 +01006433 if (global_ssl.connect_default_ciphers && !newsrv->ssl_ctx.ciphers)
6434 newsrv->ssl_ctx.ciphers = strdup(global_ssl.connect_default_ciphers);
Willy Tarreau92faadf2012-10-10 23:04:25 +02006435 return 0;
6436}
6437
Emeric Brunef42d922012-10-11 16:11:36 +02006438/* parse the "verify" server keyword */
6439static int srv_parse_verify(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
6440{
6441 if (!*args[*cur_arg + 1]) {
6442 if (err)
6443 memprintf(err, "'%s' : missing verify method", args[*cur_arg]);
6444 return ERR_ALERT | ERR_FATAL;
6445 }
6446
6447 if (strcmp(args[*cur_arg + 1], "none") == 0)
Emeric Brun850efd52014-01-29 12:24:34 +01006448 newsrv->ssl_ctx.verify = SSL_SOCK_VERIFY_NONE;
Emeric Brunef42d922012-10-11 16:11:36 +02006449 else if (strcmp(args[*cur_arg + 1], "required") == 0)
Emeric Brun850efd52014-01-29 12:24:34 +01006450 newsrv->ssl_ctx.verify = SSL_SOCK_VERIFY_REQUIRED;
Emeric Brunef42d922012-10-11 16:11:36 +02006451 else {
6452 if (err)
6453 memprintf(err, "'%s' : unknown verify method '%s', only 'none' and 'required' are supported\n",
6454 args[*cur_arg], args[*cur_arg + 1]);
6455 return ERR_ALERT | ERR_FATAL;
6456 }
6457
Evan Broderbe554312013-06-27 00:05:25 -07006458 return 0;
6459}
6460
6461/* parse the "verifyhost" server keyword */
6462static int srv_parse_verifyhost(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
6463{
6464 if (!*args[*cur_arg + 1]) {
6465 if (err)
6466 memprintf(err, "'%s' : missing hostname to verify against", args[*cur_arg]);
6467 return ERR_ALERT | ERR_FATAL;
6468 }
6469
6470 newsrv->ssl_ctx.verify_host = strdup(args[*cur_arg + 1]);
6471
Emeric Brunef42d922012-10-11 16:11:36 +02006472 return 0;
6473}
6474
Emeric Brun2c86cbf2014-10-30 15:56:50 +01006475/* parse the "ssl-default-bind-options" keyword in global section */
6476static int ssl_parse_default_bind_options(char **args, int section_type, struct proxy *curpx,
6477 struct proxy *defpx, const char *file, int line,
6478 char **err) {
6479 int i = 1;
6480
6481 if (*(args[i]) == 0) {
6482 memprintf(err, "global statement '%s' expects an option as an argument.", args[0]);
6483 return -1;
6484 }
6485 while (*(args[i])) {
6486 if (!strcmp(args[i], "no-sslv3"))
Willy Tarreauef934602016-12-22 23:12:01 +01006487 global_ssl.listen_default_ssloptions |= BC_SSL_O_NO_SSLV3;
Emeric Brun2c86cbf2014-10-30 15:56:50 +01006488 else if (!strcmp(args[i], "no-tlsv10"))
Willy Tarreauef934602016-12-22 23:12:01 +01006489 global_ssl.listen_default_ssloptions |= BC_SSL_O_NO_TLSV10;
Emeric Brun2c86cbf2014-10-30 15:56:50 +01006490 else if (!strcmp(args[i], "no-tlsv11"))
Willy Tarreauef934602016-12-22 23:12:01 +01006491 global_ssl.listen_default_ssloptions |= BC_SSL_O_NO_TLSV11;
Emeric Brun2c86cbf2014-10-30 15:56:50 +01006492 else if (!strcmp(args[i], "no-tlsv12"))
Willy Tarreauef934602016-12-22 23:12:01 +01006493 global_ssl.listen_default_ssloptions |= BC_SSL_O_NO_TLSV12;
Emeric Brun2c86cbf2014-10-30 15:56:50 +01006494 else if (!strcmp(args[i], "force-sslv3"))
Willy Tarreauef934602016-12-22 23:12:01 +01006495 global_ssl.listen_default_ssloptions |= BC_SSL_O_USE_SSLV3;
Emeric Brun2c86cbf2014-10-30 15:56:50 +01006496 else if (!strcmp(args[i], "force-tlsv10"))
Willy Tarreauef934602016-12-22 23:12:01 +01006497 global_ssl.listen_default_ssloptions |= BC_SSL_O_USE_TLSV10;
Emeric Brun2c86cbf2014-10-30 15:56:50 +01006498 else if (!strcmp(args[i], "force-tlsv11")) {
6499#if SSL_OP_NO_TLSv1_1
Willy Tarreauef934602016-12-22 23:12:01 +01006500 global_ssl.listen_default_ssloptions |= BC_SSL_O_USE_TLSV11;
Emeric Brun2c86cbf2014-10-30 15:56:50 +01006501#else
6502 memprintf(err, "'%s' '%s': library does not support protocol TLSv1.1", args[0], args[i]);
6503 return -1;
6504#endif
6505 }
6506 else if (!strcmp(args[i], "force-tlsv12")) {
6507#if SSL_OP_NO_TLSv1_2
Willy Tarreauef934602016-12-22 23:12:01 +01006508 global_ssl.listen_default_ssloptions |= BC_SSL_O_USE_TLSV12;
Emeric Brun2c86cbf2014-10-30 15:56:50 +01006509#else
6510 memprintf(err, "'%s' '%s': library does not support protocol TLSv1.2", args[0], args[i]);
6511 return -1;
6512#endif
6513 }
6514 else if (!strcmp(args[i], "no-tls-tickets"))
Willy Tarreauef934602016-12-22 23:12:01 +01006515 global_ssl.listen_default_ssloptions |= BC_SSL_O_NO_TLS_TICKETS;
Emeric Brun2c86cbf2014-10-30 15:56:50 +01006516 else {
6517 memprintf(err, "unknown option '%s' on global statement '%s'.", args[i], args[0]);
6518 return -1;
6519 }
6520 i++;
6521 }
6522 return 0;
6523}
6524
6525/* parse the "ssl-default-server-options" keyword in global section */
6526static int ssl_parse_default_server_options(char **args, int section_type, struct proxy *curpx,
6527 struct proxy *defpx, const char *file, int line,
6528 char **err) {
6529 int i = 1;
6530
6531 if (*(args[i]) == 0) {
6532 memprintf(err, "global statement '%s' expects an option as an argument.", args[0]);
6533 return -1;
6534 }
6535 while (*(args[i])) {
6536 if (!strcmp(args[i], "no-sslv3"))
Willy Tarreauef934602016-12-22 23:12:01 +01006537 global_ssl.connect_default_ssloptions |= SRV_SSL_O_NO_SSLV3;
Emeric Brun2c86cbf2014-10-30 15:56:50 +01006538 else if (!strcmp(args[i], "no-tlsv10"))
Willy Tarreauef934602016-12-22 23:12:01 +01006539 global_ssl.connect_default_ssloptions |= SRV_SSL_O_NO_TLSV10;
Emeric Brun2c86cbf2014-10-30 15:56:50 +01006540 else if (!strcmp(args[i], "no-tlsv11"))
Willy Tarreauef934602016-12-22 23:12:01 +01006541 global_ssl.connect_default_ssloptions |= SRV_SSL_O_NO_TLSV11;
Emeric Brun2c86cbf2014-10-30 15:56:50 +01006542 else if (!strcmp(args[i], "no-tlsv12"))
Willy Tarreauef934602016-12-22 23:12:01 +01006543 global_ssl.connect_default_ssloptions |= SRV_SSL_O_NO_TLSV12;
Emeric Brun2c86cbf2014-10-30 15:56:50 +01006544 else if (!strcmp(args[i], "force-sslv3"))
Willy Tarreauef934602016-12-22 23:12:01 +01006545 global_ssl.connect_default_ssloptions |= SRV_SSL_O_USE_SSLV3;
Emeric Brun2c86cbf2014-10-30 15:56:50 +01006546 else if (!strcmp(args[i], "force-tlsv10"))
Willy Tarreauef934602016-12-22 23:12:01 +01006547 global_ssl.connect_default_ssloptions |= SRV_SSL_O_USE_TLSV10;
Emeric Brun2c86cbf2014-10-30 15:56:50 +01006548 else if (!strcmp(args[i], "force-tlsv11")) {
6549#if SSL_OP_NO_TLSv1_1
Willy Tarreauef934602016-12-22 23:12:01 +01006550 global_ssl.connect_default_ssloptions |= SRV_SSL_O_USE_TLSV11;
Emeric Brun2c86cbf2014-10-30 15:56:50 +01006551#else
6552 memprintf(err, "'%s' '%s': library does not support protocol TLSv1.1", args[0], args[i]);
6553 return -1;
6554#endif
6555 }
6556 else if (!strcmp(args[i], "force-tlsv12")) {
6557#if SSL_OP_NO_TLSv1_2
Willy Tarreauef934602016-12-22 23:12:01 +01006558 global_ssl.connect_default_ssloptions |= SRV_SSL_O_USE_TLSV12;
Emeric Brun2c86cbf2014-10-30 15:56:50 +01006559#else
6560 memprintf(err, "'%s' '%s': library does not support protocol TLSv1.2", args[0], args[i]);
6561 return -1;
6562#endif
6563 }
6564 else if (!strcmp(args[i], "no-tls-tickets"))
Willy Tarreauef934602016-12-22 23:12:01 +01006565 global_ssl.connect_default_ssloptions |= SRV_SSL_O_NO_TLS_TICKETS;
Emeric Brun2c86cbf2014-10-30 15:56:50 +01006566 else {
6567 memprintf(err, "unknown option '%s' on global statement '%s'.", args[i], args[0]);
6568 return -1;
6569 }
6570 i++;
6571 }
6572 return 0;
6573}
6574
Willy Tarreau8c3b0fd2016-12-21 22:44:46 +01006575/* parse the "ca-base" / "crt-base" keywords in global section.
6576 * Returns <0 on alert, >0 on warning, 0 on success.
6577 */
6578static int ssl_parse_global_ca_crt_base(char **args, int section_type, struct proxy *curpx,
6579 struct proxy *defpx, const char *file, int line,
6580 char **err)
6581{
6582 char **target;
6583
Willy Tarreauef934602016-12-22 23:12:01 +01006584 target = (args[0][1] == 'a') ? &global_ssl.ca_base : &global_ssl.crt_base;
Willy Tarreau8c3b0fd2016-12-21 22:44:46 +01006585
6586 if (too_many_args(1, args, err, NULL))
6587 return -1;
6588
6589 if (*target) {
6590 memprintf(err, "'%s' already specified.", args[0]);
6591 return -1;
6592 }
6593
6594 if (*(args[1]) == 0) {
6595 memprintf(err, "global statement '%s' expects a directory path as an argument.", args[0]);
6596 return -1;
6597 }
6598 *target = strdup(args[1]);
6599 return 0;
6600}
6601
Willy Tarreauf22e9682016-12-21 23:23:19 +01006602/* parse the "ssl-default-bind-ciphers" / "ssl-default-server-ciphers" keywords
6603 * in global section. Returns <0 on alert, >0 on warning, 0 on success.
6604 */
6605static int ssl_parse_global_ciphers(char **args, int section_type, struct proxy *curpx,
6606 struct proxy *defpx, const char *file, int line,
6607 char **err)
6608{
6609 char **target;
6610
Willy Tarreauef934602016-12-22 23:12:01 +01006611 target = (args[0][12] == 'b') ? &global_ssl.listen_default_ciphers : &global_ssl.connect_default_ciphers;
Willy Tarreauf22e9682016-12-21 23:23:19 +01006612
6613 if (too_many_args(1, args, err, NULL))
6614 return -1;
6615
6616 if (*(args[1]) == 0) {
6617 memprintf(err, "global statement '%s' expects a cipher suite as an argument.", args[0]);
6618 return -1;
6619 }
6620
6621 free(*target);
6622 *target = strdup(args[1]);
6623 return 0;
6624}
6625
Willy Tarreau9ceda382016-12-21 23:13:03 +01006626/* parse various global tune.ssl settings consisting in positive integers.
6627 * Returns <0 on alert, >0 on warning, 0 on success.
6628 */
6629static int ssl_parse_global_int(char **args, int section_type, struct proxy *curpx,
6630 struct proxy *defpx, const char *file, int line,
6631 char **err)
6632{
6633 int *target;
6634
6635 if (strcmp(args[0], "tune.ssl.cachesize") == 0)
6636 target = &global.tune.sslcachesize;
6637 else if (strcmp(args[0], "tune.ssl.maxrecord") == 0)
Willy Tarreauef934602016-12-22 23:12:01 +01006638 target = (int *)&global_ssl.max_record;
Willy Tarreau9ceda382016-12-21 23:13:03 +01006639 else if (strcmp(args[0], "tune.ssl.ssl-ctx-cache-size") == 0)
Willy Tarreauef934602016-12-22 23:12:01 +01006640 target = &global_ssl.ctx_cache;
Willy Tarreau0bea58d2016-12-21 23:17:25 +01006641 else if (strcmp(args[0], "maxsslconn") == 0)
6642 target = &global.maxsslconn;
Willy Tarreau9ceda382016-12-21 23:13:03 +01006643 else {
6644 memprintf(err, "'%s' keyword not unhandled (please report this bug).", args[0]);
6645 return -1;
6646 }
6647
6648 if (too_many_args(1, args, err, NULL))
6649 return -1;
6650
6651 if (*(args[1]) == 0) {
6652 memprintf(err, "'%s' expects an integer argument.", args[0]);
6653 return -1;
6654 }
6655
6656 *target = atoi(args[1]);
6657 if (*target < 0) {
6658 memprintf(err, "'%s' expects a positive numeric value.", args[0]);
6659 return -1;
6660 }
6661 return 0;
6662}
6663
6664/* parse "ssl.force-private-cache".
6665 * Returns <0 on alert, >0 on warning, 0 on success.
6666 */
6667static int ssl_parse_global_private_cache(char **args, int section_type, struct proxy *curpx,
6668 struct proxy *defpx, const char *file, int line,
6669 char **err)
6670{
6671 if (too_many_args(0, args, err, NULL))
6672 return -1;
6673
Willy Tarreauef934602016-12-22 23:12:01 +01006674 global_ssl.private_cache = 1;
Willy Tarreau9ceda382016-12-21 23:13:03 +01006675 return 0;
6676}
6677
6678/* parse "ssl.lifetime".
6679 * Returns <0 on alert, >0 on warning, 0 on success.
6680 */
6681static int ssl_parse_global_lifetime(char **args, int section_type, struct proxy *curpx,
6682 struct proxy *defpx, const char *file, int line,
6683 char **err)
6684{
6685 const char *res;
6686
6687 if (too_many_args(1, args, err, NULL))
6688 return -1;
6689
6690 if (*(args[1]) == 0) {
6691 memprintf(err, "'%s' expects ssl sessions <lifetime> in seconds as argument.", args[0]);
6692 return -1;
6693 }
6694
Willy Tarreauef934602016-12-22 23:12:01 +01006695 res = parse_time_err(args[1], &global_ssl.life_time, TIME_UNIT_S);
Willy Tarreau9ceda382016-12-21 23:13:03 +01006696 if (res) {
6697 memprintf(err, "unexpected character '%c' in argument to <%s>.", *res, args[0]);
6698 return -1;
6699 }
6700 return 0;
6701}
6702
6703#ifndef OPENSSL_NO_DH
Willy Tarreau14e36a12016-12-21 23:28:13 +01006704/* parse "ssl-dh-param-file".
6705 * Returns <0 on alert, >0 on warning, 0 on success.
6706 */
6707static int ssl_parse_global_dh_param_file(char **args, int section_type, struct proxy *curpx,
6708 struct proxy *defpx, const char *file, int line,
6709 char **err)
6710{
6711 if (too_many_args(1, args, err, NULL))
6712 return -1;
6713
6714 if (*(args[1]) == 0) {
6715 memprintf(err, "'%s' expects a file path as an argument.", args[0]);
6716 return -1;
6717 }
6718
6719 if (ssl_sock_load_global_dh_param_from_file(args[1])) {
6720 memprintf(err, "'%s': unable to load DH parameters from file <%s>.", args[0], args[1]);
6721 return -1;
6722 }
6723 return 0;
6724}
6725
Willy Tarreau9ceda382016-12-21 23:13:03 +01006726/* parse "ssl.default-dh-param".
6727 * Returns <0 on alert, >0 on warning, 0 on success.
6728 */
6729static int ssl_parse_global_default_dh(char **args, int section_type, struct proxy *curpx,
6730 struct proxy *defpx, const char *file, int line,
6731 char **err)
6732{
6733 if (too_many_args(1, args, err, NULL))
6734 return -1;
6735
6736 if (*(args[1]) == 0) {
6737 memprintf(err, "'%s' expects an integer argument.", args[0]);
6738 return -1;
6739 }
6740
Willy Tarreauef934602016-12-22 23:12:01 +01006741 global_ssl.default_dh_param = atoi(args[1]);
6742 if (global_ssl.default_dh_param < 1024) {
Willy Tarreau9ceda382016-12-21 23:13:03 +01006743 memprintf(err, "'%s' expects a value >= 1024.", args[0]);
6744 return -1;
6745 }
6746 return 0;
6747}
6748#endif
6749
6750
William Lallemand32af2032016-10-29 18:09:35 +02006751/* This function is used with TLS ticket keys management. It permits to browse
6752 * each reference. The variable <getnext> must contain the current node,
6753 * <end> point to the root node.
6754 */
6755#if (defined SSL_CTRL_SET_TLSEXT_TICKET_KEY_CB && TLS_TICKETS_NO > 0)
6756static inline
6757struct tls_keys_ref *tlskeys_list_get_next(struct tls_keys_ref *getnext, struct list *end)
6758{
6759 struct tls_keys_ref *ref = getnext;
6760
6761 while (1) {
6762
6763 /* Get next list entry. */
6764 ref = LIST_NEXT(&ref->list, struct tls_keys_ref *, list);
6765
6766 /* If the entry is the last of the list, return NULL. */
6767 if (&ref->list == end)
6768 return NULL;
6769
6770 return ref;
6771 }
6772}
6773
6774static inline
6775struct tls_keys_ref *tlskeys_ref_lookup_ref(const char *reference)
6776{
6777 int id;
6778 char *error;
6779
6780 /* If the reference starts by a '#', this is numeric id. */
6781 if (reference[0] == '#') {
6782 /* Try to convert the numeric id. If the conversion fails, the lookup fails. */
6783 id = strtol(reference + 1, &error, 10);
6784 if (*error != '\0')
6785 return NULL;
6786
6787 /* Perform the unique id lookup. */
6788 return tlskeys_ref_lookupid(id);
6789 }
6790
6791 /* Perform the string lookup. */
6792 return tlskeys_ref_lookup(reference);
6793}
6794#endif
6795
6796
6797#if (defined SSL_CTRL_SET_TLSEXT_TICKET_KEY_CB && TLS_TICKETS_NO > 0)
6798
6799static int cli_io_handler_tlskeys_files(struct appctx *appctx);
6800
6801static inline int cli_io_handler_tlskeys_entries(struct appctx *appctx) {
6802 return cli_io_handler_tlskeys_files(appctx);
6803}
6804
Willy Tarreauf5f26e82016-12-16 18:47:27 +01006805/* dumps all tls keys. Relies on cli.i0 (non-null = only list file names), cli.i1
6806 * (next index to be dumped), and cli.p0 (next key reference).
6807 */
William Lallemand32af2032016-10-29 18:09:35 +02006808static int cli_io_handler_tlskeys_files(struct appctx *appctx) {
6809
6810 struct stream_interface *si = appctx->owner;
6811
6812 switch (appctx->st2) {
6813 case STAT_ST_INIT:
6814 /* Display the column headers. If the message cannot be sent,
6815 * quit the fucntion with returning 0. The function is called
6816 * later and restart at the state "STAT_ST_INIT".
6817 */
6818 chunk_reset(&trash);
6819
6820 if (appctx->io_handler == cli_io_handler_tlskeys_entries)
6821 chunk_appendf(&trash, "# id secret\n");
6822 else
6823 chunk_appendf(&trash, "# id (file)\n");
6824
6825 if (bi_putchk(si_ic(si), &trash) == -1) {
6826 si_applet_cant_put(si);
6827 return 0;
6828 }
6829
William Lallemand32af2032016-10-29 18:09:35 +02006830 /* Now, we start the browsing of the references lists.
6831 * Note that the following call to LIST_ELEM return bad pointer. The only
6832 * available field of this pointer is <list>. It is used with the function
6833 * tlskeys_list_get_next() for retruning the first available entry
6834 */
Willy Tarreauf5f26e82016-12-16 18:47:27 +01006835 if (appctx->ctx.cli.p0 == NULL) {
6836 appctx->ctx.cli.p0 = LIST_ELEM(&tlskeys_reference, struct tls_keys_ref *, list);
6837 appctx->ctx.cli.p0 = tlskeys_list_get_next(appctx->ctx.cli.p0, &tlskeys_reference);
William Lallemand32af2032016-10-29 18:09:35 +02006838 }
6839
6840 appctx->st2 = STAT_ST_LIST;
6841 /* fall through */
6842
6843 case STAT_ST_LIST:
Willy Tarreauf5f26e82016-12-16 18:47:27 +01006844 while (appctx->ctx.cli.p0) {
6845 struct tls_keys_ref *ref = appctx->ctx.cli.p0;
6846 int head = ref->tls_ticket_enc_index;
William Lallemand32af2032016-10-29 18:09:35 +02006847
6848 chunk_reset(&trash);
Willy Tarreauf5f26e82016-12-16 18:47:27 +01006849 if (appctx->io_handler == cli_io_handler_tlskeys_entries && appctx->ctx.cli.i1 == 0)
William Lallemand32af2032016-10-29 18:09:35 +02006850 chunk_appendf(&trash, "# ");
Willy Tarreauf5f26e82016-12-16 18:47:27 +01006851
6852 if (appctx->ctx.cli.i1 == 0)
6853 chunk_appendf(&trash, "%d (%s)\n", ref->unique_id, ref->filename);
6854
William Lallemand32af2032016-10-29 18:09:35 +02006855 if (appctx->io_handler == cli_io_handler_tlskeys_entries) {
Willy Tarreauf5f26e82016-12-16 18:47:27 +01006856 while (appctx->ctx.cli.i1 < TLS_TICKETS_NO) {
William Lallemand32af2032016-10-29 18:09:35 +02006857 struct chunk *t2 = get_trash_chunk();
6858
6859 chunk_reset(t2);
6860 /* should never fail here because we dump only a key in the t2 buffer */
Willy Tarreauf5f26e82016-12-16 18:47:27 +01006861 t2->len = a2base64((char *)(ref->tlskeys + (head + 2 + appctx->ctx.cli.i1) % TLS_TICKETS_NO),
William Lallemand32af2032016-10-29 18:09:35 +02006862 sizeof(struct tls_sess_key), t2->str, t2->size);
Willy Tarreauf5f26e82016-12-16 18:47:27 +01006863 chunk_appendf(&trash, "%d.%d %s\n", ref->unique_id, appctx->ctx.cli.i1, t2->str);
William Lallemand32af2032016-10-29 18:09:35 +02006864
6865 if (bi_putchk(si_ic(si), &trash) == -1) {
6866 /* let's try again later from this stream. We add ourselves into
6867 * this stream's users so that it can remove us upon termination.
6868 */
6869 si_applet_cant_put(si);
6870 return 0;
6871 }
Willy Tarreauf5f26e82016-12-16 18:47:27 +01006872 appctx->ctx.cli.i1++;
William Lallemand32af2032016-10-29 18:09:35 +02006873 }
Willy Tarreauf5f26e82016-12-16 18:47:27 +01006874 appctx->ctx.cli.i1 = 0;
William Lallemand32af2032016-10-29 18:09:35 +02006875 }
6876 if (bi_putchk(si_ic(si), &trash) == -1) {
6877 /* let's try again later from this stream. We add ourselves into
6878 * this stream's users so that it can remove us upon termination.
6879 */
6880 si_applet_cant_put(si);
6881 return 0;
6882 }
6883
Willy Tarreauf5f26e82016-12-16 18:47:27 +01006884 if (appctx->ctx.cli.i0 == 0) /* don't display everything if not necessary */
William Lallemand32af2032016-10-29 18:09:35 +02006885 break;
6886
6887 /* get next list entry and check the end of the list */
Willy Tarreauf5f26e82016-12-16 18:47:27 +01006888 appctx->ctx.cli.p0 = tlskeys_list_get_next(appctx->ctx.cli.p0, &tlskeys_reference);
William Lallemand32af2032016-10-29 18:09:35 +02006889 }
6890
6891 appctx->st2 = STAT_ST_FIN;
6892 /* fall through */
6893
6894 default:
6895 appctx->st2 = STAT_ST_FIN;
6896 return 1;
6897 }
6898 return 0;
6899}
6900
Willy Tarreauf5f26e82016-12-16 18:47:27 +01006901/* sets cli.i0 to non-zero if only file lists should be dumped */
William Lallemand32af2032016-10-29 18:09:35 +02006902static int cli_parse_show_tlskeys(char **args, struct appctx *appctx, void *private)
6903{
William Lallemand32af2032016-10-29 18:09:35 +02006904 /* no parameter, shows only file list */
6905 if (!*args[2]) {
Willy Tarreauf5f26e82016-12-16 18:47:27 +01006906 appctx->ctx.cli.i0 = 1;
William Lallemand32af2032016-10-29 18:09:35 +02006907 appctx->io_handler = cli_io_handler_tlskeys_files;
Willy Tarreau3067bfa2016-12-05 14:50:15 +01006908 return 0;
William Lallemand32af2032016-10-29 18:09:35 +02006909 }
6910
6911 if (args[2][0] == '*') {
6912 /* list every TLS ticket keys */
Willy Tarreauf5f26e82016-12-16 18:47:27 +01006913 appctx->ctx.cli.i0 = 1;
William Lallemand32af2032016-10-29 18:09:35 +02006914 } else {
Willy Tarreauf5f26e82016-12-16 18:47:27 +01006915 appctx->ctx.cli.p0 = tlskeys_ref_lookup_ref(args[2]);
6916 if (!appctx->ctx.cli.p0) {
William Lallemand32af2032016-10-29 18:09:35 +02006917 appctx->ctx.cli.msg = "'show tls-keys' unable to locate referenced filename\n";
Willy Tarreau3b6e5472016-11-24 15:53:53 +01006918 appctx->st0 = CLI_ST_PRINT;
William Lallemand32af2032016-10-29 18:09:35 +02006919 return 1;
6920 }
6921 }
William Lallemand32af2032016-10-29 18:09:35 +02006922 appctx->io_handler = cli_io_handler_tlskeys_entries;
Willy Tarreau3067bfa2016-12-05 14:50:15 +01006923 return 0;
William Lallemand32af2032016-10-29 18:09:35 +02006924}
6925
William Lallemand32af2032016-10-29 18:09:35 +02006926static int cli_parse_set_tlskeys(char **args, struct appctx *appctx, void *private)
6927{
Willy Tarreauf5f26e82016-12-16 18:47:27 +01006928 struct tls_keys_ref *ref;
6929
William Lallemand32af2032016-10-29 18:09:35 +02006930 /* Expect two parameters: the filename and the new new TLS key in encoding */
6931 if (!*args[3] || !*args[4]) {
6932 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 +01006933 appctx->st0 = CLI_ST_PRINT;
William Lallemand32af2032016-10-29 18:09:35 +02006934 return 1;
6935 }
6936
Willy Tarreauf5f26e82016-12-16 18:47:27 +01006937 ref = tlskeys_ref_lookup_ref(args[3]);
6938 if (!ref) {
William Lallemand32af2032016-10-29 18:09:35 +02006939 appctx->ctx.cli.msg = "'set ssl tls-key' unable to locate referenced filename\n";
Willy Tarreau3b6e5472016-11-24 15:53:53 +01006940 appctx->st0 = CLI_ST_PRINT;
William Lallemand32af2032016-10-29 18:09:35 +02006941 return 1;
6942 }
6943
6944 trash.len = base64dec(args[4], strlen(args[4]), trash.str, trash.size);
6945 if (trash.len != sizeof(struct tls_sess_key)) {
6946 appctx->ctx.cli.msg = "'set ssl tls-key' received invalid base64 encoded TLS key.\n";
Willy Tarreau3b6e5472016-11-24 15:53:53 +01006947 appctx->st0 = CLI_ST_PRINT;
William Lallemand32af2032016-10-29 18:09:35 +02006948 return 1;
6949 }
6950
Willy Tarreauf5f26e82016-12-16 18:47:27 +01006951 memcpy(ref->tlskeys + ((ref->tls_ticket_enc_index + 2) % TLS_TICKETS_NO), trash.str, trash.len);
6952 ref->tls_ticket_enc_index = (ref->tls_ticket_enc_index + 1) % TLS_TICKETS_NO;
William Lallemand32af2032016-10-29 18:09:35 +02006953
6954 appctx->ctx.cli.msg = "TLS ticket key updated!";
Willy Tarreau3b6e5472016-11-24 15:53:53 +01006955 appctx->st0 = CLI_ST_PRINT;
William Lallemand32af2032016-10-29 18:09:35 +02006956 return 1;
6957
6958}
Emmanuel Hocdetfdec7892017-01-13 17:48:18 +01006959#endif
William Lallemand32af2032016-10-29 18:09:35 +02006960
6961static int cli_parse_set_ocspresponse(char **args, struct appctx *appctx, void *private)
6962{
6963#if (defined SSL_CTRL_SET_TLSEXT_STATUS_REQ_CB && !defined OPENSSL_NO_OCSP)
6964 char *err = NULL;
6965
6966 /* Expect one parameter: the new response in base64 encoding */
6967 if (!*args[3]) {
6968 appctx->ctx.cli.msg = "'set ssl ocsp-response' expects response in base64 encoding.\n";
Willy Tarreau3b6e5472016-11-24 15:53:53 +01006969 appctx->st0 = CLI_ST_PRINT;
William Lallemand32af2032016-10-29 18:09:35 +02006970 return 1;
6971 }
6972
6973 trash.len = base64dec(args[3], strlen(args[3]), trash.str, trash.size);
6974 if (trash.len < 0) {
6975 appctx->ctx.cli.msg = "'set ssl ocsp-response' received invalid base64 encoded response.\n";
Willy Tarreau3b6e5472016-11-24 15:53:53 +01006976 appctx->st0 = CLI_ST_PRINT;
William Lallemand32af2032016-10-29 18:09:35 +02006977 return 1;
6978 }
6979
6980 if (ssl_sock_update_ocsp_response(&trash, &err)) {
6981 if (err) {
6982 memprintf(&err, "%s.\n", err);
6983 appctx->ctx.cli.err = err;
Willy Tarreau3b6e5472016-11-24 15:53:53 +01006984 appctx->st0 = CLI_ST_PRINT_FREE;
William Lallemand32af2032016-10-29 18:09:35 +02006985 }
6986 return 1;
6987 }
6988 appctx->ctx.cli.msg = "OCSP Response updated!";
Willy Tarreau3b6e5472016-11-24 15:53:53 +01006989 appctx->st0 = CLI_ST_PRINT;
William Lallemand32af2032016-10-29 18:09:35 +02006990 return 1;
6991#else
6992 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 +01006993 appctx->st0 = CLI_ST_PRINT;
William Lallemand32af2032016-10-29 18:09:35 +02006994 return 1;
6995#endif
6996
6997}
6998
6999/* register cli keywords */
7000static struct cli_kw_list cli_kws = {{ },{
7001#if (defined SSL_CTRL_SET_TLSEXT_TICKET_KEY_CB && TLS_TICKETS_NO > 0)
7002 { { "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 },
7003 { { "set", "ssl", "tls-keys", NULL }, NULL, cli_parse_set_tlskeys, NULL },
William Lallemand32af2032016-10-29 18:09:35 +02007004#endif
Emmanuel Hocdetfdec7892017-01-13 17:48:18 +01007005 { { "set", "ssl", "ocsp-response", NULL }, NULL, cli_parse_set_ocspresponse, NULL },
William Lallemand32af2032016-10-29 18:09:35 +02007006 { { NULL }, NULL, NULL, NULL }
7007}};
7008
7009
Willy Tarreau7875d092012-09-10 08:20:03 +02007010/* Note: must not be declared <const> as its list will be overwritten.
7011 * Please take care of keeping this list alphabetically sorted.
7012 */
Willy Tarreaudc13c112013-06-21 23:16:39 +02007013static struct sample_fetch_kw_list sample_fetch_keywords = {ILH, {
Emeric Brun645ae792014-04-30 14:21:06 +02007014 { "ssl_bc", smp_fetch_ssl_fc, 0, NULL, SMP_T_BOOL, SMP_USE_L5SRV },
Thierry FOURNIER07ee64e2015-07-06 23:43:03 +02007015 { "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 +02007016 { "ssl_bc_cipher", smp_fetch_ssl_fc_cipher, 0, NULL, SMP_T_STR, SMP_USE_L5SRV },
7017 { "ssl_bc_protocol", smp_fetch_ssl_fc_protocol, 0, NULL, SMP_T_STR, SMP_USE_L5SRV },
Emeric Brunb73a9b02014-04-30 18:49:19 +02007018 { "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 +02007019 { "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 +02007020 { "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 +02007021 { "ssl_c_ca_err", smp_fetch_ssl_c_ca_err, 0, NULL, SMP_T_SINT, SMP_USE_L5CLI },
7022 { "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 +01007023 { "ssl_c_der", smp_fetch_ssl_x_der, 0, NULL, SMP_T_BIN, SMP_USE_L5CLI },
Thierry FOURNIER07ee64e2015-07-06 23:43:03 +02007024 { "ssl_c_err", smp_fetch_ssl_c_err, 0, NULL, SMP_T_SINT, SMP_USE_L5CLI },
Emeric Brunba841a12014-04-30 17:05:08 +02007025 { "ssl_c_i_dn", smp_fetch_ssl_x_i_dn, ARG2(0,STR,SINT), NULL, SMP_T_STR, SMP_USE_L5CLI },
7026 { "ssl_c_key_alg", smp_fetch_ssl_x_key_alg, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
7027 { "ssl_c_notafter", smp_fetch_ssl_x_notafter, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
7028 { "ssl_c_notbefore", smp_fetch_ssl_x_notbefore, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
7029 { "ssl_c_sig_alg", smp_fetch_ssl_x_sig_alg, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
7030 { "ssl_c_s_dn", smp_fetch_ssl_x_s_dn, ARG2(0,STR,SINT), NULL, SMP_T_STR, SMP_USE_L5CLI },
7031 { "ssl_c_serial", smp_fetch_ssl_x_serial, 0, NULL, SMP_T_BIN, SMP_USE_L5CLI },
7032 { "ssl_c_sha1", smp_fetch_ssl_x_sha1, 0, NULL, SMP_T_BIN, SMP_USE_L5CLI },
Willy Tarreau80aca902013-01-07 15:42:20 +01007033 { "ssl_c_used", smp_fetch_ssl_c_used, 0, NULL, SMP_T_BOOL, SMP_USE_L5CLI },
Thierry FOURNIER07ee64e2015-07-06 23:43:03 +02007034 { "ssl_c_verify", smp_fetch_ssl_c_verify, 0, NULL, SMP_T_SINT, SMP_USE_L5CLI },
7035 { "ssl_c_version", smp_fetch_ssl_x_version, 0, NULL, SMP_T_SINT, SMP_USE_L5CLI },
Emeric Brun43e79582014-10-29 19:03:26 +01007036 { "ssl_f_der", smp_fetch_ssl_x_der, 0, NULL, SMP_T_BIN, SMP_USE_L5CLI },
Emeric Brunba841a12014-04-30 17:05:08 +02007037 { "ssl_f_i_dn", smp_fetch_ssl_x_i_dn, ARG2(0,STR,SINT), NULL, SMP_T_STR, SMP_USE_L5CLI },
7038 { "ssl_f_key_alg", smp_fetch_ssl_x_key_alg, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
7039 { "ssl_f_notafter", smp_fetch_ssl_x_notafter, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
7040 { "ssl_f_notbefore", smp_fetch_ssl_x_notbefore, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
7041 { "ssl_f_sig_alg", smp_fetch_ssl_x_sig_alg, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
7042 { "ssl_f_s_dn", smp_fetch_ssl_x_s_dn, ARG2(0,STR,SINT), NULL, SMP_T_STR, SMP_USE_L5CLI },
7043 { "ssl_f_serial", smp_fetch_ssl_x_serial, 0, NULL, SMP_T_BIN, SMP_USE_L5CLI },
Emeric Brun55f4fa82014-04-30 17:11:25 +02007044 { "ssl_f_sha1", smp_fetch_ssl_x_sha1, 0, NULL, SMP_T_BIN, SMP_USE_L5CLI },
Thierry FOURNIER07ee64e2015-07-06 23:43:03 +02007045 { "ssl_f_version", smp_fetch_ssl_x_version, 0, NULL, SMP_T_SINT, SMP_USE_L5CLI },
Willy Tarreau80aca902013-01-07 15:42:20 +01007046 { "ssl_fc", smp_fetch_ssl_fc, 0, NULL, SMP_T_BOOL, SMP_USE_L5CLI },
Thierry FOURNIER07ee64e2015-07-06 23:43:03 +02007047 { "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 +01007048 { "ssl_fc_cipher", smp_fetch_ssl_fc_cipher, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
Willy Tarreau80aca902013-01-07 15:42:20 +01007049 { "ssl_fc_has_crt", smp_fetch_ssl_fc_has_crt, 0, NULL, SMP_T_BOOL, SMP_USE_L5CLI },
7050 { "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 +02007051 { "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 +02007052#ifdef OPENSSL_NPN_NEGOTIATED
Thierry FOURNIER7654c9f2013-12-17 00:20:33 +01007053 { "ssl_fc_npn", smp_fetch_ssl_fc_npn, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
Willy Tarreaua33c6542012-10-15 13:19:06 +02007054#endif
Dirkjan Bussink48f1c4e2014-02-13 12:29:42 +01007055#ifdef TLSEXT_TYPE_application_layer_protocol_negotiation
Thierry FOURNIER7654c9f2013-12-17 00:20:33 +01007056 { "ssl_fc_alpn", smp_fetch_ssl_fc_alpn, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
Willy Tarreauab861d32013-04-02 02:30:41 +02007057#endif
Thierry FOURNIER7654c9f2013-12-17 00:20:33 +01007058 { "ssl_fc_protocol", smp_fetch_ssl_fc_protocol, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
Emeric Brunb73a9b02014-04-30 18:49:19 +02007059 { "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 +02007060 { "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 +01007061 { "ssl_fc_session_id", smp_fetch_ssl_fc_session_id, 0, NULL, SMP_T_BIN, SMP_USE_L5CLI },
7062 { "ssl_fc_sni", smp_fetch_ssl_fc_sni, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
Willy Tarreau7875d092012-09-10 08:20:03 +02007063 { NULL, NULL, 0, 0, 0 },
7064}};
7065
7066/* Note: must not be declared <const> as its list will be overwritten.
7067 * Please take care of keeping this list alphabetically sorted.
7068 */
Willy Tarreaudc13c112013-06-21 23:16:39 +02007069static struct acl_kw_list acl_kws = {ILH, {
Thierry FOURNIERc5a4e982014-03-05 16:07:08 +01007070 { "ssl_fc_sni_end", "ssl_fc_sni", PAT_MATCH_END },
7071 { "ssl_fc_sni_reg", "ssl_fc_sni", PAT_MATCH_REG },
Willy Tarreau8ed669b2013-01-11 15:49:37 +01007072 { /* END */ },
Willy Tarreau7875d092012-09-10 08:20:03 +02007073}};
7074
Willy Tarreau79eeafa2012-09-14 07:53:05 +02007075/* Note: must not be declared <const> as its list will be overwritten.
7076 * Please take care of keeping this list alphabetically sorted, doing so helps
7077 * all code contributors.
7078 * Optional keywords are also declared with a NULL ->parse() function so that
7079 * the config parser can report an appropriate error when a known keyword was
7080 * not enabled.
7081 */
Emmanuel Hocdet98263292016-12-29 18:26:15 +01007082static struct ssl_bind_kw ssl_bind_kws[] = {
7083 { "alpn", ssl_bind_parse_alpn, 1 }, /* set ALPN supported protocols */
7084 { "ca-file", ssl_bind_parse_ca_file, 1 }, /* set CAfile to process verify on client cert */
7085 { "ciphers", ssl_bind_parse_ciphers, 1 }, /* set SSL cipher suite */
7086 { "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 +01007087 { "curves", ssl_bind_parse_curves, 1 }, /* set SSL curve suite */
Emmanuel Hocdet98263292016-12-29 18:26:15 +01007088 { "ecdhe", ssl_bind_parse_ecdhe, 1 }, /* defines named curve for elliptic curve Diffie-Hellman */
7089 { "force-sslv3", ssl_bind_parse_force_sslv3, 0 }, /* force SSLv3 */
7090 { "force-tlsv10", ssl_bind_parse_force_tlsv10, 0 }, /* force TLSv10 */
7091 { "force-tlsv11", ssl_bind_parse_force_tlsv11, 0 }, /* force TLSv11 */
7092 { "force-tlsv12", ssl_bind_parse_force_tlsv12, 0 }, /* force TLSv12 */
7093 { "no-sslv3", ssl_bind_parse_no_sslv3, 0 }, /* disable SSLv3 */
7094 { "no-tlsv10", ssl_bind_parse_no_tlsv10, 0 }, /* disable TLSv10 */
7095 { "no-tlsv11", ssl_bind_parse_no_tlsv11, 0 }, /* disable TLSv11 */
7096 { "no-tlsv12", ssl_bind_parse_no_tlsv12, 0 }, /* disable TLSv12 */
7097 { "no-tls-tickets", ssl_bind_parse_no_tls_tickets, 0 }, /* disable session resumption tickets */
7098 { "npn", ssl_bind_parse_npn, 1 }, /* set NPN supported protocols */
7099 { "verify", ssl_bind_parse_verify, 1 }, /* set SSL verify method */
7100 { NULL, NULL, 0 },
7101};
7102
Willy Tarreau51fb7652012-09-18 18:24:39 +02007103static struct bind_kw_list bind_kws = { "SSL", { }, {
Nenad Merdanovic05552d42015-02-27 19:56:49 +01007104 { "alpn", bind_parse_alpn, 1 }, /* set ALPN supported protocols */
7105 { "ca-file", bind_parse_ca_file, 1 }, /* set CAfile to process verify on client cert */
7106 { "ca-ignore-err", bind_parse_ignore_err, 1 }, /* set error IDs to ignore on verify depth > 0 */
Christopher Faulet31af49d2015-06-09 17:29:50 +02007107 { "ca-sign-file", bind_parse_ca_sign_file, 1 }, /* set CAFile used to generate and sign server certs */
7108 { "ca-sign-pass", bind_parse_ca_sign_pass, 1 }, /* set CAKey passphrase */
Nenad Merdanovic05552d42015-02-27 19:56:49 +01007109 { "ciphers", bind_parse_ciphers, 1 }, /* set SSL cipher suite */
7110 { "crl-file", bind_parse_crl_file, 1 }, /* set certificat revocation list file use on client cert verify */
7111 { "crt", bind_parse_crt, 1 }, /* load SSL certificates from this location */
7112 { "crt-ignore-err", bind_parse_ignore_err, 1 }, /* set error IDs to ingore on verify depth == 0 */
7113 { "crt-list", bind_parse_crt_list, 1 }, /* load a list of crt from this location */
Emmanuel Hocdete7f2b732017-01-09 16:15:54 +01007114 { "curves", bind_parse_curves, 1 }, /* set SSL curve suite */
Nenad Merdanovic05552d42015-02-27 19:56:49 +01007115 { "ecdhe", bind_parse_ecdhe, 1 }, /* defines named curve for elliptic curve Diffie-Hellman */
7116 { "force-sslv3", bind_parse_force_sslv3, 0 }, /* force SSLv3 */
7117 { "force-tlsv10", bind_parse_force_tlsv10, 0 }, /* force TLSv10 */
7118 { "force-tlsv11", bind_parse_force_tlsv11, 0 }, /* force TLSv11 */
7119 { "force-tlsv12", bind_parse_force_tlsv12, 0 }, /* force TLSv12 */
Christopher Faulet31af49d2015-06-09 17:29:50 +02007120 { "generate-certificates", bind_parse_generate_certs, 0 }, /* enable the server certificates generation */
Nenad Merdanovic05552d42015-02-27 19:56:49 +01007121 { "no-sslv3", bind_parse_no_sslv3, 0 }, /* disable SSLv3 */
7122 { "no-tlsv10", bind_parse_no_tlsv10, 0 }, /* disable TLSv10 */
7123 { "no-tlsv11", bind_parse_no_tlsv11, 0 }, /* disable TLSv11 */
7124 { "no-tlsv12", bind_parse_no_tlsv12, 0 }, /* disable TLSv12 */
7125 { "no-tls-tickets", bind_parse_no_tls_tickets, 0 }, /* disable session resumption tickets */
7126 { "ssl", bind_parse_ssl, 0 }, /* enable SSL processing */
7127 { "strict-sni", bind_parse_strict_sni, 0 }, /* refuse negotiation if sni doesn't match a certificate */
7128 { "tls-ticket-keys", bind_parse_tls_ticket_keys, 1 }, /* set file to load TLS ticket keys from */
7129 { "verify", bind_parse_verify, 1 }, /* set SSL verify method */
7130 { "npn", bind_parse_npn, 1 }, /* set NPN supported protocols */
Willy Tarreau79eeafa2012-09-14 07:53:05 +02007131 { NULL, NULL, 0 },
7132}};
Emeric Brun46591952012-05-18 15:47:34 +02007133
Willy Tarreau92faadf2012-10-10 23:04:25 +02007134/* Note: must not be declared <const> as its list will be overwritten.
7135 * Please take care of keeping this list alphabetically sorted, doing so helps
7136 * all code contributors.
7137 * Optional keywords are also declared with a NULL ->parse() function so that
7138 * the config parser can report an appropriate error when a known keyword was
7139 * not enabled.
7140 */
7141static struct srv_kw_list srv_kws = { "SSL", { }, {
Emeric Brunef42d922012-10-11 16:11:36 +02007142 { "ca-file", srv_parse_ca_file, 1, 0 }, /* set CAfile to process verify server cert */
Emeric Brunecc91fe2012-10-11 15:05:10 +02007143 { "check-ssl", srv_parse_check_ssl, 0, 0 }, /* enable SSL for health checks */
7144 { "ciphers", srv_parse_ciphers, 1, 0 }, /* select the cipher suite */
Emeric Brunef42d922012-10-11 16:11:36 +02007145 { "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 +02007146 { "crt", srv_parse_crt, 1, 0 }, /* set client certificate */
Emeric Brunecc91fe2012-10-11 15:05:10 +02007147 { "force-sslv3", srv_parse_force_sslv3, 0, 0 }, /* force SSLv3 */
7148 { "force-tlsv10", srv_parse_force_tlsv10, 0, 0 }, /* force TLSv10 */
7149 { "force-tlsv11", srv_parse_force_tlsv11, 0, 0 }, /* force TLSv11 */
7150 { "force-tlsv12", srv_parse_force_tlsv12, 0, 0 }, /* force TLSv12 */
Willy Tarreau2a3fb1c2015-02-05 16:47:07 +01007151 { "no-ssl-reuse", srv_parse_no_ssl_reuse, 0, 0 }, /* disable session reuse */
Emeric Brunecc91fe2012-10-11 15:05:10 +02007152 { "no-sslv3", srv_parse_no_sslv3, 0, 0 }, /* disable SSLv3 */
7153 { "no-tlsv10", srv_parse_no_tlsv10, 0, 0 }, /* disable TLSv10 */
7154 { "no-tlsv11", srv_parse_no_tlsv11, 0, 0 }, /* disable TLSv11 */
7155 { "no-tlsv12", srv_parse_no_tlsv12, 0, 0 }, /* disable TLSv12 */
Emeric Brunf9c5c472012-10-11 15:28:34 +02007156 { "no-tls-tickets", srv_parse_no_tls_tickets, 0, 0 }, /* disable session resumption tickets */
David Safb76832014-05-08 23:42:08 -04007157 { "send-proxy-v2-ssl", srv_parse_send_proxy_ssl, 0, 0 }, /* send PROXY protocol header v2 with SSL info */
7158 { "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 +02007159 { "sni", srv_parse_sni, 1, 0 }, /* send SNI extension */
Emeric Brunecc91fe2012-10-11 15:05:10 +02007160 { "ssl", srv_parse_ssl, 0, 0 }, /* enable SSL processing */
Emeric Brunef42d922012-10-11 16:11:36 +02007161 { "verify", srv_parse_verify, 1, 0 }, /* set SSL verify method */
Evan Broderbe554312013-06-27 00:05:25 -07007162 { "verifyhost", srv_parse_verifyhost, 1, 0 }, /* require that SSL cert verifies for hostname */
Willy Tarreau92faadf2012-10-10 23:04:25 +02007163 { NULL, NULL, 0, 0 },
7164}};
7165
Emeric Brun2c86cbf2014-10-30 15:56:50 +01007166static struct cfg_kw_list cfg_kws = {ILH, {
Willy Tarreau8c3b0fd2016-12-21 22:44:46 +01007167 { CFG_GLOBAL, "ca-base", ssl_parse_global_ca_crt_base },
7168 { CFG_GLOBAL, "crt-base", ssl_parse_global_ca_crt_base },
Willy Tarreau0bea58d2016-12-21 23:17:25 +01007169 { CFG_GLOBAL, "maxsslconn", ssl_parse_global_int },
Emeric Brun2c86cbf2014-10-30 15:56:50 +01007170 { CFG_GLOBAL, "ssl-default-bind-options", ssl_parse_default_bind_options },
7171 { CFG_GLOBAL, "ssl-default-server-options", ssl_parse_default_server_options },
Willy Tarreau14e36a12016-12-21 23:28:13 +01007172#ifndef OPENSSL_NO_DH
7173 { CFG_GLOBAL, "ssl-dh-param-file", ssl_parse_global_dh_param_file },
7174#endif
Willy Tarreau9ceda382016-12-21 23:13:03 +01007175 { CFG_GLOBAL, "tune.ssl.cachesize", ssl_parse_global_int },
7176#ifndef OPENSSL_NO_DH
7177 { CFG_GLOBAL, "tune.ssl.default-dh-param", ssl_parse_global_default_dh },
7178#endif
7179 { CFG_GLOBAL, "tune.ssl.force-private-cache", ssl_parse_global_private_cache },
7180 { CFG_GLOBAL, "tune.ssl.lifetime", ssl_parse_global_lifetime },
7181 { CFG_GLOBAL, "tune.ssl.maxrecord", ssl_parse_global_int },
7182 { CFG_GLOBAL, "tune.ssl.ssl-ctx-cache-size", ssl_parse_global_int },
Willy Tarreauf22e9682016-12-21 23:23:19 +01007183 { CFG_GLOBAL, "ssl-default-bind-ciphers", ssl_parse_global_ciphers },
7184 { CFG_GLOBAL, "ssl-default-server-ciphers", ssl_parse_global_ciphers },
Emeric Brun2c86cbf2014-10-30 15:56:50 +01007185 { 0, NULL, NULL },
7186}};
7187
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02007188/* transport-layer operations for SSL sockets */
Willy Tarreaud9f5cca2016-12-22 21:08:52 +01007189static struct xprt_ops ssl_sock = {
Emeric Brun46591952012-05-18 15:47:34 +02007190 .snd_buf = ssl_sock_from_buf,
7191 .rcv_buf = ssl_sock_to_buf,
7192 .rcv_pipe = NULL,
7193 .snd_pipe = NULL,
7194 .shutr = NULL,
7195 .shutw = ssl_sock_shutw,
7196 .close = ssl_sock_close,
7197 .init = ssl_sock_init,
Willy Tarreau55d37912016-12-21 23:38:39 +01007198 .prepare_bind_conf = ssl_sock_prepare_bind_conf,
Willy Tarreau795cdab2016-12-22 17:30:54 +01007199 .destroy_bind_conf = ssl_sock_destroy_bind_conf,
Willy Tarreau17d45382016-12-22 21:16:08 +01007200 .prepare_srv = ssl_sock_prepare_srv_ctx,
7201 .destroy_srv = ssl_sock_free_srv_ctx,
Willy Tarreau8e0bb0a2016-11-24 16:58:12 +01007202 .name = "SSL",
Emeric Brun46591952012-05-18 15:47:34 +02007203};
7204
Daniel Jakots54ffb912015-11-06 20:02:41 +01007205#if (OPENSSL_VERSION_NUMBER >= 0x1000200fL && !defined OPENSSL_NO_TLSEXT && !defined OPENSSL_IS_BORINGSSL && !defined LIBRESSL_VERSION_NUMBER)
Janusz Dziemidowicz2c701b52015-03-07 23:03:59 +01007206
7207static void ssl_sock_sctl_free_func(void *parent, void *ptr, CRYPTO_EX_DATA *ad, int idx, long argl, void *argp)
7208{
7209 if (ptr) {
7210 chunk_destroy(ptr);
7211 free(ptr);
7212 }
7213}
7214
7215#endif
7216
Emeric Brun46591952012-05-18 15:47:34 +02007217__attribute__((constructor))
Willy Tarreau92faadf2012-10-10 23:04:25 +02007218static void __ssl_sock_init(void)
7219{
Willy Tarreauc2c0b612016-12-21 19:23:20 +01007220 char *ptr;
7221
Emeric Brun46591952012-05-18 15:47:34 +02007222 STACK_OF(SSL_COMP)* cm;
7223
Willy Tarreauef934602016-12-22 23:12:01 +01007224 if (global_ssl.listen_default_ciphers)
7225 global_ssl.listen_default_ciphers = strdup(global_ssl.listen_default_ciphers);
7226 if (global_ssl.connect_default_ciphers)
7227 global_ssl.connect_default_ciphers = strdup(global_ssl.connect_default_ciphers);
Willy Tarreau610f04b2014-02-13 11:36:41 +01007228
Willy Tarreau13e14102016-12-22 20:25:26 +01007229 xprt_register(XPRT_SSL, &ssl_sock);
Emeric Brun46591952012-05-18 15:47:34 +02007230 SSL_library_init();
7231 cm = SSL_COMP_get_compression_methods();
7232 sk_SSL_COMP_zero(cm);
Daniel Jakots54ffb912015-11-06 20:02:41 +01007233#if (OPENSSL_VERSION_NUMBER >= 0x1000200fL && !defined OPENSSL_NO_TLSEXT && !defined OPENSSL_IS_BORINGSSL && !defined LIBRESSL_VERSION_NUMBER)
Janusz Dziemidowicz2c701b52015-03-07 23:03:59 +01007234 sctl_ex_index = SSL_CTX_get_ex_new_index(0, NULL, NULL, NULL, ssl_sock_sctl_free_func);
7235#endif
Willy Tarreau7875d092012-09-10 08:20:03 +02007236 sample_register_fetches(&sample_fetch_keywords);
7237 acl_register_keywords(&acl_kws);
Willy Tarreau79eeafa2012-09-14 07:53:05 +02007238 bind_register_keywords(&bind_kws);
Willy Tarreau92faadf2012-10-10 23:04:25 +02007239 srv_register_keywords(&srv_kws);
Emeric Brun2c86cbf2014-10-30 15:56:50 +01007240 cfg_register_keywords(&cfg_kws);
William Lallemand32af2032016-10-29 18:09:35 +02007241 cli_register_kw(&cli_kws);
Willy Tarreaud1c57502016-12-22 22:46:15 +01007242#if (defined SSL_CTRL_SET_TLSEXT_TICKET_KEY_CB && TLS_TICKETS_NO > 0)
7243 hap_register_post_check(tlskeys_finalize_config);
7244#endif
Willy Tarreaud92aa5c2015-01-15 21:34:39 +01007245
Willy Tarreauc2c0b612016-12-21 19:23:20 +01007246 ptr = NULL;
7247 memprintf(&ptr, "Built with OpenSSL version : "
7248#ifdef OPENSSL_IS_BORINGSSL
7249 "BoringSSL\n");
7250#else /* OPENSSL_IS_BORINGSSL */
7251 OPENSSL_VERSION_TEXT
7252 "\nRunning on OpenSSL version : %s%s",
7253 SSLeay_version(SSLEAY_VERSION),
7254 ((OPENSSL_VERSION_NUMBER ^ SSLeay()) >> 8) ? " (VERSIONS DIFFER!)" : "");
7255#endif
7256 memprintf(&ptr, "%s\nOpenSSL library supports TLS extensions : "
7257#if OPENSSL_VERSION_NUMBER < 0x00907000L
7258 "no (library version too old)"
7259#elif defined(OPENSSL_NO_TLSEXT)
7260 "no (disabled via OPENSSL_NO_TLSEXT)"
7261#else
7262 "yes"
7263#endif
7264 "", ptr);
7265
7266 memprintf(&ptr, "%s\nOpenSSL library supports SNI : "
7267#ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME
7268 "yes"
7269#else
7270#ifdef OPENSSL_NO_TLSEXT
7271 "no (because of OPENSSL_NO_TLSEXT)"
7272#else
7273 "no (version might be too old, 0.9.8f min needed)"
7274#endif
7275#endif
7276 "", ptr);
7277
Willy Tarreauc2c0b612016-12-21 19:23:20 +01007278 hap_register_build_opts(ptr, 1);
7279
Willy Tarreaud92aa5c2015-01-15 21:34:39 +01007280 global.ssl_session_max_cost = SSL_SESSION_MAX_COST;
7281 global.ssl_handshake_max_cost = SSL_HANDSHAKE_MAX_COST;
Remi Gacogne4f902b82015-05-28 16:23:00 +02007282
7283#ifndef OPENSSL_NO_DH
7284 ssl_dh_ptr_index = SSL_CTX_get_ex_new_index(0, NULL, NULL, NULL, NULL);
7285#endif
Thierry FOURNIER / OZON.IO8b068c22016-10-10 11:59:50 +02007286
7287 /* Load SSL string for the verbose & debug mode. */
7288 ERR_load_SSL_strings();
Emeric Brun46591952012-05-18 15:47:34 +02007289}
7290
Remi Gacogned3a23c32015-05-28 16:39:47 +02007291__attribute__((destructor))
7292static void __ssl_sock_deinit(void)
7293{
Emmanuel Hocdetfdec7892017-01-13 17:48:18 +01007294#if (defined SSL_CTRL_SET_TLSEXT_HOSTNAME && !defined SSL_NO_GENERATE_CERTIFICATES)
Christopher Faulet31af49d2015-06-09 17:29:50 +02007295 lru64_destroy(ssl_ctx_lru_tree);
Willy Tarreaua84c2672015-10-09 12:10:13 +02007296#endif
Christopher Faulet31af49d2015-06-09 17:29:50 +02007297
Remi Gacogned3a23c32015-05-28 16:39:47 +02007298#ifndef OPENSSL_NO_DH
7299 if (local_dh_1024) {
7300 DH_free(local_dh_1024);
7301 local_dh_1024 = NULL;
7302 }
7303
7304 if (local_dh_2048) {
7305 DH_free(local_dh_2048);
7306 local_dh_2048 = NULL;
7307 }
7308
7309 if (local_dh_4096) {
7310 DH_free(local_dh_4096);
7311 local_dh_4096 = NULL;
7312 }
7313
Remi Gacogne47783ef2015-05-29 15:53:22 +02007314 if (global_dh) {
7315 DH_free(global_dh);
7316 global_dh = NULL;
7317 }
Remi Gacogned3a23c32015-05-28 16:39:47 +02007318#endif
7319
7320 ERR_remove_state(0);
7321 ERR_free_strings();
7322
7323 EVP_cleanup();
7324
7325#if OPENSSL_VERSION_NUMBER >= 0x00907000L
7326 CRYPTO_cleanup_all_ex_data();
7327#endif
7328}
7329
7330
Emeric Brun46591952012-05-18 15:47:34 +02007331/*
7332 * Local variables:
7333 * c-indent-level: 8
7334 * c-basic-offset: 8
7335 * End:
7336 */