blob: b94166cdce4ac5422d6ee77d018d64f8e5989368 [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
Emmanuel Hocdet98263292016-12-29 18:26:15 +0100197static struct ssl_bind_kw ssl_bind_kws[];
198
Christopher Faulet31af49d2015-06-09 17:29:50 +0200199/* LRU cache to store generated certificate */
200static struct lru64_head *ssl_ctx_lru_tree = NULL;
201static unsigned int ssl_ctx_lru_seed = 0;
Willy Tarreauc8ad3be2015-06-17 15:48:26 +0200202#endif // SSL_CTRL_SET_TLSEXT_HOSTNAME
203
yanbzhube2774d2015-12-10 15:07:30 -0500204#if OPENSSL_VERSION_NUMBER >= 0x1000200fL
205/* The order here matters for picking a default context,
206 * keep the most common keytype at the bottom of the list
207 */
208const char *SSL_SOCK_KEYTYPE_NAMES[] = {
209 "dsa",
210 "ecdsa",
211 "rsa"
212};
213#define SSL_SOCK_NUM_KEYTYPES 3
Willy Tarreau30da7ad2015-12-14 11:28:33 +0100214#else
215#define SSL_SOCK_NUM_KEYTYPES 1
yanbzhube2774d2015-12-10 15:07:30 -0500216#endif
217
Willy Tarreauc8ad3be2015-06-17 15:48:26 +0200218#if (defined SSL_CTRL_SET_TLSEXT_STATUS_REQ_CB && !defined OPENSSL_NO_OCSP)
yanbzhube2774d2015-12-10 15:07:30 -0500219/*
220 * struct alignment works here such that the key.key is the same as key_data
221 * Do not change the placement of key_data
222 */
Willy Tarreauc8ad3be2015-06-17 15:48:26 +0200223struct certificate_ocsp {
224 struct ebmb_node key;
225 unsigned char key_data[OCSP_MAX_CERTID_ASN1_LENGTH];
226 struct chunk response;
227 long expire;
228};
Christopher Faulet31af49d2015-06-09 17:29:50 +0200229
yanbzhube2774d2015-12-10 15:07:30 -0500230struct ocsp_cbk_arg {
231 int is_single;
232 int single_kt;
233 union {
234 struct certificate_ocsp *s_ocsp;
235 /*
236 * m_ocsp will have multiple entries dependent on key type
237 * Entry 0 - DSA
238 * Entry 1 - ECDSA
239 * Entry 2 - RSA
240 */
241 struct certificate_ocsp *m_ocsp[SSL_SOCK_NUM_KEYTYPES];
242 };
243};
244
Emeric Brun4f3c87a2014-06-20 15:46:13 +0200245/*
Thierry FOURNIER / OZON.IO8b068c22016-10-10 11:59:50 +0200246 * This function gives the detail of the SSL error. It is used only
247 * if the debug mode and the verbose mode are activated. It dump all
248 * the SSL error until the stack was empty.
249 */
250static forceinline void ssl_sock_dump_errors(struct connection *conn)
251{
252 unsigned long ret;
253
254 if (unlikely(global.mode & MODE_DEBUG)) {
255 while(1) {
256 ret = ERR_get_error();
257 if (ret == 0)
258 return;
259 fprintf(stderr, "fd[%04x] OpenSSL error[0x%lx] %s: %s\n",
260 (unsigned short)conn->t.sock.fd, ret,
261 ERR_func_error_string(ret), ERR_reason_error_string(ret));
262 }
263 }
264}
265
266/*
Emeric Brun4f3c87a2014-06-20 15:46:13 +0200267 * This function returns the number of seconds elapsed
268 * since the Epoch, 1970-01-01 00:00:00 +0000 (UTC) and the
269 * date presented un ASN1_GENERALIZEDTIME.
270 *
271 * In parsing error case, it returns -1.
272 */
273static long asn1_generalizedtime_to_epoch(ASN1_GENERALIZEDTIME *d)
274{
275 long epoch;
276 char *p, *end;
277 const unsigned short month_offset[12] = {
278 0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334
279 };
280 int year, month;
281
282 if (!d || (d->type != V_ASN1_GENERALIZEDTIME)) return -1;
283
284 p = (char *)d->data;
285 end = p + d->length;
286
287 if (end - p < 4) return -1;
288 year = 1000 * (p[0] - '0') + 100 * (p[1] - '0') + 10 * (p[2] - '0') + p[3] - '0';
289 p += 4;
290 if (end - p < 2) return -1;
291 month = 10 * (p[0] - '0') + p[1] - '0';
292 if (month < 1 || month > 12) return -1;
293 /* Compute the number of seconds since 1 jan 1970 and the beginning of current month
294 We consider leap years and the current month (<marsh or not) */
295 epoch = ( ((year - 1970) * 365)
296 + ((year - (month < 3)) / 4 - (year - (month < 3)) / 100 + (year - (month < 3)) / 400)
297 - ((1970 - 1) / 4 - (1970 - 1) / 100 + (1970 - 1) / 400)
298 + month_offset[month-1]
299 ) * 24 * 60 * 60;
300 p += 2;
301 if (end - p < 2) return -1;
302 /* Add the number of seconds of completed days of current month */
303 epoch += (10 * (p[0] - '0') + p[1] - '0' - 1) * 24 * 60 * 60;
304 p += 2;
305 if (end - p < 2) return -1;
306 /* Add the completed hours of the current day */
307 epoch += (10 * (p[0] - '0') + p[1] - '0') * 60 * 60;
308 p += 2;
309 if (end - p < 2) return -1;
310 /* Add the completed minutes of the current hour */
311 epoch += (10 * (p[0] - '0') + p[1] - '0') * 60;
312 p += 2;
313 if (p == end) return -1;
314 /* Test if there is available seconds */
315 if (p[0] < '0' || p[0] > '9')
316 goto nosec;
317 if (end - p < 2) return -1;
318 /* Add the seconds of the current minute */
319 epoch += 10 * (p[0] - '0') + p[1] - '0';
320 p += 2;
321 if (p == end) return -1;
322 /* Ignore seconds float part if present */
323 if (p[0] == '.') {
324 do {
325 if (++p == end) return -1;
326 } while (p[0] >= '0' && p[0] <= '9');
327 }
328
329nosec:
330 if (p[0] == 'Z') {
331 if (end - p != 1) return -1;
332 return epoch;
333 }
334 else if (p[0] == '+') {
335 if (end - p != 5) return -1;
336 /* Apply timezone offset */
337 return epoch - ((10 * (p[1] - '0') + p[2] - '0') * 60 + (10 * (p[3] - '0') + p[4] - '0')) * 60;
338 }
339 else if (p[0] == '-') {
340 if (end - p != 5) return -1;
341 /* Apply timezone offset */
342 return epoch + ((10 * (p[1] - '0') + p[2] - '0') * 60 + (10 * (p[3] - '0') + p[4] - '0')) * 60;
343 }
344
345 return -1;
346}
347
Emeric Brun1d3865b2014-06-20 15:37:32 +0200348static struct eb_root cert_ocsp_tree = EB_ROOT_UNIQUE;
Emeric Brun4147b2e2014-06-16 18:36:30 +0200349
350/* This function starts to check if the OCSP response (in DER format) contained
351 * in chunk 'ocsp_response' is valid (else exits on error).
352 * If 'cid' is not NULL, it will be compared to the OCSP certificate ID
353 * contained in the OCSP Response and exits on error if no match.
354 * If it's a valid OCSP Response:
355 * If 'ocsp' is not NULL, the chunk is copied in the OCSP response's container
356 * pointed by 'ocsp'.
357 * If 'ocsp' is NULL, the function looks up into the OCSP response's
358 * containers tree (using as index the ASN1 form of the OCSP Certificate ID extracted
359 * from the response) and exits on error if not found. Finally, If an OCSP response is
360 * already present in the container, it will be overwritten.
361 *
362 * Note: OCSP response containing more than one OCSP Single response is not
363 * considered valid.
364 *
365 * Returns 0 on success, 1 in error case.
366 */
367static int ssl_sock_load_ocsp_response(struct chunk *ocsp_response, struct certificate_ocsp *ocsp, OCSP_CERTID *cid, char **err)
368{
369 OCSP_RESPONSE *resp;
370 OCSP_BASICRESP *bs = NULL;
371 OCSP_SINGLERESP *sr;
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +0200372 OCSP_CERTID *id;
Emeric Brun4147b2e2014-06-16 18:36:30 +0200373 unsigned char *p = (unsigned char *)ocsp_response->str;
374 int rc , count_sr;
Emeric Brun13a6b482014-06-20 15:44:34 +0200375 ASN1_GENERALIZEDTIME *revtime, *thisupd, *nextupd = NULL;
Emeric Brun4147b2e2014-06-16 18:36:30 +0200376 int reason;
377 int ret = 1;
378
379 resp = d2i_OCSP_RESPONSE(NULL, (const unsigned char **)&p, ocsp_response->len);
380 if (!resp) {
381 memprintf(err, "Unable to parse OCSP response");
382 goto out;
383 }
384
385 rc = OCSP_response_status(resp);
386 if (rc != OCSP_RESPONSE_STATUS_SUCCESSFUL) {
387 memprintf(err, "OCSP response status not successful");
388 goto out;
389 }
390
391 bs = OCSP_response_get1_basic(resp);
392 if (!bs) {
393 memprintf(err, "Failed to get basic response from OCSP Response");
394 goto out;
395 }
396
397 count_sr = OCSP_resp_count(bs);
398 if (count_sr > 1) {
399 memprintf(err, "OCSP response ignored because contains multiple single responses (%d)", count_sr);
400 goto out;
401 }
402
403 sr = OCSP_resp_get0(bs, 0);
404 if (!sr) {
405 memprintf(err, "Failed to get OCSP single response");
406 goto out;
407 }
408
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +0200409 id = (OCSP_CERTID*)OCSP_SINGLERESP_get0_id(sr);
410
Emeric Brun4147b2e2014-06-16 18:36:30 +0200411 rc = OCSP_single_get0_status(sr, &reason, &revtime, &thisupd, &nextupd);
412 if (rc != V_OCSP_CERTSTATUS_GOOD) {
413 memprintf(err, "OCSP single response: certificate status not good");
414 goto out;
415 }
416
Emeric Brun13a6b482014-06-20 15:44:34 +0200417 if (!nextupd) {
418 memprintf(err, "OCSP single response: missing nextupdate");
419 goto out;
420 }
421
Emeric Brunc8b27b62014-06-19 14:16:17 +0200422 rc = OCSP_check_validity(thisupd, nextupd, OCSP_MAX_RESPONSE_TIME_SKEW, -1);
Emeric Brun4147b2e2014-06-16 18:36:30 +0200423 if (!rc) {
424 memprintf(err, "OCSP single response: no longer valid.");
425 goto out;
426 }
427
428 if (cid) {
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +0200429 if (OCSP_id_cmp(id, cid)) {
Emeric Brun4147b2e2014-06-16 18:36:30 +0200430 memprintf(err, "OCSP single response: Certificate ID does not match certificate and issuer");
431 goto out;
432 }
433 }
434
435 if (!ocsp) {
436 unsigned char key[OCSP_MAX_CERTID_ASN1_LENGTH];
437 unsigned char *p;
438
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +0200439 rc = i2d_OCSP_CERTID(id, NULL);
Emeric Brun4147b2e2014-06-16 18:36:30 +0200440 if (!rc) {
441 memprintf(err, "OCSP single response: Unable to encode Certificate ID");
442 goto out;
443 }
444
445 if (rc > OCSP_MAX_CERTID_ASN1_LENGTH) {
446 memprintf(err, "OCSP single response: Certificate ID too long");
447 goto out;
448 }
449
450 p = key;
451 memset(key, 0, OCSP_MAX_CERTID_ASN1_LENGTH);
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +0200452 i2d_OCSP_CERTID(id, &p);
Emeric Brun4147b2e2014-06-16 18:36:30 +0200453 ocsp = (struct certificate_ocsp *)ebmb_lookup(&cert_ocsp_tree, key, OCSP_MAX_CERTID_ASN1_LENGTH);
454 if (!ocsp) {
455 memprintf(err, "OCSP single response: Certificate ID does not match any certificate or issuer");
456 goto out;
457 }
458 }
459
460 /* According to comments on "chunk_dup", the
461 previous chunk buffer will be freed */
462 if (!chunk_dup(&ocsp->response, ocsp_response)) {
463 memprintf(err, "OCSP response: Memory allocation error");
464 goto out;
465 }
466
Emeric Brun4f3c87a2014-06-20 15:46:13 +0200467 ocsp->expire = asn1_generalizedtime_to_epoch(nextupd) - OCSP_MAX_RESPONSE_TIME_SKEW;
468
Emeric Brun4147b2e2014-06-16 18:36:30 +0200469 ret = 0;
470out:
471 if (bs)
472 OCSP_BASICRESP_free(bs);
473
474 if (resp)
475 OCSP_RESPONSE_free(resp);
476
477 return ret;
478}
479/*
480 * External function use to update the OCSP response in the OCSP response's
481 * containers tree. The chunk 'ocsp_response' must contain the OCSP response
482 * to update in DER format.
483 *
484 * Returns 0 on success, 1 in error case.
485 */
486int ssl_sock_update_ocsp_response(struct chunk *ocsp_response, char **err)
487{
488 return ssl_sock_load_ocsp_response(ocsp_response, NULL, NULL, err);
489}
490
491/*
492 * This function load the OCSP Resonse in DER format contained in file at
493 * path 'ocsp_path' and call 'ssl_sock_load_ocsp_response'
494 *
495 * Returns 0 on success, 1 in error case.
496 */
497static int ssl_sock_load_ocsp_response_from_file(const char *ocsp_path, struct certificate_ocsp *ocsp, OCSP_CERTID *cid, char **err)
498{
499 int fd = -1;
500 int r = 0;
501 int ret = 1;
502
503 fd = open(ocsp_path, O_RDONLY);
504 if (fd == -1) {
505 memprintf(err, "Error opening OCSP response file");
506 goto end;
507 }
508
509 trash.len = 0;
510 while (trash.len < trash.size) {
511 r = read(fd, trash.str + trash.len, trash.size - trash.len);
512 if (r < 0) {
513 if (errno == EINTR)
514 continue;
515
516 memprintf(err, "Error reading OCSP response from file");
517 goto end;
518 }
519 else if (r == 0) {
520 break;
521 }
522 trash.len += r;
523 }
524
525 close(fd);
526 fd = -1;
527
528 ret = ssl_sock_load_ocsp_response(&trash, ocsp, cid, err);
529end:
530 if (fd != -1)
531 close(fd);
532
533 return ret;
534}
535
Nenad Merdanovic05552d42015-02-27 19:56:49 +0100536#if (defined SSL_CTRL_SET_TLSEXT_TICKET_KEY_CB && TLS_TICKETS_NO > 0)
537static int ssl_tlsext_ticket_key_cb(SSL *s, unsigned char key_name[16], unsigned char *iv, EVP_CIPHER_CTX *ectx, HMAC_CTX *hctx, int enc)
538{
539 struct tls_sess_key *keys;
540 struct connection *conn;
541 int head;
542 int i;
543
Vincent Bernat3c2f2f22016-04-03 13:48:42 +0200544 conn = SSL_get_app_data(s);
Nenad Merdanovic146defa2015-05-09 08:46:00 +0200545 keys = objt_listener(conn->target)->bind_conf->keys_ref->tlskeys;
546 head = objt_listener(conn->target)->bind_conf->keys_ref->tls_ticket_enc_index;
Nenad Merdanovic05552d42015-02-27 19:56:49 +0100547
548 if (enc) {
549 memcpy(key_name, keys[head].name, 16);
550
551 if(!RAND_pseudo_bytes(iv, EVP_MAX_IV_LENGTH))
552 return -1;
553
554 if(!EVP_EncryptInit_ex(ectx, EVP_aes_128_cbc(), NULL, keys[head].aes_key, iv))
555 return -1;
556
557 HMAC_Init_ex(hctx, keys[head].hmac_key, 16, HASH_FUNCT(), NULL);
558
559 return 1;
560 } else {
561 for (i = 0; i < TLS_TICKETS_NO; i++) {
562 if (!memcmp(key_name, keys[(head + i) % TLS_TICKETS_NO].name, 16))
563 goto found;
564 }
565 return 0;
566
567 found:
568 HMAC_Init_ex(hctx, keys[(head + i) % TLS_TICKETS_NO].hmac_key, 16, HASH_FUNCT(), NULL);
569 if(!EVP_DecryptInit_ex(ectx, EVP_aes_128_cbc(), NULL, keys[(head + i) % TLS_TICKETS_NO].aes_key, iv))
570 return -1;
571 /* 2 for key renewal, 1 if current key is still valid */
572 return i ? 2 : 1;
573 }
Nenad Merdanovic200b0fa2015-05-09 08:46:01 +0200574}
575
576struct tls_keys_ref *tlskeys_ref_lookup(const char *filename)
577{
578 struct tls_keys_ref *ref;
579
580 list_for_each_entry(ref, &tlskeys_reference, list)
581 if (ref->filename && strcmp(filename, ref->filename) == 0)
582 return ref;
583 return NULL;
584}
585
586struct tls_keys_ref *tlskeys_ref_lookupid(int unique_id)
587{
588 struct tls_keys_ref *ref;
589
590 list_for_each_entry(ref, &tlskeys_reference, list)
591 if (ref->unique_id == unique_id)
592 return ref;
593 return NULL;
594}
595
596int ssl_sock_update_tlskey(char *filename, struct chunk *tlskey, char **err) {
597 struct tls_keys_ref *ref = tlskeys_ref_lookup(filename);
598
599 if(!ref) {
600 memprintf(err, "Unable to locate the referenced filename: %s", filename);
601 return 1;
602 }
603
Pradeep Jindalcc79b002015-08-20 18:25:17 +0530604 memcpy((char *) (ref->tlskeys + ((ref->tls_ticket_enc_index + 2) % TLS_TICKETS_NO)), tlskey->str, tlskey->len);
605 ref->tls_ticket_enc_index = (ref->tls_ticket_enc_index + 1) % TLS_TICKETS_NO;
Nenad Merdanovic200b0fa2015-05-09 08:46:01 +0200606
607 return 0;
Nenad Merdanovic05552d42015-02-27 19:56:49 +0100608}
Nenad Merdanovic200b0fa2015-05-09 08:46:01 +0200609
610/* This function finalize the configuration parsing. Its set all the
Willy Tarreaud1c57502016-12-22 22:46:15 +0100611 * automatic ids. It's called just after the basic checks. It returns
612 * 0 on success otherwise ERR_*.
Nenad Merdanovic200b0fa2015-05-09 08:46:01 +0200613 */
Willy Tarreaud1c57502016-12-22 22:46:15 +0100614static int tlskeys_finalize_config(void)
Nenad Merdanovic200b0fa2015-05-09 08:46:01 +0200615{
616 int i = 0;
617 struct tls_keys_ref *ref, *ref2, *ref3;
618 struct list tkr = LIST_HEAD_INIT(tkr);
619
620 list_for_each_entry(ref, &tlskeys_reference, list) {
621 if (ref->unique_id == -1) {
622 /* Look for the first free id. */
623 while (1) {
624 list_for_each_entry(ref2, &tlskeys_reference, list) {
625 if (ref2->unique_id == i) {
626 i++;
627 break;
628 }
629 }
630 if (&ref2->list == &tlskeys_reference)
631 break;
632 }
633
634 /* Uses the unique id and increment it for the next entry. */
635 ref->unique_id = i;
636 i++;
637 }
638 }
639
640 /* This sort the reference list by id. */
641 list_for_each_entry_safe(ref, ref2, &tlskeys_reference, list) {
642 LIST_DEL(&ref->list);
643 list_for_each_entry(ref3, &tkr, list) {
644 if (ref->unique_id < ref3->unique_id) {
645 LIST_ADDQ(&ref3->list, &ref->list);
646 break;
647 }
648 }
649 if (&ref3->list == &tkr)
650 LIST_ADDQ(&tkr, &ref->list);
651 }
652
653 /* swap root */
654 LIST_ADD(&tkr, &tlskeys_reference);
655 LIST_DEL(&tkr);
Willy Tarreaud1c57502016-12-22 22:46:15 +0100656 return 0;
Nenad Merdanovic200b0fa2015-05-09 08:46:01 +0200657}
658
Nenad Merdanovic05552d42015-02-27 19:56:49 +0100659#endif /* SSL_CTRL_SET_TLSEXT_TICKET_KEY_CB */
660
yanbzhube2774d2015-12-10 15:07:30 -0500661int ssl_sock_get_ocsp_arg_kt_index(int evp_keytype)
662{
663 switch (evp_keytype) {
664 case EVP_PKEY_RSA:
665 return 2;
666 case EVP_PKEY_DSA:
667 return 0;
668 case EVP_PKEY_EC:
669 return 1;
670 }
671
672 return -1;
673}
674
Emeric Brun4147b2e2014-06-16 18:36:30 +0200675/*
676 * Callback used to set OCSP status extension content in server hello.
677 */
678int ssl_sock_ocsp_stapling_cbk(SSL *ssl, void *arg)
679{
yanbzhube2774d2015-12-10 15:07:30 -0500680 struct certificate_ocsp *ocsp;
681 struct ocsp_cbk_arg *ocsp_arg;
682 char *ssl_buf;
683 EVP_PKEY *ssl_pkey;
684 int key_type;
685 int index;
686
Vincent Bernat3c2f2f22016-04-03 13:48:42 +0200687 ocsp_arg = arg;
yanbzhube2774d2015-12-10 15:07:30 -0500688
689 ssl_pkey = SSL_get_privatekey(ssl);
690 if (!ssl_pkey)
691 return SSL_TLSEXT_ERR_NOACK;
692
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +0200693 key_type = EVP_PKEY_base_id(ssl_pkey);
yanbzhube2774d2015-12-10 15:07:30 -0500694
695 if (ocsp_arg->is_single && ocsp_arg->single_kt == key_type)
696 ocsp = ocsp_arg->s_ocsp;
697 else {
698 /* For multiple certs per context, we have to find the correct OCSP response based on
699 * the certificate type
700 */
701 index = ssl_sock_get_ocsp_arg_kt_index(key_type);
702
703 if (index < 0)
704 return SSL_TLSEXT_ERR_NOACK;
705
706 ocsp = ocsp_arg->m_ocsp[index];
707
708 }
Emeric Brun4147b2e2014-06-16 18:36:30 +0200709
710 if (!ocsp ||
711 !ocsp->response.str ||
Emeric Brun4f3c87a2014-06-20 15:46:13 +0200712 !ocsp->response.len ||
713 (ocsp->expire < now.tv_sec))
Emeric Brun4147b2e2014-06-16 18:36:30 +0200714 return SSL_TLSEXT_ERR_NOACK;
715
716 ssl_buf = OPENSSL_malloc(ocsp->response.len);
717 if (!ssl_buf)
718 return SSL_TLSEXT_ERR_NOACK;
719
720 memcpy(ssl_buf, ocsp->response.str, ocsp->response.len);
721 SSL_set_tlsext_status_ocsp_resp(ssl, ssl_buf, ocsp->response.len);
722
723 return SSL_TLSEXT_ERR_OK;
724}
725
726/*
727 * This function enables the handling of OCSP status extension on 'ctx' if a
728 * file name 'cert_path' suffixed using ".ocsp" is present.
729 * To enable OCSP status extension, the issuer's certificate is mandatory.
730 * It should be present in the certificate's extra chain builded from file
731 * 'cert_path'. If not found, the issuer certificate is loaded from a file
732 * named 'cert_path' suffixed using '.issuer'.
733 *
734 * In addition, ".ocsp" file content is loaded as a DER format of an OCSP
735 * response. If file is empty or content is not a valid OCSP response,
736 * OCSP status extension is enabled but OCSP response is ignored (a warning
737 * is displayed).
738 *
739 * Returns 1 if no ".ocsp" file found, 0 if OCSP status extension is
740 * succesfully enabled, or -1 in other error case.
741 */
742static int ssl_sock_load_ocsp(SSL_CTX *ctx, const char *cert_path)
743{
744
745 BIO *in = NULL;
746 X509 *x, *xi = NULL, *issuer = NULL;
747 STACK_OF(X509) *chain = NULL;
748 OCSP_CERTID *cid = NULL;
749 SSL *ssl;
750 char ocsp_path[MAXPATHLEN+1];
751 int i, ret = -1;
752 struct stat st;
753 struct certificate_ocsp *ocsp = NULL, *iocsp;
754 char *warn = NULL;
755 unsigned char *p;
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +0200756 pem_password_cb *passwd_cb;
757 void *passwd_cb_userdata;
758 void (*callback) (void);
Emeric Brun4147b2e2014-06-16 18:36:30 +0200759
760 snprintf(ocsp_path, MAXPATHLEN+1, "%s.ocsp", cert_path);
761
762 if (stat(ocsp_path, &st))
763 return 1;
764
765 ssl = SSL_new(ctx);
766 if (!ssl)
767 goto out;
768
769 x = SSL_get_certificate(ssl);
770 if (!x)
771 goto out;
772
773 /* Try to lookup for issuer in certificate extra chain */
774#ifdef SSL_CTRL_GET_EXTRA_CHAIN_CERTS
775 SSL_CTX_get_extra_chain_certs(ctx, &chain);
776#else
777 chain = ctx->extra_certs;
778#endif
779 for (i = 0; i < sk_X509_num(chain); i++) {
780 issuer = sk_X509_value(chain, i);
781 if (X509_check_issued(issuer, x) == X509_V_OK)
782 break;
783 else
784 issuer = NULL;
785 }
786
787 /* If not found try to load issuer from a suffixed file */
788 if (!issuer) {
789 char issuer_path[MAXPATHLEN+1];
790
791 in = BIO_new(BIO_s_file());
792 if (!in)
793 goto out;
794
795 snprintf(issuer_path, MAXPATHLEN+1, "%s.issuer", cert_path);
796 if (BIO_read_filename(in, issuer_path) <= 0)
797 goto out;
798
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +0200799 passwd_cb = SSL_CTX_get_default_passwd_cb(ctx);
800 passwd_cb_userdata = SSL_CTX_get_default_passwd_cb_userdata(ctx);
801
802 xi = PEM_read_bio_X509_AUX(in, NULL, passwd_cb, passwd_cb_userdata);
Emeric Brun4147b2e2014-06-16 18:36:30 +0200803 if (!xi)
804 goto out;
805
806 if (X509_check_issued(xi, x) != X509_V_OK)
807 goto out;
808
809 issuer = xi;
810 }
811
812 cid = OCSP_cert_to_id(0, x, issuer);
813 if (!cid)
814 goto out;
815
816 i = i2d_OCSP_CERTID(cid, NULL);
817 if (!i || (i > OCSP_MAX_CERTID_ASN1_LENGTH))
818 goto out;
819
Vincent Bernat02779b62016-04-03 13:48:43 +0200820 ocsp = calloc(1, sizeof(*ocsp));
Emeric Brun4147b2e2014-06-16 18:36:30 +0200821 if (!ocsp)
822 goto out;
823
824 p = ocsp->key_data;
825 i2d_OCSP_CERTID(cid, &p);
826
827 iocsp = (struct certificate_ocsp *)ebmb_insert(&cert_ocsp_tree, &ocsp->key, OCSP_MAX_CERTID_ASN1_LENGTH);
828 if (iocsp == ocsp)
829 ocsp = NULL;
830
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +0200831#ifndef SSL_CTX_get_tlsext_status_cb
832# define SSL_CTX_get_tlsext_status_cb(ctx, cb) \
833 *cb = (void (*) (void))ctx->tlsext_status_cb;
834#endif
835 SSL_CTX_get_tlsext_status_cb(ctx, &callback);
836
837 if (!callback) {
Vincent Bernat02779b62016-04-03 13:48:43 +0200838 struct ocsp_cbk_arg *cb_arg = calloc(1, sizeof(*cb_arg));
Emmanuel Hocdetb7a4c342017-01-06 12:57:46 +0100839 EVP_PKEY *pkey;
yanbzhube2774d2015-12-10 15:07:30 -0500840
841 cb_arg->is_single = 1;
842 cb_arg->s_ocsp = iocsp;
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +0200843
Emmanuel Hocdetb7a4c342017-01-06 12:57:46 +0100844 pkey = X509_get_pubkey(x);
845 cb_arg->single_kt = EVP_PKEY_base_id(pkey);
846 EVP_PKEY_free(pkey);
yanbzhube2774d2015-12-10 15:07:30 -0500847
848 SSL_CTX_set_tlsext_status_cb(ctx, ssl_sock_ocsp_stapling_cbk);
849 SSL_CTX_set_tlsext_status_arg(ctx, cb_arg);
850 } else {
851 /*
852 * If the ctx has a status CB, then we have previously set an OCSP staple for this ctx
853 * Update that cb_arg with the new cert's staple
854 */
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +0200855 struct ocsp_cbk_arg *cb_arg;
yanbzhube2774d2015-12-10 15:07:30 -0500856 struct certificate_ocsp *tmp_ocsp;
857 int index;
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +0200858 int key_type;
Emmanuel Hocdetb7a4c342017-01-06 12:57:46 +0100859 EVP_PKEY *pkey;
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +0200860
861#ifdef SSL_CTX_get_tlsext_status_arg
862 SSL_CTX_ctrl(ctx, SSL_CTRL_GET_TLSEXT_STATUS_REQ_CB_ARG, 0, &cb_arg);
863#else
864 cb_arg = ctx->tlsext_status_arg;
865#endif
yanbzhube2774d2015-12-10 15:07:30 -0500866
867 /*
868 * The following few lines will convert cb_arg from a single ocsp to multi ocsp
869 * the order of operations below matter, take care when changing it
870 */
871 tmp_ocsp = cb_arg->s_ocsp;
872 index = ssl_sock_get_ocsp_arg_kt_index(cb_arg->single_kt);
873 cb_arg->s_ocsp = NULL;
874 cb_arg->m_ocsp[index] = tmp_ocsp;
875 cb_arg->is_single = 0;
876 cb_arg->single_kt = 0;
877
Emmanuel Hocdetb7a4c342017-01-06 12:57:46 +0100878 pkey = X509_get_pubkey(x);
879 key_type = EVP_PKEY_base_id(pkey);
880 EVP_PKEY_free(pkey);
881
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +0200882 index = ssl_sock_get_ocsp_arg_kt_index(key_type);
yanbzhube2774d2015-12-10 15:07:30 -0500883 if (index >= 0 && !cb_arg->m_ocsp[index])
884 cb_arg->m_ocsp[index] = iocsp;
885
886 }
Emeric Brun4147b2e2014-06-16 18:36:30 +0200887
888 ret = 0;
889
890 warn = NULL;
891 if (ssl_sock_load_ocsp_response_from_file(ocsp_path, iocsp, cid, &warn)) {
892 memprintf(&warn, "Loading '%s': %s. Content will be ignored", ocsp_path, warn ? warn : "failure");
893 Warning("%s.\n", warn);
894 }
895
896out:
897 if (ssl)
898 SSL_free(ssl);
899
900 if (in)
901 BIO_free(in);
902
903 if (xi)
904 X509_free(xi);
905
906 if (cid)
907 OCSP_CERTID_free(cid);
908
909 if (ocsp)
910 free(ocsp);
911
912 if (warn)
913 free(warn);
914
915
916 return ret;
917}
918
919#endif
920
Daniel Jakots54ffb912015-11-06 20:02:41 +0100921#if (OPENSSL_VERSION_NUMBER >= 0x1000200fL && !defined OPENSSL_NO_TLSEXT && !defined OPENSSL_IS_BORINGSSL && !defined LIBRESSL_VERSION_NUMBER)
Janusz Dziemidowicz2c701b52015-03-07 23:03:59 +0100922
923#define CT_EXTENSION_TYPE 18
924
925static int sctl_ex_index = -1;
926
927/*
928 * Try to parse Signed Certificate Timestamp List structure. This function
929 * makes only basic test if the data seems like SCTL. No signature validation
930 * is performed.
931 */
932static int ssl_sock_parse_sctl(struct chunk *sctl)
933{
934 int ret = 1;
935 int len, pos, sct_len;
936 unsigned char *data;
937
938 if (sctl->len < 2)
939 goto out;
940
941 data = (unsigned char *)sctl->str;
942 len = (data[0] << 8) | data[1];
943
944 if (len + 2 != sctl->len)
945 goto out;
946
947 data = data + 2;
948 pos = 0;
949 while (pos < len) {
950 if (len - pos < 2)
951 goto out;
952
953 sct_len = (data[pos] << 8) | data[pos + 1];
954 if (pos + sct_len + 2 > len)
955 goto out;
956
957 pos += sct_len + 2;
958 }
959
960 ret = 0;
961
962out:
963 return ret;
964}
965
966static int ssl_sock_load_sctl_from_file(const char *sctl_path, struct chunk **sctl)
967{
968 int fd = -1;
969 int r = 0;
970 int ret = 1;
971
972 *sctl = NULL;
973
974 fd = open(sctl_path, O_RDONLY);
975 if (fd == -1)
976 goto end;
977
978 trash.len = 0;
979 while (trash.len < trash.size) {
980 r = read(fd, trash.str + trash.len, trash.size - trash.len);
981 if (r < 0) {
982 if (errno == EINTR)
983 continue;
984
985 goto end;
986 }
987 else if (r == 0) {
988 break;
989 }
990 trash.len += r;
991 }
992
993 ret = ssl_sock_parse_sctl(&trash);
994 if (ret)
995 goto end;
996
Vincent Bernat02779b62016-04-03 13:48:43 +0200997 *sctl = calloc(1, sizeof(**sctl));
Janusz Dziemidowicz2c701b52015-03-07 23:03:59 +0100998 if (!chunk_dup(*sctl, &trash)) {
999 free(*sctl);
1000 *sctl = NULL;
1001 goto end;
1002 }
1003
1004end:
1005 if (fd != -1)
1006 close(fd);
1007
1008 return ret;
1009}
1010
1011int ssl_sock_sctl_add_cbk(SSL *ssl, unsigned ext_type, const unsigned char **out, size_t *outlen, int *al, void *add_arg)
1012{
Vincent Bernat3c2f2f22016-04-03 13:48:42 +02001013 struct chunk *sctl = add_arg;
Janusz Dziemidowicz2c701b52015-03-07 23:03:59 +01001014
1015 *out = (unsigned char *)sctl->str;
1016 *outlen = sctl->len;
1017
1018 return 1;
1019}
1020
1021int ssl_sock_sctl_parse_cbk(SSL *s, unsigned int ext_type, const unsigned char *in, size_t inlen, int *al, void *parse_arg)
1022{
1023 return 1;
1024}
1025
1026static int ssl_sock_load_sctl(SSL_CTX *ctx, const char *cert_path)
1027{
1028 char sctl_path[MAXPATHLEN+1];
1029 int ret = -1;
1030 struct stat st;
1031 struct chunk *sctl = NULL;
1032
1033 snprintf(sctl_path, MAXPATHLEN+1, "%s.sctl", cert_path);
1034
1035 if (stat(sctl_path, &st))
1036 return 1;
1037
1038 if (ssl_sock_load_sctl_from_file(sctl_path, &sctl))
1039 goto out;
1040
1041 if (!SSL_CTX_add_server_custom_ext(ctx, CT_EXTENSION_TYPE, ssl_sock_sctl_add_cbk, NULL, sctl, ssl_sock_sctl_parse_cbk, NULL)) {
1042 free(sctl);
1043 goto out;
1044 }
1045
1046 SSL_CTX_set_ex_data(ctx, sctl_ex_index, sctl);
1047
1048 ret = 0;
1049
1050out:
1051 return ret;
1052}
1053
1054#endif
1055
Emeric Brune1f38db2012-09-03 20:36:47 +02001056void ssl_sock_infocbk(const SSL *ssl, int where, int ret)
1057{
Vincent Bernat3c2f2f22016-04-03 13:48:42 +02001058 struct connection *conn = SSL_get_app_data(ssl);
Emeric Brund8b2bb52014-01-28 15:43:53 +01001059 BIO *write_bio;
Willy Tarreau622317d2015-02-27 16:36:16 +01001060 (void)ret; /* shut gcc stupid warning */
Emeric Brune1f38db2012-09-03 20:36:47 +02001061
1062 if (where & SSL_CB_HANDSHAKE_START) {
1063 /* Disable renegotiation (CVE-2009-3555) */
Willy Tarreau20879a02012-12-03 16:32:10 +01001064 if (conn->flags & CO_FL_CONNECTED) {
Emeric Brune1f38db2012-09-03 20:36:47 +02001065 conn->flags |= CO_FL_ERROR;
Willy Tarreau20879a02012-12-03 16:32:10 +01001066 conn->err_code = CO_ER_SSL_RENEG;
1067 }
Emeric Brune1f38db2012-09-03 20:36:47 +02001068 }
Emeric Brund8b2bb52014-01-28 15:43:53 +01001069
1070 if ((where & SSL_CB_ACCEPT_LOOP) == SSL_CB_ACCEPT_LOOP) {
1071 if (!(conn->xprt_st & SSL_SOCK_ST_FL_16K_WBFSIZE)) {
1072 /* Long certificate chains optimz
1073 If write and read bios are differents, we
1074 consider that the buffering was activated,
1075 so we rise the output buffer size from 4k
1076 to 16k */
1077 write_bio = SSL_get_wbio(ssl);
1078 if (write_bio != SSL_get_rbio(ssl)) {
1079 BIO_set_write_buffer_size(write_bio, 16384);
1080 conn->xprt_st |= SSL_SOCK_ST_FL_16K_WBFSIZE;
1081 }
1082 }
1083 }
Emeric Brunfc0421f2012-09-07 17:30:07 +02001084}
1085
Emeric Brune64aef12012-09-21 13:15:06 +02001086/* Callback is called for each certificate of the chain during a verify
1087 ok is set to 1 if preverify detect no error on current certificate.
1088 Returns 0 to break the handshake, 1 otherwise. */
Evan Broderbe554312013-06-27 00:05:25 -07001089int ssl_sock_bind_verifycbk(int ok, X509_STORE_CTX *x_store)
Emeric Brune64aef12012-09-21 13:15:06 +02001090{
1091 SSL *ssl;
1092 struct connection *conn;
Emeric Brun81c00f02012-09-21 14:31:21 +02001093 int err, depth;
Emeric Brune64aef12012-09-21 13:15:06 +02001094
1095 ssl = X509_STORE_CTX_get_ex_data(x_store, SSL_get_ex_data_X509_STORE_CTX_idx());
Vincent Bernat3c2f2f22016-04-03 13:48:42 +02001096 conn = SSL_get_app_data(ssl);
Emeric Brune64aef12012-09-21 13:15:06 +02001097
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02001098 conn->xprt_st |= SSL_SOCK_ST_FL_VERIFY_DONE;
Emeric Brune64aef12012-09-21 13:15:06 +02001099
Emeric Brun81c00f02012-09-21 14:31:21 +02001100 if (ok) /* no errors */
1101 return ok;
1102
1103 depth = X509_STORE_CTX_get_error_depth(x_store);
1104 err = X509_STORE_CTX_get_error(x_store);
1105
1106 /* check if CA error needs to be ignored */
1107 if (depth > 0) {
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02001108 if (!SSL_SOCK_ST_TO_CA_ERROR(conn->xprt_st)) {
1109 conn->xprt_st |= SSL_SOCK_CA_ERROR_TO_ST(err);
1110 conn->xprt_st |= SSL_SOCK_CAEDEPTH_TO_ST(depth);
Emeric Brunf282a812012-09-21 15:27:54 +02001111 }
1112
Emeric Brun1eb20ef2012-12-03 13:24:29 +01001113 if (objt_listener(conn->target)->bind_conf->ca_ignerr & (1ULL << err)) {
Thierry FOURNIER / OZON.IO8b068c22016-10-10 11:59:50 +02001114 ssl_sock_dump_errors(conn);
Emeric Brun1eb20ef2012-12-03 13:24:29 +01001115 ERR_clear_error();
Emeric Brun81c00f02012-09-21 14:31:21 +02001116 return 1;
Emeric Brun1eb20ef2012-12-03 13:24:29 +01001117 }
Emeric Brun81c00f02012-09-21 14:31:21 +02001118
Willy Tarreau20879a02012-12-03 16:32:10 +01001119 conn->err_code = CO_ER_SSL_CA_FAIL;
Emeric Brun81c00f02012-09-21 14:31:21 +02001120 return 0;
1121 }
1122
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02001123 if (!SSL_SOCK_ST_TO_CRTERROR(conn->xprt_st))
1124 conn->xprt_st |= SSL_SOCK_CRTERROR_TO_ST(err);
Emeric Brunf282a812012-09-21 15:27:54 +02001125
Emeric Brun81c00f02012-09-21 14:31:21 +02001126 /* check if certificate error needs to be ignored */
Emeric Brun1eb20ef2012-12-03 13:24:29 +01001127 if (objt_listener(conn->target)->bind_conf->crt_ignerr & (1ULL << err)) {
Thierry FOURNIER / OZON.IO8b068c22016-10-10 11:59:50 +02001128 ssl_sock_dump_errors(conn);
Emeric Brun1eb20ef2012-12-03 13:24:29 +01001129 ERR_clear_error();
Emeric Brun81c00f02012-09-21 14:31:21 +02001130 return 1;
Emeric Brun1eb20ef2012-12-03 13:24:29 +01001131 }
Emeric Brun81c00f02012-09-21 14:31:21 +02001132
Willy Tarreau20879a02012-12-03 16:32:10 +01001133 conn->err_code = CO_ER_SSL_CRT_FAIL;
Emeric Brun81c00f02012-09-21 14:31:21 +02001134 return 0;
Emeric Brune64aef12012-09-21 13:15:06 +02001135}
1136
Emeric Brun29f037d2014-04-25 19:05:36 +02001137/* Callback is called for ssl protocol analyse */
1138void ssl_sock_msgcbk(int write_p, int version, int content_type, const void *buf, size_t len, SSL *ssl, void *arg)
1139{
Emeric Brun29f037d2014-04-25 19:05:36 +02001140#ifdef TLS1_RT_HEARTBEAT
1141 /* test heartbeat received (write_p is set to 0
1142 for a received record) */
Willy Tarreauf51c6982014-04-25 20:02:39 +02001143 if ((content_type == TLS1_RT_HEARTBEAT) && (write_p == 0)) {
Vincent Bernat3c2f2f22016-04-03 13:48:42 +02001144 struct connection *conn = SSL_get_app_data(ssl);
Willy Tarreauf51c6982014-04-25 20:02:39 +02001145 const unsigned char *p = buf;
1146 unsigned int payload;
1147
Emeric Brun29f037d2014-04-25 19:05:36 +02001148 conn->xprt_st |= SSL_SOCK_RECV_HEARTBEAT;
Willy Tarreauf51c6982014-04-25 20:02:39 +02001149
1150 /* Check if this is a CVE-2014-0160 exploitation attempt. */
1151 if (*p != TLS1_HB_REQUEST)
1152 return;
1153
Willy Tarreauaeed6722014-04-25 23:59:58 +02001154 if (len < 1 + 2 + 16) /* 1 type + 2 size + 0 payload + 16 padding */
Willy Tarreauf51c6982014-04-25 20:02:39 +02001155 goto kill_it;
1156
1157 payload = (p[1] * 256) + p[2];
Willy Tarreau3b2fdb62014-04-25 23:44:22 +02001158 if (3 + payload + 16 <= len)
Willy Tarreauf51c6982014-04-25 20:02:39 +02001159 return; /* OK no problem */
Willy Tarreauaeed6722014-04-25 23:59:58 +02001160 kill_it:
Willy Tarreau3b2fdb62014-04-25 23:44:22 +02001161 /* We have a clear heartbleed attack (CVE-2014-0160), the
1162 * advertised payload is larger than the advertised packet
1163 * length, so we have garbage in the buffer between the
1164 * payload and the end of the buffer (p+len). We can't know
1165 * if the SSL stack is patched, and we don't know if we can
1166 * safely wipe out the area between p+3+len and payload.
1167 * So instead, we prevent the response from being sent by
1168 * setting the max_send_fragment to 0 and we report an SSL
1169 * error, which will kill this connection. It will be reported
1170 * above as SSL_ERROR_SSL while an other handshake failure with
Willy Tarreauf51c6982014-04-25 20:02:39 +02001171 * a heartbeat message will be reported as SSL_ERROR_SYSCALL.
1172 */
Willy Tarreau3b2fdb62014-04-25 23:44:22 +02001173 ssl->max_send_fragment = 0;
Willy Tarreauf51c6982014-04-25 20:02:39 +02001174 SSLerr(SSL_F_TLS1_HEARTBEAT, SSL_R_SSL_HANDSHAKE_FAILURE);
1175 return;
1176 }
Emeric Brun29f037d2014-04-25 19:05:36 +02001177#endif
1178}
1179
Willy Tarreau6c9a3d52012-10-18 18:57:14 +02001180#ifdef OPENSSL_NPN_NEGOTIATED
1181/* This callback is used so that the server advertises the list of
1182 * negociable protocols for NPN.
1183 */
1184static int ssl_sock_advertise_npn_protos(SSL *s, const unsigned char **data,
1185 unsigned int *len, void *arg)
1186{
Emmanuel Hocdet98263292016-12-29 18:26:15 +01001187 struct ssl_bind_conf *conf = arg;
Willy Tarreau6c9a3d52012-10-18 18:57:14 +02001188
1189 *data = (const unsigned char *)conf->npn_str;
1190 *len = conf->npn_len;
1191 return SSL_TLSEXT_ERR_OK;
1192}
1193#endif
1194
Dirkjan Bussink48f1c4e2014-02-13 12:29:42 +01001195#ifdef TLSEXT_TYPE_application_layer_protocol_negotiation
Willy Tarreauab861d32013-04-02 02:30:41 +02001196/* This callback is used so that the server advertises the list of
1197 * negociable protocols for ALPN.
1198 */
Dirkjan Bussink48f1c4e2014-02-13 12:29:42 +01001199static int ssl_sock_advertise_alpn_protos(SSL *s, const unsigned char **out,
1200 unsigned char *outlen,
1201 const unsigned char *server,
1202 unsigned int server_len, void *arg)
Willy Tarreauab861d32013-04-02 02:30:41 +02001203{
Emmanuel Hocdet98263292016-12-29 18:26:15 +01001204 struct ssl_bind_conf *conf = arg;
Willy Tarreauab861d32013-04-02 02:30:41 +02001205
Dirkjan Bussink48f1c4e2014-02-13 12:29:42 +01001206 if (SSL_select_next_proto((unsigned char**) out, outlen, (const unsigned char *)conf->alpn_str,
1207 conf->alpn_len, server, server_len) != OPENSSL_NPN_NEGOTIATED) {
1208 return SSL_TLSEXT_ERR_NOACK;
1209 }
Willy Tarreauab861d32013-04-02 02:30:41 +02001210 return SSL_TLSEXT_ERR_OK;
1211}
1212#endif
1213
Willy Tarreauc8ad3be2015-06-17 15:48:26 +02001214#ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME
Christopher Faulet85b5a1a2015-10-09 11:46:32 +02001215static DH *ssl_get_tmp_dh(SSL *ssl, int export, int keylen);
1216
Christopher Faulet30548802015-06-11 13:39:32 +02001217/* Create a X509 certificate with the specified servername and serial. This
1218 * function returns a SSL_CTX object or NULL if an error occurs. */
Christopher Faulet7969a332015-10-09 11:15:03 +02001219static SSL_CTX *
Christopher Faulet635c0ad2015-11-12 11:35:51 +01001220ssl_sock_do_create_cert(const char *servername, struct bind_conf *bind_conf, SSL *ssl)
Christopher Faulet31af49d2015-06-09 17:29:50 +02001221{
Christopher Faulet635c0ad2015-11-12 11:35:51 +01001222 static unsigned int serial = 0;
1223
Christopher Faulet7969a332015-10-09 11:15:03 +02001224 X509 *cacert = bind_conf->ca_sign_cert;
1225 EVP_PKEY *capkey = bind_conf->ca_sign_pkey;
Christopher Faulet31af49d2015-06-09 17:29:50 +02001226 SSL_CTX *ssl_ctx = NULL;
1227 X509 *newcrt = NULL;
1228 EVP_PKEY *pkey = NULL;
Christopher Faulet31af49d2015-06-09 17:29:50 +02001229 X509_NAME *name;
1230 const EVP_MD *digest;
1231 X509V3_CTX ctx;
1232 unsigned int i;
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02001233 int key_type;
Christopher Faulet31af49d2015-06-09 17:29:50 +02001234
Christopher Faulet7969a332015-10-09 11:15:03 +02001235 /* Get the private key of the defautl certificate and use it */
1236 if (!(pkey = SSL_get_privatekey(ssl)))
Christopher Faulet31af49d2015-06-09 17:29:50 +02001237 goto mkcert_error;
1238
1239 /* Create the certificate */
1240 if (!(newcrt = X509_new()))
1241 goto mkcert_error;
1242
1243 /* Set version number for the certificate (X509v3) and the serial
1244 * number */
1245 if (X509_set_version(newcrt, 2L) != 1)
1246 goto mkcert_error;
Christopher Faulet635c0ad2015-11-12 11:35:51 +01001247 if (!serial)
1248 serial = now_ms;
1249 ASN1_INTEGER_set(X509_get_serialNumber(newcrt), serial++);
Christopher Faulet31af49d2015-06-09 17:29:50 +02001250
1251 /* Set duration for the certificate */
1252 if (!X509_gmtime_adj(X509_get_notBefore(newcrt), (long)-60*60*24) ||
1253 !X509_gmtime_adj(X509_get_notAfter(newcrt),(long)60*60*24*365))
1254 goto mkcert_error;
1255
1256 /* set public key in the certificate */
1257 if (X509_set_pubkey(newcrt, pkey) != 1)
1258 goto mkcert_error;
1259
1260 /* Set issuer name from the CA */
1261 if (!(name = X509_get_subject_name(cacert)))
1262 goto mkcert_error;
1263 if (X509_set_issuer_name(newcrt, name) != 1)
1264 goto mkcert_error;
1265
1266 /* Set the subject name using the same, but the CN */
1267 name = X509_NAME_dup(name);
1268 if (X509_NAME_add_entry_by_txt(name, "CN", MBSTRING_ASC,
1269 (const unsigned char *)servername,
1270 -1, -1, 0) != 1) {
1271 X509_NAME_free(name);
1272 goto mkcert_error;
1273 }
1274 if (X509_set_subject_name(newcrt, name) != 1) {
1275 X509_NAME_free(name);
1276 goto mkcert_error;
1277 }
1278 X509_NAME_free(name);
1279
1280 /* Add x509v3 extensions as specified */
1281 X509V3_set_ctx(&ctx, cacert, newcrt, NULL, NULL, 0);
1282 for (i = 0; i < X509V3_EXT_SIZE; i++) {
1283 X509_EXTENSION *ext;
1284
1285 if (!(ext = X509V3_EXT_conf(NULL, &ctx, x509v3_ext_names[i], x509v3_ext_values[i])))
1286 goto mkcert_error;
1287 if (!X509_add_ext(newcrt, ext, -1)) {
1288 X509_EXTENSION_free(ext);
1289 goto mkcert_error;
1290 }
1291 X509_EXTENSION_free(ext);
1292 }
1293
1294 /* Sign the certificate with the CA private key */
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02001295
1296 key_type = EVP_PKEY_base_id(capkey);
1297
1298 if (key_type == EVP_PKEY_DSA)
1299 digest = EVP_sha1();
1300 else if (key_type == EVP_PKEY_RSA)
Christopher Faulet31af49d2015-06-09 17:29:50 +02001301 digest = EVP_sha256();
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02001302 else if (key_type == EVP_PKEY_EC)
Christopher Faulet7969a332015-10-09 11:15:03 +02001303 digest = EVP_sha256();
1304 else {
Christopher Faulete7db2162015-10-19 13:59:24 +02001305#if (OPENSSL_VERSION_NUMBER >= 0x1000000fL)
Christopher Faulet7969a332015-10-09 11:15:03 +02001306 int nid;
1307
1308 if (EVP_PKEY_get_default_digest_nid(capkey, &nid) <= 0)
1309 goto mkcert_error;
1310 if (!(digest = EVP_get_digestbynid(nid)))
1311 goto mkcert_error;
Christopher Faulete7db2162015-10-19 13:59:24 +02001312#else
1313 goto mkcert_error;
1314#endif
Christopher Faulet7969a332015-10-09 11:15:03 +02001315 }
1316
Christopher Faulet31af49d2015-06-09 17:29:50 +02001317 if (!(X509_sign(newcrt, capkey, digest)))
1318 goto mkcert_error;
1319
1320 /* Create and set the new SSL_CTX */
1321 if (!(ssl_ctx = SSL_CTX_new(SSLv23_server_method())))
1322 goto mkcert_error;
1323 if (!SSL_CTX_use_PrivateKey(ssl_ctx, pkey))
1324 goto mkcert_error;
1325 if (!SSL_CTX_use_certificate(ssl_ctx, newcrt))
1326 goto mkcert_error;
1327 if (!SSL_CTX_check_private_key(ssl_ctx))
1328 goto mkcert_error;
1329
1330 if (newcrt) X509_free(newcrt);
Christopher Faulet7969a332015-10-09 11:15:03 +02001331
Christopher Faulet85b5a1a2015-10-09 11:46:32 +02001332 SSL_CTX_set_tmp_dh_callback(ssl_ctx, ssl_get_tmp_dh);
1333#if defined(SSL_CTX_set_tmp_ecdh) && !defined(OPENSSL_NO_ECDH)
1334 {
Emmanuel Hocdet98263292016-12-29 18:26:15 +01001335 const char *ecdhe = (bind_conf->ssl_conf.ecdhe ? bind_conf->ssl_conf.ecdhe : ECDHE_DEFAULT_CURVE);
Christopher Faulet85b5a1a2015-10-09 11:46:32 +02001336 EC_KEY *ecc;
1337 int nid;
1338
1339 if ((nid = OBJ_sn2nid(ecdhe)) == NID_undef)
1340 goto end;
1341 if (!(ecc = EC_KEY_new_by_curve_name(nid)))
1342 goto end;
1343 SSL_CTX_set_tmp_ecdh(ssl_ctx, ecc);
1344 EC_KEY_free(ecc);
1345 }
1346#endif
1347 end:
Christopher Faulet31af49d2015-06-09 17:29:50 +02001348 return ssl_ctx;
1349
1350 mkcert_error:
1351 if (ssl_ctx) SSL_CTX_free(ssl_ctx);
1352 if (newcrt) X509_free(newcrt);
Christopher Faulet31af49d2015-06-09 17:29:50 +02001353 return NULL;
1354}
1355
Christopher Faulet7969a332015-10-09 11:15:03 +02001356SSL_CTX *
Christopher Faulet635c0ad2015-11-12 11:35:51 +01001357ssl_sock_create_cert(struct connection *conn, const char *servername, unsigned int key)
Christopher Faulet7969a332015-10-09 11:15:03 +02001358{
1359 struct bind_conf *bind_conf = objt_listener(conn->target)->bind_conf;
Christopher Faulet635c0ad2015-11-12 11:35:51 +01001360
1361 return ssl_sock_do_create_cert(servername, bind_conf, conn->xprt_ctx);
Christopher Faulet7969a332015-10-09 11:15:03 +02001362}
1363
Christopher Faulet30548802015-06-11 13:39:32 +02001364/* Do a lookup for a certificate in the LRU cache used to store generated
1365 * certificates. */
1366SSL_CTX *
Christopher Faulet635c0ad2015-11-12 11:35:51 +01001367ssl_sock_get_generated_cert(unsigned int key, struct bind_conf *bind_conf)
Christopher Faulet30548802015-06-11 13:39:32 +02001368{
1369 struct lru64 *lru = NULL;
1370
1371 if (ssl_ctx_lru_tree) {
Christopher Faulet635c0ad2015-11-12 11:35:51 +01001372 lru = lru64_lookup(key, ssl_ctx_lru_tree, bind_conf->ca_sign_cert, 0);
Christopher Faulet30548802015-06-11 13:39:32 +02001373 if (lru && lru->domain)
1374 return (SSL_CTX *)lru->data;
1375 }
1376 return NULL;
1377}
1378
Christopher Fauletd2cab922015-07-28 16:03:47 +02001379/* Set a certificate int the LRU cache used to store generated
1380 * certificate. Return 0 on success, otherwise -1 */
1381int
Christopher Faulet635c0ad2015-11-12 11:35:51 +01001382ssl_sock_set_generated_cert(SSL_CTX *ssl_ctx, unsigned int key, struct bind_conf *bind_conf)
Christopher Faulet30548802015-06-11 13:39:32 +02001383{
1384 struct lru64 *lru = NULL;
1385
1386 if (ssl_ctx_lru_tree) {
Christopher Faulet635c0ad2015-11-12 11:35:51 +01001387 lru = lru64_get(key, ssl_ctx_lru_tree, bind_conf->ca_sign_cert, 0);
Christopher Faulet30548802015-06-11 13:39:32 +02001388 if (!lru)
Christopher Fauletd2cab922015-07-28 16:03:47 +02001389 return -1;
Christopher Faulet30548802015-06-11 13:39:32 +02001390 if (lru->domain && lru->data)
1391 lru->free((SSL_CTX *)lru->data);
Christopher Faulet7969a332015-10-09 11:15:03 +02001392 lru64_commit(lru, ssl_ctx, bind_conf->ca_sign_cert, 0, (void (*)(void *))SSL_CTX_free);
Christopher Fauletd2cab922015-07-28 16:03:47 +02001393 return 0;
Christopher Faulet30548802015-06-11 13:39:32 +02001394 }
Christopher Fauletd2cab922015-07-28 16:03:47 +02001395 return -1;
Christopher Faulet30548802015-06-11 13:39:32 +02001396}
1397
Christopher Faulet635c0ad2015-11-12 11:35:51 +01001398/* Compute the key of the certificate. */
Christopher Faulet30548802015-06-11 13:39:32 +02001399unsigned int
Christopher Faulet635c0ad2015-11-12 11:35:51 +01001400ssl_sock_generated_cert_key(const void *data, size_t len)
Christopher Faulet30548802015-06-11 13:39:32 +02001401{
1402 return XXH32(data, len, ssl_ctx_lru_seed);
1403}
1404
Willy Tarreau2f63ef42015-10-20 15:16:01 +02001405/* Generate a cert and immediately assign it to the SSL session so that the cert's
1406 * refcount is maintained regardless of the cert's presence in the LRU cache.
1407 */
Christopher Faulet31af49d2015-06-09 17:29:50 +02001408static SSL_CTX *
Christopher Faulet7969a332015-10-09 11:15:03 +02001409ssl_sock_generate_certificate(const char *servername, struct bind_conf *bind_conf, SSL *ssl)
Christopher Faulet31af49d2015-06-09 17:29:50 +02001410{
1411 X509 *cacert = bind_conf->ca_sign_cert;
Christopher Faulet31af49d2015-06-09 17:29:50 +02001412 SSL_CTX *ssl_ctx = NULL;
1413 struct lru64 *lru = NULL;
Christopher Faulet635c0ad2015-11-12 11:35:51 +01001414 unsigned int key;
Christopher Faulet31af49d2015-06-09 17:29:50 +02001415
Christopher Faulet635c0ad2015-11-12 11:35:51 +01001416 key = ssl_sock_generated_cert_key(servername, strlen(servername));
Christopher Faulet31af49d2015-06-09 17:29:50 +02001417 if (ssl_ctx_lru_tree) {
Christopher Faulet635c0ad2015-11-12 11:35:51 +01001418 lru = lru64_get(key, ssl_ctx_lru_tree, cacert, 0);
Christopher Faulet31af49d2015-06-09 17:29:50 +02001419 if (lru && lru->domain)
1420 ssl_ctx = (SSL_CTX *)lru->data;
Christopher Fauletd2cab922015-07-28 16:03:47 +02001421 if (!ssl_ctx && lru) {
Christopher Faulet635c0ad2015-11-12 11:35:51 +01001422 ssl_ctx = ssl_sock_do_create_cert(servername, bind_conf, ssl);
Christopher Faulet31af49d2015-06-09 17:29:50 +02001423 lru64_commit(lru, ssl_ctx, cacert, 0, (void (*)(void *))SSL_CTX_free);
Christopher Fauletd2cab922015-07-28 16:03:47 +02001424 }
Willy Tarreau2f63ef42015-10-20 15:16:01 +02001425 SSL_set_SSL_CTX(ssl, ssl_ctx);
Christopher Faulet31af49d2015-06-09 17:29:50 +02001426 }
Willy Tarreau2f63ef42015-10-20 15:16:01 +02001427 else {
Christopher Faulet635c0ad2015-11-12 11:35:51 +01001428 ssl_ctx = ssl_sock_do_create_cert(servername, bind_conf, ssl);
Willy Tarreau2f63ef42015-10-20 15:16:01 +02001429 SSL_set_SSL_CTX(ssl, ssl_ctx);
1430 /* No LRU cache, this CTX will be released as soon as the session dies */
1431 SSL_CTX_free(ssl_ctx);
1432 }
Christopher Faulet31af49d2015-06-09 17:29:50 +02001433 return ssl_ctx;
1434}
1435
Emeric Brunfc0421f2012-09-07 17:30:07 +02001436/* Sets the SSL ctx of <ssl> to match the advertised server name. Returns a
1437 * warning when no match is found, which implies the default (first) cert
1438 * will keep being used.
1439 */
Willy Tarreau2a65ff02012-09-13 17:54:29 +02001440static int ssl_sock_switchctx_cbk(SSL *ssl, int *al, struct bind_conf *s)
Emeric Brunfc0421f2012-09-07 17:30:07 +02001441{
1442 const char *servername;
1443 const char *wildp = NULL;
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +02001444 struct ebmb_node *node, *n;
Emeric Brunfc0421f2012-09-07 17:30:07 +02001445 int i;
1446 (void)al; /* shut gcc stupid warning */
1447
1448 servername = SSL_get_servername(ssl, TLSEXT_NAMETYPE_host_name);
Emmanuel Hocdet65623372013-01-24 17:17:15 +01001449 if (!servername) {
Willy Tarreauf6721452015-07-07 18:04:38 +02001450 if (s->generate_certs) {
Vincent Bernat3c2f2f22016-04-03 13:48:42 +02001451 struct connection *conn = SSL_get_app_data(ssl);
Christopher Faulet635c0ad2015-11-12 11:35:51 +01001452 unsigned int key;
Willy Tarreauf6721452015-07-07 18:04:38 +02001453 SSL_CTX *ctx;
Christopher Faulet30548802015-06-11 13:39:32 +02001454
Willy Tarreauf6721452015-07-07 18:04:38 +02001455 conn_get_to_addr(conn);
1456 if (conn->flags & CO_FL_ADDR_TO_SET) {
Christopher Faulet635c0ad2015-11-12 11:35:51 +01001457 key = ssl_sock_generated_cert_key(&conn->addr.to, get_addr_len(&conn->addr.to));
1458 ctx = ssl_sock_get_generated_cert(key, s);
Willy Tarreauf6721452015-07-07 18:04:38 +02001459 if (ctx) {
1460 /* switch ctx */
1461 SSL_set_SSL_CTX(ssl, ctx);
1462 return SSL_TLSEXT_ERR_OK;
1463 }
Christopher Faulet30548802015-06-11 13:39:32 +02001464 }
1465 }
1466
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +02001467 return (s->strict_sni ?
1468 SSL_TLSEXT_ERR_ALERT_FATAL :
Emmanuel Hocdet79274e22013-05-31 12:47:44 +02001469 SSL_TLSEXT_ERR_NOACK);
Emmanuel Hocdet65623372013-01-24 17:17:15 +01001470 }
Emeric Brunfc0421f2012-09-07 17:30:07 +02001471
Willy Tarreau19d14ef2012-10-29 16:51:55 +01001472 for (i = 0; i < trash.size; i++) {
Emeric Brunfc0421f2012-09-07 17:30:07 +02001473 if (!servername[i])
1474 break;
Willy Tarreau19d14ef2012-10-29 16:51:55 +01001475 trash.str[i] = tolower(servername[i]);
1476 if (!wildp && (trash.str[i] == '.'))
1477 wildp = &trash.str[i];
Emeric Brunfc0421f2012-09-07 17:30:07 +02001478 }
Willy Tarreau19d14ef2012-10-29 16:51:55 +01001479 trash.str[i] = 0;
Emeric Brunfc0421f2012-09-07 17:30:07 +02001480
1481 /* lookup in full qualified names */
Willy Tarreau19d14ef2012-10-29 16:51:55 +01001482 node = ebst_lookup(&s->sni_ctx, trash.str);
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +02001483
1484 /* lookup a not neg filter */
1485 for (n = node; n; n = ebmb_next_dup(n)) {
1486 if (!container_of(n, struct sni_ctx, name)->neg) {
1487 node = n;
1488 break;
Emmanuel Hocdet65623372013-01-24 17:17:15 +01001489 }
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +02001490 }
1491 if (!node && wildp) {
1492 /* lookup in wildcards names */
Emeric Brunfc0421f2012-09-07 17:30:07 +02001493 node = ebst_lookup(&s->sni_w_ctx, wildp);
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +02001494 }
1495 if (!node || container_of(node, struct sni_ctx, name)->neg) {
Christopher Faulet31af49d2015-06-09 17:29:50 +02001496 SSL_CTX *ctx;
Christopher Faulet31af49d2015-06-09 17:29:50 +02001497 if (s->generate_certs &&
Christopher Faulet7969a332015-10-09 11:15:03 +02001498 (ctx = ssl_sock_generate_certificate(servername, s, ssl))) {
Christopher Faulet31af49d2015-06-09 17:29:50 +02001499 /* switch ctx */
Christopher Faulet31af49d2015-06-09 17:29:50 +02001500 return SSL_TLSEXT_ERR_OK;
1501 }
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +02001502 return (s->strict_sni ?
1503 SSL_TLSEXT_ERR_ALERT_FATAL :
1504 SSL_TLSEXT_ERR_ALERT_WARNING);
Emeric Brunfc0421f2012-09-07 17:30:07 +02001505 }
1506
1507 /* switch ctx */
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +02001508 SSL_set_SSL_CTX(ssl, container_of(node, struct sni_ctx, name)->ctx);
Emeric Brunfc0421f2012-09-07 17:30:07 +02001509 return SSL_TLSEXT_ERR_OK;
1510}
1511#endif /* SSL_CTRL_SET_TLSEXT_HOSTNAME */
1512
Emeric Bruna4bcd9a2012-09-20 16:19:02 +02001513#ifndef OPENSSL_NO_DH
Remi Gacognef46cd6e2014-06-12 14:58:40 +02001514
1515static DH * ssl_get_dh_1024(void)
1516{
Remi Gacogned3a341a2015-05-29 16:26:17 +02001517 static unsigned char dh1024_p[]={
1518 0xFA,0xF9,0x2A,0x22,0x2A,0xA7,0x7F,0xE1,0x67,0x4E,0x53,0xF7,
1519 0x56,0x13,0xC3,0xB1,0xE3,0x29,0x6B,0x66,0x31,0x6A,0x7F,0xB3,
1520 0xC2,0x68,0x6B,0xCB,0x1D,0x57,0x39,0x1D,0x1F,0xFF,0x1C,0xC9,
1521 0xA6,0xA4,0x98,0x82,0x31,0x5D,0x25,0xFF,0x8A,0xE0,0x73,0x96,
1522 0x81,0xC8,0x83,0x79,0xC1,0x5A,0x04,0xF8,0x37,0x0D,0xA8,0x3D,
1523 0xAE,0x74,0xBC,0xDB,0xB6,0xA4,0x75,0xD9,0x71,0x8A,0xA0,0x17,
1524 0x9E,0x2D,0xC8,0xA8,0xDF,0x2C,0x5F,0x82,0x95,0xF8,0x92,0x9B,
1525 0xA7,0x33,0x5F,0x89,0x71,0xC8,0x2D,0x6B,0x18,0x86,0xC4,0x94,
1526 0x22,0xA5,0x52,0x8D,0xF6,0xF6,0xD2,0x37,0x92,0x0F,0xA5,0xCC,
1527 0xDB,0x7B,0x1D,0x3D,0xA1,0x31,0xB7,0x80,0x8F,0x0B,0x67,0x5E,
1528 0x36,0xA5,0x60,0x0C,0xF1,0x95,0x33,0x8B,
1529 };
1530 static unsigned char dh1024_g[]={
1531 0x02,
1532 };
1533
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02001534 BIGNUM *p;
1535 BIGNUM *g;
Remi Gacognef46cd6e2014-06-12 14:58:40 +02001536 DH *dh = DH_new();
1537 if (dh) {
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02001538 p = BN_bin2bn(dh1024_p, sizeof dh1024_p, NULL);
1539 g = BN_bin2bn(dh1024_g, sizeof dh1024_g, NULL);
Remi Gacogned3a341a2015-05-29 16:26:17 +02001540
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02001541 if (!p || !g) {
Remi Gacognef46cd6e2014-06-12 14:58:40 +02001542 DH_free(dh);
1543 dh = NULL;
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02001544 } else {
1545 DH_set0_pqg(dh, p, NULL, g);
Remi Gacognef46cd6e2014-06-12 14:58:40 +02001546 }
1547 }
1548 return dh;
1549}
1550
1551static DH *ssl_get_dh_2048(void)
1552{
Remi Gacogned3a341a2015-05-29 16:26:17 +02001553 static unsigned char dh2048_p[]={
1554 0xEC,0x86,0xF8,0x70,0xA0,0x33,0x16,0xEC,0x05,0x1A,0x73,0x59,
1555 0xCD,0x1F,0x8B,0xF8,0x29,0xE4,0xD2,0xCF,0x52,0xDD,0xC2,0x24,
1556 0x8D,0xB5,0x38,0x9A,0xFB,0x5C,0xA4,0xE4,0xB2,0xDA,0xCE,0x66,
1557 0x50,0x74,0xA6,0x85,0x4D,0x4B,0x1D,0x30,0xB8,0x2B,0xF3,0x10,
1558 0xE9,0xA7,0x2D,0x05,0x71,0xE7,0x81,0xDF,0x8B,0x59,0x52,0x3B,
1559 0x5F,0x43,0x0B,0x68,0xF1,0xDB,0x07,0xBE,0x08,0x6B,0x1B,0x23,
1560 0xEE,0x4D,0xCC,0x9E,0x0E,0x43,0xA0,0x1E,0xDF,0x43,0x8C,0xEC,
1561 0xBE,0xBE,0x90,0xB4,0x51,0x54,0xB9,0x2F,0x7B,0x64,0x76,0x4E,
1562 0x5D,0xD4,0x2E,0xAE,0xC2,0x9E,0xAE,0x51,0x43,0x59,0xC7,0x77,
1563 0x9C,0x50,0x3C,0x0E,0xED,0x73,0x04,0x5F,0xF1,0x4C,0x76,0x2A,
1564 0xD8,0xF8,0xCF,0xFC,0x34,0x40,0xD1,0xB4,0x42,0x61,0x84,0x66,
1565 0x42,0x39,0x04,0xF8,0x68,0xB2,0x62,0xD7,0x55,0xED,0x1B,0x74,
1566 0x75,0x91,0xE0,0xC5,0x69,0xC1,0x31,0x5C,0xDB,0x7B,0x44,0x2E,
1567 0xCE,0x84,0x58,0x0D,0x1E,0x66,0x0C,0xC8,0x44,0x9E,0xFD,0x40,
1568 0x08,0x67,0x5D,0xFB,0xA7,0x76,0x8F,0x00,0x11,0x87,0xE9,0x93,
1569 0xF9,0x7D,0xC4,0xBC,0x74,0x55,0x20,0xD4,0x4A,0x41,0x2F,0x43,
1570 0x42,0x1A,0xC1,0xF2,0x97,0x17,0x49,0x27,0x37,0x6B,0x2F,0x88,
1571 0x7E,0x1C,0xA0,0xA1,0x89,0x92,0x27,0xD9,0x56,0x5A,0x71,0xC1,
1572 0x56,0x37,0x7E,0x3A,0x9D,0x05,0xE7,0xEE,0x5D,0x8F,0x82,0x17,
1573 0xBC,0xE9,0xC2,0x93,0x30,0x82,0xF9,0xF4,0xC9,0xAE,0x49,0xDB,
1574 0xD0,0x54,0xB4,0xD9,0x75,0x4D,0xFA,0x06,0xB8,0xD6,0x38,0x41,
1575 0xB7,0x1F,0x77,0xF3,
1576 };
1577 static unsigned char dh2048_g[]={
1578 0x02,
1579 };
1580
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02001581 BIGNUM *p;
1582 BIGNUM *g;
Remi Gacognef46cd6e2014-06-12 14:58:40 +02001583 DH *dh = DH_new();
1584 if (dh) {
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02001585 p = BN_bin2bn(dh2048_p, sizeof dh2048_p, NULL);
1586 g = BN_bin2bn(dh2048_g, sizeof dh2048_g, NULL);
Remi Gacogned3a341a2015-05-29 16:26:17 +02001587
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02001588 if (!p || !g) {
Remi Gacognef46cd6e2014-06-12 14:58:40 +02001589 DH_free(dh);
1590 dh = NULL;
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02001591 } else {
1592 DH_set0_pqg(dh, p, NULL, g);
Remi Gacognef46cd6e2014-06-12 14:58:40 +02001593 }
1594 }
1595 return dh;
1596}
1597
1598static DH *ssl_get_dh_4096(void)
1599{
Remi Gacogned3a341a2015-05-29 16:26:17 +02001600 static unsigned char dh4096_p[]={
1601 0xDE,0x16,0x94,0xCD,0x99,0x58,0x07,0xF1,0xF7,0x32,0x96,0x11,
1602 0x04,0x82,0xD4,0x84,0x72,0x80,0x99,0x06,0xCA,0xF0,0xA3,0x68,
1603 0x07,0xCE,0x64,0x50,0xE7,0x74,0x45,0x20,0x80,0x5E,0x4D,0xAD,
1604 0xA5,0xB6,0xED,0xFA,0x80,0x6C,0x3B,0x35,0xC4,0x9A,0x14,0x6B,
1605 0x32,0xBB,0xFD,0x1F,0x17,0x8E,0xB7,0x1F,0xD6,0xFA,0x3F,0x7B,
1606 0xEE,0x16,0xA5,0x62,0x33,0x0D,0xED,0xBC,0x4E,0x58,0xE5,0x47,
1607 0x4D,0xE9,0xAB,0x8E,0x38,0xD3,0x6E,0x90,0x57,0xE3,0x22,0x15,
1608 0x33,0xBD,0xF6,0x43,0x45,0xB5,0x10,0x0A,0xBE,0x2C,0xB4,0x35,
1609 0xB8,0x53,0x8D,0xAD,0xFB,0xA7,0x1F,0x85,0x58,0x41,0x7A,0x79,
1610 0x20,0x68,0xB3,0xE1,0x3D,0x08,0x76,0xBF,0x86,0x0D,0x49,0xE3,
1611 0x82,0x71,0x8C,0xB4,0x8D,0x81,0x84,0xD4,0xE7,0xBE,0x91,0xDC,
1612 0x26,0x39,0x48,0x0F,0x35,0xC4,0xCA,0x65,0xE3,0x40,0x93,0x52,
1613 0x76,0x58,0x7D,0xDD,0x51,0x75,0xDC,0x69,0x61,0xBF,0x47,0x2C,
1614 0x16,0x68,0x2D,0xC9,0x29,0xD3,0xE6,0xC0,0x99,0x48,0xA0,0x9A,
1615 0xC8,0x78,0xC0,0x6D,0x81,0x67,0x12,0x61,0x3F,0x71,0xBA,0x41,
1616 0x1F,0x6C,0x89,0x44,0x03,0xBA,0x3B,0x39,0x60,0xAA,0x28,0x55,
1617 0x59,0xAE,0xB8,0xFA,0xCB,0x6F,0xA5,0x1A,0xF7,0x2B,0xDD,0x52,
1618 0x8A,0x8B,0xE2,0x71,0xA6,0x5E,0x7E,0xD8,0x2E,0x18,0xE0,0x66,
1619 0xDF,0xDD,0x22,0x21,0x99,0x52,0x73,0xA6,0x33,0x20,0x65,0x0E,
1620 0x53,0xE7,0x6B,0x9B,0xC5,0xA3,0x2F,0x97,0x65,0x76,0xD3,0x47,
1621 0x23,0x77,0x12,0xB6,0x11,0x7B,0x24,0xED,0xF1,0xEF,0xC0,0xE2,
1622 0xA3,0x7E,0x67,0x05,0x3E,0x96,0x4D,0x45,0xC2,0x18,0xD1,0x73,
1623 0x9E,0x07,0xF3,0x81,0x6E,0x52,0x63,0xF6,0x20,0x76,0xB9,0x13,
1624 0xD2,0x65,0x30,0x18,0x16,0x09,0x16,0x9E,0x8F,0xF1,0xD2,0x10,
1625 0x5A,0xD3,0xD4,0xAF,0x16,0x61,0xDA,0x55,0x2E,0x18,0x5E,0x14,
1626 0x08,0x54,0x2E,0x2A,0x25,0xA2,0x1A,0x9B,0x8B,0x32,0xA9,0xFD,
1627 0xC2,0x48,0x96,0xE1,0x80,0xCA,0xE9,0x22,0x17,0xBB,0xCE,0x3E,
1628 0x9E,0xED,0xC7,0xF1,0x1F,0xEC,0x17,0x21,0xDC,0x7B,0x82,0x48,
1629 0x8E,0xBB,0x4B,0x9D,0x5B,0x04,0x04,0xDA,0xDB,0x39,0xDF,0x01,
1630 0x40,0xC3,0xAA,0x26,0x23,0x89,0x75,0xC6,0x0B,0xD0,0xA2,0x60,
1631 0x6A,0xF1,0xCC,0x65,0x18,0x98,0x1B,0x52,0xD2,0x74,0x61,0xCC,
1632 0xBD,0x60,0xAE,0xA3,0xA0,0x66,0x6A,0x16,0x34,0x92,0x3F,0x41,
1633 0x40,0x31,0x29,0xC0,0x2C,0x63,0xB2,0x07,0x8D,0xEB,0x94,0xB8,
1634 0xE8,0x47,0x92,0x52,0x93,0x6A,0x1B,0x7E,0x1A,0x61,0xB3,0x1B,
1635 0xF0,0xD6,0x72,0x9B,0xF1,0xB0,0xAF,0xBF,0x3E,0x65,0xEF,0x23,
1636 0x1D,0x6F,0xFF,0x70,0xCD,0x8A,0x4C,0x8A,0xA0,0x72,0x9D,0xBE,
1637 0xD4,0xBB,0x24,0x47,0x4A,0x68,0xB5,0xF5,0xC6,0xD5,0x7A,0xCD,
1638 0xCA,0x06,0x41,0x07,0xAD,0xC2,0x1E,0xE6,0x54,0xA7,0xAD,0x03,
1639 0xD9,0x12,0xC1,0x9C,0x13,0xB1,0xC9,0x0A,0x43,0x8E,0x1E,0x08,
1640 0xCE,0x50,0x82,0x73,0x5F,0xA7,0x55,0x1D,0xD9,0x59,0xAC,0xB5,
1641 0xEA,0x02,0x7F,0x6C,0x5B,0x74,0x96,0x98,0x67,0x24,0xA3,0x0F,
1642 0x15,0xFC,0xA9,0x7D,0x3E,0x67,0xD1,0x70,0xF8,0x97,0xF3,0x67,
1643 0xC5,0x8C,0x88,0x44,0x08,0x02,0xC7,0x2B,
Remi Gacognef46cd6e2014-06-12 14:58:40 +02001644 };
Remi Gacogned3a341a2015-05-29 16:26:17 +02001645 static unsigned char dh4096_g[]={
1646 0x02,
1647 };
Remi Gacognef46cd6e2014-06-12 14:58:40 +02001648
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02001649 BIGNUM *p;
1650 BIGNUM *g;
Remi Gacognef46cd6e2014-06-12 14:58:40 +02001651 DH *dh = DH_new();
1652 if (dh) {
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02001653 p = BN_bin2bn(dh4096_p, sizeof dh4096_p, NULL);
1654 g = BN_bin2bn(dh4096_g, sizeof dh4096_g, NULL);
Remi Gacogned3a341a2015-05-29 16:26:17 +02001655
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02001656 if (!p || !g) {
Remi Gacognef46cd6e2014-06-12 14:58:40 +02001657 DH_free(dh);
1658 dh = NULL;
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02001659 } else {
1660 DH_set0_pqg(dh, p, NULL, g);
Remi Gacognef46cd6e2014-06-12 14:58:40 +02001661 }
1662 }
1663 return dh;
1664}
1665
1666/* Returns Diffie-Hellman parameters matching the private key length
Willy Tarreauef934602016-12-22 23:12:01 +01001667 but not exceeding global_ssl.default_dh_param */
Remi Gacognef46cd6e2014-06-12 14:58:40 +02001668static DH *ssl_get_tmp_dh(SSL *ssl, int export, int keylen)
1669{
1670 DH *dh = NULL;
1671 EVP_PKEY *pkey = SSL_get_privatekey(ssl);
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02001672 int type;
1673
1674 type = pkey ? EVP_PKEY_base_id(pkey) : EVP_PKEY_NONE;
Remi Gacognef46cd6e2014-06-12 14:58:40 +02001675
1676 /* The keylen supplied by OpenSSL can only be 512 or 1024.
1677 See ssl3_send_server_key_exchange() in ssl/s3_srvr.c
1678 */
1679 if (type == EVP_PKEY_RSA || type == EVP_PKEY_DSA) {
1680 keylen = EVP_PKEY_bits(pkey);
1681 }
1682
Willy Tarreauef934602016-12-22 23:12:01 +01001683 if (keylen > global_ssl.default_dh_param) {
1684 keylen = global_ssl.default_dh_param;
Remi Gacognef46cd6e2014-06-12 14:58:40 +02001685 }
1686
Remi Gacogned3a341a2015-05-29 16:26:17 +02001687 if (keylen >= 4096) {
Remi Gacogne8de54152014-07-15 11:36:40 +02001688 dh = local_dh_4096;
Remi Gacognef46cd6e2014-06-12 14:58:40 +02001689 }
1690 else if (keylen >= 2048) {
Remi Gacogne8de54152014-07-15 11:36:40 +02001691 dh = local_dh_2048;
Remi Gacognef46cd6e2014-06-12 14:58:40 +02001692 }
1693 else {
Remi Gacogne8de54152014-07-15 11:36:40 +02001694 dh = local_dh_1024;
Remi Gacognef46cd6e2014-06-12 14:58:40 +02001695 }
1696
1697 return dh;
1698}
1699
Remi Gacogne47783ef2015-05-29 15:53:22 +02001700static DH * ssl_sock_get_dh_from_file(const char *filename)
Emeric Bruna4bcd9a2012-09-20 16:19:02 +02001701{
Emeric Bruna4bcd9a2012-09-20 16:19:02 +02001702 DH *dh = NULL;
Remi Gacogne47783ef2015-05-29 15:53:22 +02001703 BIO *in = BIO_new(BIO_s_file());
Emeric Bruna4bcd9a2012-09-20 16:19:02 +02001704
Emeric Bruna4bcd9a2012-09-20 16:19:02 +02001705 if (in == NULL)
1706 goto end;
1707
Remi Gacogne47783ef2015-05-29 15:53:22 +02001708 if (BIO_read_filename(in, filename) <= 0)
Emeric Bruna4bcd9a2012-09-20 16:19:02 +02001709 goto end;
1710
Remi Gacogne47783ef2015-05-29 15:53:22 +02001711 dh = PEM_read_bio_DHparams(in, NULL, NULL, NULL);
1712
1713end:
1714 if (in)
1715 BIO_free(in);
1716
1717 return dh;
1718}
1719
1720int ssl_sock_load_global_dh_param_from_file(const char *filename)
1721{
1722 global_dh = ssl_sock_get_dh_from_file(filename);
1723
1724 if (global_dh) {
1725 return 0;
1726 }
1727
1728 return -1;
1729}
1730
1731/* Loads Diffie-Hellman parameter from a file. Returns 1 if loaded, else -1
1732 if an error occured, and 0 if parameter not found. */
1733int ssl_sock_load_dh_params(SSL_CTX *ctx, const char *file)
1734{
1735 int ret = -1;
1736 DH *dh = ssl_sock_get_dh_from_file(file);
1737
Remi Gacognef46cd6e2014-06-12 14:58:40 +02001738 if (dh) {
1739 ret = 1;
1740 SSL_CTX_set_tmp_dh(ctx, dh);
Remi Gacogne4f902b82015-05-28 16:23:00 +02001741
1742 if (ssl_dh_ptr_index >= 0) {
1743 /* store a pointer to the DH params to avoid complaining about
1744 ssl-default-dh-param not being set for this SSL_CTX */
1745 SSL_CTX_set_ex_data(ctx, ssl_dh_ptr_index, dh);
1746 }
Remi Gacognef46cd6e2014-06-12 14:58:40 +02001747 }
Remi Gacogne47783ef2015-05-29 15:53:22 +02001748 else if (global_dh) {
1749 SSL_CTX_set_tmp_dh(ctx, global_dh);
1750 ret = 0; /* DH params not found */
1751 }
Remi Gacognef46cd6e2014-06-12 14:58:40 +02001752 else {
Emeric Brun41fdb3c2013-04-26 11:05:44 +02001753 /* Clear openssl global errors stack */
1754 ERR_clear_error();
1755
Willy Tarreauef934602016-12-22 23:12:01 +01001756 if (global_ssl.default_dh_param <= 1024) {
Remi Gacognef46cd6e2014-06-12 14:58:40 +02001757 /* we are limited to DH parameter of 1024 bits anyway */
Remi Gacognec7e12632016-07-02 16:26:10 +02001758 if (local_dh_1024 == NULL)
1759 local_dh_1024 = ssl_get_dh_1024();
1760
Remi Gacogne8de54152014-07-15 11:36:40 +02001761 if (local_dh_1024 == NULL)
Remi Gacognef46cd6e2014-06-12 14:58:40 +02001762 goto end;
Willy Tarreau6e774b42014-04-25 21:35:23 +02001763
Remi Gacogne8de54152014-07-15 11:36:40 +02001764 SSL_CTX_set_tmp_dh(ctx, local_dh_1024);
Remi Gacognef46cd6e2014-06-12 14:58:40 +02001765 }
1766 else {
1767 SSL_CTX_set_tmp_dh_callback(ctx, ssl_get_tmp_dh);
1768 }
Willy Tarreau6e774b42014-04-25 21:35:23 +02001769
Emeric Brun41fdb3c2013-04-26 11:05:44 +02001770 ret = 0; /* DH params not found */
Emeric Bruna4bcd9a2012-09-20 16:19:02 +02001771 }
Emeric Brun644cde02012-12-14 11:21:13 +01001772
Emeric Bruna4bcd9a2012-09-20 16:19:02 +02001773end:
1774 if (dh)
1775 DH_free(dh);
1776
Emeric Bruna4bcd9a2012-09-20 16:19:02 +02001777 return ret;
1778}
1779#endif
1780
Emmanuel Hocdet98263292016-12-29 18:26:15 +01001781static int ssl_sock_add_cert_sni(SSL_CTX *ctx, struct bind_conf *s,
1782 struct ssl_bind_conf *conf, char *name, int order)
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01001783{
1784 struct sni_ctx *sc;
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +02001785 int wild = 0, neg = 0;
Thierry FOURNIER / OZON.IO07c3d782016-10-06 10:56:48 +02001786 struct ebmb_node *node;
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01001787
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +02001788 if (*name == '!') {
1789 neg = 1;
1790 name++;
1791 }
1792 if (*name == '*') {
1793 wild = 1;
1794 name++;
1795 }
1796 /* !* filter is a nop */
1797 if (neg && wild)
1798 return order;
1799 if (*name) {
1800 int j, len;
1801 len = strlen(name);
Thierry FOURNIER / OZON.IO07c3d782016-10-06 10:56:48 +02001802 for (j = 0; j < len && j < trash.size; j++)
1803 trash.str[j] = tolower(name[j]);
1804 if (j >= trash.size)
1805 return order;
1806 trash.str[j] = 0;
1807
1808 /* Check for duplicates. */
1809 if (wild)
1810 node = ebst_lookup(&s->sni_w_ctx, trash.str);
1811 else
1812 node = ebst_lookup(&s->sni_ctx, trash.str);
1813 for (; node; node = ebmb_next_dup(node)) {
1814 sc = ebmb_entry(node, struct sni_ctx, name);
Emmanuel Hocdet98263292016-12-29 18:26:15 +01001815 if (sc->ctx == ctx && sc->conf == conf && sc->neg == neg)
Thierry FOURNIER / OZON.IO07c3d782016-10-06 10:56:48 +02001816 return order;
1817 }
1818
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01001819 sc = malloc(sizeof(struct sni_ctx) + len + 1);
Thierry FOURNIER / OZON.IO7a3bd3b2016-10-06 10:35:29 +02001820 if (!sc)
1821 return order;
Thierry FOURNIER / OZON.IO07c3d782016-10-06 10:56:48 +02001822 memcpy(sc->name.key, trash.str, len + 1);
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01001823 sc->ctx = ctx;
Emmanuel Hocdet98263292016-12-29 18:26:15 +01001824 sc->conf = conf;
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +02001825 sc->order = order++;
1826 sc->neg = neg;
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01001827 if (wild)
1828 ebst_insert(&s->sni_w_ctx, &sc->name);
1829 else
1830 ebst_insert(&s->sni_ctx, &sc->name);
1831 }
1832 return order;
1833}
1834
yanbzhu488a4d22015-12-01 15:16:07 -05001835
1836/* The following code is used for loading multiple crt files into
1837 * SSL_CTX's based on CN/SAN
1838 */
Luca Pizzamiglio578b1692016-12-12 10:56:56 +01001839#if OPENSSL_VERSION_NUMBER >= 0x1000200fL && !defined(LIBRESSL_VERSION_NUMBER)
yanbzhu488a4d22015-12-01 15:16:07 -05001840/* This is used to preload the certifcate, private key
1841 * and Cert Chain of a file passed in via the crt
1842 * argument
1843 *
1844 * This way, we do not have to read the file multiple times
1845 */
1846struct cert_key_and_chain {
1847 X509 *cert;
1848 EVP_PKEY *key;
1849 unsigned int num_chain_certs;
1850 /* This is an array of X509 pointers */
1851 X509 **chain_certs;
1852};
1853
yanbzhu08ce6ab2015-12-02 13:01:29 -05001854#define SSL_SOCK_POSSIBLE_KT_COMBOS (1<<(SSL_SOCK_NUM_KEYTYPES))
1855
1856struct key_combo_ctx {
1857 SSL_CTX *ctx;
1858 int order;
1859};
1860
1861/* Map used for processing multiple keypairs for a single purpose
1862 *
1863 * This maps CN/SNI name to certificate type
1864 */
1865struct sni_keytype {
1866 int keytypes; /* BITMASK for keytypes */
1867 struct ebmb_node name; /* node holding the servername value */
1868};
1869
1870
yanbzhu488a4d22015-12-01 15:16:07 -05001871/* Frees the contents of a cert_key_and_chain
1872 */
1873static void ssl_sock_free_cert_key_and_chain_contents(struct cert_key_and_chain *ckch)
1874{
1875 int i;
1876
1877 if (!ckch)
1878 return;
1879
1880 /* Free the certificate and set pointer to NULL */
1881 if (ckch->cert)
1882 X509_free(ckch->cert);
1883 ckch->cert = NULL;
1884
1885 /* Free the key and set pointer to NULL */
1886 if (ckch->key)
1887 EVP_PKEY_free(ckch->key);
1888 ckch->key = NULL;
1889
1890 /* Free each certificate in the chain */
1891 for (i = 0; i < ckch->num_chain_certs; i++) {
1892 if (ckch->chain_certs[i])
1893 X509_free(ckch->chain_certs[i]);
1894 }
1895
1896 /* Free the chain obj itself and set to NULL */
1897 if (ckch->num_chain_certs > 0) {
1898 free(ckch->chain_certs);
1899 ckch->num_chain_certs = 0;
1900 ckch->chain_certs = NULL;
1901 }
1902
1903}
1904
1905/* checks if a key and cert exists in the ckch
1906 */
1907static int ssl_sock_is_ckch_valid(struct cert_key_and_chain *ckch)
1908{
1909 return (ckch->cert != NULL && ckch->key != NULL);
1910}
1911
1912
1913/* Loads the contents of a crt file (path) into a cert_key_and_chain
1914 * This allows us to carry the contents of the file without having to
1915 * read the file multiple times.
1916 *
1917 * returns:
1918 * 0 on Success
1919 * 1 on SSL Failure
1920 * 2 on file not found
1921 */
1922static int ssl_sock_load_crt_file_into_ckch(const char *path, struct cert_key_and_chain *ckch, char **err)
1923{
1924
1925 BIO *in;
1926 X509 *ca = NULL;
1927 int ret = 1;
1928
1929 ssl_sock_free_cert_key_and_chain_contents(ckch);
1930
1931 in = BIO_new(BIO_s_file());
1932 if (in == NULL)
1933 goto end;
1934
1935 if (BIO_read_filename(in, path) <= 0)
1936 goto end;
1937
yanbzhu488a4d22015-12-01 15:16:07 -05001938 /* Read Private Key */
1939 ckch->key = PEM_read_bio_PrivateKey(in, NULL, NULL, NULL);
1940 if (ckch->key == NULL) {
1941 memprintf(err, "%sunable to load private key from file '%s'.\n",
1942 err && *err ? *err : "", path);
1943 goto end;
1944 }
1945
Willy Tarreaubb137a82016-04-06 19:02:38 +02001946 /* Seek back to beginning of file */
Thierry FOURNIER / OZON.IOd44ea3f2016-10-14 00:49:21 +02001947 if (BIO_reset(in) == -1) {
1948 memprintf(err, "%san error occurred while reading the file '%s'.\n",
1949 err && *err ? *err : "", path);
1950 goto end;
1951 }
Willy Tarreaubb137a82016-04-06 19:02:38 +02001952
1953 /* Read Certificate */
1954 ckch->cert = PEM_read_bio_X509_AUX(in, NULL, NULL, NULL);
1955 if (ckch->cert == NULL) {
1956 memprintf(err, "%sunable to load certificate from file '%s'.\n",
1957 err && *err ? *err : "", path);
1958 goto end;
1959 }
1960
yanbzhu488a4d22015-12-01 15:16:07 -05001961 /* Read Certificate Chain */
1962 while ((ca = PEM_read_bio_X509(in, NULL, NULL, NULL))) {
1963 /* Grow the chain certs */
1964 ckch->num_chain_certs++;
1965 ckch->chain_certs = realloc(ckch->chain_certs, (ckch->num_chain_certs * sizeof(X509 *)));
1966
1967 /* use - 1 here since we just incremented it above */
1968 ckch->chain_certs[ckch->num_chain_certs - 1] = ca;
1969 }
1970 ret = ERR_get_error();
1971 if (ret && (ERR_GET_LIB(ret) != ERR_LIB_PEM && ERR_GET_REASON(ret) != PEM_R_NO_START_LINE)) {
1972 memprintf(err, "%sunable to load certificate chain from file '%s'.\n",
1973 err && *err ? *err : "", path);
1974 ret = 1;
1975 goto end;
1976 }
1977
1978 ret = 0;
1979
1980end:
1981
1982 ERR_clear_error();
1983 if (in)
1984 BIO_free(in);
1985
1986 /* Something went wrong in one of the reads */
1987 if (ret != 0)
1988 ssl_sock_free_cert_key_and_chain_contents(ckch);
1989
1990 return ret;
1991}
1992
1993/* Loads the info in ckch into ctx
1994 * Currently, this does not process any information about ocsp, dhparams or
1995 * sctl
1996 * Returns
1997 * 0 on success
1998 * 1 on failure
1999 */
2000static int ssl_sock_put_ckch_into_ctx(const char *path, const struct cert_key_and_chain *ckch, SSL_CTX *ctx, char **err)
2001{
2002 int i = 0;
2003
2004 if (SSL_CTX_use_PrivateKey(ctx, ckch->key) <= 0) {
2005 memprintf(err, "%sunable to load SSL private key into SSL Context '%s'.\n",
2006 err && *err ? *err : "", path);
2007 return 1;
2008 }
2009
2010 if (!SSL_CTX_use_certificate(ctx, ckch->cert)) {
2011 memprintf(err, "%sunable to load SSL certificate into SSL Context '%s'.\n",
2012 err && *err ? *err : "", path);
2013 return 1;
2014 }
2015
yanbzhu488a4d22015-12-01 15:16:07 -05002016 /* Load all certs in the ckch into the ctx_chain for the ssl_ctx */
2017 for (i = 0; i < ckch->num_chain_certs; i++) {
2018 if (!SSL_CTX_add1_chain_cert(ctx, ckch->chain_certs[i])) {
yanbzhu08ce6ab2015-12-02 13:01:29 -05002019 memprintf(err, "%sunable to load chain certificate #%d into SSL Context '%s'. Make sure you are linking against Openssl >= 1.0.2.\n",
2020 err && *err ? *err : "", (i+1), path);
yanbzhu488a4d22015-12-01 15:16:07 -05002021 return 1;
2022 }
2023 }
2024
2025 if (SSL_CTX_check_private_key(ctx) <= 0) {
2026 memprintf(err, "%sinconsistencies between private key and certificate loaded from PEM file '%s'.\n",
2027 err && *err ? *err : "", path);
2028 return 1;
2029 }
2030
2031 return 0;
2032}
2033
yanbzhu08ce6ab2015-12-02 13:01:29 -05002034
2035static void ssl_sock_populate_sni_keytypes_hplr(const char *str, struct eb_root *sni_keytypes, int key_index)
2036{
2037 struct sni_keytype *s_kt = NULL;
2038 struct ebmb_node *node;
2039 int i;
2040
2041 for (i = 0; i < trash.size; i++) {
2042 if (!str[i])
2043 break;
2044 trash.str[i] = tolower(str[i]);
2045 }
2046 trash.str[i] = 0;
2047 node = ebst_lookup(sni_keytypes, trash.str);
2048 if (!node) {
2049 /* CN not found in tree */
2050 s_kt = malloc(sizeof(struct sni_keytype) + i + 1);
2051 /* Using memcpy here instead of strncpy.
2052 * strncpy will cause sig_abrt errors under certain versions of gcc with -O2
2053 * See: https://gcc.gnu.org/bugzilla/show_bug.cgi?id=60792
2054 */
2055 memcpy(s_kt->name.key, trash.str, i+1);
2056 s_kt->keytypes = 0;
2057 ebst_insert(sni_keytypes, &s_kt->name);
2058 } else {
2059 /* CN found in tree */
2060 s_kt = container_of(node, struct sni_keytype, name);
2061 }
2062
2063 /* Mark that this CN has the keytype of key_index via keytypes mask */
2064 s_kt->keytypes |= 1<<key_index;
2065
2066}
2067
2068
2069/* Given a path that does not exist, try to check for path.rsa, path.dsa and path.ecdsa files.
2070 * If any are found, group these files into a set of SSL_CTX*
2071 * based on shared and unique CN and SAN entries. Add these SSL_CTX* to the SNI tree.
2072 *
2073 * This will allow the user to explictly group multiple cert/keys for a single purpose
2074 *
2075 * Returns
2076 * 0 on success
2077 * 1 on failure
2078 */
Emmanuel Hocdet98263292016-12-29 18:26:15 +01002079static int ssl_sock_load_multi_cert(const char *path, struct bind_conf *bind_conf, struct ssl_bind_conf *ssl_conf,
2080 char **sni_filter, int fcount, char **err)
yanbzhu08ce6ab2015-12-02 13:01:29 -05002081{
2082 char fp[MAXPATHLEN+1] = {0};
2083 int n = 0;
2084 int i = 0;
2085 struct cert_key_and_chain certs_and_keys[SSL_SOCK_NUM_KEYTYPES] = { {0} };
2086 struct eb_root sni_keytypes_map = { {0} };
2087 struct ebmb_node *node;
2088 struct ebmb_node *next;
2089 /* Array of SSL_CTX pointers corresponding to each possible combo
2090 * of keytypes
2091 */
2092 struct key_combo_ctx key_combos[SSL_SOCK_POSSIBLE_KT_COMBOS] = { {0} };
2093 int rv = 0;
2094 X509_NAME *xname = NULL;
2095 char *str = NULL;
2096#ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME
2097 STACK_OF(GENERAL_NAME) *names = NULL;
2098#endif
2099
2100 /* Load all possible certs and keys */
2101 for (n = 0; n < SSL_SOCK_NUM_KEYTYPES; n++) {
2102 struct stat buf;
2103
2104 snprintf(fp, sizeof(fp), "%s.%s", path, SSL_SOCK_KEYTYPE_NAMES[n]);
2105 if (stat(fp, &buf) == 0) {
2106 if (ssl_sock_load_crt_file_into_ckch(fp, &certs_and_keys[n], err) == 1) {
2107 rv = 1;
2108 goto end;
2109 }
2110 }
2111 }
2112
2113 /* Process each ckch and update keytypes for each CN/SAN
2114 * for example, if CN/SAN www.a.com is associated with
2115 * certs with keytype 0 and 2, then at the end of the loop,
2116 * www.a.com will have:
2117 * keyindex = 0 | 1 | 4 = 5
2118 */
2119 for (n = 0; n < SSL_SOCK_NUM_KEYTYPES; n++) {
2120
2121 if (!ssl_sock_is_ckch_valid(&certs_and_keys[n]))
2122 continue;
2123
Emmanuel Hocdetd294aea2016-05-13 11:14:06 +02002124 if (fcount) {
Willy Tarreau24b892f2016-06-20 23:01:57 +02002125 for (i = 0; i < fcount; i++)
Emmanuel Hocdetd294aea2016-05-13 11:14:06 +02002126 ssl_sock_populate_sni_keytypes_hplr(sni_filter[i], &sni_keytypes_map, n);
2127 } else {
2128 /* A lot of the following code is OpenSSL boilerplate for processing CN's and SAN's,
2129 * so the line that contains logic is marked via comments
2130 */
2131 xname = X509_get_subject_name(certs_and_keys[n].cert);
2132 i = -1;
2133 while ((i = X509_NAME_get_index_by_NID(xname, NID_commonName, i)) != -1) {
2134 X509_NAME_ENTRY *entry = X509_NAME_get_entry(xname, i);
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02002135 ASN1_STRING *value;
2136 value = X509_NAME_ENTRY_get_data(entry);
2137 if (ASN1_STRING_to_UTF8((unsigned char **)&str, value) >= 0) {
Emmanuel Hocdetd294aea2016-05-13 11:14:06 +02002138 /* Important line is here */
2139 ssl_sock_populate_sni_keytypes_hplr(str, &sni_keytypes_map, n);
yanbzhu08ce6ab2015-12-02 13:01:29 -05002140
Emmanuel Hocdetd294aea2016-05-13 11:14:06 +02002141 OPENSSL_free(str);
2142 str = NULL;
2143 }
yanbzhu08ce6ab2015-12-02 13:01:29 -05002144 }
yanbzhu08ce6ab2015-12-02 13:01:29 -05002145
Emmanuel Hocdetd294aea2016-05-13 11:14:06 +02002146 /* Do the above logic for each SAN */
yanbzhu08ce6ab2015-12-02 13:01:29 -05002147#ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME
Emmanuel Hocdetd294aea2016-05-13 11:14:06 +02002148 names = X509_get_ext_d2i(certs_and_keys[n].cert, NID_subject_alt_name, NULL, NULL);
2149 if (names) {
2150 for (i = 0; i < sk_GENERAL_NAME_num(names); i++) {
2151 GENERAL_NAME *name = sk_GENERAL_NAME_value(names, i);
yanbzhu08ce6ab2015-12-02 13:01:29 -05002152
Emmanuel Hocdetd294aea2016-05-13 11:14:06 +02002153 if (name->type == GEN_DNS) {
2154 if (ASN1_STRING_to_UTF8((unsigned char **)&str, name->d.dNSName) >= 0) {
2155 /* Important line is here */
2156 ssl_sock_populate_sni_keytypes_hplr(str, &sni_keytypes_map, n);
yanbzhu08ce6ab2015-12-02 13:01:29 -05002157
Emmanuel Hocdetd294aea2016-05-13 11:14:06 +02002158 OPENSSL_free(str);
2159 str = NULL;
2160 }
yanbzhu08ce6ab2015-12-02 13:01:29 -05002161 }
2162 }
2163 }
2164 }
2165#endif /* SSL_CTRL_SET_TLSEXT_HOSTNAME */
2166 }
2167
2168 /* If no files found, return error */
2169 if (eb_is_empty(&sni_keytypes_map)) {
2170 memprintf(err, "%sunable to load SSL certificate file '%s' file does not exist.\n",
2171 err && *err ? *err : "", path);
2172 rv = 1;
2173 goto end;
2174 }
2175
2176 /* We now have a map of CN/SAN to keytypes that are loaded in
2177 * Iterate through the map to create the SSL_CTX's (if needed)
2178 * and add each CTX to the SNI tree
2179 *
2180 * Some math here:
2181 * There are 2^n - 1 possibile combinations, each unique
2182 * combination is denoted by the key in the map. Each key
2183 * has a value between 1 and 2^n - 1. Conveniently, the array
2184 * of SSL_CTX* is sized 2^n. So, we can simply use the i'th
2185 * entry in the array to correspond to the unique combo (key)
2186 * associated with i. This unique key combo (i) will be associated
2187 * with combos[i-1]
2188 */
2189
2190 node = ebmb_first(&sni_keytypes_map);
2191 while (node) {
2192 SSL_CTX *cur_ctx;
Bertrand Jacquin33423092016-11-13 16:37:13 +00002193 char cur_file[MAXPATHLEN+1];
yanbzhu08ce6ab2015-12-02 13:01:29 -05002194
2195 str = (char *)container_of(node, struct sni_keytype, name)->name.key;
2196 i = container_of(node, struct sni_keytype, name)->keytypes;
2197 cur_ctx = key_combos[i-1].ctx;
2198
2199 if (cur_ctx == NULL) {
2200 /* need to create SSL_CTX */
2201 cur_ctx = SSL_CTX_new(SSLv23_server_method());
2202 if (cur_ctx == NULL) {
2203 memprintf(err, "%sunable to allocate SSL context.\n",
2204 err && *err ? *err : "");
2205 rv = 1;
2206 goto end;
2207 }
2208
yanbzhube2774d2015-12-10 15:07:30 -05002209 /* Load all required certs/keys/chains/OCSPs info into SSL_CTX */
yanbzhu08ce6ab2015-12-02 13:01:29 -05002210 for (n = 0; n < SSL_SOCK_NUM_KEYTYPES; n++) {
2211 if (i & (1<<n)) {
2212 /* Key combo contains ckch[n] */
Bertrand Jacquin33423092016-11-13 16:37:13 +00002213 snprintf(cur_file, MAXPATHLEN+1, "%s.%s", path, SSL_SOCK_KEYTYPE_NAMES[n]);
2214 if (ssl_sock_put_ckch_into_ctx(cur_file, &certs_and_keys[n], cur_ctx, err) != 0) {
yanbzhu08ce6ab2015-12-02 13:01:29 -05002215 SSL_CTX_free(cur_ctx);
2216 rv = 1;
2217 goto end;
2218 }
yanbzhube2774d2015-12-10 15:07:30 -05002219
2220#if (defined SSL_CTRL_SET_TLSEXT_STATUS_REQ_CB && !defined OPENSSL_NO_OCSP)
2221 /* Load OCSP Info into context */
Bertrand Jacquin33423092016-11-13 16:37:13 +00002222 if (ssl_sock_load_ocsp(cur_ctx, cur_file) < 0) {
yanbzhube2774d2015-12-10 15:07:30 -05002223 if (err)
2224 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 +00002225 *err ? *err : "", cur_file);
yanbzhube2774d2015-12-10 15:07:30 -05002226 SSL_CTX_free(cur_ctx);
2227 rv = 1;
2228 goto end;
2229 }
2230#endif
yanbzhu08ce6ab2015-12-02 13:01:29 -05002231 }
2232 }
2233
2234 /* Load DH params into the ctx to support DHE keys */
2235#ifndef OPENSSL_NO_DH
2236 if (ssl_dh_ptr_index >= 0)
2237 SSL_CTX_set_ex_data(cur_ctx, ssl_dh_ptr_index, NULL);
2238
2239 rv = ssl_sock_load_dh_params(cur_ctx, NULL);
2240 if (rv < 0) {
2241 if (err)
2242 memprintf(err, "%sunable to load DH parameters from file '%s'.\n",
2243 *err ? *err : "", path);
2244 rv = 1;
2245 goto end;
2246 }
2247#endif
2248
2249 /* Update key_combos */
2250 key_combos[i-1].ctx = cur_ctx;
2251 }
2252
2253 /* Update SNI Tree */
Emmanuel Hocdet98263292016-12-29 18:26:15 +01002254 key_combos[i-1].order = ssl_sock_add_cert_sni(cur_ctx, bind_conf, ssl_conf, str, key_combos[i-1].order);
yanbzhu08ce6ab2015-12-02 13:01:29 -05002255 node = ebmb_next(node);
2256 }
2257
2258
2259 /* Mark a default context if none exists, using the ctx that has the most shared keys */
2260 if (!bind_conf->default_ctx) {
2261 for (i = SSL_SOCK_POSSIBLE_KT_COMBOS - 1; i >= 0; i--) {
2262 if (key_combos[i].ctx) {
2263 bind_conf->default_ctx = key_combos[i].ctx;
Emmanuel Hocdet98263292016-12-29 18:26:15 +01002264 bind_conf->default_ssl_conf = ssl_conf;
yanbzhu08ce6ab2015-12-02 13:01:29 -05002265 break;
2266 }
2267 }
2268 }
2269
2270end:
2271
2272 if (names)
2273 sk_GENERAL_NAME_pop_free(names, GENERAL_NAME_free);
2274
2275 for (n = 0; n < SSL_SOCK_NUM_KEYTYPES; n++)
2276 ssl_sock_free_cert_key_and_chain_contents(&certs_and_keys[n]);
2277
2278 node = ebmb_first(&sni_keytypes_map);
2279 while (node) {
2280 next = ebmb_next(node);
2281 ebmb_delete(node);
2282 node = next;
2283 }
2284
2285 return rv;
2286}
2287#else
2288/* This is a dummy, that just logs an error and returns error */
Emmanuel Hocdet98263292016-12-29 18:26:15 +01002289static int ssl_sock_load_multi_cert(const char *path, struct bind_conf *bind_conf, struct ssl_bind_conf *ssl_conf,
2290 char **sni_filter, int fcount, char **err)
yanbzhu08ce6ab2015-12-02 13:01:29 -05002291{
2292 memprintf(err, "%sunable to stat SSL certificate from file '%s' : %s.\n",
2293 err && *err ? *err : "", path, strerror(errno));
2294 return 1;
2295}
2296
yanbzhu488a4d22015-12-01 15:16:07 -05002297#endif /* #if OPENSSL_VERSION_NUMBER >= 0x1000200fL: Support for loading multiple certs into a single SSL_CTX */
2298
Emeric Brunfc0421f2012-09-07 17:30:07 +02002299/* Loads a certificate key and CA chain from a file. Returns 0 on error, -1 if
2300 * an early error happens and the caller must call SSL_CTX_free() by itelf.
2301 */
Emmanuel Hocdet98263292016-12-29 18:26:15 +01002302static int ssl_sock_load_cert_chain_file(SSL_CTX *ctx, const char *file, struct bind_conf *s,
2303 struct ssl_bind_conf *ssl_conf, char **sni_filter, int fcount)
Emeric Brunfc0421f2012-09-07 17:30:07 +02002304{
2305 BIO *in;
2306 X509 *x = NULL, *ca;
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +02002307 int i, err;
Emeric Brunfc0421f2012-09-07 17:30:07 +02002308 int ret = -1;
2309 int order = 0;
2310 X509_NAME *xname;
2311 char *str;
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02002312 pem_password_cb *passwd_cb;
2313 void *passwd_cb_userdata;
2314
Emeric Brunfc0421f2012-09-07 17:30:07 +02002315#ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME
2316 STACK_OF(GENERAL_NAME) *names;
2317#endif
2318
2319 in = BIO_new(BIO_s_file());
2320 if (in == NULL)
2321 goto end;
2322
2323 if (BIO_read_filename(in, file) <= 0)
2324 goto end;
2325
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02002326
2327 passwd_cb = SSL_CTX_get_default_passwd_cb(ctx);
2328 passwd_cb_userdata = SSL_CTX_get_default_passwd_cb_userdata(ctx);
2329
2330 x = PEM_read_bio_X509_AUX(in, NULL, passwd_cb, passwd_cb_userdata);
Emeric Brunfc0421f2012-09-07 17:30:07 +02002331 if (x == NULL)
2332 goto end;
2333
Emeric Brun50bcecc2013-04-22 13:05:23 +02002334 if (fcount) {
2335 while (fcount--)
Emmanuel Hocdet98263292016-12-29 18:26:15 +01002336 order = ssl_sock_add_cert_sni(ctx, s, ssl_conf, sni_filter[fcount], order);
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01002337 }
2338 else {
Emeric Brunfc0421f2012-09-07 17:30:07 +02002339#ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01002340 names = X509_get_ext_d2i(x, NID_subject_alt_name, NULL, NULL);
2341 if (names) {
2342 for (i = 0; i < sk_GENERAL_NAME_num(names); i++) {
2343 GENERAL_NAME *name = sk_GENERAL_NAME_value(names, i);
2344 if (name->type == GEN_DNS) {
2345 if (ASN1_STRING_to_UTF8((unsigned char **)&str, name->d.dNSName) >= 0) {
Emmanuel Hocdet98263292016-12-29 18:26:15 +01002346 order = ssl_sock_add_cert_sni(ctx, s, ssl_conf, str, order);
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01002347 OPENSSL_free(str);
Emeric Brunfc0421f2012-09-07 17:30:07 +02002348 }
Emeric Brunfc0421f2012-09-07 17:30:07 +02002349 }
2350 }
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01002351 sk_GENERAL_NAME_pop_free(names, GENERAL_NAME_free);
Emeric Brunfc0421f2012-09-07 17:30:07 +02002352 }
Emeric Brunfc0421f2012-09-07 17:30:07 +02002353#endif /* SSL_CTRL_SET_TLSEXT_HOSTNAME */
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01002354 xname = X509_get_subject_name(x);
2355 i = -1;
2356 while ((i = X509_NAME_get_index_by_NID(xname, NID_commonName, i)) != -1) {
2357 X509_NAME_ENTRY *entry = X509_NAME_get_entry(xname, i);
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02002358 ASN1_STRING *value;
2359
2360 value = X509_NAME_ENTRY_get_data(entry);
2361 if (ASN1_STRING_to_UTF8((unsigned char **)&str, value) >= 0) {
Emmanuel Hocdet98263292016-12-29 18:26:15 +01002362 order = ssl_sock_add_cert_sni(ctx, s, ssl_conf, str, order);
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01002363 OPENSSL_free(str);
Emeric Brunfc0421f2012-09-07 17:30:07 +02002364 }
Emeric Brunfc0421f2012-09-07 17:30:07 +02002365 }
2366 }
2367
2368 ret = 0; /* the caller must not free the SSL_CTX argument anymore */
2369 if (!SSL_CTX_use_certificate(ctx, x))
2370 goto end;
2371
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02002372#ifdef SSL_CTX_clear_extra_chain_certs
2373 SSL_CTX_clear_extra_chain_certs(ctx);
2374#else
Emeric Brunfc0421f2012-09-07 17:30:07 +02002375 if (ctx->extra_certs != NULL) {
2376 sk_X509_pop_free(ctx->extra_certs, X509_free);
2377 ctx->extra_certs = NULL;
2378 }
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02002379#endif
Emeric Brunfc0421f2012-09-07 17:30:07 +02002380
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02002381 while ((ca = PEM_read_bio_X509(in, NULL, passwd_cb, passwd_cb_userdata))) {
Emeric Brunfc0421f2012-09-07 17:30:07 +02002382 if (!SSL_CTX_add_extra_chain_cert(ctx, ca)) {
2383 X509_free(ca);
2384 goto end;
2385 }
2386 }
2387
2388 err = ERR_get_error();
2389 if (!err || (ERR_GET_LIB(err) == ERR_LIB_PEM && ERR_GET_REASON(err) == PEM_R_NO_START_LINE)) {
2390 /* we successfully reached the last cert in the file */
2391 ret = 1;
2392 }
2393 ERR_clear_error();
2394
2395end:
2396 if (x)
2397 X509_free(x);
2398
2399 if (in)
2400 BIO_free(in);
2401
2402 return ret;
2403}
2404
Emmanuel Hocdet98263292016-12-29 18:26:15 +01002405static int ssl_sock_load_cert_file(const char *path, struct bind_conf *bind_conf, struct ssl_bind_conf *ssl_conf,
2406 char **sni_filter, int fcount, char **err)
Emeric Brunfc0421f2012-09-07 17:30:07 +02002407{
2408 int ret;
2409 SSL_CTX *ctx;
2410
2411 ctx = SSL_CTX_new(SSLv23_server_method());
2412 if (!ctx) {
Willy Tarreaueb6cead2012-09-20 19:43:14 +02002413 memprintf(err, "%sunable to allocate SSL context for cert '%s'.\n",
2414 err && *err ? *err : "", path);
Emeric Brunfc0421f2012-09-07 17:30:07 +02002415 return 1;
2416 }
2417
2418 if (SSL_CTX_use_PrivateKey_file(ctx, path, SSL_FILETYPE_PEM) <= 0) {
Willy Tarreaueb6cead2012-09-20 19:43:14 +02002419 memprintf(err, "%sunable to load SSL private key from PEM file '%s'.\n",
2420 err && *err ? *err : "", path);
Emeric Brunfc0421f2012-09-07 17:30:07 +02002421 SSL_CTX_free(ctx);
2422 return 1;
2423 }
2424
Emmanuel Hocdet98263292016-12-29 18:26:15 +01002425 ret = ssl_sock_load_cert_chain_file(ctx, path, bind_conf, ssl_conf, sni_filter, fcount);
Emeric Brunfc0421f2012-09-07 17:30:07 +02002426 if (ret <= 0) {
Willy Tarreaueb6cead2012-09-20 19:43:14 +02002427 memprintf(err, "%sunable to load SSL certificate from PEM file '%s'.\n",
2428 err && *err ? *err : "", path);
Emeric Brunfc0421f2012-09-07 17:30:07 +02002429 if (ret < 0) /* serious error, must do that ourselves */
2430 SSL_CTX_free(ctx);
2431 return 1;
2432 }
Emeric Brun61694ab2012-10-26 13:35:33 +02002433
2434 if (SSL_CTX_check_private_key(ctx) <= 0) {
2435 memprintf(err, "%sinconsistencies between private key and certificate loaded from PEM file '%s'.\n",
2436 err && *err ? *err : "", path);
2437 return 1;
2438 }
2439
Emeric Brunfc0421f2012-09-07 17:30:07 +02002440 /* we must not free the SSL_CTX anymore below, since it's already in
2441 * the tree, so it will be discovered and cleaned in time.
2442 */
Emeric Bruna4bcd9a2012-09-20 16:19:02 +02002443#ifndef OPENSSL_NO_DH
Remi Gacogne4f902b82015-05-28 16:23:00 +02002444 /* store a NULL pointer to indicate we have not yet loaded
2445 a custom DH param file */
2446 if (ssl_dh_ptr_index >= 0) {
2447 SSL_CTX_set_ex_data(ctx, ssl_dh_ptr_index, NULL);
2448 }
2449
Emeric Bruna4bcd9a2012-09-20 16:19:02 +02002450 ret = ssl_sock_load_dh_params(ctx, path);
2451 if (ret < 0) {
2452 if (err)
2453 memprintf(err, "%sunable to load DH parameters from file '%s'.\n",
2454 *err ? *err : "", path);
2455 return 1;
2456 }
2457#endif
2458
Lukas Tribuse4e30f72014-12-09 16:32:51 +01002459#if (defined SSL_CTRL_SET_TLSEXT_STATUS_REQ_CB && !defined OPENSSL_NO_OCSP)
Emeric Brun4147b2e2014-06-16 18:36:30 +02002460 ret = ssl_sock_load_ocsp(ctx, path);
2461 if (ret < 0) {
2462 if (err)
2463 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",
2464 *err ? *err : "", path);
2465 return 1;
2466 }
2467#endif
2468
Daniel Jakots54ffb912015-11-06 20:02:41 +01002469#if (OPENSSL_VERSION_NUMBER >= 0x1000200fL && !defined OPENSSL_NO_TLSEXT && !defined OPENSSL_IS_BORINGSSL && !defined LIBRESSL_VERSION_NUMBER)
Janusz Dziemidowicz2c701b52015-03-07 23:03:59 +01002470 if (sctl_ex_index >= 0) {
2471 ret = ssl_sock_load_sctl(ctx, path);
2472 if (ret < 0) {
2473 if (err)
2474 memprintf(err, "%s '%s.sctl' is present but cannot be read or parsed'.\n",
2475 *err ? *err : "", path);
2476 return 1;
2477 }
2478 }
2479#endif
2480
Emeric Brunfc0421f2012-09-07 17:30:07 +02002481#ifndef SSL_CTRL_SET_TLSEXT_HOSTNAME
Willy Tarreau2a65ff02012-09-13 17:54:29 +02002482 if (bind_conf->default_ctx) {
Willy Tarreaueb6cead2012-09-20 19:43:14 +02002483 memprintf(err, "%sthis version of openssl cannot load multiple SSL certificates.\n",
2484 err && *err ? *err : "");
Emeric Brunfc0421f2012-09-07 17:30:07 +02002485 return 1;
2486 }
2487#endif
Emmanuel Hocdet98263292016-12-29 18:26:15 +01002488 if (!bind_conf->default_ctx) {
Willy Tarreau2a65ff02012-09-13 17:54:29 +02002489 bind_conf->default_ctx = ctx;
Emmanuel Hocdet98263292016-12-29 18:26:15 +01002490 bind_conf->default_ssl_conf = ssl_conf;
2491 }
Emeric Brunfc0421f2012-09-07 17:30:07 +02002492
2493 return 0;
2494}
2495
Willy Tarreau03209342016-12-22 17:08:28 +01002496int ssl_sock_load_cert(char *path, struct bind_conf *bind_conf, char **err)
Emeric Brunfc0421f2012-09-07 17:30:07 +02002497{
Cyril Bonté3180f7b2015-01-25 00:16:08 +01002498 struct dirent **de_list;
2499 int i, n;
Emeric Brunfc0421f2012-09-07 17:30:07 +02002500 DIR *dir;
2501 struct stat buf;
Willy Tarreauee2663b2012-12-06 11:36:59 +01002502 char *end;
2503 char fp[MAXPATHLEN+1];
Emeric Brunfc0421f2012-09-07 17:30:07 +02002504 int cfgerr = 0;
yanbzhu63ea8462015-12-09 13:35:14 -05002505#if OPENSSL_VERSION_NUMBER >= 0x1000200fL
2506 int is_bundle;
2507 int j;
2508#endif
Emeric Brunfc0421f2012-09-07 17:30:07 +02002509
yanbzhu08ce6ab2015-12-02 13:01:29 -05002510 if (stat(path, &buf) == 0) {
2511 dir = opendir(path);
2512 if (!dir)
Emmanuel Hocdet98263292016-12-29 18:26:15 +01002513 return ssl_sock_load_cert_file(path, bind_conf, NULL, NULL, 0, err);
Emeric Brunfc0421f2012-09-07 17:30:07 +02002514
yanbzhu08ce6ab2015-12-02 13:01:29 -05002515 /* strip trailing slashes, including first one */
2516 for (end = path + strlen(path) - 1; end >= path && *end == '/'; end--)
2517 *end = 0;
Emeric Brunfc0421f2012-09-07 17:30:07 +02002518
yanbzhu08ce6ab2015-12-02 13:01:29 -05002519 n = scandir(path, &de_list, 0, alphasort);
2520 if (n < 0) {
2521 memprintf(err, "%sunable to scan directory '%s' : %s.\n",
2522 err && *err ? *err : "", path, strerror(errno));
2523 cfgerr++;
2524 }
2525 else {
2526 for (i = 0; i < n; i++) {
2527 struct dirent *de = de_list[i];
Emeric Brun2aab7222014-06-18 18:15:09 +02002528
yanbzhu08ce6ab2015-12-02 13:01:29 -05002529 end = strrchr(de->d_name, '.');
2530 if (end && (!strcmp(end, ".issuer") || !strcmp(end, ".ocsp") || !strcmp(end, ".sctl")))
2531 goto ignore_entry;
Cyril Bonté3180f7b2015-01-25 00:16:08 +01002532
yanbzhu08ce6ab2015-12-02 13:01:29 -05002533 snprintf(fp, sizeof(fp), "%s/%s", path, de->d_name);
2534 if (stat(fp, &buf) != 0) {
2535 memprintf(err, "%sunable to stat SSL certificate from file '%s' : %s.\n",
2536 err && *err ? *err : "", fp, strerror(errno));
2537 cfgerr++;
2538 goto ignore_entry;
2539 }
2540 if (!S_ISREG(buf.st_mode))
2541 goto ignore_entry;
yanbzhu63ea8462015-12-09 13:35:14 -05002542
2543#if OPENSSL_VERSION_NUMBER >= 0x1000200fL
2544 is_bundle = 0;
2545 /* Check if current entry in directory is part of a multi-cert bundle */
2546
2547 if (end) {
2548 for (j = 0; j < SSL_SOCK_NUM_KEYTYPES; j++) {
2549 if (!strcmp(end + 1, SSL_SOCK_KEYTYPE_NAMES[j])) {
2550 is_bundle = 1;
2551 break;
2552 }
2553 }
2554
2555 if (is_bundle) {
2556 char dp[MAXPATHLEN+1] = {0}; /* this will be the filename w/o the keytype */
2557 int dp_len;
2558
2559 dp_len = end - de->d_name;
2560 snprintf(dp, dp_len + 1, "%s", de->d_name);
2561
2562 /* increment i and free de until we get to a non-bundle cert
2563 * Note here that we look at de_list[i + 1] before freeing de
2564 * this is important since ignore_entry will free de
2565 */
2566 while (i + 1 < n && !strncmp(de_list[i + 1]->d_name, dp, dp_len)) {
2567 free(de);
2568 i++;
2569 de = de_list[i];
2570 }
2571
2572 snprintf(fp, sizeof(fp), "%s/%s", path, dp);
Emmanuel Hocdet98263292016-12-29 18:26:15 +01002573 ssl_sock_load_multi_cert(fp, bind_conf, NULL, NULL, 0, err);
yanbzhu63ea8462015-12-09 13:35:14 -05002574
2575 /* Successfully processed the bundle */
2576 goto ignore_entry;
2577 }
2578 }
2579
2580#endif
Emmanuel Hocdet98263292016-12-29 18:26:15 +01002581 cfgerr += ssl_sock_load_cert_file(fp, bind_conf, NULL, NULL, 0, err);
yanbzhu08ce6ab2015-12-02 13:01:29 -05002582ignore_entry:
2583 free(de);
Cyril Bonté3180f7b2015-01-25 00:16:08 +01002584 }
yanbzhu08ce6ab2015-12-02 13:01:29 -05002585 free(de_list);
Emeric Brunfc0421f2012-09-07 17:30:07 +02002586 }
yanbzhu08ce6ab2015-12-02 13:01:29 -05002587 closedir(dir);
2588 return cfgerr;
Emeric Brunfc0421f2012-09-07 17:30:07 +02002589 }
yanbzhu08ce6ab2015-12-02 13:01:29 -05002590
Emmanuel Hocdet98263292016-12-29 18:26:15 +01002591 cfgerr = ssl_sock_load_multi_cert(path, bind_conf, NULL, NULL, 0, err);
yanbzhu08ce6ab2015-12-02 13:01:29 -05002592
Emeric Brunfc0421f2012-09-07 17:30:07 +02002593 return cfgerr;
2594}
2595
Thierry Fournier383085f2013-01-24 14:15:43 +01002596/* Make sure openssl opens /dev/urandom before the chroot. The work is only
2597 * done once. Zero is returned if the operation fails. No error is returned
2598 * if the random is said as not implemented, because we expect that openssl
2599 * will use another method once needed.
2600 */
2601static int ssl_initialize_random()
2602{
2603 unsigned char random;
2604 static int random_initialized = 0;
2605
2606 if (!random_initialized && RAND_bytes(&random, 1) != 0)
2607 random_initialized = 1;
2608
2609 return random_initialized;
2610}
2611
Emmanuel Hocdet98263292016-12-29 18:26:15 +01002612/* release ssl bind conf */
2613void ssl_sock_free_ssl_conf(struct ssl_bind_conf *conf)
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01002614{
Emmanuel Hocdet98263292016-12-29 18:26:15 +01002615 if (conf) {
2616#ifdef OPENSSL_NPN_NEGOTIATED
2617 free(conf->npn_str);
2618 conf->npn_str = NULL;
2619#endif
2620#ifdef TLSEXT_TYPE_application_layer_protocol_negotiation
2621 free(conf->alpn_str);
2622 conf->alpn_str = NULL;
2623#endif
2624 free(conf->ca_file);
2625 conf->ca_file = NULL;
2626 free(conf->crl_file);
2627 conf->crl_file = NULL;
2628 free(conf->ciphers);
2629 conf->ciphers = NULL;
2630 free(conf->ecdhe);
2631 conf->ecdhe = NULL;
2632 }
2633}
2634
2635int ssl_sock_load_cert_list_file(char *file, struct bind_conf *bind_conf, struct proxy *curproxy, char **err)
2636{
2637 char thisline[CRT_LINESIZE];
2638 char path[MAXPATHLEN+1];
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01002639 FILE *f;
yanbzhu1b04e5b2015-12-02 13:54:14 -05002640 struct stat buf;
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01002641 int linenum = 0;
2642 int cfgerr = 0;
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01002643
Willy Tarreauad1731d2013-04-02 17:35:58 +02002644 if ((f = fopen(file, "r")) == NULL) {
2645 memprintf(err, "cannot open file '%s' : %s", file, strerror(errno));
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01002646 return 1;
Willy Tarreauad1731d2013-04-02 17:35:58 +02002647 }
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01002648
2649 while (fgets(thisline, sizeof(thisline), f) != NULL) {
Emmanuel Hocdet98263292016-12-29 18:26:15 +01002650 int arg, newarg, cur_arg, i, ssl_b = 0, ssl_e = 0;
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01002651 char *end;
Emmanuel Hocdet98263292016-12-29 18:26:15 +01002652 char *args[MAX_CRT_ARGS + 1];
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01002653 char *line = thisline;
Emmanuel Hocdet98263292016-12-29 18:26:15 +01002654 char *crt_path;
2655 struct ssl_bind_conf *ssl_conf = NULL;
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01002656
2657 linenum++;
2658 end = line + strlen(line);
2659 if (end-line == sizeof(thisline)-1 && *(end-1) != '\n') {
2660 /* Check if we reached the limit and the last char is not \n.
2661 * Watch out for the last line without the terminating '\n'!
2662 */
Willy Tarreauad1731d2013-04-02 17:35:58 +02002663 memprintf(err, "line %d too long in file '%s', limit is %d characters",
2664 linenum, file, (int)sizeof(thisline)-1);
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01002665 cfgerr = 1;
Willy Tarreauad1731d2013-04-02 17:35:58 +02002666 break;
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01002667 }
2668
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01002669 arg = 0;
Emeric Brun50bcecc2013-04-22 13:05:23 +02002670 newarg = 1;
2671 while (*line) {
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01002672 if (*line == '#' || *line == '\n' || *line == '\r') {
2673 /* end of string, end of loop */
2674 *line = 0;
2675 break;
Emmanuel Hocdet98263292016-12-29 18:26:15 +01002676 } else if (isspace(*line)) {
Emeric Brun50bcecc2013-04-22 13:05:23 +02002677 newarg = 1;
2678 *line = 0;
Emmanuel Hocdet98263292016-12-29 18:26:15 +01002679 } else if (*line == '[') {
2680 if (ssl_b) {
2681 memprintf(err, "too many '[' on line %d in file '%s'.", linenum, file);
2682 cfgerr = 1;
2683 break;
2684 }
2685 if (!arg) {
2686 memprintf(err, "file must start with a cert on line %d in file '%s'", linenum, file);
2687 cfgerr = 1;
2688 break;
2689 }
2690 ssl_b = arg;
2691 newarg = 1;
2692 *line = 0;
2693 } else if (*line == ']') {
2694 if (ssl_e) {
2695 memprintf(err, "too many ']' on line %d in file '%s'.", linenum, file);
Emeric Brun50bcecc2013-04-22 13:05:23 +02002696 cfgerr = 1;
2697 break;
2698 }
Emmanuel Hocdet98263292016-12-29 18:26:15 +01002699 if (!ssl_b) {
2700 memprintf(err, "missing '[' in line %d in file '%s'.", linenum, file);
2701 cfgerr = 1;
2702 break;
2703 }
2704 ssl_e = arg;
2705 newarg = 1;
2706 *line = 0;
2707 } else if (newarg) {
2708 if (arg == MAX_CRT_ARGS) {
2709 memprintf(err, "too many args on line %d in file '%s'.", linenum, file);
2710 cfgerr = 1;
2711 break;
2712 }
Emeric Brun50bcecc2013-04-22 13:05:23 +02002713 newarg = 0;
2714 args[arg++] = line;
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01002715 }
Emeric Brun50bcecc2013-04-22 13:05:23 +02002716 line++;
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01002717 }
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +02002718 if (cfgerr)
2719 break;
Emmanuel Hocdet98263292016-12-29 18:26:15 +01002720 args[arg++] = line;
Willy Tarreauad1731d2013-04-02 17:35:58 +02002721
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01002722 /* empty line */
Emmanuel Hocdet98263292016-12-29 18:26:15 +01002723 if (!*args[0])
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01002724 continue;
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01002725
Emmanuel Hocdet98263292016-12-29 18:26:15 +01002726 crt_path = args[0];
2727 if (*crt_path != '/' && global_ssl.crt_base) {
2728 if ((strlen(global_ssl.crt_base) + 1 + strlen(crt_path)) > MAXPATHLEN) {
2729 memprintf(err, "'%s' : path too long on line %d in file '%s'",
2730 crt_path, linenum, file);
2731 cfgerr = 1;
2732 break;
2733 }
2734 snprintf(path, sizeof(path), "%s/%s", global_ssl.crt_base, crt_path);
2735 crt_path = path;
2736 }
2737
2738 ssl_conf = calloc(1, sizeof *ssl_conf);
2739 cur_arg = ssl_b ? ssl_b : 1;
2740 while (cur_arg < ssl_e) {
2741 newarg = 0;
2742 for (i = 0; ssl_bind_kws[i].kw != NULL; i++) {
2743 if (strcmp(ssl_bind_kws[i].kw, args[cur_arg]) == 0) {
2744 newarg = 1;
2745 cfgerr = ssl_bind_kws[i].parse(args, cur_arg, curproxy, ssl_conf, err);
2746 if (cur_arg + 1 + ssl_bind_kws[i].skip > ssl_e) {
2747 memprintf(err, "ssl args out of '[]' for %s on line %d in file '%s'",
2748 args[cur_arg], linenum, file);
2749 cfgerr = 1;
2750 }
2751 cur_arg += 1 + ssl_bind_kws[i].skip;
2752 break;
2753 }
2754 }
2755 if (!cfgerr && !newarg) {
2756 memprintf(err, "unknown ssl keyword %s on line %d in file '%s'.",
2757 args[cur_arg], linenum, file);
2758 cfgerr = 1;
2759 break;
2760 }
2761 }
2762 if (cfgerr) {
2763 ssl_sock_free_ssl_conf(ssl_conf);
2764 free(ssl_conf);
2765 ssl_conf = NULL;
2766 break;
2767 }
2768
2769 if (stat(crt_path, &buf) == 0) {
2770 cfgerr = ssl_sock_load_cert_file(crt_path, bind_conf, ssl_conf,
2771 &args[cur_arg], arg - cur_arg - 1, err);
yanbzhu1b04e5b2015-12-02 13:54:14 -05002772 } else {
Emmanuel Hocdet98263292016-12-29 18:26:15 +01002773 cfgerr = ssl_sock_load_multi_cert(crt_path, bind_conf, ssl_conf,
2774 &args[cur_arg], arg - cur_arg - 1, err);
yanbzhu1b04e5b2015-12-02 13:54:14 -05002775 }
2776
Willy Tarreauad1731d2013-04-02 17:35:58 +02002777 if (cfgerr) {
2778 memprintf(err, "error processing line %d in file '%s' : %s", linenum, file, *err);
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01002779 break;
Willy Tarreauad1731d2013-04-02 17:35:58 +02002780 }
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01002781 }
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01002782 fclose(f);
2783 return cfgerr;
2784}
2785
Emeric Brunfc0421f2012-09-07 17:30:07 +02002786#ifndef SSL_OP_CIPHER_SERVER_PREFERENCE /* needs OpenSSL >= 0.9.7 */
2787#define SSL_OP_CIPHER_SERVER_PREFERENCE 0
2788#endif
2789
2790#ifndef SSL_OP_NO_SESSION_RESUMPTION_ON_RENEGOTIATION /* needs OpenSSL >= 0.9.7 */
2791#define SSL_OP_NO_SESSION_RESUMPTION_ON_RENEGOTIATION 0
Willy Tarreau7d588ee2012-11-26 18:47:31 +01002792#define SSL_renegotiate_pending(arg) 0
Emeric Brunfc0421f2012-09-07 17:30:07 +02002793#endif
Emeric Brun2b58d042012-09-20 17:10:03 +02002794#ifndef SSL_OP_SINGLE_ECDH_USE /* needs OpenSSL >= 0.9.8 */
2795#define SSL_OP_SINGLE_ECDH_USE 0
2796#endif
Emeric Brun2d0c4822012-10-02 13:45:20 +02002797#ifndef SSL_OP_NO_TICKET /* needs OpenSSL >= 0.9.8 */
2798#define SSL_OP_NO_TICKET 0
2799#endif
Emeric Brunfc0421f2012-09-07 17:30:07 +02002800#ifndef SSL_OP_NO_COMPRESSION /* needs OpenSSL >= 0.9.9 */
2801#define SSL_OP_NO_COMPRESSION 0
2802#endif
Emeric Brunc0ff4922012-09-28 19:37:02 +02002803#ifndef SSL_OP_NO_TLSv1_1 /* needs OpenSSL >= 1.0.1 */
2804#define SSL_OP_NO_TLSv1_1 0
2805#endif
2806#ifndef SSL_OP_NO_TLSv1_2 /* needs OpenSSL >= 1.0.1 */
2807#define SSL_OP_NO_TLSv1_2 0
2808#endif
Emeric Bruna4bcd9a2012-09-20 16:19:02 +02002809#ifndef SSL_OP_SINGLE_DH_USE /* needs OpenSSL >= 0.9.6 */
2810#define SSL_OP_SINGLE_DH_USE 0
2811#endif
Emeric Brun2b58d042012-09-20 17:10:03 +02002812#ifndef SSL_OP_SINGLE_ECDH_USE /* needs OpenSSL >= 1.0.0 */
2813#define SSL_OP_SINGLE_ECDH_USE 0
2814#endif
Emeric Brunfc0421f2012-09-07 17:30:07 +02002815#ifndef SSL_MODE_RELEASE_BUFFERS /* needs OpenSSL >= 1.0.0 */
2816#define SSL_MODE_RELEASE_BUFFERS 0
2817#endif
Willy Tarreau396a1862014-11-13 14:06:52 +01002818#ifndef SSL_MODE_SMALL_BUFFERS /* needs small_records.patch */
2819#define SSL_MODE_SMALL_BUFFERS 0
2820#endif
Remi Gacognef46cd6e2014-06-12 14:58:40 +02002821
Emmanuel Hocdet98263292016-12-29 18:26:15 +01002822int ssl_sock_prepare_ctx(struct bind_conf *bind_conf, struct ssl_bind_conf *ssl_conf, SSL_CTX *ctx)
Emeric Brunfc0421f2012-09-07 17:30:07 +02002823{
Willy Tarreau03209342016-12-22 17:08:28 +01002824 struct proxy *curproxy = bind_conf->frontend;
Emeric Brunfc0421f2012-09-07 17:30:07 +02002825 int cfgerr = 0;
Emeric Brun850efd52014-01-29 12:24:34 +01002826 int verify = SSL_VERIFY_NONE;
Remi Gacogneaf5c3da2014-05-19 10:29:58 +02002827 long ssloptions =
Emeric Brunfc0421f2012-09-07 17:30:07 +02002828 SSL_OP_ALL | /* all known workarounds for bugs */
2829 SSL_OP_NO_SSLv2 |
2830 SSL_OP_NO_COMPRESSION |
Emeric Bruna4bcd9a2012-09-20 16:19:02 +02002831 SSL_OP_SINGLE_DH_USE |
Emeric Brun2b58d042012-09-20 17:10:03 +02002832 SSL_OP_SINGLE_ECDH_USE |
Emeric Brun3c4bc6e2012-10-04 18:44:19 +02002833 SSL_OP_NO_SESSION_RESUMPTION_ON_RENEGOTIATION |
2834 SSL_OP_CIPHER_SERVER_PREFERENCE;
Remi Gacogneaf5c3da2014-05-19 10:29:58 +02002835 long sslmode =
Emeric Brunfc0421f2012-09-07 17:30:07 +02002836 SSL_MODE_ENABLE_PARTIAL_WRITE |
2837 SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER |
Willy Tarreau396a1862014-11-13 14:06:52 +01002838 SSL_MODE_RELEASE_BUFFERS |
2839 SSL_MODE_SMALL_BUFFERS;
Remi Gacognef46cd6e2014-06-12 14:58:40 +02002840 STACK_OF(SSL_CIPHER) * ciphers = NULL;
Willy Tarreaua616ba62014-10-26 06:49:19 +01002841 SSL_CIPHER * cipher = NULL;
Remi Gacognec1eab8c2014-06-12 18:20:11 +02002842 char cipher_description[128];
2843 /* The description of ciphers using an Ephemeral Diffie Hellman key exchange
2844 contains " Kx=DH " or " Kx=DH(". Beware of " Kx=DH/",
2845 which is not ephemeral DH. */
2846 const char dhe_description[] = " Kx=DH ";
2847 const char dhe_export_description[] = " Kx=DH(";
Remi Gacognef46cd6e2014-06-12 14:58:40 +02002848 int idx = 0;
2849 int dhe_found = 0;
Remi Gacogne23d5d372014-10-10 17:04:26 +02002850 SSL *ssl = NULL;
Emmanuel Hocdet98263292016-12-29 18:26:15 +01002851 struct ssl_bind_conf *ssl_conf_cur;
2852 int conf_ssl_options = bind_conf->ssl_conf.ssl_options | (ssl_conf ? ssl_conf->ssl_options : 0);
2853 const char *conf_ciphers;
Emeric Brunfc0421f2012-09-07 17:30:07 +02002854
Thierry Fournier383085f2013-01-24 14:15:43 +01002855 /* Make sure openssl opens /dev/urandom before the chroot */
2856 if (!ssl_initialize_random()) {
2857 Alert("OpenSSL random data generator initialization failed.\n");
2858 cfgerr++;
2859 }
2860
Emmanuel Hocdet98263292016-12-29 18:26:15 +01002861 if (conf_ssl_options & BC_SSL_O_NO_SSLV3)
Emeric Brunfc0421f2012-09-07 17:30:07 +02002862 ssloptions |= SSL_OP_NO_SSLv3;
Emmanuel Hocdet98263292016-12-29 18:26:15 +01002863 if (conf_ssl_options & BC_SSL_O_NO_TLSV10)
Emeric Brunfc0421f2012-09-07 17:30:07 +02002864 ssloptions |= SSL_OP_NO_TLSv1;
Emmanuel Hocdet98263292016-12-29 18:26:15 +01002865 if (conf_ssl_options & BC_SSL_O_NO_TLSV11)
Emeric Brunc0ff4922012-09-28 19:37:02 +02002866 ssloptions |= SSL_OP_NO_TLSv1_1;
Emmanuel Hocdet98263292016-12-29 18:26:15 +01002867 if (conf_ssl_options & BC_SSL_O_NO_TLSV12)
Emeric Brunc0ff4922012-09-28 19:37:02 +02002868 ssloptions |= SSL_OP_NO_TLSv1_2;
Emmanuel Hocdet98263292016-12-29 18:26:15 +01002869 if (conf_ssl_options & BC_SSL_O_NO_TLS_TICKETS)
Emeric Brun2d0c4822012-10-02 13:45:20 +02002870 ssloptions |= SSL_OP_NO_TICKET;
Emmanuel Hocdet98263292016-12-29 18:26:15 +01002871 if (conf_ssl_options & BC_SSL_O_USE_SSLV3) {
Jérémie Courrèges-Anglas17c3f622015-07-25 16:50:52 -06002872#ifndef OPENSSL_NO_SSL3
Emeric Brun2cb7ae52012-10-05 14:14:21 +02002873 SSL_CTX_set_ssl_version(ctx, SSLv3_server_method());
Jérémie Courrèges-Anglas17c3f622015-07-25 16:50:52 -06002874#else
2875 Alert("SSLv3 support requested but unavailable.\n");
2876 cfgerr++;
2877#endif
2878 }
Emmanuel Hocdet98263292016-12-29 18:26:15 +01002879 if (conf_ssl_options & BC_SSL_O_USE_TLSV10)
Emeric Brun2cb7ae52012-10-05 14:14:21 +02002880 SSL_CTX_set_ssl_version(ctx, TLSv1_server_method());
2881#if SSL_OP_NO_TLSv1_1
Emmanuel Hocdet98263292016-12-29 18:26:15 +01002882 if (conf_ssl_options & BC_SSL_O_USE_TLSV11)
Emeric Brun2cb7ae52012-10-05 14:14:21 +02002883 SSL_CTX_set_ssl_version(ctx, TLSv1_1_server_method());
2884#endif
2885#if SSL_OP_NO_TLSv1_2
Emmanuel Hocdet98263292016-12-29 18:26:15 +01002886 if (conf_ssl_options & BC_SSL_O_USE_TLSV12)
Emeric Brun2cb7ae52012-10-05 14:14:21 +02002887 SSL_CTX_set_ssl_version(ctx, TLSv1_2_server_method());
2888#endif
Emeric Brunfc0421f2012-09-07 17:30:07 +02002889
2890 SSL_CTX_set_options(ctx, ssloptions);
2891 SSL_CTX_set_mode(ctx, sslmode);
Emmanuel Hocdet98263292016-12-29 18:26:15 +01002892 switch ((ssl_conf && ssl_conf->verify) ? ssl_conf->verify : bind_conf->ssl_conf.verify) {
Emeric Brun850efd52014-01-29 12:24:34 +01002893 case SSL_SOCK_VERIFY_NONE:
2894 verify = SSL_VERIFY_NONE;
2895 break;
2896 case SSL_SOCK_VERIFY_OPTIONAL:
2897 verify = SSL_VERIFY_PEER;
2898 break;
2899 case SSL_SOCK_VERIFY_REQUIRED:
2900 verify = SSL_VERIFY_PEER|SSL_VERIFY_FAIL_IF_NO_PEER_CERT;
2901 break;
2902 }
2903 SSL_CTX_set_verify(ctx, verify, ssl_sock_bind_verifycbk);
2904 if (verify & SSL_VERIFY_PEER) {
Emmanuel Hocdet98263292016-12-29 18:26:15 +01002905 char *ca_file = (ssl_conf && ssl_conf->ca_file) ? ssl_conf->ca_file : bind_conf->ssl_conf.ca_file;
2906 char *crl_file = (ssl_conf && ssl_conf->crl_file) ? ssl_conf->crl_file : bind_conf->ssl_conf.crl_file;
2907 if (ca_file) {
Emeric Brund94b3fe2012-09-20 18:23:56 +02002908 /* load CAfile to verify */
Emmanuel Hocdet98263292016-12-29 18:26:15 +01002909 if (!SSL_CTX_load_verify_locations(ctx, ca_file, NULL)) {
Emeric Brund94b3fe2012-09-20 18:23:56 +02002910 Alert("Proxy '%s': unable to load CA file '%s' for bind '%s' at [%s:%d].\n",
Emmanuel Hocdet98263292016-12-29 18:26:15 +01002911 curproxy->id, ca_file, bind_conf->arg, bind_conf->file, bind_conf->line);
Emeric Brund94b3fe2012-09-20 18:23:56 +02002912 cfgerr++;
2913 }
2914 /* set CA names fo client cert request, function returns void */
Emmanuel Hocdet98263292016-12-29 18:26:15 +01002915 SSL_CTX_set_client_CA_list(ctx, SSL_load_client_CA_file(ca_file));
Emeric Brund94b3fe2012-09-20 18:23:56 +02002916 }
Emeric Brun850efd52014-01-29 12:24:34 +01002917 else {
2918 Alert("Proxy '%s': verify is enabled but no CA file specified for bind '%s' at [%s:%d].\n",
2919 curproxy->id, bind_conf->arg, bind_conf->file, bind_conf->line);
2920 cfgerr++;
2921 }
Emeric Brun051cdab2012-10-02 19:25:50 +02002922#ifdef X509_V_FLAG_CRL_CHECK
Emmanuel Hocdet98263292016-12-29 18:26:15 +01002923 if (crl_file) {
Emeric Brund94b3fe2012-09-20 18:23:56 +02002924 X509_STORE *store = SSL_CTX_get_cert_store(ctx);
2925
Emmanuel Hocdet98263292016-12-29 18:26:15 +01002926 if (!store || !X509_STORE_load_locations(store, crl_file, NULL)) {
Emeric Brund94b3fe2012-09-20 18:23:56 +02002927 Alert("Proxy '%s': unable to configure CRL file '%s' for bind '%s' at [%s:%d].\n",
Emmanuel Hocdet98263292016-12-29 18:26:15 +01002928 curproxy->id, crl_file, bind_conf->arg, bind_conf->file, bind_conf->line);
Emeric Brund94b3fe2012-09-20 18:23:56 +02002929 cfgerr++;
2930 }
Emeric Brun561e5742012-10-02 15:20:55 +02002931 else {
2932 X509_STORE_set_flags(store, X509_V_FLAG_CRL_CHECK|X509_V_FLAG_CRL_CHECK_ALL);
2933 }
Emeric Brund94b3fe2012-09-20 18:23:56 +02002934 }
Emeric Brun051cdab2012-10-02 19:25:50 +02002935#endif
Emeric Brun644cde02012-12-14 11:21:13 +01002936 ERR_clear_error();
Emeric Brund94b3fe2012-09-20 18:23:56 +02002937 }
Emeric Brunfc0421f2012-09-07 17:30:07 +02002938
Nenad Merdanovic05552d42015-02-27 19:56:49 +01002939#if (defined SSL_CTRL_SET_TLSEXT_TICKET_KEY_CB && TLS_TICKETS_NO > 0)
Nenad Merdanovic146defa2015-05-09 08:46:00 +02002940 if(bind_conf->keys_ref) {
Nenad Merdanovic05552d42015-02-27 19:56:49 +01002941 if (!SSL_CTX_set_tlsext_ticket_key_cb(ctx, ssl_tlsext_ticket_key_cb)) {
2942 Alert("Proxy '%s': unable to set callback for TLS ticket validation for bind '%s' at [%s:%d].\n",
2943 curproxy->id, bind_conf->arg, bind_conf->file, bind_conf->line);
2944 cfgerr++;
2945 }
2946 }
2947#endif
2948
Willy Tarreauef934602016-12-22 23:12:01 +01002949 if (global_ssl.life_time)
2950 SSL_CTX_set_timeout(ctx, global_ssl.life_time);
Emeric Brun4f65bff2012-11-16 15:11:00 +01002951
Emeric Brunfc0421f2012-09-07 17:30:07 +02002952 shared_context_set_cache(ctx);
Emmanuel Hocdet98263292016-12-29 18:26:15 +01002953 conf_ciphers = (ssl_conf && ssl_conf->ciphers) ? ssl_conf->ciphers : bind_conf->ssl_conf.ciphers;
2954 if (conf_ciphers &&
2955 !SSL_CTX_set_cipher_list(ctx, conf_ciphers)) {
Emeric Brunfc0421f2012-09-07 17:30:07 +02002956 Alert("Proxy '%s': unable to set SSL cipher list to '%s' for bind '%s' at [%s:%d].\n",
Emmanuel Hocdet98263292016-12-29 18:26:15 +01002957 curproxy->id, conf_ciphers, bind_conf->arg, bind_conf->file, bind_conf->line);
Emeric Brunfc0421f2012-09-07 17:30:07 +02002958 cfgerr++;
2959 }
2960
Remi Gacogne47783ef2015-05-29 15:53:22 +02002961 /* If tune.ssl.default-dh-param has not been set,
2962 neither has ssl-default-dh-file and no static DH
2963 params were in the certificate file. */
Willy Tarreauef934602016-12-22 23:12:01 +01002964 if (global_ssl.default_dh_param == 0 &&
Remi Gacogne47783ef2015-05-29 15:53:22 +02002965 global_dh == NULL &&
Remi Gacogne4f902b82015-05-28 16:23:00 +02002966 (ssl_dh_ptr_index == -1 ||
2967 SSL_CTX_get_ex_data(ctx, ssl_dh_ptr_index) == NULL)) {
Lukas Tribus90132722014-08-18 00:56:33 +02002968
Remi Gacogne23d5d372014-10-10 17:04:26 +02002969 ssl = SSL_new(ctx);
Remi Gacognef46cd6e2014-06-12 14:58:40 +02002970
Remi Gacogne23d5d372014-10-10 17:04:26 +02002971 if (ssl) {
2972 ciphers = SSL_get_ciphers(ssl);
2973
2974 if (ciphers) {
2975 for (idx = 0; idx < sk_SSL_CIPHER_num(ciphers); idx++) {
2976 cipher = sk_SSL_CIPHER_value(ciphers, idx);
2977 if (SSL_CIPHER_description(cipher, cipher_description, sizeof (cipher_description)) == cipher_description) {
2978 if (strstr(cipher_description, dhe_description) != NULL ||
2979 strstr(cipher_description, dhe_export_description) != NULL) {
2980 dhe_found = 1;
2981 break;
2982 }
Remi Gacognec1eab8c2014-06-12 18:20:11 +02002983 }
Remi Gacognef46cd6e2014-06-12 14:58:40 +02002984 }
2985 }
Remi Gacogne23d5d372014-10-10 17:04:26 +02002986 SSL_free(ssl);
2987 ssl = NULL;
Lukas Tribus90132722014-08-18 00:56:33 +02002988 }
Remi Gacognef46cd6e2014-06-12 14:58:40 +02002989
Lukas Tribus90132722014-08-18 00:56:33 +02002990 if (dhe_found) {
2991 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 +02002992 }
2993
Willy Tarreauef934602016-12-22 23:12:01 +01002994 global_ssl.default_dh_param = 1024;
Remi Gacognef46cd6e2014-06-12 14:58:40 +02002995 }
Remi Gacogne8de54152014-07-15 11:36:40 +02002996
2997#ifndef OPENSSL_NO_DH
Willy Tarreauef934602016-12-22 23:12:01 +01002998 if (global_ssl.default_dh_param >= 1024) {
Remi Gacogne8de54152014-07-15 11:36:40 +02002999 if (local_dh_1024 == NULL) {
3000 local_dh_1024 = ssl_get_dh_1024();
3001 }
Willy Tarreauef934602016-12-22 23:12:01 +01003002 if (global_ssl.default_dh_param >= 2048) {
Remi Gacogne8de54152014-07-15 11:36:40 +02003003 if (local_dh_2048 == NULL) {
3004 local_dh_2048 = ssl_get_dh_2048();
3005 }
Willy Tarreauef934602016-12-22 23:12:01 +01003006 if (global_ssl.default_dh_param >= 4096) {
Remi Gacogne8de54152014-07-15 11:36:40 +02003007 if (local_dh_4096 == NULL) {
3008 local_dh_4096 = ssl_get_dh_4096();
3009 }
Remi Gacogne8de54152014-07-15 11:36:40 +02003010 }
3011 }
3012 }
3013#endif /* OPENSSL_NO_DH */
Remi Gacognef46cd6e2014-06-12 14:58:40 +02003014
Emeric Brunfc0421f2012-09-07 17:30:07 +02003015 SSL_CTX_set_info_callback(ctx, ssl_sock_infocbk);
Willy Tarreau5cbe4ef2014-05-08 22:45:11 +02003016#if OPENSSL_VERSION_NUMBER >= 0x00907000L
Emeric Brun29f037d2014-04-25 19:05:36 +02003017 SSL_CTX_set_msg_callback(ctx, ssl_sock_msgcbk);
Willy Tarreau5cbe4ef2014-05-08 22:45:11 +02003018#endif
Emeric Brun29f037d2014-04-25 19:05:36 +02003019
Willy Tarreau6c9a3d52012-10-18 18:57:14 +02003020#ifdef OPENSSL_NPN_NEGOTIATED
Emmanuel Hocdet98263292016-12-29 18:26:15 +01003021 ssl_conf_cur = NULL;
3022 if (ssl_conf && ssl_conf->npn_str)
3023 ssl_conf_cur = ssl_conf;
3024 else if (bind_conf->ssl_conf.npn_str)
3025 ssl_conf_cur = &bind_conf->ssl_conf;
3026 if (ssl_conf_cur)
3027 SSL_CTX_set_next_protos_advertised_cb(ctx, ssl_sock_advertise_npn_protos, ssl_conf_cur);
Willy Tarreau6c9a3d52012-10-18 18:57:14 +02003028#endif
Dirkjan Bussink48f1c4e2014-02-13 12:29:42 +01003029#ifdef TLSEXT_TYPE_application_layer_protocol_negotiation
Emmanuel Hocdet98263292016-12-29 18:26:15 +01003030 ssl_conf_cur = NULL;
3031 if (ssl_conf && ssl_conf->alpn_str)
3032 ssl_conf_cur = ssl_conf;
3033 else if (bind_conf->ssl_conf.alpn_str)
3034 ssl_conf_cur = &bind_conf->ssl_conf;
3035 if (ssl_conf_cur)
3036 SSL_CTX_set_alpn_select_cb(ctx, ssl_sock_advertise_alpn_protos, ssl_conf_cur);
Willy Tarreauab861d32013-04-02 02:30:41 +02003037#endif
Willy Tarreau6c9a3d52012-10-18 18:57:14 +02003038
Emeric Brunfc0421f2012-09-07 17:30:07 +02003039#ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME
3040 SSL_CTX_set_tlsext_servername_callback(ctx, ssl_sock_switchctx_cbk);
Willy Tarreau2a65ff02012-09-13 17:54:29 +02003041 SSL_CTX_set_tlsext_servername_arg(ctx, bind_conf);
Emeric Brunfc0421f2012-09-07 17:30:07 +02003042#endif
Emeric Brun2b58d042012-09-20 17:10:03 +02003043#if defined(SSL_CTX_set_tmp_ecdh) && !defined(OPENSSL_NO_ECDH)
Emeric Brun6924ef82013-03-06 14:08:53 +01003044 {
Emeric Brun2b58d042012-09-20 17:10:03 +02003045 int i;
3046 EC_KEY *ecdh;
Emmanuel Hocdet98263292016-12-29 18:26:15 +01003047 const char *ecdhe = (ssl_conf && ssl_conf->ecdhe) ? ssl_conf->ecdhe :
3048 (bind_conf->ssl_conf.ecdhe ? bind_conf->ssl_conf.ecdhe : ECDHE_DEFAULT_CURVE);
Emeric Brun2b58d042012-09-20 17:10:03 +02003049
Emmanuel Hocdet98263292016-12-29 18:26:15 +01003050 i = OBJ_sn2nid(ecdhe);
Emeric Brun2b58d042012-09-20 17:10:03 +02003051 if (!i || ((ecdh = EC_KEY_new_by_curve_name(i)) == NULL)) {
3052 Alert("Proxy '%s': unable to set elliptic named curve to '%s' for bind '%s' at [%s:%d].\n",
Emmanuel Hocdet98263292016-12-29 18:26:15 +01003053 curproxy->id, ecdhe, bind_conf->arg, bind_conf->file, bind_conf->line);
Emeric Brun2b58d042012-09-20 17:10:03 +02003054 cfgerr++;
3055 }
3056 else {
3057 SSL_CTX_set_tmp_ecdh(ctx, ecdh);
3058 EC_KEY_free(ecdh);
3059 }
3060 }
3061#endif
3062
Emeric Brunfc0421f2012-09-07 17:30:07 +02003063 return cfgerr;
3064}
3065
Evan Broderbe554312013-06-27 00:05:25 -07003066static int ssl_sock_srv_hostcheck(const char *pattern, const char *hostname)
3067{
3068 const char *pattern_wildcard, *pattern_left_label_end, *hostname_left_label_end;
3069 size_t prefixlen, suffixlen;
3070
3071 /* Trivial case */
3072 if (strcmp(pattern, hostname) == 0)
3073 return 1;
3074
Evan Broderbe554312013-06-27 00:05:25 -07003075 /* The rest of this logic is based on RFC 6125, section 6.4.3
3076 * (http://tools.ietf.org/html/rfc6125#section-6.4.3) */
3077
Emeric Bruna848dae2013-10-08 11:27:28 +02003078 pattern_wildcard = NULL;
3079 pattern_left_label_end = pattern;
3080 while (*pattern_left_label_end != '.') {
3081 switch (*pattern_left_label_end) {
3082 case 0:
3083 /* End of label not found */
3084 return 0;
3085 case '*':
3086 /* If there is more than one wildcards */
3087 if (pattern_wildcard)
3088 return 0;
3089 pattern_wildcard = pattern_left_label_end;
3090 break;
3091 }
3092 pattern_left_label_end++;
3093 }
3094
3095 /* If it's not trivial and there is no wildcard, it can't
3096 * match */
3097 if (!pattern_wildcard)
Evan Broderbe554312013-06-27 00:05:25 -07003098 return 0;
3099
3100 /* Make sure all labels match except the leftmost */
3101 hostname_left_label_end = strchr(hostname, '.');
3102 if (!hostname_left_label_end
3103 || strcmp(pattern_left_label_end, hostname_left_label_end) != 0)
3104 return 0;
3105
3106 /* Make sure the leftmost label of the hostname is long enough
3107 * that the wildcard can match */
Emeric Brun369da852013-10-08 11:39:35 +02003108 if (hostname_left_label_end - hostname < (pattern_left_label_end - pattern) - 1)
Evan Broderbe554312013-06-27 00:05:25 -07003109 return 0;
3110
3111 /* Finally compare the string on either side of the
3112 * wildcard */
3113 prefixlen = pattern_wildcard - pattern;
3114 suffixlen = pattern_left_label_end - (pattern_wildcard + 1);
Emeric Bruna848dae2013-10-08 11:27:28 +02003115 if ((prefixlen && (memcmp(pattern, hostname, prefixlen) != 0))
3116 || (suffixlen && (memcmp(pattern_wildcard + 1, hostname_left_label_end - suffixlen, suffixlen) != 0)))
Evan Broderbe554312013-06-27 00:05:25 -07003117 return 0;
3118
3119 return 1;
3120}
3121
3122static int ssl_sock_srv_verifycbk(int ok, X509_STORE_CTX *ctx)
3123{
3124 SSL *ssl;
3125 struct connection *conn;
3126 char *servername;
3127
3128 int depth;
3129 X509 *cert;
3130 STACK_OF(GENERAL_NAME) *alt_names;
3131 int i;
3132 X509_NAME *cert_subject;
3133 char *str;
3134
3135 if (ok == 0)
3136 return ok;
3137
3138 ssl = X509_STORE_CTX_get_ex_data(ctx, SSL_get_ex_data_X509_STORE_CTX_idx());
Vincent Bernat3c2f2f22016-04-03 13:48:42 +02003139 conn = SSL_get_app_data(ssl);
Evan Broderbe554312013-06-27 00:05:25 -07003140
3141 servername = objt_server(conn->target)->ssl_ctx.verify_host;
3142
3143 /* We only need to verify the CN on the actual server cert,
3144 * not the indirect CAs */
3145 depth = X509_STORE_CTX_get_error_depth(ctx);
3146 if (depth != 0)
3147 return ok;
3148
3149 /* At this point, the cert is *not* OK unless we can find a
3150 * hostname match */
3151 ok = 0;
3152
3153 cert = X509_STORE_CTX_get_current_cert(ctx);
3154 /* It seems like this might happen if verify peer isn't set */
3155 if (!cert)
3156 return ok;
3157
3158 alt_names = X509_get_ext_d2i(cert, NID_subject_alt_name, NULL, NULL);
3159 if (alt_names) {
3160 for (i = 0; !ok && i < sk_GENERAL_NAME_num(alt_names); i++) {
3161 GENERAL_NAME *name = sk_GENERAL_NAME_value(alt_names, i);
3162 if (name->type == GEN_DNS) {
Emeric Bruna33410c2013-09-17 15:47:48 +02003163#if OPENSSL_VERSION_NUMBER < 0x00907000L
3164 if (ASN1_STRING_to_UTF8((unsigned char **)&str, name->d.ia5) >= 0) {
3165#else
Evan Broderbe554312013-06-27 00:05:25 -07003166 if (ASN1_STRING_to_UTF8((unsigned char **)&str, name->d.dNSName) >= 0) {
Emeric Bruna33410c2013-09-17 15:47:48 +02003167#endif
Evan Broderbe554312013-06-27 00:05:25 -07003168 ok = ssl_sock_srv_hostcheck(str, servername);
3169 OPENSSL_free(str);
3170 }
3171 }
3172 }
Emeric Brun4ad50a42013-09-17 15:19:54 +02003173 sk_GENERAL_NAME_pop_free(alt_names, GENERAL_NAME_free);
Evan Broderbe554312013-06-27 00:05:25 -07003174 }
3175
3176 cert_subject = X509_get_subject_name(cert);
3177 i = -1;
3178 while (!ok && (i = X509_NAME_get_index_by_NID(cert_subject, NID_commonName, i)) != -1) {
3179 X509_NAME_ENTRY *entry = X509_NAME_get_entry(cert_subject, i);
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02003180 ASN1_STRING *value;
3181 value = X509_NAME_ENTRY_get_data(entry);
3182 if (ASN1_STRING_to_UTF8((unsigned char **)&str, value) >= 0) {
Evan Broderbe554312013-06-27 00:05:25 -07003183 ok = ssl_sock_srv_hostcheck(str, servername);
3184 OPENSSL_free(str);
3185 }
3186 }
3187
3188 return ok;
3189}
3190
Emeric Brun94324a42012-10-11 14:00:19 +02003191/* prepare ssl context from servers options. Returns an error count */
Willy Tarreau03209342016-12-22 17:08:28 +01003192int ssl_sock_prepare_srv_ctx(struct server *srv)
Emeric Brun94324a42012-10-11 14:00:19 +02003193{
Willy Tarreau03209342016-12-22 17:08:28 +01003194 struct proxy *curproxy = srv->proxy;
Emeric Brun94324a42012-10-11 14:00:19 +02003195 int cfgerr = 0;
Remi Gacogneaf5c3da2014-05-19 10:29:58 +02003196 long options =
Emeric Brun94324a42012-10-11 14:00:19 +02003197 SSL_OP_ALL | /* all known workarounds for bugs */
3198 SSL_OP_NO_SSLv2 |
3199 SSL_OP_NO_COMPRESSION;
Remi Gacogneaf5c3da2014-05-19 10:29:58 +02003200 long mode =
Emeric Brun94324a42012-10-11 14:00:19 +02003201 SSL_MODE_ENABLE_PARTIAL_WRITE |
3202 SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER |
Willy Tarreau396a1862014-11-13 14:06:52 +01003203 SSL_MODE_RELEASE_BUFFERS |
3204 SSL_MODE_SMALL_BUFFERS;
Emeric Brun850efd52014-01-29 12:24:34 +01003205 int verify = SSL_VERIFY_NONE;
Emeric Brun94324a42012-10-11 14:00:19 +02003206
Thierry Fournier383085f2013-01-24 14:15:43 +01003207 /* Make sure openssl opens /dev/urandom before the chroot */
3208 if (!ssl_initialize_random()) {
3209 Alert("OpenSSL random data generator initialization failed.\n");
3210 cfgerr++;
3211 }
3212
Willy Tarreaufce03112015-01-15 21:32:40 +01003213 /* Automatic memory computations need to know we use SSL there */
3214 global.ssl_used_backend = 1;
3215
3216 /* Initiate SSL context for current server */
Emeric Brun94324a42012-10-11 14:00:19 +02003217 srv->ssl_ctx.reused_sess = NULL;
3218 if (srv->use_ssl)
3219 srv->xprt = &ssl_sock;
3220 if (srv->check.use_ssl)
Cyril Bonté9ce13112014-11-15 22:41:27 +01003221 srv->check.xprt = &ssl_sock;
Emeric Brun94324a42012-10-11 14:00:19 +02003222
3223 srv->ssl_ctx.ctx = SSL_CTX_new(SSLv23_client_method());
3224 if (!srv->ssl_ctx.ctx) {
3225 Alert("config : %s '%s', server '%s': unable to allocate ssl context.\n",
3226 proxy_type_str(curproxy), curproxy->id,
3227 srv->id);
3228 cfgerr++;
3229 return cfgerr;
3230 }
Emeric Bruna7aa3092012-10-26 12:58:00 +02003231 if (srv->ssl_ctx.client_crt) {
3232 if (SSL_CTX_use_PrivateKey_file(srv->ssl_ctx.ctx, srv->ssl_ctx.client_crt, SSL_FILETYPE_PEM) <= 0) {
3233 Alert("config : %s '%s', server '%s': unable to load SSL private key from PEM file '%s'.\n",
3234 proxy_type_str(curproxy), curproxy->id,
3235 srv->id, srv->ssl_ctx.client_crt);
3236 cfgerr++;
3237 }
3238 else if (SSL_CTX_use_certificate_chain_file(srv->ssl_ctx.ctx, srv->ssl_ctx.client_crt) <= 0) {
3239 Alert("config : %s '%s', server '%s': unable to load ssl certificate from PEM file '%s'.\n",
3240 proxy_type_str(curproxy), curproxy->id,
3241 srv->id, srv->ssl_ctx.client_crt);
3242 cfgerr++;
3243 }
3244 else if (SSL_CTX_check_private_key(srv->ssl_ctx.ctx) <= 0) {
3245 Alert("config : %s '%s', server '%s': inconsistencies between private key and certificate loaded from PEM file '%s'.\n",
3246 proxy_type_str(curproxy), curproxy->id,
3247 srv->id, srv->ssl_ctx.client_crt);
3248 cfgerr++;
3249 }
3250 }
Emeric Brun94324a42012-10-11 14:00:19 +02003251
3252 if (srv->ssl_ctx.options & SRV_SSL_O_NO_SSLV3)
3253 options |= SSL_OP_NO_SSLv3;
3254 if (srv->ssl_ctx.options & SRV_SSL_O_NO_TLSV10)
3255 options |= SSL_OP_NO_TLSv1;
3256 if (srv->ssl_ctx.options & SRV_SSL_O_NO_TLSV11)
3257 options |= SSL_OP_NO_TLSv1_1;
3258 if (srv->ssl_ctx.options & SRV_SSL_O_NO_TLSV12)
3259 options |= SSL_OP_NO_TLSv1_2;
Emeric Brunf9c5c472012-10-11 15:28:34 +02003260 if (srv->ssl_ctx.options & SRV_SSL_O_NO_TLS_TICKETS)
3261 options |= SSL_OP_NO_TICKET;
Jérémie Courrèges-Anglas17c3f622015-07-25 16:50:52 -06003262 if (srv->ssl_ctx.options & SRV_SSL_O_USE_SSLV3) {
3263#ifndef OPENSSL_NO_SSL3
Emeric Brun94324a42012-10-11 14:00:19 +02003264 SSL_CTX_set_ssl_version(srv->ssl_ctx.ctx, SSLv3_client_method());
Jérémie Courrèges-Anglas17c3f622015-07-25 16:50:52 -06003265#else
Thierry FOURNIERbc965342015-08-26 08:21:26 +02003266 Alert("SSLv3 support requested but unavailable.\n");
Jérémie Courrèges-Anglas17c3f622015-07-25 16:50:52 -06003267 cfgerr++;
3268#endif
3269 }
Emeric Brun94324a42012-10-11 14:00:19 +02003270 if (srv->ssl_ctx.options & SRV_SSL_O_USE_TLSV10)
3271 SSL_CTX_set_ssl_version(srv->ssl_ctx.ctx, TLSv1_client_method());
3272#if SSL_OP_NO_TLSv1_1
3273 if (srv->ssl_ctx.options & SRV_SSL_O_USE_TLSV11)
3274 SSL_CTX_set_ssl_version(srv->ssl_ctx.ctx, TLSv1_1_client_method());
3275#endif
3276#if SSL_OP_NO_TLSv1_2
3277 if (srv->ssl_ctx.options & SRV_SSL_O_USE_TLSV12)
3278 SSL_CTX_set_ssl_version(srv->ssl_ctx.ctx, TLSv1_2_client_method());
3279#endif
3280
3281 SSL_CTX_set_options(srv->ssl_ctx.ctx, options);
3282 SSL_CTX_set_mode(srv->ssl_ctx.ctx, mode);
Emeric Brun850efd52014-01-29 12:24:34 +01003283
3284 if (global.ssl_server_verify == SSL_SERVER_VERIFY_REQUIRED)
3285 verify = SSL_VERIFY_PEER;
3286
3287 switch (srv->ssl_ctx.verify) {
3288 case SSL_SOCK_VERIFY_NONE:
3289 verify = SSL_VERIFY_NONE;
3290 break;
3291 case SSL_SOCK_VERIFY_REQUIRED:
3292 verify = SSL_VERIFY_PEER;
3293 break;
3294 }
Evan Broderbe554312013-06-27 00:05:25 -07003295 SSL_CTX_set_verify(srv->ssl_ctx.ctx,
Emeric Brun850efd52014-01-29 12:24:34 +01003296 verify,
Evan Broderbe554312013-06-27 00:05:25 -07003297 srv->ssl_ctx.verify_host ? ssl_sock_srv_verifycbk : NULL);
Emeric Brun850efd52014-01-29 12:24:34 +01003298 if (verify & SSL_VERIFY_PEER) {
Emeric Brunef42d922012-10-11 16:11:36 +02003299 if (srv->ssl_ctx.ca_file) {
3300 /* load CAfile to verify */
3301 if (!SSL_CTX_load_verify_locations(srv->ssl_ctx.ctx, srv->ssl_ctx.ca_file, NULL)) {
Willy Tarreau07ba08b2014-02-16 19:22:08 +01003302 Alert("Proxy '%s', server '%s' [%s:%d] unable to load CA file '%s'.\n",
Emeric Brunef42d922012-10-11 16:11:36 +02003303 curproxy->id, srv->id,
3304 srv->conf.file, srv->conf.line, srv->ssl_ctx.ca_file);
3305 cfgerr++;
3306 }
3307 }
Emeric Brun850efd52014-01-29 12:24:34 +01003308 else {
3309 if (global.ssl_server_verify == SSL_SERVER_VERIFY_REQUIRED)
Willy Tarreau07ba08b2014-02-16 19:22:08 +01003310 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 +01003311 curproxy->id, srv->id,
3312 srv->conf.file, srv->conf.line);
3313 else
Willy Tarreau07ba08b2014-02-16 19:22:08 +01003314 Alert("Proxy '%s', server '%s' [%s:%d] verify is enabled but no CA file specified.\n",
Emeric Brun850efd52014-01-29 12:24:34 +01003315 curproxy->id, srv->id,
3316 srv->conf.file, srv->conf.line);
3317 cfgerr++;
3318 }
Emeric Brunef42d922012-10-11 16:11:36 +02003319#ifdef X509_V_FLAG_CRL_CHECK
3320 if (srv->ssl_ctx.crl_file) {
3321 X509_STORE *store = SSL_CTX_get_cert_store(srv->ssl_ctx.ctx);
3322
3323 if (!store || !X509_STORE_load_locations(store, srv->ssl_ctx.crl_file, NULL)) {
Willy Tarreau07ba08b2014-02-16 19:22:08 +01003324 Alert("Proxy '%s', server '%s' [%s:%d] unable to configure CRL file '%s'.\n",
Emeric Brunef42d922012-10-11 16:11:36 +02003325 curproxy->id, srv->id,
3326 srv->conf.file, srv->conf.line, srv->ssl_ctx.crl_file);
3327 cfgerr++;
3328 }
3329 else {
3330 X509_STORE_set_flags(store, X509_V_FLAG_CRL_CHECK|X509_V_FLAG_CRL_CHECK_ALL);
3331 }
3332 }
3333#endif
3334 }
3335
Willy Tarreauef934602016-12-22 23:12:01 +01003336 if (global_ssl.life_time)
3337 SSL_CTX_set_timeout(srv->ssl_ctx.ctx, global_ssl.life_time);
Emeric Brun4f65bff2012-11-16 15:11:00 +01003338
Emeric Brun94324a42012-10-11 14:00:19 +02003339 SSL_CTX_set_session_cache_mode(srv->ssl_ctx.ctx, SSL_SESS_CACHE_OFF);
3340 if (srv->ssl_ctx.ciphers &&
3341 !SSL_CTX_set_cipher_list(srv->ssl_ctx.ctx, srv->ssl_ctx.ciphers)) {
3342 Alert("Proxy '%s', server '%s' [%s:%d] : unable to set SSL cipher list to '%s'.\n",
3343 curproxy->id, srv->id,
3344 srv->conf.file, srv->conf.line, srv->ssl_ctx.ciphers);
3345 cfgerr++;
3346 }
3347
3348 return cfgerr;
3349}
3350
Willy Tarreau2a65ff02012-09-13 17:54:29 +02003351/* Walks down the two trees in bind_conf and prepares all certs. The pointer may
Emeric Brunfc0421f2012-09-07 17:30:07 +02003352 * be NULL, in which case nothing is done. Returns the number of errors
3353 * encountered.
3354 */
Willy Tarreau03209342016-12-22 17:08:28 +01003355int ssl_sock_prepare_all_ctx(struct bind_conf *bind_conf)
Emeric Brunfc0421f2012-09-07 17:30:07 +02003356{
3357 struct ebmb_node *node;
3358 struct sni_ctx *sni;
3359 int err = 0;
3360
Willy Tarreau2a65ff02012-09-13 17:54:29 +02003361 if (!bind_conf || !bind_conf->is_ssl)
Emeric Brunfc0421f2012-09-07 17:30:07 +02003362 return 0;
3363
Willy Tarreaufce03112015-01-15 21:32:40 +01003364 /* Automatic memory computations need to know we use SSL there */
3365 global.ssl_used_frontend = 1;
3366
Emeric Brun0bed9942014-10-30 19:25:24 +01003367 if (bind_conf->default_ctx)
Emmanuel Hocdet98263292016-12-29 18:26:15 +01003368 err += ssl_sock_prepare_ctx(bind_conf, bind_conf->default_ssl_conf, bind_conf->default_ctx);
Emeric Brun0bed9942014-10-30 19:25:24 +01003369
Willy Tarreau2a65ff02012-09-13 17:54:29 +02003370 node = ebmb_first(&bind_conf->sni_ctx);
Emeric Brunfc0421f2012-09-07 17:30:07 +02003371 while (node) {
3372 sni = ebmb_entry(node, struct sni_ctx, name);
Emeric Brun0bed9942014-10-30 19:25:24 +01003373 if (!sni->order && sni->ctx != bind_conf->default_ctx)
3374 /* only initialize the CTX on its first occurrence and
3375 if it is not the default_ctx */
Emmanuel Hocdet98263292016-12-29 18:26:15 +01003376 err += ssl_sock_prepare_ctx(bind_conf, sni->conf, sni->ctx);
Emeric Brunfc0421f2012-09-07 17:30:07 +02003377 node = ebmb_next(node);
3378 }
3379
Willy Tarreau2a65ff02012-09-13 17:54:29 +02003380 node = ebmb_first(&bind_conf->sni_w_ctx);
Emeric Brunfc0421f2012-09-07 17:30:07 +02003381 while (node) {
3382 sni = ebmb_entry(node, struct sni_ctx, name);
Emeric Brun0bed9942014-10-30 19:25:24 +01003383 if (!sni->order && sni->ctx != bind_conf->default_ctx)
3384 /* only initialize the CTX on its first occurrence and
3385 if it is not the default_ctx */
Emmanuel Hocdet98263292016-12-29 18:26:15 +01003386 err += ssl_sock_prepare_ctx(bind_conf, sni->conf, sni->ctx);
Emeric Brunfc0421f2012-09-07 17:30:07 +02003387 node = ebmb_next(node);
3388 }
3389 return err;
3390}
3391
Willy Tarreau55d37912016-12-21 23:38:39 +01003392/* Prepares all the contexts for a bind_conf and allocates the shared SSL
3393 * context if needed. Returns < 0 on error, 0 on success. The warnings and
3394 * alerts are directly emitted since the rest of the stack does it below.
3395 */
3396int ssl_sock_prepare_bind_conf(struct bind_conf *bind_conf)
3397{
3398 struct proxy *px = bind_conf->frontend;
3399 int alloc_ctx;
3400 int err;
3401
3402 if (!bind_conf->is_ssl) {
3403 if (bind_conf->default_ctx) {
3404 Warning("Proxy '%s': A certificate was specified but SSL was not enabled on bind '%s' at [%s:%d] (use 'ssl').\n",
3405 px->id, bind_conf->arg, bind_conf->file, bind_conf->line);
3406 }
3407 return 0;
3408 }
3409 if (!bind_conf->default_ctx) {
3410 Alert("Proxy '%s': no SSL certificate specified for bind '%s' at [%s:%d] (use 'crt').\n",
3411 px->id, bind_conf->arg, bind_conf->file, bind_conf->line);
3412 return -1;
3413 }
3414
Willy Tarreauef934602016-12-22 23:12:01 +01003415 alloc_ctx = shared_context_init(global.tune.sslcachesize, (!global_ssl.private_cache && (global.nbproc > 1)) ? 1 : 0);
Willy Tarreau55d37912016-12-21 23:38:39 +01003416 if (alloc_ctx < 0) {
3417 if (alloc_ctx == SHCTX_E_INIT_LOCK)
3418 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");
3419 else
3420 Alert("Unable to allocate SSL session cache.\n");
3421 return -1;
3422 }
3423
3424 err = 0;
3425 /* initialize all certificate contexts */
3426 err += ssl_sock_prepare_all_ctx(bind_conf);
3427
3428 /* initialize CA variables if the certificates generation is enabled */
3429 err += ssl_sock_load_ca(bind_conf);
3430
3431 return -err;
3432}
Christopher Faulet77fe80c2015-07-29 13:02:40 +02003433
3434/* release ssl context allocated for servers. */
3435void ssl_sock_free_srv_ctx(struct server *srv)
3436{
3437 if (srv->ssl_ctx.ctx)
3438 SSL_CTX_free(srv->ssl_ctx.ctx);
3439}
3440
Willy Tarreau2a65ff02012-09-13 17:54:29 +02003441/* Walks down the two trees in bind_conf and frees all the certs. The pointer may
Emeric Brunfc0421f2012-09-07 17:30:07 +02003442 * be NULL, in which case nothing is done. The default_ctx is nullified too.
3443 */
Willy Tarreau2a65ff02012-09-13 17:54:29 +02003444void ssl_sock_free_all_ctx(struct bind_conf *bind_conf)
Emeric Brunfc0421f2012-09-07 17:30:07 +02003445{
3446 struct ebmb_node *node, *back;
3447 struct sni_ctx *sni;
3448
Willy Tarreau2a65ff02012-09-13 17:54:29 +02003449 if (!bind_conf || !bind_conf->is_ssl)
Emeric Brunfc0421f2012-09-07 17:30:07 +02003450 return;
3451
Willy Tarreau2a65ff02012-09-13 17:54:29 +02003452 node = ebmb_first(&bind_conf->sni_ctx);
Emeric Brunfc0421f2012-09-07 17:30:07 +02003453 while (node) {
3454 sni = ebmb_entry(node, struct sni_ctx, name);
3455 back = ebmb_next(node);
3456 ebmb_delete(node);
Emmanuel Hocdet98263292016-12-29 18:26:15 +01003457 if (!sni->order) { /* only free the CTX on its first occurrence */
Emeric Brunfc0421f2012-09-07 17:30:07 +02003458 SSL_CTX_free(sni->ctx);
Emmanuel Hocdet98263292016-12-29 18:26:15 +01003459 ssl_sock_free_ssl_conf(sni->conf);
3460 free(sni->conf);
3461 sni->conf = NULL;
3462 }
Emeric Brunfc0421f2012-09-07 17:30:07 +02003463 free(sni);
3464 node = back;
3465 }
3466
Willy Tarreau2a65ff02012-09-13 17:54:29 +02003467 node = ebmb_first(&bind_conf->sni_w_ctx);
Emeric Brunfc0421f2012-09-07 17:30:07 +02003468 while (node) {
3469 sni = ebmb_entry(node, struct sni_ctx, name);
3470 back = ebmb_next(node);
3471 ebmb_delete(node);
Emmanuel Hocdet98263292016-12-29 18:26:15 +01003472 if (!sni->order) { /* only free the CTX on its first occurrence */
Emeric Brunfc0421f2012-09-07 17:30:07 +02003473 SSL_CTX_free(sni->ctx);
Emmanuel Hocdet98263292016-12-29 18:26:15 +01003474 ssl_sock_free_ssl_conf(sni->conf);
3475 free(sni->conf);
3476 sni->conf = NULL;
3477 }
Emeric Brunfc0421f2012-09-07 17:30:07 +02003478 free(sni);
3479 node = back;
3480 }
3481
Willy Tarreau2a65ff02012-09-13 17:54:29 +02003482 bind_conf->default_ctx = NULL;
Emmanuel Hocdet98263292016-12-29 18:26:15 +01003483 bind_conf->default_ssl_conf = NULL;
Emeric Brune1f38db2012-09-03 20:36:47 +02003484}
3485
Willy Tarreau795cdab2016-12-22 17:30:54 +01003486/* Destroys all the contexts for a bind_conf. This is used during deinit(). */
3487void ssl_sock_destroy_bind_conf(struct bind_conf *bind_conf)
3488{
3489 ssl_sock_free_ca(bind_conf);
3490 ssl_sock_free_all_ctx(bind_conf);
Emmanuel Hocdet98263292016-12-29 18:26:15 +01003491 ssl_sock_free_ssl_conf(&bind_conf->ssl_conf);
Willy Tarreau795cdab2016-12-22 17:30:54 +01003492 free(bind_conf->ca_sign_file);
3493 free(bind_conf->ca_sign_pass);
Willy Tarreau795cdab2016-12-22 17:30:54 +01003494 if (bind_conf->keys_ref) {
3495 free(bind_conf->keys_ref->filename);
3496 free(bind_conf->keys_ref->tlskeys);
3497 LIST_DEL(&bind_conf->keys_ref->list);
3498 free(bind_conf->keys_ref);
3499 }
3500 bind_conf->keys_ref = NULL;
Willy Tarreau795cdab2016-12-22 17:30:54 +01003501 bind_conf->ca_sign_pass = NULL;
3502 bind_conf->ca_sign_file = NULL;
Willy Tarreau795cdab2016-12-22 17:30:54 +01003503}
3504
Christopher Faulet31af49d2015-06-09 17:29:50 +02003505/* Load CA cert file and private key used to generate certificates */
3506int
Willy Tarreau03209342016-12-22 17:08:28 +01003507ssl_sock_load_ca(struct bind_conf *bind_conf)
Christopher Faulet31af49d2015-06-09 17:29:50 +02003508{
Willy Tarreau03209342016-12-22 17:08:28 +01003509 struct proxy *px = bind_conf->frontend;
Christopher Faulet31af49d2015-06-09 17:29:50 +02003510 FILE *fp;
3511 X509 *cacert = NULL;
3512 EVP_PKEY *capkey = NULL;
3513 int err = 0;
3514
3515 if (!bind_conf || !bind_conf->generate_certs)
3516 return err;
3517
Willy Tarreaua84c2672015-10-09 12:10:13 +02003518#ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME
Willy Tarreauef934602016-12-22 23:12:01 +01003519 if (global_ssl.ctx_cache)
3520 ssl_ctx_lru_tree = lru64_new(global_ssl.ctx_cache);
Christopher Fauletd2cab922015-07-28 16:03:47 +02003521 ssl_ctx_lru_seed = (unsigned int)time(NULL);
Willy Tarreaua84c2672015-10-09 12:10:13 +02003522#endif
Christopher Fauletd2cab922015-07-28 16:03:47 +02003523
Christopher Faulet31af49d2015-06-09 17:29:50 +02003524 if (!bind_conf->ca_sign_file) {
3525 Alert("Proxy '%s': cannot enable certificate generation, "
3526 "no CA certificate File configured at [%s:%d].\n",
3527 px->id, bind_conf->file, bind_conf->line);
Christopher Faulet31af49d2015-06-09 17:29:50 +02003528 goto load_error;
Christopher Fauletc6f02fb2015-10-09 10:53:31 +02003529 }
Christopher Faulet31af49d2015-06-09 17:29:50 +02003530
3531 /* read in the CA certificate */
3532 if (!(fp = fopen(bind_conf->ca_sign_file, "r"))) {
3533 Alert("Proxy '%s': Failed to read CA certificate file '%s' at [%s:%d].\n",
3534 px->id, bind_conf->ca_sign_file, bind_conf->file, bind_conf->line);
Christopher Faulet31af49d2015-06-09 17:29:50 +02003535 goto load_error;
3536 }
3537 if (!(cacert = PEM_read_X509(fp, NULL, NULL, NULL))) {
3538 Alert("Proxy '%s': Failed to read CA certificate file '%s' at [%s:%d].\n",
3539 px->id, bind_conf->ca_sign_file, bind_conf->file, bind_conf->line);
Christopher Fauletc6f02fb2015-10-09 10:53:31 +02003540 goto read_error;
Christopher Faulet31af49d2015-06-09 17:29:50 +02003541 }
Christopher Fauletc6f02fb2015-10-09 10:53:31 +02003542 rewind(fp);
Christopher Faulet31af49d2015-06-09 17:29:50 +02003543 if (!(capkey = PEM_read_PrivateKey(fp, NULL, NULL, bind_conf->ca_sign_pass))) {
3544 Alert("Proxy '%s': Failed to read CA private key file '%s' at [%s:%d].\n",
3545 px->id, bind_conf->ca_sign_file, bind_conf->file, bind_conf->line);
Christopher Fauletc6f02fb2015-10-09 10:53:31 +02003546 goto read_error;
Christopher Faulet31af49d2015-06-09 17:29:50 +02003547 }
Christopher Faulet31af49d2015-06-09 17:29:50 +02003548
Christopher Fauletc6f02fb2015-10-09 10:53:31 +02003549 fclose (fp);
Christopher Faulet31af49d2015-06-09 17:29:50 +02003550 bind_conf->ca_sign_cert = cacert;
3551 bind_conf->ca_sign_pkey = capkey;
3552 return err;
3553
Christopher Fauletc6f02fb2015-10-09 10:53:31 +02003554 read_error:
3555 fclose (fp);
Christopher Faulet31af49d2015-06-09 17:29:50 +02003556 if (capkey) EVP_PKEY_free(capkey);
3557 if (cacert) X509_free(cacert);
Christopher Fauletc6f02fb2015-10-09 10:53:31 +02003558 load_error:
3559 bind_conf->generate_certs = 0;
3560 err++;
Christopher Faulet31af49d2015-06-09 17:29:50 +02003561 return err;
3562}
3563
3564/* Release CA cert and private key used to generate certificated */
3565void
3566ssl_sock_free_ca(struct bind_conf *bind_conf)
3567{
3568 if (!bind_conf)
3569 return;
3570
3571 if (bind_conf->ca_sign_pkey)
3572 EVP_PKEY_free(bind_conf->ca_sign_pkey);
3573 if (bind_conf->ca_sign_cert)
3574 X509_free(bind_conf->ca_sign_cert);
Willy Tarreau94ff03a2016-12-22 17:57:46 +01003575 bind_conf->ca_sign_pkey = NULL;
3576 bind_conf->ca_sign_cert = NULL;
Christopher Faulet31af49d2015-06-09 17:29:50 +02003577}
3578
Emeric Brun46591952012-05-18 15:47:34 +02003579/*
3580 * This function is called if SSL * context is not yet allocated. The function
3581 * is designed to be called before any other data-layer operation and sets the
3582 * handshake flag on the connection. It is safe to call it multiple times.
3583 * It returns 0 on success and -1 in error case.
3584 */
3585static int ssl_sock_init(struct connection *conn)
3586{
3587 /* already initialized */
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02003588 if (conn->xprt_ctx)
Emeric Brun46591952012-05-18 15:47:34 +02003589 return 0;
3590
Willy Tarreau3c728722014-01-23 13:50:42 +01003591 if (!conn_ctrl_ready(conn))
Willy Tarreauf79c8172013-10-21 16:30:56 +02003592 return 0;
3593
Willy Tarreau20879a02012-12-03 16:32:10 +01003594 if (global.maxsslconn && sslconns >= global.maxsslconn) {
3595 conn->err_code = CO_ER_SSL_TOO_MANY;
Willy Tarreau403edff2012-09-06 11:58:37 +02003596 return -1;
Willy Tarreau20879a02012-12-03 16:32:10 +01003597 }
Willy Tarreau403edff2012-09-06 11:58:37 +02003598
Emeric Brun46591952012-05-18 15:47:34 +02003599 /* If it is in client mode initiate SSL session
3600 in connect state otherwise accept state */
Willy Tarreau3fdb3662012-11-12 00:42:33 +01003601 if (objt_server(conn->target)) {
Willy Tarreaufba03cd2014-11-13 13:48:58 +01003602 int may_retry = 1;
3603
3604 retry_connect:
Emeric Brun46591952012-05-18 15:47:34 +02003605 /* Alloc a new SSL session ctx */
Willy Tarreau3fdb3662012-11-12 00:42:33 +01003606 conn->xprt_ctx = SSL_new(objt_server(conn->target)->ssl_ctx.ctx);
Willy Tarreau20879a02012-12-03 16:32:10 +01003607 if (!conn->xprt_ctx) {
Willy Tarreaufba03cd2014-11-13 13:48:58 +01003608 if (may_retry--) {
3609 pool_gc2();
3610 goto retry_connect;
3611 }
Willy Tarreau20879a02012-12-03 16:32:10 +01003612 conn->err_code = CO_ER_SSL_NO_MEM;
Emeric Brun46591952012-05-18 15:47:34 +02003613 return -1;
Willy Tarreau20879a02012-12-03 16:32:10 +01003614 }
Emeric Brun46591952012-05-18 15:47:34 +02003615
Emeric Brun46591952012-05-18 15:47:34 +02003616 /* set fd on SSL session context */
Emeric Brun55476152014-11-12 17:35:37 +01003617 if (!SSL_set_fd(conn->xprt_ctx, conn->t.sock.fd)) {
3618 SSL_free(conn->xprt_ctx);
3619 conn->xprt_ctx = NULL;
Willy Tarreaufba03cd2014-11-13 13:48:58 +01003620 if (may_retry--) {
3621 pool_gc2();
3622 goto retry_connect;
3623 }
Emeric Brun55476152014-11-12 17:35:37 +01003624 conn->err_code = CO_ER_SSL_NO_MEM;
3625 return -1;
3626 }
Emeric Brun46591952012-05-18 15:47:34 +02003627
Evan Broderbe554312013-06-27 00:05:25 -07003628 /* set connection pointer */
Emeric Brun55476152014-11-12 17:35:37 +01003629 if (!SSL_set_app_data(conn->xprt_ctx, conn)) {
3630 SSL_free(conn->xprt_ctx);
3631 conn->xprt_ctx = NULL;
Willy Tarreaufba03cd2014-11-13 13:48:58 +01003632 if (may_retry--) {
3633 pool_gc2();
3634 goto retry_connect;
3635 }
Emeric Brun55476152014-11-12 17:35:37 +01003636 conn->err_code = CO_ER_SSL_NO_MEM;
3637 return -1;
3638 }
3639
3640 SSL_set_connect_state(conn->xprt_ctx);
3641 if (objt_server(conn->target)->ssl_ctx.reused_sess) {
3642 if(!SSL_set_session(conn->xprt_ctx, objt_server(conn->target)->ssl_ctx.reused_sess)) {
3643 SSL_SESSION_free(objt_server(conn->target)->ssl_ctx.reused_sess);
3644 objt_server(conn->target)->ssl_ctx.reused_sess = NULL;
3645 }
3646 }
Evan Broderbe554312013-06-27 00:05:25 -07003647
Emeric Brun46591952012-05-18 15:47:34 +02003648 /* leave init state and start handshake */
Willy Tarreau05737472012-09-04 08:03:39 +02003649 conn->flags |= CO_FL_SSL_WAIT_HS | CO_FL_WAIT_L6_CONN;
Willy Tarreau403edff2012-09-06 11:58:37 +02003650
3651 sslconns++;
Willy Tarreau71b734c2014-01-28 15:19:44 +01003652 totalsslconns++;
Emeric Brun46591952012-05-18 15:47:34 +02003653 return 0;
3654 }
Willy Tarreau3fdb3662012-11-12 00:42:33 +01003655 else if (objt_listener(conn->target)) {
Willy Tarreaufba03cd2014-11-13 13:48:58 +01003656 int may_retry = 1;
3657
3658 retry_accept:
Emeric Brun46591952012-05-18 15:47:34 +02003659 /* Alloc a new SSL session ctx */
Willy Tarreau3fdb3662012-11-12 00:42:33 +01003660 conn->xprt_ctx = SSL_new(objt_listener(conn->target)->bind_conf->default_ctx);
Willy Tarreau20879a02012-12-03 16:32:10 +01003661 if (!conn->xprt_ctx) {
Willy Tarreaufba03cd2014-11-13 13:48:58 +01003662 if (may_retry--) {
3663 pool_gc2();
3664 goto retry_accept;
3665 }
Willy Tarreau20879a02012-12-03 16:32:10 +01003666 conn->err_code = CO_ER_SSL_NO_MEM;
Emeric Brun46591952012-05-18 15:47:34 +02003667 return -1;
Willy Tarreau20879a02012-12-03 16:32:10 +01003668 }
Emeric Brun46591952012-05-18 15:47:34 +02003669
Emeric Brun46591952012-05-18 15:47:34 +02003670 /* set fd on SSL session context */
Emeric Brun55476152014-11-12 17:35:37 +01003671 if (!SSL_set_fd(conn->xprt_ctx, conn->t.sock.fd)) {
3672 SSL_free(conn->xprt_ctx);
3673 conn->xprt_ctx = NULL;
Willy Tarreaufba03cd2014-11-13 13:48:58 +01003674 if (may_retry--) {
3675 pool_gc2();
3676 goto retry_accept;
3677 }
Emeric Brun55476152014-11-12 17:35:37 +01003678 conn->err_code = CO_ER_SSL_NO_MEM;
3679 return -1;
3680 }
Emeric Brun46591952012-05-18 15:47:34 +02003681
Emeric Brune1f38db2012-09-03 20:36:47 +02003682 /* set connection pointer */
Emeric Brun55476152014-11-12 17:35:37 +01003683 if (!SSL_set_app_data(conn->xprt_ctx, conn)) {
3684 SSL_free(conn->xprt_ctx);
3685 conn->xprt_ctx = NULL;
Willy Tarreaufba03cd2014-11-13 13:48:58 +01003686 if (may_retry--) {
3687 pool_gc2();
3688 goto retry_accept;
3689 }
Emeric Brun55476152014-11-12 17:35:37 +01003690 conn->err_code = CO_ER_SSL_NO_MEM;
3691 return -1;
3692 }
3693
3694 SSL_set_accept_state(conn->xprt_ctx);
Emeric Brune1f38db2012-09-03 20:36:47 +02003695
Emeric Brun46591952012-05-18 15:47:34 +02003696 /* leave init state and start handshake */
Willy Tarreau05737472012-09-04 08:03:39 +02003697 conn->flags |= CO_FL_SSL_WAIT_HS | CO_FL_WAIT_L6_CONN;
Willy Tarreau403edff2012-09-06 11:58:37 +02003698
3699 sslconns++;
Willy Tarreau71b734c2014-01-28 15:19:44 +01003700 totalsslconns++;
Emeric Brun46591952012-05-18 15:47:34 +02003701 return 0;
3702 }
3703 /* don't know how to handle such a target */
Willy Tarreau20879a02012-12-03 16:32:10 +01003704 conn->err_code = CO_ER_SSL_NO_TARGET;
Emeric Brun46591952012-05-18 15:47:34 +02003705 return -1;
3706}
3707
3708
3709/* This is the callback which is used when an SSL handshake is pending. It
3710 * updates the FD status if it wants some polling before being called again.
3711 * It returns 0 if it fails in a fatal way or needs to poll to go further,
3712 * otherwise it returns non-zero and removes itself from the connection's
3713 * flags (the bit is provided in <flag> by the caller).
3714 */
3715int ssl_sock_handshake(struct connection *conn, unsigned int flag)
3716{
3717 int ret;
3718
Willy Tarreau3c728722014-01-23 13:50:42 +01003719 if (!conn_ctrl_ready(conn))
Willy Tarreauf79c8172013-10-21 16:30:56 +02003720 return 0;
3721
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02003722 if (!conn->xprt_ctx)
Emeric Brun46591952012-05-18 15:47:34 +02003723 goto out_error;
3724
Emeric Brun674b7432012-11-08 19:21:55 +01003725 /* If we use SSL_do_handshake to process a reneg initiated by
3726 * the remote peer, it sometimes returns SSL_ERROR_SSL.
3727 * Usually SSL_write and SSL_read are used and process implicitly
3728 * the reneg handshake.
3729 * Here we use SSL_peek as a workaround for reneg.
3730 */
3731 if ((conn->flags & CO_FL_CONNECTED) && SSL_renegotiate_pending(conn->xprt_ctx)) {
3732 char c;
3733
3734 ret = SSL_peek(conn->xprt_ctx, &c, 1);
3735 if (ret <= 0) {
3736 /* handshake may have not been completed, let's find why */
3737 ret = SSL_get_error(conn->xprt_ctx, ret);
3738 if (ret == SSL_ERROR_WANT_WRITE) {
3739 /* SSL handshake needs to write, L4 connection may not be ready */
3740 __conn_sock_stop_recv(conn);
Willy Tarreaue1f50c42014-01-22 20:02:06 +01003741 __conn_sock_want_send(conn);
3742 fd_cant_send(conn->t.sock.fd);
Emeric Brun674b7432012-11-08 19:21:55 +01003743 return 0;
3744 }
3745 else if (ret == SSL_ERROR_WANT_READ) {
3746 /* handshake may have been completed but we have
3747 * no more data to read.
3748 */
3749 if (!SSL_renegotiate_pending(conn->xprt_ctx)) {
3750 ret = 1;
3751 goto reneg_ok;
3752 }
3753 /* SSL handshake needs to read, L4 connection is ready */
3754 if (conn->flags & CO_FL_WAIT_L4_CONN)
3755 conn->flags &= ~CO_FL_WAIT_L4_CONN;
3756 __conn_sock_stop_send(conn);
Willy Tarreaue1f50c42014-01-22 20:02:06 +01003757 __conn_sock_want_recv(conn);
3758 fd_cant_recv(conn->t.sock.fd);
Emeric Brun674b7432012-11-08 19:21:55 +01003759 return 0;
3760 }
3761 else if (ret == SSL_ERROR_SYSCALL) {
3762 /* if errno is null, then connection was successfully established */
3763 if (!errno && conn->flags & CO_FL_WAIT_L4_CONN)
3764 conn->flags &= ~CO_FL_WAIT_L4_CONN;
Willy Tarreau20879a02012-12-03 16:32:10 +01003765 if (!conn->err_code) {
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02003766 int empty_handshake;
Luca Pizzamiglio578b1692016-12-12 10:56:56 +01003767#if (OPENSSL_VERSION_NUMBER >= 0x1010000fL) && !defined(LIBRESSL_VERSION_NUMBER)
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02003768 OSSL_HANDSHAKE_STATE state = SSL_get_state((SSL *)conn->xprt_ctx);
3769 empty_handshake = state == TLS_ST_BEFORE;
3770#else
3771 empty_handshake = !((SSL *)conn->xprt_ctx)->packet_length;
3772#endif
3773
3774 if (empty_handshake) {
Emeric Brun29f037d2014-04-25 19:05:36 +02003775 if (!errno) {
3776 if (conn->xprt_st & SSL_SOCK_RECV_HEARTBEAT)
3777 conn->err_code = CO_ER_SSL_HANDSHAKE_HB;
3778 else
3779 conn->err_code = CO_ER_SSL_EMPTY;
3780 }
3781 else {
3782 if (conn->xprt_st & SSL_SOCK_RECV_HEARTBEAT)
3783 conn->err_code = CO_ER_SSL_HANDSHAKE_HB;
3784 else
3785 conn->err_code = CO_ER_SSL_ABORT;
3786 }
3787 }
3788 else {
3789 if (conn->xprt_st & SSL_SOCK_RECV_HEARTBEAT)
3790 conn->err_code = CO_ER_SSL_HANDSHAKE_HB;
Willy Tarreau20879a02012-12-03 16:32:10 +01003791 else
Emeric Brun29f037d2014-04-25 19:05:36 +02003792 conn->err_code = CO_ER_SSL_HANDSHAKE;
3793 }
Willy Tarreau20879a02012-12-03 16:32:10 +01003794 }
Emeric Brun674b7432012-11-08 19:21:55 +01003795 goto out_error;
3796 }
3797 else {
3798 /* Fail on all other handshake errors */
3799 /* Note: OpenSSL may leave unread bytes in the socket's
3800 * buffer, causing an RST to be emitted upon close() on
3801 * TCP sockets. We first try to drain possibly pending
3802 * data to avoid this as much as possible.
3803 */
Willy Tarreaud85c4852015-03-13 00:40:28 +01003804 conn_sock_drain(conn);
Willy Tarreau20879a02012-12-03 16:32:10 +01003805 if (!conn->err_code)
Willy Tarreauf51c6982014-04-25 20:02:39 +02003806 conn->err_code = (conn->xprt_st & SSL_SOCK_RECV_HEARTBEAT) ?
3807 CO_ER_SSL_KILLED_HB : CO_ER_SSL_HANDSHAKE;
Emeric Brun674b7432012-11-08 19:21:55 +01003808 goto out_error;
3809 }
3810 }
3811 /* read some data: consider handshake completed */
3812 goto reneg_ok;
3813 }
3814
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02003815 ret = SSL_do_handshake(conn->xprt_ctx);
Emeric Brun46591952012-05-18 15:47:34 +02003816 if (ret != 1) {
3817 /* handshake did not complete, let's find why */
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02003818 ret = SSL_get_error(conn->xprt_ctx, ret);
Emeric Brun46591952012-05-18 15:47:34 +02003819
3820 if (ret == SSL_ERROR_WANT_WRITE) {
3821 /* SSL handshake needs to write, L4 connection may not be ready */
3822 __conn_sock_stop_recv(conn);
Willy Tarreaue1f50c42014-01-22 20:02:06 +01003823 __conn_sock_want_send(conn);
3824 fd_cant_send(conn->t.sock.fd);
Emeric Brun46591952012-05-18 15:47:34 +02003825 return 0;
3826 }
3827 else if (ret == SSL_ERROR_WANT_READ) {
3828 /* SSL handshake needs to read, L4 connection is ready */
3829 if (conn->flags & CO_FL_WAIT_L4_CONN)
3830 conn->flags &= ~CO_FL_WAIT_L4_CONN;
3831 __conn_sock_stop_send(conn);
Willy Tarreaue1f50c42014-01-22 20:02:06 +01003832 __conn_sock_want_recv(conn);
3833 fd_cant_recv(conn->t.sock.fd);
Emeric Brun46591952012-05-18 15:47:34 +02003834 return 0;
3835 }
Willy Tarreau89230192012-09-28 20:22:13 +02003836 else if (ret == SSL_ERROR_SYSCALL) {
Luca Pizzamiglio578b1692016-12-12 10:56:56 +01003837#if (OPENSSL_VERSION_NUMBER >= 0x1010000fL) && !defined(LIBRESSL_VERSION_NUMBER)
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02003838 OSSL_HANDSHAKE_STATE state;
3839#endif
3840 int empty_handshake;
Willy Tarreau89230192012-09-28 20:22:13 +02003841 /* if errno is null, then connection was successfully established */
3842 if (!errno && conn->flags & CO_FL_WAIT_L4_CONN)
3843 conn->flags &= ~CO_FL_WAIT_L4_CONN;
Willy Tarreau20879a02012-12-03 16:32:10 +01003844
Luca Pizzamiglio578b1692016-12-12 10:56:56 +01003845#if (OPENSSL_VERSION_NUMBER >= 0x1010000fL) && !defined(LIBRESSL_VERSION_NUMBER)
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02003846 state = SSL_get_state((SSL *)conn->xprt_ctx);
3847 empty_handshake = state == TLS_ST_BEFORE;
3848#else
3849 empty_handshake = !((SSL *)conn->xprt_ctx)->packet_length;
3850#endif
3851 if (empty_handshake) {
Emeric Brun29f037d2014-04-25 19:05:36 +02003852 if (!errno) {
3853 if (conn->xprt_st & SSL_SOCK_RECV_HEARTBEAT)
3854 conn->err_code = CO_ER_SSL_HANDSHAKE_HB;
3855 else
3856 conn->err_code = CO_ER_SSL_EMPTY;
3857 }
3858 else {
3859 if (conn->xprt_st & SSL_SOCK_RECV_HEARTBEAT)
3860 conn->err_code = CO_ER_SSL_HANDSHAKE_HB;
3861 else
3862 conn->err_code = CO_ER_SSL_ABORT;
3863 }
3864 }
3865 else {
3866 if (conn->xprt_st & SSL_SOCK_RECV_HEARTBEAT)
3867 conn->err_code = CO_ER_SSL_HANDSHAKE_HB;
Willy Tarreau20879a02012-12-03 16:32:10 +01003868 else
Emeric Brun29f037d2014-04-25 19:05:36 +02003869 conn->err_code = CO_ER_SSL_HANDSHAKE;
3870 }
Willy Tarreau89230192012-09-28 20:22:13 +02003871 goto out_error;
3872 }
Emeric Brun46591952012-05-18 15:47:34 +02003873 else {
3874 /* Fail on all other handshake errors */
Willy Tarreau566dc552012-10-19 20:52:18 +02003875 /* Note: OpenSSL may leave unread bytes in the socket's
3876 * buffer, causing an RST to be emitted upon close() on
3877 * TCP sockets. We first try to drain possibly pending
3878 * data to avoid this as much as possible.
3879 */
Willy Tarreaud85c4852015-03-13 00:40:28 +01003880 conn_sock_drain(conn);
Willy Tarreau20879a02012-12-03 16:32:10 +01003881 if (!conn->err_code)
Willy Tarreauf51c6982014-04-25 20:02:39 +02003882 conn->err_code = (conn->xprt_st & SSL_SOCK_RECV_HEARTBEAT) ?
3883 CO_ER_SSL_KILLED_HB : CO_ER_SSL_HANDSHAKE;
Emeric Brun46591952012-05-18 15:47:34 +02003884 goto out_error;
3885 }
3886 }
3887
Emeric Brun674b7432012-11-08 19:21:55 +01003888reneg_ok:
Emeric Brun46591952012-05-18 15:47:34 +02003889 /* Handshake succeeded */
Willy Tarreau0c9c2722014-05-28 12:28:58 +02003890 if (!SSL_session_reused(conn->xprt_ctx)) {
3891 if (objt_server(conn->target)) {
3892 update_freq_ctr(&global.ssl_be_keys_per_sec, 1);
3893 if (global.ssl_be_keys_per_sec.curr_ctr > global.ssl_be_keys_max)
3894 global.ssl_be_keys_max = global.ssl_be_keys_per_sec.curr_ctr;
3895
Emeric Brun46591952012-05-18 15:47:34 +02003896 /* check if session was reused, if not store current session on server for reuse */
Willy Tarreau30fd4bd2016-12-22 21:54:21 +01003897 if (objt_server(conn->target)->ssl_ctx.reused_sess) {
Willy Tarreau3fdb3662012-11-12 00:42:33 +01003898 SSL_SESSION_free(objt_server(conn->target)->ssl_ctx.reused_sess);
Willy Tarreau30fd4bd2016-12-22 21:54:21 +01003899 objt_server(conn->target)->ssl_ctx.reused_sess = NULL;
3900 }
Emeric Brun46591952012-05-18 15:47:34 +02003901
Willy Tarreau2a3fb1c2015-02-05 16:47:07 +01003902 if (!(objt_server(conn->target)->ssl_ctx.options & SRV_SSL_O_NO_REUSE))
3903 objt_server(conn->target)->ssl_ctx.reused_sess = SSL_get1_session(conn->xprt_ctx);
Emeric Brun46591952012-05-18 15:47:34 +02003904 }
Willy Tarreau0c9c2722014-05-28 12:28:58 +02003905 else {
3906 update_freq_ctr(&global.ssl_fe_keys_per_sec, 1);
3907 if (global.ssl_fe_keys_per_sec.curr_ctr > global.ssl_fe_keys_max)
3908 global.ssl_fe_keys_max = global.ssl_fe_keys_per_sec.curr_ctr;
3909 }
Emeric Brun46591952012-05-18 15:47:34 +02003910 }
3911
3912 /* The connection is now established at both layers, it's time to leave */
3913 conn->flags &= ~(flag | CO_FL_WAIT_L4_CONN | CO_FL_WAIT_L6_CONN);
3914 return 1;
3915
3916 out_error:
Emeric Brun644cde02012-12-14 11:21:13 +01003917 /* Clear openssl global errors stack */
Thierry FOURNIER / OZON.IO8b068c22016-10-10 11:59:50 +02003918 ssl_sock_dump_errors(conn);
Emeric Brun644cde02012-12-14 11:21:13 +01003919 ERR_clear_error();
3920
Emeric Brun9fa89732012-10-04 17:09:56 +02003921 /* free resumed session if exists */
Willy Tarreau3fdb3662012-11-12 00:42:33 +01003922 if (objt_server(conn->target) && objt_server(conn->target)->ssl_ctx.reused_sess) {
3923 SSL_SESSION_free(objt_server(conn->target)->ssl_ctx.reused_sess);
3924 objt_server(conn->target)->ssl_ctx.reused_sess = NULL;
Emeric Brun9fa89732012-10-04 17:09:56 +02003925 }
3926
Emeric Brun46591952012-05-18 15:47:34 +02003927 /* Fail on all other handshake errors */
3928 conn->flags |= CO_FL_ERROR;
Willy Tarreau20879a02012-12-03 16:32:10 +01003929 if (!conn->err_code)
3930 conn->err_code = CO_ER_SSL_HANDSHAKE;
Emeric Brun46591952012-05-18 15:47:34 +02003931 return 0;
3932}
3933
3934/* Receive up to <count> bytes from connection <conn>'s socket and store them
Willy Tarreauabf08d92014-01-14 11:31:27 +01003935 * into buffer <buf>. Only one call to recv() is performed, unless the
Emeric Brun46591952012-05-18 15:47:34 +02003936 * buffer wraps, in which case a second call may be performed. The connection's
3937 * flags are updated with whatever special event is detected (error, read0,
3938 * empty). The caller is responsible for taking care of those events and
3939 * avoiding the call if inappropriate. The function does not call the
3940 * connection's polling update function, so the caller is responsible for this.
3941 */
3942static int ssl_sock_to_buf(struct connection *conn, struct buffer *buf, int count)
3943{
3944 int ret, done = 0;
Willy Tarreauabf08d92014-01-14 11:31:27 +01003945 int try;
Emeric Brun46591952012-05-18 15:47:34 +02003946
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02003947 if (!conn->xprt_ctx)
Emeric Brun46591952012-05-18 15:47:34 +02003948 goto out_error;
3949
3950 if (conn->flags & CO_FL_HANDSHAKE)
3951 /* a handshake was requested */
3952 return 0;
3953
Willy Tarreauabf08d92014-01-14 11:31:27 +01003954 /* let's realign the buffer to optimize I/O */
3955 if (buffer_empty(buf))
Emeric Brun46591952012-05-18 15:47:34 +02003956 buf->p = buf->data;
Emeric Brun46591952012-05-18 15:47:34 +02003957
3958 /* read the largest possible block. For this, we perform only one call
3959 * to recv() unless the buffer wraps and we exactly fill the first hunk,
3960 * in which case we accept to do it once again. A new attempt is made on
3961 * EINTR too.
3962 */
Willy Tarreau00b0fb92014-01-17 11:09:40 +01003963 while (count > 0) {
Willy Tarreauabf08d92014-01-14 11:31:27 +01003964 /* first check if we have some room after p+i */
3965 try = buf->data + buf->size - (buf->p + buf->i);
3966 /* otherwise continue between data and p-o */
3967 if (try <= 0) {
3968 try = buf->p - (buf->data + buf->o);
3969 if (try <= 0)
3970 break;
3971 }
3972 if (try > count)
3973 try = count;
3974
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02003975 ret = SSL_read(conn->xprt_ctx, bi_end(buf), try);
Emeric Brune1f38db2012-09-03 20:36:47 +02003976 if (conn->flags & CO_FL_ERROR) {
3977 /* CO_FL_ERROR may be set by ssl_sock_infocbk */
Emeric Brun644cde02012-12-14 11:21:13 +01003978 goto out_error;
Emeric Brune1f38db2012-09-03 20:36:47 +02003979 }
Emeric Brun46591952012-05-18 15:47:34 +02003980 if (ret > 0) {
3981 buf->i += ret;
3982 done += ret;
3983 if (ret < try)
3984 break;
3985 count -= ret;
Emeric Brun46591952012-05-18 15:47:34 +02003986 }
3987 else if (ret == 0) {
Emeric Brun644cde02012-12-14 11:21:13 +01003988 ret = SSL_get_error(conn->xprt_ctx, ret);
3989 if (ret != SSL_ERROR_ZERO_RETURN) {
Emeric Brun1c646862012-12-14 12:33:41 +01003990 /* error on protocol or underlying transport */
3991 if ((ret != SSL_ERROR_SYSCALL)
3992 || (errno && (errno != EAGAIN)))
3993 conn->flags |= CO_FL_ERROR;
3994
Emeric Brun644cde02012-12-14 11:21:13 +01003995 /* Clear openssl global errors stack */
Thierry FOURNIER / OZON.IO8b068c22016-10-10 11:59:50 +02003996 ssl_sock_dump_errors(conn);
Emeric Brun644cde02012-12-14 11:21:13 +01003997 ERR_clear_error();
3998 }
Emeric Brun46591952012-05-18 15:47:34 +02003999 goto read0;
4000 }
4001 else {
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02004002 ret = SSL_get_error(conn->xprt_ctx, ret);
Emeric Brun46591952012-05-18 15:47:34 +02004003 if (ret == SSL_ERROR_WANT_WRITE) {
Emeric Brun8af8dd12012-11-08 17:56:20 +01004004 /* handshake is running, and it needs to enable write */
Emeric Brun46591952012-05-18 15:47:34 +02004005 conn->flags |= CO_FL_SSL_WAIT_HS;
Emeric Brun8af8dd12012-11-08 17:56:20 +01004006 __conn_sock_want_send(conn);
Emeric Brun46591952012-05-18 15:47:34 +02004007 break;
4008 }
4009 else if (ret == SSL_ERROR_WANT_READ) {
Emeric Brun282a76a2012-11-08 18:02:56 +01004010 if (SSL_renegotiate_pending(conn->xprt_ctx)) {
4011 /* handshake is running, and it may need to re-enable read */
4012 conn->flags |= CO_FL_SSL_WAIT_HS;
4013 __conn_sock_want_recv(conn);
4014 break;
4015 }
Emeric Brun46591952012-05-18 15:47:34 +02004016 /* we need to poll for retry a read later */
Willy Tarreaue1f50c42014-01-22 20:02:06 +01004017 fd_cant_recv(conn->t.sock.fd);
Emeric Brun46591952012-05-18 15:47:34 +02004018 break;
4019 }
4020 /* otherwise it's a real error */
4021 goto out_error;
4022 }
4023 }
4024 return done;
4025
4026 read0:
4027 conn_sock_read0(conn);
4028 return done;
4029 out_error:
Emeric Brun644cde02012-12-14 11:21:13 +01004030 /* Clear openssl global errors stack */
Thierry FOURNIER / OZON.IO8b068c22016-10-10 11:59:50 +02004031 ssl_sock_dump_errors(conn);
Emeric Brun644cde02012-12-14 11:21:13 +01004032 ERR_clear_error();
4033
Emeric Brun46591952012-05-18 15:47:34 +02004034 conn->flags |= CO_FL_ERROR;
4035 return done;
4036}
4037
4038
4039/* Send all pending bytes from buffer <buf> to connection <conn>'s socket.
Willy Tarreau1049b1f2014-02-02 01:51:17 +01004040 * <flags> may contain some CO_SFL_* flags to hint the system about other
4041 * pending data for example, but this flag is ignored at the moment.
Emeric Brun46591952012-05-18 15:47:34 +02004042 * Only one call to send() is performed, unless the buffer wraps, in which case
4043 * a second call may be performed. The connection's flags are updated with
4044 * whatever special event is detected (error, empty). The caller is responsible
4045 * for taking care of those events and avoiding the call if inappropriate. The
4046 * function does not call the connection's polling update function, so the caller
4047 * is responsible for this.
4048 */
4049static int ssl_sock_from_buf(struct connection *conn, struct buffer *buf, int flags)
4050{
4051 int ret, try, done;
4052
4053 done = 0;
4054
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02004055 if (!conn->xprt_ctx)
Emeric Brun46591952012-05-18 15:47:34 +02004056 goto out_error;
4057
4058 if (conn->flags & CO_FL_HANDSHAKE)
4059 /* a handshake was requested */
4060 return 0;
4061
4062 /* send the largest possible block. For this we perform only one call
4063 * to send() unless the buffer wraps and we exactly fill the first hunk,
4064 * in which case we accept to do it once again.
4065 */
4066 while (buf->o) {
Kevin Hestercad82342013-05-30 15:12:41 -07004067 try = bo_contig_data(buf);
Willy Tarreaubfd59462013-02-21 07:46:09 +01004068
Willy Tarreau7bed9452014-02-02 02:00:24 +01004069 if (!(flags & CO_SFL_STREAMER) &&
Willy Tarreau518cedd2014-02-17 15:43:01 +01004070 !(conn->xprt_st & SSL_SOCK_SEND_UNLIMITED) &&
Willy Tarreauef934602016-12-22 23:12:01 +01004071 global_ssl.max_record && try > global_ssl.max_record) {
4072 try = global_ssl.max_record;
Willy Tarreau518cedd2014-02-17 15:43:01 +01004073 }
4074 else {
4075 /* we need to keep the information about the fact that
4076 * we're not limiting the upcoming send(), because if it
4077 * fails, we'll have to retry with at least as many data.
4078 */
4079 conn->xprt_st |= SSL_SOCK_SEND_UNLIMITED;
4080 }
Willy Tarreaubfd59462013-02-21 07:46:09 +01004081
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02004082 ret = SSL_write(conn->xprt_ctx, bo_ptr(buf), try);
Willy Tarreau518cedd2014-02-17 15:43:01 +01004083
Emeric Brune1f38db2012-09-03 20:36:47 +02004084 if (conn->flags & CO_FL_ERROR) {
4085 /* CO_FL_ERROR may be set by ssl_sock_infocbk */
Emeric Brun644cde02012-12-14 11:21:13 +01004086 goto out_error;
Emeric Brune1f38db2012-09-03 20:36:47 +02004087 }
Emeric Brun46591952012-05-18 15:47:34 +02004088 if (ret > 0) {
Willy Tarreau518cedd2014-02-17 15:43:01 +01004089 conn->xprt_st &= ~SSL_SOCK_SEND_UNLIMITED;
4090
Emeric Brun46591952012-05-18 15:47:34 +02004091 buf->o -= ret;
4092 done += ret;
4093
Willy Tarreau5fb38032012-12-16 19:39:09 +01004094 if (likely(buffer_empty(buf)))
Emeric Brun46591952012-05-18 15:47:34 +02004095 /* optimize data alignment in the buffer */
4096 buf->p = buf->data;
4097
4098 /* if the system buffer is full, don't insist */
4099 if (ret < try)
4100 break;
4101 }
4102 else {
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02004103 ret = SSL_get_error(conn->xprt_ctx, ret);
Emeric Brun46591952012-05-18 15:47:34 +02004104 if (ret == SSL_ERROR_WANT_WRITE) {
Emeric Brun282a76a2012-11-08 18:02:56 +01004105 if (SSL_renegotiate_pending(conn->xprt_ctx)) {
4106 /* handshake is running, and it may need to re-enable write */
4107 conn->flags |= CO_FL_SSL_WAIT_HS;
4108 __conn_sock_want_send(conn);
4109 break;
4110 }
Emeric Brun46591952012-05-18 15:47:34 +02004111 /* we need to poll to retry a write later */
Willy Tarreaue1f50c42014-01-22 20:02:06 +01004112 fd_cant_send(conn->t.sock.fd);
Emeric Brun46591952012-05-18 15:47:34 +02004113 break;
4114 }
4115 else if (ret == SSL_ERROR_WANT_READ) {
Emeric Brun8af8dd12012-11-08 17:56:20 +01004116 /* handshake is running, and it needs to enable read */
Emeric Brun46591952012-05-18 15:47:34 +02004117 conn->flags |= CO_FL_SSL_WAIT_HS;
Emeric Brun8af8dd12012-11-08 17:56:20 +01004118 __conn_sock_want_recv(conn);
Emeric Brun46591952012-05-18 15:47:34 +02004119 break;
4120 }
4121 goto out_error;
4122 }
4123 }
4124 return done;
4125
4126 out_error:
Emeric Brun644cde02012-12-14 11:21:13 +01004127 /* Clear openssl global errors stack */
Thierry FOURNIER / OZON.IO8b068c22016-10-10 11:59:50 +02004128 ssl_sock_dump_errors(conn);
Emeric Brun644cde02012-12-14 11:21:13 +01004129 ERR_clear_error();
4130
Emeric Brun46591952012-05-18 15:47:34 +02004131 conn->flags |= CO_FL_ERROR;
4132 return done;
4133}
4134
Emeric Brun46591952012-05-18 15:47:34 +02004135static void ssl_sock_close(struct connection *conn) {
4136
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02004137 if (conn->xprt_ctx) {
4138 SSL_free(conn->xprt_ctx);
4139 conn->xprt_ctx = NULL;
Willy Tarreau403edff2012-09-06 11:58:37 +02004140 sslconns--;
Emeric Brun46591952012-05-18 15:47:34 +02004141 }
Emeric Brun46591952012-05-18 15:47:34 +02004142}
4143
4144/* This function tries to perform a clean shutdown on an SSL connection, and in
4145 * any case, flags the connection as reusable if no handshake was in progress.
4146 */
4147static void ssl_sock_shutw(struct connection *conn, int clean)
4148{
4149 if (conn->flags & CO_FL_HANDSHAKE)
4150 return;
Emmanuel Hocdet405ff312017-01-08 14:07:39 +01004151 if (!clean)
4152 /* don't sent notify on SSL_shutdown */
4153 SSL_CTX_set_quiet_shutdown(conn->xprt_ctx, 1);
Emeric Brun46591952012-05-18 15:47:34 +02004154 /* no handshake was in progress, try a clean ssl shutdown */
Emmanuel Hocdet405ff312017-01-08 14:07:39 +01004155 if (SSL_shutdown(conn->xprt_ctx) <= 0) {
Emeric Brun644cde02012-12-14 11:21:13 +01004156 /* Clear openssl global errors stack */
Thierry FOURNIER / OZON.IO8b068c22016-10-10 11:59:50 +02004157 ssl_sock_dump_errors(conn);
Emeric Brun644cde02012-12-14 11:21:13 +01004158 ERR_clear_error();
4159 }
Emeric Brun46591952012-05-18 15:47:34 +02004160}
4161
Willy Tarreauffc3fcd2012-10-12 20:17:54 +02004162/* used for logging, may be changed for a sample fetch later */
4163const char *ssl_sock_get_cipher_name(struct connection *conn)
4164{
4165 if (!conn->xprt && !conn->xprt_ctx)
4166 return NULL;
4167 return SSL_get_cipher_name(conn->xprt_ctx);
4168}
4169
4170/* used for logging, may be changed for a sample fetch later */
4171const char *ssl_sock_get_proto_version(struct connection *conn)
4172{
4173 if (!conn->xprt && !conn->xprt_ctx)
4174 return NULL;
4175 return SSL_get_version(conn->xprt_ctx);
4176}
4177
Willy Tarreau8d598402012-10-22 17:58:39 +02004178/* Extract a serial from a cert, and copy it to a chunk.
4179 * Returns 1 if serial is found and copied, 0 if no serial found and
4180 * -1 if output is not large enough.
4181 */
4182static int
4183ssl_sock_get_serial(X509 *crt, struct chunk *out)
4184{
4185 ASN1_INTEGER *serial;
4186
4187 serial = X509_get_serialNumber(crt);
4188 if (!serial)
4189 return 0;
4190
4191 if (out->size < serial->length)
4192 return -1;
4193
4194 memcpy(out->str, serial->data, serial->length);
4195 out->len = serial->length;
4196 return 1;
4197}
4198
Emeric Brun43e79582014-10-29 19:03:26 +01004199/* Extract a cert to der, and copy it to a chunk.
4200 * Returns 1 if cert is found and copied, 0 on der convertion failure and
4201 * -1 if output is not large enough.
4202 */
4203static int
4204ssl_sock_crt2der(X509 *crt, struct chunk *out)
4205{
4206 int len;
4207 unsigned char *p = (unsigned char *)out->str;;
4208
4209 len =i2d_X509(crt, NULL);
4210 if (len <= 0)
4211 return 1;
4212
4213 if (out->size < len)
4214 return -1;
4215
4216 i2d_X509(crt,&p);
4217 out->len = len;
4218 return 1;
4219}
4220
Emeric Brunce5ad802012-10-22 14:11:22 +02004221
4222/* Copy Date in ASN1_UTCTIME format in struct chunk out.
4223 * Returns 1 if serial is found and copied, 0 if no valid time found
4224 * and -1 if output is not large enough.
4225 */
4226static int
4227ssl_sock_get_time(ASN1_TIME *tm, struct chunk *out)
4228{
4229 if (tm->type == V_ASN1_GENERALIZEDTIME) {
4230 ASN1_GENERALIZEDTIME *gentm = (ASN1_GENERALIZEDTIME *)tm;
4231
4232 if (gentm->length < 12)
4233 return 0;
4234 if (gentm->data[0] != 0x32 || gentm->data[1] != 0x30)
4235 return 0;
4236 if (out->size < gentm->length-2)
4237 return -1;
4238
4239 memcpy(out->str, gentm->data+2, gentm->length-2);
4240 out->len = gentm->length-2;
4241 return 1;
4242 }
4243 else if (tm->type == V_ASN1_UTCTIME) {
4244 ASN1_UTCTIME *utctm = (ASN1_UTCTIME *)tm;
4245
4246 if (utctm->length < 10)
4247 return 0;
4248 if (utctm->data[0] >= 0x35)
4249 return 0;
4250 if (out->size < utctm->length)
4251 return -1;
4252
4253 memcpy(out->str, utctm->data, utctm->length);
4254 out->len = utctm->length;
4255 return 1;
4256 }
4257
4258 return 0;
4259}
4260
Emeric Brun87855892012-10-17 17:39:35 +02004261/* Extract an entry from a X509_NAME and copy its value to an output chunk.
4262 * Returns 1 if entry found, 0 if entry not found, or -1 if output not large enough.
4263 */
4264static int
4265ssl_sock_get_dn_entry(X509_NAME *a, const struct chunk *entry, int pos, struct chunk *out)
4266{
4267 X509_NAME_ENTRY *ne;
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02004268 ASN1_OBJECT *obj;
4269 ASN1_STRING *data;
4270 const unsigned char *data_ptr;
4271 int data_len;
Emeric Brun87855892012-10-17 17:39:35 +02004272 int i, j, n;
4273 int cur = 0;
4274 const char *s;
4275 char tmp[128];
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02004276 int name_count;
4277
4278 name_count = X509_NAME_entry_count(a);
Emeric Brun87855892012-10-17 17:39:35 +02004279
4280 out->len = 0;
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02004281 for (i = 0; i < name_count; i++) {
Emeric Brun87855892012-10-17 17:39:35 +02004282 if (pos < 0)
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02004283 j = (name_count-1) - i;
Emeric Brun87855892012-10-17 17:39:35 +02004284 else
4285 j = i;
4286
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02004287 ne = X509_NAME_get_entry(a, j);
4288 obj = X509_NAME_ENTRY_get_object(ne);
4289 data = X509_NAME_ENTRY_get_data(ne);
4290 data_ptr = ASN1_STRING_get0_data(data);
4291 data_len = ASN1_STRING_length(data);
4292 n = OBJ_obj2nid(obj);
Emeric Brun87855892012-10-17 17:39:35 +02004293 if ((n == NID_undef) || ((s = OBJ_nid2sn(n)) == NULL)) {
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02004294 i2t_ASN1_OBJECT(tmp, sizeof(tmp), obj);
Emeric Brun87855892012-10-17 17:39:35 +02004295 s = tmp;
4296 }
4297
4298 if (chunk_strcasecmp(entry, s) != 0)
4299 continue;
4300
4301 if (pos < 0)
4302 cur--;
4303 else
4304 cur++;
4305
4306 if (cur != pos)
4307 continue;
4308
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02004309 if (data_len > out->size)
Emeric Brun87855892012-10-17 17:39:35 +02004310 return -1;
4311
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02004312 memcpy(out->str, data_ptr, data_len);
4313 out->len = data_len;
Emeric Brun87855892012-10-17 17:39:35 +02004314 return 1;
4315 }
4316
4317 return 0;
4318
4319}
4320
4321/* Extract and format full DN from a X509_NAME and copy result into a chunk
4322 * Returns 1 if dn entries exits, 0 if no dn entry found or -1 if output is not large enough.
4323 */
4324static int
4325ssl_sock_get_dn_oneline(X509_NAME *a, struct chunk *out)
4326{
4327 X509_NAME_ENTRY *ne;
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02004328 ASN1_OBJECT *obj;
4329 ASN1_STRING *data;
4330 const unsigned char *data_ptr;
4331 int data_len;
Emeric Brun87855892012-10-17 17:39:35 +02004332 int i, n, ln;
4333 int l = 0;
4334 const char *s;
4335 char *p;
4336 char tmp[128];
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02004337 int name_count;
4338
4339
4340 name_count = X509_NAME_entry_count(a);
Emeric Brun87855892012-10-17 17:39:35 +02004341
4342 out->len = 0;
4343 p = out->str;
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02004344 for (i = 0; i < name_count; i++) {
4345 ne = X509_NAME_get_entry(a, i);
4346 obj = X509_NAME_ENTRY_get_object(ne);
4347 data = X509_NAME_ENTRY_get_data(ne);
4348 data_ptr = ASN1_STRING_get0_data(data);
4349 data_len = ASN1_STRING_length(data);
4350 n = OBJ_obj2nid(obj);
Emeric Brun87855892012-10-17 17:39:35 +02004351 if ((n == NID_undef) || ((s = OBJ_nid2sn(n)) == NULL)) {
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02004352 i2t_ASN1_OBJECT(tmp, sizeof(tmp), obj);
Emeric Brun87855892012-10-17 17:39:35 +02004353 s = tmp;
4354 }
4355 ln = strlen(s);
4356
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02004357 l += 1 + ln + 1 + data_len;
Emeric Brun87855892012-10-17 17:39:35 +02004358 if (l > out->size)
4359 return -1;
4360 out->len = l;
4361
4362 *(p++)='/';
4363 memcpy(p, s, ln);
4364 p += ln;
4365 *(p++)='=';
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02004366 memcpy(p, data_ptr, data_len);
4367 p += data_len;
Emeric Brun87855892012-10-17 17:39:35 +02004368 }
4369
4370 if (!out->len)
4371 return 0;
4372
4373 return 1;
4374}
4375
David Safb76832014-05-08 23:42:08 -04004376char *ssl_sock_get_version(struct connection *conn)
4377{
4378 if (!ssl_sock_is_ssl(conn))
4379 return NULL;
4380
4381 return (char *)SSL_get_version(conn->xprt_ctx);
4382}
4383
Willy Tarreau119a4082016-12-22 21:58:38 +01004384/* Sets advertised SNI for outgoing connections. Please set <hostname> to NULL
4385 * to disable SNI.
4386 */
Willy Tarreau63076412015-07-10 11:33:32 +02004387void ssl_sock_set_servername(struct connection *conn, const char *hostname)
4388{
4389#ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME
Willy Tarreau119a4082016-12-22 21:58:38 +01004390 char *prev_name;
4391
Willy Tarreau63076412015-07-10 11:33:32 +02004392 if (!ssl_sock_is_ssl(conn))
4393 return;
4394
Willy Tarreau119a4082016-12-22 21:58:38 +01004395 /* if the SNI changes, we must destroy the reusable context so that a
4396 * new connection will present a new SNI. As an optimization we could
4397 * later imagine having a small cache of ssl_ctx to hold a few SNI per
4398 * server.
4399 */
4400 prev_name = (char *)SSL_get_servername(conn->xprt_ctx, TLSEXT_NAMETYPE_host_name);
4401 if ((!prev_name && hostname) ||
4402 (prev_name && (!hostname || strcmp(hostname, prev_name) != 0)))
4403 SSL_set_session(conn->xprt_ctx, NULL);
4404
Willy Tarreau63076412015-07-10 11:33:32 +02004405 SSL_set_tlsext_host_name(conn->xprt_ctx, hostname);
4406#endif
4407}
4408
Emeric Brun0abf8362014-06-24 18:26:41 +02004409/* Extract peer certificate's common name into the chunk dest
4410 * Returns
4411 * the len of the extracted common name
4412 * or 0 if no CN found in DN
4413 * or -1 on error case (i.e. no peer certificate)
4414 */
4415int ssl_sock_get_remote_common_name(struct connection *conn, struct chunk *dest)
David Safb76832014-05-08 23:42:08 -04004416{
4417 X509 *crt = NULL;
4418 X509_NAME *name;
David Safb76832014-05-08 23:42:08 -04004419 const char find_cn[] = "CN";
4420 const struct chunk find_cn_chunk = {
4421 .str = (char *)&find_cn,
4422 .len = sizeof(find_cn)-1
4423 };
Emeric Brun0abf8362014-06-24 18:26:41 +02004424 int result = -1;
David Safb76832014-05-08 23:42:08 -04004425
4426 if (!ssl_sock_is_ssl(conn))
Emeric Brun0abf8362014-06-24 18:26:41 +02004427 goto out;
David Safb76832014-05-08 23:42:08 -04004428
4429 /* SSL_get_peer_certificate, it increase X509 * ref count */
4430 crt = SSL_get_peer_certificate(conn->xprt_ctx);
4431 if (!crt)
4432 goto out;
4433
4434 name = X509_get_subject_name(crt);
4435 if (!name)
4436 goto out;
David Safb76832014-05-08 23:42:08 -04004437
Emeric Brun0abf8362014-06-24 18:26:41 +02004438 result = ssl_sock_get_dn_entry(name, &find_cn_chunk, 1, dest);
4439out:
David Safb76832014-05-08 23:42:08 -04004440 if (crt)
4441 X509_free(crt);
4442
4443 return result;
4444}
4445
Dave McCowan328fb582014-07-30 10:39:13 -04004446/* returns 1 if client passed a certificate for this session, 0 if not */
4447int ssl_sock_get_cert_used_sess(struct connection *conn)
4448{
4449 X509 *crt = NULL;
4450
4451 if (!ssl_sock_is_ssl(conn))
4452 return 0;
4453
4454 /* SSL_get_peer_certificate, it increase X509 * ref count */
4455 crt = SSL_get_peer_certificate(conn->xprt_ctx);
4456 if (!crt)
4457 return 0;
4458
4459 X509_free(crt);
4460 return 1;
4461}
4462
4463/* returns 1 if client passed a certificate for this connection, 0 if not */
4464int ssl_sock_get_cert_used_conn(struct connection *conn)
David Safb76832014-05-08 23:42:08 -04004465{
4466 if (!ssl_sock_is_ssl(conn))
4467 return 0;
4468
4469 return SSL_SOCK_ST_FL_VERIFY_DONE & conn->xprt_st ? 1 : 0;
4470}
4471
4472/* returns result from SSL verify */
4473unsigned int ssl_sock_get_verify_result(struct connection *conn)
4474{
4475 if (!ssl_sock_is_ssl(conn))
4476 return (unsigned int)X509_V_ERR_APPLICATION_VERIFICATION;
4477
4478 return (unsigned int)SSL_get_verify_result(conn->xprt_ctx);
4479}
4480
Willy Tarreau7875d092012-09-10 08:20:03 +02004481/***** Below are some sample fetching functions for ACL/patterns *****/
4482
Emeric Brune64aef12012-09-21 13:15:06 +02004483/* boolean, returns true if client cert was present */
4484static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02004485smp_fetch_ssl_fc_has_crt(const struct arg *args, struct sample *smp, const char *kw, void *private)
Emeric Brune64aef12012-09-21 13:15:06 +02004486{
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004487 struct connection *conn;
4488
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02004489 conn = objt_conn(smp->sess->origin);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004490 if (!conn || conn->xprt != &ssl_sock)
Emeric Brune64aef12012-09-21 13:15:06 +02004491 return 0;
4492
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004493 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brune64aef12012-09-21 13:15:06 +02004494 smp->flags |= SMP_F_MAY_CHANGE;
4495 return 0;
4496 }
4497
4498 smp->flags = 0;
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02004499 smp->data.type = SMP_T_BOOL;
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02004500 smp->data.u.sint = SSL_SOCK_ST_FL_VERIFY_DONE & conn->xprt_st ? 1 : 0;
Emeric Brune64aef12012-09-21 13:15:06 +02004501
4502 return 1;
4503}
4504
Emeric Brun43e79582014-10-29 19:03:26 +01004505/* binary, returns a certificate in a binary chunk (der/raw).
4506 * The 5th keyword char is used to know if SSL_get_certificate or SSL_get_peer_certificate
4507 * should be use.
4508 */
4509static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02004510smp_fetch_ssl_x_der(const struct arg *args, struct sample *smp, const char *kw, void *private)
Emeric Brun43e79582014-10-29 19:03:26 +01004511{
4512 int cert_peer = (kw[4] == 'c') ? 1 : 0;
4513 X509 *crt = NULL;
4514 int ret = 0;
4515 struct chunk *smp_trash;
4516 struct connection *conn;
4517
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02004518 conn = objt_conn(smp->sess->origin);
Emeric Brun43e79582014-10-29 19:03:26 +01004519 if (!conn || conn->xprt != &ssl_sock)
4520 return 0;
4521
4522 if (!(conn->flags & CO_FL_CONNECTED)) {
4523 smp->flags |= SMP_F_MAY_CHANGE;
4524 return 0;
4525 }
4526
4527 if (cert_peer)
4528 crt = SSL_get_peer_certificate(conn->xprt_ctx);
4529 else
4530 crt = SSL_get_certificate(conn->xprt_ctx);
4531
4532 if (!crt)
4533 goto out;
4534
4535 smp_trash = get_trash_chunk();
4536 if (ssl_sock_crt2der(crt, smp_trash) <= 0)
4537 goto out;
4538
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02004539 smp->data.u.str = *smp_trash;
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02004540 smp->data.type = SMP_T_BIN;
Emeric Brun43e79582014-10-29 19:03:26 +01004541 ret = 1;
4542out:
4543 /* SSL_get_peer_certificate, it increase X509 * ref count */
4544 if (cert_peer && crt)
4545 X509_free(crt);
4546 return ret;
4547}
4548
Emeric Brunba841a12014-04-30 17:05:08 +02004549/* binary, returns serial of certificate in a binary chunk.
4550 * The 5th keyword char is used to know if SSL_get_certificate or SSL_get_peer_certificate
4551 * should be use.
4552 */
Willy Tarreau8d598402012-10-22 17:58:39 +02004553static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02004554smp_fetch_ssl_x_serial(const struct arg *args, struct sample *smp, const char *kw, void *private)
Willy Tarreau8d598402012-10-22 17:58:39 +02004555{
Emeric Brunba841a12014-04-30 17:05:08 +02004556 int cert_peer = (kw[4] == 'c') ? 1 : 0;
Willy Tarreau8d598402012-10-22 17:58:39 +02004557 X509 *crt = NULL;
4558 int ret = 0;
4559 struct chunk *smp_trash;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004560 struct connection *conn;
4561
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02004562 conn = objt_conn(smp->sess->origin);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004563 if (!conn || conn->xprt != &ssl_sock)
Willy Tarreau8d598402012-10-22 17:58:39 +02004564 return 0;
4565
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004566 if (!(conn->flags & CO_FL_CONNECTED)) {
Willy Tarreau8d598402012-10-22 17:58:39 +02004567 smp->flags |= SMP_F_MAY_CHANGE;
4568 return 0;
4569 }
4570
Emeric Brunba841a12014-04-30 17:05:08 +02004571 if (cert_peer)
4572 crt = SSL_get_peer_certificate(conn->xprt_ctx);
4573 else
4574 crt = SSL_get_certificate(conn->xprt_ctx);
4575
Willy Tarreau8d598402012-10-22 17:58:39 +02004576 if (!crt)
4577 goto out;
4578
Willy Tarreau47ca5452012-12-23 20:22:19 +01004579 smp_trash = get_trash_chunk();
Willy Tarreau8d598402012-10-22 17:58:39 +02004580 if (ssl_sock_get_serial(crt, smp_trash) <= 0)
4581 goto out;
4582
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02004583 smp->data.u.str = *smp_trash;
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02004584 smp->data.type = SMP_T_BIN;
Willy Tarreau8d598402012-10-22 17:58:39 +02004585 ret = 1;
4586out:
Emeric Brunba841a12014-04-30 17:05:08 +02004587 /* SSL_get_peer_certificate, it increase X509 * ref count */
4588 if (cert_peer && crt)
Willy Tarreau8d598402012-10-22 17:58:39 +02004589 X509_free(crt);
4590 return ret;
4591}
Emeric Brune64aef12012-09-21 13:15:06 +02004592
Emeric Brunba841a12014-04-30 17:05:08 +02004593/* binary, returns the client certificate's SHA-1 fingerprint (SHA-1 hash of DER-encoded certificate) in a binary chunk.
4594 * The 5th keyword char is used to know if SSL_get_certificate or SSL_get_peer_certificate
4595 * should be use.
4596 */
James Votha051b4a2013-05-14 20:37:59 +02004597static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02004598smp_fetch_ssl_x_sha1(const struct arg *args, struct sample *smp, const char *kw, void *private)
James Votha051b4a2013-05-14 20:37:59 +02004599{
Emeric Brunba841a12014-04-30 17:05:08 +02004600 int cert_peer = (kw[4] == 'c') ? 1 : 0;
James Votha051b4a2013-05-14 20:37:59 +02004601 X509 *crt = NULL;
4602 const EVP_MD *digest;
4603 int ret = 0;
4604 struct chunk *smp_trash;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004605 struct connection *conn;
James Votha051b4a2013-05-14 20:37:59 +02004606
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02004607 conn = objt_conn(smp->sess->origin);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004608 if (!conn || conn->xprt != &ssl_sock)
4609 return 0;
4610
4611 if (!(conn->flags & CO_FL_CONNECTED)) {
James Votha051b4a2013-05-14 20:37:59 +02004612 smp->flags |= SMP_F_MAY_CHANGE;
4613 return 0;
4614 }
4615
Emeric Brunba841a12014-04-30 17:05:08 +02004616 if (cert_peer)
4617 crt = SSL_get_peer_certificate(conn->xprt_ctx);
4618 else
4619 crt = SSL_get_certificate(conn->xprt_ctx);
James Votha051b4a2013-05-14 20:37:59 +02004620 if (!crt)
4621 goto out;
4622
4623 smp_trash = get_trash_chunk();
4624 digest = EVP_sha1();
4625 X509_digest(crt, digest, (unsigned char *)smp_trash->str, (unsigned int *)&smp_trash->len);
4626
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02004627 smp->data.u.str = *smp_trash;
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02004628 smp->data.type = SMP_T_BIN;
James Votha051b4a2013-05-14 20:37:59 +02004629 ret = 1;
4630out:
Emeric Brunba841a12014-04-30 17:05:08 +02004631 /* SSL_get_peer_certificate, it increase X509 * ref count */
4632 if (cert_peer && crt)
James Votha051b4a2013-05-14 20:37:59 +02004633 X509_free(crt);
4634 return ret;
4635}
4636
Emeric Brunba841a12014-04-30 17:05:08 +02004637/* string, returns certificate's notafter date in ASN1_UTCTIME format.
4638 * The 5th keyword char is used to know if SSL_get_certificate or SSL_get_peer_certificate
4639 * should be use.
4640 */
Emeric Brunce5ad802012-10-22 14:11:22 +02004641static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02004642smp_fetch_ssl_x_notafter(const struct arg *args, struct sample *smp, const char *kw, void *private)
Emeric Brunce5ad802012-10-22 14:11:22 +02004643{
Emeric Brunba841a12014-04-30 17:05:08 +02004644 int cert_peer = (kw[4] == 'c') ? 1 : 0;
Emeric Brunce5ad802012-10-22 14:11:22 +02004645 X509 *crt = NULL;
4646 int ret = 0;
4647 struct chunk *smp_trash;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004648 struct connection *conn;
Emeric Brunce5ad802012-10-22 14:11:22 +02004649
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02004650 conn = objt_conn(smp->sess->origin);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004651 if (!conn || conn->xprt != &ssl_sock)
4652 return 0;
4653
4654 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brunce5ad802012-10-22 14:11:22 +02004655 smp->flags |= SMP_F_MAY_CHANGE;
4656 return 0;
4657 }
4658
Emeric Brunba841a12014-04-30 17:05:08 +02004659 if (cert_peer)
4660 crt = SSL_get_peer_certificate(conn->xprt_ctx);
4661 else
4662 crt = SSL_get_certificate(conn->xprt_ctx);
Emeric Brunce5ad802012-10-22 14:11:22 +02004663 if (!crt)
4664 goto out;
4665
Willy Tarreau47ca5452012-12-23 20:22:19 +01004666 smp_trash = get_trash_chunk();
Emeric Brunce5ad802012-10-22 14:11:22 +02004667 if (ssl_sock_get_time(X509_get_notAfter(crt), smp_trash) <= 0)
4668 goto out;
4669
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02004670 smp->data.u.str = *smp_trash;
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02004671 smp->data.type = SMP_T_STR;
Emeric Brunce5ad802012-10-22 14:11:22 +02004672 ret = 1;
4673out:
Emeric Brunba841a12014-04-30 17:05:08 +02004674 /* SSL_get_peer_certificate, it increase X509 * ref count */
4675 if (cert_peer && crt)
Emeric Brunce5ad802012-10-22 14:11:22 +02004676 X509_free(crt);
4677 return ret;
4678}
4679
Emeric Brunba841a12014-04-30 17:05:08 +02004680/* string, returns a string of a formatted full dn \C=..\O=..\OU=.. \CN=.. of certificate's issuer
4681 * The 5th keyword char is used to know if SSL_get_certificate or SSL_get_peer_certificate
4682 * should be use.
4683 */
Emeric Brun87855892012-10-17 17:39:35 +02004684static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02004685smp_fetch_ssl_x_i_dn(const struct arg *args, struct sample *smp, const char *kw, void *private)
Emeric Brun87855892012-10-17 17:39:35 +02004686{
Emeric Brunba841a12014-04-30 17:05:08 +02004687 int cert_peer = (kw[4] == 'c') ? 1 : 0;
Emeric Brun87855892012-10-17 17:39:35 +02004688 X509 *crt = NULL;
4689 X509_NAME *name;
4690 int ret = 0;
4691 struct chunk *smp_trash;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004692 struct connection *conn;
Emeric Brun87855892012-10-17 17:39:35 +02004693
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02004694 conn = objt_conn(smp->sess->origin);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004695 if (!conn || conn->xprt != &ssl_sock)
4696 return 0;
4697
4698 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brun87855892012-10-17 17:39:35 +02004699 smp->flags |= SMP_F_MAY_CHANGE;
4700 return 0;
4701 }
4702
Emeric Brunba841a12014-04-30 17:05:08 +02004703 if (cert_peer)
4704 crt = SSL_get_peer_certificate(conn->xprt_ctx);
4705 else
4706 crt = SSL_get_certificate(conn->xprt_ctx);
Emeric Brun87855892012-10-17 17:39:35 +02004707 if (!crt)
4708 goto out;
4709
4710 name = X509_get_issuer_name(crt);
4711 if (!name)
4712 goto out;
4713
Willy Tarreau47ca5452012-12-23 20:22:19 +01004714 smp_trash = get_trash_chunk();
Emeric Brun87855892012-10-17 17:39:35 +02004715 if (args && args[0].type == ARGT_STR) {
4716 int pos = 1;
4717
4718 if (args[1].type == ARGT_SINT)
4719 pos = args[1].data.sint;
Emeric Brun87855892012-10-17 17:39:35 +02004720
4721 if (ssl_sock_get_dn_entry(name, &args[0].data.str, pos, smp_trash) <= 0)
4722 goto out;
4723 }
4724 else if (ssl_sock_get_dn_oneline(name, smp_trash) <= 0)
4725 goto out;
4726
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02004727 smp->data.type = SMP_T_STR;
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02004728 smp->data.u.str = *smp_trash;
Emeric Brun87855892012-10-17 17:39:35 +02004729 ret = 1;
4730out:
Emeric Brunba841a12014-04-30 17:05:08 +02004731 /* SSL_get_peer_certificate, it increase X509 * ref count */
4732 if (cert_peer && crt)
Emeric Brun87855892012-10-17 17:39:35 +02004733 X509_free(crt);
4734 return ret;
4735}
4736
Emeric Brunba841a12014-04-30 17:05:08 +02004737/* string, returns notbefore date in ASN1_UTCTIME format.
4738 * The 5th keyword char is used to know if SSL_get_certificate or SSL_get_peer_certificate
4739 * should be use.
4740 */
Emeric Brunce5ad802012-10-22 14:11:22 +02004741static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02004742smp_fetch_ssl_x_notbefore(const struct arg *args, struct sample *smp, const char *kw, void *private)
Emeric Brunce5ad802012-10-22 14:11:22 +02004743{
Emeric Brunba841a12014-04-30 17:05:08 +02004744 int cert_peer = (kw[4] == 'c') ? 1 : 0;
Emeric Brunce5ad802012-10-22 14:11:22 +02004745 X509 *crt = NULL;
4746 int ret = 0;
4747 struct chunk *smp_trash;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004748 struct connection *conn;
4749
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02004750 conn = objt_conn(smp->sess->origin);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004751 if (!conn || conn->xprt != &ssl_sock)
Emeric Brunce5ad802012-10-22 14:11:22 +02004752 return 0;
4753
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004754 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brunce5ad802012-10-22 14:11:22 +02004755 smp->flags |= SMP_F_MAY_CHANGE;
4756 return 0;
4757 }
4758
Emeric Brunba841a12014-04-30 17:05:08 +02004759 if (cert_peer)
4760 crt = SSL_get_peer_certificate(conn->xprt_ctx);
4761 else
4762 crt = SSL_get_certificate(conn->xprt_ctx);
Emeric Brunce5ad802012-10-22 14:11:22 +02004763 if (!crt)
4764 goto out;
4765
Willy Tarreau47ca5452012-12-23 20:22:19 +01004766 smp_trash = get_trash_chunk();
Emeric Brunce5ad802012-10-22 14:11:22 +02004767 if (ssl_sock_get_time(X509_get_notBefore(crt), smp_trash) <= 0)
4768 goto out;
4769
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02004770 smp->data.u.str = *smp_trash;
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02004771 smp->data.type = SMP_T_STR;
Emeric Brunce5ad802012-10-22 14:11:22 +02004772 ret = 1;
4773out:
Emeric Brunba841a12014-04-30 17:05:08 +02004774 /* SSL_get_peer_certificate, it increase X509 * ref count */
4775 if (cert_peer && crt)
Emeric Brunce5ad802012-10-22 14:11:22 +02004776 X509_free(crt);
4777 return ret;
4778}
4779
Emeric Brunba841a12014-04-30 17:05:08 +02004780/* string, returns a string of a formatted full dn \C=..\O=..\OU=.. \CN=.. of certificate's subject
4781 * The 5th keyword char is used to know if SSL_get_certificate or SSL_get_peer_certificate
4782 * should be use.
4783 */
Emeric Brun87855892012-10-17 17:39:35 +02004784static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02004785smp_fetch_ssl_x_s_dn(const struct arg *args, struct sample *smp, const char *kw, void *private)
Emeric Brun87855892012-10-17 17:39:35 +02004786{
Emeric Brunba841a12014-04-30 17:05:08 +02004787 int cert_peer = (kw[4] == 'c') ? 1 : 0;
Emeric Brun87855892012-10-17 17:39:35 +02004788 X509 *crt = NULL;
4789 X509_NAME *name;
4790 int ret = 0;
4791 struct chunk *smp_trash;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004792 struct connection *conn;
Emeric Brun87855892012-10-17 17:39:35 +02004793
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02004794 conn = objt_conn(smp->sess->origin);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004795 if (!conn || conn->xprt != &ssl_sock)
4796 return 0;
4797
4798 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brun87855892012-10-17 17:39:35 +02004799 smp->flags |= SMP_F_MAY_CHANGE;
4800 return 0;
4801 }
4802
Emeric Brunba841a12014-04-30 17:05:08 +02004803 if (cert_peer)
4804 crt = SSL_get_peer_certificate(conn->xprt_ctx);
4805 else
4806 crt = SSL_get_certificate(conn->xprt_ctx);
Emeric Brun87855892012-10-17 17:39:35 +02004807 if (!crt)
4808 goto out;
4809
4810 name = X509_get_subject_name(crt);
4811 if (!name)
4812 goto out;
4813
Willy Tarreau47ca5452012-12-23 20:22:19 +01004814 smp_trash = get_trash_chunk();
Emeric Brun87855892012-10-17 17:39:35 +02004815 if (args && args[0].type == ARGT_STR) {
4816 int pos = 1;
4817
4818 if (args[1].type == ARGT_SINT)
4819 pos = args[1].data.sint;
Emeric Brun87855892012-10-17 17:39:35 +02004820
4821 if (ssl_sock_get_dn_entry(name, &args[0].data.str, pos, smp_trash) <= 0)
4822 goto out;
4823 }
4824 else if (ssl_sock_get_dn_oneline(name, smp_trash) <= 0)
4825 goto out;
4826
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02004827 smp->data.type = SMP_T_STR;
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02004828 smp->data.u.str = *smp_trash;
Emeric Brun87855892012-10-17 17:39:35 +02004829 ret = 1;
4830out:
Emeric Brunba841a12014-04-30 17:05:08 +02004831 /* SSL_get_peer_certificate, it increase X509 * ref count */
4832 if (cert_peer && crt)
Emeric Brun87855892012-10-17 17:39:35 +02004833 X509_free(crt);
4834 return ret;
4835}
Emeric Brun9143d372012-12-20 15:44:16 +01004836
4837/* integer, returns true if current session use a client certificate */
4838static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02004839smp_fetch_ssl_c_used(const struct arg *args, struct sample *smp, const char *kw, void *private)
Emeric Brun9143d372012-12-20 15:44:16 +01004840{
4841 X509 *crt;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004842 struct connection *conn;
Emeric Brun9143d372012-12-20 15:44:16 +01004843
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02004844 conn = objt_conn(smp->sess->origin);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004845 if (!conn || conn->xprt != &ssl_sock)
4846 return 0;
4847
4848 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brun9143d372012-12-20 15:44:16 +01004849 smp->flags |= SMP_F_MAY_CHANGE;
4850 return 0;
4851 }
4852
4853 /* SSL_get_peer_certificate returns a ptr on allocated X509 struct */
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004854 crt = SSL_get_peer_certificate(conn->xprt_ctx);
Emeric Brun9143d372012-12-20 15:44:16 +01004855 if (crt) {
4856 X509_free(crt);
4857 }
4858
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02004859 smp->data.type = SMP_T_BOOL;
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02004860 smp->data.u.sint = (crt != NULL);
Emeric Brun9143d372012-12-20 15:44:16 +01004861 return 1;
4862}
4863
Emeric Brunba841a12014-04-30 17:05:08 +02004864/* integer, returns the certificate version
4865 * The 5th keyword char is used to know if SSL_get_certificate or SSL_get_peer_certificate
4866 * should be use.
4867 */
Emeric Bruna7359fd2012-10-17 15:03:11 +02004868static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02004869smp_fetch_ssl_x_version(const struct arg *args, struct sample *smp, const char *kw, void *private)
Emeric Bruna7359fd2012-10-17 15:03:11 +02004870{
Emeric Brunba841a12014-04-30 17:05:08 +02004871 int cert_peer = (kw[4] == 'c') ? 1 : 0;
Emeric Bruna7359fd2012-10-17 15:03:11 +02004872 X509 *crt;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004873 struct connection *conn;
4874
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02004875 conn = objt_conn(smp->sess->origin);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004876 if (!conn || conn->xprt != &ssl_sock)
Emeric Bruna7359fd2012-10-17 15:03:11 +02004877 return 0;
4878
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004879 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Bruna7359fd2012-10-17 15:03:11 +02004880 smp->flags |= SMP_F_MAY_CHANGE;
4881 return 0;
4882 }
4883
Emeric Brunba841a12014-04-30 17:05:08 +02004884 if (cert_peer)
4885 crt = SSL_get_peer_certificate(conn->xprt_ctx);
4886 else
4887 crt = SSL_get_certificate(conn->xprt_ctx);
Emeric Bruna7359fd2012-10-17 15:03:11 +02004888 if (!crt)
4889 return 0;
4890
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02004891 smp->data.u.sint = (unsigned int)(1 + X509_get_version(crt));
Emeric Brunba841a12014-04-30 17:05:08 +02004892 /* SSL_get_peer_certificate increase X509 * ref count */
4893 if (cert_peer)
4894 X509_free(crt);
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02004895 smp->data.type = SMP_T_SINT;
Emeric Bruna7359fd2012-10-17 15:03:11 +02004896
4897 return 1;
4898}
4899
Emeric Brunba841a12014-04-30 17:05:08 +02004900/* string, returns the certificate's signature algorithm.
4901 * The 5th keyword char is used to know if SSL_get_certificate or SSL_get_peer_certificate
4902 * should be use.
4903 */
Emeric Brun7f56e742012-10-19 18:15:40 +02004904static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02004905smp_fetch_ssl_x_sig_alg(const struct arg *args, struct sample *smp, const char *kw, void *private)
Emeric Brun7f56e742012-10-19 18:15:40 +02004906{
Emeric Brunba841a12014-04-30 17:05:08 +02004907 int cert_peer = (kw[4] == 'c') ? 1 : 0;
Emeric Brun7f56e742012-10-19 18:15:40 +02004908 X509 *crt;
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02004909 __OPENSSL_110_CONST__ ASN1_OBJECT *algorithm;
Emeric Brun7f56e742012-10-19 18:15:40 +02004910 int nid;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004911 struct connection *conn;
Emeric Brun7f56e742012-10-19 18:15:40 +02004912
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02004913 conn = objt_conn(smp->sess->origin);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004914 if (!conn || conn->xprt != &ssl_sock)
4915 return 0;
4916
4917 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brun7f56e742012-10-19 18:15:40 +02004918 smp->flags |= SMP_F_MAY_CHANGE;
4919 return 0;
4920 }
4921
Emeric Brunba841a12014-04-30 17:05:08 +02004922 if (cert_peer)
4923 crt = SSL_get_peer_certificate(conn->xprt_ctx);
4924 else
4925 crt = SSL_get_certificate(conn->xprt_ctx);
Emeric Brun7f56e742012-10-19 18:15:40 +02004926 if (!crt)
4927 return 0;
4928
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02004929 X509_ALGOR_get0(&algorithm, NULL, NULL, X509_get0_tbs_sigalg(crt));
4930 nid = OBJ_obj2nid(algorithm);
Emeric Brun7f56e742012-10-19 18:15:40 +02004931
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02004932 smp->data.u.str.str = (char *)OBJ_nid2sn(nid);
4933 if (!smp->data.u.str.str) {
Emeric Brunba841a12014-04-30 17:05:08 +02004934 /* SSL_get_peer_certificate increase X509 * ref count */
4935 if (cert_peer)
4936 X509_free(crt);
Emeric Brun7f56e742012-10-19 18:15:40 +02004937 return 0;
Emeric Brun9bf3ba22013-10-07 14:31:44 +02004938 }
Emeric Brun7f56e742012-10-19 18:15:40 +02004939
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02004940 smp->data.type = SMP_T_STR;
Thierry FOURNIER7654c9f2013-12-17 00:20:33 +01004941 smp->flags |= SMP_F_CONST;
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02004942 smp->data.u.str.len = strlen(smp->data.u.str.str);
Emeric Brunba841a12014-04-30 17:05:08 +02004943 /* SSL_get_peer_certificate increase X509 * ref count */
4944 if (cert_peer)
4945 X509_free(crt);
Emeric Brun7f56e742012-10-19 18:15:40 +02004946
4947 return 1;
4948}
4949
Emeric Brunba841a12014-04-30 17:05:08 +02004950/* string, returns the certificate's key algorithm.
4951 * The 5th keyword char is used to know if SSL_get_certificate or SSL_get_peer_certificate
4952 * should be use.
4953 */
Emeric Brun521a0112012-10-22 12:22:55 +02004954static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02004955smp_fetch_ssl_x_key_alg(const struct arg *args, struct sample *smp, const char *kw, void *private)
Emeric Brun521a0112012-10-22 12:22:55 +02004956{
Emeric Brunba841a12014-04-30 17:05:08 +02004957 int cert_peer = (kw[4] == 'c') ? 1 : 0;
Emeric Brun521a0112012-10-22 12:22:55 +02004958 X509 *crt;
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02004959 ASN1_OBJECT *algorithm;
Emeric Brun521a0112012-10-22 12:22:55 +02004960 int nid;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004961 struct connection *conn;
Emeric Brun521a0112012-10-22 12:22:55 +02004962
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02004963 conn = objt_conn(smp->sess->origin);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004964 if (!conn || conn->xprt != &ssl_sock)
4965 return 0;
4966
4967 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brun521a0112012-10-22 12:22:55 +02004968 smp->flags |= SMP_F_MAY_CHANGE;
4969 return 0;
4970 }
4971
Emeric Brunba841a12014-04-30 17:05:08 +02004972 if (cert_peer)
4973 crt = SSL_get_peer_certificate(conn->xprt_ctx);
4974 else
4975 crt = SSL_get_certificate(conn->xprt_ctx);
Emeric Brun521a0112012-10-22 12:22:55 +02004976 if (!crt)
4977 return 0;
4978
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02004979 X509_PUBKEY_get0_param(&algorithm, NULL, NULL, NULL, X509_get_X509_PUBKEY(crt));
4980 nid = OBJ_obj2nid(algorithm);
Emeric Brun521a0112012-10-22 12:22:55 +02004981
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02004982 smp->data.u.str.str = (char *)OBJ_nid2sn(nid);
4983 if (!smp->data.u.str.str) {
Emeric Brunba841a12014-04-30 17:05:08 +02004984 /* SSL_get_peer_certificate increase X509 * ref count */
4985 if (cert_peer)
4986 X509_free(crt);
Emeric Brun521a0112012-10-22 12:22:55 +02004987 return 0;
Emeric Brun9bf3ba22013-10-07 14:31:44 +02004988 }
Emeric Brun521a0112012-10-22 12:22:55 +02004989
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02004990 smp->data.type = SMP_T_STR;
Thierry FOURNIER7654c9f2013-12-17 00:20:33 +01004991 smp->flags |= SMP_F_CONST;
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02004992 smp->data.u.str.len = strlen(smp->data.u.str.str);
Emeric Brunba841a12014-04-30 17:05:08 +02004993 if (cert_peer)
4994 X509_free(crt);
Emeric Brun521a0112012-10-22 12:22:55 +02004995
4996 return 1;
4997}
4998
Emeric Brun645ae792014-04-30 14:21:06 +02004999/* boolean, returns true if front conn. transport layer is SSL.
5000 * This function is also usable on backend conn if the fetch keyword 5th
5001 * char is 'b'.
5002 */
Willy Tarreau7875d092012-09-10 08:20:03 +02005003static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02005004smp_fetch_ssl_fc(const struct arg *args, struct sample *smp, const char *kw, void *private)
Willy Tarreau7875d092012-09-10 08:20:03 +02005005{
Willy Tarreaue237fe12016-03-10 17:05:28 +01005006 struct connection *conn = objt_conn((kw[4] != 'b') ? smp->sess->origin :
5007 smp->strm ? smp->strm->si[1].end : NULL);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02005008
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02005009 smp->data.type = SMP_T_BOOL;
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02005010 smp->data.u.sint = (conn && conn->xprt == &ssl_sock);
Willy Tarreau7875d092012-09-10 08:20:03 +02005011 return 1;
5012}
5013
Emeric Brun2525b6b2012-10-18 15:59:43 +02005014/* boolean, returns true if client present a SNI */
Willy Tarreau7875d092012-09-10 08:20:03 +02005015static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02005016smp_fetch_ssl_fc_has_sni(const struct arg *args, struct sample *smp, const char *kw, void *private)
Willy Tarreau7875d092012-09-10 08:20:03 +02005017{
5018#ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02005019 struct connection *conn = objt_conn(smp->sess->origin);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02005020
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02005021 smp->data.type = SMP_T_BOOL;
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02005022 smp->data.u.sint = (conn && conn->xprt == &ssl_sock) &&
Willy Tarreaub363a1f2013-10-01 10:45:07 +02005023 conn->xprt_ctx &&
5024 SSL_get_servername(conn->xprt_ctx, TLSEXT_NAMETYPE_host_name) != NULL;
Willy Tarreau7875d092012-09-10 08:20:03 +02005025 return 1;
5026#else
5027 return 0;
5028#endif
5029}
5030
Nenad Merdanovic26ea8222015-05-18 02:28:57 +02005031/* boolean, returns true if client session has been resumed */
5032static int
5033smp_fetch_ssl_fc_is_resumed(const struct arg *args, struct sample *smp, const char *kw, void *private)
5034{
5035 struct connection *conn = objt_conn(smp->sess->origin);
5036
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02005037 smp->data.type = SMP_T_BOOL;
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02005038 smp->data.u.sint = (conn && conn->xprt == &ssl_sock) &&
Nenad Merdanovic26ea8222015-05-18 02:28:57 +02005039 conn->xprt_ctx &&
5040 SSL_session_reused(conn->xprt_ctx);
5041 return 1;
5042}
5043
Emeric Brun645ae792014-04-30 14:21:06 +02005044/* string, returns the used cipher if front conn. transport layer is SSL.
5045 * This function is also usable on backend conn if the fetch keyword 5th
5046 * char is 'b'.
5047 */
Emeric Brun589fcad2012-10-16 14:13:26 +02005048static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02005049smp_fetch_ssl_fc_cipher(const struct arg *args, struct sample *smp, const char *kw, void *private)
Emeric Brun589fcad2012-10-16 14:13:26 +02005050{
Willy Tarreaue237fe12016-03-10 17:05:28 +01005051 struct connection *conn = objt_conn((kw[4] != 'b') ? smp->sess->origin :
5052 smp->strm ? smp->strm->si[1].end : NULL);
Emeric Brun589fcad2012-10-16 14:13:26 +02005053
Willy Tarreaube508f12016-03-10 11:47:01 +01005054 smp->flags = 0;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02005055 if (!conn || !conn->xprt_ctx || conn->xprt != &ssl_sock)
Emeric Brun589fcad2012-10-16 14:13:26 +02005056 return 0;
5057
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02005058 smp->data.u.str.str = (char *)SSL_get_cipher_name(conn->xprt_ctx);
5059 if (!smp->data.u.str.str)
Emeric Brun589fcad2012-10-16 14:13:26 +02005060 return 0;
5061
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02005062 smp->data.type = SMP_T_STR;
Thierry FOURNIER7654c9f2013-12-17 00:20:33 +01005063 smp->flags |= SMP_F_CONST;
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02005064 smp->data.u.str.len = strlen(smp->data.u.str.str);
Emeric Brun589fcad2012-10-16 14:13:26 +02005065
5066 return 1;
5067}
5068
Emeric Brun645ae792014-04-30 14:21:06 +02005069/* integer, returns the algoritm's keysize if front conn. transport layer
5070 * is SSL.
5071 * This function is also usable on backend conn if the fetch keyword 5th
5072 * char is 'b'.
5073 */
Emeric Brun589fcad2012-10-16 14:13:26 +02005074static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02005075smp_fetch_ssl_fc_alg_keysize(const struct arg *args, struct sample *smp, const char *kw, void *private)
Emeric Brun589fcad2012-10-16 14:13:26 +02005076{
Willy Tarreaue237fe12016-03-10 17:05:28 +01005077 struct connection *conn = objt_conn((kw[4] != 'b') ? smp->sess->origin :
5078 smp->strm ? smp->strm->si[1].end : NULL);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02005079
Willy Tarreaue237fe12016-03-10 17:05:28 +01005080 int sint;
Willy Tarreaube508f12016-03-10 11:47:01 +01005081
Emeric Brun589fcad2012-10-16 14:13:26 +02005082 smp->flags = 0;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02005083 if (!conn || !conn->xprt_ctx || conn->xprt != &ssl_sock)
Emeric Brun589fcad2012-10-16 14:13:26 +02005084 return 0;
5085
Thierry FOURNIER07ee64e2015-07-06 23:43:03 +02005086 if (!SSL_get_cipher_bits(conn->xprt_ctx, &sint))
Willy Tarreaub363a1f2013-10-01 10:45:07 +02005087 return 0;
5088
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02005089 smp->data.u.sint = sint;
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02005090 smp->data.type = SMP_T_SINT;
Emeric Brun589fcad2012-10-16 14:13:26 +02005091
5092 return 1;
5093}
5094
Emeric Brun645ae792014-04-30 14:21:06 +02005095/* integer, returns the used keysize if front conn. transport layer is SSL.
5096 * This function is also usable on backend conn if the fetch keyword 5th
5097 * char is 'b'.
5098 */
Emeric Brun589fcad2012-10-16 14:13:26 +02005099static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02005100smp_fetch_ssl_fc_use_keysize(const struct arg *args, struct sample *smp, const char *kw, void *private)
Emeric Brun589fcad2012-10-16 14:13:26 +02005101{
Willy Tarreaue237fe12016-03-10 17:05:28 +01005102 struct connection *conn = objt_conn((kw[4] != 'b') ? smp->sess->origin :
5103 smp->strm ? smp->strm->si[1].end : NULL);
Willy Tarreaube508f12016-03-10 11:47:01 +01005104
Emeric Brun589fcad2012-10-16 14:13:26 +02005105 smp->flags = 0;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02005106 if (!conn || !conn->xprt_ctx || conn->xprt != &ssl_sock)
5107 return 0;
5108
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02005109 smp->data.u.sint = (unsigned int)SSL_get_cipher_bits(conn->xprt_ctx, NULL);
5110 if (!smp->data.u.sint)
Emeric Brun589fcad2012-10-16 14:13:26 +02005111 return 0;
5112
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02005113 smp->data.type = SMP_T_SINT;
Emeric Brun589fcad2012-10-16 14:13:26 +02005114
5115 return 1;
5116}
5117
Willy Tarreau6c9a3d52012-10-18 18:57:14 +02005118#ifdef OPENSSL_NPN_NEGOTIATED
Willy Tarreau7875d092012-09-10 08:20:03 +02005119static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02005120smp_fetch_ssl_fc_npn(const struct arg *args, struct sample *smp, const char *kw, void *private)
Willy Tarreaua33c6542012-10-15 13:19:06 +02005121{
Willy Tarreaub363a1f2013-10-01 10:45:07 +02005122 struct connection *conn;
5123
Thierry FOURNIER7654c9f2013-12-17 00:20:33 +01005124 smp->flags = SMP_F_CONST;
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02005125 smp->data.type = SMP_T_STR;
Willy Tarreaua33c6542012-10-15 13:19:06 +02005126
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02005127 conn = objt_conn(smp->sess->origin);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02005128 if (!conn || !conn->xprt_ctx || conn->xprt != &ssl_sock)
5129 return 0;
5130
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02005131 smp->data.u.str.str = NULL;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02005132 SSL_get0_next_proto_negotiated(conn->xprt_ctx,
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02005133 (const unsigned char **)&smp->data.u.str.str, (unsigned *)&smp->data.u.str.len);
Willy Tarreaua33c6542012-10-15 13:19:06 +02005134
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02005135 if (!smp->data.u.str.str)
Willy Tarreaua33c6542012-10-15 13:19:06 +02005136 return 0;
5137
5138 return 1;
Willy Tarreaua33c6542012-10-15 13:19:06 +02005139}
Willy Tarreau6c9a3d52012-10-18 18:57:14 +02005140#endif
Willy Tarreaua33c6542012-10-15 13:19:06 +02005141
Dirkjan Bussink48f1c4e2014-02-13 12:29:42 +01005142#ifdef TLSEXT_TYPE_application_layer_protocol_negotiation
Willy Tarreauab861d32013-04-02 02:30:41 +02005143static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02005144smp_fetch_ssl_fc_alpn(const struct arg *args, struct sample *smp, const char *kw, void *private)
Willy Tarreauab861d32013-04-02 02:30:41 +02005145{
Willy Tarreaub363a1f2013-10-01 10:45:07 +02005146 struct connection *conn;
5147
Thierry FOURNIER7654c9f2013-12-17 00:20:33 +01005148 smp->flags = SMP_F_CONST;
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02005149 smp->data.type = SMP_T_STR;
Willy Tarreauab861d32013-04-02 02:30:41 +02005150
Willy Tarreaue26bf052015-05-12 10:30:12 +02005151 conn = objt_conn(smp->sess->origin);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02005152 if (!conn || !conn->xprt_ctx || conn->xprt != &ssl_sock)
Willy Tarreauab861d32013-04-02 02:30:41 +02005153 return 0;
5154
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02005155 smp->data.u.str.str = NULL;
Dirkjan Bussink48f1c4e2014-02-13 12:29:42 +01005156 SSL_get0_alpn_selected(conn->xprt_ctx,
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02005157 (const unsigned char **)&smp->data.u.str.str, (unsigned *)&smp->data.u.str.len);
Willy Tarreauab861d32013-04-02 02:30:41 +02005158
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02005159 if (!smp->data.u.str.str)
Willy Tarreauab861d32013-04-02 02:30:41 +02005160 return 0;
5161
5162 return 1;
5163}
5164#endif
5165
Emeric Brun645ae792014-04-30 14:21:06 +02005166/* string, returns the used protocol if front conn. transport layer is SSL.
5167 * This function is also usable on backend conn if the fetch keyword 5th
5168 * char is 'b'.
5169 */
Willy Tarreaua33c6542012-10-15 13:19:06 +02005170static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02005171smp_fetch_ssl_fc_protocol(const struct arg *args, struct sample *smp, const char *kw, void *private)
Emeric Brun589fcad2012-10-16 14:13:26 +02005172{
Willy Tarreaue237fe12016-03-10 17:05:28 +01005173 struct connection *conn = objt_conn((kw[4] != 'b') ? smp->sess->origin :
5174 smp->strm ? smp->strm->si[1].end : NULL);
Willy Tarreaube508f12016-03-10 11:47:01 +01005175
Emeric Brun589fcad2012-10-16 14:13:26 +02005176 smp->flags = 0;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02005177 if (!conn || !conn->xprt_ctx || conn->xprt != &ssl_sock)
5178 return 0;
5179
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02005180 smp->data.u.str.str = (char *)SSL_get_version(conn->xprt_ctx);
5181 if (!smp->data.u.str.str)
Emeric Brun589fcad2012-10-16 14:13:26 +02005182 return 0;
5183
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02005184 smp->data.type = SMP_T_STR;
Thierry FOURNIER7654c9f2013-12-17 00:20:33 +01005185 smp->flags = SMP_F_CONST;
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02005186 smp->data.u.str.len = strlen(smp->data.u.str.str);
Emeric Brun589fcad2012-10-16 14:13:26 +02005187
5188 return 1;
5189}
5190
Willy Tarreau87b09662015-04-03 00:22:06 +02005191/* binary, returns the SSL stream id if front conn. transport layer is SSL.
Emeric Brun645ae792014-04-30 14:21:06 +02005192 * This function is also usable on backend conn if the fetch keyword 5th
5193 * char is 'b'.
5194 */
Emeric Brun589fcad2012-10-16 14:13:26 +02005195static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02005196smp_fetch_ssl_fc_session_id(const struct arg *args, struct sample *smp, const char *kw, void *private)
Emeric Brunfe68f682012-10-16 14:59:28 +02005197{
5198#if OPENSSL_VERSION_NUMBER > 0x0090800fL
Willy Tarreaue237fe12016-03-10 17:05:28 +01005199 struct connection *conn = objt_conn((kw[4] != 'b') ? smp->sess->origin :
5200 smp->strm ? smp->strm->si[1].end : NULL);
Emeric Brunfe68f682012-10-16 14:59:28 +02005201
Willy Tarreaue237fe12016-03-10 17:05:28 +01005202 SSL_SESSION *ssl_sess;
Willy Tarreaube508f12016-03-10 11:47:01 +01005203
Thierry FOURNIER7654c9f2013-12-17 00:20:33 +01005204 smp->flags = SMP_F_CONST;
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02005205 smp->data.type = SMP_T_BIN;
Emeric Brunfe68f682012-10-16 14:59:28 +02005206
Willy Tarreaub363a1f2013-10-01 10:45:07 +02005207 if (!conn || !conn->xprt_ctx || conn->xprt != &ssl_sock)
5208 return 0;
5209
Willy Tarreau192252e2015-04-04 01:47:55 +02005210 ssl_sess = SSL_get_session(conn->xprt_ctx);
5211 if (!ssl_sess)
Emeric Brunfe68f682012-10-16 14:59:28 +02005212 return 0;
5213
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02005214 smp->data.u.str.str = (char *)SSL_SESSION_get_id(ssl_sess, (unsigned int *)&smp->data.u.str.len);
5215 if (!smp->data.u.str.str || !smp->data.u.str.len)
Emeric Brunfe68f682012-10-16 14:59:28 +02005216 return 0;
5217
5218 return 1;
5219#else
5220 return 0;
5221#endif
5222}
5223
5224static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02005225smp_fetch_ssl_fc_sni(const struct arg *args, struct sample *smp, const char *kw, void *private)
Willy Tarreau7875d092012-09-10 08:20:03 +02005226{
5227#ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME
Willy Tarreaub363a1f2013-10-01 10:45:07 +02005228 struct connection *conn;
5229
Thierry FOURNIER7654c9f2013-12-17 00:20:33 +01005230 smp->flags = SMP_F_CONST;
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02005231 smp->data.type = SMP_T_STR;
Willy Tarreau7875d092012-09-10 08:20:03 +02005232
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02005233 conn = objt_conn(smp->sess->origin);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02005234 if (!conn || !conn->xprt_ctx || conn->xprt != &ssl_sock)
5235 return 0;
5236
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02005237 smp->data.u.str.str = (char *)SSL_get_servername(conn->xprt_ctx, TLSEXT_NAMETYPE_host_name);
5238 if (!smp->data.u.str.str)
Willy Tarreau3e394c92012-09-14 23:56:58 +02005239 return 0;
5240
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02005241 smp->data.u.str.len = strlen(smp->data.u.str.str);
Willy Tarreau7875d092012-09-10 08:20:03 +02005242 return 1;
5243#else
5244 return 0;
5245#endif
5246}
5247
David Sc1ad52e2014-04-08 18:48:47 -04005248static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02005249smp_fetch_ssl_fc_unique_id(const struct arg *args, struct sample *smp, const char *kw, void *private)
David Sc1ad52e2014-04-08 18:48:47 -04005250{
5251#if OPENSSL_VERSION_NUMBER > 0x0090800fL
Willy Tarreaue237fe12016-03-10 17:05:28 +01005252 struct connection *conn = objt_conn((kw[4] != 'b') ? smp->sess->origin :
5253 smp->strm ? smp->strm->si[1].end : NULL);
5254
David Sc1ad52e2014-04-08 18:48:47 -04005255 int finished_len;
David Sc1ad52e2014-04-08 18:48:47 -04005256 struct chunk *finished_trash;
David Sc1ad52e2014-04-08 18:48:47 -04005257
5258 smp->flags = 0;
David Sc1ad52e2014-04-08 18:48:47 -04005259 if (!conn || !conn->xprt_ctx || conn->xprt != &ssl_sock)
5260 return 0;
5261
5262 if (!(conn->flags & CO_FL_CONNECTED)) {
5263 smp->flags |= SMP_F_MAY_CHANGE;
5264 return 0;
5265 }
5266
5267 finished_trash = get_trash_chunk();
5268 if (!SSL_session_reused(conn->xprt_ctx))
5269 finished_len = SSL_get_peer_finished(conn->xprt_ctx, finished_trash->str, finished_trash->size);
5270 else
5271 finished_len = SSL_get_finished(conn->xprt_ctx, finished_trash->str, finished_trash->size);
5272
5273 if (!finished_len)
5274 return 0;
5275
Emeric Brunb73a9b02014-04-30 18:49:19 +02005276 finished_trash->len = finished_len;
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02005277 smp->data.u.str = *finished_trash;
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02005278 smp->data.type = SMP_T_BIN;
David Sc1ad52e2014-04-08 18:48:47 -04005279
5280 return 1;
5281#else
5282 return 0;
5283#endif
5284}
5285
Emeric Brun2525b6b2012-10-18 15:59:43 +02005286/* integer, returns the first verify error in CA chain of client certificate chain. */
Emeric Brunf282a812012-09-21 15:27:54 +02005287static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02005288smp_fetch_ssl_c_ca_err(const struct arg *args, struct sample *smp, const char *kw, void *private)
Emeric Brunf282a812012-09-21 15:27:54 +02005289{
Willy Tarreaub363a1f2013-10-01 10:45:07 +02005290 struct connection *conn;
5291
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02005292 conn = objt_conn(smp->sess->origin);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02005293 if (!conn || conn->xprt != &ssl_sock)
5294 return 0;
5295
5296 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brunf282a812012-09-21 15:27:54 +02005297 smp->flags = SMP_F_MAY_CHANGE;
5298 return 0;
5299 }
5300
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02005301 smp->data.type = SMP_T_SINT;
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02005302 smp->data.u.sint = (unsigned long long int)SSL_SOCK_ST_TO_CA_ERROR(conn->xprt_st);
Emeric Brunf282a812012-09-21 15:27:54 +02005303 smp->flags = 0;
5304
5305 return 1;
5306}
5307
Emeric Brun2525b6b2012-10-18 15:59:43 +02005308/* integer, returns the depth of the first verify error in CA chain of client certificate chain. */
Emeric Brunf282a812012-09-21 15:27:54 +02005309static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02005310smp_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 +02005311{
Willy Tarreaub363a1f2013-10-01 10:45:07 +02005312 struct connection *conn;
5313
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02005314 conn = objt_conn(smp->sess->origin);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02005315 if (!conn || conn->xprt != &ssl_sock)
Emeric Brunf282a812012-09-21 15:27:54 +02005316 return 0;
5317
Willy Tarreaub363a1f2013-10-01 10:45:07 +02005318 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brunf282a812012-09-21 15:27:54 +02005319 smp->flags = SMP_F_MAY_CHANGE;
5320 return 0;
5321 }
5322
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02005323 smp->data.type = SMP_T_SINT;
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02005324 smp->data.u.sint = (long long int)SSL_SOCK_ST_TO_CAEDEPTH(conn->xprt_st);
Emeric Brunf282a812012-09-21 15:27:54 +02005325 smp->flags = 0;
5326
5327 return 1;
5328}
5329
Emeric Brun2525b6b2012-10-18 15:59:43 +02005330/* integer, returns the first verify error on client certificate */
Emeric Brunf282a812012-09-21 15:27:54 +02005331static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02005332smp_fetch_ssl_c_err(const struct arg *args, struct sample *smp, const char *kw, void *private)
Emeric Brunf282a812012-09-21 15:27:54 +02005333{
Willy Tarreaub363a1f2013-10-01 10:45:07 +02005334 struct connection *conn;
5335
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02005336 conn = objt_conn(smp->sess->origin);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02005337 if (!conn || conn->xprt != &ssl_sock)
5338 return 0;
5339
5340 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brunf282a812012-09-21 15:27:54 +02005341 smp->flags = SMP_F_MAY_CHANGE;
5342 return 0;
5343 }
5344
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02005345 smp->data.type = SMP_T_SINT;
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02005346 smp->data.u.sint = (long long int)SSL_SOCK_ST_TO_CRTERROR(conn->xprt_st);
Emeric Brunf282a812012-09-21 15:27:54 +02005347 smp->flags = 0;
5348
5349 return 1;
5350}
5351
Emeric Brun2525b6b2012-10-18 15:59:43 +02005352/* integer, returns the verify result on client cert */
Emeric Brunbaf8ffb2012-09-21 15:27:20 +02005353static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02005354smp_fetch_ssl_c_verify(const struct arg *args, struct sample *smp, const char *kw, void *private)
Emeric Brunbaf8ffb2012-09-21 15:27:20 +02005355{
Willy Tarreaub363a1f2013-10-01 10:45:07 +02005356 struct connection *conn;
5357
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02005358 conn = objt_conn(smp->sess->origin);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02005359 if (!conn || conn->xprt != &ssl_sock)
5360 return 0;
5361
5362 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brunbaf8ffb2012-09-21 15:27:20 +02005363 smp->flags = SMP_F_MAY_CHANGE;
5364 return 0;
5365 }
5366
Willy Tarreaub363a1f2013-10-01 10:45:07 +02005367 if (!conn->xprt_ctx)
Emeric Brunbaf8ffb2012-09-21 15:27:20 +02005368 return 0;
5369
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02005370 smp->data.type = SMP_T_SINT;
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02005371 smp->data.u.sint = (long long int)SSL_get_verify_result(conn->xprt_ctx);
Emeric Brunbaf8ffb2012-09-21 15:27:20 +02005372 smp->flags = 0;
5373
5374 return 1;
5375}
5376
Emeric Brunfb510ea2012-10-05 12:00:26 +02005377/* parse the "ca-file" bind keyword */
Emmanuel Hocdet98263292016-12-29 18:26:15 +01005378static int ssl_bind_parse_ca_file(char **args, int cur_arg, struct proxy *px, struct ssl_bind_conf *conf, char **err)
Emeric Brund94b3fe2012-09-20 18:23:56 +02005379{
5380 if (!*args[cur_arg + 1]) {
5381 if (err)
5382 memprintf(err, "'%s' : missing CAfile path", args[cur_arg]);
5383 return ERR_ALERT | ERR_FATAL;
5384 }
5385
Willy Tarreauef934602016-12-22 23:12:01 +01005386 if ((*args[cur_arg + 1] != '/') && global_ssl.ca_base)
5387 memprintf(&conf->ca_file, "%s/%s", global_ssl.ca_base, args[cur_arg + 1]);
Emeric Brunef42d922012-10-11 16:11:36 +02005388 else
5389 memprintf(&conf->ca_file, "%s", args[cur_arg + 1]);
Emeric Brunc8e8d122012-10-02 18:42:10 +02005390
Emeric Brund94b3fe2012-09-20 18:23:56 +02005391 return 0;
5392}
Emmanuel Hocdet98263292016-12-29 18:26:15 +01005393static int bind_parse_ca_file(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
5394{
5395 return ssl_bind_parse_ca_file(args, cur_arg, px, &conf->ssl_conf, err);
5396}
Emeric Brund94b3fe2012-09-20 18:23:56 +02005397
Christopher Faulet31af49d2015-06-09 17:29:50 +02005398/* parse the "ca-sign-file" bind keyword */
5399static int bind_parse_ca_sign_file(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
5400{
5401 if (!*args[cur_arg + 1]) {
5402 if (err)
5403 memprintf(err, "'%s' : missing CAfile path", args[cur_arg]);
5404 return ERR_ALERT | ERR_FATAL;
5405 }
5406
Willy Tarreauef934602016-12-22 23:12:01 +01005407 if ((*args[cur_arg + 1] != '/') && global_ssl.ca_base)
5408 memprintf(&conf->ca_sign_file, "%s/%s", global_ssl.ca_base, args[cur_arg + 1]);
Christopher Faulet31af49d2015-06-09 17:29:50 +02005409 else
5410 memprintf(&conf->ca_sign_file, "%s", args[cur_arg + 1]);
5411
5412 return 0;
5413}
5414
Bertrand Jacquinff13c062016-11-13 16:37:11 +00005415/* parse the "ca-sign-pass" bind keyword */
Christopher Faulet31af49d2015-06-09 17:29:50 +02005416static int bind_parse_ca_sign_pass(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
5417{
5418 if (!*args[cur_arg + 1]) {
5419 if (err)
5420 memprintf(err, "'%s' : missing CAkey password", args[cur_arg]);
5421 return ERR_ALERT | ERR_FATAL;
5422 }
5423 memprintf(&conf->ca_sign_pass, "%s", args[cur_arg + 1]);
5424 return 0;
5425}
5426
Willy Tarreau79eeafa2012-09-14 07:53:05 +02005427/* parse the "ciphers" bind keyword */
Emmanuel Hocdet98263292016-12-29 18:26:15 +01005428static int ssl_bind_parse_ciphers(char **args, int cur_arg, struct proxy *px, struct ssl_bind_conf *conf, char **err)
Willy Tarreau79eeafa2012-09-14 07:53:05 +02005429{
5430 if (!*args[cur_arg + 1]) {
Willy Tarreaueb6cead2012-09-20 19:43:14 +02005431 memprintf(err, "'%s' : missing cipher suite", args[cur_arg]);
Willy Tarreau79eeafa2012-09-14 07:53:05 +02005432 return ERR_ALERT | ERR_FATAL;
5433 }
5434
Emeric Brun76d88952012-10-05 15:47:31 +02005435 free(conf->ciphers);
Willy Tarreau4348fad2012-09-20 16:48:07 +02005436 conf->ciphers = strdup(args[cur_arg + 1]);
Willy Tarreau79eeafa2012-09-14 07:53:05 +02005437 return 0;
5438}
Emmanuel Hocdet98263292016-12-29 18:26:15 +01005439static int bind_parse_ciphers(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
5440{
5441 return ssl_bind_parse_ciphers(args, cur_arg, px, &conf->ssl_conf, err);
5442}
Willy Tarreau79eeafa2012-09-14 07:53:05 +02005443/* parse the "crt" bind keyword */
Willy Tarreau4348fad2012-09-20 16:48:07 +02005444static 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 +02005445{
Willy Tarreau38011032013-08-13 16:59:39 +02005446 char path[MAXPATHLEN];
Willy Tarreaub75d6922014-04-14 18:05:41 +02005447
Willy Tarreau79eeafa2012-09-14 07:53:05 +02005448 if (!*args[cur_arg + 1]) {
Willy Tarreaueb6cead2012-09-20 19:43:14 +02005449 memprintf(err, "'%s' : missing certificate location", args[cur_arg]);
Willy Tarreau79eeafa2012-09-14 07:53:05 +02005450 return ERR_ALERT | ERR_FATAL;
5451 }
5452
Willy Tarreauef934602016-12-22 23:12:01 +01005453 if ((*args[cur_arg + 1] != '/' ) && global_ssl.crt_base) {
5454 if ((strlen(global_ssl.crt_base) + 1 + strlen(args[cur_arg + 1]) + 1) > MAXPATHLEN) {
Emeric Brunc8e8d122012-10-02 18:42:10 +02005455 memprintf(err, "'%s' : path too long", args[cur_arg]);
5456 return ERR_ALERT | ERR_FATAL;
5457 }
Willy Tarreauef934602016-12-22 23:12:01 +01005458 snprintf(path, sizeof(path), "%s/%s", global_ssl.crt_base, args[cur_arg + 1]);
Willy Tarreau03209342016-12-22 17:08:28 +01005459 if (ssl_sock_load_cert(path, conf, err) > 0)
Emeric Brunc8e8d122012-10-02 18:42:10 +02005460 return ERR_ALERT | ERR_FATAL;
5461
5462 return 0;
5463 }
5464
Willy Tarreau03209342016-12-22 17:08:28 +01005465 if (ssl_sock_load_cert(args[cur_arg + 1], conf, err) > 0)
Willy Tarreau79eeafa2012-09-14 07:53:05 +02005466 return ERR_ALERT | ERR_FATAL;
Emeric Brund94b3fe2012-09-20 18:23:56 +02005467
5468 return 0;
5469}
5470
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01005471/* parse the "crt-list" bind keyword */
5472static int bind_parse_crt_list(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
5473{
5474 if (!*args[cur_arg + 1]) {
5475 memprintf(err, "'%s' : missing certificate location", args[cur_arg]);
5476 return ERR_ALERT | ERR_FATAL;
5477 }
5478
Emmanuel Hocdet98263292016-12-29 18:26:15 +01005479 if (ssl_sock_load_cert_list_file(args[cur_arg + 1], conf, px, err) > 0) {
Willy Tarreauad1731d2013-04-02 17:35:58 +02005480 memprintf(err, "'%s' : %s", args[cur_arg], *err);
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01005481 return ERR_ALERT | ERR_FATAL;
Willy Tarreauad1731d2013-04-02 17:35:58 +02005482 }
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01005483
5484 return 0;
5485}
5486
Emeric Brunfb510ea2012-10-05 12:00:26 +02005487/* parse the "crl-file" bind keyword */
Emmanuel Hocdet98263292016-12-29 18:26:15 +01005488static int ssl_bind_parse_crl_file(char **args, int cur_arg, struct proxy *px, struct ssl_bind_conf *conf, char **err)
Emeric Brund94b3fe2012-09-20 18:23:56 +02005489{
Emeric Brun051cdab2012-10-02 19:25:50 +02005490#ifndef X509_V_FLAG_CRL_CHECK
5491 if (err)
5492 memprintf(err, "'%s' : library does not support CRL verify", args[cur_arg]);
5493 return ERR_ALERT | ERR_FATAL;
5494#else
Emeric Brund94b3fe2012-09-20 18:23:56 +02005495 if (!*args[cur_arg + 1]) {
5496 if (err)
5497 memprintf(err, "'%s' : missing CRLfile path", args[cur_arg]);
5498 return ERR_ALERT | ERR_FATAL;
5499 }
Emeric Brun2b58d042012-09-20 17:10:03 +02005500
Willy Tarreauef934602016-12-22 23:12:01 +01005501 if ((*args[cur_arg + 1] != '/') && global_ssl.ca_base)
5502 memprintf(&conf->crl_file, "%s/%s", global_ssl.ca_base, args[cur_arg + 1]);
Emeric Brunef42d922012-10-11 16:11:36 +02005503 else
5504 memprintf(&conf->crl_file, "%s", args[cur_arg + 1]);
Emeric Brunc8e8d122012-10-02 18:42:10 +02005505
Emeric Brun2b58d042012-09-20 17:10:03 +02005506 return 0;
Emeric Brun051cdab2012-10-02 19:25:50 +02005507#endif
Emeric Brun2b58d042012-09-20 17:10:03 +02005508}
Emmanuel Hocdet98263292016-12-29 18:26:15 +01005509static int bind_parse_crl_file(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
5510{
5511 return ssl_bind_parse_crl_file(args, cur_arg, px, &conf->ssl_conf, err);
5512}
Emeric Brun2b58d042012-09-20 17:10:03 +02005513
Bertrand Jacquinff13c062016-11-13 16:37:11 +00005514/* parse the "ecdhe" bind keyword keyword */
Emmanuel Hocdet98263292016-12-29 18:26:15 +01005515static int ssl_bind_parse_ecdhe(char **args, int cur_arg, struct proxy *px, struct ssl_bind_conf *conf, char **err)
Emeric Brun2b58d042012-09-20 17:10:03 +02005516{
5517#if OPENSSL_VERSION_NUMBER < 0x0090800fL
5518 if (err)
5519 memprintf(err, "'%s' : library does not support elliptic curve Diffie-Hellman (too old)", args[cur_arg]);
5520 return ERR_ALERT | ERR_FATAL;
5521#elif defined(OPENSSL_NO_ECDH)
5522 if (err)
5523 memprintf(err, "'%s' : library does not support elliptic curve Diffie-Hellman (disabled via OPENSSL_NO_ECDH)", args[cur_arg]);
5524 return ERR_ALERT | ERR_FATAL;
5525#else
5526 if (!*args[cur_arg + 1]) {
5527 if (err)
5528 memprintf(err, "'%s' : missing named curve", args[cur_arg]);
5529 return ERR_ALERT | ERR_FATAL;
5530 }
5531
5532 conf->ecdhe = strdup(args[cur_arg + 1]);
Willy Tarreau79eeafa2012-09-14 07:53:05 +02005533
5534 return 0;
Emeric Brun2b58d042012-09-20 17:10:03 +02005535#endif
Willy Tarreau79eeafa2012-09-14 07:53:05 +02005536}
Emmanuel Hocdet98263292016-12-29 18:26:15 +01005537static int bind_parse_ecdhe(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
5538{
5539 return ssl_bind_parse_ecdhe(args, cur_arg, px, &conf->ssl_conf, err);
5540}
Willy Tarreau79eeafa2012-09-14 07:53:05 +02005541
Bertrand Jacquinff13c062016-11-13 16:37:11 +00005542/* parse the "crt-ignore-err" and "ca-ignore-err" bind keywords */
Emeric Brun81c00f02012-09-21 14:31:21 +02005543static int bind_parse_ignore_err(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
5544{
5545 int code;
5546 char *p = args[cur_arg + 1];
5547 unsigned long long *ignerr = &conf->crt_ignerr;
5548
5549 if (!*p) {
5550 if (err)
5551 memprintf(err, "'%s' : missing error IDs list", args[cur_arg]);
5552 return ERR_ALERT | ERR_FATAL;
5553 }
5554
5555 if (strcmp(args[cur_arg], "ca-ignore-err") == 0)
5556 ignerr = &conf->ca_ignerr;
5557
5558 if (strcmp(p, "all") == 0) {
5559 *ignerr = ~0ULL;
5560 return 0;
5561 }
5562
5563 while (p) {
5564 code = atoi(p);
5565 if ((code <= 0) || (code > 63)) {
5566 if (err)
5567 memprintf(err, "'%s' : ID '%d' out of range (1..63) in error IDs list '%s'",
5568 args[cur_arg], code, args[cur_arg + 1]);
5569 return ERR_ALERT | ERR_FATAL;
5570 }
5571 *ignerr |= 1ULL << code;
5572 p = strchr(p, ',');
5573 if (p)
5574 p++;
5575 }
5576
Emeric Brun2cb7ae52012-10-05 14:14:21 +02005577 return 0;
5578}
5579
5580/* parse the "force-sslv3" bind keyword */
Emmanuel Hocdet98263292016-12-29 18:26:15 +01005581static int ssl_bind_parse_force_sslv3(char **args, int cur_arg, struct proxy *px, struct ssl_bind_conf *conf, char **err)
Emeric Brun2cb7ae52012-10-05 14:14:21 +02005582{
5583 conf->ssl_options |= BC_SSL_O_USE_SSLV3;
5584 return 0;
5585}
Emmanuel Hocdet98263292016-12-29 18:26:15 +01005586static int bind_parse_force_sslv3(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
5587{
5588 return ssl_bind_parse_force_sslv3(args, cur_arg, px, &conf->ssl_conf, err);
5589}
Emeric Brun2cb7ae52012-10-05 14:14:21 +02005590
5591/* parse the "force-tlsv10" bind keyword */
Emmanuel Hocdet98263292016-12-29 18:26:15 +01005592static int ssl_bind_parse_force_tlsv10(char **args, int cur_arg, struct proxy *px, struct ssl_bind_conf *conf, char **err)
Emeric Brun2cb7ae52012-10-05 14:14:21 +02005593{
5594 conf->ssl_options |= BC_SSL_O_USE_TLSV10;
Emeric Brun2d0c4822012-10-02 13:45:20 +02005595 return 0;
5596}
Emmanuel Hocdet98263292016-12-29 18:26:15 +01005597static int bind_parse_force_tlsv10(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
5598{
5599 return ssl_bind_parse_force_tlsv10(args, cur_arg, px, &conf->ssl_conf, err);
5600}
Emeric Brun2d0c4822012-10-02 13:45:20 +02005601
Emeric Brun2cb7ae52012-10-05 14:14:21 +02005602/* parse the "force-tlsv11" bind keyword */
Emmanuel Hocdet98263292016-12-29 18:26:15 +01005603static int ssl_bind_parse_force_tlsv11(char **args, int cur_arg, struct proxy *px, struct ssl_bind_conf *conf, char **err)
Emeric Brun2cb7ae52012-10-05 14:14:21 +02005604{
5605#if SSL_OP_NO_TLSv1_1
5606 conf->ssl_options |= BC_SSL_O_USE_TLSV11;
5607 return 0;
5608#else
5609 if (err)
5610 memprintf(err, "'%s' : library does not support protocol TLSv1.1", args[cur_arg]);
5611 return ERR_ALERT | ERR_FATAL;
5612#endif
5613}
Emmanuel Hocdet98263292016-12-29 18:26:15 +01005614static int bind_parse_force_tlsv11(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
5615{
5616 return ssl_bind_parse_force_tlsv11(args, cur_arg, px, &conf->ssl_conf, err);
5617}
Emeric Brun2cb7ae52012-10-05 14:14:21 +02005618
5619/* parse the "force-tlsv12" bind keyword */
Emmanuel Hocdet98263292016-12-29 18:26:15 +01005620static int ssl_bind_parse_force_tlsv12(char **args, int cur_arg, struct proxy *px, struct ssl_bind_conf *conf, char **err)
Emeric Brun2cb7ae52012-10-05 14:14:21 +02005621{
5622#if SSL_OP_NO_TLSv1_2
5623 conf->ssl_options |= BC_SSL_O_USE_TLSV12;
5624 return 0;
5625#else
5626 if (err)
5627 memprintf(err, "'%s' : library does not support protocol TLSv1.2", args[cur_arg]);
5628 return ERR_ALERT | ERR_FATAL;
5629#endif
5630}
Emmanuel Hocdet98263292016-12-29 18:26:15 +01005631static int bind_parse_force_tlsv12(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
5632{
5633 return ssl_bind_parse_force_tlsv12(args, cur_arg, px, &conf->ssl_conf, err);
5634}
Emeric Brun2cb7ae52012-10-05 14:14:21 +02005635
Emeric Brun2d0c4822012-10-02 13:45:20 +02005636/* parse the "no-tls-tickets" bind keyword */
Emmanuel Hocdet98263292016-12-29 18:26:15 +01005637static int ssl_bind_parse_no_tls_tickets(char **args, int cur_arg, struct proxy *px, struct ssl_bind_conf *conf, char **err)
Emeric Brun2d0c4822012-10-02 13:45:20 +02005638{
Emeric Brun89675492012-10-05 13:48:26 +02005639 conf->ssl_options |= BC_SSL_O_NO_TLS_TICKETS;
Emeric Brun81c00f02012-09-21 14:31:21 +02005640 return 0;
5641}
Emmanuel Hocdet98263292016-12-29 18:26:15 +01005642static int bind_parse_no_tls_tickets(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
5643{
5644 return ssl_bind_parse_no_tls_tickets(args, cur_arg, px, &conf->ssl_conf, err);
5645}
Emeric Brun2d0c4822012-10-02 13:45:20 +02005646
Emeric Brun9b3009b2012-10-05 11:55:06 +02005647/* parse the "no-sslv3" bind keyword */
Emmanuel Hocdet98263292016-12-29 18:26:15 +01005648static int ssl_bind_parse_no_sslv3(char **args, int cur_arg, struct proxy *px, struct ssl_bind_conf *conf, char **err)
Willy Tarreau79eeafa2012-09-14 07:53:05 +02005649{
Emeric Brun89675492012-10-05 13:48:26 +02005650 conf->ssl_options |= BC_SSL_O_NO_SSLV3;
Willy Tarreau79eeafa2012-09-14 07:53:05 +02005651 return 0;
5652}
Emmanuel Hocdet98263292016-12-29 18:26:15 +01005653static int bind_parse_no_sslv3(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
5654{
5655 return ssl_bind_parse_no_sslv3(args, cur_arg, px, &conf->ssl_conf, err);
5656}
Willy Tarreau79eeafa2012-09-14 07:53:05 +02005657
Emeric Brun9b3009b2012-10-05 11:55:06 +02005658/* parse the "no-tlsv10" bind keyword */
Emmanuel Hocdet98263292016-12-29 18:26:15 +01005659static int ssl_bind_parse_no_tlsv10(char **args, int cur_arg, struct proxy *px, struct ssl_bind_conf *conf, char **err)
Emeric Brunc0ff4922012-09-28 19:37:02 +02005660{
Emeric Brun89675492012-10-05 13:48:26 +02005661 conf->ssl_options |= BC_SSL_O_NO_TLSV10;
Emeric Brunc0ff4922012-09-28 19:37:02 +02005662 return 0;
5663}
Emmanuel Hocdet98263292016-12-29 18:26:15 +01005664static int bind_parse_no_tlsv10(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
5665{
5666 return ssl_bind_parse_no_tlsv10(args, cur_arg, px, &conf->ssl_conf, err);
5667}
Emeric Brunc0ff4922012-09-28 19:37:02 +02005668
Emeric Brun9b3009b2012-10-05 11:55:06 +02005669/* parse the "no-tlsv11" bind keyword */
Emmanuel Hocdet98263292016-12-29 18:26:15 +01005670static int ssl_bind_parse_no_tlsv11(char **args, int cur_arg, struct proxy *px, struct ssl_bind_conf *conf, char **err)
Emeric Brunc0ff4922012-09-28 19:37:02 +02005671{
Emeric Brun89675492012-10-05 13:48:26 +02005672 conf->ssl_options |= BC_SSL_O_NO_TLSV11;
Emeric Brunc0ff4922012-09-28 19:37:02 +02005673 return 0;
5674}
Emmanuel Hocdet98263292016-12-29 18:26:15 +01005675static int bind_parse_no_tlsv11(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
5676{
5677 return ssl_bind_parse_no_tlsv11(args, cur_arg, px, &conf->ssl_conf, err);
5678}
Emeric Brunc0ff4922012-09-28 19:37:02 +02005679
Emeric Brun9b3009b2012-10-05 11:55:06 +02005680/* parse the "no-tlsv12" bind keyword */
Emmanuel Hocdet98263292016-12-29 18:26:15 +01005681static int ssl_bind_parse_no_tlsv12(char **args, int cur_arg, struct proxy *px, struct ssl_bind_conf *conf, char **err)
Willy Tarreau79eeafa2012-09-14 07:53:05 +02005682{
Emeric Brun89675492012-10-05 13:48:26 +02005683 conf->ssl_options |= BC_SSL_O_NO_TLSV12;
Willy Tarreau79eeafa2012-09-14 07:53:05 +02005684 return 0;
5685}
Emmanuel Hocdet98263292016-12-29 18:26:15 +01005686static int bind_parse_no_tlsv12(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
5687{
5688 return ssl_bind_parse_no_tlsv12(args, cur_arg, px, &conf->ssl_conf, err);
5689}
Willy Tarreau79eeafa2012-09-14 07:53:05 +02005690
Willy Tarreau6c9a3d52012-10-18 18:57:14 +02005691/* parse the "npn" bind keyword */
Emmanuel Hocdet98263292016-12-29 18:26:15 +01005692static int ssl_bind_parse_npn(char **args, int cur_arg, struct proxy *px, struct ssl_bind_conf *conf, char **err)
Willy Tarreau6c9a3d52012-10-18 18:57:14 +02005693{
5694#ifdef OPENSSL_NPN_NEGOTIATED
5695 char *p1, *p2;
5696
5697 if (!*args[cur_arg + 1]) {
5698 memprintf(err, "'%s' : missing the comma-delimited NPN protocol suite", args[cur_arg]);
5699 return ERR_ALERT | ERR_FATAL;
5700 }
5701
5702 free(conf->npn_str);
5703
Willy Tarreau3724da12016-02-12 17:11:12 +01005704 /* the NPN string is built as a suite of (<len> <name>)*,
5705 * so we reuse each comma to store the next <len> and need
5706 * one more for the end of the string.
5707 */
Willy Tarreau6c9a3d52012-10-18 18:57:14 +02005708 conf->npn_len = strlen(args[cur_arg + 1]) + 1;
Willy Tarreau3724da12016-02-12 17:11:12 +01005709 conf->npn_str = calloc(1, conf->npn_len + 1);
Willy Tarreau6c9a3d52012-10-18 18:57:14 +02005710 memcpy(conf->npn_str + 1, args[cur_arg + 1], conf->npn_len);
5711
5712 /* replace commas with the name length */
5713 p1 = conf->npn_str;
5714 p2 = p1 + 1;
5715 while (1) {
5716 p2 = memchr(p1 + 1, ',', conf->npn_str + conf->npn_len - (p1 + 1));
5717 if (!p2)
5718 p2 = p1 + 1 + strlen(p1 + 1);
5719
5720 if (p2 - (p1 + 1) > 255) {
5721 *p2 = '\0';
5722 memprintf(err, "'%s' : NPN protocol name too long : '%s'", args[cur_arg], p1 + 1);
5723 return ERR_ALERT | ERR_FATAL;
5724 }
5725
5726 *p1 = p2 - (p1 + 1);
5727 p1 = p2;
5728
5729 if (!*p2)
5730 break;
5731
5732 *(p2++) = '\0';
5733 }
5734 return 0;
5735#else
5736 if (err)
5737 memprintf(err, "'%s' : library does not support TLS NPN extension", args[cur_arg]);
5738 return ERR_ALERT | ERR_FATAL;
5739#endif
5740}
5741
Emmanuel Hocdet98263292016-12-29 18:26:15 +01005742static int bind_parse_npn(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
5743{
5744 return ssl_bind_parse_npn(args, cur_arg, px, &conf->ssl_conf, err);
5745}
5746
Willy Tarreauab861d32013-04-02 02:30:41 +02005747/* parse the "alpn" bind keyword */
Emmanuel Hocdet98263292016-12-29 18:26:15 +01005748static int ssl_bind_parse_alpn(char **args, int cur_arg, struct proxy *px, struct ssl_bind_conf *conf, char **err)
Willy Tarreauab861d32013-04-02 02:30:41 +02005749{
Dirkjan Bussink48f1c4e2014-02-13 12:29:42 +01005750#ifdef TLSEXT_TYPE_application_layer_protocol_negotiation
Willy Tarreauab861d32013-04-02 02:30:41 +02005751 char *p1, *p2;
5752
5753 if (!*args[cur_arg + 1]) {
5754 memprintf(err, "'%s' : missing the comma-delimited ALPN protocol suite", args[cur_arg]);
5755 return ERR_ALERT | ERR_FATAL;
5756 }
5757
5758 free(conf->alpn_str);
5759
Marcoen Hirschbergbef60912016-02-12 17:05:24 +01005760 /* the ALPN string is built as a suite of (<len> <name>)*,
5761 * so we reuse each comma to store the next <len> and need
5762 * one more for the end of the string.
5763 */
Willy Tarreauab861d32013-04-02 02:30:41 +02005764 conf->alpn_len = strlen(args[cur_arg + 1]) + 1;
Marcoen Hirschbergbef60912016-02-12 17:05:24 +01005765 conf->alpn_str = calloc(1, conf->alpn_len + 1);
Willy Tarreauab861d32013-04-02 02:30:41 +02005766 memcpy(conf->alpn_str + 1, args[cur_arg + 1], conf->alpn_len);
5767
5768 /* replace commas with the name length */
5769 p1 = conf->alpn_str;
5770 p2 = p1 + 1;
5771 while (1) {
5772 p2 = memchr(p1 + 1, ',', conf->alpn_str + conf->alpn_len - (p1 + 1));
5773 if (!p2)
5774 p2 = p1 + 1 + strlen(p1 + 1);
5775
5776 if (p2 - (p1 + 1) > 255) {
5777 *p2 = '\0';
5778 memprintf(err, "'%s' : ALPN protocol name too long : '%s'", args[cur_arg], p1 + 1);
5779 return ERR_ALERT | ERR_FATAL;
5780 }
5781
5782 *p1 = p2 - (p1 + 1);
5783 p1 = p2;
5784
5785 if (!*p2)
5786 break;
5787
5788 *(p2++) = '\0';
5789 }
5790 return 0;
5791#else
5792 if (err)
5793 memprintf(err, "'%s' : library does not support TLS ALPN extension", args[cur_arg]);
5794 return ERR_ALERT | ERR_FATAL;
5795#endif
5796}
5797
Emmanuel Hocdet98263292016-12-29 18:26:15 +01005798static int bind_parse_alpn(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
5799{
5800 return ssl_bind_parse_alpn(args, cur_arg, px, &conf->ssl_conf, err);
5801}
5802
Willy Tarreau79eeafa2012-09-14 07:53:05 +02005803/* parse the "ssl" bind keyword */
Willy Tarreau4348fad2012-09-20 16:48:07 +02005804static 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 +02005805{
Willy Tarreau71a8c7c2016-12-21 22:04:54 +01005806 conf->xprt = &ssl_sock;
Willy Tarreau4348fad2012-09-20 16:48:07 +02005807 conf->is_ssl = 1;
Emeric Brun76d88952012-10-05 15:47:31 +02005808
Emmanuel Hocdet98263292016-12-29 18:26:15 +01005809 if (global_ssl.listen_default_ciphers && !conf->ssl_conf.ciphers)
5810 conf->ssl_conf.ciphers = strdup(global_ssl.listen_default_ciphers);
5811 conf->ssl_conf.ssl_options |= global_ssl.listen_default_ssloptions;
Emeric Brun76d88952012-10-05 15:47:31 +02005812
Willy Tarreau79eeafa2012-09-14 07:53:05 +02005813 return 0;
5814}
5815
Christopher Faulet31af49d2015-06-09 17:29:50 +02005816/* parse the "generate-certificates" bind keyword */
5817static int bind_parse_generate_certs(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
5818{
5819#ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME
5820 conf->generate_certs = 1;
5821#else
5822 memprintf(err, "%sthis version of openssl cannot generate SSL certificates.\n",
5823 err && *err ? *err : "");
5824#endif
5825 return 0;
5826}
5827
Emmanuel Hocdet65623372013-01-24 17:17:15 +01005828/* parse the "strict-sni" bind keyword */
5829static int bind_parse_strict_sni(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
5830{
5831 conf->strict_sni = 1;
5832 return 0;
Nenad Merdanovic05552d42015-02-27 19:56:49 +01005833}
5834
5835/* parse the "tls-ticket-keys" bind keyword */
5836static int bind_parse_tls_ticket_keys(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
5837{
5838#if (defined SSL_CTRL_SET_TLSEXT_TICKET_KEY_CB && TLS_TICKETS_NO > 0)
5839 FILE *f;
5840 int i = 0;
5841 char thisline[LINESIZE];
Nenad Merdanovic146defa2015-05-09 08:46:00 +02005842 struct tls_keys_ref *keys_ref;
Nenad Merdanovic05552d42015-02-27 19:56:49 +01005843
5844 if (!*args[cur_arg + 1]) {
5845 if (err)
5846 memprintf(err, "'%s' : missing TLS ticket keys file path", args[cur_arg]);
5847 return ERR_ALERT | ERR_FATAL;
5848 }
5849
Nenad Merdanovic200b0fa2015-05-09 08:46:01 +02005850 keys_ref = tlskeys_ref_lookup(args[cur_arg + 1]);
5851 if(keys_ref) {
5852 conf->keys_ref = keys_ref;
5853 return 0;
5854 }
5855
Vincent Bernat02779b62016-04-03 13:48:43 +02005856 keys_ref = malloc(sizeof(*keys_ref));
Nenad Merdanovic146defa2015-05-09 08:46:00 +02005857 keys_ref->tlskeys = malloc(TLS_TICKETS_NO * sizeof(struct tls_sess_key));
Nenad Merdanovic05552d42015-02-27 19:56:49 +01005858
5859 if ((f = fopen(args[cur_arg + 1], "r")) == NULL) {
5860 if (err)
5861 memprintf(err, "'%s' : unable to load ssl tickets keys file", args[cur_arg+1]);
5862 return ERR_ALERT | ERR_FATAL;
5863 }
5864
Nenad Merdanovic146defa2015-05-09 08:46:00 +02005865 keys_ref->filename = strdup(args[cur_arg + 1]);
5866
Nenad Merdanovic05552d42015-02-27 19:56:49 +01005867 while (fgets(thisline, sizeof(thisline), f) != NULL) {
5868 int len = strlen(thisline);
5869 /* Strip newline characters from the end */
5870 if(thisline[len - 1] == '\n')
5871 thisline[--len] = 0;
5872
5873 if(thisline[len - 1] == '\r')
5874 thisline[--len] = 0;
5875
Nenad Merdanovic146defa2015-05-09 08:46:00 +02005876 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 +01005877 if (err)
5878 memprintf(err, "'%s' : unable to decode base64 key on line %d", args[cur_arg+1], i + 1);
mildis16aa0152016-06-22 17:46:29 +02005879 fclose(f);
Nenad Merdanovic05552d42015-02-27 19:56:49 +01005880 return ERR_ALERT | ERR_FATAL;
5881 }
5882 i++;
5883 }
5884
5885 if (i < TLS_TICKETS_NO) {
5886 if (err)
5887 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 +02005888 fclose(f);
Nenad Merdanovic05552d42015-02-27 19:56:49 +01005889 return ERR_ALERT | ERR_FATAL;
5890 }
5891
5892 fclose(f);
5893
5894 /* Use penultimate key for encryption, handle when TLS_TICKETS_NO = 1 */
Nenad Merdanovic17891152016-03-25 22:16:57 +01005895 i -= 2;
5896 keys_ref->tls_ticket_enc_index = i < 0 ? 0 : i % TLS_TICKETS_NO;
Nenad Merdanovic200b0fa2015-05-09 08:46:01 +02005897 keys_ref->unique_id = -1;
Nenad Merdanovic146defa2015-05-09 08:46:00 +02005898 conf->keys_ref = keys_ref;
Nenad Merdanovic05552d42015-02-27 19:56:49 +01005899
Nenad Merdanovic200b0fa2015-05-09 08:46:01 +02005900 LIST_ADD(&tlskeys_reference, &keys_ref->list);
5901
Nenad Merdanovic05552d42015-02-27 19:56:49 +01005902 return 0;
5903#else
5904 if (err)
5905 memprintf(err, "'%s' : TLS ticket callback extension not supported", args[cur_arg]);
5906 return ERR_ALERT | ERR_FATAL;
5907#endif /* SSL_CTRL_SET_TLSEXT_TICKET_KEY_CB */
Emmanuel Hocdet65623372013-01-24 17:17:15 +01005908}
5909
Emeric Brund94b3fe2012-09-20 18:23:56 +02005910/* parse the "verify" bind keyword */
Emmanuel Hocdet98263292016-12-29 18:26:15 +01005911static int ssl_bind_parse_verify(char **args, int cur_arg, struct proxy *px, struct ssl_bind_conf *conf, char **err)
Emeric Brund94b3fe2012-09-20 18:23:56 +02005912{
5913 if (!*args[cur_arg + 1]) {
5914 if (err)
5915 memprintf(err, "'%s' : missing verify method", args[cur_arg]);
5916 return ERR_ALERT | ERR_FATAL;
5917 }
5918
5919 if (strcmp(args[cur_arg + 1], "none") == 0)
Emeric Brun850efd52014-01-29 12:24:34 +01005920 conf->verify = SSL_SOCK_VERIFY_NONE;
Emeric Brund94b3fe2012-09-20 18:23:56 +02005921 else if (strcmp(args[cur_arg + 1], "optional") == 0)
Emeric Brun850efd52014-01-29 12:24:34 +01005922 conf->verify = SSL_SOCK_VERIFY_OPTIONAL;
Emeric Brund94b3fe2012-09-20 18:23:56 +02005923 else if (strcmp(args[cur_arg + 1], "required") == 0)
Emeric Brun850efd52014-01-29 12:24:34 +01005924 conf->verify = SSL_SOCK_VERIFY_REQUIRED;
Emeric Brund94b3fe2012-09-20 18:23:56 +02005925 else {
5926 if (err)
5927 memprintf(err, "'%s' : unknown verify method '%s', only 'none', 'optional', and 'required' are supported\n",
5928 args[cur_arg], args[cur_arg + 1]);
5929 return ERR_ALERT | ERR_FATAL;
5930 }
5931
5932 return 0;
5933}
Emmanuel Hocdet98263292016-12-29 18:26:15 +01005934static int bind_parse_verify(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
5935{
5936 return ssl_bind_parse_verify(args, cur_arg, px, &conf->ssl_conf, err);
5937}
Emeric Brund94b3fe2012-09-20 18:23:56 +02005938
Willy Tarreau92faadf2012-10-10 23:04:25 +02005939/************** "server" keywords ****************/
5940
Emeric Brunef42d922012-10-11 16:11:36 +02005941/* parse the "ca-file" server keyword */
5942static int srv_parse_ca_file(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
5943{
5944 if (!*args[*cur_arg + 1]) {
5945 if (err)
5946 memprintf(err, "'%s' : missing CAfile path", args[*cur_arg]);
5947 return ERR_ALERT | ERR_FATAL;
5948 }
5949
Willy Tarreauef934602016-12-22 23:12:01 +01005950 if ((*args[*cur_arg + 1] != '/') && global_ssl.ca_base)
5951 memprintf(&newsrv->ssl_ctx.ca_file, "%s/%s", global_ssl.ca_base, args[*cur_arg + 1]);
Emeric Brunef42d922012-10-11 16:11:36 +02005952 else
5953 memprintf(&newsrv->ssl_ctx.ca_file, "%s", args[*cur_arg + 1]);
5954
5955 return 0;
5956}
5957
Willy Tarreau92faadf2012-10-10 23:04:25 +02005958/* parse the "check-ssl" server keyword */
5959static int srv_parse_check_ssl(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
5960{
5961 newsrv->check.use_ssl = 1;
Willy Tarreauef934602016-12-22 23:12:01 +01005962 if (global_ssl.connect_default_ciphers && !newsrv->ssl_ctx.ciphers)
5963 newsrv->ssl_ctx.ciphers = strdup(global_ssl.connect_default_ciphers);
5964 newsrv->ssl_ctx.options |= global_ssl.connect_default_ssloptions;
Willy Tarreau92faadf2012-10-10 23:04:25 +02005965 return 0;
5966}
5967
5968/* parse the "ciphers" server keyword */
5969static int srv_parse_ciphers(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
5970{
5971 if (!*args[*cur_arg + 1]) {
5972 memprintf(err, "'%s' : missing cipher suite", args[*cur_arg]);
5973 return ERR_ALERT | ERR_FATAL;
5974 }
5975
5976 free(newsrv->ssl_ctx.ciphers);
5977 newsrv->ssl_ctx.ciphers = strdup(args[*cur_arg + 1]);
5978 return 0;
5979}
5980
Emeric Brunef42d922012-10-11 16:11:36 +02005981/* parse the "crl-file" server keyword */
5982static int srv_parse_crl_file(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
5983{
5984#ifndef X509_V_FLAG_CRL_CHECK
5985 if (err)
5986 memprintf(err, "'%s' : library does not support CRL verify", args[*cur_arg]);
5987 return ERR_ALERT | ERR_FATAL;
5988#else
5989 if (!*args[*cur_arg + 1]) {
5990 if (err)
5991 memprintf(err, "'%s' : missing CRLfile path", args[*cur_arg]);
5992 return ERR_ALERT | ERR_FATAL;
5993 }
5994
Willy Tarreauef934602016-12-22 23:12:01 +01005995 if ((*args[*cur_arg + 1] != '/') && global_ssl.ca_base)
5996 memprintf(&newsrv->ssl_ctx.crl_file, "%s/%s", global_ssl.ca_base, args[*cur_arg + 1]);
Emeric Brunef42d922012-10-11 16:11:36 +02005997 else
5998 memprintf(&newsrv->ssl_ctx.crl_file, "%s", args[*cur_arg + 1]);
5999
6000 return 0;
6001#endif
6002}
6003
Emeric Bruna7aa3092012-10-26 12:58:00 +02006004/* parse the "crt" server keyword */
6005static int srv_parse_crt(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
6006{
6007 if (!*args[*cur_arg + 1]) {
6008 if (err)
6009 memprintf(err, "'%s' : missing certificate file path", args[*cur_arg]);
6010 return ERR_ALERT | ERR_FATAL;
6011 }
6012
Willy Tarreauef934602016-12-22 23:12:01 +01006013 if ((*args[*cur_arg + 1] != '/') && global_ssl.crt_base)
6014 memprintf(&newsrv->ssl_ctx.client_crt, "%s/%s", global_ssl.ca_base, args[*cur_arg + 1]);
Emeric Bruna7aa3092012-10-26 12:58:00 +02006015 else
6016 memprintf(&newsrv->ssl_ctx.client_crt, "%s", args[*cur_arg + 1]);
6017
6018 return 0;
6019}
Emeric Brunef42d922012-10-11 16:11:36 +02006020
Willy Tarreau92faadf2012-10-10 23:04:25 +02006021/* parse the "force-sslv3" server keyword */
6022static int srv_parse_force_sslv3(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
6023{
6024 newsrv->ssl_ctx.options |= SRV_SSL_O_USE_SSLV3;
6025 return 0;
6026}
6027
6028/* parse the "force-tlsv10" server keyword */
6029static int srv_parse_force_tlsv10(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
6030{
6031 newsrv->ssl_ctx.options |= SRV_SSL_O_USE_TLSV10;
6032 return 0;
6033}
6034
6035/* parse the "force-tlsv11" server keyword */
6036static int srv_parse_force_tlsv11(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
6037{
6038#if SSL_OP_NO_TLSv1_1
6039 newsrv->ssl_ctx.options |= SRV_SSL_O_USE_TLSV11;
6040 return 0;
6041#else
6042 if (err)
6043 memprintf(err, "'%s' : library does not support protocol TLSv1.1", args[*cur_arg]);
6044 return ERR_ALERT | ERR_FATAL;
6045#endif
6046}
6047
6048/* parse the "force-tlsv12" server keyword */
6049static int srv_parse_force_tlsv12(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
6050{
6051#if SSL_OP_NO_TLSv1_2
6052 newsrv->ssl_ctx.options |= SRV_SSL_O_USE_TLSV12;
6053 return 0;
6054#else
6055 if (err)
6056 memprintf(err, "'%s' : library does not support protocol TLSv1.2", args[*cur_arg]);
6057 return ERR_ALERT | ERR_FATAL;
6058#endif
6059}
6060
Willy Tarreau2a3fb1c2015-02-05 16:47:07 +01006061/* parse the "no-ssl-reuse" server keyword */
6062static int srv_parse_no_ssl_reuse(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
6063{
6064 newsrv->ssl_ctx.options |= SRV_SSL_O_NO_REUSE;
6065 return 0;
6066}
6067
Willy Tarreau92faadf2012-10-10 23:04:25 +02006068/* parse the "no-sslv3" server keyword */
6069static int srv_parse_no_sslv3(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
6070{
6071 newsrv->ssl_ctx.options |= SRV_SSL_O_NO_SSLV3;
6072 return 0;
6073}
6074
6075/* parse the "no-tlsv10" server keyword */
6076static int srv_parse_no_tlsv10(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
6077{
6078 newsrv->ssl_ctx.options |= SRV_SSL_O_NO_TLSV10;
6079 return 0;
6080}
6081
6082/* parse the "no-tlsv11" server keyword */
6083static int srv_parse_no_tlsv11(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
6084{
6085 newsrv->ssl_ctx.options |= SRV_SSL_O_NO_TLSV11;
6086 return 0;
6087}
6088
6089/* parse the "no-tlsv12" server keyword */
6090static int srv_parse_no_tlsv12(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
6091{
6092 newsrv->ssl_ctx.options |= SRV_SSL_O_NO_TLSV12;
6093 return 0;
6094}
6095
Emeric Brunf9c5c472012-10-11 15:28:34 +02006096/* parse the "no-tls-tickets" server keyword */
6097static int srv_parse_no_tls_tickets(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
6098{
6099 newsrv->ssl_ctx.options |= SRV_SSL_O_NO_TLS_TICKETS;
6100 return 0;
6101}
David Safb76832014-05-08 23:42:08 -04006102/* parse the "send-proxy-v2-ssl" server keyword */
6103static int srv_parse_send_proxy_ssl(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
6104{
6105 newsrv->pp_opts |= SRV_PP_V2;
6106 newsrv->pp_opts |= SRV_PP_V2_SSL;
6107 return 0;
6108}
6109
6110/* parse the "send-proxy-v2-ssl-cn" server keyword */
6111static int srv_parse_send_proxy_cn(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
6112{
6113 newsrv->pp_opts |= SRV_PP_V2;
6114 newsrv->pp_opts |= SRV_PP_V2_SSL;
6115 newsrv->pp_opts |= SRV_PP_V2_SSL_CN;
6116 return 0;
6117}
Emeric Brunf9c5c472012-10-11 15:28:34 +02006118
Willy Tarreau732eac42015-07-09 11:40:25 +02006119/* parse the "sni" server keyword */
6120static int srv_parse_sni(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
6121{
6122#ifndef SSL_CTRL_SET_TLSEXT_HOSTNAME
6123 memprintf(err, "'%s' : the current SSL library doesn't support the SNI TLS extension", args[*cur_arg]);
6124 return ERR_ALERT | ERR_FATAL;
6125#else
Cyril Bonté23d19d62016-03-07 22:13:22 +01006126 int idx;
Willy Tarreau732eac42015-07-09 11:40:25 +02006127 struct sample_expr *expr;
6128
6129 if (!*args[*cur_arg + 1]) {
6130 memprintf(err, "'%s' : missing sni expression", args[*cur_arg]);
6131 return ERR_ALERT | ERR_FATAL;
6132 }
6133
Cyril Bonté23d19d62016-03-07 22:13:22 +01006134 idx = (*cur_arg) + 1;
Willy Tarreau732eac42015-07-09 11:40:25 +02006135 proxy->conf.args.ctx = ARGC_SRV;
6136
Cyril Bonté23d19d62016-03-07 22:13:22 +01006137 expr = sample_parse_expr((char **)args, &idx, px->conf.file, px->conf.line, err, &proxy->conf.args);
Willy Tarreau732eac42015-07-09 11:40:25 +02006138 if (!expr) {
6139 memprintf(err, "error detected while parsing sni expression : %s", *err);
6140 return ERR_ALERT | ERR_FATAL;
6141 }
6142
6143 if (!(expr->fetch->val & SMP_VAL_BE_SRV_CON)) {
6144 memprintf(err, "error detected while parsing sni expression : "
6145 " fetch method '%s' extracts information from '%s', none of which is available here.\n",
Cyril Bonté23d19d62016-03-07 22:13:22 +01006146 args[idx-1], sample_src_names(expr->fetch->use));
Willy Tarreau732eac42015-07-09 11:40:25 +02006147 return ERR_ALERT | ERR_FATAL;
6148 }
6149
6150 px->http_needed |= !!(expr->fetch->use & SMP_USE_HTTP_ANY);
6151 newsrv->ssl_ctx.sni = expr;
6152 return 0;
6153#endif
6154}
6155
Willy Tarreau92faadf2012-10-10 23:04:25 +02006156/* parse the "ssl" server keyword */
6157static int srv_parse_ssl(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
6158{
6159 newsrv->use_ssl = 1;
Willy Tarreauef934602016-12-22 23:12:01 +01006160 if (global_ssl.connect_default_ciphers && !newsrv->ssl_ctx.ciphers)
6161 newsrv->ssl_ctx.ciphers = strdup(global_ssl.connect_default_ciphers);
Willy Tarreau92faadf2012-10-10 23:04:25 +02006162 return 0;
6163}
6164
Emeric Brunef42d922012-10-11 16:11:36 +02006165/* parse the "verify" server keyword */
6166static int srv_parse_verify(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
6167{
6168 if (!*args[*cur_arg + 1]) {
6169 if (err)
6170 memprintf(err, "'%s' : missing verify method", args[*cur_arg]);
6171 return ERR_ALERT | ERR_FATAL;
6172 }
6173
6174 if (strcmp(args[*cur_arg + 1], "none") == 0)
Emeric Brun850efd52014-01-29 12:24:34 +01006175 newsrv->ssl_ctx.verify = SSL_SOCK_VERIFY_NONE;
Emeric Brunef42d922012-10-11 16:11:36 +02006176 else if (strcmp(args[*cur_arg + 1], "required") == 0)
Emeric Brun850efd52014-01-29 12:24:34 +01006177 newsrv->ssl_ctx.verify = SSL_SOCK_VERIFY_REQUIRED;
Emeric Brunef42d922012-10-11 16:11:36 +02006178 else {
6179 if (err)
6180 memprintf(err, "'%s' : unknown verify method '%s', only 'none' and 'required' are supported\n",
6181 args[*cur_arg], args[*cur_arg + 1]);
6182 return ERR_ALERT | ERR_FATAL;
6183 }
6184
Evan Broderbe554312013-06-27 00:05:25 -07006185 return 0;
6186}
6187
6188/* parse the "verifyhost" server keyword */
6189static int srv_parse_verifyhost(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
6190{
6191 if (!*args[*cur_arg + 1]) {
6192 if (err)
6193 memprintf(err, "'%s' : missing hostname to verify against", args[*cur_arg]);
6194 return ERR_ALERT | ERR_FATAL;
6195 }
6196
6197 newsrv->ssl_ctx.verify_host = strdup(args[*cur_arg + 1]);
6198
Emeric Brunef42d922012-10-11 16:11:36 +02006199 return 0;
6200}
6201
Emeric Brun2c86cbf2014-10-30 15:56:50 +01006202/* parse the "ssl-default-bind-options" keyword in global section */
6203static int ssl_parse_default_bind_options(char **args, int section_type, struct proxy *curpx,
6204 struct proxy *defpx, const char *file, int line,
6205 char **err) {
6206 int i = 1;
6207
6208 if (*(args[i]) == 0) {
6209 memprintf(err, "global statement '%s' expects an option as an argument.", args[0]);
6210 return -1;
6211 }
6212 while (*(args[i])) {
6213 if (!strcmp(args[i], "no-sslv3"))
Willy Tarreauef934602016-12-22 23:12:01 +01006214 global_ssl.listen_default_ssloptions |= BC_SSL_O_NO_SSLV3;
Emeric Brun2c86cbf2014-10-30 15:56:50 +01006215 else if (!strcmp(args[i], "no-tlsv10"))
Willy Tarreauef934602016-12-22 23:12:01 +01006216 global_ssl.listen_default_ssloptions |= BC_SSL_O_NO_TLSV10;
Emeric Brun2c86cbf2014-10-30 15:56:50 +01006217 else if (!strcmp(args[i], "no-tlsv11"))
Willy Tarreauef934602016-12-22 23:12:01 +01006218 global_ssl.listen_default_ssloptions |= BC_SSL_O_NO_TLSV11;
Emeric Brun2c86cbf2014-10-30 15:56:50 +01006219 else if (!strcmp(args[i], "no-tlsv12"))
Willy Tarreauef934602016-12-22 23:12:01 +01006220 global_ssl.listen_default_ssloptions |= BC_SSL_O_NO_TLSV12;
Emeric Brun2c86cbf2014-10-30 15:56:50 +01006221 else if (!strcmp(args[i], "force-sslv3"))
Willy Tarreauef934602016-12-22 23:12:01 +01006222 global_ssl.listen_default_ssloptions |= BC_SSL_O_USE_SSLV3;
Emeric Brun2c86cbf2014-10-30 15:56:50 +01006223 else if (!strcmp(args[i], "force-tlsv10"))
Willy Tarreauef934602016-12-22 23:12:01 +01006224 global_ssl.listen_default_ssloptions |= BC_SSL_O_USE_TLSV10;
Emeric Brun2c86cbf2014-10-30 15:56:50 +01006225 else if (!strcmp(args[i], "force-tlsv11")) {
6226#if SSL_OP_NO_TLSv1_1
Willy Tarreauef934602016-12-22 23:12:01 +01006227 global_ssl.listen_default_ssloptions |= BC_SSL_O_USE_TLSV11;
Emeric Brun2c86cbf2014-10-30 15:56:50 +01006228#else
6229 memprintf(err, "'%s' '%s': library does not support protocol TLSv1.1", args[0], args[i]);
6230 return -1;
6231#endif
6232 }
6233 else if (!strcmp(args[i], "force-tlsv12")) {
6234#if SSL_OP_NO_TLSv1_2
Willy Tarreauef934602016-12-22 23:12:01 +01006235 global_ssl.listen_default_ssloptions |= BC_SSL_O_USE_TLSV12;
Emeric Brun2c86cbf2014-10-30 15:56:50 +01006236#else
6237 memprintf(err, "'%s' '%s': library does not support protocol TLSv1.2", args[0], args[i]);
6238 return -1;
6239#endif
6240 }
6241 else if (!strcmp(args[i], "no-tls-tickets"))
Willy Tarreauef934602016-12-22 23:12:01 +01006242 global_ssl.listen_default_ssloptions |= BC_SSL_O_NO_TLS_TICKETS;
Emeric Brun2c86cbf2014-10-30 15:56:50 +01006243 else {
6244 memprintf(err, "unknown option '%s' on global statement '%s'.", args[i], args[0]);
6245 return -1;
6246 }
6247 i++;
6248 }
6249 return 0;
6250}
6251
6252/* parse the "ssl-default-server-options" keyword in global section */
6253static int ssl_parse_default_server_options(char **args, int section_type, struct proxy *curpx,
6254 struct proxy *defpx, const char *file, int line,
6255 char **err) {
6256 int i = 1;
6257
6258 if (*(args[i]) == 0) {
6259 memprintf(err, "global statement '%s' expects an option as an argument.", args[0]);
6260 return -1;
6261 }
6262 while (*(args[i])) {
6263 if (!strcmp(args[i], "no-sslv3"))
Willy Tarreauef934602016-12-22 23:12:01 +01006264 global_ssl.connect_default_ssloptions |= SRV_SSL_O_NO_SSLV3;
Emeric Brun2c86cbf2014-10-30 15:56:50 +01006265 else if (!strcmp(args[i], "no-tlsv10"))
Willy Tarreauef934602016-12-22 23:12:01 +01006266 global_ssl.connect_default_ssloptions |= SRV_SSL_O_NO_TLSV10;
Emeric Brun2c86cbf2014-10-30 15:56:50 +01006267 else if (!strcmp(args[i], "no-tlsv11"))
Willy Tarreauef934602016-12-22 23:12:01 +01006268 global_ssl.connect_default_ssloptions |= SRV_SSL_O_NO_TLSV11;
Emeric Brun2c86cbf2014-10-30 15:56:50 +01006269 else if (!strcmp(args[i], "no-tlsv12"))
Willy Tarreauef934602016-12-22 23:12:01 +01006270 global_ssl.connect_default_ssloptions |= SRV_SSL_O_NO_TLSV12;
Emeric Brun2c86cbf2014-10-30 15:56:50 +01006271 else if (!strcmp(args[i], "force-sslv3"))
Willy Tarreauef934602016-12-22 23:12:01 +01006272 global_ssl.connect_default_ssloptions |= SRV_SSL_O_USE_SSLV3;
Emeric Brun2c86cbf2014-10-30 15:56:50 +01006273 else if (!strcmp(args[i], "force-tlsv10"))
Willy Tarreauef934602016-12-22 23:12:01 +01006274 global_ssl.connect_default_ssloptions |= SRV_SSL_O_USE_TLSV10;
Emeric Brun2c86cbf2014-10-30 15:56:50 +01006275 else if (!strcmp(args[i], "force-tlsv11")) {
6276#if SSL_OP_NO_TLSv1_1
Willy Tarreauef934602016-12-22 23:12:01 +01006277 global_ssl.connect_default_ssloptions |= SRV_SSL_O_USE_TLSV11;
Emeric Brun2c86cbf2014-10-30 15:56:50 +01006278#else
6279 memprintf(err, "'%s' '%s': library does not support protocol TLSv1.1", args[0], args[i]);
6280 return -1;
6281#endif
6282 }
6283 else if (!strcmp(args[i], "force-tlsv12")) {
6284#if SSL_OP_NO_TLSv1_2
Willy Tarreauef934602016-12-22 23:12:01 +01006285 global_ssl.connect_default_ssloptions |= SRV_SSL_O_USE_TLSV12;
Emeric Brun2c86cbf2014-10-30 15:56:50 +01006286#else
6287 memprintf(err, "'%s' '%s': library does not support protocol TLSv1.2", args[0], args[i]);
6288 return -1;
6289#endif
6290 }
6291 else if (!strcmp(args[i], "no-tls-tickets"))
Willy Tarreauef934602016-12-22 23:12:01 +01006292 global_ssl.connect_default_ssloptions |= SRV_SSL_O_NO_TLS_TICKETS;
Emeric Brun2c86cbf2014-10-30 15:56:50 +01006293 else {
6294 memprintf(err, "unknown option '%s' on global statement '%s'.", args[i], args[0]);
6295 return -1;
6296 }
6297 i++;
6298 }
6299 return 0;
6300}
6301
Willy Tarreau8c3b0fd2016-12-21 22:44:46 +01006302/* parse the "ca-base" / "crt-base" keywords in global section.
6303 * Returns <0 on alert, >0 on warning, 0 on success.
6304 */
6305static int ssl_parse_global_ca_crt_base(char **args, int section_type, struct proxy *curpx,
6306 struct proxy *defpx, const char *file, int line,
6307 char **err)
6308{
6309 char **target;
6310
Willy Tarreauef934602016-12-22 23:12:01 +01006311 target = (args[0][1] == 'a') ? &global_ssl.ca_base : &global_ssl.crt_base;
Willy Tarreau8c3b0fd2016-12-21 22:44:46 +01006312
6313 if (too_many_args(1, args, err, NULL))
6314 return -1;
6315
6316 if (*target) {
6317 memprintf(err, "'%s' already specified.", args[0]);
6318 return -1;
6319 }
6320
6321 if (*(args[1]) == 0) {
6322 memprintf(err, "global statement '%s' expects a directory path as an argument.", args[0]);
6323 return -1;
6324 }
6325 *target = strdup(args[1]);
6326 return 0;
6327}
6328
Willy Tarreauf22e9682016-12-21 23:23:19 +01006329/* parse the "ssl-default-bind-ciphers" / "ssl-default-server-ciphers" keywords
6330 * in global section. Returns <0 on alert, >0 on warning, 0 on success.
6331 */
6332static int ssl_parse_global_ciphers(char **args, int section_type, struct proxy *curpx,
6333 struct proxy *defpx, const char *file, int line,
6334 char **err)
6335{
6336 char **target;
6337
Willy Tarreauef934602016-12-22 23:12:01 +01006338 target = (args[0][12] == 'b') ? &global_ssl.listen_default_ciphers : &global_ssl.connect_default_ciphers;
Willy Tarreauf22e9682016-12-21 23:23:19 +01006339
6340 if (too_many_args(1, args, err, NULL))
6341 return -1;
6342
6343 if (*(args[1]) == 0) {
6344 memprintf(err, "global statement '%s' expects a cipher suite as an argument.", args[0]);
6345 return -1;
6346 }
6347
6348 free(*target);
6349 *target = strdup(args[1]);
6350 return 0;
6351}
6352
Willy Tarreau9ceda382016-12-21 23:13:03 +01006353/* parse various global tune.ssl settings consisting in positive integers.
6354 * Returns <0 on alert, >0 on warning, 0 on success.
6355 */
6356static int ssl_parse_global_int(char **args, int section_type, struct proxy *curpx,
6357 struct proxy *defpx, const char *file, int line,
6358 char **err)
6359{
6360 int *target;
6361
6362 if (strcmp(args[0], "tune.ssl.cachesize") == 0)
6363 target = &global.tune.sslcachesize;
6364 else if (strcmp(args[0], "tune.ssl.maxrecord") == 0)
Willy Tarreauef934602016-12-22 23:12:01 +01006365 target = (int *)&global_ssl.max_record;
Willy Tarreau9ceda382016-12-21 23:13:03 +01006366 else if (strcmp(args[0], "tune.ssl.ssl-ctx-cache-size") == 0)
Willy Tarreauef934602016-12-22 23:12:01 +01006367 target = &global_ssl.ctx_cache;
Willy Tarreau0bea58d2016-12-21 23:17:25 +01006368 else if (strcmp(args[0], "maxsslconn") == 0)
6369 target = &global.maxsslconn;
Willy Tarreau9ceda382016-12-21 23:13:03 +01006370 else {
6371 memprintf(err, "'%s' keyword not unhandled (please report this bug).", args[0]);
6372 return -1;
6373 }
6374
6375 if (too_many_args(1, args, err, NULL))
6376 return -1;
6377
6378 if (*(args[1]) == 0) {
6379 memprintf(err, "'%s' expects an integer argument.", args[0]);
6380 return -1;
6381 }
6382
6383 *target = atoi(args[1]);
6384 if (*target < 0) {
6385 memprintf(err, "'%s' expects a positive numeric value.", args[0]);
6386 return -1;
6387 }
6388 return 0;
6389}
6390
6391/* parse "ssl.force-private-cache".
6392 * Returns <0 on alert, >0 on warning, 0 on success.
6393 */
6394static int ssl_parse_global_private_cache(char **args, int section_type, struct proxy *curpx,
6395 struct proxy *defpx, const char *file, int line,
6396 char **err)
6397{
6398 if (too_many_args(0, args, err, NULL))
6399 return -1;
6400
Willy Tarreauef934602016-12-22 23:12:01 +01006401 global_ssl.private_cache = 1;
Willy Tarreau9ceda382016-12-21 23:13:03 +01006402 return 0;
6403}
6404
6405/* parse "ssl.lifetime".
6406 * Returns <0 on alert, >0 on warning, 0 on success.
6407 */
6408static int ssl_parse_global_lifetime(char **args, int section_type, struct proxy *curpx,
6409 struct proxy *defpx, const char *file, int line,
6410 char **err)
6411{
6412 const char *res;
6413
6414 if (too_many_args(1, args, err, NULL))
6415 return -1;
6416
6417 if (*(args[1]) == 0) {
6418 memprintf(err, "'%s' expects ssl sessions <lifetime> in seconds as argument.", args[0]);
6419 return -1;
6420 }
6421
Willy Tarreauef934602016-12-22 23:12:01 +01006422 res = parse_time_err(args[1], &global_ssl.life_time, TIME_UNIT_S);
Willy Tarreau9ceda382016-12-21 23:13:03 +01006423 if (res) {
6424 memprintf(err, "unexpected character '%c' in argument to <%s>.", *res, args[0]);
6425 return -1;
6426 }
6427 return 0;
6428}
6429
6430#ifndef OPENSSL_NO_DH
Willy Tarreau14e36a12016-12-21 23:28:13 +01006431/* parse "ssl-dh-param-file".
6432 * Returns <0 on alert, >0 on warning, 0 on success.
6433 */
6434static int ssl_parse_global_dh_param_file(char **args, int section_type, struct proxy *curpx,
6435 struct proxy *defpx, const char *file, int line,
6436 char **err)
6437{
6438 if (too_many_args(1, args, err, NULL))
6439 return -1;
6440
6441 if (*(args[1]) == 0) {
6442 memprintf(err, "'%s' expects a file path as an argument.", args[0]);
6443 return -1;
6444 }
6445
6446 if (ssl_sock_load_global_dh_param_from_file(args[1])) {
6447 memprintf(err, "'%s': unable to load DH parameters from file <%s>.", args[0], args[1]);
6448 return -1;
6449 }
6450 return 0;
6451}
6452
Willy Tarreau9ceda382016-12-21 23:13:03 +01006453/* parse "ssl.default-dh-param".
6454 * Returns <0 on alert, >0 on warning, 0 on success.
6455 */
6456static int ssl_parse_global_default_dh(char **args, int section_type, struct proxy *curpx,
6457 struct proxy *defpx, const char *file, int line,
6458 char **err)
6459{
6460 if (too_many_args(1, args, err, NULL))
6461 return -1;
6462
6463 if (*(args[1]) == 0) {
6464 memprintf(err, "'%s' expects an integer argument.", args[0]);
6465 return -1;
6466 }
6467
Willy Tarreauef934602016-12-22 23:12:01 +01006468 global_ssl.default_dh_param = atoi(args[1]);
6469 if (global_ssl.default_dh_param < 1024) {
Willy Tarreau9ceda382016-12-21 23:13:03 +01006470 memprintf(err, "'%s' expects a value >= 1024.", args[0]);
6471 return -1;
6472 }
6473 return 0;
6474}
6475#endif
6476
6477
William Lallemand32af2032016-10-29 18:09:35 +02006478/* This function is used with TLS ticket keys management. It permits to browse
6479 * each reference. The variable <getnext> must contain the current node,
6480 * <end> point to the root node.
6481 */
6482#if (defined SSL_CTRL_SET_TLSEXT_TICKET_KEY_CB && TLS_TICKETS_NO > 0)
6483static inline
6484struct tls_keys_ref *tlskeys_list_get_next(struct tls_keys_ref *getnext, struct list *end)
6485{
6486 struct tls_keys_ref *ref = getnext;
6487
6488 while (1) {
6489
6490 /* Get next list entry. */
6491 ref = LIST_NEXT(&ref->list, struct tls_keys_ref *, list);
6492
6493 /* If the entry is the last of the list, return NULL. */
6494 if (&ref->list == end)
6495 return NULL;
6496
6497 return ref;
6498 }
6499}
6500
6501static inline
6502struct tls_keys_ref *tlskeys_ref_lookup_ref(const char *reference)
6503{
6504 int id;
6505 char *error;
6506
6507 /* If the reference starts by a '#', this is numeric id. */
6508 if (reference[0] == '#') {
6509 /* Try to convert the numeric id. If the conversion fails, the lookup fails. */
6510 id = strtol(reference + 1, &error, 10);
6511 if (*error != '\0')
6512 return NULL;
6513
6514 /* Perform the unique id lookup. */
6515 return tlskeys_ref_lookupid(id);
6516 }
6517
6518 /* Perform the string lookup. */
6519 return tlskeys_ref_lookup(reference);
6520}
6521#endif
6522
6523
6524#if (defined SSL_CTRL_SET_TLSEXT_TICKET_KEY_CB && TLS_TICKETS_NO > 0)
6525
6526static int cli_io_handler_tlskeys_files(struct appctx *appctx);
6527
6528static inline int cli_io_handler_tlskeys_entries(struct appctx *appctx) {
6529 return cli_io_handler_tlskeys_files(appctx);
6530}
6531
Willy Tarreauf5f26e82016-12-16 18:47:27 +01006532/* dumps all tls keys. Relies on cli.i0 (non-null = only list file names), cli.i1
6533 * (next index to be dumped), and cli.p0 (next key reference).
6534 */
William Lallemand32af2032016-10-29 18:09:35 +02006535static int cli_io_handler_tlskeys_files(struct appctx *appctx) {
6536
6537 struct stream_interface *si = appctx->owner;
6538
6539 switch (appctx->st2) {
6540 case STAT_ST_INIT:
6541 /* Display the column headers. If the message cannot be sent,
6542 * quit the fucntion with returning 0. The function is called
6543 * later and restart at the state "STAT_ST_INIT".
6544 */
6545 chunk_reset(&trash);
6546
6547 if (appctx->io_handler == cli_io_handler_tlskeys_entries)
6548 chunk_appendf(&trash, "# id secret\n");
6549 else
6550 chunk_appendf(&trash, "# id (file)\n");
6551
6552 if (bi_putchk(si_ic(si), &trash) == -1) {
6553 si_applet_cant_put(si);
6554 return 0;
6555 }
6556
William Lallemand32af2032016-10-29 18:09:35 +02006557 /* Now, we start the browsing of the references lists.
6558 * Note that the following call to LIST_ELEM return bad pointer. The only
6559 * available field of this pointer is <list>. It is used with the function
6560 * tlskeys_list_get_next() for retruning the first available entry
6561 */
Willy Tarreauf5f26e82016-12-16 18:47:27 +01006562 if (appctx->ctx.cli.p0 == NULL) {
6563 appctx->ctx.cli.p0 = LIST_ELEM(&tlskeys_reference, struct tls_keys_ref *, list);
6564 appctx->ctx.cli.p0 = tlskeys_list_get_next(appctx->ctx.cli.p0, &tlskeys_reference);
William Lallemand32af2032016-10-29 18:09:35 +02006565 }
6566
6567 appctx->st2 = STAT_ST_LIST;
6568 /* fall through */
6569
6570 case STAT_ST_LIST:
Willy Tarreauf5f26e82016-12-16 18:47:27 +01006571 while (appctx->ctx.cli.p0) {
6572 struct tls_keys_ref *ref = appctx->ctx.cli.p0;
6573 int head = ref->tls_ticket_enc_index;
William Lallemand32af2032016-10-29 18:09:35 +02006574
6575 chunk_reset(&trash);
Willy Tarreauf5f26e82016-12-16 18:47:27 +01006576 if (appctx->io_handler == cli_io_handler_tlskeys_entries && appctx->ctx.cli.i1 == 0)
William Lallemand32af2032016-10-29 18:09:35 +02006577 chunk_appendf(&trash, "# ");
Willy Tarreauf5f26e82016-12-16 18:47:27 +01006578
6579 if (appctx->ctx.cli.i1 == 0)
6580 chunk_appendf(&trash, "%d (%s)\n", ref->unique_id, ref->filename);
6581
William Lallemand32af2032016-10-29 18:09:35 +02006582 if (appctx->io_handler == cli_io_handler_tlskeys_entries) {
Willy Tarreauf5f26e82016-12-16 18:47:27 +01006583 while (appctx->ctx.cli.i1 < TLS_TICKETS_NO) {
William Lallemand32af2032016-10-29 18:09:35 +02006584 struct chunk *t2 = get_trash_chunk();
6585
6586 chunk_reset(t2);
6587 /* should never fail here because we dump only a key in the t2 buffer */
Willy Tarreauf5f26e82016-12-16 18:47:27 +01006588 t2->len = a2base64((char *)(ref->tlskeys + (head + 2 + appctx->ctx.cli.i1) % TLS_TICKETS_NO),
William Lallemand32af2032016-10-29 18:09:35 +02006589 sizeof(struct tls_sess_key), t2->str, t2->size);
Willy Tarreauf5f26e82016-12-16 18:47:27 +01006590 chunk_appendf(&trash, "%d.%d %s\n", ref->unique_id, appctx->ctx.cli.i1, t2->str);
William Lallemand32af2032016-10-29 18:09:35 +02006591
6592 if (bi_putchk(si_ic(si), &trash) == -1) {
6593 /* let's try again later from this stream. We add ourselves into
6594 * this stream's users so that it can remove us upon termination.
6595 */
6596 si_applet_cant_put(si);
6597 return 0;
6598 }
Willy Tarreauf5f26e82016-12-16 18:47:27 +01006599 appctx->ctx.cli.i1++;
William Lallemand32af2032016-10-29 18:09:35 +02006600 }
Willy Tarreauf5f26e82016-12-16 18:47:27 +01006601 appctx->ctx.cli.i1 = 0;
William Lallemand32af2032016-10-29 18:09:35 +02006602 }
6603 if (bi_putchk(si_ic(si), &trash) == -1) {
6604 /* let's try again later from this stream. We add ourselves into
6605 * this stream's users so that it can remove us upon termination.
6606 */
6607 si_applet_cant_put(si);
6608 return 0;
6609 }
6610
Willy Tarreauf5f26e82016-12-16 18:47:27 +01006611 if (appctx->ctx.cli.i0 == 0) /* don't display everything if not necessary */
William Lallemand32af2032016-10-29 18:09:35 +02006612 break;
6613
6614 /* get next list entry and check the end of the list */
Willy Tarreauf5f26e82016-12-16 18:47:27 +01006615 appctx->ctx.cli.p0 = tlskeys_list_get_next(appctx->ctx.cli.p0, &tlskeys_reference);
William Lallemand32af2032016-10-29 18:09:35 +02006616 }
6617
6618 appctx->st2 = STAT_ST_FIN;
6619 /* fall through */
6620
6621 default:
6622 appctx->st2 = STAT_ST_FIN;
6623 return 1;
6624 }
6625 return 0;
6626}
6627
6628#endif
6629
Willy Tarreauf5f26e82016-12-16 18:47:27 +01006630/* sets cli.i0 to non-zero if only file lists should be dumped */
William Lallemand32af2032016-10-29 18:09:35 +02006631static int cli_parse_show_tlskeys(char **args, struct appctx *appctx, void *private)
6632{
William Lallemand32af2032016-10-29 18:09:35 +02006633 /* no parameter, shows only file list */
6634 if (!*args[2]) {
Willy Tarreauf5f26e82016-12-16 18:47:27 +01006635 appctx->ctx.cli.i0 = 1;
William Lallemand32af2032016-10-29 18:09:35 +02006636 appctx->io_handler = cli_io_handler_tlskeys_files;
Willy Tarreau3067bfa2016-12-05 14:50:15 +01006637 return 0;
William Lallemand32af2032016-10-29 18:09:35 +02006638 }
6639
6640 if (args[2][0] == '*') {
6641 /* list every TLS ticket keys */
Willy Tarreauf5f26e82016-12-16 18:47:27 +01006642 appctx->ctx.cli.i0 = 1;
William Lallemand32af2032016-10-29 18:09:35 +02006643 } else {
Willy Tarreauf5f26e82016-12-16 18:47:27 +01006644 appctx->ctx.cli.p0 = tlskeys_ref_lookup_ref(args[2]);
6645 if (!appctx->ctx.cli.p0) {
William Lallemand32af2032016-10-29 18:09:35 +02006646 appctx->ctx.cli.msg = "'show tls-keys' unable to locate referenced filename\n";
Willy Tarreau3b6e5472016-11-24 15:53:53 +01006647 appctx->st0 = CLI_ST_PRINT;
William Lallemand32af2032016-10-29 18:09:35 +02006648 return 1;
6649 }
6650 }
William Lallemand32af2032016-10-29 18:09:35 +02006651 appctx->io_handler = cli_io_handler_tlskeys_entries;
Willy Tarreau3067bfa2016-12-05 14:50:15 +01006652 return 0;
William Lallemand32af2032016-10-29 18:09:35 +02006653}
6654
6655
6656static int cli_parse_set_tlskeys(char **args, struct appctx *appctx, void *private)
6657{
Willy Tarreauf5f26e82016-12-16 18:47:27 +01006658 struct tls_keys_ref *ref;
6659
William Lallemand32af2032016-10-29 18:09:35 +02006660 /* Expect two parameters: the filename and the new new TLS key in encoding */
6661 if (!*args[3] || !*args[4]) {
6662 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 +01006663 appctx->st0 = CLI_ST_PRINT;
William Lallemand32af2032016-10-29 18:09:35 +02006664 return 1;
6665 }
6666
Willy Tarreauf5f26e82016-12-16 18:47:27 +01006667 ref = tlskeys_ref_lookup_ref(args[3]);
6668 if (!ref) {
William Lallemand32af2032016-10-29 18:09:35 +02006669 appctx->ctx.cli.msg = "'set ssl tls-key' unable to locate referenced filename\n";
Willy Tarreau3b6e5472016-11-24 15:53:53 +01006670 appctx->st0 = CLI_ST_PRINT;
William Lallemand32af2032016-10-29 18:09:35 +02006671 return 1;
6672 }
6673
6674 trash.len = base64dec(args[4], strlen(args[4]), trash.str, trash.size);
6675 if (trash.len != sizeof(struct tls_sess_key)) {
6676 appctx->ctx.cli.msg = "'set ssl tls-key' received invalid base64 encoded TLS key.\n";
Willy Tarreau3b6e5472016-11-24 15:53:53 +01006677 appctx->st0 = CLI_ST_PRINT;
William Lallemand32af2032016-10-29 18:09:35 +02006678 return 1;
6679 }
6680
Willy Tarreauf5f26e82016-12-16 18:47:27 +01006681 memcpy(ref->tlskeys + ((ref->tls_ticket_enc_index + 2) % TLS_TICKETS_NO), trash.str, trash.len);
6682 ref->tls_ticket_enc_index = (ref->tls_ticket_enc_index + 1) % TLS_TICKETS_NO;
William Lallemand32af2032016-10-29 18:09:35 +02006683
6684 appctx->ctx.cli.msg = "TLS ticket key updated!";
Willy Tarreau3b6e5472016-11-24 15:53:53 +01006685 appctx->st0 = CLI_ST_PRINT;
William Lallemand32af2032016-10-29 18:09:35 +02006686 return 1;
6687
6688}
6689
6690static int cli_parse_set_ocspresponse(char **args, struct appctx *appctx, void *private)
6691{
6692#if (defined SSL_CTRL_SET_TLSEXT_STATUS_REQ_CB && !defined OPENSSL_NO_OCSP)
6693 char *err = NULL;
6694
6695 /* Expect one parameter: the new response in base64 encoding */
6696 if (!*args[3]) {
6697 appctx->ctx.cli.msg = "'set ssl ocsp-response' expects response in base64 encoding.\n";
Willy Tarreau3b6e5472016-11-24 15:53:53 +01006698 appctx->st0 = CLI_ST_PRINT;
William Lallemand32af2032016-10-29 18:09:35 +02006699 return 1;
6700 }
6701
6702 trash.len = base64dec(args[3], strlen(args[3]), trash.str, trash.size);
6703 if (trash.len < 0) {
6704 appctx->ctx.cli.msg = "'set ssl ocsp-response' received invalid base64 encoded response.\n";
Willy Tarreau3b6e5472016-11-24 15:53:53 +01006705 appctx->st0 = CLI_ST_PRINT;
William Lallemand32af2032016-10-29 18:09:35 +02006706 return 1;
6707 }
6708
6709 if (ssl_sock_update_ocsp_response(&trash, &err)) {
6710 if (err) {
6711 memprintf(&err, "%s.\n", err);
6712 appctx->ctx.cli.err = err;
Willy Tarreau3b6e5472016-11-24 15:53:53 +01006713 appctx->st0 = CLI_ST_PRINT_FREE;
William Lallemand32af2032016-10-29 18:09:35 +02006714 }
6715 return 1;
6716 }
6717 appctx->ctx.cli.msg = "OCSP Response updated!";
Willy Tarreau3b6e5472016-11-24 15:53:53 +01006718 appctx->st0 = CLI_ST_PRINT;
William Lallemand32af2032016-10-29 18:09:35 +02006719 return 1;
6720#else
6721 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 +01006722 appctx->st0 = CLI_ST_PRINT;
William Lallemand32af2032016-10-29 18:09:35 +02006723 return 1;
6724#endif
6725
6726}
6727
6728/* register cli keywords */
6729static struct cli_kw_list cli_kws = {{ },{
6730#if (defined SSL_CTRL_SET_TLSEXT_TICKET_KEY_CB && TLS_TICKETS_NO > 0)
6731 { { "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 },
6732 { { "set", "ssl", "tls-keys", NULL }, NULL, cli_parse_set_tlskeys, NULL },
6733 { { "set", "ssl", "ocsp-response", NULL }, NULL, cli_parse_set_ocspresponse, NULL },
6734#endif
6735 { { NULL }, NULL, NULL, NULL }
6736}};
6737
6738
6739
Willy Tarreau7875d092012-09-10 08:20:03 +02006740/* Note: must not be declared <const> as its list will be overwritten.
6741 * Please take care of keeping this list alphabetically sorted.
6742 */
Willy Tarreaudc13c112013-06-21 23:16:39 +02006743static struct sample_fetch_kw_list sample_fetch_keywords = {ILH, {
Emeric Brun645ae792014-04-30 14:21:06 +02006744 { "ssl_bc", smp_fetch_ssl_fc, 0, NULL, SMP_T_BOOL, SMP_USE_L5SRV },
Thierry FOURNIER07ee64e2015-07-06 23:43:03 +02006745 { "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 +02006746 { "ssl_bc_cipher", smp_fetch_ssl_fc_cipher, 0, NULL, SMP_T_STR, SMP_USE_L5SRV },
6747 { "ssl_bc_protocol", smp_fetch_ssl_fc_protocol, 0, NULL, SMP_T_STR, SMP_USE_L5SRV },
Emeric Brunb73a9b02014-04-30 18:49:19 +02006748 { "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 +02006749 { "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 +02006750 { "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 +02006751 { "ssl_c_ca_err", smp_fetch_ssl_c_ca_err, 0, NULL, SMP_T_SINT, SMP_USE_L5CLI },
6752 { "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 +01006753 { "ssl_c_der", smp_fetch_ssl_x_der, 0, NULL, SMP_T_BIN, SMP_USE_L5CLI },
Thierry FOURNIER07ee64e2015-07-06 23:43:03 +02006754 { "ssl_c_err", smp_fetch_ssl_c_err, 0, NULL, SMP_T_SINT, SMP_USE_L5CLI },
Emeric Brunba841a12014-04-30 17:05:08 +02006755 { "ssl_c_i_dn", smp_fetch_ssl_x_i_dn, ARG2(0,STR,SINT), NULL, SMP_T_STR, SMP_USE_L5CLI },
6756 { "ssl_c_key_alg", smp_fetch_ssl_x_key_alg, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
6757 { "ssl_c_notafter", smp_fetch_ssl_x_notafter, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
6758 { "ssl_c_notbefore", smp_fetch_ssl_x_notbefore, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
6759 { "ssl_c_sig_alg", smp_fetch_ssl_x_sig_alg, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
6760 { "ssl_c_s_dn", smp_fetch_ssl_x_s_dn, ARG2(0,STR,SINT), NULL, SMP_T_STR, SMP_USE_L5CLI },
6761 { "ssl_c_serial", smp_fetch_ssl_x_serial, 0, NULL, SMP_T_BIN, SMP_USE_L5CLI },
6762 { "ssl_c_sha1", smp_fetch_ssl_x_sha1, 0, NULL, SMP_T_BIN, SMP_USE_L5CLI },
Willy Tarreau80aca902013-01-07 15:42:20 +01006763 { "ssl_c_used", smp_fetch_ssl_c_used, 0, NULL, SMP_T_BOOL, SMP_USE_L5CLI },
Thierry FOURNIER07ee64e2015-07-06 23:43:03 +02006764 { "ssl_c_verify", smp_fetch_ssl_c_verify, 0, NULL, SMP_T_SINT, SMP_USE_L5CLI },
6765 { "ssl_c_version", smp_fetch_ssl_x_version, 0, NULL, SMP_T_SINT, SMP_USE_L5CLI },
Emeric Brun43e79582014-10-29 19:03:26 +01006766 { "ssl_f_der", smp_fetch_ssl_x_der, 0, NULL, SMP_T_BIN, SMP_USE_L5CLI },
Emeric Brunba841a12014-04-30 17:05:08 +02006767 { "ssl_f_i_dn", smp_fetch_ssl_x_i_dn, ARG2(0,STR,SINT), NULL, SMP_T_STR, SMP_USE_L5CLI },
6768 { "ssl_f_key_alg", smp_fetch_ssl_x_key_alg, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
6769 { "ssl_f_notafter", smp_fetch_ssl_x_notafter, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
6770 { "ssl_f_notbefore", smp_fetch_ssl_x_notbefore, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
6771 { "ssl_f_sig_alg", smp_fetch_ssl_x_sig_alg, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
6772 { "ssl_f_s_dn", smp_fetch_ssl_x_s_dn, ARG2(0,STR,SINT), NULL, SMP_T_STR, SMP_USE_L5CLI },
6773 { "ssl_f_serial", smp_fetch_ssl_x_serial, 0, NULL, SMP_T_BIN, SMP_USE_L5CLI },
Emeric Brun55f4fa82014-04-30 17:11:25 +02006774 { "ssl_f_sha1", smp_fetch_ssl_x_sha1, 0, NULL, SMP_T_BIN, SMP_USE_L5CLI },
Thierry FOURNIER07ee64e2015-07-06 23:43:03 +02006775 { "ssl_f_version", smp_fetch_ssl_x_version, 0, NULL, SMP_T_SINT, SMP_USE_L5CLI },
Willy Tarreau80aca902013-01-07 15:42:20 +01006776 { "ssl_fc", smp_fetch_ssl_fc, 0, NULL, SMP_T_BOOL, SMP_USE_L5CLI },
Thierry FOURNIER07ee64e2015-07-06 23:43:03 +02006777 { "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 +01006778 { "ssl_fc_cipher", smp_fetch_ssl_fc_cipher, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
Willy Tarreau80aca902013-01-07 15:42:20 +01006779 { "ssl_fc_has_crt", smp_fetch_ssl_fc_has_crt, 0, NULL, SMP_T_BOOL, SMP_USE_L5CLI },
6780 { "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 +02006781 { "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 +02006782#ifdef OPENSSL_NPN_NEGOTIATED
Thierry FOURNIER7654c9f2013-12-17 00:20:33 +01006783 { "ssl_fc_npn", smp_fetch_ssl_fc_npn, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
Willy Tarreaua33c6542012-10-15 13:19:06 +02006784#endif
Dirkjan Bussink48f1c4e2014-02-13 12:29:42 +01006785#ifdef TLSEXT_TYPE_application_layer_protocol_negotiation
Thierry FOURNIER7654c9f2013-12-17 00:20:33 +01006786 { "ssl_fc_alpn", smp_fetch_ssl_fc_alpn, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
Willy Tarreauab861d32013-04-02 02:30:41 +02006787#endif
Thierry FOURNIER7654c9f2013-12-17 00:20:33 +01006788 { "ssl_fc_protocol", smp_fetch_ssl_fc_protocol, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
Emeric Brunb73a9b02014-04-30 18:49:19 +02006789 { "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 +02006790 { "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 +01006791 { "ssl_fc_session_id", smp_fetch_ssl_fc_session_id, 0, NULL, SMP_T_BIN, SMP_USE_L5CLI },
6792 { "ssl_fc_sni", smp_fetch_ssl_fc_sni, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
Willy Tarreau7875d092012-09-10 08:20:03 +02006793 { NULL, NULL, 0, 0, 0 },
6794}};
6795
6796/* Note: must not be declared <const> as its list will be overwritten.
6797 * Please take care of keeping this list alphabetically sorted.
6798 */
Willy Tarreaudc13c112013-06-21 23:16:39 +02006799static struct acl_kw_list acl_kws = {ILH, {
Thierry FOURNIERc5a4e982014-03-05 16:07:08 +01006800 { "ssl_fc_sni_end", "ssl_fc_sni", PAT_MATCH_END },
6801 { "ssl_fc_sni_reg", "ssl_fc_sni", PAT_MATCH_REG },
Willy Tarreau8ed669b2013-01-11 15:49:37 +01006802 { /* END */ },
Willy Tarreau7875d092012-09-10 08:20:03 +02006803}};
6804
Willy Tarreau79eeafa2012-09-14 07:53:05 +02006805/* Note: must not be declared <const> as its list will be overwritten.
6806 * Please take care of keeping this list alphabetically sorted, doing so helps
6807 * all code contributors.
6808 * Optional keywords are also declared with a NULL ->parse() function so that
6809 * the config parser can report an appropriate error when a known keyword was
6810 * not enabled.
6811 */
Emmanuel Hocdet98263292016-12-29 18:26:15 +01006812static struct ssl_bind_kw ssl_bind_kws[] = {
6813 { "alpn", ssl_bind_parse_alpn, 1 }, /* set ALPN supported protocols */
6814 { "ca-file", ssl_bind_parse_ca_file, 1 }, /* set CAfile to process verify on client cert */
6815 { "ciphers", ssl_bind_parse_ciphers, 1 }, /* set SSL cipher suite */
6816 { "crl-file", ssl_bind_parse_crl_file, 1 }, /* set certificat revocation list file use on client cert verify */
6817 { "ecdhe", ssl_bind_parse_ecdhe, 1 }, /* defines named curve for elliptic curve Diffie-Hellman */
6818 { "force-sslv3", ssl_bind_parse_force_sslv3, 0 }, /* force SSLv3 */
6819 { "force-tlsv10", ssl_bind_parse_force_tlsv10, 0 }, /* force TLSv10 */
6820 { "force-tlsv11", ssl_bind_parse_force_tlsv11, 0 }, /* force TLSv11 */
6821 { "force-tlsv12", ssl_bind_parse_force_tlsv12, 0 }, /* force TLSv12 */
6822 { "no-sslv3", ssl_bind_parse_no_sslv3, 0 }, /* disable SSLv3 */
6823 { "no-tlsv10", ssl_bind_parse_no_tlsv10, 0 }, /* disable TLSv10 */
6824 { "no-tlsv11", ssl_bind_parse_no_tlsv11, 0 }, /* disable TLSv11 */
6825 { "no-tlsv12", ssl_bind_parse_no_tlsv12, 0 }, /* disable TLSv12 */
6826 { "no-tls-tickets", ssl_bind_parse_no_tls_tickets, 0 }, /* disable session resumption tickets */
6827 { "npn", ssl_bind_parse_npn, 1 }, /* set NPN supported protocols */
6828 { "verify", ssl_bind_parse_verify, 1 }, /* set SSL verify method */
6829 { NULL, NULL, 0 },
6830};
6831
Willy Tarreau51fb7652012-09-18 18:24:39 +02006832static struct bind_kw_list bind_kws = { "SSL", { }, {
Nenad Merdanovic05552d42015-02-27 19:56:49 +01006833 { "alpn", bind_parse_alpn, 1 }, /* set ALPN supported protocols */
6834 { "ca-file", bind_parse_ca_file, 1 }, /* set CAfile to process verify on client cert */
6835 { "ca-ignore-err", bind_parse_ignore_err, 1 }, /* set error IDs to ignore on verify depth > 0 */
Christopher Faulet31af49d2015-06-09 17:29:50 +02006836 { "ca-sign-file", bind_parse_ca_sign_file, 1 }, /* set CAFile used to generate and sign server certs */
6837 { "ca-sign-pass", bind_parse_ca_sign_pass, 1 }, /* set CAKey passphrase */
Nenad Merdanovic05552d42015-02-27 19:56:49 +01006838 { "ciphers", bind_parse_ciphers, 1 }, /* set SSL cipher suite */
6839 { "crl-file", bind_parse_crl_file, 1 }, /* set certificat revocation list file use on client cert verify */
6840 { "crt", bind_parse_crt, 1 }, /* load SSL certificates from this location */
6841 { "crt-ignore-err", bind_parse_ignore_err, 1 }, /* set error IDs to ingore on verify depth == 0 */
6842 { "crt-list", bind_parse_crt_list, 1 }, /* load a list of crt from this location */
6843 { "ecdhe", bind_parse_ecdhe, 1 }, /* defines named curve for elliptic curve Diffie-Hellman */
6844 { "force-sslv3", bind_parse_force_sslv3, 0 }, /* force SSLv3 */
6845 { "force-tlsv10", bind_parse_force_tlsv10, 0 }, /* force TLSv10 */
6846 { "force-tlsv11", bind_parse_force_tlsv11, 0 }, /* force TLSv11 */
6847 { "force-tlsv12", bind_parse_force_tlsv12, 0 }, /* force TLSv12 */
Christopher Faulet31af49d2015-06-09 17:29:50 +02006848 { "generate-certificates", bind_parse_generate_certs, 0 }, /* enable the server certificates generation */
Nenad Merdanovic05552d42015-02-27 19:56:49 +01006849 { "no-sslv3", bind_parse_no_sslv3, 0 }, /* disable SSLv3 */
6850 { "no-tlsv10", bind_parse_no_tlsv10, 0 }, /* disable TLSv10 */
6851 { "no-tlsv11", bind_parse_no_tlsv11, 0 }, /* disable TLSv11 */
6852 { "no-tlsv12", bind_parse_no_tlsv12, 0 }, /* disable TLSv12 */
6853 { "no-tls-tickets", bind_parse_no_tls_tickets, 0 }, /* disable session resumption tickets */
6854 { "ssl", bind_parse_ssl, 0 }, /* enable SSL processing */
6855 { "strict-sni", bind_parse_strict_sni, 0 }, /* refuse negotiation if sni doesn't match a certificate */
6856 { "tls-ticket-keys", bind_parse_tls_ticket_keys, 1 }, /* set file to load TLS ticket keys from */
6857 { "verify", bind_parse_verify, 1 }, /* set SSL verify method */
6858 { "npn", bind_parse_npn, 1 }, /* set NPN supported protocols */
Willy Tarreau79eeafa2012-09-14 07:53:05 +02006859 { NULL, NULL, 0 },
6860}};
Emeric Brun46591952012-05-18 15:47:34 +02006861
Willy Tarreau92faadf2012-10-10 23:04:25 +02006862/* Note: must not be declared <const> as its list will be overwritten.
6863 * Please take care of keeping this list alphabetically sorted, doing so helps
6864 * all code contributors.
6865 * Optional keywords are also declared with a NULL ->parse() function so that
6866 * the config parser can report an appropriate error when a known keyword was
6867 * not enabled.
6868 */
6869static struct srv_kw_list srv_kws = { "SSL", { }, {
Emeric Brunef42d922012-10-11 16:11:36 +02006870 { "ca-file", srv_parse_ca_file, 1, 0 }, /* set CAfile to process verify server cert */
Emeric Brunecc91fe2012-10-11 15:05:10 +02006871 { "check-ssl", srv_parse_check_ssl, 0, 0 }, /* enable SSL for health checks */
6872 { "ciphers", srv_parse_ciphers, 1, 0 }, /* select the cipher suite */
Emeric Brunef42d922012-10-11 16:11:36 +02006873 { "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 +02006874 { "crt", srv_parse_crt, 1, 0 }, /* set client certificate */
Emeric Brunecc91fe2012-10-11 15:05:10 +02006875 { "force-sslv3", srv_parse_force_sslv3, 0, 0 }, /* force SSLv3 */
6876 { "force-tlsv10", srv_parse_force_tlsv10, 0, 0 }, /* force TLSv10 */
6877 { "force-tlsv11", srv_parse_force_tlsv11, 0, 0 }, /* force TLSv11 */
6878 { "force-tlsv12", srv_parse_force_tlsv12, 0, 0 }, /* force TLSv12 */
Willy Tarreau2a3fb1c2015-02-05 16:47:07 +01006879 { "no-ssl-reuse", srv_parse_no_ssl_reuse, 0, 0 }, /* disable session reuse */
Emeric Brunecc91fe2012-10-11 15:05:10 +02006880 { "no-sslv3", srv_parse_no_sslv3, 0, 0 }, /* disable SSLv3 */
6881 { "no-tlsv10", srv_parse_no_tlsv10, 0, 0 }, /* disable TLSv10 */
6882 { "no-tlsv11", srv_parse_no_tlsv11, 0, 0 }, /* disable TLSv11 */
6883 { "no-tlsv12", srv_parse_no_tlsv12, 0, 0 }, /* disable TLSv12 */
Emeric Brunf9c5c472012-10-11 15:28:34 +02006884 { "no-tls-tickets", srv_parse_no_tls_tickets, 0, 0 }, /* disable session resumption tickets */
David Safb76832014-05-08 23:42:08 -04006885 { "send-proxy-v2-ssl", srv_parse_send_proxy_ssl, 0, 0 }, /* send PROXY protocol header v2 with SSL info */
6886 { "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 +02006887 { "sni", srv_parse_sni, 1, 0 }, /* send SNI extension */
Emeric Brunecc91fe2012-10-11 15:05:10 +02006888 { "ssl", srv_parse_ssl, 0, 0 }, /* enable SSL processing */
Emeric Brunef42d922012-10-11 16:11:36 +02006889 { "verify", srv_parse_verify, 1, 0 }, /* set SSL verify method */
Evan Broderbe554312013-06-27 00:05:25 -07006890 { "verifyhost", srv_parse_verifyhost, 1, 0 }, /* require that SSL cert verifies for hostname */
Willy Tarreau92faadf2012-10-10 23:04:25 +02006891 { NULL, NULL, 0, 0 },
6892}};
6893
Emeric Brun2c86cbf2014-10-30 15:56:50 +01006894static struct cfg_kw_list cfg_kws = {ILH, {
Willy Tarreau8c3b0fd2016-12-21 22:44:46 +01006895 { CFG_GLOBAL, "ca-base", ssl_parse_global_ca_crt_base },
6896 { CFG_GLOBAL, "crt-base", ssl_parse_global_ca_crt_base },
Willy Tarreau0bea58d2016-12-21 23:17:25 +01006897 { CFG_GLOBAL, "maxsslconn", ssl_parse_global_int },
Emeric Brun2c86cbf2014-10-30 15:56:50 +01006898 { CFG_GLOBAL, "ssl-default-bind-options", ssl_parse_default_bind_options },
6899 { CFG_GLOBAL, "ssl-default-server-options", ssl_parse_default_server_options },
Willy Tarreau14e36a12016-12-21 23:28:13 +01006900#ifndef OPENSSL_NO_DH
6901 { CFG_GLOBAL, "ssl-dh-param-file", ssl_parse_global_dh_param_file },
6902#endif
Willy Tarreau9ceda382016-12-21 23:13:03 +01006903 { CFG_GLOBAL, "tune.ssl.cachesize", ssl_parse_global_int },
6904#ifndef OPENSSL_NO_DH
6905 { CFG_GLOBAL, "tune.ssl.default-dh-param", ssl_parse_global_default_dh },
6906#endif
6907 { CFG_GLOBAL, "tune.ssl.force-private-cache", ssl_parse_global_private_cache },
6908 { CFG_GLOBAL, "tune.ssl.lifetime", ssl_parse_global_lifetime },
6909 { CFG_GLOBAL, "tune.ssl.maxrecord", ssl_parse_global_int },
6910 { CFG_GLOBAL, "tune.ssl.ssl-ctx-cache-size", ssl_parse_global_int },
Willy Tarreauf22e9682016-12-21 23:23:19 +01006911 { CFG_GLOBAL, "ssl-default-bind-ciphers", ssl_parse_global_ciphers },
6912 { CFG_GLOBAL, "ssl-default-server-ciphers", ssl_parse_global_ciphers },
Emeric Brun2c86cbf2014-10-30 15:56:50 +01006913 { 0, NULL, NULL },
6914}};
6915
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02006916/* transport-layer operations for SSL sockets */
Willy Tarreaud9f5cca2016-12-22 21:08:52 +01006917static struct xprt_ops ssl_sock = {
Emeric Brun46591952012-05-18 15:47:34 +02006918 .snd_buf = ssl_sock_from_buf,
6919 .rcv_buf = ssl_sock_to_buf,
6920 .rcv_pipe = NULL,
6921 .snd_pipe = NULL,
6922 .shutr = NULL,
6923 .shutw = ssl_sock_shutw,
6924 .close = ssl_sock_close,
6925 .init = ssl_sock_init,
Willy Tarreau55d37912016-12-21 23:38:39 +01006926 .prepare_bind_conf = ssl_sock_prepare_bind_conf,
Willy Tarreau795cdab2016-12-22 17:30:54 +01006927 .destroy_bind_conf = ssl_sock_destroy_bind_conf,
Willy Tarreau17d45382016-12-22 21:16:08 +01006928 .prepare_srv = ssl_sock_prepare_srv_ctx,
6929 .destroy_srv = ssl_sock_free_srv_ctx,
Willy Tarreau8e0bb0a2016-11-24 16:58:12 +01006930 .name = "SSL",
Emeric Brun46591952012-05-18 15:47:34 +02006931};
6932
Daniel Jakots54ffb912015-11-06 20:02:41 +01006933#if (OPENSSL_VERSION_NUMBER >= 0x1000200fL && !defined OPENSSL_NO_TLSEXT && !defined OPENSSL_IS_BORINGSSL && !defined LIBRESSL_VERSION_NUMBER)
Janusz Dziemidowicz2c701b52015-03-07 23:03:59 +01006934
6935static void ssl_sock_sctl_free_func(void *parent, void *ptr, CRYPTO_EX_DATA *ad, int idx, long argl, void *argp)
6936{
6937 if (ptr) {
6938 chunk_destroy(ptr);
6939 free(ptr);
6940 }
6941}
6942
6943#endif
6944
Emeric Brun46591952012-05-18 15:47:34 +02006945__attribute__((constructor))
Willy Tarreau92faadf2012-10-10 23:04:25 +02006946static void __ssl_sock_init(void)
6947{
Willy Tarreauc2c0b612016-12-21 19:23:20 +01006948 char *ptr;
6949
Emeric Brun46591952012-05-18 15:47:34 +02006950 STACK_OF(SSL_COMP)* cm;
6951
Willy Tarreauef934602016-12-22 23:12:01 +01006952 if (global_ssl.listen_default_ciphers)
6953 global_ssl.listen_default_ciphers = strdup(global_ssl.listen_default_ciphers);
6954 if (global_ssl.connect_default_ciphers)
6955 global_ssl.connect_default_ciphers = strdup(global_ssl.connect_default_ciphers);
Willy Tarreau610f04b2014-02-13 11:36:41 +01006956
Willy Tarreau13e14102016-12-22 20:25:26 +01006957 xprt_register(XPRT_SSL, &ssl_sock);
Emeric Brun46591952012-05-18 15:47:34 +02006958 SSL_library_init();
6959 cm = SSL_COMP_get_compression_methods();
6960 sk_SSL_COMP_zero(cm);
Daniel Jakots54ffb912015-11-06 20:02:41 +01006961#if (OPENSSL_VERSION_NUMBER >= 0x1000200fL && !defined OPENSSL_NO_TLSEXT && !defined OPENSSL_IS_BORINGSSL && !defined LIBRESSL_VERSION_NUMBER)
Janusz Dziemidowicz2c701b52015-03-07 23:03:59 +01006962 sctl_ex_index = SSL_CTX_get_ex_new_index(0, NULL, NULL, NULL, ssl_sock_sctl_free_func);
6963#endif
Willy Tarreau7875d092012-09-10 08:20:03 +02006964 sample_register_fetches(&sample_fetch_keywords);
6965 acl_register_keywords(&acl_kws);
Willy Tarreau79eeafa2012-09-14 07:53:05 +02006966 bind_register_keywords(&bind_kws);
Willy Tarreau92faadf2012-10-10 23:04:25 +02006967 srv_register_keywords(&srv_kws);
Emeric Brun2c86cbf2014-10-30 15:56:50 +01006968 cfg_register_keywords(&cfg_kws);
William Lallemand32af2032016-10-29 18:09:35 +02006969 cli_register_kw(&cli_kws);
Willy Tarreaud1c57502016-12-22 22:46:15 +01006970#if (defined SSL_CTRL_SET_TLSEXT_TICKET_KEY_CB && TLS_TICKETS_NO > 0)
6971 hap_register_post_check(tlskeys_finalize_config);
6972#endif
Willy Tarreaud92aa5c2015-01-15 21:34:39 +01006973
Willy Tarreauc2c0b612016-12-21 19:23:20 +01006974 ptr = NULL;
6975 memprintf(&ptr, "Built with OpenSSL version : "
6976#ifdef OPENSSL_IS_BORINGSSL
6977 "BoringSSL\n");
6978#else /* OPENSSL_IS_BORINGSSL */
6979 OPENSSL_VERSION_TEXT
6980 "\nRunning on OpenSSL version : %s%s",
6981 SSLeay_version(SSLEAY_VERSION),
6982 ((OPENSSL_VERSION_NUMBER ^ SSLeay()) >> 8) ? " (VERSIONS DIFFER!)" : "");
6983#endif
6984 memprintf(&ptr, "%s\nOpenSSL library supports TLS extensions : "
6985#if OPENSSL_VERSION_NUMBER < 0x00907000L
6986 "no (library version too old)"
6987#elif defined(OPENSSL_NO_TLSEXT)
6988 "no (disabled via OPENSSL_NO_TLSEXT)"
6989#else
6990 "yes"
6991#endif
6992 "", ptr);
6993
6994 memprintf(&ptr, "%s\nOpenSSL library supports SNI : "
6995#ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME
6996 "yes"
6997#else
6998#ifdef OPENSSL_NO_TLSEXT
6999 "no (because of OPENSSL_NO_TLSEXT)"
7000#else
7001 "no (version might be too old, 0.9.8f min needed)"
7002#endif
7003#endif
7004 "", ptr);
7005
Willy Tarreauc2c0b612016-12-21 19:23:20 +01007006 hap_register_build_opts(ptr, 1);
7007
Willy Tarreaud92aa5c2015-01-15 21:34:39 +01007008 global.ssl_session_max_cost = SSL_SESSION_MAX_COST;
7009 global.ssl_handshake_max_cost = SSL_HANDSHAKE_MAX_COST;
Remi Gacogne4f902b82015-05-28 16:23:00 +02007010
7011#ifndef OPENSSL_NO_DH
7012 ssl_dh_ptr_index = SSL_CTX_get_ex_new_index(0, NULL, NULL, NULL, NULL);
7013#endif
Thierry FOURNIER / OZON.IO8b068c22016-10-10 11:59:50 +02007014
7015 /* Load SSL string for the verbose & debug mode. */
7016 ERR_load_SSL_strings();
Emeric Brun46591952012-05-18 15:47:34 +02007017}
7018
Remi Gacogned3a23c32015-05-28 16:39:47 +02007019__attribute__((destructor))
7020static void __ssl_sock_deinit(void)
7021{
Willy Tarreaua84c2672015-10-09 12:10:13 +02007022#ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME
Christopher Faulet31af49d2015-06-09 17:29:50 +02007023 lru64_destroy(ssl_ctx_lru_tree);
Willy Tarreaua84c2672015-10-09 12:10:13 +02007024#endif
Christopher Faulet31af49d2015-06-09 17:29:50 +02007025
Remi Gacogned3a23c32015-05-28 16:39:47 +02007026#ifndef OPENSSL_NO_DH
7027 if (local_dh_1024) {
7028 DH_free(local_dh_1024);
7029 local_dh_1024 = NULL;
7030 }
7031
7032 if (local_dh_2048) {
7033 DH_free(local_dh_2048);
7034 local_dh_2048 = NULL;
7035 }
7036
7037 if (local_dh_4096) {
7038 DH_free(local_dh_4096);
7039 local_dh_4096 = NULL;
7040 }
7041
Remi Gacogne47783ef2015-05-29 15:53:22 +02007042 if (global_dh) {
7043 DH_free(global_dh);
7044 global_dh = NULL;
7045 }
Remi Gacogned3a23c32015-05-28 16:39:47 +02007046#endif
7047
7048 ERR_remove_state(0);
7049 ERR_free_strings();
7050
7051 EVP_cleanup();
7052
7053#if OPENSSL_VERSION_NUMBER >= 0x00907000L
7054 CRYPTO_cleanup_all_ex_data();
7055#endif
7056}
7057
7058
Emeric Brun46591952012-05-18 15:47:34 +02007059/*
7060 * Local variables:
7061 * c-indent-level: 8
7062 * c-basic-offset: 8
7063 * End:
7064 */