blob: 101f7f34239d50d7e086f75813e5dccfa2b3e163 [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;
Emeric Brune1f38db2012-09-03 20:36:47 +0200133
Nenad Merdanovic200b0fa2015-05-09 08:46:01 +0200134#if (defined SSL_CTRL_SET_TLSEXT_TICKET_KEY_CB && TLS_TICKETS_NO > 0)
135struct list tlskeys_reference = LIST_HEAD_INIT(tlskeys_reference);
136#endif
137
Remi Gacogne8de54152014-07-15 11:36:40 +0200138#ifndef OPENSSL_NO_DH
Remi Gacogne4f902b82015-05-28 16:23:00 +0200139static int ssl_dh_ptr_index = -1;
Remi Gacogne47783ef2015-05-29 15:53:22 +0200140static DH *global_dh = NULL;
Remi Gacogne8de54152014-07-15 11:36:40 +0200141static DH *local_dh_1024 = NULL;
142static DH *local_dh_2048 = NULL;
143static DH *local_dh_4096 = NULL;
Remi Gacogne8de54152014-07-15 11:36:40 +0200144#endif /* OPENSSL_NO_DH */
145
Willy Tarreauc8ad3be2015-06-17 15:48:26 +0200146#ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME
Christopher Faulet31af49d2015-06-09 17:29:50 +0200147/* X509V3 Extensions that will be added on generated certificates */
148#define X509V3_EXT_SIZE 5
149static char *x509v3_ext_names[X509V3_EXT_SIZE] = {
150 "basicConstraints",
151 "nsComment",
152 "subjectKeyIdentifier",
153 "authorityKeyIdentifier",
154 "keyUsage",
155};
156static char *x509v3_ext_values[X509V3_EXT_SIZE] = {
157 "CA:FALSE",
158 "\"OpenSSL Generated Certificate\"",
159 "hash",
160 "keyid,issuer:always",
161 "nonRepudiation,digitalSignature,keyEncipherment"
162};
163
164/* LRU cache to store generated certificate */
165static struct lru64_head *ssl_ctx_lru_tree = NULL;
166static unsigned int ssl_ctx_lru_seed = 0;
Willy Tarreauc8ad3be2015-06-17 15:48:26 +0200167#endif // SSL_CTRL_SET_TLSEXT_HOSTNAME
168
yanbzhube2774d2015-12-10 15:07:30 -0500169#if OPENSSL_VERSION_NUMBER >= 0x1000200fL
170/* The order here matters for picking a default context,
171 * keep the most common keytype at the bottom of the list
172 */
173const char *SSL_SOCK_KEYTYPE_NAMES[] = {
174 "dsa",
175 "ecdsa",
176 "rsa"
177};
178#define SSL_SOCK_NUM_KEYTYPES 3
Willy Tarreau30da7ad2015-12-14 11:28:33 +0100179#else
180#define SSL_SOCK_NUM_KEYTYPES 1
yanbzhube2774d2015-12-10 15:07:30 -0500181#endif
182
Willy Tarreauc8ad3be2015-06-17 15:48:26 +0200183#if (defined SSL_CTRL_SET_TLSEXT_STATUS_REQ_CB && !defined OPENSSL_NO_OCSP)
yanbzhube2774d2015-12-10 15:07:30 -0500184/*
185 * struct alignment works here such that the key.key is the same as key_data
186 * Do not change the placement of key_data
187 */
Willy Tarreauc8ad3be2015-06-17 15:48:26 +0200188struct certificate_ocsp {
189 struct ebmb_node key;
190 unsigned char key_data[OCSP_MAX_CERTID_ASN1_LENGTH];
191 struct chunk response;
192 long expire;
193};
Christopher Faulet31af49d2015-06-09 17:29:50 +0200194
yanbzhube2774d2015-12-10 15:07:30 -0500195struct ocsp_cbk_arg {
196 int is_single;
197 int single_kt;
198 union {
199 struct certificate_ocsp *s_ocsp;
200 /*
201 * m_ocsp will have multiple entries dependent on key type
202 * Entry 0 - DSA
203 * Entry 1 - ECDSA
204 * Entry 2 - RSA
205 */
206 struct certificate_ocsp *m_ocsp[SSL_SOCK_NUM_KEYTYPES];
207 };
208};
209
Emeric Brun4f3c87a2014-06-20 15:46:13 +0200210/*
Thierry FOURNIER / OZON.IO8b068c22016-10-10 11:59:50 +0200211 * This function gives the detail of the SSL error. It is used only
212 * if the debug mode and the verbose mode are activated. It dump all
213 * the SSL error until the stack was empty.
214 */
215static forceinline void ssl_sock_dump_errors(struct connection *conn)
216{
217 unsigned long ret;
218
219 if (unlikely(global.mode & MODE_DEBUG)) {
220 while(1) {
221 ret = ERR_get_error();
222 if (ret == 0)
223 return;
224 fprintf(stderr, "fd[%04x] OpenSSL error[0x%lx] %s: %s\n",
225 (unsigned short)conn->t.sock.fd, ret,
226 ERR_func_error_string(ret), ERR_reason_error_string(ret));
227 }
228 }
229}
230
231/*
Emeric Brun4f3c87a2014-06-20 15:46:13 +0200232 * This function returns the number of seconds elapsed
233 * since the Epoch, 1970-01-01 00:00:00 +0000 (UTC) and the
234 * date presented un ASN1_GENERALIZEDTIME.
235 *
236 * In parsing error case, it returns -1.
237 */
238static long asn1_generalizedtime_to_epoch(ASN1_GENERALIZEDTIME *d)
239{
240 long epoch;
241 char *p, *end;
242 const unsigned short month_offset[12] = {
243 0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334
244 };
245 int year, month;
246
247 if (!d || (d->type != V_ASN1_GENERALIZEDTIME)) return -1;
248
249 p = (char *)d->data;
250 end = p + d->length;
251
252 if (end - p < 4) return -1;
253 year = 1000 * (p[0] - '0') + 100 * (p[1] - '0') + 10 * (p[2] - '0') + p[3] - '0';
254 p += 4;
255 if (end - p < 2) return -1;
256 month = 10 * (p[0] - '0') + p[1] - '0';
257 if (month < 1 || month > 12) return -1;
258 /* Compute the number of seconds since 1 jan 1970 and the beginning of current month
259 We consider leap years and the current month (<marsh or not) */
260 epoch = ( ((year - 1970) * 365)
261 + ((year - (month < 3)) / 4 - (year - (month < 3)) / 100 + (year - (month < 3)) / 400)
262 - ((1970 - 1) / 4 - (1970 - 1) / 100 + (1970 - 1) / 400)
263 + month_offset[month-1]
264 ) * 24 * 60 * 60;
265 p += 2;
266 if (end - p < 2) return -1;
267 /* Add the number of seconds of completed days of current month */
268 epoch += (10 * (p[0] - '0') + p[1] - '0' - 1) * 24 * 60 * 60;
269 p += 2;
270 if (end - p < 2) return -1;
271 /* Add the completed hours of the current day */
272 epoch += (10 * (p[0] - '0') + p[1] - '0') * 60 * 60;
273 p += 2;
274 if (end - p < 2) return -1;
275 /* Add the completed minutes of the current hour */
276 epoch += (10 * (p[0] - '0') + p[1] - '0') * 60;
277 p += 2;
278 if (p == end) return -1;
279 /* Test if there is available seconds */
280 if (p[0] < '0' || p[0] > '9')
281 goto nosec;
282 if (end - p < 2) return -1;
283 /* Add the seconds of the current minute */
284 epoch += 10 * (p[0] - '0') + p[1] - '0';
285 p += 2;
286 if (p == end) return -1;
287 /* Ignore seconds float part if present */
288 if (p[0] == '.') {
289 do {
290 if (++p == end) return -1;
291 } while (p[0] >= '0' && p[0] <= '9');
292 }
293
294nosec:
295 if (p[0] == 'Z') {
296 if (end - p != 1) return -1;
297 return epoch;
298 }
299 else if (p[0] == '+') {
300 if (end - p != 5) return -1;
301 /* Apply timezone offset */
302 return epoch - ((10 * (p[1] - '0') + p[2] - '0') * 60 + (10 * (p[3] - '0') + p[4] - '0')) * 60;
303 }
304 else if (p[0] == '-') {
305 if (end - p != 5) return -1;
306 /* Apply timezone offset */
307 return epoch + ((10 * (p[1] - '0') + p[2] - '0') * 60 + (10 * (p[3] - '0') + p[4] - '0')) * 60;
308 }
309
310 return -1;
311}
312
Emeric Brun1d3865b2014-06-20 15:37:32 +0200313static struct eb_root cert_ocsp_tree = EB_ROOT_UNIQUE;
Emeric Brun4147b2e2014-06-16 18:36:30 +0200314
315/* This function starts to check if the OCSP response (in DER format) contained
316 * in chunk 'ocsp_response' is valid (else exits on error).
317 * If 'cid' is not NULL, it will be compared to the OCSP certificate ID
318 * contained in the OCSP Response and exits on error if no match.
319 * If it's a valid OCSP Response:
320 * If 'ocsp' is not NULL, the chunk is copied in the OCSP response's container
321 * pointed by 'ocsp'.
322 * If 'ocsp' is NULL, the function looks up into the OCSP response's
323 * containers tree (using as index the ASN1 form of the OCSP Certificate ID extracted
324 * from the response) and exits on error if not found. Finally, If an OCSP response is
325 * already present in the container, it will be overwritten.
326 *
327 * Note: OCSP response containing more than one OCSP Single response is not
328 * considered valid.
329 *
330 * Returns 0 on success, 1 in error case.
331 */
332static int ssl_sock_load_ocsp_response(struct chunk *ocsp_response, struct certificate_ocsp *ocsp, OCSP_CERTID *cid, char **err)
333{
334 OCSP_RESPONSE *resp;
335 OCSP_BASICRESP *bs = NULL;
336 OCSP_SINGLERESP *sr;
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +0200337 OCSP_CERTID *id;
Emeric Brun4147b2e2014-06-16 18:36:30 +0200338 unsigned char *p = (unsigned char *)ocsp_response->str;
339 int rc , count_sr;
Emeric Brun13a6b482014-06-20 15:44:34 +0200340 ASN1_GENERALIZEDTIME *revtime, *thisupd, *nextupd = NULL;
Emeric Brun4147b2e2014-06-16 18:36:30 +0200341 int reason;
342 int ret = 1;
343
344 resp = d2i_OCSP_RESPONSE(NULL, (const unsigned char **)&p, ocsp_response->len);
345 if (!resp) {
346 memprintf(err, "Unable to parse OCSP response");
347 goto out;
348 }
349
350 rc = OCSP_response_status(resp);
351 if (rc != OCSP_RESPONSE_STATUS_SUCCESSFUL) {
352 memprintf(err, "OCSP response status not successful");
353 goto out;
354 }
355
356 bs = OCSP_response_get1_basic(resp);
357 if (!bs) {
358 memprintf(err, "Failed to get basic response from OCSP Response");
359 goto out;
360 }
361
362 count_sr = OCSP_resp_count(bs);
363 if (count_sr > 1) {
364 memprintf(err, "OCSP response ignored because contains multiple single responses (%d)", count_sr);
365 goto out;
366 }
367
368 sr = OCSP_resp_get0(bs, 0);
369 if (!sr) {
370 memprintf(err, "Failed to get OCSP single response");
371 goto out;
372 }
373
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +0200374 id = (OCSP_CERTID*)OCSP_SINGLERESP_get0_id(sr);
375
Emeric Brun4147b2e2014-06-16 18:36:30 +0200376 rc = OCSP_single_get0_status(sr, &reason, &revtime, &thisupd, &nextupd);
377 if (rc != V_OCSP_CERTSTATUS_GOOD) {
378 memprintf(err, "OCSP single response: certificate status not good");
379 goto out;
380 }
381
Emeric Brun13a6b482014-06-20 15:44:34 +0200382 if (!nextupd) {
383 memprintf(err, "OCSP single response: missing nextupdate");
384 goto out;
385 }
386
Emeric Brunc8b27b62014-06-19 14:16:17 +0200387 rc = OCSP_check_validity(thisupd, nextupd, OCSP_MAX_RESPONSE_TIME_SKEW, -1);
Emeric Brun4147b2e2014-06-16 18:36:30 +0200388 if (!rc) {
389 memprintf(err, "OCSP single response: no longer valid.");
390 goto out;
391 }
392
393 if (cid) {
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +0200394 if (OCSP_id_cmp(id, cid)) {
Emeric Brun4147b2e2014-06-16 18:36:30 +0200395 memprintf(err, "OCSP single response: Certificate ID does not match certificate and issuer");
396 goto out;
397 }
398 }
399
400 if (!ocsp) {
401 unsigned char key[OCSP_MAX_CERTID_ASN1_LENGTH];
402 unsigned char *p;
403
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +0200404 rc = i2d_OCSP_CERTID(id, NULL);
Emeric Brun4147b2e2014-06-16 18:36:30 +0200405 if (!rc) {
406 memprintf(err, "OCSP single response: Unable to encode Certificate ID");
407 goto out;
408 }
409
410 if (rc > OCSP_MAX_CERTID_ASN1_LENGTH) {
411 memprintf(err, "OCSP single response: Certificate ID too long");
412 goto out;
413 }
414
415 p = key;
416 memset(key, 0, OCSP_MAX_CERTID_ASN1_LENGTH);
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +0200417 i2d_OCSP_CERTID(id, &p);
Emeric Brun4147b2e2014-06-16 18:36:30 +0200418 ocsp = (struct certificate_ocsp *)ebmb_lookup(&cert_ocsp_tree, key, OCSP_MAX_CERTID_ASN1_LENGTH);
419 if (!ocsp) {
420 memprintf(err, "OCSP single response: Certificate ID does not match any certificate or issuer");
421 goto out;
422 }
423 }
424
425 /* According to comments on "chunk_dup", the
426 previous chunk buffer will be freed */
427 if (!chunk_dup(&ocsp->response, ocsp_response)) {
428 memprintf(err, "OCSP response: Memory allocation error");
429 goto out;
430 }
431
Emeric Brun4f3c87a2014-06-20 15:46:13 +0200432 ocsp->expire = asn1_generalizedtime_to_epoch(nextupd) - OCSP_MAX_RESPONSE_TIME_SKEW;
433
Emeric Brun4147b2e2014-06-16 18:36:30 +0200434 ret = 0;
435out:
436 if (bs)
437 OCSP_BASICRESP_free(bs);
438
439 if (resp)
440 OCSP_RESPONSE_free(resp);
441
442 return ret;
443}
444/*
445 * External function use to update the OCSP response in the OCSP response's
446 * containers tree. The chunk 'ocsp_response' must contain the OCSP response
447 * to update in DER format.
448 *
449 * Returns 0 on success, 1 in error case.
450 */
451int ssl_sock_update_ocsp_response(struct chunk *ocsp_response, char **err)
452{
453 return ssl_sock_load_ocsp_response(ocsp_response, NULL, NULL, err);
454}
455
456/*
457 * This function load the OCSP Resonse in DER format contained in file at
458 * path 'ocsp_path' and call 'ssl_sock_load_ocsp_response'
459 *
460 * Returns 0 on success, 1 in error case.
461 */
462static int ssl_sock_load_ocsp_response_from_file(const char *ocsp_path, struct certificate_ocsp *ocsp, OCSP_CERTID *cid, char **err)
463{
464 int fd = -1;
465 int r = 0;
466 int ret = 1;
467
468 fd = open(ocsp_path, O_RDONLY);
469 if (fd == -1) {
470 memprintf(err, "Error opening OCSP response file");
471 goto end;
472 }
473
474 trash.len = 0;
475 while (trash.len < trash.size) {
476 r = read(fd, trash.str + trash.len, trash.size - trash.len);
477 if (r < 0) {
478 if (errno == EINTR)
479 continue;
480
481 memprintf(err, "Error reading OCSP response from file");
482 goto end;
483 }
484 else if (r == 0) {
485 break;
486 }
487 trash.len += r;
488 }
489
490 close(fd);
491 fd = -1;
492
493 ret = ssl_sock_load_ocsp_response(&trash, ocsp, cid, err);
494end:
495 if (fd != -1)
496 close(fd);
497
498 return ret;
499}
500
Nenad Merdanovic05552d42015-02-27 19:56:49 +0100501#if (defined SSL_CTRL_SET_TLSEXT_TICKET_KEY_CB && TLS_TICKETS_NO > 0)
502static 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)
503{
504 struct tls_sess_key *keys;
505 struct connection *conn;
506 int head;
507 int i;
508
Vincent Bernat3c2f2f22016-04-03 13:48:42 +0200509 conn = SSL_get_app_data(s);
Nenad Merdanovic146defa2015-05-09 08:46:00 +0200510 keys = objt_listener(conn->target)->bind_conf->keys_ref->tlskeys;
511 head = objt_listener(conn->target)->bind_conf->keys_ref->tls_ticket_enc_index;
Nenad Merdanovic05552d42015-02-27 19:56:49 +0100512
513 if (enc) {
514 memcpy(key_name, keys[head].name, 16);
515
516 if(!RAND_pseudo_bytes(iv, EVP_MAX_IV_LENGTH))
517 return -1;
518
519 if(!EVP_EncryptInit_ex(ectx, EVP_aes_128_cbc(), NULL, keys[head].aes_key, iv))
520 return -1;
521
522 HMAC_Init_ex(hctx, keys[head].hmac_key, 16, HASH_FUNCT(), NULL);
523
524 return 1;
525 } else {
526 for (i = 0; i < TLS_TICKETS_NO; i++) {
527 if (!memcmp(key_name, keys[(head + i) % TLS_TICKETS_NO].name, 16))
528 goto found;
529 }
530 return 0;
531
532 found:
533 HMAC_Init_ex(hctx, keys[(head + i) % TLS_TICKETS_NO].hmac_key, 16, HASH_FUNCT(), NULL);
534 if(!EVP_DecryptInit_ex(ectx, EVP_aes_128_cbc(), NULL, keys[(head + i) % TLS_TICKETS_NO].aes_key, iv))
535 return -1;
536 /* 2 for key renewal, 1 if current key is still valid */
537 return i ? 2 : 1;
538 }
Nenad Merdanovic200b0fa2015-05-09 08:46:01 +0200539}
540
541struct tls_keys_ref *tlskeys_ref_lookup(const char *filename)
542{
543 struct tls_keys_ref *ref;
544
545 list_for_each_entry(ref, &tlskeys_reference, list)
546 if (ref->filename && strcmp(filename, ref->filename) == 0)
547 return ref;
548 return NULL;
549}
550
551struct tls_keys_ref *tlskeys_ref_lookupid(int unique_id)
552{
553 struct tls_keys_ref *ref;
554
555 list_for_each_entry(ref, &tlskeys_reference, list)
556 if (ref->unique_id == unique_id)
557 return ref;
558 return NULL;
559}
560
561int ssl_sock_update_tlskey(char *filename, struct chunk *tlskey, char **err) {
562 struct tls_keys_ref *ref = tlskeys_ref_lookup(filename);
563
564 if(!ref) {
565 memprintf(err, "Unable to locate the referenced filename: %s", filename);
566 return 1;
567 }
568
Pradeep Jindalcc79b002015-08-20 18:25:17 +0530569 memcpy((char *) (ref->tlskeys + ((ref->tls_ticket_enc_index + 2) % TLS_TICKETS_NO)), tlskey->str, tlskey->len);
570 ref->tls_ticket_enc_index = (ref->tls_ticket_enc_index + 1) % TLS_TICKETS_NO;
Nenad Merdanovic200b0fa2015-05-09 08:46:01 +0200571
572 return 0;
Nenad Merdanovic05552d42015-02-27 19:56:49 +0100573}
Nenad Merdanovic200b0fa2015-05-09 08:46:01 +0200574
575/* This function finalize the configuration parsing. Its set all the
576 * automatic ids
577 */
578void tlskeys_finalize_config(void)
579{
580 int i = 0;
581 struct tls_keys_ref *ref, *ref2, *ref3;
582 struct list tkr = LIST_HEAD_INIT(tkr);
583
584 list_for_each_entry(ref, &tlskeys_reference, list) {
585 if (ref->unique_id == -1) {
586 /* Look for the first free id. */
587 while (1) {
588 list_for_each_entry(ref2, &tlskeys_reference, list) {
589 if (ref2->unique_id == i) {
590 i++;
591 break;
592 }
593 }
594 if (&ref2->list == &tlskeys_reference)
595 break;
596 }
597
598 /* Uses the unique id and increment it for the next entry. */
599 ref->unique_id = i;
600 i++;
601 }
602 }
603
604 /* This sort the reference list by id. */
605 list_for_each_entry_safe(ref, ref2, &tlskeys_reference, list) {
606 LIST_DEL(&ref->list);
607 list_for_each_entry(ref3, &tkr, list) {
608 if (ref->unique_id < ref3->unique_id) {
609 LIST_ADDQ(&ref3->list, &ref->list);
610 break;
611 }
612 }
613 if (&ref3->list == &tkr)
614 LIST_ADDQ(&tkr, &ref->list);
615 }
616
617 /* swap root */
618 LIST_ADD(&tkr, &tlskeys_reference);
619 LIST_DEL(&tkr);
620}
621
Nenad Merdanovic05552d42015-02-27 19:56:49 +0100622#endif /* SSL_CTRL_SET_TLSEXT_TICKET_KEY_CB */
623
yanbzhube2774d2015-12-10 15:07:30 -0500624int ssl_sock_get_ocsp_arg_kt_index(int evp_keytype)
625{
626 switch (evp_keytype) {
627 case EVP_PKEY_RSA:
628 return 2;
629 case EVP_PKEY_DSA:
630 return 0;
631 case EVP_PKEY_EC:
632 return 1;
633 }
634
635 return -1;
636}
637
Emeric Brun4147b2e2014-06-16 18:36:30 +0200638/*
639 * Callback used to set OCSP status extension content in server hello.
640 */
641int ssl_sock_ocsp_stapling_cbk(SSL *ssl, void *arg)
642{
yanbzhube2774d2015-12-10 15:07:30 -0500643 struct certificate_ocsp *ocsp;
644 struct ocsp_cbk_arg *ocsp_arg;
645 char *ssl_buf;
646 EVP_PKEY *ssl_pkey;
647 int key_type;
648 int index;
649
Vincent Bernat3c2f2f22016-04-03 13:48:42 +0200650 ocsp_arg = arg;
yanbzhube2774d2015-12-10 15:07:30 -0500651
652 ssl_pkey = SSL_get_privatekey(ssl);
653 if (!ssl_pkey)
654 return SSL_TLSEXT_ERR_NOACK;
655
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +0200656 key_type = EVP_PKEY_base_id(ssl_pkey);
yanbzhube2774d2015-12-10 15:07:30 -0500657
658 if (ocsp_arg->is_single && ocsp_arg->single_kt == key_type)
659 ocsp = ocsp_arg->s_ocsp;
660 else {
661 /* For multiple certs per context, we have to find the correct OCSP response based on
662 * the certificate type
663 */
664 index = ssl_sock_get_ocsp_arg_kt_index(key_type);
665
666 if (index < 0)
667 return SSL_TLSEXT_ERR_NOACK;
668
669 ocsp = ocsp_arg->m_ocsp[index];
670
671 }
Emeric Brun4147b2e2014-06-16 18:36:30 +0200672
673 if (!ocsp ||
674 !ocsp->response.str ||
Emeric Brun4f3c87a2014-06-20 15:46:13 +0200675 !ocsp->response.len ||
676 (ocsp->expire < now.tv_sec))
Emeric Brun4147b2e2014-06-16 18:36:30 +0200677 return SSL_TLSEXT_ERR_NOACK;
678
679 ssl_buf = OPENSSL_malloc(ocsp->response.len);
680 if (!ssl_buf)
681 return SSL_TLSEXT_ERR_NOACK;
682
683 memcpy(ssl_buf, ocsp->response.str, ocsp->response.len);
684 SSL_set_tlsext_status_ocsp_resp(ssl, ssl_buf, ocsp->response.len);
685
686 return SSL_TLSEXT_ERR_OK;
687}
688
689/*
690 * This function enables the handling of OCSP status extension on 'ctx' if a
691 * file name 'cert_path' suffixed using ".ocsp" is present.
692 * To enable OCSP status extension, the issuer's certificate is mandatory.
693 * It should be present in the certificate's extra chain builded from file
694 * 'cert_path'. If not found, the issuer certificate is loaded from a file
695 * named 'cert_path' suffixed using '.issuer'.
696 *
697 * In addition, ".ocsp" file content is loaded as a DER format of an OCSP
698 * response. If file is empty or content is not a valid OCSP response,
699 * OCSP status extension is enabled but OCSP response is ignored (a warning
700 * is displayed).
701 *
702 * Returns 1 if no ".ocsp" file found, 0 if OCSP status extension is
703 * succesfully enabled, or -1 in other error case.
704 */
705static int ssl_sock_load_ocsp(SSL_CTX *ctx, const char *cert_path)
706{
707
708 BIO *in = NULL;
709 X509 *x, *xi = NULL, *issuer = NULL;
710 STACK_OF(X509) *chain = NULL;
711 OCSP_CERTID *cid = NULL;
712 SSL *ssl;
713 char ocsp_path[MAXPATHLEN+1];
714 int i, ret = -1;
715 struct stat st;
716 struct certificate_ocsp *ocsp = NULL, *iocsp;
717 char *warn = NULL;
718 unsigned char *p;
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +0200719 pem_password_cb *passwd_cb;
720 void *passwd_cb_userdata;
721 void (*callback) (void);
Emeric Brun4147b2e2014-06-16 18:36:30 +0200722
723 snprintf(ocsp_path, MAXPATHLEN+1, "%s.ocsp", cert_path);
724
725 if (stat(ocsp_path, &st))
726 return 1;
727
728 ssl = SSL_new(ctx);
729 if (!ssl)
730 goto out;
731
732 x = SSL_get_certificate(ssl);
733 if (!x)
734 goto out;
735
736 /* Try to lookup for issuer in certificate extra chain */
737#ifdef SSL_CTRL_GET_EXTRA_CHAIN_CERTS
738 SSL_CTX_get_extra_chain_certs(ctx, &chain);
739#else
740 chain = ctx->extra_certs;
741#endif
742 for (i = 0; i < sk_X509_num(chain); i++) {
743 issuer = sk_X509_value(chain, i);
744 if (X509_check_issued(issuer, x) == X509_V_OK)
745 break;
746 else
747 issuer = NULL;
748 }
749
750 /* If not found try to load issuer from a suffixed file */
751 if (!issuer) {
752 char issuer_path[MAXPATHLEN+1];
753
754 in = BIO_new(BIO_s_file());
755 if (!in)
756 goto out;
757
758 snprintf(issuer_path, MAXPATHLEN+1, "%s.issuer", cert_path);
759 if (BIO_read_filename(in, issuer_path) <= 0)
760 goto out;
761
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +0200762 passwd_cb = SSL_CTX_get_default_passwd_cb(ctx);
763 passwd_cb_userdata = SSL_CTX_get_default_passwd_cb_userdata(ctx);
764
765 xi = PEM_read_bio_X509_AUX(in, NULL, passwd_cb, passwd_cb_userdata);
Emeric Brun4147b2e2014-06-16 18:36:30 +0200766 if (!xi)
767 goto out;
768
769 if (X509_check_issued(xi, x) != X509_V_OK)
770 goto out;
771
772 issuer = xi;
773 }
774
775 cid = OCSP_cert_to_id(0, x, issuer);
776 if (!cid)
777 goto out;
778
779 i = i2d_OCSP_CERTID(cid, NULL);
780 if (!i || (i > OCSP_MAX_CERTID_ASN1_LENGTH))
781 goto out;
782
Vincent Bernat02779b62016-04-03 13:48:43 +0200783 ocsp = calloc(1, sizeof(*ocsp));
Emeric Brun4147b2e2014-06-16 18:36:30 +0200784 if (!ocsp)
785 goto out;
786
787 p = ocsp->key_data;
788 i2d_OCSP_CERTID(cid, &p);
789
790 iocsp = (struct certificate_ocsp *)ebmb_insert(&cert_ocsp_tree, &ocsp->key, OCSP_MAX_CERTID_ASN1_LENGTH);
791 if (iocsp == ocsp)
792 ocsp = NULL;
793
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +0200794#ifndef SSL_CTX_get_tlsext_status_cb
795# define SSL_CTX_get_tlsext_status_cb(ctx, cb) \
796 *cb = (void (*) (void))ctx->tlsext_status_cb;
797#endif
798 SSL_CTX_get_tlsext_status_cb(ctx, &callback);
799
800 if (!callback) {
Vincent Bernat02779b62016-04-03 13:48:43 +0200801 struct ocsp_cbk_arg *cb_arg = calloc(1, sizeof(*cb_arg));
yanbzhube2774d2015-12-10 15:07:30 -0500802
803 cb_arg->is_single = 1;
804 cb_arg->s_ocsp = iocsp;
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +0200805
806 cb_arg->single_kt = EVP_PKEY_base_id(X509_get_pubkey(x));
yanbzhube2774d2015-12-10 15:07:30 -0500807
808 SSL_CTX_set_tlsext_status_cb(ctx, ssl_sock_ocsp_stapling_cbk);
809 SSL_CTX_set_tlsext_status_arg(ctx, cb_arg);
810 } else {
811 /*
812 * If the ctx has a status CB, then we have previously set an OCSP staple for this ctx
813 * Update that cb_arg with the new cert's staple
814 */
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +0200815 struct ocsp_cbk_arg *cb_arg;
yanbzhube2774d2015-12-10 15:07:30 -0500816 struct certificate_ocsp *tmp_ocsp;
817 int index;
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +0200818 int key_type;
819
820#ifdef SSL_CTX_get_tlsext_status_arg
821 SSL_CTX_ctrl(ctx, SSL_CTRL_GET_TLSEXT_STATUS_REQ_CB_ARG, 0, &cb_arg);
822#else
823 cb_arg = ctx->tlsext_status_arg;
824#endif
yanbzhube2774d2015-12-10 15:07:30 -0500825
826 /*
827 * The following few lines will convert cb_arg from a single ocsp to multi ocsp
828 * the order of operations below matter, take care when changing it
829 */
830 tmp_ocsp = cb_arg->s_ocsp;
831 index = ssl_sock_get_ocsp_arg_kt_index(cb_arg->single_kt);
832 cb_arg->s_ocsp = NULL;
833 cb_arg->m_ocsp[index] = tmp_ocsp;
834 cb_arg->is_single = 0;
835 cb_arg->single_kt = 0;
836
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +0200837 key_type = EVP_PKEY_base_id(X509_get_pubkey(x));
838 index = ssl_sock_get_ocsp_arg_kt_index(key_type);
yanbzhube2774d2015-12-10 15:07:30 -0500839 if (index >= 0 && !cb_arg->m_ocsp[index])
840 cb_arg->m_ocsp[index] = iocsp;
841
842 }
Emeric Brun4147b2e2014-06-16 18:36:30 +0200843
844 ret = 0;
845
846 warn = NULL;
847 if (ssl_sock_load_ocsp_response_from_file(ocsp_path, iocsp, cid, &warn)) {
848 memprintf(&warn, "Loading '%s': %s. Content will be ignored", ocsp_path, warn ? warn : "failure");
849 Warning("%s.\n", warn);
850 }
851
852out:
853 if (ssl)
854 SSL_free(ssl);
855
856 if (in)
857 BIO_free(in);
858
859 if (xi)
860 X509_free(xi);
861
862 if (cid)
863 OCSP_CERTID_free(cid);
864
865 if (ocsp)
866 free(ocsp);
867
868 if (warn)
869 free(warn);
870
871
872 return ret;
873}
874
875#endif
876
Daniel Jakots54ffb912015-11-06 20:02:41 +0100877#if (OPENSSL_VERSION_NUMBER >= 0x1000200fL && !defined OPENSSL_NO_TLSEXT && !defined OPENSSL_IS_BORINGSSL && !defined LIBRESSL_VERSION_NUMBER)
Janusz Dziemidowicz2c701b52015-03-07 23:03:59 +0100878
879#define CT_EXTENSION_TYPE 18
880
881static int sctl_ex_index = -1;
882
883/*
884 * Try to parse Signed Certificate Timestamp List structure. This function
885 * makes only basic test if the data seems like SCTL. No signature validation
886 * is performed.
887 */
888static int ssl_sock_parse_sctl(struct chunk *sctl)
889{
890 int ret = 1;
891 int len, pos, sct_len;
892 unsigned char *data;
893
894 if (sctl->len < 2)
895 goto out;
896
897 data = (unsigned char *)sctl->str;
898 len = (data[0] << 8) | data[1];
899
900 if (len + 2 != sctl->len)
901 goto out;
902
903 data = data + 2;
904 pos = 0;
905 while (pos < len) {
906 if (len - pos < 2)
907 goto out;
908
909 sct_len = (data[pos] << 8) | data[pos + 1];
910 if (pos + sct_len + 2 > len)
911 goto out;
912
913 pos += sct_len + 2;
914 }
915
916 ret = 0;
917
918out:
919 return ret;
920}
921
922static int ssl_sock_load_sctl_from_file(const char *sctl_path, struct chunk **sctl)
923{
924 int fd = -1;
925 int r = 0;
926 int ret = 1;
927
928 *sctl = NULL;
929
930 fd = open(sctl_path, O_RDONLY);
931 if (fd == -1)
932 goto end;
933
934 trash.len = 0;
935 while (trash.len < trash.size) {
936 r = read(fd, trash.str + trash.len, trash.size - trash.len);
937 if (r < 0) {
938 if (errno == EINTR)
939 continue;
940
941 goto end;
942 }
943 else if (r == 0) {
944 break;
945 }
946 trash.len += r;
947 }
948
949 ret = ssl_sock_parse_sctl(&trash);
950 if (ret)
951 goto end;
952
Vincent Bernat02779b62016-04-03 13:48:43 +0200953 *sctl = calloc(1, sizeof(**sctl));
Janusz Dziemidowicz2c701b52015-03-07 23:03:59 +0100954 if (!chunk_dup(*sctl, &trash)) {
955 free(*sctl);
956 *sctl = NULL;
957 goto end;
958 }
959
960end:
961 if (fd != -1)
962 close(fd);
963
964 return ret;
965}
966
967int ssl_sock_sctl_add_cbk(SSL *ssl, unsigned ext_type, const unsigned char **out, size_t *outlen, int *al, void *add_arg)
968{
Vincent Bernat3c2f2f22016-04-03 13:48:42 +0200969 struct chunk *sctl = add_arg;
Janusz Dziemidowicz2c701b52015-03-07 23:03:59 +0100970
971 *out = (unsigned char *)sctl->str;
972 *outlen = sctl->len;
973
974 return 1;
975}
976
977int ssl_sock_sctl_parse_cbk(SSL *s, unsigned int ext_type, const unsigned char *in, size_t inlen, int *al, void *parse_arg)
978{
979 return 1;
980}
981
982static int ssl_sock_load_sctl(SSL_CTX *ctx, const char *cert_path)
983{
984 char sctl_path[MAXPATHLEN+1];
985 int ret = -1;
986 struct stat st;
987 struct chunk *sctl = NULL;
988
989 snprintf(sctl_path, MAXPATHLEN+1, "%s.sctl", cert_path);
990
991 if (stat(sctl_path, &st))
992 return 1;
993
994 if (ssl_sock_load_sctl_from_file(sctl_path, &sctl))
995 goto out;
996
997 if (!SSL_CTX_add_server_custom_ext(ctx, CT_EXTENSION_TYPE, ssl_sock_sctl_add_cbk, NULL, sctl, ssl_sock_sctl_parse_cbk, NULL)) {
998 free(sctl);
999 goto out;
1000 }
1001
1002 SSL_CTX_set_ex_data(ctx, sctl_ex_index, sctl);
1003
1004 ret = 0;
1005
1006out:
1007 return ret;
1008}
1009
1010#endif
1011
Emeric Brune1f38db2012-09-03 20:36:47 +02001012void ssl_sock_infocbk(const SSL *ssl, int where, int ret)
1013{
Vincent Bernat3c2f2f22016-04-03 13:48:42 +02001014 struct connection *conn = SSL_get_app_data(ssl);
Emeric Brund8b2bb52014-01-28 15:43:53 +01001015 BIO *write_bio;
Willy Tarreau622317d2015-02-27 16:36:16 +01001016 (void)ret; /* shut gcc stupid warning */
Emeric Brune1f38db2012-09-03 20:36:47 +02001017
1018 if (where & SSL_CB_HANDSHAKE_START) {
1019 /* Disable renegotiation (CVE-2009-3555) */
Willy Tarreau20879a02012-12-03 16:32:10 +01001020 if (conn->flags & CO_FL_CONNECTED) {
Emeric Brune1f38db2012-09-03 20:36:47 +02001021 conn->flags |= CO_FL_ERROR;
Willy Tarreau20879a02012-12-03 16:32:10 +01001022 conn->err_code = CO_ER_SSL_RENEG;
1023 }
Emeric Brune1f38db2012-09-03 20:36:47 +02001024 }
Emeric Brund8b2bb52014-01-28 15:43:53 +01001025
1026 if ((where & SSL_CB_ACCEPT_LOOP) == SSL_CB_ACCEPT_LOOP) {
1027 if (!(conn->xprt_st & SSL_SOCK_ST_FL_16K_WBFSIZE)) {
1028 /* Long certificate chains optimz
1029 If write and read bios are differents, we
1030 consider that the buffering was activated,
1031 so we rise the output buffer size from 4k
1032 to 16k */
1033 write_bio = SSL_get_wbio(ssl);
1034 if (write_bio != SSL_get_rbio(ssl)) {
1035 BIO_set_write_buffer_size(write_bio, 16384);
1036 conn->xprt_st |= SSL_SOCK_ST_FL_16K_WBFSIZE;
1037 }
1038 }
1039 }
Emeric Brunfc0421f2012-09-07 17:30:07 +02001040}
1041
Emeric Brune64aef12012-09-21 13:15:06 +02001042/* Callback is called for each certificate of the chain during a verify
1043 ok is set to 1 if preverify detect no error on current certificate.
1044 Returns 0 to break the handshake, 1 otherwise. */
Evan Broderbe554312013-06-27 00:05:25 -07001045int ssl_sock_bind_verifycbk(int ok, X509_STORE_CTX *x_store)
Emeric Brune64aef12012-09-21 13:15:06 +02001046{
1047 SSL *ssl;
1048 struct connection *conn;
Emeric Brun81c00f02012-09-21 14:31:21 +02001049 int err, depth;
Emeric Brune64aef12012-09-21 13:15:06 +02001050
1051 ssl = X509_STORE_CTX_get_ex_data(x_store, SSL_get_ex_data_X509_STORE_CTX_idx());
Vincent Bernat3c2f2f22016-04-03 13:48:42 +02001052 conn = SSL_get_app_data(ssl);
Emeric Brune64aef12012-09-21 13:15:06 +02001053
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02001054 conn->xprt_st |= SSL_SOCK_ST_FL_VERIFY_DONE;
Emeric Brune64aef12012-09-21 13:15:06 +02001055
Emeric Brun81c00f02012-09-21 14:31:21 +02001056 if (ok) /* no errors */
1057 return ok;
1058
1059 depth = X509_STORE_CTX_get_error_depth(x_store);
1060 err = X509_STORE_CTX_get_error(x_store);
1061
1062 /* check if CA error needs to be ignored */
1063 if (depth > 0) {
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02001064 if (!SSL_SOCK_ST_TO_CA_ERROR(conn->xprt_st)) {
1065 conn->xprt_st |= SSL_SOCK_CA_ERROR_TO_ST(err);
1066 conn->xprt_st |= SSL_SOCK_CAEDEPTH_TO_ST(depth);
Emeric Brunf282a812012-09-21 15:27:54 +02001067 }
1068
Emeric Brun1eb20ef2012-12-03 13:24:29 +01001069 if (objt_listener(conn->target)->bind_conf->ca_ignerr & (1ULL << err)) {
Thierry FOURNIER / OZON.IO8b068c22016-10-10 11:59:50 +02001070 ssl_sock_dump_errors(conn);
Emeric Brun1eb20ef2012-12-03 13:24:29 +01001071 ERR_clear_error();
Emeric Brun81c00f02012-09-21 14:31:21 +02001072 return 1;
Emeric Brun1eb20ef2012-12-03 13:24:29 +01001073 }
Emeric Brun81c00f02012-09-21 14:31:21 +02001074
Willy Tarreau20879a02012-12-03 16:32:10 +01001075 conn->err_code = CO_ER_SSL_CA_FAIL;
Emeric Brun81c00f02012-09-21 14:31:21 +02001076 return 0;
1077 }
1078
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02001079 if (!SSL_SOCK_ST_TO_CRTERROR(conn->xprt_st))
1080 conn->xprt_st |= SSL_SOCK_CRTERROR_TO_ST(err);
Emeric Brunf282a812012-09-21 15:27:54 +02001081
Emeric Brun81c00f02012-09-21 14:31:21 +02001082 /* check if certificate error needs to be ignored */
Emeric Brun1eb20ef2012-12-03 13:24:29 +01001083 if (objt_listener(conn->target)->bind_conf->crt_ignerr & (1ULL << err)) {
Thierry FOURNIER / OZON.IO8b068c22016-10-10 11:59:50 +02001084 ssl_sock_dump_errors(conn);
Emeric Brun1eb20ef2012-12-03 13:24:29 +01001085 ERR_clear_error();
Emeric Brun81c00f02012-09-21 14:31:21 +02001086 return 1;
Emeric Brun1eb20ef2012-12-03 13:24:29 +01001087 }
Emeric Brun81c00f02012-09-21 14:31:21 +02001088
Willy Tarreau20879a02012-12-03 16:32:10 +01001089 conn->err_code = CO_ER_SSL_CRT_FAIL;
Emeric Brun81c00f02012-09-21 14:31:21 +02001090 return 0;
Emeric Brune64aef12012-09-21 13:15:06 +02001091}
1092
Emeric Brun29f037d2014-04-25 19:05:36 +02001093/* Callback is called for ssl protocol analyse */
1094void ssl_sock_msgcbk(int write_p, int version, int content_type, const void *buf, size_t len, SSL *ssl, void *arg)
1095{
Emeric Brun29f037d2014-04-25 19:05:36 +02001096#ifdef TLS1_RT_HEARTBEAT
1097 /* test heartbeat received (write_p is set to 0
1098 for a received record) */
Willy Tarreauf51c6982014-04-25 20:02:39 +02001099 if ((content_type == TLS1_RT_HEARTBEAT) && (write_p == 0)) {
Vincent Bernat3c2f2f22016-04-03 13:48:42 +02001100 struct connection *conn = SSL_get_app_data(ssl);
Willy Tarreauf51c6982014-04-25 20:02:39 +02001101 const unsigned char *p = buf;
1102 unsigned int payload;
1103
Emeric Brun29f037d2014-04-25 19:05:36 +02001104 conn->xprt_st |= SSL_SOCK_RECV_HEARTBEAT;
Willy Tarreauf51c6982014-04-25 20:02:39 +02001105
1106 /* Check if this is a CVE-2014-0160 exploitation attempt. */
1107 if (*p != TLS1_HB_REQUEST)
1108 return;
1109
Willy Tarreauaeed6722014-04-25 23:59:58 +02001110 if (len < 1 + 2 + 16) /* 1 type + 2 size + 0 payload + 16 padding */
Willy Tarreauf51c6982014-04-25 20:02:39 +02001111 goto kill_it;
1112
1113 payload = (p[1] * 256) + p[2];
Willy Tarreau3b2fdb62014-04-25 23:44:22 +02001114 if (3 + payload + 16 <= len)
Willy Tarreauf51c6982014-04-25 20:02:39 +02001115 return; /* OK no problem */
Willy Tarreauaeed6722014-04-25 23:59:58 +02001116 kill_it:
Willy Tarreau3b2fdb62014-04-25 23:44:22 +02001117 /* We have a clear heartbleed attack (CVE-2014-0160), the
1118 * advertised payload is larger than the advertised packet
1119 * length, so we have garbage in the buffer between the
1120 * payload and the end of the buffer (p+len). We can't know
1121 * if the SSL stack is patched, and we don't know if we can
1122 * safely wipe out the area between p+3+len and payload.
1123 * So instead, we prevent the response from being sent by
1124 * setting the max_send_fragment to 0 and we report an SSL
1125 * error, which will kill this connection. It will be reported
1126 * above as SSL_ERROR_SSL while an other handshake failure with
Willy Tarreauf51c6982014-04-25 20:02:39 +02001127 * a heartbeat message will be reported as SSL_ERROR_SYSCALL.
1128 */
Willy Tarreau3b2fdb62014-04-25 23:44:22 +02001129 ssl->max_send_fragment = 0;
Willy Tarreauf51c6982014-04-25 20:02:39 +02001130 SSLerr(SSL_F_TLS1_HEARTBEAT, SSL_R_SSL_HANDSHAKE_FAILURE);
1131 return;
1132 }
Emeric Brun29f037d2014-04-25 19:05:36 +02001133#endif
1134}
1135
Willy Tarreau6c9a3d52012-10-18 18:57:14 +02001136#ifdef OPENSSL_NPN_NEGOTIATED
1137/* This callback is used so that the server advertises the list of
1138 * negociable protocols for NPN.
1139 */
1140static int ssl_sock_advertise_npn_protos(SSL *s, const unsigned char **data,
1141 unsigned int *len, void *arg)
1142{
1143 struct bind_conf *conf = arg;
1144
1145 *data = (const unsigned char *)conf->npn_str;
1146 *len = conf->npn_len;
1147 return SSL_TLSEXT_ERR_OK;
1148}
1149#endif
1150
Dirkjan Bussink48f1c4e2014-02-13 12:29:42 +01001151#ifdef TLSEXT_TYPE_application_layer_protocol_negotiation
Willy Tarreauab861d32013-04-02 02:30:41 +02001152/* This callback is used so that the server advertises the list of
1153 * negociable protocols for ALPN.
1154 */
Dirkjan Bussink48f1c4e2014-02-13 12:29:42 +01001155static int ssl_sock_advertise_alpn_protos(SSL *s, const unsigned char **out,
1156 unsigned char *outlen,
1157 const unsigned char *server,
1158 unsigned int server_len, void *arg)
Willy Tarreauab861d32013-04-02 02:30:41 +02001159{
1160 struct bind_conf *conf = arg;
1161
Dirkjan Bussink48f1c4e2014-02-13 12:29:42 +01001162 if (SSL_select_next_proto((unsigned char**) out, outlen, (const unsigned char *)conf->alpn_str,
1163 conf->alpn_len, server, server_len) != OPENSSL_NPN_NEGOTIATED) {
1164 return SSL_TLSEXT_ERR_NOACK;
1165 }
Willy Tarreauab861d32013-04-02 02:30:41 +02001166 return SSL_TLSEXT_ERR_OK;
1167}
1168#endif
1169
Willy Tarreauc8ad3be2015-06-17 15:48:26 +02001170#ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME
Christopher Faulet85b5a1a2015-10-09 11:46:32 +02001171static DH *ssl_get_tmp_dh(SSL *ssl, int export, int keylen);
1172
Christopher Faulet30548802015-06-11 13:39:32 +02001173/* Create a X509 certificate with the specified servername and serial. This
1174 * function returns a SSL_CTX object or NULL if an error occurs. */
Christopher Faulet7969a332015-10-09 11:15:03 +02001175static SSL_CTX *
Christopher Faulet635c0ad2015-11-12 11:35:51 +01001176ssl_sock_do_create_cert(const char *servername, struct bind_conf *bind_conf, SSL *ssl)
Christopher Faulet31af49d2015-06-09 17:29:50 +02001177{
Christopher Faulet635c0ad2015-11-12 11:35:51 +01001178 static unsigned int serial = 0;
1179
Christopher Faulet7969a332015-10-09 11:15:03 +02001180 X509 *cacert = bind_conf->ca_sign_cert;
1181 EVP_PKEY *capkey = bind_conf->ca_sign_pkey;
Christopher Faulet31af49d2015-06-09 17:29:50 +02001182 SSL_CTX *ssl_ctx = NULL;
1183 X509 *newcrt = NULL;
1184 EVP_PKEY *pkey = NULL;
Christopher Faulet31af49d2015-06-09 17:29:50 +02001185 X509_NAME *name;
1186 const EVP_MD *digest;
1187 X509V3_CTX ctx;
1188 unsigned int i;
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02001189 int key_type;
Christopher Faulet31af49d2015-06-09 17:29:50 +02001190
Christopher Faulet7969a332015-10-09 11:15:03 +02001191 /* Get the private key of the defautl certificate and use it */
1192 if (!(pkey = SSL_get_privatekey(ssl)))
Christopher Faulet31af49d2015-06-09 17:29:50 +02001193 goto mkcert_error;
1194
1195 /* Create the certificate */
1196 if (!(newcrt = X509_new()))
1197 goto mkcert_error;
1198
1199 /* Set version number for the certificate (X509v3) and the serial
1200 * number */
1201 if (X509_set_version(newcrt, 2L) != 1)
1202 goto mkcert_error;
Christopher Faulet635c0ad2015-11-12 11:35:51 +01001203 if (!serial)
1204 serial = now_ms;
1205 ASN1_INTEGER_set(X509_get_serialNumber(newcrt), serial++);
Christopher Faulet31af49d2015-06-09 17:29:50 +02001206
1207 /* Set duration for the certificate */
1208 if (!X509_gmtime_adj(X509_get_notBefore(newcrt), (long)-60*60*24) ||
1209 !X509_gmtime_adj(X509_get_notAfter(newcrt),(long)60*60*24*365))
1210 goto mkcert_error;
1211
1212 /* set public key in the certificate */
1213 if (X509_set_pubkey(newcrt, pkey) != 1)
1214 goto mkcert_error;
1215
1216 /* Set issuer name from the CA */
1217 if (!(name = X509_get_subject_name(cacert)))
1218 goto mkcert_error;
1219 if (X509_set_issuer_name(newcrt, name) != 1)
1220 goto mkcert_error;
1221
1222 /* Set the subject name using the same, but the CN */
1223 name = X509_NAME_dup(name);
1224 if (X509_NAME_add_entry_by_txt(name, "CN", MBSTRING_ASC,
1225 (const unsigned char *)servername,
1226 -1, -1, 0) != 1) {
1227 X509_NAME_free(name);
1228 goto mkcert_error;
1229 }
1230 if (X509_set_subject_name(newcrt, name) != 1) {
1231 X509_NAME_free(name);
1232 goto mkcert_error;
1233 }
1234 X509_NAME_free(name);
1235
1236 /* Add x509v3 extensions as specified */
1237 X509V3_set_ctx(&ctx, cacert, newcrt, NULL, NULL, 0);
1238 for (i = 0; i < X509V3_EXT_SIZE; i++) {
1239 X509_EXTENSION *ext;
1240
1241 if (!(ext = X509V3_EXT_conf(NULL, &ctx, x509v3_ext_names[i], x509v3_ext_values[i])))
1242 goto mkcert_error;
1243 if (!X509_add_ext(newcrt, ext, -1)) {
1244 X509_EXTENSION_free(ext);
1245 goto mkcert_error;
1246 }
1247 X509_EXTENSION_free(ext);
1248 }
1249
1250 /* Sign the certificate with the CA private key */
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02001251
1252 key_type = EVP_PKEY_base_id(capkey);
1253
1254 if (key_type == EVP_PKEY_DSA)
1255 digest = EVP_sha1();
1256 else if (key_type == EVP_PKEY_RSA)
Christopher Faulet31af49d2015-06-09 17:29:50 +02001257 digest = EVP_sha256();
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02001258 else if (key_type == EVP_PKEY_EC)
Christopher Faulet7969a332015-10-09 11:15:03 +02001259 digest = EVP_sha256();
1260 else {
Christopher Faulete7db2162015-10-19 13:59:24 +02001261#if (OPENSSL_VERSION_NUMBER >= 0x1000000fL)
Christopher Faulet7969a332015-10-09 11:15:03 +02001262 int nid;
1263
1264 if (EVP_PKEY_get_default_digest_nid(capkey, &nid) <= 0)
1265 goto mkcert_error;
1266 if (!(digest = EVP_get_digestbynid(nid)))
1267 goto mkcert_error;
Christopher Faulete7db2162015-10-19 13:59:24 +02001268#else
1269 goto mkcert_error;
1270#endif
Christopher Faulet7969a332015-10-09 11:15:03 +02001271 }
1272
Christopher Faulet31af49d2015-06-09 17:29:50 +02001273 if (!(X509_sign(newcrt, capkey, digest)))
1274 goto mkcert_error;
1275
1276 /* Create and set the new SSL_CTX */
1277 if (!(ssl_ctx = SSL_CTX_new(SSLv23_server_method())))
1278 goto mkcert_error;
1279 if (!SSL_CTX_use_PrivateKey(ssl_ctx, pkey))
1280 goto mkcert_error;
1281 if (!SSL_CTX_use_certificate(ssl_ctx, newcrt))
1282 goto mkcert_error;
1283 if (!SSL_CTX_check_private_key(ssl_ctx))
1284 goto mkcert_error;
1285
1286 if (newcrt) X509_free(newcrt);
Christopher Faulet7969a332015-10-09 11:15:03 +02001287
Christopher Faulet85b5a1a2015-10-09 11:46:32 +02001288 SSL_CTX_set_tmp_dh_callback(ssl_ctx, ssl_get_tmp_dh);
1289#if defined(SSL_CTX_set_tmp_ecdh) && !defined(OPENSSL_NO_ECDH)
1290 {
1291 const char *ecdhe = (bind_conf->ecdhe ? bind_conf->ecdhe : ECDHE_DEFAULT_CURVE);
1292 EC_KEY *ecc;
1293 int nid;
1294
1295 if ((nid = OBJ_sn2nid(ecdhe)) == NID_undef)
1296 goto end;
1297 if (!(ecc = EC_KEY_new_by_curve_name(nid)))
1298 goto end;
1299 SSL_CTX_set_tmp_ecdh(ssl_ctx, ecc);
1300 EC_KEY_free(ecc);
1301 }
1302#endif
1303 end:
Christopher Faulet31af49d2015-06-09 17:29:50 +02001304 return ssl_ctx;
1305
1306 mkcert_error:
1307 if (ssl_ctx) SSL_CTX_free(ssl_ctx);
1308 if (newcrt) X509_free(newcrt);
Christopher Faulet31af49d2015-06-09 17:29:50 +02001309 return NULL;
1310}
1311
Christopher Faulet7969a332015-10-09 11:15:03 +02001312SSL_CTX *
Christopher Faulet635c0ad2015-11-12 11:35:51 +01001313ssl_sock_create_cert(struct connection *conn, const char *servername, unsigned int key)
Christopher Faulet7969a332015-10-09 11:15:03 +02001314{
1315 struct bind_conf *bind_conf = objt_listener(conn->target)->bind_conf;
Christopher Faulet635c0ad2015-11-12 11:35:51 +01001316
1317 return ssl_sock_do_create_cert(servername, bind_conf, conn->xprt_ctx);
Christopher Faulet7969a332015-10-09 11:15:03 +02001318}
1319
Christopher Faulet30548802015-06-11 13:39:32 +02001320/* Do a lookup for a certificate in the LRU cache used to store generated
1321 * certificates. */
1322SSL_CTX *
Christopher Faulet635c0ad2015-11-12 11:35:51 +01001323ssl_sock_get_generated_cert(unsigned int key, struct bind_conf *bind_conf)
Christopher Faulet30548802015-06-11 13:39:32 +02001324{
1325 struct lru64 *lru = NULL;
1326
1327 if (ssl_ctx_lru_tree) {
Christopher Faulet635c0ad2015-11-12 11:35:51 +01001328 lru = lru64_lookup(key, ssl_ctx_lru_tree, bind_conf->ca_sign_cert, 0);
Christopher Faulet30548802015-06-11 13:39:32 +02001329 if (lru && lru->domain)
1330 return (SSL_CTX *)lru->data;
1331 }
1332 return NULL;
1333}
1334
Christopher Fauletd2cab922015-07-28 16:03:47 +02001335/* Set a certificate int the LRU cache used to store generated
1336 * certificate. Return 0 on success, otherwise -1 */
1337int
Christopher Faulet635c0ad2015-11-12 11:35:51 +01001338ssl_sock_set_generated_cert(SSL_CTX *ssl_ctx, unsigned int key, struct bind_conf *bind_conf)
Christopher Faulet30548802015-06-11 13:39:32 +02001339{
1340 struct lru64 *lru = NULL;
1341
1342 if (ssl_ctx_lru_tree) {
Christopher Faulet635c0ad2015-11-12 11:35:51 +01001343 lru = lru64_get(key, ssl_ctx_lru_tree, bind_conf->ca_sign_cert, 0);
Christopher Faulet30548802015-06-11 13:39:32 +02001344 if (!lru)
Christopher Fauletd2cab922015-07-28 16:03:47 +02001345 return -1;
Christopher Faulet30548802015-06-11 13:39:32 +02001346 if (lru->domain && lru->data)
1347 lru->free((SSL_CTX *)lru->data);
Christopher Faulet7969a332015-10-09 11:15:03 +02001348 lru64_commit(lru, ssl_ctx, bind_conf->ca_sign_cert, 0, (void (*)(void *))SSL_CTX_free);
Christopher Fauletd2cab922015-07-28 16:03:47 +02001349 return 0;
Christopher Faulet30548802015-06-11 13:39:32 +02001350 }
Christopher Fauletd2cab922015-07-28 16:03:47 +02001351 return -1;
Christopher Faulet30548802015-06-11 13:39:32 +02001352}
1353
Christopher Faulet635c0ad2015-11-12 11:35:51 +01001354/* Compute the key of the certificate. */
Christopher Faulet30548802015-06-11 13:39:32 +02001355unsigned int
Christopher Faulet635c0ad2015-11-12 11:35:51 +01001356ssl_sock_generated_cert_key(const void *data, size_t len)
Christopher Faulet30548802015-06-11 13:39:32 +02001357{
1358 return XXH32(data, len, ssl_ctx_lru_seed);
1359}
1360
Willy Tarreau2f63ef42015-10-20 15:16:01 +02001361/* Generate a cert and immediately assign it to the SSL session so that the cert's
1362 * refcount is maintained regardless of the cert's presence in the LRU cache.
1363 */
Christopher Faulet31af49d2015-06-09 17:29:50 +02001364static SSL_CTX *
Christopher Faulet7969a332015-10-09 11:15:03 +02001365ssl_sock_generate_certificate(const char *servername, struct bind_conf *bind_conf, SSL *ssl)
Christopher Faulet31af49d2015-06-09 17:29:50 +02001366{
1367 X509 *cacert = bind_conf->ca_sign_cert;
Christopher Faulet31af49d2015-06-09 17:29:50 +02001368 SSL_CTX *ssl_ctx = NULL;
1369 struct lru64 *lru = NULL;
Christopher Faulet635c0ad2015-11-12 11:35:51 +01001370 unsigned int key;
Christopher Faulet31af49d2015-06-09 17:29:50 +02001371
Christopher Faulet635c0ad2015-11-12 11:35:51 +01001372 key = ssl_sock_generated_cert_key(servername, strlen(servername));
Christopher Faulet31af49d2015-06-09 17:29:50 +02001373 if (ssl_ctx_lru_tree) {
Christopher Faulet635c0ad2015-11-12 11:35:51 +01001374 lru = lru64_get(key, ssl_ctx_lru_tree, cacert, 0);
Christopher Faulet31af49d2015-06-09 17:29:50 +02001375 if (lru && lru->domain)
1376 ssl_ctx = (SSL_CTX *)lru->data;
Christopher Fauletd2cab922015-07-28 16:03:47 +02001377 if (!ssl_ctx && lru) {
Christopher Faulet635c0ad2015-11-12 11:35:51 +01001378 ssl_ctx = ssl_sock_do_create_cert(servername, bind_conf, ssl);
Christopher Faulet31af49d2015-06-09 17:29:50 +02001379 lru64_commit(lru, ssl_ctx, cacert, 0, (void (*)(void *))SSL_CTX_free);
Christopher Fauletd2cab922015-07-28 16:03:47 +02001380 }
Willy Tarreau2f63ef42015-10-20 15:16:01 +02001381 SSL_set_SSL_CTX(ssl, ssl_ctx);
Christopher Faulet31af49d2015-06-09 17:29:50 +02001382 }
Willy Tarreau2f63ef42015-10-20 15:16:01 +02001383 else {
Christopher Faulet635c0ad2015-11-12 11:35:51 +01001384 ssl_ctx = ssl_sock_do_create_cert(servername, bind_conf, ssl);
Willy Tarreau2f63ef42015-10-20 15:16:01 +02001385 SSL_set_SSL_CTX(ssl, ssl_ctx);
1386 /* No LRU cache, this CTX will be released as soon as the session dies */
1387 SSL_CTX_free(ssl_ctx);
1388 }
Christopher Faulet31af49d2015-06-09 17:29:50 +02001389 return ssl_ctx;
1390}
1391
Emeric Brunfc0421f2012-09-07 17:30:07 +02001392/* Sets the SSL ctx of <ssl> to match the advertised server name. Returns a
1393 * warning when no match is found, which implies the default (first) cert
1394 * will keep being used.
1395 */
Willy Tarreau2a65ff02012-09-13 17:54:29 +02001396static int ssl_sock_switchctx_cbk(SSL *ssl, int *al, struct bind_conf *s)
Emeric Brunfc0421f2012-09-07 17:30:07 +02001397{
1398 const char *servername;
1399 const char *wildp = NULL;
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +02001400 struct ebmb_node *node, *n;
Emeric Brunfc0421f2012-09-07 17:30:07 +02001401 int i;
1402 (void)al; /* shut gcc stupid warning */
1403
1404 servername = SSL_get_servername(ssl, TLSEXT_NAMETYPE_host_name);
Emmanuel Hocdet65623372013-01-24 17:17:15 +01001405 if (!servername) {
Willy Tarreauf6721452015-07-07 18:04:38 +02001406 if (s->generate_certs) {
Vincent Bernat3c2f2f22016-04-03 13:48:42 +02001407 struct connection *conn = SSL_get_app_data(ssl);
Christopher Faulet635c0ad2015-11-12 11:35:51 +01001408 unsigned int key;
Willy Tarreauf6721452015-07-07 18:04:38 +02001409 SSL_CTX *ctx;
Christopher Faulet30548802015-06-11 13:39:32 +02001410
Willy Tarreauf6721452015-07-07 18:04:38 +02001411 conn_get_to_addr(conn);
1412 if (conn->flags & CO_FL_ADDR_TO_SET) {
Christopher Faulet635c0ad2015-11-12 11:35:51 +01001413 key = ssl_sock_generated_cert_key(&conn->addr.to, get_addr_len(&conn->addr.to));
1414 ctx = ssl_sock_get_generated_cert(key, s);
Willy Tarreauf6721452015-07-07 18:04:38 +02001415 if (ctx) {
1416 /* switch ctx */
1417 SSL_set_SSL_CTX(ssl, ctx);
1418 return SSL_TLSEXT_ERR_OK;
1419 }
Christopher Faulet30548802015-06-11 13:39:32 +02001420 }
1421 }
1422
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +02001423 return (s->strict_sni ?
1424 SSL_TLSEXT_ERR_ALERT_FATAL :
Emmanuel Hocdet79274e22013-05-31 12:47:44 +02001425 SSL_TLSEXT_ERR_NOACK);
Emmanuel Hocdet65623372013-01-24 17:17:15 +01001426 }
Emeric Brunfc0421f2012-09-07 17:30:07 +02001427
Willy Tarreau19d14ef2012-10-29 16:51:55 +01001428 for (i = 0; i < trash.size; i++) {
Emeric Brunfc0421f2012-09-07 17:30:07 +02001429 if (!servername[i])
1430 break;
Willy Tarreau19d14ef2012-10-29 16:51:55 +01001431 trash.str[i] = tolower(servername[i]);
1432 if (!wildp && (trash.str[i] == '.'))
1433 wildp = &trash.str[i];
Emeric Brunfc0421f2012-09-07 17:30:07 +02001434 }
Willy Tarreau19d14ef2012-10-29 16:51:55 +01001435 trash.str[i] = 0;
Emeric Brunfc0421f2012-09-07 17:30:07 +02001436
1437 /* lookup in full qualified names */
Willy Tarreau19d14ef2012-10-29 16:51:55 +01001438 node = ebst_lookup(&s->sni_ctx, trash.str);
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +02001439
1440 /* lookup a not neg filter */
1441 for (n = node; n; n = ebmb_next_dup(n)) {
1442 if (!container_of(n, struct sni_ctx, name)->neg) {
1443 node = n;
1444 break;
Emmanuel Hocdet65623372013-01-24 17:17:15 +01001445 }
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +02001446 }
1447 if (!node && wildp) {
1448 /* lookup in wildcards names */
Emeric Brunfc0421f2012-09-07 17:30:07 +02001449 node = ebst_lookup(&s->sni_w_ctx, wildp);
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +02001450 }
1451 if (!node || container_of(node, struct sni_ctx, name)->neg) {
Christopher Faulet31af49d2015-06-09 17:29:50 +02001452 SSL_CTX *ctx;
Christopher Faulet31af49d2015-06-09 17:29:50 +02001453 if (s->generate_certs &&
Christopher Faulet7969a332015-10-09 11:15:03 +02001454 (ctx = ssl_sock_generate_certificate(servername, s, ssl))) {
Christopher Faulet31af49d2015-06-09 17:29:50 +02001455 /* switch ctx */
Christopher Faulet31af49d2015-06-09 17:29:50 +02001456 return SSL_TLSEXT_ERR_OK;
1457 }
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +02001458 return (s->strict_sni ?
1459 SSL_TLSEXT_ERR_ALERT_FATAL :
1460 SSL_TLSEXT_ERR_ALERT_WARNING);
Emeric Brunfc0421f2012-09-07 17:30:07 +02001461 }
1462
1463 /* switch ctx */
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +02001464 SSL_set_SSL_CTX(ssl, container_of(node, struct sni_ctx, name)->ctx);
Emeric Brunfc0421f2012-09-07 17:30:07 +02001465 return SSL_TLSEXT_ERR_OK;
1466}
1467#endif /* SSL_CTRL_SET_TLSEXT_HOSTNAME */
1468
Emeric Bruna4bcd9a2012-09-20 16:19:02 +02001469#ifndef OPENSSL_NO_DH
Remi Gacognef46cd6e2014-06-12 14:58:40 +02001470
1471static DH * ssl_get_dh_1024(void)
1472{
Remi Gacogned3a341a2015-05-29 16:26:17 +02001473 static unsigned char dh1024_p[]={
1474 0xFA,0xF9,0x2A,0x22,0x2A,0xA7,0x7F,0xE1,0x67,0x4E,0x53,0xF7,
1475 0x56,0x13,0xC3,0xB1,0xE3,0x29,0x6B,0x66,0x31,0x6A,0x7F,0xB3,
1476 0xC2,0x68,0x6B,0xCB,0x1D,0x57,0x39,0x1D,0x1F,0xFF,0x1C,0xC9,
1477 0xA6,0xA4,0x98,0x82,0x31,0x5D,0x25,0xFF,0x8A,0xE0,0x73,0x96,
1478 0x81,0xC8,0x83,0x79,0xC1,0x5A,0x04,0xF8,0x37,0x0D,0xA8,0x3D,
1479 0xAE,0x74,0xBC,0xDB,0xB6,0xA4,0x75,0xD9,0x71,0x8A,0xA0,0x17,
1480 0x9E,0x2D,0xC8,0xA8,0xDF,0x2C,0x5F,0x82,0x95,0xF8,0x92,0x9B,
1481 0xA7,0x33,0x5F,0x89,0x71,0xC8,0x2D,0x6B,0x18,0x86,0xC4,0x94,
1482 0x22,0xA5,0x52,0x8D,0xF6,0xF6,0xD2,0x37,0x92,0x0F,0xA5,0xCC,
1483 0xDB,0x7B,0x1D,0x3D,0xA1,0x31,0xB7,0x80,0x8F,0x0B,0x67,0x5E,
1484 0x36,0xA5,0x60,0x0C,0xF1,0x95,0x33,0x8B,
1485 };
1486 static unsigned char dh1024_g[]={
1487 0x02,
1488 };
1489
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02001490 BIGNUM *p;
1491 BIGNUM *g;
Remi Gacognef46cd6e2014-06-12 14:58:40 +02001492 DH *dh = DH_new();
1493 if (dh) {
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02001494 p = BN_bin2bn(dh1024_p, sizeof dh1024_p, NULL);
1495 g = BN_bin2bn(dh1024_g, sizeof dh1024_g, NULL);
Remi Gacogned3a341a2015-05-29 16:26:17 +02001496
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02001497 if (!p || !g) {
Remi Gacognef46cd6e2014-06-12 14:58:40 +02001498 DH_free(dh);
1499 dh = NULL;
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02001500 } else {
1501 DH_set0_pqg(dh, p, NULL, g);
Remi Gacognef46cd6e2014-06-12 14:58:40 +02001502 }
1503 }
1504 return dh;
1505}
1506
1507static DH *ssl_get_dh_2048(void)
1508{
Remi Gacogned3a341a2015-05-29 16:26:17 +02001509 static unsigned char dh2048_p[]={
1510 0xEC,0x86,0xF8,0x70,0xA0,0x33,0x16,0xEC,0x05,0x1A,0x73,0x59,
1511 0xCD,0x1F,0x8B,0xF8,0x29,0xE4,0xD2,0xCF,0x52,0xDD,0xC2,0x24,
1512 0x8D,0xB5,0x38,0x9A,0xFB,0x5C,0xA4,0xE4,0xB2,0xDA,0xCE,0x66,
1513 0x50,0x74,0xA6,0x85,0x4D,0x4B,0x1D,0x30,0xB8,0x2B,0xF3,0x10,
1514 0xE9,0xA7,0x2D,0x05,0x71,0xE7,0x81,0xDF,0x8B,0x59,0x52,0x3B,
1515 0x5F,0x43,0x0B,0x68,0xF1,0xDB,0x07,0xBE,0x08,0x6B,0x1B,0x23,
1516 0xEE,0x4D,0xCC,0x9E,0x0E,0x43,0xA0,0x1E,0xDF,0x43,0x8C,0xEC,
1517 0xBE,0xBE,0x90,0xB4,0x51,0x54,0xB9,0x2F,0x7B,0x64,0x76,0x4E,
1518 0x5D,0xD4,0x2E,0xAE,0xC2,0x9E,0xAE,0x51,0x43,0x59,0xC7,0x77,
1519 0x9C,0x50,0x3C,0x0E,0xED,0x73,0x04,0x5F,0xF1,0x4C,0x76,0x2A,
1520 0xD8,0xF8,0xCF,0xFC,0x34,0x40,0xD1,0xB4,0x42,0x61,0x84,0x66,
1521 0x42,0x39,0x04,0xF8,0x68,0xB2,0x62,0xD7,0x55,0xED,0x1B,0x74,
1522 0x75,0x91,0xE0,0xC5,0x69,0xC1,0x31,0x5C,0xDB,0x7B,0x44,0x2E,
1523 0xCE,0x84,0x58,0x0D,0x1E,0x66,0x0C,0xC8,0x44,0x9E,0xFD,0x40,
1524 0x08,0x67,0x5D,0xFB,0xA7,0x76,0x8F,0x00,0x11,0x87,0xE9,0x93,
1525 0xF9,0x7D,0xC4,0xBC,0x74,0x55,0x20,0xD4,0x4A,0x41,0x2F,0x43,
1526 0x42,0x1A,0xC1,0xF2,0x97,0x17,0x49,0x27,0x37,0x6B,0x2F,0x88,
1527 0x7E,0x1C,0xA0,0xA1,0x89,0x92,0x27,0xD9,0x56,0x5A,0x71,0xC1,
1528 0x56,0x37,0x7E,0x3A,0x9D,0x05,0xE7,0xEE,0x5D,0x8F,0x82,0x17,
1529 0xBC,0xE9,0xC2,0x93,0x30,0x82,0xF9,0xF4,0xC9,0xAE,0x49,0xDB,
1530 0xD0,0x54,0xB4,0xD9,0x75,0x4D,0xFA,0x06,0xB8,0xD6,0x38,0x41,
1531 0xB7,0x1F,0x77,0xF3,
1532 };
1533 static unsigned char dh2048_g[]={
1534 0x02,
1535 };
1536
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02001537 BIGNUM *p;
1538 BIGNUM *g;
Remi Gacognef46cd6e2014-06-12 14:58:40 +02001539 DH *dh = DH_new();
1540 if (dh) {
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02001541 p = BN_bin2bn(dh2048_p, sizeof dh2048_p, NULL);
1542 g = BN_bin2bn(dh2048_g, sizeof dh2048_g, NULL);
Remi Gacogned3a341a2015-05-29 16:26:17 +02001543
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02001544 if (!p || !g) {
Remi Gacognef46cd6e2014-06-12 14:58:40 +02001545 DH_free(dh);
1546 dh = NULL;
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02001547 } else {
1548 DH_set0_pqg(dh, p, NULL, g);
Remi Gacognef46cd6e2014-06-12 14:58:40 +02001549 }
1550 }
1551 return dh;
1552}
1553
1554static DH *ssl_get_dh_4096(void)
1555{
Remi Gacogned3a341a2015-05-29 16:26:17 +02001556 static unsigned char dh4096_p[]={
1557 0xDE,0x16,0x94,0xCD,0x99,0x58,0x07,0xF1,0xF7,0x32,0x96,0x11,
1558 0x04,0x82,0xD4,0x84,0x72,0x80,0x99,0x06,0xCA,0xF0,0xA3,0x68,
1559 0x07,0xCE,0x64,0x50,0xE7,0x74,0x45,0x20,0x80,0x5E,0x4D,0xAD,
1560 0xA5,0xB6,0xED,0xFA,0x80,0x6C,0x3B,0x35,0xC4,0x9A,0x14,0x6B,
1561 0x32,0xBB,0xFD,0x1F,0x17,0x8E,0xB7,0x1F,0xD6,0xFA,0x3F,0x7B,
1562 0xEE,0x16,0xA5,0x62,0x33,0x0D,0xED,0xBC,0x4E,0x58,0xE5,0x47,
1563 0x4D,0xE9,0xAB,0x8E,0x38,0xD3,0x6E,0x90,0x57,0xE3,0x22,0x15,
1564 0x33,0xBD,0xF6,0x43,0x45,0xB5,0x10,0x0A,0xBE,0x2C,0xB4,0x35,
1565 0xB8,0x53,0x8D,0xAD,0xFB,0xA7,0x1F,0x85,0x58,0x41,0x7A,0x79,
1566 0x20,0x68,0xB3,0xE1,0x3D,0x08,0x76,0xBF,0x86,0x0D,0x49,0xE3,
1567 0x82,0x71,0x8C,0xB4,0x8D,0x81,0x84,0xD4,0xE7,0xBE,0x91,0xDC,
1568 0x26,0x39,0x48,0x0F,0x35,0xC4,0xCA,0x65,0xE3,0x40,0x93,0x52,
1569 0x76,0x58,0x7D,0xDD,0x51,0x75,0xDC,0x69,0x61,0xBF,0x47,0x2C,
1570 0x16,0x68,0x2D,0xC9,0x29,0xD3,0xE6,0xC0,0x99,0x48,0xA0,0x9A,
1571 0xC8,0x78,0xC0,0x6D,0x81,0x67,0x12,0x61,0x3F,0x71,0xBA,0x41,
1572 0x1F,0x6C,0x89,0x44,0x03,0xBA,0x3B,0x39,0x60,0xAA,0x28,0x55,
1573 0x59,0xAE,0xB8,0xFA,0xCB,0x6F,0xA5,0x1A,0xF7,0x2B,0xDD,0x52,
1574 0x8A,0x8B,0xE2,0x71,0xA6,0x5E,0x7E,0xD8,0x2E,0x18,0xE0,0x66,
1575 0xDF,0xDD,0x22,0x21,0x99,0x52,0x73,0xA6,0x33,0x20,0x65,0x0E,
1576 0x53,0xE7,0x6B,0x9B,0xC5,0xA3,0x2F,0x97,0x65,0x76,0xD3,0x47,
1577 0x23,0x77,0x12,0xB6,0x11,0x7B,0x24,0xED,0xF1,0xEF,0xC0,0xE2,
1578 0xA3,0x7E,0x67,0x05,0x3E,0x96,0x4D,0x45,0xC2,0x18,0xD1,0x73,
1579 0x9E,0x07,0xF3,0x81,0x6E,0x52,0x63,0xF6,0x20,0x76,0xB9,0x13,
1580 0xD2,0x65,0x30,0x18,0x16,0x09,0x16,0x9E,0x8F,0xF1,0xD2,0x10,
1581 0x5A,0xD3,0xD4,0xAF,0x16,0x61,0xDA,0x55,0x2E,0x18,0x5E,0x14,
1582 0x08,0x54,0x2E,0x2A,0x25,0xA2,0x1A,0x9B,0x8B,0x32,0xA9,0xFD,
1583 0xC2,0x48,0x96,0xE1,0x80,0xCA,0xE9,0x22,0x17,0xBB,0xCE,0x3E,
1584 0x9E,0xED,0xC7,0xF1,0x1F,0xEC,0x17,0x21,0xDC,0x7B,0x82,0x48,
1585 0x8E,0xBB,0x4B,0x9D,0x5B,0x04,0x04,0xDA,0xDB,0x39,0xDF,0x01,
1586 0x40,0xC3,0xAA,0x26,0x23,0x89,0x75,0xC6,0x0B,0xD0,0xA2,0x60,
1587 0x6A,0xF1,0xCC,0x65,0x18,0x98,0x1B,0x52,0xD2,0x74,0x61,0xCC,
1588 0xBD,0x60,0xAE,0xA3,0xA0,0x66,0x6A,0x16,0x34,0x92,0x3F,0x41,
1589 0x40,0x31,0x29,0xC0,0x2C,0x63,0xB2,0x07,0x8D,0xEB,0x94,0xB8,
1590 0xE8,0x47,0x92,0x52,0x93,0x6A,0x1B,0x7E,0x1A,0x61,0xB3,0x1B,
1591 0xF0,0xD6,0x72,0x9B,0xF1,0xB0,0xAF,0xBF,0x3E,0x65,0xEF,0x23,
1592 0x1D,0x6F,0xFF,0x70,0xCD,0x8A,0x4C,0x8A,0xA0,0x72,0x9D,0xBE,
1593 0xD4,0xBB,0x24,0x47,0x4A,0x68,0xB5,0xF5,0xC6,0xD5,0x7A,0xCD,
1594 0xCA,0x06,0x41,0x07,0xAD,0xC2,0x1E,0xE6,0x54,0xA7,0xAD,0x03,
1595 0xD9,0x12,0xC1,0x9C,0x13,0xB1,0xC9,0x0A,0x43,0x8E,0x1E,0x08,
1596 0xCE,0x50,0x82,0x73,0x5F,0xA7,0x55,0x1D,0xD9,0x59,0xAC,0xB5,
1597 0xEA,0x02,0x7F,0x6C,0x5B,0x74,0x96,0x98,0x67,0x24,0xA3,0x0F,
1598 0x15,0xFC,0xA9,0x7D,0x3E,0x67,0xD1,0x70,0xF8,0x97,0xF3,0x67,
1599 0xC5,0x8C,0x88,0x44,0x08,0x02,0xC7,0x2B,
Remi Gacognef46cd6e2014-06-12 14:58:40 +02001600 };
Remi Gacogned3a341a2015-05-29 16:26:17 +02001601 static unsigned char dh4096_g[]={
1602 0x02,
1603 };
Remi Gacognef46cd6e2014-06-12 14:58:40 +02001604
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02001605 BIGNUM *p;
1606 BIGNUM *g;
Remi Gacognef46cd6e2014-06-12 14:58:40 +02001607 DH *dh = DH_new();
1608 if (dh) {
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02001609 p = BN_bin2bn(dh4096_p, sizeof dh4096_p, NULL);
1610 g = BN_bin2bn(dh4096_g, sizeof dh4096_g, NULL);
Remi Gacogned3a341a2015-05-29 16:26:17 +02001611
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02001612 if (!p || !g) {
Remi Gacognef46cd6e2014-06-12 14:58:40 +02001613 DH_free(dh);
1614 dh = NULL;
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02001615 } else {
1616 DH_set0_pqg(dh, p, NULL, g);
Remi Gacognef46cd6e2014-06-12 14:58:40 +02001617 }
1618 }
1619 return dh;
1620}
1621
1622/* Returns Diffie-Hellman parameters matching the private key length
1623 but not exceeding global.tune.ssl_default_dh_param */
1624static DH *ssl_get_tmp_dh(SSL *ssl, int export, int keylen)
1625{
1626 DH *dh = NULL;
1627 EVP_PKEY *pkey = SSL_get_privatekey(ssl);
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02001628 int type;
1629
1630 type = pkey ? EVP_PKEY_base_id(pkey) : EVP_PKEY_NONE;
Remi Gacognef46cd6e2014-06-12 14:58:40 +02001631
1632 /* The keylen supplied by OpenSSL can only be 512 or 1024.
1633 See ssl3_send_server_key_exchange() in ssl/s3_srvr.c
1634 */
1635 if (type == EVP_PKEY_RSA || type == EVP_PKEY_DSA) {
1636 keylen = EVP_PKEY_bits(pkey);
1637 }
1638
1639 if (keylen > global.tune.ssl_default_dh_param) {
1640 keylen = global.tune.ssl_default_dh_param;
1641 }
1642
Remi Gacogned3a341a2015-05-29 16:26:17 +02001643 if (keylen >= 4096) {
Remi Gacogne8de54152014-07-15 11:36:40 +02001644 dh = local_dh_4096;
Remi Gacognef46cd6e2014-06-12 14:58:40 +02001645 }
1646 else if (keylen >= 2048) {
Remi Gacogne8de54152014-07-15 11:36:40 +02001647 dh = local_dh_2048;
Remi Gacognef46cd6e2014-06-12 14:58:40 +02001648 }
1649 else {
Remi Gacogne8de54152014-07-15 11:36:40 +02001650 dh = local_dh_1024;
Remi Gacognef46cd6e2014-06-12 14:58:40 +02001651 }
1652
1653 return dh;
1654}
1655
Remi Gacogne47783ef2015-05-29 15:53:22 +02001656static DH * ssl_sock_get_dh_from_file(const char *filename)
Emeric Bruna4bcd9a2012-09-20 16:19:02 +02001657{
Emeric Bruna4bcd9a2012-09-20 16:19:02 +02001658 DH *dh = NULL;
Remi Gacogne47783ef2015-05-29 15:53:22 +02001659 BIO *in = BIO_new(BIO_s_file());
Emeric Bruna4bcd9a2012-09-20 16:19:02 +02001660
Emeric Bruna4bcd9a2012-09-20 16:19:02 +02001661 if (in == NULL)
1662 goto end;
1663
Remi Gacogne47783ef2015-05-29 15:53:22 +02001664 if (BIO_read_filename(in, filename) <= 0)
Emeric Bruna4bcd9a2012-09-20 16:19:02 +02001665 goto end;
1666
Remi Gacogne47783ef2015-05-29 15:53:22 +02001667 dh = PEM_read_bio_DHparams(in, NULL, NULL, NULL);
1668
1669end:
1670 if (in)
1671 BIO_free(in);
1672
1673 return dh;
1674}
1675
1676int ssl_sock_load_global_dh_param_from_file(const char *filename)
1677{
1678 global_dh = ssl_sock_get_dh_from_file(filename);
1679
1680 if (global_dh) {
1681 return 0;
1682 }
1683
1684 return -1;
1685}
1686
1687/* Loads Diffie-Hellman parameter from a file. Returns 1 if loaded, else -1
1688 if an error occured, and 0 if parameter not found. */
1689int ssl_sock_load_dh_params(SSL_CTX *ctx, const char *file)
1690{
1691 int ret = -1;
1692 DH *dh = ssl_sock_get_dh_from_file(file);
1693
Remi Gacognef46cd6e2014-06-12 14:58:40 +02001694 if (dh) {
1695 ret = 1;
1696 SSL_CTX_set_tmp_dh(ctx, dh);
Remi Gacogne4f902b82015-05-28 16:23:00 +02001697
1698 if (ssl_dh_ptr_index >= 0) {
1699 /* store a pointer to the DH params to avoid complaining about
1700 ssl-default-dh-param not being set for this SSL_CTX */
1701 SSL_CTX_set_ex_data(ctx, ssl_dh_ptr_index, dh);
1702 }
Remi Gacognef46cd6e2014-06-12 14:58:40 +02001703 }
Remi Gacogne47783ef2015-05-29 15:53:22 +02001704 else if (global_dh) {
1705 SSL_CTX_set_tmp_dh(ctx, global_dh);
1706 ret = 0; /* DH params not found */
1707 }
Remi Gacognef46cd6e2014-06-12 14:58:40 +02001708 else {
Emeric Brun41fdb3c2013-04-26 11:05:44 +02001709 /* Clear openssl global errors stack */
1710 ERR_clear_error();
1711
Remi Gacognef46cd6e2014-06-12 14:58:40 +02001712 if (global.tune.ssl_default_dh_param <= 1024) {
1713 /* we are limited to DH parameter of 1024 bits anyway */
Remi Gacognec7e12632016-07-02 16:26:10 +02001714 if (local_dh_1024 == NULL)
1715 local_dh_1024 = ssl_get_dh_1024();
1716
Remi Gacogne8de54152014-07-15 11:36:40 +02001717 if (local_dh_1024 == NULL)
Remi Gacognef46cd6e2014-06-12 14:58:40 +02001718 goto end;
Willy Tarreau6e774b42014-04-25 21:35:23 +02001719
Remi Gacogne8de54152014-07-15 11:36:40 +02001720 SSL_CTX_set_tmp_dh(ctx, local_dh_1024);
Remi Gacognef46cd6e2014-06-12 14:58:40 +02001721 }
1722 else {
1723 SSL_CTX_set_tmp_dh_callback(ctx, ssl_get_tmp_dh);
1724 }
Willy Tarreau6e774b42014-04-25 21:35:23 +02001725
Emeric Brun41fdb3c2013-04-26 11:05:44 +02001726 ret = 0; /* DH params not found */
Emeric Bruna4bcd9a2012-09-20 16:19:02 +02001727 }
Emeric Brun644cde02012-12-14 11:21:13 +01001728
Emeric Bruna4bcd9a2012-09-20 16:19:02 +02001729end:
1730 if (dh)
1731 DH_free(dh);
1732
Emeric Bruna4bcd9a2012-09-20 16:19:02 +02001733 return ret;
1734}
1735#endif
1736
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +02001737static int ssl_sock_add_cert_sni(SSL_CTX *ctx, struct bind_conf *s, char *name, int order)
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01001738{
1739 struct sni_ctx *sc;
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +02001740 int wild = 0, neg = 0;
Thierry FOURNIER / OZON.IO07c3d782016-10-06 10:56:48 +02001741 struct ebmb_node *node;
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01001742
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +02001743 if (*name == '!') {
1744 neg = 1;
1745 name++;
1746 }
1747 if (*name == '*') {
1748 wild = 1;
1749 name++;
1750 }
1751 /* !* filter is a nop */
1752 if (neg && wild)
1753 return order;
1754 if (*name) {
1755 int j, len;
1756 len = strlen(name);
Thierry FOURNIER / OZON.IO07c3d782016-10-06 10:56:48 +02001757 for (j = 0; j < len && j < trash.size; j++)
1758 trash.str[j] = tolower(name[j]);
1759 if (j >= trash.size)
1760 return order;
1761 trash.str[j] = 0;
1762
1763 /* Check for duplicates. */
1764 if (wild)
1765 node = ebst_lookup(&s->sni_w_ctx, trash.str);
1766 else
1767 node = ebst_lookup(&s->sni_ctx, trash.str);
1768 for (; node; node = ebmb_next_dup(node)) {
1769 sc = ebmb_entry(node, struct sni_ctx, name);
1770 if (sc->ctx == ctx && sc->neg == neg)
1771 return order;
1772 }
1773
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01001774 sc = malloc(sizeof(struct sni_ctx) + len + 1);
Thierry FOURNIER / OZON.IO7a3bd3b2016-10-06 10:35:29 +02001775 if (!sc)
1776 return order;
Thierry FOURNIER / OZON.IO07c3d782016-10-06 10:56:48 +02001777 memcpy(sc->name.key, trash.str, len + 1);
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01001778 sc->ctx = ctx;
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +02001779 sc->order = order++;
1780 sc->neg = neg;
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01001781 if (wild)
1782 ebst_insert(&s->sni_w_ctx, &sc->name);
1783 else
1784 ebst_insert(&s->sni_ctx, &sc->name);
1785 }
1786 return order;
1787}
1788
yanbzhu488a4d22015-12-01 15:16:07 -05001789
1790/* The following code is used for loading multiple crt files into
1791 * SSL_CTX's based on CN/SAN
1792 */
Luca Pizzamiglio578b1692016-12-12 10:56:56 +01001793#if OPENSSL_VERSION_NUMBER >= 0x1000200fL && !defined(LIBRESSL_VERSION_NUMBER)
yanbzhu488a4d22015-12-01 15:16:07 -05001794/* This is used to preload the certifcate, private key
1795 * and Cert Chain of a file passed in via the crt
1796 * argument
1797 *
1798 * This way, we do not have to read the file multiple times
1799 */
1800struct cert_key_and_chain {
1801 X509 *cert;
1802 EVP_PKEY *key;
1803 unsigned int num_chain_certs;
1804 /* This is an array of X509 pointers */
1805 X509 **chain_certs;
1806};
1807
yanbzhu08ce6ab2015-12-02 13:01:29 -05001808#define SSL_SOCK_POSSIBLE_KT_COMBOS (1<<(SSL_SOCK_NUM_KEYTYPES))
1809
1810struct key_combo_ctx {
1811 SSL_CTX *ctx;
1812 int order;
1813};
1814
1815/* Map used for processing multiple keypairs for a single purpose
1816 *
1817 * This maps CN/SNI name to certificate type
1818 */
1819struct sni_keytype {
1820 int keytypes; /* BITMASK for keytypes */
1821 struct ebmb_node name; /* node holding the servername value */
1822};
1823
1824
yanbzhu488a4d22015-12-01 15:16:07 -05001825/* Frees the contents of a cert_key_and_chain
1826 */
1827static void ssl_sock_free_cert_key_and_chain_contents(struct cert_key_and_chain *ckch)
1828{
1829 int i;
1830
1831 if (!ckch)
1832 return;
1833
1834 /* Free the certificate and set pointer to NULL */
1835 if (ckch->cert)
1836 X509_free(ckch->cert);
1837 ckch->cert = NULL;
1838
1839 /* Free the key and set pointer to NULL */
1840 if (ckch->key)
1841 EVP_PKEY_free(ckch->key);
1842 ckch->key = NULL;
1843
1844 /* Free each certificate in the chain */
1845 for (i = 0; i < ckch->num_chain_certs; i++) {
1846 if (ckch->chain_certs[i])
1847 X509_free(ckch->chain_certs[i]);
1848 }
1849
1850 /* Free the chain obj itself and set to NULL */
1851 if (ckch->num_chain_certs > 0) {
1852 free(ckch->chain_certs);
1853 ckch->num_chain_certs = 0;
1854 ckch->chain_certs = NULL;
1855 }
1856
1857}
1858
1859/* checks if a key and cert exists in the ckch
1860 */
1861static int ssl_sock_is_ckch_valid(struct cert_key_and_chain *ckch)
1862{
1863 return (ckch->cert != NULL && ckch->key != NULL);
1864}
1865
1866
1867/* Loads the contents of a crt file (path) into a cert_key_and_chain
1868 * This allows us to carry the contents of the file without having to
1869 * read the file multiple times.
1870 *
1871 * returns:
1872 * 0 on Success
1873 * 1 on SSL Failure
1874 * 2 on file not found
1875 */
1876static int ssl_sock_load_crt_file_into_ckch(const char *path, struct cert_key_and_chain *ckch, char **err)
1877{
1878
1879 BIO *in;
1880 X509 *ca = NULL;
1881 int ret = 1;
1882
1883 ssl_sock_free_cert_key_and_chain_contents(ckch);
1884
1885 in = BIO_new(BIO_s_file());
1886 if (in == NULL)
1887 goto end;
1888
1889 if (BIO_read_filename(in, path) <= 0)
1890 goto end;
1891
yanbzhu488a4d22015-12-01 15:16:07 -05001892 /* Read Private Key */
1893 ckch->key = PEM_read_bio_PrivateKey(in, NULL, NULL, NULL);
1894 if (ckch->key == NULL) {
1895 memprintf(err, "%sunable to load private key from file '%s'.\n",
1896 err && *err ? *err : "", path);
1897 goto end;
1898 }
1899
Willy Tarreaubb137a82016-04-06 19:02:38 +02001900 /* Seek back to beginning of file */
Thierry FOURNIER / OZON.IOd44ea3f2016-10-14 00:49:21 +02001901 if (BIO_reset(in) == -1) {
1902 memprintf(err, "%san error occurred while reading the file '%s'.\n",
1903 err && *err ? *err : "", path);
1904 goto end;
1905 }
Willy Tarreaubb137a82016-04-06 19:02:38 +02001906
1907 /* Read Certificate */
1908 ckch->cert = PEM_read_bio_X509_AUX(in, NULL, NULL, NULL);
1909 if (ckch->cert == NULL) {
1910 memprintf(err, "%sunable to load certificate from file '%s'.\n",
1911 err && *err ? *err : "", path);
1912 goto end;
1913 }
1914
yanbzhu488a4d22015-12-01 15:16:07 -05001915 /* Read Certificate Chain */
1916 while ((ca = PEM_read_bio_X509(in, NULL, NULL, NULL))) {
1917 /* Grow the chain certs */
1918 ckch->num_chain_certs++;
1919 ckch->chain_certs = realloc(ckch->chain_certs, (ckch->num_chain_certs * sizeof(X509 *)));
1920
1921 /* use - 1 here since we just incremented it above */
1922 ckch->chain_certs[ckch->num_chain_certs - 1] = ca;
1923 }
1924 ret = ERR_get_error();
1925 if (ret && (ERR_GET_LIB(ret) != ERR_LIB_PEM && ERR_GET_REASON(ret) != PEM_R_NO_START_LINE)) {
1926 memprintf(err, "%sunable to load certificate chain from file '%s'.\n",
1927 err && *err ? *err : "", path);
1928 ret = 1;
1929 goto end;
1930 }
1931
1932 ret = 0;
1933
1934end:
1935
1936 ERR_clear_error();
1937 if (in)
1938 BIO_free(in);
1939
1940 /* Something went wrong in one of the reads */
1941 if (ret != 0)
1942 ssl_sock_free_cert_key_and_chain_contents(ckch);
1943
1944 return ret;
1945}
1946
1947/* Loads the info in ckch into ctx
1948 * Currently, this does not process any information about ocsp, dhparams or
1949 * sctl
1950 * Returns
1951 * 0 on success
1952 * 1 on failure
1953 */
1954static int ssl_sock_put_ckch_into_ctx(const char *path, const struct cert_key_and_chain *ckch, SSL_CTX *ctx, char **err)
1955{
1956 int i = 0;
1957
1958 if (SSL_CTX_use_PrivateKey(ctx, ckch->key) <= 0) {
1959 memprintf(err, "%sunable to load SSL private key into SSL Context '%s'.\n",
1960 err && *err ? *err : "", path);
1961 return 1;
1962 }
1963
1964 if (!SSL_CTX_use_certificate(ctx, ckch->cert)) {
1965 memprintf(err, "%sunable to load SSL certificate into SSL Context '%s'.\n",
1966 err && *err ? *err : "", path);
1967 return 1;
1968 }
1969
yanbzhu488a4d22015-12-01 15:16:07 -05001970 /* Load all certs in the ckch into the ctx_chain for the ssl_ctx */
1971 for (i = 0; i < ckch->num_chain_certs; i++) {
1972 if (!SSL_CTX_add1_chain_cert(ctx, ckch->chain_certs[i])) {
yanbzhu08ce6ab2015-12-02 13:01:29 -05001973 memprintf(err, "%sunable to load chain certificate #%d into SSL Context '%s'. Make sure you are linking against Openssl >= 1.0.2.\n",
1974 err && *err ? *err : "", (i+1), path);
yanbzhu488a4d22015-12-01 15:16:07 -05001975 return 1;
1976 }
1977 }
1978
1979 if (SSL_CTX_check_private_key(ctx) <= 0) {
1980 memprintf(err, "%sinconsistencies between private key and certificate loaded from PEM file '%s'.\n",
1981 err && *err ? *err : "", path);
1982 return 1;
1983 }
1984
1985 return 0;
1986}
1987
yanbzhu08ce6ab2015-12-02 13:01:29 -05001988
1989static void ssl_sock_populate_sni_keytypes_hplr(const char *str, struct eb_root *sni_keytypes, int key_index)
1990{
1991 struct sni_keytype *s_kt = NULL;
1992 struct ebmb_node *node;
1993 int i;
1994
1995 for (i = 0; i < trash.size; i++) {
1996 if (!str[i])
1997 break;
1998 trash.str[i] = tolower(str[i]);
1999 }
2000 trash.str[i] = 0;
2001 node = ebst_lookup(sni_keytypes, trash.str);
2002 if (!node) {
2003 /* CN not found in tree */
2004 s_kt = malloc(sizeof(struct sni_keytype) + i + 1);
2005 /* Using memcpy here instead of strncpy.
2006 * strncpy will cause sig_abrt errors under certain versions of gcc with -O2
2007 * See: https://gcc.gnu.org/bugzilla/show_bug.cgi?id=60792
2008 */
2009 memcpy(s_kt->name.key, trash.str, i+1);
2010 s_kt->keytypes = 0;
2011 ebst_insert(sni_keytypes, &s_kt->name);
2012 } else {
2013 /* CN found in tree */
2014 s_kt = container_of(node, struct sni_keytype, name);
2015 }
2016
2017 /* Mark that this CN has the keytype of key_index via keytypes mask */
2018 s_kt->keytypes |= 1<<key_index;
2019
2020}
2021
2022
2023/* Given a path that does not exist, try to check for path.rsa, path.dsa and path.ecdsa files.
2024 * If any are found, group these files into a set of SSL_CTX*
2025 * based on shared and unique CN and SAN entries. Add these SSL_CTX* to the SNI tree.
2026 *
2027 * This will allow the user to explictly group multiple cert/keys for a single purpose
2028 *
2029 * Returns
2030 * 0 on success
2031 * 1 on failure
2032 */
Willy Tarreau03209342016-12-22 17:08:28 +01002033static int ssl_sock_load_multi_cert(const char *path, struct bind_conf *bind_conf, char **sni_filter, int fcount, char **err)
yanbzhu08ce6ab2015-12-02 13:01:29 -05002034{
2035 char fp[MAXPATHLEN+1] = {0};
2036 int n = 0;
2037 int i = 0;
2038 struct cert_key_and_chain certs_and_keys[SSL_SOCK_NUM_KEYTYPES] = { {0} };
2039 struct eb_root sni_keytypes_map = { {0} };
2040 struct ebmb_node *node;
2041 struct ebmb_node *next;
2042 /* Array of SSL_CTX pointers corresponding to each possible combo
2043 * of keytypes
2044 */
2045 struct key_combo_ctx key_combos[SSL_SOCK_POSSIBLE_KT_COMBOS] = { {0} };
2046 int rv = 0;
2047 X509_NAME *xname = NULL;
2048 char *str = NULL;
2049#ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME
2050 STACK_OF(GENERAL_NAME) *names = NULL;
2051#endif
2052
2053 /* Load all possible certs and keys */
2054 for (n = 0; n < SSL_SOCK_NUM_KEYTYPES; n++) {
2055 struct stat buf;
2056
2057 snprintf(fp, sizeof(fp), "%s.%s", path, SSL_SOCK_KEYTYPE_NAMES[n]);
2058 if (stat(fp, &buf) == 0) {
2059 if (ssl_sock_load_crt_file_into_ckch(fp, &certs_and_keys[n], err) == 1) {
2060 rv = 1;
2061 goto end;
2062 }
2063 }
2064 }
2065
2066 /* Process each ckch and update keytypes for each CN/SAN
2067 * for example, if CN/SAN www.a.com is associated with
2068 * certs with keytype 0 and 2, then at the end of the loop,
2069 * www.a.com will have:
2070 * keyindex = 0 | 1 | 4 = 5
2071 */
2072 for (n = 0; n < SSL_SOCK_NUM_KEYTYPES; n++) {
2073
2074 if (!ssl_sock_is_ckch_valid(&certs_and_keys[n]))
2075 continue;
2076
Emmanuel Hocdetd294aea2016-05-13 11:14:06 +02002077 if (fcount) {
Willy Tarreau24b892f2016-06-20 23:01:57 +02002078 for (i = 0; i < fcount; i++)
Emmanuel Hocdetd294aea2016-05-13 11:14:06 +02002079 ssl_sock_populate_sni_keytypes_hplr(sni_filter[i], &sni_keytypes_map, n);
2080 } else {
2081 /* A lot of the following code is OpenSSL boilerplate for processing CN's and SAN's,
2082 * so the line that contains logic is marked via comments
2083 */
2084 xname = X509_get_subject_name(certs_and_keys[n].cert);
2085 i = -1;
2086 while ((i = X509_NAME_get_index_by_NID(xname, NID_commonName, i)) != -1) {
2087 X509_NAME_ENTRY *entry = X509_NAME_get_entry(xname, i);
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02002088 ASN1_STRING *value;
2089 value = X509_NAME_ENTRY_get_data(entry);
2090 if (ASN1_STRING_to_UTF8((unsigned char **)&str, value) >= 0) {
Emmanuel Hocdetd294aea2016-05-13 11:14:06 +02002091 /* Important line is here */
2092 ssl_sock_populate_sni_keytypes_hplr(str, &sni_keytypes_map, n);
yanbzhu08ce6ab2015-12-02 13:01:29 -05002093
Emmanuel Hocdetd294aea2016-05-13 11:14:06 +02002094 OPENSSL_free(str);
2095 str = NULL;
2096 }
yanbzhu08ce6ab2015-12-02 13:01:29 -05002097 }
yanbzhu08ce6ab2015-12-02 13:01:29 -05002098
Emmanuel Hocdetd294aea2016-05-13 11:14:06 +02002099 /* Do the above logic for each SAN */
yanbzhu08ce6ab2015-12-02 13:01:29 -05002100#ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME
Emmanuel Hocdetd294aea2016-05-13 11:14:06 +02002101 names = X509_get_ext_d2i(certs_and_keys[n].cert, NID_subject_alt_name, NULL, NULL);
2102 if (names) {
2103 for (i = 0; i < sk_GENERAL_NAME_num(names); i++) {
2104 GENERAL_NAME *name = sk_GENERAL_NAME_value(names, i);
yanbzhu08ce6ab2015-12-02 13:01:29 -05002105
Emmanuel Hocdetd294aea2016-05-13 11:14:06 +02002106 if (name->type == GEN_DNS) {
2107 if (ASN1_STRING_to_UTF8((unsigned char **)&str, name->d.dNSName) >= 0) {
2108 /* Important line is here */
2109 ssl_sock_populate_sni_keytypes_hplr(str, &sni_keytypes_map, n);
yanbzhu08ce6ab2015-12-02 13:01:29 -05002110
Emmanuel Hocdetd294aea2016-05-13 11:14:06 +02002111 OPENSSL_free(str);
2112 str = NULL;
2113 }
yanbzhu08ce6ab2015-12-02 13:01:29 -05002114 }
2115 }
2116 }
2117 }
2118#endif /* SSL_CTRL_SET_TLSEXT_HOSTNAME */
2119 }
2120
2121 /* If no files found, return error */
2122 if (eb_is_empty(&sni_keytypes_map)) {
2123 memprintf(err, "%sunable to load SSL certificate file '%s' file does not exist.\n",
2124 err && *err ? *err : "", path);
2125 rv = 1;
2126 goto end;
2127 }
2128
2129 /* We now have a map of CN/SAN to keytypes that are loaded in
2130 * Iterate through the map to create the SSL_CTX's (if needed)
2131 * and add each CTX to the SNI tree
2132 *
2133 * Some math here:
2134 * There are 2^n - 1 possibile combinations, each unique
2135 * combination is denoted by the key in the map. Each key
2136 * has a value between 1 and 2^n - 1. Conveniently, the array
2137 * of SSL_CTX* is sized 2^n. So, we can simply use the i'th
2138 * entry in the array to correspond to the unique combo (key)
2139 * associated with i. This unique key combo (i) will be associated
2140 * with combos[i-1]
2141 */
2142
2143 node = ebmb_first(&sni_keytypes_map);
2144 while (node) {
2145 SSL_CTX *cur_ctx;
Bertrand Jacquin33423092016-11-13 16:37:13 +00002146 char cur_file[MAXPATHLEN+1];
yanbzhu08ce6ab2015-12-02 13:01:29 -05002147
2148 str = (char *)container_of(node, struct sni_keytype, name)->name.key;
2149 i = container_of(node, struct sni_keytype, name)->keytypes;
2150 cur_ctx = key_combos[i-1].ctx;
2151
2152 if (cur_ctx == NULL) {
2153 /* need to create SSL_CTX */
2154 cur_ctx = SSL_CTX_new(SSLv23_server_method());
2155 if (cur_ctx == NULL) {
2156 memprintf(err, "%sunable to allocate SSL context.\n",
2157 err && *err ? *err : "");
2158 rv = 1;
2159 goto end;
2160 }
2161
yanbzhube2774d2015-12-10 15:07:30 -05002162 /* Load all required certs/keys/chains/OCSPs info into SSL_CTX */
yanbzhu08ce6ab2015-12-02 13:01:29 -05002163 for (n = 0; n < SSL_SOCK_NUM_KEYTYPES; n++) {
2164 if (i & (1<<n)) {
2165 /* Key combo contains ckch[n] */
Bertrand Jacquin33423092016-11-13 16:37:13 +00002166 snprintf(cur_file, MAXPATHLEN+1, "%s.%s", path, SSL_SOCK_KEYTYPE_NAMES[n]);
2167 if (ssl_sock_put_ckch_into_ctx(cur_file, &certs_and_keys[n], cur_ctx, err) != 0) {
yanbzhu08ce6ab2015-12-02 13:01:29 -05002168 SSL_CTX_free(cur_ctx);
2169 rv = 1;
2170 goto end;
2171 }
yanbzhube2774d2015-12-10 15:07:30 -05002172
2173#if (defined SSL_CTRL_SET_TLSEXT_STATUS_REQ_CB && !defined OPENSSL_NO_OCSP)
2174 /* Load OCSP Info into context */
Bertrand Jacquin33423092016-11-13 16:37:13 +00002175 if (ssl_sock_load_ocsp(cur_ctx, cur_file) < 0) {
yanbzhube2774d2015-12-10 15:07:30 -05002176 if (err)
2177 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 +00002178 *err ? *err : "", cur_file);
yanbzhube2774d2015-12-10 15:07:30 -05002179 SSL_CTX_free(cur_ctx);
2180 rv = 1;
2181 goto end;
2182 }
2183#endif
yanbzhu08ce6ab2015-12-02 13:01:29 -05002184 }
2185 }
2186
2187 /* Load DH params into the ctx to support DHE keys */
2188#ifndef OPENSSL_NO_DH
2189 if (ssl_dh_ptr_index >= 0)
2190 SSL_CTX_set_ex_data(cur_ctx, ssl_dh_ptr_index, NULL);
2191
2192 rv = ssl_sock_load_dh_params(cur_ctx, NULL);
2193 if (rv < 0) {
2194 if (err)
2195 memprintf(err, "%sunable to load DH parameters from file '%s'.\n",
2196 *err ? *err : "", path);
2197 rv = 1;
2198 goto end;
2199 }
2200#endif
2201
2202 /* Update key_combos */
2203 key_combos[i-1].ctx = cur_ctx;
2204 }
2205
2206 /* Update SNI Tree */
Emmanuel Hocdetd294aea2016-05-13 11:14:06 +02002207 key_combos[i-1].order = ssl_sock_add_cert_sni(cur_ctx, bind_conf, str, key_combos[i-1].order);
yanbzhu08ce6ab2015-12-02 13:01:29 -05002208 node = ebmb_next(node);
2209 }
2210
2211
2212 /* Mark a default context if none exists, using the ctx that has the most shared keys */
2213 if (!bind_conf->default_ctx) {
2214 for (i = SSL_SOCK_POSSIBLE_KT_COMBOS - 1; i >= 0; i--) {
2215 if (key_combos[i].ctx) {
2216 bind_conf->default_ctx = key_combos[i].ctx;
2217 break;
2218 }
2219 }
2220 }
2221
2222end:
2223
2224 if (names)
2225 sk_GENERAL_NAME_pop_free(names, GENERAL_NAME_free);
2226
2227 for (n = 0; n < SSL_SOCK_NUM_KEYTYPES; n++)
2228 ssl_sock_free_cert_key_and_chain_contents(&certs_and_keys[n]);
2229
2230 node = ebmb_first(&sni_keytypes_map);
2231 while (node) {
2232 next = ebmb_next(node);
2233 ebmb_delete(node);
2234 node = next;
2235 }
2236
2237 return rv;
2238}
2239#else
2240/* This is a dummy, that just logs an error and returns error */
Willy Tarreau03209342016-12-22 17:08:28 +01002241static int ssl_sock_load_multi_cert(const char *path, struct bind_conf *bind_conf, char **sni_filter, int fcount, char **err)
yanbzhu08ce6ab2015-12-02 13:01:29 -05002242{
2243 memprintf(err, "%sunable to stat SSL certificate from file '%s' : %s.\n",
2244 err && *err ? *err : "", path, strerror(errno));
2245 return 1;
2246}
2247
yanbzhu488a4d22015-12-01 15:16:07 -05002248#endif /* #if OPENSSL_VERSION_NUMBER >= 0x1000200fL: Support for loading multiple certs into a single SSL_CTX */
2249
Emeric Brunfc0421f2012-09-07 17:30:07 +02002250/* Loads a certificate key and CA chain from a file. Returns 0 on error, -1 if
2251 * an early error happens and the caller must call SSL_CTX_free() by itelf.
2252 */
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +02002253static int ssl_sock_load_cert_chain_file(SSL_CTX *ctx, const char *file, struct bind_conf *s, char **sni_filter, int fcount)
Emeric Brunfc0421f2012-09-07 17:30:07 +02002254{
2255 BIO *in;
2256 X509 *x = NULL, *ca;
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +02002257 int i, err;
Emeric Brunfc0421f2012-09-07 17:30:07 +02002258 int ret = -1;
2259 int order = 0;
2260 X509_NAME *xname;
2261 char *str;
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02002262 pem_password_cb *passwd_cb;
2263 void *passwd_cb_userdata;
2264
Emeric Brunfc0421f2012-09-07 17:30:07 +02002265#ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME
2266 STACK_OF(GENERAL_NAME) *names;
2267#endif
2268
2269 in = BIO_new(BIO_s_file());
2270 if (in == NULL)
2271 goto end;
2272
2273 if (BIO_read_filename(in, file) <= 0)
2274 goto end;
2275
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02002276
2277 passwd_cb = SSL_CTX_get_default_passwd_cb(ctx);
2278 passwd_cb_userdata = SSL_CTX_get_default_passwd_cb_userdata(ctx);
2279
2280 x = PEM_read_bio_X509_AUX(in, NULL, passwd_cb, passwd_cb_userdata);
Emeric Brunfc0421f2012-09-07 17:30:07 +02002281 if (x == NULL)
2282 goto end;
2283
Emeric Brun50bcecc2013-04-22 13:05:23 +02002284 if (fcount) {
2285 while (fcount--)
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +02002286 order = ssl_sock_add_cert_sni(ctx, s, sni_filter[fcount], order);
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01002287 }
2288 else {
Emeric Brunfc0421f2012-09-07 17:30:07 +02002289#ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01002290 names = X509_get_ext_d2i(x, NID_subject_alt_name, NULL, NULL);
2291 if (names) {
2292 for (i = 0; i < sk_GENERAL_NAME_num(names); i++) {
2293 GENERAL_NAME *name = sk_GENERAL_NAME_value(names, i);
2294 if (name->type == GEN_DNS) {
2295 if (ASN1_STRING_to_UTF8((unsigned char **)&str, name->d.dNSName) >= 0) {
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +02002296 order = ssl_sock_add_cert_sni(ctx, s, str, order);
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01002297 OPENSSL_free(str);
Emeric Brunfc0421f2012-09-07 17:30:07 +02002298 }
Emeric Brunfc0421f2012-09-07 17:30:07 +02002299 }
2300 }
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01002301 sk_GENERAL_NAME_pop_free(names, GENERAL_NAME_free);
Emeric Brunfc0421f2012-09-07 17:30:07 +02002302 }
Emeric Brunfc0421f2012-09-07 17:30:07 +02002303#endif /* SSL_CTRL_SET_TLSEXT_HOSTNAME */
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01002304 xname = X509_get_subject_name(x);
2305 i = -1;
2306 while ((i = X509_NAME_get_index_by_NID(xname, NID_commonName, i)) != -1) {
2307 X509_NAME_ENTRY *entry = X509_NAME_get_entry(xname, i);
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02002308 ASN1_STRING *value;
2309
2310 value = X509_NAME_ENTRY_get_data(entry);
2311 if (ASN1_STRING_to_UTF8((unsigned char **)&str, value) >= 0) {
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +02002312 order = ssl_sock_add_cert_sni(ctx, s, str, order);
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01002313 OPENSSL_free(str);
Emeric Brunfc0421f2012-09-07 17:30:07 +02002314 }
Emeric Brunfc0421f2012-09-07 17:30:07 +02002315 }
2316 }
2317
2318 ret = 0; /* the caller must not free the SSL_CTX argument anymore */
2319 if (!SSL_CTX_use_certificate(ctx, x))
2320 goto end;
2321
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02002322#ifdef SSL_CTX_clear_extra_chain_certs
2323 SSL_CTX_clear_extra_chain_certs(ctx);
2324#else
Emeric Brunfc0421f2012-09-07 17:30:07 +02002325 if (ctx->extra_certs != NULL) {
2326 sk_X509_pop_free(ctx->extra_certs, X509_free);
2327 ctx->extra_certs = NULL;
2328 }
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02002329#endif
Emeric Brunfc0421f2012-09-07 17:30:07 +02002330
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02002331 while ((ca = PEM_read_bio_X509(in, NULL, passwd_cb, passwd_cb_userdata))) {
Emeric Brunfc0421f2012-09-07 17:30:07 +02002332 if (!SSL_CTX_add_extra_chain_cert(ctx, ca)) {
2333 X509_free(ca);
2334 goto end;
2335 }
2336 }
2337
2338 err = ERR_get_error();
2339 if (!err || (ERR_GET_LIB(err) == ERR_LIB_PEM && ERR_GET_REASON(err) == PEM_R_NO_START_LINE)) {
2340 /* we successfully reached the last cert in the file */
2341 ret = 1;
2342 }
2343 ERR_clear_error();
2344
2345end:
2346 if (x)
2347 X509_free(x);
2348
2349 if (in)
2350 BIO_free(in);
2351
2352 return ret;
2353}
2354
Willy Tarreau03209342016-12-22 17:08:28 +01002355static int ssl_sock_load_cert_file(const char *path, struct bind_conf *bind_conf, char **sni_filter, int fcount, char **err)
Emeric Brunfc0421f2012-09-07 17:30:07 +02002356{
2357 int ret;
2358 SSL_CTX *ctx;
2359
2360 ctx = SSL_CTX_new(SSLv23_server_method());
2361 if (!ctx) {
Willy Tarreaueb6cead2012-09-20 19:43:14 +02002362 memprintf(err, "%sunable to allocate SSL context for cert '%s'.\n",
2363 err && *err ? *err : "", path);
Emeric Brunfc0421f2012-09-07 17:30:07 +02002364 return 1;
2365 }
2366
2367 if (SSL_CTX_use_PrivateKey_file(ctx, path, SSL_FILETYPE_PEM) <= 0) {
Willy Tarreaueb6cead2012-09-20 19:43:14 +02002368 memprintf(err, "%sunable to load SSL private key from PEM file '%s'.\n",
2369 err && *err ? *err : "", path);
Emeric Brunfc0421f2012-09-07 17:30:07 +02002370 SSL_CTX_free(ctx);
2371 return 1;
2372 }
2373
Emeric Brun50bcecc2013-04-22 13:05:23 +02002374 ret = ssl_sock_load_cert_chain_file(ctx, path, bind_conf, sni_filter, fcount);
Emeric Brunfc0421f2012-09-07 17:30:07 +02002375 if (ret <= 0) {
Willy Tarreaueb6cead2012-09-20 19:43:14 +02002376 memprintf(err, "%sunable to load SSL certificate from PEM file '%s'.\n",
2377 err && *err ? *err : "", path);
Emeric Brunfc0421f2012-09-07 17:30:07 +02002378 if (ret < 0) /* serious error, must do that ourselves */
2379 SSL_CTX_free(ctx);
2380 return 1;
2381 }
Emeric Brun61694ab2012-10-26 13:35:33 +02002382
2383 if (SSL_CTX_check_private_key(ctx) <= 0) {
2384 memprintf(err, "%sinconsistencies between private key and certificate loaded from PEM file '%s'.\n",
2385 err && *err ? *err : "", path);
2386 return 1;
2387 }
2388
Emeric Brunfc0421f2012-09-07 17:30:07 +02002389 /* we must not free the SSL_CTX anymore below, since it's already in
2390 * the tree, so it will be discovered and cleaned in time.
2391 */
Emeric Bruna4bcd9a2012-09-20 16:19:02 +02002392#ifndef OPENSSL_NO_DH
Remi Gacogne4f902b82015-05-28 16:23:00 +02002393 /* store a NULL pointer to indicate we have not yet loaded
2394 a custom DH param file */
2395 if (ssl_dh_ptr_index >= 0) {
2396 SSL_CTX_set_ex_data(ctx, ssl_dh_ptr_index, NULL);
2397 }
2398
Emeric Bruna4bcd9a2012-09-20 16:19:02 +02002399 ret = ssl_sock_load_dh_params(ctx, path);
2400 if (ret < 0) {
2401 if (err)
2402 memprintf(err, "%sunable to load DH parameters from file '%s'.\n",
2403 *err ? *err : "", path);
2404 return 1;
2405 }
2406#endif
2407
Lukas Tribuse4e30f72014-12-09 16:32:51 +01002408#if (defined SSL_CTRL_SET_TLSEXT_STATUS_REQ_CB && !defined OPENSSL_NO_OCSP)
Emeric Brun4147b2e2014-06-16 18:36:30 +02002409 ret = ssl_sock_load_ocsp(ctx, path);
2410 if (ret < 0) {
2411 if (err)
2412 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",
2413 *err ? *err : "", path);
2414 return 1;
2415 }
2416#endif
2417
Daniel Jakots54ffb912015-11-06 20:02:41 +01002418#if (OPENSSL_VERSION_NUMBER >= 0x1000200fL && !defined OPENSSL_NO_TLSEXT && !defined OPENSSL_IS_BORINGSSL && !defined LIBRESSL_VERSION_NUMBER)
Janusz Dziemidowicz2c701b52015-03-07 23:03:59 +01002419 if (sctl_ex_index >= 0) {
2420 ret = ssl_sock_load_sctl(ctx, path);
2421 if (ret < 0) {
2422 if (err)
2423 memprintf(err, "%s '%s.sctl' is present but cannot be read or parsed'.\n",
2424 *err ? *err : "", path);
2425 return 1;
2426 }
2427 }
2428#endif
2429
Emeric Brunfc0421f2012-09-07 17:30:07 +02002430#ifndef SSL_CTRL_SET_TLSEXT_HOSTNAME
Willy Tarreau2a65ff02012-09-13 17:54:29 +02002431 if (bind_conf->default_ctx) {
Willy Tarreaueb6cead2012-09-20 19:43:14 +02002432 memprintf(err, "%sthis version of openssl cannot load multiple SSL certificates.\n",
2433 err && *err ? *err : "");
Emeric Brunfc0421f2012-09-07 17:30:07 +02002434 return 1;
2435 }
2436#endif
Willy Tarreau2a65ff02012-09-13 17:54:29 +02002437 if (!bind_conf->default_ctx)
2438 bind_conf->default_ctx = ctx;
Emeric Brunfc0421f2012-09-07 17:30:07 +02002439
2440 return 0;
2441}
2442
Willy Tarreau03209342016-12-22 17:08:28 +01002443int ssl_sock_load_cert(char *path, struct bind_conf *bind_conf, char **err)
Emeric Brunfc0421f2012-09-07 17:30:07 +02002444{
Cyril Bonté3180f7b2015-01-25 00:16:08 +01002445 struct dirent **de_list;
2446 int i, n;
Emeric Brunfc0421f2012-09-07 17:30:07 +02002447 DIR *dir;
2448 struct stat buf;
Willy Tarreauee2663b2012-12-06 11:36:59 +01002449 char *end;
2450 char fp[MAXPATHLEN+1];
Emeric Brunfc0421f2012-09-07 17:30:07 +02002451 int cfgerr = 0;
yanbzhu63ea8462015-12-09 13:35:14 -05002452#if OPENSSL_VERSION_NUMBER >= 0x1000200fL
2453 int is_bundle;
2454 int j;
2455#endif
Emeric Brunfc0421f2012-09-07 17:30:07 +02002456
yanbzhu08ce6ab2015-12-02 13:01:29 -05002457 if (stat(path, &buf) == 0) {
2458 dir = opendir(path);
2459 if (!dir)
Willy Tarreau03209342016-12-22 17:08:28 +01002460 return ssl_sock_load_cert_file(path, bind_conf, NULL, 0, err);
Emeric Brunfc0421f2012-09-07 17:30:07 +02002461
yanbzhu08ce6ab2015-12-02 13:01:29 -05002462 /* strip trailing slashes, including first one */
2463 for (end = path + strlen(path) - 1; end >= path && *end == '/'; end--)
2464 *end = 0;
Emeric Brunfc0421f2012-09-07 17:30:07 +02002465
yanbzhu08ce6ab2015-12-02 13:01:29 -05002466 n = scandir(path, &de_list, 0, alphasort);
2467 if (n < 0) {
2468 memprintf(err, "%sunable to scan directory '%s' : %s.\n",
2469 err && *err ? *err : "", path, strerror(errno));
2470 cfgerr++;
2471 }
2472 else {
2473 for (i = 0; i < n; i++) {
2474 struct dirent *de = de_list[i];
Emeric Brun2aab7222014-06-18 18:15:09 +02002475
yanbzhu08ce6ab2015-12-02 13:01:29 -05002476 end = strrchr(de->d_name, '.');
2477 if (end && (!strcmp(end, ".issuer") || !strcmp(end, ".ocsp") || !strcmp(end, ".sctl")))
2478 goto ignore_entry;
Cyril Bonté3180f7b2015-01-25 00:16:08 +01002479
yanbzhu08ce6ab2015-12-02 13:01:29 -05002480 snprintf(fp, sizeof(fp), "%s/%s", path, de->d_name);
2481 if (stat(fp, &buf) != 0) {
2482 memprintf(err, "%sunable to stat SSL certificate from file '%s' : %s.\n",
2483 err && *err ? *err : "", fp, strerror(errno));
2484 cfgerr++;
2485 goto ignore_entry;
2486 }
2487 if (!S_ISREG(buf.st_mode))
2488 goto ignore_entry;
yanbzhu63ea8462015-12-09 13:35:14 -05002489
2490#if OPENSSL_VERSION_NUMBER >= 0x1000200fL
2491 is_bundle = 0;
2492 /* Check if current entry in directory is part of a multi-cert bundle */
2493
2494 if (end) {
2495 for (j = 0; j < SSL_SOCK_NUM_KEYTYPES; j++) {
2496 if (!strcmp(end + 1, SSL_SOCK_KEYTYPE_NAMES[j])) {
2497 is_bundle = 1;
2498 break;
2499 }
2500 }
2501
2502 if (is_bundle) {
2503 char dp[MAXPATHLEN+1] = {0}; /* this will be the filename w/o the keytype */
2504 int dp_len;
2505
2506 dp_len = end - de->d_name;
2507 snprintf(dp, dp_len + 1, "%s", de->d_name);
2508
2509 /* increment i and free de until we get to a non-bundle cert
2510 * Note here that we look at de_list[i + 1] before freeing de
2511 * this is important since ignore_entry will free de
2512 */
2513 while (i + 1 < n && !strncmp(de_list[i + 1]->d_name, dp, dp_len)) {
2514 free(de);
2515 i++;
2516 de = de_list[i];
2517 }
2518
2519 snprintf(fp, sizeof(fp), "%s/%s", path, dp);
Willy Tarreau03209342016-12-22 17:08:28 +01002520 ssl_sock_load_multi_cert(fp, bind_conf, NULL, 0, err);
yanbzhu63ea8462015-12-09 13:35:14 -05002521
2522 /* Successfully processed the bundle */
2523 goto ignore_entry;
2524 }
2525 }
2526
2527#endif
Willy Tarreau03209342016-12-22 17:08:28 +01002528 cfgerr += ssl_sock_load_cert_file(fp, bind_conf, NULL, 0, err);
yanbzhu08ce6ab2015-12-02 13:01:29 -05002529ignore_entry:
2530 free(de);
Cyril Bonté3180f7b2015-01-25 00:16:08 +01002531 }
yanbzhu08ce6ab2015-12-02 13:01:29 -05002532 free(de_list);
Emeric Brunfc0421f2012-09-07 17:30:07 +02002533 }
yanbzhu08ce6ab2015-12-02 13:01:29 -05002534 closedir(dir);
2535 return cfgerr;
Emeric Brunfc0421f2012-09-07 17:30:07 +02002536 }
yanbzhu08ce6ab2015-12-02 13:01:29 -05002537
Willy Tarreau03209342016-12-22 17:08:28 +01002538 cfgerr = ssl_sock_load_multi_cert(path, bind_conf, NULL, 0, err);
yanbzhu08ce6ab2015-12-02 13:01:29 -05002539
Emeric Brunfc0421f2012-09-07 17:30:07 +02002540 return cfgerr;
2541}
2542
Thierry Fournier383085f2013-01-24 14:15:43 +01002543/* Make sure openssl opens /dev/urandom before the chroot. The work is only
2544 * done once. Zero is returned if the operation fails. No error is returned
2545 * if the random is said as not implemented, because we expect that openssl
2546 * will use another method once needed.
2547 */
2548static int ssl_initialize_random()
2549{
2550 unsigned char random;
2551 static int random_initialized = 0;
2552
2553 if (!random_initialized && RAND_bytes(&random, 1) != 0)
2554 random_initialized = 1;
2555
2556 return random_initialized;
2557}
2558
Willy Tarreau03209342016-12-22 17:08:28 +01002559int ssl_sock_load_cert_list_file(char *file, struct bind_conf *bind_conf, char **err)
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01002560{
Emmanuel Hocdet5e0e6e42016-05-13 11:18:50 +02002561 char thisline[LINESIZE*CRTLIST_FACTOR];
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01002562 FILE *f;
yanbzhu1b04e5b2015-12-02 13:54:14 -05002563 struct stat buf;
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01002564 int linenum = 0;
2565 int cfgerr = 0;
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01002566
Willy Tarreauad1731d2013-04-02 17:35:58 +02002567 if ((f = fopen(file, "r")) == NULL) {
2568 memprintf(err, "cannot open file '%s' : %s", file, strerror(errno));
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01002569 return 1;
Willy Tarreauad1731d2013-04-02 17:35:58 +02002570 }
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01002571
2572 while (fgets(thisline, sizeof(thisline), f) != NULL) {
2573 int arg;
Emeric Brun50bcecc2013-04-22 13:05:23 +02002574 int newarg;
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01002575 char *end;
Emmanuel Hocdet5e0e6e42016-05-13 11:18:50 +02002576 char *args[MAX_LINE_ARGS*CRTLIST_FACTOR + 1];
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01002577 char *line = thisline;
2578
2579 linenum++;
2580 end = line + strlen(line);
2581 if (end-line == sizeof(thisline)-1 && *(end-1) != '\n') {
2582 /* Check if we reached the limit and the last char is not \n.
2583 * Watch out for the last line without the terminating '\n'!
2584 */
Willy Tarreauad1731d2013-04-02 17:35:58 +02002585 memprintf(err, "line %d too long in file '%s', limit is %d characters",
2586 linenum, file, (int)sizeof(thisline)-1);
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01002587 cfgerr = 1;
Willy Tarreauad1731d2013-04-02 17:35:58 +02002588 break;
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01002589 }
2590
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01002591 arg = 0;
Emeric Brun50bcecc2013-04-22 13:05:23 +02002592 newarg = 1;
2593 while (*line) {
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01002594 if (*line == '#' || *line == '\n' || *line == '\r') {
2595 /* end of string, end of loop */
2596 *line = 0;
2597 break;
2598 }
2599 else if (isspace(*line)) {
Emeric Brun50bcecc2013-04-22 13:05:23 +02002600 newarg = 1;
2601 *line = 0;
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01002602 }
Emeric Brun50bcecc2013-04-22 13:05:23 +02002603 else if (newarg) {
Emmanuel Hocdet5e0e6e42016-05-13 11:18:50 +02002604 if (arg == MAX_LINE_ARGS*CRTLIST_FACTOR) {
Emeric Brun50bcecc2013-04-22 13:05:23 +02002605 memprintf(err, "too many args on line %d in file '%s'.",
2606 linenum, file);
2607 cfgerr = 1;
2608 break;
2609 }
2610 newarg = 0;
2611 args[arg++] = line;
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01002612 }
Emeric Brun50bcecc2013-04-22 13:05:23 +02002613 line++;
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01002614 }
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +02002615 if (cfgerr)
2616 break;
Willy Tarreauad1731d2013-04-02 17:35:58 +02002617
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01002618 /* empty line */
Emeric Brun50bcecc2013-04-22 13:05:23 +02002619 if (!arg)
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01002620 continue;
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01002621
yanbzhu1b04e5b2015-12-02 13:54:14 -05002622 if (stat(args[0], &buf) == 0) {
Willy Tarreau03209342016-12-22 17:08:28 +01002623 cfgerr = ssl_sock_load_cert_file(args[0], bind_conf, &args[1], arg-1, err);
yanbzhu1b04e5b2015-12-02 13:54:14 -05002624 } else {
Willy Tarreau03209342016-12-22 17:08:28 +01002625 cfgerr = ssl_sock_load_multi_cert(args[0], bind_conf, &args[1], arg-1, err);
yanbzhu1b04e5b2015-12-02 13:54:14 -05002626 }
2627
Willy Tarreauad1731d2013-04-02 17:35:58 +02002628 if (cfgerr) {
2629 memprintf(err, "error processing line %d in file '%s' : %s", linenum, file, *err);
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01002630 break;
Willy Tarreauad1731d2013-04-02 17:35:58 +02002631 }
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01002632 }
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01002633 fclose(f);
2634 return cfgerr;
2635}
2636
Emeric Brunfc0421f2012-09-07 17:30:07 +02002637#ifndef SSL_OP_CIPHER_SERVER_PREFERENCE /* needs OpenSSL >= 0.9.7 */
2638#define SSL_OP_CIPHER_SERVER_PREFERENCE 0
2639#endif
2640
2641#ifndef SSL_OP_NO_SESSION_RESUMPTION_ON_RENEGOTIATION /* needs OpenSSL >= 0.9.7 */
2642#define SSL_OP_NO_SESSION_RESUMPTION_ON_RENEGOTIATION 0
Willy Tarreau7d588ee2012-11-26 18:47:31 +01002643#define SSL_renegotiate_pending(arg) 0
Emeric Brunfc0421f2012-09-07 17:30:07 +02002644#endif
Emeric Brun2b58d042012-09-20 17:10:03 +02002645#ifndef SSL_OP_SINGLE_ECDH_USE /* needs OpenSSL >= 0.9.8 */
2646#define SSL_OP_SINGLE_ECDH_USE 0
2647#endif
Emeric Brun2d0c4822012-10-02 13:45:20 +02002648#ifndef SSL_OP_NO_TICKET /* needs OpenSSL >= 0.9.8 */
2649#define SSL_OP_NO_TICKET 0
2650#endif
Emeric Brunfc0421f2012-09-07 17:30:07 +02002651#ifndef SSL_OP_NO_COMPRESSION /* needs OpenSSL >= 0.9.9 */
2652#define SSL_OP_NO_COMPRESSION 0
2653#endif
Emeric Brunc0ff4922012-09-28 19:37:02 +02002654#ifndef SSL_OP_NO_TLSv1_1 /* needs OpenSSL >= 1.0.1 */
2655#define SSL_OP_NO_TLSv1_1 0
2656#endif
2657#ifndef SSL_OP_NO_TLSv1_2 /* needs OpenSSL >= 1.0.1 */
2658#define SSL_OP_NO_TLSv1_2 0
2659#endif
Emeric Bruna4bcd9a2012-09-20 16:19:02 +02002660#ifndef SSL_OP_SINGLE_DH_USE /* needs OpenSSL >= 0.9.6 */
2661#define SSL_OP_SINGLE_DH_USE 0
2662#endif
Emeric Brun2b58d042012-09-20 17:10:03 +02002663#ifndef SSL_OP_SINGLE_ECDH_USE /* needs OpenSSL >= 1.0.0 */
2664#define SSL_OP_SINGLE_ECDH_USE 0
2665#endif
Emeric Brunfc0421f2012-09-07 17:30:07 +02002666#ifndef SSL_MODE_RELEASE_BUFFERS /* needs OpenSSL >= 1.0.0 */
2667#define SSL_MODE_RELEASE_BUFFERS 0
2668#endif
Willy Tarreau396a1862014-11-13 14:06:52 +01002669#ifndef SSL_MODE_SMALL_BUFFERS /* needs small_records.patch */
2670#define SSL_MODE_SMALL_BUFFERS 0
2671#endif
Remi Gacognef46cd6e2014-06-12 14:58:40 +02002672
Willy Tarreau03209342016-12-22 17:08:28 +01002673int ssl_sock_prepare_ctx(struct bind_conf *bind_conf, SSL_CTX *ctx)
Emeric Brunfc0421f2012-09-07 17:30:07 +02002674{
Willy Tarreau03209342016-12-22 17:08:28 +01002675 struct proxy *curproxy = bind_conf->frontend;
Emeric Brunfc0421f2012-09-07 17:30:07 +02002676 int cfgerr = 0;
Emeric Brun850efd52014-01-29 12:24:34 +01002677 int verify = SSL_VERIFY_NONE;
Remi Gacogneaf5c3da2014-05-19 10:29:58 +02002678 long ssloptions =
Emeric Brunfc0421f2012-09-07 17:30:07 +02002679 SSL_OP_ALL | /* all known workarounds for bugs */
2680 SSL_OP_NO_SSLv2 |
2681 SSL_OP_NO_COMPRESSION |
Emeric Bruna4bcd9a2012-09-20 16:19:02 +02002682 SSL_OP_SINGLE_DH_USE |
Emeric Brun2b58d042012-09-20 17:10:03 +02002683 SSL_OP_SINGLE_ECDH_USE |
Emeric Brun3c4bc6e2012-10-04 18:44:19 +02002684 SSL_OP_NO_SESSION_RESUMPTION_ON_RENEGOTIATION |
2685 SSL_OP_CIPHER_SERVER_PREFERENCE;
Remi Gacogneaf5c3da2014-05-19 10:29:58 +02002686 long sslmode =
Emeric Brunfc0421f2012-09-07 17:30:07 +02002687 SSL_MODE_ENABLE_PARTIAL_WRITE |
2688 SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER |
Willy Tarreau396a1862014-11-13 14:06:52 +01002689 SSL_MODE_RELEASE_BUFFERS |
2690 SSL_MODE_SMALL_BUFFERS;
Remi Gacognef46cd6e2014-06-12 14:58:40 +02002691 STACK_OF(SSL_CIPHER) * ciphers = NULL;
Willy Tarreaua616ba62014-10-26 06:49:19 +01002692 SSL_CIPHER * cipher = NULL;
Remi Gacognec1eab8c2014-06-12 18:20:11 +02002693 char cipher_description[128];
2694 /* The description of ciphers using an Ephemeral Diffie Hellman key exchange
2695 contains " Kx=DH " or " Kx=DH(". Beware of " Kx=DH/",
2696 which is not ephemeral DH. */
2697 const char dhe_description[] = " Kx=DH ";
2698 const char dhe_export_description[] = " Kx=DH(";
Remi Gacognef46cd6e2014-06-12 14:58:40 +02002699 int idx = 0;
2700 int dhe_found = 0;
Remi Gacogne23d5d372014-10-10 17:04:26 +02002701 SSL *ssl = NULL;
Emeric Brunfc0421f2012-09-07 17:30:07 +02002702
Thierry Fournier383085f2013-01-24 14:15:43 +01002703 /* Make sure openssl opens /dev/urandom before the chroot */
2704 if (!ssl_initialize_random()) {
2705 Alert("OpenSSL random data generator initialization failed.\n");
2706 cfgerr++;
2707 }
2708
Emeric Brun89675492012-10-05 13:48:26 +02002709 if (bind_conf->ssl_options & BC_SSL_O_NO_SSLV3)
Emeric Brunfc0421f2012-09-07 17:30:07 +02002710 ssloptions |= SSL_OP_NO_SSLv3;
Emeric Brun89675492012-10-05 13:48:26 +02002711 if (bind_conf->ssl_options & BC_SSL_O_NO_TLSV10)
Emeric Brunfc0421f2012-09-07 17:30:07 +02002712 ssloptions |= SSL_OP_NO_TLSv1;
Emeric Brun89675492012-10-05 13:48:26 +02002713 if (bind_conf->ssl_options & BC_SSL_O_NO_TLSV11)
Emeric Brunc0ff4922012-09-28 19:37:02 +02002714 ssloptions |= SSL_OP_NO_TLSv1_1;
Emeric Brun89675492012-10-05 13:48:26 +02002715 if (bind_conf->ssl_options & BC_SSL_O_NO_TLSV12)
Emeric Brunc0ff4922012-09-28 19:37:02 +02002716 ssloptions |= SSL_OP_NO_TLSv1_2;
Emeric Brun89675492012-10-05 13:48:26 +02002717 if (bind_conf->ssl_options & BC_SSL_O_NO_TLS_TICKETS)
Emeric Brun2d0c4822012-10-02 13:45:20 +02002718 ssloptions |= SSL_OP_NO_TICKET;
Jérémie Courrèges-Anglas17c3f622015-07-25 16:50:52 -06002719 if (bind_conf->ssl_options & BC_SSL_O_USE_SSLV3) {
2720#ifndef OPENSSL_NO_SSL3
Emeric Brun2cb7ae52012-10-05 14:14:21 +02002721 SSL_CTX_set_ssl_version(ctx, SSLv3_server_method());
Jérémie Courrèges-Anglas17c3f622015-07-25 16:50:52 -06002722#else
2723 Alert("SSLv3 support requested but unavailable.\n");
2724 cfgerr++;
2725#endif
2726 }
Emeric Brun2cb7ae52012-10-05 14:14:21 +02002727 if (bind_conf->ssl_options & BC_SSL_O_USE_TLSV10)
2728 SSL_CTX_set_ssl_version(ctx, TLSv1_server_method());
2729#if SSL_OP_NO_TLSv1_1
2730 if (bind_conf->ssl_options & BC_SSL_O_USE_TLSV11)
2731 SSL_CTX_set_ssl_version(ctx, TLSv1_1_server_method());
2732#endif
2733#if SSL_OP_NO_TLSv1_2
2734 if (bind_conf->ssl_options & BC_SSL_O_USE_TLSV12)
2735 SSL_CTX_set_ssl_version(ctx, TLSv1_2_server_method());
2736#endif
Emeric Brunfc0421f2012-09-07 17:30:07 +02002737
2738 SSL_CTX_set_options(ctx, ssloptions);
2739 SSL_CTX_set_mode(ctx, sslmode);
Emeric Brun850efd52014-01-29 12:24:34 +01002740 switch (bind_conf->verify) {
2741 case SSL_SOCK_VERIFY_NONE:
2742 verify = SSL_VERIFY_NONE;
2743 break;
2744 case SSL_SOCK_VERIFY_OPTIONAL:
2745 verify = SSL_VERIFY_PEER;
2746 break;
2747 case SSL_SOCK_VERIFY_REQUIRED:
2748 verify = SSL_VERIFY_PEER|SSL_VERIFY_FAIL_IF_NO_PEER_CERT;
2749 break;
2750 }
2751 SSL_CTX_set_verify(ctx, verify, ssl_sock_bind_verifycbk);
2752 if (verify & SSL_VERIFY_PEER) {
Emeric Brunfb510ea2012-10-05 12:00:26 +02002753 if (bind_conf->ca_file) {
Emeric Brund94b3fe2012-09-20 18:23:56 +02002754 /* load CAfile to verify */
Emeric Brunfb510ea2012-10-05 12:00:26 +02002755 if (!SSL_CTX_load_verify_locations(ctx, bind_conf->ca_file, NULL)) {
Emeric Brund94b3fe2012-09-20 18:23:56 +02002756 Alert("Proxy '%s': unable to load CA file '%s' for bind '%s' at [%s:%d].\n",
Emeric Brunfb510ea2012-10-05 12:00:26 +02002757 curproxy->id, bind_conf->ca_file, bind_conf->arg, bind_conf->file, bind_conf->line);
Emeric Brund94b3fe2012-09-20 18:23:56 +02002758 cfgerr++;
2759 }
2760 /* set CA names fo client cert request, function returns void */
Emeric Brunfb510ea2012-10-05 12:00:26 +02002761 SSL_CTX_set_client_CA_list(ctx, SSL_load_client_CA_file(bind_conf->ca_file));
Emeric Brund94b3fe2012-09-20 18:23:56 +02002762 }
Emeric Brun850efd52014-01-29 12:24:34 +01002763 else {
2764 Alert("Proxy '%s': verify is enabled but no CA file specified for bind '%s' at [%s:%d].\n",
2765 curproxy->id, bind_conf->arg, bind_conf->file, bind_conf->line);
2766 cfgerr++;
2767 }
Emeric Brun051cdab2012-10-02 19:25:50 +02002768#ifdef X509_V_FLAG_CRL_CHECK
Emeric Brunfb510ea2012-10-05 12:00:26 +02002769 if (bind_conf->crl_file) {
Emeric Brund94b3fe2012-09-20 18:23:56 +02002770 X509_STORE *store = SSL_CTX_get_cert_store(ctx);
2771
Emeric Brunfb510ea2012-10-05 12:00:26 +02002772 if (!store || !X509_STORE_load_locations(store, bind_conf->crl_file, NULL)) {
Emeric Brund94b3fe2012-09-20 18:23:56 +02002773 Alert("Proxy '%s': unable to configure CRL file '%s' for bind '%s' at [%s:%d].\n",
Alexander Rigbofc65af02015-04-07 14:02:16 +02002774 curproxy->id, bind_conf->crl_file, bind_conf->arg, bind_conf->file, bind_conf->line);
Emeric Brund94b3fe2012-09-20 18:23:56 +02002775 cfgerr++;
2776 }
Emeric Brun561e5742012-10-02 15:20:55 +02002777 else {
2778 X509_STORE_set_flags(store, X509_V_FLAG_CRL_CHECK|X509_V_FLAG_CRL_CHECK_ALL);
2779 }
Emeric Brund94b3fe2012-09-20 18:23:56 +02002780 }
Emeric Brun051cdab2012-10-02 19:25:50 +02002781#endif
Emeric Brun644cde02012-12-14 11:21:13 +01002782 ERR_clear_error();
Emeric Brund94b3fe2012-09-20 18:23:56 +02002783 }
Emeric Brunfc0421f2012-09-07 17:30:07 +02002784
Nenad Merdanovic05552d42015-02-27 19:56:49 +01002785#if (defined SSL_CTRL_SET_TLSEXT_TICKET_KEY_CB && TLS_TICKETS_NO > 0)
Nenad Merdanovic146defa2015-05-09 08:46:00 +02002786 if(bind_conf->keys_ref) {
Nenad Merdanovic05552d42015-02-27 19:56:49 +01002787 if (!SSL_CTX_set_tlsext_ticket_key_cb(ctx, ssl_tlsext_ticket_key_cb)) {
2788 Alert("Proxy '%s': unable to set callback for TLS ticket validation for bind '%s' at [%s:%d].\n",
2789 curproxy->id, bind_conf->arg, bind_conf->file, bind_conf->line);
2790 cfgerr++;
2791 }
2792 }
2793#endif
2794
Emeric Brun4f65bff2012-11-16 15:11:00 +01002795 if (global.tune.ssllifetime)
2796 SSL_CTX_set_timeout(ctx, global.tune.ssllifetime);
2797
Emeric Brunfc0421f2012-09-07 17:30:07 +02002798 shared_context_set_cache(ctx);
Willy Tarreau2a65ff02012-09-13 17:54:29 +02002799 if (bind_conf->ciphers &&
2800 !SSL_CTX_set_cipher_list(ctx, bind_conf->ciphers)) {
Emeric Brunfc0421f2012-09-07 17:30:07 +02002801 Alert("Proxy '%s': unable to set SSL cipher list to '%s' for bind '%s' at [%s:%d].\n",
Willy Tarreau2a65ff02012-09-13 17:54:29 +02002802 curproxy->id, bind_conf->ciphers, bind_conf->arg, bind_conf->file, bind_conf->line);
Emeric Brunfc0421f2012-09-07 17:30:07 +02002803 cfgerr++;
2804 }
2805
Remi Gacogne47783ef2015-05-29 15:53:22 +02002806 /* If tune.ssl.default-dh-param has not been set,
2807 neither has ssl-default-dh-file and no static DH
2808 params were in the certificate file. */
Remi Gacogne4f902b82015-05-28 16:23:00 +02002809 if (global.tune.ssl_default_dh_param == 0 &&
Remi Gacogne47783ef2015-05-29 15:53:22 +02002810 global_dh == NULL &&
Remi Gacogne4f902b82015-05-28 16:23:00 +02002811 (ssl_dh_ptr_index == -1 ||
2812 SSL_CTX_get_ex_data(ctx, ssl_dh_ptr_index) == NULL)) {
Lukas Tribus90132722014-08-18 00:56:33 +02002813
Remi Gacogne23d5d372014-10-10 17:04:26 +02002814 ssl = SSL_new(ctx);
Remi Gacognef46cd6e2014-06-12 14:58:40 +02002815
Remi Gacogne23d5d372014-10-10 17:04:26 +02002816 if (ssl) {
2817 ciphers = SSL_get_ciphers(ssl);
2818
2819 if (ciphers) {
2820 for (idx = 0; idx < sk_SSL_CIPHER_num(ciphers); idx++) {
2821 cipher = sk_SSL_CIPHER_value(ciphers, idx);
2822 if (SSL_CIPHER_description(cipher, cipher_description, sizeof (cipher_description)) == cipher_description) {
2823 if (strstr(cipher_description, dhe_description) != NULL ||
2824 strstr(cipher_description, dhe_export_description) != NULL) {
2825 dhe_found = 1;
2826 break;
2827 }
Remi Gacognec1eab8c2014-06-12 18:20:11 +02002828 }
Remi Gacognef46cd6e2014-06-12 14:58:40 +02002829 }
2830 }
Remi Gacogne23d5d372014-10-10 17:04:26 +02002831 SSL_free(ssl);
2832 ssl = NULL;
Lukas Tribus90132722014-08-18 00:56:33 +02002833 }
Remi Gacognef46cd6e2014-06-12 14:58:40 +02002834
Lukas Tribus90132722014-08-18 00:56:33 +02002835 if (dhe_found) {
2836 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 +02002837 }
2838
2839 global.tune.ssl_default_dh_param = 1024;
2840 }
Remi Gacogne8de54152014-07-15 11:36:40 +02002841
2842#ifndef OPENSSL_NO_DH
2843 if (global.tune.ssl_default_dh_param >= 1024) {
2844 if (local_dh_1024 == NULL) {
2845 local_dh_1024 = ssl_get_dh_1024();
2846 }
2847 if (global.tune.ssl_default_dh_param >= 2048) {
2848 if (local_dh_2048 == NULL) {
2849 local_dh_2048 = ssl_get_dh_2048();
2850 }
2851 if (global.tune.ssl_default_dh_param >= 4096) {
2852 if (local_dh_4096 == NULL) {
2853 local_dh_4096 = ssl_get_dh_4096();
2854 }
Remi Gacogne8de54152014-07-15 11:36:40 +02002855 }
2856 }
2857 }
2858#endif /* OPENSSL_NO_DH */
Remi Gacognef46cd6e2014-06-12 14:58:40 +02002859
Emeric Brunfc0421f2012-09-07 17:30:07 +02002860 SSL_CTX_set_info_callback(ctx, ssl_sock_infocbk);
Willy Tarreau5cbe4ef2014-05-08 22:45:11 +02002861#if OPENSSL_VERSION_NUMBER >= 0x00907000L
Emeric Brun29f037d2014-04-25 19:05:36 +02002862 SSL_CTX_set_msg_callback(ctx, ssl_sock_msgcbk);
Willy Tarreau5cbe4ef2014-05-08 22:45:11 +02002863#endif
Emeric Brun29f037d2014-04-25 19:05:36 +02002864
Willy Tarreau6c9a3d52012-10-18 18:57:14 +02002865#ifdef OPENSSL_NPN_NEGOTIATED
2866 if (bind_conf->npn_str)
2867 SSL_CTX_set_next_protos_advertised_cb(ctx, ssl_sock_advertise_npn_protos, bind_conf);
2868#endif
Dirkjan Bussink48f1c4e2014-02-13 12:29:42 +01002869#ifdef TLSEXT_TYPE_application_layer_protocol_negotiation
Willy Tarreauab861d32013-04-02 02:30:41 +02002870 if (bind_conf->alpn_str)
Dirkjan Bussink48f1c4e2014-02-13 12:29:42 +01002871 SSL_CTX_set_alpn_select_cb(ctx, ssl_sock_advertise_alpn_protos, bind_conf);
Willy Tarreauab861d32013-04-02 02:30:41 +02002872#endif
Willy Tarreau6c9a3d52012-10-18 18:57:14 +02002873
Emeric Brunfc0421f2012-09-07 17:30:07 +02002874#ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME
2875 SSL_CTX_set_tlsext_servername_callback(ctx, ssl_sock_switchctx_cbk);
Willy Tarreau2a65ff02012-09-13 17:54:29 +02002876 SSL_CTX_set_tlsext_servername_arg(ctx, bind_conf);
Emeric Brunfc0421f2012-09-07 17:30:07 +02002877#endif
Emeric Brun2b58d042012-09-20 17:10:03 +02002878#if defined(SSL_CTX_set_tmp_ecdh) && !defined(OPENSSL_NO_ECDH)
Emeric Brun6924ef82013-03-06 14:08:53 +01002879 {
Emeric Brun2b58d042012-09-20 17:10:03 +02002880 int i;
2881 EC_KEY *ecdh;
2882
Emeric Brun6924ef82013-03-06 14:08:53 +01002883 i = OBJ_sn2nid(bind_conf->ecdhe ? bind_conf->ecdhe : ECDHE_DEFAULT_CURVE);
Emeric Brun2b58d042012-09-20 17:10:03 +02002884 if (!i || ((ecdh = EC_KEY_new_by_curve_name(i)) == NULL)) {
2885 Alert("Proxy '%s': unable to set elliptic named curve to '%s' for bind '%s' at [%s:%d].\n",
Emeric Brun6924ef82013-03-06 14:08:53 +01002886 curproxy->id, bind_conf->ecdhe ? bind_conf->ecdhe : ECDHE_DEFAULT_CURVE,
2887 bind_conf->arg, bind_conf->file, bind_conf->line);
Emeric Brun2b58d042012-09-20 17:10:03 +02002888 cfgerr++;
2889 }
2890 else {
2891 SSL_CTX_set_tmp_ecdh(ctx, ecdh);
2892 EC_KEY_free(ecdh);
2893 }
2894 }
2895#endif
2896
Emeric Brunfc0421f2012-09-07 17:30:07 +02002897 return cfgerr;
2898}
2899
Evan Broderbe554312013-06-27 00:05:25 -07002900static int ssl_sock_srv_hostcheck(const char *pattern, const char *hostname)
2901{
2902 const char *pattern_wildcard, *pattern_left_label_end, *hostname_left_label_end;
2903 size_t prefixlen, suffixlen;
2904
2905 /* Trivial case */
2906 if (strcmp(pattern, hostname) == 0)
2907 return 1;
2908
Evan Broderbe554312013-06-27 00:05:25 -07002909 /* The rest of this logic is based on RFC 6125, section 6.4.3
2910 * (http://tools.ietf.org/html/rfc6125#section-6.4.3) */
2911
Emeric Bruna848dae2013-10-08 11:27:28 +02002912 pattern_wildcard = NULL;
2913 pattern_left_label_end = pattern;
2914 while (*pattern_left_label_end != '.') {
2915 switch (*pattern_left_label_end) {
2916 case 0:
2917 /* End of label not found */
2918 return 0;
2919 case '*':
2920 /* If there is more than one wildcards */
2921 if (pattern_wildcard)
2922 return 0;
2923 pattern_wildcard = pattern_left_label_end;
2924 break;
2925 }
2926 pattern_left_label_end++;
2927 }
2928
2929 /* If it's not trivial and there is no wildcard, it can't
2930 * match */
2931 if (!pattern_wildcard)
Evan Broderbe554312013-06-27 00:05:25 -07002932 return 0;
2933
2934 /* Make sure all labels match except the leftmost */
2935 hostname_left_label_end = strchr(hostname, '.');
2936 if (!hostname_left_label_end
2937 || strcmp(pattern_left_label_end, hostname_left_label_end) != 0)
2938 return 0;
2939
2940 /* Make sure the leftmost label of the hostname is long enough
2941 * that the wildcard can match */
Emeric Brun369da852013-10-08 11:39:35 +02002942 if (hostname_left_label_end - hostname < (pattern_left_label_end - pattern) - 1)
Evan Broderbe554312013-06-27 00:05:25 -07002943 return 0;
2944
2945 /* Finally compare the string on either side of the
2946 * wildcard */
2947 prefixlen = pattern_wildcard - pattern;
2948 suffixlen = pattern_left_label_end - (pattern_wildcard + 1);
Emeric Bruna848dae2013-10-08 11:27:28 +02002949 if ((prefixlen && (memcmp(pattern, hostname, prefixlen) != 0))
2950 || (suffixlen && (memcmp(pattern_wildcard + 1, hostname_left_label_end - suffixlen, suffixlen) != 0)))
Evan Broderbe554312013-06-27 00:05:25 -07002951 return 0;
2952
2953 return 1;
2954}
2955
2956static int ssl_sock_srv_verifycbk(int ok, X509_STORE_CTX *ctx)
2957{
2958 SSL *ssl;
2959 struct connection *conn;
2960 char *servername;
2961
2962 int depth;
2963 X509 *cert;
2964 STACK_OF(GENERAL_NAME) *alt_names;
2965 int i;
2966 X509_NAME *cert_subject;
2967 char *str;
2968
2969 if (ok == 0)
2970 return ok;
2971
2972 ssl = X509_STORE_CTX_get_ex_data(ctx, SSL_get_ex_data_X509_STORE_CTX_idx());
Vincent Bernat3c2f2f22016-04-03 13:48:42 +02002973 conn = SSL_get_app_data(ssl);
Evan Broderbe554312013-06-27 00:05:25 -07002974
2975 servername = objt_server(conn->target)->ssl_ctx.verify_host;
2976
2977 /* We only need to verify the CN on the actual server cert,
2978 * not the indirect CAs */
2979 depth = X509_STORE_CTX_get_error_depth(ctx);
2980 if (depth != 0)
2981 return ok;
2982
2983 /* At this point, the cert is *not* OK unless we can find a
2984 * hostname match */
2985 ok = 0;
2986
2987 cert = X509_STORE_CTX_get_current_cert(ctx);
2988 /* It seems like this might happen if verify peer isn't set */
2989 if (!cert)
2990 return ok;
2991
2992 alt_names = X509_get_ext_d2i(cert, NID_subject_alt_name, NULL, NULL);
2993 if (alt_names) {
2994 for (i = 0; !ok && i < sk_GENERAL_NAME_num(alt_names); i++) {
2995 GENERAL_NAME *name = sk_GENERAL_NAME_value(alt_names, i);
2996 if (name->type == GEN_DNS) {
Emeric Bruna33410c2013-09-17 15:47:48 +02002997#if OPENSSL_VERSION_NUMBER < 0x00907000L
2998 if (ASN1_STRING_to_UTF8((unsigned char **)&str, name->d.ia5) >= 0) {
2999#else
Evan Broderbe554312013-06-27 00:05:25 -07003000 if (ASN1_STRING_to_UTF8((unsigned char **)&str, name->d.dNSName) >= 0) {
Emeric Bruna33410c2013-09-17 15:47:48 +02003001#endif
Evan Broderbe554312013-06-27 00:05:25 -07003002 ok = ssl_sock_srv_hostcheck(str, servername);
3003 OPENSSL_free(str);
3004 }
3005 }
3006 }
Emeric Brun4ad50a42013-09-17 15:19:54 +02003007 sk_GENERAL_NAME_pop_free(alt_names, GENERAL_NAME_free);
Evan Broderbe554312013-06-27 00:05:25 -07003008 }
3009
3010 cert_subject = X509_get_subject_name(cert);
3011 i = -1;
3012 while (!ok && (i = X509_NAME_get_index_by_NID(cert_subject, NID_commonName, i)) != -1) {
3013 X509_NAME_ENTRY *entry = X509_NAME_get_entry(cert_subject, i);
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02003014 ASN1_STRING *value;
3015 value = X509_NAME_ENTRY_get_data(entry);
3016 if (ASN1_STRING_to_UTF8((unsigned char **)&str, value) >= 0) {
Evan Broderbe554312013-06-27 00:05:25 -07003017 ok = ssl_sock_srv_hostcheck(str, servername);
3018 OPENSSL_free(str);
3019 }
3020 }
3021
3022 return ok;
3023}
3024
Emeric Brun94324a42012-10-11 14:00:19 +02003025/* prepare ssl context from servers options. Returns an error count */
Willy Tarreau03209342016-12-22 17:08:28 +01003026int ssl_sock_prepare_srv_ctx(struct server *srv)
Emeric Brun94324a42012-10-11 14:00:19 +02003027{
Willy Tarreau03209342016-12-22 17:08:28 +01003028 struct proxy *curproxy = srv->proxy;
Emeric Brun94324a42012-10-11 14:00:19 +02003029 int cfgerr = 0;
Remi Gacogneaf5c3da2014-05-19 10:29:58 +02003030 long options =
Emeric Brun94324a42012-10-11 14:00:19 +02003031 SSL_OP_ALL | /* all known workarounds for bugs */
3032 SSL_OP_NO_SSLv2 |
3033 SSL_OP_NO_COMPRESSION;
Remi Gacogneaf5c3da2014-05-19 10:29:58 +02003034 long mode =
Emeric Brun94324a42012-10-11 14:00:19 +02003035 SSL_MODE_ENABLE_PARTIAL_WRITE |
3036 SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER |
Willy Tarreau396a1862014-11-13 14:06:52 +01003037 SSL_MODE_RELEASE_BUFFERS |
3038 SSL_MODE_SMALL_BUFFERS;
Emeric Brun850efd52014-01-29 12:24:34 +01003039 int verify = SSL_VERIFY_NONE;
Emeric Brun94324a42012-10-11 14:00:19 +02003040
Thierry Fournier383085f2013-01-24 14:15:43 +01003041 /* Make sure openssl opens /dev/urandom before the chroot */
3042 if (!ssl_initialize_random()) {
3043 Alert("OpenSSL random data generator initialization failed.\n");
3044 cfgerr++;
3045 }
3046
Willy Tarreaufce03112015-01-15 21:32:40 +01003047 /* Automatic memory computations need to know we use SSL there */
3048 global.ssl_used_backend = 1;
3049
3050 /* Initiate SSL context for current server */
Emeric Brun94324a42012-10-11 14:00:19 +02003051 srv->ssl_ctx.reused_sess = NULL;
3052 if (srv->use_ssl)
3053 srv->xprt = &ssl_sock;
3054 if (srv->check.use_ssl)
Cyril Bonté9ce13112014-11-15 22:41:27 +01003055 srv->check.xprt = &ssl_sock;
Emeric Brun94324a42012-10-11 14:00:19 +02003056
3057 srv->ssl_ctx.ctx = SSL_CTX_new(SSLv23_client_method());
3058 if (!srv->ssl_ctx.ctx) {
3059 Alert("config : %s '%s', server '%s': unable to allocate ssl context.\n",
3060 proxy_type_str(curproxy), curproxy->id,
3061 srv->id);
3062 cfgerr++;
3063 return cfgerr;
3064 }
Emeric Bruna7aa3092012-10-26 12:58:00 +02003065 if (srv->ssl_ctx.client_crt) {
3066 if (SSL_CTX_use_PrivateKey_file(srv->ssl_ctx.ctx, srv->ssl_ctx.client_crt, SSL_FILETYPE_PEM) <= 0) {
3067 Alert("config : %s '%s', server '%s': unable to load SSL private key from PEM file '%s'.\n",
3068 proxy_type_str(curproxy), curproxy->id,
3069 srv->id, srv->ssl_ctx.client_crt);
3070 cfgerr++;
3071 }
3072 else if (SSL_CTX_use_certificate_chain_file(srv->ssl_ctx.ctx, srv->ssl_ctx.client_crt) <= 0) {
3073 Alert("config : %s '%s', server '%s': unable to load ssl certificate from PEM file '%s'.\n",
3074 proxy_type_str(curproxy), curproxy->id,
3075 srv->id, srv->ssl_ctx.client_crt);
3076 cfgerr++;
3077 }
3078 else if (SSL_CTX_check_private_key(srv->ssl_ctx.ctx) <= 0) {
3079 Alert("config : %s '%s', server '%s': inconsistencies between private key and certificate loaded from PEM file '%s'.\n",
3080 proxy_type_str(curproxy), curproxy->id,
3081 srv->id, srv->ssl_ctx.client_crt);
3082 cfgerr++;
3083 }
3084 }
Emeric Brun94324a42012-10-11 14:00:19 +02003085
3086 if (srv->ssl_ctx.options & SRV_SSL_O_NO_SSLV3)
3087 options |= SSL_OP_NO_SSLv3;
3088 if (srv->ssl_ctx.options & SRV_SSL_O_NO_TLSV10)
3089 options |= SSL_OP_NO_TLSv1;
3090 if (srv->ssl_ctx.options & SRV_SSL_O_NO_TLSV11)
3091 options |= SSL_OP_NO_TLSv1_1;
3092 if (srv->ssl_ctx.options & SRV_SSL_O_NO_TLSV12)
3093 options |= SSL_OP_NO_TLSv1_2;
Emeric Brunf9c5c472012-10-11 15:28:34 +02003094 if (srv->ssl_ctx.options & SRV_SSL_O_NO_TLS_TICKETS)
3095 options |= SSL_OP_NO_TICKET;
Jérémie Courrèges-Anglas17c3f622015-07-25 16:50:52 -06003096 if (srv->ssl_ctx.options & SRV_SSL_O_USE_SSLV3) {
3097#ifndef OPENSSL_NO_SSL3
Emeric Brun94324a42012-10-11 14:00:19 +02003098 SSL_CTX_set_ssl_version(srv->ssl_ctx.ctx, SSLv3_client_method());
Jérémie Courrèges-Anglas17c3f622015-07-25 16:50:52 -06003099#else
Thierry FOURNIERbc965342015-08-26 08:21:26 +02003100 Alert("SSLv3 support requested but unavailable.\n");
Jérémie Courrèges-Anglas17c3f622015-07-25 16:50:52 -06003101 cfgerr++;
3102#endif
3103 }
Emeric Brun94324a42012-10-11 14:00:19 +02003104 if (srv->ssl_ctx.options & SRV_SSL_O_USE_TLSV10)
3105 SSL_CTX_set_ssl_version(srv->ssl_ctx.ctx, TLSv1_client_method());
3106#if SSL_OP_NO_TLSv1_1
3107 if (srv->ssl_ctx.options & SRV_SSL_O_USE_TLSV11)
3108 SSL_CTX_set_ssl_version(srv->ssl_ctx.ctx, TLSv1_1_client_method());
3109#endif
3110#if SSL_OP_NO_TLSv1_2
3111 if (srv->ssl_ctx.options & SRV_SSL_O_USE_TLSV12)
3112 SSL_CTX_set_ssl_version(srv->ssl_ctx.ctx, TLSv1_2_client_method());
3113#endif
3114
3115 SSL_CTX_set_options(srv->ssl_ctx.ctx, options);
3116 SSL_CTX_set_mode(srv->ssl_ctx.ctx, mode);
Emeric Brun850efd52014-01-29 12:24:34 +01003117
3118 if (global.ssl_server_verify == SSL_SERVER_VERIFY_REQUIRED)
3119 verify = SSL_VERIFY_PEER;
3120
3121 switch (srv->ssl_ctx.verify) {
3122 case SSL_SOCK_VERIFY_NONE:
3123 verify = SSL_VERIFY_NONE;
3124 break;
3125 case SSL_SOCK_VERIFY_REQUIRED:
3126 verify = SSL_VERIFY_PEER;
3127 break;
3128 }
Evan Broderbe554312013-06-27 00:05:25 -07003129 SSL_CTX_set_verify(srv->ssl_ctx.ctx,
Emeric Brun850efd52014-01-29 12:24:34 +01003130 verify,
Evan Broderbe554312013-06-27 00:05:25 -07003131 srv->ssl_ctx.verify_host ? ssl_sock_srv_verifycbk : NULL);
Emeric Brun850efd52014-01-29 12:24:34 +01003132 if (verify & SSL_VERIFY_PEER) {
Emeric Brunef42d922012-10-11 16:11:36 +02003133 if (srv->ssl_ctx.ca_file) {
3134 /* load CAfile to verify */
3135 if (!SSL_CTX_load_verify_locations(srv->ssl_ctx.ctx, srv->ssl_ctx.ca_file, NULL)) {
Willy Tarreau07ba08b2014-02-16 19:22:08 +01003136 Alert("Proxy '%s', server '%s' [%s:%d] unable to load CA file '%s'.\n",
Emeric Brunef42d922012-10-11 16:11:36 +02003137 curproxy->id, srv->id,
3138 srv->conf.file, srv->conf.line, srv->ssl_ctx.ca_file);
3139 cfgerr++;
3140 }
3141 }
Emeric Brun850efd52014-01-29 12:24:34 +01003142 else {
3143 if (global.ssl_server_verify == SSL_SERVER_VERIFY_REQUIRED)
Willy Tarreau07ba08b2014-02-16 19:22:08 +01003144 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 +01003145 curproxy->id, srv->id,
3146 srv->conf.file, srv->conf.line);
3147 else
Willy Tarreau07ba08b2014-02-16 19:22:08 +01003148 Alert("Proxy '%s', server '%s' [%s:%d] verify is enabled but no CA file specified.\n",
Emeric Brun850efd52014-01-29 12:24:34 +01003149 curproxy->id, srv->id,
3150 srv->conf.file, srv->conf.line);
3151 cfgerr++;
3152 }
Emeric Brunef42d922012-10-11 16:11:36 +02003153#ifdef X509_V_FLAG_CRL_CHECK
3154 if (srv->ssl_ctx.crl_file) {
3155 X509_STORE *store = SSL_CTX_get_cert_store(srv->ssl_ctx.ctx);
3156
3157 if (!store || !X509_STORE_load_locations(store, srv->ssl_ctx.crl_file, NULL)) {
Willy Tarreau07ba08b2014-02-16 19:22:08 +01003158 Alert("Proxy '%s', server '%s' [%s:%d] unable to configure CRL file '%s'.\n",
Emeric Brunef42d922012-10-11 16:11:36 +02003159 curproxy->id, srv->id,
3160 srv->conf.file, srv->conf.line, srv->ssl_ctx.crl_file);
3161 cfgerr++;
3162 }
3163 else {
3164 X509_STORE_set_flags(store, X509_V_FLAG_CRL_CHECK|X509_V_FLAG_CRL_CHECK_ALL);
3165 }
3166 }
3167#endif
3168 }
3169
Emeric Brun4f65bff2012-11-16 15:11:00 +01003170 if (global.tune.ssllifetime)
3171 SSL_CTX_set_timeout(srv->ssl_ctx.ctx, global.tune.ssllifetime);
3172
Emeric Brun94324a42012-10-11 14:00:19 +02003173 SSL_CTX_set_session_cache_mode(srv->ssl_ctx.ctx, SSL_SESS_CACHE_OFF);
3174 if (srv->ssl_ctx.ciphers &&
3175 !SSL_CTX_set_cipher_list(srv->ssl_ctx.ctx, srv->ssl_ctx.ciphers)) {
3176 Alert("Proxy '%s', server '%s' [%s:%d] : unable to set SSL cipher list to '%s'.\n",
3177 curproxy->id, srv->id,
3178 srv->conf.file, srv->conf.line, srv->ssl_ctx.ciphers);
3179 cfgerr++;
3180 }
3181
3182 return cfgerr;
3183}
3184
Willy Tarreau2a65ff02012-09-13 17:54:29 +02003185/* Walks down the two trees in bind_conf and prepares all certs. The pointer may
Emeric Brunfc0421f2012-09-07 17:30:07 +02003186 * be NULL, in which case nothing is done. Returns the number of errors
3187 * encountered.
3188 */
Willy Tarreau03209342016-12-22 17:08:28 +01003189int ssl_sock_prepare_all_ctx(struct bind_conf *bind_conf)
Emeric Brunfc0421f2012-09-07 17:30:07 +02003190{
3191 struct ebmb_node *node;
3192 struct sni_ctx *sni;
3193 int err = 0;
3194
Willy Tarreau2a65ff02012-09-13 17:54:29 +02003195 if (!bind_conf || !bind_conf->is_ssl)
Emeric Brunfc0421f2012-09-07 17:30:07 +02003196 return 0;
3197
Willy Tarreaufce03112015-01-15 21:32:40 +01003198 /* Automatic memory computations need to know we use SSL there */
3199 global.ssl_used_frontend = 1;
3200
Emeric Brun0bed9942014-10-30 19:25:24 +01003201 if (bind_conf->default_ctx)
Willy Tarreau03209342016-12-22 17:08:28 +01003202 err += ssl_sock_prepare_ctx(bind_conf, bind_conf->default_ctx);
Emeric Brun0bed9942014-10-30 19:25:24 +01003203
Willy Tarreau2a65ff02012-09-13 17:54:29 +02003204 node = ebmb_first(&bind_conf->sni_ctx);
Emeric Brunfc0421f2012-09-07 17:30:07 +02003205 while (node) {
3206 sni = ebmb_entry(node, struct sni_ctx, name);
Emeric Brun0bed9942014-10-30 19:25:24 +01003207 if (!sni->order && sni->ctx != bind_conf->default_ctx)
3208 /* only initialize the CTX on its first occurrence and
3209 if it is not the default_ctx */
Willy Tarreau03209342016-12-22 17:08:28 +01003210 err += ssl_sock_prepare_ctx(bind_conf, sni->ctx);
Emeric Brunfc0421f2012-09-07 17:30:07 +02003211 node = ebmb_next(node);
3212 }
3213
Willy Tarreau2a65ff02012-09-13 17:54:29 +02003214 node = ebmb_first(&bind_conf->sni_w_ctx);
Emeric Brunfc0421f2012-09-07 17:30:07 +02003215 while (node) {
3216 sni = ebmb_entry(node, struct sni_ctx, name);
Emeric Brun0bed9942014-10-30 19:25:24 +01003217 if (!sni->order && sni->ctx != bind_conf->default_ctx)
3218 /* only initialize the CTX on its first occurrence and
3219 if it is not the default_ctx */
Willy Tarreau03209342016-12-22 17:08:28 +01003220 err += ssl_sock_prepare_ctx(bind_conf, sni->ctx);
Emeric Brunfc0421f2012-09-07 17:30:07 +02003221 node = ebmb_next(node);
3222 }
3223 return err;
3224}
3225
Willy Tarreau55d37912016-12-21 23:38:39 +01003226/* Prepares all the contexts for a bind_conf and allocates the shared SSL
3227 * context if needed. Returns < 0 on error, 0 on success. The warnings and
3228 * alerts are directly emitted since the rest of the stack does it below.
3229 */
3230int ssl_sock_prepare_bind_conf(struct bind_conf *bind_conf)
3231{
3232 struct proxy *px = bind_conf->frontend;
3233 int alloc_ctx;
3234 int err;
3235
3236 if (!bind_conf->is_ssl) {
3237 if (bind_conf->default_ctx) {
3238 Warning("Proxy '%s': A certificate was specified but SSL was not enabled on bind '%s' at [%s:%d] (use 'ssl').\n",
3239 px->id, bind_conf->arg, bind_conf->file, bind_conf->line);
3240 }
3241 return 0;
3242 }
3243 if (!bind_conf->default_ctx) {
3244 Alert("Proxy '%s': no SSL certificate specified for bind '%s' at [%s:%d] (use 'crt').\n",
3245 px->id, bind_conf->arg, bind_conf->file, bind_conf->line);
3246 return -1;
3247 }
3248
3249 alloc_ctx = shared_context_init(global.tune.sslcachesize, (!global.tune.sslprivatecache && (global.nbproc > 1)) ? 1 : 0);
3250 if (alloc_ctx < 0) {
3251 if (alloc_ctx == SHCTX_E_INIT_LOCK)
3252 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");
3253 else
3254 Alert("Unable to allocate SSL session cache.\n");
3255 return -1;
3256 }
3257
3258 err = 0;
3259 /* initialize all certificate contexts */
3260 err += ssl_sock_prepare_all_ctx(bind_conf);
3261
3262 /* initialize CA variables if the certificates generation is enabled */
3263 err += ssl_sock_load_ca(bind_conf);
3264
3265 return -err;
3266}
Christopher Faulet77fe80c2015-07-29 13:02:40 +02003267
3268/* release ssl context allocated for servers. */
3269void ssl_sock_free_srv_ctx(struct server *srv)
3270{
3271 if (srv->ssl_ctx.ctx)
3272 SSL_CTX_free(srv->ssl_ctx.ctx);
3273}
3274
Willy Tarreau2a65ff02012-09-13 17:54:29 +02003275/* Walks down the two trees in bind_conf and frees all the certs. The pointer may
Emeric Brunfc0421f2012-09-07 17:30:07 +02003276 * be NULL, in which case nothing is done. The default_ctx is nullified too.
3277 */
Willy Tarreau2a65ff02012-09-13 17:54:29 +02003278void ssl_sock_free_all_ctx(struct bind_conf *bind_conf)
Emeric Brunfc0421f2012-09-07 17:30:07 +02003279{
3280 struct ebmb_node *node, *back;
3281 struct sni_ctx *sni;
3282
Willy Tarreau2a65ff02012-09-13 17:54:29 +02003283 if (!bind_conf || !bind_conf->is_ssl)
Emeric Brunfc0421f2012-09-07 17:30:07 +02003284 return;
3285
Willy Tarreau2a65ff02012-09-13 17:54:29 +02003286 node = ebmb_first(&bind_conf->sni_ctx);
Emeric Brunfc0421f2012-09-07 17:30:07 +02003287 while (node) {
3288 sni = ebmb_entry(node, struct sni_ctx, name);
3289 back = ebmb_next(node);
3290 ebmb_delete(node);
3291 if (!sni->order) /* only free the CTX on its first occurrence */
3292 SSL_CTX_free(sni->ctx);
3293 free(sni);
3294 node = back;
3295 }
3296
Willy Tarreau2a65ff02012-09-13 17:54:29 +02003297 node = ebmb_first(&bind_conf->sni_w_ctx);
Emeric Brunfc0421f2012-09-07 17:30:07 +02003298 while (node) {
3299 sni = ebmb_entry(node, struct sni_ctx, name);
3300 back = ebmb_next(node);
3301 ebmb_delete(node);
3302 if (!sni->order) /* only free the CTX on its first occurrence */
3303 SSL_CTX_free(sni->ctx);
3304 free(sni);
3305 node = back;
3306 }
3307
Willy Tarreau2a65ff02012-09-13 17:54:29 +02003308 bind_conf->default_ctx = NULL;
Emeric Brune1f38db2012-09-03 20:36:47 +02003309}
3310
Willy Tarreau795cdab2016-12-22 17:30:54 +01003311/* Destroys all the contexts for a bind_conf. This is used during deinit(). */
3312void ssl_sock_destroy_bind_conf(struct bind_conf *bind_conf)
3313{
3314 ssl_sock_free_ca(bind_conf);
3315 ssl_sock_free_all_ctx(bind_conf);
3316 free(bind_conf->ca_file);
3317 free(bind_conf->ca_sign_file);
3318 free(bind_conf->ca_sign_pass);
3319 free(bind_conf->ciphers);
3320 free(bind_conf->ecdhe);
3321 free(bind_conf->crl_file);
3322 if (bind_conf->keys_ref) {
3323 free(bind_conf->keys_ref->filename);
3324 free(bind_conf->keys_ref->tlskeys);
3325 LIST_DEL(&bind_conf->keys_ref->list);
3326 free(bind_conf->keys_ref);
3327 }
3328 bind_conf->keys_ref = NULL;
3329 bind_conf->crl_file = NULL;
3330 bind_conf->ecdhe = NULL;
3331 bind_conf->ciphers = NULL;
3332 bind_conf->ca_sign_pass = NULL;
3333 bind_conf->ca_sign_file = NULL;
3334 bind_conf->ca_file = NULL;
3335}
3336
Christopher Faulet31af49d2015-06-09 17:29:50 +02003337/* Load CA cert file and private key used to generate certificates */
3338int
Willy Tarreau03209342016-12-22 17:08:28 +01003339ssl_sock_load_ca(struct bind_conf *bind_conf)
Christopher Faulet31af49d2015-06-09 17:29:50 +02003340{
Willy Tarreau03209342016-12-22 17:08:28 +01003341 struct proxy *px = bind_conf->frontend;
Christopher Faulet31af49d2015-06-09 17:29:50 +02003342 FILE *fp;
3343 X509 *cacert = NULL;
3344 EVP_PKEY *capkey = NULL;
3345 int err = 0;
3346
3347 if (!bind_conf || !bind_conf->generate_certs)
3348 return err;
3349
Willy Tarreaua84c2672015-10-09 12:10:13 +02003350#ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME
Christopher Fauletd2cab922015-07-28 16:03:47 +02003351 if (global.tune.ssl_ctx_cache)
3352 ssl_ctx_lru_tree = lru64_new(global.tune.ssl_ctx_cache);
3353 ssl_ctx_lru_seed = (unsigned int)time(NULL);
Willy Tarreaua84c2672015-10-09 12:10:13 +02003354#endif
Christopher Fauletd2cab922015-07-28 16:03:47 +02003355
Christopher Faulet31af49d2015-06-09 17:29:50 +02003356 if (!bind_conf->ca_sign_file) {
3357 Alert("Proxy '%s': cannot enable certificate generation, "
3358 "no CA certificate File configured at [%s:%d].\n",
3359 px->id, bind_conf->file, bind_conf->line);
Christopher Faulet31af49d2015-06-09 17:29:50 +02003360 goto load_error;
Christopher Fauletc6f02fb2015-10-09 10:53:31 +02003361 }
Christopher Faulet31af49d2015-06-09 17:29:50 +02003362
3363 /* read in the CA certificate */
3364 if (!(fp = fopen(bind_conf->ca_sign_file, "r"))) {
3365 Alert("Proxy '%s': Failed to read CA certificate file '%s' at [%s:%d].\n",
3366 px->id, bind_conf->ca_sign_file, bind_conf->file, bind_conf->line);
Christopher Faulet31af49d2015-06-09 17:29:50 +02003367 goto load_error;
3368 }
3369 if (!(cacert = PEM_read_X509(fp, NULL, NULL, NULL))) {
3370 Alert("Proxy '%s': Failed to read CA certificate file '%s' at [%s:%d].\n",
3371 px->id, bind_conf->ca_sign_file, bind_conf->file, bind_conf->line);
Christopher Fauletc6f02fb2015-10-09 10:53:31 +02003372 goto read_error;
Christopher Faulet31af49d2015-06-09 17:29:50 +02003373 }
Christopher Fauletc6f02fb2015-10-09 10:53:31 +02003374 rewind(fp);
Christopher Faulet31af49d2015-06-09 17:29:50 +02003375 if (!(capkey = PEM_read_PrivateKey(fp, NULL, NULL, bind_conf->ca_sign_pass))) {
3376 Alert("Proxy '%s': Failed to read CA private key file '%s' at [%s:%d].\n",
3377 px->id, bind_conf->ca_sign_file, bind_conf->file, bind_conf->line);
Christopher Fauletc6f02fb2015-10-09 10:53:31 +02003378 goto read_error;
Christopher Faulet31af49d2015-06-09 17:29:50 +02003379 }
Christopher Faulet31af49d2015-06-09 17:29:50 +02003380
Christopher Fauletc6f02fb2015-10-09 10:53:31 +02003381 fclose (fp);
Christopher Faulet31af49d2015-06-09 17:29:50 +02003382 bind_conf->ca_sign_cert = cacert;
3383 bind_conf->ca_sign_pkey = capkey;
3384 return err;
3385
Christopher Fauletc6f02fb2015-10-09 10:53:31 +02003386 read_error:
3387 fclose (fp);
Christopher Faulet31af49d2015-06-09 17:29:50 +02003388 if (capkey) EVP_PKEY_free(capkey);
3389 if (cacert) X509_free(cacert);
Christopher Fauletc6f02fb2015-10-09 10:53:31 +02003390 load_error:
3391 bind_conf->generate_certs = 0;
3392 err++;
Christopher Faulet31af49d2015-06-09 17:29:50 +02003393 return err;
3394}
3395
3396/* Release CA cert and private key used to generate certificated */
3397void
3398ssl_sock_free_ca(struct bind_conf *bind_conf)
3399{
3400 if (!bind_conf)
3401 return;
3402
3403 if (bind_conf->ca_sign_pkey)
3404 EVP_PKEY_free(bind_conf->ca_sign_pkey);
3405 if (bind_conf->ca_sign_cert)
3406 X509_free(bind_conf->ca_sign_cert);
Willy Tarreau94ff03a2016-12-22 17:57:46 +01003407 bind_conf->ca_sign_pkey = NULL;
3408 bind_conf->ca_sign_cert = NULL;
Christopher Faulet31af49d2015-06-09 17:29:50 +02003409}
3410
Emeric Brun46591952012-05-18 15:47:34 +02003411/*
3412 * This function is called if SSL * context is not yet allocated. The function
3413 * is designed to be called before any other data-layer operation and sets the
3414 * handshake flag on the connection. It is safe to call it multiple times.
3415 * It returns 0 on success and -1 in error case.
3416 */
3417static int ssl_sock_init(struct connection *conn)
3418{
3419 /* already initialized */
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02003420 if (conn->xprt_ctx)
Emeric Brun46591952012-05-18 15:47:34 +02003421 return 0;
3422
Willy Tarreau3c728722014-01-23 13:50:42 +01003423 if (!conn_ctrl_ready(conn))
Willy Tarreauf79c8172013-10-21 16:30:56 +02003424 return 0;
3425
Willy Tarreau20879a02012-12-03 16:32:10 +01003426 if (global.maxsslconn && sslconns >= global.maxsslconn) {
3427 conn->err_code = CO_ER_SSL_TOO_MANY;
Willy Tarreau403edff2012-09-06 11:58:37 +02003428 return -1;
Willy Tarreau20879a02012-12-03 16:32:10 +01003429 }
Willy Tarreau403edff2012-09-06 11:58:37 +02003430
Emeric Brun46591952012-05-18 15:47:34 +02003431 /* If it is in client mode initiate SSL session
3432 in connect state otherwise accept state */
Willy Tarreau3fdb3662012-11-12 00:42:33 +01003433 if (objt_server(conn->target)) {
Willy Tarreaufba03cd2014-11-13 13:48:58 +01003434 int may_retry = 1;
3435
3436 retry_connect:
Emeric Brun46591952012-05-18 15:47:34 +02003437 /* Alloc a new SSL session ctx */
Willy Tarreau3fdb3662012-11-12 00:42:33 +01003438 conn->xprt_ctx = SSL_new(objt_server(conn->target)->ssl_ctx.ctx);
Willy Tarreau20879a02012-12-03 16:32:10 +01003439 if (!conn->xprt_ctx) {
Willy Tarreaufba03cd2014-11-13 13:48:58 +01003440 if (may_retry--) {
3441 pool_gc2();
3442 goto retry_connect;
3443 }
Willy Tarreau20879a02012-12-03 16:32:10 +01003444 conn->err_code = CO_ER_SSL_NO_MEM;
Emeric Brun46591952012-05-18 15:47:34 +02003445 return -1;
Willy Tarreau20879a02012-12-03 16:32:10 +01003446 }
Emeric Brun46591952012-05-18 15:47:34 +02003447
Emeric Brun46591952012-05-18 15:47:34 +02003448 /* set fd on SSL session context */
Emeric Brun55476152014-11-12 17:35:37 +01003449 if (!SSL_set_fd(conn->xprt_ctx, conn->t.sock.fd)) {
3450 SSL_free(conn->xprt_ctx);
3451 conn->xprt_ctx = NULL;
Willy Tarreaufba03cd2014-11-13 13:48:58 +01003452 if (may_retry--) {
3453 pool_gc2();
3454 goto retry_connect;
3455 }
Emeric Brun55476152014-11-12 17:35:37 +01003456 conn->err_code = CO_ER_SSL_NO_MEM;
3457 return -1;
3458 }
Emeric Brun46591952012-05-18 15:47:34 +02003459
Evan Broderbe554312013-06-27 00:05:25 -07003460 /* set connection pointer */
Emeric Brun55476152014-11-12 17:35:37 +01003461 if (!SSL_set_app_data(conn->xprt_ctx, conn)) {
3462 SSL_free(conn->xprt_ctx);
3463 conn->xprt_ctx = NULL;
Willy Tarreaufba03cd2014-11-13 13:48:58 +01003464 if (may_retry--) {
3465 pool_gc2();
3466 goto retry_connect;
3467 }
Emeric Brun55476152014-11-12 17:35:37 +01003468 conn->err_code = CO_ER_SSL_NO_MEM;
3469 return -1;
3470 }
3471
3472 SSL_set_connect_state(conn->xprt_ctx);
3473 if (objt_server(conn->target)->ssl_ctx.reused_sess) {
3474 if(!SSL_set_session(conn->xprt_ctx, objt_server(conn->target)->ssl_ctx.reused_sess)) {
3475 SSL_SESSION_free(objt_server(conn->target)->ssl_ctx.reused_sess);
3476 objt_server(conn->target)->ssl_ctx.reused_sess = NULL;
3477 }
3478 }
Evan Broderbe554312013-06-27 00:05:25 -07003479
Emeric Brun46591952012-05-18 15:47:34 +02003480 /* leave init state and start handshake */
Willy Tarreau05737472012-09-04 08:03:39 +02003481 conn->flags |= CO_FL_SSL_WAIT_HS | CO_FL_WAIT_L6_CONN;
Willy Tarreau403edff2012-09-06 11:58:37 +02003482
3483 sslconns++;
Willy Tarreau71b734c2014-01-28 15:19:44 +01003484 totalsslconns++;
Emeric Brun46591952012-05-18 15:47:34 +02003485 return 0;
3486 }
Willy Tarreau3fdb3662012-11-12 00:42:33 +01003487 else if (objt_listener(conn->target)) {
Willy Tarreaufba03cd2014-11-13 13:48:58 +01003488 int may_retry = 1;
3489
3490 retry_accept:
Emeric Brun46591952012-05-18 15:47:34 +02003491 /* Alloc a new SSL session ctx */
Willy Tarreau3fdb3662012-11-12 00:42:33 +01003492 conn->xprt_ctx = SSL_new(objt_listener(conn->target)->bind_conf->default_ctx);
Willy Tarreau20879a02012-12-03 16:32:10 +01003493 if (!conn->xprt_ctx) {
Willy Tarreaufba03cd2014-11-13 13:48:58 +01003494 if (may_retry--) {
3495 pool_gc2();
3496 goto retry_accept;
3497 }
Willy Tarreau20879a02012-12-03 16:32:10 +01003498 conn->err_code = CO_ER_SSL_NO_MEM;
Emeric Brun46591952012-05-18 15:47:34 +02003499 return -1;
Willy Tarreau20879a02012-12-03 16:32:10 +01003500 }
Emeric Brun46591952012-05-18 15:47:34 +02003501
Emeric Brun46591952012-05-18 15:47:34 +02003502 /* set fd on SSL session context */
Emeric Brun55476152014-11-12 17:35:37 +01003503 if (!SSL_set_fd(conn->xprt_ctx, conn->t.sock.fd)) {
3504 SSL_free(conn->xprt_ctx);
3505 conn->xprt_ctx = NULL;
Willy Tarreaufba03cd2014-11-13 13:48:58 +01003506 if (may_retry--) {
3507 pool_gc2();
3508 goto retry_accept;
3509 }
Emeric Brun55476152014-11-12 17:35:37 +01003510 conn->err_code = CO_ER_SSL_NO_MEM;
3511 return -1;
3512 }
Emeric Brun46591952012-05-18 15:47:34 +02003513
Emeric Brune1f38db2012-09-03 20:36:47 +02003514 /* set connection pointer */
Emeric Brun55476152014-11-12 17:35:37 +01003515 if (!SSL_set_app_data(conn->xprt_ctx, conn)) {
3516 SSL_free(conn->xprt_ctx);
3517 conn->xprt_ctx = NULL;
Willy Tarreaufba03cd2014-11-13 13:48:58 +01003518 if (may_retry--) {
3519 pool_gc2();
3520 goto retry_accept;
3521 }
Emeric Brun55476152014-11-12 17:35:37 +01003522 conn->err_code = CO_ER_SSL_NO_MEM;
3523 return -1;
3524 }
3525
3526 SSL_set_accept_state(conn->xprt_ctx);
Emeric Brune1f38db2012-09-03 20:36:47 +02003527
Emeric Brun46591952012-05-18 15:47:34 +02003528 /* leave init state and start handshake */
Willy Tarreau05737472012-09-04 08:03:39 +02003529 conn->flags |= CO_FL_SSL_WAIT_HS | CO_FL_WAIT_L6_CONN;
Willy Tarreau403edff2012-09-06 11:58:37 +02003530
3531 sslconns++;
Willy Tarreau71b734c2014-01-28 15:19:44 +01003532 totalsslconns++;
Emeric Brun46591952012-05-18 15:47:34 +02003533 return 0;
3534 }
3535 /* don't know how to handle such a target */
Willy Tarreau20879a02012-12-03 16:32:10 +01003536 conn->err_code = CO_ER_SSL_NO_TARGET;
Emeric Brun46591952012-05-18 15:47:34 +02003537 return -1;
3538}
3539
3540
3541/* This is the callback which is used when an SSL handshake is pending. It
3542 * updates the FD status if it wants some polling before being called again.
3543 * It returns 0 if it fails in a fatal way or needs to poll to go further,
3544 * otherwise it returns non-zero and removes itself from the connection's
3545 * flags (the bit is provided in <flag> by the caller).
3546 */
3547int ssl_sock_handshake(struct connection *conn, unsigned int flag)
3548{
3549 int ret;
3550
Willy Tarreau3c728722014-01-23 13:50:42 +01003551 if (!conn_ctrl_ready(conn))
Willy Tarreauf79c8172013-10-21 16:30:56 +02003552 return 0;
3553
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02003554 if (!conn->xprt_ctx)
Emeric Brun46591952012-05-18 15:47:34 +02003555 goto out_error;
3556
Emeric Brun674b7432012-11-08 19:21:55 +01003557 /* If we use SSL_do_handshake to process a reneg initiated by
3558 * the remote peer, it sometimes returns SSL_ERROR_SSL.
3559 * Usually SSL_write and SSL_read are used and process implicitly
3560 * the reneg handshake.
3561 * Here we use SSL_peek as a workaround for reneg.
3562 */
3563 if ((conn->flags & CO_FL_CONNECTED) && SSL_renegotiate_pending(conn->xprt_ctx)) {
3564 char c;
3565
3566 ret = SSL_peek(conn->xprt_ctx, &c, 1);
3567 if (ret <= 0) {
3568 /* handshake may have not been completed, let's find why */
3569 ret = SSL_get_error(conn->xprt_ctx, ret);
3570 if (ret == SSL_ERROR_WANT_WRITE) {
3571 /* SSL handshake needs to write, L4 connection may not be ready */
3572 __conn_sock_stop_recv(conn);
Willy Tarreaue1f50c42014-01-22 20:02:06 +01003573 __conn_sock_want_send(conn);
3574 fd_cant_send(conn->t.sock.fd);
Emeric Brun674b7432012-11-08 19:21:55 +01003575 return 0;
3576 }
3577 else if (ret == SSL_ERROR_WANT_READ) {
3578 /* handshake may have been completed but we have
3579 * no more data to read.
3580 */
3581 if (!SSL_renegotiate_pending(conn->xprt_ctx)) {
3582 ret = 1;
3583 goto reneg_ok;
3584 }
3585 /* SSL handshake needs to read, L4 connection is ready */
3586 if (conn->flags & CO_FL_WAIT_L4_CONN)
3587 conn->flags &= ~CO_FL_WAIT_L4_CONN;
3588 __conn_sock_stop_send(conn);
Willy Tarreaue1f50c42014-01-22 20:02:06 +01003589 __conn_sock_want_recv(conn);
3590 fd_cant_recv(conn->t.sock.fd);
Emeric Brun674b7432012-11-08 19:21:55 +01003591 return 0;
3592 }
3593 else if (ret == SSL_ERROR_SYSCALL) {
3594 /* if errno is null, then connection was successfully established */
3595 if (!errno && conn->flags & CO_FL_WAIT_L4_CONN)
3596 conn->flags &= ~CO_FL_WAIT_L4_CONN;
Willy Tarreau20879a02012-12-03 16:32:10 +01003597 if (!conn->err_code) {
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02003598 int empty_handshake;
Luca Pizzamiglio578b1692016-12-12 10:56:56 +01003599#if (OPENSSL_VERSION_NUMBER >= 0x1010000fL) && !defined(LIBRESSL_VERSION_NUMBER)
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02003600 OSSL_HANDSHAKE_STATE state = SSL_get_state((SSL *)conn->xprt_ctx);
3601 empty_handshake = state == TLS_ST_BEFORE;
3602#else
3603 empty_handshake = !((SSL *)conn->xprt_ctx)->packet_length;
3604#endif
3605
3606 if (empty_handshake) {
Emeric Brun29f037d2014-04-25 19:05:36 +02003607 if (!errno) {
3608 if (conn->xprt_st & SSL_SOCK_RECV_HEARTBEAT)
3609 conn->err_code = CO_ER_SSL_HANDSHAKE_HB;
3610 else
3611 conn->err_code = CO_ER_SSL_EMPTY;
3612 }
3613 else {
3614 if (conn->xprt_st & SSL_SOCK_RECV_HEARTBEAT)
3615 conn->err_code = CO_ER_SSL_HANDSHAKE_HB;
3616 else
3617 conn->err_code = CO_ER_SSL_ABORT;
3618 }
3619 }
3620 else {
3621 if (conn->xprt_st & SSL_SOCK_RECV_HEARTBEAT)
3622 conn->err_code = CO_ER_SSL_HANDSHAKE_HB;
Willy Tarreau20879a02012-12-03 16:32:10 +01003623 else
Emeric Brun29f037d2014-04-25 19:05:36 +02003624 conn->err_code = CO_ER_SSL_HANDSHAKE;
3625 }
Willy Tarreau20879a02012-12-03 16:32:10 +01003626 }
Emeric Brun674b7432012-11-08 19:21:55 +01003627 goto out_error;
3628 }
3629 else {
3630 /* Fail on all other handshake errors */
3631 /* Note: OpenSSL may leave unread bytes in the socket's
3632 * buffer, causing an RST to be emitted upon close() on
3633 * TCP sockets. We first try to drain possibly pending
3634 * data to avoid this as much as possible.
3635 */
Willy Tarreaud85c4852015-03-13 00:40:28 +01003636 conn_sock_drain(conn);
Willy Tarreau20879a02012-12-03 16:32:10 +01003637 if (!conn->err_code)
Willy Tarreauf51c6982014-04-25 20:02:39 +02003638 conn->err_code = (conn->xprt_st & SSL_SOCK_RECV_HEARTBEAT) ?
3639 CO_ER_SSL_KILLED_HB : CO_ER_SSL_HANDSHAKE;
Emeric Brun674b7432012-11-08 19:21:55 +01003640 goto out_error;
3641 }
3642 }
3643 /* read some data: consider handshake completed */
3644 goto reneg_ok;
3645 }
3646
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02003647 ret = SSL_do_handshake(conn->xprt_ctx);
Emeric Brun46591952012-05-18 15:47:34 +02003648 if (ret != 1) {
3649 /* handshake did not complete, let's find why */
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02003650 ret = SSL_get_error(conn->xprt_ctx, ret);
Emeric Brun46591952012-05-18 15:47:34 +02003651
3652 if (ret == SSL_ERROR_WANT_WRITE) {
3653 /* SSL handshake needs to write, L4 connection may not be ready */
3654 __conn_sock_stop_recv(conn);
Willy Tarreaue1f50c42014-01-22 20:02:06 +01003655 __conn_sock_want_send(conn);
3656 fd_cant_send(conn->t.sock.fd);
Emeric Brun46591952012-05-18 15:47:34 +02003657 return 0;
3658 }
3659 else if (ret == SSL_ERROR_WANT_READ) {
3660 /* SSL handshake needs to read, L4 connection is ready */
3661 if (conn->flags & CO_FL_WAIT_L4_CONN)
3662 conn->flags &= ~CO_FL_WAIT_L4_CONN;
3663 __conn_sock_stop_send(conn);
Willy Tarreaue1f50c42014-01-22 20:02:06 +01003664 __conn_sock_want_recv(conn);
3665 fd_cant_recv(conn->t.sock.fd);
Emeric Brun46591952012-05-18 15:47:34 +02003666 return 0;
3667 }
Willy Tarreau89230192012-09-28 20:22:13 +02003668 else if (ret == SSL_ERROR_SYSCALL) {
Luca Pizzamiglio578b1692016-12-12 10:56:56 +01003669#if (OPENSSL_VERSION_NUMBER >= 0x1010000fL) && !defined(LIBRESSL_VERSION_NUMBER)
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02003670 OSSL_HANDSHAKE_STATE state;
3671#endif
3672 int empty_handshake;
Willy Tarreau89230192012-09-28 20:22:13 +02003673 /* if errno is null, then connection was successfully established */
3674 if (!errno && conn->flags & CO_FL_WAIT_L4_CONN)
3675 conn->flags &= ~CO_FL_WAIT_L4_CONN;
Willy Tarreau20879a02012-12-03 16:32:10 +01003676
Luca Pizzamiglio578b1692016-12-12 10:56:56 +01003677#if (OPENSSL_VERSION_NUMBER >= 0x1010000fL) && !defined(LIBRESSL_VERSION_NUMBER)
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02003678 state = SSL_get_state((SSL *)conn->xprt_ctx);
3679 empty_handshake = state == TLS_ST_BEFORE;
3680#else
3681 empty_handshake = !((SSL *)conn->xprt_ctx)->packet_length;
3682#endif
3683 if (empty_handshake) {
Emeric Brun29f037d2014-04-25 19:05:36 +02003684 if (!errno) {
3685 if (conn->xprt_st & SSL_SOCK_RECV_HEARTBEAT)
3686 conn->err_code = CO_ER_SSL_HANDSHAKE_HB;
3687 else
3688 conn->err_code = CO_ER_SSL_EMPTY;
3689 }
3690 else {
3691 if (conn->xprt_st & SSL_SOCK_RECV_HEARTBEAT)
3692 conn->err_code = CO_ER_SSL_HANDSHAKE_HB;
3693 else
3694 conn->err_code = CO_ER_SSL_ABORT;
3695 }
3696 }
3697 else {
3698 if (conn->xprt_st & SSL_SOCK_RECV_HEARTBEAT)
3699 conn->err_code = CO_ER_SSL_HANDSHAKE_HB;
Willy Tarreau20879a02012-12-03 16:32:10 +01003700 else
Emeric Brun29f037d2014-04-25 19:05:36 +02003701 conn->err_code = CO_ER_SSL_HANDSHAKE;
3702 }
Willy Tarreau89230192012-09-28 20:22:13 +02003703 goto out_error;
3704 }
Emeric Brun46591952012-05-18 15:47:34 +02003705 else {
3706 /* Fail on all other handshake errors */
Willy Tarreau566dc552012-10-19 20:52:18 +02003707 /* Note: OpenSSL may leave unread bytes in the socket's
3708 * buffer, causing an RST to be emitted upon close() on
3709 * TCP sockets. We first try to drain possibly pending
3710 * data to avoid this as much as possible.
3711 */
Willy Tarreaud85c4852015-03-13 00:40:28 +01003712 conn_sock_drain(conn);
Willy Tarreau20879a02012-12-03 16:32:10 +01003713 if (!conn->err_code)
Willy Tarreauf51c6982014-04-25 20:02:39 +02003714 conn->err_code = (conn->xprt_st & SSL_SOCK_RECV_HEARTBEAT) ?
3715 CO_ER_SSL_KILLED_HB : CO_ER_SSL_HANDSHAKE;
Emeric Brun46591952012-05-18 15:47:34 +02003716 goto out_error;
3717 }
3718 }
3719
Emeric Brun674b7432012-11-08 19:21:55 +01003720reneg_ok:
Emeric Brun46591952012-05-18 15:47:34 +02003721 /* Handshake succeeded */
Willy Tarreau0c9c2722014-05-28 12:28:58 +02003722 if (!SSL_session_reused(conn->xprt_ctx)) {
3723 if (objt_server(conn->target)) {
3724 update_freq_ctr(&global.ssl_be_keys_per_sec, 1);
3725 if (global.ssl_be_keys_per_sec.curr_ctr > global.ssl_be_keys_max)
3726 global.ssl_be_keys_max = global.ssl_be_keys_per_sec.curr_ctr;
3727
Emeric Brun46591952012-05-18 15:47:34 +02003728 /* check if session was reused, if not store current session on server for reuse */
Willy Tarreau30fd4bd2016-12-22 21:54:21 +01003729 if (objt_server(conn->target)->ssl_ctx.reused_sess) {
Willy Tarreau3fdb3662012-11-12 00:42:33 +01003730 SSL_SESSION_free(objt_server(conn->target)->ssl_ctx.reused_sess);
Willy Tarreau30fd4bd2016-12-22 21:54:21 +01003731 objt_server(conn->target)->ssl_ctx.reused_sess = NULL;
3732 }
Emeric Brun46591952012-05-18 15:47:34 +02003733
Willy Tarreau2a3fb1c2015-02-05 16:47:07 +01003734 if (!(objt_server(conn->target)->ssl_ctx.options & SRV_SSL_O_NO_REUSE))
3735 objt_server(conn->target)->ssl_ctx.reused_sess = SSL_get1_session(conn->xprt_ctx);
Emeric Brun46591952012-05-18 15:47:34 +02003736 }
Willy Tarreau0c9c2722014-05-28 12:28:58 +02003737 else {
3738 update_freq_ctr(&global.ssl_fe_keys_per_sec, 1);
3739 if (global.ssl_fe_keys_per_sec.curr_ctr > global.ssl_fe_keys_max)
3740 global.ssl_fe_keys_max = global.ssl_fe_keys_per_sec.curr_ctr;
3741 }
Emeric Brun46591952012-05-18 15:47:34 +02003742 }
3743
3744 /* The connection is now established at both layers, it's time to leave */
3745 conn->flags &= ~(flag | CO_FL_WAIT_L4_CONN | CO_FL_WAIT_L6_CONN);
3746 return 1;
3747
3748 out_error:
Emeric Brun644cde02012-12-14 11:21:13 +01003749 /* Clear openssl global errors stack */
Thierry FOURNIER / OZON.IO8b068c22016-10-10 11:59:50 +02003750 ssl_sock_dump_errors(conn);
Emeric Brun644cde02012-12-14 11:21:13 +01003751 ERR_clear_error();
3752
Emeric Brun9fa89732012-10-04 17:09:56 +02003753 /* free resumed session if exists */
Willy Tarreau3fdb3662012-11-12 00:42:33 +01003754 if (objt_server(conn->target) && objt_server(conn->target)->ssl_ctx.reused_sess) {
3755 SSL_SESSION_free(objt_server(conn->target)->ssl_ctx.reused_sess);
3756 objt_server(conn->target)->ssl_ctx.reused_sess = NULL;
Emeric Brun9fa89732012-10-04 17:09:56 +02003757 }
3758
Emeric Brun46591952012-05-18 15:47:34 +02003759 /* Fail on all other handshake errors */
3760 conn->flags |= CO_FL_ERROR;
Willy Tarreau20879a02012-12-03 16:32:10 +01003761 if (!conn->err_code)
3762 conn->err_code = CO_ER_SSL_HANDSHAKE;
Emeric Brun46591952012-05-18 15:47:34 +02003763 return 0;
3764}
3765
3766/* Receive up to <count> bytes from connection <conn>'s socket and store them
Willy Tarreauabf08d92014-01-14 11:31:27 +01003767 * into buffer <buf>. Only one call to recv() is performed, unless the
Emeric Brun46591952012-05-18 15:47:34 +02003768 * buffer wraps, in which case a second call may be performed. The connection's
3769 * flags are updated with whatever special event is detected (error, read0,
3770 * empty). The caller is responsible for taking care of those events and
3771 * avoiding the call if inappropriate. The function does not call the
3772 * connection's polling update function, so the caller is responsible for this.
3773 */
3774static int ssl_sock_to_buf(struct connection *conn, struct buffer *buf, int count)
3775{
3776 int ret, done = 0;
Willy Tarreauabf08d92014-01-14 11:31:27 +01003777 int try;
Emeric Brun46591952012-05-18 15:47:34 +02003778
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02003779 if (!conn->xprt_ctx)
Emeric Brun46591952012-05-18 15:47:34 +02003780 goto out_error;
3781
3782 if (conn->flags & CO_FL_HANDSHAKE)
3783 /* a handshake was requested */
3784 return 0;
3785
Willy Tarreauabf08d92014-01-14 11:31:27 +01003786 /* let's realign the buffer to optimize I/O */
3787 if (buffer_empty(buf))
Emeric Brun46591952012-05-18 15:47:34 +02003788 buf->p = buf->data;
Emeric Brun46591952012-05-18 15:47:34 +02003789
3790 /* read the largest possible block. For this, we perform only one call
3791 * to recv() unless the buffer wraps and we exactly fill the first hunk,
3792 * in which case we accept to do it once again. A new attempt is made on
3793 * EINTR too.
3794 */
Willy Tarreau00b0fb92014-01-17 11:09:40 +01003795 while (count > 0) {
Willy Tarreauabf08d92014-01-14 11:31:27 +01003796 /* first check if we have some room after p+i */
3797 try = buf->data + buf->size - (buf->p + buf->i);
3798 /* otherwise continue between data and p-o */
3799 if (try <= 0) {
3800 try = buf->p - (buf->data + buf->o);
3801 if (try <= 0)
3802 break;
3803 }
3804 if (try > count)
3805 try = count;
3806
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02003807 ret = SSL_read(conn->xprt_ctx, bi_end(buf), try);
Emeric Brune1f38db2012-09-03 20:36:47 +02003808 if (conn->flags & CO_FL_ERROR) {
3809 /* CO_FL_ERROR may be set by ssl_sock_infocbk */
Emeric Brun644cde02012-12-14 11:21:13 +01003810 goto out_error;
Emeric Brune1f38db2012-09-03 20:36:47 +02003811 }
Emeric Brun46591952012-05-18 15:47:34 +02003812 if (ret > 0) {
3813 buf->i += ret;
3814 done += ret;
3815 if (ret < try)
3816 break;
3817 count -= ret;
Emeric Brun46591952012-05-18 15:47:34 +02003818 }
3819 else if (ret == 0) {
Emeric Brun644cde02012-12-14 11:21:13 +01003820 ret = SSL_get_error(conn->xprt_ctx, ret);
3821 if (ret != SSL_ERROR_ZERO_RETURN) {
Emeric Brun1c646862012-12-14 12:33:41 +01003822 /* error on protocol or underlying transport */
3823 if ((ret != SSL_ERROR_SYSCALL)
3824 || (errno && (errno != EAGAIN)))
3825 conn->flags |= CO_FL_ERROR;
3826
Emeric Brun644cde02012-12-14 11:21:13 +01003827 /* Clear openssl global errors stack */
Thierry FOURNIER / OZON.IO8b068c22016-10-10 11:59:50 +02003828 ssl_sock_dump_errors(conn);
Emeric Brun644cde02012-12-14 11:21:13 +01003829 ERR_clear_error();
3830 }
Emeric Brun46591952012-05-18 15:47:34 +02003831 goto read0;
3832 }
3833 else {
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02003834 ret = SSL_get_error(conn->xprt_ctx, ret);
Emeric Brun46591952012-05-18 15:47:34 +02003835 if (ret == SSL_ERROR_WANT_WRITE) {
Emeric Brun8af8dd12012-11-08 17:56:20 +01003836 /* handshake is running, and it needs to enable write */
Emeric Brun46591952012-05-18 15:47:34 +02003837 conn->flags |= CO_FL_SSL_WAIT_HS;
Emeric Brun8af8dd12012-11-08 17:56:20 +01003838 __conn_sock_want_send(conn);
Emeric Brun46591952012-05-18 15:47:34 +02003839 break;
3840 }
3841 else if (ret == SSL_ERROR_WANT_READ) {
Emeric Brun282a76a2012-11-08 18:02:56 +01003842 if (SSL_renegotiate_pending(conn->xprt_ctx)) {
3843 /* handshake is running, and it may need to re-enable read */
3844 conn->flags |= CO_FL_SSL_WAIT_HS;
3845 __conn_sock_want_recv(conn);
3846 break;
3847 }
Emeric Brun46591952012-05-18 15:47:34 +02003848 /* we need to poll for retry a read later */
Willy Tarreaue1f50c42014-01-22 20:02:06 +01003849 fd_cant_recv(conn->t.sock.fd);
Emeric Brun46591952012-05-18 15:47:34 +02003850 break;
3851 }
3852 /* otherwise it's a real error */
3853 goto out_error;
3854 }
3855 }
3856 return done;
3857
3858 read0:
3859 conn_sock_read0(conn);
3860 return done;
3861 out_error:
Emeric Brun644cde02012-12-14 11:21:13 +01003862 /* Clear openssl global errors stack */
Thierry FOURNIER / OZON.IO8b068c22016-10-10 11:59:50 +02003863 ssl_sock_dump_errors(conn);
Emeric Brun644cde02012-12-14 11:21:13 +01003864 ERR_clear_error();
3865
Emeric Brun46591952012-05-18 15:47:34 +02003866 conn->flags |= CO_FL_ERROR;
3867 return done;
3868}
3869
3870
3871/* Send all pending bytes from buffer <buf> to connection <conn>'s socket.
Willy Tarreau1049b1f2014-02-02 01:51:17 +01003872 * <flags> may contain some CO_SFL_* flags to hint the system about other
3873 * pending data for example, but this flag is ignored at the moment.
Emeric Brun46591952012-05-18 15:47:34 +02003874 * Only one call to send() is performed, unless the buffer wraps, in which case
3875 * a second call may be performed. The connection's flags are updated with
3876 * whatever special event is detected (error, empty). The caller is responsible
3877 * for taking care of those events and avoiding the call if inappropriate. The
3878 * function does not call the connection's polling update function, so the caller
3879 * is responsible for this.
3880 */
3881static int ssl_sock_from_buf(struct connection *conn, struct buffer *buf, int flags)
3882{
3883 int ret, try, done;
3884
3885 done = 0;
3886
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02003887 if (!conn->xprt_ctx)
Emeric Brun46591952012-05-18 15:47:34 +02003888 goto out_error;
3889
3890 if (conn->flags & CO_FL_HANDSHAKE)
3891 /* a handshake was requested */
3892 return 0;
3893
3894 /* send the largest possible block. For this we perform only one call
3895 * to send() unless the buffer wraps and we exactly fill the first hunk,
3896 * in which case we accept to do it once again.
3897 */
3898 while (buf->o) {
Kevin Hestercad82342013-05-30 15:12:41 -07003899 try = bo_contig_data(buf);
Willy Tarreaubfd59462013-02-21 07:46:09 +01003900
Willy Tarreau7bed9452014-02-02 02:00:24 +01003901 if (!(flags & CO_SFL_STREAMER) &&
Willy Tarreau518cedd2014-02-17 15:43:01 +01003902 !(conn->xprt_st & SSL_SOCK_SEND_UNLIMITED) &&
3903 global.tune.ssl_max_record && try > global.tune.ssl_max_record) {
Willy Tarreaubfd59462013-02-21 07:46:09 +01003904 try = global.tune.ssl_max_record;
Willy Tarreau518cedd2014-02-17 15:43:01 +01003905 }
3906 else {
3907 /* we need to keep the information about the fact that
3908 * we're not limiting the upcoming send(), because if it
3909 * fails, we'll have to retry with at least as many data.
3910 */
3911 conn->xprt_st |= SSL_SOCK_SEND_UNLIMITED;
3912 }
Willy Tarreaubfd59462013-02-21 07:46:09 +01003913
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02003914 ret = SSL_write(conn->xprt_ctx, bo_ptr(buf), try);
Willy Tarreau518cedd2014-02-17 15:43:01 +01003915
Emeric Brune1f38db2012-09-03 20:36:47 +02003916 if (conn->flags & CO_FL_ERROR) {
3917 /* CO_FL_ERROR may be set by ssl_sock_infocbk */
Emeric Brun644cde02012-12-14 11:21:13 +01003918 goto out_error;
Emeric Brune1f38db2012-09-03 20:36:47 +02003919 }
Emeric Brun46591952012-05-18 15:47:34 +02003920 if (ret > 0) {
Willy Tarreau518cedd2014-02-17 15:43:01 +01003921 conn->xprt_st &= ~SSL_SOCK_SEND_UNLIMITED;
3922
Emeric Brun46591952012-05-18 15:47:34 +02003923 buf->o -= ret;
3924 done += ret;
3925
Willy Tarreau5fb38032012-12-16 19:39:09 +01003926 if (likely(buffer_empty(buf)))
Emeric Brun46591952012-05-18 15:47:34 +02003927 /* optimize data alignment in the buffer */
3928 buf->p = buf->data;
3929
3930 /* if the system buffer is full, don't insist */
3931 if (ret < try)
3932 break;
3933 }
3934 else {
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02003935 ret = SSL_get_error(conn->xprt_ctx, ret);
Emeric Brun46591952012-05-18 15:47:34 +02003936 if (ret == SSL_ERROR_WANT_WRITE) {
Emeric Brun282a76a2012-11-08 18:02:56 +01003937 if (SSL_renegotiate_pending(conn->xprt_ctx)) {
3938 /* handshake is running, and it may need to re-enable write */
3939 conn->flags |= CO_FL_SSL_WAIT_HS;
3940 __conn_sock_want_send(conn);
3941 break;
3942 }
Emeric Brun46591952012-05-18 15:47:34 +02003943 /* we need to poll to retry a write later */
Willy Tarreaue1f50c42014-01-22 20:02:06 +01003944 fd_cant_send(conn->t.sock.fd);
Emeric Brun46591952012-05-18 15:47:34 +02003945 break;
3946 }
3947 else if (ret == SSL_ERROR_WANT_READ) {
Emeric Brun8af8dd12012-11-08 17:56:20 +01003948 /* handshake is running, and it needs to enable read */
Emeric Brun46591952012-05-18 15:47:34 +02003949 conn->flags |= CO_FL_SSL_WAIT_HS;
Emeric Brun8af8dd12012-11-08 17:56:20 +01003950 __conn_sock_want_recv(conn);
Emeric Brun46591952012-05-18 15:47:34 +02003951 break;
3952 }
3953 goto out_error;
3954 }
3955 }
3956 return done;
3957
3958 out_error:
Emeric Brun644cde02012-12-14 11:21:13 +01003959 /* Clear openssl global errors stack */
Thierry FOURNIER / OZON.IO8b068c22016-10-10 11:59:50 +02003960 ssl_sock_dump_errors(conn);
Emeric Brun644cde02012-12-14 11:21:13 +01003961 ERR_clear_error();
3962
Emeric Brun46591952012-05-18 15:47:34 +02003963 conn->flags |= CO_FL_ERROR;
3964 return done;
3965}
3966
Emeric Brun46591952012-05-18 15:47:34 +02003967static void ssl_sock_close(struct connection *conn) {
3968
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02003969 if (conn->xprt_ctx) {
3970 SSL_free(conn->xprt_ctx);
3971 conn->xprt_ctx = NULL;
Willy Tarreau403edff2012-09-06 11:58:37 +02003972 sslconns--;
Emeric Brun46591952012-05-18 15:47:34 +02003973 }
Emeric Brun46591952012-05-18 15:47:34 +02003974}
3975
3976/* This function tries to perform a clean shutdown on an SSL connection, and in
3977 * any case, flags the connection as reusable if no handshake was in progress.
3978 */
3979static void ssl_sock_shutw(struct connection *conn, int clean)
3980{
3981 if (conn->flags & CO_FL_HANDSHAKE)
3982 return;
3983 /* no handshake was in progress, try a clean ssl shutdown */
Emeric Brun644cde02012-12-14 11:21:13 +01003984 if (clean && (SSL_shutdown(conn->xprt_ctx) <= 0)) {
3985 /* Clear openssl global errors stack */
Thierry FOURNIER / OZON.IO8b068c22016-10-10 11:59:50 +02003986 ssl_sock_dump_errors(conn);
Emeric Brun644cde02012-12-14 11:21:13 +01003987 ERR_clear_error();
3988 }
Emeric Brun46591952012-05-18 15:47:34 +02003989
3990 /* force flag on ssl to keep session in cache regardless shutdown result */
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02003991 SSL_set_shutdown(conn->xprt_ctx, SSL_SENT_SHUTDOWN);
Emeric Brun46591952012-05-18 15:47:34 +02003992}
3993
Willy Tarreauffc3fcd2012-10-12 20:17:54 +02003994/* used for logging, may be changed for a sample fetch later */
3995const char *ssl_sock_get_cipher_name(struct connection *conn)
3996{
3997 if (!conn->xprt && !conn->xprt_ctx)
3998 return NULL;
3999 return SSL_get_cipher_name(conn->xprt_ctx);
4000}
4001
4002/* used for logging, may be changed for a sample fetch later */
4003const char *ssl_sock_get_proto_version(struct connection *conn)
4004{
4005 if (!conn->xprt && !conn->xprt_ctx)
4006 return NULL;
4007 return SSL_get_version(conn->xprt_ctx);
4008}
4009
Willy Tarreau8d598402012-10-22 17:58:39 +02004010/* Extract a serial from a cert, and copy it to a chunk.
4011 * Returns 1 if serial is found and copied, 0 if no serial found and
4012 * -1 if output is not large enough.
4013 */
4014static int
4015ssl_sock_get_serial(X509 *crt, struct chunk *out)
4016{
4017 ASN1_INTEGER *serial;
4018
4019 serial = X509_get_serialNumber(crt);
4020 if (!serial)
4021 return 0;
4022
4023 if (out->size < serial->length)
4024 return -1;
4025
4026 memcpy(out->str, serial->data, serial->length);
4027 out->len = serial->length;
4028 return 1;
4029}
4030
Emeric Brun43e79582014-10-29 19:03:26 +01004031/* Extract a cert to der, and copy it to a chunk.
4032 * Returns 1 if cert is found and copied, 0 on der convertion failure and
4033 * -1 if output is not large enough.
4034 */
4035static int
4036ssl_sock_crt2der(X509 *crt, struct chunk *out)
4037{
4038 int len;
4039 unsigned char *p = (unsigned char *)out->str;;
4040
4041 len =i2d_X509(crt, NULL);
4042 if (len <= 0)
4043 return 1;
4044
4045 if (out->size < len)
4046 return -1;
4047
4048 i2d_X509(crt,&p);
4049 out->len = len;
4050 return 1;
4051}
4052
Emeric Brunce5ad802012-10-22 14:11:22 +02004053
4054/* Copy Date in ASN1_UTCTIME format in struct chunk out.
4055 * Returns 1 if serial is found and copied, 0 if no valid time found
4056 * and -1 if output is not large enough.
4057 */
4058static int
4059ssl_sock_get_time(ASN1_TIME *tm, struct chunk *out)
4060{
4061 if (tm->type == V_ASN1_GENERALIZEDTIME) {
4062 ASN1_GENERALIZEDTIME *gentm = (ASN1_GENERALIZEDTIME *)tm;
4063
4064 if (gentm->length < 12)
4065 return 0;
4066 if (gentm->data[0] != 0x32 || gentm->data[1] != 0x30)
4067 return 0;
4068 if (out->size < gentm->length-2)
4069 return -1;
4070
4071 memcpy(out->str, gentm->data+2, gentm->length-2);
4072 out->len = gentm->length-2;
4073 return 1;
4074 }
4075 else if (tm->type == V_ASN1_UTCTIME) {
4076 ASN1_UTCTIME *utctm = (ASN1_UTCTIME *)tm;
4077
4078 if (utctm->length < 10)
4079 return 0;
4080 if (utctm->data[0] >= 0x35)
4081 return 0;
4082 if (out->size < utctm->length)
4083 return -1;
4084
4085 memcpy(out->str, utctm->data, utctm->length);
4086 out->len = utctm->length;
4087 return 1;
4088 }
4089
4090 return 0;
4091}
4092
Emeric Brun87855892012-10-17 17:39:35 +02004093/* Extract an entry from a X509_NAME and copy its value to an output chunk.
4094 * Returns 1 if entry found, 0 if entry not found, or -1 if output not large enough.
4095 */
4096static int
4097ssl_sock_get_dn_entry(X509_NAME *a, const struct chunk *entry, int pos, struct chunk *out)
4098{
4099 X509_NAME_ENTRY *ne;
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02004100 ASN1_OBJECT *obj;
4101 ASN1_STRING *data;
4102 const unsigned char *data_ptr;
4103 int data_len;
Emeric Brun87855892012-10-17 17:39:35 +02004104 int i, j, n;
4105 int cur = 0;
4106 const char *s;
4107 char tmp[128];
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02004108 int name_count;
4109
4110 name_count = X509_NAME_entry_count(a);
Emeric Brun87855892012-10-17 17:39:35 +02004111
4112 out->len = 0;
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02004113 for (i = 0; i < name_count; i++) {
Emeric Brun87855892012-10-17 17:39:35 +02004114 if (pos < 0)
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02004115 j = (name_count-1) - i;
Emeric Brun87855892012-10-17 17:39:35 +02004116 else
4117 j = i;
4118
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02004119 ne = X509_NAME_get_entry(a, j);
4120 obj = X509_NAME_ENTRY_get_object(ne);
4121 data = X509_NAME_ENTRY_get_data(ne);
4122 data_ptr = ASN1_STRING_get0_data(data);
4123 data_len = ASN1_STRING_length(data);
4124 n = OBJ_obj2nid(obj);
Emeric Brun87855892012-10-17 17:39:35 +02004125 if ((n == NID_undef) || ((s = OBJ_nid2sn(n)) == NULL)) {
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02004126 i2t_ASN1_OBJECT(tmp, sizeof(tmp), obj);
Emeric Brun87855892012-10-17 17:39:35 +02004127 s = tmp;
4128 }
4129
4130 if (chunk_strcasecmp(entry, s) != 0)
4131 continue;
4132
4133 if (pos < 0)
4134 cur--;
4135 else
4136 cur++;
4137
4138 if (cur != pos)
4139 continue;
4140
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02004141 if (data_len > out->size)
Emeric Brun87855892012-10-17 17:39:35 +02004142 return -1;
4143
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02004144 memcpy(out->str, data_ptr, data_len);
4145 out->len = data_len;
Emeric Brun87855892012-10-17 17:39:35 +02004146 return 1;
4147 }
4148
4149 return 0;
4150
4151}
4152
4153/* Extract and format full DN from a X509_NAME and copy result into a chunk
4154 * Returns 1 if dn entries exits, 0 if no dn entry found or -1 if output is not large enough.
4155 */
4156static int
4157ssl_sock_get_dn_oneline(X509_NAME *a, struct chunk *out)
4158{
4159 X509_NAME_ENTRY *ne;
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02004160 ASN1_OBJECT *obj;
4161 ASN1_STRING *data;
4162 const unsigned char *data_ptr;
4163 int data_len;
Emeric Brun87855892012-10-17 17:39:35 +02004164 int i, n, ln;
4165 int l = 0;
4166 const char *s;
4167 char *p;
4168 char tmp[128];
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02004169 int name_count;
4170
4171
4172 name_count = X509_NAME_entry_count(a);
Emeric Brun87855892012-10-17 17:39:35 +02004173
4174 out->len = 0;
4175 p = out->str;
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02004176 for (i = 0; i < name_count; i++) {
4177 ne = X509_NAME_get_entry(a, i);
4178 obj = X509_NAME_ENTRY_get_object(ne);
4179 data = X509_NAME_ENTRY_get_data(ne);
4180 data_ptr = ASN1_STRING_get0_data(data);
4181 data_len = ASN1_STRING_length(data);
4182 n = OBJ_obj2nid(obj);
Emeric Brun87855892012-10-17 17:39:35 +02004183 if ((n == NID_undef) || ((s = OBJ_nid2sn(n)) == NULL)) {
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02004184 i2t_ASN1_OBJECT(tmp, sizeof(tmp), obj);
Emeric Brun87855892012-10-17 17:39:35 +02004185 s = tmp;
4186 }
4187 ln = strlen(s);
4188
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02004189 l += 1 + ln + 1 + data_len;
Emeric Brun87855892012-10-17 17:39:35 +02004190 if (l > out->size)
4191 return -1;
4192 out->len = l;
4193
4194 *(p++)='/';
4195 memcpy(p, s, ln);
4196 p += ln;
4197 *(p++)='=';
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02004198 memcpy(p, data_ptr, data_len);
4199 p += data_len;
Emeric Brun87855892012-10-17 17:39:35 +02004200 }
4201
4202 if (!out->len)
4203 return 0;
4204
4205 return 1;
4206}
4207
David Safb76832014-05-08 23:42:08 -04004208char *ssl_sock_get_version(struct connection *conn)
4209{
4210 if (!ssl_sock_is_ssl(conn))
4211 return NULL;
4212
4213 return (char *)SSL_get_version(conn->xprt_ctx);
4214}
4215
Willy Tarreau63076412015-07-10 11:33:32 +02004216void ssl_sock_set_servername(struct connection *conn, const char *hostname)
4217{
4218#ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME
4219 if (!ssl_sock_is_ssl(conn))
4220 return;
4221
4222 SSL_set_tlsext_host_name(conn->xprt_ctx, hostname);
4223#endif
4224}
4225
Emeric Brun0abf8362014-06-24 18:26:41 +02004226/* Extract peer certificate's common name into the chunk dest
4227 * Returns
4228 * the len of the extracted common name
4229 * or 0 if no CN found in DN
4230 * or -1 on error case (i.e. no peer certificate)
4231 */
4232int ssl_sock_get_remote_common_name(struct connection *conn, struct chunk *dest)
David Safb76832014-05-08 23:42:08 -04004233{
4234 X509 *crt = NULL;
4235 X509_NAME *name;
David Safb76832014-05-08 23:42:08 -04004236 const char find_cn[] = "CN";
4237 const struct chunk find_cn_chunk = {
4238 .str = (char *)&find_cn,
4239 .len = sizeof(find_cn)-1
4240 };
Emeric Brun0abf8362014-06-24 18:26:41 +02004241 int result = -1;
David Safb76832014-05-08 23:42:08 -04004242
4243 if (!ssl_sock_is_ssl(conn))
Emeric Brun0abf8362014-06-24 18:26:41 +02004244 goto out;
David Safb76832014-05-08 23:42:08 -04004245
4246 /* SSL_get_peer_certificate, it increase X509 * ref count */
4247 crt = SSL_get_peer_certificate(conn->xprt_ctx);
4248 if (!crt)
4249 goto out;
4250
4251 name = X509_get_subject_name(crt);
4252 if (!name)
4253 goto out;
David Safb76832014-05-08 23:42:08 -04004254
Emeric Brun0abf8362014-06-24 18:26:41 +02004255 result = ssl_sock_get_dn_entry(name, &find_cn_chunk, 1, dest);
4256out:
David Safb76832014-05-08 23:42:08 -04004257 if (crt)
4258 X509_free(crt);
4259
4260 return result;
4261}
4262
Dave McCowan328fb582014-07-30 10:39:13 -04004263/* returns 1 if client passed a certificate for this session, 0 if not */
4264int ssl_sock_get_cert_used_sess(struct connection *conn)
4265{
4266 X509 *crt = NULL;
4267
4268 if (!ssl_sock_is_ssl(conn))
4269 return 0;
4270
4271 /* SSL_get_peer_certificate, it increase X509 * ref count */
4272 crt = SSL_get_peer_certificate(conn->xprt_ctx);
4273 if (!crt)
4274 return 0;
4275
4276 X509_free(crt);
4277 return 1;
4278}
4279
4280/* returns 1 if client passed a certificate for this connection, 0 if not */
4281int ssl_sock_get_cert_used_conn(struct connection *conn)
David Safb76832014-05-08 23:42:08 -04004282{
4283 if (!ssl_sock_is_ssl(conn))
4284 return 0;
4285
4286 return SSL_SOCK_ST_FL_VERIFY_DONE & conn->xprt_st ? 1 : 0;
4287}
4288
4289/* returns result from SSL verify */
4290unsigned int ssl_sock_get_verify_result(struct connection *conn)
4291{
4292 if (!ssl_sock_is_ssl(conn))
4293 return (unsigned int)X509_V_ERR_APPLICATION_VERIFICATION;
4294
4295 return (unsigned int)SSL_get_verify_result(conn->xprt_ctx);
4296}
4297
Willy Tarreau7875d092012-09-10 08:20:03 +02004298/***** Below are some sample fetching functions for ACL/patterns *****/
4299
Emeric Brune64aef12012-09-21 13:15:06 +02004300/* boolean, returns true if client cert was present */
4301static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02004302smp_fetch_ssl_fc_has_crt(const struct arg *args, struct sample *smp, const char *kw, void *private)
Emeric Brune64aef12012-09-21 13:15:06 +02004303{
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004304 struct connection *conn;
4305
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02004306 conn = objt_conn(smp->sess->origin);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004307 if (!conn || conn->xprt != &ssl_sock)
Emeric Brune64aef12012-09-21 13:15:06 +02004308 return 0;
4309
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004310 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brune64aef12012-09-21 13:15:06 +02004311 smp->flags |= SMP_F_MAY_CHANGE;
4312 return 0;
4313 }
4314
4315 smp->flags = 0;
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02004316 smp->data.type = SMP_T_BOOL;
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02004317 smp->data.u.sint = SSL_SOCK_ST_FL_VERIFY_DONE & conn->xprt_st ? 1 : 0;
Emeric Brune64aef12012-09-21 13:15:06 +02004318
4319 return 1;
4320}
4321
Emeric Brun43e79582014-10-29 19:03:26 +01004322/* binary, returns a certificate in a binary chunk (der/raw).
4323 * The 5th keyword char is used to know if SSL_get_certificate or SSL_get_peer_certificate
4324 * should be use.
4325 */
4326static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02004327smp_fetch_ssl_x_der(const struct arg *args, struct sample *smp, const char *kw, void *private)
Emeric Brun43e79582014-10-29 19:03:26 +01004328{
4329 int cert_peer = (kw[4] == 'c') ? 1 : 0;
4330 X509 *crt = NULL;
4331 int ret = 0;
4332 struct chunk *smp_trash;
4333 struct connection *conn;
4334
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02004335 conn = objt_conn(smp->sess->origin);
Emeric Brun43e79582014-10-29 19:03:26 +01004336 if (!conn || conn->xprt != &ssl_sock)
4337 return 0;
4338
4339 if (!(conn->flags & CO_FL_CONNECTED)) {
4340 smp->flags |= SMP_F_MAY_CHANGE;
4341 return 0;
4342 }
4343
4344 if (cert_peer)
4345 crt = SSL_get_peer_certificate(conn->xprt_ctx);
4346 else
4347 crt = SSL_get_certificate(conn->xprt_ctx);
4348
4349 if (!crt)
4350 goto out;
4351
4352 smp_trash = get_trash_chunk();
4353 if (ssl_sock_crt2der(crt, smp_trash) <= 0)
4354 goto out;
4355
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02004356 smp->data.u.str = *smp_trash;
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02004357 smp->data.type = SMP_T_BIN;
Emeric Brun43e79582014-10-29 19:03:26 +01004358 ret = 1;
4359out:
4360 /* SSL_get_peer_certificate, it increase X509 * ref count */
4361 if (cert_peer && crt)
4362 X509_free(crt);
4363 return ret;
4364}
4365
Emeric Brunba841a12014-04-30 17:05:08 +02004366/* binary, returns serial of certificate in a binary chunk.
4367 * The 5th keyword char is used to know if SSL_get_certificate or SSL_get_peer_certificate
4368 * should be use.
4369 */
Willy Tarreau8d598402012-10-22 17:58:39 +02004370static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02004371smp_fetch_ssl_x_serial(const struct arg *args, struct sample *smp, const char *kw, void *private)
Willy Tarreau8d598402012-10-22 17:58:39 +02004372{
Emeric Brunba841a12014-04-30 17:05:08 +02004373 int cert_peer = (kw[4] == 'c') ? 1 : 0;
Willy Tarreau8d598402012-10-22 17:58:39 +02004374 X509 *crt = NULL;
4375 int ret = 0;
4376 struct chunk *smp_trash;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004377 struct connection *conn;
4378
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02004379 conn = objt_conn(smp->sess->origin);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004380 if (!conn || conn->xprt != &ssl_sock)
Willy Tarreau8d598402012-10-22 17:58:39 +02004381 return 0;
4382
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004383 if (!(conn->flags & CO_FL_CONNECTED)) {
Willy Tarreau8d598402012-10-22 17:58:39 +02004384 smp->flags |= SMP_F_MAY_CHANGE;
4385 return 0;
4386 }
4387
Emeric Brunba841a12014-04-30 17:05:08 +02004388 if (cert_peer)
4389 crt = SSL_get_peer_certificate(conn->xprt_ctx);
4390 else
4391 crt = SSL_get_certificate(conn->xprt_ctx);
4392
Willy Tarreau8d598402012-10-22 17:58:39 +02004393 if (!crt)
4394 goto out;
4395
Willy Tarreau47ca5452012-12-23 20:22:19 +01004396 smp_trash = get_trash_chunk();
Willy Tarreau8d598402012-10-22 17:58:39 +02004397 if (ssl_sock_get_serial(crt, smp_trash) <= 0)
4398 goto out;
4399
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02004400 smp->data.u.str = *smp_trash;
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02004401 smp->data.type = SMP_T_BIN;
Willy Tarreau8d598402012-10-22 17:58:39 +02004402 ret = 1;
4403out:
Emeric Brunba841a12014-04-30 17:05:08 +02004404 /* SSL_get_peer_certificate, it increase X509 * ref count */
4405 if (cert_peer && crt)
Willy Tarreau8d598402012-10-22 17:58:39 +02004406 X509_free(crt);
4407 return ret;
4408}
Emeric Brune64aef12012-09-21 13:15:06 +02004409
Emeric Brunba841a12014-04-30 17:05:08 +02004410/* binary, returns the client certificate's SHA-1 fingerprint (SHA-1 hash of DER-encoded certificate) in a binary chunk.
4411 * The 5th keyword char is used to know if SSL_get_certificate or SSL_get_peer_certificate
4412 * should be use.
4413 */
James Votha051b4a2013-05-14 20:37:59 +02004414static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02004415smp_fetch_ssl_x_sha1(const struct arg *args, struct sample *smp, const char *kw, void *private)
James Votha051b4a2013-05-14 20:37:59 +02004416{
Emeric Brunba841a12014-04-30 17:05:08 +02004417 int cert_peer = (kw[4] == 'c') ? 1 : 0;
James Votha051b4a2013-05-14 20:37:59 +02004418 X509 *crt = NULL;
4419 const EVP_MD *digest;
4420 int ret = 0;
4421 struct chunk *smp_trash;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004422 struct connection *conn;
James Votha051b4a2013-05-14 20:37:59 +02004423
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02004424 conn = objt_conn(smp->sess->origin);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004425 if (!conn || conn->xprt != &ssl_sock)
4426 return 0;
4427
4428 if (!(conn->flags & CO_FL_CONNECTED)) {
James Votha051b4a2013-05-14 20:37:59 +02004429 smp->flags |= SMP_F_MAY_CHANGE;
4430 return 0;
4431 }
4432
Emeric Brunba841a12014-04-30 17:05:08 +02004433 if (cert_peer)
4434 crt = SSL_get_peer_certificate(conn->xprt_ctx);
4435 else
4436 crt = SSL_get_certificate(conn->xprt_ctx);
James Votha051b4a2013-05-14 20:37:59 +02004437 if (!crt)
4438 goto out;
4439
4440 smp_trash = get_trash_chunk();
4441 digest = EVP_sha1();
4442 X509_digest(crt, digest, (unsigned char *)smp_trash->str, (unsigned int *)&smp_trash->len);
4443
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02004444 smp->data.u.str = *smp_trash;
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02004445 smp->data.type = SMP_T_BIN;
James Votha051b4a2013-05-14 20:37:59 +02004446 ret = 1;
4447out:
Emeric Brunba841a12014-04-30 17:05:08 +02004448 /* SSL_get_peer_certificate, it increase X509 * ref count */
4449 if (cert_peer && crt)
James Votha051b4a2013-05-14 20:37:59 +02004450 X509_free(crt);
4451 return ret;
4452}
4453
Emeric Brunba841a12014-04-30 17:05:08 +02004454/* string, returns certificate's notafter date in ASN1_UTCTIME format.
4455 * The 5th keyword char is used to know if SSL_get_certificate or SSL_get_peer_certificate
4456 * should be use.
4457 */
Emeric Brunce5ad802012-10-22 14:11:22 +02004458static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02004459smp_fetch_ssl_x_notafter(const struct arg *args, struct sample *smp, const char *kw, void *private)
Emeric Brunce5ad802012-10-22 14:11:22 +02004460{
Emeric Brunba841a12014-04-30 17:05:08 +02004461 int cert_peer = (kw[4] == 'c') ? 1 : 0;
Emeric Brunce5ad802012-10-22 14:11:22 +02004462 X509 *crt = NULL;
4463 int ret = 0;
4464 struct chunk *smp_trash;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004465 struct connection *conn;
Emeric Brunce5ad802012-10-22 14:11:22 +02004466
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02004467 conn = objt_conn(smp->sess->origin);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004468 if (!conn || conn->xprt != &ssl_sock)
4469 return 0;
4470
4471 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brunce5ad802012-10-22 14:11:22 +02004472 smp->flags |= SMP_F_MAY_CHANGE;
4473 return 0;
4474 }
4475
Emeric Brunba841a12014-04-30 17:05:08 +02004476 if (cert_peer)
4477 crt = SSL_get_peer_certificate(conn->xprt_ctx);
4478 else
4479 crt = SSL_get_certificate(conn->xprt_ctx);
Emeric Brunce5ad802012-10-22 14:11:22 +02004480 if (!crt)
4481 goto out;
4482
Willy Tarreau47ca5452012-12-23 20:22:19 +01004483 smp_trash = get_trash_chunk();
Emeric Brunce5ad802012-10-22 14:11:22 +02004484 if (ssl_sock_get_time(X509_get_notAfter(crt), smp_trash) <= 0)
4485 goto out;
4486
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02004487 smp->data.u.str = *smp_trash;
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02004488 smp->data.type = SMP_T_STR;
Emeric Brunce5ad802012-10-22 14:11:22 +02004489 ret = 1;
4490out:
Emeric Brunba841a12014-04-30 17:05:08 +02004491 /* SSL_get_peer_certificate, it increase X509 * ref count */
4492 if (cert_peer && crt)
Emeric Brunce5ad802012-10-22 14:11:22 +02004493 X509_free(crt);
4494 return ret;
4495}
4496
Emeric Brunba841a12014-04-30 17:05:08 +02004497/* string, returns a string of a formatted full dn \C=..\O=..\OU=.. \CN=.. of certificate's issuer
4498 * The 5th keyword char is used to know if SSL_get_certificate or SSL_get_peer_certificate
4499 * should be use.
4500 */
Emeric Brun87855892012-10-17 17:39:35 +02004501static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02004502smp_fetch_ssl_x_i_dn(const struct arg *args, struct sample *smp, const char *kw, void *private)
Emeric Brun87855892012-10-17 17:39:35 +02004503{
Emeric Brunba841a12014-04-30 17:05:08 +02004504 int cert_peer = (kw[4] == 'c') ? 1 : 0;
Emeric Brun87855892012-10-17 17:39:35 +02004505 X509 *crt = NULL;
4506 X509_NAME *name;
4507 int ret = 0;
4508 struct chunk *smp_trash;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004509 struct connection *conn;
Emeric Brun87855892012-10-17 17:39:35 +02004510
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02004511 conn = objt_conn(smp->sess->origin);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004512 if (!conn || conn->xprt != &ssl_sock)
4513 return 0;
4514
4515 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brun87855892012-10-17 17:39:35 +02004516 smp->flags |= SMP_F_MAY_CHANGE;
4517 return 0;
4518 }
4519
Emeric Brunba841a12014-04-30 17:05:08 +02004520 if (cert_peer)
4521 crt = SSL_get_peer_certificate(conn->xprt_ctx);
4522 else
4523 crt = SSL_get_certificate(conn->xprt_ctx);
Emeric Brun87855892012-10-17 17:39:35 +02004524 if (!crt)
4525 goto out;
4526
4527 name = X509_get_issuer_name(crt);
4528 if (!name)
4529 goto out;
4530
Willy Tarreau47ca5452012-12-23 20:22:19 +01004531 smp_trash = get_trash_chunk();
Emeric Brun87855892012-10-17 17:39:35 +02004532 if (args && args[0].type == ARGT_STR) {
4533 int pos = 1;
4534
4535 if (args[1].type == ARGT_SINT)
4536 pos = args[1].data.sint;
Emeric Brun87855892012-10-17 17:39:35 +02004537
4538 if (ssl_sock_get_dn_entry(name, &args[0].data.str, pos, smp_trash) <= 0)
4539 goto out;
4540 }
4541 else if (ssl_sock_get_dn_oneline(name, smp_trash) <= 0)
4542 goto out;
4543
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02004544 smp->data.type = SMP_T_STR;
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02004545 smp->data.u.str = *smp_trash;
Emeric Brun87855892012-10-17 17:39:35 +02004546 ret = 1;
4547out:
Emeric Brunba841a12014-04-30 17:05:08 +02004548 /* SSL_get_peer_certificate, it increase X509 * ref count */
4549 if (cert_peer && crt)
Emeric Brun87855892012-10-17 17:39:35 +02004550 X509_free(crt);
4551 return ret;
4552}
4553
Emeric Brunba841a12014-04-30 17:05:08 +02004554/* string, returns notbefore date in ASN1_UTCTIME format.
4555 * The 5th keyword char is used to know if SSL_get_certificate or SSL_get_peer_certificate
4556 * should be use.
4557 */
Emeric Brunce5ad802012-10-22 14:11:22 +02004558static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02004559smp_fetch_ssl_x_notbefore(const struct arg *args, struct sample *smp, const char *kw, void *private)
Emeric Brunce5ad802012-10-22 14:11:22 +02004560{
Emeric Brunba841a12014-04-30 17:05:08 +02004561 int cert_peer = (kw[4] == 'c') ? 1 : 0;
Emeric Brunce5ad802012-10-22 14:11:22 +02004562 X509 *crt = NULL;
4563 int ret = 0;
4564 struct chunk *smp_trash;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004565 struct connection *conn;
4566
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02004567 conn = objt_conn(smp->sess->origin);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004568 if (!conn || conn->xprt != &ssl_sock)
Emeric Brunce5ad802012-10-22 14:11:22 +02004569 return 0;
4570
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004571 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brunce5ad802012-10-22 14:11:22 +02004572 smp->flags |= SMP_F_MAY_CHANGE;
4573 return 0;
4574 }
4575
Emeric Brunba841a12014-04-30 17:05:08 +02004576 if (cert_peer)
4577 crt = SSL_get_peer_certificate(conn->xprt_ctx);
4578 else
4579 crt = SSL_get_certificate(conn->xprt_ctx);
Emeric Brunce5ad802012-10-22 14:11:22 +02004580 if (!crt)
4581 goto out;
4582
Willy Tarreau47ca5452012-12-23 20:22:19 +01004583 smp_trash = get_trash_chunk();
Emeric Brunce5ad802012-10-22 14:11:22 +02004584 if (ssl_sock_get_time(X509_get_notBefore(crt), smp_trash) <= 0)
4585 goto out;
4586
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02004587 smp->data.u.str = *smp_trash;
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02004588 smp->data.type = SMP_T_STR;
Emeric Brunce5ad802012-10-22 14:11:22 +02004589 ret = 1;
4590out:
Emeric Brunba841a12014-04-30 17:05:08 +02004591 /* SSL_get_peer_certificate, it increase X509 * ref count */
4592 if (cert_peer && crt)
Emeric Brunce5ad802012-10-22 14:11:22 +02004593 X509_free(crt);
4594 return ret;
4595}
4596
Emeric Brunba841a12014-04-30 17:05:08 +02004597/* string, returns a string of a formatted full dn \C=..\O=..\OU=.. \CN=.. of certificate's subject
4598 * The 5th keyword char is used to know if SSL_get_certificate or SSL_get_peer_certificate
4599 * should be use.
4600 */
Emeric Brun87855892012-10-17 17:39:35 +02004601static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02004602smp_fetch_ssl_x_s_dn(const struct arg *args, struct sample *smp, const char *kw, void *private)
Emeric Brun87855892012-10-17 17:39:35 +02004603{
Emeric Brunba841a12014-04-30 17:05:08 +02004604 int cert_peer = (kw[4] == 'c') ? 1 : 0;
Emeric Brun87855892012-10-17 17:39:35 +02004605 X509 *crt = NULL;
4606 X509_NAME *name;
4607 int ret = 0;
4608 struct chunk *smp_trash;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004609 struct connection *conn;
Emeric Brun87855892012-10-17 17:39:35 +02004610
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02004611 conn = objt_conn(smp->sess->origin);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004612 if (!conn || conn->xprt != &ssl_sock)
4613 return 0;
4614
4615 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brun87855892012-10-17 17:39:35 +02004616 smp->flags |= SMP_F_MAY_CHANGE;
4617 return 0;
4618 }
4619
Emeric Brunba841a12014-04-30 17:05:08 +02004620 if (cert_peer)
4621 crt = SSL_get_peer_certificate(conn->xprt_ctx);
4622 else
4623 crt = SSL_get_certificate(conn->xprt_ctx);
Emeric Brun87855892012-10-17 17:39:35 +02004624 if (!crt)
4625 goto out;
4626
4627 name = X509_get_subject_name(crt);
4628 if (!name)
4629 goto out;
4630
Willy Tarreau47ca5452012-12-23 20:22:19 +01004631 smp_trash = get_trash_chunk();
Emeric Brun87855892012-10-17 17:39:35 +02004632 if (args && args[0].type == ARGT_STR) {
4633 int pos = 1;
4634
4635 if (args[1].type == ARGT_SINT)
4636 pos = args[1].data.sint;
Emeric Brun87855892012-10-17 17:39:35 +02004637
4638 if (ssl_sock_get_dn_entry(name, &args[0].data.str, pos, smp_trash) <= 0)
4639 goto out;
4640 }
4641 else if (ssl_sock_get_dn_oneline(name, smp_trash) <= 0)
4642 goto out;
4643
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02004644 smp->data.type = SMP_T_STR;
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02004645 smp->data.u.str = *smp_trash;
Emeric Brun87855892012-10-17 17:39:35 +02004646 ret = 1;
4647out:
Emeric Brunba841a12014-04-30 17:05:08 +02004648 /* SSL_get_peer_certificate, it increase X509 * ref count */
4649 if (cert_peer && crt)
Emeric Brun87855892012-10-17 17:39:35 +02004650 X509_free(crt);
4651 return ret;
4652}
Emeric Brun9143d372012-12-20 15:44:16 +01004653
4654/* integer, returns true if current session use a client certificate */
4655static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02004656smp_fetch_ssl_c_used(const struct arg *args, struct sample *smp, const char *kw, void *private)
Emeric Brun9143d372012-12-20 15:44:16 +01004657{
4658 X509 *crt;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004659 struct connection *conn;
Emeric Brun9143d372012-12-20 15:44:16 +01004660
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02004661 conn = objt_conn(smp->sess->origin);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004662 if (!conn || conn->xprt != &ssl_sock)
4663 return 0;
4664
4665 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brun9143d372012-12-20 15:44:16 +01004666 smp->flags |= SMP_F_MAY_CHANGE;
4667 return 0;
4668 }
4669
4670 /* SSL_get_peer_certificate returns a ptr on allocated X509 struct */
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004671 crt = SSL_get_peer_certificate(conn->xprt_ctx);
Emeric Brun9143d372012-12-20 15:44:16 +01004672 if (crt) {
4673 X509_free(crt);
4674 }
4675
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02004676 smp->data.type = SMP_T_BOOL;
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02004677 smp->data.u.sint = (crt != NULL);
Emeric Brun9143d372012-12-20 15:44:16 +01004678 return 1;
4679}
4680
Emeric Brunba841a12014-04-30 17:05:08 +02004681/* integer, returns the certificate version
4682 * The 5th keyword char is used to know if SSL_get_certificate or SSL_get_peer_certificate
4683 * should be use.
4684 */
Emeric Bruna7359fd2012-10-17 15:03:11 +02004685static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02004686smp_fetch_ssl_x_version(const struct arg *args, struct sample *smp, const char *kw, void *private)
Emeric Bruna7359fd2012-10-17 15:03:11 +02004687{
Emeric Brunba841a12014-04-30 17:05:08 +02004688 int cert_peer = (kw[4] == 'c') ? 1 : 0;
Emeric Bruna7359fd2012-10-17 15:03:11 +02004689 X509 *crt;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004690 struct connection *conn;
4691
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02004692 conn = objt_conn(smp->sess->origin);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004693 if (!conn || conn->xprt != &ssl_sock)
Emeric Bruna7359fd2012-10-17 15:03:11 +02004694 return 0;
4695
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004696 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Bruna7359fd2012-10-17 15:03:11 +02004697 smp->flags |= SMP_F_MAY_CHANGE;
4698 return 0;
4699 }
4700
Emeric Brunba841a12014-04-30 17:05:08 +02004701 if (cert_peer)
4702 crt = SSL_get_peer_certificate(conn->xprt_ctx);
4703 else
4704 crt = SSL_get_certificate(conn->xprt_ctx);
Emeric Bruna7359fd2012-10-17 15:03:11 +02004705 if (!crt)
4706 return 0;
4707
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02004708 smp->data.u.sint = (unsigned int)(1 + X509_get_version(crt));
Emeric Brunba841a12014-04-30 17:05:08 +02004709 /* SSL_get_peer_certificate increase X509 * ref count */
4710 if (cert_peer)
4711 X509_free(crt);
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02004712 smp->data.type = SMP_T_SINT;
Emeric Bruna7359fd2012-10-17 15:03:11 +02004713
4714 return 1;
4715}
4716
Emeric Brunba841a12014-04-30 17:05:08 +02004717/* string, returns the certificate's signature algorithm.
4718 * The 5th keyword char is used to know if SSL_get_certificate or SSL_get_peer_certificate
4719 * should be use.
4720 */
Emeric Brun7f56e742012-10-19 18:15:40 +02004721static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02004722smp_fetch_ssl_x_sig_alg(const struct arg *args, struct sample *smp, const char *kw, void *private)
Emeric Brun7f56e742012-10-19 18:15:40 +02004723{
Emeric Brunba841a12014-04-30 17:05:08 +02004724 int cert_peer = (kw[4] == 'c') ? 1 : 0;
Emeric Brun7f56e742012-10-19 18:15:40 +02004725 X509 *crt;
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02004726 __OPENSSL_110_CONST__ ASN1_OBJECT *algorithm;
Emeric Brun7f56e742012-10-19 18:15:40 +02004727 int nid;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004728 struct connection *conn;
Emeric Brun7f56e742012-10-19 18:15:40 +02004729
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02004730 conn = objt_conn(smp->sess->origin);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004731 if (!conn || conn->xprt != &ssl_sock)
4732 return 0;
4733
4734 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brun7f56e742012-10-19 18:15:40 +02004735 smp->flags |= SMP_F_MAY_CHANGE;
4736 return 0;
4737 }
4738
Emeric Brunba841a12014-04-30 17:05:08 +02004739 if (cert_peer)
4740 crt = SSL_get_peer_certificate(conn->xprt_ctx);
4741 else
4742 crt = SSL_get_certificate(conn->xprt_ctx);
Emeric Brun7f56e742012-10-19 18:15:40 +02004743 if (!crt)
4744 return 0;
4745
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02004746 X509_ALGOR_get0(&algorithm, NULL, NULL, X509_get0_tbs_sigalg(crt));
4747 nid = OBJ_obj2nid(algorithm);
Emeric Brun7f56e742012-10-19 18:15:40 +02004748
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02004749 smp->data.u.str.str = (char *)OBJ_nid2sn(nid);
4750 if (!smp->data.u.str.str) {
Emeric Brunba841a12014-04-30 17:05:08 +02004751 /* SSL_get_peer_certificate increase X509 * ref count */
4752 if (cert_peer)
4753 X509_free(crt);
Emeric Brun7f56e742012-10-19 18:15:40 +02004754 return 0;
Emeric Brun9bf3ba22013-10-07 14:31:44 +02004755 }
Emeric Brun7f56e742012-10-19 18:15:40 +02004756
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02004757 smp->data.type = SMP_T_STR;
Thierry FOURNIER7654c9f2013-12-17 00:20:33 +01004758 smp->flags |= SMP_F_CONST;
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02004759 smp->data.u.str.len = strlen(smp->data.u.str.str);
Emeric Brunba841a12014-04-30 17:05:08 +02004760 /* SSL_get_peer_certificate increase X509 * ref count */
4761 if (cert_peer)
4762 X509_free(crt);
Emeric Brun7f56e742012-10-19 18:15:40 +02004763
4764 return 1;
4765}
4766
Emeric Brunba841a12014-04-30 17:05:08 +02004767/* string, returns the certificate's key algorithm.
4768 * The 5th keyword char is used to know if SSL_get_certificate or SSL_get_peer_certificate
4769 * should be use.
4770 */
Emeric Brun521a0112012-10-22 12:22:55 +02004771static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02004772smp_fetch_ssl_x_key_alg(const struct arg *args, struct sample *smp, const char *kw, void *private)
Emeric Brun521a0112012-10-22 12:22:55 +02004773{
Emeric Brunba841a12014-04-30 17:05:08 +02004774 int cert_peer = (kw[4] == 'c') ? 1 : 0;
Emeric Brun521a0112012-10-22 12:22:55 +02004775 X509 *crt;
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02004776 ASN1_OBJECT *algorithm;
Emeric Brun521a0112012-10-22 12:22:55 +02004777 int nid;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004778 struct connection *conn;
Emeric Brun521a0112012-10-22 12:22:55 +02004779
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02004780 conn = objt_conn(smp->sess->origin);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004781 if (!conn || conn->xprt != &ssl_sock)
4782 return 0;
4783
4784 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brun521a0112012-10-22 12:22:55 +02004785 smp->flags |= SMP_F_MAY_CHANGE;
4786 return 0;
4787 }
4788
Emeric Brunba841a12014-04-30 17:05:08 +02004789 if (cert_peer)
4790 crt = SSL_get_peer_certificate(conn->xprt_ctx);
4791 else
4792 crt = SSL_get_certificate(conn->xprt_ctx);
Emeric Brun521a0112012-10-22 12:22:55 +02004793 if (!crt)
4794 return 0;
4795
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02004796 X509_PUBKEY_get0_param(&algorithm, NULL, NULL, NULL, X509_get_X509_PUBKEY(crt));
4797 nid = OBJ_obj2nid(algorithm);
Emeric Brun521a0112012-10-22 12:22:55 +02004798
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02004799 smp->data.u.str.str = (char *)OBJ_nid2sn(nid);
4800 if (!smp->data.u.str.str) {
Emeric Brunba841a12014-04-30 17:05:08 +02004801 /* SSL_get_peer_certificate increase X509 * ref count */
4802 if (cert_peer)
4803 X509_free(crt);
Emeric Brun521a0112012-10-22 12:22:55 +02004804 return 0;
Emeric Brun9bf3ba22013-10-07 14:31:44 +02004805 }
Emeric Brun521a0112012-10-22 12:22:55 +02004806
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02004807 smp->data.type = SMP_T_STR;
Thierry FOURNIER7654c9f2013-12-17 00:20:33 +01004808 smp->flags |= SMP_F_CONST;
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02004809 smp->data.u.str.len = strlen(smp->data.u.str.str);
Emeric Brunba841a12014-04-30 17:05:08 +02004810 if (cert_peer)
4811 X509_free(crt);
Emeric Brun521a0112012-10-22 12:22:55 +02004812
4813 return 1;
4814}
4815
Emeric Brun645ae792014-04-30 14:21:06 +02004816/* boolean, returns true if front conn. transport layer is SSL.
4817 * This function is also usable on backend conn if the fetch keyword 5th
4818 * char is 'b'.
4819 */
Willy Tarreau7875d092012-09-10 08:20:03 +02004820static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02004821smp_fetch_ssl_fc(const struct arg *args, struct sample *smp, const char *kw, void *private)
Willy Tarreau7875d092012-09-10 08:20:03 +02004822{
Willy Tarreaue237fe12016-03-10 17:05:28 +01004823 struct connection *conn = objt_conn((kw[4] != 'b') ? smp->sess->origin :
4824 smp->strm ? smp->strm->si[1].end : NULL);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004825
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02004826 smp->data.type = SMP_T_BOOL;
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02004827 smp->data.u.sint = (conn && conn->xprt == &ssl_sock);
Willy Tarreau7875d092012-09-10 08:20:03 +02004828 return 1;
4829}
4830
Emeric Brun2525b6b2012-10-18 15:59:43 +02004831/* boolean, returns true if client present a SNI */
Willy Tarreau7875d092012-09-10 08:20:03 +02004832static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02004833smp_fetch_ssl_fc_has_sni(const struct arg *args, struct sample *smp, const char *kw, void *private)
Willy Tarreau7875d092012-09-10 08:20:03 +02004834{
4835#ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02004836 struct connection *conn = objt_conn(smp->sess->origin);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004837
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02004838 smp->data.type = SMP_T_BOOL;
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02004839 smp->data.u.sint = (conn && conn->xprt == &ssl_sock) &&
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004840 conn->xprt_ctx &&
4841 SSL_get_servername(conn->xprt_ctx, TLSEXT_NAMETYPE_host_name) != NULL;
Willy Tarreau7875d092012-09-10 08:20:03 +02004842 return 1;
4843#else
4844 return 0;
4845#endif
4846}
4847
Nenad Merdanovic26ea8222015-05-18 02:28:57 +02004848/* boolean, returns true if client session has been resumed */
4849static int
4850smp_fetch_ssl_fc_is_resumed(const struct arg *args, struct sample *smp, const char *kw, void *private)
4851{
4852 struct connection *conn = objt_conn(smp->sess->origin);
4853
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02004854 smp->data.type = SMP_T_BOOL;
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02004855 smp->data.u.sint = (conn && conn->xprt == &ssl_sock) &&
Nenad Merdanovic26ea8222015-05-18 02:28:57 +02004856 conn->xprt_ctx &&
4857 SSL_session_reused(conn->xprt_ctx);
4858 return 1;
4859}
4860
Emeric Brun645ae792014-04-30 14:21:06 +02004861/* string, returns the used cipher if front conn. transport layer is SSL.
4862 * This function is also usable on backend conn if the fetch keyword 5th
4863 * char is 'b'.
4864 */
Emeric Brun589fcad2012-10-16 14:13:26 +02004865static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02004866smp_fetch_ssl_fc_cipher(const struct arg *args, struct sample *smp, const char *kw, void *private)
Emeric Brun589fcad2012-10-16 14:13:26 +02004867{
Willy Tarreaue237fe12016-03-10 17:05:28 +01004868 struct connection *conn = objt_conn((kw[4] != 'b') ? smp->sess->origin :
4869 smp->strm ? smp->strm->si[1].end : NULL);
Emeric Brun589fcad2012-10-16 14:13:26 +02004870
Willy Tarreaube508f12016-03-10 11:47:01 +01004871 smp->flags = 0;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004872 if (!conn || !conn->xprt_ctx || conn->xprt != &ssl_sock)
Emeric Brun589fcad2012-10-16 14:13:26 +02004873 return 0;
4874
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02004875 smp->data.u.str.str = (char *)SSL_get_cipher_name(conn->xprt_ctx);
4876 if (!smp->data.u.str.str)
Emeric Brun589fcad2012-10-16 14:13:26 +02004877 return 0;
4878
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02004879 smp->data.type = SMP_T_STR;
Thierry FOURNIER7654c9f2013-12-17 00:20:33 +01004880 smp->flags |= SMP_F_CONST;
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02004881 smp->data.u.str.len = strlen(smp->data.u.str.str);
Emeric Brun589fcad2012-10-16 14:13:26 +02004882
4883 return 1;
4884}
4885
Emeric Brun645ae792014-04-30 14:21:06 +02004886/* integer, returns the algoritm's keysize if front conn. transport layer
4887 * is SSL.
4888 * This function is also usable on backend conn if the fetch keyword 5th
4889 * char is 'b'.
4890 */
Emeric Brun589fcad2012-10-16 14:13:26 +02004891static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02004892smp_fetch_ssl_fc_alg_keysize(const struct arg *args, struct sample *smp, const char *kw, void *private)
Emeric Brun589fcad2012-10-16 14:13:26 +02004893{
Willy Tarreaue237fe12016-03-10 17:05:28 +01004894 struct connection *conn = objt_conn((kw[4] != 'b') ? smp->sess->origin :
4895 smp->strm ? smp->strm->si[1].end : NULL);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004896
Willy Tarreaue237fe12016-03-10 17:05:28 +01004897 int sint;
Willy Tarreaube508f12016-03-10 11:47:01 +01004898
Emeric Brun589fcad2012-10-16 14:13:26 +02004899 smp->flags = 0;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004900 if (!conn || !conn->xprt_ctx || conn->xprt != &ssl_sock)
Emeric Brun589fcad2012-10-16 14:13:26 +02004901 return 0;
4902
Thierry FOURNIER07ee64e2015-07-06 23:43:03 +02004903 if (!SSL_get_cipher_bits(conn->xprt_ctx, &sint))
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004904 return 0;
4905
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02004906 smp->data.u.sint = sint;
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02004907 smp->data.type = SMP_T_SINT;
Emeric Brun589fcad2012-10-16 14:13:26 +02004908
4909 return 1;
4910}
4911
Emeric Brun645ae792014-04-30 14:21:06 +02004912/* integer, returns the used keysize if front conn. transport layer is SSL.
4913 * This function is also usable on backend conn if the fetch keyword 5th
4914 * char is 'b'.
4915 */
Emeric Brun589fcad2012-10-16 14:13:26 +02004916static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02004917smp_fetch_ssl_fc_use_keysize(const struct arg *args, struct sample *smp, const char *kw, void *private)
Emeric Brun589fcad2012-10-16 14:13:26 +02004918{
Willy Tarreaue237fe12016-03-10 17:05:28 +01004919 struct connection *conn = objt_conn((kw[4] != 'b') ? smp->sess->origin :
4920 smp->strm ? smp->strm->si[1].end : NULL);
Willy Tarreaube508f12016-03-10 11:47:01 +01004921
Emeric Brun589fcad2012-10-16 14:13:26 +02004922 smp->flags = 0;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004923 if (!conn || !conn->xprt_ctx || conn->xprt != &ssl_sock)
4924 return 0;
4925
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02004926 smp->data.u.sint = (unsigned int)SSL_get_cipher_bits(conn->xprt_ctx, NULL);
4927 if (!smp->data.u.sint)
Emeric Brun589fcad2012-10-16 14:13:26 +02004928 return 0;
4929
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02004930 smp->data.type = SMP_T_SINT;
Emeric Brun589fcad2012-10-16 14:13:26 +02004931
4932 return 1;
4933}
4934
Willy Tarreau6c9a3d52012-10-18 18:57:14 +02004935#ifdef OPENSSL_NPN_NEGOTIATED
Willy Tarreau7875d092012-09-10 08:20:03 +02004936static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02004937smp_fetch_ssl_fc_npn(const struct arg *args, struct sample *smp, const char *kw, void *private)
Willy Tarreaua33c6542012-10-15 13:19:06 +02004938{
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004939 struct connection *conn;
4940
Thierry FOURNIER7654c9f2013-12-17 00:20:33 +01004941 smp->flags = SMP_F_CONST;
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02004942 smp->data.type = SMP_T_STR;
Willy Tarreaua33c6542012-10-15 13:19:06 +02004943
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02004944 conn = objt_conn(smp->sess->origin);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004945 if (!conn || !conn->xprt_ctx || conn->xprt != &ssl_sock)
4946 return 0;
4947
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02004948 smp->data.u.str.str = NULL;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004949 SSL_get0_next_proto_negotiated(conn->xprt_ctx,
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02004950 (const unsigned char **)&smp->data.u.str.str, (unsigned *)&smp->data.u.str.len);
Willy Tarreaua33c6542012-10-15 13:19:06 +02004951
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02004952 if (!smp->data.u.str.str)
Willy Tarreaua33c6542012-10-15 13:19:06 +02004953 return 0;
4954
4955 return 1;
Willy Tarreaua33c6542012-10-15 13:19:06 +02004956}
Willy Tarreau6c9a3d52012-10-18 18:57:14 +02004957#endif
Willy Tarreaua33c6542012-10-15 13:19:06 +02004958
Dirkjan Bussink48f1c4e2014-02-13 12:29:42 +01004959#ifdef TLSEXT_TYPE_application_layer_protocol_negotiation
Willy Tarreauab861d32013-04-02 02:30:41 +02004960static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02004961smp_fetch_ssl_fc_alpn(const struct arg *args, struct sample *smp, const char *kw, void *private)
Willy Tarreauab861d32013-04-02 02:30:41 +02004962{
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004963 struct connection *conn;
4964
Thierry FOURNIER7654c9f2013-12-17 00:20:33 +01004965 smp->flags = SMP_F_CONST;
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02004966 smp->data.type = SMP_T_STR;
Willy Tarreauab861d32013-04-02 02:30:41 +02004967
Willy Tarreaue26bf052015-05-12 10:30:12 +02004968 conn = objt_conn(smp->sess->origin);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004969 if (!conn || !conn->xprt_ctx || conn->xprt != &ssl_sock)
Willy Tarreauab861d32013-04-02 02:30:41 +02004970 return 0;
4971
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02004972 smp->data.u.str.str = NULL;
Dirkjan Bussink48f1c4e2014-02-13 12:29:42 +01004973 SSL_get0_alpn_selected(conn->xprt_ctx,
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02004974 (const unsigned char **)&smp->data.u.str.str, (unsigned *)&smp->data.u.str.len);
Willy Tarreauab861d32013-04-02 02:30:41 +02004975
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02004976 if (!smp->data.u.str.str)
Willy Tarreauab861d32013-04-02 02:30:41 +02004977 return 0;
4978
4979 return 1;
4980}
4981#endif
4982
Emeric Brun645ae792014-04-30 14:21:06 +02004983/* string, returns the used protocol if front conn. transport layer is SSL.
4984 * This function is also usable on backend conn if the fetch keyword 5th
4985 * char is 'b'.
4986 */
Willy Tarreaua33c6542012-10-15 13:19:06 +02004987static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02004988smp_fetch_ssl_fc_protocol(const struct arg *args, struct sample *smp, const char *kw, void *private)
Emeric Brun589fcad2012-10-16 14:13:26 +02004989{
Willy Tarreaue237fe12016-03-10 17:05:28 +01004990 struct connection *conn = objt_conn((kw[4] != 'b') ? smp->sess->origin :
4991 smp->strm ? smp->strm->si[1].end : NULL);
Willy Tarreaube508f12016-03-10 11:47:01 +01004992
Emeric Brun589fcad2012-10-16 14:13:26 +02004993 smp->flags = 0;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004994 if (!conn || !conn->xprt_ctx || conn->xprt != &ssl_sock)
4995 return 0;
4996
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02004997 smp->data.u.str.str = (char *)SSL_get_version(conn->xprt_ctx);
4998 if (!smp->data.u.str.str)
Emeric Brun589fcad2012-10-16 14:13:26 +02004999 return 0;
5000
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02005001 smp->data.type = SMP_T_STR;
Thierry FOURNIER7654c9f2013-12-17 00:20:33 +01005002 smp->flags = SMP_F_CONST;
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02005003 smp->data.u.str.len = strlen(smp->data.u.str.str);
Emeric Brun589fcad2012-10-16 14:13:26 +02005004
5005 return 1;
5006}
5007
Willy Tarreau87b09662015-04-03 00:22:06 +02005008/* binary, returns the SSL stream id if front conn. transport layer is SSL.
Emeric Brun645ae792014-04-30 14:21:06 +02005009 * This function is also usable on backend conn if the fetch keyword 5th
5010 * char is 'b'.
5011 */
Emeric Brun589fcad2012-10-16 14:13:26 +02005012static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02005013smp_fetch_ssl_fc_session_id(const struct arg *args, struct sample *smp, const char *kw, void *private)
Emeric Brunfe68f682012-10-16 14:59:28 +02005014{
5015#if OPENSSL_VERSION_NUMBER > 0x0090800fL
Willy Tarreaue237fe12016-03-10 17:05:28 +01005016 struct connection *conn = objt_conn((kw[4] != 'b') ? smp->sess->origin :
5017 smp->strm ? smp->strm->si[1].end : NULL);
Emeric Brunfe68f682012-10-16 14:59:28 +02005018
Willy Tarreaue237fe12016-03-10 17:05:28 +01005019 SSL_SESSION *ssl_sess;
Willy Tarreaube508f12016-03-10 11:47:01 +01005020
Thierry FOURNIER7654c9f2013-12-17 00:20:33 +01005021 smp->flags = SMP_F_CONST;
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02005022 smp->data.type = SMP_T_BIN;
Emeric Brunfe68f682012-10-16 14:59:28 +02005023
Willy Tarreaub363a1f2013-10-01 10:45:07 +02005024 if (!conn || !conn->xprt_ctx || conn->xprt != &ssl_sock)
5025 return 0;
5026
Willy Tarreau192252e2015-04-04 01:47:55 +02005027 ssl_sess = SSL_get_session(conn->xprt_ctx);
5028 if (!ssl_sess)
Emeric Brunfe68f682012-10-16 14:59:28 +02005029 return 0;
5030
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02005031 smp->data.u.str.str = (char *)SSL_SESSION_get_id(ssl_sess, (unsigned int *)&smp->data.u.str.len);
5032 if (!smp->data.u.str.str || !smp->data.u.str.len)
Emeric Brunfe68f682012-10-16 14:59:28 +02005033 return 0;
5034
5035 return 1;
5036#else
5037 return 0;
5038#endif
5039}
5040
5041static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02005042smp_fetch_ssl_fc_sni(const struct arg *args, struct sample *smp, const char *kw, void *private)
Willy Tarreau7875d092012-09-10 08:20:03 +02005043{
5044#ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME
Willy Tarreaub363a1f2013-10-01 10:45:07 +02005045 struct connection *conn;
5046
Thierry FOURNIER7654c9f2013-12-17 00:20:33 +01005047 smp->flags = SMP_F_CONST;
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02005048 smp->data.type = SMP_T_STR;
Willy Tarreau7875d092012-09-10 08:20:03 +02005049
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02005050 conn = objt_conn(smp->sess->origin);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02005051 if (!conn || !conn->xprt_ctx || conn->xprt != &ssl_sock)
5052 return 0;
5053
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02005054 smp->data.u.str.str = (char *)SSL_get_servername(conn->xprt_ctx, TLSEXT_NAMETYPE_host_name);
5055 if (!smp->data.u.str.str)
Willy Tarreau3e394c92012-09-14 23:56:58 +02005056 return 0;
5057
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02005058 smp->data.u.str.len = strlen(smp->data.u.str.str);
Willy Tarreau7875d092012-09-10 08:20:03 +02005059 return 1;
5060#else
5061 return 0;
5062#endif
5063}
5064
David Sc1ad52e2014-04-08 18:48:47 -04005065static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02005066smp_fetch_ssl_fc_unique_id(const struct arg *args, struct sample *smp, const char *kw, void *private)
David Sc1ad52e2014-04-08 18:48:47 -04005067{
5068#if OPENSSL_VERSION_NUMBER > 0x0090800fL
Willy Tarreaue237fe12016-03-10 17:05:28 +01005069 struct connection *conn = objt_conn((kw[4] != 'b') ? smp->sess->origin :
5070 smp->strm ? smp->strm->si[1].end : NULL);
5071
David Sc1ad52e2014-04-08 18:48:47 -04005072 int finished_len;
David Sc1ad52e2014-04-08 18:48:47 -04005073 struct chunk *finished_trash;
David Sc1ad52e2014-04-08 18:48:47 -04005074
5075 smp->flags = 0;
David Sc1ad52e2014-04-08 18:48:47 -04005076 if (!conn || !conn->xprt_ctx || conn->xprt != &ssl_sock)
5077 return 0;
5078
5079 if (!(conn->flags & CO_FL_CONNECTED)) {
5080 smp->flags |= SMP_F_MAY_CHANGE;
5081 return 0;
5082 }
5083
5084 finished_trash = get_trash_chunk();
5085 if (!SSL_session_reused(conn->xprt_ctx))
5086 finished_len = SSL_get_peer_finished(conn->xprt_ctx, finished_trash->str, finished_trash->size);
5087 else
5088 finished_len = SSL_get_finished(conn->xprt_ctx, finished_trash->str, finished_trash->size);
5089
5090 if (!finished_len)
5091 return 0;
5092
Emeric Brunb73a9b02014-04-30 18:49:19 +02005093 finished_trash->len = finished_len;
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02005094 smp->data.u.str = *finished_trash;
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02005095 smp->data.type = SMP_T_BIN;
David Sc1ad52e2014-04-08 18:48:47 -04005096
5097 return 1;
5098#else
5099 return 0;
5100#endif
5101}
5102
Emeric Brun2525b6b2012-10-18 15:59:43 +02005103/* integer, returns the first verify error in CA chain of client certificate chain. */
Emeric Brunf282a812012-09-21 15:27:54 +02005104static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02005105smp_fetch_ssl_c_ca_err(const struct arg *args, struct sample *smp, const char *kw, void *private)
Emeric Brunf282a812012-09-21 15:27:54 +02005106{
Willy Tarreaub363a1f2013-10-01 10:45:07 +02005107 struct connection *conn;
5108
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02005109 conn = objt_conn(smp->sess->origin);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02005110 if (!conn || conn->xprt != &ssl_sock)
5111 return 0;
5112
5113 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brunf282a812012-09-21 15:27:54 +02005114 smp->flags = SMP_F_MAY_CHANGE;
5115 return 0;
5116 }
5117
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02005118 smp->data.type = SMP_T_SINT;
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02005119 smp->data.u.sint = (unsigned long long int)SSL_SOCK_ST_TO_CA_ERROR(conn->xprt_st);
Emeric Brunf282a812012-09-21 15:27:54 +02005120 smp->flags = 0;
5121
5122 return 1;
5123}
5124
Emeric Brun2525b6b2012-10-18 15:59:43 +02005125/* integer, returns the depth of the first verify error in CA chain of client certificate chain. */
Emeric Brunf282a812012-09-21 15:27:54 +02005126static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02005127smp_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 +02005128{
Willy Tarreaub363a1f2013-10-01 10:45:07 +02005129 struct connection *conn;
5130
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02005131 conn = objt_conn(smp->sess->origin);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02005132 if (!conn || conn->xprt != &ssl_sock)
Emeric Brunf282a812012-09-21 15:27:54 +02005133 return 0;
5134
Willy Tarreaub363a1f2013-10-01 10:45:07 +02005135 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brunf282a812012-09-21 15:27:54 +02005136 smp->flags = SMP_F_MAY_CHANGE;
5137 return 0;
5138 }
5139
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02005140 smp->data.type = SMP_T_SINT;
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02005141 smp->data.u.sint = (long long int)SSL_SOCK_ST_TO_CAEDEPTH(conn->xprt_st);
Emeric Brunf282a812012-09-21 15:27:54 +02005142 smp->flags = 0;
5143
5144 return 1;
5145}
5146
Emeric Brun2525b6b2012-10-18 15:59:43 +02005147/* integer, returns the first verify error on client certificate */
Emeric Brunf282a812012-09-21 15:27:54 +02005148static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02005149smp_fetch_ssl_c_err(const struct arg *args, struct sample *smp, const char *kw, void *private)
Emeric Brunf282a812012-09-21 15:27:54 +02005150{
Willy Tarreaub363a1f2013-10-01 10:45:07 +02005151 struct connection *conn;
5152
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02005153 conn = objt_conn(smp->sess->origin);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02005154 if (!conn || conn->xprt != &ssl_sock)
5155 return 0;
5156
5157 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brunf282a812012-09-21 15:27:54 +02005158 smp->flags = SMP_F_MAY_CHANGE;
5159 return 0;
5160 }
5161
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02005162 smp->data.type = SMP_T_SINT;
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02005163 smp->data.u.sint = (long long int)SSL_SOCK_ST_TO_CRTERROR(conn->xprt_st);
Emeric Brunf282a812012-09-21 15:27:54 +02005164 smp->flags = 0;
5165
5166 return 1;
5167}
5168
Emeric Brun2525b6b2012-10-18 15:59:43 +02005169/* integer, returns the verify result on client cert */
Emeric Brunbaf8ffb2012-09-21 15:27:20 +02005170static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02005171smp_fetch_ssl_c_verify(const struct arg *args, struct sample *smp, const char *kw, void *private)
Emeric Brunbaf8ffb2012-09-21 15:27:20 +02005172{
Willy Tarreaub363a1f2013-10-01 10:45:07 +02005173 struct connection *conn;
5174
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02005175 conn = objt_conn(smp->sess->origin);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02005176 if (!conn || conn->xprt != &ssl_sock)
5177 return 0;
5178
5179 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brunbaf8ffb2012-09-21 15:27:20 +02005180 smp->flags = SMP_F_MAY_CHANGE;
5181 return 0;
5182 }
5183
Willy Tarreaub363a1f2013-10-01 10:45:07 +02005184 if (!conn->xprt_ctx)
Emeric Brunbaf8ffb2012-09-21 15:27:20 +02005185 return 0;
5186
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02005187 smp->data.type = SMP_T_SINT;
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02005188 smp->data.u.sint = (long long int)SSL_get_verify_result(conn->xprt_ctx);
Emeric Brunbaf8ffb2012-09-21 15:27:20 +02005189 smp->flags = 0;
5190
5191 return 1;
5192}
5193
Emeric Brunfb510ea2012-10-05 12:00:26 +02005194/* parse the "ca-file" bind keyword */
5195static int bind_parse_ca_file(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
Emeric Brund94b3fe2012-09-20 18:23:56 +02005196{
5197 if (!*args[cur_arg + 1]) {
5198 if (err)
5199 memprintf(err, "'%s' : missing CAfile path", args[cur_arg]);
5200 return ERR_ALERT | ERR_FATAL;
5201 }
5202
Emeric Brunef42d922012-10-11 16:11:36 +02005203 if ((*args[cur_arg + 1] != '/') && global.ca_base)
5204 memprintf(&conf->ca_file, "%s/%s", global.ca_base, args[cur_arg + 1]);
5205 else
5206 memprintf(&conf->ca_file, "%s", args[cur_arg + 1]);
Emeric Brunc8e8d122012-10-02 18:42:10 +02005207
Emeric Brund94b3fe2012-09-20 18:23:56 +02005208 return 0;
5209}
5210
Christopher Faulet31af49d2015-06-09 17:29:50 +02005211/* parse the "ca-sign-file" bind keyword */
5212static int bind_parse_ca_sign_file(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
5213{
5214 if (!*args[cur_arg + 1]) {
5215 if (err)
5216 memprintf(err, "'%s' : missing CAfile path", args[cur_arg]);
5217 return ERR_ALERT | ERR_FATAL;
5218 }
5219
5220 if ((*args[cur_arg + 1] != '/') && global.ca_base)
5221 memprintf(&conf->ca_sign_file, "%s/%s", global.ca_base, args[cur_arg + 1]);
5222 else
5223 memprintf(&conf->ca_sign_file, "%s", args[cur_arg + 1]);
5224
5225 return 0;
5226}
5227
Bertrand Jacquinff13c062016-11-13 16:37:11 +00005228/* parse the "ca-sign-pass" bind keyword */
Christopher Faulet31af49d2015-06-09 17:29:50 +02005229static int bind_parse_ca_sign_pass(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
5230{
5231 if (!*args[cur_arg + 1]) {
5232 if (err)
5233 memprintf(err, "'%s' : missing CAkey password", args[cur_arg]);
5234 return ERR_ALERT | ERR_FATAL;
5235 }
5236 memprintf(&conf->ca_sign_pass, "%s", args[cur_arg + 1]);
5237 return 0;
5238}
5239
Willy Tarreau79eeafa2012-09-14 07:53:05 +02005240/* parse the "ciphers" bind keyword */
Willy Tarreau4348fad2012-09-20 16:48:07 +02005241static int bind_parse_ciphers(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
Willy Tarreau79eeafa2012-09-14 07:53:05 +02005242{
5243 if (!*args[cur_arg + 1]) {
Willy Tarreaueb6cead2012-09-20 19:43:14 +02005244 memprintf(err, "'%s' : missing cipher suite", args[cur_arg]);
Willy Tarreau79eeafa2012-09-14 07:53:05 +02005245 return ERR_ALERT | ERR_FATAL;
5246 }
5247
Emeric Brun76d88952012-10-05 15:47:31 +02005248 free(conf->ciphers);
Willy Tarreau4348fad2012-09-20 16:48:07 +02005249 conf->ciphers = strdup(args[cur_arg + 1]);
Willy Tarreau79eeafa2012-09-14 07:53:05 +02005250 return 0;
5251}
5252
5253/* parse the "crt" bind keyword */
Willy Tarreau4348fad2012-09-20 16:48:07 +02005254static 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 +02005255{
Willy Tarreau38011032013-08-13 16:59:39 +02005256 char path[MAXPATHLEN];
Willy Tarreaub75d6922014-04-14 18:05:41 +02005257
Willy Tarreau79eeafa2012-09-14 07:53:05 +02005258 if (!*args[cur_arg + 1]) {
Willy Tarreaueb6cead2012-09-20 19:43:14 +02005259 memprintf(err, "'%s' : missing certificate location", args[cur_arg]);
Willy Tarreau79eeafa2012-09-14 07:53:05 +02005260 return ERR_ALERT | ERR_FATAL;
5261 }
5262
Emeric Brunc8e8d122012-10-02 18:42:10 +02005263 if ((*args[cur_arg + 1] != '/' ) && global.crt_base) {
Willy Tarreau38011032013-08-13 16:59:39 +02005264 if ((strlen(global.crt_base) + 1 + strlen(args[cur_arg + 1]) + 1) > MAXPATHLEN) {
Emeric Brunc8e8d122012-10-02 18:42:10 +02005265 memprintf(err, "'%s' : path too long", args[cur_arg]);
5266 return ERR_ALERT | ERR_FATAL;
5267 }
Willy Tarreaub75d6922014-04-14 18:05:41 +02005268 snprintf(path, sizeof(path), "%s/%s", global.crt_base, args[cur_arg + 1]);
Willy Tarreau03209342016-12-22 17:08:28 +01005269 if (ssl_sock_load_cert(path, conf, err) > 0)
Emeric Brunc8e8d122012-10-02 18:42:10 +02005270 return ERR_ALERT | ERR_FATAL;
5271
5272 return 0;
5273 }
5274
Willy Tarreau03209342016-12-22 17:08:28 +01005275 if (ssl_sock_load_cert(args[cur_arg + 1], conf, err) > 0)
Willy Tarreau79eeafa2012-09-14 07:53:05 +02005276 return ERR_ALERT | ERR_FATAL;
Emeric Brund94b3fe2012-09-20 18:23:56 +02005277
5278 return 0;
5279}
5280
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01005281/* parse the "crt-list" bind keyword */
5282static int bind_parse_crt_list(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
5283{
5284 if (!*args[cur_arg + 1]) {
5285 memprintf(err, "'%s' : missing certificate location", args[cur_arg]);
5286 return ERR_ALERT | ERR_FATAL;
5287 }
5288
Willy Tarreau03209342016-12-22 17:08:28 +01005289 if (ssl_sock_load_cert_list_file(args[cur_arg + 1], conf, err) > 0) {
Willy Tarreauad1731d2013-04-02 17:35:58 +02005290 memprintf(err, "'%s' : %s", args[cur_arg], *err);
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01005291 return ERR_ALERT | ERR_FATAL;
Willy Tarreauad1731d2013-04-02 17:35:58 +02005292 }
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01005293
5294 return 0;
5295}
5296
Emeric Brunfb510ea2012-10-05 12:00:26 +02005297/* parse the "crl-file" bind keyword */
5298static int bind_parse_crl_file(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
Emeric Brund94b3fe2012-09-20 18:23:56 +02005299{
Emeric Brun051cdab2012-10-02 19:25:50 +02005300#ifndef X509_V_FLAG_CRL_CHECK
5301 if (err)
5302 memprintf(err, "'%s' : library does not support CRL verify", args[cur_arg]);
5303 return ERR_ALERT | ERR_FATAL;
5304#else
Emeric Brund94b3fe2012-09-20 18:23:56 +02005305 if (!*args[cur_arg + 1]) {
5306 if (err)
5307 memprintf(err, "'%s' : missing CRLfile path", args[cur_arg]);
5308 return ERR_ALERT | ERR_FATAL;
5309 }
Emeric Brun2b58d042012-09-20 17:10:03 +02005310
Emeric Brunef42d922012-10-11 16:11:36 +02005311 if ((*args[cur_arg + 1] != '/') && global.ca_base)
5312 memprintf(&conf->crl_file, "%s/%s", global.ca_base, args[cur_arg + 1]);
5313 else
5314 memprintf(&conf->crl_file, "%s", args[cur_arg + 1]);
Emeric Brunc8e8d122012-10-02 18:42:10 +02005315
Emeric Brun2b58d042012-09-20 17:10:03 +02005316 return 0;
Emeric Brun051cdab2012-10-02 19:25:50 +02005317#endif
Emeric Brun2b58d042012-09-20 17:10:03 +02005318}
5319
Bertrand Jacquinff13c062016-11-13 16:37:11 +00005320/* parse the "ecdhe" bind keyword keyword */
Emeric Brun2b58d042012-09-20 17:10:03 +02005321static int bind_parse_ecdhe(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
5322{
5323#if OPENSSL_VERSION_NUMBER < 0x0090800fL
5324 if (err)
5325 memprintf(err, "'%s' : library does not support elliptic curve Diffie-Hellman (too old)", args[cur_arg]);
5326 return ERR_ALERT | ERR_FATAL;
5327#elif defined(OPENSSL_NO_ECDH)
5328 if (err)
5329 memprintf(err, "'%s' : library does not support elliptic curve Diffie-Hellman (disabled via OPENSSL_NO_ECDH)", args[cur_arg]);
5330 return ERR_ALERT | ERR_FATAL;
5331#else
5332 if (!*args[cur_arg + 1]) {
5333 if (err)
5334 memprintf(err, "'%s' : missing named curve", args[cur_arg]);
5335 return ERR_ALERT | ERR_FATAL;
5336 }
5337
5338 conf->ecdhe = strdup(args[cur_arg + 1]);
Willy Tarreau79eeafa2012-09-14 07:53:05 +02005339
5340 return 0;
Emeric Brun2b58d042012-09-20 17:10:03 +02005341#endif
Willy Tarreau79eeafa2012-09-14 07:53:05 +02005342}
5343
Bertrand Jacquinff13c062016-11-13 16:37:11 +00005344/* parse the "crt-ignore-err" and "ca-ignore-err" bind keywords */
Emeric Brun81c00f02012-09-21 14:31:21 +02005345static int bind_parse_ignore_err(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
5346{
5347 int code;
5348 char *p = args[cur_arg + 1];
5349 unsigned long long *ignerr = &conf->crt_ignerr;
5350
5351 if (!*p) {
5352 if (err)
5353 memprintf(err, "'%s' : missing error IDs list", args[cur_arg]);
5354 return ERR_ALERT | ERR_FATAL;
5355 }
5356
5357 if (strcmp(args[cur_arg], "ca-ignore-err") == 0)
5358 ignerr = &conf->ca_ignerr;
5359
5360 if (strcmp(p, "all") == 0) {
5361 *ignerr = ~0ULL;
5362 return 0;
5363 }
5364
5365 while (p) {
5366 code = atoi(p);
5367 if ((code <= 0) || (code > 63)) {
5368 if (err)
5369 memprintf(err, "'%s' : ID '%d' out of range (1..63) in error IDs list '%s'",
5370 args[cur_arg], code, args[cur_arg + 1]);
5371 return ERR_ALERT | ERR_FATAL;
5372 }
5373 *ignerr |= 1ULL << code;
5374 p = strchr(p, ',');
5375 if (p)
5376 p++;
5377 }
5378
Emeric Brun2cb7ae52012-10-05 14:14:21 +02005379 return 0;
5380}
5381
5382/* parse the "force-sslv3" bind keyword */
5383static int bind_parse_force_sslv3(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
5384{
5385 conf->ssl_options |= BC_SSL_O_USE_SSLV3;
5386 return 0;
5387}
5388
5389/* parse the "force-tlsv10" bind keyword */
5390static int bind_parse_force_tlsv10(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
5391{
5392 conf->ssl_options |= BC_SSL_O_USE_TLSV10;
Emeric Brun2d0c4822012-10-02 13:45:20 +02005393 return 0;
5394}
5395
Emeric Brun2cb7ae52012-10-05 14:14:21 +02005396/* parse the "force-tlsv11" bind keyword */
5397static int bind_parse_force_tlsv11(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
5398{
5399#if SSL_OP_NO_TLSv1_1
5400 conf->ssl_options |= BC_SSL_O_USE_TLSV11;
5401 return 0;
5402#else
5403 if (err)
5404 memprintf(err, "'%s' : library does not support protocol TLSv1.1", args[cur_arg]);
5405 return ERR_ALERT | ERR_FATAL;
5406#endif
5407}
5408
5409/* parse the "force-tlsv12" bind keyword */
5410static int bind_parse_force_tlsv12(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
5411{
5412#if SSL_OP_NO_TLSv1_2
5413 conf->ssl_options |= BC_SSL_O_USE_TLSV12;
5414 return 0;
5415#else
5416 if (err)
5417 memprintf(err, "'%s' : library does not support protocol TLSv1.2", args[cur_arg]);
5418 return ERR_ALERT | ERR_FATAL;
5419#endif
5420}
5421
5422
Emeric Brun2d0c4822012-10-02 13:45:20 +02005423/* parse the "no-tls-tickets" bind keyword */
5424static int bind_parse_no_tls_tickets(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
5425{
Emeric Brun89675492012-10-05 13:48:26 +02005426 conf->ssl_options |= BC_SSL_O_NO_TLS_TICKETS;
Emeric Brun81c00f02012-09-21 14:31:21 +02005427 return 0;
5428}
5429
Emeric Brun2d0c4822012-10-02 13:45:20 +02005430
Emeric Brun9b3009b2012-10-05 11:55:06 +02005431/* parse the "no-sslv3" bind keyword */
5432static int bind_parse_no_sslv3(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
Willy Tarreau79eeafa2012-09-14 07:53:05 +02005433{
Emeric Brun89675492012-10-05 13:48:26 +02005434 conf->ssl_options |= BC_SSL_O_NO_SSLV3;
Willy Tarreau79eeafa2012-09-14 07:53:05 +02005435 return 0;
5436}
5437
Emeric Brun9b3009b2012-10-05 11:55:06 +02005438/* parse the "no-tlsv10" bind keyword */
5439static int bind_parse_no_tlsv10(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
Emeric Brunc0ff4922012-09-28 19:37:02 +02005440{
Emeric Brun89675492012-10-05 13:48:26 +02005441 conf->ssl_options |= BC_SSL_O_NO_TLSV10;
Emeric Brunc0ff4922012-09-28 19:37:02 +02005442 return 0;
5443}
5444
Emeric Brun9b3009b2012-10-05 11:55:06 +02005445/* parse the "no-tlsv11" bind keyword */
5446static int bind_parse_no_tlsv11(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
Emeric Brunc0ff4922012-09-28 19:37:02 +02005447{
Emeric Brun89675492012-10-05 13:48:26 +02005448 conf->ssl_options |= BC_SSL_O_NO_TLSV11;
Emeric Brunc0ff4922012-09-28 19:37:02 +02005449 return 0;
5450}
5451
Emeric Brun9b3009b2012-10-05 11:55:06 +02005452/* parse the "no-tlsv12" bind keyword */
5453static int bind_parse_no_tlsv12(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
Willy Tarreau79eeafa2012-09-14 07:53:05 +02005454{
Emeric Brun89675492012-10-05 13:48:26 +02005455 conf->ssl_options |= BC_SSL_O_NO_TLSV12;
Willy Tarreau79eeafa2012-09-14 07:53:05 +02005456 return 0;
5457}
5458
Willy Tarreau6c9a3d52012-10-18 18:57:14 +02005459/* parse the "npn" bind keyword */
5460static int bind_parse_npn(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
5461{
5462#ifdef OPENSSL_NPN_NEGOTIATED
5463 char *p1, *p2;
5464
5465 if (!*args[cur_arg + 1]) {
5466 memprintf(err, "'%s' : missing the comma-delimited NPN protocol suite", args[cur_arg]);
5467 return ERR_ALERT | ERR_FATAL;
5468 }
5469
5470 free(conf->npn_str);
5471
Willy Tarreau3724da12016-02-12 17:11:12 +01005472 /* the NPN string is built as a suite of (<len> <name>)*,
5473 * so we reuse each comma to store the next <len> and need
5474 * one more for the end of the string.
5475 */
Willy Tarreau6c9a3d52012-10-18 18:57:14 +02005476 conf->npn_len = strlen(args[cur_arg + 1]) + 1;
Willy Tarreau3724da12016-02-12 17:11:12 +01005477 conf->npn_str = calloc(1, conf->npn_len + 1);
Willy Tarreau6c9a3d52012-10-18 18:57:14 +02005478 memcpy(conf->npn_str + 1, args[cur_arg + 1], conf->npn_len);
5479
5480 /* replace commas with the name length */
5481 p1 = conf->npn_str;
5482 p2 = p1 + 1;
5483 while (1) {
5484 p2 = memchr(p1 + 1, ',', conf->npn_str + conf->npn_len - (p1 + 1));
5485 if (!p2)
5486 p2 = p1 + 1 + strlen(p1 + 1);
5487
5488 if (p2 - (p1 + 1) > 255) {
5489 *p2 = '\0';
5490 memprintf(err, "'%s' : NPN protocol name too long : '%s'", args[cur_arg], p1 + 1);
5491 return ERR_ALERT | ERR_FATAL;
5492 }
5493
5494 *p1 = p2 - (p1 + 1);
5495 p1 = p2;
5496
5497 if (!*p2)
5498 break;
5499
5500 *(p2++) = '\0';
5501 }
5502 return 0;
5503#else
5504 if (err)
5505 memprintf(err, "'%s' : library does not support TLS NPN extension", args[cur_arg]);
5506 return ERR_ALERT | ERR_FATAL;
5507#endif
5508}
5509
Willy Tarreauab861d32013-04-02 02:30:41 +02005510/* parse the "alpn" bind keyword */
5511static int bind_parse_alpn(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
5512{
Dirkjan Bussink48f1c4e2014-02-13 12:29:42 +01005513#ifdef TLSEXT_TYPE_application_layer_protocol_negotiation
Willy Tarreauab861d32013-04-02 02:30:41 +02005514 char *p1, *p2;
5515
5516 if (!*args[cur_arg + 1]) {
5517 memprintf(err, "'%s' : missing the comma-delimited ALPN protocol suite", args[cur_arg]);
5518 return ERR_ALERT | ERR_FATAL;
5519 }
5520
5521 free(conf->alpn_str);
5522
Marcoen Hirschbergbef60912016-02-12 17:05:24 +01005523 /* the ALPN string is built as a suite of (<len> <name>)*,
5524 * so we reuse each comma to store the next <len> and need
5525 * one more for the end of the string.
5526 */
Willy Tarreauab861d32013-04-02 02:30:41 +02005527 conf->alpn_len = strlen(args[cur_arg + 1]) + 1;
Marcoen Hirschbergbef60912016-02-12 17:05:24 +01005528 conf->alpn_str = calloc(1, conf->alpn_len + 1);
Willy Tarreauab861d32013-04-02 02:30:41 +02005529 memcpy(conf->alpn_str + 1, args[cur_arg + 1], conf->alpn_len);
5530
5531 /* replace commas with the name length */
5532 p1 = conf->alpn_str;
5533 p2 = p1 + 1;
5534 while (1) {
5535 p2 = memchr(p1 + 1, ',', conf->alpn_str + conf->alpn_len - (p1 + 1));
5536 if (!p2)
5537 p2 = p1 + 1 + strlen(p1 + 1);
5538
5539 if (p2 - (p1 + 1) > 255) {
5540 *p2 = '\0';
5541 memprintf(err, "'%s' : ALPN protocol name too long : '%s'", args[cur_arg], p1 + 1);
5542 return ERR_ALERT | ERR_FATAL;
5543 }
5544
5545 *p1 = p2 - (p1 + 1);
5546 p1 = p2;
5547
5548 if (!*p2)
5549 break;
5550
5551 *(p2++) = '\0';
5552 }
5553 return 0;
5554#else
5555 if (err)
5556 memprintf(err, "'%s' : library does not support TLS ALPN extension", args[cur_arg]);
5557 return ERR_ALERT | ERR_FATAL;
5558#endif
5559}
5560
Willy Tarreau79eeafa2012-09-14 07:53:05 +02005561/* parse the "ssl" bind keyword */
Willy Tarreau4348fad2012-09-20 16:48:07 +02005562static 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 +02005563{
Willy Tarreau71a8c7c2016-12-21 22:04:54 +01005564 conf->xprt = &ssl_sock;
Willy Tarreau4348fad2012-09-20 16:48:07 +02005565 conf->is_ssl = 1;
Emeric Brun76d88952012-10-05 15:47:31 +02005566
5567 if (global.listen_default_ciphers && !conf->ciphers)
5568 conf->ciphers = strdup(global.listen_default_ciphers);
Emeric Brun2c86cbf2014-10-30 15:56:50 +01005569 conf->ssl_options |= global.listen_default_ssloptions;
Emeric Brun76d88952012-10-05 15:47:31 +02005570
Willy Tarreau79eeafa2012-09-14 07:53:05 +02005571 return 0;
5572}
5573
Christopher Faulet31af49d2015-06-09 17:29:50 +02005574/* parse the "generate-certificates" bind keyword */
5575static int bind_parse_generate_certs(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
5576{
5577#ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME
5578 conf->generate_certs = 1;
5579#else
5580 memprintf(err, "%sthis version of openssl cannot generate SSL certificates.\n",
5581 err && *err ? *err : "");
5582#endif
5583 return 0;
5584}
5585
Emmanuel Hocdet65623372013-01-24 17:17:15 +01005586/* parse the "strict-sni" bind keyword */
5587static int bind_parse_strict_sni(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
5588{
5589 conf->strict_sni = 1;
5590 return 0;
Nenad Merdanovic05552d42015-02-27 19:56:49 +01005591}
5592
5593/* parse the "tls-ticket-keys" bind keyword */
5594static int bind_parse_tls_ticket_keys(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
5595{
5596#if (defined SSL_CTRL_SET_TLSEXT_TICKET_KEY_CB && TLS_TICKETS_NO > 0)
5597 FILE *f;
5598 int i = 0;
5599 char thisline[LINESIZE];
Nenad Merdanovic146defa2015-05-09 08:46:00 +02005600 struct tls_keys_ref *keys_ref;
Nenad Merdanovic05552d42015-02-27 19:56:49 +01005601
5602 if (!*args[cur_arg + 1]) {
5603 if (err)
5604 memprintf(err, "'%s' : missing TLS ticket keys file path", args[cur_arg]);
5605 return ERR_ALERT | ERR_FATAL;
5606 }
5607
Nenad Merdanovic200b0fa2015-05-09 08:46:01 +02005608 keys_ref = tlskeys_ref_lookup(args[cur_arg + 1]);
5609 if(keys_ref) {
5610 conf->keys_ref = keys_ref;
5611 return 0;
5612 }
5613
Vincent Bernat02779b62016-04-03 13:48:43 +02005614 keys_ref = malloc(sizeof(*keys_ref));
Nenad Merdanovic146defa2015-05-09 08:46:00 +02005615 keys_ref->tlskeys = malloc(TLS_TICKETS_NO * sizeof(struct tls_sess_key));
Nenad Merdanovic05552d42015-02-27 19:56:49 +01005616
5617 if ((f = fopen(args[cur_arg + 1], "r")) == NULL) {
5618 if (err)
5619 memprintf(err, "'%s' : unable to load ssl tickets keys file", args[cur_arg+1]);
5620 return ERR_ALERT | ERR_FATAL;
5621 }
5622
Nenad Merdanovic146defa2015-05-09 08:46:00 +02005623 keys_ref->filename = strdup(args[cur_arg + 1]);
5624
Nenad Merdanovic05552d42015-02-27 19:56:49 +01005625 while (fgets(thisline, sizeof(thisline), f) != NULL) {
5626 int len = strlen(thisline);
5627 /* Strip newline characters from the end */
5628 if(thisline[len - 1] == '\n')
5629 thisline[--len] = 0;
5630
5631 if(thisline[len - 1] == '\r')
5632 thisline[--len] = 0;
5633
Nenad Merdanovic146defa2015-05-09 08:46:00 +02005634 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 +01005635 if (err)
5636 memprintf(err, "'%s' : unable to decode base64 key on line %d", args[cur_arg+1], i + 1);
mildis16aa0152016-06-22 17:46:29 +02005637 fclose(f);
Nenad Merdanovic05552d42015-02-27 19:56:49 +01005638 return ERR_ALERT | ERR_FATAL;
5639 }
5640 i++;
5641 }
5642
5643 if (i < TLS_TICKETS_NO) {
5644 if (err)
5645 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 +02005646 fclose(f);
Nenad Merdanovic05552d42015-02-27 19:56:49 +01005647 return ERR_ALERT | ERR_FATAL;
5648 }
5649
5650 fclose(f);
5651
5652 /* Use penultimate key for encryption, handle when TLS_TICKETS_NO = 1 */
Nenad Merdanovic17891152016-03-25 22:16:57 +01005653 i -= 2;
5654 keys_ref->tls_ticket_enc_index = i < 0 ? 0 : i % TLS_TICKETS_NO;
Nenad Merdanovic200b0fa2015-05-09 08:46:01 +02005655 keys_ref->unique_id = -1;
Nenad Merdanovic146defa2015-05-09 08:46:00 +02005656 conf->keys_ref = keys_ref;
Nenad Merdanovic05552d42015-02-27 19:56:49 +01005657
Nenad Merdanovic200b0fa2015-05-09 08:46:01 +02005658 LIST_ADD(&tlskeys_reference, &keys_ref->list);
5659
Nenad Merdanovic05552d42015-02-27 19:56:49 +01005660 return 0;
5661#else
5662 if (err)
5663 memprintf(err, "'%s' : TLS ticket callback extension not supported", args[cur_arg]);
5664 return ERR_ALERT | ERR_FATAL;
5665#endif /* SSL_CTRL_SET_TLSEXT_TICKET_KEY_CB */
Emmanuel Hocdet65623372013-01-24 17:17:15 +01005666}
5667
Emeric Brund94b3fe2012-09-20 18:23:56 +02005668/* parse the "verify" bind keyword */
5669static int bind_parse_verify(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
5670{
5671 if (!*args[cur_arg + 1]) {
5672 if (err)
5673 memprintf(err, "'%s' : missing verify method", args[cur_arg]);
5674 return ERR_ALERT | ERR_FATAL;
5675 }
5676
5677 if (strcmp(args[cur_arg + 1], "none") == 0)
Emeric Brun850efd52014-01-29 12:24:34 +01005678 conf->verify = SSL_SOCK_VERIFY_NONE;
Emeric Brund94b3fe2012-09-20 18:23:56 +02005679 else if (strcmp(args[cur_arg + 1], "optional") == 0)
Emeric Brun850efd52014-01-29 12:24:34 +01005680 conf->verify = SSL_SOCK_VERIFY_OPTIONAL;
Emeric Brund94b3fe2012-09-20 18:23:56 +02005681 else if (strcmp(args[cur_arg + 1], "required") == 0)
Emeric Brun850efd52014-01-29 12:24:34 +01005682 conf->verify = SSL_SOCK_VERIFY_REQUIRED;
Emeric Brund94b3fe2012-09-20 18:23:56 +02005683 else {
5684 if (err)
5685 memprintf(err, "'%s' : unknown verify method '%s', only 'none', 'optional', and 'required' are supported\n",
5686 args[cur_arg], args[cur_arg + 1]);
5687 return ERR_ALERT | ERR_FATAL;
5688 }
5689
5690 return 0;
5691}
5692
Willy Tarreau92faadf2012-10-10 23:04:25 +02005693/************** "server" keywords ****************/
5694
Emeric Brunef42d922012-10-11 16:11:36 +02005695/* parse the "ca-file" server keyword */
5696static int srv_parse_ca_file(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
5697{
5698 if (!*args[*cur_arg + 1]) {
5699 if (err)
5700 memprintf(err, "'%s' : missing CAfile path", args[*cur_arg]);
5701 return ERR_ALERT | ERR_FATAL;
5702 }
5703
5704 if ((*args[*cur_arg + 1] != '/') && global.ca_base)
5705 memprintf(&newsrv->ssl_ctx.ca_file, "%s/%s", global.ca_base, args[*cur_arg + 1]);
5706 else
5707 memprintf(&newsrv->ssl_ctx.ca_file, "%s", args[*cur_arg + 1]);
5708
5709 return 0;
5710}
5711
Willy Tarreau92faadf2012-10-10 23:04:25 +02005712/* parse the "check-ssl" server keyword */
5713static int srv_parse_check_ssl(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
5714{
5715 newsrv->check.use_ssl = 1;
5716 if (global.connect_default_ciphers && !newsrv->ssl_ctx.ciphers)
5717 newsrv->ssl_ctx.ciphers = strdup(global.connect_default_ciphers);
Emeric Brun2c86cbf2014-10-30 15:56:50 +01005718 newsrv->ssl_ctx.options |= global.connect_default_ssloptions;
Willy Tarreau92faadf2012-10-10 23:04:25 +02005719 return 0;
5720}
5721
5722/* parse the "ciphers" server keyword */
5723static int srv_parse_ciphers(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
5724{
5725 if (!*args[*cur_arg + 1]) {
5726 memprintf(err, "'%s' : missing cipher suite", args[*cur_arg]);
5727 return ERR_ALERT | ERR_FATAL;
5728 }
5729
5730 free(newsrv->ssl_ctx.ciphers);
5731 newsrv->ssl_ctx.ciphers = strdup(args[*cur_arg + 1]);
5732 return 0;
5733}
5734
Emeric Brunef42d922012-10-11 16:11:36 +02005735/* parse the "crl-file" server keyword */
5736static int srv_parse_crl_file(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
5737{
5738#ifndef X509_V_FLAG_CRL_CHECK
5739 if (err)
5740 memprintf(err, "'%s' : library does not support CRL verify", args[*cur_arg]);
5741 return ERR_ALERT | ERR_FATAL;
5742#else
5743 if (!*args[*cur_arg + 1]) {
5744 if (err)
5745 memprintf(err, "'%s' : missing CRLfile path", args[*cur_arg]);
5746 return ERR_ALERT | ERR_FATAL;
5747 }
5748
5749 if ((*args[*cur_arg + 1] != '/') && global.ca_base)
5750 memprintf(&newsrv->ssl_ctx.crl_file, "%s/%s", global.ca_base, args[*cur_arg + 1]);
5751 else
5752 memprintf(&newsrv->ssl_ctx.crl_file, "%s", args[*cur_arg + 1]);
5753
5754 return 0;
5755#endif
5756}
5757
Emeric Bruna7aa3092012-10-26 12:58:00 +02005758/* parse the "crt" server keyword */
5759static int srv_parse_crt(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
5760{
5761 if (!*args[*cur_arg + 1]) {
5762 if (err)
5763 memprintf(err, "'%s' : missing certificate file path", args[*cur_arg]);
5764 return ERR_ALERT | ERR_FATAL;
5765 }
5766
5767 if ((*args[*cur_arg + 1] != '/') && global.crt_base)
5768 memprintf(&newsrv->ssl_ctx.client_crt, "%s/%s", global.ca_base, args[*cur_arg + 1]);
5769 else
5770 memprintf(&newsrv->ssl_ctx.client_crt, "%s", args[*cur_arg + 1]);
5771
5772 return 0;
5773}
Emeric Brunef42d922012-10-11 16:11:36 +02005774
Willy Tarreau92faadf2012-10-10 23:04:25 +02005775/* parse the "force-sslv3" server keyword */
5776static int srv_parse_force_sslv3(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
5777{
5778 newsrv->ssl_ctx.options |= SRV_SSL_O_USE_SSLV3;
5779 return 0;
5780}
5781
5782/* parse the "force-tlsv10" server keyword */
5783static int srv_parse_force_tlsv10(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
5784{
5785 newsrv->ssl_ctx.options |= SRV_SSL_O_USE_TLSV10;
5786 return 0;
5787}
5788
5789/* parse the "force-tlsv11" server keyword */
5790static int srv_parse_force_tlsv11(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
5791{
5792#if SSL_OP_NO_TLSv1_1
5793 newsrv->ssl_ctx.options |= SRV_SSL_O_USE_TLSV11;
5794 return 0;
5795#else
5796 if (err)
5797 memprintf(err, "'%s' : library does not support protocol TLSv1.1", args[*cur_arg]);
5798 return ERR_ALERT | ERR_FATAL;
5799#endif
5800}
5801
5802/* parse the "force-tlsv12" server keyword */
5803static int srv_parse_force_tlsv12(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
5804{
5805#if SSL_OP_NO_TLSv1_2
5806 newsrv->ssl_ctx.options |= SRV_SSL_O_USE_TLSV12;
5807 return 0;
5808#else
5809 if (err)
5810 memprintf(err, "'%s' : library does not support protocol TLSv1.2", args[*cur_arg]);
5811 return ERR_ALERT | ERR_FATAL;
5812#endif
5813}
5814
Willy Tarreau2a3fb1c2015-02-05 16:47:07 +01005815/* parse the "no-ssl-reuse" server keyword */
5816static int srv_parse_no_ssl_reuse(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
5817{
5818 newsrv->ssl_ctx.options |= SRV_SSL_O_NO_REUSE;
5819 return 0;
5820}
5821
Willy Tarreau92faadf2012-10-10 23:04:25 +02005822/* parse the "no-sslv3" server keyword */
5823static int srv_parse_no_sslv3(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
5824{
5825 newsrv->ssl_ctx.options |= SRV_SSL_O_NO_SSLV3;
5826 return 0;
5827}
5828
5829/* parse the "no-tlsv10" server keyword */
5830static int srv_parse_no_tlsv10(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
5831{
5832 newsrv->ssl_ctx.options |= SRV_SSL_O_NO_TLSV10;
5833 return 0;
5834}
5835
5836/* parse the "no-tlsv11" server keyword */
5837static int srv_parse_no_tlsv11(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
5838{
5839 newsrv->ssl_ctx.options |= SRV_SSL_O_NO_TLSV11;
5840 return 0;
5841}
5842
5843/* parse the "no-tlsv12" server keyword */
5844static int srv_parse_no_tlsv12(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
5845{
5846 newsrv->ssl_ctx.options |= SRV_SSL_O_NO_TLSV12;
5847 return 0;
5848}
5849
Emeric Brunf9c5c472012-10-11 15:28:34 +02005850/* parse the "no-tls-tickets" server keyword */
5851static int srv_parse_no_tls_tickets(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
5852{
5853 newsrv->ssl_ctx.options |= SRV_SSL_O_NO_TLS_TICKETS;
5854 return 0;
5855}
David Safb76832014-05-08 23:42:08 -04005856/* parse the "send-proxy-v2-ssl" server keyword */
5857static int srv_parse_send_proxy_ssl(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
5858{
5859 newsrv->pp_opts |= SRV_PP_V2;
5860 newsrv->pp_opts |= SRV_PP_V2_SSL;
5861 return 0;
5862}
5863
5864/* parse the "send-proxy-v2-ssl-cn" server keyword */
5865static int srv_parse_send_proxy_cn(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
5866{
5867 newsrv->pp_opts |= SRV_PP_V2;
5868 newsrv->pp_opts |= SRV_PP_V2_SSL;
5869 newsrv->pp_opts |= SRV_PP_V2_SSL_CN;
5870 return 0;
5871}
Emeric Brunf9c5c472012-10-11 15:28:34 +02005872
Willy Tarreau732eac42015-07-09 11:40:25 +02005873/* parse the "sni" server keyword */
5874static int srv_parse_sni(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
5875{
5876#ifndef SSL_CTRL_SET_TLSEXT_HOSTNAME
5877 memprintf(err, "'%s' : the current SSL library doesn't support the SNI TLS extension", args[*cur_arg]);
5878 return ERR_ALERT | ERR_FATAL;
5879#else
Cyril Bonté23d19d62016-03-07 22:13:22 +01005880 int idx;
Willy Tarreau732eac42015-07-09 11:40:25 +02005881 struct sample_expr *expr;
5882
5883 if (!*args[*cur_arg + 1]) {
5884 memprintf(err, "'%s' : missing sni expression", args[*cur_arg]);
5885 return ERR_ALERT | ERR_FATAL;
5886 }
5887
Cyril Bonté23d19d62016-03-07 22:13:22 +01005888 idx = (*cur_arg) + 1;
Willy Tarreau732eac42015-07-09 11:40:25 +02005889 proxy->conf.args.ctx = ARGC_SRV;
5890
Cyril Bonté23d19d62016-03-07 22:13:22 +01005891 expr = sample_parse_expr((char **)args, &idx, px->conf.file, px->conf.line, err, &proxy->conf.args);
Willy Tarreau732eac42015-07-09 11:40:25 +02005892 if (!expr) {
5893 memprintf(err, "error detected while parsing sni expression : %s", *err);
5894 return ERR_ALERT | ERR_FATAL;
5895 }
5896
5897 if (!(expr->fetch->val & SMP_VAL_BE_SRV_CON)) {
5898 memprintf(err, "error detected while parsing sni expression : "
5899 " fetch method '%s' extracts information from '%s', none of which is available here.\n",
Cyril Bonté23d19d62016-03-07 22:13:22 +01005900 args[idx-1], sample_src_names(expr->fetch->use));
Willy Tarreau732eac42015-07-09 11:40:25 +02005901 return ERR_ALERT | ERR_FATAL;
5902 }
5903
5904 px->http_needed |= !!(expr->fetch->use & SMP_USE_HTTP_ANY);
5905 newsrv->ssl_ctx.sni = expr;
5906 return 0;
5907#endif
5908}
5909
Willy Tarreau92faadf2012-10-10 23:04:25 +02005910/* parse the "ssl" server keyword */
5911static int srv_parse_ssl(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
5912{
5913 newsrv->use_ssl = 1;
5914 if (global.connect_default_ciphers && !newsrv->ssl_ctx.ciphers)
5915 newsrv->ssl_ctx.ciphers = strdup(global.connect_default_ciphers);
5916 return 0;
5917}
5918
Emeric Brunef42d922012-10-11 16:11:36 +02005919/* parse the "verify" server keyword */
5920static int srv_parse_verify(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
5921{
5922 if (!*args[*cur_arg + 1]) {
5923 if (err)
5924 memprintf(err, "'%s' : missing verify method", args[*cur_arg]);
5925 return ERR_ALERT | ERR_FATAL;
5926 }
5927
5928 if (strcmp(args[*cur_arg + 1], "none") == 0)
Emeric Brun850efd52014-01-29 12:24:34 +01005929 newsrv->ssl_ctx.verify = SSL_SOCK_VERIFY_NONE;
Emeric Brunef42d922012-10-11 16:11:36 +02005930 else if (strcmp(args[*cur_arg + 1], "required") == 0)
Emeric Brun850efd52014-01-29 12:24:34 +01005931 newsrv->ssl_ctx.verify = SSL_SOCK_VERIFY_REQUIRED;
Emeric Brunef42d922012-10-11 16:11:36 +02005932 else {
5933 if (err)
5934 memprintf(err, "'%s' : unknown verify method '%s', only 'none' and 'required' are supported\n",
5935 args[*cur_arg], args[*cur_arg + 1]);
5936 return ERR_ALERT | ERR_FATAL;
5937 }
5938
Evan Broderbe554312013-06-27 00:05:25 -07005939 return 0;
5940}
5941
5942/* parse the "verifyhost" server keyword */
5943static int srv_parse_verifyhost(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
5944{
5945 if (!*args[*cur_arg + 1]) {
5946 if (err)
5947 memprintf(err, "'%s' : missing hostname to verify against", args[*cur_arg]);
5948 return ERR_ALERT | ERR_FATAL;
5949 }
5950
5951 newsrv->ssl_ctx.verify_host = strdup(args[*cur_arg + 1]);
5952
Emeric Brunef42d922012-10-11 16:11:36 +02005953 return 0;
5954}
5955
Emeric Brun2c86cbf2014-10-30 15:56:50 +01005956/* parse the "ssl-default-bind-options" keyword in global section */
5957static int ssl_parse_default_bind_options(char **args, int section_type, struct proxy *curpx,
5958 struct proxy *defpx, const char *file, int line,
5959 char **err) {
5960 int i = 1;
5961
5962 if (*(args[i]) == 0) {
5963 memprintf(err, "global statement '%s' expects an option as an argument.", args[0]);
5964 return -1;
5965 }
5966 while (*(args[i])) {
5967 if (!strcmp(args[i], "no-sslv3"))
5968 global.listen_default_ssloptions |= BC_SSL_O_NO_SSLV3;
5969 else if (!strcmp(args[i], "no-tlsv10"))
5970 global.listen_default_ssloptions |= BC_SSL_O_NO_TLSV10;
5971 else if (!strcmp(args[i], "no-tlsv11"))
5972 global.listen_default_ssloptions |= BC_SSL_O_NO_TLSV11;
5973 else if (!strcmp(args[i], "no-tlsv12"))
5974 global.listen_default_ssloptions |= BC_SSL_O_NO_TLSV12;
5975 else if (!strcmp(args[i], "force-sslv3"))
5976 global.listen_default_ssloptions |= BC_SSL_O_USE_SSLV3;
5977 else if (!strcmp(args[i], "force-tlsv10"))
5978 global.listen_default_ssloptions |= BC_SSL_O_USE_TLSV10;
5979 else if (!strcmp(args[i], "force-tlsv11")) {
5980#if SSL_OP_NO_TLSv1_1
5981 global.listen_default_ssloptions |= BC_SSL_O_USE_TLSV11;
5982#else
5983 memprintf(err, "'%s' '%s': library does not support protocol TLSv1.1", args[0], args[i]);
5984 return -1;
5985#endif
5986 }
5987 else if (!strcmp(args[i], "force-tlsv12")) {
5988#if SSL_OP_NO_TLSv1_2
5989 global.listen_default_ssloptions |= BC_SSL_O_USE_TLSV12;
5990#else
5991 memprintf(err, "'%s' '%s': library does not support protocol TLSv1.2", args[0], args[i]);
5992 return -1;
5993#endif
5994 }
5995 else if (!strcmp(args[i], "no-tls-tickets"))
5996 global.listen_default_ssloptions |= BC_SSL_O_NO_TLS_TICKETS;
5997 else {
5998 memprintf(err, "unknown option '%s' on global statement '%s'.", args[i], args[0]);
5999 return -1;
6000 }
6001 i++;
6002 }
6003 return 0;
6004}
6005
6006/* parse the "ssl-default-server-options" keyword in global section */
6007static int ssl_parse_default_server_options(char **args, int section_type, struct proxy *curpx,
6008 struct proxy *defpx, const char *file, int line,
6009 char **err) {
6010 int i = 1;
6011
6012 if (*(args[i]) == 0) {
6013 memprintf(err, "global statement '%s' expects an option as an argument.", args[0]);
6014 return -1;
6015 }
6016 while (*(args[i])) {
6017 if (!strcmp(args[i], "no-sslv3"))
6018 global.connect_default_ssloptions |= SRV_SSL_O_NO_SSLV3;
6019 else if (!strcmp(args[i], "no-tlsv10"))
6020 global.connect_default_ssloptions |= SRV_SSL_O_NO_TLSV10;
6021 else if (!strcmp(args[i], "no-tlsv11"))
6022 global.connect_default_ssloptions |= SRV_SSL_O_NO_TLSV11;
6023 else if (!strcmp(args[i], "no-tlsv12"))
6024 global.connect_default_ssloptions |= SRV_SSL_O_NO_TLSV12;
6025 else if (!strcmp(args[i], "force-sslv3"))
6026 global.connect_default_ssloptions |= SRV_SSL_O_USE_SSLV3;
6027 else if (!strcmp(args[i], "force-tlsv10"))
6028 global.connect_default_ssloptions |= SRV_SSL_O_USE_TLSV10;
6029 else if (!strcmp(args[i], "force-tlsv11")) {
6030#if SSL_OP_NO_TLSv1_1
6031 global.connect_default_ssloptions |= SRV_SSL_O_USE_TLSV11;
6032#else
6033 memprintf(err, "'%s' '%s': library does not support protocol TLSv1.1", args[0], args[i]);
6034 return -1;
6035#endif
6036 }
6037 else if (!strcmp(args[i], "force-tlsv12")) {
6038#if SSL_OP_NO_TLSv1_2
6039 global.connect_default_ssloptions |= SRV_SSL_O_USE_TLSV12;
6040#else
6041 memprintf(err, "'%s' '%s': library does not support protocol TLSv1.2", args[0], args[i]);
6042 return -1;
6043#endif
6044 }
6045 else if (!strcmp(args[i], "no-tls-tickets"))
6046 global.connect_default_ssloptions |= SRV_SSL_O_NO_TLS_TICKETS;
6047 else {
6048 memprintf(err, "unknown option '%s' on global statement '%s'.", args[i], args[0]);
6049 return -1;
6050 }
6051 i++;
6052 }
6053 return 0;
6054}
6055
Willy Tarreau8c3b0fd2016-12-21 22:44:46 +01006056/* parse the "ca-base" / "crt-base" keywords in global section.
6057 * Returns <0 on alert, >0 on warning, 0 on success.
6058 */
6059static int ssl_parse_global_ca_crt_base(char **args, int section_type, struct proxy *curpx,
6060 struct proxy *defpx, const char *file, int line,
6061 char **err)
6062{
6063 char **target;
6064
6065 target = (args[0][1] == 'a') ? &global.ca_base : &global.crt_base;
6066
6067 if (too_many_args(1, args, err, NULL))
6068 return -1;
6069
6070 if (*target) {
6071 memprintf(err, "'%s' already specified.", args[0]);
6072 return -1;
6073 }
6074
6075 if (*(args[1]) == 0) {
6076 memprintf(err, "global statement '%s' expects a directory path as an argument.", args[0]);
6077 return -1;
6078 }
6079 *target = strdup(args[1]);
6080 return 0;
6081}
6082
Willy Tarreauf22e9682016-12-21 23:23:19 +01006083/* parse the "ssl-default-bind-ciphers" / "ssl-default-server-ciphers" keywords
6084 * in global section. Returns <0 on alert, >0 on warning, 0 on success.
6085 */
6086static int ssl_parse_global_ciphers(char **args, int section_type, struct proxy *curpx,
6087 struct proxy *defpx, const char *file, int line,
6088 char **err)
6089{
6090 char **target;
6091
6092 target = (args[0][12] == 'b') ? &global.listen_default_ciphers : &global.connect_default_ciphers;
6093
6094 if (too_many_args(1, args, err, NULL))
6095 return -1;
6096
6097 if (*(args[1]) == 0) {
6098 memprintf(err, "global statement '%s' expects a cipher suite as an argument.", args[0]);
6099 return -1;
6100 }
6101
6102 free(*target);
6103 *target = strdup(args[1]);
6104 return 0;
6105}
6106
Willy Tarreau9ceda382016-12-21 23:13:03 +01006107/* parse various global tune.ssl settings consisting in positive integers.
6108 * Returns <0 on alert, >0 on warning, 0 on success.
6109 */
6110static int ssl_parse_global_int(char **args, int section_type, struct proxy *curpx,
6111 struct proxy *defpx, const char *file, int line,
6112 char **err)
6113{
6114 int *target;
6115
6116 if (strcmp(args[0], "tune.ssl.cachesize") == 0)
6117 target = &global.tune.sslcachesize;
6118 else if (strcmp(args[0], "tune.ssl.maxrecord") == 0)
6119 target = (int *)&global.tune.ssl_max_record;
6120 else if (strcmp(args[0], "tune.ssl.ssl-ctx-cache-size") == 0)
6121 target = &global.tune.ssl_ctx_cache;
Willy Tarreau0bea58d2016-12-21 23:17:25 +01006122 else if (strcmp(args[0], "maxsslconn") == 0)
6123 target = &global.maxsslconn;
Willy Tarreau9ceda382016-12-21 23:13:03 +01006124 else {
6125 memprintf(err, "'%s' keyword not unhandled (please report this bug).", args[0]);
6126 return -1;
6127 }
6128
6129 if (too_many_args(1, args, err, NULL))
6130 return -1;
6131
6132 if (*(args[1]) == 0) {
6133 memprintf(err, "'%s' expects an integer argument.", args[0]);
6134 return -1;
6135 }
6136
6137 *target = atoi(args[1]);
6138 if (*target < 0) {
6139 memprintf(err, "'%s' expects a positive numeric value.", args[0]);
6140 return -1;
6141 }
6142 return 0;
6143}
6144
6145/* parse "ssl.force-private-cache".
6146 * Returns <0 on alert, >0 on warning, 0 on success.
6147 */
6148static int ssl_parse_global_private_cache(char **args, int section_type, struct proxy *curpx,
6149 struct proxy *defpx, const char *file, int line,
6150 char **err)
6151{
6152 if (too_many_args(0, args, err, NULL))
6153 return -1;
6154
6155 global.tune.sslprivatecache = 1;
6156 return 0;
6157}
6158
6159/* parse "ssl.lifetime".
6160 * Returns <0 on alert, >0 on warning, 0 on success.
6161 */
6162static int ssl_parse_global_lifetime(char **args, int section_type, struct proxy *curpx,
6163 struct proxy *defpx, const char *file, int line,
6164 char **err)
6165{
6166 const char *res;
6167
6168 if (too_many_args(1, args, err, NULL))
6169 return -1;
6170
6171 if (*(args[1]) == 0) {
6172 memprintf(err, "'%s' expects ssl sessions <lifetime> in seconds as argument.", args[0]);
6173 return -1;
6174 }
6175
6176 res = parse_time_err(args[1], &global.tune.ssllifetime, TIME_UNIT_S);
6177 if (res) {
6178 memprintf(err, "unexpected character '%c' in argument to <%s>.", *res, args[0]);
6179 return -1;
6180 }
6181 return 0;
6182}
6183
6184#ifndef OPENSSL_NO_DH
Willy Tarreau14e36a12016-12-21 23:28:13 +01006185/* parse "ssl-dh-param-file".
6186 * Returns <0 on alert, >0 on warning, 0 on success.
6187 */
6188static int ssl_parse_global_dh_param_file(char **args, int section_type, struct proxy *curpx,
6189 struct proxy *defpx, const char *file, int line,
6190 char **err)
6191{
6192 if (too_many_args(1, args, err, NULL))
6193 return -1;
6194
6195 if (*(args[1]) == 0) {
6196 memprintf(err, "'%s' expects a file path as an argument.", args[0]);
6197 return -1;
6198 }
6199
6200 if (ssl_sock_load_global_dh_param_from_file(args[1])) {
6201 memprintf(err, "'%s': unable to load DH parameters from file <%s>.", args[0], args[1]);
6202 return -1;
6203 }
6204 return 0;
6205}
6206
Willy Tarreau9ceda382016-12-21 23:13:03 +01006207/* parse "ssl.default-dh-param".
6208 * Returns <0 on alert, >0 on warning, 0 on success.
6209 */
6210static int ssl_parse_global_default_dh(char **args, int section_type, struct proxy *curpx,
6211 struct proxy *defpx, const char *file, int line,
6212 char **err)
6213{
6214 if (too_many_args(1, args, err, NULL))
6215 return -1;
6216
6217 if (*(args[1]) == 0) {
6218 memprintf(err, "'%s' expects an integer argument.", args[0]);
6219 return -1;
6220 }
6221
6222 global.tune.ssl_default_dh_param = atoi(args[1]);
6223 if (global.tune.ssl_default_dh_param < 1024) {
6224 memprintf(err, "'%s' expects a value >= 1024.", args[0]);
6225 return -1;
6226 }
6227 return 0;
6228}
6229#endif
6230
6231
William Lallemand32af2032016-10-29 18:09:35 +02006232/* This function is used with TLS ticket keys management. It permits to browse
6233 * each reference. The variable <getnext> must contain the current node,
6234 * <end> point to the root node.
6235 */
6236#if (defined SSL_CTRL_SET_TLSEXT_TICKET_KEY_CB && TLS_TICKETS_NO > 0)
6237static inline
6238struct tls_keys_ref *tlskeys_list_get_next(struct tls_keys_ref *getnext, struct list *end)
6239{
6240 struct tls_keys_ref *ref = getnext;
6241
6242 while (1) {
6243
6244 /* Get next list entry. */
6245 ref = LIST_NEXT(&ref->list, struct tls_keys_ref *, list);
6246
6247 /* If the entry is the last of the list, return NULL. */
6248 if (&ref->list == end)
6249 return NULL;
6250
6251 return ref;
6252 }
6253}
6254
6255static inline
6256struct tls_keys_ref *tlskeys_ref_lookup_ref(const char *reference)
6257{
6258 int id;
6259 char *error;
6260
6261 /* If the reference starts by a '#', this is numeric id. */
6262 if (reference[0] == '#') {
6263 /* Try to convert the numeric id. If the conversion fails, the lookup fails. */
6264 id = strtol(reference + 1, &error, 10);
6265 if (*error != '\0')
6266 return NULL;
6267
6268 /* Perform the unique id lookup. */
6269 return tlskeys_ref_lookupid(id);
6270 }
6271
6272 /* Perform the string lookup. */
6273 return tlskeys_ref_lookup(reference);
6274}
6275#endif
6276
6277
6278#if (defined SSL_CTRL_SET_TLSEXT_TICKET_KEY_CB && TLS_TICKETS_NO > 0)
6279
6280static int cli_io_handler_tlskeys_files(struct appctx *appctx);
6281
6282static inline int cli_io_handler_tlskeys_entries(struct appctx *appctx) {
6283 return cli_io_handler_tlskeys_files(appctx);
6284}
6285
Willy Tarreauf5f26e82016-12-16 18:47:27 +01006286/* dumps all tls keys. Relies on cli.i0 (non-null = only list file names), cli.i1
6287 * (next index to be dumped), and cli.p0 (next key reference).
6288 */
William Lallemand32af2032016-10-29 18:09:35 +02006289static int cli_io_handler_tlskeys_files(struct appctx *appctx) {
6290
6291 struct stream_interface *si = appctx->owner;
6292
6293 switch (appctx->st2) {
6294 case STAT_ST_INIT:
6295 /* Display the column headers. If the message cannot be sent,
6296 * quit the fucntion with returning 0. The function is called
6297 * later and restart at the state "STAT_ST_INIT".
6298 */
6299 chunk_reset(&trash);
6300
6301 if (appctx->io_handler == cli_io_handler_tlskeys_entries)
6302 chunk_appendf(&trash, "# id secret\n");
6303 else
6304 chunk_appendf(&trash, "# id (file)\n");
6305
6306 if (bi_putchk(si_ic(si), &trash) == -1) {
6307 si_applet_cant_put(si);
6308 return 0;
6309 }
6310
William Lallemand32af2032016-10-29 18:09:35 +02006311 /* Now, we start the browsing of the references lists.
6312 * Note that the following call to LIST_ELEM return bad pointer. The only
6313 * available field of this pointer is <list>. It is used with the function
6314 * tlskeys_list_get_next() for retruning the first available entry
6315 */
Willy Tarreauf5f26e82016-12-16 18:47:27 +01006316 if (appctx->ctx.cli.p0 == NULL) {
6317 appctx->ctx.cli.p0 = LIST_ELEM(&tlskeys_reference, struct tls_keys_ref *, list);
6318 appctx->ctx.cli.p0 = tlskeys_list_get_next(appctx->ctx.cli.p0, &tlskeys_reference);
William Lallemand32af2032016-10-29 18:09:35 +02006319 }
6320
6321 appctx->st2 = STAT_ST_LIST;
6322 /* fall through */
6323
6324 case STAT_ST_LIST:
Willy Tarreauf5f26e82016-12-16 18:47:27 +01006325 while (appctx->ctx.cli.p0) {
6326 struct tls_keys_ref *ref = appctx->ctx.cli.p0;
6327 int head = ref->tls_ticket_enc_index;
William Lallemand32af2032016-10-29 18:09:35 +02006328
6329 chunk_reset(&trash);
Willy Tarreauf5f26e82016-12-16 18:47:27 +01006330 if (appctx->io_handler == cli_io_handler_tlskeys_entries && appctx->ctx.cli.i1 == 0)
William Lallemand32af2032016-10-29 18:09:35 +02006331 chunk_appendf(&trash, "# ");
Willy Tarreauf5f26e82016-12-16 18:47:27 +01006332
6333 if (appctx->ctx.cli.i1 == 0)
6334 chunk_appendf(&trash, "%d (%s)\n", ref->unique_id, ref->filename);
6335
William Lallemand32af2032016-10-29 18:09:35 +02006336 if (appctx->io_handler == cli_io_handler_tlskeys_entries) {
Willy Tarreauf5f26e82016-12-16 18:47:27 +01006337 while (appctx->ctx.cli.i1 < TLS_TICKETS_NO) {
William Lallemand32af2032016-10-29 18:09:35 +02006338 struct chunk *t2 = get_trash_chunk();
6339
6340 chunk_reset(t2);
6341 /* should never fail here because we dump only a key in the t2 buffer */
Willy Tarreauf5f26e82016-12-16 18:47:27 +01006342 t2->len = a2base64((char *)(ref->tlskeys + (head + 2 + appctx->ctx.cli.i1) % TLS_TICKETS_NO),
William Lallemand32af2032016-10-29 18:09:35 +02006343 sizeof(struct tls_sess_key), t2->str, t2->size);
Willy Tarreauf5f26e82016-12-16 18:47:27 +01006344 chunk_appendf(&trash, "%d.%d %s\n", ref->unique_id, appctx->ctx.cli.i1, t2->str);
William Lallemand32af2032016-10-29 18:09:35 +02006345
6346 if (bi_putchk(si_ic(si), &trash) == -1) {
6347 /* let's try again later from this stream. We add ourselves into
6348 * this stream's users so that it can remove us upon termination.
6349 */
6350 si_applet_cant_put(si);
6351 return 0;
6352 }
Willy Tarreauf5f26e82016-12-16 18:47:27 +01006353 appctx->ctx.cli.i1++;
William Lallemand32af2032016-10-29 18:09:35 +02006354 }
Willy Tarreauf5f26e82016-12-16 18:47:27 +01006355 appctx->ctx.cli.i1 = 0;
William Lallemand32af2032016-10-29 18:09:35 +02006356 }
6357 if (bi_putchk(si_ic(si), &trash) == -1) {
6358 /* let's try again later from this stream. We add ourselves into
6359 * this stream's users so that it can remove us upon termination.
6360 */
6361 si_applet_cant_put(si);
6362 return 0;
6363 }
6364
Willy Tarreauf5f26e82016-12-16 18:47:27 +01006365 if (appctx->ctx.cli.i0 == 0) /* don't display everything if not necessary */
William Lallemand32af2032016-10-29 18:09:35 +02006366 break;
6367
6368 /* get next list entry and check the end of the list */
Willy Tarreauf5f26e82016-12-16 18:47:27 +01006369 appctx->ctx.cli.p0 = tlskeys_list_get_next(appctx->ctx.cli.p0, &tlskeys_reference);
William Lallemand32af2032016-10-29 18:09:35 +02006370 }
6371
6372 appctx->st2 = STAT_ST_FIN;
6373 /* fall through */
6374
6375 default:
6376 appctx->st2 = STAT_ST_FIN;
6377 return 1;
6378 }
6379 return 0;
6380}
6381
6382#endif
6383
Willy Tarreauf5f26e82016-12-16 18:47:27 +01006384/* sets cli.i0 to non-zero if only file lists should be dumped */
William Lallemand32af2032016-10-29 18:09:35 +02006385static int cli_parse_show_tlskeys(char **args, struct appctx *appctx, void *private)
6386{
William Lallemand32af2032016-10-29 18:09:35 +02006387 /* no parameter, shows only file list */
6388 if (!*args[2]) {
Willy Tarreauf5f26e82016-12-16 18:47:27 +01006389 appctx->ctx.cli.i0 = 1;
William Lallemand32af2032016-10-29 18:09:35 +02006390 appctx->io_handler = cli_io_handler_tlskeys_files;
Willy Tarreau3067bfa2016-12-05 14:50:15 +01006391 return 0;
William Lallemand32af2032016-10-29 18:09:35 +02006392 }
6393
6394 if (args[2][0] == '*') {
6395 /* list every TLS ticket keys */
Willy Tarreauf5f26e82016-12-16 18:47:27 +01006396 appctx->ctx.cli.i0 = 1;
William Lallemand32af2032016-10-29 18:09:35 +02006397 } else {
Willy Tarreauf5f26e82016-12-16 18:47:27 +01006398 appctx->ctx.cli.p0 = tlskeys_ref_lookup_ref(args[2]);
6399 if (!appctx->ctx.cli.p0) {
William Lallemand32af2032016-10-29 18:09:35 +02006400 appctx->ctx.cli.msg = "'show tls-keys' unable to locate referenced filename\n";
Willy Tarreau3b6e5472016-11-24 15:53:53 +01006401 appctx->st0 = CLI_ST_PRINT;
William Lallemand32af2032016-10-29 18:09:35 +02006402 return 1;
6403 }
6404 }
William Lallemand32af2032016-10-29 18:09:35 +02006405 appctx->io_handler = cli_io_handler_tlskeys_entries;
Willy Tarreau3067bfa2016-12-05 14:50:15 +01006406 return 0;
William Lallemand32af2032016-10-29 18:09:35 +02006407}
6408
6409
6410static int cli_parse_set_tlskeys(char **args, struct appctx *appctx, void *private)
6411{
Willy Tarreauf5f26e82016-12-16 18:47:27 +01006412 struct tls_keys_ref *ref;
6413
William Lallemand32af2032016-10-29 18:09:35 +02006414 /* Expect two parameters: the filename and the new new TLS key in encoding */
6415 if (!*args[3] || !*args[4]) {
6416 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 +01006417 appctx->st0 = CLI_ST_PRINT;
William Lallemand32af2032016-10-29 18:09:35 +02006418 return 1;
6419 }
6420
Willy Tarreauf5f26e82016-12-16 18:47:27 +01006421 ref = tlskeys_ref_lookup_ref(args[3]);
6422 if (!ref) {
William Lallemand32af2032016-10-29 18:09:35 +02006423 appctx->ctx.cli.msg = "'set ssl tls-key' unable to locate referenced filename\n";
Willy Tarreau3b6e5472016-11-24 15:53:53 +01006424 appctx->st0 = CLI_ST_PRINT;
William Lallemand32af2032016-10-29 18:09:35 +02006425 return 1;
6426 }
6427
6428 trash.len = base64dec(args[4], strlen(args[4]), trash.str, trash.size);
6429 if (trash.len != sizeof(struct tls_sess_key)) {
6430 appctx->ctx.cli.msg = "'set ssl tls-key' received invalid base64 encoded TLS key.\n";
Willy Tarreau3b6e5472016-11-24 15:53:53 +01006431 appctx->st0 = CLI_ST_PRINT;
William Lallemand32af2032016-10-29 18:09:35 +02006432 return 1;
6433 }
6434
Willy Tarreauf5f26e82016-12-16 18:47:27 +01006435 memcpy(ref->tlskeys + ((ref->tls_ticket_enc_index + 2) % TLS_TICKETS_NO), trash.str, trash.len);
6436 ref->tls_ticket_enc_index = (ref->tls_ticket_enc_index + 1) % TLS_TICKETS_NO;
William Lallemand32af2032016-10-29 18:09:35 +02006437
6438 appctx->ctx.cli.msg = "TLS ticket key updated!";
Willy Tarreau3b6e5472016-11-24 15:53:53 +01006439 appctx->st0 = CLI_ST_PRINT;
William Lallemand32af2032016-10-29 18:09:35 +02006440 return 1;
6441
6442}
6443
6444static int cli_parse_set_ocspresponse(char **args, struct appctx *appctx, void *private)
6445{
6446#if (defined SSL_CTRL_SET_TLSEXT_STATUS_REQ_CB && !defined OPENSSL_NO_OCSP)
6447 char *err = NULL;
6448
6449 /* Expect one parameter: the new response in base64 encoding */
6450 if (!*args[3]) {
6451 appctx->ctx.cli.msg = "'set ssl ocsp-response' expects response in base64 encoding.\n";
Willy Tarreau3b6e5472016-11-24 15:53:53 +01006452 appctx->st0 = CLI_ST_PRINT;
William Lallemand32af2032016-10-29 18:09:35 +02006453 return 1;
6454 }
6455
6456 trash.len = base64dec(args[3], strlen(args[3]), trash.str, trash.size);
6457 if (trash.len < 0) {
6458 appctx->ctx.cli.msg = "'set ssl ocsp-response' received invalid base64 encoded response.\n";
Willy Tarreau3b6e5472016-11-24 15:53:53 +01006459 appctx->st0 = CLI_ST_PRINT;
William Lallemand32af2032016-10-29 18:09:35 +02006460 return 1;
6461 }
6462
6463 if (ssl_sock_update_ocsp_response(&trash, &err)) {
6464 if (err) {
6465 memprintf(&err, "%s.\n", err);
6466 appctx->ctx.cli.err = err;
Willy Tarreau3b6e5472016-11-24 15:53:53 +01006467 appctx->st0 = CLI_ST_PRINT_FREE;
William Lallemand32af2032016-10-29 18:09:35 +02006468 }
6469 return 1;
6470 }
6471 appctx->ctx.cli.msg = "OCSP Response updated!";
Willy Tarreau3b6e5472016-11-24 15:53:53 +01006472 appctx->st0 = CLI_ST_PRINT;
William Lallemand32af2032016-10-29 18:09:35 +02006473 return 1;
6474#else
6475 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 +01006476 appctx->st0 = CLI_ST_PRINT;
William Lallemand32af2032016-10-29 18:09:35 +02006477 return 1;
6478#endif
6479
6480}
6481
6482/* register cli keywords */
6483static struct cli_kw_list cli_kws = {{ },{
6484#if (defined SSL_CTRL_SET_TLSEXT_TICKET_KEY_CB && TLS_TICKETS_NO > 0)
6485 { { "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 },
6486 { { "set", "ssl", "tls-keys", NULL }, NULL, cli_parse_set_tlskeys, NULL },
6487 { { "set", "ssl", "ocsp-response", NULL }, NULL, cli_parse_set_ocspresponse, NULL },
6488#endif
6489 { { NULL }, NULL, NULL, NULL }
6490}};
6491
6492
6493
Willy Tarreau7875d092012-09-10 08:20:03 +02006494/* Note: must not be declared <const> as its list will be overwritten.
6495 * Please take care of keeping this list alphabetically sorted.
6496 */
Willy Tarreaudc13c112013-06-21 23:16:39 +02006497static struct sample_fetch_kw_list sample_fetch_keywords = {ILH, {
Emeric Brun645ae792014-04-30 14:21:06 +02006498 { "ssl_bc", smp_fetch_ssl_fc, 0, NULL, SMP_T_BOOL, SMP_USE_L5SRV },
Thierry FOURNIER07ee64e2015-07-06 23:43:03 +02006499 { "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 +02006500 { "ssl_bc_cipher", smp_fetch_ssl_fc_cipher, 0, NULL, SMP_T_STR, SMP_USE_L5SRV },
6501 { "ssl_bc_protocol", smp_fetch_ssl_fc_protocol, 0, NULL, SMP_T_STR, SMP_USE_L5SRV },
Emeric Brunb73a9b02014-04-30 18:49:19 +02006502 { "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 +02006503 { "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 +02006504 { "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 +02006505 { "ssl_c_ca_err", smp_fetch_ssl_c_ca_err, 0, NULL, SMP_T_SINT, SMP_USE_L5CLI },
6506 { "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 +01006507 { "ssl_c_der", smp_fetch_ssl_x_der, 0, NULL, SMP_T_BIN, SMP_USE_L5CLI },
Thierry FOURNIER07ee64e2015-07-06 23:43:03 +02006508 { "ssl_c_err", smp_fetch_ssl_c_err, 0, NULL, SMP_T_SINT, SMP_USE_L5CLI },
Emeric Brunba841a12014-04-30 17:05:08 +02006509 { "ssl_c_i_dn", smp_fetch_ssl_x_i_dn, ARG2(0,STR,SINT), NULL, SMP_T_STR, SMP_USE_L5CLI },
6510 { "ssl_c_key_alg", smp_fetch_ssl_x_key_alg, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
6511 { "ssl_c_notafter", smp_fetch_ssl_x_notafter, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
6512 { "ssl_c_notbefore", smp_fetch_ssl_x_notbefore, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
6513 { "ssl_c_sig_alg", smp_fetch_ssl_x_sig_alg, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
6514 { "ssl_c_s_dn", smp_fetch_ssl_x_s_dn, ARG2(0,STR,SINT), NULL, SMP_T_STR, SMP_USE_L5CLI },
6515 { "ssl_c_serial", smp_fetch_ssl_x_serial, 0, NULL, SMP_T_BIN, SMP_USE_L5CLI },
6516 { "ssl_c_sha1", smp_fetch_ssl_x_sha1, 0, NULL, SMP_T_BIN, SMP_USE_L5CLI },
Willy Tarreau80aca902013-01-07 15:42:20 +01006517 { "ssl_c_used", smp_fetch_ssl_c_used, 0, NULL, SMP_T_BOOL, SMP_USE_L5CLI },
Thierry FOURNIER07ee64e2015-07-06 23:43:03 +02006518 { "ssl_c_verify", smp_fetch_ssl_c_verify, 0, NULL, SMP_T_SINT, SMP_USE_L5CLI },
6519 { "ssl_c_version", smp_fetch_ssl_x_version, 0, NULL, SMP_T_SINT, SMP_USE_L5CLI },
Emeric Brun43e79582014-10-29 19:03:26 +01006520 { "ssl_f_der", smp_fetch_ssl_x_der, 0, NULL, SMP_T_BIN, SMP_USE_L5CLI },
Emeric Brunba841a12014-04-30 17:05:08 +02006521 { "ssl_f_i_dn", smp_fetch_ssl_x_i_dn, ARG2(0,STR,SINT), NULL, SMP_T_STR, SMP_USE_L5CLI },
6522 { "ssl_f_key_alg", smp_fetch_ssl_x_key_alg, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
6523 { "ssl_f_notafter", smp_fetch_ssl_x_notafter, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
6524 { "ssl_f_notbefore", smp_fetch_ssl_x_notbefore, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
6525 { "ssl_f_sig_alg", smp_fetch_ssl_x_sig_alg, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
6526 { "ssl_f_s_dn", smp_fetch_ssl_x_s_dn, ARG2(0,STR,SINT), NULL, SMP_T_STR, SMP_USE_L5CLI },
6527 { "ssl_f_serial", smp_fetch_ssl_x_serial, 0, NULL, SMP_T_BIN, SMP_USE_L5CLI },
Emeric Brun55f4fa82014-04-30 17:11:25 +02006528 { "ssl_f_sha1", smp_fetch_ssl_x_sha1, 0, NULL, SMP_T_BIN, SMP_USE_L5CLI },
Thierry FOURNIER07ee64e2015-07-06 23:43:03 +02006529 { "ssl_f_version", smp_fetch_ssl_x_version, 0, NULL, SMP_T_SINT, SMP_USE_L5CLI },
Willy Tarreau80aca902013-01-07 15:42:20 +01006530 { "ssl_fc", smp_fetch_ssl_fc, 0, NULL, SMP_T_BOOL, SMP_USE_L5CLI },
Thierry FOURNIER07ee64e2015-07-06 23:43:03 +02006531 { "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 +01006532 { "ssl_fc_cipher", smp_fetch_ssl_fc_cipher, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
Willy Tarreau80aca902013-01-07 15:42:20 +01006533 { "ssl_fc_has_crt", smp_fetch_ssl_fc_has_crt, 0, NULL, SMP_T_BOOL, SMP_USE_L5CLI },
6534 { "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 +02006535 { "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 +02006536#ifdef OPENSSL_NPN_NEGOTIATED
Thierry FOURNIER7654c9f2013-12-17 00:20:33 +01006537 { "ssl_fc_npn", smp_fetch_ssl_fc_npn, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
Willy Tarreaua33c6542012-10-15 13:19:06 +02006538#endif
Dirkjan Bussink48f1c4e2014-02-13 12:29:42 +01006539#ifdef TLSEXT_TYPE_application_layer_protocol_negotiation
Thierry FOURNIER7654c9f2013-12-17 00:20:33 +01006540 { "ssl_fc_alpn", smp_fetch_ssl_fc_alpn, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
Willy Tarreauab861d32013-04-02 02:30:41 +02006541#endif
Thierry FOURNIER7654c9f2013-12-17 00:20:33 +01006542 { "ssl_fc_protocol", smp_fetch_ssl_fc_protocol, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
Emeric Brunb73a9b02014-04-30 18:49:19 +02006543 { "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 +02006544 { "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 +01006545 { "ssl_fc_session_id", smp_fetch_ssl_fc_session_id, 0, NULL, SMP_T_BIN, SMP_USE_L5CLI },
6546 { "ssl_fc_sni", smp_fetch_ssl_fc_sni, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
Willy Tarreau7875d092012-09-10 08:20:03 +02006547 { NULL, NULL, 0, 0, 0 },
6548}};
6549
6550/* Note: must not be declared <const> as its list will be overwritten.
6551 * Please take care of keeping this list alphabetically sorted.
6552 */
Willy Tarreaudc13c112013-06-21 23:16:39 +02006553static struct acl_kw_list acl_kws = {ILH, {
Thierry FOURNIERc5a4e982014-03-05 16:07:08 +01006554 { "ssl_fc_sni_end", "ssl_fc_sni", PAT_MATCH_END },
6555 { "ssl_fc_sni_reg", "ssl_fc_sni", PAT_MATCH_REG },
Willy Tarreau8ed669b2013-01-11 15:49:37 +01006556 { /* END */ },
Willy Tarreau7875d092012-09-10 08:20:03 +02006557}};
6558
Willy Tarreau79eeafa2012-09-14 07:53:05 +02006559/* Note: must not be declared <const> as its list will be overwritten.
6560 * Please take care of keeping this list alphabetically sorted, doing so helps
6561 * all code contributors.
6562 * Optional keywords are also declared with a NULL ->parse() function so that
6563 * the config parser can report an appropriate error when a known keyword was
6564 * not enabled.
6565 */
Willy Tarreau51fb7652012-09-18 18:24:39 +02006566static struct bind_kw_list bind_kws = { "SSL", { }, {
Nenad Merdanovic05552d42015-02-27 19:56:49 +01006567 { "alpn", bind_parse_alpn, 1 }, /* set ALPN supported protocols */
6568 { "ca-file", bind_parse_ca_file, 1 }, /* set CAfile to process verify on client cert */
6569 { "ca-ignore-err", bind_parse_ignore_err, 1 }, /* set error IDs to ignore on verify depth > 0 */
Christopher Faulet31af49d2015-06-09 17:29:50 +02006570 { "ca-sign-file", bind_parse_ca_sign_file, 1 }, /* set CAFile used to generate and sign server certs */
6571 { "ca-sign-pass", bind_parse_ca_sign_pass, 1 }, /* set CAKey passphrase */
Nenad Merdanovic05552d42015-02-27 19:56:49 +01006572 { "ciphers", bind_parse_ciphers, 1 }, /* set SSL cipher suite */
6573 { "crl-file", bind_parse_crl_file, 1 }, /* set certificat revocation list file use on client cert verify */
6574 { "crt", bind_parse_crt, 1 }, /* load SSL certificates from this location */
6575 { "crt-ignore-err", bind_parse_ignore_err, 1 }, /* set error IDs to ingore on verify depth == 0 */
6576 { "crt-list", bind_parse_crt_list, 1 }, /* load a list of crt from this location */
6577 { "ecdhe", bind_parse_ecdhe, 1 }, /* defines named curve for elliptic curve Diffie-Hellman */
6578 { "force-sslv3", bind_parse_force_sslv3, 0 }, /* force SSLv3 */
6579 { "force-tlsv10", bind_parse_force_tlsv10, 0 }, /* force TLSv10 */
6580 { "force-tlsv11", bind_parse_force_tlsv11, 0 }, /* force TLSv11 */
6581 { "force-tlsv12", bind_parse_force_tlsv12, 0 }, /* force TLSv12 */
Christopher Faulet31af49d2015-06-09 17:29:50 +02006582 { "generate-certificates", bind_parse_generate_certs, 0 }, /* enable the server certificates generation */
Nenad Merdanovic05552d42015-02-27 19:56:49 +01006583 { "no-sslv3", bind_parse_no_sslv3, 0 }, /* disable SSLv3 */
6584 { "no-tlsv10", bind_parse_no_tlsv10, 0 }, /* disable TLSv10 */
6585 { "no-tlsv11", bind_parse_no_tlsv11, 0 }, /* disable TLSv11 */
6586 { "no-tlsv12", bind_parse_no_tlsv12, 0 }, /* disable TLSv12 */
6587 { "no-tls-tickets", bind_parse_no_tls_tickets, 0 }, /* disable session resumption tickets */
6588 { "ssl", bind_parse_ssl, 0 }, /* enable SSL processing */
6589 { "strict-sni", bind_parse_strict_sni, 0 }, /* refuse negotiation if sni doesn't match a certificate */
6590 { "tls-ticket-keys", bind_parse_tls_ticket_keys, 1 }, /* set file to load TLS ticket keys from */
6591 { "verify", bind_parse_verify, 1 }, /* set SSL verify method */
6592 { "npn", bind_parse_npn, 1 }, /* set NPN supported protocols */
Willy Tarreau79eeafa2012-09-14 07:53:05 +02006593 { NULL, NULL, 0 },
6594}};
Emeric Brun46591952012-05-18 15:47:34 +02006595
Willy Tarreau92faadf2012-10-10 23:04:25 +02006596/* Note: must not be declared <const> as its list will be overwritten.
6597 * Please take care of keeping this list alphabetically sorted, doing so helps
6598 * all code contributors.
6599 * Optional keywords are also declared with a NULL ->parse() function so that
6600 * the config parser can report an appropriate error when a known keyword was
6601 * not enabled.
6602 */
6603static struct srv_kw_list srv_kws = { "SSL", { }, {
Emeric Brunef42d922012-10-11 16:11:36 +02006604 { "ca-file", srv_parse_ca_file, 1, 0 }, /* set CAfile to process verify server cert */
Emeric Brunecc91fe2012-10-11 15:05:10 +02006605 { "check-ssl", srv_parse_check_ssl, 0, 0 }, /* enable SSL for health checks */
6606 { "ciphers", srv_parse_ciphers, 1, 0 }, /* select the cipher suite */
Emeric Brunef42d922012-10-11 16:11:36 +02006607 { "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 +02006608 { "crt", srv_parse_crt, 1, 0 }, /* set client certificate */
Emeric Brunecc91fe2012-10-11 15:05:10 +02006609 { "force-sslv3", srv_parse_force_sslv3, 0, 0 }, /* force SSLv3 */
6610 { "force-tlsv10", srv_parse_force_tlsv10, 0, 0 }, /* force TLSv10 */
6611 { "force-tlsv11", srv_parse_force_tlsv11, 0, 0 }, /* force TLSv11 */
6612 { "force-tlsv12", srv_parse_force_tlsv12, 0, 0 }, /* force TLSv12 */
Willy Tarreau2a3fb1c2015-02-05 16:47:07 +01006613 { "no-ssl-reuse", srv_parse_no_ssl_reuse, 0, 0 }, /* disable session reuse */
Emeric Brunecc91fe2012-10-11 15:05:10 +02006614 { "no-sslv3", srv_parse_no_sslv3, 0, 0 }, /* disable SSLv3 */
6615 { "no-tlsv10", srv_parse_no_tlsv10, 0, 0 }, /* disable TLSv10 */
6616 { "no-tlsv11", srv_parse_no_tlsv11, 0, 0 }, /* disable TLSv11 */
6617 { "no-tlsv12", srv_parse_no_tlsv12, 0, 0 }, /* disable TLSv12 */
Emeric Brunf9c5c472012-10-11 15:28:34 +02006618 { "no-tls-tickets", srv_parse_no_tls_tickets, 0, 0 }, /* disable session resumption tickets */
David Safb76832014-05-08 23:42:08 -04006619 { "send-proxy-v2-ssl", srv_parse_send_proxy_ssl, 0, 0 }, /* send PROXY protocol header v2 with SSL info */
6620 { "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 +02006621 { "sni", srv_parse_sni, 1, 0 }, /* send SNI extension */
Emeric Brunecc91fe2012-10-11 15:05:10 +02006622 { "ssl", srv_parse_ssl, 0, 0 }, /* enable SSL processing */
Emeric Brunef42d922012-10-11 16:11:36 +02006623 { "verify", srv_parse_verify, 1, 0 }, /* set SSL verify method */
Evan Broderbe554312013-06-27 00:05:25 -07006624 { "verifyhost", srv_parse_verifyhost, 1, 0 }, /* require that SSL cert verifies for hostname */
Willy Tarreau92faadf2012-10-10 23:04:25 +02006625 { NULL, NULL, 0, 0 },
6626}};
6627
Emeric Brun2c86cbf2014-10-30 15:56:50 +01006628static struct cfg_kw_list cfg_kws = {ILH, {
Willy Tarreau8c3b0fd2016-12-21 22:44:46 +01006629 { CFG_GLOBAL, "ca-base", ssl_parse_global_ca_crt_base },
6630 { CFG_GLOBAL, "crt-base", ssl_parse_global_ca_crt_base },
Willy Tarreau0bea58d2016-12-21 23:17:25 +01006631 { CFG_GLOBAL, "maxsslconn", ssl_parse_global_int },
Emeric Brun2c86cbf2014-10-30 15:56:50 +01006632 { CFG_GLOBAL, "ssl-default-bind-options", ssl_parse_default_bind_options },
6633 { CFG_GLOBAL, "ssl-default-server-options", ssl_parse_default_server_options },
Willy Tarreau14e36a12016-12-21 23:28:13 +01006634#ifndef OPENSSL_NO_DH
6635 { CFG_GLOBAL, "ssl-dh-param-file", ssl_parse_global_dh_param_file },
6636#endif
Willy Tarreau9ceda382016-12-21 23:13:03 +01006637 { CFG_GLOBAL, "tune.ssl.cachesize", ssl_parse_global_int },
6638#ifndef OPENSSL_NO_DH
6639 { CFG_GLOBAL, "tune.ssl.default-dh-param", ssl_parse_global_default_dh },
6640#endif
6641 { CFG_GLOBAL, "tune.ssl.force-private-cache", ssl_parse_global_private_cache },
6642 { CFG_GLOBAL, "tune.ssl.lifetime", ssl_parse_global_lifetime },
6643 { CFG_GLOBAL, "tune.ssl.maxrecord", ssl_parse_global_int },
6644 { CFG_GLOBAL, "tune.ssl.ssl-ctx-cache-size", ssl_parse_global_int },
Willy Tarreauf22e9682016-12-21 23:23:19 +01006645 { CFG_GLOBAL, "ssl-default-bind-ciphers", ssl_parse_global_ciphers },
6646 { CFG_GLOBAL, "ssl-default-server-ciphers", ssl_parse_global_ciphers },
Emeric Brun2c86cbf2014-10-30 15:56:50 +01006647 { 0, NULL, NULL },
6648}};
6649
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02006650/* transport-layer operations for SSL sockets */
6651struct xprt_ops ssl_sock = {
Emeric Brun46591952012-05-18 15:47:34 +02006652 .snd_buf = ssl_sock_from_buf,
6653 .rcv_buf = ssl_sock_to_buf,
6654 .rcv_pipe = NULL,
6655 .snd_pipe = NULL,
6656 .shutr = NULL,
6657 .shutw = ssl_sock_shutw,
6658 .close = ssl_sock_close,
6659 .init = ssl_sock_init,
Willy Tarreau55d37912016-12-21 23:38:39 +01006660 .prepare_bind_conf = ssl_sock_prepare_bind_conf,
Willy Tarreau795cdab2016-12-22 17:30:54 +01006661 .destroy_bind_conf = ssl_sock_destroy_bind_conf,
Willy Tarreau8e0bb0a2016-11-24 16:58:12 +01006662 .name = "SSL",
Emeric Brun46591952012-05-18 15:47:34 +02006663};
6664
Daniel Jakots54ffb912015-11-06 20:02:41 +01006665#if (OPENSSL_VERSION_NUMBER >= 0x1000200fL && !defined OPENSSL_NO_TLSEXT && !defined OPENSSL_IS_BORINGSSL && !defined LIBRESSL_VERSION_NUMBER)
Janusz Dziemidowicz2c701b52015-03-07 23:03:59 +01006666
6667static void ssl_sock_sctl_free_func(void *parent, void *ptr, CRYPTO_EX_DATA *ad, int idx, long argl, void *argp)
6668{
6669 if (ptr) {
6670 chunk_destroy(ptr);
6671 free(ptr);
6672 }
6673}
6674
6675#endif
6676
Emeric Brun46591952012-05-18 15:47:34 +02006677__attribute__((constructor))
Willy Tarreau92faadf2012-10-10 23:04:25 +02006678static void __ssl_sock_init(void)
6679{
Willy Tarreauc2c0b612016-12-21 19:23:20 +01006680 char *ptr;
6681
Emeric Brun46591952012-05-18 15:47:34 +02006682 STACK_OF(SSL_COMP)* cm;
6683
Willy Tarreau610f04b2014-02-13 11:36:41 +01006684#ifdef LISTEN_DEFAULT_CIPHERS
6685 global.listen_default_ciphers = LISTEN_DEFAULT_CIPHERS;
6686#endif
6687#ifdef CONNECT_DEFAULT_CIPHERS
6688 global.connect_default_ciphers = CONNECT_DEFAULT_CIPHERS;
6689#endif
6690 if (global.listen_default_ciphers)
6691 global.listen_default_ciphers = strdup(global.listen_default_ciphers);
6692 if (global.connect_default_ciphers)
6693 global.connect_default_ciphers = strdup(global.connect_default_ciphers);
Emeric Brun2c86cbf2014-10-30 15:56:50 +01006694 global.listen_default_ssloptions = BC_SSL_O_NONE;
6695 global.connect_default_ssloptions = SRV_SSL_O_NONE;
Willy Tarreau610f04b2014-02-13 11:36:41 +01006696
Willy Tarreau13e14102016-12-22 20:25:26 +01006697 xprt_register(XPRT_SSL, &ssl_sock);
Emeric Brun46591952012-05-18 15:47:34 +02006698 SSL_library_init();
6699 cm = SSL_COMP_get_compression_methods();
6700 sk_SSL_COMP_zero(cm);
Daniel Jakots54ffb912015-11-06 20:02:41 +01006701#if (OPENSSL_VERSION_NUMBER >= 0x1000200fL && !defined OPENSSL_NO_TLSEXT && !defined OPENSSL_IS_BORINGSSL && !defined LIBRESSL_VERSION_NUMBER)
Janusz Dziemidowicz2c701b52015-03-07 23:03:59 +01006702 sctl_ex_index = SSL_CTX_get_ex_new_index(0, NULL, NULL, NULL, ssl_sock_sctl_free_func);
6703#endif
Willy Tarreau7875d092012-09-10 08:20:03 +02006704 sample_register_fetches(&sample_fetch_keywords);
6705 acl_register_keywords(&acl_kws);
Willy Tarreau79eeafa2012-09-14 07:53:05 +02006706 bind_register_keywords(&bind_kws);
Willy Tarreau92faadf2012-10-10 23:04:25 +02006707 srv_register_keywords(&srv_kws);
Emeric Brun2c86cbf2014-10-30 15:56:50 +01006708 cfg_register_keywords(&cfg_kws);
William Lallemand32af2032016-10-29 18:09:35 +02006709 cli_register_kw(&cli_kws);
Willy Tarreaud92aa5c2015-01-15 21:34:39 +01006710
Willy Tarreauc2c0b612016-12-21 19:23:20 +01006711 ptr = NULL;
6712 memprintf(&ptr, "Built with OpenSSL version : "
6713#ifdef OPENSSL_IS_BORINGSSL
6714 "BoringSSL\n");
6715#else /* OPENSSL_IS_BORINGSSL */
6716 OPENSSL_VERSION_TEXT
6717 "\nRunning on OpenSSL version : %s%s",
6718 SSLeay_version(SSLEAY_VERSION),
6719 ((OPENSSL_VERSION_NUMBER ^ SSLeay()) >> 8) ? " (VERSIONS DIFFER!)" : "");
6720#endif
6721 memprintf(&ptr, "%s\nOpenSSL library supports TLS extensions : "
6722#if OPENSSL_VERSION_NUMBER < 0x00907000L
6723 "no (library version too old)"
6724#elif defined(OPENSSL_NO_TLSEXT)
6725 "no (disabled via OPENSSL_NO_TLSEXT)"
6726#else
6727 "yes"
6728#endif
6729 "", ptr);
6730
6731 memprintf(&ptr, "%s\nOpenSSL library supports SNI : "
6732#ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME
6733 "yes"
6734#else
6735#ifdef OPENSSL_NO_TLSEXT
6736 "no (because of OPENSSL_NO_TLSEXT)"
6737#else
6738 "no (version might be too old, 0.9.8f min needed)"
6739#endif
6740#endif
6741 "", ptr);
6742
6743 memprintf(&ptr, "%s\nOpenSSL library supports prefer-server-ciphers : "
6744#ifdef SSL_OP_CIPHER_SERVER_PREFERENCE
6745 "yes"
6746#else
6747 "no (0.9.7 or later needed)"
6748#endif
6749 "", ptr);
6750 hap_register_build_opts(ptr, 1);
6751
Willy Tarreaud92aa5c2015-01-15 21:34:39 +01006752 global.ssl_session_max_cost = SSL_SESSION_MAX_COST;
6753 global.ssl_handshake_max_cost = SSL_HANDSHAKE_MAX_COST;
Remi Gacogne4f902b82015-05-28 16:23:00 +02006754
6755#ifndef OPENSSL_NO_DH
6756 ssl_dh_ptr_index = SSL_CTX_get_ex_new_index(0, NULL, NULL, NULL, NULL);
6757#endif
Thierry FOURNIER / OZON.IO8b068c22016-10-10 11:59:50 +02006758
6759 /* Load SSL string for the verbose & debug mode. */
6760 ERR_load_SSL_strings();
Emeric Brun46591952012-05-18 15:47:34 +02006761}
6762
Remi Gacogned3a23c32015-05-28 16:39:47 +02006763__attribute__((destructor))
6764static void __ssl_sock_deinit(void)
6765{
Willy Tarreaua84c2672015-10-09 12:10:13 +02006766#ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME
Christopher Faulet31af49d2015-06-09 17:29:50 +02006767 lru64_destroy(ssl_ctx_lru_tree);
Willy Tarreaua84c2672015-10-09 12:10:13 +02006768#endif
Christopher Faulet31af49d2015-06-09 17:29:50 +02006769
Remi Gacogned3a23c32015-05-28 16:39:47 +02006770#ifndef OPENSSL_NO_DH
6771 if (local_dh_1024) {
6772 DH_free(local_dh_1024);
6773 local_dh_1024 = NULL;
6774 }
6775
6776 if (local_dh_2048) {
6777 DH_free(local_dh_2048);
6778 local_dh_2048 = NULL;
6779 }
6780
6781 if (local_dh_4096) {
6782 DH_free(local_dh_4096);
6783 local_dh_4096 = NULL;
6784 }
6785
Remi Gacogne47783ef2015-05-29 15:53:22 +02006786 if (global_dh) {
6787 DH_free(global_dh);
6788 global_dh = NULL;
6789 }
Remi Gacogned3a23c32015-05-28 16:39:47 +02006790#endif
6791
6792 ERR_remove_state(0);
6793 ERR_free_strings();
6794
6795 EVP_cleanup();
6796
6797#if OPENSSL_VERSION_NUMBER >= 0x00907000L
6798 CRYPTO_cleanup_all_ex_data();
6799#endif
6800}
6801
6802
Emeric Brun46591952012-05-18 15:47:34 +02006803/*
6804 * Local variables:
6805 * c-indent-level: 8
6806 * c-basic-offset: 8
6807 * End:
6808 */