blob: 3705917a8fd6213f5ad7392813eabd1d22a6a035 [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
Willy Tarreauc8ad3be2015-06-17 15:48:26 +0200179#ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME
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};
196
197/* LRU cache to store generated certificate */
198static struct lru64_head *ssl_ctx_lru_tree = NULL;
199static unsigned int ssl_ctx_lru_seed = 0;
Willy Tarreauc8ad3be2015-06-17 15:48:26 +0200200#endif // SSL_CTRL_SET_TLSEXT_HOSTNAME
201
yanbzhube2774d2015-12-10 15:07:30 -0500202#if OPENSSL_VERSION_NUMBER >= 0x1000200fL
203/* The order here matters for picking a default context,
204 * keep the most common keytype at the bottom of the list
205 */
206const char *SSL_SOCK_KEYTYPE_NAMES[] = {
207 "dsa",
208 "ecdsa",
209 "rsa"
210};
211#define SSL_SOCK_NUM_KEYTYPES 3
Willy Tarreau30da7ad2015-12-14 11:28:33 +0100212#else
213#define SSL_SOCK_NUM_KEYTYPES 1
yanbzhube2774d2015-12-10 15:07:30 -0500214#endif
215
Willy Tarreauc8ad3be2015-06-17 15:48:26 +0200216#if (defined SSL_CTRL_SET_TLSEXT_STATUS_REQ_CB && !defined OPENSSL_NO_OCSP)
yanbzhube2774d2015-12-10 15:07:30 -0500217/*
218 * struct alignment works here such that the key.key is the same as key_data
219 * Do not change the placement of key_data
220 */
Willy Tarreauc8ad3be2015-06-17 15:48:26 +0200221struct certificate_ocsp {
222 struct ebmb_node key;
223 unsigned char key_data[OCSP_MAX_CERTID_ASN1_LENGTH];
224 struct chunk response;
225 long expire;
226};
Christopher Faulet31af49d2015-06-09 17:29:50 +0200227
yanbzhube2774d2015-12-10 15:07:30 -0500228struct ocsp_cbk_arg {
229 int is_single;
230 int single_kt;
231 union {
232 struct certificate_ocsp *s_ocsp;
233 /*
234 * m_ocsp will have multiple entries dependent on key type
235 * Entry 0 - DSA
236 * Entry 1 - ECDSA
237 * Entry 2 - RSA
238 */
239 struct certificate_ocsp *m_ocsp[SSL_SOCK_NUM_KEYTYPES];
240 };
241};
242
Emeric Brun4f3c87a2014-06-20 15:46:13 +0200243/*
Thierry FOURNIER / OZON.IO8b068c22016-10-10 11:59:50 +0200244 * This function gives the detail of the SSL error. It is used only
245 * if the debug mode and the verbose mode are activated. It dump all
246 * the SSL error until the stack was empty.
247 */
248static forceinline void ssl_sock_dump_errors(struct connection *conn)
249{
250 unsigned long ret;
251
252 if (unlikely(global.mode & MODE_DEBUG)) {
253 while(1) {
254 ret = ERR_get_error();
255 if (ret == 0)
256 return;
257 fprintf(stderr, "fd[%04x] OpenSSL error[0x%lx] %s: %s\n",
258 (unsigned short)conn->t.sock.fd, ret,
259 ERR_func_error_string(ret), ERR_reason_error_string(ret));
260 }
261 }
262}
263
264/*
Emeric Brun4f3c87a2014-06-20 15:46:13 +0200265 * This function returns the number of seconds elapsed
266 * since the Epoch, 1970-01-01 00:00:00 +0000 (UTC) and the
267 * date presented un ASN1_GENERALIZEDTIME.
268 *
269 * In parsing error case, it returns -1.
270 */
271static long asn1_generalizedtime_to_epoch(ASN1_GENERALIZEDTIME *d)
272{
273 long epoch;
274 char *p, *end;
275 const unsigned short month_offset[12] = {
276 0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334
277 };
278 int year, month;
279
280 if (!d || (d->type != V_ASN1_GENERALIZEDTIME)) return -1;
281
282 p = (char *)d->data;
283 end = p + d->length;
284
285 if (end - p < 4) return -1;
286 year = 1000 * (p[0] - '0') + 100 * (p[1] - '0') + 10 * (p[2] - '0') + p[3] - '0';
287 p += 4;
288 if (end - p < 2) return -1;
289 month = 10 * (p[0] - '0') + p[1] - '0';
290 if (month < 1 || month > 12) return -1;
291 /* Compute the number of seconds since 1 jan 1970 and the beginning of current month
292 We consider leap years and the current month (<marsh or not) */
293 epoch = ( ((year - 1970) * 365)
294 + ((year - (month < 3)) / 4 - (year - (month < 3)) / 100 + (year - (month < 3)) / 400)
295 - ((1970 - 1) / 4 - (1970 - 1) / 100 + (1970 - 1) / 400)
296 + month_offset[month-1]
297 ) * 24 * 60 * 60;
298 p += 2;
299 if (end - p < 2) return -1;
300 /* Add the number of seconds of completed days of current month */
301 epoch += (10 * (p[0] - '0') + p[1] - '0' - 1) * 24 * 60 * 60;
302 p += 2;
303 if (end - p < 2) return -1;
304 /* Add the completed hours of the current day */
305 epoch += (10 * (p[0] - '0') + p[1] - '0') * 60 * 60;
306 p += 2;
307 if (end - p < 2) return -1;
308 /* Add the completed minutes of the current hour */
309 epoch += (10 * (p[0] - '0') + p[1] - '0') * 60;
310 p += 2;
311 if (p == end) return -1;
312 /* Test if there is available seconds */
313 if (p[0] < '0' || p[0] > '9')
314 goto nosec;
315 if (end - p < 2) return -1;
316 /* Add the seconds of the current minute */
317 epoch += 10 * (p[0] - '0') + p[1] - '0';
318 p += 2;
319 if (p == end) return -1;
320 /* Ignore seconds float part if present */
321 if (p[0] == '.') {
322 do {
323 if (++p == end) return -1;
324 } while (p[0] >= '0' && p[0] <= '9');
325 }
326
327nosec:
328 if (p[0] == 'Z') {
329 if (end - p != 1) return -1;
330 return epoch;
331 }
332 else if (p[0] == '+') {
333 if (end - p != 5) return -1;
334 /* Apply timezone offset */
335 return epoch - ((10 * (p[1] - '0') + p[2] - '0') * 60 + (10 * (p[3] - '0') + p[4] - '0')) * 60;
336 }
337 else if (p[0] == '-') {
338 if (end - p != 5) return -1;
339 /* Apply timezone offset */
340 return epoch + ((10 * (p[1] - '0') + p[2] - '0') * 60 + (10 * (p[3] - '0') + p[4] - '0')) * 60;
341 }
342
343 return -1;
344}
345
Emeric Brun1d3865b2014-06-20 15:37:32 +0200346static struct eb_root cert_ocsp_tree = EB_ROOT_UNIQUE;
Emeric Brun4147b2e2014-06-16 18:36:30 +0200347
348/* This function starts to check if the OCSP response (in DER format) contained
349 * in chunk 'ocsp_response' is valid (else exits on error).
350 * If 'cid' is not NULL, it will be compared to the OCSP certificate ID
351 * contained in the OCSP Response and exits on error if no match.
352 * If it's a valid OCSP Response:
353 * If 'ocsp' is not NULL, the chunk is copied in the OCSP response's container
354 * pointed by 'ocsp'.
355 * If 'ocsp' is NULL, the function looks up into the OCSP response's
356 * containers tree (using as index the ASN1 form of the OCSP Certificate ID extracted
357 * from the response) and exits on error if not found. Finally, If an OCSP response is
358 * already present in the container, it will be overwritten.
359 *
360 * Note: OCSP response containing more than one OCSP Single response is not
361 * considered valid.
362 *
363 * Returns 0 on success, 1 in error case.
364 */
365static int ssl_sock_load_ocsp_response(struct chunk *ocsp_response, struct certificate_ocsp *ocsp, OCSP_CERTID *cid, char **err)
366{
367 OCSP_RESPONSE *resp;
368 OCSP_BASICRESP *bs = NULL;
369 OCSP_SINGLERESP *sr;
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +0200370 OCSP_CERTID *id;
Emeric Brun4147b2e2014-06-16 18:36:30 +0200371 unsigned char *p = (unsigned char *)ocsp_response->str;
372 int rc , count_sr;
Emeric Brun13a6b482014-06-20 15:44:34 +0200373 ASN1_GENERALIZEDTIME *revtime, *thisupd, *nextupd = NULL;
Emeric Brun4147b2e2014-06-16 18:36:30 +0200374 int reason;
375 int ret = 1;
376
377 resp = d2i_OCSP_RESPONSE(NULL, (const unsigned char **)&p, ocsp_response->len);
378 if (!resp) {
379 memprintf(err, "Unable to parse OCSP response");
380 goto out;
381 }
382
383 rc = OCSP_response_status(resp);
384 if (rc != OCSP_RESPONSE_STATUS_SUCCESSFUL) {
385 memprintf(err, "OCSP response status not successful");
386 goto out;
387 }
388
389 bs = OCSP_response_get1_basic(resp);
390 if (!bs) {
391 memprintf(err, "Failed to get basic response from OCSP Response");
392 goto out;
393 }
394
395 count_sr = OCSP_resp_count(bs);
396 if (count_sr > 1) {
397 memprintf(err, "OCSP response ignored because contains multiple single responses (%d)", count_sr);
398 goto out;
399 }
400
401 sr = OCSP_resp_get0(bs, 0);
402 if (!sr) {
403 memprintf(err, "Failed to get OCSP single response");
404 goto out;
405 }
406
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +0200407 id = (OCSP_CERTID*)OCSP_SINGLERESP_get0_id(sr);
408
Emeric Brun4147b2e2014-06-16 18:36:30 +0200409 rc = OCSP_single_get0_status(sr, &reason, &revtime, &thisupd, &nextupd);
410 if (rc != V_OCSP_CERTSTATUS_GOOD) {
411 memprintf(err, "OCSP single response: certificate status not good");
412 goto out;
413 }
414
Emeric Brun13a6b482014-06-20 15:44:34 +0200415 if (!nextupd) {
416 memprintf(err, "OCSP single response: missing nextupdate");
417 goto out;
418 }
419
Emeric Brunc8b27b62014-06-19 14:16:17 +0200420 rc = OCSP_check_validity(thisupd, nextupd, OCSP_MAX_RESPONSE_TIME_SKEW, -1);
Emeric Brun4147b2e2014-06-16 18:36:30 +0200421 if (!rc) {
422 memprintf(err, "OCSP single response: no longer valid.");
423 goto out;
424 }
425
426 if (cid) {
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +0200427 if (OCSP_id_cmp(id, cid)) {
Emeric Brun4147b2e2014-06-16 18:36:30 +0200428 memprintf(err, "OCSP single response: Certificate ID does not match certificate and issuer");
429 goto out;
430 }
431 }
432
433 if (!ocsp) {
434 unsigned char key[OCSP_MAX_CERTID_ASN1_LENGTH];
435 unsigned char *p;
436
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +0200437 rc = i2d_OCSP_CERTID(id, NULL);
Emeric Brun4147b2e2014-06-16 18:36:30 +0200438 if (!rc) {
439 memprintf(err, "OCSP single response: Unable to encode Certificate ID");
440 goto out;
441 }
442
443 if (rc > OCSP_MAX_CERTID_ASN1_LENGTH) {
444 memprintf(err, "OCSP single response: Certificate ID too long");
445 goto out;
446 }
447
448 p = key;
449 memset(key, 0, OCSP_MAX_CERTID_ASN1_LENGTH);
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +0200450 i2d_OCSP_CERTID(id, &p);
Emeric Brun4147b2e2014-06-16 18:36:30 +0200451 ocsp = (struct certificate_ocsp *)ebmb_lookup(&cert_ocsp_tree, key, OCSP_MAX_CERTID_ASN1_LENGTH);
452 if (!ocsp) {
453 memprintf(err, "OCSP single response: Certificate ID does not match any certificate or issuer");
454 goto out;
455 }
456 }
457
458 /* According to comments on "chunk_dup", the
459 previous chunk buffer will be freed */
460 if (!chunk_dup(&ocsp->response, ocsp_response)) {
461 memprintf(err, "OCSP response: Memory allocation error");
462 goto out;
463 }
464
Emeric Brun4f3c87a2014-06-20 15:46:13 +0200465 ocsp->expire = asn1_generalizedtime_to_epoch(nextupd) - OCSP_MAX_RESPONSE_TIME_SKEW;
466
Emeric Brun4147b2e2014-06-16 18:36:30 +0200467 ret = 0;
468out:
469 if (bs)
470 OCSP_BASICRESP_free(bs);
471
472 if (resp)
473 OCSP_RESPONSE_free(resp);
474
475 return ret;
476}
477/*
478 * External function use to update the OCSP response in the OCSP response's
479 * containers tree. The chunk 'ocsp_response' must contain the OCSP response
480 * to update in DER format.
481 *
482 * Returns 0 on success, 1 in error case.
483 */
484int ssl_sock_update_ocsp_response(struct chunk *ocsp_response, char **err)
485{
486 return ssl_sock_load_ocsp_response(ocsp_response, NULL, NULL, err);
487}
488
489/*
490 * This function load the OCSP Resonse in DER format contained in file at
491 * path 'ocsp_path' and call 'ssl_sock_load_ocsp_response'
492 *
493 * Returns 0 on success, 1 in error case.
494 */
495static int ssl_sock_load_ocsp_response_from_file(const char *ocsp_path, struct certificate_ocsp *ocsp, OCSP_CERTID *cid, char **err)
496{
497 int fd = -1;
498 int r = 0;
499 int ret = 1;
500
501 fd = open(ocsp_path, O_RDONLY);
502 if (fd == -1) {
503 memprintf(err, "Error opening OCSP response file");
504 goto end;
505 }
506
507 trash.len = 0;
508 while (trash.len < trash.size) {
509 r = read(fd, trash.str + trash.len, trash.size - trash.len);
510 if (r < 0) {
511 if (errno == EINTR)
512 continue;
513
514 memprintf(err, "Error reading OCSP response from file");
515 goto end;
516 }
517 else if (r == 0) {
518 break;
519 }
520 trash.len += r;
521 }
522
523 close(fd);
524 fd = -1;
525
526 ret = ssl_sock_load_ocsp_response(&trash, ocsp, cid, err);
527end:
528 if (fd != -1)
529 close(fd);
530
531 return ret;
532}
533
Nenad Merdanovic05552d42015-02-27 19:56:49 +0100534#if (defined SSL_CTRL_SET_TLSEXT_TICKET_KEY_CB && TLS_TICKETS_NO > 0)
535static 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)
536{
537 struct tls_sess_key *keys;
538 struct connection *conn;
539 int head;
540 int i;
541
Vincent Bernat3c2f2f22016-04-03 13:48:42 +0200542 conn = SSL_get_app_data(s);
Nenad Merdanovic146defa2015-05-09 08:46:00 +0200543 keys = objt_listener(conn->target)->bind_conf->keys_ref->tlskeys;
544 head = objt_listener(conn->target)->bind_conf->keys_ref->tls_ticket_enc_index;
Nenad Merdanovic05552d42015-02-27 19:56:49 +0100545
546 if (enc) {
547 memcpy(key_name, keys[head].name, 16);
548
549 if(!RAND_pseudo_bytes(iv, EVP_MAX_IV_LENGTH))
550 return -1;
551
552 if(!EVP_EncryptInit_ex(ectx, EVP_aes_128_cbc(), NULL, keys[head].aes_key, iv))
553 return -1;
554
555 HMAC_Init_ex(hctx, keys[head].hmac_key, 16, HASH_FUNCT(), NULL);
556
557 return 1;
558 } else {
559 for (i = 0; i < TLS_TICKETS_NO; i++) {
560 if (!memcmp(key_name, keys[(head + i) % TLS_TICKETS_NO].name, 16))
561 goto found;
562 }
563 return 0;
564
565 found:
566 HMAC_Init_ex(hctx, keys[(head + i) % TLS_TICKETS_NO].hmac_key, 16, HASH_FUNCT(), NULL);
567 if(!EVP_DecryptInit_ex(ectx, EVP_aes_128_cbc(), NULL, keys[(head + i) % TLS_TICKETS_NO].aes_key, iv))
568 return -1;
569 /* 2 for key renewal, 1 if current key is still valid */
570 return i ? 2 : 1;
571 }
Nenad Merdanovic200b0fa2015-05-09 08:46:01 +0200572}
573
574struct tls_keys_ref *tlskeys_ref_lookup(const char *filename)
575{
576 struct tls_keys_ref *ref;
577
578 list_for_each_entry(ref, &tlskeys_reference, list)
579 if (ref->filename && strcmp(filename, ref->filename) == 0)
580 return ref;
581 return NULL;
582}
583
584struct tls_keys_ref *tlskeys_ref_lookupid(int unique_id)
585{
586 struct tls_keys_ref *ref;
587
588 list_for_each_entry(ref, &tlskeys_reference, list)
589 if (ref->unique_id == unique_id)
590 return ref;
591 return NULL;
592}
593
594int ssl_sock_update_tlskey(char *filename, struct chunk *tlskey, char **err) {
595 struct tls_keys_ref *ref = tlskeys_ref_lookup(filename);
596
597 if(!ref) {
598 memprintf(err, "Unable to locate the referenced filename: %s", filename);
599 return 1;
600 }
601
Pradeep Jindalcc79b002015-08-20 18:25:17 +0530602 memcpy((char *) (ref->tlskeys + ((ref->tls_ticket_enc_index + 2) % TLS_TICKETS_NO)), tlskey->str, tlskey->len);
603 ref->tls_ticket_enc_index = (ref->tls_ticket_enc_index + 1) % TLS_TICKETS_NO;
Nenad Merdanovic200b0fa2015-05-09 08:46:01 +0200604
605 return 0;
Nenad Merdanovic05552d42015-02-27 19:56:49 +0100606}
Nenad Merdanovic200b0fa2015-05-09 08:46:01 +0200607
608/* This function finalize the configuration parsing. Its set all the
Willy Tarreaud1c57502016-12-22 22:46:15 +0100609 * automatic ids. It's called just after the basic checks. It returns
610 * 0 on success otherwise ERR_*.
Nenad Merdanovic200b0fa2015-05-09 08:46:01 +0200611 */
Willy Tarreaud1c57502016-12-22 22:46:15 +0100612static int tlskeys_finalize_config(void)
Nenad Merdanovic200b0fa2015-05-09 08:46:01 +0200613{
614 int i = 0;
615 struct tls_keys_ref *ref, *ref2, *ref3;
616 struct list tkr = LIST_HEAD_INIT(tkr);
617
618 list_for_each_entry(ref, &tlskeys_reference, list) {
619 if (ref->unique_id == -1) {
620 /* Look for the first free id. */
621 while (1) {
622 list_for_each_entry(ref2, &tlskeys_reference, list) {
623 if (ref2->unique_id == i) {
624 i++;
625 break;
626 }
627 }
628 if (&ref2->list == &tlskeys_reference)
629 break;
630 }
631
632 /* Uses the unique id and increment it for the next entry. */
633 ref->unique_id = i;
634 i++;
635 }
636 }
637
638 /* This sort the reference list by id. */
639 list_for_each_entry_safe(ref, ref2, &tlskeys_reference, list) {
640 LIST_DEL(&ref->list);
641 list_for_each_entry(ref3, &tkr, list) {
642 if (ref->unique_id < ref3->unique_id) {
643 LIST_ADDQ(&ref3->list, &ref->list);
644 break;
645 }
646 }
647 if (&ref3->list == &tkr)
648 LIST_ADDQ(&tkr, &ref->list);
649 }
650
651 /* swap root */
652 LIST_ADD(&tkr, &tlskeys_reference);
653 LIST_DEL(&tkr);
Willy Tarreaud1c57502016-12-22 22:46:15 +0100654 return 0;
Nenad Merdanovic200b0fa2015-05-09 08:46:01 +0200655}
656
Nenad Merdanovic05552d42015-02-27 19:56:49 +0100657#endif /* SSL_CTRL_SET_TLSEXT_TICKET_KEY_CB */
658
yanbzhube2774d2015-12-10 15:07:30 -0500659int ssl_sock_get_ocsp_arg_kt_index(int evp_keytype)
660{
661 switch (evp_keytype) {
662 case EVP_PKEY_RSA:
663 return 2;
664 case EVP_PKEY_DSA:
665 return 0;
666 case EVP_PKEY_EC:
667 return 1;
668 }
669
670 return -1;
671}
672
Emeric Brun4147b2e2014-06-16 18:36:30 +0200673/*
674 * Callback used to set OCSP status extension content in server hello.
675 */
676int ssl_sock_ocsp_stapling_cbk(SSL *ssl, void *arg)
677{
yanbzhube2774d2015-12-10 15:07:30 -0500678 struct certificate_ocsp *ocsp;
679 struct ocsp_cbk_arg *ocsp_arg;
680 char *ssl_buf;
681 EVP_PKEY *ssl_pkey;
682 int key_type;
683 int index;
684
Vincent Bernat3c2f2f22016-04-03 13:48:42 +0200685 ocsp_arg = arg;
yanbzhube2774d2015-12-10 15:07:30 -0500686
687 ssl_pkey = SSL_get_privatekey(ssl);
688 if (!ssl_pkey)
689 return SSL_TLSEXT_ERR_NOACK;
690
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +0200691 key_type = EVP_PKEY_base_id(ssl_pkey);
yanbzhube2774d2015-12-10 15:07:30 -0500692
693 if (ocsp_arg->is_single && ocsp_arg->single_kt == key_type)
694 ocsp = ocsp_arg->s_ocsp;
695 else {
696 /* For multiple certs per context, we have to find the correct OCSP response based on
697 * the certificate type
698 */
699 index = ssl_sock_get_ocsp_arg_kt_index(key_type);
700
701 if (index < 0)
702 return SSL_TLSEXT_ERR_NOACK;
703
704 ocsp = ocsp_arg->m_ocsp[index];
705
706 }
Emeric Brun4147b2e2014-06-16 18:36:30 +0200707
708 if (!ocsp ||
709 !ocsp->response.str ||
Emeric Brun4f3c87a2014-06-20 15:46:13 +0200710 !ocsp->response.len ||
711 (ocsp->expire < now.tv_sec))
Emeric Brun4147b2e2014-06-16 18:36:30 +0200712 return SSL_TLSEXT_ERR_NOACK;
713
714 ssl_buf = OPENSSL_malloc(ocsp->response.len);
715 if (!ssl_buf)
716 return SSL_TLSEXT_ERR_NOACK;
717
718 memcpy(ssl_buf, ocsp->response.str, ocsp->response.len);
719 SSL_set_tlsext_status_ocsp_resp(ssl, ssl_buf, ocsp->response.len);
720
721 return SSL_TLSEXT_ERR_OK;
722}
723
724/*
725 * This function enables the handling of OCSP status extension on 'ctx' if a
726 * file name 'cert_path' suffixed using ".ocsp" is present.
727 * To enable OCSP status extension, the issuer's certificate is mandatory.
728 * It should be present in the certificate's extra chain builded from file
729 * 'cert_path'. If not found, the issuer certificate is loaded from a file
730 * named 'cert_path' suffixed using '.issuer'.
731 *
732 * In addition, ".ocsp" file content is loaded as a DER format of an OCSP
733 * response. If file is empty or content is not a valid OCSP response,
734 * OCSP status extension is enabled but OCSP response is ignored (a warning
735 * is displayed).
736 *
737 * Returns 1 if no ".ocsp" file found, 0 if OCSP status extension is
738 * succesfully enabled, or -1 in other error case.
739 */
740static int ssl_sock_load_ocsp(SSL_CTX *ctx, const char *cert_path)
741{
742
743 BIO *in = NULL;
744 X509 *x, *xi = NULL, *issuer = NULL;
745 STACK_OF(X509) *chain = NULL;
746 OCSP_CERTID *cid = NULL;
747 SSL *ssl;
748 char ocsp_path[MAXPATHLEN+1];
749 int i, ret = -1;
750 struct stat st;
751 struct certificate_ocsp *ocsp = NULL, *iocsp;
752 char *warn = NULL;
753 unsigned char *p;
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +0200754 pem_password_cb *passwd_cb;
755 void *passwd_cb_userdata;
756 void (*callback) (void);
Emeric Brun4147b2e2014-06-16 18:36:30 +0200757
758 snprintf(ocsp_path, MAXPATHLEN+1, "%s.ocsp", cert_path);
759
760 if (stat(ocsp_path, &st))
761 return 1;
762
763 ssl = SSL_new(ctx);
764 if (!ssl)
765 goto out;
766
767 x = SSL_get_certificate(ssl);
768 if (!x)
769 goto out;
770
771 /* Try to lookup for issuer in certificate extra chain */
772#ifdef SSL_CTRL_GET_EXTRA_CHAIN_CERTS
773 SSL_CTX_get_extra_chain_certs(ctx, &chain);
774#else
775 chain = ctx->extra_certs;
776#endif
777 for (i = 0; i < sk_X509_num(chain); i++) {
778 issuer = sk_X509_value(chain, i);
779 if (X509_check_issued(issuer, x) == X509_V_OK)
780 break;
781 else
782 issuer = NULL;
783 }
784
785 /* If not found try to load issuer from a suffixed file */
786 if (!issuer) {
787 char issuer_path[MAXPATHLEN+1];
788
789 in = BIO_new(BIO_s_file());
790 if (!in)
791 goto out;
792
793 snprintf(issuer_path, MAXPATHLEN+1, "%s.issuer", cert_path);
794 if (BIO_read_filename(in, issuer_path) <= 0)
795 goto out;
796
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +0200797 passwd_cb = SSL_CTX_get_default_passwd_cb(ctx);
798 passwd_cb_userdata = SSL_CTX_get_default_passwd_cb_userdata(ctx);
799
800 xi = PEM_read_bio_X509_AUX(in, NULL, passwd_cb, passwd_cb_userdata);
Emeric Brun4147b2e2014-06-16 18:36:30 +0200801 if (!xi)
802 goto out;
803
804 if (X509_check_issued(xi, x) != X509_V_OK)
805 goto out;
806
807 issuer = xi;
808 }
809
810 cid = OCSP_cert_to_id(0, x, issuer);
811 if (!cid)
812 goto out;
813
814 i = i2d_OCSP_CERTID(cid, NULL);
815 if (!i || (i > OCSP_MAX_CERTID_ASN1_LENGTH))
816 goto out;
817
Vincent Bernat02779b62016-04-03 13:48:43 +0200818 ocsp = calloc(1, sizeof(*ocsp));
Emeric Brun4147b2e2014-06-16 18:36:30 +0200819 if (!ocsp)
820 goto out;
821
822 p = ocsp->key_data;
823 i2d_OCSP_CERTID(cid, &p);
824
825 iocsp = (struct certificate_ocsp *)ebmb_insert(&cert_ocsp_tree, &ocsp->key, OCSP_MAX_CERTID_ASN1_LENGTH);
826 if (iocsp == ocsp)
827 ocsp = NULL;
828
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +0200829#ifndef SSL_CTX_get_tlsext_status_cb
830# define SSL_CTX_get_tlsext_status_cb(ctx, cb) \
831 *cb = (void (*) (void))ctx->tlsext_status_cb;
832#endif
833 SSL_CTX_get_tlsext_status_cb(ctx, &callback);
834
835 if (!callback) {
Vincent Bernat02779b62016-04-03 13:48:43 +0200836 struct ocsp_cbk_arg *cb_arg = calloc(1, sizeof(*cb_arg));
Emmanuel Hocdetb7a4c342017-01-06 12:57:46 +0100837 EVP_PKEY *pkey;
yanbzhube2774d2015-12-10 15:07:30 -0500838
839 cb_arg->is_single = 1;
840 cb_arg->s_ocsp = iocsp;
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +0200841
Emmanuel Hocdetb7a4c342017-01-06 12:57:46 +0100842 pkey = X509_get_pubkey(x);
843 cb_arg->single_kt = EVP_PKEY_base_id(pkey);
844 EVP_PKEY_free(pkey);
yanbzhube2774d2015-12-10 15:07:30 -0500845
846 SSL_CTX_set_tlsext_status_cb(ctx, ssl_sock_ocsp_stapling_cbk);
847 SSL_CTX_set_tlsext_status_arg(ctx, cb_arg);
848 } else {
849 /*
850 * If the ctx has a status CB, then we have previously set an OCSP staple for this ctx
851 * Update that cb_arg with the new cert's staple
852 */
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +0200853 struct ocsp_cbk_arg *cb_arg;
yanbzhube2774d2015-12-10 15:07:30 -0500854 struct certificate_ocsp *tmp_ocsp;
855 int index;
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +0200856 int key_type;
Emmanuel Hocdetb7a4c342017-01-06 12:57:46 +0100857 EVP_PKEY *pkey;
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +0200858
859#ifdef SSL_CTX_get_tlsext_status_arg
860 SSL_CTX_ctrl(ctx, SSL_CTRL_GET_TLSEXT_STATUS_REQ_CB_ARG, 0, &cb_arg);
861#else
862 cb_arg = ctx->tlsext_status_arg;
863#endif
yanbzhube2774d2015-12-10 15:07:30 -0500864
865 /*
866 * The following few lines will convert cb_arg from a single ocsp to multi ocsp
867 * the order of operations below matter, take care when changing it
868 */
869 tmp_ocsp = cb_arg->s_ocsp;
870 index = ssl_sock_get_ocsp_arg_kt_index(cb_arg->single_kt);
871 cb_arg->s_ocsp = NULL;
872 cb_arg->m_ocsp[index] = tmp_ocsp;
873 cb_arg->is_single = 0;
874 cb_arg->single_kt = 0;
875
Emmanuel Hocdetb7a4c342017-01-06 12:57:46 +0100876 pkey = X509_get_pubkey(x);
877 key_type = EVP_PKEY_base_id(pkey);
878 EVP_PKEY_free(pkey);
879
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +0200880 index = ssl_sock_get_ocsp_arg_kt_index(key_type);
yanbzhube2774d2015-12-10 15:07:30 -0500881 if (index >= 0 && !cb_arg->m_ocsp[index])
882 cb_arg->m_ocsp[index] = iocsp;
883
884 }
Emeric Brun4147b2e2014-06-16 18:36:30 +0200885
886 ret = 0;
887
888 warn = NULL;
889 if (ssl_sock_load_ocsp_response_from_file(ocsp_path, iocsp, cid, &warn)) {
890 memprintf(&warn, "Loading '%s': %s. Content will be ignored", ocsp_path, warn ? warn : "failure");
891 Warning("%s.\n", warn);
892 }
893
894out:
895 if (ssl)
896 SSL_free(ssl);
897
898 if (in)
899 BIO_free(in);
900
901 if (xi)
902 X509_free(xi);
903
904 if (cid)
905 OCSP_CERTID_free(cid);
906
907 if (ocsp)
908 free(ocsp);
909
910 if (warn)
911 free(warn);
912
913
914 return ret;
915}
916
917#endif
918
Daniel Jakots54ffb912015-11-06 20:02:41 +0100919#if (OPENSSL_VERSION_NUMBER >= 0x1000200fL && !defined OPENSSL_NO_TLSEXT && !defined OPENSSL_IS_BORINGSSL && !defined LIBRESSL_VERSION_NUMBER)
Janusz Dziemidowicz2c701b52015-03-07 23:03:59 +0100920
921#define CT_EXTENSION_TYPE 18
922
923static int sctl_ex_index = -1;
924
925/*
926 * Try to parse Signed Certificate Timestamp List structure. This function
927 * makes only basic test if the data seems like SCTL. No signature validation
928 * is performed.
929 */
930static int ssl_sock_parse_sctl(struct chunk *sctl)
931{
932 int ret = 1;
933 int len, pos, sct_len;
934 unsigned char *data;
935
936 if (sctl->len < 2)
937 goto out;
938
939 data = (unsigned char *)sctl->str;
940 len = (data[0] << 8) | data[1];
941
942 if (len + 2 != sctl->len)
943 goto out;
944
945 data = data + 2;
946 pos = 0;
947 while (pos < len) {
948 if (len - pos < 2)
949 goto out;
950
951 sct_len = (data[pos] << 8) | data[pos + 1];
952 if (pos + sct_len + 2 > len)
953 goto out;
954
955 pos += sct_len + 2;
956 }
957
958 ret = 0;
959
960out:
961 return ret;
962}
963
964static int ssl_sock_load_sctl_from_file(const char *sctl_path, struct chunk **sctl)
965{
966 int fd = -1;
967 int r = 0;
968 int ret = 1;
969
970 *sctl = NULL;
971
972 fd = open(sctl_path, O_RDONLY);
973 if (fd == -1)
974 goto end;
975
976 trash.len = 0;
977 while (trash.len < trash.size) {
978 r = read(fd, trash.str + trash.len, trash.size - trash.len);
979 if (r < 0) {
980 if (errno == EINTR)
981 continue;
982
983 goto end;
984 }
985 else if (r == 0) {
986 break;
987 }
988 trash.len += r;
989 }
990
991 ret = ssl_sock_parse_sctl(&trash);
992 if (ret)
993 goto end;
994
Vincent Bernat02779b62016-04-03 13:48:43 +0200995 *sctl = calloc(1, sizeof(**sctl));
Janusz Dziemidowicz2c701b52015-03-07 23:03:59 +0100996 if (!chunk_dup(*sctl, &trash)) {
997 free(*sctl);
998 *sctl = NULL;
999 goto end;
1000 }
1001
1002end:
1003 if (fd != -1)
1004 close(fd);
1005
1006 return ret;
1007}
1008
1009int ssl_sock_sctl_add_cbk(SSL *ssl, unsigned ext_type, const unsigned char **out, size_t *outlen, int *al, void *add_arg)
1010{
Vincent Bernat3c2f2f22016-04-03 13:48:42 +02001011 struct chunk *sctl = add_arg;
Janusz Dziemidowicz2c701b52015-03-07 23:03:59 +01001012
1013 *out = (unsigned char *)sctl->str;
1014 *outlen = sctl->len;
1015
1016 return 1;
1017}
1018
1019int ssl_sock_sctl_parse_cbk(SSL *s, unsigned int ext_type, const unsigned char *in, size_t inlen, int *al, void *parse_arg)
1020{
1021 return 1;
1022}
1023
1024static int ssl_sock_load_sctl(SSL_CTX *ctx, const char *cert_path)
1025{
1026 char sctl_path[MAXPATHLEN+1];
1027 int ret = -1;
1028 struct stat st;
1029 struct chunk *sctl = NULL;
1030
1031 snprintf(sctl_path, MAXPATHLEN+1, "%s.sctl", cert_path);
1032
1033 if (stat(sctl_path, &st))
1034 return 1;
1035
1036 if (ssl_sock_load_sctl_from_file(sctl_path, &sctl))
1037 goto out;
1038
1039 if (!SSL_CTX_add_server_custom_ext(ctx, CT_EXTENSION_TYPE, ssl_sock_sctl_add_cbk, NULL, sctl, ssl_sock_sctl_parse_cbk, NULL)) {
1040 free(sctl);
1041 goto out;
1042 }
1043
1044 SSL_CTX_set_ex_data(ctx, sctl_ex_index, sctl);
1045
1046 ret = 0;
1047
1048out:
1049 return ret;
1050}
1051
1052#endif
1053
Emeric Brune1f38db2012-09-03 20:36:47 +02001054void ssl_sock_infocbk(const SSL *ssl, int where, int ret)
1055{
Vincent Bernat3c2f2f22016-04-03 13:48:42 +02001056 struct connection *conn = SSL_get_app_data(ssl);
Emeric Brund8b2bb52014-01-28 15:43:53 +01001057 BIO *write_bio;
Willy Tarreau622317d2015-02-27 16:36:16 +01001058 (void)ret; /* shut gcc stupid warning */
Emeric Brune1f38db2012-09-03 20:36:47 +02001059
1060 if (where & SSL_CB_HANDSHAKE_START) {
1061 /* Disable renegotiation (CVE-2009-3555) */
Willy Tarreau20879a02012-12-03 16:32:10 +01001062 if (conn->flags & CO_FL_CONNECTED) {
Emeric Brune1f38db2012-09-03 20:36:47 +02001063 conn->flags |= CO_FL_ERROR;
Willy Tarreau20879a02012-12-03 16:32:10 +01001064 conn->err_code = CO_ER_SSL_RENEG;
1065 }
Emeric Brune1f38db2012-09-03 20:36:47 +02001066 }
Emeric Brund8b2bb52014-01-28 15:43:53 +01001067
1068 if ((where & SSL_CB_ACCEPT_LOOP) == SSL_CB_ACCEPT_LOOP) {
1069 if (!(conn->xprt_st & SSL_SOCK_ST_FL_16K_WBFSIZE)) {
1070 /* Long certificate chains optimz
1071 If write and read bios are differents, we
1072 consider that the buffering was activated,
1073 so we rise the output buffer size from 4k
1074 to 16k */
1075 write_bio = SSL_get_wbio(ssl);
1076 if (write_bio != SSL_get_rbio(ssl)) {
1077 BIO_set_write_buffer_size(write_bio, 16384);
1078 conn->xprt_st |= SSL_SOCK_ST_FL_16K_WBFSIZE;
1079 }
1080 }
1081 }
Emeric Brunfc0421f2012-09-07 17:30:07 +02001082}
1083
Emeric Brune64aef12012-09-21 13:15:06 +02001084/* Callback is called for each certificate of the chain during a verify
1085 ok is set to 1 if preverify detect no error on current certificate.
1086 Returns 0 to break the handshake, 1 otherwise. */
Evan Broderbe554312013-06-27 00:05:25 -07001087int ssl_sock_bind_verifycbk(int ok, X509_STORE_CTX *x_store)
Emeric Brune64aef12012-09-21 13:15:06 +02001088{
1089 SSL *ssl;
1090 struct connection *conn;
Emeric Brun81c00f02012-09-21 14:31:21 +02001091 int err, depth;
Emeric Brune64aef12012-09-21 13:15:06 +02001092
1093 ssl = X509_STORE_CTX_get_ex_data(x_store, SSL_get_ex_data_X509_STORE_CTX_idx());
Vincent Bernat3c2f2f22016-04-03 13:48:42 +02001094 conn = SSL_get_app_data(ssl);
Emeric Brune64aef12012-09-21 13:15:06 +02001095
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02001096 conn->xprt_st |= SSL_SOCK_ST_FL_VERIFY_DONE;
Emeric Brune64aef12012-09-21 13:15:06 +02001097
Emeric Brun81c00f02012-09-21 14:31:21 +02001098 if (ok) /* no errors */
1099 return ok;
1100
1101 depth = X509_STORE_CTX_get_error_depth(x_store);
1102 err = X509_STORE_CTX_get_error(x_store);
1103
1104 /* check if CA error needs to be ignored */
1105 if (depth > 0) {
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02001106 if (!SSL_SOCK_ST_TO_CA_ERROR(conn->xprt_st)) {
1107 conn->xprt_st |= SSL_SOCK_CA_ERROR_TO_ST(err);
1108 conn->xprt_st |= SSL_SOCK_CAEDEPTH_TO_ST(depth);
Emeric Brunf282a812012-09-21 15:27:54 +02001109 }
1110
Emeric Brun1eb20ef2012-12-03 13:24:29 +01001111 if (objt_listener(conn->target)->bind_conf->ca_ignerr & (1ULL << err)) {
Thierry FOURNIER / OZON.IO8b068c22016-10-10 11:59:50 +02001112 ssl_sock_dump_errors(conn);
Emeric Brun1eb20ef2012-12-03 13:24:29 +01001113 ERR_clear_error();
Emeric Brun81c00f02012-09-21 14:31:21 +02001114 return 1;
Emeric Brun1eb20ef2012-12-03 13:24:29 +01001115 }
Emeric Brun81c00f02012-09-21 14:31:21 +02001116
Willy Tarreau20879a02012-12-03 16:32:10 +01001117 conn->err_code = CO_ER_SSL_CA_FAIL;
Emeric Brun81c00f02012-09-21 14:31:21 +02001118 return 0;
1119 }
1120
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02001121 if (!SSL_SOCK_ST_TO_CRTERROR(conn->xprt_st))
1122 conn->xprt_st |= SSL_SOCK_CRTERROR_TO_ST(err);
Emeric Brunf282a812012-09-21 15:27:54 +02001123
Emeric Brun81c00f02012-09-21 14:31:21 +02001124 /* check if certificate error needs to be ignored */
Emeric Brun1eb20ef2012-12-03 13:24:29 +01001125 if (objt_listener(conn->target)->bind_conf->crt_ignerr & (1ULL << err)) {
Thierry FOURNIER / OZON.IO8b068c22016-10-10 11:59:50 +02001126 ssl_sock_dump_errors(conn);
Emeric Brun1eb20ef2012-12-03 13:24:29 +01001127 ERR_clear_error();
Emeric Brun81c00f02012-09-21 14:31:21 +02001128 return 1;
Emeric Brun1eb20ef2012-12-03 13:24:29 +01001129 }
Emeric Brun81c00f02012-09-21 14:31:21 +02001130
Willy Tarreau20879a02012-12-03 16:32:10 +01001131 conn->err_code = CO_ER_SSL_CRT_FAIL;
Emeric Brun81c00f02012-09-21 14:31:21 +02001132 return 0;
Emeric Brune64aef12012-09-21 13:15:06 +02001133}
1134
Emeric Brun29f037d2014-04-25 19:05:36 +02001135/* Callback is called for ssl protocol analyse */
1136void ssl_sock_msgcbk(int write_p, int version, int content_type, const void *buf, size_t len, SSL *ssl, void *arg)
1137{
Emeric Brun29f037d2014-04-25 19:05:36 +02001138#ifdef TLS1_RT_HEARTBEAT
1139 /* test heartbeat received (write_p is set to 0
1140 for a received record) */
Willy Tarreauf51c6982014-04-25 20:02:39 +02001141 if ((content_type == TLS1_RT_HEARTBEAT) && (write_p == 0)) {
Vincent Bernat3c2f2f22016-04-03 13:48:42 +02001142 struct connection *conn = SSL_get_app_data(ssl);
Willy Tarreauf51c6982014-04-25 20:02:39 +02001143 const unsigned char *p = buf;
1144 unsigned int payload;
1145
Emeric Brun29f037d2014-04-25 19:05:36 +02001146 conn->xprt_st |= SSL_SOCK_RECV_HEARTBEAT;
Willy Tarreauf51c6982014-04-25 20:02:39 +02001147
1148 /* Check if this is a CVE-2014-0160 exploitation attempt. */
1149 if (*p != TLS1_HB_REQUEST)
1150 return;
1151
Willy Tarreauaeed6722014-04-25 23:59:58 +02001152 if (len < 1 + 2 + 16) /* 1 type + 2 size + 0 payload + 16 padding */
Willy Tarreauf51c6982014-04-25 20:02:39 +02001153 goto kill_it;
1154
1155 payload = (p[1] * 256) + p[2];
Willy Tarreau3b2fdb62014-04-25 23:44:22 +02001156 if (3 + payload + 16 <= len)
Willy Tarreauf51c6982014-04-25 20:02:39 +02001157 return; /* OK no problem */
Willy Tarreauaeed6722014-04-25 23:59:58 +02001158 kill_it:
Willy Tarreau3b2fdb62014-04-25 23:44:22 +02001159 /* We have a clear heartbleed attack (CVE-2014-0160), the
1160 * advertised payload is larger than the advertised packet
1161 * length, so we have garbage in the buffer between the
1162 * payload and the end of the buffer (p+len). We can't know
1163 * if the SSL stack is patched, and we don't know if we can
1164 * safely wipe out the area between p+3+len and payload.
1165 * So instead, we prevent the response from being sent by
1166 * setting the max_send_fragment to 0 and we report an SSL
1167 * error, which will kill this connection. It will be reported
1168 * above as SSL_ERROR_SSL while an other handshake failure with
Willy Tarreauf51c6982014-04-25 20:02:39 +02001169 * a heartbeat message will be reported as SSL_ERROR_SYSCALL.
1170 */
Willy Tarreau3b2fdb62014-04-25 23:44:22 +02001171 ssl->max_send_fragment = 0;
Willy Tarreauf51c6982014-04-25 20:02:39 +02001172 SSLerr(SSL_F_TLS1_HEARTBEAT, SSL_R_SSL_HANDSHAKE_FAILURE);
1173 return;
1174 }
Emeric Brun29f037d2014-04-25 19:05:36 +02001175#endif
1176}
1177
Willy Tarreau6c9a3d52012-10-18 18:57:14 +02001178#ifdef OPENSSL_NPN_NEGOTIATED
1179/* This callback is used so that the server advertises the list of
1180 * negociable protocols for NPN.
1181 */
1182static int ssl_sock_advertise_npn_protos(SSL *s, const unsigned char **data,
1183 unsigned int *len, void *arg)
1184{
1185 struct bind_conf *conf = arg;
1186
1187 *data = (const unsigned char *)conf->npn_str;
1188 *len = conf->npn_len;
1189 return SSL_TLSEXT_ERR_OK;
1190}
1191#endif
1192
Dirkjan Bussink48f1c4e2014-02-13 12:29:42 +01001193#ifdef TLSEXT_TYPE_application_layer_protocol_negotiation
Willy Tarreauab861d32013-04-02 02:30:41 +02001194/* This callback is used so that the server advertises the list of
1195 * negociable protocols for ALPN.
1196 */
Dirkjan Bussink48f1c4e2014-02-13 12:29:42 +01001197static int ssl_sock_advertise_alpn_protos(SSL *s, const unsigned char **out,
1198 unsigned char *outlen,
1199 const unsigned char *server,
1200 unsigned int server_len, void *arg)
Willy Tarreauab861d32013-04-02 02:30:41 +02001201{
1202 struct bind_conf *conf = arg;
1203
Dirkjan Bussink48f1c4e2014-02-13 12:29:42 +01001204 if (SSL_select_next_proto((unsigned char**) out, outlen, (const unsigned char *)conf->alpn_str,
1205 conf->alpn_len, server, server_len) != OPENSSL_NPN_NEGOTIATED) {
1206 return SSL_TLSEXT_ERR_NOACK;
1207 }
Willy Tarreauab861d32013-04-02 02:30:41 +02001208 return SSL_TLSEXT_ERR_OK;
1209}
1210#endif
1211
Willy Tarreauc8ad3be2015-06-17 15:48:26 +02001212#ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME
Christopher Faulet85b5a1a2015-10-09 11:46:32 +02001213static DH *ssl_get_tmp_dh(SSL *ssl, int export, int keylen);
1214
Christopher Faulet30548802015-06-11 13:39:32 +02001215/* Create a X509 certificate with the specified servername and serial. This
1216 * function returns a SSL_CTX object or NULL if an error occurs. */
Christopher Faulet7969a332015-10-09 11:15:03 +02001217static SSL_CTX *
Christopher Faulet635c0ad2015-11-12 11:35:51 +01001218ssl_sock_do_create_cert(const char *servername, struct bind_conf *bind_conf, SSL *ssl)
Christopher Faulet31af49d2015-06-09 17:29:50 +02001219{
Christopher Faulet635c0ad2015-11-12 11:35:51 +01001220 static unsigned int serial = 0;
1221
Christopher Faulet7969a332015-10-09 11:15:03 +02001222 X509 *cacert = bind_conf->ca_sign_cert;
1223 EVP_PKEY *capkey = bind_conf->ca_sign_pkey;
Christopher Faulet31af49d2015-06-09 17:29:50 +02001224 SSL_CTX *ssl_ctx = NULL;
1225 X509 *newcrt = NULL;
1226 EVP_PKEY *pkey = NULL;
Christopher Faulet31af49d2015-06-09 17:29:50 +02001227 X509_NAME *name;
1228 const EVP_MD *digest;
1229 X509V3_CTX ctx;
1230 unsigned int i;
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02001231 int key_type;
Christopher Faulet31af49d2015-06-09 17:29:50 +02001232
Christopher Faulet7969a332015-10-09 11:15:03 +02001233 /* Get the private key of the defautl certificate and use it */
1234 if (!(pkey = SSL_get_privatekey(ssl)))
Christopher Faulet31af49d2015-06-09 17:29:50 +02001235 goto mkcert_error;
1236
1237 /* Create the certificate */
1238 if (!(newcrt = X509_new()))
1239 goto mkcert_error;
1240
1241 /* Set version number for the certificate (X509v3) and the serial
1242 * number */
1243 if (X509_set_version(newcrt, 2L) != 1)
1244 goto mkcert_error;
Christopher Faulet635c0ad2015-11-12 11:35:51 +01001245 if (!serial)
1246 serial = now_ms;
1247 ASN1_INTEGER_set(X509_get_serialNumber(newcrt), serial++);
Christopher Faulet31af49d2015-06-09 17:29:50 +02001248
1249 /* Set duration for the certificate */
1250 if (!X509_gmtime_adj(X509_get_notBefore(newcrt), (long)-60*60*24) ||
1251 !X509_gmtime_adj(X509_get_notAfter(newcrt),(long)60*60*24*365))
1252 goto mkcert_error;
1253
1254 /* set public key in the certificate */
1255 if (X509_set_pubkey(newcrt, pkey) != 1)
1256 goto mkcert_error;
1257
1258 /* Set issuer name from the CA */
1259 if (!(name = X509_get_subject_name(cacert)))
1260 goto mkcert_error;
1261 if (X509_set_issuer_name(newcrt, name) != 1)
1262 goto mkcert_error;
1263
1264 /* Set the subject name using the same, but the CN */
1265 name = X509_NAME_dup(name);
1266 if (X509_NAME_add_entry_by_txt(name, "CN", MBSTRING_ASC,
1267 (const unsigned char *)servername,
1268 -1, -1, 0) != 1) {
1269 X509_NAME_free(name);
1270 goto mkcert_error;
1271 }
1272 if (X509_set_subject_name(newcrt, name) != 1) {
1273 X509_NAME_free(name);
1274 goto mkcert_error;
1275 }
1276 X509_NAME_free(name);
1277
1278 /* Add x509v3 extensions as specified */
1279 X509V3_set_ctx(&ctx, cacert, newcrt, NULL, NULL, 0);
1280 for (i = 0; i < X509V3_EXT_SIZE; i++) {
1281 X509_EXTENSION *ext;
1282
1283 if (!(ext = X509V3_EXT_conf(NULL, &ctx, x509v3_ext_names[i], x509v3_ext_values[i])))
1284 goto mkcert_error;
1285 if (!X509_add_ext(newcrt, ext, -1)) {
1286 X509_EXTENSION_free(ext);
1287 goto mkcert_error;
1288 }
1289 X509_EXTENSION_free(ext);
1290 }
1291
1292 /* Sign the certificate with the CA private key */
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02001293
1294 key_type = EVP_PKEY_base_id(capkey);
1295
1296 if (key_type == EVP_PKEY_DSA)
1297 digest = EVP_sha1();
1298 else if (key_type == EVP_PKEY_RSA)
Christopher Faulet31af49d2015-06-09 17:29:50 +02001299 digest = EVP_sha256();
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02001300 else if (key_type == EVP_PKEY_EC)
Christopher Faulet7969a332015-10-09 11:15:03 +02001301 digest = EVP_sha256();
1302 else {
Christopher Faulete7db2162015-10-19 13:59:24 +02001303#if (OPENSSL_VERSION_NUMBER >= 0x1000000fL)
Christopher Faulet7969a332015-10-09 11:15:03 +02001304 int nid;
1305
1306 if (EVP_PKEY_get_default_digest_nid(capkey, &nid) <= 0)
1307 goto mkcert_error;
1308 if (!(digest = EVP_get_digestbynid(nid)))
1309 goto mkcert_error;
Christopher Faulete7db2162015-10-19 13:59:24 +02001310#else
1311 goto mkcert_error;
1312#endif
Christopher Faulet7969a332015-10-09 11:15:03 +02001313 }
1314
Christopher Faulet31af49d2015-06-09 17:29:50 +02001315 if (!(X509_sign(newcrt, capkey, digest)))
1316 goto mkcert_error;
1317
1318 /* Create and set the new SSL_CTX */
1319 if (!(ssl_ctx = SSL_CTX_new(SSLv23_server_method())))
1320 goto mkcert_error;
1321 if (!SSL_CTX_use_PrivateKey(ssl_ctx, pkey))
1322 goto mkcert_error;
1323 if (!SSL_CTX_use_certificate(ssl_ctx, newcrt))
1324 goto mkcert_error;
1325 if (!SSL_CTX_check_private_key(ssl_ctx))
1326 goto mkcert_error;
1327
1328 if (newcrt) X509_free(newcrt);
Christopher Faulet7969a332015-10-09 11:15:03 +02001329
Christopher Faulet85b5a1a2015-10-09 11:46:32 +02001330 SSL_CTX_set_tmp_dh_callback(ssl_ctx, ssl_get_tmp_dh);
1331#if defined(SSL_CTX_set_tmp_ecdh) && !defined(OPENSSL_NO_ECDH)
1332 {
1333 const char *ecdhe = (bind_conf->ecdhe ? bind_conf->ecdhe : ECDHE_DEFAULT_CURVE);
1334 EC_KEY *ecc;
1335 int nid;
1336
1337 if ((nid = OBJ_sn2nid(ecdhe)) == NID_undef)
1338 goto end;
1339 if (!(ecc = EC_KEY_new_by_curve_name(nid)))
1340 goto end;
1341 SSL_CTX_set_tmp_ecdh(ssl_ctx, ecc);
1342 EC_KEY_free(ecc);
1343 }
1344#endif
1345 end:
Christopher Faulet31af49d2015-06-09 17:29:50 +02001346 return ssl_ctx;
1347
1348 mkcert_error:
1349 if (ssl_ctx) SSL_CTX_free(ssl_ctx);
1350 if (newcrt) X509_free(newcrt);
Christopher Faulet31af49d2015-06-09 17:29:50 +02001351 return NULL;
1352}
1353
Christopher Faulet7969a332015-10-09 11:15:03 +02001354SSL_CTX *
Christopher Faulet635c0ad2015-11-12 11:35:51 +01001355ssl_sock_create_cert(struct connection *conn, const char *servername, unsigned int key)
Christopher Faulet7969a332015-10-09 11:15:03 +02001356{
1357 struct bind_conf *bind_conf = objt_listener(conn->target)->bind_conf;
Christopher Faulet635c0ad2015-11-12 11:35:51 +01001358
1359 return ssl_sock_do_create_cert(servername, bind_conf, conn->xprt_ctx);
Christopher Faulet7969a332015-10-09 11:15:03 +02001360}
1361
Christopher Faulet30548802015-06-11 13:39:32 +02001362/* Do a lookup for a certificate in the LRU cache used to store generated
1363 * certificates. */
1364SSL_CTX *
Christopher Faulet635c0ad2015-11-12 11:35:51 +01001365ssl_sock_get_generated_cert(unsigned int key, struct bind_conf *bind_conf)
Christopher Faulet30548802015-06-11 13:39:32 +02001366{
1367 struct lru64 *lru = NULL;
1368
1369 if (ssl_ctx_lru_tree) {
Christopher Faulet635c0ad2015-11-12 11:35:51 +01001370 lru = lru64_lookup(key, ssl_ctx_lru_tree, bind_conf->ca_sign_cert, 0);
Christopher Faulet30548802015-06-11 13:39:32 +02001371 if (lru && lru->domain)
1372 return (SSL_CTX *)lru->data;
1373 }
1374 return NULL;
1375}
1376
Christopher Fauletd2cab922015-07-28 16:03:47 +02001377/* Set a certificate int the LRU cache used to store generated
1378 * certificate. Return 0 on success, otherwise -1 */
1379int
Christopher Faulet635c0ad2015-11-12 11:35:51 +01001380ssl_sock_set_generated_cert(SSL_CTX *ssl_ctx, unsigned int key, struct bind_conf *bind_conf)
Christopher Faulet30548802015-06-11 13:39:32 +02001381{
1382 struct lru64 *lru = NULL;
1383
1384 if (ssl_ctx_lru_tree) {
Christopher Faulet635c0ad2015-11-12 11:35:51 +01001385 lru = lru64_get(key, ssl_ctx_lru_tree, bind_conf->ca_sign_cert, 0);
Christopher Faulet30548802015-06-11 13:39:32 +02001386 if (!lru)
Christopher Fauletd2cab922015-07-28 16:03:47 +02001387 return -1;
Christopher Faulet30548802015-06-11 13:39:32 +02001388 if (lru->domain && lru->data)
1389 lru->free((SSL_CTX *)lru->data);
Christopher Faulet7969a332015-10-09 11:15:03 +02001390 lru64_commit(lru, ssl_ctx, bind_conf->ca_sign_cert, 0, (void (*)(void *))SSL_CTX_free);
Christopher Fauletd2cab922015-07-28 16:03:47 +02001391 return 0;
Christopher Faulet30548802015-06-11 13:39:32 +02001392 }
Christopher Fauletd2cab922015-07-28 16:03:47 +02001393 return -1;
Christopher Faulet30548802015-06-11 13:39:32 +02001394}
1395
Christopher Faulet635c0ad2015-11-12 11:35:51 +01001396/* Compute the key of the certificate. */
Christopher Faulet30548802015-06-11 13:39:32 +02001397unsigned int
Christopher Faulet635c0ad2015-11-12 11:35:51 +01001398ssl_sock_generated_cert_key(const void *data, size_t len)
Christopher Faulet30548802015-06-11 13:39:32 +02001399{
1400 return XXH32(data, len, ssl_ctx_lru_seed);
1401}
1402
Willy Tarreau2f63ef42015-10-20 15:16:01 +02001403/* Generate a cert and immediately assign it to the SSL session so that the cert's
1404 * refcount is maintained regardless of the cert's presence in the LRU cache.
1405 */
Christopher Faulet31af49d2015-06-09 17:29:50 +02001406static SSL_CTX *
Christopher Faulet7969a332015-10-09 11:15:03 +02001407ssl_sock_generate_certificate(const char *servername, struct bind_conf *bind_conf, SSL *ssl)
Christopher Faulet31af49d2015-06-09 17:29:50 +02001408{
1409 X509 *cacert = bind_conf->ca_sign_cert;
Christopher Faulet31af49d2015-06-09 17:29:50 +02001410 SSL_CTX *ssl_ctx = NULL;
1411 struct lru64 *lru = NULL;
Christopher Faulet635c0ad2015-11-12 11:35:51 +01001412 unsigned int key;
Christopher Faulet31af49d2015-06-09 17:29:50 +02001413
Christopher Faulet635c0ad2015-11-12 11:35:51 +01001414 key = ssl_sock_generated_cert_key(servername, strlen(servername));
Christopher Faulet31af49d2015-06-09 17:29:50 +02001415 if (ssl_ctx_lru_tree) {
Christopher Faulet635c0ad2015-11-12 11:35:51 +01001416 lru = lru64_get(key, ssl_ctx_lru_tree, cacert, 0);
Christopher Faulet31af49d2015-06-09 17:29:50 +02001417 if (lru && lru->domain)
1418 ssl_ctx = (SSL_CTX *)lru->data;
Christopher Fauletd2cab922015-07-28 16:03:47 +02001419 if (!ssl_ctx && lru) {
Christopher Faulet635c0ad2015-11-12 11:35:51 +01001420 ssl_ctx = ssl_sock_do_create_cert(servername, bind_conf, ssl);
Christopher Faulet31af49d2015-06-09 17:29:50 +02001421 lru64_commit(lru, ssl_ctx, cacert, 0, (void (*)(void *))SSL_CTX_free);
Christopher Fauletd2cab922015-07-28 16:03:47 +02001422 }
Willy Tarreau2f63ef42015-10-20 15:16:01 +02001423 SSL_set_SSL_CTX(ssl, ssl_ctx);
Christopher Faulet31af49d2015-06-09 17:29:50 +02001424 }
Willy Tarreau2f63ef42015-10-20 15:16:01 +02001425 else {
Christopher Faulet635c0ad2015-11-12 11:35:51 +01001426 ssl_ctx = ssl_sock_do_create_cert(servername, bind_conf, ssl);
Willy Tarreau2f63ef42015-10-20 15:16:01 +02001427 SSL_set_SSL_CTX(ssl, ssl_ctx);
1428 /* No LRU cache, this CTX will be released as soon as the session dies */
1429 SSL_CTX_free(ssl_ctx);
1430 }
Christopher Faulet31af49d2015-06-09 17:29:50 +02001431 return ssl_ctx;
1432}
1433
Emeric Brunfc0421f2012-09-07 17:30:07 +02001434/* Sets the SSL ctx of <ssl> to match the advertised server name. Returns a
1435 * warning when no match is found, which implies the default (first) cert
1436 * will keep being used.
1437 */
Willy Tarreau2a65ff02012-09-13 17:54:29 +02001438static int ssl_sock_switchctx_cbk(SSL *ssl, int *al, struct bind_conf *s)
Emeric Brunfc0421f2012-09-07 17:30:07 +02001439{
1440 const char *servername;
1441 const char *wildp = NULL;
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +02001442 struct ebmb_node *node, *n;
Emeric Brunfc0421f2012-09-07 17:30:07 +02001443 int i;
1444 (void)al; /* shut gcc stupid warning */
1445
1446 servername = SSL_get_servername(ssl, TLSEXT_NAMETYPE_host_name);
Emmanuel Hocdet65623372013-01-24 17:17:15 +01001447 if (!servername) {
Willy Tarreauf6721452015-07-07 18:04:38 +02001448 if (s->generate_certs) {
Vincent Bernat3c2f2f22016-04-03 13:48:42 +02001449 struct connection *conn = SSL_get_app_data(ssl);
Christopher Faulet635c0ad2015-11-12 11:35:51 +01001450 unsigned int key;
Willy Tarreauf6721452015-07-07 18:04:38 +02001451 SSL_CTX *ctx;
Christopher Faulet30548802015-06-11 13:39:32 +02001452
Willy Tarreauf6721452015-07-07 18:04:38 +02001453 conn_get_to_addr(conn);
1454 if (conn->flags & CO_FL_ADDR_TO_SET) {
Christopher Faulet635c0ad2015-11-12 11:35:51 +01001455 key = ssl_sock_generated_cert_key(&conn->addr.to, get_addr_len(&conn->addr.to));
1456 ctx = ssl_sock_get_generated_cert(key, s);
Willy Tarreauf6721452015-07-07 18:04:38 +02001457 if (ctx) {
1458 /* switch ctx */
1459 SSL_set_SSL_CTX(ssl, ctx);
1460 return SSL_TLSEXT_ERR_OK;
1461 }
Christopher Faulet30548802015-06-11 13:39:32 +02001462 }
1463 }
1464
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +02001465 return (s->strict_sni ?
1466 SSL_TLSEXT_ERR_ALERT_FATAL :
Emmanuel Hocdet79274e22013-05-31 12:47:44 +02001467 SSL_TLSEXT_ERR_NOACK);
Emmanuel Hocdet65623372013-01-24 17:17:15 +01001468 }
Emeric Brunfc0421f2012-09-07 17:30:07 +02001469
Willy Tarreau19d14ef2012-10-29 16:51:55 +01001470 for (i = 0; i < trash.size; i++) {
Emeric Brunfc0421f2012-09-07 17:30:07 +02001471 if (!servername[i])
1472 break;
Willy Tarreau19d14ef2012-10-29 16:51:55 +01001473 trash.str[i] = tolower(servername[i]);
1474 if (!wildp && (trash.str[i] == '.'))
1475 wildp = &trash.str[i];
Emeric Brunfc0421f2012-09-07 17:30:07 +02001476 }
Willy Tarreau19d14ef2012-10-29 16:51:55 +01001477 trash.str[i] = 0;
Emeric Brunfc0421f2012-09-07 17:30:07 +02001478
1479 /* lookup in full qualified names */
Willy Tarreau19d14ef2012-10-29 16:51:55 +01001480 node = ebst_lookup(&s->sni_ctx, trash.str);
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +02001481
1482 /* lookup a not neg filter */
1483 for (n = node; n; n = ebmb_next_dup(n)) {
1484 if (!container_of(n, struct sni_ctx, name)->neg) {
1485 node = n;
1486 break;
Emmanuel Hocdet65623372013-01-24 17:17:15 +01001487 }
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +02001488 }
1489 if (!node && wildp) {
1490 /* lookup in wildcards names */
Emeric Brunfc0421f2012-09-07 17:30:07 +02001491 node = ebst_lookup(&s->sni_w_ctx, wildp);
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +02001492 }
1493 if (!node || container_of(node, struct sni_ctx, name)->neg) {
Christopher Faulet31af49d2015-06-09 17:29:50 +02001494 SSL_CTX *ctx;
Christopher Faulet31af49d2015-06-09 17:29:50 +02001495 if (s->generate_certs &&
Christopher Faulet7969a332015-10-09 11:15:03 +02001496 (ctx = ssl_sock_generate_certificate(servername, s, ssl))) {
Christopher Faulet31af49d2015-06-09 17:29:50 +02001497 /* switch ctx */
Christopher Faulet31af49d2015-06-09 17:29:50 +02001498 return SSL_TLSEXT_ERR_OK;
1499 }
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +02001500 return (s->strict_sni ?
1501 SSL_TLSEXT_ERR_ALERT_FATAL :
1502 SSL_TLSEXT_ERR_ALERT_WARNING);
Emeric Brunfc0421f2012-09-07 17:30:07 +02001503 }
1504
1505 /* switch ctx */
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +02001506 SSL_set_SSL_CTX(ssl, container_of(node, struct sni_ctx, name)->ctx);
Emeric Brunfc0421f2012-09-07 17:30:07 +02001507 return SSL_TLSEXT_ERR_OK;
1508}
1509#endif /* SSL_CTRL_SET_TLSEXT_HOSTNAME */
1510
Emeric Bruna4bcd9a2012-09-20 16:19:02 +02001511#ifndef OPENSSL_NO_DH
Remi Gacognef46cd6e2014-06-12 14:58:40 +02001512
1513static DH * ssl_get_dh_1024(void)
1514{
Remi Gacogned3a341a2015-05-29 16:26:17 +02001515 static unsigned char dh1024_p[]={
1516 0xFA,0xF9,0x2A,0x22,0x2A,0xA7,0x7F,0xE1,0x67,0x4E,0x53,0xF7,
1517 0x56,0x13,0xC3,0xB1,0xE3,0x29,0x6B,0x66,0x31,0x6A,0x7F,0xB3,
1518 0xC2,0x68,0x6B,0xCB,0x1D,0x57,0x39,0x1D,0x1F,0xFF,0x1C,0xC9,
1519 0xA6,0xA4,0x98,0x82,0x31,0x5D,0x25,0xFF,0x8A,0xE0,0x73,0x96,
1520 0x81,0xC8,0x83,0x79,0xC1,0x5A,0x04,0xF8,0x37,0x0D,0xA8,0x3D,
1521 0xAE,0x74,0xBC,0xDB,0xB6,0xA4,0x75,0xD9,0x71,0x8A,0xA0,0x17,
1522 0x9E,0x2D,0xC8,0xA8,0xDF,0x2C,0x5F,0x82,0x95,0xF8,0x92,0x9B,
1523 0xA7,0x33,0x5F,0x89,0x71,0xC8,0x2D,0x6B,0x18,0x86,0xC4,0x94,
1524 0x22,0xA5,0x52,0x8D,0xF6,0xF6,0xD2,0x37,0x92,0x0F,0xA5,0xCC,
1525 0xDB,0x7B,0x1D,0x3D,0xA1,0x31,0xB7,0x80,0x8F,0x0B,0x67,0x5E,
1526 0x36,0xA5,0x60,0x0C,0xF1,0x95,0x33,0x8B,
1527 };
1528 static unsigned char dh1024_g[]={
1529 0x02,
1530 };
1531
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02001532 BIGNUM *p;
1533 BIGNUM *g;
Remi Gacognef46cd6e2014-06-12 14:58:40 +02001534 DH *dh = DH_new();
1535 if (dh) {
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02001536 p = BN_bin2bn(dh1024_p, sizeof dh1024_p, NULL);
1537 g = BN_bin2bn(dh1024_g, sizeof dh1024_g, NULL);
Remi Gacogned3a341a2015-05-29 16:26:17 +02001538
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02001539 if (!p || !g) {
Remi Gacognef46cd6e2014-06-12 14:58:40 +02001540 DH_free(dh);
1541 dh = NULL;
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02001542 } else {
1543 DH_set0_pqg(dh, p, NULL, g);
Remi Gacognef46cd6e2014-06-12 14:58:40 +02001544 }
1545 }
1546 return dh;
1547}
1548
1549static DH *ssl_get_dh_2048(void)
1550{
Remi Gacogned3a341a2015-05-29 16:26:17 +02001551 static unsigned char dh2048_p[]={
1552 0xEC,0x86,0xF8,0x70,0xA0,0x33,0x16,0xEC,0x05,0x1A,0x73,0x59,
1553 0xCD,0x1F,0x8B,0xF8,0x29,0xE4,0xD2,0xCF,0x52,0xDD,0xC2,0x24,
1554 0x8D,0xB5,0x38,0x9A,0xFB,0x5C,0xA4,0xE4,0xB2,0xDA,0xCE,0x66,
1555 0x50,0x74,0xA6,0x85,0x4D,0x4B,0x1D,0x30,0xB8,0x2B,0xF3,0x10,
1556 0xE9,0xA7,0x2D,0x05,0x71,0xE7,0x81,0xDF,0x8B,0x59,0x52,0x3B,
1557 0x5F,0x43,0x0B,0x68,0xF1,0xDB,0x07,0xBE,0x08,0x6B,0x1B,0x23,
1558 0xEE,0x4D,0xCC,0x9E,0x0E,0x43,0xA0,0x1E,0xDF,0x43,0x8C,0xEC,
1559 0xBE,0xBE,0x90,0xB4,0x51,0x54,0xB9,0x2F,0x7B,0x64,0x76,0x4E,
1560 0x5D,0xD4,0x2E,0xAE,0xC2,0x9E,0xAE,0x51,0x43,0x59,0xC7,0x77,
1561 0x9C,0x50,0x3C,0x0E,0xED,0x73,0x04,0x5F,0xF1,0x4C,0x76,0x2A,
1562 0xD8,0xF8,0xCF,0xFC,0x34,0x40,0xD1,0xB4,0x42,0x61,0x84,0x66,
1563 0x42,0x39,0x04,0xF8,0x68,0xB2,0x62,0xD7,0x55,0xED,0x1B,0x74,
1564 0x75,0x91,0xE0,0xC5,0x69,0xC1,0x31,0x5C,0xDB,0x7B,0x44,0x2E,
1565 0xCE,0x84,0x58,0x0D,0x1E,0x66,0x0C,0xC8,0x44,0x9E,0xFD,0x40,
1566 0x08,0x67,0x5D,0xFB,0xA7,0x76,0x8F,0x00,0x11,0x87,0xE9,0x93,
1567 0xF9,0x7D,0xC4,0xBC,0x74,0x55,0x20,0xD4,0x4A,0x41,0x2F,0x43,
1568 0x42,0x1A,0xC1,0xF2,0x97,0x17,0x49,0x27,0x37,0x6B,0x2F,0x88,
1569 0x7E,0x1C,0xA0,0xA1,0x89,0x92,0x27,0xD9,0x56,0x5A,0x71,0xC1,
1570 0x56,0x37,0x7E,0x3A,0x9D,0x05,0xE7,0xEE,0x5D,0x8F,0x82,0x17,
1571 0xBC,0xE9,0xC2,0x93,0x30,0x82,0xF9,0xF4,0xC9,0xAE,0x49,0xDB,
1572 0xD0,0x54,0xB4,0xD9,0x75,0x4D,0xFA,0x06,0xB8,0xD6,0x38,0x41,
1573 0xB7,0x1F,0x77,0xF3,
1574 };
1575 static unsigned char dh2048_g[]={
1576 0x02,
1577 };
1578
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02001579 BIGNUM *p;
1580 BIGNUM *g;
Remi Gacognef46cd6e2014-06-12 14:58:40 +02001581 DH *dh = DH_new();
1582 if (dh) {
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02001583 p = BN_bin2bn(dh2048_p, sizeof dh2048_p, NULL);
1584 g = BN_bin2bn(dh2048_g, sizeof dh2048_g, NULL);
Remi Gacogned3a341a2015-05-29 16:26:17 +02001585
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02001586 if (!p || !g) {
Remi Gacognef46cd6e2014-06-12 14:58:40 +02001587 DH_free(dh);
1588 dh = NULL;
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02001589 } else {
1590 DH_set0_pqg(dh, p, NULL, g);
Remi Gacognef46cd6e2014-06-12 14:58:40 +02001591 }
1592 }
1593 return dh;
1594}
1595
1596static DH *ssl_get_dh_4096(void)
1597{
Remi Gacogned3a341a2015-05-29 16:26:17 +02001598 static unsigned char dh4096_p[]={
1599 0xDE,0x16,0x94,0xCD,0x99,0x58,0x07,0xF1,0xF7,0x32,0x96,0x11,
1600 0x04,0x82,0xD4,0x84,0x72,0x80,0x99,0x06,0xCA,0xF0,0xA3,0x68,
1601 0x07,0xCE,0x64,0x50,0xE7,0x74,0x45,0x20,0x80,0x5E,0x4D,0xAD,
1602 0xA5,0xB6,0xED,0xFA,0x80,0x6C,0x3B,0x35,0xC4,0x9A,0x14,0x6B,
1603 0x32,0xBB,0xFD,0x1F,0x17,0x8E,0xB7,0x1F,0xD6,0xFA,0x3F,0x7B,
1604 0xEE,0x16,0xA5,0x62,0x33,0x0D,0xED,0xBC,0x4E,0x58,0xE5,0x47,
1605 0x4D,0xE9,0xAB,0x8E,0x38,0xD3,0x6E,0x90,0x57,0xE3,0x22,0x15,
1606 0x33,0xBD,0xF6,0x43,0x45,0xB5,0x10,0x0A,0xBE,0x2C,0xB4,0x35,
1607 0xB8,0x53,0x8D,0xAD,0xFB,0xA7,0x1F,0x85,0x58,0x41,0x7A,0x79,
1608 0x20,0x68,0xB3,0xE1,0x3D,0x08,0x76,0xBF,0x86,0x0D,0x49,0xE3,
1609 0x82,0x71,0x8C,0xB4,0x8D,0x81,0x84,0xD4,0xE7,0xBE,0x91,0xDC,
1610 0x26,0x39,0x48,0x0F,0x35,0xC4,0xCA,0x65,0xE3,0x40,0x93,0x52,
1611 0x76,0x58,0x7D,0xDD,0x51,0x75,0xDC,0x69,0x61,0xBF,0x47,0x2C,
1612 0x16,0x68,0x2D,0xC9,0x29,0xD3,0xE6,0xC0,0x99,0x48,0xA0,0x9A,
1613 0xC8,0x78,0xC0,0x6D,0x81,0x67,0x12,0x61,0x3F,0x71,0xBA,0x41,
1614 0x1F,0x6C,0x89,0x44,0x03,0xBA,0x3B,0x39,0x60,0xAA,0x28,0x55,
1615 0x59,0xAE,0xB8,0xFA,0xCB,0x6F,0xA5,0x1A,0xF7,0x2B,0xDD,0x52,
1616 0x8A,0x8B,0xE2,0x71,0xA6,0x5E,0x7E,0xD8,0x2E,0x18,0xE0,0x66,
1617 0xDF,0xDD,0x22,0x21,0x99,0x52,0x73,0xA6,0x33,0x20,0x65,0x0E,
1618 0x53,0xE7,0x6B,0x9B,0xC5,0xA3,0x2F,0x97,0x65,0x76,0xD3,0x47,
1619 0x23,0x77,0x12,0xB6,0x11,0x7B,0x24,0xED,0xF1,0xEF,0xC0,0xE2,
1620 0xA3,0x7E,0x67,0x05,0x3E,0x96,0x4D,0x45,0xC2,0x18,0xD1,0x73,
1621 0x9E,0x07,0xF3,0x81,0x6E,0x52,0x63,0xF6,0x20,0x76,0xB9,0x13,
1622 0xD2,0x65,0x30,0x18,0x16,0x09,0x16,0x9E,0x8F,0xF1,0xD2,0x10,
1623 0x5A,0xD3,0xD4,0xAF,0x16,0x61,0xDA,0x55,0x2E,0x18,0x5E,0x14,
1624 0x08,0x54,0x2E,0x2A,0x25,0xA2,0x1A,0x9B,0x8B,0x32,0xA9,0xFD,
1625 0xC2,0x48,0x96,0xE1,0x80,0xCA,0xE9,0x22,0x17,0xBB,0xCE,0x3E,
1626 0x9E,0xED,0xC7,0xF1,0x1F,0xEC,0x17,0x21,0xDC,0x7B,0x82,0x48,
1627 0x8E,0xBB,0x4B,0x9D,0x5B,0x04,0x04,0xDA,0xDB,0x39,0xDF,0x01,
1628 0x40,0xC3,0xAA,0x26,0x23,0x89,0x75,0xC6,0x0B,0xD0,0xA2,0x60,
1629 0x6A,0xF1,0xCC,0x65,0x18,0x98,0x1B,0x52,0xD2,0x74,0x61,0xCC,
1630 0xBD,0x60,0xAE,0xA3,0xA0,0x66,0x6A,0x16,0x34,0x92,0x3F,0x41,
1631 0x40,0x31,0x29,0xC0,0x2C,0x63,0xB2,0x07,0x8D,0xEB,0x94,0xB8,
1632 0xE8,0x47,0x92,0x52,0x93,0x6A,0x1B,0x7E,0x1A,0x61,0xB3,0x1B,
1633 0xF0,0xD6,0x72,0x9B,0xF1,0xB0,0xAF,0xBF,0x3E,0x65,0xEF,0x23,
1634 0x1D,0x6F,0xFF,0x70,0xCD,0x8A,0x4C,0x8A,0xA0,0x72,0x9D,0xBE,
1635 0xD4,0xBB,0x24,0x47,0x4A,0x68,0xB5,0xF5,0xC6,0xD5,0x7A,0xCD,
1636 0xCA,0x06,0x41,0x07,0xAD,0xC2,0x1E,0xE6,0x54,0xA7,0xAD,0x03,
1637 0xD9,0x12,0xC1,0x9C,0x13,0xB1,0xC9,0x0A,0x43,0x8E,0x1E,0x08,
1638 0xCE,0x50,0x82,0x73,0x5F,0xA7,0x55,0x1D,0xD9,0x59,0xAC,0xB5,
1639 0xEA,0x02,0x7F,0x6C,0x5B,0x74,0x96,0x98,0x67,0x24,0xA3,0x0F,
1640 0x15,0xFC,0xA9,0x7D,0x3E,0x67,0xD1,0x70,0xF8,0x97,0xF3,0x67,
1641 0xC5,0x8C,0x88,0x44,0x08,0x02,0xC7,0x2B,
Remi Gacognef46cd6e2014-06-12 14:58:40 +02001642 };
Remi Gacogned3a341a2015-05-29 16:26:17 +02001643 static unsigned char dh4096_g[]={
1644 0x02,
1645 };
Remi Gacognef46cd6e2014-06-12 14:58:40 +02001646
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02001647 BIGNUM *p;
1648 BIGNUM *g;
Remi Gacognef46cd6e2014-06-12 14:58:40 +02001649 DH *dh = DH_new();
1650 if (dh) {
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02001651 p = BN_bin2bn(dh4096_p, sizeof dh4096_p, NULL);
1652 g = BN_bin2bn(dh4096_g, sizeof dh4096_g, NULL);
Remi Gacogned3a341a2015-05-29 16:26:17 +02001653
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02001654 if (!p || !g) {
Remi Gacognef46cd6e2014-06-12 14:58:40 +02001655 DH_free(dh);
1656 dh = NULL;
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02001657 } else {
1658 DH_set0_pqg(dh, p, NULL, g);
Remi Gacognef46cd6e2014-06-12 14:58:40 +02001659 }
1660 }
1661 return dh;
1662}
1663
1664/* Returns Diffie-Hellman parameters matching the private key length
Willy Tarreauef934602016-12-22 23:12:01 +01001665 but not exceeding global_ssl.default_dh_param */
Remi Gacognef46cd6e2014-06-12 14:58:40 +02001666static DH *ssl_get_tmp_dh(SSL *ssl, int export, int keylen)
1667{
1668 DH *dh = NULL;
1669 EVP_PKEY *pkey = SSL_get_privatekey(ssl);
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02001670 int type;
1671
1672 type = pkey ? EVP_PKEY_base_id(pkey) : EVP_PKEY_NONE;
Remi Gacognef46cd6e2014-06-12 14:58:40 +02001673
1674 /* The keylen supplied by OpenSSL can only be 512 or 1024.
1675 See ssl3_send_server_key_exchange() in ssl/s3_srvr.c
1676 */
1677 if (type == EVP_PKEY_RSA || type == EVP_PKEY_DSA) {
1678 keylen = EVP_PKEY_bits(pkey);
1679 }
1680
Willy Tarreauef934602016-12-22 23:12:01 +01001681 if (keylen > global_ssl.default_dh_param) {
1682 keylen = global_ssl.default_dh_param;
Remi Gacognef46cd6e2014-06-12 14:58:40 +02001683 }
1684
Remi Gacogned3a341a2015-05-29 16:26:17 +02001685 if (keylen >= 4096) {
Remi Gacogne8de54152014-07-15 11:36:40 +02001686 dh = local_dh_4096;
Remi Gacognef46cd6e2014-06-12 14:58:40 +02001687 }
1688 else if (keylen >= 2048) {
Remi Gacogne8de54152014-07-15 11:36:40 +02001689 dh = local_dh_2048;
Remi Gacognef46cd6e2014-06-12 14:58:40 +02001690 }
1691 else {
Remi Gacogne8de54152014-07-15 11:36:40 +02001692 dh = local_dh_1024;
Remi Gacognef46cd6e2014-06-12 14:58:40 +02001693 }
1694
1695 return dh;
1696}
1697
Remi Gacogne47783ef2015-05-29 15:53:22 +02001698static DH * ssl_sock_get_dh_from_file(const char *filename)
Emeric Bruna4bcd9a2012-09-20 16:19:02 +02001699{
Emeric Bruna4bcd9a2012-09-20 16:19:02 +02001700 DH *dh = NULL;
Remi Gacogne47783ef2015-05-29 15:53:22 +02001701 BIO *in = BIO_new(BIO_s_file());
Emeric Bruna4bcd9a2012-09-20 16:19:02 +02001702
Emeric Bruna4bcd9a2012-09-20 16:19:02 +02001703 if (in == NULL)
1704 goto end;
1705
Remi Gacogne47783ef2015-05-29 15:53:22 +02001706 if (BIO_read_filename(in, filename) <= 0)
Emeric Bruna4bcd9a2012-09-20 16:19:02 +02001707 goto end;
1708
Remi Gacogne47783ef2015-05-29 15:53:22 +02001709 dh = PEM_read_bio_DHparams(in, NULL, NULL, NULL);
1710
1711end:
1712 if (in)
1713 BIO_free(in);
1714
1715 return dh;
1716}
1717
1718int ssl_sock_load_global_dh_param_from_file(const char *filename)
1719{
1720 global_dh = ssl_sock_get_dh_from_file(filename);
1721
1722 if (global_dh) {
1723 return 0;
1724 }
1725
1726 return -1;
1727}
1728
1729/* Loads Diffie-Hellman parameter from a file. Returns 1 if loaded, else -1
1730 if an error occured, and 0 if parameter not found. */
1731int ssl_sock_load_dh_params(SSL_CTX *ctx, const char *file)
1732{
1733 int ret = -1;
1734 DH *dh = ssl_sock_get_dh_from_file(file);
1735
Remi Gacognef46cd6e2014-06-12 14:58:40 +02001736 if (dh) {
1737 ret = 1;
1738 SSL_CTX_set_tmp_dh(ctx, dh);
Remi Gacogne4f902b82015-05-28 16:23:00 +02001739
1740 if (ssl_dh_ptr_index >= 0) {
1741 /* store a pointer to the DH params to avoid complaining about
1742 ssl-default-dh-param not being set for this SSL_CTX */
1743 SSL_CTX_set_ex_data(ctx, ssl_dh_ptr_index, dh);
1744 }
Remi Gacognef46cd6e2014-06-12 14:58:40 +02001745 }
Remi Gacogne47783ef2015-05-29 15:53:22 +02001746 else if (global_dh) {
1747 SSL_CTX_set_tmp_dh(ctx, global_dh);
1748 ret = 0; /* DH params not found */
1749 }
Remi Gacognef46cd6e2014-06-12 14:58:40 +02001750 else {
Emeric Brun41fdb3c2013-04-26 11:05:44 +02001751 /* Clear openssl global errors stack */
1752 ERR_clear_error();
1753
Willy Tarreauef934602016-12-22 23:12:01 +01001754 if (global_ssl.default_dh_param <= 1024) {
Remi Gacognef46cd6e2014-06-12 14:58:40 +02001755 /* we are limited to DH parameter of 1024 bits anyway */
Remi Gacognec7e12632016-07-02 16:26:10 +02001756 if (local_dh_1024 == NULL)
1757 local_dh_1024 = ssl_get_dh_1024();
1758
Remi Gacogne8de54152014-07-15 11:36:40 +02001759 if (local_dh_1024 == NULL)
Remi Gacognef46cd6e2014-06-12 14:58:40 +02001760 goto end;
Willy Tarreau6e774b42014-04-25 21:35:23 +02001761
Remi Gacogne8de54152014-07-15 11:36:40 +02001762 SSL_CTX_set_tmp_dh(ctx, local_dh_1024);
Remi Gacognef46cd6e2014-06-12 14:58:40 +02001763 }
1764 else {
1765 SSL_CTX_set_tmp_dh_callback(ctx, ssl_get_tmp_dh);
1766 }
Willy Tarreau6e774b42014-04-25 21:35:23 +02001767
Emeric Brun41fdb3c2013-04-26 11:05:44 +02001768 ret = 0; /* DH params not found */
Emeric Bruna4bcd9a2012-09-20 16:19:02 +02001769 }
Emeric Brun644cde02012-12-14 11:21:13 +01001770
Emeric Bruna4bcd9a2012-09-20 16:19:02 +02001771end:
1772 if (dh)
1773 DH_free(dh);
1774
Emeric Bruna4bcd9a2012-09-20 16:19:02 +02001775 return ret;
1776}
1777#endif
1778
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +02001779static int ssl_sock_add_cert_sni(SSL_CTX *ctx, struct bind_conf *s, char *name, int order)
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01001780{
1781 struct sni_ctx *sc;
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +02001782 int wild = 0, neg = 0;
Thierry FOURNIER / OZON.IO07c3d782016-10-06 10:56:48 +02001783 struct ebmb_node *node;
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01001784
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +02001785 if (*name == '!') {
1786 neg = 1;
1787 name++;
1788 }
1789 if (*name == '*') {
1790 wild = 1;
1791 name++;
1792 }
1793 /* !* filter is a nop */
1794 if (neg && wild)
1795 return order;
1796 if (*name) {
1797 int j, len;
1798 len = strlen(name);
Thierry FOURNIER / OZON.IO07c3d782016-10-06 10:56:48 +02001799 for (j = 0; j < len && j < trash.size; j++)
1800 trash.str[j] = tolower(name[j]);
1801 if (j >= trash.size)
1802 return order;
1803 trash.str[j] = 0;
1804
1805 /* Check for duplicates. */
1806 if (wild)
1807 node = ebst_lookup(&s->sni_w_ctx, trash.str);
1808 else
1809 node = ebst_lookup(&s->sni_ctx, trash.str);
1810 for (; node; node = ebmb_next_dup(node)) {
1811 sc = ebmb_entry(node, struct sni_ctx, name);
1812 if (sc->ctx == ctx && sc->neg == neg)
1813 return order;
1814 }
1815
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01001816 sc = malloc(sizeof(struct sni_ctx) + len + 1);
Thierry FOURNIER / OZON.IO7a3bd3b2016-10-06 10:35:29 +02001817 if (!sc)
1818 return order;
Thierry FOURNIER / OZON.IO07c3d782016-10-06 10:56:48 +02001819 memcpy(sc->name.key, trash.str, len + 1);
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01001820 sc->ctx = ctx;
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +02001821 sc->order = order++;
1822 sc->neg = neg;
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01001823 if (wild)
1824 ebst_insert(&s->sni_w_ctx, &sc->name);
1825 else
1826 ebst_insert(&s->sni_ctx, &sc->name);
1827 }
1828 return order;
1829}
1830
yanbzhu488a4d22015-12-01 15:16:07 -05001831
1832/* The following code is used for loading multiple crt files into
1833 * SSL_CTX's based on CN/SAN
1834 */
Luca Pizzamiglio578b1692016-12-12 10:56:56 +01001835#if OPENSSL_VERSION_NUMBER >= 0x1000200fL && !defined(LIBRESSL_VERSION_NUMBER)
yanbzhu488a4d22015-12-01 15:16:07 -05001836/* This is used to preload the certifcate, private key
1837 * and Cert Chain of a file passed in via the crt
1838 * argument
1839 *
1840 * This way, we do not have to read the file multiple times
1841 */
1842struct cert_key_and_chain {
1843 X509 *cert;
1844 EVP_PKEY *key;
1845 unsigned int num_chain_certs;
1846 /* This is an array of X509 pointers */
1847 X509 **chain_certs;
1848};
1849
yanbzhu08ce6ab2015-12-02 13:01:29 -05001850#define SSL_SOCK_POSSIBLE_KT_COMBOS (1<<(SSL_SOCK_NUM_KEYTYPES))
1851
1852struct key_combo_ctx {
1853 SSL_CTX *ctx;
1854 int order;
1855};
1856
1857/* Map used for processing multiple keypairs for a single purpose
1858 *
1859 * This maps CN/SNI name to certificate type
1860 */
1861struct sni_keytype {
1862 int keytypes; /* BITMASK for keytypes */
1863 struct ebmb_node name; /* node holding the servername value */
1864};
1865
1866
yanbzhu488a4d22015-12-01 15:16:07 -05001867/* Frees the contents of a cert_key_and_chain
1868 */
1869static void ssl_sock_free_cert_key_and_chain_contents(struct cert_key_and_chain *ckch)
1870{
1871 int i;
1872
1873 if (!ckch)
1874 return;
1875
1876 /* Free the certificate and set pointer to NULL */
1877 if (ckch->cert)
1878 X509_free(ckch->cert);
1879 ckch->cert = NULL;
1880
1881 /* Free the key and set pointer to NULL */
1882 if (ckch->key)
1883 EVP_PKEY_free(ckch->key);
1884 ckch->key = NULL;
1885
1886 /* Free each certificate in the chain */
1887 for (i = 0; i < ckch->num_chain_certs; i++) {
1888 if (ckch->chain_certs[i])
1889 X509_free(ckch->chain_certs[i]);
1890 }
1891
1892 /* Free the chain obj itself and set to NULL */
1893 if (ckch->num_chain_certs > 0) {
1894 free(ckch->chain_certs);
1895 ckch->num_chain_certs = 0;
1896 ckch->chain_certs = NULL;
1897 }
1898
1899}
1900
1901/* checks if a key and cert exists in the ckch
1902 */
1903static int ssl_sock_is_ckch_valid(struct cert_key_and_chain *ckch)
1904{
1905 return (ckch->cert != NULL && ckch->key != NULL);
1906}
1907
1908
1909/* Loads the contents of a crt file (path) into a cert_key_and_chain
1910 * This allows us to carry the contents of the file without having to
1911 * read the file multiple times.
1912 *
1913 * returns:
1914 * 0 on Success
1915 * 1 on SSL Failure
1916 * 2 on file not found
1917 */
1918static int ssl_sock_load_crt_file_into_ckch(const char *path, struct cert_key_and_chain *ckch, char **err)
1919{
1920
1921 BIO *in;
1922 X509 *ca = NULL;
1923 int ret = 1;
1924
1925 ssl_sock_free_cert_key_and_chain_contents(ckch);
1926
1927 in = BIO_new(BIO_s_file());
1928 if (in == NULL)
1929 goto end;
1930
1931 if (BIO_read_filename(in, path) <= 0)
1932 goto end;
1933
yanbzhu488a4d22015-12-01 15:16:07 -05001934 /* Read Private Key */
1935 ckch->key = PEM_read_bio_PrivateKey(in, NULL, NULL, NULL);
1936 if (ckch->key == NULL) {
1937 memprintf(err, "%sunable to load private key from file '%s'.\n",
1938 err && *err ? *err : "", path);
1939 goto end;
1940 }
1941
Willy Tarreaubb137a82016-04-06 19:02:38 +02001942 /* Seek back to beginning of file */
Thierry FOURNIER / OZON.IOd44ea3f2016-10-14 00:49:21 +02001943 if (BIO_reset(in) == -1) {
1944 memprintf(err, "%san error occurred while reading the file '%s'.\n",
1945 err && *err ? *err : "", path);
1946 goto end;
1947 }
Willy Tarreaubb137a82016-04-06 19:02:38 +02001948
1949 /* Read Certificate */
1950 ckch->cert = PEM_read_bio_X509_AUX(in, NULL, NULL, NULL);
1951 if (ckch->cert == NULL) {
1952 memprintf(err, "%sunable to load certificate from file '%s'.\n",
1953 err && *err ? *err : "", path);
1954 goto end;
1955 }
1956
yanbzhu488a4d22015-12-01 15:16:07 -05001957 /* Read Certificate Chain */
1958 while ((ca = PEM_read_bio_X509(in, NULL, NULL, NULL))) {
1959 /* Grow the chain certs */
1960 ckch->num_chain_certs++;
1961 ckch->chain_certs = realloc(ckch->chain_certs, (ckch->num_chain_certs * sizeof(X509 *)));
1962
1963 /* use - 1 here since we just incremented it above */
1964 ckch->chain_certs[ckch->num_chain_certs - 1] = ca;
1965 }
1966 ret = ERR_get_error();
1967 if (ret && (ERR_GET_LIB(ret) != ERR_LIB_PEM && ERR_GET_REASON(ret) != PEM_R_NO_START_LINE)) {
1968 memprintf(err, "%sunable to load certificate chain from file '%s'.\n",
1969 err && *err ? *err : "", path);
1970 ret = 1;
1971 goto end;
1972 }
1973
1974 ret = 0;
1975
1976end:
1977
1978 ERR_clear_error();
1979 if (in)
1980 BIO_free(in);
1981
1982 /* Something went wrong in one of the reads */
1983 if (ret != 0)
1984 ssl_sock_free_cert_key_and_chain_contents(ckch);
1985
1986 return ret;
1987}
1988
1989/* Loads the info in ckch into ctx
1990 * Currently, this does not process any information about ocsp, dhparams or
1991 * sctl
1992 * Returns
1993 * 0 on success
1994 * 1 on failure
1995 */
1996static int ssl_sock_put_ckch_into_ctx(const char *path, const struct cert_key_and_chain *ckch, SSL_CTX *ctx, char **err)
1997{
1998 int i = 0;
1999
2000 if (SSL_CTX_use_PrivateKey(ctx, ckch->key) <= 0) {
2001 memprintf(err, "%sunable to load SSL private key into SSL Context '%s'.\n",
2002 err && *err ? *err : "", path);
2003 return 1;
2004 }
2005
2006 if (!SSL_CTX_use_certificate(ctx, ckch->cert)) {
2007 memprintf(err, "%sunable to load SSL certificate into SSL Context '%s'.\n",
2008 err && *err ? *err : "", path);
2009 return 1;
2010 }
2011
yanbzhu488a4d22015-12-01 15:16:07 -05002012 /* Load all certs in the ckch into the ctx_chain for the ssl_ctx */
2013 for (i = 0; i < ckch->num_chain_certs; i++) {
2014 if (!SSL_CTX_add1_chain_cert(ctx, ckch->chain_certs[i])) {
yanbzhu08ce6ab2015-12-02 13:01:29 -05002015 memprintf(err, "%sunable to load chain certificate #%d into SSL Context '%s'. Make sure you are linking against Openssl >= 1.0.2.\n",
2016 err && *err ? *err : "", (i+1), path);
yanbzhu488a4d22015-12-01 15:16:07 -05002017 return 1;
2018 }
2019 }
2020
2021 if (SSL_CTX_check_private_key(ctx) <= 0) {
2022 memprintf(err, "%sinconsistencies between private key and certificate loaded from PEM file '%s'.\n",
2023 err && *err ? *err : "", path);
2024 return 1;
2025 }
2026
2027 return 0;
2028}
2029
yanbzhu08ce6ab2015-12-02 13:01:29 -05002030
2031static void ssl_sock_populate_sni_keytypes_hplr(const char *str, struct eb_root *sni_keytypes, int key_index)
2032{
2033 struct sni_keytype *s_kt = NULL;
2034 struct ebmb_node *node;
2035 int i;
2036
2037 for (i = 0; i < trash.size; i++) {
2038 if (!str[i])
2039 break;
2040 trash.str[i] = tolower(str[i]);
2041 }
2042 trash.str[i] = 0;
2043 node = ebst_lookup(sni_keytypes, trash.str);
2044 if (!node) {
2045 /* CN not found in tree */
2046 s_kt = malloc(sizeof(struct sni_keytype) + i + 1);
2047 /* Using memcpy here instead of strncpy.
2048 * strncpy will cause sig_abrt errors under certain versions of gcc with -O2
2049 * See: https://gcc.gnu.org/bugzilla/show_bug.cgi?id=60792
2050 */
2051 memcpy(s_kt->name.key, trash.str, i+1);
2052 s_kt->keytypes = 0;
2053 ebst_insert(sni_keytypes, &s_kt->name);
2054 } else {
2055 /* CN found in tree */
2056 s_kt = container_of(node, struct sni_keytype, name);
2057 }
2058
2059 /* Mark that this CN has the keytype of key_index via keytypes mask */
2060 s_kt->keytypes |= 1<<key_index;
2061
2062}
2063
2064
2065/* Given a path that does not exist, try to check for path.rsa, path.dsa and path.ecdsa files.
2066 * If any are found, group these files into a set of SSL_CTX*
2067 * based on shared and unique CN and SAN entries. Add these SSL_CTX* to the SNI tree.
2068 *
2069 * This will allow the user to explictly group multiple cert/keys for a single purpose
2070 *
2071 * Returns
2072 * 0 on success
2073 * 1 on failure
2074 */
Willy Tarreau03209342016-12-22 17:08:28 +01002075static int ssl_sock_load_multi_cert(const char *path, struct bind_conf *bind_conf, char **sni_filter, int fcount, char **err)
yanbzhu08ce6ab2015-12-02 13:01:29 -05002076{
2077 char fp[MAXPATHLEN+1] = {0};
2078 int n = 0;
2079 int i = 0;
2080 struct cert_key_and_chain certs_and_keys[SSL_SOCK_NUM_KEYTYPES] = { {0} };
2081 struct eb_root sni_keytypes_map = { {0} };
2082 struct ebmb_node *node;
2083 struct ebmb_node *next;
2084 /* Array of SSL_CTX pointers corresponding to each possible combo
2085 * of keytypes
2086 */
2087 struct key_combo_ctx key_combos[SSL_SOCK_POSSIBLE_KT_COMBOS] = { {0} };
2088 int rv = 0;
2089 X509_NAME *xname = NULL;
2090 char *str = NULL;
2091#ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME
2092 STACK_OF(GENERAL_NAME) *names = NULL;
2093#endif
2094
2095 /* Load all possible certs and keys */
2096 for (n = 0; n < SSL_SOCK_NUM_KEYTYPES; n++) {
2097 struct stat buf;
2098
2099 snprintf(fp, sizeof(fp), "%s.%s", path, SSL_SOCK_KEYTYPE_NAMES[n]);
2100 if (stat(fp, &buf) == 0) {
2101 if (ssl_sock_load_crt_file_into_ckch(fp, &certs_and_keys[n], err) == 1) {
2102 rv = 1;
2103 goto end;
2104 }
2105 }
2106 }
2107
2108 /* Process each ckch and update keytypes for each CN/SAN
2109 * for example, if CN/SAN www.a.com is associated with
2110 * certs with keytype 0 and 2, then at the end of the loop,
2111 * www.a.com will have:
2112 * keyindex = 0 | 1 | 4 = 5
2113 */
2114 for (n = 0; n < SSL_SOCK_NUM_KEYTYPES; n++) {
2115
2116 if (!ssl_sock_is_ckch_valid(&certs_and_keys[n]))
2117 continue;
2118
Emmanuel Hocdetd294aea2016-05-13 11:14:06 +02002119 if (fcount) {
Willy Tarreau24b892f2016-06-20 23:01:57 +02002120 for (i = 0; i < fcount; i++)
Emmanuel Hocdetd294aea2016-05-13 11:14:06 +02002121 ssl_sock_populate_sni_keytypes_hplr(sni_filter[i], &sni_keytypes_map, n);
2122 } else {
2123 /* A lot of the following code is OpenSSL boilerplate for processing CN's and SAN's,
2124 * so the line that contains logic is marked via comments
2125 */
2126 xname = X509_get_subject_name(certs_and_keys[n].cert);
2127 i = -1;
2128 while ((i = X509_NAME_get_index_by_NID(xname, NID_commonName, i)) != -1) {
2129 X509_NAME_ENTRY *entry = X509_NAME_get_entry(xname, i);
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02002130 ASN1_STRING *value;
2131 value = X509_NAME_ENTRY_get_data(entry);
2132 if (ASN1_STRING_to_UTF8((unsigned char **)&str, value) >= 0) {
Emmanuel Hocdetd294aea2016-05-13 11:14:06 +02002133 /* Important line is here */
2134 ssl_sock_populate_sni_keytypes_hplr(str, &sni_keytypes_map, n);
yanbzhu08ce6ab2015-12-02 13:01:29 -05002135
Emmanuel Hocdetd294aea2016-05-13 11:14:06 +02002136 OPENSSL_free(str);
2137 str = NULL;
2138 }
yanbzhu08ce6ab2015-12-02 13:01:29 -05002139 }
yanbzhu08ce6ab2015-12-02 13:01:29 -05002140
Emmanuel Hocdetd294aea2016-05-13 11:14:06 +02002141 /* Do the above logic for each SAN */
yanbzhu08ce6ab2015-12-02 13:01:29 -05002142#ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME
Emmanuel Hocdetd294aea2016-05-13 11:14:06 +02002143 names = X509_get_ext_d2i(certs_and_keys[n].cert, NID_subject_alt_name, NULL, NULL);
2144 if (names) {
2145 for (i = 0; i < sk_GENERAL_NAME_num(names); i++) {
2146 GENERAL_NAME *name = sk_GENERAL_NAME_value(names, i);
yanbzhu08ce6ab2015-12-02 13:01:29 -05002147
Emmanuel Hocdetd294aea2016-05-13 11:14:06 +02002148 if (name->type == GEN_DNS) {
2149 if (ASN1_STRING_to_UTF8((unsigned char **)&str, name->d.dNSName) >= 0) {
2150 /* Important line is here */
2151 ssl_sock_populate_sni_keytypes_hplr(str, &sni_keytypes_map, n);
yanbzhu08ce6ab2015-12-02 13:01:29 -05002152
Emmanuel Hocdetd294aea2016-05-13 11:14:06 +02002153 OPENSSL_free(str);
2154 str = NULL;
2155 }
yanbzhu08ce6ab2015-12-02 13:01:29 -05002156 }
2157 }
2158 }
2159 }
2160#endif /* SSL_CTRL_SET_TLSEXT_HOSTNAME */
2161 }
2162
2163 /* If no files found, return error */
2164 if (eb_is_empty(&sni_keytypes_map)) {
2165 memprintf(err, "%sunable to load SSL certificate file '%s' file does not exist.\n",
2166 err && *err ? *err : "", path);
2167 rv = 1;
2168 goto end;
2169 }
2170
2171 /* We now have a map of CN/SAN to keytypes that are loaded in
2172 * Iterate through the map to create the SSL_CTX's (if needed)
2173 * and add each CTX to the SNI tree
2174 *
2175 * Some math here:
2176 * There are 2^n - 1 possibile combinations, each unique
2177 * combination is denoted by the key in the map. Each key
2178 * has a value between 1 and 2^n - 1. Conveniently, the array
2179 * of SSL_CTX* is sized 2^n. So, we can simply use the i'th
2180 * entry in the array to correspond to the unique combo (key)
2181 * associated with i. This unique key combo (i) will be associated
2182 * with combos[i-1]
2183 */
2184
2185 node = ebmb_first(&sni_keytypes_map);
2186 while (node) {
2187 SSL_CTX *cur_ctx;
Bertrand Jacquin33423092016-11-13 16:37:13 +00002188 char cur_file[MAXPATHLEN+1];
yanbzhu08ce6ab2015-12-02 13:01:29 -05002189
2190 str = (char *)container_of(node, struct sni_keytype, name)->name.key;
2191 i = container_of(node, struct sni_keytype, name)->keytypes;
2192 cur_ctx = key_combos[i-1].ctx;
2193
2194 if (cur_ctx == NULL) {
2195 /* need to create SSL_CTX */
2196 cur_ctx = SSL_CTX_new(SSLv23_server_method());
2197 if (cur_ctx == NULL) {
2198 memprintf(err, "%sunable to allocate SSL context.\n",
2199 err && *err ? *err : "");
2200 rv = 1;
2201 goto end;
2202 }
2203
yanbzhube2774d2015-12-10 15:07:30 -05002204 /* Load all required certs/keys/chains/OCSPs info into SSL_CTX */
yanbzhu08ce6ab2015-12-02 13:01:29 -05002205 for (n = 0; n < SSL_SOCK_NUM_KEYTYPES; n++) {
2206 if (i & (1<<n)) {
2207 /* Key combo contains ckch[n] */
Bertrand Jacquin33423092016-11-13 16:37:13 +00002208 snprintf(cur_file, MAXPATHLEN+1, "%s.%s", path, SSL_SOCK_KEYTYPE_NAMES[n]);
2209 if (ssl_sock_put_ckch_into_ctx(cur_file, &certs_and_keys[n], cur_ctx, err) != 0) {
yanbzhu08ce6ab2015-12-02 13:01:29 -05002210 SSL_CTX_free(cur_ctx);
2211 rv = 1;
2212 goto end;
2213 }
yanbzhube2774d2015-12-10 15:07:30 -05002214
2215#if (defined SSL_CTRL_SET_TLSEXT_STATUS_REQ_CB && !defined OPENSSL_NO_OCSP)
2216 /* Load OCSP Info into context */
Bertrand Jacquin33423092016-11-13 16:37:13 +00002217 if (ssl_sock_load_ocsp(cur_ctx, cur_file) < 0) {
yanbzhube2774d2015-12-10 15:07:30 -05002218 if (err)
2219 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 +00002220 *err ? *err : "", cur_file);
yanbzhube2774d2015-12-10 15:07:30 -05002221 SSL_CTX_free(cur_ctx);
2222 rv = 1;
2223 goto end;
2224 }
2225#endif
yanbzhu08ce6ab2015-12-02 13:01:29 -05002226 }
2227 }
2228
2229 /* Load DH params into the ctx to support DHE keys */
2230#ifndef OPENSSL_NO_DH
2231 if (ssl_dh_ptr_index >= 0)
2232 SSL_CTX_set_ex_data(cur_ctx, ssl_dh_ptr_index, NULL);
2233
2234 rv = ssl_sock_load_dh_params(cur_ctx, NULL);
2235 if (rv < 0) {
2236 if (err)
2237 memprintf(err, "%sunable to load DH parameters from file '%s'.\n",
2238 *err ? *err : "", path);
2239 rv = 1;
2240 goto end;
2241 }
2242#endif
2243
2244 /* Update key_combos */
2245 key_combos[i-1].ctx = cur_ctx;
2246 }
2247
2248 /* Update SNI Tree */
Emmanuel Hocdetd294aea2016-05-13 11:14:06 +02002249 key_combos[i-1].order = ssl_sock_add_cert_sni(cur_ctx, bind_conf, str, key_combos[i-1].order);
yanbzhu08ce6ab2015-12-02 13:01:29 -05002250 node = ebmb_next(node);
2251 }
2252
2253
2254 /* Mark a default context if none exists, using the ctx that has the most shared keys */
2255 if (!bind_conf->default_ctx) {
2256 for (i = SSL_SOCK_POSSIBLE_KT_COMBOS - 1; i >= 0; i--) {
2257 if (key_combos[i].ctx) {
2258 bind_conf->default_ctx = key_combos[i].ctx;
2259 break;
2260 }
2261 }
2262 }
2263
2264end:
2265
2266 if (names)
2267 sk_GENERAL_NAME_pop_free(names, GENERAL_NAME_free);
2268
2269 for (n = 0; n < SSL_SOCK_NUM_KEYTYPES; n++)
2270 ssl_sock_free_cert_key_and_chain_contents(&certs_and_keys[n]);
2271
2272 node = ebmb_first(&sni_keytypes_map);
2273 while (node) {
2274 next = ebmb_next(node);
2275 ebmb_delete(node);
2276 node = next;
2277 }
2278
2279 return rv;
2280}
2281#else
2282/* This is a dummy, that just logs an error and returns error */
Willy Tarreau03209342016-12-22 17:08:28 +01002283static int ssl_sock_load_multi_cert(const char *path, struct bind_conf *bind_conf, char **sni_filter, int fcount, char **err)
yanbzhu08ce6ab2015-12-02 13:01:29 -05002284{
2285 memprintf(err, "%sunable to stat SSL certificate from file '%s' : %s.\n",
2286 err && *err ? *err : "", path, strerror(errno));
2287 return 1;
2288}
2289
yanbzhu488a4d22015-12-01 15:16:07 -05002290#endif /* #if OPENSSL_VERSION_NUMBER >= 0x1000200fL: Support for loading multiple certs into a single SSL_CTX */
2291
Emeric Brunfc0421f2012-09-07 17:30:07 +02002292/* Loads a certificate key and CA chain from a file. Returns 0 on error, -1 if
2293 * an early error happens and the caller must call SSL_CTX_free() by itelf.
2294 */
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +02002295static int ssl_sock_load_cert_chain_file(SSL_CTX *ctx, const char *file, struct bind_conf *s, char **sni_filter, int fcount)
Emeric Brunfc0421f2012-09-07 17:30:07 +02002296{
2297 BIO *in;
2298 X509 *x = NULL, *ca;
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +02002299 int i, err;
Emeric Brunfc0421f2012-09-07 17:30:07 +02002300 int ret = -1;
2301 int order = 0;
2302 X509_NAME *xname;
2303 char *str;
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02002304 pem_password_cb *passwd_cb;
2305 void *passwd_cb_userdata;
2306
Emeric Brunfc0421f2012-09-07 17:30:07 +02002307#ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME
2308 STACK_OF(GENERAL_NAME) *names;
2309#endif
2310
2311 in = BIO_new(BIO_s_file());
2312 if (in == NULL)
2313 goto end;
2314
2315 if (BIO_read_filename(in, file) <= 0)
2316 goto end;
2317
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02002318
2319 passwd_cb = SSL_CTX_get_default_passwd_cb(ctx);
2320 passwd_cb_userdata = SSL_CTX_get_default_passwd_cb_userdata(ctx);
2321
2322 x = PEM_read_bio_X509_AUX(in, NULL, passwd_cb, passwd_cb_userdata);
Emeric Brunfc0421f2012-09-07 17:30:07 +02002323 if (x == NULL)
2324 goto end;
2325
Emeric Brun50bcecc2013-04-22 13:05:23 +02002326 if (fcount) {
2327 while (fcount--)
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +02002328 order = ssl_sock_add_cert_sni(ctx, s, sni_filter[fcount], order);
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01002329 }
2330 else {
Emeric Brunfc0421f2012-09-07 17:30:07 +02002331#ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01002332 names = X509_get_ext_d2i(x, NID_subject_alt_name, NULL, NULL);
2333 if (names) {
2334 for (i = 0; i < sk_GENERAL_NAME_num(names); i++) {
2335 GENERAL_NAME *name = sk_GENERAL_NAME_value(names, i);
2336 if (name->type == GEN_DNS) {
2337 if (ASN1_STRING_to_UTF8((unsigned char **)&str, name->d.dNSName) >= 0) {
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +02002338 order = ssl_sock_add_cert_sni(ctx, s, str, order);
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01002339 OPENSSL_free(str);
Emeric Brunfc0421f2012-09-07 17:30:07 +02002340 }
Emeric Brunfc0421f2012-09-07 17:30:07 +02002341 }
2342 }
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01002343 sk_GENERAL_NAME_pop_free(names, GENERAL_NAME_free);
Emeric Brunfc0421f2012-09-07 17:30:07 +02002344 }
Emeric Brunfc0421f2012-09-07 17:30:07 +02002345#endif /* SSL_CTRL_SET_TLSEXT_HOSTNAME */
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01002346 xname = X509_get_subject_name(x);
2347 i = -1;
2348 while ((i = X509_NAME_get_index_by_NID(xname, NID_commonName, i)) != -1) {
2349 X509_NAME_ENTRY *entry = X509_NAME_get_entry(xname, i);
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02002350 ASN1_STRING *value;
2351
2352 value = X509_NAME_ENTRY_get_data(entry);
2353 if (ASN1_STRING_to_UTF8((unsigned char **)&str, value) >= 0) {
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +02002354 order = ssl_sock_add_cert_sni(ctx, s, str, order);
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01002355 OPENSSL_free(str);
Emeric Brunfc0421f2012-09-07 17:30:07 +02002356 }
Emeric Brunfc0421f2012-09-07 17:30:07 +02002357 }
2358 }
2359
2360 ret = 0; /* the caller must not free the SSL_CTX argument anymore */
2361 if (!SSL_CTX_use_certificate(ctx, x))
2362 goto end;
2363
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02002364#ifdef SSL_CTX_clear_extra_chain_certs
2365 SSL_CTX_clear_extra_chain_certs(ctx);
2366#else
Emeric Brunfc0421f2012-09-07 17:30:07 +02002367 if (ctx->extra_certs != NULL) {
2368 sk_X509_pop_free(ctx->extra_certs, X509_free);
2369 ctx->extra_certs = NULL;
2370 }
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02002371#endif
Emeric Brunfc0421f2012-09-07 17:30:07 +02002372
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02002373 while ((ca = PEM_read_bio_X509(in, NULL, passwd_cb, passwd_cb_userdata))) {
Emeric Brunfc0421f2012-09-07 17:30:07 +02002374 if (!SSL_CTX_add_extra_chain_cert(ctx, ca)) {
2375 X509_free(ca);
2376 goto end;
2377 }
2378 }
2379
2380 err = ERR_get_error();
2381 if (!err || (ERR_GET_LIB(err) == ERR_LIB_PEM && ERR_GET_REASON(err) == PEM_R_NO_START_LINE)) {
2382 /* we successfully reached the last cert in the file */
2383 ret = 1;
2384 }
2385 ERR_clear_error();
2386
2387end:
2388 if (x)
2389 X509_free(x);
2390
2391 if (in)
2392 BIO_free(in);
2393
2394 return ret;
2395}
2396
Willy Tarreau03209342016-12-22 17:08:28 +01002397static int ssl_sock_load_cert_file(const char *path, struct bind_conf *bind_conf, char **sni_filter, int fcount, char **err)
Emeric Brunfc0421f2012-09-07 17:30:07 +02002398{
2399 int ret;
2400 SSL_CTX *ctx;
2401
2402 ctx = SSL_CTX_new(SSLv23_server_method());
2403 if (!ctx) {
Willy Tarreaueb6cead2012-09-20 19:43:14 +02002404 memprintf(err, "%sunable to allocate SSL context for cert '%s'.\n",
2405 err && *err ? *err : "", path);
Emeric Brunfc0421f2012-09-07 17:30:07 +02002406 return 1;
2407 }
2408
2409 if (SSL_CTX_use_PrivateKey_file(ctx, path, SSL_FILETYPE_PEM) <= 0) {
Willy Tarreaueb6cead2012-09-20 19:43:14 +02002410 memprintf(err, "%sunable to load SSL private key from PEM file '%s'.\n",
2411 err && *err ? *err : "", path);
Emeric Brunfc0421f2012-09-07 17:30:07 +02002412 SSL_CTX_free(ctx);
2413 return 1;
2414 }
2415
Emeric Brun50bcecc2013-04-22 13:05:23 +02002416 ret = ssl_sock_load_cert_chain_file(ctx, path, bind_conf, sni_filter, fcount);
Emeric Brunfc0421f2012-09-07 17:30:07 +02002417 if (ret <= 0) {
Willy Tarreaueb6cead2012-09-20 19:43:14 +02002418 memprintf(err, "%sunable to load SSL certificate from PEM file '%s'.\n",
2419 err && *err ? *err : "", path);
Emeric Brunfc0421f2012-09-07 17:30:07 +02002420 if (ret < 0) /* serious error, must do that ourselves */
2421 SSL_CTX_free(ctx);
2422 return 1;
2423 }
Emeric Brun61694ab2012-10-26 13:35:33 +02002424
2425 if (SSL_CTX_check_private_key(ctx) <= 0) {
2426 memprintf(err, "%sinconsistencies between private key and certificate loaded from PEM file '%s'.\n",
2427 err && *err ? *err : "", path);
2428 return 1;
2429 }
2430
Emeric Brunfc0421f2012-09-07 17:30:07 +02002431 /* we must not free the SSL_CTX anymore below, since it's already in
2432 * the tree, so it will be discovered and cleaned in time.
2433 */
Emeric Bruna4bcd9a2012-09-20 16:19:02 +02002434#ifndef OPENSSL_NO_DH
Remi Gacogne4f902b82015-05-28 16:23:00 +02002435 /* store a NULL pointer to indicate we have not yet loaded
2436 a custom DH param file */
2437 if (ssl_dh_ptr_index >= 0) {
2438 SSL_CTX_set_ex_data(ctx, ssl_dh_ptr_index, NULL);
2439 }
2440
Emeric Bruna4bcd9a2012-09-20 16:19:02 +02002441 ret = ssl_sock_load_dh_params(ctx, path);
2442 if (ret < 0) {
2443 if (err)
2444 memprintf(err, "%sunable to load DH parameters from file '%s'.\n",
2445 *err ? *err : "", path);
2446 return 1;
2447 }
2448#endif
2449
Lukas Tribuse4e30f72014-12-09 16:32:51 +01002450#if (defined SSL_CTRL_SET_TLSEXT_STATUS_REQ_CB && !defined OPENSSL_NO_OCSP)
Emeric Brun4147b2e2014-06-16 18:36:30 +02002451 ret = ssl_sock_load_ocsp(ctx, path);
2452 if (ret < 0) {
2453 if (err)
2454 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",
2455 *err ? *err : "", path);
2456 return 1;
2457 }
2458#endif
2459
Daniel Jakots54ffb912015-11-06 20:02:41 +01002460#if (OPENSSL_VERSION_NUMBER >= 0x1000200fL && !defined OPENSSL_NO_TLSEXT && !defined OPENSSL_IS_BORINGSSL && !defined LIBRESSL_VERSION_NUMBER)
Janusz Dziemidowicz2c701b52015-03-07 23:03:59 +01002461 if (sctl_ex_index >= 0) {
2462 ret = ssl_sock_load_sctl(ctx, path);
2463 if (ret < 0) {
2464 if (err)
2465 memprintf(err, "%s '%s.sctl' is present but cannot be read or parsed'.\n",
2466 *err ? *err : "", path);
2467 return 1;
2468 }
2469 }
2470#endif
2471
Emeric Brunfc0421f2012-09-07 17:30:07 +02002472#ifndef SSL_CTRL_SET_TLSEXT_HOSTNAME
Willy Tarreau2a65ff02012-09-13 17:54:29 +02002473 if (bind_conf->default_ctx) {
Willy Tarreaueb6cead2012-09-20 19:43:14 +02002474 memprintf(err, "%sthis version of openssl cannot load multiple SSL certificates.\n",
2475 err && *err ? *err : "");
Emeric Brunfc0421f2012-09-07 17:30:07 +02002476 return 1;
2477 }
2478#endif
Willy Tarreau2a65ff02012-09-13 17:54:29 +02002479 if (!bind_conf->default_ctx)
2480 bind_conf->default_ctx = ctx;
Emeric Brunfc0421f2012-09-07 17:30:07 +02002481
2482 return 0;
2483}
2484
Willy Tarreau03209342016-12-22 17:08:28 +01002485int ssl_sock_load_cert(char *path, struct bind_conf *bind_conf, char **err)
Emeric Brunfc0421f2012-09-07 17:30:07 +02002486{
Cyril Bonté3180f7b2015-01-25 00:16:08 +01002487 struct dirent **de_list;
2488 int i, n;
Emeric Brunfc0421f2012-09-07 17:30:07 +02002489 DIR *dir;
2490 struct stat buf;
Willy Tarreauee2663b2012-12-06 11:36:59 +01002491 char *end;
2492 char fp[MAXPATHLEN+1];
Emeric Brunfc0421f2012-09-07 17:30:07 +02002493 int cfgerr = 0;
yanbzhu63ea8462015-12-09 13:35:14 -05002494#if OPENSSL_VERSION_NUMBER >= 0x1000200fL
2495 int is_bundle;
2496 int j;
2497#endif
Emeric Brunfc0421f2012-09-07 17:30:07 +02002498
yanbzhu08ce6ab2015-12-02 13:01:29 -05002499 if (stat(path, &buf) == 0) {
2500 dir = opendir(path);
2501 if (!dir)
Willy Tarreau03209342016-12-22 17:08:28 +01002502 return ssl_sock_load_cert_file(path, bind_conf, NULL, 0, err);
Emeric Brunfc0421f2012-09-07 17:30:07 +02002503
yanbzhu08ce6ab2015-12-02 13:01:29 -05002504 /* strip trailing slashes, including first one */
2505 for (end = path + strlen(path) - 1; end >= path && *end == '/'; end--)
2506 *end = 0;
Emeric Brunfc0421f2012-09-07 17:30:07 +02002507
yanbzhu08ce6ab2015-12-02 13:01:29 -05002508 n = scandir(path, &de_list, 0, alphasort);
2509 if (n < 0) {
2510 memprintf(err, "%sunable to scan directory '%s' : %s.\n",
2511 err && *err ? *err : "", path, strerror(errno));
2512 cfgerr++;
2513 }
2514 else {
2515 for (i = 0; i < n; i++) {
2516 struct dirent *de = de_list[i];
Emeric Brun2aab7222014-06-18 18:15:09 +02002517
yanbzhu08ce6ab2015-12-02 13:01:29 -05002518 end = strrchr(de->d_name, '.');
2519 if (end && (!strcmp(end, ".issuer") || !strcmp(end, ".ocsp") || !strcmp(end, ".sctl")))
2520 goto ignore_entry;
Cyril Bonté3180f7b2015-01-25 00:16:08 +01002521
yanbzhu08ce6ab2015-12-02 13:01:29 -05002522 snprintf(fp, sizeof(fp), "%s/%s", path, de->d_name);
2523 if (stat(fp, &buf) != 0) {
2524 memprintf(err, "%sunable to stat SSL certificate from file '%s' : %s.\n",
2525 err && *err ? *err : "", fp, strerror(errno));
2526 cfgerr++;
2527 goto ignore_entry;
2528 }
2529 if (!S_ISREG(buf.st_mode))
2530 goto ignore_entry;
yanbzhu63ea8462015-12-09 13:35:14 -05002531
2532#if OPENSSL_VERSION_NUMBER >= 0x1000200fL
2533 is_bundle = 0;
2534 /* Check if current entry in directory is part of a multi-cert bundle */
2535
2536 if (end) {
2537 for (j = 0; j < SSL_SOCK_NUM_KEYTYPES; j++) {
2538 if (!strcmp(end + 1, SSL_SOCK_KEYTYPE_NAMES[j])) {
2539 is_bundle = 1;
2540 break;
2541 }
2542 }
2543
2544 if (is_bundle) {
2545 char dp[MAXPATHLEN+1] = {0}; /* this will be the filename w/o the keytype */
2546 int dp_len;
2547
2548 dp_len = end - de->d_name;
2549 snprintf(dp, dp_len + 1, "%s", de->d_name);
2550
2551 /* increment i and free de until we get to a non-bundle cert
2552 * Note here that we look at de_list[i + 1] before freeing de
2553 * this is important since ignore_entry will free de
2554 */
2555 while (i + 1 < n && !strncmp(de_list[i + 1]->d_name, dp, dp_len)) {
2556 free(de);
2557 i++;
2558 de = de_list[i];
2559 }
2560
2561 snprintf(fp, sizeof(fp), "%s/%s", path, dp);
Willy Tarreau03209342016-12-22 17:08:28 +01002562 ssl_sock_load_multi_cert(fp, bind_conf, NULL, 0, err);
yanbzhu63ea8462015-12-09 13:35:14 -05002563
2564 /* Successfully processed the bundle */
2565 goto ignore_entry;
2566 }
2567 }
2568
2569#endif
Willy Tarreau03209342016-12-22 17:08:28 +01002570 cfgerr += ssl_sock_load_cert_file(fp, bind_conf, NULL, 0, err);
yanbzhu08ce6ab2015-12-02 13:01:29 -05002571ignore_entry:
2572 free(de);
Cyril Bonté3180f7b2015-01-25 00:16:08 +01002573 }
yanbzhu08ce6ab2015-12-02 13:01:29 -05002574 free(de_list);
Emeric Brunfc0421f2012-09-07 17:30:07 +02002575 }
yanbzhu08ce6ab2015-12-02 13:01:29 -05002576 closedir(dir);
2577 return cfgerr;
Emeric Brunfc0421f2012-09-07 17:30:07 +02002578 }
yanbzhu08ce6ab2015-12-02 13:01:29 -05002579
Willy Tarreau03209342016-12-22 17:08:28 +01002580 cfgerr = ssl_sock_load_multi_cert(path, bind_conf, NULL, 0, err);
yanbzhu08ce6ab2015-12-02 13:01:29 -05002581
Emeric Brunfc0421f2012-09-07 17:30:07 +02002582 return cfgerr;
2583}
2584
Thierry Fournier383085f2013-01-24 14:15:43 +01002585/* Make sure openssl opens /dev/urandom before the chroot. The work is only
2586 * done once. Zero is returned if the operation fails. No error is returned
2587 * if the random is said as not implemented, because we expect that openssl
2588 * will use another method once needed.
2589 */
2590static int ssl_initialize_random()
2591{
2592 unsigned char random;
2593 static int random_initialized = 0;
2594
2595 if (!random_initialized && RAND_bytes(&random, 1) != 0)
2596 random_initialized = 1;
2597
2598 return random_initialized;
2599}
2600
Willy Tarreau03209342016-12-22 17:08:28 +01002601int ssl_sock_load_cert_list_file(char *file, struct bind_conf *bind_conf, char **err)
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01002602{
Emmanuel Hocdet5e0e6e42016-05-13 11:18:50 +02002603 char thisline[LINESIZE*CRTLIST_FACTOR];
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01002604 FILE *f;
yanbzhu1b04e5b2015-12-02 13:54:14 -05002605 struct stat buf;
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01002606 int linenum = 0;
2607 int cfgerr = 0;
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01002608
Willy Tarreauad1731d2013-04-02 17:35:58 +02002609 if ((f = fopen(file, "r")) == NULL) {
2610 memprintf(err, "cannot open file '%s' : %s", file, strerror(errno));
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01002611 return 1;
Willy Tarreauad1731d2013-04-02 17:35:58 +02002612 }
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01002613
2614 while (fgets(thisline, sizeof(thisline), f) != NULL) {
2615 int arg;
Emeric Brun50bcecc2013-04-22 13:05:23 +02002616 int newarg;
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01002617 char *end;
Emmanuel Hocdet5e0e6e42016-05-13 11:18:50 +02002618 char *args[MAX_LINE_ARGS*CRTLIST_FACTOR + 1];
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01002619 char *line = thisline;
2620
2621 linenum++;
2622 end = line + strlen(line);
2623 if (end-line == sizeof(thisline)-1 && *(end-1) != '\n') {
2624 /* Check if we reached the limit and the last char is not \n.
2625 * Watch out for the last line without the terminating '\n'!
2626 */
Willy Tarreauad1731d2013-04-02 17:35:58 +02002627 memprintf(err, "line %d too long in file '%s', limit is %d characters",
2628 linenum, file, (int)sizeof(thisline)-1);
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01002629 cfgerr = 1;
Willy Tarreauad1731d2013-04-02 17:35:58 +02002630 break;
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01002631 }
2632
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01002633 arg = 0;
Emeric Brun50bcecc2013-04-22 13:05:23 +02002634 newarg = 1;
2635 while (*line) {
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01002636 if (*line == '#' || *line == '\n' || *line == '\r') {
2637 /* end of string, end of loop */
2638 *line = 0;
2639 break;
2640 }
2641 else if (isspace(*line)) {
Emeric Brun50bcecc2013-04-22 13:05:23 +02002642 newarg = 1;
2643 *line = 0;
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01002644 }
Emeric Brun50bcecc2013-04-22 13:05:23 +02002645 else if (newarg) {
Emmanuel Hocdet5e0e6e42016-05-13 11:18:50 +02002646 if (arg == MAX_LINE_ARGS*CRTLIST_FACTOR) {
Emeric Brun50bcecc2013-04-22 13:05:23 +02002647 memprintf(err, "too many args on line %d in file '%s'.",
2648 linenum, file);
2649 cfgerr = 1;
2650 break;
2651 }
2652 newarg = 0;
2653 args[arg++] = line;
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01002654 }
Emeric Brun50bcecc2013-04-22 13:05:23 +02002655 line++;
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01002656 }
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +02002657 if (cfgerr)
2658 break;
Willy Tarreauad1731d2013-04-02 17:35:58 +02002659
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01002660 /* empty line */
Emeric Brun50bcecc2013-04-22 13:05:23 +02002661 if (!arg)
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01002662 continue;
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01002663
yanbzhu1b04e5b2015-12-02 13:54:14 -05002664 if (stat(args[0], &buf) == 0) {
Willy Tarreau03209342016-12-22 17:08:28 +01002665 cfgerr = ssl_sock_load_cert_file(args[0], bind_conf, &args[1], arg-1, err);
yanbzhu1b04e5b2015-12-02 13:54:14 -05002666 } else {
Willy Tarreau03209342016-12-22 17:08:28 +01002667 cfgerr = ssl_sock_load_multi_cert(args[0], bind_conf, &args[1], arg-1, err);
yanbzhu1b04e5b2015-12-02 13:54:14 -05002668 }
2669
Willy Tarreauad1731d2013-04-02 17:35:58 +02002670 if (cfgerr) {
2671 memprintf(err, "error processing line %d in file '%s' : %s", linenum, file, *err);
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01002672 break;
Willy Tarreauad1731d2013-04-02 17:35:58 +02002673 }
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01002674 }
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01002675 fclose(f);
2676 return cfgerr;
2677}
2678
Emeric Brunfc0421f2012-09-07 17:30:07 +02002679#ifndef SSL_OP_CIPHER_SERVER_PREFERENCE /* needs OpenSSL >= 0.9.7 */
2680#define SSL_OP_CIPHER_SERVER_PREFERENCE 0
2681#endif
2682
2683#ifndef SSL_OP_NO_SESSION_RESUMPTION_ON_RENEGOTIATION /* needs OpenSSL >= 0.9.7 */
2684#define SSL_OP_NO_SESSION_RESUMPTION_ON_RENEGOTIATION 0
Willy Tarreau7d588ee2012-11-26 18:47:31 +01002685#define SSL_renegotiate_pending(arg) 0
Emeric Brunfc0421f2012-09-07 17:30:07 +02002686#endif
Emeric Brun2b58d042012-09-20 17:10:03 +02002687#ifndef SSL_OP_SINGLE_ECDH_USE /* needs OpenSSL >= 0.9.8 */
2688#define SSL_OP_SINGLE_ECDH_USE 0
2689#endif
Emeric Brun2d0c4822012-10-02 13:45:20 +02002690#ifndef SSL_OP_NO_TICKET /* needs OpenSSL >= 0.9.8 */
2691#define SSL_OP_NO_TICKET 0
2692#endif
Emeric Brunfc0421f2012-09-07 17:30:07 +02002693#ifndef SSL_OP_NO_COMPRESSION /* needs OpenSSL >= 0.9.9 */
2694#define SSL_OP_NO_COMPRESSION 0
2695#endif
Emeric Brunc0ff4922012-09-28 19:37:02 +02002696#ifndef SSL_OP_NO_TLSv1_1 /* needs OpenSSL >= 1.0.1 */
2697#define SSL_OP_NO_TLSv1_1 0
2698#endif
2699#ifndef SSL_OP_NO_TLSv1_2 /* needs OpenSSL >= 1.0.1 */
2700#define SSL_OP_NO_TLSv1_2 0
2701#endif
Emeric Bruna4bcd9a2012-09-20 16:19:02 +02002702#ifndef SSL_OP_SINGLE_DH_USE /* needs OpenSSL >= 0.9.6 */
2703#define SSL_OP_SINGLE_DH_USE 0
2704#endif
Emeric Brun2b58d042012-09-20 17:10:03 +02002705#ifndef SSL_OP_SINGLE_ECDH_USE /* needs OpenSSL >= 1.0.0 */
2706#define SSL_OP_SINGLE_ECDH_USE 0
2707#endif
Emeric Brunfc0421f2012-09-07 17:30:07 +02002708#ifndef SSL_MODE_RELEASE_BUFFERS /* needs OpenSSL >= 1.0.0 */
2709#define SSL_MODE_RELEASE_BUFFERS 0
2710#endif
Willy Tarreau396a1862014-11-13 14:06:52 +01002711#ifndef SSL_MODE_SMALL_BUFFERS /* needs small_records.patch */
2712#define SSL_MODE_SMALL_BUFFERS 0
2713#endif
Remi Gacognef46cd6e2014-06-12 14:58:40 +02002714
Willy Tarreau03209342016-12-22 17:08:28 +01002715int ssl_sock_prepare_ctx(struct bind_conf *bind_conf, SSL_CTX *ctx)
Emeric Brunfc0421f2012-09-07 17:30:07 +02002716{
Willy Tarreau03209342016-12-22 17:08:28 +01002717 struct proxy *curproxy = bind_conf->frontend;
Emeric Brunfc0421f2012-09-07 17:30:07 +02002718 int cfgerr = 0;
Emeric Brun850efd52014-01-29 12:24:34 +01002719 int verify = SSL_VERIFY_NONE;
Remi Gacogneaf5c3da2014-05-19 10:29:58 +02002720 long ssloptions =
Emeric Brunfc0421f2012-09-07 17:30:07 +02002721 SSL_OP_ALL | /* all known workarounds for bugs */
2722 SSL_OP_NO_SSLv2 |
2723 SSL_OP_NO_COMPRESSION |
Emeric Bruna4bcd9a2012-09-20 16:19:02 +02002724 SSL_OP_SINGLE_DH_USE |
Emeric Brun2b58d042012-09-20 17:10:03 +02002725 SSL_OP_SINGLE_ECDH_USE |
Emeric Brun3c4bc6e2012-10-04 18:44:19 +02002726 SSL_OP_NO_SESSION_RESUMPTION_ON_RENEGOTIATION |
2727 SSL_OP_CIPHER_SERVER_PREFERENCE;
Remi Gacogneaf5c3da2014-05-19 10:29:58 +02002728 long sslmode =
Emeric Brunfc0421f2012-09-07 17:30:07 +02002729 SSL_MODE_ENABLE_PARTIAL_WRITE |
2730 SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER |
Willy Tarreau396a1862014-11-13 14:06:52 +01002731 SSL_MODE_RELEASE_BUFFERS |
2732 SSL_MODE_SMALL_BUFFERS;
Remi Gacognef46cd6e2014-06-12 14:58:40 +02002733 STACK_OF(SSL_CIPHER) * ciphers = NULL;
Willy Tarreaua616ba62014-10-26 06:49:19 +01002734 SSL_CIPHER * cipher = NULL;
Remi Gacognec1eab8c2014-06-12 18:20:11 +02002735 char cipher_description[128];
2736 /* The description of ciphers using an Ephemeral Diffie Hellman key exchange
2737 contains " Kx=DH " or " Kx=DH(". Beware of " Kx=DH/",
2738 which is not ephemeral DH. */
2739 const char dhe_description[] = " Kx=DH ";
2740 const char dhe_export_description[] = " Kx=DH(";
Remi Gacognef46cd6e2014-06-12 14:58:40 +02002741 int idx = 0;
2742 int dhe_found = 0;
Remi Gacogne23d5d372014-10-10 17:04:26 +02002743 SSL *ssl = NULL;
Emeric Brunfc0421f2012-09-07 17:30:07 +02002744
Thierry Fournier383085f2013-01-24 14:15:43 +01002745 /* Make sure openssl opens /dev/urandom before the chroot */
2746 if (!ssl_initialize_random()) {
2747 Alert("OpenSSL random data generator initialization failed.\n");
2748 cfgerr++;
2749 }
2750
Emeric Brun89675492012-10-05 13:48:26 +02002751 if (bind_conf->ssl_options & BC_SSL_O_NO_SSLV3)
Emeric Brunfc0421f2012-09-07 17:30:07 +02002752 ssloptions |= SSL_OP_NO_SSLv3;
Emeric Brun89675492012-10-05 13:48:26 +02002753 if (bind_conf->ssl_options & BC_SSL_O_NO_TLSV10)
Emeric Brunfc0421f2012-09-07 17:30:07 +02002754 ssloptions |= SSL_OP_NO_TLSv1;
Emeric Brun89675492012-10-05 13:48:26 +02002755 if (bind_conf->ssl_options & BC_SSL_O_NO_TLSV11)
Emeric Brunc0ff4922012-09-28 19:37:02 +02002756 ssloptions |= SSL_OP_NO_TLSv1_1;
Emeric Brun89675492012-10-05 13:48:26 +02002757 if (bind_conf->ssl_options & BC_SSL_O_NO_TLSV12)
Emeric Brunc0ff4922012-09-28 19:37:02 +02002758 ssloptions |= SSL_OP_NO_TLSv1_2;
Emeric Brun89675492012-10-05 13:48:26 +02002759 if (bind_conf->ssl_options & BC_SSL_O_NO_TLS_TICKETS)
Emeric Brun2d0c4822012-10-02 13:45:20 +02002760 ssloptions |= SSL_OP_NO_TICKET;
Jérémie Courrèges-Anglas17c3f622015-07-25 16:50:52 -06002761 if (bind_conf->ssl_options & BC_SSL_O_USE_SSLV3) {
2762#ifndef OPENSSL_NO_SSL3
Emeric Brun2cb7ae52012-10-05 14:14:21 +02002763 SSL_CTX_set_ssl_version(ctx, SSLv3_server_method());
Jérémie Courrèges-Anglas17c3f622015-07-25 16:50:52 -06002764#else
2765 Alert("SSLv3 support requested but unavailable.\n");
2766 cfgerr++;
2767#endif
2768 }
Emeric Brun2cb7ae52012-10-05 14:14:21 +02002769 if (bind_conf->ssl_options & BC_SSL_O_USE_TLSV10)
2770 SSL_CTX_set_ssl_version(ctx, TLSv1_server_method());
2771#if SSL_OP_NO_TLSv1_1
2772 if (bind_conf->ssl_options & BC_SSL_O_USE_TLSV11)
2773 SSL_CTX_set_ssl_version(ctx, TLSv1_1_server_method());
2774#endif
2775#if SSL_OP_NO_TLSv1_2
2776 if (bind_conf->ssl_options & BC_SSL_O_USE_TLSV12)
2777 SSL_CTX_set_ssl_version(ctx, TLSv1_2_server_method());
2778#endif
Emeric Brunfc0421f2012-09-07 17:30:07 +02002779
2780 SSL_CTX_set_options(ctx, ssloptions);
2781 SSL_CTX_set_mode(ctx, sslmode);
Emeric Brun850efd52014-01-29 12:24:34 +01002782 switch (bind_conf->verify) {
2783 case SSL_SOCK_VERIFY_NONE:
2784 verify = SSL_VERIFY_NONE;
2785 break;
2786 case SSL_SOCK_VERIFY_OPTIONAL:
2787 verify = SSL_VERIFY_PEER;
2788 break;
2789 case SSL_SOCK_VERIFY_REQUIRED:
2790 verify = SSL_VERIFY_PEER|SSL_VERIFY_FAIL_IF_NO_PEER_CERT;
2791 break;
2792 }
2793 SSL_CTX_set_verify(ctx, verify, ssl_sock_bind_verifycbk);
2794 if (verify & SSL_VERIFY_PEER) {
Emeric Brunfb510ea2012-10-05 12:00:26 +02002795 if (bind_conf->ca_file) {
Emeric Brund94b3fe2012-09-20 18:23:56 +02002796 /* load CAfile to verify */
Emeric Brunfb510ea2012-10-05 12:00:26 +02002797 if (!SSL_CTX_load_verify_locations(ctx, bind_conf->ca_file, NULL)) {
Emeric Brund94b3fe2012-09-20 18:23:56 +02002798 Alert("Proxy '%s': unable to load CA file '%s' for bind '%s' at [%s:%d].\n",
Emeric Brunfb510ea2012-10-05 12:00:26 +02002799 curproxy->id, bind_conf->ca_file, bind_conf->arg, bind_conf->file, bind_conf->line);
Emeric Brund94b3fe2012-09-20 18:23:56 +02002800 cfgerr++;
2801 }
2802 /* set CA names fo client cert request, function returns void */
Emeric Brunfb510ea2012-10-05 12:00:26 +02002803 SSL_CTX_set_client_CA_list(ctx, SSL_load_client_CA_file(bind_conf->ca_file));
Emeric Brund94b3fe2012-09-20 18:23:56 +02002804 }
Emeric Brun850efd52014-01-29 12:24:34 +01002805 else {
2806 Alert("Proxy '%s': verify is enabled but no CA file specified for bind '%s' at [%s:%d].\n",
2807 curproxy->id, bind_conf->arg, bind_conf->file, bind_conf->line);
2808 cfgerr++;
2809 }
Emeric Brun051cdab2012-10-02 19:25:50 +02002810#ifdef X509_V_FLAG_CRL_CHECK
Emeric Brunfb510ea2012-10-05 12:00:26 +02002811 if (bind_conf->crl_file) {
Emeric Brund94b3fe2012-09-20 18:23:56 +02002812 X509_STORE *store = SSL_CTX_get_cert_store(ctx);
2813
Emeric Brunfb510ea2012-10-05 12:00:26 +02002814 if (!store || !X509_STORE_load_locations(store, bind_conf->crl_file, NULL)) {
Emeric Brund94b3fe2012-09-20 18:23:56 +02002815 Alert("Proxy '%s': unable to configure CRL file '%s' for bind '%s' at [%s:%d].\n",
Alexander Rigbofc65af02015-04-07 14:02:16 +02002816 curproxy->id, bind_conf->crl_file, bind_conf->arg, bind_conf->file, bind_conf->line);
Emeric Brund94b3fe2012-09-20 18:23:56 +02002817 cfgerr++;
2818 }
Emeric Brun561e5742012-10-02 15:20:55 +02002819 else {
2820 X509_STORE_set_flags(store, X509_V_FLAG_CRL_CHECK|X509_V_FLAG_CRL_CHECK_ALL);
2821 }
Emeric Brund94b3fe2012-09-20 18:23:56 +02002822 }
Emeric Brun051cdab2012-10-02 19:25:50 +02002823#endif
Emeric Brun644cde02012-12-14 11:21:13 +01002824 ERR_clear_error();
Emeric Brund94b3fe2012-09-20 18:23:56 +02002825 }
Emeric Brunfc0421f2012-09-07 17:30:07 +02002826
Nenad Merdanovic05552d42015-02-27 19:56:49 +01002827#if (defined SSL_CTRL_SET_TLSEXT_TICKET_KEY_CB && TLS_TICKETS_NO > 0)
Nenad Merdanovic146defa2015-05-09 08:46:00 +02002828 if(bind_conf->keys_ref) {
Nenad Merdanovic05552d42015-02-27 19:56:49 +01002829 if (!SSL_CTX_set_tlsext_ticket_key_cb(ctx, ssl_tlsext_ticket_key_cb)) {
2830 Alert("Proxy '%s': unable to set callback for TLS ticket validation for bind '%s' at [%s:%d].\n",
2831 curproxy->id, bind_conf->arg, bind_conf->file, bind_conf->line);
2832 cfgerr++;
2833 }
2834 }
2835#endif
2836
Willy Tarreauef934602016-12-22 23:12:01 +01002837 if (global_ssl.life_time)
2838 SSL_CTX_set_timeout(ctx, global_ssl.life_time);
Emeric Brun4f65bff2012-11-16 15:11:00 +01002839
Emeric Brunfc0421f2012-09-07 17:30:07 +02002840 shared_context_set_cache(ctx);
Willy Tarreau2a65ff02012-09-13 17:54:29 +02002841 if (bind_conf->ciphers &&
2842 !SSL_CTX_set_cipher_list(ctx, bind_conf->ciphers)) {
Emeric Brunfc0421f2012-09-07 17:30:07 +02002843 Alert("Proxy '%s': unable to set SSL cipher list to '%s' for bind '%s' at [%s:%d].\n",
Willy Tarreau2a65ff02012-09-13 17:54:29 +02002844 curproxy->id, bind_conf->ciphers, bind_conf->arg, bind_conf->file, bind_conf->line);
Emeric Brunfc0421f2012-09-07 17:30:07 +02002845 cfgerr++;
2846 }
2847
Remi Gacogne47783ef2015-05-29 15:53:22 +02002848 /* If tune.ssl.default-dh-param has not been set,
2849 neither has ssl-default-dh-file and no static DH
2850 params were in the certificate file. */
Willy Tarreauef934602016-12-22 23:12:01 +01002851 if (global_ssl.default_dh_param == 0 &&
Remi Gacogne47783ef2015-05-29 15:53:22 +02002852 global_dh == NULL &&
Remi Gacogne4f902b82015-05-28 16:23:00 +02002853 (ssl_dh_ptr_index == -1 ||
2854 SSL_CTX_get_ex_data(ctx, ssl_dh_ptr_index) == NULL)) {
Lukas Tribus90132722014-08-18 00:56:33 +02002855
Remi Gacogne23d5d372014-10-10 17:04:26 +02002856 ssl = SSL_new(ctx);
Remi Gacognef46cd6e2014-06-12 14:58:40 +02002857
Remi Gacogne23d5d372014-10-10 17:04:26 +02002858 if (ssl) {
2859 ciphers = SSL_get_ciphers(ssl);
2860
2861 if (ciphers) {
2862 for (idx = 0; idx < sk_SSL_CIPHER_num(ciphers); idx++) {
2863 cipher = sk_SSL_CIPHER_value(ciphers, idx);
2864 if (SSL_CIPHER_description(cipher, cipher_description, sizeof (cipher_description)) == cipher_description) {
2865 if (strstr(cipher_description, dhe_description) != NULL ||
2866 strstr(cipher_description, dhe_export_description) != NULL) {
2867 dhe_found = 1;
2868 break;
2869 }
Remi Gacognec1eab8c2014-06-12 18:20:11 +02002870 }
Remi Gacognef46cd6e2014-06-12 14:58:40 +02002871 }
2872 }
Remi Gacogne23d5d372014-10-10 17:04:26 +02002873 SSL_free(ssl);
2874 ssl = NULL;
Lukas Tribus90132722014-08-18 00:56:33 +02002875 }
Remi Gacognef46cd6e2014-06-12 14:58:40 +02002876
Lukas Tribus90132722014-08-18 00:56:33 +02002877 if (dhe_found) {
2878 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 +02002879 }
2880
Willy Tarreauef934602016-12-22 23:12:01 +01002881 global_ssl.default_dh_param = 1024;
Remi Gacognef46cd6e2014-06-12 14:58:40 +02002882 }
Remi Gacogne8de54152014-07-15 11:36:40 +02002883
2884#ifndef OPENSSL_NO_DH
Willy Tarreauef934602016-12-22 23:12:01 +01002885 if (global_ssl.default_dh_param >= 1024) {
Remi Gacogne8de54152014-07-15 11:36:40 +02002886 if (local_dh_1024 == NULL) {
2887 local_dh_1024 = ssl_get_dh_1024();
2888 }
Willy Tarreauef934602016-12-22 23:12:01 +01002889 if (global_ssl.default_dh_param >= 2048) {
Remi Gacogne8de54152014-07-15 11:36:40 +02002890 if (local_dh_2048 == NULL) {
2891 local_dh_2048 = ssl_get_dh_2048();
2892 }
Willy Tarreauef934602016-12-22 23:12:01 +01002893 if (global_ssl.default_dh_param >= 4096) {
Remi Gacogne8de54152014-07-15 11:36:40 +02002894 if (local_dh_4096 == NULL) {
2895 local_dh_4096 = ssl_get_dh_4096();
2896 }
Remi Gacogne8de54152014-07-15 11:36:40 +02002897 }
2898 }
2899 }
2900#endif /* OPENSSL_NO_DH */
Remi Gacognef46cd6e2014-06-12 14:58:40 +02002901
Emeric Brunfc0421f2012-09-07 17:30:07 +02002902 SSL_CTX_set_info_callback(ctx, ssl_sock_infocbk);
Willy Tarreau5cbe4ef2014-05-08 22:45:11 +02002903#if OPENSSL_VERSION_NUMBER >= 0x00907000L
Emeric Brun29f037d2014-04-25 19:05:36 +02002904 SSL_CTX_set_msg_callback(ctx, ssl_sock_msgcbk);
Willy Tarreau5cbe4ef2014-05-08 22:45:11 +02002905#endif
Emeric Brun29f037d2014-04-25 19:05:36 +02002906
Willy Tarreau6c9a3d52012-10-18 18:57:14 +02002907#ifdef OPENSSL_NPN_NEGOTIATED
2908 if (bind_conf->npn_str)
2909 SSL_CTX_set_next_protos_advertised_cb(ctx, ssl_sock_advertise_npn_protos, bind_conf);
2910#endif
Dirkjan Bussink48f1c4e2014-02-13 12:29:42 +01002911#ifdef TLSEXT_TYPE_application_layer_protocol_negotiation
Willy Tarreauab861d32013-04-02 02:30:41 +02002912 if (bind_conf->alpn_str)
Dirkjan Bussink48f1c4e2014-02-13 12:29:42 +01002913 SSL_CTX_set_alpn_select_cb(ctx, ssl_sock_advertise_alpn_protos, bind_conf);
Willy Tarreauab861d32013-04-02 02:30:41 +02002914#endif
Willy Tarreau6c9a3d52012-10-18 18:57:14 +02002915
Emeric Brunfc0421f2012-09-07 17:30:07 +02002916#ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME
2917 SSL_CTX_set_tlsext_servername_callback(ctx, ssl_sock_switchctx_cbk);
Willy Tarreau2a65ff02012-09-13 17:54:29 +02002918 SSL_CTX_set_tlsext_servername_arg(ctx, bind_conf);
Emeric Brunfc0421f2012-09-07 17:30:07 +02002919#endif
Emeric Brun2b58d042012-09-20 17:10:03 +02002920#if defined(SSL_CTX_set_tmp_ecdh) && !defined(OPENSSL_NO_ECDH)
Emeric Brun6924ef82013-03-06 14:08:53 +01002921 {
Emeric Brun2b58d042012-09-20 17:10:03 +02002922 int i;
2923 EC_KEY *ecdh;
2924
Emeric Brun6924ef82013-03-06 14:08:53 +01002925 i = OBJ_sn2nid(bind_conf->ecdhe ? bind_conf->ecdhe : ECDHE_DEFAULT_CURVE);
Emeric Brun2b58d042012-09-20 17:10:03 +02002926 if (!i || ((ecdh = EC_KEY_new_by_curve_name(i)) == NULL)) {
2927 Alert("Proxy '%s': unable to set elliptic named curve to '%s' for bind '%s' at [%s:%d].\n",
Emeric Brun6924ef82013-03-06 14:08:53 +01002928 curproxy->id, bind_conf->ecdhe ? bind_conf->ecdhe : ECDHE_DEFAULT_CURVE,
2929 bind_conf->arg, bind_conf->file, bind_conf->line);
Emeric Brun2b58d042012-09-20 17:10:03 +02002930 cfgerr++;
2931 }
2932 else {
2933 SSL_CTX_set_tmp_ecdh(ctx, ecdh);
2934 EC_KEY_free(ecdh);
2935 }
2936 }
2937#endif
2938
Emeric Brunfc0421f2012-09-07 17:30:07 +02002939 return cfgerr;
2940}
2941
Evan Broderbe554312013-06-27 00:05:25 -07002942static int ssl_sock_srv_hostcheck(const char *pattern, const char *hostname)
2943{
2944 const char *pattern_wildcard, *pattern_left_label_end, *hostname_left_label_end;
2945 size_t prefixlen, suffixlen;
2946
2947 /* Trivial case */
2948 if (strcmp(pattern, hostname) == 0)
2949 return 1;
2950
Evan Broderbe554312013-06-27 00:05:25 -07002951 /* The rest of this logic is based on RFC 6125, section 6.4.3
2952 * (http://tools.ietf.org/html/rfc6125#section-6.4.3) */
2953
Emeric Bruna848dae2013-10-08 11:27:28 +02002954 pattern_wildcard = NULL;
2955 pattern_left_label_end = pattern;
2956 while (*pattern_left_label_end != '.') {
2957 switch (*pattern_left_label_end) {
2958 case 0:
2959 /* End of label not found */
2960 return 0;
2961 case '*':
2962 /* If there is more than one wildcards */
2963 if (pattern_wildcard)
2964 return 0;
2965 pattern_wildcard = pattern_left_label_end;
2966 break;
2967 }
2968 pattern_left_label_end++;
2969 }
2970
2971 /* If it's not trivial and there is no wildcard, it can't
2972 * match */
2973 if (!pattern_wildcard)
Evan Broderbe554312013-06-27 00:05:25 -07002974 return 0;
2975
2976 /* Make sure all labels match except the leftmost */
2977 hostname_left_label_end = strchr(hostname, '.');
2978 if (!hostname_left_label_end
2979 || strcmp(pattern_left_label_end, hostname_left_label_end) != 0)
2980 return 0;
2981
2982 /* Make sure the leftmost label of the hostname is long enough
2983 * that the wildcard can match */
Emeric Brun369da852013-10-08 11:39:35 +02002984 if (hostname_left_label_end - hostname < (pattern_left_label_end - pattern) - 1)
Evan Broderbe554312013-06-27 00:05:25 -07002985 return 0;
2986
2987 /* Finally compare the string on either side of the
2988 * wildcard */
2989 prefixlen = pattern_wildcard - pattern;
2990 suffixlen = pattern_left_label_end - (pattern_wildcard + 1);
Emeric Bruna848dae2013-10-08 11:27:28 +02002991 if ((prefixlen && (memcmp(pattern, hostname, prefixlen) != 0))
2992 || (suffixlen && (memcmp(pattern_wildcard + 1, hostname_left_label_end - suffixlen, suffixlen) != 0)))
Evan Broderbe554312013-06-27 00:05:25 -07002993 return 0;
2994
2995 return 1;
2996}
2997
2998static int ssl_sock_srv_verifycbk(int ok, X509_STORE_CTX *ctx)
2999{
3000 SSL *ssl;
3001 struct connection *conn;
3002 char *servername;
3003
3004 int depth;
3005 X509 *cert;
3006 STACK_OF(GENERAL_NAME) *alt_names;
3007 int i;
3008 X509_NAME *cert_subject;
3009 char *str;
3010
3011 if (ok == 0)
3012 return ok;
3013
3014 ssl = X509_STORE_CTX_get_ex_data(ctx, SSL_get_ex_data_X509_STORE_CTX_idx());
Vincent Bernat3c2f2f22016-04-03 13:48:42 +02003015 conn = SSL_get_app_data(ssl);
Evan Broderbe554312013-06-27 00:05:25 -07003016
3017 servername = objt_server(conn->target)->ssl_ctx.verify_host;
3018
3019 /* We only need to verify the CN on the actual server cert,
3020 * not the indirect CAs */
3021 depth = X509_STORE_CTX_get_error_depth(ctx);
3022 if (depth != 0)
3023 return ok;
3024
3025 /* At this point, the cert is *not* OK unless we can find a
3026 * hostname match */
3027 ok = 0;
3028
3029 cert = X509_STORE_CTX_get_current_cert(ctx);
3030 /* It seems like this might happen if verify peer isn't set */
3031 if (!cert)
3032 return ok;
3033
3034 alt_names = X509_get_ext_d2i(cert, NID_subject_alt_name, NULL, NULL);
3035 if (alt_names) {
3036 for (i = 0; !ok && i < sk_GENERAL_NAME_num(alt_names); i++) {
3037 GENERAL_NAME *name = sk_GENERAL_NAME_value(alt_names, i);
3038 if (name->type == GEN_DNS) {
Emeric Bruna33410c2013-09-17 15:47:48 +02003039#if OPENSSL_VERSION_NUMBER < 0x00907000L
3040 if (ASN1_STRING_to_UTF8((unsigned char **)&str, name->d.ia5) >= 0) {
3041#else
Evan Broderbe554312013-06-27 00:05:25 -07003042 if (ASN1_STRING_to_UTF8((unsigned char **)&str, name->d.dNSName) >= 0) {
Emeric Bruna33410c2013-09-17 15:47:48 +02003043#endif
Evan Broderbe554312013-06-27 00:05:25 -07003044 ok = ssl_sock_srv_hostcheck(str, servername);
3045 OPENSSL_free(str);
3046 }
3047 }
3048 }
Emeric Brun4ad50a42013-09-17 15:19:54 +02003049 sk_GENERAL_NAME_pop_free(alt_names, GENERAL_NAME_free);
Evan Broderbe554312013-06-27 00:05:25 -07003050 }
3051
3052 cert_subject = X509_get_subject_name(cert);
3053 i = -1;
3054 while (!ok && (i = X509_NAME_get_index_by_NID(cert_subject, NID_commonName, i)) != -1) {
3055 X509_NAME_ENTRY *entry = X509_NAME_get_entry(cert_subject, i);
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02003056 ASN1_STRING *value;
3057 value = X509_NAME_ENTRY_get_data(entry);
3058 if (ASN1_STRING_to_UTF8((unsigned char **)&str, value) >= 0) {
Evan Broderbe554312013-06-27 00:05:25 -07003059 ok = ssl_sock_srv_hostcheck(str, servername);
3060 OPENSSL_free(str);
3061 }
3062 }
3063
3064 return ok;
3065}
3066
Emeric Brun94324a42012-10-11 14:00:19 +02003067/* prepare ssl context from servers options. Returns an error count */
Willy Tarreau03209342016-12-22 17:08:28 +01003068int ssl_sock_prepare_srv_ctx(struct server *srv)
Emeric Brun94324a42012-10-11 14:00:19 +02003069{
Willy Tarreau03209342016-12-22 17:08:28 +01003070 struct proxy *curproxy = srv->proxy;
Emeric Brun94324a42012-10-11 14:00:19 +02003071 int cfgerr = 0;
Remi Gacogneaf5c3da2014-05-19 10:29:58 +02003072 long options =
Emeric Brun94324a42012-10-11 14:00:19 +02003073 SSL_OP_ALL | /* all known workarounds for bugs */
3074 SSL_OP_NO_SSLv2 |
3075 SSL_OP_NO_COMPRESSION;
Remi Gacogneaf5c3da2014-05-19 10:29:58 +02003076 long mode =
Emeric Brun94324a42012-10-11 14:00:19 +02003077 SSL_MODE_ENABLE_PARTIAL_WRITE |
3078 SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER |
Willy Tarreau396a1862014-11-13 14:06:52 +01003079 SSL_MODE_RELEASE_BUFFERS |
3080 SSL_MODE_SMALL_BUFFERS;
Emeric Brun850efd52014-01-29 12:24:34 +01003081 int verify = SSL_VERIFY_NONE;
Emeric Brun94324a42012-10-11 14:00:19 +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
Willy Tarreaufce03112015-01-15 21:32:40 +01003089 /* Automatic memory computations need to know we use SSL there */
3090 global.ssl_used_backend = 1;
3091
3092 /* Initiate SSL context for current server */
Emeric Brun94324a42012-10-11 14:00:19 +02003093 srv->ssl_ctx.reused_sess = NULL;
3094 if (srv->use_ssl)
3095 srv->xprt = &ssl_sock;
3096 if (srv->check.use_ssl)
Cyril Bonté9ce13112014-11-15 22:41:27 +01003097 srv->check.xprt = &ssl_sock;
Emeric Brun94324a42012-10-11 14:00:19 +02003098
3099 srv->ssl_ctx.ctx = SSL_CTX_new(SSLv23_client_method());
3100 if (!srv->ssl_ctx.ctx) {
3101 Alert("config : %s '%s', server '%s': unable to allocate ssl context.\n",
3102 proxy_type_str(curproxy), curproxy->id,
3103 srv->id);
3104 cfgerr++;
3105 return cfgerr;
3106 }
Emeric Bruna7aa3092012-10-26 12:58:00 +02003107 if (srv->ssl_ctx.client_crt) {
3108 if (SSL_CTX_use_PrivateKey_file(srv->ssl_ctx.ctx, srv->ssl_ctx.client_crt, SSL_FILETYPE_PEM) <= 0) {
3109 Alert("config : %s '%s', server '%s': unable to load SSL private key from PEM file '%s'.\n",
3110 proxy_type_str(curproxy), curproxy->id,
3111 srv->id, srv->ssl_ctx.client_crt);
3112 cfgerr++;
3113 }
3114 else if (SSL_CTX_use_certificate_chain_file(srv->ssl_ctx.ctx, srv->ssl_ctx.client_crt) <= 0) {
3115 Alert("config : %s '%s', server '%s': unable to load ssl certificate from PEM file '%s'.\n",
3116 proxy_type_str(curproxy), curproxy->id,
3117 srv->id, srv->ssl_ctx.client_crt);
3118 cfgerr++;
3119 }
3120 else if (SSL_CTX_check_private_key(srv->ssl_ctx.ctx) <= 0) {
3121 Alert("config : %s '%s', server '%s': inconsistencies between private key and certificate loaded from PEM file '%s'.\n",
3122 proxy_type_str(curproxy), curproxy->id,
3123 srv->id, srv->ssl_ctx.client_crt);
3124 cfgerr++;
3125 }
3126 }
Emeric Brun94324a42012-10-11 14:00:19 +02003127
3128 if (srv->ssl_ctx.options & SRV_SSL_O_NO_SSLV3)
3129 options |= SSL_OP_NO_SSLv3;
3130 if (srv->ssl_ctx.options & SRV_SSL_O_NO_TLSV10)
3131 options |= SSL_OP_NO_TLSv1;
3132 if (srv->ssl_ctx.options & SRV_SSL_O_NO_TLSV11)
3133 options |= SSL_OP_NO_TLSv1_1;
3134 if (srv->ssl_ctx.options & SRV_SSL_O_NO_TLSV12)
3135 options |= SSL_OP_NO_TLSv1_2;
Emeric Brunf9c5c472012-10-11 15:28:34 +02003136 if (srv->ssl_ctx.options & SRV_SSL_O_NO_TLS_TICKETS)
3137 options |= SSL_OP_NO_TICKET;
Jérémie Courrèges-Anglas17c3f622015-07-25 16:50:52 -06003138 if (srv->ssl_ctx.options & SRV_SSL_O_USE_SSLV3) {
3139#ifndef OPENSSL_NO_SSL3
Emeric Brun94324a42012-10-11 14:00:19 +02003140 SSL_CTX_set_ssl_version(srv->ssl_ctx.ctx, SSLv3_client_method());
Jérémie Courrèges-Anglas17c3f622015-07-25 16:50:52 -06003141#else
Thierry FOURNIERbc965342015-08-26 08:21:26 +02003142 Alert("SSLv3 support requested but unavailable.\n");
Jérémie Courrèges-Anglas17c3f622015-07-25 16:50:52 -06003143 cfgerr++;
3144#endif
3145 }
Emeric Brun94324a42012-10-11 14:00:19 +02003146 if (srv->ssl_ctx.options & SRV_SSL_O_USE_TLSV10)
3147 SSL_CTX_set_ssl_version(srv->ssl_ctx.ctx, TLSv1_client_method());
3148#if SSL_OP_NO_TLSv1_1
3149 if (srv->ssl_ctx.options & SRV_SSL_O_USE_TLSV11)
3150 SSL_CTX_set_ssl_version(srv->ssl_ctx.ctx, TLSv1_1_client_method());
3151#endif
3152#if SSL_OP_NO_TLSv1_2
3153 if (srv->ssl_ctx.options & SRV_SSL_O_USE_TLSV12)
3154 SSL_CTX_set_ssl_version(srv->ssl_ctx.ctx, TLSv1_2_client_method());
3155#endif
3156
3157 SSL_CTX_set_options(srv->ssl_ctx.ctx, options);
3158 SSL_CTX_set_mode(srv->ssl_ctx.ctx, mode);
Emeric Brun850efd52014-01-29 12:24:34 +01003159
3160 if (global.ssl_server_verify == SSL_SERVER_VERIFY_REQUIRED)
3161 verify = SSL_VERIFY_PEER;
3162
3163 switch (srv->ssl_ctx.verify) {
3164 case SSL_SOCK_VERIFY_NONE:
3165 verify = SSL_VERIFY_NONE;
3166 break;
3167 case SSL_SOCK_VERIFY_REQUIRED:
3168 verify = SSL_VERIFY_PEER;
3169 break;
3170 }
Evan Broderbe554312013-06-27 00:05:25 -07003171 SSL_CTX_set_verify(srv->ssl_ctx.ctx,
Emeric Brun850efd52014-01-29 12:24:34 +01003172 verify,
Evan Broderbe554312013-06-27 00:05:25 -07003173 srv->ssl_ctx.verify_host ? ssl_sock_srv_verifycbk : NULL);
Emeric Brun850efd52014-01-29 12:24:34 +01003174 if (verify & SSL_VERIFY_PEER) {
Emeric Brunef42d922012-10-11 16:11:36 +02003175 if (srv->ssl_ctx.ca_file) {
3176 /* load CAfile to verify */
3177 if (!SSL_CTX_load_verify_locations(srv->ssl_ctx.ctx, srv->ssl_ctx.ca_file, NULL)) {
Willy Tarreau07ba08b2014-02-16 19:22:08 +01003178 Alert("Proxy '%s', server '%s' [%s:%d] unable to load CA file '%s'.\n",
Emeric Brunef42d922012-10-11 16:11:36 +02003179 curproxy->id, srv->id,
3180 srv->conf.file, srv->conf.line, srv->ssl_ctx.ca_file);
3181 cfgerr++;
3182 }
3183 }
Emeric Brun850efd52014-01-29 12:24:34 +01003184 else {
3185 if (global.ssl_server_verify == SSL_SERVER_VERIFY_REQUIRED)
Willy Tarreau07ba08b2014-02-16 19:22:08 +01003186 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 +01003187 curproxy->id, srv->id,
3188 srv->conf.file, srv->conf.line);
3189 else
Willy Tarreau07ba08b2014-02-16 19:22:08 +01003190 Alert("Proxy '%s', server '%s' [%s:%d] verify is enabled but no CA file specified.\n",
Emeric Brun850efd52014-01-29 12:24:34 +01003191 curproxy->id, srv->id,
3192 srv->conf.file, srv->conf.line);
3193 cfgerr++;
3194 }
Emeric Brunef42d922012-10-11 16:11:36 +02003195#ifdef X509_V_FLAG_CRL_CHECK
3196 if (srv->ssl_ctx.crl_file) {
3197 X509_STORE *store = SSL_CTX_get_cert_store(srv->ssl_ctx.ctx);
3198
3199 if (!store || !X509_STORE_load_locations(store, srv->ssl_ctx.crl_file, NULL)) {
Willy Tarreau07ba08b2014-02-16 19:22:08 +01003200 Alert("Proxy '%s', server '%s' [%s:%d] unable to configure CRL file '%s'.\n",
Emeric Brunef42d922012-10-11 16:11:36 +02003201 curproxy->id, srv->id,
3202 srv->conf.file, srv->conf.line, srv->ssl_ctx.crl_file);
3203 cfgerr++;
3204 }
3205 else {
3206 X509_STORE_set_flags(store, X509_V_FLAG_CRL_CHECK|X509_V_FLAG_CRL_CHECK_ALL);
3207 }
3208 }
3209#endif
3210 }
3211
Willy Tarreauef934602016-12-22 23:12:01 +01003212 if (global_ssl.life_time)
3213 SSL_CTX_set_timeout(srv->ssl_ctx.ctx, global_ssl.life_time);
Emeric Brun4f65bff2012-11-16 15:11:00 +01003214
Emeric Brun94324a42012-10-11 14:00:19 +02003215 SSL_CTX_set_session_cache_mode(srv->ssl_ctx.ctx, SSL_SESS_CACHE_OFF);
3216 if (srv->ssl_ctx.ciphers &&
3217 !SSL_CTX_set_cipher_list(srv->ssl_ctx.ctx, srv->ssl_ctx.ciphers)) {
3218 Alert("Proxy '%s', server '%s' [%s:%d] : unable to set SSL cipher list to '%s'.\n",
3219 curproxy->id, srv->id,
3220 srv->conf.file, srv->conf.line, srv->ssl_ctx.ciphers);
3221 cfgerr++;
3222 }
3223
3224 return cfgerr;
3225}
3226
Willy Tarreau2a65ff02012-09-13 17:54:29 +02003227/* Walks down the two trees in bind_conf and prepares all certs. The pointer may
Emeric Brunfc0421f2012-09-07 17:30:07 +02003228 * be NULL, in which case nothing is done. Returns the number of errors
3229 * encountered.
3230 */
Willy Tarreau03209342016-12-22 17:08:28 +01003231int ssl_sock_prepare_all_ctx(struct bind_conf *bind_conf)
Emeric Brunfc0421f2012-09-07 17:30:07 +02003232{
3233 struct ebmb_node *node;
3234 struct sni_ctx *sni;
3235 int err = 0;
3236
Willy Tarreau2a65ff02012-09-13 17:54:29 +02003237 if (!bind_conf || !bind_conf->is_ssl)
Emeric Brunfc0421f2012-09-07 17:30:07 +02003238 return 0;
3239
Willy Tarreaufce03112015-01-15 21:32:40 +01003240 /* Automatic memory computations need to know we use SSL there */
3241 global.ssl_used_frontend = 1;
3242
Emeric Brun0bed9942014-10-30 19:25:24 +01003243 if (bind_conf->default_ctx)
Willy Tarreau03209342016-12-22 17:08:28 +01003244 err += ssl_sock_prepare_ctx(bind_conf, bind_conf->default_ctx);
Emeric Brun0bed9942014-10-30 19:25:24 +01003245
Willy Tarreau2a65ff02012-09-13 17:54:29 +02003246 node = ebmb_first(&bind_conf->sni_ctx);
Emeric Brunfc0421f2012-09-07 17:30:07 +02003247 while (node) {
3248 sni = ebmb_entry(node, struct sni_ctx, name);
Emeric Brun0bed9942014-10-30 19:25:24 +01003249 if (!sni->order && sni->ctx != bind_conf->default_ctx)
3250 /* only initialize the CTX on its first occurrence and
3251 if it is not the default_ctx */
Willy Tarreau03209342016-12-22 17:08:28 +01003252 err += ssl_sock_prepare_ctx(bind_conf, sni->ctx);
Emeric Brunfc0421f2012-09-07 17:30:07 +02003253 node = ebmb_next(node);
3254 }
3255
Willy Tarreau2a65ff02012-09-13 17:54:29 +02003256 node = ebmb_first(&bind_conf->sni_w_ctx);
Emeric Brunfc0421f2012-09-07 17:30:07 +02003257 while (node) {
3258 sni = ebmb_entry(node, struct sni_ctx, name);
Emeric Brun0bed9942014-10-30 19:25:24 +01003259 if (!sni->order && sni->ctx != bind_conf->default_ctx)
3260 /* only initialize the CTX on its first occurrence and
3261 if it is not the default_ctx */
Willy Tarreau03209342016-12-22 17:08:28 +01003262 err += ssl_sock_prepare_ctx(bind_conf, sni->ctx);
Emeric Brunfc0421f2012-09-07 17:30:07 +02003263 node = ebmb_next(node);
3264 }
3265 return err;
3266}
3267
Willy Tarreau55d37912016-12-21 23:38:39 +01003268/* Prepares all the contexts for a bind_conf and allocates the shared SSL
3269 * context if needed. Returns < 0 on error, 0 on success. The warnings and
3270 * alerts are directly emitted since the rest of the stack does it below.
3271 */
3272int ssl_sock_prepare_bind_conf(struct bind_conf *bind_conf)
3273{
3274 struct proxy *px = bind_conf->frontend;
3275 int alloc_ctx;
3276 int err;
3277
3278 if (!bind_conf->is_ssl) {
3279 if (bind_conf->default_ctx) {
3280 Warning("Proxy '%s': A certificate was specified but SSL was not enabled on bind '%s' at [%s:%d] (use 'ssl').\n",
3281 px->id, bind_conf->arg, bind_conf->file, bind_conf->line);
3282 }
3283 return 0;
3284 }
3285 if (!bind_conf->default_ctx) {
3286 Alert("Proxy '%s': no SSL certificate specified for bind '%s' at [%s:%d] (use 'crt').\n",
3287 px->id, bind_conf->arg, bind_conf->file, bind_conf->line);
3288 return -1;
3289 }
3290
Willy Tarreauef934602016-12-22 23:12:01 +01003291 alloc_ctx = shared_context_init(global.tune.sslcachesize, (!global_ssl.private_cache && (global.nbproc > 1)) ? 1 : 0);
Willy Tarreau55d37912016-12-21 23:38:39 +01003292 if (alloc_ctx < 0) {
3293 if (alloc_ctx == SHCTX_E_INIT_LOCK)
3294 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");
3295 else
3296 Alert("Unable to allocate SSL session cache.\n");
3297 return -1;
3298 }
3299
3300 err = 0;
3301 /* initialize all certificate contexts */
3302 err += ssl_sock_prepare_all_ctx(bind_conf);
3303
3304 /* initialize CA variables if the certificates generation is enabled */
3305 err += ssl_sock_load_ca(bind_conf);
3306
3307 return -err;
3308}
Christopher Faulet77fe80c2015-07-29 13:02:40 +02003309
3310/* release ssl context allocated for servers. */
3311void ssl_sock_free_srv_ctx(struct server *srv)
3312{
3313 if (srv->ssl_ctx.ctx)
3314 SSL_CTX_free(srv->ssl_ctx.ctx);
3315}
3316
Willy Tarreau2a65ff02012-09-13 17:54:29 +02003317/* Walks down the two trees in bind_conf and frees all the certs. The pointer may
Emeric Brunfc0421f2012-09-07 17:30:07 +02003318 * be NULL, in which case nothing is done. The default_ctx is nullified too.
3319 */
Willy Tarreau2a65ff02012-09-13 17:54:29 +02003320void ssl_sock_free_all_ctx(struct bind_conf *bind_conf)
Emeric Brunfc0421f2012-09-07 17:30:07 +02003321{
3322 struct ebmb_node *node, *back;
3323 struct sni_ctx *sni;
3324
Willy Tarreau2a65ff02012-09-13 17:54:29 +02003325 if (!bind_conf || !bind_conf->is_ssl)
Emeric Brunfc0421f2012-09-07 17:30:07 +02003326 return;
3327
Willy Tarreau2a65ff02012-09-13 17:54:29 +02003328 node = ebmb_first(&bind_conf->sni_ctx);
Emeric Brunfc0421f2012-09-07 17:30:07 +02003329 while (node) {
3330 sni = ebmb_entry(node, struct sni_ctx, name);
3331 back = ebmb_next(node);
3332 ebmb_delete(node);
3333 if (!sni->order) /* only free the CTX on its first occurrence */
3334 SSL_CTX_free(sni->ctx);
3335 free(sni);
3336 node = back;
3337 }
3338
Willy Tarreau2a65ff02012-09-13 17:54:29 +02003339 node = ebmb_first(&bind_conf->sni_w_ctx);
Emeric Brunfc0421f2012-09-07 17:30:07 +02003340 while (node) {
3341 sni = ebmb_entry(node, struct sni_ctx, name);
3342 back = ebmb_next(node);
3343 ebmb_delete(node);
3344 if (!sni->order) /* only free the CTX on its first occurrence */
3345 SSL_CTX_free(sni->ctx);
3346 free(sni);
3347 node = back;
3348 }
3349
Willy Tarreau2a65ff02012-09-13 17:54:29 +02003350 bind_conf->default_ctx = NULL;
Emeric Brune1f38db2012-09-03 20:36:47 +02003351}
3352
Willy Tarreau795cdab2016-12-22 17:30:54 +01003353/* Destroys all the contexts for a bind_conf. This is used during deinit(). */
3354void ssl_sock_destroy_bind_conf(struct bind_conf *bind_conf)
3355{
3356 ssl_sock_free_ca(bind_conf);
3357 ssl_sock_free_all_ctx(bind_conf);
3358 free(bind_conf->ca_file);
3359 free(bind_conf->ca_sign_file);
3360 free(bind_conf->ca_sign_pass);
3361 free(bind_conf->ciphers);
3362 free(bind_conf->ecdhe);
3363 free(bind_conf->crl_file);
3364 if (bind_conf->keys_ref) {
3365 free(bind_conf->keys_ref->filename);
3366 free(bind_conf->keys_ref->tlskeys);
3367 LIST_DEL(&bind_conf->keys_ref->list);
3368 free(bind_conf->keys_ref);
3369 }
3370 bind_conf->keys_ref = NULL;
3371 bind_conf->crl_file = NULL;
3372 bind_conf->ecdhe = NULL;
3373 bind_conf->ciphers = NULL;
3374 bind_conf->ca_sign_pass = NULL;
3375 bind_conf->ca_sign_file = NULL;
3376 bind_conf->ca_file = NULL;
3377}
3378
Christopher Faulet31af49d2015-06-09 17:29:50 +02003379/* Load CA cert file and private key used to generate certificates */
3380int
Willy Tarreau03209342016-12-22 17:08:28 +01003381ssl_sock_load_ca(struct bind_conf *bind_conf)
Christopher Faulet31af49d2015-06-09 17:29:50 +02003382{
Willy Tarreau03209342016-12-22 17:08:28 +01003383 struct proxy *px = bind_conf->frontend;
Christopher Faulet31af49d2015-06-09 17:29:50 +02003384 FILE *fp;
3385 X509 *cacert = NULL;
3386 EVP_PKEY *capkey = NULL;
3387 int err = 0;
3388
3389 if (!bind_conf || !bind_conf->generate_certs)
3390 return err;
3391
Willy Tarreaua84c2672015-10-09 12:10:13 +02003392#ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME
Willy Tarreauef934602016-12-22 23:12:01 +01003393 if (global_ssl.ctx_cache)
3394 ssl_ctx_lru_tree = lru64_new(global_ssl.ctx_cache);
Christopher Fauletd2cab922015-07-28 16:03:47 +02003395 ssl_ctx_lru_seed = (unsigned int)time(NULL);
Willy Tarreaua84c2672015-10-09 12:10:13 +02003396#endif
Christopher Fauletd2cab922015-07-28 16:03:47 +02003397
Christopher Faulet31af49d2015-06-09 17:29:50 +02003398 if (!bind_conf->ca_sign_file) {
3399 Alert("Proxy '%s': cannot enable certificate generation, "
3400 "no CA certificate File configured at [%s:%d].\n",
3401 px->id, bind_conf->file, bind_conf->line);
Christopher Faulet31af49d2015-06-09 17:29:50 +02003402 goto load_error;
Christopher Fauletc6f02fb2015-10-09 10:53:31 +02003403 }
Christopher Faulet31af49d2015-06-09 17:29:50 +02003404
3405 /* read in the CA certificate */
3406 if (!(fp = fopen(bind_conf->ca_sign_file, "r"))) {
3407 Alert("Proxy '%s': Failed to read CA certificate file '%s' at [%s:%d].\n",
3408 px->id, bind_conf->ca_sign_file, bind_conf->file, bind_conf->line);
Christopher Faulet31af49d2015-06-09 17:29:50 +02003409 goto load_error;
3410 }
3411 if (!(cacert = PEM_read_X509(fp, NULL, NULL, NULL))) {
3412 Alert("Proxy '%s': Failed to read CA certificate file '%s' at [%s:%d].\n",
3413 px->id, bind_conf->ca_sign_file, bind_conf->file, bind_conf->line);
Christopher Fauletc6f02fb2015-10-09 10:53:31 +02003414 goto read_error;
Christopher Faulet31af49d2015-06-09 17:29:50 +02003415 }
Christopher Fauletc6f02fb2015-10-09 10:53:31 +02003416 rewind(fp);
Christopher Faulet31af49d2015-06-09 17:29:50 +02003417 if (!(capkey = PEM_read_PrivateKey(fp, NULL, NULL, bind_conf->ca_sign_pass))) {
3418 Alert("Proxy '%s': Failed to read CA private key file '%s' at [%s:%d].\n",
3419 px->id, bind_conf->ca_sign_file, bind_conf->file, bind_conf->line);
Christopher Fauletc6f02fb2015-10-09 10:53:31 +02003420 goto read_error;
Christopher Faulet31af49d2015-06-09 17:29:50 +02003421 }
Christopher Faulet31af49d2015-06-09 17:29:50 +02003422
Christopher Fauletc6f02fb2015-10-09 10:53:31 +02003423 fclose (fp);
Christopher Faulet31af49d2015-06-09 17:29:50 +02003424 bind_conf->ca_sign_cert = cacert;
3425 bind_conf->ca_sign_pkey = capkey;
3426 return err;
3427
Christopher Fauletc6f02fb2015-10-09 10:53:31 +02003428 read_error:
3429 fclose (fp);
Christopher Faulet31af49d2015-06-09 17:29:50 +02003430 if (capkey) EVP_PKEY_free(capkey);
3431 if (cacert) X509_free(cacert);
Christopher Fauletc6f02fb2015-10-09 10:53:31 +02003432 load_error:
3433 bind_conf->generate_certs = 0;
3434 err++;
Christopher Faulet31af49d2015-06-09 17:29:50 +02003435 return err;
3436}
3437
3438/* Release CA cert and private key used to generate certificated */
3439void
3440ssl_sock_free_ca(struct bind_conf *bind_conf)
3441{
3442 if (!bind_conf)
3443 return;
3444
3445 if (bind_conf->ca_sign_pkey)
3446 EVP_PKEY_free(bind_conf->ca_sign_pkey);
3447 if (bind_conf->ca_sign_cert)
3448 X509_free(bind_conf->ca_sign_cert);
Willy Tarreau94ff03a2016-12-22 17:57:46 +01003449 bind_conf->ca_sign_pkey = NULL;
3450 bind_conf->ca_sign_cert = NULL;
Christopher Faulet31af49d2015-06-09 17:29:50 +02003451}
3452
Emeric Brun46591952012-05-18 15:47:34 +02003453/*
3454 * This function is called if SSL * context is not yet allocated. The function
3455 * is designed to be called before any other data-layer operation and sets the
3456 * handshake flag on the connection. It is safe to call it multiple times.
3457 * It returns 0 on success and -1 in error case.
3458 */
3459static int ssl_sock_init(struct connection *conn)
3460{
3461 /* already initialized */
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02003462 if (conn->xprt_ctx)
Emeric Brun46591952012-05-18 15:47:34 +02003463 return 0;
3464
Willy Tarreau3c728722014-01-23 13:50:42 +01003465 if (!conn_ctrl_ready(conn))
Willy Tarreauf79c8172013-10-21 16:30:56 +02003466 return 0;
3467
Willy Tarreau20879a02012-12-03 16:32:10 +01003468 if (global.maxsslconn && sslconns >= global.maxsslconn) {
3469 conn->err_code = CO_ER_SSL_TOO_MANY;
Willy Tarreau403edff2012-09-06 11:58:37 +02003470 return -1;
Willy Tarreau20879a02012-12-03 16:32:10 +01003471 }
Willy Tarreau403edff2012-09-06 11:58:37 +02003472
Emeric Brun46591952012-05-18 15:47:34 +02003473 /* If it is in client mode initiate SSL session
3474 in connect state otherwise accept state */
Willy Tarreau3fdb3662012-11-12 00:42:33 +01003475 if (objt_server(conn->target)) {
Willy Tarreaufba03cd2014-11-13 13:48:58 +01003476 int may_retry = 1;
3477
3478 retry_connect:
Emeric Brun46591952012-05-18 15:47:34 +02003479 /* Alloc a new SSL session ctx */
Willy Tarreau3fdb3662012-11-12 00:42:33 +01003480 conn->xprt_ctx = SSL_new(objt_server(conn->target)->ssl_ctx.ctx);
Willy Tarreau20879a02012-12-03 16:32:10 +01003481 if (!conn->xprt_ctx) {
Willy Tarreaufba03cd2014-11-13 13:48:58 +01003482 if (may_retry--) {
3483 pool_gc2();
3484 goto retry_connect;
3485 }
Willy Tarreau20879a02012-12-03 16:32:10 +01003486 conn->err_code = CO_ER_SSL_NO_MEM;
Emeric Brun46591952012-05-18 15:47:34 +02003487 return -1;
Willy Tarreau20879a02012-12-03 16:32:10 +01003488 }
Emeric Brun46591952012-05-18 15:47:34 +02003489
Emeric Brun46591952012-05-18 15:47:34 +02003490 /* set fd on SSL session context */
Emeric Brun55476152014-11-12 17:35:37 +01003491 if (!SSL_set_fd(conn->xprt_ctx, conn->t.sock.fd)) {
3492 SSL_free(conn->xprt_ctx);
3493 conn->xprt_ctx = NULL;
Willy Tarreaufba03cd2014-11-13 13:48:58 +01003494 if (may_retry--) {
3495 pool_gc2();
3496 goto retry_connect;
3497 }
Emeric Brun55476152014-11-12 17:35:37 +01003498 conn->err_code = CO_ER_SSL_NO_MEM;
3499 return -1;
3500 }
Emeric Brun46591952012-05-18 15:47:34 +02003501
Evan Broderbe554312013-06-27 00:05:25 -07003502 /* set connection pointer */
Emeric Brun55476152014-11-12 17:35:37 +01003503 if (!SSL_set_app_data(conn->xprt_ctx, conn)) {
3504 SSL_free(conn->xprt_ctx);
3505 conn->xprt_ctx = NULL;
Willy Tarreaufba03cd2014-11-13 13:48:58 +01003506 if (may_retry--) {
3507 pool_gc2();
3508 goto retry_connect;
3509 }
Emeric Brun55476152014-11-12 17:35:37 +01003510 conn->err_code = CO_ER_SSL_NO_MEM;
3511 return -1;
3512 }
3513
3514 SSL_set_connect_state(conn->xprt_ctx);
3515 if (objt_server(conn->target)->ssl_ctx.reused_sess) {
3516 if(!SSL_set_session(conn->xprt_ctx, objt_server(conn->target)->ssl_ctx.reused_sess)) {
3517 SSL_SESSION_free(objt_server(conn->target)->ssl_ctx.reused_sess);
3518 objt_server(conn->target)->ssl_ctx.reused_sess = NULL;
3519 }
3520 }
Evan Broderbe554312013-06-27 00:05:25 -07003521
Emeric Brun46591952012-05-18 15:47:34 +02003522 /* leave init state and start handshake */
Willy Tarreau05737472012-09-04 08:03:39 +02003523 conn->flags |= CO_FL_SSL_WAIT_HS | CO_FL_WAIT_L6_CONN;
Willy Tarreau403edff2012-09-06 11:58:37 +02003524
3525 sslconns++;
Willy Tarreau71b734c2014-01-28 15:19:44 +01003526 totalsslconns++;
Emeric Brun46591952012-05-18 15:47:34 +02003527 return 0;
3528 }
Willy Tarreau3fdb3662012-11-12 00:42:33 +01003529 else if (objt_listener(conn->target)) {
Willy Tarreaufba03cd2014-11-13 13:48:58 +01003530 int may_retry = 1;
3531
3532 retry_accept:
Emeric Brun46591952012-05-18 15:47:34 +02003533 /* Alloc a new SSL session ctx */
Willy Tarreau3fdb3662012-11-12 00:42:33 +01003534 conn->xprt_ctx = SSL_new(objt_listener(conn->target)->bind_conf->default_ctx);
Willy Tarreau20879a02012-12-03 16:32:10 +01003535 if (!conn->xprt_ctx) {
Willy Tarreaufba03cd2014-11-13 13:48:58 +01003536 if (may_retry--) {
3537 pool_gc2();
3538 goto retry_accept;
3539 }
Willy Tarreau20879a02012-12-03 16:32:10 +01003540 conn->err_code = CO_ER_SSL_NO_MEM;
Emeric Brun46591952012-05-18 15:47:34 +02003541 return -1;
Willy Tarreau20879a02012-12-03 16:32:10 +01003542 }
Emeric Brun46591952012-05-18 15:47:34 +02003543
Emeric Brun46591952012-05-18 15:47:34 +02003544 /* set fd on SSL session context */
Emeric Brun55476152014-11-12 17:35:37 +01003545 if (!SSL_set_fd(conn->xprt_ctx, conn->t.sock.fd)) {
3546 SSL_free(conn->xprt_ctx);
3547 conn->xprt_ctx = NULL;
Willy Tarreaufba03cd2014-11-13 13:48:58 +01003548 if (may_retry--) {
3549 pool_gc2();
3550 goto retry_accept;
3551 }
Emeric Brun55476152014-11-12 17:35:37 +01003552 conn->err_code = CO_ER_SSL_NO_MEM;
3553 return -1;
3554 }
Emeric Brun46591952012-05-18 15:47:34 +02003555
Emeric Brune1f38db2012-09-03 20:36:47 +02003556 /* set connection pointer */
Emeric Brun55476152014-11-12 17:35:37 +01003557 if (!SSL_set_app_data(conn->xprt_ctx, conn)) {
3558 SSL_free(conn->xprt_ctx);
3559 conn->xprt_ctx = NULL;
Willy Tarreaufba03cd2014-11-13 13:48:58 +01003560 if (may_retry--) {
3561 pool_gc2();
3562 goto retry_accept;
3563 }
Emeric Brun55476152014-11-12 17:35:37 +01003564 conn->err_code = CO_ER_SSL_NO_MEM;
3565 return -1;
3566 }
3567
3568 SSL_set_accept_state(conn->xprt_ctx);
Emeric Brune1f38db2012-09-03 20:36:47 +02003569
Emeric Brun46591952012-05-18 15:47:34 +02003570 /* leave init state and start handshake */
Willy Tarreau05737472012-09-04 08:03:39 +02003571 conn->flags |= CO_FL_SSL_WAIT_HS | CO_FL_WAIT_L6_CONN;
Willy Tarreau403edff2012-09-06 11:58:37 +02003572
3573 sslconns++;
Willy Tarreau71b734c2014-01-28 15:19:44 +01003574 totalsslconns++;
Emeric Brun46591952012-05-18 15:47:34 +02003575 return 0;
3576 }
3577 /* don't know how to handle such a target */
Willy Tarreau20879a02012-12-03 16:32:10 +01003578 conn->err_code = CO_ER_SSL_NO_TARGET;
Emeric Brun46591952012-05-18 15:47:34 +02003579 return -1;
3580}
3581
3582
3583/* This is the callback which is used when an SSL handshake is pending. It
3584 * updates the FD status if it wants some polling before being called again.
3585 * It returns 0 if it fails in a fatal way or needs to poll to go further,
3586 * otherwise it returns non-zero and removes itself from the connection's
3587 * flags (the bit is provided in <flag> by the caller).
3588 */
3589int ssl_sock_handshake(struct connection *conn, unsigned int flag)
3590{
3591 int ret;
3592
Willy Tarreau3c728722014-01-23 13:50:42 +01003593 if (!conn_ctrl_ready(conn))
Willy Tarreauf79c8172013-10-21 16:30:56 +02003594 return 0;
3595
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02003596 if (!conn->xprt_ctx)
Emeric Brun46591952012-05-18 15:47:34 +02003597 goto out_error;
3598
Emeric Brun674b7432012-11-08 19:21:55 +01003599 /* If we use SSL_do_handshake to process a reneg initiated by
3600 * the remote peer, it sometimes returns SSL_ERROR_SSL.
3601 * Usually SSL_write and SSL_read are used and process implicitly
3602 * the reneg handshake.
3603 * Here we use SSL_peek as a workaround for reneg.
3604 */
3605 if ((conn->flags & CO_FL_CONNECTED) && SSL_renegotiate_pending(conn->xprt_ctx)) {
3606 char c;
3607
3608 ret = SSL_peek(conn->xprt_ctx, &c, 1);
3609 if (ret <= 0) {
3610 /* handshake may have not been completed, let's find why */
3611 ret = SSL_get_error(conn->xprt_ctx, ret);
3612 if (ret == SSL_ERROR_WANT_WRITE) {
3613 /* SSL handshake needs to write, L4 connection may not be ready */
3614 __conn_sock_stop_recv(conn);
Willy Tarreaue1f50c42014-01-22 20:02:06 +01003615 __conn_sock_want_send(conn);
3616 fd_cant_send(conn->t.sock.fd);
Emeric Brun674b7432012-11-08 19:21:55 +01003617 return 0;
3618 }
3619 else if (ret == SSL_ERROR_WANT_READ) {
3620 /* handshake may have been completed but we have
3621 * no more data to read.
3622 */
3623 if (!SSL_renegotiate_pending(conn->xprt_ctx)) {
3624 ret = 1;
3625 goto reneg_ok;
3626 }
3627 /* SSL handshake needs to read, L4 connection is ready */
3628 if (conn->flags & CO_FL_WAIT_L4_CONN)
3629 conn->flags &= ~CO_FL_WAIT_L4_CONN;
3630 __conn_sock_stop_send(conn);
Willy Tarreaue1f50c42014-01-22 20:02:06 +01003631 __conn_sock_want_recv(conn);
3632 fd_cant_recv(conn->t.sock.fd);
Emeric Brun674b7432012-11-08 19:21:55 +01003633 return 0;
3634 }
3635 else if (ret == SSL_ERROR_SYSCALL) {
3636 /* if errno is null, then connection was successfully established */
3637 if (!errno && conn->flags & CO_FL_WAIT_L4_CONN)
3638 conn->flags &= ~CO_FL_WAIT_L4_CONN;
Willy Tarreau20879a02012-12-03 16:32:10 +01003639 if (!conn->err_code) {
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02003640 int empty_handshake;
Luca Pizzamiglio578b1692016-12-12 10:56:56 +01003641#if (OPENSSL_VERSION_NUMBER >= 0x1010000fL) && !defined(LIBRESSL_VERSION_NUMBER)
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02003642 OSSL_HANDSHAKE_STATE state = SSL_get_state((SSL *)conn->xprt_ctx);
3643 empty_handshake = state == TLS_ST_BEFORE;
3644#else
3645 empty_handshake = !((SSL *)conn->xprt_ctx)->packet_length;
3646#endif
3647
3648 if (empty_handshake) {
Emeric Brun29f037d2014-04-25 19:05:36 +02003649 if (!errno) {
3650 if (conn->xprt_st & SSL_SOCK_RECV_HEARTBEAT)
3651 conn->err_code = CO_ER_SSL_HANDSHAKE_HB;
3652 else
3653 conn->err_code = CO_ER_SSL_EMPTY;
3654 }
3655 else {
3656 if (conn->xprt_st & SSL_SOCK_RECV_HEARTBEAT)
3657 conn->err_code = CO_ER_SSL_HANDSHAKE_HB;
3658 else
3659 conn->err_code = CO_ER_SSL_ABORT;
3660 }
3661 }
3662 else {
3663 if (conn->xprt_st & SSL_SOCK_RECV_HEARTBEAT)
3664 conn->err_code = CO_ER_SSL_HANDSHAKE_HB;
Willy Tarreau20879a02012-12-03 16:32:10 +01003665 else
Emeric Brun29f037d2014-04-25 19:05:36 +02003666 conn->err_code = CO_ER_SSL_HANDSHAKE;
3667 }
Willy Tarreau20879a02012-12-03 16:32:10 +01003668 }
Emeric Brun674b7432012-11-08 19:21:55 +01003669 goto out_error;
3670 }
3671 else {
3672 /* Fail on all other handshake errors */
3673 /* Note: OpenSSL may leave unread bytes in the socket's
3674 * buffer, causing an RST to be emitted upon close() on
3675 * TCP sockets. We first try to drain possibly pending
3676 * data to avoid this as much as possible.
3677 */
Willy Tarreaud85c4852015-03-13 00:40:28 +01003678 conn_sock_drain(conn);
Willy Tarreau20879a02012-12-03 16:32:10 +01003679 if (!conn->err_code)
Willy Tarreauf51c6982014-04-25 20:02:39 +02003680 conn->err_code = (conn->xprt_st & SSL_SOCK_RECV_HEARTBEAT) ?
3681 CO_ER_SSL_KILLED_HB : CO_ER_SSL_HANDSHAKE;
Emeric Brun674b7432012-11-08 19:21:55 +01003682 goto out_error;
3683 }
3684 }
3685 /* read some data: consider handshake completed */
3686 goto reneg_ok;
3687 }
3688
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02003689 ret = SSL_do_handshake(conn->xprt_ctx);
Emeric Brun46591952012-05-18 15:47:34 +02003690 if (ret != 1) {
3691 /* handshake did not complete, let's find why */
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02003692 ret = SSL_get_error(conn->xprt_ctx, ret);
Emeric Brun46591952012-05-18 15:47:34 +02003693
3694 if (ret == SSL_ERROR_WANT_WRITE) {
3695 /* SSL handshake needs to write, L4 connection may not be ready */
3696 __conn_sock_stop_recv(conn);
Willy Tarreaue1f50c42014-01-22 20:02:06 +01003697 __conn_sock_want_send(conn);
3698 fd_cant_send(conn->t.sock.fd);
Emeric Brun46591952012-05-18 15:47:34 +02003699 return 0;
3700 }
3701 else if (ret == SSL_ERROR_WANT_READ) {
3702 /* SSL handshake needs to read, L4 connection is ready */
3703 if (conn->flags & CO_FL_WAIT_L4_CONN)
3704 conn->flags &= ~CO_FL_WAIT_L4_CONN;
3705 __conn_sock_stop_send(conn);
Willy Tarreaue1f50c42014-01-22 20:02:06 +01003706 __conn_sock_want_recv(conn);
3707 fd_cant_recv(conn->t.sock.fd);
Emeric Brun46591952012-05-18 15:47:34 +02003708 return 0;
3709 }
Willy Tarreau89230192012-09-28 20:22:13 +02003710 else if (ret == SSL_ERROR_SYSCALL) {
Luca Pizzamiglio578b1692016-12-12 10:56:56 +01003711#if (OPENSSL_VERSION_NUMBER >= 0x1010000fL) && !defined(LIBRESSL_VERSION_NUMBER)
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02003712 OSSL_HANDSHAKE_STATE state;
3713#endif
3714 int empty_handshake;
Willy Tarreau89230192012-09-28 20:22:13 +02003715 /* if errno is null, then connection was successfully established */
3716 if (!errno && conn->flags & CO_FL_WAIT_L4_CONN)
3717 conn->flags &= ~CO_FL_WAIT_L4_CONN;
Willy Tarreau20879a02012-12-03 16:32:10 +01003718
Luca Pizzamiglio578b1692016-12-12 10:56:56 +01003719#if (OPENSSL_VERSION_NUMBER >= 0x1010000fL) && !defined(LIBRESSL_VERSION_NUMBER)
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02003720 state = SSL_get_state((SSL *)conn->xprt_ctx);
3721 empty_handshake = state == TLS_ST_BEFORE;
3722#else
3723 empty_handshake = !((SSL *)conn->xprt_ctx)->packet_length;
3724#endif
3725 if (empty_handshake) {
Emeric Brun29f037d2014-04-25 19:05:36 +02003726 if (!errno) {
3727 if (conn->xprt_st & SSL_SOCK_RECV_HEARTBEAT)
3728 conn->err_code = CO_ER_SSL_HANDSHAKE_HB;
3729 else
3730 conn->err_code = CO_ER_SSL_EMPTY;
3731 }
3732 else {
3733 if (conn->xprt_st & SSL_SOCK_RECV_HEARTBEAT)
3734 conn->err_code = CO_ER_SSL_HANDSHAKE_HB;
3735 else
3736 conn->err_code = CO_ER_SSL_ABORT;
3737 }
3738 }
3739 else {
3740 if (conn->xprt_st & SSL_SOCK_RECV_HEARTBEAT)
3741 conn->err_code = CO_ER_SSL_HANDSHAKE_HB;
Willy Tarreau20879a02012-12-03 16:32:10 +01003742 else
Emeric Brun29f037d2014-04-25 19:05:36 +02003743 conn->err_code = CO_ER_SSL_HANDSHAKE;
3744 }
Willy Tarreau89230192012-09-28 20:22:13 +02003745 goto out_error;
3746 }
Emeric Brun46591952012-05-18 15:47:34 +02003747 else {
3748 /* Fail on all other handshake errors */
Willy Tarreau566dc552012-10-19 20:52:18 +02003749 /* Note: OpenSSL may leave unread bytes in the socket's
3750 * buffer, causing an RST to be emitted upon close() on
3751 * TCP sockets. We first try to drain possibly pending
3752 * data to avoid this as much as possible.
3753 */
Willy Tarreaud85c4852015-03-13 00:40:28 +01003754 conn_sock_drain(conn);
Willy Tarreau20879a02012-12-03 16:32:10 +01003755 if (!conn->err_code)
Willy Tarreauf51c6982014-04-25 20:02:39 +02003756 conn->err_code = (conn->xprt_st & SSL_SOCK_RECV_HEARTBEAT) ?
3757 CO_ER_SSL_KILLED_HB : CO_ER_SSL_HANDSHAKE;
Emeric Brun46591952012-05-18 15:47:34 +02003758 goto out_error;
3759 }
3760 }
3761
Emeric Brun674b7432012-11-08 19:21:55 +01003762reneg_ok:
Emeric Brun46591952012-05-18 15:47:34 +02003763 /* Handshake succeeded */
Willy Tarreau0c9c2722014-05-28 12:28:58 +02003764 if (!SSL_session_reused(conn->xprt_ctx)) {
3765 if (objt_server(conn->target)) {
3766 update_freq_ctr(&global.ssl_be_keys_per_sec, 1);
3767 if (global.ssl_be_keys_per_sec.curr_ctr > global.ssl_be_keys_max)
3768 global.ssl_be_keys_max = global.ssl_be_keys_per_sec.curr_ctr;
3769
Emeric Brun46591952012-05-18 15:47:34 +02003770 /* check if session was reused, if not store current session on server for reuse */
Willy Tarreau30fd4bd2016-12-22 21:54:21 +01003771 if (objt_server(conn->target)->ssl_ctx.reused_sess) {
Willy Tarreau3fdb3662012-11-12 00:42:33 +01003772 SSL_SESSION_free(objt_server(conn->target)->ssl_ctx.reused_sess);
Willy Tarreau30fd4bd2016-12-22 21:54:21 +01003773 objt_server(conn->target)->ssl_ctx.reused_sess = NULL;
3774 }
Emeric Brun46591952012-05-18 15:47:34 +02003775
Willy Tarreau2a3fb1c2015-02-05 16:47:07 +01003776 if (!(objt_server(conn->target)->ssl_ctx.options & SRV_SSL_O_NO_REUSE))
3777 objt_server(conn->target)->ssl_ctx.reused_sess = SSL_get1_session(conn->xprt_ctx);
Emeric Brun46591952012-05-18 15:47:34 +02003778 }
Willy Tarreau0c9c2722014-05-28 12:28:58 +02003779 else {
3780 update_freq_ctr(&global.ssl_fe_keys_per_sec, 1);
3781 if (global.ssl_fe_keys_per_sec.curr_ctr > global.ssl_fe_keys_max)
3782 global.ssl_fe_keys_max = global.ssl_fe_keys_per_sec.curr_ctr;
3783 }
Emeric Brun46591952012-05-18 15:47:34 +02003784 }
3785
3786 /* The connection is now established at both layers, it's time to leave */
3787 conn->flags &= ~(flag | CO_FL_WAIT_L4_CONN | CO_FL_WAIT_L6_CONN);
3788 return 1;
3789
3790 out_error:
Emeric Brun644cde02012-12-14 11:21:13 +01003791 /* Clear openssl global errors stack */
Thierry FOURNIER / OZON.IO8b068c22016-10-10 11:59:50 +02003792 ssl_sock_dump_errors(conn);
Emeric Brun644cde02012-12-14 11:21:13 +01003793 ERR_clear_error();
3794
Emeric Brun9fa89732012-10-04 17:09:56 +02003795 /* free resumed session if exists */
Willy Tarreau3fdb3662012-11-12 00:42:33 +01003796 if (objt_server(conn->target) && objt_server(conn->target)->ssl_ctx.reused_sess) {
3797 SSL_SESSION_free(objt_server(conn->target)->ssl_ctx.reused_sess);
3798 objt_server(conn->target)->ssl_ctx.reused_sess = NULL;
Emeric Brun9fa89732012-10-04 17:09:56 +02003799 }
3800
Emeric Brun46591952012-05-18 15:47:34 +02003801 /* Fail on all other handshake errors */
3802 conn->flags |= CO_FL_ERROR;
Willy Tarreau20879a02012-12-03 16:32:10 +01003803 if (!conn->err_code)
3804 conn->err_code = CO_ER_SSL_HANDSHAKE;
Emeric Brun46591952012-05-18 15:47:34 +02003805 return 0;
3806}
3807
3808/* Receive up to <count> bytes from connection <conn>'s socket and store them
Willy Tarreauabf08d92014-01-14 11:31:27 +01003809 * into buffer <buf>. Only one call to recv() is performed, unless the
Emeric Brun46591952012-05-18 15:47:34 +02003810 * buffer wraps, in which case a second call may be performed. The connection's
3811 * flags are updated with whatever special event is detected (error, read0,
3812 * empty). The caller is responsible for taking care of those events and
3813 * avoiding the call if inappropriate. The function does not call the
3814 * connection's polling update function, so the caller is responsible for this.
3815 */
3816static int ssl_sock_to_buf(struct connection *conn, struct buffer *buf, int count)
3817{
3818 int ret, done = 0;
Willy Tarreauabf08d92014-01-14 11:31:27 +01003819 int try;
Emeric Brun46591952012-05-18 15:47:34 +02003820
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02003821 if (!conn->xprt_ctx)
Emeric Brun46591952012-05-18 15:47:34 +02003822 goto out_error;
3823
3824 if (conn->flags & CO_FL_HANDSHAKE)
3825 /* a handshake was requested */
3826 return 0;
3827
Willy Tarreauabf08d92014-01-14 11:31:27 +01003828 /* let's realign the buffer to optimize I/O */
3829 if (buffer_empty(buf))
Emeric Brun46591952012-05-18 15:47:34 +02003830 buf->p = buf->data;
Emeric Brun46591952012-05-18 15:47:34 +02003831
3832 /* read the largest possible block. For this, we perform only one call
3833 * to recv() unless the buffer wraps and we exactly fill the first hunk,
3834 * in which case we accept to do it once again. A new attempt is made on
3835 * EINTR too.
3836 */
Willy Tarreau00b0fb92014-01-17 11:09:40 +01003837 while (count > 0) {
Willy Tarreauabf08d92014-01-14 11:31:27 +01003838 /* first check if we have some room after p+i */
3839 try = buf->data + buf->size - (buf->p + buf->i);
3840 /* otherwise continue between data and p-o */
3841 if (try <= 0) {
3842 try = buf->p - (buf->data + buf->o);
3843 if (try <= 0)
3844 break;
3845 }
3846 if (try > count)
3847 try = count;
3848
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02003849 ret = SSL_read(conn->xprt_ctx, bi_end(buf), try);
Emeric Brune1f38db2012-09-03 20:36:47 +02003850 if (conn->flags & CO_FL_ERROR) {
3851 /* CO_FL_ERROR may be set by ssl_sock_infocbk */
Emeric Brun644cde02012-12-14 11:21:13 +01003852 goto out_error;
Emeric Brune1f38db2012-09-03 20:36:47 +02003853 }
Emeric Brun46591952012-05-18 15:47:34 +02003854 if (ret > 0) {
3855 buf->i += ret;
3856 done += ret;
3857 if (ret < try)
3858 break;
3859 count -= ret;
Emeric Brun46591952012-05-18 15:47:34 +02003860 }
3861 else if (ret == 0) {
Emeric Brun644cde02012-12-14 11:21:13 +01003862 ret = SSL_get_error(conn->xprt_ctx, ret);
3863 if (ret != SSL_ERROR_ZERO_RETURN) {
Emeric Brun1c646862012-12-14 12:33:41 +01003864 /* error on protocol or underlying transport */
3865 if ((ret != SSL_ERROR_SYSCALL)
3866 || (errno && (errno != EAGAIN)))
3867 conn->flags |= CO_FL_ERROR;
3868
Emeric Brun644cde02012-12-14 11:21:13 +01003869 /* Clear openssl global errors stack */
Thierry FOURNIER / OZON.IO8b068c22016-10-10 11:59:50 +02003870 ssl_sock_dump_errors(conn);
Emeric Brun644cde02012-12-14 11:21:13 +01003871 ERR_clear_error();
3872 }
Emeric Brun46591952012-05-18 15:47:34 +02003873 goto read0;
3874 }
3875 else {
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02003876 ret = SSL_get_error(conn->xprt_ctx, ret);
Emeric Brun46591952012-05-18 15:47:34 +02003877 if (ret == SSL_ERROR_WANT_WRITE) {
Emeric Brun8af8dd12012-11-08 17:56:20 +01003878 /* handshake is running, and it needs to enable write */
Emeric Brun46591952012-05-18 15:47:34 +02003879 conn->flags |= CO_FL_SSL_WAIT_HS;
Emeric Brun8af8dd12012-11-08 17:56:20 +01003880 __conn_sock_want_send(conn);
Emeric Brun46591952012-05-18 15:47:34 +02003881 break;
3882 }
3883 else if (ret == SSL_ERROR_WANT_READ) {
Emeric Brun282a76a2012-11-08 18:02:56 +01003884 if (SSL_renegotiate_pending(conn->xprt_ctx)) {
3885 /* handshake is running, and it may need to re-enable read */
3886 conn->flags |= CO_FL_SSL_WAIT_HS;
3887 __conn_sock_want_recv(conn);
3888 break;
3889 }
Emeric Brun46591952012-05-18 15:47:34 +02003890 /* we need to poll for retry a read later */
Willy Tarreaue1f50c42014-01-22 20:02:06 +01003891 fd_cant_recv(conn->t.sock.fd);
Emeric Brun46591952012-05-18 15:47:34 +02003892 break;
3893 }
3894 /* otherwise it's a real error */
3895 goto out_error;
3896 }
3897 }
3898 return done;
3899
3900 read0:
3901 conn_sock_read0(conn);
3902 return done;
3903 out_error:
Emeric Brun644cde02012-12-14 11:21:13 +01003904 /* Clear openssl global errors stack */
Thierry FOURNIER / OZON.IO8b068c22016-10-10 11:59:50 +02003905 ssl_sock_dump_errors(conn);
Emeric Brun644cde02012-12-14 11:21:13 +01003906 ERR_clear_error();
3907
Emeric Brun46591952012-05-18 15:47:34 +02003908 conn->flags |= CO_FL_ERROR;
3909 return done;
3910}
3911
3912
3913/* Send all pending bytes from buffer <buf> to connection <conn>'s socket.
Willy Tarreau1049b1f2014-02-02 01:51:17 +01003914 * <flags> may contain some CO_SFL_* flags to hint the system about other
3915 * pending data for example, but this flag is ignored at the moment.
Emeric Brun46591952012-05-18 15:47:34 +02003916 * Only one call to send() is performed, unless the buffer wraps, in which case
3917 * a second call may be performed. The connection's flags are updated with
3918 * whatever special event is detected (error, empty). The caller is responsible
3919 * for taking care of those events and avoiding the call if inappropriate. The
3920 * function does not call the connection's polling update function, so the caller
3921 * is responsible for this.
3922 */
3923static int ssl_sock_from_buf(struct connection *conn, struct buffer *buf, int flags)
3924{
3925 int ret, try, done;
3926
3927 done = 0;
3928
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02003929 if (!conn->xprt_ctx)
Emeric Brun46591952012-05-18 15:47:34 +02003930 goto out_error;
3931
3932 if (conn->flags & CO_FL_HANDSHAKE)
3933 /* a handshake was requested */
3934 return 0;
3935
3936 /* send the largest possible block. For this we perform only one call
3937 * to send() unless the buffer wraps and we exactly fill the first hunk,
3938 * in which case we accept to do it once again.
3939 */
3940 while (buf->o) {
Kevin Hestercad82342013-05-30 15:12:41 -07003941 try = bo_contig_data(buf);
Willy Tarreaubfd59462013-02-21 07:46:09 +01003942
Willy Tarreau7bed9452014-02-02 02:00:24 +01003943 if (!(flags & CO_SFL_STREAMER) &&
Willy Tarreau518cedd2014-02-17 15:43:01 +01003944 !(conn->xprt_st & SSL_SOCK_SEND_UNLIMITED) &&
Willy Tarreauef934602016-12-22 23:12:01 +01003945 global_ssl.max_record && try > global_ssl.max_record) {
3946 try = global_ssl.max_record;
Willy Tarreau518cedd2014-02-17 15:43:01 +01003947 }
3948 else {
3949 /* we need to keep the information about the fact that
3950 * we're not limiting the upcoming send(), because if it
3951 * fails, we'll have to retry with at least as many data.
3952 */
3953 conn->xprt_st |= SSL_SOCK_SEND_UNLIMITED;
3954 }
Willy Tarreaubfd59462013-02-21 07:46:09 +01003955
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02003956 ret = SSL_write(conn->xprt_ctx, bo_ptr(buf), try);
Willy Tarreau518cedd2014-02-17 15:43:01 +01003957
Emeric Brune1f38db2012-09-03 20:36:47 +02003958 if (conn->flags & CO_FL_ERROR) {
3959 /* CO_FL_ERROR may be set by ssl_sock_infocbk */
Emeric Brun644cde02012-12-14 11:21:13 +01003960 goto out_error;
Emeric Brune1f38db2012-09-03 20:36:47 +02003961 }
Emeric Brun46591952012-05-18 15:47:34 +02003962 if (ret > 0) {
Willy Tarreau518cedd2014-02-17 15:43:01 +01003963 conn->xprt_st &= ~SSL_SOCK_SEND_UNLIMITED;
3964
Emeric Brun46591952012-05-18 15:47:34 +02003965 buf->o -= ret;
3966 done += ret;
3967
Willy Tarreau5fb38032012-12-16 19:39:09 +01003968 if (likely(buffer_empty(buf)))
Emeric Brun46591952012-05-18 15:47:34 +02003969 /* optimize data alignment in the buffer */
3970 buf->p = buf->data;
3971
3972 /* if the system buffer is full, don't insist */
3973 if (ret < try)
3974 break;
3975 }
3976 else {
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02003977 ret = SSL_get_error(conn->xprt_ctx, ret);
Emeric Brun46591952012-05-18 15:47:34 +02003978 if (ret == SSL_ERROR_WANT_WRITE) {
Emeric Brun282a76a2012-11-08 18:02:56 +01003979 if (SSL_renegotiate_pending(conn->xprt_ctx)) {
3980 /* handshake is running, and it may need to re-enable write */
3981 conn->flags |= CO_FL_SSL_WAIT_HS;
3982 __conn_sock_want_send(conn);
3983 break;
3984 }
Emeric Brun46591952012-05-18 15:47:34 +02003985 /* we need to poll to retry a write later */
Willy Tarreaue1f50c42014-01-22 20:02:06 +01003986 fd_cant_send(conn->t.sock.fd);
Emeric Brun46591952012-05-18 15:47:34 +02003987 break;
3988 }
3989 else if (ret == SSL_ERROR_WANT_READ) {
Emeric Brun8af8dd12012-11-08 17:56:20 +01003990 /* handshake is running, and it needs to enable read */
Emeric Brun46591952012-05-18 15:47:34 +02003991 conn->flags |= CO_FL_SSL_WAIT_HS;
Emeric Brun8af8dd12012-11-08 17:56:20 +01003992 __conn_sock_want_recv(conn);
Emeric Brun46591952012-05-18 15:47:34 +02003993 break;
3994 }
3995 goto out_error;
3996 }
3997 }
3998 return done;
3999
4000 out_error:
Emeric Brun644cde02012-12-14 11:21:13 +01004001 /* Clear openssl global errors stack */
Thierry FOURNIER / OZON.IO8b068c22016-10-10 11:59:50 +02004002 ssl_sock_dump_errors(conn);
Emeric Brun644cde02012-12-14 11:21:13 +01004003 ERR_clear_error();
4004
Emeric Brun46591952012-05-18 15:47:34 +02004005 conn->flags |= CO_FL_ERROR;
4006 return done;
4007}
4008
Emeric Brun46591952012-05-18 15:47:34 +02004009static void ssl_sock_close(struct connection *conn) {
4010
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02004011 if (conn->xprt_ctx) {
4012 SSL_free(conn->xprt_ctx);
4013 conn->xprt_ctx = NULL;
Willy Tarreau403edff2012-09-06 11:58:37 +02004014 sslconns--;
Emeric Brun46591952012-05-18 15:47:34 +02004015 }
Emeric Brun46591952012-05-18 15:47:34 +02004016}
4017
4018/* This function tries to perform a clean shutdown on an SSL connection, and in
4019 * any case, flags the connection as reusable if no handshake was in progress.
4020 */
4021static void ssl_sock_shutw(struct connection *conn, int clean)
4022{
4023 if (conn->flags & CO_FL_HANDSHAKE)
4024 return;
Emmanuel Hocdet405ff312017-01-08 14:07:39 +01004025 if (!clean)
4026 /* don't sent notify on SSL_shutdown */
4027 SSL_CTX_set_quiet_shutdown(conn->xprt_ctx, 1);
Emeric Brun46591952012-05-18 15:47:34 +02004028 /* no handshake was in progress, try a clean ssl shutdown */
Emmanuel Hocdet405ff312017-01-08 14:07:39 +01004029 if (SSL_shutdown(conn->xprt_ctx) <= 0) {
Emeric Brun644cde02012-12-14 11:21:13 +01004030 /* Clear openssl global errors stack */
Thierry FOURNIER / OZON.IO8b068c22016-10-10 11:59:50 +02004031 ssl_sock_dump_errors(conn);
Emeric Brun644cde02012-12-14 11:21:13 +01004032 ERR_clear_error();
4033 }
Emeric Brun46591952012-05-18 15:47:34 +02004034}
4035
Willy Tarreauffc3fcd2012-10-12 20:17:54 +02004036/* used for logging, may be changed for a sample fetch later */
4037const char *ssl_sock_get_cipher_name(struct connection *conn)
4038{
4039 if (!conn->xprt && !conn->xprt_ctx)
4040 return NULL;
4041 return SSL_get_cipher_name(conn->xprt_ctx);
4042}
4043
4044/* used for logging, may be changed for a sample fetch later */
4045const char *ssl_sock_get_proto_version(struct connection *conn)
4046{
4047 if (!conn->xprt && !conn->xprt_ctx)
4048 return NULL;
4049 return SSL_get_version(conn->xprt_ctx);
4050}
4051
Willy Tarreau8d598402012-10-22 17:58:39 +02004052/* Extract a serial from a cert, and copy it to a chunk.
4053 * Returns 1 if serial is found and copied, 0 if no serial found and
4054 * -1 if output is not large enough.
4055 */
4056static int
4057ssl_sock_get_serial(X509 *crt, struct chunk *out)
4058{
4059 ASN1_INTEGER *serial;
4060
4061 serial = X509_get_serialNumber(crt);
4062 if (!serial)
4063 return 0;
4064
4065 if (out->size < serial->length)
4066 return -1;
4067
4068 memcpy(out->str, serial->data, serial->length);
4069 out->len = serial->length;
4070 return 1;
4071}
4072
Emeric Brun43e79582014-10-29 19:03:26 +01004073/* Extract a cert to der, and copy it to a chunk.
4074 * Returns 1 if cert is found and copied, 0 on der convertion failure and
4075 * -1 if output is not large enough.
4076 */
4077static int
4078ssl_sock_crt2der(X509 *crt, struct chunk *out)
4079{
4080 int len;
4081 unsigned char *p = (unsigned char *)out->str;;
4082
4083 len =i2d_X509(crt, NULL);
4084 if (len <= 0)
4085 return 1;
4086
4087 if (out->size < len)
4088 return -1;
4089
4090 i2d_X509(crt,&p);
4091 out->len = len;
4092 return 1;
4093}
4094
Emeric Brunce5ad802012-10-22 14:11:22 +02004095
4096/* Copy Date in ASN1_UTCTIME format in struct chunk out.
4097 * Returns 1 if serial is found and copied, 0 if no valid time found
4098 * and -1 if output is not large enough.
4099 */
4100static int
4101ssl_sock_get_time(ASN1_TIME *tm, struct chunk *out)
4102{
4103 if (tm->type == V_ASN1_GENERALIZEDTIME) {
4104 ASN1_GENERALIZEDTIME *gentm = (ASN1_GENERALIZEDTIME *)tm;
4105
4106 if (gentm->length < 12)
4107 return 0;
4108 if (gentm->data[0] != 0x32 || gentm->data[1] != 0x30)
4109 return 0;
4110 if (out->size < gentm->length-2)
4111 return -1;
4112
4113 memcpy(out->str, gentm->data+2, gentm->length-2);
4114 out->len = gentm->length-2;
4115 return 1;
4116 }
4117 else if (tm->type == V_ASN1_UTCTIME) {
4118 ASN1_UTCTIME *utctm = (ASN1_UTCTIME *)tm;
4119
4120 if (utctm->length < 10)
4121 return 0;
4122 if (utctm->data[0] >= 0x35)
4123 return 0;
4124 if (out->size < utctm->length)
4125 return -1;
4126
4127 memcpy(out->str, utctm->data, utctm->length);
4128 out->len = utctm->length;
4129 return 1;
4130 }
4131
4132 return 0;
4133}
4134
Emeric Brun87855892012-10-17 17:39:35 +02004135/* Extract an entry from a X509_NAME and copy its value to an output chunk.
4136 * Returns 1 if entry found, 0 if entry not found, or -1 if output not large enough.
4137 */
4138static int
4139ssl_sock_get_dn_entry(X509_NAME *a, const struct chunk *entry, int pos, struct chunk *out)
4140{
4141 X509_NAME_ENTRY *ne;
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02004142 ASN1_OBJECT *obj;
4143 ASN1_STRING *data;
4144 const unsigned char *data_ptr;
4145 int data_len;
Emeric Brun87855892012-10-17 17:39:35 +02004146 int i, j, n;
4147 int cur = 0;
4148 const char *s;
4149 char tmp[128];
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02004150 int name_count;
4151
4152 name_count = X509_NAME_entry_count(a);
Emeric Brun87855892012-10-17 17:39:35 +02004153
4154 out->len = 0;
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02004155 for (i = 0; i < name_count; i++) {
Emeric Brun87855892012-10-17 17:39:35 +02004156 if (pos < 0)
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02004157 j = (name_count-1) - i;
Emeric Brun87855892012-10-17 17:39:35 +02004158 else
4159 j = i;
4160
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02004161 ne = X509_NAME_get_entry(a, j);
4162 obj = X509_NAME_ENTRY_get_object(ne);
4163 data = X509_NAME_ENTRY_get_data(ne);
4164 data_ptr = ASN1_STRING_get0_data(data);
4165 data_len = ASN1_STRING_length(data);
4166 n = OBJ_obj2nid(obj);
Emeric Brun87855892012-10-17 17:39:35 +02004167 if ((n == NID_undef) || ((s = OBJ_nid2sn(n)) == NULL)) {
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02004168 i2t_ASN1_OBJECT(tmp, sizeof(tmp), obj);
Emeric Brun87855892012-10-17 17:39:35 +02004169 s = tmp;
4170 }
4171
4172 if (chunk_strcasecmp(entry, s) != 0)
4173 continue;
4174
4175 if (pos < 0)
4176 cur--;
4177 else
4178 cur++;
4179
4180 if (cur != pos)
4181 continue;
4182
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02004183 if (data_len > out->size)
Emeric Brun87855892012-10-17 17:39:35 +02004184 return -1;
4185
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02004186 memcpy(out->str, data_ptr, data_len);
4187 out->len = data_len;
Emeric Brun87855892012-10-17 17:39:35 +02004188 return 1;
4189 }
4190
4191 return 0;
4192
4193}
4194
4195/* Extract and format full DN from a X509_NAME and copy result into a chunk
4196 * Returns 1 if dn entries exits, 0 if no dn entry found or -1 if output is not large enough.
4197 */
4198static int
4199ssl_sock_get_dn_oneline(X509_NAME *a, struct chunk *out)
4200{
4201 X509_NAME_ENTRY *ne;
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02004202 ASN1_OBJECT *obj;
4203 ASN1_STRING *data;
4204 const unsigned char *data_ptr;
4205 int data_len;
Emeric Brun87855892012-10-17 17:39:35 +02004206 int i, n, ln;
4207 int l = 0;
4208 const char *s;
4209 char *p;
4210 char tmp[128];
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02004211 int name_count;
4212
4213
4214 name_count = X509_NAME_entry_count(a);
Emeric Brun87855892012-10-17 17:39:35 +02004215
4216 out->len = 0;
4217 p = out->str;
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02004218 for (i = 0; i < name_count; i++) {
4219 ne = X509_NAME_get_entry(a, i);
4220 obj = X509_NAME_ENTRY_get_object(ne);
4221 data = X509_NAME_ENTRY_get_data(ne);
4222 data_ptr = ASN1_STRING_get0_data(data);
4223 data_len = ASN1_STRING_length(data);
4224 n = OBJ_obj2nid(obj);
Emeric Brun87855892012-10-17 17:39:35 +02004225 if ((n == NID_undef) || ((s = OBJ_nid2sn(n)) == NULL)) {
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02004226 i2t_ASN1_OBJECT(tmp, sizeof(tmp), obj);
Emeric Brun87855892012-10-17 17:39:35 +02004227 s = tmp;
4228 }
4229 ln = strlen(s);
4230
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02004231 l += 1 + ln + 1 + data_len;
Emeric Brun87855892012-10-17 17:39:35 +02004232 if (l > out->size)
4233 return -1;
4234 out->len = l;
4235
4236 *(p++)='/';
4237 memcpy(p, s, ln);
4238 p += ln;
4239 *(p++)='=';
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02004240 memcpy(p, data_ptr, data_len);
4241 p += data_len;
Emeric Brun87855892012-10-17 17:39:35 +02004242 }
4243
4244 if (!out->len)
4245 return 0;
4246
4247 return 1;
4248}
4249
David Safb76832014-05-08 23:42:08 -04004250char *ssl_sock_get_version(struct connection *conn)
4251{
4252 if (!ssl_sock_is_ssl(conn))
4253 return NULL;
4254
4255 return (char *)SSL_get_version(conn->xprt_ctx);
4256}
4257
Willy Tarreau119a4082016-12-22 21:58:38 +01004258/* Sets advertised SNI for outgoing connections. Please set <hostname> to NULL
4259 * to disable SNI.
4260 */
Willy Tarreau63076412015-07-10 11:33:32 +02004261void ssl_sock_set_servername(struct connection *conn, const char *hostname)
4262{
4263#ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME
Willy Tarreau119a4082016-12-22 21:58:38 +01004264 char *prev_name;
4265
Willy Tarreau63076412015-07-10 11:33:32 +02004266 if (!ssl_sock_is_ssl(conn))
4267 return;
4268
Willy Tarreau119a4082016-12-22 21:58:38 +01004269 /* if the SNI changes, we must destroy the reusable context so that a
4270 * new connection will present a new SNI. As an optimization we could
4271 * later imagine having a small cache of ssl_ctx to hold a few SNI per
4272 * server.
4273 */
4274 prev_name = (char *)SSL_get_servername(conn->xprt_ctx, TLSEXT_NAMETYPE_host_name);
4275 if ((!prev_name && hostname) ||
4276 (prev_name && (!hostname || strcmp(hostname, prev_name) != 0)))
4277 SSL_set_session(conn->xprt_ctx, NULL);
4278
Willy Tarreau63076412015-07-10 11:33:32 +02004279 SSL_set_tlsext_host_name(conn->xprt_ctx, hostname);
4280#endif
4281}
4282
Emeric Brun0abf8362014-06-24 18:26:41 +02004283/* Extract peer certificate's common name into the chunk dest
4284 * Returns
4285 * the len of the extracted common name
4286 * or 0 if no CN found in DN
4287 * or -1 on error case (i.e. no peer certificate)
4288 */
4289int ssl_sock_get_remote_common_name(struct connection *conn, struct chunk *dest)
David Safb76832014-05-08 23:42:08 -04004290{
4291 X509 *crt = NULL;
4292 X509_NAME *name;
David Safb76832014-05-08 23:42:08 -04004293 const char find_cn[] = "CN";
4294 const struct chunk find_cn_chunk = {
4295 .str = (char *)&find_cn,
4296 .len = sizeof(find_cn)-1
4297 };
Emeric Brun0abf8362014-06-24 18:26:41 +02004298 int result = -1;
David Safb76832014-05-08 23:42:08 -04004299
4300 if (!ssl_sock_is_ssl(conn))
Emeric Brun0abf8362014-06-24 18:26:41 +02004301 goto out;
David Safb76832014-05-08 23:42:08 -04004302
4303 /* SSL_get_peer_certificate, it increase X509 * ref count */
4304 crt = SSL_get_peer_certificate(conn->xprt_ctx);
4305 if (!crt)
4306 goto out;
4307
4308 name = X509_get_subject_name(crt);
4309 if (!name)
4310 goto out;
David Safb76832014-05-08 23:42:08 -04004311
Emeric Brun0abf8362014-06-24 18:26:41 +02004312 result = ssl_sock_get_dn_entry(name, &find_cn_chunk, 1, dest);
4313out:
David Safb76832014-05-08 23:42:08 -04004314 if (crt)
4315 X509_free(crt);
4316
4317 return result;
4318}
4319
Dave McCowan328fb582014-07-30 10:39:13 -04004320/* returns 1 if client passed a certificate for this session, 0 if not */
4321int ssl_sock_get_cert_used_sess(struct connection *conn)
4322{
4323 X509 *crt = NULL;
4324
4325 if (!ssl_sock_is_ssl(conn))
4326 return 0;
4327
4328 /* SSL_get_peer_certificate, it increase X509 * ref count */
4329 crt = SSL_get_peer_certificate(conn->xprt_ctx);
4330 if (!crt)
4331 return 0;
4332
4333 X509_free(crt);
4334 return 1;
4335}
4336
4337/* returns 1 if client passed a certificate for this connection, 0 if not */
4338int ssl_sock_get_cert_used_conn(struct connection *conn)
David Safb76832014-05-08 23:42:08 -04004339{
4340 if (!ssl_sock_is_ssl(conn))
4341 return 0;
4342
4343 return SSL_SOCK_ST_FL_VERIFY_DONE & conn->xprt_st ? 1 : 0;
4344}
4345
4346/* returns result from SSL verify */
4347unsigned int ssl_sock_get_verify_result(struct connection *conn)
4348{
4349 if (!ssl_sock_is_ssl(conn))
4350 return (unsigned int)X509_V_ERR_APPLICATION_VERIFICATION;
4351
4352 return (unsigned int)SSL_get_verify_result(conn->xprt_ctx);
4353}
4354
Willy Tarreau7875d092012-09-10 08:20:03 +02004355/***** Below are some sample fetching functions for ACL/patterns *****/
4356
Emeric Brune64aef12012-09-21 13:15:06 +02004357/* boolean, returns true if client cert was present */
4358static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02004359smp_fetch_ssl_fc_has_crt(const struct arg *args, struct sample *smp, const char *kw, void *private)
Emeric Brune64aef12012-09-21 13:15:06 +02004360{
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004361 struct connection *conn;
4362
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02004363 conn = objt_conn(smp->sess->origin);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004364 if (!conn || conn->xprt != &ssl_sock)
Emeric Brune64aef12012-09-21 13:15:06 +02004365 return 0;
4366
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004367 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brune64aef12012-09-21 13:15:06 +02004368 smp->flags |= SMP_F_MAY_CHANGE;
4369 return 0;
4370 }
4371
4372 smp->flags = 0;
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02004373 smp->data.type = SMP_T_BOOL;
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02004374 smp->data.u.sint = SSL_SOCK_ST_FL_VERIFY_DONE & conn->xprt_st ? 1 : 0;
Emeric Brune64aef12012-09-21 13:15:06 +02004375
4376 return 1;
4377}
4378
Emeric Brun43e79582014-10-29 19:03:26 +01004379/* binary, returns a certificate in a binary chunk (der/raw).
4380 * The 5th keyword char is used to know if SSL_get_certificate or SSL_get_peer_certificate
4381 * should be use.
4382 */
4383static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02004384smp_fetch_ssl_x_der(const struct arg *args, struct sample *smp, const char *kw, void *private)
Emeric Brun43e79582014-10-29 19:03:26 +01004385{
4386 int cert_peer = (kw[4] == 'c') ? 1 : 0;
4387 X509 *crt = NULL;
4388 int ret = 0;
4389 struct chunk *smp_trash;
4390 struct connection *conn;
4391
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02004392 conn = objt_conn(smp->sess->origin);
Emeric Brun43e79582014-10-29 19:03:26 +01004393 if (!conn || conn->xprt != &ssl_sock)
4394 return 0;
4395
4396 if (!(conn->flags & CO_FL_CONNECTED)) {
4397 smp->flags |= SMP_F_MAY_CHANGE;
4398 return 0;
4399 }
4400
4401 if (cert_peer)
4402 crt = SSL_get_peer_certificate(conn->xprt_ctx);
4403 else
4404 crt = SSL_get_certificate(conn->xprt_ctx);
4405
4406 if (!crt)
4407 goto out;
4408
4409 smp_trash = get_trash_chunk();
4410 if (ssl_sock_crt2der(crt, smp_trash) <= 0)
4411 goto out;
4412
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02004413 smp->data.u.str = *smp_trash;
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02004414 smp->data.type = SMP_T_BIN;
Emeric Brun43e79582014-10-29 19:03:26 +01004415 ret = 1;
4416out:
4417 /* SSL_get_peer_certificate, it increase X509 * ref count */
4418 if (cert_peer && crt)
4419 X509_free(crt);
4420 return ret;
4421}
4422
Emeric Brunba841a12014-04-30 17:05:08 +02004423/* binary, returns serial of certificate in a binary chunk.
4424 * The 5th keyword char is used to know if SSL_get_certificate or SSL_get_peer_certificate
4425 * should be use.
4426 */
Willy Tarreau8d598402012-10-22 17:58:39 +02004427static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02004428smp_fetch_ssl_x_serial(const struct arg *args, struct sample *smp, const char *kw, void *private)
Willy Tarreau8d598402012-10-22 17:58:39 +02004429{
Emeric Brunba841a12014-04-30 17:05:08 +02004430 int cert_peer = (kw[4] == 'c') ? 1 : 0;
Willy Tarreau8d598402012-10-22 17:58:39 +02004431 X509 *crt = NULL;
4432 int ret = 0;
4433 struct chunk *smp_trash;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004434 struct connection *conn;
4435
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02004436 conn = objt_conn(smp->sess->origin);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004437 if (!conn || conn->xprt != &ssl_sock)
Willy Tarreau8d598402012-10-22 17:58:39 +02004438 return 0;
4439
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004440 if (!(conn->flags & CO_FL_CONNECTED)) {
Willy Tarreau8d598402012-10-22 17:58:39 +02004441 smp->flags |= SMP_F_MAY_CHANGE;
4442 return 0;
4443 }
4444
Emeric Brunba841a12014-04-30 17:05:08 +02004445 if (cert_peer)
4446 crt = SSL_get_peer_certificate(conn->xprt_ctx);
4447 else
4448 crt = SSL_get_certificate(conn->xprt_ctx);
4449
Willy Tarreau8d598402012-10-22 17:58:39 +02004450 if (!crt)
4451 goto out;
4452
Willy Tarreau47ca5452012-12-23 20:22:19 +01004453 smp_trash = get_trash_chunk();
Willy Tarreau8d598402012-10-22 17:58:39 +02004454 if (ssl_sock_get_serial(crt, smp_trash) <= 0)
4455 goto out;
4456
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02004457 smp->data.u.str = *smp_trash;
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02004458 smp->data.type = SMP_T_BIN;
Willy Tarreau8d598402012-10-22 17:58:39 +02004459 ret = 1;
4460out:
Emeric Brunba841a12014-04-30 17:05:08 +02004461 /* SSL_get_peer_certificate, it increase X509 * ref count */
4462 if (cert_peer && crt)
Willy Tarreau8d598402012-10-22 17:58:39 +02004463 X509_free(crt);
4464 return ret;
4465}
Emeric Brune64aef12012-09-21 13:15:06 +02004466
Emeric Brunba841a12014-04-30 17:05:08 +02004467/* binary, returns the client certificate's SHA-1 fingerprint (SHA-1 hash of DER-encoded certificate) in a binary chunk.
4468 * The 5th keyword char is used to know if SSL_get_certificate or SSL_get_peer_certificate
4469 * should be use.
4470 */
James Votha051b4a2013-05-14 20:37:59 +02004471static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02004472smp_fetch_ssl_x_sha1(const struct arg *args, struct sample *smp, const char *kw, void *private)
James Votha051b4a2013-05-14 20:37:59 +02004473{
Emeric Brunba841a12014-04-30 17:05:08 +02004474 int cert_peer = (kw[4] == 'c') ? 1 : 0;
James Votha051b4a2013-05-14 20:37:59 +02004475 X509 *crt = NULL;
4476 const EVP_MD *digest;
4477 int ret = 0;
4478 struct chunk *smp_trash;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004479 struct connection *conn;
James Votha051b4a2013-05-14 20:37:59 +02004480
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02004481 conn = objt_conn(smp->sess->origin);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004482 if (!conn || conn->xprt != &ssl_sock)
4483 return 0;
4484
4485 if (!(conn->flags & CO_FL_CONNECTED)) {
James Votha051b4a2013-05-14 20:37:59 +02004486 smp->flags |= SMP_F_MAY_CHANGE;
4487 return 0;
4488 }
4489
Emeric Brunba841a12014-04-30 17:05:08 +02004490 if (cert_peer)
4491 crt = SSL_get_peer_certificate(conn->xprt_ctx);
4492 else
4493 crt = SSL_get_certificate(conn->xprt_ctx);
James Votha051b4a2013-05-14 20:37:59 +02004494 if (!crt)
4495 goto out;
4496
4497 smp_trash = get_trash_chunk();
4498 digest = EVP_sha1();
4499 X509_digest(crt, digest, (unsigned char *)smp_trash->str, (unsigned int *)&smp_trash->len);
4500
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02004501 smp->data.u.str = *smp_trash;
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02004502 smp->data.type = SMP_T_BIN;
James Votha051b4a2013-05-14 20:37:59 +02004503 ret = 1;
4504out:
Emeric Brunba841a12014-04-30 17:05:08 +02004505 /* SSL_get_peer_certificate, it increase X509 * ref count */
4506 if (cert_peer && crt)
James Votha051b4a2013-05-14 20:37:59 +02004507 X509_free(crt);
4508 return ret;
4509}
4510
Emeric Brunba841a12014-04-30 17:05:08 +02004511/* string, returns certificate's notafter date in ASN1_UTCTIME format.
4512 * The 5th keyword char is used to know if SSL_get_certificate or SSL_get_peer_certificate
4513 * should be use.
4514 */
Emeric Brunce5ad802012-10-22 14:11:22 +02004515static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02004516smp_fetch_ssl_x_notafter(const struct arg *args, struct sample *smp, const char *kw, void *private)
Emeric Brunce5ad802012-10-22 14:11:22 +02004517{
Emeric Brunba841a12014-04-30 17:05:08 +02004518 int cert_peer = (kw[4] == 'c') ? 1 : 0;
Emeric Brunce5ad802012-10-22 14:11:22 +02004519 X509 *crt = NULL;
4520 int ret = 0;
4521 struct chunk *smp_trash;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004522 struct connection *conn;
Emeric Brunce5ad802012-10-22 14:11:22 +02004523
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02004524 conn = objt_conn(smp->sess->origin);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004525 if (!conn || conn->xprt != &ssl_sock)
4526 return 0;
4527
4528 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brunce5ad802012-10-22 14:11:22 +02004529 smp->flags |= SMP_F_MAY_CHANGE;
4530 return 0;
4531 }
4532
Emeric Brunba841a12014-04-30 17:05:08 +02004533 if (cert_peer)
4534 crt = SSL_get_peer_certificate(conn->xprt_ctx);
4535 else
4536 crt = SSL_get_certificate(conn->xprt_ctx);
Emeric Brunce5ad802012-10-22 14:11:22 +02004537 if (!crt)
4538 goto out;
4539
Willy Tarreau47ca5452012-12-23 20:22:19 +01004540 smp_trash = get_trash_chunk();
Emeric Brunce5ad802012-10-22 14:11:22 +02004541 if (ssl_sock_get_time(X509_get_notAfter(crt), smp_trash) <= 0)
4542 goto out;
4543
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02004544 smp->data.u.str = *smp_trash;
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02004545 smp->data.type = SMP_T_STR;
Emeric Brunce5ad802012-10-22 14:11:22 +02004546 ret = 1;
4547out:
Emeric Brunba841a12014-04-30 17:05:08 +02004548 /* SSL_get_peer_certificate, it increase X509 * ref count */
4549 if (cert_peer && crt)
Emeric Brunce5ad802012-10-22 14:11:22 +02004550 X509_free(crt);
4551 return ret;
4552}
4553
Emeric Brunba841a12014-04-30 17:05:08 +02004554/* string, returns a string of a formatted full dn \C=..\O=..\OU=.. \CN=.. of certificate's issuer
4555 * The 5th keyword char is used to know if SSL_get_certificate or SSL_get_peer_certificate
4556 * should be use.
4557 */
Emeric Brun87855892012-10-17 17:39:35 +02004558static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02004559smp_fetch_ssl_x_i_dn(const struct arg *args, struct sample *smp, const char *kw, void *private)
Emeric Brun87855892012-10-17 17:39:35 +02004560{
Emeric Brunba841a12014-04-30 17:05:08 +02004561 int cert_peer = (kw[4] == 'c') ? 1 : 0;
Emeric Brun87855892012-10-17 17:39:35 +02004562 X509 *crt = NULL;
4563 X509_NAME *name;
4564 int ret = 0;
4565 struct chunk *smp_trash;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004566 struct connection *conn;
Emeric Brun87855892012-10-17 17:39:35 +02004567
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02004568 conn = objt_conn(smp->sess->origin);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004569 if (!conn || conn->xprt != &ssl_sock)
4570 return 0;
4571
4572 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brun87855892012-10-17 17:39:35 +02004573 smp->flags |= SMP_F_MAY_CHANGE;
4574 return 0;
4575 }
4576
Emeric Brunba841a12014-04-30 17:05:08 +02004577 if (cert_peer)
4578 crt = SSL_get_peer_certificate(conn->xprt_ctx);
4579 else
4580 crt = SSL_get_certificate(conn->xprt_ctx);
Emeric Brun87855892012-10-17 17:39:35 +02004581 if (!crt)
4582 goto out;
4583
4584 name = X509_get_issuer_name(crt);
4585 if (!name)
4586 goto out;
4587
Willy Tarreau47ca5452012-12-23 20:22:19 +01004588 smp_trash = get_trash_chunk();
Emeric Brun87855892012-10-17 17:39:35 +02004589 if (args && args[0].type == ARGT_STR) {
4590 int pos = 1;
4591
4592 if (args[1].type == ARGT_SINT)
4593 pos = args[1].data.sint;
Emeric Brun87855892012-10-17 17:39:35 +02004594
4595 if (ssl_sock_get_dn_entry(name, &args[0].data.str, pos, smp_trash) <= 0)
4596 goto out;
4597 }
4598 else if (ssl_sock_get_dn_oneline(name, smp_trash) <= 0)
4599 goto out;
4600
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02004601 smp->data.type = SMP_T_STR;
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02004602 smp->data.u.str = *smp_trash;
Emeric Brun87855892012-10-17 17:39:35 +02004603 ret = 1;
4604out:
Emeric Brunba841a12014-04-30 17:05:08 +02004605 /* SSL_get_peer_certificate, it increase X509 * ref count */
4606 if (cert_peer && crt)
Emeric Brun87855892012-10-17 17:39:35 +02004607 X509_free(crt);
4608 return ret;
4609}
4610
Emeric Brunba841a12014-04-30 17:05:08 +02004611/* string, returns notbefore date in ASN1_UTCTIME format.
4612 * The 5th keyword char is used to know if SSL_get_certificate or SSL_get_peer_certificate
4613 * should be use.
4614 */
Emeric Brunce5ad802012-10-22 14:11:22 +02004615static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02004616smp_fetch_ssl_x_notbefore(const struct arg *args, struct sample *smp, const char *kw, void *private)
Emeric Brunce5ad802012-10-22 14:11:22 +02004617{
Emeric Brunba841a12014-04-30 17:05:08 +02004618 int cert_peer = (kw[4] == 'c') ? 1 : 0;
Emeric Brunce5ad802012-10-22 14:11:22 +02004619 X509 *crt = NULL;
4620 int ret = 0;
4621 struct chunk *smp_trash;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004622 struct connection *conn;
4623
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02004624 conn = objt_conn(smp->sess->origin);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004625 if (!conn || conn->xprt != &ssl_sock)
Emeric Brunce5ad802012-10-22 14:11:22 +02004626 return 0;
4627
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004628 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brunce5ad802012-10-22 14:11:22 +02004629 smp->flags |= SMP_F_MAY_CHANGE;
4630 return 0;
4631 }
4632
Emeric Brunba841a12014-04-30 17:05:08 +02004633 if (cert_peer)
4634 crt = SSL_get_peer_certificate(conn->xprt_ctx);
4635 else
4636 crt = SSL_get_certificate(conn->xprt_ctx);
Emeric Brunce5ad802012-10-22 14:11:22 +02004637 if (!crt)
4638 goto out;
4639
Willy Tarreau47ca5452012-12-23 20:22:19 +01004640 smp_trash = get_trash_chunk();
Emeric Brunce5ad802012-10-22 14:11:22 +02004641 if (ssl_sock_get_time(X509_get_notBefore(crt), smp_trash) <= 0)
4642 goto out;
4643
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02004644 smp->data.u.str = *smp_trash;
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02004645 smp->data.type = SMP_T_STR;
Emeric Brunce5ad802012-10-22 14:11:22 +02004646 ret = 1;
4647out:
Emeric Brunba841a12014-04-30 17:05:08 +02004648 /* SSL_get_peer_certificate, it increase X509 * ref count */
4649 if (cert_peer && crt)
Emeric Brunce5ad802012-10-22 14:11:22 +02004650 X509_free(crt);
4651 return ret;
4652}
4653
Emeric Brunba841a12014-04-30 17:05:08 +02004654/* string, returns a string of a formatted full dn \C=..\O=..\OU=.. \CN=.. of certificate's subject
4655 * The 5th keyword char is used to know if SSL_get_certificate or SSL_get_peer_certificate
4656 * should be use.
4657 */
Emeric Brun87855892012-10-17 17:39:35 +02004658static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02004659smp_fetch_ssl_x_s_dn(const struct arg *args, struct sample *smp, const char *kw, void *private)
Emeric Brun87855892012-10-17 17:39:35 +02004660{
Emeric Brunba841a12014-04-30 17:05:08 +02004661 int cert_peer = (kw[4] == 'c') ? 1 : 0;
Emeric Brun87855892012-10-17 17:39:35 +02004662 X509 *crt = NULL;
4663 X509_NAME *name;
4664 int ret = 0;
4665 struct chunk *smp_trash;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004666 struct connection *conn;
Emeric Brun87855892012-10-17 17:39:35 +02004667
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02004668 conn = objt_conn(smp->sess->origin);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004669 if (!conn || conn->xprt != &ssl_sock)
4670 return 0;
4671
4672 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brun87855892012-10-17 17:39:35 +02004673 smp->flags |= SMP_F_MAY_CHANGE;
4674 return 0;
4675 }
4676
Emeric Brunba841a12014-04-30 17:05:08 +02004677 if (cert_peer)
4678 crt = SSL_get_peer_certificate(conn->xprt_ctx);
4679 else
4680 crt = SSL_get_certificate(conn->xprt_ctx);
Emeric Brun87855892012-10-17 17:39:35 +02004681 if (!crt)
4682 goto out;
4683
4684 name = X509_get_subject_name(crt);
4685 if (!name)
4686 goto out;
4687
Willy Tarreau47ca5452012-12-23 20:22:19 +01004688 smp_trash = get_trash_chunk();
Emeric Brun87855892012-10-17 17:39:35 +02004689 if (args && args[0].type == ARGT_STR) {
4690 int pos = 1;
4691
4692 if (args[1].type == ARGT_SINT)
4693 pos = args[1].data.sint;
Emeric Brun87855892012-10-17 17:39:35 +02004694
4695 if (ssl_sock_get_dn_entry(name, &args[0].data.str, pos, smp_trash) <= 0)
4696 goto out;
4697 }
4698 else if (ssl_sock_get_dn_oneline(name, smp_trash) <= 0)
4699 goto out;
4700
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02004701 smp->data.type = SMP_T_STR;
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02004702 smp->data.u.str = *smp_trash;
Emeric Brun87855892012-10-17 17:39:35 +02004703 ret = 1;
4704out:
Emeric Brunba841a12014-04-30 17:05:08 +02004705 /* SSL_get_peer_certificate, it increase X509 * ref count */
4706 if (cert_peer && crt)
Emeric Brun87855892012-10-17 17:39:35 +02004707 X509_free(crt);
4708 return ret;
4709}
Emeric Brun9143d372012-12-20 15:44:16 +01004710
4711/* integer, returns true if current session use a client certificate */
4712static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02004713smp_fetch_ssl_c_used(const struct arg *args, struct sample *smp, const char *kw, void *private)
Emeric Brun9143d372012-12-20 15:44:16 +01004714{
4715 X509 *crt;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004716 struct connection *conn;
Emeric Brun9143d372012-12-20 15:44:16 +01004717
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02004718 conn = objt_conn(smp->sess->origin);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004719 if (!conn || conn->xprt != &ssl_sock)
4720 return 0;
4721
4722 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brun9143d372012-12-20 15:44:16 +01004723 smp->flags |= SMP_F_MAY_CHANGE;
4724 return 0;
4725 }
4726
4727 /* SSL_get_peer_certificate returns a ptr on allocated X509 struct */
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004728 crt = SSL_get_peer_certificate(conn->xprt_ctx);
Emeric Brun9143d372012-12-20 15:44:16 +01004729 if (crt) {
4730 X509_free(crt);
4731 }
4732
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02004733 smp->data.type = SMP_T_BOOL;
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02004734 smp->data.u.sint = (crt != NULL);
Emeric Brun9143d372012-12-20 15:44:16 +01004735 return 1;
4736}
4737
Emeric Brunba841a12014-04-30 17:05:08 +02004738/* integer, returns the certificate version
4739 * The 5th keyword char is used to know if SSL_get_certificate or SSL_get_peer_certificate
4740 * should be use.
4741 */
Emeric Bruna7359fd2012-10-17 15:03:11 +02004742static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02004743smp_fetch_ssl_x_version(const struct arg *args, struct sample *smp, const char *kw, void *private)
Emeric Bruna7359fd2012-10-17 15:03:11 +02004744{
Emeric Brunba841a12014-04-30 17:05:08 +02004745 int cert_peer = (kw[4] == 'c') ? 1 : 0;
Emeric Bruna7359fd2012-10-17 15:03:11 +02004746 X509 *crt;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004747 struct connection *conn;
4748
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02004749 conn = objt_conn(smp->sess->origin);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004750 if (!conn || conn->xprt != &ssl_sock)
Emeric Bruna7359fd2012-10-17 15:03:11 +02004751 return 0;
4752
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004753 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Bruna7359fd2012-10-17 15:03:11 +02004754 smp->flags |= SMP_F_MAY_CHANGE;
4755 return 0;
4756 }
4757
Emeric Brunba841a12014-04-30 17:05:08 +02004758 if (cert_peer)
4759 crt = SSL_get_peer_certificate(conn->xprt_ctx);
4760 else
4761 crt = SSL_get_certificate(conn->xprt_ctx);
Emeric Bruna7359fd2012-10-17 15:03:11 +02004762 if (!crt)
4763 return 0;
4764
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02004765 smp->data.u.sint = (unsigned int)(1 + X509_get_version(crt));
Emeric Brunba841a12014-04-30 17:05:08 +02004766 /* SSL_get_peer_certificate increase X509 * ref count */
4767 if (cert_peer)
4768 X509_free(crt);
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02004769 smp->data.type = SMP_T_SINT;
Emeric Bruna7359fd2012-10-17 15:03:11 +02004770
4771 return 1;
4772}
4773
Emeric Brunba841a12014-04-30 17:05:08 +02004774/* string, returns the certificate's signature algorithm.
4775 * The 5th keyword char is used to know if SSL_get_certificate or SSL_get_peer_certificate
4776 * should be use.
4777 */
Emeric Brun7f56e742012-10-19 18:15:40 +02004778static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02004779smp_fetch_ssl_x_sig_alg(const struct arg *args, struct sample *smp, const char *kw, void *private)
Emeric Brun7f56e742012-10-19 18:15:40 +02004780{
Emeric Brunba841a12014-04-30 17:05:08 +02004781 int cert_peer = (kw[4] == 'c') ? 1 : 0;
Emeric Brun7f56e742012-10-19 18:15:40 +02004782 X509 *crt;
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02004783 __OPENSSL_110_CONST__ ASN1_OBJECT *algorithm;
Emeric Brun7f56e742012-10-19 18:15:40 +02004784 int nid;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004785 struct connection *conn;
Emeric Brun7f56e742012-10-19 18:15:40 +02004786
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02004787 conn = objt_conn(smp->sess->origin);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004788 if (!conn || conn->xprt != &ssl_sock)
4789 return 0;
4790
4791 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brun7f56e742012-10-19 18:15:40 +02004792 smp->flags |= SMP_F_MAY_CHANGE;
4793 return 0;
4794 }
4795
Emeric Brunba841a12014-04-30 17:05:08 +02004796 if (cert_peer)
4797 crt = SSL_get_peer_certificate(conn->xprt_ctx);
4798 else
4799 crt = SSL_get_certificate(conn->xprt_ctx);
Emeric Brun7f56e742012-10-19 18:15:40 +02004800 if (!crt)
4801 return 0;
4802
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02004803 X509_ALGOR_get0(&algorithm, NULL, NULL, X509_get0_tbs_sigalg(crt));
4804 nid = OBJ_obj2nid(algorithm);
Emeric Brun7f56e742012-10-19 18:15:40 +02004805
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02004806 smp->data.u.str.str = (char *)OBJ_nid2sn(nid);
4807 if (!smp->data.u.str.str) {
Emeric Brunba841a12014-04-30 17:05:08 +02004808 /* SSL_get_peer_certificate increase X509 * ref count */
4809 if (cert_peer)
4810 X509_free(crt);
Emeric Brun7f56e742012-10-19 18:15:40 +02004811 return 0;
Emeric Brun9bf3ba22013-10-07 14:31:44 +02004812 }
Emeric Brun7f56e742012-10-19 18:15:40 +02004813
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02004814 smp->data.type = SMP_T_STR;
Thierry FOURNIER7654c9f2013-12-17 00:20:33 +01004815 smp->flags |= SMP_F_CONST;
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02004816 smp->data.u.str.len = strlen(smp->data.u.str.str);
Emeric Brunba841a12014-04-30 17:05:08 +02004817 /* SSL_get_peer_certificate increase X509 * ref count */
4818 if (cert_peer)
4819 X509_free(crt);
Emeric Brun7f56e742012-10-19 18:15:40 +02004820
4821 return 1;
4822}
4823
Emeric Brunba841a12014-04-30 17:05:08 +02004824/* string, returns the certificate's key algorithm.
4825 * The 5th keyword char is used to know if SSL_get_certificate or SSL_get_peer_certificate
4826 * should be use.
4827 */
Emeric Brun521a0112012-10-22 12:22:55 +02004828static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02004829smp_fetch_ssl_x_key_alg(const struct arg *args, struct sample *smp, const char *kw, void *private)
Emeric Brun521a0112012-10-22 12:22:55 +02004830{
Emeric Brunba841a12014-04-30 17:05:08 +02004831 int cert_peer = (kw[4] == 'c') ? 1 : 0;
Emeric Brun521a0112012-10-22 12:22:55 +02004832 X509 *crt;
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02004833 ASN1_OBJECT *algorithm;
Emeric Brun521a0112012-10-22 12:22:55 +02004834 int nid;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004835 struct connection *conn;
Emeric Brun521a0112012-10-22 12:22:55 +02004836
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02004837 conn = objt_conn(smp->sess->origin);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004838 if (!conn || conn->xprt != &ssl_sock)
4839 return 0;
4840
4841 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brun521a0112012-10-22 12:22:55 +02004842 smp->flags |= SMP_F_MAY_CHANGE;
4843 return 0;
4844 }
4845
Emeric Brunba841a12014-04-30 17:05:08 +02004846 if (cert_peer)
4847 crt = SSL_get_peer_certificate(conn->xprt_ctx);
4848 else
4849 crt = SSL_get_certificate(conn->xprt_ctx);
Emeric Brun521a0112012-10-22 12:22:55 +02004850 if (!crt)
4851 return 0;
4852
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02004853 X509_PUBKEY_get0_param(&algorithm, NULL, NULL, NULL, X509_get_X509_PUBKEY(crt));
4854 nid = OBJ_obj2nid(algorithm);
Emeric Brun521a0112012-10-22 12:22:55 +02004855
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02004856 smp->data.u.str.str = (char *)OBJ_nid2sn(nid);
4857 if (!smp->data.u.str.str) {
Emeric Brunba841a12014-04-30 17:05:08 +02004858 /* SSL_get_peer_certificate increase X509 * ref count */
4859 if (cert_peer)
4860 X509_free(crt);
Emeric Brun521a0112012-10-22 12:22:55 +02004861 return 0;
Emeric Brun9bf3ba22013-10-07 14:31:44 +02004862 }
Emeric Brun521a0112012-10-22 12:22:55 +02004863
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02004864 smp->data.type = SMP_T_STR;
Thierry FOURNIER7654c9f2013-12-17 00:20:33 +01004865 smp->flags |= SMP_F_CONST;
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02004866 smp->data.u.str.len = strlen(smp->data.u.str.str);
Emeric Brunba841a12014-04-30 17:05:08 +02004867 if (cert_peer)
4868 X509_free(crt);
Emeric Brun521a0112012-10-22 12:22:55 +02004869
4870 return 1;
4871}
4872
Emeric Brun645ae792014-04-30 14:21:06 +02004873/* boolean, returns true if front conn. transport layer is SSL.
4874 * This function is also usable on backend conn if the fetch keyword 5th
4875 * char is 'b'.
4876 */
Willy Tarreau7875d092012-09-10 08:20:03 +02004877static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02004878smp_fetch_ssl_fc(const struct arg *args, struct sample *smp, const char *kw, void *private)
Willy Tarreau7875d092012-09-10 08:20:03 +02004879{
Willy Tarreaue237fe12016-03-10 17:05:28 +01004880 struct connection *conn = objt_conn((kw[4] != 'b') ? smp->sess->origin :
4881 smp->strm ? smp->strm->si[1].end : NULL);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004882
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02004883 smp->data.type = SMP_T_BOOL;
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02004884 smp->data.u.sint = (conn && conn->xprt == &ssl_sock);
Willy Tarreau7875d092012-09-10 08:20:03 +02004885 return 1;
4886}
4887
Emeric Brun2525b6b2012-10-18 15:59:43 +02004888/* boolean, returns true if client present a SNI */
Willy Tarreau7875d092012-09-10 08:20:03 +02004889static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02004890smp_fetch_ssl_fc_has_sni(const struct arg *args, struct sample *smp, const char *kw, void *private)
Willy Tarreau7875d092012-09-10 08:20:03 +02004891{
4892#ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02004893 struct connection *conn = objt_conn(smp->sess->origin);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004894
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02004895 smp->data.type = SMP_T_BOOL;
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02004896 smp->data.u.sint = (conn && conn->xprt == &ssl_sock) &&
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004897 conn->xprt_ctx &&
4898 SSL_get_servername(conn->xprt_ctx, TLSEXT_NAMETYPE_host_name) != NULL;
Willy Tarreau7875d092012-09-10 08:20:03 +02004899 return 1;
4900#else
4901 return 0;
4902#endif
4903}
4904
Nenad Merdanovic26ea8222015-05-18 02:28:57 +02004905/* boolean, returns true if client session has been resumed */
4906static int
4907smp_fetch_ssl_fc_is_resumed(const struct arg *args, struct sample *smp, const char *kw, void *private)
4908{
4909 struct connection *conn = objt_conn(smp->sess->origin);
4910
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02004911 smp->data.type = SMP_T_BOOL;
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02004912 smp->data.u.sint = (conn && conn->xprt == &ssl_sock) &&
Nenad Merdanovic26ea8222015-05-18 02:28:57 +02004913 conn->xprt_ctx &&
4914 SSL_session_reused(conn->xprt_ctx);
4915 return 1;
4916}
4917
Emeric Brun645ae792014-04-30 14:21:06 +02004918/* string, returns the used cipher if front conn. transport layer is SSL.
4919 * This function is also usable on backend conn if the fetch keyword 5th
4920 * char is 'b'.
4921 */
Emeric Brun589fcad2012-10-16 14:13:26 +02004922static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02004923smp_fetch_ssl_fc_cipher(const struct arg *args, struct sample *smp, const char *kw, void *private)
Emeric Brun589fcad2012-10-16 14:13:26 +02004924{
Willy Tarreaue237fe12016-03-10 17:05:28 +01004925 struct connection *conn = objt_conn((kw[4] != 'b') ? smp->sess->origin :
4926 smp->strm ? smp->strm->si[1].end : NULL);
Emeric Brun589fcad2012-10-16 14:13:26 +02004927
Willy Tarreaube508f12016-03-10 11:47:01 +01004928 smp->flags = 0;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004929 if (!conn || !conn->xprt_ctx || conn->xprt != &ssl_sock)
Emeric Brun589fcad2012-10-16 14:13:26 +02004930 return 0;
4931
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02004932 smp->data.u.str.str = (char *)SSL_get_cipher_name(conn->xprt_ctx);
4933 if (!smp->data.u.str.str)
Emeric Brun589fcad2012-10-16 14:13:26 +02004934 return 0;
4935
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02004936 smp->data.type = SMP_T_STR;
Thierry FOURNIER7654c9f2013-12-17 00:20:33 +01004937 smp->flags |= SMP_F_CONST;
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02004938 smp->data.u.str.len = strlen(smp->data.u.str.str);
Emeric Brun589fcad2012-10-16 14:13:26 +02004939
4940 return 1;
4941}
4942
Emeric Brun645ae792014-04-30 14:21:06 +02004943/* integer, returns the algoritm's keysize if front conn. transport layer
4944 * is SSL.
4945 * This function is also usable on backend conn if the fetch keyword 5th
4946 * char is 'b'.
4947 */
Emeric Brun589fcad2012-10-16 14:13:26 +02004948static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02004949smp_fetch_ssl_fc_alg_keysize(const struct arg *args, struct sample *smp, const char *kw, void *private)
Emeric Brun589fcad2012-10-16 14:13:26 +02004950{
Willy Tarreaue237fe12016-03-10 17:05:28 +01004951 struct connection *conn = objt_conn((kw[4] != 'b') ? smp->sess->origin :
4952 smp->strm ? smp->strm->si[1].end : NULL);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004953
Willy Tarreaue237fe12016-03-10 17:05:28 +01004954 int sint;
Willy Tarreaube508f12016-03-10 11:47:01 +01004955
Emeric Brun589fcad2012-10-16 14:13:26 +02004956 smp->flags = 0;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004957 if (!conn || !conn->xprt_ctx || conn->xprt != &ssl_sock)
Emeric Brun589fcad2012-10-16 14:13:26 +02004958 return 0;
4959
Thierry FOURNIER07ee64e2015-07-06 23:43:03 +02004960 if (!SSL_get_cipher_bits(conn->xprt_ctx, &sint))
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004961 return 0;
4962
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02004963 smp->data.u.sint = sint;
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02004964 smp->data.type = SMP_T_SINT;
Emeric Brun589fcad2012-10-16 14:13:26 +02004965
4966 return 1;
4967}
4968
Emeric Brun645ae792014-04-30 14:21:06 +02004969/* integer, returns the used keysize if front conn. transport layer is SSL.
4970 * This function is also usable on backend conn if the fetch keyword 5th
4971 * char is 'b'.
4972 */
Emeric Brun589fcad2012-10-16 14:13:26 +02004973static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02004974smp_fetch_ssl_fc_use_keysize(const struct arg *args, struct sample *smp, const char *kw, void *private)
Emeric Brun589fcad2012-10-16 14:13:26 +02004975{
Willy Tarreaue237fe12016-03-10 17:05:28 +01004976 struct connection *conn = objt_conn((kw[4] != 'b') ? smp->sess->origin :
4977 smp->strm ? smp->strm->si[1].end : NULL);
Willy Tarreaube508f12016-03-10 11:47:01 +01004978
Emeric Brun589fcad2012-10-16 14:13:26 +02004979 smp->flags = 0;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004980 if (!conn || !conn->xprt_ctx || conn->xprt != &ssl_sock)
4981 return 0;
4982
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02004983 smp->data.u.sint = (unsigned int)SSL_get_cipher_bits(conn->xprt_ctx, NULL);
4984 if (!smp->data.u.sint)
Emeric Brun589fcad2012-10-16 14:13:26 +02004985 return 0;
4986
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02004987 smp->data.type = SMP_T_SINT;
Emeric Brun589fcad2012-10-16 14:13:26 +02004988
4989 return 1;
4990}
4991
Willy Tarreau6c9a3d52012-10-18 18:57:14 +02004992#ifdef OPENSSL_NPN_NEGOTIATED
Willy Tarreau7875d092012-09-10 08:20:03 +02004993static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02004994smp_fetch_ssl_fc_npn(const struct arg *args, struct sample *smp, const char *kw, void *private)
Willy Tarreaua33c6542012-10-15 13:19:06 +02004995{
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004996 struct connection *conn;
4997
Thierry FOURNIER7654c9f2013-12-17 00:20:33 +01004998 smp->flags = SMP_F_CONST;
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02004999 smp->data.type = SMP_T_STR;
Willy Tarreaua33c6542012-10-15 13:19:06 +02005000
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_ctx || conn->xprt != &ssl_sock)
5003 return 0;
5004
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02005005 smp->data.u.str.str = NULL;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02005006 SSL_get0_next_proto_negotiated(conn->xprt_ctx,
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02005007 (const unsigned char **)&smp->data.u.str.str, (unsigned *)&smp->data.u.str.len);
Willy Tarreaua33c6542012-10-15 13:19:06 +02005008
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02005009 if (!smp->data.u.str.str)
Willy Tarreaua33c6542012-10-15 13:19:06 +02005010 return 0;
5011
5012 return 1;
Willy Tarreaua33c6542012-10-15 13:19:06 +02005013}
Willy Tarreau6c9a3d52012-10-18 18:57:14 +02005014#endif
Willy Tarreaua33c6542012-10-15 13:19:06 +02005015
Dirkjan Bussink48f1c4e2014-02-13 12:29:42 +01005016#ifdef TLSEXT_TYPE_application_layer_protocol_negotiation
Willy Tarreauab861d32013-04-02 02:30:41 +02005017static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02005018smp_fetch_ssl_fc_alpn(const struct arg *args, struct sample *smp, const char *kw, void *private)
Willy Tarreauab861d32013-04-02 02:30:41 +02005019{
Willy Tarreaub363a1f2013-10-01 10:45:07 +02005020 struct connection *conn;
5021
Thierry FOURNIER7654c9f2013-12-17 00:20:33 +01005022 smp->flags = SMP_F_CONST;
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02005023 smp->data.type = SMP_T_STR;
Willy Tarreauab861d32013-04-02 02:30:41 +02005024
Willy Tarreaue26bf052015-05-12 10:30:12 +02005025 conn = objt_conn(smp->sess->origin);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02005026 if (!conn || !conn->xprt_ctx || conn->xprt != &ssl_sock)
Willy Tarreauab861d32013-04-02 02:30:41 +02005027 return 0;
5028
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02005029 smp->data.u.str.str = NULL;
Dirkjan Bussink48f1c4e2014-02-13 12:29:42 +01005030 SSL_get0_alpn_selected(conn->xprt_ctx,
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02005031 (const unsigned char **)&smp->data.u.str.str, (unsigned *)&smp->data.u.str.len);
Willy Tarreauab861d32013-04-02 02:30:41 +02005032
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02005033 if (!smp->data.u.str.str)
Willy Tarreauab861d32013-04-02 02:30:41 +02005034 return 0;
5035
5036 return 1;
5037}
5038#endif
5039
Emeric Brun645ae792014-04-30 14:21:06 +02005040/* string, returns the used protocol if front conn. transport layer is SSL.
5041 * This function is also usable on backend conn if the fetch keyword 5th
5042 * char is 'b'.
5043 */
Willy Tarreaua33c6542012-10-15 13:19:06 +02005044static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02005045smp_fetch_ssl_fc_protocol(const struct arg *args, struct sample *smp, const char *kw, void *private)
Emeric Brun589fcad2012-10-16 14:13:26 +02005046{
Willy Tarreaue237fe12016-03-10 17:05:28 +01005047 struct connection *conn = objt_conn((kw[4] != 'b') ? smp->sess->origin :
5048 smp->strm ? smp->strm->si[1].end : NULL);
Willy Tarreaube508f12016-03-10 11:47:01 +01005049
Emeric Brun589fcad2012-10-16 14:13:26 +02005050 smp->flags = 0;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02005051 if (!conn || !conn->xprt_ctx || conn->xprt != &ssl_sock)
5052 return 0;
5053
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02005054 smp->data.u.str.str = (char *)SSL_get_version(conn->xprt_ctx);
5055 if (!smp->data.u.str.str)
Emeric Brun589fcad2012-10-16 14:13:26 +02005056 return 0;
5057
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02005058 smp->data.type = SMP_T_STR;
Thierry FOURNIER7654c9f2013-12-17 00:20:33 +01005059 smp->flags = SMP_F_CONST;
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02005060 smp->data.u.str.len = strlen(smp->data.u.str.str);
Emeric Brun589fcad2012-10-16 14:13:26 +02005061
5062 return 1;
5063}
5064
Willy Tarreau87b09662015-04-03 00:22:06 +02005065/* binary, returns the SSL stream id if front conn. transport layer is SSL.
Emeric Brun645ae792014-04-30 14:21:06 +02005066 * This function is also usable on backend conn if the fetch keyword 5th
5067 * char is 'b'.
5068 */
Emeric Brun589fcad2012-10-16 14:13:26 +02005069static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02005070smp_fetch_ssl_fc_session_id(const struct arg *args, struct sample *smp, const char *kw, void *private)
Emeric Brunfe68f682012-10-16 14:59:28 +02005071{
5072#if OPENSSL_VERSION_NUMBER > 0x0090800fL
Willy Tarreaue237fe12016-03-10 17:05:28 +01005073 struct connection *conn = objt_conn((kw[4] != 'b') ? smp->sess->origin :
5074 smp->strm ? smp->strm->si[1].end : NULL);
Emeric Brunfe68f682012-10-16 14:59:28 +02005075
Willy Tarreaue237fe12016-03-10 17:05:28 +01005076 SSL_SESSION *ssl_sess;
Willy Tarreaube508f12016-03-10 11:47:01 +01005077
Thierry FOURNIER7654c9f2013-12-17 00:20:33 +01005078 smp->flags = SMP_F_CONST;
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02005079 smp->data.type = SMP_T_BIN;
Emeric Brunfe68f682012-10-16 14:59:28 +02005080
Willy Tarreaub363a1f2013-10-01 10:45:07 +02005081 if (!conn || !conn->xprt_ctx || conn->xprt != &ssl_sock)
5082 return 0;
5083
Willy Tarreau192252e2015-04-04 01:47:55 +02005084 ssl_sess = SSL_get_session(conn->xprt_ctx);
5085 if (!ssl_sess)
Emeric Brunfe68f682012-10-16 14:59:28 +02005086 return 0;
5087
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02005088 smp->data.u.str.str = (char *)SSL_SESSION_get_id(ssl_sess, (unsigned int *)&smp->data.u.str.len);
5089 if (!smp->data.u.str.str || !smp->data.u.str.len)
Emeric Brunfe68f682012-10-16 14:59:28 +02005090 return 0;
5091
5092 return 1;
5093#else
5094 return 0;
5095#endif
5096}
5097
5098static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02005099smp_fetch_ssl_fc_sni(const struct arg *args, struct sample *smp, const char *kw, void *private)
Willy Tarreau7875d092012-09-10 08:20:03 +02005100{
5101#ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME
Willy Tarreaub363a1f2013-10-01 10:45:07 +02005102 struct connection *conn;
5103
Thierry FOURNIER7654c9f2013-12-17 00:20:33 +01005104 smp->flags = SMP_F_CONST;
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02005105 smp->data.type = SMP_T_STR;
Willy Tarreau7875d092012-09-10 08:20:03 +02005106
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02005107 conn = objt_conn(smp->sess->origin);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02005108 if (!conn || !conn->xprt_ctx || conn->xprt != &ssl_sock)
5109 return 0;
5110
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02005111 smp->data.u.str.str = (char *)SSL_get_servername(conn->xprt_ctx, TLSEXT_NAMETYPE_host_name);
5112 if (!smp->data.u.str.str)
Willy Tarreau3e394c92012-09-14 23:56:58 +02005113 return 0;
5114
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02005115 smp->data.u.str.len = strlen(smp->data.u.str.str);
Willy Tarreau7875d092012-09-10 08:20:03 +02005116 return 1;
5117#else
5118 return 0;
5119#endif
5120}
5121
David Sc1ad52e2014-04-08 18:48:47 -04005122static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02005123smp_fetch_ssl_fc_unique_id(const struct arg *args, struct sample *smp, const char *kw, void *private)
David Sc1ad52e2014-04-08 18:48:47 -04005124{
5125#if OPENSSL_VERSION_NUMBER > 0x0090800fL
Willy Tarreaue237fe12016-03-10 17:05:28 +01005126 struct connection *conn = objt_conn((kw[4] != 'b') ? smp->sess->origin :
5127 smp->strm ? smp->strm->si[1].end : NULL);
5128
David Sc1ad52e2014-04-08 18:48:47 -04005129 int finished_len;
David Sc1ad52e2014-04-08 18:48:47 -04005130 struct chunk *finished_trash;
David Sc1ad52e2014-04-08 18:48:47 -04005131
5132 smp->flags = 0;
David Sc1ad52e2014-04-08 18:48:47 -04005133 if (!conn || !conn->xprt_ctx || conn->xprt != &ssl_sock)
5134 return 0;
5135
5136 if (!(conn->flags & CO_FL_CONNECTED)) {
5137 smp->flags |= SMP_F_MAY_CHANGE;
5138 return 0;
5139 }
5140
5141 finished_trash = get_trash_chunk();
5142 if (!SSL_session_reused(conn->xprt_ctx))
5143 finished_len = SSL_get_peer_finished(conn->xprt_ctx, finished_trash->str, finished_trash->size);
5144 else
5145 finished_len = SSL_get_finished(conn->xprt_ctx, finished_trash->str, finished_trash->size);
5146
5147 if (!finished_len)
5148 return 0;
5149
Emeric Brunb73a9b02014-04-30 18:49:19 +02005150 finished_trash->len = finished_len;
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02005151 smp->data.u.str = *finished_trash;
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02005152 smp->data.type = SMP_T_BIN;
David Sc1ad52e2014-04-08 18:48:47 -04005153
5154 return 1;
5155#else
5156 return 0;
5157#endif
5158}
5159
Emeric Brun2525b6b2012-10-18 15:59:43 +02005160/* integer, returns the first verify error in CA chain of client certificate chain. */
Emeric Brunf282a812012-09-21 15:27:54 +02005161static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02005162smp_fetch_ssl_c_ca_err(const struct arg *args, struct sample *smp, const char *kw, void *private)
Emeric Brunf282a812012-09-21 15:27:54 +02005163{
Willy Tarreaub363a1f2013-10-01 10:45:07 +02005164 struct connection *conn;
5165
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02005166 conn = objt_conn(smp->sess->origin);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02005167 if (!conn || conn->xprt != &ssl_sock)
5168 return 0;
5169
5170 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brunf282a812012-09-21 15:27:54 +02005171 smp->flags = SMP_F_MAY_CHANGE;
5172 return 0;
5173 }
5174
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02005175 smp->data.type = SMP_T_SINT;
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02005176 smp->data.u.sint = (unsigned long long int)SSL_SOCK_ST_TO_CA_ERROR(conn->xprt_st);
Emeric Brunf282a812012-09-21 15:27:54 +02005177 smp->flags = 0;
5178
5179 return 1;
5180}
5181
Emeric Brun2525b6b2012-10-18 15:59:43 +02005182/* integer, returns the depth of the first verify error in CA chain of client certificate chain. */
Emeric Brunf282a812012-09-21 15:27:54 +02005183static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02005184smp_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 +02005185{
Willy Tarreaub363a1f2013-10-01 10:45:07 +02005186 struct connection *conn;
5187
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02005188 conn = objt_conn(smp->sess->origin);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02005189 if (!conn || conn->xprt != &ssl_sock)
Emeric Brunf282a812012-09-21 15:27:54 +02005190 return 0;
5191
Willy Tarreaub363a1f2013-10-01 10:45:07 +02005192 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brunf282a812012-09-21 15:27:54 +02005193 smp->flags = SMP_F_MAY_CHANGE;
5194 return 0;
5195 }
5196
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02005197 smp->data.type = SMP_T_SINT;
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02005198 smp->data.u.sint = (long long int)SSL_SOCK_ST_TO_CAEDEPTH(conn->xprt_st);
Emeric Brunf282a812012-09-21 15:27:54 +02005199 smp->flags = 0;
5200
5201 return 1;
5202}
5203
Emeric Brun2525b6b2012-10-18 15:59:43 +02005204/* integer, returns the first verify error on client certificate */
Emeric Brunf282a812012-09-21 15:27:54 +02005205static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02005206smp_fetch_ssl_c_err(const struct arg *args, struct sample *smp, const char *kw, void *private)
Emeric Brunf282a812012-09-21 15:27:54 +02005207{
Willy Tarreaub363a1f2013-10-01 10:45:07 +02005208 struct connection *conn;
5209
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02005210 conn = objt_conn(smp->sess->origin);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02005211 if (!conn || conn->xprt != &ssl_sock)
5212 return 0;
5213
5214 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brunf282a812012-09-21 15:27:54 +02005215 smp->flags = SMP_F_MAY_CHANGE;
5216 return 0;
5217 }
5218
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02005219 smp->data.type = SMP_T_SINT;
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02005220 smp->data.u.sint = (long long int)SSL_SOCK_ST_TO_CRTERROR(conn->xprt_st);
Emeric Brunf282a812012-09-21 15:27:54 +02005221 smp->flags = 0;
5222
5223 return 1;
5224}
5225
Emeric Brun2525b6b2012-10-18 15:59:43 +02005226/* integer, returns the verify result on client cert */
Emeric Brunbaf8ffb2012-09-21 15:27:20 +02005227static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02005228smp_fetch_ssl_c_verify(const struct arg *args, struct sample *smp, const char *kw, void *private)
Emeric Brunbaf8ffb2012-09-21 15:27:20 +02005229{
Willy Tarreaub363a1f2013-10-01 10:45:07 +02005230 struct connection *conn;
5231
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02005232 conn = objt_conn(smp->sess->origin);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02005233 if (!conn || conn->xprt != &ssl_sock)
5234 return 0;
5235
5236 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brunbaf8ffb2012-09-21 15:27:20 +02005237 smp->flags = SMP_F_MAY_CHANGE;
5238 return 0;
5239 }
5240
Willy Tarreaub363a1f2013-10-01 10:45:07 +02005241 if (!conn->xprt_ctx)
Emeric Brunbaf8ffb2012-09-21 15:27:20 +02005242 return 0;
5243
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02005244 smp->data.type = SMP_T_SINT;
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02005245 smp->data.u.sint = (long long int)SSL_get_verify_result(conn->xprt_ctx);
Emeric Brunbaf8ffb2012-09-21 15:27:20 +02005246 smp->flags = 0;
5247
5248 return 1;
5249}
5250
Emeric Brunfb510ea2012-10-05 12:00:26 +02005251/* parse the "ca-file" bind keyword */
5252static int bind_parse_ca_file(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
Emeric Brund94b3fe2012-09-20 18:23:56 +02005253{
5254 if (!*args[cur_arg + 1]) {
5255 if (err)
5256 memprintf(err, "'%s' : missing CAfile path", args[cur_arg]);
5257 return ERR_ALERT | ERR_FATAL;
5258 }
5259
Willy Tarreauef934602016-12-22 23:12:01 +01005260 if ((*args[cur_arg + 1] != '/') && global_ssl.ca_base)
5261 memprintf(&conf->ca_file, "%s/%s", global_ssl.ca_base, args[cur_arg + 1]);
Emeric Brunef42d922012-10-11 16:11:36 +02005262 else
5263 memprintf(&conf->ca_file, "%s", args[cur_arg + 1]);
Emeric Brunc8e8d122012-10-02 18:42:10 +02005264
Emeric Brund94b3fe2012-09-20 18:23:56 +02005265 return 0;
5266}
5267
Christopher Faulet31af49d2015-06-09 17:29:50 +02005268/* parse the "ca-sign-file" bind keyword */
5269static int bind_parse_ca_sign_file(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
5270{
5271 if (!*args[cur_arg + 1]) {
5272 if (err)
5273 memprintf(err, "'%s' : missing CAfile path", args[cur_arg]);
5274 return ERR_ALERT | ERR_FATAL;
5275 }
5276
Willy Tarreauef934602016-12-22 23:12:01 +01005277 if ((*args[cur_arg + 1] != '/') && global_ssl.ca_base)
5278 memprintf(&conf->ca_sign_file, "%s/%s", global_ssl.ca_base, args[cur_arg + 1]);
Christopher Faulet31af49d2015-06-09 17:29:50 +02005279 else
5280 memprintf(&conf->ca_sign_file, "%s", args[cur_arg + 1]);
5281
5282 return 0;
5283}
5284
Bertrand Jacquinff13c062016-11-13 16:37:11 +00005285/* parse the "ca-sign-pass" bind keyword */
Christopher Faulet31af49d2015-06-09 17:29:50 +02005286static int bind_parse_ca_sign_pass(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
5287{
5288 if (!*args[cur_arg + 1]) {
5289 if (err)
5290 memprintf(err, "'%s' : missing CAkey password", args[cur_arg]);
5291 return ERR_ALERT | ERR_FATAL;
5292 }
5293 memprintf(&conf->ca_sign_pass, "%s", args[cur_arg + 1]);
5294 return 0;
5295}
5296
Willy Tarreau79eeafa2012-09-14 07:53:05 +02005297/* parse the "ciphers" bind keyword */
Willy Tarreau4348fad2012-09-20 16:48:07 +02005298static int bind_parse_ciphers(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
Willy Tarreau79eeafa2012-09-14 07:53:05 +02005299{
5300 if (!*args[cur_arg + 1]) {
Willy Tarreaueb6cead2012-09-20 19:43:14 +02005301 memprintf(err, "'%s' : missing cipher suite", args[cur_arg]);
Willy Tarreau79eeafa2012-09-14 07:53:05 +02005302 return ERR_ALERT | ERR_FATAL;
5303 }
5304
Emeric Brun76d88952012-10-05 15:47:31 +02005305 free(conf->ciphers);
Willy Tarreau4348fad2012-09-20 16:48:07 +02005306 conf->ciphers = strdup(args[cur_arg + 1]);
Willy Tarreau79eeafa2012-09-14 07:53:05 +02005307 return 0;
5308}
5309
5310/* parse the "crt" bind keyword */
Willy Tarreau4348fad2012-09-20 16:48:07 +02005311static 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 +02005312{
Willy Tarreau38011032013-08-13 16:59:39 +02005313 char path[MAXPATHLEN];
Willy Tarreaub75d6922014-04-14 18:05:41 +02005314
Willy Tarreau79eeafa2012-09-14 07:53:05 +02005315 if (!*args[cur_arg + 1]) {
Willy Tarreaueb6cead2012-09-20 19:43:14 +02005316 memprintf(err, "'%s' : missing certificate location", args[cur_arg]);
Willy Tarreau79eeafa2012-09-14 07:53:05 +02005317 return ERR_ALERT | ERR_FATAL;
5318 }
5319
Willy Tarreauef934602016-12-22 23:12:01 +01005320 if ((*args[cur_arg + 1] != '/' ) && global_ssl.crt_base) {
5321 if ((strlen(global_ssl.crt_base) + 1 + strlen(args[cur_arg + 1]) + 1) > MAXPATHLEN) {
Emeric Brunc8e8d122012-10-02 18:42:10 +02005322 memprintf(err, "'%s' : path too long", args[cur_arg]);
5323 return ERR_ALERT | ERR_FATAL;
5324 }
Willy Tarreauef934602016-12-22 23:12:01 +01005325 snprintf(path, sizeof(path), "%s/%s", global_ssl.crt_base, args[cur_arg + 1]);
Willy Tarreau03209342016-12-22 17:08:28 +01005326 if (ssl_sock_load_cert(path, conf, err) > 0)
Emeric Brunc8e8d122012-10-02 18:42:10 +02005327 return ERR_ALERT | ERR_FATAL;
5328
5329 return 0;
5330 }
5331
Willy Tarreau03209342016-12-22 17:08:28 +01005332 if (ssl_sock_load_cert(args[cur_arg + 1], conf, err) > 0)
Willy Tarreau79eeafa2012-09-14 07:53:05 +02005333 return ERR_ALERT | ERR_FATAL;
Emeric Brund94b3fe2012-09-20 18:23:56 +02005334
5335 return 0;
5336}
5337
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01005338/* parse the "crt-list" bind keyword */
5339static int bind_parse_crt_list(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
5340{
5341 if (!*args[cur_arg + 1]) {
5342 memprintf(err, "'%s' : missing certificate location", args[cur_arg]);
5343 return ERR_ALERT | ERR_FATAL;
5344 }
5345
Willy Tarreau03209342016-12-22 17:08:28 +01005346 if (ssl_sock_load_cert_list_file(args[cur_arg + 1], conf, err) > 0) {
Willy Tarreauad1731d2013-04-02 17:35:58 +02005347 memprintf(err, "'%s' : %s", args[cur_arg], *err);
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01005348 return ERR_ALERT | ERR_FATAL;
Willy Tarreauad1731d2013-04-02 17:35:58 +02005349 }
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01005350
5351 return 0;
5352}
5353
Emeric Brunfb510ea2012-10-05 12:00:26 +02005354/* parse the "crl-file" bind keyword */
5355static int bind_parse_crl_file(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
Emeric Brund94b3fe2012-09-20 18:23:56 +02005356{
Emeric Brun051cdab2012-10-02 19:25:50 +02005357#ifndef X509_V_FLAG_CRL_CHECK
5358 if (err)
5359 memprintf(err, "'%s' : library does not support CRL verify", args[cur_arg]);
5360 return ERR_ALERT | ERR_FATAL;
5361#else
Emeric Brund94b3fe2012-09-20 18:23:56 +02005362 if (!*args[cur_arg + 1]) {
5363 if (err)
5364 memprintf(err, "'%s' : missing CRLfile path", args[cur_arg]);
5365 return ERR_ALERT | ERR_FATAL;
5366 }
Emeric Brun2b58d042012-09-20 17:10:03 +02005367
Willy Tarreauef934602016-12-22 23:12:01 +01005368 if ((*args[cur_arg + 1] != '/') && global_ssl.ca_base)
5369 memprintf(&conf->crl_file, "%s/%s", global_ssl.ca_base, args[cur_arg + 1]);
Emeric Brunef42d922012-10-11 16:11:36 +02005370 else
5371 memprintf(&conf->crl_file, "%s", args[cur_arg + 1]);
Emeric Brunc8e8d122012-10-02 18:42:10 +02005372
Emeric Brun2b58d042012-09-20 17:10:03 +02005373 return 0;
Emeric Brun051cdab2012-10-02 19:25:50 +02005374#endif
Emeric Brun2b58d042012-09-20 17:10:03 +02005375}
5376
Bertrand Jacquinff13c062016-11-13 16:37:11 +00005377/* parse the "ecdhe" bind keyword keyword */
Emeric Brun2b58d042012-09-20 17:10:03 +02005378static int bind_parse_ecdhe(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
5379{
5380#if OPENSSL_VERSION_NUMBER < 0x0090800fL
5381 if (err)
5382 memprintf(err, "'%s' : library does not support elliptic curve Diffie-Hellman (too old)", args[cur_arg]);
5383 return ERR_ALERT | ERR_FATAL;
5384#elif defined(OPENSSL_NO_ECDH)
5385 if (err)
5386 memprintf(err, "'%s' : library does not support elliptic curve Diffie-Hellman (disabled via OPENSSL_NO_ECDH)", args[cur_arg]);
5387 return ERR_ALERT | ERR_FATAL;
5388#else
5389 if (!*args[cur_arg + 1]) {
5390 if (err)
5391 memprintf(err, "'%s' : missing named curve", args[cur_arg]);
5392 return ERR_ALERT | ERR_FATAL;
5393 }
5394
5395 conf->ecdhe = strdup(args[cur_arg + 1]);
Willy Tarreau79eeafa2012-09-14 07:53:05 +02005396
5397 return 0;
Emeric Brun2b58d042012-09-20 17:10:03 +02005398#endif
Willy Tarreau79eeafa2012-09-14 07:53:05 +02005399}
5400
Bertrand Jacquinff13c062016-11-13 16:37:11 +00005401/* parse the "crt-ignore-err" and "ca-ignore-err" bind keywords */
Emeric Brun81c00f02012-09-21 14:31:21 +02005402static int bind_parse_ignore_err(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
5403{
5404 int code;
5405 char *p = args[cur_arg + 1];
5406 unsigned long long *ignerr = &conf->crt_ignerr;
5407
5408 if (!*p) {
5409 if (err)
5410 memprintf(err, "'%s' : missing error IDs list", args[cur_arg]);
5411 return ERR_ALERT | ERR_FATAL;
5412 }
5413
5414 if (strcmp(args[cur_arg], "ca-ignore-err") == 0)
5415 ignerr = &conf->ca_ignerr;
5416
5417 if (strcmp(p, "all") == 0) {
5418 *ignerr = ~0ULL;
5419 return 0;
5420 }
5421
5422 while (p) {
5423 code = atoi(p);
5424 if ((code <= 0) || (code > 63)) {
5425 if (err)
5426 memprintf(err, "'%s' : ID '%d' out of range (1..63) in error IDs list '%s'",
5427 args[cur_arg], code, args[cur_arg + 1]);
5428 return ERR_ALERT | ERR_FATAL;
5429 }
5430 *ignerr |= 1ULL << code;
5431 p = strchr(p, ',');
5432 if (p)
5433 p++;
5434 }
5435
Emeric Brun2cb7ae52012-10-05 14:14:21 +02005436 return 0;
5437}
5438
5439/* parse the "force-sslv3" bind keyword */
5440static int bind_parse_force_sslv3(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
5441{
5442 conf->ssl_options |= BC_SSL_O_USE_SSLV3;
5443 return 0;
5444}
5445
5446/* parse the "force-tlsv10" bind keyword */
5447static int bind_parse_force_tlsv10(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
5448{
5449 conf->ssl_options |= BC_SSL_O_USE_TLSV10;
Emeric Brun2d0c4822012-10-02 13:45:20 +02005450 return 0;
5451}
5452
Emeric Brun2cb7ae52012-10-05 14:14:21 +02005453/* parse the "force-tlsv11" bind keyword */
5454static int bind_parse_force_tlsv11(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
5455{
5456#if SSL_OP_NO_TLSv1_1
5457 conf->ssl_options |= BC_SSL_O_USE_TLSV11;
5458 return 0;
5459#else
5460 if (err)
5461 memprintf(err, "'%s' : library does not support protocol TLSv1.1", args[cur_arg]);
5462 return ERR_ALERT | ERR_FATAL;
5463#endif
5464}
5465
5466/* parse the "force-tlsv12" bind keyword */
5467static int bind_parse_force_tlsv12(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
5468{
5469#if SSL_OP_NO_TLSv1_2
5470 conf->ssl_options |= BC_SSL_O_USE_TLSV12;
5471 return 0;
5472#else
5473 if (err)
5474 memprintf(err, "'%s' : library does not support protocol TLSv1.2", args[cur_arg]);
5475 return ERR_ALERT | ERR_FATAL;
5476#endif
5477}
5478
5479
Emeric Brun2d0c4822012-10-02 13:45:20 +02005480/* parse the "no-tls-tickets" bind keyword */
5481static int bind_parse_no_tls_tickets(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
5482{
Emeric Brun89675492012-10-05 13:48:26 +02005483 conf->ssl_options |= BC_SSL_O_NO_TLS_TICKETS;
Emeric Brun81c00f02012-09-21 14:31:21 +02005484 return 0;
5485}
5486
Emeric Brun2d0c4822012-10-02 13:45:20 +02005487
Emeric Brun9b3009b2012-10-05 11:55:06 +02005488/* parse the "no-sslv3" bind keyword */
5489static int bind_parse_no_sslv3(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
Willy Tarreau79eeafa2012-09-14 07:53:05 +02005490{
Emeric Brun89675492012-10-05 13:48:26 +02005491 conf->ssl_options |= BC_SSL_O_NO_SSLV3;
Willy Tarreau79eeafa2012-09-14 07:53:05 +02005492 return 0;
5493}
5494
Emeric Brun9b3009b2012-10-05 11:55:06 +02005495/* parse the "no-tlsv10" bind keyword */
5496static int bind_parse_no_tlsv10(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
Emeric Brunc0ff4922012-09-28 19:37:02 +02005497{
Emeric Brun89675492012-10-05 13:48:26 +02005498 conf->ssl_options |= BC_SSL_O_NO_TLSV10;
Emeric Brunc0ff4922012-09-28 19:37:02 +02005499 return 0;
5500}
5501
Emeric Brun9b3009b2012-10-05 11:55:06 +02005502/* parse the "no-tlsv11" bind keyword */
5503static int bind_parse_no_tlsv11(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
Emeric Brunc0ff4922012-09-28 19:37:02 +02005504{
Emeric Brun89675492012-10-05 13:48:26 +02005505 conf->ssl_options |= BC_SSL_O_NO_TLSV11;
Emeric Brunc0ff4922012-09-28 19:37:02 +02005506 return 0;
5507}
5508
Emeric Brun9b3009b2012-10-05 11:55:06 +02005509/* parse the "no-tlsv12" bind keyword */
5510static int bind_parse_no_tlsv12(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
Willy Tarreau79eeafa2012-09-14 07:53:05 +02005511{
Emeric Brun89675492012-10-05 13:48:26 +02005512 conf->ssl_options |= BC_SSL_O_NO_TLSV12;
Willy Tarreau79eeafa2012-09-14 07:53:05 +02005513 return 0;
5514}
5515
Willy Tarreau6c9a3d52012-10-18 18:57:14 +02005516/* parse the "npn" bind keyword */
5517static int bind_parse_npn(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
5518{
5519#ifdef OPENSSL_NPN_NEGOTIATED
5520 char *p1, *p2;
5521
5522 if (!*args[cur_arg + 1]) {
5523 memprintf(err, "'%s' : missing the comma-delimited NPN protocol suite", args[cur_arg]);
5524 return ERR_ALERT | ERR_FATAL;
5525 }
5526
5527 free(conf->npn_str);
5528
Willy Tarreau3724da12016-02-12 17:11:12 +01005529 /* the NPN string is built as a suite of (<len> <name>)*,
5530 * so we reuse each comma to store the next <len> and need
5531 * one more for the end of the string.
5532 */
Willy Tarreau6c9a3d52012-10-18 18:57:14 +02005533 conf->npn_len = strlen(args[cur_arg + 1]) + 1;
Willy Tarreau3724da12016-02-12 17:11:12 +01005534 conf->npn_str = calloc(1, conf->npn_len + 1);
Willy Tarreau6c9a3d52012-10-18 18:57:14 +02005535 memcpy(conf->npn_str + 1, args[cur_arg + 1], conf->npn_len);
5536
5537 /* replace commas with the name length */
5538 p1 = conf->npn_str;
5539 p2 = p1 + 1;
5540 while (1) {
5541 p2 = memchr(p1 + 1, ',', conf->npn_str + conf->npn_len - (p1 + 1));
5542 if (!p2)
5543 p2 = p1 + 1 + strlen(p1 + 1);
5544
5545 if (p2 - (p1 + 1) > 255) {
5546 *p2 = '\0';
5547 memprintf(err, "'%s' : NPN protocol name too long : '%s'", args[cur_arg], p1 + 1);
5548 return ERR_ALERT | ERR_FATAL;
5549 }
5550
5551 *p1 = p2 - (p1 + 1);
5552 p1 = p2;
5553
5554 if (!*p2)
5555 break;
5556
5557 *(p2++) = '\0';
5558 }
5559 return 0;
5560#else
5561 if (err)
5562 memprintf(err, "'%s' : library does not support TLS NPN extension", args[cur_arg]);
5563 return ERR_ALERT | ERR_FATAL;
5564#endif
5565}
5566
Willy Tarreauab861d32013-04-02 02:30:41 +02005567/* parse the "alpn" bind keyword */
5568static int bind_parse_alpn(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
5569{
Dirkjan Bussink48f1c4e2014-02-13 12:29:42 +01005570#ifdef TLSEXT_TYPE_application_layer_protocol_negotiation
Willy Tarreauab861d32013-04-02 02:30:41 +02005571 char *p1, *p2;
5572
5573 if (!*args[cur_arg + 1]) {
5574 memprintf(err, "'%s' : missing the comma-delimited ALPN protocol suite", args[cur_arg]);
5575 return ERR_ALERT | ERR_FATAL;
5576 }
5577
5578 free(conf->alpn_str);
5579
Marcoen Hirschbergbef60912016-02-12 17:05:24 +01005580 /* the ALPN string is built as a suite of (<len> <name>)*,
5581 * so we reuse each comma to store the next <len> and need
5582 * one more for the end of the string.
5583 */
Willy Tarreauab861d32013-04-02 02:30:41 +02005584 conf->alpn_len = strlen(args[cur_arg + 1]) + 1;
Marcoen Hirschbergbef60912016-02-12 17:05:24 +01005585 conf->alpn_str = calloc(1, conf->alpn_len + 1);
Willy Tarreauab861d32013-04-02 02:30:41 +02005586 memcpy(conf->alpn_str + 1, args[cur_arg + 1], conf->alpn_len);
5587
5588 /* replace commas with the name length */
5589 p1 = conf->alpn_str;
5590 p2 = p1 + 1;
5591 while (1) {
5592 p2 = memchr(p1 + 1, ',', conf->alpn_str + conf->alpn_len - (p1 + 1));
5593 if (!p2)
5594 p2 = p1 + 1 + strlen(p1 + 1);
5595
5596 if (p2 - (p1 + 1) > 255) {
5597 *p2 = '\0';
5598 memprintf(err, "'%s' : ALPN protocol name too long : '%s'", args[cur_arg], p1 + 1);
5599 return ERR_ALERT | ERR_FATAL;
5600 }
5601
5602 *p1 = p2 - (p1 + 1);
5603 p1 = p2;
5604
5605 if (!*p2)
5606 break;
5607
5608 *(p2++) = '\0';
5609 }
5610 return 0;
5611#else
5612 if (err)
5613 memprintf(err, "'%s' : library does not support TLS ALPN extension", args[cur_arg]);
5614 return ERR_ALERT | ERR_FATAL;
5615#endif
5616}
5617
Willy Tarreau79eeafa2012-09-14 07:53:05 +02005618/* parse the "ssl" bind keyword */
Willy Tarreau4348fad2012-09-20 16:48:07 +02005619static 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 +02005620{
Willy Tarreau71a8c7c2016-12-21 22:04:54 +01005621 conf->xprt = &ssl_sock;
Willy Tarreau4348fad2012-09-20 16:48:07 +02005622 conf->is_ssl = 1;
Emeric Brun76d88952012-10-05 15:47:31 +02005623
Willy Tarreauef934602016-12-22 23:12:01 +01005624 if (global_ssl.listen_default_ciphers && !conf->ciphers)
5625 conf->ciphers = strdup(global_ssl.listen_default_ciphers);
5626 conf->ssl_options |= global_ssl.listen_default_ssloptions;
Emeric Brun76d88952012-10-05 15:47:31 +02005627
Willy Tarreau79eeafa2012-09-14 07:53:05 +02005628 return 0;
5629}
5630
Christopher Faulet31af49d2015-06-09 17:29:50 +02005631/* parse the "generate-certificates" bind keyword */
5632static int bind_parse_generate_certs(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
5633{
5634#ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME
5635 conf->generate_certs = 1;
5636#else
5637 memprintf(err, "%sthis version of openssl cannot generate SSL certificates.\n",
5638 err && *err ? *err : "");
5639#endif
5640 return 0;
5641}
5642
Emmanuel Hocdet65623372013-01-24 17:17:15 +01005643/* parse the "strict-sni" bind keyword */
5644static int bind_parse_strict_sni(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
5645{
5646 conf->strict_sni = 1;
5647 return 0;
Nenad Merdanovic05552d42015-02-27 19:56:49 +01005648}
5649
5650/* parse the "tls-ticket-keys" bind keyword */
5651static int bind_parse_tls_ticket_keys(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
5652{
5653#if (defined SSL_CTRL_SET_TLSEXT_TICKET_KEY_CB && TLS_TICKETS_NO > 0)
5654 FILE *f;
5655 int i = 0;
5656 char thisline[LINESIZE];
Nenad Merdanovic146defa2015-05-09 08:46:00 +02005657 struct tls_keys_ref *keys_ref;
Nenad Merdanovic05552d42015-02-27 19:56:49 +01005658
5659 if (!*args[cur_arg + 1]) {
5660 if (err)
5661 memprintf(err, "'%s' : missing TLS ticket keys file path", args[cur_arg]);
5662 return ERR_ALERT | ERR_FATAL;
5663 }
5664
Nenad Merdanovic200b0fa2015-05-09 08:46:01 +02005665 keys_ref = tlskeys_ref_lookup(args[cur_arg + 1]);
5666 if(keys_ref) {
5667 conf->keys_ref = keys_ref;
5668 return 0;
5669 }
5670
Vincent Bernat02779b62016-04-03 13:48:43 +02005671 keys_ref = malloc(sizeof(*keys_ref));
Nenad Merdanovic146defa2015-05-09 08:46:00 +02005672 keys_ref->tlskeys = malloc(TLS_TICKETS_NO * sizeof(struct tls_sess_key));
Nenad Merdanovic05552d42015-02-27 19:56:49 +01005673
5674 if ((f = fopen(args[cur_arg + 1], "r")) == NULL) {
5675 if (err)
5676 memprintf(err, "'%s' : unable to load ssl tickets keys file", args[cur_arg+1]);
5677 return ERR_ALERT | ERR_FATAL;
5678 }
5679
Nenad Merdanovic146defa2015-05-09 08:46:00 +02005680 keys_ref->filename = strdup(args[cur_arg + 1]);
5681
Nenad Merdanovic05552d42015-02-27 19:56:49 +01005682 while (fgets(thisline, sizeof(thisline), f) != NULL) {
5683 int len = strlen(thisline);
5684 /* Strip newline characters from the end */
5685 if(thisline[len - 1] == '\n')
5686 thisline[--len] = 0;
5687
5688 if(thisline[len - 1] == '\r')
5689 thisline[--len] = 0;
5690
Nenad Merdanovic146defa2015-05-09 08:46:00 +02005691 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 +01005692 if (err)
5693 memprintf(err, "'%s' : unable to decode base64 key on line %d", args[cur_arg+1], i + 1);
mildis16aa0152016-06-22 17:46:29 +02005694 fclose(f);
Nenad Merdanovic05552d42015-02-27 19:56:49 +01005695 return ERR_ALERT | ERR_FATAL;
5696 }
5697 i++;
5698 }
5699
5700 if (i < TLS_TICKETS_NO) {
5701 if (err)
5702 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 +02005703 fclose(f);
Nenad Merdanovic05552d42015-02-27 19:56:49 +01005704 return ERR_ALERT | ERR_FATAL;
5705 }
5706
5707 fclose(f);
5708
5709 /* Use penultimate key for encryption, handle when TLS_TICKETS_NO = 1 */
Nenad Merdanovic17891152016-03-25 22:16:57 +01005710 i -= 2;
5711 keys_ref->tls_ticket_enc_index = i < 0 ? 0 : i % TLS_TICKETS_NO;
Nenad Merdanovic200b0fa2015-05-09 08:46:01 +02005712 keys_ref->unique_id = -1;
Nenad Merdanovic146defa2015-05-09 08:46:00 +02005713 conf->keys_ref = keys_ref;
Nenad Merdanovic05552d42015-02-27 19:56:49 +01005714
Nenad Merdanovic200b0fa2015-05-09 08:46:01 +02005715 LIST_ADD(&tlskeys_reference, &keys_ref->list);
5716
Nenad Merdanovic05552d42015-02-27 19:56:49 +01005717 return 0;
5718#else
5719 if (err)
5720 memprintf(err, "'%s' : TLS ticket callback extension not supported", args[cur_arg]);
5721 return ERR_ALERT | ERR_FATAL;
5722#endif /* SSL_CTRL_SET_TLSEXT_TICKET_KEY_CB */
Emmanuel Hocdet65623372013-01-24 17:17:15 +01005723}
5724
Emeric Brund94b3fe2012-09-20 18:23:56 +02005725/* parse the "verify" bind keyword */
5726static int bind_parse_verify(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
5727{
5728 if (!*args[cur_arg + 1]) {
5729 if (err)
5730 memprintf(err, "'%s' : missing verify method", args[cur_arg]);
5731 return ERR_ALERT | ERR_FATAL;
5732 }
5733
5734 if (strcmp(args[cur_arg + 1], "none") == 0)
Emeric Brun850efd52014-01-29 12:24:34 +01005735 conf->verify = SSL_SOCK_VERIFY_NONE;
Emeric Brund94b3fe2012-09-20 18:23:56 +02005736 else if (strcmp(args[cur_arg + 1], "optional") == 0)
Emeric Brun850efd52014-01-29 12:24:34 +01005737 conf->verify = SSL_SOCK_VERIFY_OPTIONAL;
Emeric Brund94b3fe2012-09-20 18:23:56 +02005738 else if (strcmp(args[cur_arg + 1], "required") == 0)
Emeric Brun850efd52014-01-29 12:24:34 +01005739 conf->verify = SSL_SOCK_VERIFY_REQUIRED;
Emeric Brund94b3fe2012-09-20 18:23:56 +02005740 else {
5741 if (err)
5742 memprintf(err, "'%s' : unknown verify method '%s', only 'none', 'optional', and 'required' are supported\n",
5743 args[cur_arg], args[cur_arg + 1]);
5744 return ERR_ALERT | ERR_FATAL;
5745 }
5746
5747 return 0;
5748}
5749
Willy Tarreau92faadf2012-10-10 23:04:25 +02005750/************** "server" keywords ****************/
5751
Emeric Brunef42d922012-10-11 16:11:36 +02005752/* parse the "ca-file" server keyword */
5753static int srv_parse_ca_file(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
5754{
5755 if (!*args[*cur_arg + 1]) {
5756 if (err)
5757 memprintf(err, "'%s' : missing CAfile path", args[*cur_arg]);
5758 return ERR_ALERT | ERR_FATAL;
5759 }
5760
Willy Tarreauef934602016-12-22 23:12:01 +01005761 if ((*args[*cur_arg + 1] != '/') && global_ssl.ca_base)
5762 memprintf(&newsrv->ssl_ctx.ca_file, "%s/%s", global_ssl.ca_base, args[*cur_arg + 1]);
Emeric Brunef42d922012-10-11 16:11:36 +02005763 else
5764 memprintf(&newsrv->ssl_ctx.ca_file, "%s", args[*cur_arg + 1]);
5765
5766 return 0;
5767}
5768
Willy Tarreau92faadf2012-10-10 23:04:25 +02005769/* parse the "check-ssl" server keyword */
5770static int srv_parse_check_ssl(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
5771{
5772 newsrv->check.use_ssl = 1;
Willy Tarreauef934602016-12-22 23:12:01 +01005773 if (global_ssl.connect_default_ciphers && !newsrv->ssl_ctx.ciphers)
5774 newsrv->ssl_ctx.ciphers = strdup(global_ssl.connect_default_ciphers);
5775 newsrv->ssl_ctx.options |= global_ssl.connect_default_ssloptions;
Willy Tarreau92faadf2012-10-10 23:04:25 +02005776 return 0;
5777}
5778
5779/* parse the "ciphers" server keyword */
5780static int srv_parse_ciphers(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
5781{
5782 if (!*args[*cur_arg + 1]) {
5783 memprintf(err, "'%s' : missing cipher suite", args[*cur_arg]);
5784 return ERR_ALERT | ERR_FATAL;
5785 }
5786
5787 free(newsrv->ssl_ctx.ciphers);
5788 newsrv->ssl_ctx.ciphers = strdup(args[*cur_arg + 1]);
5789 return 0;
5790}
5791
Emeric Brunef42d922012-10-11 16:11:36 +02005792/* parse the "crl-file" server keyword */
5793static int srv_parse_crl_file(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
5794{
5795#ifndef X509_V_FLAG_CRL_CHECK
5796 if (err)
5797 memprintf(err, "'%s' : library does not support CRL verify", args[*cur_arg]);
5798 return ERR_ALERT | ERR_FATAL;
5799#else
5800 if (!*args[*cur_arg + 1]) {
5801 if (err)
5802 memprintf(err, "'%s' : missing CRLfile path", args[*cur_arg]);
5803 return ERR_ALERT | ERR_FATAL;
5804 }
5805
Willy Tarreauef934602016-12-22 23:12:01 +01005806 if ((*args[*cur_arg + 1] != '/') && global_ssl.ca_base)
5807 memprintf(&newsrv->ssl_ctx.crl_file, "%s/%s", global_ssl.ca_base, args[*cur_arg + 1]);
Emeric Brunef42d922012-10-11 16:11:36 +02005808 else
5809 memprintf(&newsrv->ssl_ctx.crl_file, "%s", args[*cur_arg + 1]);
5810
5811 return 0;
5812#endif
5813}
5814
Emeric Bruna7aa3092012-10-26 12:58:00 +02005815/* parse the "crt" server keyword */
5816static int srv_parse_crt(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
5817{
5818 if (!*args[*cur_arg + 1]) {
5819 if (err)
5820 memprintf(err, "'%s' : missing certificate file path", args[*cur_arg]);
5821 return ERR_ALERT | ERR_FATAL;
5822 }
5823
Willy Tarreauef934602016-12-22 23:12:01 +01005824 if ((*args[*cur_arg + 1] != '/') && global_ssl.crt_base)
5825 memprintf(&newsrv->ssl_ctx.client_crt, "%s/%s", global_ssl.ca_base, args[*cur_arg + 1]);
Emeric Bruna7aa3092012-10-26 12:58:00 +02005826 else
5827 memprintf(&newsrv->ssl_ctx.client_crt, "%s", args[*cur_arg + 1]);
5828
5829 return 0;
5830}
Emeric Brunef42d922012-10-11 16:11:36 +02005831
Willy Tarreau92faadf2012-10-10 23:04:25 +02005832/* parse the "force-sslv3" server keyword */
5833static int srv_parse_force_sslv3(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
5834{
5835 newsrv->ssl_ctx.options |= SRV_SSL_O_USE_SSLV3;
5836 return 0;
5837}
5838
5839/* parse the "force-tlsv10" server keyword */
5840static int srv_parse_force_tlsv10(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
5841{
5842 newsrv->ssl_ctx.options |= SRV_SSL_O_USE_TLSV10;
5843 return 0;
5844}
5845
5846/* parse the "force-tlsv11" server keyword */
5847static int srv_parse_force_tlsv11(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
5848{
5849#if SSL_OP_NO_TLSv1_1
5850 newsrv->ssl_ctx.options |= SRV_SSL_O_USE_TLSV11;
5851 return 0;
5852#else
5853 if (err)
5854 memprintf(err, "'%s' : library does not support protocol TLSv1.1", args[*cur_arg]);
5855 return ERR_ALERT | ERR_FATAL;
5856#endif
5857}
5858
5859/* parse the "force-tlsv12" server keyword */
5860static int srv_parse_force_tlsv12(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
5861{
5862#if SSL_OP_NO_TLSv1_2
5863 newsrv->ssl_ctx.options |= SRV_SSL_O_USE_TLSV12;
5864 return 0;
5865#else
5866 if (err)
5867 memprintf(err, "'%s' : library does not support protocol TLSv1.2", args[*cur_arg]);
5868 return ERR_ALERT | ERR_FATAL;
5869#endif
5870}
5871
Willy Tarreau2a3fb1c2015-02-05 16:47:07 +01005872/* parse the "no-ssl-reuse" server keyword */
5873static int srv_parse_no_ssl_reuse(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
5874{
5875 newsrv->ssl_ctx.options |= SRV_SSL_O_NO_REUSE;
5876 return 0;
5877}
5878
Willy Tarreau92faadf2012-10-10 23:04:25 +02005879/* parse the "no-sslv3" server keyword */
5880static int srv_parse_no_sslv3(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
5881{
5882 newsrv->ssl_ctx.options |= SRV_SSL_O_NO_SSLV3;
5883 return 0;
5884}
5885
5886/* parse the "no-tlsv10" server keyword */
5887static int srv_parse_no_tlsv10(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
5888{
5889 newsrv->ssl_ctx.options |= SRV_SSL_O_NO_TLSV10;
5890 return 0;
5891}
5892
5893/* parse the "no-tlsv11" server keyword */
5894static int srv_parse_no_tlsv11(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
5895{
5896 newsrv->ssl_ctx.options |= SRV_SSL_O_NO_TLSV11;
5897 return 0;
5898}
5899
5900/* parse the "no-tlsv12" server keyword */
5901static int srv_parse_no_tlsv12(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
5902{
5903 newsrv->ssl_ctx.options |= SRV_SSL_O_NO_TLSV12;
5904 return 0;
5905}
5906
Emeric Brunf9c5c472012-10-11 15:28:34 +02005907/* parse the "no-tls-tickets" server keyword */
5908static int srv_parse_no_tls_tickets(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
5909{
5910 newsrv->ssl_ctx.options |= SRV_SSL_O_NO_TLS_TICKETS;
5911 return 0;
5912}
David Safb76832014-05-08 23:42:08 -04005913/* parse the "send-proxy-v2-ssl" server keyword */
5914static int srv_parse_send_proxy_ssl(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
5915{
5916 newsrv->pp_opts |= SRV_PP_V2;
5917 newsrv->pp_opts |= SRV_PP_V2_SSL;
5918 return 0;
5919}
5920
5921/* parse the "send-proxy-v2-ssl-cn" server keyword */
5922static int srv_parse_send_proxy_cn(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
5923{
5924 newsrv->pp_opts |= SRV_PP_V2;
5925 newsrv->pp_opts |= SRV_PP_V2_SSL;
5926 newsrv->pp_opts |= SRV_PP_V2_SSL_CN;
5927 return 0;
5928}
Emeric Brunf9c5c472012-10-11 15:28:34 +02005929
Willy Tarreau732eac42015-07-09 11:40:25 +02005930/* parse the "sni" server keyword */
5931static int srv_parse_sni(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
5932{
5933#ifndef SSL_CTRL_SET_TLSEXT_HOSTNAME
5934 memprintf(err, "'%s' : the current SSL library doesn't support the SNI TLS extension", args[*cur_arg]);
5935 return ERR_ALERT | ERR_FATAL;
5936#else
Cyril Bonté23d19d62016-03-07 22:13:22 +01005937 int idx;
Willy Tarreau732eac42015-07-09 11:40:25 +02005938 struct sample_expr *expr;
5939
5940 if (!*args[*cur_arg + 1]) {
5941 memprintf(err, "'%s' : missing sni expression", args[*cur_arg]);
5942 return ERR_ALERT | ERR_FATAL;
5943 }
5944
Cyril Bonté23d19d62016-03-07 22:13:22 +01005945 idx = (*cur_arg) + 1;
Willy Tarreau732eac42015-07-09 11:40:25 +02005946 proxy->conf.args.ctx = ARGC_SRV;
5947
Cyril Bonté23d19d62016-03-07 22:13:22 +01005948 expr = sample_parse_expr((char **)args, &idx, px->conf.file, px->conf.line, err, &proxy->conf.args);
Willy Tarreau732eac42015-07-09 11:40:25 +02005949 if (!expr) {
5950 memprintf(err, "error detected while parsing sni expression : %s", *err);
5951 return ERR_ALERT | ERR_FATAL;
5952 }
5953
5954 if (!(expr->fetch->val & SMP_VAL_BE_SRV_CON)) {
5955 memprintf(err, "error detected while parsing sni expression : "
5956 " fetch method '%s' extracts information from '%s', none of which is available here.\n",
Cyril Bonté23d19d62016-03-07 22:13:22 +01005957 args[idx-1], sample_src_names(expr->fetch->use));
Willy Tarreau732eac42015-07-09 11:40:25 +02005958 return ERR_ALERT | ERR_FATAL;
5959 }
5960
5961 px->http_needed |= !!(expr->fetch->use & SMP_USE_HTTP_ANY);
5962 newsrv->ssl_ctx.sni = expr;
5963 return 0;
5964#endif
5965}
5966
Willy Tarreau92faadf2012-10-10 23:04:25 +02005967/* parse the "ssl" server keyword */
5968static int srv_parse_ssl(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
5969{
5970 newsrv->use_ssl = 1;
Willy Tarreauef934602016-12-22 23:12:01 +01005971 if (global_ssl.connect_default_ciphers && !newsrv->ssl_ctx.ciphers)
5972 newsrv->ssl_ctx.ciphers = strdup(global_ssl.connect_default_ciphers);
Willy Tarreau92faadf2012-10-10 23:04:25 +02005973 return 0;
5974}
5975
Emeric Brunef42d922012-10-11 16:11:36 +02005976/* parse the "verify" server keyword */
5977static int srv_parse_verify(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
5978{
5979 if (!*args[*cur_arg + 1]) {
5980 if (err)
5981 memprintf(err, "'%s' : missing verify method", args[*cur_arg]);
5982 return ERR_ALERT | ERR_FATAL;
5983 }
5984
5985 if (strcmp(args[*cur_arg + 1], "none") == 0)
Emeric Brun850efd52014-01-29 12:24:34 +01005986 newsrv->ssl_ctx.verify = SSL_SOCK_VERIFY_NONE;
Emeric Brunef42d922012-10-11 16:11:36 +02005987 else if (strcmp(args[*cur_arg + 1], "required") == 0)
Emeric Brun850efd52014-01-29 12:24:34 +01005988 newsrv->ssl_ctx.verify = SSL_SOCK_VERIFY_REQUIRED;
Emeric Brunef42d922012-10-11 16:11:36 +02005989 else {
5990 if (err)
5991 memprintf(err, "'%s' : unknown verify method '%s', only 'none' and 'required' are supported\n",
5992 args[*cur_arg], args[*cur_arg + 1]);
5993 return ERR_ALERT | ERR_FATAL;
5994 }
5995
Evan Broderbe554312013-06-27 00:05:25 -07005996 return 0;
5997}
5998
5999/* parse the "verifyhost" server keyword */
6000static int srv_parse_verifyhost(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
6001{
6002 if (!*args[*cur_arg + 1]) {
6003 if (err)
6004 memprintf(err, "'%s' : missing hostname to verify against", args[*cur_arg]);
6005 return ERR_ALERT | ERR_FATAL;
6006 }
6007
6008 newsrv->ssl_ctx.verify_host = strdup(args[*cur_arg + 1]);
6009
Emeric Brunef42d922012-10-11 16:11:36 +02006010 return 0;
6011}
6012
Emeric Brun2c86cbf2014-10-30 15:56:50 +01006013/* parse the "ssl-default-bind-options" keyword in global section */
6014static int ssl_parse_default_bind_options(char **args, int section_type, struct proxy *curpx,
6015 struct proxy *defpx, const char *file, int line,
6016 char **err) {
6017 int i = 1;
6018
6019 if (*(args[i]) == 0) {
6020 memprintf(err, "global statement '%s' expects an option as an argument.", args[0]);
6021 return -1;
6022 }
6023 while (*(args[i])) {
6024 if (!strcmp(args[i], "no-sslv3"))
Willy Tarreauef934602016-12-22 23:12:01 +01006025 global_ssl.listen_default_ssloptions |= BC_SSL_O_NO_SSLV3;
Emeric Brun2c86cbf2014-10-30 15:56:50 +01006026 else if (!strcmp(args[i], "no-tlsv10"))
Willy Tarreauef934602016-12-22 23:12:01 +01006027 global_ssl.listen_default_ssloptions |= BC_SSL_O_NO_TLSV10;
Emeric Brun2c86cbf2014-10-30 15:56:50 +01006028 else if (!strcmp(args[i], "no-tlsv11"))
Willy Tarreauef934602016-12-22 23:12:01 +01006029 global_ssl.listen_default_ssloptions |= BC_SSL_O_NO_TLSV11;
Emeric Brun2c86cbf2014-10-30 15:56:50 +01006030 else if (!strcmp(args[i], "no-tlsv12"))
Willy Tarreauef934602016-12-22 23:12:01 +01006031 global_ssl.listen_default_ssloptions |= BC_SSL_O_NO_TLSV12;
Emeric Brun2c86cbf2014-10-30 15:56:50 +01006032 else if (!strcmp(args[i], "force-sslv3"))
Willy Tarreauef934602016-12-22 23:12:01 +01006033 global_ssl.listen_default_ssloptions |= BC_SSL_O_USE_SSLV3;
Emeric Brun2c86cbf2014-10-30 15:56:50 +01006034 else if (!strcmp(args[i], "force-tlsv10"))
Willy Tarreauef934602016-12-22 23:12:01 +01006035 global_ssl.listen_default_ssloptions |= BC_SSL_O_USE_TLSV10;
Emeric Brun2c86cbf2014-10-30 15:56:50 +01006036 else if (!strcmp(args[i], "force-tlsv11")) {
6037#if SSL_OP_NO_TLSv1_1
Willy Tarreauef934602016-12-22 23:12:01 +01006038 global_ssl.listen_default_ssloptions |= BC_SSL_O_USE_TLSV11;
Emeric Brun2c86cbf2014-10-30 15:56:50 +01006039#else
6040 memprintf(err, "'%s' '%s': library does not support protocol TLSv1.1", args[0], args[i]);
6041 return -1;
6042#endif
6043 }
6044 else if (!strcmp(args[i], "force-tlsv12")) {
6045#if SSL_OP_NO_TLSv1_2
Willy Tarreauef934602016-12-22 23:12:01 +01006046 global_ssl.listen_default_ssloptions |= BC_SSL_O_USE_TLSV12;
Emeric Brun2c86cbf2014-10-30 15:56:50 +01006047#else
6048 memprintf(err, "'%s' '%s': library does not support protocol TLSv1.2", args[0], args[i]);
6049 return -1;
6050#endif
6051 }
6052 else if (!strcmp(args[i], "no-tls-tickets"))
Willy Tarreauef934602016-12-22 23:12:01 +01006053 global_ssl.listen_default_ssloptions |= BC_SSL_O_NO_TLS_TICKETS;
Emeric Brun2c86cbf2014-10-30 15:56:50 +01006054 else {
6055 memprintf(err, "unknown option '%s' on global statement '%s'.", args[i], args[0]);
6056 return -1;
6057 }
6058 i++;
6059 }
6060 return 0;
6061}
6062
6063/* parse the "ssl-default-server-options" keyword in global section */
6064static int ssl_parse_default_server_options(char **args, int section_type, struct proxy *curpx,
6065 struct proxy *defpx, const char *file, int line,
6066 char **err) {
6067 int i = 1;
6068
6069 if (*(args[i]) == 0) {
6070 memprintf(err, "global statement '%s' expects an option as an argument.", args[0]);
6071 return -1;
6072 }
6073 while (*(args[i])) {
6074 if (!strcmp(args[i], "no-sslv3"))
Willy Tarreauef934602016-12-22 23:12:01 +01006075 global_ssl.connect_default_ssloptions |= SRV_SSL_O_NO_SSLV3;
Emeric Brun2c86cbf2014-10-30 15:56:50 +01006076 else if (!strcmp(args[i], "no-tlsv10"))
Willy Tarreauef934602016-12-22 23:12:01 +01006077 global_ssl.connect_default_ssloptions |= SRV_SSL_O_NO_TLSV10;
Emeric Brun2c86cbf2014-10-30 15:56:50 +01006078 else if (!strcmp(args[i], "no-tlsv11"))
Willy Tarreauef934602016-12-22 23:12:01 +01006079 global_ssl.connect_default_ssloptions |= SRV_SSL_O_NO_TLSV11;
Emeric Brun2c86cbf2014-10-30 15:56:50 +01006080 else if (!strcmp(args[i], "no-tlsv12"))
Willy Tarreauef934602016-12-22 23:12:01 +01006081 global_ssl.connect_default_ssloptions |= SRV_SSL_O_NO_TLSV12;
Emeric Brun2c86cbf2014-10-30 15:56:50 +01006082 else if (!strcmp(args[i], "force-sslv3"))
Willy Tarreauef934602016-12-22 23:12:01 +01006083 global_ssl.connect_default_ssloptions |= SRV_SSL_O_USE_SSLV3;
Emeric Brun2c86cbf2014-10-30 15:56:50 +01006084 else if (!strcmp(args[i], "force-tlsv10"))
Willy Tarreauef934602016-12-22 23:12:01 +01006085 global_ssl.connect_default_ssloptions |= SRV_SSL_O_USE_TLSV10;
Emeric Brun2c86cbf2014-10-30 15:56:50 +01006086 else if (!strcmp(args[i], "force-tlsv11")) {
6087#if SSL_OP_NO_TLSv1_1
Willy Tarreauef934602016-12-22 23:12:01 +01006088 global_ssl.connect_default_ssloptions |= SRV_SSL_O_USE_TLSV11;
Emeric Brun2c86cbf2014-10-30 15:56:50 +01006089#else
6090 memprintf(err, "'%s' '%s': library does not support protocol TLSv1.1", args[0], args[i]);
6091 return -1;
6092#endif
6093 }
6094 else if (!strcmp(args[i], "force-tlsv12")) {
6095#if SSL_OP_NO_TLSv1_2
Willy Tarreauef934602016-12-22 23:12:01 +01006096 global_ssl.connect_default_ssloptions |= SRV_SSL_O_USE_TLSV12;
Emeric Brun2c86cbf2014-10-30 15:56:50 +01006097#else
6098 memprintf(err, "'%s' '%s': library does not support protocol TLSv1.2", args[0], args[i]);
6099 return -1;
6100#endif
6101 }
6102 else if (!strcmp(args[i], "no-tls-tickets"))
Willy Tarreauef934602016-12-22 23:12:01 +01006103 global_ssl.connect_default_ssloptions |= SRV_SSL_O_NO_TLS_TICKETS;
Emeric Brun2c86cbf2014-10-30 15:56:50 +01006104 else {
6105 memprintf(err, "unknown option '%s' on global statement '%s'.", args[i], args[0]);
6106 return -1;
6107 }
6108 i++;
6109 }
6110 return 0;
6111}
6112
Willy Tarreau8c3b0fd2016-12-21 22:44:46 +01006113/* parse the "ca-base" / "crt-base" keywords in global section.
6114 * Returns <0 on alert, >0 on warning, 0 on success.
6115 */
6116static int ssl_parse_global_ca_crt_base(char **args, int section_type, struct proxy *curpx,
6117 struct proxy *defpx, const char *file, int line,
6118 char **err)
6119{
6120 char **target;
6121
Willy Tarreauef934602016-12-22 23:12:01 +01006122 target = (args[0][1] == 'a') ? &global_ssl.ca_base : &global_ssl.crt_base;
Willy Tarreau8c3b0fd2016-12-21 22:44:46 +01006123
6124 if (too_many_args(1, args, err, NULL))
6125 return -1;
6126
6127 if (*target) {
6128 memprintf(err, "'%s' already specified.", args[0]);
6129 return -1;
6130 }
6131
6132 if (*(args[1]) == 0) {
6133 memprintf(err, "global statement '%s' expects a directory path as an argument.", args[0]);
6134 return -1;
6135 }
6136 *target = strdup(args[1]);
6137 return 0;
6138}
6139
Willy Tarreauf22e9682016-12-21 23:23:19 +01006140/* parse the "ssl-default-bind-ciphers" / "ssl-default-server-ciphers" keywords
6141 * in global section. Returns <0 on alert, >0 on warning, 0 on success.
6142 */
6143static int ssl_parse_global_ciphers(char **args, int section_type, struct proxy *curpx,
6144 struct proxy *defpx, const char *file, int line,
6145 char **err)
6146{
6147 char **target;
6148
Willy Tarreauef934602016-12-22 23:12:01 +01006149 target = (args[0][12] == 'b') ? &global_ssl.listen_default_ciphers : &global_ssl.connect_default_ciphers;
Willy Tarreauf22e9682016-12-21 23:23:19 +01006150
6151 if (too_many_args(1, args, err, NULL))
6152 return -1;
6153
6154 if (*(args[1]) == 0) {
6155 memprintf(err, "global statement '%s' expects a cipher suite as an argument.", args[0]);
6156 return -1;
6157 }
6158
6159 free(*target);
6160 *target = strdup(args[1]);
6161 return 0;
6162}
6163
Willy Tarreau9ceda382016-12-21 23:13:03 +01006164/* parse various global tune.ssl settings consisting in positive integers.
6165 * Returns <0 on alert, >0 on warning, 0 on success.
6166 */
6167static int ssl_parse_global_int(char **args, int section_type, struct proxy *curpx,
6168 struct proxy *defpx, const char *file, int line,
6169 char **err)
6170{
6171 int *target;
6172
6173 if (strcmp(args[0], "tune.ssl.cachesize") == 0)
6174 target = &global.tune.sslcachesize;
6175 else if (strcmp(args[0], "tune.ssl.maxrecord") == 0)
Willy Tarreauef934602016-12-22 23:12:01 +01006176 target = (int *)&global_ssl.max_record;
Willy Tarreau9ceda382016-12-21 23:13:03 +01006177 else if (strcmp(args[0], "tune.ssl.ssl-ctx-cache-size") == 0)
Willy Tarreauef934602016-12-22 23:12:01 +01006178 target = &global_ssl.ctx_cache;
Willy Tarreau0bea58d2016-12-21 23:17:25 +01006179 else if (strcmp(args[0], "maxsslconn") == 0)
6180 target = &global.maxsslconn;
Willy Tarreau9ceda382016-12-21 23:13:03 +01006181 else {
6182 memprintf(err, "'%s' keyword not unhandled (please report this bug).", args[0]);
6183 return -1;
6184 }
6185
6186 if (too_many_args(1, args, err, NULL))
6187 return -1;
6188
6189 if (*(args[1]) == 0) {
6190 memprintf(err, "'%s' expects an integer argument.", args[0]);
6191 return -1;
6192 }
6193
6194 *target = atoi(args[1]);
6195 if (*target < 0) {
6196 memprintf(err, "'%s' expects a positive numeric value.", args[0]);
6197 return -1;
6198 }
6199 return 0;
6200}
6201
6202/* parse "ssl.force-private-cache".
6203 * Returns <0 on alert, >0 on warning, 0 on success.
6204 */
6205static int ssl_parse_global_private_cache(char **args, int section_type, struct proxy *curpx,
6206 struct proxy *defpx, const char *file, int line,
6207 char **err)
6208{
6209 if (too_many_args(0, args, err, NULL))
6210 return -1;
6211
Willy Tarreauef934602016-12-22 23:12:01 +01006212 global_ssl.private_cache = 1;
Willy Tarreau9ceda382016-12-21 23:13:03 +01006213 return 0;
6214}
6215
6216/* parse "ssl.lifetime".
6217 * Returns <0 on alert, >0 on warning, 0 on success.
6218 */
6219static int ssl_parse_global_lifetime(char **args, int section_type, struct proxy *curpx,
6220 struct proxy *defpx, const char *file, int line,
6221 char **err)
6222{
6223 const char *res;
6224
6225 if (too_many_args(1, args, err, NULL))
6226 return -1;
6227
6228 if (*(args[1]) == 0) {
6229 memprintf(err, "'%s' expects ssl sessions <lifetime> in seconds as argument.", args[0]);
6230 return -1;
6231 }
6232
Willy Tarreauef934602016-12-22 23:12:01 +01006233 res = parse_time_err(args[1], &global_ssl.life_time, TIME_UNIT_S);
Willy Tarreau9ceda382016-12-21 23:13:03 +01006234 if (res) {
6235 memprintf(err, "unexpected character '%c' in argument to <%s>.", *res, args[0]);
6236 return -1;
6237 }
6238 return 0;
6239}
6240
6241#ifndef OPENSSL_NO_DH
Willy Tarreau14e36a12016-12-21 23:28:13 +01006242/* parse "ssl-dh-param-file".
6243 * Returns <0 on alert, >0 on warning, 0 on success.
6244 */
6245static int ssl_parse_global_dh_param_file(char **args, int section_type, struct proxy *curpx,
6246 struct proxy *defpx, const char *file, int line,
6247 char **err)
6248{
6249 if (too_many_args(1, args, err, NULL))
6250 return -1;
6251
6252 if (*(args[1]) == 0) {
6253 memprintf(err, "'%s' expects a file path as an argument.", args[0]);
6254 return -1;
6255 }
6256
6257 if (ssl_sock_load_global_dh_param_from_file(args[1])) {
6258 memprintf(err, "'%s': unable to load DH parameters from file <%s>.", args[0], args[1]);
6259 return -1;
6260 }
6261 return 0;
6262}
6263
Willy Tarreau9ceda382016-12-21 23:13:03 +01006264/* parse "ssl.default-dh-param".
6265 * Returns <0 on alert, >0 on warning, 0 on success.
6266 */
6267static int ssl_parse_global_default_dh(char **args, int section_type, struct proxy *curpx,
6268 struct proxy *defpx, const char *file, int line,
6269 char **err)
6270{
6271 if (too_many_args(1, args, err, NULL))
6272 return -1;
6273
6274 if (*(args[1]) == 0) {
6275 memprintf(err, "'%s' expects an integer argument.", args[0]);
6276 return -1;
6277 }
6278
Willy Tarreauef934602016-12-22 23:12:01 +01006279 global_ssl.default_dh_param = atoi(args[1]);
6280 if (global_ssl.default_dh_param < 1024) {
Willy Tarreau9ceda382016-12-21 23:13:03 +01006281 memprintf(err, "'%s' expects a value >= 1024.", args[0]);
6282 return -1;
6283 }
6284 return 0;
6285}
6286#endif
6287
6288
William Lallemand32af2032016-10-29 18:09:35 +02006289/* This function is used with TLS ticket keys management. It permits to browse
6290 * each reference. The variable <getnext> must contain the current node,
6291 * <end> point to the root node.
6292 */
6293#if (defined SSL_CTRL_SET_TLSEXT_TICKET_KEY_CB && TLS_TICKETS_NO > 0)
6294static inline
6295struct tls_keys_ref *tlskeys_list_get_next(struct tls_keys_ref *getnext, struct list *end)
6296{
6297 struct tls_keys_ref *ref = getnext;
6298
6299 while (1) {
6300
6301 /* Get next list entry. */
6302 ref = LIST_NEXT(&ref->list, struct tls_keys_ref *, list);
6303
6304 /* If the entry is the last of the list, return NULL. */
6305 if (&ref->list == end)
6306 return NULL;
6307
6308 return ref;
6309 }
6310}
6311
6312static inline
6313struct tls_keys_ref *tlskeys_ref_lookup_ref(const char *reference)
6314{
6315 int id;
6316 char *error;
6317
6318 /* If the reference starts by a '#', this is numeric id. */
6319 if (reference[0] == '#') {
6320 /* Try to convert the numeric id. If the conversion fails, the lookup fails. */
6321 id = strtol(reference + 1, &error, 10);
6322 if (*error != '\0')
6323 return NULL;
6324
6325 /* Perform the unique id lookup. */
6326 return tlskeys_ref_lookupid(id);
6327 }
6328
6329 /* Perform the string lookup. */
6330 return tlskeys_ref_lookup(reference);
6331}
6332#endif
6333
6334
6335#if (defined SSL_CTRL_SET_TLSEXT_TICKET_KEY_CB && TLS_TICKETS_NO > 0)
6336
6337static int cli_io_handler_tlskeys_files(struct appctx *appctx);
6338
6339static inline int cli_io_handler_tlskeys_entries(struct appctx *appctx) {
6340 return cli_io_handler_tlskeys_files(appctx);
6341}
6342
Willy Tarreauf5f26e82016-12-16 18:47:27 +01006343/* dumps all tls keys. Relies on cli.i0 (non-null = only list file names), cli.i1
6344 * (next index to be dumped), and cli.p0 (next key reference).
6345 */
William Lallemand32af2032016-10-29 18:09:35 +02006346static int cli_io_handler_tlskeys_files(struct appctx *appctx) {
6347
6348 struct stream_interface *si = appctx->owner;
6349
6350 switch (appctx->st2) {
6351 case STAT_ST_INIT:
6352 /* Display the column headers. If the message cannot be sent,
6353 * quit the fucntion with returning 0. The function is called
6354 * later and restart at the state "STAT_ST_INIT".
6355 */
6356 chunk_reset(&trash);
6357
6358 if (appctx->io_handler == cli_io_handler_tlskeys_entries)
6359 chunk_appendf(&trash, "# id secret\n");
6360 else
6361 chunk_appendf(&trash, "# id (file)\n");
6362
6363 if (bi_putchk(si_ic(si), &trash) == -1) {
6364 si_applet_cant_put(si);
6365 return 0;
6366 }
6367
William Lallemand32af2032016-10-29 18:09:35 +02006368 /* Now, we start the browsing of the references lists.
6369 * Note that the following call to LIST_ELEM return bad pointer. The only
6370 * available field of this pointer is <list>. It is used with the function
6371 * tlskeys_list_get_next() for retruning the first available entry
6372 */
Willy Tarreauf5f26e82016-12-16 18:47:27 +01006373 if (appctx->ctx.cli.p0 == NULL) {
6374 appctx->ctx.cli.p0 = LIST_ELEM(&tlskeys_reference, struct tls_keys_ref *, list);
6375 appctx->ctx.cli.p0 = tlskeys_list_get_next(appctx->ctx.cli.p0, &tlskeys_reference);
William Lallemand32af2032016-10-29 18:09:35 +02006376 }
6377
6378 appctx->st2 = STAT_ST_LIST;
6379 /* fall through */
6380
6381 case STAT_ST_LIST:
Willy Tarreauf5f26e82016-12-16 18:47:27 +01006382 while (appctx->ctx.cli.p0) {
6383 struct tls_keys_ref *ref = appctx->ctx.cli.p0;
6384 int head = ref->tls_ticket_enc_index;
William Lallemand32af2032016-10-29 18:09:35 +02006385
6386 chunk_reset(&trash);
Willy Tarreauf5f26e82016-12-16 18:47:27 +01006387 if (appctx->io_handler == cli_io_handler_tlskeys_entries && appctx->ctx.cli.i1 == 0)
William Lallemand32af2032016-10-29 18:09:35 +02006388 chunk_appendf(&trash, "# ");
Willy Tarreauf5f26e82016-12-16 18:47:27 +01006389
6390 if (appctx->ctx.cli.i1 == 0)
6391 chunk_appendf(&trash, "%d (%s)\n", ref->unique_id, ref->filename);
6392
William Lallemand32af2032016-10-29 18:09:35 +02006393 if (appctx->io_handler == cli_io_handler_tlskeys_entries) {
Willy Tarreauf5f26e82016-12-16 18:47:27 +01006394 while (appctx->ctx.cli.i1 < TLS_TICKETS_NO) {
William Lallemand32af2032016-10-29 18:09:35 +02006395 struct chunk *t2 = get_trash_chunk();
6396
6397 chunk_reset(t2);
6398 /* should never fail here because we dump only a key in the t2 buffer */
Willy Tarreauf5f26e82016-12-16 18:47:27 +01006399 t2->len = a2base64((char *)(ref->tlskeys + (head + 2 + appctx->ctx.cli.i1) % TLS_TICKETS_NO),
William Lallemand32af2032016-10-29 18:09:35 +02006400 sizeof(struct tls_sess_key), t2->str, t2->size);
Willy Tarreauf5f26e82016-12-16 18:47:27 +01006401 chunk_appendf(&trash, "%d.%d %s\n", ref->unique_id, appctx->ctx.cli.i1, t2->str);
William Lallemand32af2032016-10-29 18:09:35 +02006402
6403 if (bi_putchk(si_ic(si), &trash) == -1) {
6404 /* let's try again later from this stream. We add ourselves into
6405 * this stream's users so that it can remove us upon termination.
6406 */
6407 si_applet_cant_put(si);
6408 return 0;
6409 }
Willy Tarreauf5f26e82016-12-16 18:47:27 +01006410 appctx->ctx.cli.i1++;
William Lallemand32af2032016-10-29 18:09:35 +02006411 }
Willy Tarreauf5f26e82016-12-16 18:47:27 +01006412 appctx->ctx.cli.i1 = 0;
William Lallemand32af2032016-10-29 18:09:35 +02006413 }
6414 if (bi_putchk(si_ic(si), &trash) == -1) {
6415 /* let's try again later from this stream. We add ourselves into
6416 * this stream's users so that it can remove us upon termination.
6417 */
6418 si_applet_cant_put(si);
6419 return 0;
6420 }
6421
Willy Tarreauf5f26e82016-12-16 18:47:27 +01006422 if (appctx->ctx.cli.i0 == 0) /* don't display everything if not necessary */
William Lallemand32af2032016-10-29 18:09:35 +02006423 break;
6424
6425 /* get next list entry and check the end of the list */
Willy Tarreauf5f26e82016-12-16 18:47:27 +01006426 appctx->ctx.cli.p0 = tlskeys_list_get_next(appctx->ctx.cli.p0, &tlskeys_reference);
William Lallemand32af2032016-10-29 18:09:35 +02006427 }
6428
6429 appctx->st2 = STAT_ST_FIN;
6430 /* fall through */
6431
6432 default:
6433 appctx->st2 = STAT_ST_FIN;
6434 return 1;
6435 }
6436 return 0;
6437}
6438
6439#endif
6440
Willy Tarreauf5f26e82016-12-16 18:47:27 +01006441/* sets cli.i0 to non-zero if only file lists should be dumped */
William Lallemand32af2032016-10-29 18:09:35 +02006442static int cli_parse_show_tlskeys(char **args, struct appctx *appctx, void *private)
6443{
William Lallemand32af2032016-10-29 18:09:35 +02006444 /* no parameter, shows only file list */
6445 if (!*args[2]) {
Willy Tarreauf5f26e82016-12-16 18:47:27 +01006446 appctx->ctx.cli.i0 = 1;
William Lallemand32af2032016-10-29 18:09:35 +02006447 appctx->io_handler = cli_io_handler_tlskeys_files;
Willy Tarreau3067bfa2016-12-05 14:50:15 +01006448 return 0;
William Lallemand32af2032016-10-29 18:09:35 +02006449 }
6450
6451 if (args[2][0] == '*') {
6452 /* list every TLS ticket keys */
Willy Tarreauf5f26e82016-12-16 18:47:27 +01006453 appctx->ctx.cli.i0 = 1;
William Lallemand32af2032016-10-29 18:09:35 +02006454 } else {
Willy Tarreauf5f26e82016-12-16 18:47:27 +01006455 appctx->ctx.cli.p0 = tlskeys_ref_lookup_ref(args[2]);
6456 if (!appctx->ctx.cli.p0) {
William Lallemand32af2032016-10-29 18:09:35 +02006457 appctx->ctx.cli.msg = "'show tls-keys' unable to locate referenced filename\n";
Willy Tarreau3b6e5472016-11-24 15:53:53 +01006458 appctx->st0 = CLI_ST_PRINT;
William Lallemand32af2032016-10-29 18:09:35 +02006459 return 1;
6460 }
6461 }
William Lallemand32af2032016-10-29 18:09:35 +02006462 appctx->io_handler = cli_io_handler_tlskeys_entries;
Willy Tarreau3067bfa2016-12-05 14:50:15 +01006463 return 0;
William Lallemand32af2032016-10-29 18:09:35 +02006464}
6465
6466
6467static int cli_parse_set_tlskeys(char **args, struct appctx *appctx, void *private)
6468{
Willy Tarreauf5f26e82016-12-16 18:47:27 +01006469 struct tls_keys_ref *ref;
6470
William Lallemand32af2032016-10-29 18:09:35 +02006471 /* Expect two parameters: the filename and the new new TLS key in encoding */
6472 if (!*args[3] || !*args[4]) {
6473 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 +01006474 appctx->st0 = CLI_ST_PRINT;
William Lallemand32af2032016-10-29 18:09:35 +02006475 return 1;
6476 }
6477
Willy Tarreauf5f26e82016-12-16 18:47:27 +01006478 ref = tlskeys_ref_lookup_ref(args[3]);
6479 if (!ref) {
William Lallemand32af2032016-10-29 18:09:35 +02006480 appctx->ctx.cli.msg = "'set ssl tls-key' unable to locate referenced filename\n";
Willy Tarreau3b6e5472016-11-24 15:53:53 +01006481 appctx->st0 = CLI_ST_PRINT;
William Lallemand32af2032016-10-29 18:09:35 +02006482 return 1;
6483 }
6484
6485 trash.len = base64dec(args[4], strlen(args[4]), trash.str, trash.size);
6486 if (trash.len != sizeof(struct tls_sess_key)) {
6487 appctx->ctx.cli.msg = "'set ssl tls-key' received invalid base64 encoded TLS key.\n";
Willy Tarreau3b6e5472016-11-24 15:53:53 +01006488 appctx->st0 = CLI_ST_PRINT;
William Lallemand32af2032016-10-29 18:09:35 +02006489 return 1;
6490 }
6491
Willy Tarreauf5f26e82016-12-16 18:47:27 +01006492 memcpy(ref->tlskeys + ((ref->tls_ticket_enc_index + 2) % TLS_TICKETS_NO), trash.str, trash.len);
6493 ref->tls_ticket_enc_index = (ref->tls_ticket_enc_index + 1) % TLS_TICKETS_NO;
William Lallemand32af2032016-10-29 18:09:35 +02006494
6495 appctx->ctx.cli.msg = "TLS ticket key updated!";
Willy Tarreau3b6e5472016-11-24 15:53:53 +01006496 appctx->st0 = CLI_ST_PRINT;
William Lallemand32af2032016-10-29 18:09:35 +02006497 return 1;
6498
6499}
6500
6501static int cli_parse_set_ocspresponse(char **args, struct appctx *appctx, void *private)
6502{
6503#if (defined SSL_CTRL_SET_TLSEXT_STATUS_REQ_CB && !defined OPENSSL_NO_OCSP)
6504 char *err = NULL;
6505
6506 /* Expect one parameter: the new response in base64 encoding */
6507 if (!*args[3]) {
6508 appctx->ctx.cli.msg = "'set ssl ocsp-response' expects response in base64 encoding.\n";
Willy Tarreau3b6e5472016-11-24 15:53:53 +01006509 appctx->st0 = CLI_ST_PRINT;
William Lallemand32af2032016-10-29 18:09:35 +02006510 return 1;
6511 }
6512
6513 trash.len = base64dec(args[3], strlen(args[3]), trash.str, trash.size);
6514 if (trash.len < 0) {
6515 appctx->ctx.cli.msg = "'set ssl ocsp-response' received invalid base64 encoded response.\n";
Willy Tarreau3b6e5472016-11-24 15:53:53 +01006516 appctx->st0 = CLI_ST_PRINT;
William Lallemand32af2032016-10-29 18:09:35 +02006517 return 1;
6518 }
6519
6520 if (ssl_sock_update_ocsp_response(&trash, &err)) {
6521 if (err) {
6522 memprintf(&err, "%s.\n", err);
6523 appctx->ctx.cli.err = err;
Willy Tarreau3b6e5472016-11-24 15:53:53 +01006524 appctx->st0 = CLI_ST_PRINT_FREE;
William Lallemand32af2032016-10-29 18:09:35 +02006525 }
6526 return 1;
6527 }
6528 appctx->ctx.cli.msg = "OCSP Response updated!";
Willy Tarreau3b6e5472016-11-24 15:53:53 +01006529 appctx->st0 = CLI_ST_PRINT;
William Lallemand32af2032016-10-29 18:09:35 +02006530 return 1;
6531#else
6532 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 +01006533 appctx->st0 = CLI_ST_PRINT;
William Lallemand32af2032016-10-29 18:09:35 +02006534 return 1;
6535#endif
6536
6537}
6538
6539/* register cli keywords */
6540static struct cli_kw_list cli_kws = {{ },{
6541#if (defined SSL_CTRL_SET_TLSEXT_TICKET_KEY_CB && TLS_TICKETS_NO > 0)
6542 { { "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 },
6543 { { "set", "ssl", "tls-keys", NULL }, NULL, cli_parse_set_tlskeys, NULL },
6544 { { "set", "ssl", "ocsp-response", NULL }, NULL, cli_parse_set_ocspresponse, NULL },
6545#endif
6546 { { NULL }, NULL, NULL, NULL }
6547}};
6548
6549
6550
Willy Tarreau7875d092012-09-10 08:20:03 +02006551/* Note: must not be declared <const> as its list will be overwritten.
6552 * Please take care of keeping this list alphabetically sorted.
6553 */
Willy Tarreaudc13c112013-06-21 23:16:39 +02006554static struct sample_fetch_kw_list sample_fetch_keywords = {ILH, {
Emeric Brun645ae792014-04-30 14:21:06 +02006555 { "ssl_bc", smp_fetch_ssl_fc, 0, NULL, SMP_T_BOOL, SMP_USE_L5SRV },
Thierry FOURNIER07ee64e2015-07-06 23:43:03 +02006556 { "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 +02006557 { "ssl_bc_cipher", smp_fetch_ssl_fc_cipher, 0, NULL, SMP_T_STR, SMP_USE_L5SRV },
6558 { "ssl_bc_protocol", smp_fetch_ssl_fc_protocol, 0, NULL, SMP_T_STR, SMP_USE_L5SRV },
Emeric Brunb73a9b02014-04-30 18:49:19 +02006559 { "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 +02006560 { "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 +02006561 { "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 +02006562 { "ssl_c_ca_err", smp_fetch_ssl_c_ca_err, 0, NULL, SMP_T_SINT, SMP_USE_L5CLI },
6563 { "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 +01006564 { "ssl_c_der", smp_fetch_ssl_x_der, 0, NULL, SMP_T_BIN, SMP_USE_L5CLI },
Thierry FOURNIER07ee64e2015-07-06 23:43:03 +02006565 { "ssl_c_err", smp_fetch_ssl_c_err, 0, NULL, SMP_T_SINT, SMP_USE_L5CLI },
Emeric Brunba841a12014-04-30 17:05:08 +02006566 { "ssl_c_i_dn", smp_fetch_ssl_x_i_dn, ARG2(0,STR,SINT), NULL, SMP_T_STR, SMP_USE_L5CLI },
6567 { "ssl_c_key_alg", smp_fetch_ssl_x_key_alg, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
6568 { "ssl_c_notafter", smp_fetch_ssl_x_notafter, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
6569 { "ssl_c_notbefore", smp_fetch_ssl_x_notbefore, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
6570 { "ssl_c_sig_alg", smp_fetch_ssl_x_sig_alg, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
6571 { "ssl_c_s_dn", smp_fetch_ssl_x_s_dn, ARG2(0,STR,SINT), NULL, SMP_T_STR, SMP_USE_L5CLI },
6572 { "ssl_c_serial", smp_fetch_ssl_x_serial, 0, NULL, SMP_T_BIN, SMP_USE_L5CLI },
6573 { "ssl_c_sha1", smp_fetch_ssl_x_sha1, 0, NULL, SMP_T_BIN, SMP_USE_L5CLI },
Willy Tarreau80aca902013-01-07 15:42:20 +01006574 { "ssl_c_used", smp_fetch_ssl_c_used, 0, NULL, SMP_T_BOOL, SMP_USE_L5CLI },
Thierry FOURNIER07ee64e2015-07-06 23:43:03 +02006575 { "ssl_c_verify", smp_fetch_ssl_c_verify, 0, NULL, SMP_T_SINT, SMP_USE_L5CLI },
6576 { "ssl_c_version", smp_fetch_ssl_x_version, 0, NULL, SMP_T_SINT, SMP_USE_L5CLI },
Emeric Brun43e79582014-10-29 19:03:26 +01006577 { "ssl_f_der", smp_fetch_ssl_x_der, 0, NULL, SMP_T_BIN, SMP_USE_L5CLI },
Emeric Brunba841a12014-04-30 17:05:08 +02006578 { "ssl_f_i_dn", smp_fetch_ssl_x_i_dn, ARG2(0,STR,SINT), NULL, SMP_T_STR, SMP_USE_L5CLI },
6579 { "ssl_f_key_alg", smp_fetch_ssl_x_key_alg, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
6580 { "ssl_f_notafter", smp_fetch_ssl_x_notafter, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
6581 { "ssl_f_notbefore", smp_fetch_ssl_x_notbefore, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
6582 { "ssl_f_sig_alg", smp_fetch_ssl_x_sig_alg, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
6583 { "ssl_f_s_dn", smp_fetch_ssl_x_s_dn, ARG2(0,STR,SINT), NULL, SMP_T_STR, SMP_USE_L5CLI },
6584 { "ssl_f_serial", smp_fetch_ssl_x_serial, 0, NULL, SMP_T_BIN, SMP_USE_L5CLI },
Emeric Brun55f4fa82014-04-30 17:11:25 +02006585 { "ssl_f_sha1", smp_fetch_ssl_x_sha1, 0, NULL, SMP_T_BIN, SMP_USE_L5CLI },
Thierry FOURNIER07ee64e2015-07-06 23:43:03 +02006586 { "ssl_f_version", smp_fetch_ssl_x_version, 0, NULL, SMP_T_SINT, SMP_USE_L5CLI },
Willy Tarreau80aca902013-01-07 15:42:20 +01006587 { "ssl_fc", smp_fetch_ssl_fc, 0, NULL, SMP_T_BOOL, SMP_USE_L5CLI },
Thierry FOURNIER07ee64e2015-07-06 23:43:03 +02006588 { "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 +01006589 { "ssl_fc_cipher", smp_fetch_ssl_fc_cipher, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
Willy Tarreau80aca902013-01-07 15:42:20 +01006590 { "ssl_fc_has_crt", smp_fetch_ssl_fc_has_crt, 0, NULL, SMP_T_BOOL, SMP_USE_L5CLI },
6591 { "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 +02006592 { "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 +02006593#ifdef OPENSSL_NPN_NEGOTIATED
Thierry FOURNIER7654c9f2013-12-17 00:20:33 +01006594 { "ssl_fc_npn", smp_fetch_ssl_fc_npn, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
Willy Tarreaua33c6542012-10-15 13:19:06 +02006595#endif
Dirkjan Bussink48f1c4e2014-02-13 12:29:42 +01006596#ifdef TLSEXT_TYPE_application_layer_protocol_negotiation
Thierry FOURNIER7654c9f2013-12-17 00:20:33 +01006597 { "ssl_fc_alpn", smp_fetch_ssl_fc_alpn, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
Willy Tarreauab861d32013-04-02 02:30:41 +02006598#endif
Thierry FOURNIER7654c9f2013-12-17 00:20:33 +01006599 { "ssl_fc_protocol", smp_fetch_ssl_fc_protocol, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
Emeric Brunb73a9b02014-04-30 18:49:19 +02006600 { "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 +02006601 { "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 +01006602 { "ssl_fc_session_id", smp_fetch_ssl_fc_session_id, 0, NULL, SMP_T_BIN, SMP_USE_L5CLI },
6603 { "ssl_fc_sni", smp_fetch_ssl_fc_sni, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
Willy Tarreau7875d092012-09-10 08:20:03 +02006604 { NULL, NULL, 0, 0, 0 },
6605}};
6606
6607/* Note: must not be declared <const> as its list will be overwritten.
6608 * Please take care of keeping this list alphabetically sorted.
6609 */
Willy Tarreaudc13c112013-06-21 23:16:39 +02006610static struct acl_kw_list acl_kws = {ILH, {
Thierry FOURNIERc5a4e982014-03-05 16:07:08 +01006611 { "ssl_fc_sni_end", "ssl_fc_sni", PAT_MATCH_END },
6612 { "ssl_fc_sni_reg", "ssl_fc_sni", PAT_MATCH_REG },
Willy Tarreau8ed669b2013-01-11 15:49:37 +01006613 { /* END */ },
Willy Tarreau7875d092012-09-10 08:20:03 +02006614}};
6615
Willy Tarreau79eeafa2012-09-14 07:53:05 +02006616/* Note: must not be declared <const> as its list will be overwritten.
6617 * Please take care of keeping this list alphabetically sorted, doing so helps
6618 * all code contributors.
6619 * Optional keywords are also declared with a NULL ->parse() function so that
6620 * the config parser can report an appropriate error when a known keyword was
6621 * not enabled.
6622 */
Willy Tarreau51fb7652012-09-18 18:24:39 +02006623static struct bind_kw_list bind_kws = { "SSL", { }, {
Nenad Merdanovic05552d42015-02-27 19:56:49 +01006624 { "alpn", bind_parse_alpn, 1 }, /* set ALPN supported protocols */
6625 { "ca-file", bind_parse_ca_file, 1 }, /* set CAfile to process verify on client cert */
6626 { "ca-ignore-err", bind_parse_ignore_err, 1 }, /* set error IDs to ignore on verify depth > 0 */
Christopher Faulet31af49d2015-06-09 17:29:50 +02006627 { "ca-sign-file", bind_parse_ca_sign_file, 1 }, /* set CAFile used to generate and sign server certs */
6628 { "ca-sign-pass", bind_parse_ca_sign_pass, 1 }, /* set CAKey passphrase */
Nenad Merdanovic05552d42015-02-27 19:56:49 +01006629 { "ciphers", bind_parse_ciphers, 1 }, /* set SSL cipher suite */
6630 { "crl-file", bind_parse_crl_file, 1 }, /* set certificat revocation list file use on client cert verify */
6631 { "crt", bind_parse_crt, 1 }, /* load SSL certificates from this location */
6632 { "crt-ignore-err", bind_parse_ignore_err, 1 }, /* set error IDs to ingore on verify depth == 0 */
6633 { "crt-list", bind_parse_crt_list, 1 }, /* load a list of crt from this location */
6634 { "ecdhe", bind_parse_ecdhe, 1 }, /* defines named curve for elliptic curve Diffie-Hellman */
6635 { "force-sslv3", bind_parse_force_sslv3, 0 }, /* force SSLv3 */
6636 { "force-tlsv10", bind_parse_force_tlsv10, 0 }, /* force TLSv10 */
6637 { "force-tlsv11", bind_parse_force_tlsv11, 0 }, /* force TLSv11 */
6638 { "force-tlsv12", bind_parse_force_tlsv12, 0 }, /* force TLSv12 */
Christopher Faulet31af49d2015-06-09 17:29:50 +02006639 { "generate-certificates", bind_parse_generate_certs, 0 }, /* enable the server certificates generation */
Nenad Merdanovic05552d42015-02-27 19:56:49 +01006640 { "no-sslv3", bind_parse_no_sslv3, 0 }, /* disable SSLv3 */
6641 { "no-tlsv10", bind_parse_no_tlsv10, 0 }, /* disable TLSv10 */
6642 { "no-tlsv11", bind_parse_no_tlsv11, 0 }, /* disable TLSv11 */
6643 { "no-tlsv12", bind_parse_no_tlsv12, 0 }, /* disable TLSv12 */
6644 { "no-tls-tickets", bind_parse_no_tls_tickets, 0 }, /* disable session resumption tickets */
6645 { "ssl", bind_parse_ssl, 0 }, /* enable SSL processing */
6646 { "strict-sni", bind_parse_strict_sni, 0 }, /* refuse negotiation if sni doesn't match a certificate */
6647 { "tls-ticket-keys", bind_parse_tls_ticket_keys, 1 }, /* set file to load TLS ticket keys from */
6648 { "verify", bind_parse_verify, 1 }, /* set SSL verify method */
6649 { "npn", bind_parse_npn, 1 }, /* set NPN supported protocols */
Willy Tarreau79eeafa2012-09-14 07:53:05 +02006650 { NULL, NULL, 0 },
6651}};
Emeric Brun46591952012-05-18 15:47:34 +02006652
Willy Tarreau92faadf2012-10-10 23:04:25 +02006653/* Note: must not be declared <const> as its list will be overwritten.
6654 * Please take care of keeping this list alphabetically sorted, doing so helps
6655 * all code contributors.
6656 * Optional keywords are also declared with a NULL ->parse() function so that
6657 * the config parser can report an appropriate error when a known keyword was
6658 * not enabled.
6659 */
6660static struct srv_kw_list srv_kws = { "SSL", { }, {
Emeric Brunef42d922012-10-11 16:11:36 +02006661 { "ca-file", srv_parse_ca_file, 1, 0 }, /* set CAfile to process verify server cert */
Emeric Brunecc91fe2012-10-11 15:05:10 +02006662 { "check-ssl", srv_parse_check_ssl, 0, 0 }, /* enable SSL for health checks */
6663 { "ciphers", srv_parse_ciphers, 1, 0 }, /* select the cipher suite */
Emeric Brunef42d922012-10-11 16:11:36 +02006664 { "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 +02006665 { "crt", srv_parse_crt, 1, 0 }, /* set client certificate */
Emeric Brunecc91fe2012-10-11 15:05:10 +02006666 { "force-sslv3", srv_parse_force_sslv3, 0, 0 }, /* force SSLv3 */
6667 { "force-tlsv10", srv_parse_force_tlsv10, 0, 0 }, /* force TLSv10 */
6668 { "force-tlsv11", srv_parse_force_tlsv11, 0, 0 }, /* force TLSv11 */
6669 { "force-tlsv12", srv_parse_force_tlsv12, 0, 0 }, /* force TLSv12 */
Willy Tarreau2a3fb1c2015-02-05 16:47:07 +01006670 { "no-ssl-reuse", srv_parse_no_ssl_reuse, 0, 0 }, /* disable session reuse */
Emeric Brunecc91fe2012-10-11 15:05:10 +02006671 { "no-sslv3", srv_parse_no_sslv3, 0, 0 }, /* disable SSLv3 */
6672 { "no-tlsv10", srv_parse_no_tlsv10, 0, 0 }, /* disable TLSv10 */
6673 { "no-tlsv11", srv_parse_no_tlsv11, 0, 0 }, /* disable TLSv11 */
6674 { "no-tlsv12", srv_parse_no_tlsv12, 0, 0 }, /* disable TLSv12 */
Emeric Brunf9c5c472012-10-11 15:28:34 +02006675 { "no-tls-tickets", srv_parse_no_tls_tickets, 0, 0 }, /* disable session resumption tickets */
David Safb76832014-05-08 23:42:08 -04006676 { "send-proxy-v2-ssl", srv_parse_send_proxy_ssl, 0, 0 }, /* send PROXY protocol header v2 with SSL info */
6677 { "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 +02006678 { "sni", srv_parse_sni, 1, 0 }, /* send SNI extension */
Emeric Brunecc91fe2012-10-11 15:05:10 +02006679 { "ssl", srv_parse_ssl, 0, 0 }, /* enable SSL processing */
Emeric Brunef42d922012-10-11 16:11:36 +02006680 { "verify", srv_parse_verify, 1, 0 }, /* set SSL verify method */
Evan Broderbe554312013-06-27 00:05:25 -07006681 { "verifyhost", srv_parse_verifyhost, 1, 0 }, /* require that SSL cert verifies for hostname */
Willy Tarreau92faadf2012-10-10 23:04:25 +02006682 { NULL, NULL, 0, 0 },
6683}};
6684
Emeric Brun2c86cbf2014-10-30 15:56:50 +01006685static struct cfg_kw_list cfg_kws = {ILH, {
Willy Tarreau8c3b0fd2016-12-21 22:44:46 +01006686 { CFG_GLOBAL, "ca-base", ssl_parse_global_ca_crt_base },
6687 { CFG_GLOBAL, "crt-base", ssl_parse_global_ca_crt_base },
Willy Tarreau0bea58d2016-12-21 23:17:25 +01006688 { CFG_GLOBAL, "maxsslconn", ssl_parse_global_int },
Emeric Brun2c86cbf2014-10-30 15:56:50 +01006689 { CFG_GLOBAL, "ssl-default-bind-options", ssl_parse_default_bind_options },
6690 { CFG_GLOBAL, "ssl-default-server-options", ssl_parse_default_server_options },
Willy Tarreau14e36a12016-12-21 23:28:13 +01006691#ifndef OPENSSL_NO_DH
6692 { CFG_GLOBAL, "ssl-dh-param-file", ssl_parse_global_dh_param_file },
6693#endif
Willy Tarreau9ceda382016-12-21 23:13:03 +01006694 { CFG_GLOBAL, "tune.ssl.cachesize", ssl_parse_global_int },
6695#ifndef OPENSSL_NO_DH
6696 { CFG_GLOBAL, "tune.ssl.default-dh-param", ssl_parse_global_default_dh },
6697#endif
6698 { CFG_GLOBAL, "tune.ssl.force-private-cache", ssl_parse_global_private_cache },
6699 { CFG_GLOBAL, "tune.ssl.lifetime", ssl_parse_global_lifetime },
6700 { CFG_GLOBAL, "tune.ssl.maxrecord", ssl_parse_global_int },
6701 { CFG_GLOBAL, "tune.ssl.ssl-ctx-cache-size", ssl_parse_global_int },
Willy Tarreauf22e9682016-12-21 23:23:19 +01006702 { CFG_GLOBAL, "ssl-default-bind-ciphers", ssl_parse_global_ciphers },
6703 { CFG_GLOBAL, "ssl-default-server-ciphers", ssl_parse_global_ciphers },
Emeric Brun2c86cbf2014-10-30 15:56:50 +01006704 { 0, NULL, NULL },
6705}};
6706
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02006707/* transport-layer operations for SSL sockets */
Willy Tarreaud9f5cca2016-12-22 21:08:52 +01006708static struct xprt_ops ssl_sock = {
Emeric Brun46591952012-05-18 15:47:34 +02006709 .snd_buf = ssl_sock_from_buf,
6710 .rcv_buf = ssl_sock_to_buf,
6711 .rcv_pipe = NULL,
6712 .snd_pipe = NULL,
6713 .shutr = NULL,
6714 .shutw = ssl_sock_shutw,
6715 .close = ssl_sock_close,
6716 .init = ssl_sock_init,
Willy Tarreau55d37912016-12-21 23:38:39 +01006717 .prepare_bind_conf = ssl_sock_prepare_bind_conf,
Willy Tarreau795cdab2016-12-22 17:30:54 +01006718 .destroy_bind_conf = ssl_sock_destroy_bind_conf,
Willy Tarreau17d45382016-12-22 21:16:08 +01006719 .prepare_srv = ssl_sock_prepare_srv_ctx,
6720 .destroy_srv = ssl_sock_free_srv_ctx,
Willy Tarreau8e0bb0a2016-11-24 16:58:12 +01006721 .name = "SSL",
Emeric Brun46591952012-05-18 15:47:34 +02006722};
6723
Daniel Jakots54ffb912015-11-06 20:02:41 +01006724#if (OPENSSL_VERSION_NUMBER >= 0x1000200fL && !defined OPENSSL_NO_TLSEXT && !defined OPENSSL_IS_BORINGSSL && !defined LIBRESSL_VERSION_NUMBER)
Janusz Dziemidowicz2c701b52015-03-07 23:03:59 +01006725
6726static void ssl_sock_sctl_free_func(void *parent, void *ptr, CRYPTO_EX_DATA *ad, int idx, long argl, void *argp)
6727{
6728 if (ptr) {
6729 chunk_destroy(ptr);
6730 free(ptr);
6731 }
6732}
6733
6734#endif
6735
Emeric Brun46591952012-05-18 15:47:34 +02006736__attribute__((constructor))
Willy Tarreau92faadf2012-10-10 23:04:25 +02006737static void __ssl_sock_init(void)
6738{
Willy Tarreauc2c0b612016-12-21 19:23:20 +01006739 char *ptr;
6740
Emeric Brun46591952012-05-18 15:47:34 +02006741 STACK_OF(SSL_COMP)* cm;
6742
Willy Tarreauef934602016-12-22 23:12:01 +01006743 if (global_ssl.listen_default_ciphers)
6744 global_ssl.listen_default_ciphers = strdup(global_ssl.listen_default_ciphers);
6745 if (global_ssl.connect_default_ciphers)
6746 global_ssl.connect_default_ciphers = strdup(global_ssl.connect_default_ciphers);
Willy Tarreau610f04b2014-02-13 11:36:41 +01006747
Willy Tarreau13e14102016-12-22 20:25:26 +01006748 xprt_register(XPRT_SSL, &ssl_sock);
Emeric Brun46591952012-05-18 15:47:34 +02006749 SSL_library_init();
6750 cm = SSL_COMP_get_compression_methods();
6751 sk_SSL_COMP_zero(cm);
Daniel Jakots54ffb912015-11-06 20:02:41 +01006752#if (OPENSSL_VERSION_NUMBER >= 0x1000200fL && !defined OPENSSL_NO_TLSEXT && !defined OPENSSL_IS_BORINGSSL && !defined LIBRESSL_VERSION_NUMBER)
Janusz Dziemidowicz2c701b52015-03-07 23:03:59 +01006753 sctl_ex_index = SSL_CTX_get_ex_new_index(0, NULL, NULL, NULL, ssl_sock_sctl_free_func);
6754#endif
Willy Tarreau7875d092012-09-10 08:20:03 +02006755 sample_register_fetches(&sample_fetch_keywords);
6756 acl_register_keywords(&acl_kws);
Willy Tarreau79eeafa2012-09-14 07:53:05 +02006757 bind_register_keywords(&bind_kws);
Willy Tarreau92faadf2012-10-10 23:04:25 +02006758 srv_register_keywords(&srv_kws);
Emeric Brun2c86cbf2014-10-30 15:56:50 +01006759 cfg_register_keywords(&cfg_kws);
William Lallemand32af2032016-10-29 18:09:35 +02006760 cli_register_kw(&cli_kws);
Willy Tarreaud1c57502016-12-22 22:46:15 +01006761#if (defined SSL_CTRL_SET_TLSEXT_TICKET_KEY_CB && TLS_TICKETS_NO > 0)
6762 hap_register_post_check(tlskeys_finalize_config);
6763#endif
Willy Tarreaud92aa5c2015-01-15 21:34:39 +01006764
Willy Tarreauc2c0b612016-12-21 19:23:20 +01006765 ptr = NULL;
6766 memprintf(&ptr, "Built with OpenSSL version : "
6767#ifdef OPENSSL_IS_BORINGSSL
6768 "BoringSSL\n");
6769#else /* OPENSSL_IS_BORINGSSL */
6770 OPENSSL_VERSION_TEXT
6771 "\nRunning on OpenSSL version : %s%s",
6772 SSLeay_version(SSLEAY_VERSION),
6773 ((OPENSSL_VERSION_NUMBER ^ SSLeay()) >> 8) ? " (VERSIONS DIFFER!)" : "");
6774#endif
6775 memprintf(&ptr, "%s\nOpenSSL library supports TLS extensions : "
6776#if OPENSSL_VERSION_NUMBER < 0x00907000L
6777 "no (library version too old)"
6778#elif defined(OPENSSL_NO_TLSEXT)
6779 "no (disabled via OPENSSL_NO_TLSEXT)"
6780#else
6781 "yes"
6782#endif
6783 "", ptr);
6784
6785 memprintf(&ptr, "%s\nOpenSSL library supports SNI : "
6786#ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME
6787 "yes"
6788#else
6789#ifdef OPENSSL_NO_TLSEXT
6790 "no (because of OPENSSL_NO_TLSEXT)"
6791#else
6792 "no (version might be too old, 0.9.8f min needed)"
6793#endif
6794#endif
6795 "", ptr);
6796
Willy Tarreauc2c0b612016-12-21 19:23:20 +01006797 hap_register_build_opts(ptr, 1);
6798
Willy Tarreaud92aa5c2015-01-15 21:34:39 +01006799 global.ssl_session_max_cost = SSL_SESSION_MAX_COST;
6800 global.ssl_handshake_max_cost = SSL_HANDSHAKE_MAX_COST;
Remi Gacogne4f902b82015-05-28 16:23:00 +02006801
6802#ifndef OPENSSL_NO_DH
6803 ssl_dh_ptr_index = SSL_CTX_get_ex_new_index(0, NULL, NULL, NULL, NULL);
6804#endif
Thierry FOURNIER / OZON.IO8b068c22016-10-10 11:59:50 +02006805
6806 /* Load SSL string for the verbose & debug mode. */
6807 ERR_load_SSL_strings();
Emeric Brun46591952012-05-18 15:47:34 +02006808}
6809
Remi Gacogned3a23c32015-05-28 16:39:47 +02006810__attribute__((destructor))
6811static void __ssl_sock_deinit(void)
6812{
Willy Tarreaua84c2672015-10-09 12:10:13 +02006813#ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME
Christopher Faulet31af49d2015-06-09 17:29:50 +02006814 lru64_destroy(ssl_ctx_lru_tree);
Willy Tarreaua84c2672015-10-09 12:10:13 +02006815#endif
Christopher Faulet31af49d2015-06-09 17:29:50 +02006816
Remi Gacogned3a23c32015-05-28 16:39:47 +02006817#ifndef OPENSSL_NO_DH
6818 if (local_dh_1024) {
6819 DH_free(local_dh_1024);
6820 local_dh_1024 = NULL;
6821 }
6822
6823 if (local_dh_2048) {
6824 DH_free(local_dh_2048);
6825 local_dh_2048 = NULL;
6826 }
6827
6828 if (local_dh_4096) {
6829 DH_free(local_dh_4096);
6830 local_dh_4096 = NULL;
6831 }
6832
Remi Gacogne47783ef2015-05-29 15:53:22 +02006833 if (global_dh) {
6834 DH_free(global_dh);
6835 global_dh = NULL;
6836 }
Remi Gacogned3a23c32015-05-28 16:39:47 +02006837#endif
6838
6839 ERR_remove_state(0);
6840 ERR_free_strings();
6841
6842 EVP_cleanup();
6843
6844#if OPENSSL_VERSION_NUMBER >= 0x00907000L
6845 CRYPTO_cleanup_all_ex_data();
6846#endif
6847}
6848
6849
Emeric Brun46591952012-05-18 15:47:34 +02006850/*
6851 * Local variables:
6852 * c-indent-level: 8
6853 * c-basic-offset: 8
6854 * End:
6855 */