blob: acf1c39ce3acf6a55429f0e1743dbc4655c25b01 [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));
yanbzhube2774d2015-12-10 15:07:30 -0500837
838 cb_arg->is_single = 1;
839 cb_arg->s_ocsp = iocsp;
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +0200840
841 cb_arg->single_kt = EVP_PKEY_base_id(X509_get_pubkey(x));
yanbzhube2774d2015-12-10 15:07:30 -0500842
843 SSL_CTX_set_tlsext_status_cb(ctx, ssl_sock_ocsp_stapling_cbk);
844 SSL_CTX_set_tlsext_status_arg(ctx, cb_arg);
845 } else {
846 /*
847 * If the ctx has a status CB, then we have previously set an OCSP staple for this ctx
848 * Update that cb_arg with the new cert's staple
849 */
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +0200850 struct ocsp_cbk_arg *cb_arg;
yanbzhube2774d2015-12-10 15:07:30 -0500851 struct certificate_ocsp *tmp_ocsp;
852 int index;
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +0200853 int key_type;
854
855#ifdef SSL_CTX_get_tlsext_status_arg
856 SSL_CTX_ctrl(ctx, SSL_CTRL_GET_TLSEXT_STATUS_REQ_CB_ARG, 0, &cb_arg);
857#else
858 cb_arg = ctx->tlsext_status_arg;
859#endif
yanbzhube2774d2015-12-10 15:07:30 -0500860
861 /*
862 * The following few lines will convert cb_arg from a single ocsp to multi ocsp
863 * the order of operations below matter, take care when changing it
864 */
865 tmp_ocsp = cb_arg->s_ocsp;
866 index = ssl_sock_get_ocsp_arg_kt_index(cb_arg->single_kt);
867 cb_arg->s_ocsp = NULL;
868 cb_arg->m_ocsp[index] = tmp_ocsp;
869 cb_arg->is_single = 0;
870 cb_arg->single_kt = 0;
871
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +0200872 key_type = EVP_PKEY_base_id(X509_get_pubkey(x));
873 index = ssl_sock_get_ocsp_arg_kt_index(key_type);
yanbzhube2774d2015-12-10 15:07:30 -0500874 if (index >= 0 && !cb_arg->m_ocsp[index])
875 cb_arg->m_ocsp[index] = iocsp;
876
877 }
Emeric Brun4147b2e2014-06-16 18:36:30 +0200878
879 ret = 0;
880
881 warn = NULL;
882 if (ssl_sock_load_ocsp_response_from_file(ocsp_path, iocsp, cid, &warn)) {
883 memprintf(&warn, "Loading '%s': %s. Content will be ignored", ocsp_path, warn ? warn : "failure");
884 Warning("%s.\n", warn);
885 }
886
887out:
888 if (ssl)
889 SSL_free(ssl);
890
891 if (in)
892 BIO_free(in);
893
894 if (xi)
895 X509_free(xi);
896
897 if (cid)
898 OCSP_CERTID_free(cid);
899
900 if (ocsp)
901 free(ocsp);
902
903 if (warn)
904 free(warn);
905
906
907 return ret;
908}
909
910#endif
911
Daniel Jakots54ffb912015-11-06 20:02:41 +0100912#if (OPENSSL_VERSION_NUMBER >= 0x1000200fL && !defined OPENSSL_NO_TLSEXT && !defined OPENSSL_IS_BORINGSSL && !defined LIBRESSL_VERSION_NUMBER)
Janusz Dziemidowicz2c701b52015-03-07 23:03:59 +0100913
914#define CT_EXTENSION_TYPE 18
915
916static int sctl_ex_index = -1;
917
918/*
919 * Try to parse Signed Certificate Timestamp List structure. This function
920 * makes only basic test if the data seems like SCTL. No signature validation
921 * is performed.
922 */
923static int ssl_sock_parse_sctl(struct chunk *sctl)
924{
925 int ret = 1;
926 int len, pos, sct_len;
927 unsigned char *data;
928
929 if (sctl->len < 2)
930 goto out;
931
932 data = (unsigned char *)sctl->str;
933 len = (data[0] << 8) | data[1];
934
935 if (len + 2 != sctl->len)
936 goto out;
937
938 data = data + 2;
939 pos = 0;
940 while (pos < len) {
941 if (len - pos < 2)
942 goto out;
943
944 sct_len = (data[pos] << 8) | data[pos + 1];
945 if (pos + sct_len + 2 > len)
946 goto out;
947
948 pos += sct_len + 2;
949 }
950
951 ret = 0;
952
953out:
954 return ret;
955}
956
957static int ssl_sock_load_sctl_from_file(const char *sctl_path, struct chunk **sctl)
958{
959 int fd = -1;
960 int r = 0;
961 int ret = 1;
962
963 *sctl = NULL;
964
965 fd = open(sctl_path, O_RDONLY);
966 if (fd == -1)
967 goto end;
968
969 trash.len = 0;
970 while (trash.len < trash.size) {
971 r = read(fd, trash.str + trash.len, trash.size - trash.len);
972 if (r < 0) {
973 if (errno == EINTR)
974 continue;
975
976 goto end;
977 }
978 else if (r == 0) {
979 break;
980 }
981 trash.len += r;
982 }
983
984 ret = ssl_sock_parse_sctl(&trash);
985 if (ret)
986 goto end;
987
Vincent Bernat02779b62016-04-03 13:48:43 +0200988 *sctl = calloc(1, sizeof(**sctl));
Janusz Dziemidowicz2c701b52015-03-07 23:03:59 +0100989 if (!chunk_dup(*sctl, &trash)) {
990 free(*sctl);
991 *sctl = NULL;
992 goto end;
993 }
994
995end:
996 if (fd != -1)
997 close(fd);
998
999 return ret;
1000}
1001
1002int ssl_sock_sctl_add_cbk(SSL *ssl, unsigned ext_type, const unsigned char **out, size_t *outlen, int *al, void *add_arg)
1003{
Vincent Bernat3c2f2f22016-04-03 13:48:42 +02001004 struct chunk *sctl = add_arg;
Janusz Dziemidowicz2c701b52015-03-07 23:03:59 +01001005
1006 *out = (unsigned char *)sctl->str;
1007 *outlen = sctl->len;
1008
1009 return 1;
1010}
1011
1012int ssl_sock_sctl_parse_cbk(SSL *s, unsigned int ext_type, const unsigned char *in, size_t inlen, int *al, void *parse_arg)
1013{
1014 return 1;
1015}
1016
1017static int ssl_sock_load_sctl(SSL_CTX *ctx, const char *cert_path)
1018{
1019 char sctl_path[MAXPATHLEN+1];
1020 int ret = -1;
1021 struct stat st;
1022 struct chunk *sctl = NULL;
1023
1024 snprintf(sctl_path, MAXPATHLEN+1, "%s.sctl", cert_path);
1025
1026 if (stat(sctl_path, &st))
1027 return 1;
1028
1029 if (ssl_sock_load_sctl_from_file(sctl_path, &sctl))
1030 goto out;
1031
1032 if (!SSL_CTX_add_server_custom_ext(ctx, CT_EXTENSION_TYPE, ssl_sock_sctl_add_cbk, NULL, sctl, ssl_sock_sctl_parse_cbk, NULL)) {
1033 free(sctl);
1034 goto out;
1035 }
1036
1037 SSL_CTX_set_ex_data(ctx, sctl_ex_index, sctl);
1038
1039 ret = 0;
1040
1041out:
1042 return ret;
1043}
1044
1045#endif
1046
Emeric Brune1f38db2012-09-03 20:36:47 +02001047void ssl_sock_infocbk(const SSL *ssl, int where, int ret)
1048{
Vincent Bernat3c2f2f22016-04-03 13:48:42 +02001049 struct connection *conn = SSL_get_app_data(ssl);
Emeric Brund8b2bb52014-01-28 15:43:53 +01001050 BIO *write_bio;
Willy Tarreau622317d2015-02-27 16:36:16 +01001051 (void)ret; /* shut gcc stupid warning */
Emeric Brune1f38db2012-09-03 20:36:47 +02001052
1053 if (where & SSL_CB_HANDSHAKE_START) {
1054 /* Disable renegotiation (CVE-2009-3555) */
Willy Tarreau20879a02012-12-03 16:32:10 +01001055 if (conn->flags & CO_FL_CONNECTED) {
Emeric Brune1f38db2012-09-03 20:36:47 +02001056 conn->flags |= CO_FL_ERROR;
Willy Tarreau20879a02012-12-03 16:32:10 +01001057 conn->err_code = CO_ER_SSL_RENEG;
1058 }
Emeric Brune1f38db2012-09-03 20:36:47 +02001059 }
Emeric Brund8b2bb52014-01-28 15:43:53 +01001060
1061 if ((where & SSL_CB_ACCEPT_LOOP) == SSL_CB_ACCEPT_LOOP) {
1062 if (!(conn->xprt_st & SSL_SOCK_ST_FL_16K_WBFSIZE)) {
1063 /* Long certificate chains optimz
1064 If write and read bios are differents, we
1065 consider that the buffering was activated,
1066 so we rise the output buffer size from 4k
1067 to 16k */
1068 write_bio = SSL_get_wbio(ssl);
1069 if (write_bio != SSL_get_rbio(ssl)) {
1070 BIO_set_write_buffer_size(write_bio, 16384);
1071 conn->xprt_st |= SSL_SOCK_ST_FL_16K_WBFSIZE;
1072 }
1073 }
1074 }
Emeric Brunfc0421f2012-09-07 17:30:07 +02001075}
1076
Emeric Brune64aef12012-09-21 13:15:06 +02001077/* Callback is called for each certificate of the chain during a verify
1078 ok is set to 1 if preverify detect no error on current certificate.
1079 Returns 0 to break the handshake, 1 otherwise. */
Evan Broderbe554312013-06-27 00:05:25 -07001080int ssl_sock_bind_verifycbk(int ok, X509_STORE_CTX *x_store)
Emeric Brune64aef12012-09-21 13:15:06 +02001081{
1082 SSL *ssl;
1083 struct connection *conn;
Emeric Brun81c00f02012-09-21 14:31:21 +02001084 int err, depth;
Emeric Brune64aef12012-09-21 13:15:06 +02001085
1086 ssl = X509_STORE_CTX_get_ex_data(x_store, SSL_get_ex_data_X509_STORE_CTX_idx());
Vincent Bernat3c2f2f22016-04-03 13:48:42 +02001087 conn = SSL_get_app_data(ssl);
Emeric Brune64aef12012-09-21 13:15:06 +02001088
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02001089 conn->xprt_st |= SSL_SOCK_ST_FL_VERIFY_DONE;
Emeric Brune64aef12012-09-21 13:15:06 +02001090
Emeric Brun81c00f02012-09-21 14:31:21 +02001091 if (ok) /* no errors */
1092 return ok;
1093
1094 depth = X509_STORE_CTX_get_error_depth(x_store);
1095 err = X509_STORE_CTX_get_error(x_store);
1096
1097 /* check if CA error needs to be ignored */
1098 if (depth > 0) {
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02001099 if (!SSL_SOCK_ST_TO_CA_ERROR(conn->xprt_st)) {
1100 conn->xprt_st |= SSL_SOCK_CA_ERROR_TO_ST(err);
1101 conn->xprt_st |= SSL_SOCK_CAEDEPTH_TO_ST(depth);
Emeric Brunf282a812012-09-21 15:27:54 +02001102 }
1103
Emeric Brun1eb20ef2012-12-03 13:24:29 +01001104 if (objt_listener(conn->target)->bind_conf->ca_ignerr & (1ULL << err)) {
Thierry FOURNIER / OZON.IO8b068c22016-10-10 11:59:50 +02001105 ssl_sock_dump_errors(conn);
Emeric Brun1eb20ef2012-12-03 13:24:29 +01001106 ERR_clear_error();
Emeric Brun81c00f02012-09-21 14:31:21 +02001107 return 1;
Emeric Brun1eb20ef2012-12-03 13:24:29 +01001108 }
Emeric Brun81c00f02012-09-21 14:31:21 +02001109
Willy Tarreau20879a02012-12-03 16:32:10 +01001110 conn->err_code = CO_ER_SSL_CA_FAIL;
Emeric Brun81c00f02012-09-21 14:31:21 +02001111 return 0;
1112 }
1113
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02001114 if (!SSL_SOCK_ST_TO_CRTERROR(conn->xprt_st))
1115 conn->xprt_st |= SSL_SOCK_CRTERROR_TO_ST(err);
Emeric Brunf282a812012-09-21 15:27:54 +02001116
Emeric Brun81c00f02012-09-21 14:31:21 +02001117 /* check if certificate error needs to be ignored */
Emeric Brun1eb20ef2012-12-03 13:24:29 +01001118 if (objt_listener(conn->target)->bind_conf->crt_ignerr & (1ULL << err)) {
Thierry FOURNIER / OZON.IO8b068c22016-10-10 11:59:50 +02001119 ssl_sock_dump_errors(conn);
Emeric Brun1eb20ef2012-12-03 13:24:29 +01001120 ERR_clear_error();
Emeric Brun81c00f02012-09-21 14:31:21 +02001121 return 1;
Emeric Brun1eb20ef2012-12-03 13:24:29 +01001122 }
Emeric Brun81c00f02012-09-21 14:31:21 +02001123
Willy Tarreau20879a02012-12-03 16:32:10 +01001124 conn->err_code = CO_ER_SSL_CRT_FAIL;
Emeric Brun81c00f02012-09-21 14:31:21 +02001125 return 0;
Emeric Brune64aef12012-09-21 13:15:06 +02001126}
1127
Emeric Brun29f037d2014-04-25 19:05:36 +02001128/* Callback is called for ssl protocol analyse */
1129void ssl_sock_msgcbk(int write_p, int version, int content_type, const void *buf, size_t len, SSL *ssl, void *arg)
1130{
Emeric Brun29f037d2014-04-25 19:05:36 +02001131#ifdef TLS1_RT_HEARTBEAT
1132 /* test heartbeat received (write_p is set to 0
1133 for a received record) */
Willy Tarreauf51c6982014-04-25 20:02:39 +02001134 if ((content_type == TLS1_RT_HEARTBEAT) && (write_p == 0)) {
Vincent Bernat3c2f2f22016-04-03 13:48:42 +02001135 struct connection *conn = SSL_get_app_data(ssl);
Willy Tarreauf51c6982014-04-25 20:02:39 +02001136 const unsigned char *p = buf;
1137 unsigned int payload;
1138
Emeric Brun29f037d2014-04-25 19:05:36 +02001139 conn->xprt_st |= SSL_SOCK_RECV_HEARTBEAT;
Willy Tarreauf51c6982014-04-25 20:02:39 +02001140
1141 /* Check if this is a CVE-2014-0160 exploitation attempt. */
1142 if (*p != TLS1_HB_REQUEST)
1143 return;
1144
Willy Tarreauaeed6722014-04-25 23:59:58 +02001145 if (len < 1 + 2 + 16) /* 1 type + 2 size + 0 payload + 16 padding */
Willy Tarreauf51c6982014-04-25 20:02:39 +02001146 goto kill_it;
1147
1148 payload = (p[1] * 256) + p[2];
Willy Tarreau3b2fdb62014-04-25 23:44:22 +02001149 if (3 + payload + 16 <= len)
Willy Tarreauf51c6982014-04-25 20:02:39 +02001150 return; /* OK no problem */
Willy Tarreauaeed6722014-04-25 23:59:58 +02001151 kill_it:
Willy Tarreau3b2fdb62014-04-25 23:44:22 +02001152 /* We have a clear heartbleed attack (CVE-2014-0160), the
1153 * advertised payload is larger than the advertised packet
1154 * length, so we have garbage in the buffer between the
1155 * payload and the end of the buffer (p+len). We can't know
1156 * if the SSL stack is patched, and we don't know if we can
1157 * safely wipe out the area between p+3+len and payload.
1158 * So instead, we prevent the response from being sent by
1159 * setting the max_send_fragment to 0 and we report an SSL
1160 * error, which will kill this connection. It will be reported
1161 * above as SSL_ERROR_SSL while an other handshake failure with
Willy Tarreauf51c6982014-04-25 20:02:39 +02001162 * a heartbeat message will be reported as SSL_ERROR_SYSCALL.
1163 */
Willy Tarreau3b2fdb62014-04-25 23:44:22 +02001164 ssl->max_send_fragment = 0;
Willy Tarreauf51c6982014-04-25 20:02:39 +02001165 SSLerr(SSL_F_TLS1_HEARTBEAT, SSL_R_SSL_HANDSHAKE_FAILURE);
1166 return;
1167 }
Emeric Brun29f037d2014-04-25 19:05:36 +02001168#endif
1169}
1170
Willy Tarreau6c9a3d52012-10-18 18:57:14 +02001171#ifdef OPENSSL_NPN_NEGOTIATED
1172/* This callback is used so that the server advertises the list of
1173 * negociable protocols for NPN.
1174 */
1175static int ssl_sock_advertise_npn_protos(SSL *s, const unsigned char **data,
1176 unsigned int *len, void *arg)
1177{
1178 struct bind_conf *conf = arg;
1179
1180 *data = (const unsigned char *)conf->npn_str;
1181 *len = conf->npn_len;
1182 return SSL_TLSEXT_ERR_OK;
1183}
1184#endif
1185
Dirkjan Bussink48f1c4e2014-02-13 12:29:42 +01001186#ifdef TLSEXT_TYPE_application_layer_protocol_negotiation
Willy Tarreauab861d32013-04-02 02:30:41 +02001187/* This callback is used so that the server advertises the list of
1188 * negociable protocols for ALPN.
1189 */
Dirkjan Bussink48f1c4e2014-02-13 12:29:42 +01001190static int ssl_sock_advertise_alpn_protos(SSL *s, const unsigned char **out,
1191 unsigned char *outlen,
1192 const unsigned char *server,
1193 unsigned int server_len, void *arg)
Willy Tarreauab861d32013-04-02 02:30:41 +02001194{
1195 struct bind_conf *conf = arg;
1196
Dirkjan Bussink48f1c4e2014-02-13 12:29:42 +01001197 if (SSL_select_next_proto((unsigned char**) out, outlen, (const unsigned char *)conf->alpn_str,
1198 conf->alpn_len, server, server_len) != OPENSSL_NPN_NEGOTIATED) {
1199 return SSL_TLSEXT_ERR_NOACK;
1200 }
Willy Tarreauab861d32013-04-02 02:30:41 +02001201 return SSL_TLSEXT_ERR_OK;
1202}
1203#endif
1204
Willy Tarreauc8ad3be2015-06-17 15:48:26 +02001205#ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME
Christopher Faulet85b5a1a2015-10-09 11:46:32 +02001206static DH *ssl_get_tmp_dh(SSL *ssl, int export, int keylen);
1207
Christopher Faulet30548802015-06-11 13:39:32 +02001208/* Create a X509 certificate with the specified servername and serial. This
1209 * function returns a SSL_CTX object or NULL if an error occurs. */
Christopher Faulet7969a332015-10-09 11:15:03 +02001210static SSL_CTX *
Christopher Faulet635c0ad2015-11-12 11:35:51 +01001211ssl_sock_do_create_cert(const char *servername, struct bind_conf *bind_conf, SSL *ssl)
Christopher Faulet31af49d2015-06-09 17:29:50 +02001212{
Christopher Faulet635c0ad2015-11-12 11:35:51 +01001213 static unsigned int serial = 0;
1214
Christopher Faulet7969a332015-10-09 11:15:03 +02001215 X509 *cacert = bind_conf->ca_sign_cert;
1216 EVP_PKEY *capkey = bind_conf->ca_sign_pkey;
Christopher Faulet31af49d2015-06-09 17:29:50 +02001217 SSL_CTX *ssl_ctx = NULL;
1218 X509 *newcrt = NULL;
1219 EVP_PKEY *pkey = NULL;
Christopher Faulet31af49d2015-06-09 17:29:50 +02001220 X509_NAME *name;
1221 const EVP_MD *digest;
1222 X509V3_CTX ctx;
1223 unsigned int i;
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02001224 int key_type;
Christopher Faulet31af49d2015-06-09 17:29:50 +02001225
Christopher Faulet7969a332015-10-09 11:15:03 +02001226 /* Get the private key of the defautl certificate and use it */
1227 if (!(pkey = SSL_get_privatekey(ssl)))
Christopher Faulet31af49d2015-06-09 17:29:50 +02001228 goto mkcert_error;
1229
1230 /* Create the certificate */
1231 if (!(newcrt = X509_new()))
1232 goto mkcert_error;
1233
1234 /* Set version number for the certificate (X509v3) and the serial
1235 * number */
1236 if (X509_set_version(newcrt, 2L) != 1)
1237 goto mkcert_error;
Christopher Faulet635c0ad2015-11-12 11:35:51 +01001238 if (!serial)
1239 serial = now_ms;
1240 ASN1_INTEGER_set(X509_get_serialNumber(newcrt), serial++);
Christopher Faulet31af49d2015-06-09 17:29:50 +02001241
1242 /* Set duration for the certificate */
1243 if (!X509_gmtime_adj(X509_get_notBefore(newcrt), (long)-60*60*24) ||
1244 !X509_gmtime_adj(X509_get_notAfter(newcrt),(long)60*60*24*365))
1245 goto mkcert_error;
1246
1247 /* set public key in the certificate */
1248 if (X509_set_pubkey(newcrt, pkey) != 1)
1249 goto mkcert_error;
1250
1251 /* Set issuer name from the CA */
1252 if (!(name = X509_get_subject_name(cacert)))
1253 goto mkcert_error;
1254 if (X509_set_issuer_name(newcrt, name) != 1)
1255 goto mkcert_error;
1256
1257 /* Set the subject name using the same, but the CN */
1258 name = X509_NAME_dup(name);
1259 if (X509_NAME_add_entry_by_txt(name, "CN", MBSTRING_ASC,
1260 (const unsigned char *)servername,
1261 -1, -1, 0) != 1) {
1262 X509_NAME_free(name);
1263 goto mkcert_error;
1264 }
1265 if (X509_set_subject_name(newcrt, name) != 1) {
1266 X509_NAME_free(name);
1267 goto mkcert_error;
1268 }
1269 X509_NAME_free(name);
1270
1271 /* Add x509v3 extensions as specified */
1272 X509V3_set_ctx(&ctx, cacert, newcrt, NULL, NULL, 0);
1273 for (i = 0; i < X509V3_EXT_SIZE; i++) {
1274 X509_EXTENSION *ext;
1275
1276 if (!(ext = X509V3_EXT_conf(NULL, &ctx, x509v3_ext_names[i], x509v3_ext_values[i])))
1277 goto mkcert_error;
1278 if (!X509_add_ext(newcrt, ext, -1)) {
1279 X509_EXTENSION_free(ext);
1280 goto mkcert_error;
1281 }
1282 X509_EXTENSION_free(ext);
1283 }
1284
1285 /* Sign the certificate with the CA private key */
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02001286
1287 key_type = EVP_PKEY_base_id(capkey);
1288
1289 if (key_type == EVP_PKEY_DSA)
1290 digest = EVP_sha1();
1291 else if (key_type == EVP_PKEY_RSA)
Christopher Faulet31af49d2015-06-09 17:29:50 +02001292 digest = EVP_sha256();
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02001293 else if (key_type == EVP_PKEY_EC)
Christopher Faulet7969a332015-10-09 11:15:03 +02001294 digest = EVP_sha256();
1295 else {
Christopher Faulete7db2162015-10-19 13:59:24 +02001296#if (OPENSSL_VERSION_NUMBER >= 0x1000000fL)
Christopher Faulet7969a332015-10-09 11:15:03 +02001297 int nid;
1298
1299 if (EVP_PKEY_get_default_digest_nid(capkey, &nid) <= 0)
1300 goto mkcert_error;
1301 if (!(digest = EVP_get_digestbynid(nid)))
1302 goto mkcert_error;
Christopher Faulete7db2162015-10-19 13:59:24 +02001303#else
1304 goto mkcert_error;
1305#endif
Christopher Faulet7969a332015-10-09 11:15:03 +02001306 }
1307
Christopher Faulet31af49d2015-06-09 17:29:50 +02001308 if (!(X509_sign(newcrt, capkey, digest)))
1309 goto mkcert_error;
1310
1311 /* Create and set the new SSL_CTX */
1312 if (!(ssl_ctx = SSL_CTX_new(SSLv23_server_method())))
1313 goto mkcert_error;
1314 if (!SSL_CTX_use_PrivateKey(ssl_ctx, pkey))
1315 goto mkcert_error;
1316 if (!SSL_CTX_use_certificate(ssl_ctx, newcrt))
1317 goto mkcert_error;
1318 if (!SSL_CTX_check_private_key(ssl_ctx))
1319 goto mkcert_error;
1320
1321 if (newcrt) X509_free(newcrt);
Christopher Faulet7969a332015-10-09 11:15:03 +02001322
Christopher Faulet85b5a1a2015-10-09 11:46:32 +02001323 SSL_CTX_set_tmp_dh_callback(ssl_ctx, ssl_get_tmp_dh);
1324#if defined(SSL_CTX_set_tmp_ecdh) && !defined(OPENSSL_NO_ECDH)
1325 {
1326 const char *ecdhe = (bind_conf->ecdhe ? bind_conf->ecdhe : ECDHE_DEFAULT_CURVE);
1327 EC_KEY *ecc;
1328 int nid;
1329
1330 if ((nid = OBJ_sn2nid(ecdhe)) == NID_undef)
1331 goto end;
1332 if (!(ecc = EC_KEY_new_by_curve_name(nid)))
1333 goto end;
1334 SSL_CTX_set_tmp_ecdh(ssl_ctx, ecc);
1335 EC_KEY_free(ecc);
1336 }
1337#endif
1338 end:
Christopher Faulet31af49d2015-06-09 17:29:50 +02001339 return ssl_ctx;
1340
1341 mkcert_error:
1342 if (ssl_ctx) SSL_CTX_free(ssl_ctx);
1343 if (newcrt) X509_free(newcrt);
Christopher Faulet31af49d2015-06-09 17:29:50 +02001344 return NULL;
1345}
1346
Christopher Faulet7969a332015-10-09 11:15:03 +02001347SSL_CTX *
Christopher Faulet635c0ad2015-11-12 11:35:51 +01001348ssl_sock_create_cert(struct connection *conn, const char *servername, unsigned int key)
Christopher Faulet7969a332015-10-09 11:15:03 +02001349{
1350 struct bind_conf *bind_conf = objt_listener(conn->target)->bind_conf;
Christopher Faulet635c0ad2015-11-12 11:35:51 +01001351
1352 return ssl_sock_do_create_cert(servername, bind_conf, conn->xprt_ctx);
Christopher Faulet7969a332015-10-09 11:15:03 +02001353}
1354
Christopher Faulet30548802015-06-11 13:39:32 +02001355/* Do a lookup for a certificate in the LRU cache used to store generated
1356 * certificates. */
1357SSL_CTX *
Christopher Faulet635c0ad2015-11-12 11:35:51 +01001358ssl_sock_get_generated_cert(unsigned int key, struct bind_conf *bind_conf)
Christopher Faulet30548802015-06-11 13:39:32 +02001359{
1360 struct lru64 *lru = NULL;
1361
1362 if (ssl_ctx_lru_tree) {
Christopher Faulet635c0ad2015-11-12 11:35:51 +01001363 lru = lru64_lookup(key, ssl_ctx_lru_tree, bind_conf->ca_sign_cert, 0);
Christopher Faulet30548802015-06-11 13:39:32 +02001364 if (lru && lru->domain)
1365 return (SSL_CTX *)lru->data;
1366 }
1367 return NULL;
1368}
1369
Christopher Fauletd2cab922015-07-28 16:03:47 +02001370/* Set a certificate int the LRU cache used to store generated
1371 * certificate. Return 0 on success, otherwise -1 */
1372int
Christopher Faulet635c0ad2015-11-12 11:35:51 +01001373ssl_sock_set_generated_cert(SSL_CTX *ssl_ctx, unsigned int key, struct bind_conf *bind_conf)
Christopher Faulet30548802015-06-11 13:39:32 +02001374{
1375 struct lru64 *lru = NULL;
1376
1377 if (ssl_ctx_lru_tree) {
Christopher Faulet635c0ad2015-11-12 11:35:51 +01001378 lru = lru64_get(key, ssl_ctx_lru_tree, bind_conf->ca_sign_cert, 0);
Christopher Faulet30548802015-06-11 13:39:32 +02001379 if (!lru)
Christopher Fauletd2cab922015-07-28 16:03:47 +02001380 return -1;
Christopher Faulet30548802015-06-11 13:39:32 +02001381 if (lru->domain && lru->data)
1382 lru->free((SSL_CTX *)lru->data);
Christopher Faulet7969a332015-10-09 11:15:03 +02001383 lru64_commit(lru, ssl_ctx, bind_conf->ca_sign_cert, 0, (void (*)(void *))SSL_CTX_free);
Christopher Fauletd2cab922015-07-28 16:03:47 +02001384 return 0;
Christopher Faulet30548802015-06-11 13:39:32 +02001385 }
Christopher Fauletd2cab922015-07-28 16:03:47 +02001386 return -1;
Christopher Faulet30548802015-06-11 13:39:32 +02001387}
1388
Christopher Faulet635c0ad2015-11-12 11:35:51 +01001389/* Compute the key of the certificate. */
Christopher Faulet30548802015-06-11 13:39:32 +02001390unsigned int
Christopher Faulet635c0ad2015-11-12 11:35:51 +01001391ssl_sock_generated_cert_key(const void *data, size_t len)
Christopher Faulet30548802015-06-11 13:39:32 +02001392{
1393 return XXH32(data, len, ssl_ctx_lru_seed);
1394}
1395
Willy Tarreau2f63ef42015-10-20 15:16:01 +02001396/* Generate a cert and immediately assign it to the SSL session so that the cert's
1397 * refcount is maintained regardless of the cert's presence in the LRU cache.
1398 */
Christopher Faulet31af49d2015-06-09 17:29:50 +02001399static SSL_CTX *
Christopher Faulet7969a332015-10-09 11:15:03 +02001400ssl_sock_generate_certificate(const char *servername, struct bind_conf *bind_conf, SSL *ssl)
Christopher Faulet31af49d2015-06-09 17:29:50 +02001401{
1402 X509 *cacert = bind_conf->ca_sign_cert;
Christopher Faulet31af49d2015-06-09 17:29:50 +02001403 SSL_CTX *ssl_ctx = NULL;
1404 struct lru64 *lru = NULL;
Christopher Faulet635c0ad2015-11-12 11:35:51 +01001405 unsigned int key;
Christopher Faulet31af49d2015-06-09 17:29:50 +02001406
Christopher Faulet635c0ad2015-11-12 11:35:51 +01001407 key = ssl_sock_generated_cert_key(servername, strlen(servername));
Christopher Faulet31af49d2015-06-09 17:29:50 +02001408 if (ssl_ctx_lru_tree) {
Christopher Faulet635c0ad2015-11-12 11:35:51 +01001409 lru = lru64_get(key, ssl_ctx_lru_tree, cacert, 0);
Christopher Faulet31af49d2015-06-09 17:29:50 +02001410 if (lru && lru->domain)
1411 ssl_ctx = (SSL_CTX *)lru->data;
Christopher Fauletd2cab922015-07-28 16:03:47 +02001412 if (!ssl_ctx && lru) {
Christopher Faulet635c0ad2015-11-12 11:35:51 +01001413 ssl_ctx = ssl_sock_do_create_cert(servername, bind_conf, ssl);
Christopher Faulet31af49d2015-06-09 17:29:50 +02001414 lru64_commit(lru, ssl_ctx, cacert, 0, (void (*)(void *))SSL_CTX_free);
Christopher Fauletd2cab922015-07-28 16:03:47 +02001415 }
Willy Tarreau2f63ef42015-10-20 15:16:01 +02001416 SSL_set_SSL_CTX(ssl, ssl_ctx);
Christopher Faulet31af49d2015-06-09 17:29:50 +02001417 }
Willy Tarreau2f63ef42015-10-20 15:16:01 +02001418 else {
Christopher Faulet635c0ad2015-11-12 11:35:51 +01001419 ssl_ctx = ssl_sock_do_create_cert(servername, bind_conf, ssl);
Willy Tarreau2f63ef42015-10-20 15:16:01 +02001420 SSL_set_SSL_CTX(ssl, ssl_ctx);
1421 /* No LRU cache, this CTX will be released as soon as the session dies */
1422 SSL_CTX_free(ssl_ctx);
1423 }
Christopher Faulet31af49d2015-06-09 17:29:50 +02001424 return ssl_ctx;
1425}
1426
Emeric Brunfc0421f2012-09-07 17:30:07 +02001427/* Sets the SSL ctx of <ssl> to match the advertised server name. Returns a
1428 * warning when no match is found, which implies the default (first) cert
1429 * will keep being used.
1430 */
Willy Tarreau2a65ff02012-09-13 17:54:29 +02001431static int ssl_sock_switchctx_cbk(SSL *ssl, int *al, struct bind_conf *s)
Emeric Brunfc0421f2012-09-07 17:30:07 +02001432{
1433 const char *servername;
1434 const char *wildp = NULL;
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +02001435 struct ebmb_node *node, *n;
Emeric Brunfc0421f2012-09-07 17:30:07 +02001436 int i;
1437 (void)al; /* shut gcc stupid warning */
1438
1439 servername = SSL_get_servername(ssl, TLSEXT_NAMETYPE_host_name);
Emmanuel Hocdet65623372013-01-24 17:17:15 +01001440 if (!servername) {
Willy Tarreauf6721452015-07-07 18:04:38 +02001441 if (s->generate_certs) {
Vincent Bernat3c2f2f22016-04-03 13:48:42 +02001442 struct connection *conn = SSL_get_app_data(ssl);
Christopher Faulet635c0ad2015-11-12 11:35:51 +01001443 unsigned int key;
Willy Tarreauf6721452015-07-07 18:04:38 +02001444 SSL_CTX *ctx;
Christopher Faulet30548802015-06-11 13:39:32 +02001445
Willy Tarreauf6721452015-07-07 18:04:38 +02001446 conn_get_to_addr(conn);
1447 if (conn->flags & CO_FL_ADDR_TO_SET) {
Christopher Faulet635c0ad2015-11-12 11:35:51 +01001448 key = ssl_sock_generated_cert_key(&conn->addr.to, get_addr_len(&conn->addr.to));
1449 ctx = ssl_sock_get_generated_cert(key, s);
Willy Tarreauf6721452015-07-07 18:04:38 +02001450 if (ctx) {
1451 /* switch ctx */
1452 SSL_set_SSL_CTX(ssl, ctx);
1453 return SSL_TLSEXT_ERR_OK;
1454 }
Christopher Faulet30548802015-06-11 13:39:32 +02001455 }
1456 }
1457
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +02001458 return (s->strict_sni ?
1459 SSL_TLSEXT_ERR_ALERT_FATAL :
Emmanuel Hocdet79274e22013-05-31 12:47:44 +02001460 SSL_TLSEXT_ERR_NOACK);
Emmanuel Hocdet65623372013-01-24 17:17:15 +01001461 }
Emeric Brunfc0421f2012-09-07 17:30:07 +02001462
Willy Tarreau19d14ef2012-10-29 16:51:55 +01001463 for (i = 0; i < trash.size; i++) {
Emeric Brunfc0421f2012-09-07 17:30:07 +02001464 if (!servername[i])
1465 break;
Willy Tarreau19d14ef2012-10-29 16:51:55 +01001466 trash.str[i] = tolower(servername[i]);
1467 if (!wildp && (trash.str[i] == '.'))
1468 wildp = &trash.str[i];
Emeric Brunfc0421f2012-09-07 17:30:07 +02001469 }
Willy Tarreau19d14ef2012-10-29 16:51:55 +01001470 trash.str[i] = 0;
Emeric Brunfc0421f2012-09-07 17:30:07 +02001471
1472 /* lookup in full qualified names */
Willy Tarreau19d14ef2012-10-29 16:51:55 +01001473 node = ebst_lookup(&s->sni_ctx, trash.str);
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +02001474
1475 /* lookup a not neg filter */
1476 for (n = node; n; n = ebmb_next_dup(n)) {
1477 if (!container_of(n, struct sni_ctx, name)->neg) {
1478 node = n;
1479 break;
Emmanuel Hocdet65623372013-01-24 17:17:15 +01001480 }
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +02001481 }
1482 if (!node && wildp) {
1483 /* lookup in wildcards names */
Emeric Brunfc0421f2012-09-07 17:30:07 +02001484 node = ebst_lookup(&s->sni_w_ctx, wildp);
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +02001485 }
1486 if (!node || container_of(node, struct sni_ctx, name)->neg) {
Christopher Faulet31af49d2015-06-09 17:29:50 +02001487 SSL_CTX *ctx;
Christopher Faulet31af49d2015-06-09 17:29:50 +02001488 if (s->generate_certs &&
Christopher Faulet7969a332015-10-09 11:15:03 +02001489 (ctx = ssl_sock_generate_certificate(servername, s, ssl))) {
Christopher Faulet31af49d2015-06-09 17:29:50 +02001490 /* switch ctx */
Christopher Faulet31af49d2015-06-09 17:29:50 +02001491 return SSL_TLSEXT_ERR_OK;
1492 }
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +02001493 return (s->strict_sni ?
1494 SSL_TLSEXT_ERR_ALERT_FATAL :
1495 SSL_TLSEXT_ERR_ALERT_WARNING);
Emeric Brunfc0421f2012-09-07 17:30:07 +02001496 }
1497
1498 /* switch ctx */
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +02001499 SSL_set_SSL_CTX(ssl, container_of(node, struct sni_ctx, name)->ctx);
Emeric Brunfc0421f2012-09-07 17:30:07 +02001500 return SSL_TLSEXT_ERR_OK;
1501}
1502#endif /* SSL_CTRL_SET_TLSEXT_HOSTNAME */
1503
Emeric Bruna4bcd9a2012-09-20 16:19:02 +02001504#ifndef OPENSSL_NO_DH
Remi Gacognef46cd6e2014-06-12 14:58:40 +02001505
1506static DH * ssl_get_dh_1024(void)
1507{
Remi Gacogned3a341a2015-05-29 16:26:17 +02001508 static unsigned char dh1024_p[]={
1509 0xFA,0xF9,0x2A,0x22,0x2A,0xA7,0x7F,0xE1,0x67,0x4E,0x53,0xF7,
1510 0x56,0x13,0xC3,0xB1,0xE3,0x29,0x6B,0x66,0x31,0x6A,0x7F,0xB3,
1511 0xC2,0x68,0x6B,0xCB,0x1D,0x57,0x39,0x1D,0x1F,0xFF,0x1C,0xC9,
1512 0xA6,0xA4,0x98,0x82,0x31,0x5D,0x25,0xFF,0x8A,0xE0,0x73,0x96,
1513 0x81,0xC8,0x83,0x79,0xC1,0x5A,0x04,0xF8,0x37,0x0D,0xA8,0x3D,
1514 0xAE,0x74,0xBC,0xDB,0xB6,0xA4,0x75,0xD9,0x71,0x8A,0xA0,0x17,
1515 0x9E,0x2D,0xC8,0xA8,0xDF,0x2C,0x5F,0x82,0x95,0xF8,0x92,0x9B,
1516 0xA7,0x33,0x5F,0x89,0x71,0xC8,0x2D,0x6B,0x18,0x86,0xC4,0x94,
1517 0x22,0xA5,0x52,0x8D,0xF6,0xF6,0xD2,0x37,0x92,0x0F,0xA5,0xCC,
1518 0xDB,0x7B,0x1D,0x3D,0xA1,0x31,0xB7,0x80,0x8F,0x0B,0x67,0x5E,
1519 0x36,0xA5,0x60,0x0C,0xF1,0x95,0x33,0x8B,
1520 };
1521 static unsigned char dh1024_g[]={
1522 0x02,
1523 };
1524
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02001525 BIGNUM *p;
1526 BIGNUM *g;
Remi Gacognef46cd6e2014-06-12 14:58:40 +02001527 DH *dh = DH_new();
1528 if (dh) {
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02001529 p = BN_bin2bn(dh1024_p, sizeof dh1024_p, NULL);
1530 g = BN_bin2bn(dh1024_g, sizeof dh1024_g, NULL);
Remi Gacogned3a341a2015-05-29 16:26:17 +02001531
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02001532 if (!p || !g) {
Remi Gacognef46cd6e2014-06-12 14:58:40 +02001533 DH_free(dh);
1534 dh = NULL;
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02001535 } else {
1536 DH_set0_pqg(dh, p, NULL, g);
Remi Gacognef46cd6e2014-06-12 14:58:40 +02001537 }
1538 }
1539 return dh;
1540}
1541
1542static DH *ssl_get_dh_2048(void)
1543{
Remi Gacogned3a341a2015-05-29 16:26:17 +02001544 static unsigned char dh2048_p[]={
1545 0xEC,0x86,0xF8,0x70,0xA0,0x33,0x16,0xEC,0x05,0x1A,0x73,0x59,
1546 0xCD,0x1F,0x8B,0xF8,0x29,0xE4,0xD2,0xCF,0x52,0xDD,0xC2,0x24,
1547 0x8D,0xB5,0x38,0x9A,0xFB,0x5C,0xA4,0xE4,0xB2,0xDA,0xCE,0x66,
1548 0x50,0x74,0xA6,0x85,0x4D,0x4B,0x1D,0x30,0xB8,0x2B,0xF3,0x10,
1549 0xE9,0xA7,0x2D,0x05,0x71,0xE7,0x81,0xDF,0x8B,0x59,0x52,0x3B,
1550 0x5F,0x43,0x0B,0x68,0xF1,0xDB,0x07,0xBE,0x08,0x6B,0x1B,0x23,
1551 0xEE,0x4D,0xCC,0x9E,0x0E,0x43,0xA0,0x1E,0xDF,0x43,0x8C,0xEC,
1552 0xBE,0xBE,0x90,0xB4,0x51,0x54,0xB9,0x2F,0x7B,0x64,0x76,0x4E,
1553 0x5D,0xD4,0x2E,0xAE,0xC2,0x9E,0xAE,0x51,0x43,0x59,0xC7,0x77,
1554 0x9C,0x50,0x3C,0x0E,0xED,0x73,0x04,0x5F,0xF1,0x4C,0x76,0x2A,
1555 0xD8,0xF8,0xCF,0xFC,0x34,0x40,0xD1,0xB4,0x42,0x61,0x84,0x66,
1556 0x42,0x39,0x04,0xF8,0x68,0xB2,0x62,0xD7,0x55,0xED,0x1B,0x74,
1557 0x75,0x91,0xE0,0xC5,0x69,0xC1,0x31,0x5C,0xDB,0x7B,0x44,0x2E,
1558 0xCE,0x84,0x58,0x0D,0x1E,0x66,0x0C,0xC8,0x44,0x9E,0xFD,0x40,
1559 0x08,0x67,0x5D,0xFB,0xA7,0x76,0x8F,0x00,0x11,0x87,0xE9,0x93,
1560 0xF9,0x7D,0xC4,0xBC,0x74,0x55,0x20,0xD4,0x4A,0x41,0x2F,0x43,
1561 0x42,0x1A,0xC1,0xF2,0x97,0x17,0x49,0x27,0x37,0x6B,0x2F,0x88,
1562 0x7E,0x1C,0xA0,0xA1,0x89,0x92,0x27,0xD9,0x56,0x5A,0x71,0xC1,
1563 0x56,0x37,0x7E,0x3A,0x9D,0x05,0xE7,0xEE,0x5D,0x8F,0x82,0x17,
1564 0xBC,0xE9,0xC2,0x93,0x30,0x82,0xF9,0xF4,0xC9,0xAE,0x49,0xDB,
1565 0xD0,0x54,0xB4,0xD9,0x75,0x4D,0xFA,0x06,0xB8,0xD6,0x38,0x41,
1566 0xB7,0x1F,0x77,0xF3,
1567 };
1568 static unsigned char dh2048_g[]={
1569 0x02,
1570 };
1571
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02001572 BIGNUM *p;
1573 BIGNUM *g;
Remi Gacognef46cd6e2014-06-12 14:58:40 +02001574 DH *dh = DH_new();
1575 if (dh) {
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02001576 p = BN_bin2bn(dh2048_p, sizeof dh2048_p, NULL);
1577 g = BN_bin2bn(dh2048_g, sizeof dh2048_g, NULL);
Remi Gacogned3a341a2015-05-29 16:26:17 +02001578
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02001579 if (!p || !g) {
Remi Gacognef46cd6e2014-06-12 14:58:40 +02001580 DH_free(dh);
1581 dh = NULL;
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02001582 } else {
1583 DH_set0_pqg(dh, p, NULL, g);
Remi Gacognef46cd6e2014-06-12 14:58:40 +02001584 }
1585 }
1586 return dh;
1587}
1588
1589static DH *ssl_get_dh_4096(void)
1590{
Remi Gacogned3a341a2015-05-29 16:26:17 +02001591 static unsigned char dh4096_p[]={
1592 0xDE,0x16,0x94,0xCD,0x99,0x58,0x07,0xF1,0xF7,0x32,0x96,0x11,
1593 0x04,0x82,0xD4,0x84,0x72,0x80,0x99,0x06,0xCA,0xF0,0xA3,0x68,
1594 0x07,0xCE,0x64,0x50,0xE7,0x74,0x45,0x20,0x80,0x5E,0x4D,0xAD,
1595 0xA5,0xB6,0xED,0xFA,0x80,0x6C,0x3B,0x35,0xC4,0x9A,0x14,0x6B,
1596 0x32,0xBB,0xFD,0x1F,0x17,0x8E,0xB7,0x1F,0xD6,0xFA,0x3F,0x7B,
1597 0xEE,0x16,0xA5,0x62,0x33,0x0D,0xED,0xBC,0x4E,0x58,0xE5,0x47,
1598 0x4D,0xE9,0xAB,0x8E,0x38,0xD3,0x6E,0x90,0x57,0xE3,0x22,0x15,
1599 0x33,0xBD,0xF6,0x43,0x45,0xB5,0x10,0x0A,0xBE,0x2C,0xB4,0x35,
1600 0xB8,0x53,0x8D,0xAD,0xFB,0xA7,0x1F,0x85,0x58,0x41,0x7A,0x79,
1601 0x20,0x68,0xB3,0xE1,0x3D,0x08,0x76,0xBF,0x86,0x0D,0x49,0xE3,
1602 0x82,0x71,0x8C,0xB4,0x8D,0x81,0x84,0xD4,0xE7,0xBE,0x91,0xDC,
1603 0x26,0x39,0x48,0x0F,0x35,0xC4,0xCA,0x65,0xE3,0x40,0x93,0x52,
1604 0x76,0x58,0x7D,0xDD,0x51,0x75,0xDC,0x69,0x61,0xBF,0x47,0x2C,
1605 0x16,0x68,0x2D,0xC9,0x29,0xD3,0xE6,0xC0,0x99,0x48,0xA0,0x9A,
1606 0xC8,0x78,0xC0,0x6D,0x81,0x67,0x12,0x61,0x3F,0x71,0xBA,0x41,
1607 0x1F,0x6C,0x89,0x44,0x03,0xBA,0x3B,0x39,0x60,0xAA,0x28,0x55,
1608 0x59,0xAE,0xB8,0xFA,0xCB,0x6F,0xA5,0x1A,0xF7,0x2B,0xDD,0x52,
1609 0x8A,0x8B,0xE2,0x71,0xA6,0x5E,0x7E,0xD8,0x2E,0x18,0xE0,0x66,
1610 0xDF,0xDD,0x22,0x21,0x99,0x52,0x73,0xA6,0x33,0x20,0x65,0x0E,
1611 0x53,0xE7,0x6B,0x9B,0xC5,0xA3,0x2F,0x97,0x65,0x76,0xD3,0x47,
1612 0x23,0x77,0x12,0xB6,0x11,0x7B,0x24,0xED,0xF1,0xEF,0xC0,0xE2,
1613 0xA3,0x7E,0x67,0x05,0x3E,0x96,0x4D,0x45,0xC2,0x18,0xD1,0x73,
1614 0x9E,0x07,0xF3,0x81,0x6E,0x52,0x63,0xF6,0x20,0x76,0xB9,0x13,
1615 0xD2,0x65,0x30,0x18,0x16,0x09,0x16,0x9E,0x8F,0xF1,0xD2,0x10,
1616 0x5A,0xD3,0xD4,0xAF,0x16,0x61,0xDA,0x55,0x2E,0x18,0x5E,0x14,
1617 0x08,0x54,0x2E,0x2A,0x25,0xA2,0x1A,0x9B,0x8B,0x32,0xA9,0xFD,
1618 0xC2,0x48,0x96,0xE1,0x80,0xCA,0xE9,0x22,0x17,0xBB,0xCE,0x3E,
1619 0x9E,0xED,0xC7,0xF1,0x1F,0xEC,0x17,0x21,0xDC,0x7B,0x82,0x48,
1620 0x8E,0xBB,0x4B,0x9D,0x5B,0x04,0x04,0xDA,0xDB,0x39,0xDF,0x01,
1621 0x40,0xC3,0xAA,0x26,0x23,0x89,0x75,0xC6,0x0B,0xD0,0xA2,0x60,
1622 0x6A,0xF1,0xCC,0x65,0x18,0x98,0x1B,0x52,0xD2,0x74,0x61,0xCC,
1623 0xBD,0x60,0xAE,0xA3,0xA0,0x66,0x6A,0x16,0x34,0x92,0x3F,0x41,
1624 0x40,0x31,0x29,0xC0,0x2C,0x63,0xB2,0x07,0x8D,0xEB,0x94,0xB8,
1625 0xE8,0x47,0x92,0x52,0x93,0x6A,0x1B,0x7E,0x1A,0x61,0xB3,0x1B,
1626 0xF0,0xD6,0x72,0x9B,0xF1,0xB0,0xAF,0xBF,0x3E,0x65,0xEF,0x23,
1627 0x1D,0x6F,0xFF,0x70,0xCD,0x8A,0x4C,0x8A,0xA0,0x72,0x9D,0xBE,
1628 0xD4,0xBB,0x24,0x47,0x4A,0x68,0xB5,0xF5,0xC6,0xD5,0x7A,0xCD,
1629 0xCA,0x06,0x41,0x07,0xAD,0xC2,0x1E,0xE6,0x54,0xA7,0xAD,0x03,
1630 0xD9,0x12,0xC1,0x9C,0x13,0xB1,0xC9,0x0A,0x43,0x8E,0x1E,0x08,
1631 0xCE,0x50,0x82,0x73,0x5F,0xA7,0x55,0x1D,0xD9,0x59,0xAC,0xB5,
1632 0xEA,0x02,0x7F,0x6C,0x5B,0x74,0x96,0x98,0x67,0x24,0xA3,0x0F,
1633 0x15,0xFC,0xA9,0x7D,0x3E,0x67,0xD1,0x70,0xF8,0x97,0xF3,0x67,
1634 0xC5,0x8C,0x88,0x44,0x08,0x02,0xC7,0x2B,
Remi Gacognef46cd6e2014-06-12 14:58:40 +02001635 };
Remi Gacogned3a341a2015-05-29 16:26:17 +02001636 static unsigned char dh4096_g[]={
1637 0x02,
1638 };
Remi Gacognef46cd6e2014-06-12 14:58:40 +02001639
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02001640 BIGNUM *p;
1641 BIGNUM *g;
Remi Gacognef46cd6e2014-06-12 14:58:40 +02001642 DH *dh = DH_new();
1643 if (dh) {
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02001644 p = BN_bin2bn(dh4096_p, sizeof dh4096_p, NULL);
1645 g = BN_bin2bn(dh4096_g, sizeof dh4096_g, NULL);
Remi Gacogned3a341a2015-05-29 16:26:17 +02001646
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02001647 if (!p || !g) {
Remi Gacognef46cd6e2014-06-12 14:58:40 +02001648 DH_free(dh);
1649 dh = NULL;
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02001650 } else {
1651 DH_set0_pqg(dh, p, NULL, g);
Remi Gacognef46cd6e2014-06-12 14:58:40 +02001652 }
1653 }
1654 return dh;
1655}
1656
1657/* Returns Diffie-Hellman parameters matching the private key length
Willy Tarreauef934602016-12-22 23:12:01 +01001658 but not exceeding global_ssl.default_dh_param */
Remi Gacognef46cd6e2014-06-12 14:58:40 +02001659static DH *ssl_get_tmp_dh(SSL *ssl, int export, int keylen)
1660{
1661 DH *dh = NULL;
1662 EVP_PKEY *pkey = SSL_get_privatekey(ssl);
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02001663 int type;
1664
1665 type = pkey ? EVP_PKEY_base_id(pkey) : EVP_PKEY_NONE;
Remi Gacognef46cd6e2014-06-12 14:58:40 +02001666
1667 /* The keylen supplied by OpenSSL can only be 512 or 1024.
1668 See ssl3_send_server_key_exchange() in ssl/s3_srvr.c
1669 */
1670 if (type == EVP_PKEY_RSA || type == EVP_PKEY_DSA) {
1671 keylen = EVP_PKEY_bits(pkey);
1672 }
1673
Willy Tarreauef934602016-12-22 23:12:01 +01001674 if (keylen > global_ssl.default_dh_param) {
1675 keylen = global_ssl.default_dh_param;
Remi Gacognef46cd6e2014-06-12 14:58:40 +02001676 }
1677
Remi Gacogned3a341a2015-05-29 16:26:17 +02001678 if (keylen >= 4096) {
Remi Gacogne8de54152014-07-15 11:36:40 +02001679 dh = local_dh_4096;
Remi Gacognef46cd6e2014-06-12 14:58:40 +02001680 }
1681 else if (keylen >= 2048) {
Remi Gacogne8de54152014-07-15 11:36:40 +02001682 dh = local_dh_2048;
Remi Gacognef46cd6e2014-06-12 14:58:40 +02001683 }
1684 else {
Remi Gacogne8de54152014-07-15 11:36:40 +02001685 dh = local_dh_1024;
Remi Gacognef46cd6e2014-06-12 14:58:40 +02001686 }
1687
1688 return dh;
1689}
1690
Remi Gacogne47783ef2015-05-29 15:53:22 +02001691static DH * ssl_sock_get_dh_from_file(const char *filename)
Emeric Bruna4bcd9a2012-09-20 16:19:02 +02001692{
Emeric Bruna4bcd9a2012-09-20 16:19:02 +02001693 DH *dh = NULL;
Remi Gacogne47783ef2015-05-29 15:53:22 +02001694 BIO *in = BIO_new(BIO_s_file());
Emeric Bruna4bcd9a2012-09-20 16:19:02 +02001695
Emeric Bruna4bcd9a2012-09-20 16:19:02 +02001696 if (in == NULL)
1697 goto end;
1698
Remi Gacogne47783ef2015-05-29 15:53:22 +02001699 if (BIO_read_filename(in, filename) <= 0)
Emeric Bruna4bcd9a2012-09-20 16:19:02 +02001700 goto end;
1701
Remi Gacogne47783ef2015-05-29 15:53:22 +02001702 dh = PEM_read_bio_DHparams(in, NULL, NULL, NULL);
1703
1704end:
1705 if (in)
1706 BIO_free(in);
1707
1708 return dh;
1709}
1710
1711int ssl_sock_load_global_dh_param_from_file(const char *filename)
1712{
1713 global_dh = ssl_sock_get_dh_from_file(filename);
1714
1715 if (global_dh) {
1716 return 0;
1717 }
1718
1719 return -1;
1720}
1721
1722/* Loads Diffie-Hellman parameter from a file. Returns 1 if loaded, else -1
1723 if an error occured, and 0 if parameter not found. */
1724int ssl_sock_load_dh_params(SSL_CTX *ctx, const char *file)
1725{
1726 int ret = -1;
1727 DH *dh = ssl_sock_get_dh_from_file(file);
1728
Remi Gacognef46cd6e2014-06-12 14:58:40 +02001729 if (dh) {
1730 ret = 1;
1731 SSL_CTX_set_tmp_dh(ctx, dh);
Remi Gacogne4f902b82015-05-28 16:23:00 +02001732
1733 if (ssl_dh_ptr_index >= 0) {
1734 /* store a pointer to the DH params to avoid complaining about
1735 ssl-default-dh-param not being set for this SSL_CTX */
1736 SSL_CTX_set_ex_data(ctx, ssl_dh_ptr_index, dh);
1737 }
Remi Gacognef46cd6e2014-06-12 14:58:40 +02001738 }
Remi Gacogne47783ef2015-05-29 15:53:22 +02001739 else if (global_dh) {
1740 SSL_CTX_set_tmp_dh(ctx, global_dh);
1741 ret = 0; /* DH params not found */
1742 }
Remi Gacognef46cd6e2014-06-12 14:58:40 +02001743 else {
Emeric Brun41fdb3c2013-04-26 11:05:44 +02001744 /* Clear openssl global errors stack */
1745 ERR_clear_error();
1746
Willy Tarreauef934602016-12-22 23:12:01 +01001747 if (global_ssl.default_dh_param <= 1024) {
Remi Gacognef46cd6e2014-06-12 14:58:40 +02001748 /* we are limited to DH parameter of 1024 bits anyway */
Remi Gacognec7e12632016-07-02 16:26:10 +02001749 if (local_dh_1024 == NULL)
1750 local_dh_1024 = ssl_get_dh_1024();
1751
Remi Gacogne8de54152014-07-15 11:36:40 +02001752 if (local_dh_1024 == NULL)
Remi Gacognef46cd6e2014-06-12 14:58:40 +02001753 goto end;
Willy Tarreau6e774b42014-04-25 21:35:23 +02001754
Remi Gacogne8de54152014-07-15 11:36:40 +02001755 SSL_CTX_set_tmp_dh(ctx, local_dh_1024);
Remi Gacognef46cd6e2014-06-12 14:58:40 +02001756 }
1757 else {
1758 SSL_CTX_set_tmp_dh_callback(ctx, ssl_get_tmp_dh);
1759 }
Willy Tarreau6e774b42014-04-25 21:35:23 +02001760
Emeric Brun41fdb3c2013-04-26 11:05:44 +02001761 ret = 0; /* DH params not found */
Emeric Bruna4bcd9a2012-09-20 16:19:02 +02001762 }
Emeric Brun644cde02012-12-14 11:21:13 +01001763
Emeric Bruna4bcd9a2012-09-20 16:19:02 +02001764end:
1765 if (dh)
1766 DH_free(dh);
1767
Emeric Bruna4bcd9a2012-09-20 16:19:02 +02001768 return ret;
1769}
1770#endif
1771
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +02001772static int ssl_sock_add_cert_sni(SSL_CTX *ctx, struct bind_conf *s, char *name, int order)
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01001773{
1774 struct sni_ctx *sc;
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +02001775 int wild = 0, neg = 0;
Thierry FOURNIER / OZON.IO07c3d782016-10-06 10:56:48 +02001776 struct ebmb_node *node;
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01001777
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +02001778 if (*name == '!') {
1779 neg = 1;
1780 name++;
1781 }
1782 if (*name == '*') {
1783 wild = 1;
1784 name++;
1785 }
1786 /* !* filter is a nop */
1787 if (neg && wild)
1788 return order;
1789 if (*name) {
1790 int j, len;
1791 len = strlen(name);
Thierry FOURNIER / OZON.IO07c3d782016-10-06 10:56:48 +02001792 for (j = 0; j < len && j < trash.size; j++)
1793 trash.str[j] = tolower(name[j]);
1794 if (j >= trash.size)
1795 return order;
1796 trash.str[j] = 0;
1797
1798 /* Check for duplicates. */
1799 if (wild)
1800 node = ebst_lookup(&s->sni_w_ctx, trash.str);
1801 else
1802 node = ebst_lookup(&s->sni_ctx, trash.str);
1803 for (; node; node = ebmb_next_dup(node)) {
1804 sc = ebmb_entry(node, struct sni_ctx, name);
1805 if (sc->ctx == ctx && sc->neg == neg)
1806 return order;
1807 }
1808
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01001809 sc = malloc(sizeof(struct sni_ctx) + len + 1);
Thierry FOURNIER / OZON.IO7a3bd3b2016-10-06 10:35:29 +02001810 if (!sc)
1811 return order;
Thierry FOURNIER / OZON.IO07c3d782016-10-06 10:56:48 +02001812 memcpy(sc->name.key, trash.str, len + 1);
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01001813 sc->ctx = ctx;
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +02001814 sc->order = order++;
1815 sc->neg = neg;
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01001816 if (wild)
1817 ebst_insert(&s->sni_w_ctx, &sc->name);
1818 else
1819 ebst_insert(&s->sni_ctx, &sc->name);
1820 }
1821 return order;
1822}
1823
yanbzhu488a4d22015-12-01 15:16:07 -05001824
1825/* The following code is used for loading multiple crt files into
1826 * SSL_CTX's based on CN/SAN
1827 */
Luca Pizzamiglio578b1692016-12-12 10:56:56 +01001828#if OPENSSL_VERSION_NUMBER >= 0x1000200fL && !defined(LIBRESSL_VERSION_NUMBER)
yanbzhu488a4d22015-12-01 15:16:07 -05001829/* This is used to preload the certifcate, private key
1830 * and Cert Chain of a file passed in via the crt
1831 * argument
1832 *
1833 * This way, we do not have to read the file multiple times
1834 */
1835struct cert_key_and_chain {
1836 X509 *cert;
1837 EVP_PKEY *key;
1838 unsigned int num_chain_certs;
1839 /* This is an array of X509 pointers */
1840 X509 **chain_certs;
1841};
1842
yanbzhu08ce6ab2015-12-02 13:01:29 -05001843#define SSL_SOCK_POSSIBLE_KT_COMBOS (1<<(SSL_SOCK_NUM_KEYTYPES))
1844
1845struct key_combo_ctx {
1846 SSL_CTX *ctx;
1847 int order;
1848};
1849
1850/* Map used for processing multiple keypairs for a single purpose
1851 *
1852 * This maps CN/SNI name to certificate type
1853 */
1854struct sni_keytype {
1855 int keytypes; /* BITMASK for keytypes */
1856 struct ebmb_node name; /* node holding the servername value */
1857};
1858
1859
yanbzhu488a4d22015-12-01 15:16:07 -05001860/* Frees the contents of a cert_key_and_chain
1861 */
1862static void ssl_sock_free_cert_key_and_chain_contents(struct cert_key_and_chain *ckch)
1863{
1864 int i;
1865
1866 if (!ckch)
1867 return;
1868
1869 /* Free the certificate and set pointer to NULL */
1870 if (ckch->cert)
1871 X509_free(ckch->cert);
1872 ckch->cert = NULL;
1873
1874 /* Free the key and set pointer to NULL */
1875 if (ckch->key)
1876 EVP_PKEY_free(ckch->key);
1877 ckch->key = NULL;
1878
1879 /* Free each certificate in the chain */
1880 for (i = 0; i < ckch->num_chain_certs; i++) {
1881 if (ckch->chain_certs[i])
1882 X509_free(ckch->chain_certs[i]);
1883 }
1884
1885 /* Free the chain obj itself and set to NULL */
1886 if (ckch->num_chain_certs > 0) {
1887 free(ckch->chain_certs);
1888 ckch->num_chain_certs = 0;
1889 ckch->chain_certs = NULL;
1890 }
1891
1892}
1893
1894/* checks if a key and cert exists in the ckch
1895 */
1896static int ssl_sock_is_ckch_valid(struct cert_key_and_chain *ckch)
1897{
1898 return (ckch->cert != NULL && ckch->key != NULL);
1899}
1900
1901
1902/* Loads the contents of a crt file (path) into a cert_key_and_chain
1903 * This allows us to carry the contents of the file without having to
1904 * read the file multiple times.
1905 *
1906 * returns:
1907 * 0 on Success
1908 * 1 on SSL Failure
1909 * 2 on file not found
1910 */
1911static int ssl_sock_load_crt_file_into_ckch(const char *path, struct cert_key_and_chain *ckch, char **err)
1912{
1913
1914 BIO *in;
1915 X509 *ca = NULL;
1916 int ret = 1;
1917
1918 ssl_sock_free_cert_key_and_chain_contents(ckch);
1919
1920 in = BIO_new(BIO_s_file());
1921 if (in == NULL)
1922 goto end;
1923
1924 if (BIO_read_filename(in, path) <= 0)
1925 goto end;
1926
yanbzhu488a4d22015-12-01 15:16:07 -05001927 /* Read Private Key */
1928 ckch->key = PEM_read_bio_PrivateKey(in, NULL, NULL, NULL);
1929 if (ckch->key == NULL) {
1930 memprintf(err, "%sunable to load private key from file '%s'.\n",
1931 err && *err ? *err : "", path);
1932 goto end;
1933 }
1934
Willy Tarreaubb137a82016-04-06 19:02:38 +02001935 /* Seek back to beginning of file */
Thierry FOURNIER / OZON.IOd44ea3f2016-10-14 00:49:21 +02001936 if (BIO_reset(in) == -1) {
1937 memprintf(err, "%san error occurred while reading the file '%s'.\n",
1938 err && *err ? *err : "", path);
1939 goto end;
1940 }
Willy Tarreaubb137a82016-04-06 19:02:38 +02001941
1942 /* Read Certificate */
1943 ckch->cert = PEM_read_bio_X509_AUX(in, NULL, NULL, NULL);
1944 if (ckch->cert == NULL) {
1945 memprintf(err, "%sunable to load certificate from file '%s'.\n",
1946 err && *err ? *err : "", path);
1947 goto end;
1948 }
1949
yanbzhu488a4d22015-12-01 15:16:07 -05001950 /* Read Certificate Chain */
1951 while ((ca = PEM_read_bio_X509(in, NULL, NULL, NULL))) {
1952 /* Grow the chain certs */
1953 ckch->num_chain_certs++;
1954 ckch->chain_certs = realloc(ckch->chain_certs, (ckch->num_chain_certs * sizeof(X509 *)));
1955
1956 /* use - 1 here since we just incremented it above */
1957 ckch->chain_certs[ckch->num_chain_certs - 1] = ca;
1958 }
1959 ret = ERR_get_error();
1960 if (ret && (ERR_GET_LIB(ret) != ERR_LIB_PEM && ERR_GET_REASON(ret) != PEM_R_NO_START_LINE)) {
1961 memprintf(err, "%sunable to load certificate chain from file '%s'.\n",
1962 err && *err ? *err : "", path);
1963 ret = 1;
1964 goto end;
1965 }
1966
1967 ret = 0;
1968
1969end:
1970
1971 ERR_clear_error();
1972 if (in)
1973 BIO_free(in);
1974
1975 /* Something went wrong in one of the reads */
1976 if (ret != 0)
1977 ssl_sock_free_cert_key_and_chain_contents(ckch);
1978
1979 return ret;
1980}
1981
1982/* Loads the info in ckch into ctx
1983 * Currently, this does not process any information about ocsp, dhparams or
1984 * sctl
1985 * Returns
1986 * 0 on success
1987 * 1 on failure
1988 */
1989static int ssl_sock_put_ckch_into_ctx(const char *path, const struct cert_key_and_chain *ckch, SSL_CTX *ctx, char **err)
1990{
1991 int i = 0;
1992
1993 if (SSL_CTX_use_PrivateKey(ctx, ckch->key) <= 0) {
1994 memprintf(err, "%sunable to load SSL private key into SSL Context '%s'.\n",
1995 err && *err ? *err : "", path);
1996 return 1;
1997 }
1998
1999 if (!SSL_CTX_use_certificate(ctx, ckch->cert)) {
2000 memprintf(err, "%sunable to load SSL certificate into SSL Context '%s'.\n",
2001 err && *err ? *err : "", path);
2002 return 1;
2003 }
2004
yanbzhu488a4d22015-12-01 15:16:07 -05002005 /* Load all certs in the ckch into the ctx_chain for the ssl_ctx */
2006 for (i = 0; i < ckch->num_chain_certs; i++) {
2007 if (!SSL_CTX_add1_chain_cert(ctx, ckch->chain_certs[i])) {
yanbzhu08ce6ab2015-12-02 13:01:29 -05002008 memprintf(err, "%sunable to load chain certificate #%d into SSL Context '%s'. Make sure you are linking against Openssl >= 1.0.2.\n",
2009 err && *err ? *err : "", (i+1), path);
yanbzhu488a4d22015-12-01 15:16:07 -05002010 return 1;
2011 }
2012 }
2013
2014 if (SSL_CTX_check_private_key(ctx) <= 0) {
2015 memprintf(err, "%sinconsistencies between private key and certificate loaded from PEM file '%s'.\n",
2016 err && *err ? *err : "", path);
2017 return 1;
2018 }
2019
2020 return 0;
2021}
2022
yanbzhu08ce6ab2015-12-02 13:01:29 -05002023
2024static void ssl_sock_populate_sni_keytypes_hplr(const char *str, struct eb_root *sni_keytypes, int key_index)
2025{
2026 struct sni_keytype *s_kt = NULL;
2027 struct ebmb_node *node;
2028 int i;
2029
2030 for (i = 0; i < trash.size; i++) {
2031 if (!str[i])
2032 break;
2033 trash.str[i] = tolower(str[i]);
2034 }
2035 trash.str[i] = 0;
2036 node = ebst_lookup(sni_keytypes, trash.str);
2037 if (!node) {
2038 /* CN not found in tree */
2039 s_kt = malloc(sizeof(struct sni_keytype) + i + 1);
2040 /* Using memcpy here instead of strncpy.
2041 * strncpy will cause sig_abrt errors under certain versions of gcc with -O2
2042 * See: https://gcc.gnu.org/bugzilla/show_bug.cgi?id=60792
2043 */
2044 memcpy(s_kt->name.key, trash.str, i+1);
2045 s_kt->keytypes = 0;
2046 ebst_insert(sni_keytypes, &s_kt->name);
2047 } else {
2048 /* CN found in tree */
2049 s_kt = container_of(node, struct sni_keytype, name);
2050 }
2051
2052 /* Mark that this CN has the keytype of key_index via keytypes mask */
2053 s_kt->keytypes |= 1<<key_index;
2054
2055}
2056
2057
2058/* Given a path that does not exist, try to check for path.rsa, path.dsa and path.ecdsa files.
2059 * If any are found, group these files into a set of SSL_CTX*
2060 * based on shared and unique CN and SAN entries. Add these SSL_CTX* to the SNI tree.
2061 *
2062 * This will allow the user to explictly group multiple cert/keys for a single purpose
2063 *
2064 * Returns
2065 * 0 on success
2066 * 1 on failure
2067 */
Willy Tarreau03209342016-12-22 17:08:28 +01002068static 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 -05002069{
2070 char fp[MAXPATHLEN+1] = {0};
2071 int n = 0;
2072 int i = 0;
2073 struct cert_key_and_chain certs_and_keys[SSL_SOCK_NUM_KEYTYPES] = { {0} };
2074 struct eb_root sni_keytypes_map = { {0} };
2075 struct ebmb_node *node;
2076 struct ebmb_node *next;
2077 /* Array of SSL_CTX pointers corresponding to each possible combo
2078 * of keytypes
2079 */
2080 struct key_combo_ctx key_combos[SSL_SOCK_POSSIBLE_KT_COMBOS] = { {0} };
2081 int rv = 0;
2082 X509_NAME *xname = NULL;
2083 char *str = NULL;
2084#ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME
2085 STACK_OF(GENERAL_NAME) *names = NULL;
2086#endif
2087
2088 /* Load all possible certs and keys */
2089 for (n = 0; n < SSL_SOCK_NUM_KEYTYPES; n++) {
2090 struct stat buf;
2091
2092 snprintf(fp, sizeof(fp), "%s.%s", path, SSL_SOCK_KEYTYPE_NAMES[n]);
2093 if (stat(fp, &buf) == 0) {
2094 if (ssl_sock_load_crt_file_into_ckch(fp, &certs_and_keys[n], err) == 1) {
2095 rv = 1;
2096 goto end;
2097 }
2098 }
2099 }
2100
2101 /* Process each ckch and update keytypes for each CN/SAN
2102 * for example, if CN/SAN www.a.com is associated with
2103 * certs with keytype 0 and 2, then at the end of the loop,
2104 * www.a.com will have:
2105 * keyindex = 0 | 1 | 4 = 5
2106 */
2107 for (n = 0; n < SSL_SOCK_NUM_KEYTYPES; n++) {
2108
2109 if (!ssl_sock_is_ckch_valid(&certs_and_keys[n]))
2110 continue;
2111
Emmanuel Hocdetd294aea2016-05-13 11:14:06 +02002112 if (fcount) {
Willy Tarreau24b892f2016-06-20 23:01:57 +02002113 for (i = 0; i < fcount; i++)
Emmanuel Hocdetd294aea2016-05-13 11:14:06 +02002114 ssl_sock_populate_sni_keytypes_hplr(sni_filter[i], &sni_keytypes_map, n);
2115 } else {
2116 /* A lot of the following code is OpenSSL boilerplate for processing CN's and SAN's,
2117 * so the line that contains logic is marked via comments
2118 */
2119 xname = X509_get_subject_name(certs_and_keys[n].cert);
2120 i = -1;
2121 while ((i = X509_NAME_get_index_by_NID(xname, NID_commonName, i)) != -1) {
2122 X509_NAME_ENTRY *entry = X509_NAME_get_entry(xname, i);
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02002123 ASN1_STRING *value;
2124 value = X509_NAME_ENTRY_get_data(entry);
2125 if (ASN1_STRING_to_UTF8((unsigned char **)&str, value) >= 0) {
Emmanuel Hocdetd294aea2016-05-13 11:14:06 +02002126 /* Important line is here */
2127 ssl_sock_populate_sni_keytypes_hplr(str, &sni_keytypes_map, n);
yanbzhu08ce6ab2015-12-02 13:01:29 -05002128
Emmanuel Hocdetd294aea2016-05-13 11:14:06 +02002129 OPENSSL_free(str);
2130 str = NULL;
2131 }
yanbzhu08ce6ab2015-12-02 13:01:29 -05002132 }
yanbzhu08ce6ab2015-12-02 13:01:29 -05002133
Emmanuel Hocdetd294aea2016-05-13 11:14:06 +02002134 /* Do the above logic for each SAN */
yanbzhu08ce6ab2015-12-02 13:01:29 -05002135#ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME
Emmanuel Hocdetd294aea2016-05-13 11:14:06 +02002136 names = X509_get_ext_d2i(certs_and_keys[n].cert, NID_subject_alt_name, NULL, NULL);
2137 if (names) {
2138 for (i = 0; i < sk_GENERAL_NAME_num(names); i++) {
2139 GENERAL_NAME *name = sk_GENERAL_NAME_value(names, i);
yanbzhu08ce6ab2015-12-02 13:01:29 -05002140
Emmanuel Hocdetd294aea2016-05-13 11:14:06 +02002141 if (name->type == GEN_DNS) {
2142 if (ASN1_STRING_to_UTF8((unsigned char **)&str, name->d.dNSName) >= 0) {
2143 /* Important line is here */
2144 ssl_sock_populate_sni_keytypes_hplr(str, &sni_keytypes_map, n);
yanbzhu08ce6ab2015-12-02 13:01:29 -05002145
Emmanuel Hocdetd294aea2016-05-13 11:14:06 +02002146 OPENSSL_free(str);
2147 str = NULL;
2148 }
yanbzhu08ce6ab2015-12-02 13:01:29 -05002149 }
2150 }
2151 }
2152 }
2153#endif /* SSL_CTRL_SET_TLSEXT_HOSTNAME */
2154 }
2155
2156 /* If no files found, return error */
2157 if (eb_is_empty(&sni_keytypes_map)) {
2158 memprintf(err, "%sunable to load SSL certificate file '%s' file does not exist.\n",
2159 err && *err ? *err : "", path);
2160 rv = 1;
2161 goto end;
2162 }
2163
2164 /* We now have a map of CN/SAN to keytypes that are loaded in
2165 * Iterate through the map to create the SSL_CTX's (if needed)
2166 * and add each CTX to the SNI tree
2167 *
2168 * Some math here:
2169 * There are 2^n - 1 possibile combinations, each unique
2170 * combination is denoted by the key in the map. Each key
2171 * has a value between 1 and 2^n - 1. Conveniently, the array
2172 * of SSL_CTX* is sized 2^n. So, we can simply use the i'th
2173 * entry in the array to correspond to the unique combo (key)
2174 * associated with i. This unique key combo (i) will be associated
2175 * with combos[i-1]
2176 */
2177
2178 node = ebmb_first(&sni_keytypes_map);
2179 while (node) {
2180 SSL_CTX *cur_ctx;
Bertrand Jacquin33423092016-11-13 16:37:13 +00002181 char cur_file[MAXPATHLEN+1];
yanbzhu08ce6ab2015-12-02 13:01:29 -05002182
2183 str = (char *)container_of(node, struct sni_keytype, name)->name.key;
2184 i = container_of(node, struct sni_keytype, name)->keytypes;
2185 cur_ctx = key_combos[i-1].ctx;
2186
2187 if (cur_ctx == NULL) {
2188 /* need to create SSL_CTX */
2189 cur_ctx = SSL_CTX_new(SSLv23_server_method());
2190 if (cur_ctx == NULL) {
2191 memprintf(err, "%sunable to allocate SSL context.\n",
2192 err && *err ? *err : "");
2193 rv = 1;
2194 goto end;
2195 }
2196
yanbzhube2774d2015-12-10 15:07:30 -05002197 /* Load all required certs/keys/chains/OCSPs info into SSL_CTX */
yanbzhu08ce6ab2015-12-02 13:01:29 -05002198 for (n = 0; n < SSL_SOCK_NUM_KEYTYPES; n++) {
2199 if (i & (1<<n)) {
2200 /* Key combo contains ckch[n] */
Bertrand Jacquin33423092016-11-13 16:37:13 +00002201 snprintf(cur_file, MAXPATHLEN+1, "%s.%s", path, SSL_SOCK_KEYTYPE_NAMES[n]);
2202 if (ssl_sock_put_ckch_into_ctx(cur_file, &certs_and_keys[n], cur_ctx, err) != 0) {
yanbzhu08ce6ab2015-12-02 13:01:29 -05002203 SSL_CTX_free(cur_ctx);
2204 rv = 1;
2205 goto end;
2206 }
yanbzhube2774d2015-12-10 15:07:30 -05002207
2208#if (defined SSL_CTRL_SET_TLSEXT_STATUS_REQ_CB && !defined OPENSSL_NO_OCSP)
2209 /* Load OCSP Info into context */
Bertrand Jacquin33423092016-11-13 16:37:13 +00002210 if (ssl_sock_load_ocsp(cur_ctx, cur_file) < 0) {
yanbzhube2774d2015-12-10 15:07:30 -05002211 if (err)
2212 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 +00002213 *err ? *err : "", cur_file);
yanbzhube2774d2015-12-10 15:07:30 -05002214 SSL_CTX_free(cur_ctx);
2215 rv = 1;
2216 goto end;
2217 }
2218#endif
yanbzhu08ce6ab2015-12-02 13:01:29 -05002219 }
2220 }
2221
2222 /* Load DH params into the ctx to support DHE keys */
2223#ifndef OPENSSL_NO_DH
2224 if (ssl_dh_ptr_index >= 0)
2225 SSL_CTX_set_ex_data(cur_ctx, ssl_dh_ptr_index, NULL);
2226
2227 rv = ssl_sock_load_dh_params(cur_ctx, NULL);
2228 if (rv < 0) {
2229 if (err)
2230 memprintf(err, "%sunable to load DH parameters from file '%s'.\n",
2231 *err ? *err : "", path);
2232 rv = 1;
2233 goto end;
2234 }
2235#endif
2236
2237 /* Update key_combos */
2238 key_combos[i-1].ctx = cur_ctx;
2239 }
2240
2241 /* Update SNI Tree */
Emmanuel Hocdetd294aea2016-05-13 11:14:06 +02002242 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 -05002243 node = ebmb_next(node);
2244 }
2245
2246
2247 /* Mark a default context if none exists, using the ctx that has the most shared keys */
2248 if (!bind_conf->default_ctx) {
2249 for (i = SSL_SOCK_POSSIBLE_KT_COMBOS - 1; i >= 0; i--) {
2250 if (key_combos[i].ctx) {
2251 bind_conf->default_ctx = key_combos[i].ctx;
2252 break;
2253 }
2254 }
2255 }
2256
2257end:
2258
2259 if (names)
2260 sk_GENERAL_NAME_pop_free(names, GENERAL_NAME_free);
2261
2262 for (n = 0; n < SSL_SOCK_NUM_KEYTYPES; n++)
2263 ssl_sock_free_cert_key_and_chain_contents(&certs_and_keys[n]);
2264
2265 node = ebmb_first(&sni_keytypes_map);
2266 while (node) {
2267 next = ebmb_next(node);
2268 ebmb_delete(node);
2269 node = next;
2270 }
2271
2272 return rv;
2273}
2274#else
2275/* This is a dummy, that just logs an error and returns error */
Willy Tarreau03209342016-12-22 17:08:28 +01002276static 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 -05002277{
2278 memprintf(err, "%sunable to stat SSL certificate from file '%s' : %s.\n",
2279 err && *err ? *err : "", path, strerror(errno));
2280 return 1;
2281}
2282
yanbzhu488a4d22015-12-01 15:16:07 -05002283#endif /* #if OPENSSL_VERSION_NUMBER >= 0x1000200fL: Support for loading multiple certs into a single SSL_CTX */
2284
Emeric Brunfc0421f2012-09-07 17:30:07 +02002285/* Loads a certificate key and CA chain from a file. Returns 0 on error, -1 if
2286 * an early error happens and the caller must call SSL_CTX_free() by itelf.
2287 */
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +02002288static 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 +02002289{
2290 BIO *in;
2291 X509 *x = NULL, *ca;
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +02002292 int i, err;
Emeric Brunfc0421f2012-09-07 17:30:07 +02002293 int ret = -1;
2294 int order = 0;
2295 X509_NAME *xname;
2296 char *str;
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02002297 pem_password_cb *passwd_cb;
2298 void *passwd_cb_userdata;
2299
Emeric Brunfc0421f2012-09-07 17:30:07 +02002300#ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME
2301 STACK_OF(GENERAL_NAME) *names;
2302#endif
2303
2304 in = BIO_new(BIO_s_file());
2305 if (in == NULL)
2306 goto end;
2307
2308 if (BIO_read_filename(in, file) <= 0)
2309 goto end;
2310
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02002311
2312 passwd_cb = SSL_CTX_get_default_passwd_cb(ctx);
2313 passwd_cb_userdata = SSL_CTX_get_default_passwd_cb_userdata(ctx);
2314
2315 x = PEM_read_bio_X509_AUX(in, NULL, passwd_cb, passwd_cb_userdata);
Emeric Brunfc0421f2012-09-07 17:30:07 +02002316 if (x == NULL)
2317 goto end;
2318
Emeric Brun50bcecc2013-04-22 13:05:23 +02002319 if (fcount) {
2320 while (fcount--)
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +02002321 order = ssl_sock_add_cert_sni(ctx, s, sni_filter[fcount], order);
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01002322 }
2323 else {
Emeric Brunfc0421f2012-09-07 17:30:07 +02002324#ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01002325 names = X509_get_ext_d2i(x, NID_subject_alt_name, NULL, NULL);
2326 if (names) {
2327 for (i = 0; i < sk_GENERAL_NAME_num(names); i++) {
2328 GENERAL_NAME *name = sk_GENERAL_NAME_value(names, i);
2329 if (name->type == GEN_DNS) {
2330 if (ASN1_STRING_to_UTF8((unsigned char **)&str, name->d.dNSName) >= 0) {
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +02002331 order = ssl_sock_add_cert_sni(ctx, s, str, order);
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01002332 OPENSSL_free(str);
Emeric Brunfc0421f2012-09-07 17:30:07 +02002333 }
Emeric Brunfc0421f2012-09-07 17:30:07 +02002334 }
2335 }
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01002336 sk_GENERAL_NAME_pop_free(names, GENERAL_NAME_free);
Emeric Brunfc0421f2012-09-07 17:30:07 +02002337 }
Emeric Brunfc0421f2012-09-07 17:30:07 +02002338#endif /* SSL_CTRL_SET_TLSEXT_HOSTNAME */
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01002339 xname = X509_get_subject_name(x);
2340 i = -1;
2341 while ((i = X509_NAME_get_index_by_NID(xname, NID_commonName, i)) != -1) {
2342 X509_NAME_ENTRY *entry = X509_NAME_get_entry(xname, i);
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02002343 ASN1_STRING *value;
2344
2345 value = X509_NAME_ENTRY_get_data(entry);
2346 if (ASN1_STRING_to_UTF8((unsigned char **)&str, value) >= 0) {
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +02002347 order = ssl_sock_add_cert_sni(ctx, s, str, order);
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01002348 OPENSSL_free(str);
Emeric Brunfc0421f2012-09-07 17:30:07 +02002349 }
Emeric Brunfc0421f2012-09-07 17:30:07 +02002350 }
2351 }
2352
2353 ret = 0; /* the caller must not free the SSL_CTX argument anymore */
2354 if (!SSL_CTX_use_certificate(ctx, x))
2355 goto end;
2356
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02002357#ifdef SSL_CTX_clear_extra_chain_certs
2358 SSL_CTX_clear_extra_chain_certs(ctx);
2359#else
Emeric Brunfc0421f2012-09-07 17:30:07 +02002360 if (ctx->extra_certs != NULL) {
2361 sk_X509_pop_free(ctx->extra_certs, X509_free);
2362 ctx->extra_certs = NULL;
2363 }
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02002364#endif
Emeric Brunfc0421f2012-09-07 17:30:07 +02002365
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02002366 while ((ca = PEM_read_bio_X509(in, NULL, passwd_cb, passwd_cb_userdata))) {
Emeric Brunfc0421f2012-09-07 17:30:07 +02002367 if (!SSL_CTX_add_extra_chain_cert(ctx, ca)) {
2368 X509_free(ca);
2369 goto end;
2370 }
2371 }
2372
2373 err = ERR_get_error();
2374 if (!err || (ERR_GET_LIB(err) == ERR_LIB_PEM && ERR_GET_REASON(err) == PEM_R_NO_START_LINE)) {
2375 /* we successfully reached the last cert in the file */
2376 ret = 1;
2377 }
2378 ERR_clear_error();
2379
2380end:
2381 if (x)
2382 X509_free(x);
2383
2384 if (in)
2385 BIO_free(in);
2386
2387 return ret;
2388}
2389
Willy Tarreau03209342016-12-22 17:08:28 +01002390static 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 +02002391{
2392 int ret;
2393 SSL_CTX *ctx;
2394
2395 ctx = SSL_CTX_new(SSLv23_server_method());
2396 if (!ctx) {
Willy Tarreaueb6cead2012-09-20 19:43:14 +02002397 memprintf(err, "%sunable to allocate SSL context for cert '%s'.\n",
2398 err && *err ? *err : "", path);
Emeric Brunfc0421f2012-09-07 17:30:07 +02002399 return 1;
2400 }
2401
2402 if (SSL_CTX_use_PrivateKey_file(ctx, path, SSL_FILETYPE_PEM) <= 0) {
Willy Tarreaueb6cead2012-09-20 19:43:14 +02002403 memprintf(err, "%sunable to load SSL private key from PEM file '%s'.\n",
2404 err && *err ? *err : "", path);
Emeric Brunfc0421f2012-09-07 17:30:07 +02002405 SSL_CTX_free(ctx);
2406 return 1;
2407 }
2408
Emeric Brun50bcecc2013-04-22 13:05:23 +02002409 ret = ssl_sock_load_cert_chain_file(ctx, path, bind_conf, sni_filter, fcount);
Emeric Brunfc0421f2012-09-07 17:30:07 +02002410 if (ret <= 0) {
Willy Tarreaueb6cead2012-09-20 19:43:14 +02002411 memprintf(err, "%sunable to load SSL certificate from PEM file '%s'.\n",
2412 err && *err ? *err : "", path);
Emeric Brunfc0421f2012-09-07 17:30:07 +02002413 if (ret < 0) /* serious error, must do that ourselves */
2414 SSL_CTX_free(ctx);
2415 return 1;
2416 }
Emeric Brun61694ab2012-10-26 13:35:33 +02002417
2418 if (SSL_CTX_check_private_key(ctx) <= 0) {
2419 memprintf(err, "%sinconsistencies between private key and certificate loaded from PEM file '%s'.\n",
2420 err && *err ? *err : "", path);
2421 return 1;
2422 }
2423
Emeric Brunfc0421f2012-09-07 17:30:07 +02002424 /* we must not free the SSL_CTX anymore below, since it's already in
2425 * the tree, so it will be discovered and cleaned in time.
2426 */
Emeric Bruna4bcd9a2012-09-20 16:19:02 +02002427#ifndef OPENSSL_NO_DH
Remi Gacogne4f902b82015-05-28 16:23:00 +02002428 /* store a NULL pointer to indicate we have not yet loaded
2429 a custom DH param file */
2430 if (ssl_dh_ptr_index >= 0) {
2431 SSL_CTX_set_ex_data(ctx, ssl_dh_ptr_index, NULL);
2432 }
2433
Emeric Bruna4bcd9a2012-09-20 16:19:02 +02002434 ret = ssl_sock_load_dh_params(ctx, path);
2435 if (ret < 0) {
2436 if (err)
2437 memprintf(err, "%sunable to load DH parameters from file '%s'.\n",
2438 *err ? *err : "", path);
2439 return 1;
2440 }
2441#endif
2442
Lukas Tribuse4e30f72014-12-09 16:32:51 +01002443#if (defined SSL_CTRL_SET_TLSEXT_STATUS_REQ_CB && !defined OPENSSL_NO_OCSP)
Emeric Brun4147b2e2014-06-16 18:36:30 +02002444 ret = ssl_sock_load_ocsp(ctx, path);
2445 if (ret < 0) {
2446 if (err)
2447 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",
2448 *err ? *err : "", path);
2449 return 1;
2450 }
2451#endif
2452
Daniel Jakots54ffb912015-11-06 20:02:41 +01002453#if (OPENSSL_VERSION_NUMBER >= 0x1000200fL && !defined OPENSSL_NO_TLSEXT && !defined OPENSSL_IS_BORINGSSL && !defined LIBRESSL_VERSION_NUMBER)
Janusz Dziemidowicz2c701b52015-03-07 23:03:59 +01002454 if (sctl_ex_index >= 0) {
2455 ret = ssl_sock_load_sctl(ctx, path);
2456 if (ret < 0) {
2457 if (err)
2458 memprintf(err, "%s '%s.sctl' is present but cannot be read or parsed'.\n",
2459 *err ? *err : "", path);
2460 return 1;
2461 }
2462 }
2463#endif
2464
Emeric Brunfc0421f2012-09-07 17:30:07 +02002465#ifndef SSL_CTRL_SET_TLSEXT_HOSTNAME
Willy Tarreau2a65ff02012-09-13 17:54:29 +02002466 if (bind_conf->default_ctx) {
Willy Tarreaueb6cead2012-09-20 19:43:14 +02002467 memprintf(err, "%sthis version of openssl cannot load multiple SSL certificates.\n",
2468 err && *err ? *err : "");
Emeric Brunfc0421f2012-09-07 17:30:07 +02002469 return 1;
2470 }
2471#endif
Willy Tarreau2a65ff02012-09-13 17:54:29 +02002472 if (!bind_conf->default_ctx)
2473 bind_conf->default_ctx = ctx;
Emeric Brunfc0421f2012-09-07 17:30:07 +02002474
2475 return 0;
2476}
2477
Willy Tarreau03209342016-12-22 17:08:28 +01002478int ssl_sock_load_cert(char *path, struct bind_conf *bind_conf, char **err)
Emeric Brunfc0421f2012-09-07 17:30:07 +02002479{
Cyril Bonté3180f7b2015-01-25 00:16:08 +01002480 struct dirent **de_list;
2481 int i, n;
Emeric Brunfc0421f2012-09-07 17:30:07 +02002482 DIR *dir;
2483 struct stat buf;
Willy Tarreauee2663b2012-12-06 11:36:59 +01002484 char *end;
2485 char fp[MAXPATHLEN+1];
Emeric Brunfc0421f2012-09-07 17:30:07 +02002486 int cfgerr = 0;
yanbzhu63ea8462015-12-09 13:35:14 -05002487#if OPENSSL_VERSION_NUMBER >= 0x1000200fL
2488 int is_bundle;
2489 int j;
2490#endif
Emeric Brunfc0421f2012-09-07 17:30:07 +02002491
yanbzhu08ce6ab2015-12-02 13:01:29 -05002492 if (stat(path, &buf) == 0) {
2493 dir = opendir(path);
2494 if (!dir)
Willy Tarreau03209342016-12-22 17:08:28 +01002495 return ssl_sock_load_cert_file(path, bind_conf, NULL, 0, err);
Emeric Brunfc0421f2012-09-07 17:30:07 +02002496
yanbzhu08ce6ab2015-12-02 13:01:29 -05002497 /* strip trailing slashes, including first one */
2498 for (end = path + strlen(path) - 1; end >= path && *end == '/'; end--)
2499 *end = 0;
Emeric Brunfc0421f2012-09-07 17:30:07 +02002500
yanbzhu08ce6ab2015-12-02 13:01:29 -05002501 n = scandir(path, &de_list, 0, alphasort);
2502 if (n < 0) {
2503 memprintf(err, "%sunable to scan directory '%s' : %s.\n",
2504 err && *err ? *err : "", path, strerror(errno));
2505 cfgerr++;
2506 }
2507 else {
2508 for (i = 0; i < n; i++) {
2509 struct dirent *de = de_list[i];
Emeric Brun2aab7222014-06-18 18:15:09 +02002510
yanbzhu08ce6ab2015-12-02 13:01:29 -05002511 end = strrchr(de->d_name, '.');
2512 if (end && (!strcmp(end, ".issuer") || !strcmp(end, ".ocsp") || !strcmp(end, ".sctl")))
2513 goto ignore_entry;
Cyril Bonté3180f7b2015-01-25 00:16:08 +01002514
yanbzhu08ce6ab2015-12-02 13:01:29 -05002515 snprintf(fp, sizeof(fp), "%s/%s", path, de->d_name);
2516 if (stat(fp, &buf) != 0) {
2517 memprintf(err, "%sunable to stat SSL certificate from file '%s' : %s.\n",
2518 err && *err ? *err : "", fp, strerror(errno));
2519 cfgerr++;
2520 goto ignore_entry;
2521 }
2522 if (!S_ISREG(buf.st_mode))
2523 goto ignore_entry;
yanbzhu63ea8462015-12-09 13:35:14 -05002524
2525#if OPENSSL_VERSION_NUMBER >= 0x1000200fL
2526 is_bundle = 0;
2527 /* Check if current entry in directory is part of a multi-cert bundle */
2528
2529 if (end) {
2530 for (j = 0; j < SSL_SOCK_NUM_KEYTYPES; j++) {
2531 if (!strcmp(end + 1, SSL_SOCK_KEYTYPE_NAMES[j])) {
2532 is_bundle = 1;
2533 break;
2534 }
2535 }
2536
2537 if (is_bundle) {
2538 char dp[MAXPATHLEN+1] = {0}; /* this will be the filename w/o the keytype */
2539 int dp_len;
2540
2541 dp_len = end - de->d_name;
2542 snprintf(dp, dp_len + 1, "%s", de->d_name);
2543
2544 /* increment i and free de until we get to a non-bundle cert
2545 * Note here that we look at de_list[i + 1] before freeing de
2546 * this is important since ignore_entry will free de
2547 */
2548 while (i + 1 < n && !strncmp(de_list[i + 1]->d_name, dp, dp_len)) {
2549 free(de);
2550 i++;
2551 de = de_list[i];
2552 }
2553
2554 snprintf(fp, sizeof(fp), "%s/%s", path, dp);
Willy Tarreau03209342016-12-22 17:08:28 +01002555 ssl_sock_load_multi_cert(fp, bind_conf, NULL, 0, err);
yanbzhu63ea8462015-12-09 13:35:14 -05002556
2557 /* Successfully processed the bundle */
2558 goto ignore_entry;
2559 }
2560 }
2561
2562#endif
Willy Tarreau03209342016-12-22 17:08:28 +01002563 cfgerr += ssl_sock_load_cert_file(fp, bind_conf, NULL, 0, err);
yanbzhu08ce6ab2015-12-02 13:01:29 -05002564ignore_entry:
2565 free(de);
Cyril Bonté3180f7b2015-01-25 00:16:08 +01002566 }
yanbzhu08ce6ab2015-12-02 13:01:29 -05002567 free(de_list);
Emeric Brunfc0421f2012-09-07 17:30:07 +02002568 }
yanbzhu08ce6ab2015-12-02 13:01:29 -05002569 closedir(dir);
2570 return cfgerr;
Emeric Brunfc0421f2012-09-07 17:30:07 +02002571 }
yanbzhu08ce6ab2015-12-02 13:01:29 -05002572
Willy Tarreau03209342016-12-22 17:08:28 +01002573 cfgerr = ssl_sock_load_multi_cert(path, bind_conf, NULL, 0, err);
yanbzhu08ce6ab2015-12-02 13:01:29 -05002574
Emeric Brunfc0421f2012-09-07 17:30:07 +02002575 return cfgerr;
2576}
2577
Thierry Fournier383085f2013-01-24 14:15:43 +01002578/* Make sure openssl opens /dev/urandom before the chroot. The work is only
2579 * done once. Zero is returned if the operation fails. No error is returned
2580 * if the random is said as not implemented, because we expect that openssl
2581 * will use another method once needed.
2582 */
2583static int ssl_initialize_random()
2584{
2585 unsigned char random;
2586 static int random_initialized = 0;
2587
2588 if (!random_initialized && RAND_bytes(&random, 1) != 0)
2589 random_initialized = 1;
2590
2591 return random_initialized;
2592}
2593
Willy Tarreau03209342016-12-22 17:08:28 +01002594int ssl_sock_load_cert_list_file(char *file, struct bind_conf *bind_conf, char **err)
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01002595{
Emmanuel Hocdet5e0e6e42016-05-13 11:18:50 +02002596 char thisline[LINESIZE*CRTLIST_FACTOR];
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01002597 FILE *f;
yanbzhu1b04e5b2015-12-02 13:54:14 -05002598 struct stat buf;
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01002599 int linenum = 0;
2600 int cfgerr = 0;
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01002601
Willy Tarreauad1731d2013-04-02 17:35:58 +02002602 if ((f = fopen(file, "r")) == NULL) {
2603 memprintf(err, "cannot open file '%s' : %s", file, strerror(errno));
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01002604 return 1;
Willy Tarreauad1731d2013-04-02 17:35:58 +02002605 }
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01002606
2607 while (fgets(thisline, sizeof(thisline), f) != NULL) {
2608 int arg;
Emeric Brun50bcecc2013-04-22 13:05:23 +02002609 int newarg;
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01002610 char *end;
Emmanuel Hocdet5e0e6e42016-05-13 11:18:50 +02002611 char *args[MAX_LINE_ARGS*CRTLIST_FACTOR + 1];
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01002612 char *line = thisline;
2613
2614 linenum++;
2615 end = line + strlen(line);
2616 if (end-line == sizeof(thisline)-1 && *(end-1) != '\n') {
2617 /* Check if we reached the limit and the last char is not \n.
2618 * Watch out for the last line without the terminating '\n'!
2619 */
Willy Tarreauad1731d2013-04-02 17:35:58 +02002620 memprintf(err, "line %d too long in file '%s', limit is %d characters",
2621 linenum, file, (int)sizeof(thisline)-1);
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01002622 cfgerr = 1;
Willy Tarreauad1731d2013-04-02 17:35:58 +02002623 break;
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01002624 }
2625
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01002626 arg = 0;
Emeric Brun50bcecc2013-04-22 13:05:23 +02002627 newarg = 1;
2628 while (*line) {
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01002629 if (*line == '#' || *line == '\n' || *line == '\r') {
2630 /* end of string, end of loop */
2631 *line = 0;
2632 break;
2633 }
2634 else if (isspace(*line)) {
Emeric Brun50bcecc2013-04-22 13:05:23 +02002635 newarg = 1;
2636 *line = 0;
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01002637 }
Emeric Brun50bcecc2013-04-22 13:05:23 +02002638 else if (newarg) {
Emmanuel Hocdet5e0e6e42016-05-13 11:18:50 +02002639 if (arg == MAX_LINE_ARGS*CRTLIST_FACTOR) {
Emeric Brun50bcecc2013-04-22 13:05:23 +02002640 memprintf(err, "too many args on line %d in file '%s'.",
2641 linenum, file);
2642 cfgerr = 1;
2643 break;
2644 }
2645 newarg = 0;
2646 args[arg++] = line;
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01002647 }
Emeric Brun50bcecc2013-04-22 13:05:23 +02002648 line++;
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01002649 }
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +02002650 if (cfgerr)
2651 break;
Willy Tarreauad1731d2013-04-02 17:35:58 +02002652
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01002653 /* empty line */
Emeric Brun50bcecc2013-04-22 13:05:23 +02002654 if (!arg)
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01002655 continue;
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01002656
yanbzhu1b04e5b2015-12-02 13:54:14 -05002657 if (stat(args[0], &buf) == 0) {
Willy Tarreau03209342016-12-22 17:08:28 +01002658 cfgerr = ssl_sock_load_cert_file(args[0], bind_conf, &args[1], arg-1, err);
yanbzhu1b04e5b2015-12-02 13:54:14 -05002659 } else {
Willy Tarreau03209342016-12-22 17:08:28 +01002660 cfgerr = ssl_sock_load_multi_cert(args[0], bind_conf, &args[1], arg-1, err);
yanbzhu1b04e5b2015-12-02 13:54:14 -05002661 }
2662
Willy Tarreauad1731d2013-04-02 17:35:58 +02002663 if (cfgerr) {
2664 memprintf(err, "error processing line %d in file '%s' : %s", linenum, file, *err);
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01002665 break;
Willy Tarreauad1731d2013-04-02 17:35:58 +02002666 }
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01002667 }
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01002668 fclose(f);
2669 return cfgerr;
2670}
2671
Emeric Brunfc0421f2012-09-07 17:30:07 +02002672#ifndef SSL_OP_CIPHER_SERVER_PREFERENCE /* needs OpenSSL >= 0.9.7 */
2673#define SSL_OP_CIPHER_SERVER_PREFERENCE 0
2674#endif
2675
2676#ifndef SSL_OP_NO_SESSION_RESUMPTION_ON_RENEGOTIATION /* needs OpenSSL >= 0.9.7 */
2677#define SSL_OP_NO_SESSION_RESUMPTION_ON_RENEGOTIATION 0
Willy Tarreau7d588ee2012-11-26 18:47:31 +01002678#define SSL_renegotiate_pending(arg) 0
Emeric Brunfc0421f2012-09-07 17:30:07 +02002679#endif
Emeric Brun2b58d042012-09-20 17:10:03 +02002680#ifndef SSL_OP_SINGLE_ECDH_USE /* needs OpenSSL >= 0.9.8 */
2681#define SSL_OP_SINGLE_ECDH_USE 0
2682#endif
Emeric Brun2d0c4822012-10-02 13:45:20 +02002683#ifndef SSL_OP_NO_TICKET /* needs OpenSSL >= 0.9.8 */
2684#define SSL_OP_NO_TICKET 0
2685#endif
Emeric Brunfc0421f2012-09-07 17:30:07 +02002686#ifndef SSL_OP_NO_COMPRESSION /* needs OpenSSL >= 0.9.9 */
2687#define SSL_OP_NO_COMPRESSION 0
2688#endif
Emeric Brunc0ff4922012-09-28 19:37:02 +02002689#ifndef SSL_OP_NO_TLSv1_1 /* needs OpenSSL >= 1.0.1 */
2690#define SSL_OP_NO_TLSv1_1 0
2691#endif
2692#ifndef SSL_OP_NO_TLSv1_2 /* needs OpenSSL >= 1.0.1 */
2693#define SSL_OP_NO_TLSv1_2 0
2694#endif
Emeric Bruna4bcd9a2012-09-20 16:19:02 +02002695#ifndef SSL_OP_SINGLE_DH_USE /* needs OpenSSL >= 0.9.6 */
2696#define SSL_OP_SINGLE_DH_USE 0
2697#endif
Emeric Brun2b58d042012-09-20 17:10:03 +02002698#ifndef SSL_OP_SINGLE_ECDH_USE /* needs OpenSSL >= 1.0.0 */
2699#define SSL_OP_SINGLE_ECDH_USE 0
2700#endif
Emeric Brunfc0421f2012-09-07 17:30:07 +02002701#ifndef SSL_MODE_RELEASE_BUFFERS /* needs OpenSSL >= 1.0.0 */
2702#define SSL_MODE_RELEASE_BUFFERS 0
2703#endif
Willy Tarreau396a1862014-11-13 14:06:52 +01002704#ifndef SSL_MODE_SMALL_BUFFERS /* needs small_records.patch */
2705#define SSL_MODE_SMALL_BUFFERS 0
2706#endif
Remi Gacognef46cd6e2014-06-12 14:58:40 +02002707
Willy Tarreau03209342016-12-22 17:08:28 +01002708int ssl_sock_prepare_ctx(struct bind_conf *bind_conf, SSL_CTX *ctx)
Emeric Brunfc0421f2012-09-07 17:30:07 +02002709{
Willy Tarreau03209342016-12-22 17:08:28 +01002710 struct proxy *curproxy = bind_conf->frontend;
Emeric Brunfc0421f2012-09-07 17:30:07 +02002711 int cfgerr = 0;
Emeric Brun850efd52014-01-29 12:24:34 +01002712 int verify = SSL_VERIFY_NONE;
Remi Gacogneaf5c3da2014-05-19 10:29:58 +02002713 long ssloptions =
Emeric Brunfc0421f2012-09-07 17:30:07 +02002714 SSL_OP_ALL | /* all known workarounds for bugs */
2715 SSL_OP_NO_SSLv2 |
2716 SSL_OP_NO_COMPRESSION |
Emeric Bruna4bcd9a2012-09-20 16:19:02 +02002717 SSL_OP_SINGLE_DH_USE |
Emeric Brun2b58d042012-09-20 17:10:03 +02002718 SSL_OP_SINGLE_ECDH_USE |
Emeric Brun3c4bc6e2012-10-04 18:44:19 +02002719 SSL_OP_NO_SESSION_RESUMPTION_ON_RENEGOTIATION |
2720 SSL_OP_CIPHER_SERVER_PREFERENCE;
Remi Gacogneaf5c3da2014-05-19 10:29:58 +02002721 long sslmode =
Emeric Brunfc0421f2012-09-07 17:30:07 +02002722 SSL_MODE_ENABLE_PARTIAL_WRITE |
2723 SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER |
Willy Tarreau396a1862014-11-13 14:06:52 +01002724 SSL_MODE_RELEASE_BUFFERS |
2725 SSL_MODE_SMALL_BUFFERS;
Remi Gacognef46cd6e2014-06-12 14:58:40 +02002726 STACK_OF(SSL_CIPHER) * ciphers = NULL;
Willy Tarreaua616ba62014-10-26 06:49:19 +01002727 SSL_CIPHER * cipher = NULL;
Remi Gacognec1eab8c2014-06-12 18:20:11 +02002728 char cipher_description[128];
2729 /* The description of ciphers using an Ephemeral Diffie Hellman key exchange
2730 contains " Kx=DH " or " Kx=DH(". Beware of " Kx=DH/",
2731 which is not ephemeral DH. */
2732 const char dhe_description[] = " Kx=DH ";
2733 const char dhe_export_description[] = " Kx=DH(";
Remi Gacognef46cd6e2014-06-12 14:58:40 +02002734 int idx = 0;
2735 int dhe_found = 0;
Remi Gacogne23d5d372014-10-10 17:04:26 +02002736 SSL *ssl = NULL;
Emeric Brunfc0421f2012-09-07 17:30:07 +02002737
Thierry Fournier383085f2013-01-24 14:15:43 +01002738 /* Make sure openssl opens /dev/urandom before the chroot */
2739 if (!ssl_initialize_random()) {
2740 Alert("OpenSSL random data generator initialization failed.\n");
2741 cfgerr++;
2742 }
2743
Emeric Brun89675492012-10-05 13:48:26 +02002744 if (bind_conf->ssl_options & BC_SSL_O_NO_SSLV3)
Emeric Brunfc0421f2012-09-07 17:30:07 +02002745 ssloptions |= SSL_OP_NO_SSLv3;
Emeric Brun89675492012-10-05 13:48:26 +02002746 if (bind_conf->ssl_options & BC_SSL_O_NO_TLSV10)
Emeric Brunfc0421f2012-09-07 17:30:07 +02002747 ssloptions |= SSL_OP_NO_TLSv1;
Emeric Brun89675492012-10-05 13:48:26 +02002748 if (bind_conf->ssl_options & BC_SSL_O_NO_TLSV11)
Emeric Brunc0ff4922012-09-28 19:37:02 +02002749 ssloptions |= SSL_OP_NO_TLSv1_1;
Emeric Brun89675492012-10-05 13:48:26 +02002750 if (bind_conf->ssl_options & BC_SSL_O_NO_TLSV12)
Emeric Brunc0ff4922012-09-28 19:37:02 +02002751 ssloptions |= SSL_OP_NO_TLSv1_2;
Emeric Brun89675492012-10-05 13:48:26 +02002752 if (bind_conf->ssl_options & BC_SSL_O_NO_TLS_TICKETS)
Emeric Brun2d0c4822012-10-02 13:45:20 +02002753 ssloptions |= SSL_OP_NO_TICKET;
Jérémie Courrèges-Anglas17c3f622015-07-25 16:50:52 -06002754 if (bind_conf->ssl_options & BC_SSL_O_USE_SSLV3) {
2755#ifndef OPENSSL_NO_SSL3
Emeric Brun2cb7ae52012-10-05 14:14:21 +02002756 SSL_CTX_set_ssl_version(ctx, SSLv3_server_method());
Jérémie Courrèges-Anglas17c3f622015-07-25 16:50:52 -06002757#else
2758 Alert("SSLv3 support requested but unavailable.\n");
2759 cfgerr++;
2760#endif
2761 }
Emeric Brun2cb7ae52012-10-05 14:14:21 +02002762 if (bind_conf->ssl_options & BC_SSL_O_USE_TLSV10)
2763 SSL_CTX_set_ssl_version(ctx, TLSv1_server_method());
2764#if SSL_OP_NO_TLSv1_1
2765 if (bind_conf->ssl_options & BC_SSL_O_USE_TLSV11)
2766 SSL_CTX_set_ssl_version(ctx, TLSv1_1_server_method());
2767#endif
2768#if SSL_OP_NO_TLSv1_2
2769 if (bind_conf->ssl_options & BC_SSL_O_USE_TLSV12)
2770 SSL_CTX_set_ssl_version(ctx, TLSv1_2_server_method());
2771#endif
Emeric Brunfc0421f2012-09-07 17:30:07 +02002772
2773 SSL_CTX_set_options(ctx, ssloptions);
2774 SSL_CTX_set_mode(ctx, sslmode);
Emeric Brun850efd52014-01-29 12:24:34 +01002775 switch (bind_conf->verify) {
2776 case SSL_SOCK_VERIFY_NONE:
2777 verify = SSL_VERIFY_NONE;
2778 break;
2779 case SSL_SOCK_VERIFY_OPTIONAL:
2780 verify = SSL_VERIFY_PEER;
2781 break;
2782 case SSL_SOCK_VERIFY_REQUIRED:
2783 verify = SSL_VERIFY_PEER|SSL_VERIFY_FAIL_IF_NO_PEER_CERT;
2784 break;
2785 }
2786 SSL_CTX_set_verify(ctx, verify, ssl_sock_bind_verifycbk);
2787 if (verify & SSL_VERIFY_PEER) {
Emeric Brunfb510ea2012-10-05 12:00:26 +02002788 if (bind_conf->ca_file) {
Emeric Brund94b3fe2012-09-20 18:23:56 +02002789 /* load CAfile to verify */
Emeric Brunfb510ea2012-10-05 12:00:26 +02002790 if (!SSL_CTX_load_verify_locations(ctx, bind_conf->ca_file, NULL)) {
Emeric Brund94b3fe2012-09-20 18:23:56 +02002791 Alert("Proxy '%s': unable to load CA file '%s' for bind '%s' at [%s:%d].\n",
Emeric Brunfb510ea2012-10-05 12:00:26 +02002792 curproxy->id, bind_conf->ca_file, bind_conf->arg, bind_conf->file, bind_conf->line);
Emeric Brund94b3fe2012-09-20 18:23:56 +02002793 cfgerr++;
2794 }
2795 /* set CA names fo client cert request, function returns void */
Emeric Brunfb510ea2012-10-05 12:00:26 +02002796 SSL_CTX_set_client_CA_list(ctx, SSL_load_client_CA_file(bind_conf->ca_file));
Emeric Brund94b3fe2012-09-20 18:23:56 +02002797 }
Emeric Brun850efd52014-01-29 12:24:34 +01002798 else {
2799 Alert("Proxy '%s': verify is enabled but no CA file specified for bind '%s' at [%s:%d].\n",
2800 curproxy->id, bind_conf->arg, bind_conf->file, bind_conf->line);
2801 cfgerr++;
2802 }
Emeric Brun051cdab2012-10-02 19:25:50 +02002803#ifdef X509_V_FLAG_CRL_CHECK
Emeric Brunfb510ea2012-10-05 12:00:26 +02002804 if (bind_conf->crl_file) {
Emeric Brund94b3fe2012-09-20 18:23:56 +02002805 X509_STORE *store = SSL_CTX_get_cert_store(ctx);
2806
Emeric Brunfb510ea2012-10-05 12:00:26 +02002807 if (!store || !X509_STORE_load_locations(store, bind_conf->crl_file, NULL)) {
Emeric Brund94b3fe2012-09-20 18:23:56 +02002808 Alert("Proxy '%s': unable to configure CRL file '%s' for bind '%s' at [%s:%d].\n",
Alexander Rigbofc65af02015-04-07 14:02:16 +02002809 curproxy->id, bind_conf->crl_file, bind_conf->arg, bind_conf->file, bind_conf->line);
Emeric Brund94b3fe2012-09-20 18:23:56 +02002810 cfgerr++;
2811 }
Emeric Brun561e5742012-10-02 15:20:55 +02002812 else {
2813 X509_STORE_set_flags(store, X509_V_FLAG_CRL_CHECK|X509_V_FLAG_CRL_CHECK_ALL);
2814 }
Emeric Brund94b3fe2012-09-20 18:23:56 +02002815 }
Emeric Brun051cdab2012-10-02 19:25:50 +02002816#endif
Emeric Brun644cde02012-12-14 11:21:13 +01002817 ERR_clear_error();
Emeric Brund94b3fe2012-09-20 18:23:56 +02002818 }
Emeric Brunfc0421f2012-09-07 17:30:07 +02002819
Nenad Merdanovic05552d42015-02-27 19:56:49 +01002820#if (defined SSL_CTRL_SET_TLSEXT_TICKET_KEY_CB && TLS_TICKETS_NO > 0)
Nenad Merdanovic146defa2015-05-09 08:46:00 +02002821 if(bind_conf->keys_ref) {
Nenad Merdanovic05552d42015-02-27 19:56:49 +01002822 if (!SSL_CTX_set_tlsext_ticket_key_cb(ctx, ssl_tlsext_ticket_key_cb)) {
2823 Alert("Proxy '%s': unable to set callback for TLS ticket validation for bind '%s' at [%s:%d].\n",
2824 curproxy->id, bind_conf->arg, bind_conf->file, bind_conf->line);
2825 cfgerr++;
2826 }
2827 }
2828#endif
2829
Willy Tarreauef934602016-12-22 23:12:01 +01002830 if (global_ssl.life_time)
2831 SSL_CTX_set_timeout(ctx, global_ssl.life_time);
Emeric Brun4f65bff2012-11-16 15:11:00 +01002832
Emeric Brunfc0421f2012-09-07 17:30:07 +02002833 shared_context_set_cache(ctx);
Willy Tarreau2a65ff02012-09-13 17:54:29 +02002834 if (bind_conf->ciphers &&
2835 !SSL_CTX_set_cipher_list(ctx, bind_conf->ciphers)) {
Emeric Brunfc0421f2012-09-07 17:30:07 +02002836 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 +02002837 curproxy->id, bind_conf->ciphers, bind_conf->arg, bind_conf->file, bind_conf->line);
Emeric Brunfc0421f2012-09-07 17:30:07 +02002838 cfgerr++;
2839 }
2840
Remi Gacogne47783ef2015-05-29 15:53:22 +02002841 /* If tune.ssl.default-dh-param has not been set,
2842 neither has ssl-default-dh-file and no static DH
2843 params were in the certificate file. */
Willy Tarreauef934602016-12-22 23:12:01 +01002844 if (global_ssl.default_dh_param == 0 &&
Remi Gacogne47783ef2015-05-29 15:53:22 +02002845 global_dh == NULL &&
Remi Gacogne4f902b82015-05-28 16:23:00 +02002846 (ssl_dh_ptr_index == -1 ||
2847 SSL_CTX_get_ex_data(ctx, ssl_dh_ptr_index) == NULL)) {
Lukas Tribus90132722014-08-18 00:56:33 +02002848
Remi Gacogne23d5d372014-10-10 17:04:26 +02002849 ssl = SSL_new(ctx);
Remi Gacognef46cd6e2014-06-12 14:58:40 +02002850
Remi Gacogne23d5d372014-10-10 17:04:26 +02002851 if (ssl) {
2852 ciphers = SSL_get_ciphers(ssl);
2853
2854 if (ciphers) {
2855 for (idx = 0; idx < sk_SSL_CIPHER_num(ciphers); idx++) {
2856 cipher = sk_SSL_CIPHER_value(ciphers, idx);
2857 if (SSL_CIPHER_description(cipher, cipher_description, sizeof (cipher_description)) == cipher_description) {
2858 if (strstr(cipher_description, dhe_description) != NULL ||
2859 strstr(cipher_description, dhe_export_description) != NULL) {
2860 dhe_found = 1;
2861 break;
2862 }
Remi Gacognec1eab8c2014-06-12 18:20:11 +02002863 }
Remi Gacognef46cd6e2014-06-12 14:58:40 +02002864 }
2865 }
Remi Gacogne23d5d372014-10-10 17:04:26 +02002866 SSL_free(ssl);
2867 ssl = NULL;
Lukas Tribus90132722014-08-18 00:56:33 +02002868 }
Remi Gacognef46cd6e2014-06-12 14:58:40 +02002869
Lukas Tribus90132722014-08-18 00:56:33 +02002870 if (dhe_found) {
2871 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 +02002872 }
2873
Willy Tarreauef934602016-12-22 23:12:01 +01002874 global_ssl.default_dh_param = 1024;
Remi Gacognef46cd6e2014-06-12 14:58:40 +02002875 }
Remi Gacogne8de54152014-07-15 11:36:40 +02002876
2877#ifndef OPENSSL_NO_DH
Willy Tarreauef934602016-12-22 23:12:01 +01002878 if (global_ssl.default_dh_param >= 1024) {
Remi Gacogne8de54152014-07-15 11:36:40 +02002879 if (local_dh_1024 == NULL) {
2880 local_dh_1024 = ssl_get_dh_1024();
2881 }
Willy Tarreauef934602016-12-22 23:12:01 +01002882 if (global_ssl.default_dh_param >= 2048) {
Remi Gacogne8de54152014-07-15 11:36:40 +02002883 if (local_dh_2048 == NULL) {
2884 local_dh_2048 = ssl_get_dh_2048();
2885 }
Willy Tarreauef934602016-12-22 23:12:01 +01002886 if (global_ssl.default_dh_param >= 4096) {
Remi Gacogne8de54152014-07-15 11:36:40 +02002887 if (local_dh_4096 == NULL) {
2888 local_dh_4096 = ssl_get_dh_4096();
2889 }
Remi Gacogne8de54152014-07-15 11:36:40 +02002890 }
2891 }
2892 }
2893#endif /* OPENSSL_NO_DH */
Remi Gacognef46cd6e2014-06-12 14:58:40 +02002894
Emeric Brunfc0421f2012-09-07 17:30:07 +02002895 SSL_CTX_set_info_callback(ctx, ssl_sock_infocbk);
Willy Tarreau5cbe4ef2014-05-08 22:45:11 +02002896#if OPENSSL_VERSION_NUMBER >= 0x00907000L
Emeric Brun29f037d2014-04-25 19:05:36 +02002897 SSL_CTX_set_msg_callback(ctx, ssl_sock_msgcbk);
Willy Tarreau5cbe4ef2014-05-08 22:45:11 +02002898#endif
Emeric Brun29f037d2014-04-25 19:05:36 +02002899
Willy Tarreau6c9a3d52012-10-18 18:57:14 +02002900#ifdef OPENSSL_NPN_NEGOTIATED
2901 if (bind_conf->npn_str)
2902 SSL_CTX_set_next_protos_advertised_cb(ctx, ssl_sock_advertise_npn_protos, bind_conf);
2903#endif
Dirkjan Bussink48f1c4e2014-02-13 12:29:42 +01002904#ifdef TLSEXT_TYPE_application_layer_protocol_negotiation
Willy Tarreauab861d32013-04-02 02:30:41 +02002905 if (bind_conf->alpn_str)
Dirkjan Bussink48f1c4e2014-02-13 12:29:42 +01002906 SSL_CTX_set_alpn_select_cb(ctx, ssl_sock_advertise_alpn_protos, bind_conf);
Willy Tarreauab861d32013-04-02 02:30:41 +02002907#endif
Willy Tarreau6c9a3d52012-10-18 18:57:14 +02002908
Emeric Brunfc0421f2012-09-07 17:30:07 +02002909#ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME
2910 SSL_CTX_set_tlsext_servername_callback(ctx, ssl_sock_switchctx_cbk);
Willy Tarreau2a65ff02012-09-13 17:54:29 +02002911 SSL_CTX_set_tlsext_servername_arg(ctx, bind_conf);
Emeric Brunfc0421f2012-09-07 17:30:07 +02002912#endif
Emeric Brun2b58d042012-09-20 17:10:03 +02002913#if defined(SSL_CTX_set_tmp_ecdh) && !defined(OPENSSL_NO_ECDH)
Emeric Brun6924ef82013-03-06 14:08:53 +01002914 {
Emeric Brun2b58d042012-09-20 17:10:03 +02002915 int i;
2916 EC_KEY *ecdh;
2917
Emeric Brun6924ef82013-03-06 14:08:53 +01002918 i = OBJ_sn2nid(bind_conf->ecdhe ? bind_conf->ecdhe : ECDHE_DEFAULT_CURVE);
Emeric Brun2b58d042012-09-20 17:10:03 +02002919 if (!i || ((ecdh = EC_KEY_new_by_curve_name(i)) == NULL)) {
2920 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 +01002921 curproxy->id, bind_conf->ecdhe ? bind_conf->ecdhe : ECDHE_DEFAULT_CURVE,
2922 bind_conf->arg, bind_conf->file, bind_conf->line);
Emeric Brun2b58d042012-09-20 17:10:03 +02002923 cfgerr++;
2924 }
2925 else {
2926 SSL_CTX_set_tmp_ecdh(ctx, ecdh);
2927 EC_KEY_free(ecdh);
2928 }
2929 }
2930#endif
2931
Emeric Brunfc0421f2012-09-07 17:30:07 +02002932 return cfgerr;
2933}
2934
Evan Broderbe554312013-06-27 00:05:25 -07002935static int ssl_sock_srv_hostcheck(const char *pattern, const char *hostname)
2936{
2937 const char *pattern_wildcard, *pattern_left_label_end, *hostname_left_label_end;
2938 size_t prefixlen, suffixlen;
2939
2940 /* Trivial case */
2941 if (strcmp(pattern, hostname) == 0)
2942 return 1;
2943
Evan Broderbe554312013-06-27 00:05:25 -07002944 /* The rest of this logic is based on RFC 6125, section 6.4.3
2945 * (http://tools.ietf.org/html/rfc6125#section-6.4.3) */
2946
Emeric Bruna848dae2013-10-08 11:27:28 +02002947 pattern_wildcard = NULL;
2948 pattern_left_label_end = pattern;
2949 while (*pattern_left_label_end != '.') {
2950 switch (*pattern_left_label_end) {
2951 case 0:
2952 /* End of label not found */
2953 return 0;
2954 case '*':
2955 /* If there is more than one wildcards */
2956 if (pattern_wildcard)
2957 return 0;
2958 pattern_wildcard = pattern_left_label_end;
2959 break;
2960 }
2961 pattern_left_label_end++;
2962 }
2963
2964 /* If it's not trivial and there is no wildcard, it can't
2965 * match */
2966 if (!pattern_wildcard)
Evan Broderbe554312013-06-27 00:05:25 -07002967 return 0;
2968
2969 /* Make sure all labels match except the leftmost */
2970 hostname_left_label_end = strchr(hostname, '.');
2971 if (!hostname_left_label_end
2972 || strcmp(pattern_left_label_end, hostname_left_label_end) != 0)
2973 return 0;
2974
2975 /* Make sure the leftmost label of the hostname is long enough
2976 * that the wildcard can match */
Emeric Brun369da852013-10-08 11:39:35 +02002977 if (hostname_left_label_end - hostname < (pattern_left_label_end - pattern) - 1)
Evan Broderbe554312013-06-27 00:05:25 -07002978 return 0;
2979
2980 /* Finally compare the string on either side of the
2981 * wildcard */
2982 prefixlen = pattern_wildcard - pattern;
2983 suffixlen = pattern_left_label_end - (pattern_wildcard + 1);
Emeric Bruna848dae2013-10-08 11:27:28 +02002984 if ((prefixlen && (memcmp(pattern, hostname, prefixlen) != 0))
2985 || (suffixlen && (memcmp(pattern_wildcard + 1, hostname_left_label_end - suffixlen, suffixlen) != 0)))
Evan Broderbe554312013-06-27 00:05:25 -07002986 return 0;
2987
2988 return 1;
2989}
2990
2991static int ssl_sock_srv_verifycbk(int ok, X509_STORE_CTX *ctx)
2992{
2993 SSL *ssl;
2994 struct connection *conn;
2995 char *servername;
2996
2997 int depth;
2998 X509 *cert;
2999 STACK_OF(GENERAL_NAME) *alt_names;
3000 int i;
3001 X509_NAME *cert_subject;
3002 char *str;
3003
3004 if (ok == 0)
3005 return ok;
3006
3007 ssl = X509_STORE_CTX_get_ex_data(ctx, SSL_get_ex_data_X509_STORE_CTX_idx());
Vincent Bernat3c2f2f22016-04-03 13:48:42 +02003008 conn = SSL_get_app_data(ssl);
Evan Broderbe554312013-06-27 00:05:25 -07003009
3010 servername = objt_server(conn->target)->ssl_ctx.verify_host;
3011
3012 /* We only need to verify the CN on the actual server cert,
3013 * not the indirect CAs */
3014 depth = X509_STORE_CTX_get_error_depth(ctx);
3015 if (depth != 0)
3016 return ok;
3017
3018 /* At this point, the cert is *not* OK unless we can find a
3019 * hostname match */
3020 ok = 0;
3021
3022 cert = X509_STORE_CTX_get_current_cert(ctx);
3023 /* It seems like this might happen if verify peer isn't set */
3024 if (!cert)
3025 return ok;
3026
3027 alt_names = X509_get_ext_d2i(cert, NID_subject_alt_name, NULL, NULL);
3028 if (alt_names) {
3029 for (i = 0; !ok && i < sk_GENERAL_NAME_num(alt_names); i++) {
3030 GENERAL_NAME *name = sk_GENERAL_NAME_value(alt_names, i);
3031 if (name->type == GEN_DNS) {
Emeric Bruna33410c2013-09-17 15:47:48 +02003032#if OPENSSL_VERSION_NUMBER < 0x00907000L
3033 if (ASN1_STRING_to_UTF8((unsigned char **)&str, name->d.ia5) >= 0) {
3034#else
Evan Broderbe554312013-06-27 00:05:25 -07003035 if (ASN1_STRING_to_UTF8((unsigned char **)&str, name->d.dNSName) >= 0) {
Emeric Bruna33410c2013-09-17 15:47:48 +02003036#endif
Evan Broderbe554312013-06-27 00:05:25 -07003037 ok = ssl_sock_srv_hostcheck(str, servername);
3038 OPENSSL_free(str);
3039 }
3040 }
3041 }
Emeric Brun4ad50a42013-09-17 15:19:54 +02003042 sk_GENERAL_NAME_pop_free(alt_names, GENERAL_NAME_free);
Evan Broderbe554312013-06-27 00:05:25 -07003043 }
3044
3045 cert_subject = X509_get_subject_name(cert);
3046 i = -1;
3047 while (!ok && (i = X509_NAME_get_index_by_NID(cert_subject, NID_commonName, i)) != -1) {
3048 X509_NAME_ENTRY *entry = X509_NAME_get_entry(cert_subject, i);
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02003049 ASN1_STRING *value;
3050 value = X509_NAME_ENTRY_get_data(entry);
3051 if (ASN1_STRING_to_UTF8((unsigned char **)&str, value) >= 0) {
Evan Broderbe554312013-06-27 00:05:25 -07003052 ok = ssl_sock_srv_hostcheck(str, servername);
3053 OPENSSL_free(str);
3054 }
3055 }
3056
3057 return ok;
3058}
3059
Emeric Brun94324a42012-10-11 14:00:19 +02003060/* prepare ssl context from servers options. Returns an error count */
Willy Tarreau03209342016-12-22 17:08:28 +01003061int ssl_sock_prepare_srv_ctx(struct server *srv)
Emeric Brun94324a42012-10-11 14:00:19 +02003062{
Willy Tarreau03209342016-12-22 17:08:28 +01003063 struct proxy *curproxy = srv->proxy;
Emeric Brun94324a42012-10-11 14:00:19 +02003064 int cfgerr = 0;
Remi Gacogneaf5c3da2014-05-19 10:29:58 +02003065 long options =
Emeric Brun94324a42012-10-11 14:00:19 +02003066 SSL_OP_ALL | /* all known workarounds for bugs */
3067 SSL_OP_NO_SSLv2 |
3068 SSL_OP_NO_COMPRESSION;
Remi Gacogneaf5c3da2014-05-19 10:29:58 +02003069 long mode =
Emeric Brun94324a42012-10-11 14:00:19 +02003070 SSL_MODE_ENABLE_PARTIAL_WRITE |
3071 SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER |
Willy Tarreau396a1862014-11-13 14:06:52 +01003072 SSL_MODE_RELEASE_BUFFERS |
3073 SSL_MODE_SMALL_BUFFERS;
Emeric Brun850efd52014-01-29 12:24:34 +01003074 int verify = SSL_VERIFY_NONE;
Emeric Brun94324a42012-10-11 14:00:19 +02003075
Thierry Fournier383085f2013-01-24 14:15:43 +01003076 /* Make sure openssl opens /dev/urandom before the chroot */
3077 if (!ssl_initialize_random()) {
3078 Alert("OpenSSL random data generator initialization failed.\n");
3079 cfgerr++;
3080 }
3081
Willy Tarreaufce03112015-01-15 21:32:40 +01003082 /* Automatic memory computations need to know we use SSL there */
3083 global.ssl_used_backend = 1;
3084
3085 /* Initiate SSL context for current server */
Emeric Brun94324a42012-10-11 14:00:19 +02003086 srv->ssl_ctx.reused_sess = NULL;
3087 if (srv->use_ssl)
3088 srv->xprt = &ssl_sock;
3089 if (srv->check.use_ssl)
Cyril Bonté9ce13112014-11-15 22:41:27 +01003090 srv->check.xprt = &ssl_sock;
Emeric Brun94324a42012-10-11 14:00:19 +02003091
3092 srv->ssl_ctx.ctx = SSL_CTX_new(SSLv23_client_method());
3093 if (!srv->ssl_ctx.ctx) {
3094 Alert("config : %s '%s', server '%s': unable to allocate ssl context.\n",
3095 proxy_type_str(curproxy), curproxy->id,
3096 srv->id);
3097 cfgerr++;
3098 return cfgerr;
3099 }
Emeric Bruna7aa3092012-10-26 12:58:00 +02003100 if (srv->ssl_ctx.client_crt) {
3101 if (SSL_CTX_use_PrivateKey_file(srv->ssl_ctx.ctx, srv->ssl_ctx.client_crt, SSL_FILETYPE_PEM) <= 0) {
3102 Alert("config : %s '%s', server '%s': unable to load SSL private key from PEM file '%s'.\n",
3103 proxy_type_str(curproxy), curproxy->id,
3104 srv->id, srv->ssl_ctx.client_crt);
3105 cfgerr++;
3106 }
3107 else if (SSL_CTX_use_certificate_chain_file(srv->ssl_ctx.ctx, srv->ssl_ctx.client_crt) <= 0) {
3108 Alert("config : %s '%s', server '%s': unable to load ssl certificate from PEM file '%s'.\n",
3109 proxy_type_str(curproxy), curproxy->id,
3110 srv->id, srv->ssl_ctx.client_crt);
3111 cfgerr++;
3112 }
3113 else if (SSL_CTX_check_private_key(srv->ssl_ctx.ctx) <= 0) {
3114 Alert("config : %s '%s', server '%s': inconsistencies between private key and certificate loaded from PEM file '%s'.\n",
3115 proxy_type_str(curproxy), curproxy->id,
3116 srv->id, srv->ssl_ctx.client_crt);
3117 cfgerr++;
3118 }
3119 }
Emeric Brun94324a42012-10-11 14:00:19 +02003120
3121 if (srv->ssl_ctx.options & SRV_SSL_O_NO_SSLV3)
3122 options |= SSL_OP_NO_SSLv3;
3123 if (srv->ssl_ctx.options & SRV_SSL_O_NO_TLSV10)
3124 options |= SSL_OP_NO_TLSv1;
3125 if (srv->ssl_ctx.options & SRV_SSL_O_NO_TLSV11)
3126 options |= SSL_OP_NO_TLSv1_1;
3127 if (srv->ssl_ctx.options & SRV_SSL_O_NO_TLSV12)
3128 options |= SSL_OP_NO_TLSv1_2;
Emeric Brunf9c5c472012-10-11 15:28:34 +02003129 if (srv->ssl_ctx.options & SRV_SSL_O_NO_TLS_TICKETS)
3130 options |= SSL_OP_NO_TICKET;
Jérémie Courrèges-Anglas17c3f622015-07-25 16:50:52 -06003131 if (srv->ssl_ctx.options & SRV_SSL_O_USE_SSLV3) {
3132#ifndef OPENSSL_NO_SSL3
Emeric Brun94324a42012-10-11 14:00:19 +02003133 SSL_CTX_set_ssl_version(srv->ssl_ctx.ctx, SSLv3_client_method());
Jérémie Courrèges-Anglas17c3f622015-07-25 16:50:52 -06003134#else
Thierry FOURNIERbc965342015-08-26 08:21:26 +02003135 Alert("SSLv3 support requested but unavailable.\n");
Jérémie Courrèges-Anglas17c3f622015-07-25 16:50:52 -06003136 cfgerr++;
3137#endif
3138 }
Emeric Brun94324a42012-10-11 14:00:19 +02003139 if (srv->ssl_ctx.options & SRV_SSL_O_USE_TLSV10)
3140 SSL_CTX_set_ssl_version(srv->ssl_ctx.ctx, TLSv1_client_method());
3141#if SSL_OP_NO_TLSv1_1
3142 if (srv->ssl_ctx.options & SRV_SSL_O_USE_TLSV11)
3143 SSL_CTX_set_ssl_version(srv->ssl_ctx.ctx, TLSv1_1_client_method());
3144#endif
3145#if SSL_OP_NO_TLSv1_2
3146 if (srv->ssl_ctx.options & SRV_SSL_O_USE_TLSV12)
3147 SSL_CTX_set_ssl_version(srv->ssl_ctx.ctx, TLSv1_2_client_method());
3148#endif
3149
3150 SSL_CTX_set_options(srv->ssl_ctx.ctx, options);
3151 SSL_CTX_set_mode(srv->ssl_ctx.ctx, mode);
Emeric Brun850efd52014-01-29 12:24:34 +01003152
3153 if (global.ssl_server_verify == SSL_SERVER_VERIFY_REQUIRED)
3154 verify = SSL_VERIFY_PEER;
3155
3156 switch (srv->ssl_ctx.verify) {
3157 case SSL_SOCK_VERIFY_NONE:
3158 verify = SSL_VERIFY_NONE;
3159 break;
3160 case SSL_SOCK_VERIFY_REQUIRED:
3161 verify = SSL_VERIFY_PEER;
3162 break;
3163 }
Evan Broderbe554312013-06-27 00:05:25 -07003164 SSL_CTX_set_verify(srv->ssl_ctx.ctx,
Emeric Brun850efd52014-01-29 12:24:34 +01003165 verify,
Evan Broderbe554312013-06-27 00:05:25 -07003166 srv->ssl_ctx.verify_host ? ssl_sock_srv_verifycbk : NULL);
Emeric Brun850efd52014-01-29 12:24:34 +01003167 if (verify & SSL_VERIFY_PEER) {
Emeric Brunef42d922012-10-11 16:11:36 +02003168 if (srv->ssl_ctx.ca_file) {
3169 /* load CAfile to verify */
3170 if (!SSL_CTX_load_verify_locations(srv->ssl_ctx.ctx, srv->ssl_ctx.ca_file, NULL)) {
Willy Tarreau07ba08b2014-02-16 19:22:08 +01003171 Alert("Proxy '%s', server '%s' [%s:%d] unable to load CA file '%s'.\n",
Emeric Brunef42d922012-10-11 16:11:36 +02003172 curproxy->id, srv->id,
3173 srv->conf.file, srv->conf.line, srv->ssl_ctx.ca_file);
3174 cfgerr++;
3175 }
3176 }
Emeric Brun850efd52014-01-29 12:24:34 +01003177 else {
3178 if (global.ssl_server_verify == SSL_SERVER_VERIFY_REQUIRED)
Willy Tarreau07ba08b2014-02-16 19:22:08 +01003179 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 +01003180 curproxy->id, srv->id,
3181 srv->conf.file, srv->conf.line);
3182 else
Willy Tarreau07ba08b2014-02-16 19:22:08 +01003183 Alert("Proxy '%s', server '%s' [%s:%d] verify is enabled but no CA file specified.\n",
Emeric Brun850efd52014-01-29 12:24:34 +01003184 curproxy->id, srv->id,
3185 srv->conf.file, srv->conf.line);
3186 cfgerr++;
3187 }
Emeric Brunef42d922012-10-11 16:11:36 +02003188#ifdef X509_V_FLAG_CRL_CHECK
3189 if (srv->ssl_ctx.crl_file) {
3190 X509_STORE *store = SSL_CTX_get_cert_store(srv->ssl_ctx.ctx);
3191
3192 if (!store || !X509_STORE_load_locations(store, srv->ssl_ctx.crl_file, NULL)) {
Willy Tarreau07ba08b2014-02-16 19:22:08 +01003193 Alert("Proxy '%s', server '%s' [%s:%d] unable to configure CRL file '%s'.\n",
Emeric Brunef42d922012-10-11 16:11:36 +02003194 curproxy->id, srv->id,
3195 srv->conf.file, srv->conf.line, srv->ssl_ctx.crl_file);
3196 cfgerr++;
3197 }
3198 else {
3199 X509_STORE_set_flags(store, X509_V_FLAG_CRL_CHECK|X509_V_FLAG_CRL_CHECK_ALL);
3200 }
3201 }
3202#endif
3203 }
3204
Willy Tarreauef934602016-12-22 23:12:01 +01003205 if (global_ssl.life_time)
3206 SSL_CTX_set_timeout(srv->ssl_ctx.ctx, global_ssl.life_time);
Emeric Brun4f65bff2012-11-16 15:11:00 +01003207
Emeric Brun94324a42012-10-11 14:00:19 +02003208 SSL_CTX_set_session_cache_mode(srv->ssl_ctx.ctx, SSL_SESS_CACHE_OFF);
3209 if (srv->ssl_ctx.ciphers &&
3210 !SSL_CTX_set_cipher_list(srv->ssl_ctx.ctx, srv->ssl_ctx.ciphers)) {
3211 Alert("Proxy '%s', server '%s' [%s:%d] : unable to set SSL cipher list to '%s'.\n",
3212 curproxy->id, srv->id,
3213 srv->conf.file, srv->conf.line, srv->ssl_ctx.ciphers);
3214 cfgerr++;
3215 }
3216
3217 return cfgerr;
3218}
3219
Willy Tarreau2a65ff02012-09-13 17:54:29 +02003220/* Walks down the two trees in bind_conf and prepares all certs. The pointer may
Emeric Brunfc0421f2012-09-07 17:30:07 +02003221 * be NULL, in which case nothing is done. Returns the number of errors
3222 * encountered.
3223 */
Willy Tarreau03209342016-12-22 17:08:28 +01003224int ssl_sock_prepare_all_ctx(struct bind_conf *bind_conf)
Emeric Brunfc0421f2012-09-07 17:30:07 +02003225{
3226 struct ebmb_node *node;
3227 struct sni_ctx *sni;
3228 int err = 0;
3229
Willy Tarreau2a65ff02012-09-13 17:54:29 +02003230 if (!bind_conf || !bind_conf->is_ssl)
Emeric Brunfc0421f2012-09-07 17:30:07 +02003231 return 0;
3232
Willy Tarreaufce03112015-01-15 21:32:40 +01003233 /* Automatic memory computations need to know we use SSL there */
3234 global.ssl_used_frontend = 1;
3235
Emeric Brun0bed9942014-10-30 19:25:24 +01003236 if (bind_conf->default_ctx)
Willy Tarreau03209342016-12-22 17:08:28 +01003237 err += ssl_sock_prepare_ctx(bind_conf, bind_conf->default_ctx);
Emeric Brun0bed9942014-10-30 19:25:24 +01003238
Willy Tarreau2a65ff02012-09-13 17:54:29 +02003239 node = ebmb_first(&bind_conf->sni_ctx);
Emeric Brunfc0421f2012-09-07 17:30:07 +02003240 while (node) {
3241 sni = ebmb_entry(node, struct sni_ctx, name);
Emeric Brun0bed9942014-10-30 19:25:24 +01003242 if (!sni->order && sni->ctx != bind_conf->default_ctx)
3243 /* only initialize the CTX on its first occurrence and
3244 if it is not the default_ctx */
Willy Tarreau03209342016-12-22 17:08:28 +01003245 err += ssl_sock_prepare_ctx(bind_conf, sni->ctx);
Emeric Brunfc0421f2012-09-07 17:30:07 +02003246 node = ebmb_next(node);
3247 }
3248
Willy Tarreau2a65ff02012-09-13 17:54:29 +02003249 node = ebmb_first(&bind_conf->sni_w_ctx);
Emeric Brunfc0421f2012-09-07 17:30:07 +02003250 while (node) {
3251 sni = ebmb_entry(node, struct sni_ctx, name);
Emeric Brun0bed9942014-10-30 19:25:24 +01003252 if (!sni->order && sni->ctx != bind_conf->default_ctx)
3253 /* only initialize the CTX on its first occurrence and
3254 if it is not the default_ctx */
Willy Tarreau03209342016-12-22 17:08:28 +01003255 err += ssl_sock_prepare_ctx(bind_conf, sni->ctx);
Emeric Brunfc0421f2012-09-07 17:30:07 +02003256 node = ebmb_next(node);
3257 }
3258 return err;
3259}
3260
Willy Tarreau55d37912016-12-21 23:38:39 +01003261/* Prepares all the contexts for a bind_conf and allocates the shared SSL
3262 * context if needed. Returns < 0 on error, 0 on success. The warnings and
3263 * alerts are directly emitted since the rest of the stack does it below.
3264 */
3265int ssl_sock_prepare_bind_conf(struct bind_conf *bind_conf)
3266{
3267 struct proxy *px = bind_conf->frontend;
3268 int alloc_ctx;
3269 int err;
3270
3271 if (!bind_conf->is_ssl) {
3272 if (bind_conf->default_ctx) {
3273 Warning("Proxy '%s': A certificate was specified but SSL was not enabled on bind '%s' at [%s:%d] (use 'ssl').\n",
3274 px->id, bind_conf->arg, bind_conf->file, bind_conf->line);
3275 }
3276 return 0;
3277 }
3278 if (!bind_conf->default_ctx) {
3279 Alert("Proxy '%s': no SSL certificate specified for bind '%s' at [%s:%d] (use 'crt').\n",
3280 px->id, bind_conf->arg, bind_conf->file, bind_conf->line);
3281 return -1;
3282 }
3283
Willy Tarreauef934602016-12-22 23:12:01 +01003284 alloc_ctx = shared_context_init(global.tune.sslcachesize, (!global_ssl.private_cache && (global.nbproc > 1)) ? 1 : 0);
Willy Tarreau55d37912016-12-21 23:38:39 +01003285 if (alloc_ctx < 0) {
3286 if (alloc_ctx == SHCTX_E_INIT_LOCK)
3287 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");
3288 else
3289 Alert("Unable to allocate SSL session cache.\n");
3290 return -1;
3291 }
3292
3293 err = 0;
3294 /* initialize all certificate contexts */
3295 err += ssl_sock_prepare_all_ctx(bind_conf);
3296
3297 /* initialize CA variables if the certificates generation is enabled */
3298 err += ssl_sock_load_ca(bind_conf);
3299
3300 return -err;
3301}
Christopher Faulet77fe80c2015-07-29 13:02:40 +02003302
3303/* release ssl context allocated for servers. */
3304void ssl_sock_free_srv_ctx(struct server *srv)
3305{
3306 if (srv->ssl_ctx.ctx)
3307 SSL_CTX_free(srv->ssl_ctx.ctx);
3308}
3309
Willy Tarreau2a65ff02012-09-13 17:54:29 +02003310/* Walks down the two trees in bind_conf and frees all the certs. The pointer may
Emeric Brunfc0421f2012-09-07 17:30:07 +02003311 * be NULL, in which case nothing is done. The default_ctx is nullified too.
3312 */
Willy Tarreau2a65ff02012-09-13 17:54:29 +02003313void ssl_sock_free_all_ctx(struct bind_conf *bind_conf)
Emeric Brunfc0421f2012-09-07 17:30:07 +02003314{
3315 struct ebmb_node *node, *back;
3316 struct sni_ctx *sni;
3317
Willy Tarreau2a65ff02012-09-13 17:54:29 +02003318 if (!bind_conf || !bind_conf->is_ssl)
Emeric Brunfc0421f2012-09-07 17:30:07 +02003319 return;
3320
Willy Tarreau2a65ff02012-09-13 17:54:29 +02003321 node = ebmb_first(&bind_conf->sni_ctx);
Emeric Brunfc0421f2012-09-07 17:30:07 +02003322 while (node) {
3323 sni = ebmb_entry(node, struct sni_ctx, name);
3324 back = ebmb_next(node);
3325 ebmb_delete(node);
3326 if (!sni->order) /* only free the CTX on its first occurrence */
3327 SSL_CTX_free(sni->ctx);
3328 free(sni);
3329 node = back;
3330 }
3331
Willy Tarreau2a65ff02012-09-13 17:54:29 +02003332 node = ebmb_first(&bind_conf->sni_w_ctx);
Emeric Brunfc0421f2012-09-07 17:30:07 +02003333 while (node) {
3334 sni = ebmb_entry(node, struct sni_ctx, name);
3335 back = ebmb_next(node);
3336 ebmb_delete(node);
3337 if (!sni->order) /* only free the CTX on its first occurrence */
3338 SSL_CTX_free(sni->ctx);
3339 free(sni);
3340 node = back;
3341 }
3342
Willy Tarreau2a65ff02012-09-13 17:54:29 +02003343 bind_conf->default_ctx = NULL;
Emeric Brune1f38db2012-09-03 20:36:47 +02003344}
3345
Willy Tarreau795cdab2016-12-22 17:30:54 +01003346/* Destroys all the contexts for a bind_conf. This is used during deinit(). */
3347void ssl_sock_destroy_bind_conf(struct bind_conf *bind_conf)
3348{
3349 ssl_sock_free_ca(bind_conf);
3350 ssl_sock_free_all_ctx(bind_conf);
3351 free(bind_conf->ca_file);
3352 free(bind_conf->ca_sign_file);
3353 free(bind_conf->ca_sign_pass);
3354 free(bind_conf->ciphers);
3355 free(bind_conf->ecdhe);
3356 free(bind_conf->crl_file);
3357 if (bind_conf->keys_ref) {
3358 free(bind_conf->keys_ref->filename);
3359 free(bind_conf->keys_ref->tlskeys);
3360 LIST_DEL(&bind_conf->keys_ref->list);
3361 free(bind_conf->keys_ref);
3362 }
3363 bind_conf->keys_ref = NULL;
3364 bind_conf->crl_file = NULL;
3365 bind_conf->ecdhe = NULL;
3366 bind_conf->ciphers = NULL;
3367 bind_conf->ca_sign_pass = NULL;
3368 bind_conf->ca_sign_file = NULL;
3369 bind_conf->ca_file = NULL;
3370}
3371
Christopher Faulet31af49d2015-06-09 17:29:50 +02003372/* Load CA cert file and private key used to generate certificates */
3373int
Willy Tarreau03209342016-12-22 17:08:28 +01003374ssl_sock_load_ca(struct bind_conf *bind_conf)
Christopher Faulet31af49d2015-06-09 17:29:50 +02003375{
Willy Tarreau03209342016-12-22 17:08:28 +01003376 struct proxy *px = bind_conf->frontend;
Christopher Faulet31af49d2015-06-09 17:29:50 +02003377 FILE *fp;
3378 X509 *cacert = NULL;
3379 EVP_PKEY *capkey = NULL;
3380 int err = 0;
3381
3382 if (!bind_conf || !bind_conf->generate_certs)
3383 return err;
3384
Willy Tarreaua84c2672015-10-09 12:10:13 +02003385#ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME
Willy Tarreauef934602016-12-22 23:12:01 +01003386 if (global_ssl.ctx_cache)
3387 ssl_ctx_lru_tree = lru64_new(global_ssl.ctx_cache);
Christopher Fauletd2cab922015-07-28 16:03:47 +02003388 ssl_ctx_lru_seed = (unsigned int)time(NULL);
Willy Tarreaua84c2672015-10-09 12:10:13 +02003389#endif
Christopher Fauletd2cab922015-07-28 16:03:47 +02003390
Christopher Faulet31af49d2015-06-09 17:29:50 +02003391 if (!bind_conf->ca_sign_file) {
3392 Alert("Proxy '%s': cannot enable certificate generation, "
3393 "no CA certificate File configured at [%s:%d].\n",
3394 px->id, bind_conf->file, bind_conf->line);
Christopher Faulet31af49d2015-06-09 17:29:50 +02003395 goto load_error;
Christopher Fauletc6f02fb2015-10-09 10:53:31 +02003396 }
Christopher Faulet31af49d2015-06-09 17:29:50 +02003397
3398 /* read in the CA certificate */
3399 if (!(fp = fopen(bind_conf->ca_sign_file, "r"))) {
3400 Alert("Proxy '%s': Failed to read CA certificate file '%s' at [%s:%d].\n",
3401 px->id, bind_conf->ca_sign_file, bind_conf->file, bind_conf->line);
Christopher Faulet31af49d2015-06-09 17:29:50 +02003402 goto load_error;
3403 }
3404 if (!(cacert = PEM_read_X509(fp, NULL, NULL, NULL))) {
3405 Alert("Proxy '%s': Failed to read CA certificate file '%s' at [%s:%d].\n",
3406 px->id, bind_conf->ca_sign_file, bind_conf->file, bind_conf->line);
Christopher Fauletc6f02fb2015-10-09 10:53:31 +02003407 goto read_error;
Christopher Faulet31af49d2015-06-09 17:29:50 +02003408 }
Christopher Fauletc6f02fb2015-10-09 10:53:31 +02003409 rewind(fp);
Christopher Faulet31af49d2015-06-09 17:29:50 +02003410 if (!(capkey = PEM_read_PrivateKey(fp, NULL, NULL, bind_conf->ca_sign_pass))) {
3411 Alert("Proxy '%s': Failed to read CA private key file '%s' at [%s:%d].\n",
3412 px->id, bind_conf->ca_sign_file, bind_conf->file, bind_conf->line);
Christopher Fauletc6f02fb2015-10-09 10:53:31 +02003413 goto read_error;
Christopher Faulet31af49d2015-06-09 17:29:50 +02003414 }
Christopher Faulet31af49d2015-06-09 17:29:50 +02003415
Christopher Fauletc6f02fb2015-10-09 10:53:31 +02003416 fclose (fp);
Christopher Faulet31af49d2015-06-09 17:29:50 +02003417 bind_conf->ca_sign_cert = cacert;
3418 bind_conf->ca_sign_pkey = capkey;
3419 return err;
3420
Christopher Fauletc6f02fb2015-10-09 10:53:31 +02003421 read_error:
3422 fclose (fp);
Christopher Faulet31af49d2015-06-09 17:29:50 +02003423 if (capkey) EVP_PKEY_free(capkey);
3424 if (cacert) X509_free(cacert);
Christopher Fauletc6f02fb2015-10-09 10:53:31 +02003425 load_error:
3426 bind_conf->generate_certs = 0;
3427 err++;
Christopher Faulet31af49d2015-06-09 17:29:50 +02003428 return err;
3429}
3430
3431/* Release CA cert and private key used to generate certificated */
3432void
3433ssl_sock_free_ca(struct bind_conf *bind_conf)
3434{
3435 if (!bind_conf)
3436 return;
3437
3438 if (bind_conf->ca_sign_pkey)
3439 EVP_PKEY_free(bind_conf->ca_sign_pkey);
3440 if (bind_conf->ca_sign_cert)
3441 X509_free(bind_conf->ca_sign_cert);
Willy Tarreau94ff03a2016-12-22 17:57:46 +01003442 bind_conf->ca_sign_pkey = NULL;
3443 bind_conf->ca_sign_cert = NULL;
Christopher Faulet31af49d2015-06-09 17:29:50 +02003444}
3445
Emeric Brun46591952012-05-18 15:47:34 +02003446/*
3447 * This function is called if SSL * context is not yet allocated. The function
3448 * is designed to be called before any other data-layer operation and sets the
3449 * handshake flag on the connection. It is safe to call it multiple times.
3450 * It returns 0 on success and -1 in error case.
3451 */
3452static int ssl_sock_init(struct connection *conn)
3453{
3454 /* already initialized */
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02003455 if (conn->xprt_ctx)
Emeric Brun46591952012-05-18 15:47:34 +02003456 return 0;
3457
Willy Tarreau3c728722014-01-23 13:50:42 +01003458 if (!conn_ctrl_ready(conn))
Willy Tarreauf79c8172013-10-21 16:30:56 +02003459 return 0;
3460
Willy Tarreau20879a02012-12-03 16:32:10 +01003461 if (global.maxsslconn && sslconns >= global.maxsslconn) {
3462 conn->err_code = CO_ER_SSL_TOO_MANY;
Willy Tarreau403edff2012-09-06 11:58:37 +02003463 return -1;
Willy Tarreau20879a02012-12-03 16:32:10 +01003464 }
Willy Tarreau403edff2012-09-06 11:58:37 +02003465
Emeric Brun46591952012-05-18 15:47:34 +02003466 /* If it is in client mode initiate SSL session
3467 in connect state otherwise accept state */
Willy Tarreau3fdb3662012-11-12 00:42:33 +01003468 if (objt_server(conn->target)) {
Willy Tarreaufba03cd2014-11-13 13:48:58 +01003469 int may_retry = 1;
3470
3471 retry_connect:
Emeric Brun46591952012-05-18 15:47:34 +02003472 /* Alloc a new SSL session ctx */
Willy Tarreau3fdb3662012-11-12 00:42:33 +01003473 conn->xprt_ctx = SSL_new(objt_server(conn->target)->ssl_ctx.ctx);
Willy Tarreau20879a02012-12-03 16:32:10 +01003474 if (!conn->xprt_ctx) {
Willy Tarreaufba03cd2014-11-13 13:48:58 +01003475 if (may_retry--) {
3476 pool_gc2();
3477 goto retry_connect;
3478 }
Willy Tarreau20879a02012-12-03 16:32:10 +01003479 conn->err_code = CO_ER_SSL_NO_MEM;
Emeric Brun46591952012-05-18 15:47:34 +02003480 return -1;
Willy Tarreau20879a02012-12-03 16:32:10 +01003481 }
Emeric Brun46591952012-05-18 15:47:34 +02003482
Emeric Brun46591952012-05-18 15:47:34 +02003483 /* set fd on SSL session context */
Emeric Brun55476152014-11-12 17:35:37 +01003484 if (!SSL_set_fd(conn->xprt_ctx, conn->t.sock.fd)) {
3485 SSL_free(conn->xprt_ctx);
3486 conn->xprt_ctx = NULL;
Willy Tarreaufba03cd2014-11-13 13:48:58 +01003487 if (may_retry--) {
3488 pool_gc2();
3489 goto retry_connect;
3490 }
Emeric Brun55476152014-11-12 17:35:37 +01003491 conn->err_code = CO_ER_SSL_NO_MEM;
3492 return -1;
3493 }
Emeric Brun46591952012-05-18 15:47:34 +02003494
Evan Broderbe554312013-06-27 00:05:25 -07003495 /* set connection pointer */
Emeric Brun55476152014-11-12 17:35:37 +01003496 if (!SSL_set_app_data(conn->xprt_ctx, conn)) {
3497 SSL_free(conn->xprt_ctx);
3498 conn->xprt_ctx = NULL;
Willy Tarreaufba03cd2014-11-13 13:48:58 +01003499 if (may_retry--) {
3500 pool_gc2();
3501 goto retry_connect;
3502 }
Emeric Brun55476152014-11-12 17:35:37 +01003503 conn->err_code = CO_ER_SSL_NO_MEM;
3504 return -1;
3505 }
3506
3507 SSL_set_connect_state(conn->xprt_ctx);
3508 if (objt_server(conn->target)->ssl_ctx.reused_sess) {
3509 if(!SSL_set_session(conn->xprt_ctx, objt_server(conn->target)->ssl_ctx.reused_sess)) {
3510 SSL_SESSION_free(objt_server(conn->target)->ssl_ctx.reused_sess);
3511 objt_server(conn->target)->ssl_ctx.reused_sess = NULL;
3512 }
3513 }
Evan Broderbe554312013-06-27 00:05:25 -07003514
Emeric Brun46591952012-05-18 15:47:34 +02003515 /* leave init state and start handshake */
Willy Tarreau05737472012-09-04 08:03:39 +02003516 conn->flags |= CO_FL_SSL_WAIT_HS | CO_FL_WAIT_L6_CONN;
Willy Tarreau403edff2012-09-06 11:58:37 +02003517
3518 sslconns++;
Willy Tarreau71b734c2014-01-28 15:19:44 +01003519 totalsslconns++;
Emeric Brun46591952012-05-18 15:47:34 +02003520 return 0;
3521 }
Willy Tarreau3fdb3662012-11-12 00:42:33 +01003522 else if (objt_listener(conn->target)) {
Willy Tarreaufba03cd2014-11-13 13:48:58 +01003523 int may_retry = 1;
3524
3525 retry_accept:
Emeric Brun46591952012-05-18 15:47:34 +02003526 /* Alloc a new SSL session ctx */
Willy Tarreau3fdb3662012-11-12 00:42:33 +01003527 conn->xprt_ctx = SSL_new(objt_listener(conn->target)->bind_conf->default_ctx);
Willy Tarreau20879a02012-12-03 16:32:10 +01003528 if (!conn->xprt_ctx) {
Willy Tarreaufba03cd2014-11-13 13:48:58 +01003529 if (may_retry--) {
3530 pool_gc2();
3531 goto retry_accept;
3532 }
Willy Tarreau20879a02012-12-03 16:32:10 +01003533 conn->err_code = CO_ER_SSL_NO_MEM;
Emeric Brun46591952012-05-18 15:47:34 +02003534 return -1;
Willy Tarreau20879a02012-12-03 16:32:10 +01003535 }
Emeric Brun46591952012-05-18 15:47:34 +02003536
Emeric Brun46591952012-05-18 15:47:34 +02003537 /* set fd on SSL session context */
Emeric Brun55476152014-11-12 17:35:37 +01003538 if (!SSL_set_fd(conn->xprt_ctx, conn->t.sock.fd)) {
3539 SSL_free(conn->xprt_ctx);
3540 conn->xprt_ctx = NULL;
Willy Tarreaufba03cd2014-11-13 13:48:58 +01003541 if (may_retry--) {
3542 pool_gc2();
3543 goto retry_accept;
3544 }
Emeric Brun55476152014-11-12 17:35:37 +01003545 conn->err_code = CO_ER_SSL_NO_MEM;
3546 return -1;
3547 }
Emeric Brun46591952012-05-18 15:47:34 +02003548
Emeric Brune1f38db2012-09-03 20:36:47 +02003549 /* set connection pointer */
Emeric Brun55476152014-11-12 17:35:37 +01003550 if (!SSL_set_app_data(conn->xprt_ctx, conn)) {
3551 SSL_free(conn->xprt_ctx);
3552 conn->xprt_ctx = NULL;
Willy Tarreaufba03cd2014-11-13 13:48:58 +01003553 if (may_retry--) {
3554 pool_gc2();
3555 goto retry_accept;
3556 }
Emeric Brun55476152014-11-12 17:35:37 +01003557 conn->err_code = CO_ER_SSL_NO_MEM;
3558 return -1;
3559 }
3560
3561 SSL_set_accept_state(conn->xprt_ctx);
Emeric Brune1f38db2012-09-03 20:36:47 +02003562
Emeric Brun46591952012-05-18 15:47:34 +02003563 /* leave init state and start handshake */
Willy Tarreau05737472012-09-04 08:03:39 +02003564 conn->flags |= CO_FL_SSL_WAIT_HS | CO_FL_WAIT_L6_CONN;
Willy Tarreau403edff2012-09-06 11:58:37 +02003565
3566 sslconns++;
Willy Tarreau71b734c2014-01-28 15:19:44 +01003567 totalsslconns++;
Emeric Brun46591952012-05-18 15:47:34 +02003568 return 0;
3569 }
3570 /* don't know how to handle such a target */
Willy Tarreau20879a02012-12-03 16:32:10 +01003571 conn->err_code = CO_ER_SSL_NO_TARGET;
Emeric Brun46591952012-05-18 15:47:34 +02003572 return -1;
3573}
3574
3575
3576/* This is the callback which is used when an SSL handshake is pending. It
3577 * updates the FD status if it wants some polling before being called again.
3578 * It returns 0 if it fails in a fatal way or needs to poll to go further,
3579 * otherwise it returns non-zero and removes itself from the connection's
3580 * flags (the bit is provided in <flag> by the caller).
3581 */
3582int ssl_sock_handshake(struct connection *conn, unsigned int flag)
3583{
3584 int ret;
3585
Willy Tarreau3c728722014-01-23 13:50:42 +01003586 if (!conn_ctrl_ready(conn))
Willy Tarreauf79c8172013-10-21 16:30:56 +02003587 return 0;
3588
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02003589 if (!conn->xprt_ctx)
Emeric Brun46591952012-05-18 15:47:34 +02003590 goto out_error;
3591
Emeric Brun674b7432012-11-08 19:21:55 +01003592 /* If we use SSL_do_handshake to process a reneg initiated by
3593 * the remote peer, it sometimes returns SSL_ERROR_SSL.
3594 * Usually SSL_write and SSL_read are used and process implicitly
3595 * the reneg handshake.
3596 * Here we use SSL_peek as a workaround for reneg.
3597 */
3598 if ((conn->flags & CO_FL_CONNECTED) && SSL_renegotiate_pending(conn->xprt_ctx)) {
3599 char c;
3600
3601 ret = SSL_peek(conn->xprt_ctx, &c, 1);
3602 if (ret <= 0) {
3603 /* handshake may have not been completed, let's find why */
3604 ret = SSL_get_error(conn->xprt_ctx, ret);
3605 if (ret == SSL_ERROR_WANT_WRITE) {
3606 /* SSL handshake needs to write, L4 connection may not be ready */
3607 __conn_sock_stop_recv(conn);
Willy Tarreaue1f50c42014-01-22 20:02:06 +01003608 __conn_sock_want_send(conn);
3609 fd_cant_send(conn->t.sock.fd);
Emeric Brun674b7432012-11-08 19:21:55 +01003610 return 0;
3611 }
3612 else if (ret == SSL_ERROR_WANT_READ) {
3613 /* handshake may have been completed but we have
3614 * no more data to read.
3615 */
3616 if (!SSL_renegotiate_pending(conn->xprt_ctx)) {
3617 ret = 1;
3618 goto reneg_ok;
3619 }
3620 /* SSL handshake needs to read, L4 connection is ready */
3621 if (conn->flags & CO_FL_WAIT_L4_CONN)
3622 conn->flags &= ~CO_FL_WAIT_L4_CONN;
3623 __conn_sock_stop_send(conn);
Willy Tarreaue1f50c42014-01-22 20:02:06 +01003624 __conn_sock_want_recv(conn);
3625 fd_cant_recv(conn->t.sock.fd);
Emeric Brun674b7432012-11-08 19:21:55 +01003626 return 0;
3627 }
3628 else if (ret == SSL_ERROR_SYSCALL) {
3629 /* if errno is null, then connection was successfully established */
3630 if (!errno && conn->flags & CO_FL_WAIT_L4_CONN)
3631 conn->flags &= ~CO_FL_WAIT_L4_CONN;
Willy Tarreau20879a02012-12-03 16:32:10 +01003632 if (!conn->err_code) {
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02003633 int empty_handshake;
Luca Pizzamiglio578b1692016-12-12 10:56:56 +01003634#if (OPENSSL_VERSION_NUMBER >= 0x1010000fL) && !defined(LIBRESSL_VERSION_NUMBER)
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02003635 OSSL_HANDSHAKE_STATE state = SSL_get_state((SSL *)conn->xprt_ctx);
3636 empty_handshake = state == TLS_ST_BEFORE;
3637#else
3638 empty_handshake = !((SSL *)conn->xprt_ctx)->packet_length;
3639#endif
3640
3641 if (empty_handshake) {
Emeric Brun29f037d2014-04-25 19:05:36 +02003642 if (!errno) {
3643 if (conn->xprt_st & SSL_SOCK_RECV_HEARTBEAT)
3644 conn->err_code = CO_ER_SSL_HANDSHAKE_HB;
3645 else
3646 conn->err_code = CO_ER_SSL_EMPTY;
3647 }
3648 else {
3649 if (conn->xprt_st & SSL_SOCK_RECV_HEARTBEAT)
3650 conn->err_code = CO_ER_SSL_HANDSHAKE_HB;
3651 else
3652 conn->err_code = CO_ER_SSL_ABORT;
3653 }
3654 }
3655 else {
3656 if (conn->xprt_st & SSL_SOCK_RECV_HEARTBEAT)
3657 conn->err_code = CO_ER_SSL_HANDSHAKE_HB;
Willy Tarreau20879a02012-12-03 16:32:10 +01003658 else
Emeric Brun29f037d2014-04-25 19:05:36 +02003659 conn->err_code = CO_ER_SSL_HANDSHAKE;
3660 }
Willy Tarreau20879a02012-12-03 16:32:10 +01003661 }
Emeric Brun674b7432012-11-08 19:21:55 +01003662 goto out_error;
3663 }
3664 else {
3665 /* Fail on all other handshake errors */
3666 /* Note: OpenSSL may leave unread bytes in the socket's
3667 * buffer, causing an RST to be emitted upon close() on
3668 * TCP sockets. We first try to drain possibly pending
3669 * data to avoid this as much as possible.
3670 */
Willy Tarreaud85c4852015-03-13 00:40:28 +01003671 conn_sock_drain(conn);
Willy Tarreau20879a02012-12-03 16:32:10 +01003672 if (!conn->err_code)
Willy Tarreauf51c6982014-04-25 20:02:39 +02003673 conn->err_code = (conn->xprt_st & SSL_SOCK_RECV_HEARTBEAT) ?
3674 CO_ER_SSL_KILLED_HB : CO_ER_SSL_HANDSHAKE;
Emeric Brun674b7432012-11-08 19:21:55 +01003675 goto out_error;
3676 }
3677 }
3678 /* read some data: consider handshake completed */
3679 goto reneg_ok;
3680 }
3681
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02003682 ret = SSL_do_handshake(conn->xprt_ctx);
Emeric Brun46591952012-05-18 15:47:34 +02003683 if (ret != 1) {
3684 /* handshake did not complete, let's find why */
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02003685 ret = SSL_get_error(conn->xprt_ctx, ret);
Emeric Brun46591952012-05-18 15:47:34 +02003686
3687 if (ret == SSL_ERROR_WANT_WRITE) {
3688 /* SSL handshake needs to write, L4 connection may not be ready */
3689 __conn_sock_stop_recv(conn);
Willy Tarreaue1f50c42014-01-22 20:02:06 +01003690 __conn_sock_want_send(conn);
3691 fd_cant_send(conn->t.sock.fd);
Emeric Brun46591952012-05-18 15:47:34 +02003692 return 0;
3693 }
3694 else if (ret == SSL_ERROR_WANT_READ) {
3695 /* SSL handshake needs to read, L4 connection is ready */
3696 if (conn->flags & CO_FL_WAIT_L4_CONN)
3697 conn->flags &= ~CO_FL_WAIT_L4_CONN;
3698 __conn_sock_stop_send(conn);
Willy Tarreaue1f50c42014-01-22 20:02:06 +01003699 __conn_sock_want_recv(conn);
3700 fd_cant_recv(conn->t.sock.fd);
Emeric Brun46591952012-05-18 15:47:34 +02003701 return 0;
3702 }
Willy Tarreau89230192012-09-28 20:22:13 +02003703 else if (ret == SSL_ERROR_SYSCALL) {
Luca Pizzamiglio578b1692016-12-12 10:56:56 +01003704#if (OPENSSL_VERSION_NUMBER >= 0x1010000fL) && !defined(LIBRESSL_VERSION_NUMBER)
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02003705 OSSL_HANDSHAKE_STATE state;
3706#endif
3707 int empty_handshake;
Willy Tarreau89230192012-09-28 20:22:13 +02003708 /* if errno is null, then connection was successfully established */
3709 if (!errno && conn->flags & CO_FL_WAIT_L4_CONN)
3710 conn->flags &= ~CO_FL_WAIT_L4_CONN;
Willy Tarreau20879a02012-12-03 16:32:10 +01003711
Luca Pizzamiglio578b1692016-12-12 10:56:56 +01003712#if (OPENSSL_VERSION_NUMBER >= 0x1010000fL) && !defined(LIBRESSL_VERSION_NUMBER)
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02003713 state = SSL_get_state((SSL *)conn->xprt_ctx);
3714 empty_handshake = state == TLS_ST_BEFORE;
3715#else
3716 empty_handshake = !((SSL *)conn->xprt_ctx)->packet_length;
3717#endif
3718 if (empty_handshake) {
Emeric Brun29f037d2014-04-25 19:05:36 +02003719 if (!errno) {
3720 if (conn->xprt_st & SSL_SOCK_RECV_HEARTBEAT)
3721 conn->err_code = CO_ER_SSL_HANDSHAKE_HB;
3722 else
3723 conn->err_code = CO_ER_SSL_EMPTY;
3724 }
3725 else {
3726 if (conn->xprt_st & SSL_SOCK_RECV_HEARTBEAT)
3727 conn->err_code = CO_ER_SSL_HANDSHAKE_HB;
3728 else
3729 conn->err_code = CO_ER_SSL_ABORT;
3730 }
3731 }
3732 else {
3733 if (conn->xprt_st & SSL_SOCK_RECV_HEARTBEAT)
3734 conn->err_code = CO_ER_SSL_HANDSHAKE_HB;
Willy Tarreau20879a02012-12-03 16:32:10 +01003735 else
Emeric Brun29f037d2014-04-25 19:05:36 +02003736 conn->err_code = CO_ER_SSL_HANDSHAKE;
3737 }
Willy Tarreau89230192012-09-28 20:22:13 +02003738 goto out_error;
3739 }
Emeric Brun46591952012-05-18 15:47:34 +02003740 else {
3741 /* Fail on all other handshake errors */
Willy Tarreau566dc552012-10-19 20:52:18 +02003742 /* Note: OpenSSL may leave unread bytes in the socket's
3743 * buffer, causing an RST to be emitted upon close() on
3744 * TCP sockets. We first try to drain possibly pending
3745 * data to avoid this as much as possible.
3746 */
Willy Tarreaud85c4852015-03-13 00:40:28 +01003747 conn_sock_drain(conn);
Willy Tarreau20879a02012-12-03 16:32:10 +01003748 if (!conn->err_code)
Willy Tarreauf51c6982014-04-25 20:02:39 +02003749 conn->err_code = (conn->xprt_st & SSL_SOCK_RECV_HEARTBEAT) ?
3750 CO_ER_SSL_KILLED_HB : CO_ER_SSL_HANDSHAKE;
Emeric Brun46591952012-05-18 15:47:34 +02003751 goto out_error;
3752 }
3753 }
3754
Emeric Brun674b7432012-11-08 19:21:55 +01003755reneg_ok:
Emeric Brun46591952012-05-18 15:47:34 +02003756 /* Handshake succeeded */
Willy Tarreau0c9c2722014-05-28 12:28:58 +02003757 if (!SSL_session_reused(conn->xprt_ctx)) {
3758 if (objt_server(conn->target)) {
3759 update_freq_ctr(&global.ssl_be_keys_per_sec, 1);
3760 if (global.ssl_be_keys_per_sec.curr_ctr > global.ssl_be_keys_max)
3761 global.ssl_be_keys_max = global.ssl_be_keys_per_sec.curr_ctr;
3762
Emeric Brun46591952012-05-18 15:47:34 +02003763 /* check if session was reused, if not store current session on server for reuse */
Willy Tarreau30fd4bd2016-12-22 21:54:21 +01003764 if (objt_server(conn->target)->ssl_ctx.reused_sess) {
Willy Tarreau3fdb3662012-11-12 00:42:33 +01003765 SSL_SESSION_free(objt_server(conn->target)->ssl_ctx.reused_sess);
Willy Tarreau30fd4bd2016-12-22 21:54:21 +01003766 objt_server(conn->target)->ssl_ctx.reused_sess = NULL;
3767 }
Emeric Brun46591952012-05-18 15:47:34 +02003768
Willy Tarreau2a3fb1c2015-02-05 16:47:07 +01003769 if (!(objt_server(conn->target)->ssl_ctx.options & SRV_SSL_O_NO_REUSE))
3770 objt_server(conn->target)->ssl_ctx.reused_sess = SSL_get1_session(conn->xprt_ctx);
Emeric Brun46591952012-05-18 15:47:34 +02003771 }
Willy Tarreau0c9c2722014-05-28 12:28:58 +02003772 else {
3773 update_freq_ctr(&global.ssl_fe_keys_per_sec, 1);
3774 if (global.ssl_fe_keys_per_sec.curr_ctr > global.ssl_fe_keys_max)
3775 global.ssl_fe_keys_max = global.ssl_fe_keys_per_sec.curr_ctr;
3776 }
Emeric Brun46591952012-05-18 15:47:34 +02003777 }
3778
3779 /* The connection is now established at both layers, it's time to leave */
3780 conn->flags &= ~(flag | CO_FL_WAIT_L4_CONN | CO_FL_WAIT_L6_CONN);
3781 return 1;
3782
3783 out_error:
Emeric Brun644cde02012-12-14 11:21:13 +01003784 /* Clear openssl global errors stack */
Thierry FOURNIER / OZON.IO8b068c22016-10-10 11:59:50 +02003785 ssl_sock_dump_errors(conn);
Emeric Brun644cde02012-12-14 11:21:13 +01003786 ERR_clear_error();
3787
Emeric Brun9fa89732012-10-04 17:09:56 +02003788 /* free resumed session if exists */
Willy Tarreau3fdb3662012-11-12 00:42:33 +01003789 if (objt_server(conn->target) && objt_server(conn->target)->ssl_ctx.reused_sess) {
3790 SSL_SESSION_free(objt_server(conn->target)->ssl_ctx.reused_sess);
3791 objt_server(conn->target)->ssl_ctx.reused_sess = NULL;
Emeric Brun9fa89732012-10-04 17:09:56 +02003792 }
3793
Emeric Brun46591952012-05-18 15:47:34 +02003794 /* Fail on all other handshake errors */
3795 conn->flags |= CO_FL_ERROR;
Willy Tarreau20879a02012-12-03 16:32:10 +01003796 if (!conn->err_code)
3797 conn->err_code = CO_ER_SSL_HANDSHAKE;
Emeric Brun46591952012-05-18 15:47:34 +02003798 return 0;
3799}
3800
3801/* Receive up to <count> bytes from connection <conn>'s socket and store them
Willy Tarreauabf08d92014-01-14 11:31:27 +01003802 * into buffer <buf>. Only one call to recv() is performed, unless the
Emeric Brun46591952012-05-18 15:47:34 +02003803 * buffer wraps, in which case a second call may be performed. The connection's
3804 * flags are updated with whatever special event is detected (error, read0,
3805 * empty). The caller is responsible for taking care of those events and
3806 * avoiding the call if inappropriate. The function does not call the
3807 * connection's polling update function, so the caller is responsible for this.
3808 */
3809static int ssl_sock_to_buf(struct connection *conn, struct buffer *buf, int count)
3810{
3811 int ret, done = 0;
Willy Tarreauabf08d92014-01-14 11:31:27 +01003812 int try;
Emeric Brun46591952012-05-18 15:47:34 +02003813
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02003814 if (!conn->xprt_ctx)
Emeric Brun46591952012-05-18 15:47:34 +02003815 goto out_error;
3816
3817 if (conn->flags & CO_FL_HANDSHAKE)
3818 /* a handshake was requested */
3819 return 0;
3820
Willy Tarreauabf08d92014-01-14 11:31:27 +01003821 /* let's realign the buffer to optimize I/O */
3822 if (buffer_empty(buf))
Emeric Brun46591952012-05-18 15:47:34 +02003823 buf->p = buf->data;
Emeric Brun46591952012-05-18 15:47:34 +02003824
3825 /* read the largest possible block. For this, we perform only one call
3826 * to recv() unless the buffer wraps and we exactly fill the first hunk,
3827 * in which case we accept to do it once again. A new attempt is made on
3828 * EINTR too.
3829 */
Willy Tarreau00b0fb92014-01-17 11:09:40 +01003830 while (count > 0) {
Willy Tarreauabf08d92014-01-14 11:31:27 +01003831 /* first check if we have some room after p+i */
3832 try = buf->data + buf->size - (buf->p + buf->i);
3833 /* otherwise continue between data and p-o */
3834 if (try <= 0) {
3835 try = buf->p - (buf->data + buf->o);
3836 if (try <= 0)
3837 break;
3838 }
3839 if (try > count)
3840 try = count;
3841
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02003842 ret = SSL_read(conn->xprt_ctx, bi_end(buf), try);
Emeric Brune1f38db2012-09-03 20:36:47 +02003843 if (conn->flags & CO_FL_ERROR) {
3844 /* CO_FL_ERROR may be set by ssl_sock_infocbk */
Emeric Brun644cde02012-12-14 11:21:13 +01003845 goto out_error;
Emeric Brune1f38db2012-09-03 20:36:47 +02003846 }
Emeric Brun46591952012-05-18 15:47:34 +02003847 if (ret > 0) {
3848 buf->i += ret;
3849 done += ret;
3850 if (ret < try)
3851 break;
3852 count -= ret;
Emeric Brun46591952012-05-18 15:47:34 +02003853 }
3854 else if (ret == 0) {
Emeric Brun644cde02012-12-14 11:21:13 +01003855 ret = SSL_get_error(conn->xprt_ctx, ret);
3856 if (ret != SSL_ERROR_ZERO_RETURN) {
Emeric Brun1c646862012-12-14 12:33:41 +01003857 /* error on protocol or underlying transport */
3858 if ((ret != SSL_ERROR_SYSCALL)
3859 || (errno && (errno != EAGAIN)))
3860 conn->flags |= CO_FL_ERROR;
3861
Emeric Brun644cde02012-12-14 11:21:13 +01003862 /* Clear openssl global errors stack */
Thierry FOURNIER / OZON.IO8b068c22016-10-10 11:59:50 +02003863 ssl_sock_dump_errors(conn);
Emeric Brun644cde02012-12-14 11:21:13 +01003864 ERR_clear_error();
3865 }
Emeric Brun46591952012-05-18 15:47:34 +02003866 goto read0;
3867 }
3868 else {
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02003869 ret = SSL_get_error(conn->xprt_ctx, ret);
Emeric Brun46591952012-05-18 15:47:34 +02003870 if (ret == SSL_ERROR_WANT_WRITE) {
Emeric Brun8af8dd12012-11-08 17:56:20 +01003871 /* handshake is running, and it needs to enable write */
Emeric Brun46591952012-05-18 15:47:34 +02003872 conn->flags |= CO_FL_SSL_WAIT_HS;
Emeric Brun8af8dd12012-11-08 17:56:20 +01003873 __conn_sock_want_send(conn);
Emeric Brun46591952012-05-18 15:47:34 +02003874 break;
3875 }
3876 else if (ret == SSL_ERROR_WANT_READ) {
Emeric Brun282a76a2012-11-08 18:02:56 +01003877 if (SSL_renegotiate_pending(conn->xprt_ctx)) {
3878 /* handshake is running, and it may need to re-enable read */
3879 conn->flags |= CO_FL_SSL_WAIT_HS;
3880 __conn_sock_want_recv(conn);
3881 break;
3882 }
Emeric Brun46591952012-05-18 15:47:34 +02003883 /* we need to poll for retry a read later */
Willy Tarreaue1f50c42014-01-22 20:02:06 +01003884 fd_cant_recv(conn->t.sock.fd);
Emeric Brun46591952012-05-18 15:47:34 +02003885 break;
3886 }
3887 /* otherwise it's a real error */
3888 goto out_error;
3889 }
3890 }
3891 return done;
3892
3893 read0:
3894 conn_sock_read0(conn);
3895 return done;
3896 out_error:
Emeric Brun644cde02012-12-14 11:21:13 +01003897 /* Clear openssl global errors stack */
Thierry FOURNIER / OZON.IO8b068c22016-10-10 11:59:50 +02003898 ssl_sock_dump_errors(conn);
Emeric Brun644cde02012-12-14 11:21:13 +01003899 ERR_clear_error();
3900
Emeric Brun46591952012-05-18 15:47:34 +02003901 conn->flags |= CO_FL_ERROR;
3902 return done;
3903}
3904
3905
3906/* Send all pending bytes from buffer <buf> to connection <conn>'s socket.
Willy Tarreau1049b1f2014-02-02 01:51:17 +01003907 * <flags> may contain some CO_SFL_* flags to hint the system about other
3908 * pending data for example, but this flag is ignored at the moment.
Emeric Brun46591952012-05-18 15:47:34 +02003909 * Only one call to send() is performed, unless the buffer wraps, in which case
3910 * a second call may be performed. The connection's flags are updated with
3911 * whatever special event is detected (error, empty). The caller is responsible
3912 * for taking care of those events and avoiding the call if inappropriate. The
3913 * function does not call the connection's polling update function, so the caller
3914 * is responsible for this.
3915 */
3916static int ssl_sock_from_buf(struct connection *conn, struct buffer *buf, int flags)
3917{
3918 int ret, try, done;
3919
3920 done = 0;
3921
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02003922 if (!conn->xprt_ctx)
Emeric Brun46591952012-05-18 15:47:34 +02003923 goto out_error;
3924
3925 if (conn->flags & CO_FL_HANDSHAKE)
3926 /* a handshake was requested */
3927 return 0;
3928
3929 /* send the largest possible block. For this we perform only one call
3930 * to send() unless the buffer wraps and we exactly fill the first hunk,
3931 * in which case we accept to do it once again.
3932 */
3933 while (buf->o) {
Kevin Hestercad82342013-05-30 15:12:41 -07003934 try = bo_contig_data(buf);
Willy Tarreaubfd59462013-02-21 07:46:09 +01003935
Willy Tarreau7bed9452014-02-02 02:00:24 +01003936 if (!(flags & CO_SFL_STREAMER) &&
Willy Tarreau518cedd2014-02-17 15:43:01 +01003937 !(conn->xprt_st & SSL_SOCK_SEND_UNLIMITED) &&
Willy Tarreauef934602016-12-22 23:12:01 +01003938 global_ssl.max_record && try > global_ssl.max_record) {
3939 try = global_ssl.max_record;
Willy Tarreau518cedd2014-02-17 15:43:01 +01003940 }
3941 else {
3942 /* we need to keep the information about the fact that
3943 * we're not limiting the upcoming send(), because if it
3944 * fails, we'll have to retry with at least as many data.
3945 */
3946 conn->xprt_st |= SSL_SOCK_SEND_UNLIMITED;
3947 }
Willy Tarreaubfd59462013-02-21 07:46:09 +01003948
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02003949 ret = SSL_write(conn->xprt_ctx, bo_ptr(buf), try);
Willy Tarreau518cedd2014-02-17 15:43:01 +01003950
Emeric Brune1f38db2012-09-03 20:36:47 +02003951 if (conn->flags & CO_FL_ERROR) {
3952 /* CO_FL_ERROR may be set by ssl_sock_infocbk */
Emeric Brun644cde02012-12-14 11:21:13 +01003953 goto out_error;
Emeric Brune1f38db2012-09-03 20:36:47 +02003954 }
Emeric Brun46591952012-05-18 15:47:34 +02003955 if (ret > 0) {
Willy Tarreau518cedd2014-02-17 15:43:01 +01003956 conn->xprt_st &= ~SSL_SOCK_SEND_UNLIMITED;
3957
Emeric Brun46591952012-05-18 15:47:34 +02003958 buf->o -= ret;
3959 done += ret;
3960
Willy Tarreau5fb38032012-12-16 19:39:09 +01003961 if (likely(buffer_empty(buf)))
Emeric Brun46591952012-05-18 15:47:34 +02003962 /* optimize data alignment in the buffer */
3963 buf->p = buf->data;
3964
3965 /* if the system buffer is full, don't insist */
3966 if (ret < try)
3967 break;
3968 }
3969 else {
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02003970 ret = SSL_get_error(conn->xprt_ctx, ret);
Emeric Brun46591952012-05-18 15:47:34 +02003971 if (ret == SSL_ERROR_WANT_WRITE) {
Emeric Brun282a76a2012-11-08 18:02:56 +01003972 if (SSL_renegotiate_pending(conn->xprt_ctx)) {
3973 /* handshake is running, and it may need to re-enable write */
3974 conn->flags |= CO_FL_SSL_WAIT_HS;
3975 __conn_sock_want_send(conn);
3976 break;
3977 }
Emeric Brun46591952012-05-18 15:47:34 +02003978 /* we need to poll to retry a write later */
Willy Tarreaue1f50c42014-01-22 20:02:06 +01003979 fd_cant_send(conn->t.sock.fd);
Emeric Brun46591952012-05-18 15:47:34 +02003980 break;
3981 }
3982 else if (ret == SSL_ERROR_WANT_READ) {
Emeric Brun8af8dd12012-11-08 17:56:20 +01003983 /* handshake is running, and it needs to enable read */
Emeric Brun46591952012-05-18 15:47:34 +02003984 conn->flags |= CO_FL_SSL_WAIT_HS;
Emeric Brun8af8dd12012-11-08 17:56:20 +01003985 __conn_sock_want_recv(conn);
Emeric Brun46591952012-05-18 15:47:34 +02003986 break;
3987 }
3988 goto out_error;
3989 }
3990 }
3991 return done;
3992
3993 out_error:
Emeric Brun644cde02012-12-14 11:21:13 +01003994 /* Clear openssl global errors stack */
Thierry FOURNIER / OZON.IO8b068c22016-10-10 11:59:50 +02003995 ssl_sock_dump_errors(conn);
Emeric Brun644cde02012-12-14 11:21:13 +01003996 ERR_clear_error();
3997
Emeric Brun46591952012-05-18 15:47:34 +02003998 conn->flags |= CO_FL_ERROR;
3999 return done;
4000}
4001
Emeric Brun46591952012-05-18 15:47:34 +02004002static void ssl_sock_close(struct connection *conn) {
4003
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02004004 if (conn->xprt_ctx) {
4005 SSL_free(conn->xprt_ctx);
4006 conn->xprt_ctx = NULL;
Willy Tarreau403edff2012-09-06 11:58:37 +02004007 sslconns--;
Emeric Brun46591952012-05-18 15:47:34 +02004008 }
Emeric Brun46591952012-05-18 15:47:34 +02004009}
4010
4011/* This function tries to perform a clean shutdown on an SSL connection, and in
4012 * any case, flags the connection as reusable if no handshake was in progress.
4013 */
4014static void ssl_sock_shutw(struct connection *conn, int clean)
4015{
4016 if (conn->flags & CO_FL_HANDSHAKE)
4017 return;
4018 /* no handshake was in progress, try a clean ssl shutdown */
Emeric Brun644cde02012-12-14 11:21:13 +01004019 if (clean && (SSL_shutdown(conn->xprt_ctx) <= 0)) {
4020 /* Clear openssl global errors stack */
Thierry FOURNIER / OZON.IO8b068c22016-10-10 11:59:50 +02004021 ssl_sock_dump_errors(conn);
Emeric Brun644cde02012-12-14 11:21:13 +01004022 ERR_clear_error();
4023 }
Emeric Brun46591952012-05-18 15:47:34 +02004024
4025 /* force flag on ssl to keep session in cache regardless shutdown result */
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02004026 SSL_set_shutdown(conn->xprt_ctx, SSL_SENT_SHUTDOWN);
Emeric Brun46591952012-05-18 15:47:34 +02004027}
4028
Willy Tarreauffc3fcd2012-10-12 20:17:54 +02004029/* used for logging, may be changed for a sample fetch later */
4030const char *ssl_sock_get_cipher_name(struct connection *conn)
4031{
4032 if (!conn->xprt && !conn->xprt_ctx)
4033 return NULL;
4034 return SSL_get_cipher_name(conn->xprt_ctx);
4035}
4036
4037/* used for logging, may be changed for a sample fetch later */
4038const char *ssl_sock_get_proto_version(struct connection *conn)
4039{
4040 if (!conn->xprt && !conn->xprt_ctx)
4041 return NULL;
4042 return SSL_get_version(conn->xprt_ctx);
4043}
4044
Willy Tarreau8d598402012-10-22 17:58:39 +02004045/* Extract a serial from a cert, and copy it to a chunk.
4046 * Returns 1 if serial is found and copied, 0 if no serial found and
4047 * -1 if output is not large enough.
4048 */
4049static int
4050ssl_sock_get_serial(X509 *crt, struct chunk *out)
4051{
4052 ASN1_INTEGER *serial;
4053
4054 serial = X509_get_serialNumber(crt);
4055 if (!serial)
4056 return 0;
4057
4058 if (out->size < serial->length)
4059 return -1;
4060
4061 memcpy(out->str, serial->data, serial->length);
4062 out->len = serial->length;
4063 return 1;
4064}
4065
Emeric Brun43e79582014-10-29 19:03:26 +01004066/* Extract a cert to der, and copy it to a chunk.
4067 * Returns 1 if cert is found and copied, 0 on der convertion failure and
4068 * -1 if output is not large enough.
4069 */
4070static int
4071ssl_sock_crt2der(X509 *crt, struct chunk *out)
4072{
4073 int len;
4074 unsigned char *p = (unsigned char *)out->str;;
4075
4076 len =i2d_X509(crt, NULL);
4077 if (len <= 0)
4078 return 1;
4079
4080 if (out->size < len)
4081 return -1;
4082
4083 i2d_X509(crt,&p);
4084 out->len = len;
4085 return 1;
4086}
4087
Emeric Brunce5ad802012-10-22 14:11:22 +02004088
4089/* Copy Date in ASN1_UTCTIME format in struct chunk out.
4090 * Returns 1 if serial is found and copied, 0 if no valid time found
4091 * and -1 if output is not large enough.
4092 */
4093static int
4094ssl_sock_get_time(ASN1_TIME *tm, struct chunk *out)
4095{
4096 if (tm->type == V_ASN1_GENERALIZEDTIME) {
4097 ASN1_GENERALIZEDTIME *gentm = (ASN1_GENERALIZEDTIME *)tm;
4098
4099 if (gentm->length < 12)
4100 return 0;
4101 if (gentm->data[0] != 0x32 || gentm->data[1] != 0x30)
4102 return 0;
4103 if (out->size < gentm->length-2)
4104 return -1;
4105
4106 memcpy(out->str, gentm->data+2, gentm->length-2);
4107 out->len = gentm->length-2;
4108 return 1;
4109 }
4110 else if (tm->type == V_ASN1_UTCTIME) {
4111 ASN1_UTCTIME *utctm = (ASN1_UTCTIME *)tm;
4112
4113 if (utctm->length < 10)
4114 return 0;
4115 if (utctm->data[0] >= 0x35)
4116 return 0;
4117 if (out->size < utctm->length)
4118 return -1;
4119
4120 memcpy(out->str, utctm->data, utctm->length);
4121 out->len = utctm->length;
4122 return 1;
4123 }
4124
4125 return 0;
4126}
4127
Emeric Brun87855892012-10-17 17:39:35 +02004128/* Extract an entry from a X509_NAME and copy its value to an output chunk.
4129 * Returns 1 if entry found, 0 if entry not found, or -1 if output not large enough.
4130 */
4131static int
4132ssl_sock_get_dn_entry(X509_NAME *a, const struct chunk *entry, int pos, struct chunk *out)
4133{
4134 X509_NAME_ENTRY *ne;
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02004135 ASN1_OBJECT *obj;
4136 ASN1_STRING *data;
4137 const unsigned char *data_ptr;
4138 int data_len;
Emeric Brun87855892012-10-17 17:39:35 +02004139 int i, j, n;
4140 int cur = 0;
4141 const char *s;
4142 char tmp[128];
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02004143 int name_count;
4144
4145 name_count = X509_NAME_entry_count(a);
Emeric Brun87855892012-10-17 17:39:35 +02004146
4147 out->len = 0;
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02004148 for (i = 0; i < name_count; i++) {
Emeric Brun87855892012-10-17 17:39:35 +02004149 if (pos < 0)
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02004150 j = (name_count-1) - i;
Emeric Brun87855892012-10-17 17:39:35 +02004151 else
4152 j = i;
4153
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02004154 ne = X509_NAME_get_entry(a, j);
4155 obj = X509_NAME_ENTRY_get_object(ne);
4156 data = X509_NAME_ENTRY_get_data(ne);
4157 data_ptr = ASN1_STRING_get0_data(data);
4158 data_len = ASN1_STRING_length(data);
4159 n = OBJ_obj2nid(obj);
Emeric Brun87855892012-10-17 17:39:35 +02004160 if ((n == NID_undef) || ((s = OBJ_nid2sn(n)) == NULL)) {
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02004161 i2t_ASN1_OBJECT(tmp, sizeof(tmp), obj);
Emeric Brun87855892012-10-17 17:39:35 +02004162 s = tmp;
4163 }
4164
4165 if (chunk_strcasecmp(entry, s) != 0)
4166 continue;
4167
4168 if (pos < 0)
4169 cur--;
4170 else
4171 cur++;
4172
4173 if (cur != pos)
4174 continue;
4175
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02004176 if (data_len > out->size)
Emeric Brun87855892012-10-17 17:39:35 +02004177 return -1;
4178
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02004179 memcpy(out->str, data_ptr, data_len);
4180 out->len = data_len;
Emeric Brun87855892012-10-17 17:39:35 +02004181 return 1;
4182 }
4183
4184 return 0;
4185
4186}
4187
4188/* Extract and format full DN from a X509_NAME and copy result into a chunk
4189 * Returns 1 if dn entries exits, 0 if no dn entry found or -1 if output is not large enough.
4190 */
4191static int
4192ssl_sock_get_dn_oneline(X509_NAME *a, struct chunk *out)
4193{
4194 X509_NAME_ENTRY *ne;
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02004195 ASN1_OBJECT *obj;
4196 ASN1_STRING *data;
4197 const unsigned char *data_ptr;
4198 int data_len;
Emeric Brun87855892012-10-17 17:39:35 +02004199 int i, n, ln;
4200 int l = 0;
4201 const char *s;
4202 char *p;
4203 char tmp[128];
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02004204 int name_count;
4205
4206
4207 name_count = X509_NAME_entry_count(a);
Emeric Brun87855892012-10-17 17:39:35 +02004208
4209 out->len = 0;
4210 p = out->str;
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02004211 for (i = 0; i < name_count; i++) {
4212 ne = X509_NAME_get_entry(a, i);
4213 obj = X509_NAME_ENTRY_get_object(ne);
4214 data = X509_NAME_ENTRY_get_data(ne);
4215 data_ptr = ASN1_STRING_get0_data(data);
4216 data_len = ASN1_STRING_length(data);
4217 n = OBJ_obj2nid(obj);
Emeric Brun87855892012-10-17 17:39:35 +02004218 if ((n == NID_undef) || ((s = OBJ_nid2sn(n)) == NULL)) {
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02004219 i2t_ASN1_OBJECT(tmp, sizeof(tmp), obj);
Emeric Brun87855892012-10-17 17:39:35 +02004220 s = tmp;
4221 }
4222 ln = strlen(s);
4223
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02004224 l += 1 + ln + 1 + data_len;
Emeric Brun87855892012-10-17 17:39:35 +02004225 if (l > out->size)
4226 return -1;
4227 out->len = l;
4228
4229 *(p++)='/';
4230 memcpy(p, s, ln);
4231 p += ln;
4232 *(p++)='=';
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02004233 memcpy(p, data_ptr, data_len);
4234 p += data_len;
Emeric Brun87855892012-10-17 17:39:35 +02004235 }
4236
4237 if (!out->len)
4238 return 0;
4239
4240 return 1;
4241}
4242
David Safb76832014-05-08 23:42:08 -04004243char *ssl_sock_get_version(struct connection *conn)
4244{
4245 if (!ssl_sock_is_ssl(conn))
4246 return NULL;
4247
4248 return (char *)SSL_get_version(conn->xprt_ctx);
4249}
4250
Willy Tarreau119a4082016-12-22 21:58:38 +01004251/* Sets advertised SNI for outgoing connections. Please set <hostname> to NULL
4252 * to disable SNI.
4253 */
Willy Tarreau63076412015-07-10 11:33:32 +02004254void ssl_sock_set_servername(struct connection *conn, const char *hostname)
4255{
4256#ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME
Willy Tarreau119a4082016-12-22 21:58:38 +01004257 char *prev_name;
4258
Willy Tarreau63076412015-07-10 11:33:32 +02004259 if (!ssl_sock_is_ssl(conn))
4260 return;
4261
Willy Tarreau119a4082016-12-22 21:58:38 +01004262 /* if the SNI changes, we must destroy the reusable context so that a
4263 * new connection will present a new SNI. As an optimization we could
4264 * later imagine having a small cache of ssl_ctx to hold a few SNI per
4265 * server.
4266 */
4267 prev_name = (char *)SSL_get_servername(conn->xprt_ctx, TLSEXT_NAMETYPE_host_name);
4268 if ((!prev_name && hostname) ||
4269 (prev_name && (!hostname || strcmp(hostname, prev_name) != 0)))
4270 SSL_set_session(conn->xprt_ctx, NULL);
4271
Willy Tarreau63076412015-07-10 11:33:32 +02004272 SSL_set_tlsext_host_name(conn->xprt_ctx, hostname);
4273#endif
4274}
4275
Emeric Brun0abf8362014-06-24 18:26:41 +02004276/* Extract peer certificate's common name into the chunk dest
4277 * Returns
4278 * the len of the extracted common name
4279 * or 0 if no CN found in DN
4280 * or -1 on error case (i.e. no peer certificate)
4281 */
4282int ssl_sock_get_remote_common_name(struct connection *conn, struct chunk *dest)
David Safb76832014-05-08 23:42:08 -04004283{
4284 X509 *crt = NULL;
4285 X509_NAME *name;
David Safb76832014-05-08 23:42:08 -04004286 const char find_cn[] = "CN";
4287 const struct chunk find_cn_chunk = {
4288 .str = (char *)&find_cn,
4289 .len = sizeof(find_cn)-1
4290 };
Emeric Brun0abf8362014-06-24 18:26:41 +02004291 int result = -1;
David Safb76832014-05-08 23:42:08 -04004292
4293 if (!ssl_sock_is_ssl(conn))
Emeric Brun0abf8362014-06-24 18:26:41 +02004294 goto out;
David Safb76832014-05-08 23:42:08 -04004295
4296 /* SSL_get_peer_certificate, it increase X509 * ref count */
4297 crt = SSL_get_peer_certificate(conn->xprt_ctx);
4298 if (!crt)
4299 goto out;
4300
4301 name = X509_get_subject_name(crt);
4302 if (!name)
4303 goto out;
David Safb76832014-05-08 23:42:08 -04004304
Emeric Brun0abf8362014-06-24 18:26:41 +02004305 result = ssl_sock_get_dn_entry(name, &find_cn_chunk, 1, dest);
4306out:
David Safb76832014-05-08 23:42:08 -04004307 if (crt)
4308 X509_free(crt);
4309
4310 return result;
4311}
4312
Dave McCowan328fb582014-07-30 10:39:13 -04004313/* returns 1 if client passed a certificate for this session, 0 if not */
4314int ssl_sock_get_cert_used_sess(struct connection *conn)
4315{
4316 X509 *crt = NULL;
4317
4318 if (!ssl_sock_is_ssl(conn))
4319 return 0;
4320
4321 /* SSL_get_peer_certificate, it increase X509 * ref count */
4322 crt = SSL_get_peer_certificate(conn->xprt_ctx);
4323 if (!crt)
4324 return 0;
4325
4326 X509_free(crt);
4327 return 1;
4328}
4329
4330/* returns 1 if client passed a certificate for this connection, 0 if not */
4331int ssl_sock_get_cert_used_conn(struct connection *conn)
David Safb76832014-05-08 23:42:08 -04004332{
4333 if (!ssl_sock_is_ssl(conn))
4334 return 0;
4335
4336 return SSL_SOCK_ST_FL_VERIFY_DONE & conn->xprt_st ? 1 : 0;
4337}
4338
4339/* returns result from SSL verify */
4340unsigned int ssl_sock_get_verify_result(struct connection *conn)
4341{
4342 if (!ssl_sock_is_ssl(conn))
4343 return (unsigned int)X509_V_ERR_APPLICATION_VERIFICATION;
4344
4345 return (unsigned int)SSL_get_verify_result(conn->xprt_ctx);
4346}
4347
Willy Tarreau7875d092012-09-10 08:20:03 +02004348/***** Below are some sample fetching functions for ACL/patterns *****/
4349
Emeric Brune64aef12012-09-21 13:15:06 +02004350/* boolean, returns true if client cert was present */
4351static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02004352smp_fetch_ssl_fc_has_crt(const struct arg *args, struct sample *smp, const char *kw, void *private)
Emeric Brune64aef12012-09-21 13:15:06 +02004353{
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004354 struct connection *conn;
4355
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02004356 conn = objt_conn(smp->sess->origin);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004357 if (!conn || conn->xprt != &ssl_sock)
Emeric Brune64aef12012-09-21 13:15:06 +02004358 return 0;
4359
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004360 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brune64aef12012-09-21 13:15:06 +02004361 smp->flags |= SMP_F_MAY_CHANGE;
4362 return 0;
4363 }
4364
4365 smp->flags = 0;
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02004366 smp->data.type = SMP_T_BOOL;
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02004367 smp->data.u.sint = SSL_SOCK_ST_FL_VERIFY_DONE & conn->xprt_st ? 1 : 0;
Emeric Brune64aef12012-09-21 13:15:06 +02004368
4369 return 1;
4370}
4371
Emeric Brun43e79582014-10-29 19:03:26 +01004372/* binary, returns a certificate in a binary chunk (der/raw).
4373 * The 5th keyword char is used to know if SSL_get_certificate or SSL_get_peer_certificate
4374 * should be use.
4375 */
4376static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02004377smp_fetch_ssl_x_der(const struct arg *args, struct sample *smp, const char *kw, void *private)
Emeric Brun43e79582014-10-29 19:03:26 +01004378{
4379 int cert_peer = (kw[4] == 'c') ? 1 : 0;
4380 X509 *crt = NULL;
4381 int ret = 0;
4382 struct chunk *smp_trash;
4383 struct connection *conn;
4384
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02004385 conn = objt_conn(smp->sess->origin);
Emeric Brun43e79582014-10-29 19:03:26 +01004386 if (!conn || conn->xprt != &ssl_sock)
4387 return 0;
4388
4389 if (!(conn->flags & CO_FL_CONNECTED)) {
4390 smp->flags |= SMP_F_MAY_CHANGE;
4391 return 0;
4392 }
4393
4394 if (cert_peer)
4395 crt = SSL_get_peer_certificate(conn->xprt_ctx);
4396 else
4397 crt = SSL_get_certificate(conn->xprt_ctx);
4398
4399 if (!crt)
4400 goto out;
4401
4402 smp_trash = get_trash_chunk();
4403 if (ssl_sock_crt2der(crt, smp_trash) <= 0)
4404 goto out;
4405
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02004406 smp->data.u.str = *smp_trash;
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02004407 smp->data.type = SMP_T_BIN;
Emeric Brun43e79582014-10-29 19:03:26 +01004408 ret = 1;
4409out:
4410 /* SSL_get_peer_certificate, it increase X509 * ref count */
4411 if (cert_peer && crt)
4412 X509_free(crt);
4413 return ret;
4414}
4415
Emeric Brunba841a12014-04-30 17:05:08 +02004416/* binary, returns serial of certificate in a binary chunk.
4417 * The 5th keyword char is used to know if SSL_get_certificate or SSL_get_peer_certificate
4418 * should be use.
4419 */
Willy Tarreau8d598402012-10-22 17:58:39 +02004420static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02004421smp_fetch_ssl_x_serial(const struct arg *args, struct sample *smp, const char *kw, void *private)
Willy Tarreau8d598402012-10-22 17:58:39 +02004422{
Emeric Brunba841a12014-04-30 17:05:08 +02004423 int cert_peer = (kw[4] == 'c') ? 1 : 0;
Willy Tarreau8d598402012-10-22 17:58:39 +02004424 X509 *crt = NULL;
4425 int ret = 0;
4426 struct chunk *smp_trash;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004427 struct connection *conn;
4428
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02004429 conn = objt_conn(smp->sess->origin);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004430 if (!conn || conn->xprt != &ssl_sock)
Willy Tarreau8d598402012-10-22 17:58:39 +02004431 return 0;
4432
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004433 if (!(conn->flags & CO_FL_CONNECTED)) {
Willy Tarreau8d598402012-10-22 17:58:39 +02004434 smp->flags |= SMP_F_MAY_CHANGE;
4435 return 0;
4436 }
4437
Emeric Brunba841a12014-04-30 17:05:08 +02004438 if (cert_peer)
4439 crt = SSL_get_peer_certificate(conn->xprt_ctx);
4440 else
4441 crt = SSL_get_certificate(conn->xprt_ctx);
4442
Willy Tarreau8d598402012-10-22 17:58:39 +02004443 if (!crt)
4444 goto out;
4445
Willy Tarreau47ca5452012-12-23 20:22:19 +01004446 smp_trash = get_trash_chunk();
Willy Tarreau8d598402012-10-22 17:58:39 +02004447 if (ssl_sock_get_serial(crt, smp_trash) <= 0)
4448 goto out;
4449
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02004450 smp->data.u.str = *smp_trash;
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02004451 smp->data.type = SMP_T_BIN;
Willy Tarreau8d598402012-10-22 17:58:39 +02004452 ret = 1;
4453out:
Emeric Brunba841a12014-04-30 17:05:08 +02004454 /* SSL_get_peer_certificate, it increase X509 * ref count */
4455 if (cert_peer && crt)
Willy Tarreau8d598402012-10-22 17:58:39 +02004456 X509_free(crt);
4457 return ret;
4458}
Emeric Brune64aef12012-09-21 13:15:06 +02004459
Emeric Brunba841a12014-04-30 17:05:08 +02004460/* binary, returns the client certificate's SHA-1 fingerprint (SHA-1 hash of DER-encoded certificate) in a binary chunk.
4461 * The 5th keyword char is used to know if SSL_get_certificate or SSL_get_peer_certificate
4462 * should be use.
4463 */
James Votha051b4a2013-05-14 20:37:59 +02004464static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02004465smp_fetch_ssl_x_sha1(const struct arg *args, struct sample *smp, const char *kw, void *private)
James Votha051b4a2013-05-14 20:37:59 +02004466{
Emeric Brunba841a12014-04-30 17:05:08 +02004467 int cert_peer = (kw[4] == 'c') ? 1 : 0;
James Votha051b4a2013-05-14 20:37:59 +02004468 X509 *crt = NULL;
4469 const EVP_MD *digest;
4470 int ret = 0;
4471 struct chunk *smp_trash;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004472 struct connection *conn;
James Votha051b4a2013-05-14 20:37:59 +02004473
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02004474 conn = objt_conn(smp->sess->origin);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004475 if (!conn || conn->xprt != &ssl_sock)
4476 return 0;
4477
4478 if (!(conn->flags & CO_FL_CONNECTED)) {
James Votha051b4a2013-05-14 20:37:59 +02004479 smp->flags |= SMP_F_MAY_CHANGE;
4480 return 0;
4481 }
4482
Emeric Brunba841a12014-04-30 17:05:08 +02004483 if (cert_peer)
4484 crt = SSL_get_peer_certificate(conn->xprt_ctx);
4485 else
4486 crt = SSL_get_certificate(conn->xprt_ctx);
James Votha051b4a2013-05-14 20:37:59 +02004487 if (!crt)
4488 goto out;
4489
4490 smp_trash = get_trash_chunk();
4491 digest = EVP_sha1();
4492 X509_digest(crt, digest, (unsigned char *)smp_trash->str, (unsigned int *)&smp_trash->len);
4493
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02004494 smp->data.u.str = *smp_trash;
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02004495 smp->data.type = SMP_T_BIN;
James Votha051b4a2013-05-14 20:37:59 +02004496 ret = 1;
4497out:
Emeric Brunba841a12014-04-30 17:05:08 +02004498 /* SSL_get_peer_certificate, it increase X509 * ref count */
4499 if (cert_peer && crt)
James Votha051b4a2013-05-14 20:37:59 +02004500 X509_free(crt);
4501 return ret;
4502}
4503
Emeric Brunba841a12014-04-30 17:05:08 +02004504/* string, returns certificate's notafter date in ASN1_UTCTIME format.
4505 * The 5th keyword char is used to know if SSL_get_certificate or SSL_get_peer_certificate
4506 * should be use.
4507 */
Emeric Brunce5ad802012-10-22 14:11:22 +02004508static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02004509smp_fetch_ssl_x_notafter(const struct arg *args, struct sample *smp, const char *kw, void *private)
Emeric Brunce5ad802012-10-22 14:11:22 +02004510{
Emeric Brunba841a12014-04-30 17:05:08 +02004511 int cert_peer = (kw[4] == 'c') ? 1 : 0;
Emeric Brunce5ad802012-10-22 14:11:22 +02004512 X509 *crt = NULL;
4513 int ret = 0;
4514 struct chunk *smp_trash;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004515 struct connection *conn;
Emeric Brunce5ad802012-10-22 14:11:22 +02004516
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02004517 conn = objt_conn(smp->sess->origin);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004518 if (!conn || conn->xprt != &ssl_sock)
4519 return 0;
4520
4521 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brunce5ad802012-10-22 14:11:22 +02004522 smp->flags |= SMP_F_MAY_CHANGE;
4523 return 0;
4524 }
4525
Emeric Brunba841a12014-04-30 17:05:08 +02004526 if (cert_peer)
4527 crt = SSL_get_peer_certificate(conn->xprt_ctx);
4528 else
4529 crt = SSL_get_certificate(conn->xprt_ctx);
Emeric Brunce5ad802012-10-22 14:11:22 +02004530 if (!crt)
4531 goto out;
4532
Willy Tarreau47ca5452012-12-23 20:22:19 +01004533 smp_trash = get_trash_chunk();
Emeric Brunce5ad802012-10-22 14:11:22 +02004534 if (ssl_sock_get_time(X509_get_notAfter(crt), smp_trash) <= 0)
4535 goto out;
4536
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02004537 smp->data.u.str = *smp_trash;
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02004538 smp->data.type = SMP_T_STR;
Emeric Brunce5ad802012-10-22 14:11:22 +02004539 ret = 1;
4540out:
Emeric Brunba841a12014-04-30 17:05:08 +02004541 /* SSL_get_peer_certificate, it increase X509 * ref count */
4542 if (cert_peer && crt)
Emeric Brunce5ad802012-10-22 14:11:22 +02004543 X509_free(crt);
4544 return ret;
4545}
4546
Emeric Brunba841a12014-04-30 17:05:08 +02004547/* string, returns a string of a formatted full dn \C=..\O=..\OU=.. \CN=.. of certificate's issuer
4548 * The 5th keyword char is used to know if SSL_get_certificate or SSL_get_peer_certificate
4549 * should be use.
4550 */
Emeric Brun87855892012-10-17 17:39:35 +02004551static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02004552smp_fetch_ssl_x_i_dn(const struct arg *args, struct sample *smp, const char *kw, void *private)
Emeric Brun87855892012-10-17 17:39:35 +02004553{
Emeric Brunba841a12014-04-30 17:05:08 +02004554 int cert_peer = (kw[4] == 'c') ? 1 : 0;
Emeric Brun87855892012-10-17 17:39:35 +02004555 X509 *crt = NULL;
4556 X509_NAME *name;
4557 int ret = 0;
4558 struct chunk *smp_trash;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004559 struct connection *conn;
Emeric Brun87855892012-10-17 17:39:35 +02004560
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02004561 conn = objt_conn(smp->sess->origin);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004562 if (!conn || conn->xprt != &ssl_sock)
4563 return 0;
4564
4565 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brun87855892012-10-17 17:39:35 +02004566 smp->flags |= SMP_F_MAY_CHANGE;
4567 return 0;
4568 }
4569
Emeric Brunba841a12014-04-30 17:05:08 +02004570 if (cert_peer)
4571 crt = SSL_get_peer_certificate(conn->xprt_ctx);
4572 else
4573 crt = SSL_get_certificate(conn->xprt_ctx);
Emeric Brun87855892012-10-17 17:39:35 +02004574 if (!crt)
4575 goto out;
4576
4577 name = X509_get_issuer_name(crt);
4578 if (!name)
4579 goto out;
4580
Willy Tarreau47ca5452012-12-23 20:22:19 +01004581 smp_trash = get_trash_chunk();
Emeric Brun87855892012-10-17 17:39:35 +02004582 if (args && args[0].type == ARGT_STR) {
4583 int pos = 1;
4584
4585 if (args[1].type == ARGT_SINT)
4586 pos = args[1].data.sint;
Emeric Brun87855892012-10-17 17:39:35 +02004587
4588 if (ssl_sock_get_dn_entry(name, &args[0].data.str, pos, smp_trash) <= 0)
4589 goto out;
4590 }
4591 else if (ssl_sock_get_dn_oneline(name, smp_trash) <= 0)
4592 goto out;
4593
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02004594 smp->data.type = SMP_T_STR;
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02004595 smp->data.u.str = *smp_trash;
Emeric Brun87855892012-10-17 17:39:35 +02004596 ret = 1;
4597out:
Emeric Brunba841a12014-04-30 17:05:08 +02004598 /* SSL_get_peer_certificate, it increase X509 * ref count */
4599 if (cert_peer && crt)
Emeric Brun87855892012-10-17 17:39:35 +02004600 X509_free(crt);
4601 return ret;
4602}
4603
Emeric Brunba841a12014-04-30 17:05:08 +02004604/* string, returns notbefore date in ASN1_UTCTIME format.
4605 * The 5th keyword char is used to know if SSL_get_certificate or SSL_get_peer_certificate
4606 * should be use.
4607 */
Emeric Brunce5ad802012-10-22 14:11:22 +02004608static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02004609smp_fetch_ssl_x_notbefore(const struct arg *args, struct sample *smp, const char *kw, void *private)
Emeric Brunce5ad802012-10-22 14:11:22 +02004610{
Emeric Brunba841a12014-04-30 17:05:08 +02004611 int cert_peer = (kw[4] == 'c') ? 1 : 0;
Emeric Brunce5ad802012-10-22 14:11:22 +02004612 X509 *crt = NULL;
4613 int ret = 0;
4614 struct chunk *smp_trash;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004615 struct connection *conn;
4616
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02004617 conn = objt_conn(smp->sess->origin);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004618 if (!conn || conn->xprt != &ssl_sock)
Emeric Brunce5ad802012-10-22 14:11:22 +02004619 return 0;
4620
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004621 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brunce5ad802012-10-22 14:11:22 +02004622 smp->flags |= SMP_F_MAY_CHANGE;
4623 return 0;
4624 }
4625
Emeric Brunba841a12014-04-30 17:05:08 +02004626 if (cert_peer)
4627 crt = SSL_get_peer_certificate(conn->xprt_ctx);
4628 else
4629 crt = SSL_get_certificate(conn->xprt_ctx);
Emeric Brunce5ad802012-10-22 14:11:22 +02004630 if (!crt)
4631 goto out;
4632
Willy Tarreau47ca5452012-12-23 20:22:19 +01004633 smp_trash = get_trash_chunk();
Emeric Brunce5ad802012-10-22 14:11:22 +02004634 if (ssl_sock_get_time(X509_get_notBefore(crt), smp_trash) <= 0)
4635 goto out;
4636
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02004637 smp->data.u.str = *smp_trash;
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02004638 smp->data.type = SMP_T_STR;
Emeric Brunce5ad802012-10-22 14:11:22 +02004639 ret = 1;
4640out:
Emeric Brunba841a12014-04-30 17:05:08 +02004641 /* SSL_get_peer_certificate, it increase X509 * ref count */
4642 if (cert_peer && crt)
Emeric Brunce5ad802012-10-22 14:11:22 +02004643 X509_free(crt);
4644 return ret;
4645}
4646
Emeric Brunba841a12014-04-30 17:05:08 +02004647/* string, returns a string of a formatted full dn \C=..\O=..\OU=.. \CN=.. of certificate's subject
4648 * The 5th keyword char is used to know if SSL_get_certificate or SSL_get_peer_certificate
4649 * should be use.
4650 */
Emeric Brun87855892012-10-17 17:39:35 +02004651static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02004652smp_fetch_ssl_x_s_dn(const struct arg *args, struct sample *smp, const char *kw, void *private)
Emeric Brun87855892012-10-17 17:39:35 +02004653{
Emeric Brunba841a12014-04-30 17:05:08 +02004654 int cert_peer = (kw[4] == 'c') ? 1 : 0;
Emeric Brun87855892012-10-17 17:39:35 +02004655 X509 *crt = NULL;
4656 X509_NAME *name;
4657 int ret = 0;
4658 struct chunk *smp_trash;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004659 struct connection *conn;
Emeric Brun87855892012-10-17 17:39:35 +02004660
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02004661 conn = objt_conn(smp->sess->origin);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004662 if (!conn || conn->xprt != &ssl_sock)
4663 return 0;
4664
4665 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brun87855892012-10-17 17:39:35 +02004666 smp->flags |= SMP_F_MAY_CHANGE;
4667 return 0;
4668 }
4669
Emeric Brunba841a12014-04-30 17:05:08 +02004670 if (cert_peer)
4671 crt = SSL_get_peer_certificate(conn->xprt_ctx);
4672 else
4673 crt = SSL_get_certificate(conn->xprt_ctx);
Emeric Brun87855892012-10-17 17:39:35 +02004674 if (!crt)
4675 goto out;
4676
4677 name = X509_get_subject_name(crt);
4678 if (!name)
4679 goto out;
4680
Willy Tarreau47ca5452012-12-23 20:22:19 +01004681 smp_trash = get_trash_chunk();
Emeric Brun87855892012-10-17 17:39:35 +02004682 if (args && args[0].type == ARGT_STR) {
4683 int pos = 1;
4684
4685 if (args[1].type == ARGT_SINT)
4686 pos = args[1].data.sint;
Emeric Brun87855892012-10-17 17:39:35 +02004687
4688 if (ssl_sock_get_dn_entry(name, &args[0].data.str, pos, smp_trash) <= 0)
4689 goto out;
4690 }
4691 else if (ssl_sock_get_dn_oneline(name, smp_trash) <= 0)
4692 goto out;
4693
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02004694 smp->data.type = SMP_T_STR;
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02004695 smp->data.u.str = *smp_trash;
Emeric Brun87855892012-10-17 17:39:35 +02004696 ret = 1;
4697out:
Emeric Brunba841a12014-04-30 17:05:08 +02004698 /* SSL_get_peer_certificate, it increase X509 * ref count */
4699 if (cert_peer && crt)
Emeric Brun87855892012-10-17 17:39:35 +02004700 X509_free(crt);
4701 return ret;
4702}
Emeric Brun9143d372012-12-20 15:44:16 +01004703
4704/* integer, returns true if current session use a client certificate */
4705static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02004706smp_fetch_ssl_c_used(const struct arg *args, struct sample *smp, const char *kw, void *private)
Emeric Brun9143d372012-12-20 15:44:16 +01004707{
4708 X509 *crt;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004709 struct connection *conn;
Emeric Brun9143d372012-12-20 15:44:16 +01004710
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02004711 conn = objt_conn(smp->sess->origin);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004712 if (!conn || conn->xprt != &ssl_sock)
4713 return 0;
4714
4715 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brun9143d372012-12-20 15:44:16 +01004716 smp->flags |= SMP_F_MAY_CHANGE;
4717 return 0;
4718 }
4719
4720 /* SSL_get_peer_certificate returns a ptr on allocated X509 struct */
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004721 crt = SSL_get_peer_certificate(conn->xprt_ctx);
Emeric Brun9143d372012-12-20 15:44:16 +01004722 if (crt) {
4723 X509_free(crt);
4724 }
4725
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02004726 smp->data.type = SMP_T_BOOL;
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02004727 smp->data.u.sint = (crt != NULL);
Emeric Brun9143d372012-12-20 15:44:16 +01004728 return 1;
4729}
4730
Emeric Brunba841a12014-04-30 17:05:08 +02004731/* integer, returns the certificate version
4732 * The 5th keyword char is used to know if SSL_get_certificate or SSL_get_peer_certificate
4733 * should be use.
4734 */
Emeric Bruna7359fd2012-10-17 15:03:11 +02004735static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02004736smp_fetch_ssl_x_version(const struct arg *args, struct sample *smp, const char *kw, void *private)
Emeric Bruna7359fd2012-10-17 15:03:11 +02004737{
Emeric Brunba841a12014-04-30 17:05:08 +02004738 int cert_peer = (kw[4] == 'c') ? 1 : 0;
Emeric Bruna7359fd2012-10-17 15:03:11 +02004739 X509 *crt;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004740 struct connection *conn;
4741
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02004742 conn = objt_conn(smp->sess->origin);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004743 if (!conn || conn->xprt != &ssl_sock)
Emeric Bruna7359fd2012-10-17 15:03:11 +02004744 return 0;
4745
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004746 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Bruna7359fd2012-10-17 15:03:11 +02004747 smp->flags |= SMP_F_MAY_CHANGE;
4748 return 0;
4749 }
4750
Emeric Brunba841a12014-04-30 17:05:08 +02004751 if (cert_peer)
4752 crt = SSL_get_peer_certificate(conn->xprt_ctx);
4753 else
4754 crt = SSL_get_certificate(conn->xprt_ctx);
Emeric Bruna7359fd2012-10-17 15:03:11 +02004755 if (!crt)
4756 return 0;
4757
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02004758 smp->data.u.sint = (unsigned int)(1 + X509_get_version(crt));
Emeric Brunba841a12014-04-30 17:05:08 +02004759 /* SSL_get_peer_certificate increase X509 * ref count */
4760 if (cert_peer)
4761 X509_free(crt);
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02004762 smp->data.type = SMP_T_SINT;
Emeric Bruna7359fd2012-10-17 15:03:11 +02004763
4764 return 1;
4765}
4766
Emeric Brunba841a12014-04-30 17:05:08 +02004767/* string, returns the certificate's signature algorithm.
4768 * The 5th keyword char is used to know if SSL_get_certificate or SSL_get_peer_certificate
4769 * should be use.
4770 */
Emeric Brun7f56e742012-10-19 18:15:40 +02004771static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02004772smp_fetch_ssl_x_sig_alg(const struct arg *args, struct sample *smp, const char *kw, void *private)
Emeric Brun7f56e742012-10-19 18:15:40 +02004773{
Emeric Brunba841a12014-04-30 17:05:08 +02004774 int cert_peer = (kw[4] == 'c') ? 1 : 0;
Emeric Brun7f56e742012-10-19 18:15:40 +02004775 X509 *crt;
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02004776 __OPENSSL_110_CONST__ ASN1_OBJECT *algorithm;
Emeric Brun7f56e742012-10-19 18:15:40 +02004777 int nid;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004778 struct connection *conn;
Emeric Brun7f56e742012-10-19 18:15:40 +02004779
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02004780 conn = objt_conn(smp->sess->origin);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004781 if (!conn || conn->xprt != &ssl_sock)
4782 return 0;
4783
4784 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brun7f56e742012-10-19 18:15:40 +02004785 smp->flags |= SMP_F_MAY_CHANGE;
4786 return 0;
4787 }
4788
Emeric Brunba841a12014-04-30 17:05:08 +02004789 if (cert_peer)
4790 crt = SSL_get_peer_certificate(conn->xprt_ctx);
4791 else
4792 crt = SSL_get_certificate(conn->xprt_ctx);
Emeric Brun7f56e742012-10-19 18:15:40 +02004793 if (!crt)
4794 return 0;
4795
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02004796 X509_ALGOR_get0(&algorithm, NULL, NULL, X509_get0_tbs_sigalg(crt));
4797 nid = OBJ_obj2nid(algorithm);
Emeric Brun7f56e742012-10-19 18:15:40 +02004798
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02004799 smp->data.u.str.str = (char *)OBJ_nid2sn(nid);
4800 if (!smp->data.u.str.str) {
Emeric Brunba841a12014-04-30 17:05:08 +02004801 /* SSL_get_peer_certificate increase X509 * ref count */
4802 if (cert_peer)
4803 X509_free(crt);
Emeric Brun7f56e742012-10-19 18:15:40 +02004804 return 0;
Emeric Brun9bf3ba22013-10-07 14:31:44 +02004805 }
Emeric Brun7f56e742012-10-19 18:15:40 +02004806
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02004807 smp->data.type = SMP_T_STR;
Thierry FOURNIER7654c9f2013-12-17 00:20:33 +01004808 smp->flags |= SMP_F_CONST;
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02004809 smp->data.u.str.len = strlen(smp->data.u.str.str);
Emeric Brunba841a12014-04-30 17:05:08 +02004810 /* SSL_get_peer_certificate increase X509 * ref count */
4811 if (cert_peer)
4812 X509_free(crt);
Emeric Brun7f56e742012-10-19 18:15:40 +02004813
4814 return 1;
4815}
4816
Emeric Brunba841a12014-04-30 17:05:08 +02004817/* string, returns the certificate's key algorithm.
4818 * The 5th keyword char is used to know if SSL_get_certificate or SSL_get_peer_certificate
4819 * should be use.
4820 */
Emeric Brun521a0112012-10-22 12:22:55 +02004821static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02004822smp_fetch_ssl_x_key_alg(const struct arg *args, struct sample *smp, const char *kw, void *private)
Emeric Brun521a0112012-10-22 12:22:55 +02004823{
Emeric Brunba841a12014-04-30 17:05:08 +02004824 int cert_peer = (kw[4] == 'c') ? 1 : 0;
Emeric Brun521a0112012-10-22 12:22:55 +02004825 X509 *crt;
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02004826 ASN1_OBJECT *algorithm;
Emeric Brun521a0112012-10-22 12:22:55 +02004827 int nid;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004828 struct connection *conn;
Emeric Brun521a0112012-10-22 12:22:55 +02004829
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02004830 conn = objt_conn(smp->sess->origin);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004831 if (!conn || conn->xprt != &ssl_sock)
4832 return 0;
4833
4834 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brun521a0112012-10-22 12:22:55 +02004835 smp->flags |= SMP_F_MAY_CHANGE;
4836 return 0;
4837 }
4838
Emeric Brunba841a12014-04-30 17:05:08 +02004839 if (cert_peer)
4840 crt = SSL_get_peer_certificate(conn->xprt_ctx);
4841 else
4842 crt = SSL_get_certificate(conn->xprt_ctx);
Emeric Brun521a0112012-10-22 12:22:55 +02004843 if (!crt)
4844 return 0;
4845
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02004846 X509_PUBKEY_get0_param(&algorithm, NULL, NULL, NULL, X509_get_X509_PUBKEY(crt));
4847 nid = OBJ_obj2nid(algorithm);
Emeric Brun521a0112012-10-22 12:22:55 +02004848
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02004849 smp->data.u.str.str = (char *)OBJ_nid2sn(nid);
4850 if (!smp->data.u.str.str) {
Emeric Brunba841a12014-04-30 17:05:08 +02004851 /* SSL_get_peer_certificate increase X509 * ref count */
4852 if (cert_peer)
4853 X509_free(crt);
Emeric Brun521a0112012-10-22 12:22:55 +02004854 return 0;
Emeric Brun9bf3ba22013-10-07 14:31:44 +02004855 }
Emeric Brun521a0112012-10-22 12:22:55 +02004856
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02004857 smp->data.type = SMP_T_STR;
Thierry FOURNIER7654c9f2013-12-17 00:20:33 +01004858 smp->flags |= SMP_F_CONST;
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02004859 smp->data.u.str.len = strlen(smp->data.u.str.str);
Emeric Brunba841a12014-04-30 17:05:08 +02004860 if (cert_peer)
4861 X509_free(crt);
Emeric Brun521a0112012-10-22 12:22:55 +02004862
4863 return 1;
4864}
4865
Emeric Brun645ae792014-04-30 14:21:06 +02004866/* boolean, returns true if front conn. transport layer is SSL.
4867 * This function is also usable on backend conn if the fetch keyword 5th
4868 * char is 'b'.
4869 */
Willy Tarreau7875d092012-09-10 08:20:03 +02004870static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02004871smp_fetch_ssl_fc(const struct arg *args, struct sample *smp, const char *kw, void *private)
Willy Tarreau7875d092012-09-10 08:20:03 +02004872{
Willy Tarreaue237fe12016-03-10 17:05:28 +01004873 struct connection *conn = objt_conn((kw[4] != 'b') ? smp->sess->origin :
4874 smp->strm ? smp->strm->si[1].end : NULL);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004875
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02004876 smp->data.type = SMP_T_BOOL;
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02004877 smp->data.u.sint = (conn && conn->xprt == &ssl_sock);
Willy Tarreau7875d092012-09-10 08:20:03 +02004878 return 1;
4879}
4880
Emeric Brun2525b6b2012-10-18 15:59:43 +02004881/* boolean, returns true if client present a SNI */
Willy Tarreau7875d092012-09-10 08:20:03 +02004882static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02004883smp_fetch_ssl_fc_has_sni(const struct arg *args, struct sample *smp, const char *kw, void *private)
Willy Tarreau7875d092012-09-10 08:20:03 +02004884{
4885#ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02004886 struct connection *conn = objt_conn(smp->sess->origin);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004887
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02004888 smp->data.type = SMP_T_BOOL;
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02004889 smp->data.u.sint = (conn && conn->xprt == &ssl_sock) &&
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004890 conn->xprt_ctx &&
4891 SSL_get_servername(conn->xprt_ctx, TLSEXT_NAMETYPE_host_name) != NULL;
Willy Tarreau7875d092012-09-10 08:20:03 +02004892 return 1;
4893#else
4894 return 0;
4895#endif
4896}
4897
Nenad Merdanovic26ea8222015-05-18 02:28:57 +02004898/* boolean, returns true if client session has been resumed */
4899static int
4900smp_fetch_ssl_fc_is_resumed(const struct arg *args, struct sample *smp, const char *kw, void *private)
4901{
4902 struct connection *conn = objt_conn(smp->sess->origin);
4903
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02004904 smp->data.type = SMP_T_BOOL;
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02004905 smp->data.u.sint = (conn && conn->xprt == &ssl_sock) &&
Nenad Merdanovic26ea8222015-05-18 02:28:57 +02004906 conn->xprt_ctx &&
4907 SSL_session_reused(conn->xprt_ctx);
4908 return 1;
4909}
4910
Emeric Brun645ae792014-04-30 14:21:06 +02004911/* string, returns the used cipher if front conn. transport layer is SSL.
4912 * This function is also usable on backend conn if the fetch keyword 5th
4913 * char is 'b'.
4914 */
Emeric Brun589fcad2012-10-16 14:13:26 +02004915static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02004916smp_fetch_ssl_fc_cipher(const struct arg *args, struct sample *smp, const char *kw, void *private)
Emeric Brun589fcad2012-10-16 14:13:26 +02004917{
Willy Tarreaue237fe12016-03-10 17:05:28 +01004918 struct connection *conn = objt_conn((kw[4] != 'b') ? smp->sess->origin :
4919 smp->strm ? smp->strm->si[1].end : NULL);
Emeric Brun589fcad2012-10-16 14:13:26 +02004920
Willy Tarreaube508f12016-03-10 11:47:01 +01004921 smp->flags = 0;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004922 if (!conn || !conn->xprt_ctx || conn->xprt != &ssl_sock)
Emeric Brun589fcad2012-10-16 14:13:26 +02004923 return 0;
4924
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02004925 smp->data.u.str.str = (char *)SSL_get_cipher_name(conn->xprt_ctx);
4926 if (!smp->data.u.str.str)
Emeric Brun589fcad2012-10-16 14:13:26 +02004927 return 0;
4928
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02004929 smp->data.type = SMP_T_STR;
Thierry FOURNIER7654c9f2013-12-17 00:20:33 +01004930 smp->flags |= SMP_F_CONST;
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02004931 smp->data.u.str.len = strlen(smp->data.u.str.str);
Emeric Brun589fcad2012-10-16 14:13:26 +02004932
4933 return 1;
4934}
4935
Emeric Brun645ae792014-04-30 14:21:06 +02004936/* integer, returns the algoritm's keysize if front conn. transport layer
4937 * is SSL.
4938 * This function is also usable on backend conn if the fetch keyword 5th
4939 * char is 'b'.
4940 */
Emeric Brun589fcad2012-10-16 14:13:26 +02004941static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02004942smp_fetch_ssl_fc_alg_keysize(const struct arg *args, struct sample *smp, const char *kw, void *private)
Emeric Brun589fcad2012-10-16 14:13:26 +02004943{
Willy Tarreaue237fe12016-03-10 17:05:28 +01004944 struct connection *conn = objt_conn((kw[4] != 'b') ? smp->sess->origin :
4945 smp->strm ? smp->strm->si[1].end : NULL);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004946
Willy Tarreaue237fe12016-03-10 17:05:28 +01004947 int sint;
Willy Tarreaube508f12016-03-10 11:47:01 +01004948
Emeric Brun589fcad2012-10-16 14:13:26 +02004949 smp->flags = 0;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004950 if (!conn || !conn->xprt_ctx || conn->xprt != &ssl_sock)
Emeric Brun589fcad2012-10-16 14:13:26 +02004951 return 0;
4952
Thierry FOURNIER07ee64e2015-07-06 23:43:03 +02004953 if (!SSL_get_cipher_bits(conn->xprt_ctx, &sint))
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004954 return 0;
4955
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02004956 smp->data.u.sint = sint;
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02004957 smp->data.type = SMP_T_SINT;
Emeric Brun589fcad2012-10-16 14:13:26 +02004958
4959 return 1;
4960}
4961
Emeric Brun645ae792014-04-30 14:21:06 +02004962/* integer, returns the used keysize if front conn. transport layer is SSL.
4963 * This function is also usable on backend conn if the fetch keyword 5th
4964 * char is 'b'.
4965 */
Emeric Brun589fcad2012-10-16 14:13:26 +02004966static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02004967smp_fetch_ssl_fc_use_keysize(const struct arg *args, struct sample *smp, const char *kw, void *private)
Emeric Brun589fcad2012-10-16 14:13:26 +02004968{
Willy Tarreaue237fe12016-03-10 17:05:28 +01004969 struct connection *conn = objt_conn((kw[4] != 'b') ? smp->sess->origin :
4970 smp->strm ? smp->strm->si[1].end : NULL);
Willy Tarreaube508f12016-03-10 11:47:01 +01004971
Emeric Brun589fcad2012-10-16 14:13:26 +02004972 smp->flags = 0;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004973 if (!conn || !conn->xprt_ctx || conn->xprt != &ssl_sock)
4974 return 0;
4975
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02004976 smp->data.u.sint = (unsigned int)SSL_get_cipher_bits(conn->xprt_ctx, NULL);
4977 if (!smp->data.u.sint)
Emeric Brun589fcad2012-10-16 14:13:26 +02004978 return 0;
4979
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02004980 smp->data.type = SMP_T_SINT;
Emeric Brun589fcad2012-10-16 14:13:26 +02004981
4982 return 1;
4983}
4984
Willy Tarreau6c9a3d52012-10-18 18:57:14 +02004985#ifdef OPENSSL_NPN_NEGOTIATED
Willy Tarreau7875d092012-09-10 08:20:03 +02004986static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02004987smp_fetch_ssl_fc_npn(const struct arg *args, struct sample *smp, const char *kw, void *private)
Willy Tarreaua33c6542012-10-15 13:19:06 +02004988{
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004989 struct connection *conn;
4990
Thierry FOURNIER7654c9f2013-12-17 00:20:33 +01004991 smp->flags = SMP_F_CONST;
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02004992 smp->data.type = SMP_T_STR;
Willy Tarreaua33c6542012-10-15 13:19:06 +02004993
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02004994 conn = objt_conn(smp->sess->origin);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004995 if (!conn || !conn->xprt_ctx || conn->xprt != &ssl_sock)
4996 return 0;
4997
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02004998 smp->data.u.str.str = NULL;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004999 SSL_get0_next_proto_negotiated(conn->xprt_ctx,
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02005000 (const unsigned char **)&smp->data.u.str.str, (unsigned *)&smp->data.u.str.len);
Willy Tarreaua33c6542012-10-15 13:19:06 +02005001
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02005002 if (!smp->data.u.str.str)
Willy Tarreaua33c6542012-10-15 13:19:06 +02005003 return 0;
5004
5005 return 1;
Willy Tarreaua33c6542012-10-15 13:19:06 +02005006}
Willy Tarreau6c9a3d52012-10-18 18:57:14 +02005007#endif
Willy Tarreaua33c6542012-10-15 13:19:06 +02005008
Dirkjan Bussink48f1c4e2014-02-13 12:29:42 +01005009#ifdef TLSEXT_TYPE_application_layer_protocol_negotiation
Willy Tarreauab861d32013-04-02 02:30:41 +02005010static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02005011smp_fetch_ssl_fc_alpn(const struct arg *args, struct sample *smp, const char *kw, void *private)
Willy Tarreauab861d32013-04-02 02:30:41 +02005012{
Willy Tarreaub363a1f2013-10-01 10:45:07 +02005013 struct connection *conn;
5014
Thierry FOURNIER7654c9f2013-12-17 00:20:33 +01005015 smp->flags = SMP_F_CONST;
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02005016 smp->data.type = SMP_T_STR;
Willy Tarreauab861d32013-04-02 02:30:41 +02005017
Willy Tarreaue26bf052015-05-12 10:30:12 +02005018 conn = objt_conn(smp->sess->origin);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02005019 if (!conn || !conn->xprt_ctx || conn->xprt != &ssl_sock)
Willy Tarreauab861d32013-04-02 02:30:41 +02005020 return 0;
5021
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02005022 smp->data.u.str.str = NULL;
Dirkjan Bussink48f1c4e2014-02-13 12:29:42 +01005023 SSL_get0_alpn_selected(conn->xprt_ctx,
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02005024 (const unsigned char **)&smp->data.u.str.str, (unsigned *)&smp->data.u.str.len);
Willy Tarreauab861d32013-04-02 02:30:41 +02005025
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02005026 if (!smp->data.u.str.str)
Willy Tarreauab861d32013-04-02 02:30:41 +02005027 return 0;
5028
5029 return 1;
5030}
5031#endif
5032
Emeric Brun645ae792014-04-30 14:21:06 +02005033/* string, returns the used protocol if front conn. transport layer is SSL.
5034 * This function is also usable on backend conn if the fetch keyword 5th
5035 * char is 'b'.
5036 */
Willy Tarreaua33c6542012-10-15 13:19:06 +02005037static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02005038smp_fetch_ssl_fc_protocol(const struct arg *args, struct sample *smp, const char *kw, void *private)
Emeric Brun589fcad2012-10-16 14:13:26 +02005039{
Willy Tarreaue237fe12016-03-10 17:05:28 +01005040 struct connection *conn = objt_conn((kw[4] != 'b') ? smp->sess->origin :
5041 smp->strm ? smp->strm->si[1].end : NULL);
Willy Tarreaube508f12016-03-10 11:47:01 +01005042
Emeric Brun589fcad2012-10-16 14:13:26 +02005043 smp->flags = 0;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02005044 if (!conn || !conn->xprt_ctx || conn->xprt != &ssl_sock)
5045 return 0;
5046
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02005047 smp->data.u.str.str = (char *)SSL_get_version(conn->xprt_ctx);
5048 if (!smp->data.u.str.str)
Emeric Brun589fcad2012-10-16 14:13:26 +02005049 return 0;
5050
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02005051 smp->data.type = SMP_T_STR;
Thierry FOURNIER7654c9f2013-12-17 00:20:33 +01005052 smp->flags = SMP_F_CONST;
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02005053 smp->data.u.str.len = strlen(smp->data.u.str.str);
Emeric Brun589fcad2012-10-16 14:13:26 +02005054
5055 return 1;
5056}
5057
Willy Tarreau87b09662015-04-03 00:22:06 +02005058/* binary, returns the SSL stream id if front conn. transport layer is SSL.
Emeric Brun645ae792014-04-30 14:21:06 +02005059 * This function is also usable on backend conn if the fetch keyword 5th
5060 * char is 'b'.
5061 */
Emeric Brun589fcad2012-10-16 14:13:26 +02005062static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02005063smp_fetch_ssl_fc_session_id(const struct arg *args, struct sample *smp, const char *kw, void *private)
Emeric Brunfe68f682012-10-16 14:59:28 +02005064{
5065#if OPENSSL_VERSION_NUMBER > 0x0090800fL
Willy Tarreaue237fe12016-03-10 17:05:28 +01005066 struct connection *conn = objt_conn((kw[4] != 'b') ? smp->sess->origin :
5067 smp->strm ? smp->strm->si[1].end : NULL);
Emeric Brunfe68f682012-10-16 14:59:28 +02005068
Willy Tarreaue237fe12016-03-10 17:05:28 +01005069 SSL_SESSION *ssl_sess;
Willy Tarreaube508f12016-03-10 11:47:01 +01005070
Thierry FOURNIER7654c9f2013-12-17 00:20:33 +01005071 smp->flags = SMP_F_CONST;
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02005072 smp->data.type = SMP_T_BIN;
Emeric Brunfe68f682012-10-16 14:59:28 +02005073
Willy Tarreaub363a1f2013-10-01 10:45:07 +02005074 if (!conn || !conn->xprt_ctx || conn->xprt != &ssl_sock)
5075 return 0;
5076
Willy Tarreau192252e2015-04-04 01:47:55 +02005077 ssl_sess = SSL_get_session(conn->xprt_ctx);
5078 if (!ssl_sess)
Emeric Brunfe68f682012-10-16 14:59:28 +02005079 return 0;
5080
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02005081 smp->data.u.str.str = (char *)SSL_SESSION_get_id(ssl_sess, (unsigned int *)&smp->data.u.str.len);
5082 if (!smp->data.u.str.str || !smp->data.u.str.len)
Emeric Brunfe68f682012-10-16 14:59:28 +02005083 return 0;
5084
5085 return 1;
5086#else
5087 return 0;
5088#endif
5089}
5090
5091static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02005092smp_fetch_ssl_fc_sni(const struct arg *args, struct sample *smp, const char *kw, void *private)
Willy Tarreau7875d092012-09-10 08:20:03 +02005093{
5094#ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME
Willy Tarreaub363a1f2013-10-01 10:45:07 +02005095 struct connection *conn;
5096
Thierry FOURNIER7654c9f2013-12-17 00:20:33 +01005097 smp->flags = SMP_F_CONST;
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02005098 smp->data.type = SMP_T_STR;
Willy Tarreau7875d092012-09-10 08:20:03 +02005099
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02005100 conn = objt_conn(smp->sess->origin);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02005101 if (!conn || !conn->xprt_ctx || conn->xprt != &ssl_sock)
5102 return 0;
5103
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02005104 smp->data.u.str.str = (char *)SSL_get_servername(conn->xprt_ctx, TLSEXT_NAMETYPE_host_name);
5105 if (!smp->data.u.str.str)
Willy Tarreau3e394c92012-09-14 23:56:58 +02005106 return 0;
5107
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02005108 smp->data.u.str.len = strlen(smp->data.u.str.str);
Willy Tarreau7875d092012-09-10 08:20:03 +02005109 return 1;
5110#else
5111 return 0;
5112#endif
5113}
5114
David Sc1ad52e2014-04-08 18:48:47 -04005115static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02005116smp_fetch_ssl_fc_unique_id(const struct arg *args, struct sample *smp, const char *kw, void *private)
David Sc1ad52e2014-04-08 18:48:47 -04005117{
5118#if OPENSSL_VERSION_NUMBER > 0x0090800fL
Willy Tarreaue237fe12016-03-10 17:05:28 +01005119 struct connection *conn = objt_conn((kw[4] != 'b') ? smp->sess->origin :
5120 smp->strm ? smp->strm->si[1].end : NULL);
5121
David Sc1ad52e2014-04-08 18:48:47 -04005122 int finished_len;
David Sc1ad52e2014-04-08 18:48:47 -04005123 struct chunk *finished_trash;
David Sc1ad52e2014-04-08 18:48:47 -04005124
5125 smp->flags = 0;
David Sc1ad52e2014-04-08 18:48:47 -04005126 if (!conn || !conn->xprt_ctx || conn->xprt != &ssl_sock)
5127 return 0;
5128
5129 if (!(conn->flags & CO_FL_CONNECTED)) {
5130 smp->flags |= SMP_F_MAY_CHANGE;
5131 return 0;
5132 }
5133
5134 finished_trash = get_trash_chunk();
5135 if (!SSL_session_reused(conn->xprt_ctx))
5136 finished_len = SSL_get_peer_finished(conn->xprt_ctx, finished_trash->str, finished_trash->size);
5137 else
5138 finished_len = SSL_get_finished(conn->xprt_ctx, finished_trash->str, finished_trash->size);
5139
5140 if (!finished_len)
5141 return 0;
5142
Emeric Brunb73a9b02014-04-30 18:49:19 +02005143 finished_trash->len = finished_len;
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02005144 smp->data.u.str = *finished_trash;
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02005145 smp->data.type = SMP_T_BIN;
David Sc1ad52e2014-04-08 18:48:47 -04005146
5147 return 1;
5148#else
5149 return 0;
5150#endif
5151}
5152
Emeric Brun2525b6b2012-10-18 15:59:43 +02005153/* integer, returns the first verify error in CA chain of client certificate chain. */
Emeric Brunf282a812012-09-21 15:27:54 +02005154static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02005155smp_fetch_ssl_c_ca_err(const struct arg *args, struct sample *smp, const char *kw, void *private)
Emeric Brunf282a812012-09-21 15:27:54 +02005156{
Willy Tarreaub363a1f2013-10-01 10:45:07 +02005157 struct connection *conn;
5158
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02005159 conn = objt_conn(smp->sess->origin);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02005160 if (!conn || conn->xprt != &ssl_sock)
5161 return 0;
5162
5163 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brunf282a812012-09-21 15:27:54 +02005164 smp->flags = SMP_F_MAY_CHANGE;
5165 return 0;
5166 }
5167
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02005168 smp->data.type = SMP_T_SINT;
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02005169 smp->data.u.sint = (unsigned long long int)SSL_SOCK_ST_TO_CA_ERROR(conn->xprt_st);
Emeric Brunf282a812012-09-21 15:27:54 +02005170 smp->flags = 0;
5171
5172 return 1;
5173}
5174
Emeric Brun2525b6b2012-10-18 15:59:43 +02005175/* integer, returns the depth of the first verify error in CA chain of client certificate chain. */
Emeric Brunf282a812012-09-21 15:27:54 +02005176static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02005177smp_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 +02005178{
Willy Tarreaub363a1f2013-10-01 10:45:07 +02005179 struct connection *conn;
5180
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02005181 conn = objt_conn(smp->sess->origin);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02005182 if (!conn || conn->xprt != &ssl_sock)
Emeric Brunf282a812012-09-21 15:27:54 +02005183 return 0;
5184
Willy Tarreaub363a1f2013-10-01 10:45:07 +02005185 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brunf282a812012-09-21 15:27:54 +02005186 smp->flags = SMP_F_MAY_CHANGE;
5187 return 0;
5188 }
5189
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02005190 smp->data.type = SMP_T_SINT;
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02005191 smp->data.u.sint = (long long int)SSL_SOCK_ST_TO_CAEDEPTH(conn->xprt_st);
Emeric Brunf282a812012-09-21 15:27:54 +02005192 smp->flags = 0;
5193
5194 return 1;
5195}
5196
Emeric Brun2525b6b2012-10-18 15:59:43 +02005197/* integer, returns the first verify error on client certificate */
Emeric Brunf282a812012-09-21 15:27:54 +02005198static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02005199smp_fetch_ssl_c_err(const struct arg *args, struct sample *smp, const char *kw, void *private)
Emeric Brunf282a812012-09-21 15:27:54 +02005200{
Willy Tarreaub363a1f2013-10-01 10:45:07 +02005201 struct connection *conn;
5202
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02005203 conn = objt_conn(smp->sess->origin);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02005204 if (!conn || conn->xprt != &ssl_sock)
5205 return 0;
5206
5207 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brunf282a812012-09-21 15:27:54 +02005208 smp->flags = SMP_F_MAY_CHANGE;
5209 return 0;
5210 }
5211
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02005212 smp->data.type = SMP_T_SINT;
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02005213 smp->data.u.sint = (long long int)SSL_SOCK_ST_TO_CRTERROR(conn->xprt_st);
Emeric Brunf282a812012-09-21 15:27:54 +02005214 smp->flags = 0;
5215
5216 return 1;
5217}
5218
Emeric Brun2525b6b2012-10-18 15:59:43 +02005219/* integer, returns the verify result on client cert */
Emeric Brunbaf8ffb2012-09-21 15:27:20 +02005220static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02005221smp_fetch_ssl_c_verify(const struct arg *args, struct sample *smp, const char *kw, void *private)
Emeric Brunbaf8ffb2012-09-21 15:27:20 +02005222{
Willy Tarreaub363a1f2013-10-01 10:45:07 +02005223 struct connection *conn;
5224
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02005225 conn = objt_conn(smp->sess->origin);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02005226 if (!conn || conn->xprt != &ssl_sock)
5227 return 0;
5228
5229 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brunbaf8ffb2012-09-21 15:27:20 +02005230 smp->flags = SMP_F_MAY_CHANGE;
5231 return 0;
5232 }
5233
Willy Tarreaub363a1f2013-10-01 10:45:07 +02005234 if (!conn->xprt_ctx)
Emeric Brunbaf8ffb2012-09-21 15:27:20 +02005235 return 0;
5236
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02005237 smp->data.type = SMP_T_SINT;
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02005238 smp->data.u.sint = (long long int)SSL_get_verify_result(conn->xprt_ctx);
Emeric Brunbaf8ffb2012-09-21 15:27:20 +02005239 smp->flags = 0;
5240
5241 return 1;
5242}
5243
Emeric Brunfb510ea2012-10-05 12:00:26 +02005244/* parse the "ca-file" bind keyword */
5245static 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 +02005246{
5247 if (!*args[cur_arg + 1]) {
5248 if (err)
5249 memprintf(err, "'%s' : missing CAfile path", args[cur_arg]);
5250 return ERR_ALERT | ERR_FATAL;
5251 }
5252
Willy Tarreauef934602016-12-22 23:12:01 +01005253 if ((*args[cur_arg + 1] != '/') && global_ssl.ca_base)
5254 memprintf(&conf->ca_file, "%s/%s", global_ssl.ca_base, args[cur_arg + 1]);
Emeric Brunef42d922012-10-11 16:11:36 +02005255 else
5256 memprintf(&conf->ca_file, "%s", args[cur_arg + 1]);
Emeric Brunc8e8d122012-10-02 18:42:10 +02005257
Emeric Brund94b3fe2012-09-20 18:23:56 +02005258 return 0;
5259}
5260
Christopher Faulet31af49d2015-06-09 17:29:50 +02005261/* parse the "ca-sign-file" bind keyword */
5262static int bind_parse_ca_sign_file(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
5263{
5264 if (!*args[cur_arg + 1]) {
5265 if (err)
5266 memprintf(err, "'%s' : missing CAfile path", args[cur_arg]);
5267 return ERR_ALERT | ERR_FATAL;
5268 }
5269
Willy Tarreauef934602016-12-22 23:12:01 +01005270 if ((*args[cur_arg + 1] != '/') && global_ssl.ca_base)
5271 memprintf(&conf->ca_sign_file, "%s/%s", global_ssl.ca_base, args[cur_arg + 1]);
Christopher Faulet31af49d2015-06-09 17:29:50 +02005272 else
5273 memprintf(&conf->ca_sign_file, "%s", args[cur_arg + 1]);
5274
5275 return 0;
5276}
5277
Bertrand Jacquinff13c062016-11-13 16:37:11 +00005278/* parse the "ca-sign-pass" bind keyword */
Christopher Faulet31af49d2015-06-09 17:29:50 +02005279static int bind_parse_ca_sign_pass(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
5280{
5281 if (!*args[cur_arg + 1]) {
5282 if (err)
5283 memprintf(err, "'%s' : missing CAkey password", args[cur_arg]);
5284 return ERR_ALERT | ERR_FATAL;
5285 }
5286 memprintf(&conf->ca_sign_pass, "%s", args[cur_arg + 1]);
5287 return 0;
5288}
5289
Willy Tarreau79eeafa2012-09-14 07:53:05 +02005290/* parse the "ciphers" bind keyword */
Willy Tarreau4348fad2012-09-20 16:48:07 +02005291static 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 +02005292{
5293 if (!*args[cur_arg + 1]) {
Willy Tarreaueb6cead2012-09-20 19:43:14 +02005294 memprintf(err, "'%s' : missing cipher suite", args[cur_arg]);
Willy Tarreau79eeafa2012-09-14 07:53:05 +02005295 return ERR_ALERT | ERR_FATAL;
5296 }
5297
Emeric Brun76d88952012-10-05 15:47:31 +02005298 free(conf->ciphers);
Willy Tarreau4348fad2012-09-20 16:48:07 +02005299 conf->ciphers = strdup(args[cur_arg + 1]);
Willy Tarreau79eeafa2012-09-14 07:53:05 +02005300 return 0;
5301}
5302
5303/* parse the "crt" bind keyword */
Willy Tarreau4348fad2012-09-20 16:48:07 +02005304static 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 +02005305{
Willy Tarreau38011032013-08-13 16:59:39 +02005306 char path[MAXPATHLEN];
Willy Tarreaub75d6922014-04-14 18:05:41 +02005307
Willy Tarreau79eeafa2012-09-14 07:53:05 +02005308 if (!*args[cur_arg + 1]) {
Willy Tarreaueb6cead2012-09-20 19:43:14 +02005309 memprintf(err, "'%s' : missing certificate location", args[cur_arg]);
Willy Tarreau79eeafa2012-09-14 07:53:05 +02005310 return ERR_ALERT | ERR_FATAL;
5311 }
5312
Willy Tarreauef934602016-12-22 23:12:01 +01005313 if ((*args[cur_arg + 1] != '/' ) && global_ssl.crt_base) {
5314 if ((strlen(global_ssl.crt_base) + 1 + strlen(args[cur_arg + 1]) + 1) > MAXPATHLEN) {
Emeric Brunc8e8d122012-10-02 18:42:10 +02005315 memprintf(err, "'%s' : path too long", args[cur_arg]);
5316 return ERR_ALERT | ERR_FATAL;
5317 }
Willy Tarreauef934602016-12-22 23:12:01 +01005318 snprintf(path, sizeof(path), "%s/%s", global_ssl.crt_base, args[cur_arg + 1]);
Willy Tarreau03209342016-12-22 17:08:28 +01005319 if (ssl_sock_load_cert(path, conf, err) > 0)
Emeric Brunc8e8d122012-10-02 18:42:10 +02005320 return ERR_ALERT | ERR_FATAL;
5321
5322 return 0;
5323 }
5324
Willy Tarreau03209342016-12-22 17:08:28 +01005325 if (ssl_sock_load_cert(args[cur_arg + 1], conf, err) > 0)
Willy Tarreau79eeafa2012-09-14 07:53:05 +02005326 return ERR_ALERT | ERR_FATAL;
Emeric Brund94b3fe2012-09-20 18:23:56 +02005327
5328 return 0;
5329}
5330
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01005331/* parse the "crt-list" bind keyword */
5332static int bind_parse_crt_list(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
5333{
5334 if (!*args[cur_arg + 1]) {
5335 memprintf(err, "'%s' : missing certificate location", args[cur_arg]);
5336 return ERR_ALERT | ERR_FATAL;
5337 }
5338
Willy Tarreau03209342016-12-22 17:08:28 +01005339 if (ssl_sock_load_cert_list_file(args[cur_arg + 1], conf, err) > 0) {
Willy Tarreauad1731d2013-04-02 17:35:58 +02005340 memprintf(err, "'%s' : %s", args[cur_arg], *err);
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01005341 return ERR_ALERT | ERR_FATAL;
Willy Tarreauad1731d2013-04-02 17:35:58 +02005342 }
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01005343
5344 return 0;
5345}
5346
Emeric Brunfb510ea2012-10-05 12:00:26 +02005347/* parse the "crl-file" bind keyword */
5348static 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 +02005349{
Emeric Brun051cdab2012-10-02 19:25:50 +02005350#ifndef X509_V_FLAG_CRL_CHECK
5351 if (err)
5352 memprintf(err, "'%s' : library does not support CRL verify", args[cur_arg]);
5353 return ERR_ALERT | ERR_FATAL;
5354#else
Emeric Brund94b3fe2012-09-20 18:23:56 +02005355 if (!*args[cur_arg + 1]) {
5356 if (err)
5357 memprintf(err, "'%s' : missing CRLfile path", args[cur_arg]);
5358 return ERR_ALERT | ERR_FATAL;
5359 }
Emeric Brun2b58d042012-09-20 17:10:03 +02005360
Willy Tarreauef934602016-12-22 23:12:01 +01005361 if ((*args[cur_arg + 1] != '/') && global_ssl.ca_base)
5362 memprintf(&conf->crl_file, "%s/%s", global_ssl.ca_base, args[cur_arg + 1]);
Emeric Brunef42d922012-10-11 16:11:36 +02005363 else
5364 memprintf(&conf->crl_file, "%s", args[cur_arg + 1]);
Emeric Brunc8e8d122012-10-02 18:42:10 +02005365
Emeric Brun2b58d042012-09-20 17:10:03 +02005366 return 0;
Emeric Brun051cdab2012-10-02 19:25:50 +02005367#endif
Emeric Brun2b58d042012-09-20 17:10:03 +02005368}
5369
Bertrand Jacquinff13c062016-11-13 16:37:11 +00005370/* parse the "ecdhe" bind keyword keyword */
Emeric Brun2b58d042012-09-20 17:10:03 +02005371static int bind_parse_ecdhe(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
5372{
5373#if OPENSSL_VERSION_NUMBER < 0x0090800fL
5374 if (err)
5375 memprintf(err, "'%s' : library does not support elliptic curve Diffie-Hellman (too old)", args[cur_arg]);
5376 return ERR_ALERT | ERR_FATAL;
5377#elif defined(OPENSSL_NO_ECDH)
5378 if (err)
5379 memprintf(err, "'%s' : library does not support elliptic curve Diffie-Hellman (disabled via OPENSSL_NO_ECDH)", args[cur_arg]);
5380 return ERR_ALERT | ERR_FATAL;
5381#else
5382 if (!*args[cur_arg + 1]) {
5383 if (err)
5384 memprintf(err, "'%s' : missing named curve", args[cur_arg]);
5385 return ERR_ALERT | ERR_FATAL;
5386 }
5387
5388 conf->ecdhe = strdup(args[cur_arg + 1]);
Willy Tarreau79eeafa2012-09-14 07:53:05 +02005389
5390 return 0;
Emeric Brun2b58d042012-09-20 17:10:03 +02005391#endif
Willy Tarreau79eeafa2012-09-14 07:53:05 +02005392}
5393
Bertrand Jacquinff13c062016-11-13 16:37:11 +00005394/* parse the "crt-ignore-err" and "ca-ignore-err" bind keywords */
Emeric Brun81c00f02012-09-21 14:31:21 +02005395static int bind_parse_ignore_err(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
5396{
5397 int code;
5398 char *p = args[cur_arg + 1];
5399 unsigned long long *ignerr = &conf->crt_ignerr;
5400
5401 if (!*p) {
5402 if (err)
5403 memprintf(err, "'%s' : missing error IDs list", args[cur_arg]);
5404 return ERR_ALERT | ERR_FATAL;
5405 }
5406
5407 if (strcmp(args[cur_arg], "ca-ignore-err") == 0)
5408 ignerr = &conf->ca_ignerr;
5409
5410 if (strcmp(p, "all") == 0) {
5411 *ignerr = ~0ULL;
5412 return 0;
5413 }
5414
5415 while (p) {
5416 code = atoi(p);
5417 if ((code <= 0) || (code > 63)) {
5418 if (err)
5419 memprintf(err, "'%s' : ID '%d' out of range (1..63) in error IDs list '%s'",
5420 args[cur_arg], code, args[cur_arg + 1]);
5421 return ERR_ALERT | ERR_FATAL;
5422 }
5423 *ignerr |= 1ULL << code;
5424 p = strchr(p, ',');
5425 if (p)
5426 p++;
5427 }
5428
Emeric Brun2cb7ae52012-10-05 14:14:21 +02005429 return 0;
5430}
5431
5432/* parse the "force-sslv3" bind keyword */
5433static int bind_parse_force_sslv3(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
5434{
5435 conf->ssl_options |= BC_SSL_O_USE_SSLV3;
5436 return 0;
5437}
5438
5439/* parse the "force-tlsv10" bind keyword */
5440static int bind_parse_force_tlsv10(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
5441{
5442 conf->ssl_options |= BC_SSL_O_USE_TLSV10;
Emeric Brun2d0c4822012-10-02 13:45:20 +02005443 return 0;
5444}
5445
Emeric Brun2cb7ae52012-10-05 14:14:21 +02005446/* parse the "force-tlsv11" bind keyword */
5447static int bind_parse_force_tlsv11(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
5448{
5449#if SSL_OP_NO_TLSv1_1
5450 conf->ssl_options |= BC_SSL_O_USE_TLSV11;
5451 return 0;
5452#else
5453 if (err)
5454 memprintf(err, "'%s' : library does not support protocol TLSv1.1", args[cur_arg]);
5455 return ERR_ALERT | ERR_FATAL;
5456#endif
5457}
5458
5459/* parse the "force-tlsv12" bind keyword */
5460static int bind_parse_force_tlsv12(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
5461{
5462#if SSL_OP_NO_TLSv1_2
5463 conf->ssl_options |= BC_SSL_O_USE_TLSV12;
5464 return 0;
5465#else
5466 if (err)
5467 memprintf(err, "'%s' : library does not support protocol TLSv1.2", args[cur_arg]);
5468 return ERR_ALERT | ERR_FATAL;
5469#endif
5470}
5471
5472
Emeric Brun2d0c4822012-10-02 13:45:20 +02005473/* parse the "no-tls-tickets" bind keyword */
5474static int bind_parse_no_tls_tickets(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
5475{
Emeric Brun89675492012-10-05 13:48:26 +02005476 conf->ssl_options |= BC_SSL_O_NO_TLS_TICKETS;
Emeric Brun81c00f02012-09-21 14:31:21 +02005477 return 0;
5478}
5479
Emeric Brun2d0c4822012-10-02 13:45:20 +02005480
Emeric Brun9b3009b2012-10-05 11:55:06 +02005481/* parse the "no-sslv3" bind keyword */
5482static 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 +02005483{
Emeric Brun89675492012-10-05 13:48:26 +02005484 conf->ssl_options |= BC_SSL_O_NO_SSLV3;
Willy Tarreau79eeafa2012-09-14 07:53:05 +02005485 return 0;
5486}
5487
Emeric Brun9b3009b2012-10-05 11:55:06 +02005488/* parse the "no-tlsv10" bind keyword */
5489static 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 +02005490{
Emeric Brun89675492012-10-05 13:48:26 +02005491 conf->ssl_options |= BC_SSL_O_NO_TLSV10;
Emeric Brunc0ff4922012-09-28 19:37:02 +02005492 return 0;
5493}
5494
Emeric Brun9b3009b2012-10-05 11:55:06 +02005495/* parse the "no-tlsv11" bind keyword */
5496static 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 +02005497{
Emeric Brun89675492012-10-05 13:48:26 +02005498 conf->ssl_options |= BC_SSL_O_NO_TLSV11;
Emeric Brunc0ff4922012-09-28 19:37:02 +02005499 return 0;
5500}
5501
Emeric Brun9b3009b2012-10-05 11:55:06 +02005502/* parse the "no-tlsv12" bind keyword */
5503static 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 +02005504{
Emeric Brun89675492012-10-05 13:48:26 +02005505 conf->ssl_options |= BC_SSL_O_NO_TLSV12;
Willy Tarreau79eeafa2012-09-14 07:53:05 +02005506 return 0;
5507}
5508
Willy Tarreau6c9a3d52012-10-18 18:57:14 +02005509/* parse the "npn" bind keyword */
5510static int bind_parse_npn(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
5511{
5512#ifdef OPENSSL_NPN_NEGOTIATED
5513 char *p1, *p2;
5514
5515 if (!*args[cur_arg + 1]) {
5516 memprintf(err, "'%s' : missing the comma-delimited NPN protocol suite", args[cur_arg]);
5517 return ERR_ALERT | ERR_FATAL;
5518 }
5519
5520 free(conf->npn_str);
5521
Willy Tarreau3724da12016-02-12 17:11:12 +01005522 /* the NPN string is built as a suite of (<len> <name>)*,
5523 * so we reuse each comma to store the next <len> and need
5524 * one more for the end of the string.
5525 */
Willy Tarreau6c9a3d52012-10-18 18:57:14 +02005526 conf->npn_len = strlen(args[cur_arg + 1]) + 1;
Willy Tarreau3724da12016-02-12 17:11:12 +01005527 conf->npn_str = calloc(1, conf->npn_len + 1);
Willy Tarreau6c9a3d52012-10-18 18:57:14 +02005528 memcpy(conf->npn_str + 1, args[cur_arg + 1], conf->npn_len);
5529
5530 /* replace commas with the name length */
5531 p1 = conf->npn_str;
5532 p2 = p1 + 1;
5533 while (1) {
5534 p2 = memchr(p1 + 1, ',', conf->npn_str + conf->npn_len - (p1 + 1));
5535 if (!p2)
5536 p2 = p1 + 1 + strlen(p1 + 1);
5537
5538 if (p2 - (p1 + 1) > 255) {
5539 *p2 = '\0';
5540 memprintf(err, "'%s' : NPN protocol name too long : '%s'", args[cur_arg], p1 + 1);
5541 return ERR_ALERT | ERR_FATAL;
5542 }
5543
5544 *p1 = p2 - (p1 + 1);
5545 p1 = p2;
5546
5547 if (!*p2)
5548 break;
5549
5550 *(p2++) = '\0';
5551 }
5552 return 0;
5553#else
5554 if (err)
5555 memprintf(err, "'%s' : library does not support TLS NPN extension", args[cur_arg]);
5556 return ERR_ALERT | ERR_FATAL;
5557#endif
5558}
5559
Willy Tarreauab861d32013-04-02 02:30:41 +02005560/* parse the "alpn" bind keyword */
5561static int bind_parse_alpn(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
5562{
Dirkjan Bussink48f1c4e2014-02-13 12:29:42 +01005563#ifdef TLSEXT_TYPE_application_layer_protocol_negotiation
Willy Tarreauab861d32013-04-02 02:30:41 +02005564 char *p1, *p2;
5565
5566 if (!*args[cur_arg + 1]) {
5567 memprintf(err, "'%s' : missing the comma-delimited ALPN protocol suite", args[cur_arg]);
5568 return ERR_ALERT | ERR_FATAL;
5569 }
5570
5571 free(conf->alpn_str);
5572
Marcoen Hirschbergbef60912016-02-12 17:05:24 +01005573 /* the ALPN string is built as a suite of (<len> <name>)*,
5574 * so we reuse each comma to store the next <len> and need
5575 * one more for the end of the string.
5576 */
Willy Tarreauab861d32013-04-02 02:30:41 +02005577 conf->alpn_len = strlen(args[cur_arg + 1]) + 1;
Marcoen Hirschbergbef60912016-02-12 17:05:24 +01005578 conf->alpn_str = calloc(1, conf->alpn_len + 1);
Willy Tarreauab861d32013-04-02 02:30:41 +02005579 memcpy(conf->alpn_str + 1, args[cur_arg + 1], conf->alpn_len);
5580
5581 /* replace commas with the name length */
5582 p1 = conf->alpn_str;
5583 p2 = p1 + 1;
5584 while (1) {
5585 p2 = memchr(p1 + 1, ',', conf->alpn_str + conf->alpn_len - (p1 + 1));
5586 if (!p2)
5587 p2 = p1 + 1 + strlen(p1 + 1);
5588
5589 if (p2 - (p1 + 1) > 255) {
5590 *p2 = '\0';
5591 memprintf(err, "'%s' : ALPN protocol name too long : '%s'", args[cur_arg], p1 + 1);
5592 return ERR_ALERT | ERR_FATAL;
5593 }
5594
5595 *p1 = p2 - (p1 + 1);
5596 p1 = p2;
5597
5598 if (!*p2)
5599 break;
5600
5601 *(p2++) = '\0';
5602 }
5603 return 0;
5604#else
5605 if (err)
5606 memprintf(err, "'%s' : library does not support TLS ALPN extension", args[cur_arg]);
5607 return ERR_ALERT | ERR_FATAL;
5608#endif
5609}
5610
Willy Tarreau79eeafa2012-09-14 07:53:05 +02005611/* parse the "ssl" bind keyword */
Willy Tarreau4348fad2012-09-20 16:48:07 +02005612static 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 +02005613{
Willy Tarreau71a8c7c2016-12-21 22:04:54 +01005614 conf->xprt = &ssl_sock;
Willy Tarreau4348fad2012-09-20 16:48:07 +02005615 conf->is_ssl = 1;
Emeric Brun76d88952012-10-05 15:47:31 +02005616
Willy Tarreauef934602016-12-22 23:12:01 +01005617 if (global_ssl.listen_default_ciphers && !conf->ciphers)
5618 conf->ciphers = strdup(global_ssl.listen_default_ciphers);
5619 conf->ssl_options |= global_ssl.listen_default_ssloptions;
Emeric Brun76d88952012-10-05 15:47:31 +02005620
Willy Tarreau79eeafa2012-09-14 07:53:05 +02005621 return 0;
5622}
5623
Christopher Faulet31af49d2015-06-09 17:29:50 +02005624/* parse the "generate-certificates" bind keyword */
5625static int bind_parse_generate_certs(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
5626{
5627#ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME
5628 conf->generate_certs = 1;
5629#else
5630 memprintf(err, "%sthis version of openssl cannot generate SSL certificates.\n",
5631 err && *err ? *err : "");
5632#endif
5633 return 0;
5634}
5635
Emmanuel Hocdet65623372013-01-24 17:17:15 +01005636/* parse the "strict-sni" bind keyword */
5637static int bind_parse_strict_sni(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
5638{
5639 conf->strict_sni = 1;
5640 return 0;
Nenad Merdanovic05552d42015-02-27 19:56:49 +01005641}
5642
5643/* parse the "tls-ticket-keys" bind keyword */
5644static int bind_parse_tls_ticket_keys(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
5645{
5646#if (defined SSL_CTRL_SET_TLSEXT_TICKET_KEY_CB && TLS_TICKETS_NO > 0)
5647 FILE *f;
5648 int i = 0;
5649 char thisline[LINESIZE];
Nenad Merdanovic146defa2015-05-09 08:46:00 +02005650 struct tls_keys_ref *keys_ref;
Nenad Merdanovic05552d42015-02-27 19:56:49 +01005651
5652 if (!*args[cur_arg + 1]) {
5653 if (err)
5654 memprintf(err, "'%s' : missing TLS ticket keys file path", args[cur_arg]);
5655 return ERR_ALERT | ERR_FATAL;
5656 }
5657
Nenad Merdanovic200b0fa2015-05-09 08:46:01 +02005658 keys_ref = tlskeys_ref_lookup(args[cur_arg + 1]);
5659 if(keys_ref) {
5660 conf->keys_ref = keys_ref;
5661 return 0;
5662 }
5663
Vincent Bernat02779b62016-04-03 13:48:43 +02005664 keys_ref = malloc(sizeof(*keys_ref));
Nenad Merdanovic146defa2015-05-09 08:46:00 +02005665 keys_ref->tlskeys = malloc(TLS_TICKETS_NO * sizeof(struct tls_sess_key));
Nenad Merdanovic05552d42015-02-27 19:56:49 +01005666
5667 if ((f = fopen(args[cur_arg + 1], "r")) == NULL) {
5668 if (err)
5669 memprintf(err, "'%s' : unable to load ssl tickets keys file", args[cur_arg+1]);
5670 return ERR_ALERT | ERR_FATAL;
5671 }
5672
Nenad Merdanovic146defa2015-05-09 08:46:00 +02005673 keys_ref->filename = strdup(args[cur_arg + 1]);
5674
Nenad Merdanovic05552d42015-02-27 19:56:49 +01005675 while (fgets(thisline, sizeof(thisline), f) != NULL) {
5676 int len = strlen(thisline);
5677 /* Strip newline characters from the end */
5678 if(thisline[len - 1] == '\n')
5679 thisline[--len] = 0;
5680
5681 if(thisline[len - 1] == '\r')
5682 thisline[--len] = 0;
5683
Nenad Merdanovic146defa2015-05-09 08:46:00 +02005684 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 +01005685 if (err)
5686 memprintf(err, "'%s' : unable to decode base64 key on line %d", args[cur_arg+1], i + 1);
mildis16aa0152016-06-22 17:46:29 +02005687 fclose(f);
Nenad Merdanovic05552d42015-02-27 19:56:49 +01005688 return ERR_ALERT | ERR_FATAL;
5689 }
5690 i++;
5691 }
5692
5693 if (i < TLS_TICKETS_NO) {
5694 if (err)
5695 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 +02005696 fclose(f);
Nenad Merdanovic05552d42015-02-27 19:56:49 +01005697 return ERR_ALERT | ERR_FATAL;
5698 }
5699
5700 fclose(f);
5701
5702 /* Use penultimate key for encryption, handle when TLS_TICKETS_NO = 1 */
Nenad Merdanovic17891152016-03-25 22:16:57 +01005703 i -= 2;
5704 keys_ref->tls_ticket_enc_index = i < 0 ? 0 : i % TLS_TICKETS_NO;
Nenad Merdanovic200b0fa2015-05-09 08:46:01 +02005705 keys_ref->unique_id = -1;
Nenad Merdanovic146defa2015-05-09 08:46:00 +02005706 conf->keys_ref = keys_ref;
Nenad Merdanovic05552d42015-02-27 19:56:49 +01005707
Nenad Merdanovic200b0fa2015-05-09 08:46:01 +02005708 LIST_ADD(&tlskeys_reference, &keys_ref->list);
5709
Nenad Merdanovic05552d42015-02-27 19:56:49 +01005710 return 0;
5711#else
5712 if (err)
5713 memprintf(err, "'%s' : TLS ticket callback extension not supported", args[cur_arg]);
5714 return ERR_ALERT | ERR_FATAL;
5715#endif /* SSL_CTRL_SET_TLSEXT_TICKET_KEY_CB */
Emmanuel Hocdet65623372013-01-24 17:17:15 +01005716}
5717
Emeric Brund94b3fe2012-09-20 18:23:56 +02005718/* parse the "verify" bind keyword */
5719static int bind_parse_verify(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
5720{
5721 if (!*args[cur_arg + 1]) {
5722 if (err)
5723 memprintf(err, "'%s' : missing verify method", args[cur_arg]);
5724 return ERR_ALERT | ERR_FATAL;
5725 }
5726
5727 if (strcmp(args[cur_arg + 1], "none") == 0)
Emeric Brun850efd52014-01-29 12:24:34 +01005728 conf->verify = SSL_SOCK_VERIFY_NONE;
Emeric Brund94b3fe2012-09-20 18:23:56 +02005729 else if (strcmp(args[cur_arg + 1], "optional") == 0)
Emeric Brun850efd52014-01-29 12:24:34 +01005730 conf->verify = SSL_SOCK_VERIFY_OPTIONAL;
Emeric Brund94b3fe2012-09-20 18:23:56 +02005731 else if (strcmp(args[cur_arg + 1], "required") == 0)
Emeric Brun850efd52014-01-29 12:24:34 +01005732 conf->verify = SSL_SOCK_VERIFY_REQUIRED;
Emeric Brund94b3fe2012-09-20 18:23:56 +02005733 else {
5734 if (err)
5735 memprintf(err, "'%s' : unknown verify method '%s', only 'none', 'optional', and 'required' are supported\n",
5736 args[cur_arg], args[cur_arg + 1]);
5737 return ERR_ALERT | ERR_FATAL;
5738 }
5739
5740 return 0;
5741}
5742
Willy Tarreau92faadf2012-10-10 23:04:25 +02005743/************** "server" keywords ****************/
5744
Emeric Brunef42d922012-10-11 16:11:36 +02005745/* parse the "ca-file" server keyword */
5746static int srv_parse_ca_file(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
5747{
5748 if (!*args[*cur_arg + 1]) {
5749 if (err)
5750 memprintf(err, "'%s' : missing CAfile path", args[*cur_arg]);
5751 return ERR_ALERT | ERR_FATAL;
5752 }
5753
Willy Tarreauef934602016-12-22 23:12:01 +01005754 if ((*args[*cur_arg + 1] != '/') && global_ssl.ca_base)
5755 memprintf(&newsrv->ssl_ctx.ca_file, "%s/%s", global_ssl.ca_base, args[*cur_arg + 1]);
Emeric Brunef42d922012-10-11 16:11:36 +02005756 else
5757 memprintf(&newsrv->ssl_ctx.ca_file, "%s", args[*cur_arg + 1]);
5758
5759 return 0;
5760}
5761
Willy Tarreau92faadf2012-10-10 23:04:25 +02005762/* parse the "check-ssl" server keyword */
5763static int srv_parse_check_ssl(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
5764{
5765 newsrv->check.use_ssl = 1;
Willy Tarreauef934602016-12-22 23:12:01 +01005766 if (global_ssl.connect_default_ciphers && !newsrv->ssl_ctx.ciphers)
5767 newsrv->ssl_ctx.ciphers = strdup(global_ssl.connect_default_ciphers);
5768 newsrv->ssl_ctx.options |= global_ssl.connect_default_ssloptions;
Willy Tarreau92faadf2012-10-10 23:04:25 +02005769 return 0;
5770}
5771
5772/* parse the "ciphers" server keyword */
5773static int srv_parse_ciphers(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
5774{
5775 if (!*args[*cur_arg + 1]) {
5776 memprintf(err, "'%s' : missing cipher suite", args[*cur_arg]);
5777 return ERR_ALERT | ERR_FATAL;
5778 }
5779
5780 free(newsrv->ssl_ctx.ciphers);
5781 newsrv->ssl_ctx.ciphers = strdup(args[*cur_arg + 1]);
5782 return 0;
5783}
5784
Emeric Brunef42d922012-10-11 16:11:36 +02005785/* parse the "crl-file" server keyword */
5786static int srv_parse_crl_file(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
5787{
5788#ifndef X509_V_FLAG_CRL_CHECK
5789 if (err)
5790 memprintf(err, "'%s' : library does not support CRL verify", args[*cur_arg]);
5791 return ERR_ALERT | ERR_FATAL;
5792#else
5793 if (!*args[*cur_arg + 1]) {
5794 if (err)
5795 memprintf(err, "'%s' : missing CRLfile path", args[*cur_arg]);
5796 return ERR_ALERT | ERR_FATAL;
5797 }
5798
Willy Tarreauef934602016-12-22 23:12:01 +01005799 if ((*args[*cur_arg + 1] != '/') && global_ssl.ca_base)
5800 memprintf(&newsrv->ssl_ctx.crl_file, "%s/%s", global_ssl.ca_base, args[*cur_arg + 1]);
Emeric Brunef42d922012-10-11 16:11:36 +02005801 else
5802 memprintf(&newsrv->ssl_ctx.crl_file, "%s", args[*cur_arg + 1]);
5803
5804 return 0;
5805#endif
5806}
5807
Emeric Bruna7aa3092012-10-26 12:58:00 +02005808/* parse the "crt" server keyword */
5809static int srv_parse_crt(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
5810{
5811 if (!*args[*cur_arg + 1]) {
5812 if (err)
5813 memprintf(err, "'%s' : missing certificate file path", args[*cur_arg]);
5814 return ERR_ALERT | ERR_FATAL;
5815 }
5816
Willy Tarreauef934602016-12-22 23:12:01 +01005817 if ((*args[*cur_arg + 1] != '/') && global_ssl.crt_base)
5818 memprintf(&newsrv->ssl_ctx.client_crt, "%s/%s", global_ssl.ca_base, args[*cur_arg + 1]);
Emeric Bruna7aa3092012-10-26 12:58:00 +02005819 else
5820 memprintf(&newsrv->ssl_ctx.client_crt, "%s", args[*cur_arg + 1]);
5821
5822 return 0;
5823}
Emeric Brunef42d922012-10-11 16:11:36 +02005824
Willy Tarreau92faadf2012-10-10 23:04:25 +02005825/* parse the "force-sslv3" server keyword */
5826static int srv_parse_force_sslv3(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
5827{
5828 newsrv->ssl_ctx.options |= SRV_SSL_O_USE_SSLV3;
5829 return 0;
5830}
5831
5832/* parse the "force-tlsv10" server keyword */
5833static int srv_parse_force_tlsv10(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
5834{
5835 newsrv->ssl_ctx.options |= SRV_SSL_O_USE_TLSV10;
5836 return 0;
5837}
5838
5839/* parse the "force-tlsv11" server keyword */
5840static int srv_parse_force_tlsv11(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
5841{
5842#if SSL_OP_NO_TLSv1_1
5843 newsrv->ssl_ctx.options |= SRV_SSL_O_USE_TLSV11;
5844 return 0;
5845#else
5846 if (err)
5847 memprintf(err, "'%s' : library does not support protocol TLSv1.1", args[*cur_arg]);
5848 return ERR_ALERT | ERR_FATAL;
5849#endif
5850}
5851
5852/* parse the "force-tlsv12" server keyword */
5853static int srv_parse_force_tlsv12(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
5854{
5855#if SSL_OP_NO_TLSv1_2
5856 newsrv->ssl_ctx.options |= SRV_SSL_O_USE_TLSV12;
5857 return 0;
5858#else
5859 if (err)
5860 memprintf(err, "'%s' : library does not support protocol TLSv1.2", args[*cur_arg]);
5861 return ERR_ALERT | ERR_FATAL;
5862#endif
5863}
5864
Willy Tarreau2a3fb1c2015-02-05 16:47:07 +01005865/* parse the "no-ssl-reuse" server keyword */
5866static int srv_parse_no_ssl_reuse(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
5867{
5868 newsrv->ssl_ctx.options |= SRV_SSL_O_NO_REUSE;
5869 return 0;
5870}
5871
Willy Tarreau92faadf2012-10-10 23:04:25 +02005872/* parse the "no-sslv3" server keyword */
5873static int srv_parse_no_sslv3(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
5874{
5875 newsrv->ssl_ctx.options |= SRV_SSL_O_NO_SSLV3;
5876 return 0;
5877}
5878
5879/* parse the "no-tlsv10" server keyword */
5880static int srv_parse_no_tlsv10(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
5881{
5882 newsrv->ssl_ctx.options |= SRV_SSL_O_NO_TLSV10;
5883 return 0;
5884}
5885
5886/* parse the "no-tlsv11" server keyword */
5887static int srv_parse_no_tlsv11(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
5888{
5889 newsrv->ssl_ctx.options |= SRV_SSL_O_NO_TLSV11;
5890 return 0;
5891}
5892
5893/* parse the "no-tlsv12" server keyword */
5894static int srv_parse_no_tlsv12(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
5895{
5896 newsrv->ssl_ctx.options |= SRV_SSL_O_NO_TLSV12;
5897 return 0;
5898}
5899
Emeric Brunf9c5c472012-10-11 15:28:34 +02005900/* parse the "no-tls-tickets" server keyword */
5901static int srv_parse_no_tls_tickets(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
5902{
5903 newsrv->ssl_ctx.options |= SRV_SSL_O_NO_TLS_TICKETS;
5904 return 0;
5905}
David Safb76832014-05-08 23:42:08 -04005906/* parse the "send-proxy-v2-ssl" server keyword */
5907static int srv_parse_send_proxy_ssl(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
5908{
5909 newsrv->pp_opts |= SRV_PP_V2;
5910 newsrv->pp_opts |= SRV_PP_V2_SSL;
5911 return 0;
5912}
5913
5914/* parse the "send-proxy-v2-ssl-cn" server keyword */
5915static int srv_parse_send_proxy_cn(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
5916{
5917 newsrv->pp_opts |= SRV_PP_V2;
5918 newsrv->pp_opts |= SRV_PP_V2_SSL;
5919 newsrv->pp_opts |= SRV_PP_V2_SSL_CN;
5920 return 0;
5921}
Emeric Brunf9c5c472012-10-11 15:28:34 +02005922
Willy Tarreau732eac42015-07-09 11:40:25 +02005923/* parse the "sni" server keyword */
5924static int srv_parse_sni(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
5925{
5926#ifndef SSL_CTRL_SET_TLSEXT_HOSTNAME
5927 memprintf(err, "'%s' : the current SSL library doesn't support the SNI TLS extension", args[*cur_arg]);
5928 return ERR_ALERT | ERR_FATAL;
5929#else
Cyril Bonté23d19d62016-03-07 22:13:22 +01005930 int idx;
Willy Tarreau732eac42015-07-09 11:40:25 +02005931 struct sample_expr *expr;
5932
5933 if (!*args[*cur_arg + 1]) {
5934 memprintf(err, "'%s' : missing sni expression", args[*cur_arg]);
5935 return ERR_ALERT | ERR_FATAL;
5936 }
5937
Cyril Bonté23d19d62016-03-07 22:13:22 +01005938 idx = (*cur_arg) + 1;
Willy Tarreau732eac42015-07-09 11:40:25 +02005939 proxy->conf.args.ctx = ARGC_SRV;
5940
Cyril Bonté23d19d62016-03-07 22:13:22 +01005941 expr = sample_parse_expr((char **)args, &idx, px->conf.file, px->conf.line, err, &proxy->conf.args);
Willy Tarreau732eac42015-07-09 11:40:25 +02005942 if (!expr) {
5943 memprintf(err, "error detected while parsing sni expression : %s", *err);
5944 return ERR_ALERT | ERR_FATAL;
5945 }
5946
5947 if (!(expr->fetch->val & SMP_VAL_BE_SRV_CON)) {
5948 memprintf(err, "error detected while parsing sni expression : "
5949 " fetch method '%s' extracts information from '%s', none of which is available here.\n",
Cyril Bonté23d19d62016-03-07 22:13:22 +01005950 args[idx-1], sample_src_names(expr->fetch->use));
Willy Tarreau732eac42015-07-09 11:40:25 +02005951 return ERR_ALERT | ERR_FATAL;
5952 }
5953
5954 px->http_needed |= !!(expr->fetch->use & SMP_USE_HTTP_ANY);
5955 newsrv->ssl_ctx.sni = expr;
5956 return 0;
5957#endif
5958}
5959
Willy Tarreau92faadf2012-10-10 23:04:25 +02005960/* parse the "ssl" server keyword */
5961static int srv_parse_ssl(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
5962{
5963 newsrv->use_ssl = 1;
Willy Tarreauef934602016-12-22 23:12:01 +01005964 if (global_ssl.connect_default_ciphers && !newsrv->ssl_ctx.ciphers)
5965 newsrv->ssl_ctx.ciphers = strdup(global_ssl.connect_default_ciphers);
Willy Tarreau92faadf2012-10-10 23:04:25 +02005966 return 0;
5967}
5968
Emeric Brunef42d922012-10-11 16:11:36 +02005969/* parse the "verify" server keyword */
5970static int srv_parse_verify(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
5971{
5972 if (!*args[*cur_arg + 1]) {
5973 if (err)
5974 memprintf(err, "'%s' : missing verify method", args[*cur_arg]);
5975 return ERR_ALERT | ERR_FATAL;
5976 }
5977
5978 if (strcmp(args[*cur_arg + 1], "none") == 0)
Emeric Brun850efd52014-01-29 12:24:34 +01005979 newsrv->ssl_ctx.verify = SSL_SOCK_VERIFY_NONE;
Emeric Brunef42d922012-10-11 16:11:36 +02005980 else if (strcmp(args[*cur_arg + 1], "required") == 0)
Emeric Brun850efd52014-01-29 12:24:34 +01005981 newsrv->ssl_ctx.verify = SSL_SOCK_VERIFY_REQUIRED;
Emeric Brunef42d922012-10-11 16:11:36 +02005982 else {
5983 if (err)
5984 memprintf(err, "'%s' : unknown verify method '%s', only 'none' and 'required' are supported\n",
5985 args[*cur_arg], args[*cur_arg + 1]);
5986 return ERR_ALERT | ERR_FATAL;
5987 }
5988
Evan Broderbe554312013-06-27 00:05:25 -07005989 return 0;
5990}
5991
5992/* parse the "verifyhost" server keyword */
5993static int srv_parse_verifyhost(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
5994{
5995 if (!*args[*cur_arg + 1]) {
5996 if (err)
5997 memprintf(err, "'%s' : missing hostname to verify against", args[*cur_arg]);
5998 return ERR_ALERT | ERR_FATAL;
5999 }
6000
6001 newsrv->ssl_ctx.verify_host = strdup(args[*cur_arg + 1]);
6002
Emeric Brunef42d922012-10-11 16:11:36 +02006003 return 0;
6004}
6005
Emeric Brun2c86cbf2014-10-30 15:56:50 +01006006/* parse the "ssl-default-bind-options" keyword in global section */
6007static int ssl_parse_default_bind_options(char **args, int section_type, struct proxy *curpx,
6008 struct proxy *defpx, const char *file, int line,
6009 char **err) {
6010 int i = 1;
6011
6012 if (*(args[i]) == 0) {
6013 memprintf(err, "global statement '%s' expects an option as an argument.", args[0]);
6014 return -1;
6015 }
6016 while (*(args[i])) {
6017 if (!strcmp(args[i], "no-sslv3"))
Willy Tarreauef934602016-12-22 23:12:01 +01006018 global_ssl.listen_default_ssloptions |= BC_SSL_O_NO_SSLV3;
Emeric Brun2c86cbf2014-10-30 15:56:50 +01006019 else if (!strcmp(args[i], "no-tlsv10"))
Willy Tarreauef934602016-12-22 23:12:01 +01006020 global_ssl.listen_default_ssloptions |= BC_SSL_O_NO_TLSV10;
Emeric Brun2c86cbf2014-10-30 15:56:50 +01006021 else if (!strcmp(args[i], "no-tlsv11"))
Willy Tarreauef934602016-12-22 23:12:01 +01006022 global_ssl.listen_default_ssloptions |= BC_SSL_O_NO_TLSV11;
Emeric Brun2c86cbf2014-10-30 15:56:50 +01006023 else if (!strcmp(args[i], "no-tlsv12"))
Willy Tarreauef934602016-12-22 23:12:01 +01006024 global_ssl.listen_default_ssloptions |= BC_SSL_O_NO_TLSV12;
Emeric Brun2c86cbf2014-10-30 15:56:50 +01006025 else if (!strcmp(args[i], "force-sslv3"))
Willy Tarreauef934602016-12-22 23:12:01 +01006026 global_ssl.listen_default_ssloptions |= BC_SSL_O_USE_SSLV3;
Emeric Brun2c86cbf2014-10-30 15:56:50 +01006027 else if (!strcmp(args[i], "force-tlsv10"))
Willy Tarreauef934602016-12-22 23:12:01 +01006028 global_ssl.listen_default_ssloptions |= BC_SSL_O_USE_TLSV10;
Emeric Brun2c86cbf2014-10-30 15:56:50 +01006029 else if (!strcmp(args[i], "force-tlsv11")) {
6030#if SSL_OP_NO_TLSv1_1
Willy Tarreauef934602016-12-22 23:12:01 +01006031 global_ssl.listen_default_ssloptions |= BC_SSL_O_USE_TLSV11;
Emeric Brun2c86cbf2014-10-30 15:56:50 +01006032#else
6033 memprintf(err, "'%s' '%s': library does not support protocol TLSv1.1", args[0], args[i]);
6034 return -1;
6035#endif
6036 }
6037 else if (!strcmp(args[i], "force-tlsv12")) {
6038#if SSL_OP_NO_TLSv1_2
Willy Tarreauef934602016-12-22 23:12:01 +01006039 global_ssl.listen_default_ssloptions |= BC_SSL_O_USE_TLSV12;
Emeric Brun2c86cbf2014-10-30 15:56:50 +01006040#else
6041 memprintf(err, "'%s' '%s': library does not support protocol TLSv1.2", args[0], args[i]);
6042 return -1;
6043#endif
6044 }
6045 else if (!strcmp(args[i], "no-tls-tickets"))
Willy Tarreauef934602016-12-22 23:12:01 +01006046 global_ssl.listen_default_ssloptions |= BC_SSL_O_NO_TLS_TICKETS;
Emeric Brun2c86cbf2014-10-30 15:56:50 +01006047 else {
6048 memprintf(err, "unknown option '%s' on global statement '%s'.", args[i], args[0]);
6049 return -1;
6050 }
6051 i++;
6052 }
6053 return 0;
6054}
6055
6056/* parse the "ssl-default-server-options" keyword in global section */
6057static int ssl_parse_default_server_options(char **args, int section_type, struct proxy *curpx,
6058 struct proxy *defpx, const char *file, int line,
6059 char **err) {
6060 int i = 1;
6061
6062 if (*(args[i]) == 0) {
6063 memprintf(err, "global statement '%s' expects an option as an argument.", args[0]);
6064 return -1;
6065 }
6066 while (*(args[i])) {
6067 if (!strcmp(args[i], "no-sslv3"))
Willy Tarreauef934602016-12-22 23:12:01 +01006068 global_ssl.connect_default_ssloptions |= SRV_SSL_O_NO_SSLV3;
Emeric Brun2c86cbf2014-10-30 15:56:50 +01006069 else if (!strcmp(args[i], "no-tlsv10"))
Willy Tarreauef934602016-12-22 23:12:01 +01006070 global_ssl.connect_default_ssloptions |= SRV_SSL_O_NO_TLSV10;
Emeric Brun2c86cbf2014-10-30 15:56:50 +01006071 else if (!strcmp(args[i], "no-tlsv11"))
Willy Tarreauef934602016-12-22 23:12:01 +01006072 global_ssl.connect_default_ssloptions |= SRV_SSL_O_NO_TLSV11;
Emeric Brun2c86cbf2014-10-30 15:56:50 +01006073 else if (!strcmp(args[i], "no-tlsv12"))
Willy Tarreauef934602016-12-22 23:12:01 +01006074 global_ssl.connect_default_ssloptions |= SRV_SSL_O_NO_TLSV12;
Emeric Brun2c86cbf2014-10-30 15:56:50 +01006075 else if (!strcmp(args[i], "force-sslv3"))
Willy Tarreauef934602016-12-22 23:12:01 +01006076 global_ssl.connect_default_ssloptions |= SRV_SSL_O_USE_SSLV3;
Emeric Brun2c86cbf2014-10-30 15:56:50 +01006077 else if (!strcmp(args[i], "force-tlsv10"))
Willy Tarreauef934602016-12-22 23:12:01 +01006078 global_ssl.connect_default_ssloptions |= SRV_SSL_O_USE_TLSV10;
Emeric Brun2c86cbf2014-10-30 15:56:50 +01006079 else if (!strcmp(args[i], "force-tlsv11")) {
6080#if SSL_OP_NO_TLSv1_1
Willy Tarreauef934602016-12-22 23:12:01 +01006081 global_ssl.connect_default_ssloptions |= SRV_SSL_O_USE_TLSV11;
Emeric Brun2c86cbf2014-10-30 15:56:50 +01006082#else
6083 memprintf(err, "'%s' '%s': library does not support protocol TLSv1.1", args[0], args[i]);
6084 return -1;
6085#endif
6086 }
6087 else if (!strcmp(args[i], "force-tlsv12")) {
6088#if SSL_OP_NO_TLSv1_2
Willy Tarreauef934602016-12-22 23:12:01 +01006089 global_ssl.connect_default_ssloptions |= SRV_SSL_O_USE_TLSV12;
Emeric Brun2c86cbf2014-10-30 15:56:50 +01006090#else
6091 memprintf(err, "'%s' '%s': library does not support protocol TLSv1.2", args[0], args[i]);
6092 return -1;
6093#endif
6094 }
6095 else if (!strcmp(args[i], "no-tls-tickets"))
Willy Tarreauef934602016-12-22 23:12:01 +01006096 global_ssl.connect_default_ssloptions |= SRV_SSL_O_NO_TLS_TICKETS;
Emeric Brun2c86cbf2014-10-30 15:56:50 +01006097 else {
6098 memprintf(err, "unknown option '%s' on global statement '%s'.", args[i], args[0]);
6099 return -1;
6100 }
6101 i++;
6102 }
6103 return 0;
6104}
6105
Willy Tarreau8c3b0fd2016-12-21 22:44:46 +01006106/* parse the "ca-base" / "crt-base" keywords in global section.
6107 * Returns <0 on alert, >0 on warning, 0 on success.
6108 */
6109static int ssl_parse_global_ca_crt_base(char **args, int section_type, struct proxy *curpx,
6110 struct proxy *defpx, const char *file, int line,
6111 char **err)
6112{
6113 char **target;
6114
Willy Tarreauef934602016-12-22 23:12:01 +01006115 target = (args[0][1] == 'a') ? &global_ssl.ca_base : &global_ssl.crt_base;
Willy Tarreau8c3b0fd2016-12-21 22:44:46 +01006116
6117 if (too_many_args(1, args, err, NULL))
6118 return -1;
6119
6120 if (*target) {
6121 memprintf(err, "'%s' already specified.", args[0]);
6122 return -1;
6123 }
6124
6125 if (*(args[1]) == 0) {
6126 memprintf(err, "global statement '%s' expects a directory path as an argument.", args[0]);
6127 return -1;
6128 }
6129 *target = strdup(args[1]);
6130 return 0;
6131}
6132
Willy Tarreauf22e9682016-12-21 23:23:19 +01006133/* parse the "ssl-default-bind-ciphers" / "ssl-default-server-ciphers" keywords
6134 * in global section. Returns <0 on alert, >0 on warning, 0 on success.
6135 */
6136static int ssl_parse_global_ciphers(char **args, int section_type, struct proxy *curpx,
6137 struct proxy *defpx, const char *file, int line,
6138 char **err)
6139{
6140 char **target;
6141
Willy Tarreauef934602016-12-22 23:12:01 +01006142 target = (args[0][12] == 'b') ? &global_ssl.listen_default_ciphers : &global_ssl.connect_default_ciphers;
Willy Tarreauf22e9682016-12-21 23:23:19 +01006143
6144 if (too_many_args(1, args, err, NULL))
6145 return -1;
6146
6147 if (*(args[1]) == 0) {
6148 memprintf(err, "global statement '%s' expects a cipher suite as an argument.", args[0]);
6149 return -1;
6150 }
6151
6152 free(*target);
6153 *target = strdup(args[1]);
6154 return 0;
6155}
6156
Willy Tarreau9ceda382016-12-21 23:13:03 +01006157/* parse various global tune.ssl settings consisting in positive integers.
6158 * Returns <0 on alert, >0 on warning, 0 on success.
6159 */
6160static int ssl_parse_global_int(char **args, int section_type, struct proxy *curpx,
6161 struct proxy *defpx, const char *file, int line,
6162 char **err)
6163{
6164 int *target;
6165
6166 if (strcmp(args[0], "tune.ssl.cachesize") == 0)
6167 target = &global.tune.sslcachesize;
6168 else if (strcmp(args[0], "tune.ssl.maxrecord") == 0)
Willy Tarreauef934602016-12-22 23:12:01 +01006169 target = (int *)&global_ssl.max_record;
Willy Tarreau9ceda382016-12-21 23:13:03 +01006170 else if (strcmp(args[0], "tune.ssl.ssl-ctx-cache-size") == 0)
Willy Tarreauef934602016-12-22 23:12:01 +01006171 target = &global_ssl.ctx_cache;
Willy Tarreau0bea58d2016-12-21 23:17:25 +01006172 else if (strcmp(args[0], "maxsslconn") == 0)
6173 target = &global.maxsslconn;
Willy Tarreau9ceda382016-12-21 23:13:03 +01006174 else {
6175 memprintf(err, "'%s' keyword not unhandled (please report this bug).", args[0]);
6176 return -1;
6177 }
6178
6179 if (too_many_args(1, args, err, NULL))
6180 return -1;
6181
6182 if (*(args[1]) == 0) {
6183 memprintf(err, "'%s' expects an integer argument.", args[0]);
6184 return -1;
6185 }
6186
6187 *target = atoi(args[1]);
6188 if (*target < 0) {
6189 memprintf(err, "'%s' expects a positive numeric value.", args[0]);
6190 return -1;
6191 }
6192 return 0;
6193}
6194
6195/* parse "ssl.force-private-cache".
6196 * Returns <0 on alert, >0 on warning, 0 on success.
6197 */
6198static int ssl_parse_global_private_cache(char **args, int section_type, struct proxy *curpx,
6199 struct proxy *defpx, const char *file, int line,
6200 char **err)
6201{
6202 if (too_many_args(0, args, err, NULL))
6203 return -1;
6204
Willy Tarreauef934602016-12-22 23:12:01 +01006205 global_ssl.private_cache = 1;
Willy Tarreau9ceda382016-12-21 23:13:03 +01006206 return 0;
6207}
6208
6209/* parse "ssl.lifetime".
6210 * Returns <0 on alert, >0 on warning, 0 on success.
6211 */
6212static int ssl_parse_global_lifetime(char **args, int section_type, struct proxy *curpx,
6213 struct proxy *defpx, const char *file, int line,
6214 char **err)
6215{
6216 const char *res;
6217
6218 if (too_many_args(1, args, err, NULL))
6219 return -1;
6220
6221 if (*(args[1]) == 0) {
6222 memprintf(err, "'%s' expects ssl sessions <lifetime> in seconds as argument.", args[0]);
6223 return -1;
6224 }
6225
Willy Tarreauef934602016-12-22 23:12:01 +01006226 res = parse_time_err(args[1], &global_ssl.life_time, TIME_UNIT_S);
Willy Tarreau9ceda382016-12-21 23:13:03 +01006227 if (res) {
6228 memprintf(err, "unexpected character '%c' in argument to <%s>.", *res, args[0]);
6229 return -1;
6230 }
6231 return 0;
6232}
6233
6234#ifndef OPENSSL_NO_DH
Willy Tarreau14e36a12016-12-21 23:28:13 +01006235/* parse "ssl-dh-param-file".
6236 * Returns <0 on alert, >0 on warning, 0 on success.
6237 */
6238static int ssl_parse_global_dh_param_file(char **args, int section_type, struct proxy *curpx,
6239 struct proxy *defpx, const char *file, int line,
6240 char **err)
6241{
6242 if (too_many_args(1, args, err, NULL))
6243 return -1;
6244
6245 if (*(args[1]) == 0) {
6246 memprintf(err, "'%s' expects a file path as an argument.", args[0]);
6247 return -1;
6248 }
6249
6250 if (ssl_sock_load_global_dh_param_from_file(args[1])) {
6251 memprintf(err, "'%s': unable to load DH parameters from file <%s>.", args[0], args[1]);
6252 return -1;
6253 }
6254 return 0;
6255}
6256
Willy Tarreau9ceda382016-12-21 23:13:03 +01006257/* parse "ssl.default-dh-param".
6258 * Returns <0 on alert, >0 on warning, 0 on success.
6259 */
6260static int ssl_parse_global_default_dh(char **args, int section_type, struct proxy *curpx,
6261 struct proxy *defpx, const char *file, int line,
6262 char **err)
6263{
6264 if (too_many_args(1, args, err, NULL))
6265 return -1;
6266
6267 if (*(args[1]) == 0) {
6268 memprintf(err, "'%s' expects an integer argument.", args[0]);
6269 return -1;
6270 }
6271
Willy Tarreauef934602016-12-22 23:12:01 +01006272 global_ssl.default_dh_param = atoi(args[1]);
6273 if (global_ssl.default_dh_param < 1024) {
Willy Tarreau9ceda382016-12-21 23:13:03 +01006274 memprintf(err, "'%s' expects a value >= 1024.", args[0]);
6275 return -1;
6276 }
6277 return 0;
6278}
6279#endif
6280
6281
William Lallemand32af2032016-10-29 18:09:35 +02006282/* This function is used with TLS ticket keys management. It permits to browse
6283 * each reference. The variable <getnext> must contain the current node,
6284 * <end> point to the root node.
6285 */
6286#if (defined SSL_CTRL_SET_TLSEXT_TICKET_KEY_CB && TLS_TICKETS_NO > 0)
6287static inline
6288struct tls_keys_ref *tlskeys_list_get_next(struct tls_keys_ref *getnext, struct list *end)
6289{
6290 struct tls_keys_ref *ref = getnext;
6291
6292 while (1) {
6293
6294 /* Get next list entry. */
6295 ref = LIST_NEXT(&ref->list, struct tls_keys_ref *, list);
6296
6297 /* If the entry is the last of the list, return NULL. */
6298 if (&ref->list == end)
6299 return NULL;
6300
6301 return ref;
6302 }
6303}
6304
6305static inline
6306struct tls_keys_ref *tlskeys_ref_lookup_ref(const char *reference)
6307{
6308 int id;
6309 char *error;
6310
6311 /* If the reference starts by a '#', this is numeric id. */
6312 if (reference[0] == '#') {
6313 /* Try to convert the numeric id. If the conversion fails, the lookup fails. */
6314 id = strtol(reference + 1, &error, 10);
6315 if (*error != '\0')
6316 return NULL;
6317
6318 /* Perform the unique id lookup. */
6319 return tlskeys_ref_lookupid(id);
6320 }
6321
6322 /* Perform the string lookup. */
6323 return tlskeys_ref_lookup(reference);
6324}
6325#endif
6326
6327
6328#if (defined SSL_CTRL_SET_TLSEXT_TICKET_KEY_CB && TLS_TICKETS_NO > 0)
6329
6330static int cli_io_handler_tlskeys_files(struct appctx *appctx);
6331
6332static inline int cli_io_handler_tlskeys_entries(struct appctx *appctx) {
6333 return cli_io_handler_tlskeys_files(appctx);
6334}
6335
Willy Tarreauf5f26e82016-12-16 18:47:27 +01006336/* dumps all tls keys. Relies on cli.i0 (non-null = only list file names), cli.i1
6337 * (next index to be dumped), and cli.p0 (next key reference).
6338 */
William Lallemand32af2032016-10-29 18:09:35 +02006339static int cli_io_handler_tlskeys_files(struct appctx *appctx) {
6340
6341 struct stream_interface *si = appctx->owner;
6342
6343 switch (appctx->st2) {
6344 case STAT_ST_INIT:
6345 /* Display the column headers. If the message cannot be sent,
6346 * quit the fucntion with returning 0. The function is called
6347 * later and restart at the state "STAT_ST_INIT".
6348 */
6349 chunk_reset(&trash);
6350
6351 if (appctx->io_handler == cli_io_handler_tlskeys_entries)
6352 chunk_appendf(&trash, "# id secret\n");
6353 else
6354 chunk_appendf(&trash, "# id (file)\n");
6355
6356 if (bi_putchk(si_ic(si), &trash) == -1) {
6357 si_applet_cant_put(si);
6358 return 0;
6359 }
6360
William Lallemand32af2032016-10-29 18:09:35 +02006361 /* Now, we start the browsing of the references lists.
6362 * Note that the following call to LIST_ELEM return bad pointer. The only
6363 * available field of this pointer is <list>. It is used with the function
6364 * tlskeys_list_get_next() for retruning the first available entry
6365 */
Willy Tarreauf5f26e82016-12-16 18:47:27 +01006366 if (appctx->ctx.cli.p0 == NULL) {
6367 appctx->ctx.cli.p0 = LIST_ELEM(&tlskeys_reference, struct tls_keys_ref *, list);
6368 appctx->ctx.cli.p0 = tlskeys_list_get_next(appctx->ctx.cli.p0, &tlskeys_reference);
William Lallemand32af2032016-10-29 18:09:35 +02006369 }
6370
6371 appctx->st2 = STAT_ST_LIST;
6372 /* fall through */
6373
6374 case STAT_ST_LIST:
Willy Tarreauf5f26e82016-12-16 18:47:27 +01006375 while (appctx->ctx.cli.p0) {
6376 struct tls_keys_ref *ref = appctx->ctx.cli.p0;
6377 int head = ref->tls_ticket_enc_index;
William Lallemand32af2032016-10-29 18:09:35 +02006378
6379 chunk_reset(&trash);
Willy Tarreauf5f26e82016-12-16 18:47:27 +01006380 if (appctx->io_handler == cli_io_handler_tlskeys_entries && appctx->ctx.cli.i1 == 0)
William Lallemand32af2032016-10-29 18:09:35 +02006381 chunk_appendf(&trash, "# ");
Willy Tarreauf5f26e82016-12-16 18:47:27 +01006382
6383 if (appctx->ctx.cli.i1 == 0)
6384 chunk_appendf(&trash, "%d (%s)\n", ref->unique_id, ref->filename);
6385
William Lallemand32af2032016-10-29 18:09:35 +02006386 if (appctx->io_handler == cli_io_handler_tlskeys_entries) {
Willy Tarreauf5f26e82016-12-16 18:47:27 +01006387 while (appctx->ctx.cli.i1 < TLS_TICKETS_NO) {
William Lallemand32af2032016-10-29 18:09:35 +02006388 struct chunk *t2 = get_trash_chunk();
6389
6390 chunk_reset(t2);
6391 /* should never fail here because we dump only a key in the t2 buffer */
Willy Tarreauf5f26e82016-12-16 18:47:27 +01006392 t2->len = a2base64((char *)(ref->tlskeys + (head + 2 + appctx->ctx.cli.i1) % TLS_TICKETS_NO),
William Lallemand32af2032016-10-29 18:09:35 +02006393 sizeof(struct tls_sess_key), t2->str, t2->size);
Willy Tarreauf5f26e82016-12-16 18:47:27 +01006394 chunk_appendf(&trash, "%d.%d %s\n", ref->unique_id, appctx->ctx.cli.i1, t2->str);
William Lallemand32af2032016-10-29 18:09:35 +02006395
6396 if (bi_putchk(si_ic(si), &trash) == -1) {
6397 /* let's try again later from this stream. We add ourselves into
6398 * this stream's users so that it can remove us upon termination.
6399 */
6400 si_applet_cant_put(si);
6401 return 0;
6402 }
Willy Tarreauf5f26e82016-12-16 18:47:27 +01006403 appctx->ctx.cli.i1++;
William Lallemand32af2032016-10-29 18:09:35 +02006404 }
Willy Tarreauf5f26e82016-12-16 18:47:27 +01006405 appctx->ctx.cli.i1 = 0;
William Lallemand32af2032016-10-29 18:09:35 +02006406 }
6407 if (bi_putchk(si_ic(si), &trash) == -1) {
6408 /* let's try again later from this stream. We add ourselves into
6409 * this stream's users so that it can remove us upon termination.
6410 */
6411 si_applet_cant_put(si);
6412 return 0;
6413 }
6414
Willy Tarreauf5f26e82016-12-16 18:47:27 +01006415 if (appctx->ctx.cli.i0 == 0) /* don't display everything if not necessary */
William Lallemand32af2032016-10-29 18:09:35 +02006416 break;
6417
6418 /* get next list entry and check the end of the list */
Willy Tarreauf5f26e82016-12-16 18:47:27 +01006419 appctx->ctx.cli.p0 = tlskeys_list_get_next(appctx->ctx.cli.p0, &tlskeys_reference);
William Lallemand32af2032016-10-29 18:09:35 +02006420 }
6421
6422 appctx->st2 = STAT_ST_FIN;
6423 /* fall through */
6424
6425 default:
6426 appctx->st2 = STAT_ST_FIN;
6427 return 1;
6428 }
6429 return 0;
6430}
6431
6432#endif
6433
Willy Tarreauf5f26e82016-12-16 18:47:27 +01006434/* sets cli.i0 to non-zero if only file lists should be dumped */
William Lallemand32af2032016-10-29 18:09:35 +02006435static int cli_parse_show_tlskeys(char **args, struct appctx *appctx, void *private)
6436{
William Lallemand32af2032016-10-29 18:09:35 +02006437 /* no parameter, shows only file list */
6438 if (!*args[2]) {
Willy Tarreauf5f26e82016-12-16 18:47:27 +01006439 appctx->ctx.cli.i0 = 1;
William Lallemand32af2032016-10-29 18:09:35 +02006440 appctx->io_handler = cli_io_handler_tlskeys_files;
Willy Tarreau3067bfa2016-12-05 14:50:15 +01006441 return 0;
William Lallemand32af2032016-10-29 18:09:35 +02006442 }
6443
6444 if (args[2][0] == '*') {
6445 /* list every TLS ticket keys */
Willy Tarreauf5f26e82016-12-16 18:47:27 +01006446 appctx->ctx.cli.i0 = 1;
William Lallemand32af2032016-10-29 18:09:35 +02006447 } else {
Willy Tarreauf5f26e82016-12-16 18:47:27 +01006448 appctx->ctx.cli.p0 = tlskeys_ref_lookup_ref(args[2]);
6449 if (!appctx->ctx.cli.p0) {
William Lallemand32af2032016-10-29 18:09:35 +02006450 appctx->ctx.cli.msg = "'show tls-keys' unable to locate referenced filename\n";
Willy Tarreau3b6e5472016-11-24 15:53:53 +01006451 appctx->st0 = CLI_ST_PRINT;
William Lallemand32af2032016-10-29 18:09:35 +02006452 return 1;
6453 }
6454 }
William Lallemand32af2032016-10-29 18:09:35 +02006455 appctx->io_handler = cli_io_handler_tlskeys_entries;
Willy Tarreau3067bfa2016-12-05 14:50:15 +01006456 return 0;
William Lallemand32af2032016-10-29 18:09:35 +02006457}
6458
6459
6460static int cli_parse_set_tlskeys(char **args, struct appctx *appctx, void *private)
6461{
Willy Tarreauf5f26e82016-12-16 18:47:27 +01006462 struct tls_keys_ref *ref;
6463
William Lallemand32af2032016-10-29 18:09:35 +02006464 /* Expect two parameters: the filename and the new new TLS key in encoding */
6465 if (!*args[3] || !*args[4]) {
6466 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 +01006467 appctx->st0 = CLI_ST_PRINT;
William Lallemand32af2032016-10-29 18:09:35 +02006468 return 1;
6469 }
6470
Willy Tarreauf5f26e82016-12-16 18:47:27 +01006471 ref = tlskeys_ref_lookup_ref(args[3]);
6472 if (!ref) {
William Lallemand32af2032016-10-29 18:09:35 +02006473 appctx->ctx.cli.msg = "'set ssl tls-key' unable to locate referenced filename\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
6478 trash.len = base64dec(args[4], strlen(args[4]), trash.str, trash.size);
6479 if (trash.len != sizeof(struct tls_sess_key)) {
6480 appctx->ctx.cli.msg = "'set ssl tls-key' received invalid base64 encoded TLS key.\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
Willy Tarreauf5f26e82016-12-16 18:47:27 +01006485 memcpy(ref->tlskeys + ((ref->tls_ticket_enc_index + 2) % TLS_TICKETS_NO), trash.str, trash.len);
6486 ref->tls_ticket_enc_index = (ref->tls_ticket_enc_index + 1) % TLS_TICKETS_NO;
William Lallemand32af2032016-10-29 18:09:35 +02006487
6488 appctx->ctx.cli.msg = "TLS ticket key updated!";
Willy Tarreau3b6e5472016-11-24 15:53:53 +01006489 appctx->st0 = CLI_ST_PRINT;
William Lallemand32af2032016-10-29 18:09:35 +02006490 return 1;
6491
6492}
6493
6494static int cli_parse_set_ocspresponse(char **args, struct appctx *appctx, void *private)
6495{
6496#if (defined SSL_CTRL_SET_TLSEXT_STATUS_REQ_CB && !defined OPENSSL_NO_OCSP)
6497 char *err = NULL;
6498
6499 /* Expect one parameter: the new response in base64 encoding */
6500 if (!*args[3]) {
6501 appctx->ctx.cli.msg = "'set ssl ocsp-response' expects response in base64 encoding.\n";
Willy Tarreau3b6e5472016-11-24 15:53:53 +01006502 appctx->st0 = CLI_ST_PRINT;
William Lallemand32af2032016-10-29 18:09:35 +02006503 return 1;
6504 }
6505
6506 trash.len = base64dec(args[3], strlen(args[3]), trash.str, trash.size);
6507 if (trash.len < 0) {
6508 appctx->ctx.cli.msg = "'set ssl ocsp-response' received invalid base64 encoded response.\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 if (ssl_sock_update_ocsp_response(&trash, &err)) {
6514 if (err) {
6515 memprintf(&err, "%s.\n", err);
6516 appctx->ctx.cli.err = err;
Willy Tarreau3b6e5472016-11-24 15:53:53 +01006517 appctx->st0 = CLI_ST_PRINT_FREE;
William Lallemand32af2032016-10-29 18:09:35 +02006518 }
6519 return 1;
6520 }
6521 appctx->ctx.cli.msg = "OCSP Response updated!";
Willy Tarreau3b6e5472016-11-24 15:53:53 +01006522 appctx->st0 = CLI_ST_PRINT;
William Lallemand32af2032016-10-29 18:09:35 +02006523 return 1;
6524#else
6525 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 +01006526 appctx->st0 = CLI_ST_PRINT;
William Lallemand32af2032016-10-29 18:09:35 +02006527 return 1;
6528#endif
6529
6530}
6531
6532/* register cli keywords */
6533static struct cli_kw_list cli_kws = {{ },{
6534#if (defined SSL_CTRL_SET_TLSEXT_TICKET_KEY_CB && TLS_TICKETS_NO > 0)
6535 { { "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 },
6536 { { "set", "ssl", "tls-keys", NULL }, NULL, cli_parse_set_tlskeys, NULL },
6537 { { "set", "ssl", "ocsp-response", NULL }, NULL, cli_parse_set_ocspresponse, NULL },
6538#endif
6539 { { NULL }, NULL, NULL, NULL }
6540}};
6541
6542
6543
Willy Tarreau7875d092012-09-10 08:20:03 +02006544/* Note: must not be declared <const> as its list will be overwritten.
6545 * Please take care of keeping this list alphabetically sorted.
6546 */
Willy Tarreaudc13c112013-06-21 23:16:39 +02006547static struct sample_fetch_kw_list sample_fetch_keywords = {ILH, {
Emeric Brun645ae792014-04-30 14:21:06 +02006548 { "ssl_bc", smp_fetch_ssl_fc, 0, NULL, SMP_T_BOOL, SMP_USE_L5SRV },
Thierry FOURNIER07ee64e2015-07-06 23:43:03 +02006549 { "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 +02006550 { "ssl_bc_cipher", smp_fetch_ssl_fc_cipher, 0, NULL, SMP_T_STR, SMP_USE_L5SRV },
6551 { "ssl_bc_protocol", smp_fetch_ssl_fc_protocol, 0, NULL, SMP_T_STR, SMP_USE_L5SRV },
Emeric Brunb73a9b02014-04-30 18:49:19 +02006552 { "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 +02006553 { "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 +02006554 { "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 +02006555 { "ssl_c_ca_err", smp_fetch_ssl_c_ca_err, 0, NULL, SMP_T_SINT, SMP_USE_L5CLI },
6556 { "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 +01006557 { "ssl_c_der", smp_fetch_ssl_x_der, 0, NULL, SMP_T_BIN, SMP_USE_L5CLI },
Thierry FOURNIER07ee64e2015-07-06 23:43:03 +02006558 { "ssl_c_err", smp_fetch_ssl_c_err, 0, NULL, SMP_T_SINT, SMP_USE_L5CLI },
Emeric Brunba841a12014-04-30 17:05:08 +02006559 { "ssl_c_i_dn", smp_fetch_ssl_x_i_dn, ARG2(0,STR,SINT), NULL, SMP_T_STR, SMP_USE_L5CLI },
6560 { "ssl_c_key_alg", smp_fetch_ssl_x_key_alg, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
6561 { "ssl_c_notafter", smp_fetch_ssl_x_notafter, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
6562 { "ssl_c_notbefore", smp_fetch_ssl_x_notbefore, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
6563 { "ssl_c_sig_alg", smp_fetch_ssl_x_sig_alg, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
6564 { "ssl_c_s_dn", smp_fetch_ssl_x_s_dn, ARG2(0,STR,SINT), NULL, SMP_T_STR, SMP_USE_L5CLI },
6565 { "ssl_c_serial", smp_fetch_ssl_x_serial, 0, NULL, SMP_T_BIN, SMP_USE_L5CLI },
6566 { "ssl_c_sha1", smp_fetch_ssl_x_sha1, 0, NULL, SMP_T_BIN, SMP_USE_L5CLI },
Willy Tarreau80aca902013-01-07 15:42:20 +01006567 { "ssl_c_used", smp_fetch_ssl_c_used, 0, NULL, SMP_T_BOOL, SMP_USE_L5CLI },
Thierry FOURNIER07ee64e2015-07-06 23:43:03 +02006568 { "ssl_c_verify", smp_fetch_ssl_c_verify, 0, NULL, SMP_T_SINT, SMP_USE_L5CLI },
6569 { "ssl_c_version", smp_fetch_ssl_x_version, 0, NULL, SMP_T_SINT, SMP_USE_L5CLI },
Emeric Brun43e79582014-10-29 19:03:26 +01006570 { "ssl_f_der", smp_fetch_ssl_x_der, 0, NULL, SMP_T_BIN, SMP_USE_L5CLI },
Emeric Brunba841a12014-04-30 17:05:08 +02006571 { "ssl_f_i_dn", smp_fetch_ssl_x_i_dn, ARG2(0,STR,SINT), NULL, SMP_T_STR, SMP_USE_L5CLI },
6572 { "ssl_f_key_alg", smp_fetch_ssl_x_key_alg, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
6573 { "ssl_f_notafter", smp_fetch_ssl_x_notafter, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
6574 { "ssl_f_notbefore", smp_fetch_ssl_x_notbefore, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
6575 { "ssl_f_sig_alg", smp_fetch_ssl_x_sig_alg, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
6576 { "ssl_f_s_dn", smp_fetch_ssl_x_s_dn, ARG2(0,STR,SINT), NULL, SMP_T_STR, SMP_USE_L5CLI },
6577 { "ssl_f_serial", smp_fetch_ssl_x_serial, 0, NULL, SMP_T_BIN, SMP_USE_L5CLI },
Emeric Brun55f4fa82014-04-30 17:11:25 +02006578 { "ssl_f_sha1", smp_fetch_ssl_x_sha1, 0, NULL, SMP_T_BIN, SMP_USE_L5CLI },
Thierry FOURNIER07ee64e2015-07-06 23:43:03 +02006579 { "ssl_f_version", smp_fetch_ssl_x_version, 0, NULL, SMP_T_SINT, SMP_USE_L5CLI },
Willy Tarreau80aca902013-01-07 15:42:20 +01006580 { "ssl_fc", smp_fetch_ssl_fc, 0, NULL, SMP_T_BOOL, SMP_USE_L5CLI },
Thierry FOURNIER07ee64e2015-07-06 23:43:03 +02006581 { "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 +01006582 { "ssl_fc_cipher", smp_fetch_ssl_fc_cipher, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
Willy Tarreau80aca902013-01-07 15:42:20 +01006583 { "ssl_fc_has_crt", smp_fetch_ssl_fc_has_crt, 0, NULL, SMP_T_BOOL, SMP_USE_L5CLI },
6584 { "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 +02006585 { "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 +02006586#ifdef OPENSSL_NPN_NEGOTIATED
Thierry FOURNIER7654c9f2013-12-17 00:20:33 +01006587 { "ssl_fc_npn", smp_fetch_ssl_fc_npn, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
Willy Tarreaua33c6542012-10-15 13:19:06 +02006588#endif
Dirkjan Bussink48f1c4e2014-02-13 12:29:42 +01006589#ifdef TLSEXT_TYPE_application_layer_protocol_negotiation
Thierry FOURNIER7654c9f2013-12-17 00:20:33 +01006590 { "ssl_fc_alpn", smp_fetch_ssl_fc_alpn, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
Willy Tarreauab861d32013-04-02 02:30:41 +02006591#endif
Thierry FOURNIER7654c9f2013-12-17 00:20:33 +01006592 { "ssl_fc_protocol", smp_fetch_ssl_fc_protocol, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
Emeric Brunb73a9b02014-04-30 18:49:19 +02006593 { "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 +02006594 { "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 +01006595 { "ssl_fc_session_id", smp_fetch_ssl_fc_session_id, 0, NULL, SMP_T_BIN, SMP_USE_L5CLI },
6596 { "ssl_fc_sni", smp_fetch_ssl_fc_sni, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
Willy Tarreau7875d092012-09-10 08:20:03 +02006597 { NULL, NULL, 0, 0, 0 },
6598}};
6599
6600/* Note: must not be declared <const> as its list will be overwritten.
6601 * Please take care of keeping this list alphabetically sorted.
6602 */
Willy Tarreaudc13c112013-06-21 23:16:39 +02006603static struct acl_kw_list acl_kws = {ILH, {
Thierry FOURNIERc5a4e982014-03-05 16:07:08 +01006604 { "ssl_fc_sni_end", "ssl_fc_sni", PAT_MATCH_END },
6605 { "ssl_fc_sni_reg", "ssl_fc_sni", PAT_MATCH_REG },
Willy Tarreau8ed669b2013-01-11 15:49:37 +01006606 { /* END */ },
Willy Tarreau7875d092012-09-10 08:20:03 +02006607}};
6608
Willy Tarreau79eeafa2012-09-14 07:53:05 +02006609/* Note: must not be declared <const> as its list will be overwritten.
6610 * Please take care of keeping this list alphabetically sorted, doing so helps
6611 * all code contributors.
6612 * Optional keywords are also declared with a NULL ->parse() function so that
6613 * the config parser can report an appropriate error when a known keyword was
6614 * not enabled.
6615 */
Willy Tarreau51fb7652012-09-18 18:24:39 +02006616static struct bind_kw_list bind_kws = { "SSL", { }, {
Nenad Merdanovic05552d42015-02-27 19:56:49 +01006617 { "alpn", bind_parse_alpn, 1 }, /* set ALPN supported protocols */
6618 { "ca-file", bind_parse_ca_file, 1 }, /* set CAfile to process verify on client cert */
6619 { "ca-ignore-err", bind_parse_ignore_err, 1 }, /* set error IDs to ignore on verify depth > 0 */
Christopher Faulet31af49d2015-06-09 17:29:50 +02006620 { "ca-sign-file", bind_parse_ca_sign_file, 1 }, /* set CAFile used to generate and sign server certs */
6621 { "ca-sign-pass", bind_parse_ca_sign_pass, 1 }, /* set CAKey passphrase */
Nenad Merdanovic05552d42015-02-27 19:56:49 +01006622 { "ciphers", bind_parse_ciphers, 1 }, /* set SSL cipher suite */
6623 { "crl-file", bind_parse_crl_file, 1 }, /* set certificat revocation list file use on client cert verify */
6624 { "crt", bind_parse_crt, 1 }, /* load SSL certificates from this location */
6625 { "crt-ignore-err", bind_parse_ignore_err, 1 }, /* set error IDs to ingore on verify depth == 0 */
6626 { "crt-list", bind_parse_crt_list, 1 }, /* load a list of crt from this location */
6627 { "ecdhe", bind_parse_ecdhe, 1 }, /* defines named curve for elliptic curve Diffie-Hellman */
6628 { "force-sslv3", bind_parse_force_sslv3, 0 }, /* force SSLv3 */
6629 { "force-tlsv10", bind_parse_force_tlsv10, 0 }, /* force TLSv10 */
6630 { "force-tlsv11", bind_parse_force_tlsv11, 0 }, /* force TLSv11 */
6631 { "force-tlsv12", bind_parse_force_tlsv12, 0 }, /* force TLSv12 */
Christopher Faulet31af49d2015-06-09 17:29:50 +02006632 { "generate-certificates", bind_parse_generate_certs, 0 }, /* enable the server certificates generation */
Nenad Merdanovic05552d42015-02-27 19:56:49 +01006633 { "no-sslv3", bind_parse_no_sslv3, 0 }, /* disable SSLv3 */
6634 { "no-tlsv10", bind_parse_no_tlsv10, 0 }, /* disable TLSv10 */
6635 { "no-tlsv11", bind_parse_no_tlsv11, 0 }, /* disable TLSv11 */
6636 { "no-tlsv12", bind_parse_no_tlsv12, 0 }, /* disable TLSv12 */
6637 { "no-tls-tickets", bind_parse_no_tls_tickets, 0 }, /* disable session resumption tickets */
6638 { "ssl", bind_parse_ssl, 0 }, /* enable SSL processing */
6639 { "strict-sni", bind_parse_strict_sni, 0 }, /* refuse negotiation if sni doesn't match a certificate */
6640 { "tls-ticket-keys", bind_parse_tls_ticket_keys, 1 }, /* set file to load TLS ticket keys from */
6641 { "verify", bind_parse_verify, 1 }, /* set SSL verify method */
6642 { "npn", bind_parse_npn, 1 }, /* set NPN supported protocols */
Willy Tarreau79eeafa2012-09-14 07:53:05 +02006643 { NULL, NULL, 0 },
6644}};
Emeric Brun46591952012-05-18 15:47:34 +02006645
Willy Tarreau92faadf2012-10-10 23:04:25 +02006646/* Note: must not be declared <const> as its list will be overwritten.
6647 * Please take care of keeping this list alphabetically sorted, doing so helps
6648 * all code contributors.
6649 * Optional keywords are also declared with a NULL ->parse() function so that
6650 * the config parser can report an appropriate error when a known keyword was
6651 * not enabled.
6652 */
6653static struct srv_kw_list srv_kws = { "SSL", { }, {
Emeric Brunef42d922012-10-11 16:11:36 +02006654 { "ca-file", srv_parse_ca_file, 1, 0 }, /* set CAfile to process verify server cert */
Emeric Brunecc91fe2012-10-11 15:05:10 +02006655 { "check-ssl", srv_parse_check_ssl, 0, 0 }, /* enable SSL for health checks */
6656 { "ciphers", srv_parse_ciphers, 1, 0 }, /* select the cipher suite */
Emeric Brunef42d922012-10-11 16:11:36 +02006657 { "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 +02006658 { "crt", srv_parse_crt, 1, 0 }, /* set client certificate */
Emeric Brunecc91fe2012-10-11 15:05:10 +02006659 { "force-sslv3", srv_parse_force_sslv3, 0, 0 }, /* force SSLv3 */
6660 { "force-tlsv10", srv_parse_force_tlsv10, 0, 0 }, /* force TLSv10 */
6661 { "force-tlsv11", srv_parse_force_tlsv11, 0, 0 }, /* force TLSv11 */
6662 { "force-tlsv12", srv_parse_force_tlsv12, 0, 0 }, /* force TLSv12 */
Willy Tarreau2a3fb1c2015-02-05 16:47:07 +01006663 { "no-ssl-reuse", srv_parse_no_ssl_reuse, 0, 0 }, /* disable session reuse */
Emeric Brunecc91fe2012-10-11 15:05:10 +02006664 { "no-sslv3", srv_parse_no_sslv3, 0, 0 }, /* disable SSLv3 */
6665 { "no-tlsv10", srv_parse_no_tlsv10, 0, 0 }, /* disable TLSv10 */
6666 { "no-tlsv11", srv_parse_no_tlsv11, 0, 0 }, /* disable TLSv11 */
6667 { "no-tlsv12", srv_parse_no_tlsv12, 0, 0 }, /* disable TLSv12 */
Emeric Brunf9c5c472012-10-11 15:28:34 +02006668 { "no-tls-tickets", srv_parse_no_tls_tickets, 0, 0 }, /* disable session resumption tickets */
David Safb76832014-05-08 23:42:08 -04006669 { "send-proxy-v2-ssl", srv_parse_send_proxy_ssl, 0, 0 }, /* send PROXY protocol header v2 with SSL info */
6670 { "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 +02006671 { "sni", srv_parse_sni, 1, 0 }, /* send SNI extension */
Emeric Brunecc91fe2012-10-11 15:05:10 +02006672 { "ssl", srv_parse_ssl, 0, 0 }, /* enable SSL processing */
Emeric Brunef42d922012-10-11 16:11:36 +02006673 { "verify", srv_parse_verify, 1, 0 }, /* set SSL verify method */
Evan Broderbe554312013-06-27 00:05:25 -07006674 { "verifyhost", srv_parse_verifyhost, 1, 0 }, /* require that SSL cert verifies for hostname */
Willy Tarreau92faadf2012-10-10 23:04:25 +02006675 { NULL, NULL, 0, 0 },
6676}};
6677
Emeric Brun2c86cbf2014-10-30 15:56:50 +01006678static struct cfg_kw_list cfg_kws = {ILH, {
Willy Tarreau8c3b0fd2016-12-21 22:44:46 +01006679 { CFG_GLOBAL, "ca-base", ssl_parse_global_ca_crt_base },
6680 { CFG_GLOBAL, "crt-base", ssl_parse_global_ca_crt_base },
Willy Tarreau0bea58d2016-12-21 23:17:25 +01006681 { CFG_GLOBAL, "maxsslconn", ssl_parse_global_int },
Emeric Brun2c86cbf2014-10-30 15:56:50 +01006682 { CFG_GLOBAL, "ssl-default-bind-options", ssl_parse_default_bind_options },
6683 { CFG_GLOBAL, "ssl-default-server-options", ssl_parse_default_server_options },
Willy Tarreau14e36a12016-12-21 23:28:13 +01006684#ifndef OPENSSL_NO_DH
6685 { CFG_GLOBAL, "ssl-dh-param-file", ssl_parse_global_dh_param_file },
6686#endif
Willy Tarreau9ceda382016-12-21 23:13:03 +01006687 { CFG_GLOBAL, "tune.ssl.cachesize", ssl_parse_global_int },
6688#ifndef OPENSSL_NO_DH
6689 { CFG_GLOBAL, "tune.ssl.default-dh-param", ssl_parse_global_default_dh },
6690#endif
6691 { CFG_GLOBAL, "tune.ssl.force-private-cache", ssl_parse_global_private_cache },
6692 { CFG_GLOBAL, "tune.ssl.lifetime", ssl_parse_global_lifetime },
6693 { CFG_GLOBAL, "tune.ssl.maxrecord", ssl_parse_global_int },
6694 { CFG_GLOBAL, "tune.ssl.ssl-ctx-cache-size", ssl_parse_global_int },
Willy Tarreauf22e9682016-12-21 23:23:19 +01006695 { CFG_GLOBAL, "ssl-default-bind-ciphers", ssl_parse_global_ciphers },
6696 { CFG_GLOBAL, "ssl-default-server-ciphers", ssl_parse_global_ciphers },
Emeric Brun2c86cbf2014-10-30 15:56:50 +01006697 { 0, NULL, NULL },
6698}};
6699
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02006700/* transport-layer operations for SSL sockets */
Willy Tarreaud9f5cca2016-12-22 21:08:52 +01006701static struct xprt_ops ssl_sock = {
Emeric Brun46591952012-05-18 15:47:34 +02006702 .snd_buf = ssl_sock_from_buf,
6703 .rcv_buf = ssl_sock_to_buf,
6704 .rcv_pipe = NULL,
6705 .snd_pipe = NULL,
6706 .shutr = NULL,
6707 .shutw = ssl_sock_shutw,
6708 .close = ssl_sock_close,
6709 .init = ssl_sock_init,
Willy Tarreau55d37912016-12-21 23:38:39 +01006710 .prepare_bind_conf = ssl_sock_prepare_bind_conf,
Willy Tarreau795cdab2016-12-22 17:30:54 +01006711 .destroy_bind_conf = ssl_sock_destroy_bind_conf,
Willy Tarreau17d45382016-12-22 21:16:08 +01006712 .prepare_srv = ssl_sock_prepare_srv_ctx,
6713 .destroy_srv = ssl_sock_free_srv_ctx,
Willy Tarreau8e0bb0a2016-11-24 16:58:12 +01006714 .name = "SSL",
Emeric Brun46591952012-05-18 15:47:34 +02006715};
6716
Daniel Jakots54ffb912015-11-06 20:02:41 +01006717#if (OPENSSL_VERSION_NUMBER >= 0x1000200fL && !defined OPENSSL_NO_TLSEXT && !defined OPENSSL_IS_BORINGSSL && !defined LIBRESSL_VERSION_NUMBER)
Janusz Dziemidowicz2c701b52015-03-07 23:03:59 +01006718
6719static void ssl_sock_sctl_free_func(void *parent, void *ptr, CRYPTO_EX_DATA *ad, int idx, long argl, void *argp)
6720{
6721 if (ptr) {
6722 chunk_destroy(ptr);
6723 free(ptr);
6724 }
6725}
6726
6727#endif
6728
Emeric Brun46591952012-05-18 15:47:34 +02006729__attribute__((constructor))
Willy Tarreau92faadf2012-10-10 23:04:25 +02006730static void __ssl_sock_init(void)
6731{
Willy Tarreauc2c0b612016-12-21 19:23:20 +01006732 char *ptr;
6733
Emeric Brun46591952012-05-18 15:47:34 +02006734 STACK_OF(SSL_COMP)* cm;
6735
Willy Tarreauef934602016-12-22 23:12:01 +01006736 if (global_ssl.listen_default_ciphers)
6737 global_ssl.listen_default_ciphers = strdup(global_ssl.listen_default_ciphers);
6738 if (global_ssl.connect_default_ciphers)
6739 global_ssl.connect_default_ciphers = strdup(global_ssl.connect_default_ciphers);
Willy Tarreau610f04b2014-02-13 11:36:41 +01006740
Willy Tarreau13e14102016-12-22 20:25:26 +01006741 xprt_register(XPRT_SSL, &ssl_sock);
Emeric Brun46591952012-05-18 15:47:34 +02006742 SSL_library_init();
6743 cm = SSL_COMP_get_compression_methods();
6744 sk_SSL_COMP_zero(cm);
Daniel Jakots54ffb912015-11-06 20:02:41 +01006745#if (OPENSSL_VERSION_NUMBER >= 0x1000200fL && !defined OPENSSL_NO_TLSEXT && !defined OPENSSL_IS_BORINGSSL && !defined LIBRESSL_VERSION_NUMBER)
Janusz Dziemidowicz2c701b52015-03-07 23:03:59 +01006746 sctl_ex_index = SSL_CTX_get_ex_new_index(0, NULL, NULL, NULL, ssl_sock_sctl_free_func);
6747#endif
Willy Tarreau7875d092012-09-10 08:20:03 +02006748 sample_register_fetches(&sample_fetch_keywords);
6749 acl_register_keywords(&acl_kws);
Willy Tarreau79eeafa2012-09-14 07:53:05 +02006750 bind_register_keywords(&bind_kws);
Willy Tarreau92faadf2012-10-10 23:04:25 +02006751 srv_register_keywords(&srv_kws);
Emeric Brun2c86cbf2014-10-30 15:56:50 +01006752 cfg_register_keywords(&cfg_kws);
William Lallemand32af2032016-10-29 18:09:35 +02006753 cli_register_kw(&cli_kws);
Willy Tarreaud1c57502016-12-22 22:46:15 +01006754#if (defined SSL_CTRL_SET_TLSEXT_TICKET_KEY_CB && TLS_TICKETS_NO > 0)
6755 hap_register_post_check(tlskeys_finalize_config);
6756#endif
Willy Tarreaud92aa5c2015-01-15 21:34:39 +01006757
Willy Tarreauc2c0b612016-12-21 19:23:20 +01006758 ptr = NULL;
6759 memprintf(&ptr, "Built with OpenSSL version : "
6760#ifdef OPENSSL_IS_BORINGSSL
6761 "BoringSSL\n");
6762#else /* OPENSSL_IS_BORINGSSL */
6763 OPENSSL_VERSION_TEXT
6764 "\nRunning on OpenSSL version : %s%s",
6765 SSLeay_version(SSLEAY_VERSION),
6766 ((OPENSSL_VERSION_NUMBER ^ SSLeay()) >> 8) ? " (VERSIONS DIFFER!)" : "");
6767#endif
6768 memprintf(&ptr, "%s\nOpenSSL library supports TLS extensions : "
6769#if OPENSSL_VERSION_NUMBER < 0x00907000L
6770 "no (library version too old)"
6771#elif defined(OPENSSL_NO_TLSEXT)
6772 "no (disabled via OPENSSL_NO_TLSEXT)"
6773#else
6774 "yes"
6775#endif
6776 "", ptr);
6777
6778 memprintf(&ptr, "%s\nOpenSSL library supports SNI : "
6779#ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME
6780 "yes"
6781#else
6782#ifdef OPENSSL_NO_TLSEXT
6783 "no (because of OPENSSL_NO_TLSEXT)"
6784#else
6785 "no (version might be too old, 0.9.8f min needed)"
6786#endif
6787#endif
6788 "", ptr);
6789
6790 memprintf(&ptr, "%s\nOpenSSL library supports prefer-server-ciphers : "
6791#ifdef SSL_OP_CIPHER_SERVER_PREFERENCE
6792 "yes"
6793#else
6794 "no (0.9.7 or later needed)"
6795#endif
6796 "", ptr);
6797 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 */