blob: 0a06adbbe7691f85597a1bcd139c820af7e6c53d [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 */
Emmanuel Hocdetd294aea2016-05-13 11:14:06 +02002033static int ssl_sock_load_multi_cert(const char *path, struct bind_conf *bind_conf, struct proxy *curproxy, 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 */
Emmanuel Hocdetd294aea2016-05-13 11:14:06 +02002241static int ssl_sock_load_multi_cert(const char *path, struct bind_conf *bind_conf, struct proxy *curproxy, 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
Emeric Brun50bcecc2013-04-22 13:05:23 +02002355static int ssl_sock_load_cert_file(const char *path, struct bind_conf *bind_conf, struct proxy *curproxy, 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 Tarreau79eeafa2012-09-14 07:53:05 +02002443int ssl_sock_load_cert(char *path, struct bind_conf *bind_conf, struct proxy *curproxy, 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)
2460 return ssl_sock_load_cert_file(path, bind_conf, curproxy, 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);
Emmanuel Hocdetd294aea2016-05-13 11:14:06 +02002520 ssl_sock_load_multi_cert(fp, bind_conf, curproxy, NULL, 0, err);
yanbzhu63ea8462015-12-09 13:35:14 -05002521
2522 /* Successfully processed the bundle */
2523 goto ignore_entry;
2524 }
2525 }
2526
2527#endif
yanbzhu08ce6ab2015-12-02 13:01:29 -05002528 cfgerr += ssl_sock_load_cert_file(fp, bind_conf, curproxy, NULL, 0, err);
2529ignore_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
Emmanuel Hocdetd294aea2016-05-13 11:14:06 +02002538 cfgerr = ssl_sock_load_multi_cert(path, bind_conf, curproxy, 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
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01002559int ssl_sock_load_cert_list_file(char *file, struct bind_conf *bind_conf, struct proxy *curproxy, char **err)
2560{
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) {
2623 cfgerr = ssl_sock_load_cert_file(args[0], bind_conf, curproxy, &args[1], arg-1, err);
2624 } else {
Emmanuel Hocdetd294aea2016-05-13 11:14:06 +02002625 cfgerr = ssl_sock_load_multi_cert(args[0], bind_conf, curproxy, &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 Tarreau2a65ff02012-09-13 17:54:29 +02002673int ssl_sock_prepare_ctx(struct bind_conf *bind_conf, SSL_CTX *ctx, struct proxy *curproxy)
Emeric Brunfc0421f2012-09-07 17:30:07 +02002674{
2675 int cfgerr = 0;
Emeric Brun850efd52014-01-29 12:24:34 +01002676 int verify = SSL_VERIFY_NONE;
Remi Gacogneaf5c3da2014-05-19 10:29:58 +02002677 long ssloptions =
Emeric Brunfc0421f2012-09-07 17:30:07 +02002678 SSL_OP_ALL | /* all known workarounds for bugs */
2679 SSL_OP_NO_SSLv2 |
2680 SSL_OP_NO_COMPRESSION |
Emeric Bruna4bcd9a2012-09-20 16:19:02 +02002681 SSL_OP_SINGLE_DH_USE |
Emeric Brun2b58d042012-09-20 17:10:03 +02002682 SSL_OP_SINGLE_ECDH_USE |
Emeric Brun3c4bc6e2012-10-04 18:44:19 +02002683 SSL_OP_NO_SESSION_RESUMPTION_ON_RENEGOTIATION |
2684 SSL_OP_CIPHER_SERVER_PREFERENCE;
Remi Gacogneaf5c3da2014-05-19 10:29:58 +02002685 long sslmode =
Emeric Brunfc0421f2012-09-07 17:30:07 +02002686 SSL_MODE_ENABLE_PARTIAL_WRITE |
2687 SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER |
Willy Tarreau396a1862014-11-13 14:06:52 +01002688 SSL_MODE_RELEASE_BUFFERS |
2689 SSL_MODE_SMALL_BUFFERS;
Remi Gacognef46cd6e2014-06-12 14:58:40 +02002690 STACK_OF(SSL_CIPHER) * ciphers = NULL;
Willy Tarreaua616ba62014-10-26 06:49:19 +01002691 SSL_CIPHER * cipher = NULL;
Remi Gacognec1eab8c2014-06-12 18:20:11 +02002692 char cipher_description[128];
2693 /* The description of ciphers using an Ephemeral Diffie Hellman key exchange
2694 contains " Kx=DH " or " Kx=DH(". Beware of " Kx=DH/",
2695 which is not ephemeral DH. */
2696 const char dhe_description[] = " Kx=DH ";
2697 const char dhe_export_description[] = " Kx=DH(";
Remi Gacognef46cd6e2014-06-12 14:58:40 +02002698 int idx = 0;
2699 int dhe_found = 0;
Remi Gacogne23d5d372014-10-10 17:04:26 +02002700 SSL *ssl = NULL;
Emeric Brunfc0421f2012-09-07 17:30:07 +02002701
Thierry Fournier383085f2013-01-24 14:15:43 +01002702 /* Make sure openssl opens /dev/urandom before the chroot */
2703 if (!ssl_initialize_random()) {
2704 Alert("OpenSSL random data generator initialization failed.\n");
2705 cfgerr++;
2706 }
2707
Emeric Brun89675492012-10-05 13:48:26 +02002708 if (bind_conf->ssl_options & BC_SSL_O_NO_SSLV3)
Emeric Brunfc0421f2012-09-07 17:30:07 +02002709 ssloptions |= SSL_OP_NO_SSLv3;
Emeric Brun89675492012-10-05 13:48:26 +02002710 if (bind_conf->ssl_options & BC_SSL_O_NO_TLSV10)
Emeric Brunfc0421f2012-09-07 17:30:07 +02002711 ssloptions |= SSL_OP_NO_TLSv1;
Emeric Brun89675492012-10-05 13:48:26 +02002712 if (bind_conf->ssl_options & BC_SSL_O_NO_TLSV11)
Emeric Brunc0ff4922012-09-28 19:37:02 +02002713 ssloptions |= SSL_OP_NO_TLSv1_1;
Emeric Brun89675492012-10-05 13:48:26 +02002714 if (bind_conf->ssl_options & BC_SSL_O_NO_TLSV12)
Emeric Brunc0ff4922012-09-28 19:37:02 +02002715 ssloptions |= SSL_OP_NO_TLSv1_2;
Emeric Brun89675492012-10-05 13:48:26 +02002716 if (bind_conf->ssl_options & BC_SSL_O_NO_TLS_TICKETS)
Emeric Brun2d0c4822012-10-02 13:45:20 +02002717 ssloptions |= SSL_OP_NO_TICKET;
Jérémie Courrèges-Anglas17c3f622015-07-25 16:50:52 -06002718 if (bind_conf->ssl_options & BC_SSL_O_USE_SSLV3) {
2719#ifndef OPENSSL_NO_SSL3
Emeric Brun2cb7ae52012-10-05 14:14:21 +02002720 SSL_CTX_set_ssl_version(ctx, SSLv3_server_method());
Jérémie Courrèges-Anglas17c3f622015-07-25 16:50:52 -06002721#else
2722 Alert("SSLv3 support requested but unavailable.\n");
2723 cfgerr++;
2724#endif
2725 }
Emeric Brun2cb7ae52012-10-05 14:14:21 +02002726 if (bind_conf->ssl_options & BC_SSL_O_USE_TLSV10)
2727 SSL_CTX_set_ssl_version(ctx, TLSv1_server_method());
2728#if SSL_OP_NO_TLSv1_1
2729 if (bind_conf->ssl_options & BC_SSL_O_USE_TLSV11)
2730 SSL_CTX_set_ssl_version(ctx, TLSv1_1_server_method());
2731#endif
2732#if SSL_OP_NO_TLSv1_2
2733 if (bind_conf->ssl_options & BC_SSL_O_USE_TLSV12)
2734 SSL_CTX_set_ssl_version(ctx, TLSv1_2_server_method());
2735#endif
Emeric Brunfc0421f2012-09-07 17:30:07 +02002736
2737 SSL_CTX_set_options(ctx, ssloptions);
2738 SSL_CTX_set_mode(ctx, sslmode);
Emeric Brun850efd52014-01-29 12:24:34 +01002739 switch (bind_conf->verify) {
2740 case SSL_SOCK_VERIFY_NONE:
2741 verify = SSL_VERIFY_NONE;
2742 break;
2743 case SSL_SOCK_VERIFY_OPTIONAL:
2744 verify = SSL_VERIFY_PEER;
2745 break;
2746 case SSL_SOCK_VERIFY_REQUIRED:
2747 verify = SSL_VERIFY_PEER|SSL_VERIFY_FAIL_IF_NO_PEER_CERT;
2748 break;
2749 }
2750 SSL_CTX_set_verify(ctx, verify, ssl_sock_bind_verifycbk);
2751 if (verify & SSL_VERIFY_PEER) {
Emeric Brunfb510ea2012-10-05 12:00:26 +02002752 if (bind_conf->ca_file) {
Emeric Brund94b3fe2012-09-20 18:23:56 +02002753 /* load CAfile to verify */
Emeric Brunfb510ea2012-10-05 12:00:26 +02002754 if (!SSL_CTX_load_verify_locations(ctx, bind_conf->ca_file, NULL)) {
Emeric Brund94b3fe2012-09-20 18:23:56 +02002755 Alert("Proxy '%s': unable to load CA file '%s' for bind '%s' at [%s:%d].\n",
Emeric Brunfb510ea2012-10-05 12:00:26 +02002756 curproxy->id, bind_conf->ca_file, bind_conf->arg, bind_conf->file, bind_conf->line);
Emeric Brund94b3fe2012-09-20 18:23:56 +02002757 cfgerr++;
2758 }
2759 /* set CA names fo client cert request, function returns void */
Emeric Brunfb510ea2012-10-05 12:00:26 +02002760 SSL_CTX_set_client_CA_list(ctx, SSL_load_client_CA_file(bind_conf->ca_file));
Emeric Brund94b3fe2012-09-20 18:23:56 +02002761 }
Emeric Brun850efd52014-01-29 12:24:34 +01002762 else {
2763 Alert("Proxy '%s': verify is enabled but no CA file specified for bind '%s' at [%s:%d].\n",
2764 curproxy->id, bind_conf->arg, bind_conf->file, bind_conf->line);
2765 cfgerr++;
2766 }
Emeric Brun051cdab2012-10-02 19:25:50 +02002767#ifdef X509_V_FLAG_CRL_CHECK
Emeric Brunfb510ea2012-10-05 12:00:26 +02002768 if (bind_conf->crl_file) {
Emeric Brund94b3fe2012-09-20 18:23:56 +02002769 X509_STORE *store = SSL_CTX_get_cert_store(ctx);
2770
Emeric Brunfb510ea2012-10-05 12:00:26 +02002771 if (!store || !X509_STORE_load_locations(store, bind_conf->crl_file, NULL)) {
Emeric Brund94b3fe2012-09-20 18:23:56 +02002772 Alert("Proxy '%s': unable to configure CRL file '%s' for bind '%s' at [%s:%d].\n",
Alexander Rigbofc65af02015-04-07 14:02:16 +02002773 curproxy->id, bind_conf->crl_file, bind_conf->arg, bind_conf->file, bind_conf->line);
Emeric Brund94b3fe2012-09-20 18:23:56 +02002774 cfgerr++;
2775 }
Emeric Brun561e5742012-10-02 15:20:55 +02002776 else {
2777 X509_STORE_set_flags(store, X509_V_FLAG_CRL_CHECK|X509_V_FLAG_CRL_CHECK_ALL);
2778 }
Emeric Brund94b3fe2012-09-20 18:23:56 +02002779 }
Emeric Brun051cdab2012-10-02 19:25:50 +02002780#endif
Emeric Brun644cde02012-12-14 11:21:13 +01002781 ERR_clear_error();
Emeric Brund94b3fe2012-09-20 18:23:56 +02002782 }
Emeric Brunfc0421f2012-09-07 17:30:07 +02002783
Nenad Merdanovic05552d42015-02-27 19:56:49 +01002784#if (defined SSL_CTRL_SET_TLSEXT_TICKET_KEY_CB && TLS_TICKETS_NO > 0)
Nenad Merdanovic146defa2015-05-09 08:46:00 +02002785 if(bind_conf->keys_ref) {
Nenad Merdanovic05552d42015-02-27 19:56:49 +01002786 if (!SSL_CTX_set_tlsext_ticket_key_cb(ctx, ssl_tlsext_ticket_key_cb)) {
2787 Alert("Proxy '%s': unable to set callback for TLS ticket validation for bind '%s' at [%s:%d].\n",
2788 curproxy->id, bind_conf->arg, bind_conf->file, bind_conf->line);
2789 cfgerr++;
2790 }
2791 }
2792#endif
2793
Emeric Brun4f65bff2012-11-16 15:11:00 +01002794 if (global.tune.ssllifetime)
2795 SSL_CTX_set_timeout(ctx, global.tune.ssllifetime);
2796
Emeric Brunfc0421f2012-09-07 17:30:07 +02002797 shared_context_set_cache(ctx);
Willy Tarreau2a65ff02012-09-13 17:54:29 +02002798 if (bind_conf->ciphers &&
2799 !SSL_CTX_set_cipher_list(ctx, bind_conf->ciphers)) {
Emeric Brunfc0421f2012-09-07 17:30:07 +02002800 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 +02002801 curproxy->id, bind_conf->ciphers, bind_conf->arg, bind_conf->file, bind_conf->line);
Emeric Brunfc0421f2012-09-07 17:30:07 +02002802 cfgerr++;
2803 }
2804
Remi Gacogne47783ef2015-05-29 15:53:22 +02002805 /* If tune.ssl.default-dh-param has not been set,
2806 neither has ssl-default-dh-file and no static DH
2807 params were in the certificate file. */
Remi Gacogne4f902b82015-05-28 16:23:00 +02002808 if (global.tune.ssl_default_dh_param == 0 &&
Remi Gacogne47783ef2015-05-29 15:53:22 +02002809 global_dh == NULL &&
Remi Gacogne4f902b82015-05-28 16:23:00 +02002810 (ssl_dh_ptr_index == -1 ||
2811 SSL_CTX_get_ex_data(ctx, ssl_dh_ptr_index) == NULL)) {
Lukas Tribus90132722014-08-18 00:56:33 +02002812
Remi Gacogne23d5d372014-10-10 17:04:26 +02002813 ssl = SSL_new(ctx);
Remi Gacognef46cd6e2014-06-12 14:58:40 +02002814
Remi Gacogne23d5d372014-10-10 17:04:26 +02002815 if (ssl) {
2816 ciphers = SSL_get_ciphers(ssl);
2817
2818 if (ciphers) {
2819 for (idx = 0; idx < sk_SSL_CIPHER_num(ciphers); idx++) {
2820 cipher = sk_SSL_CIPHER_value(ciphers, idx);
2821 if (SSL_CIPHER_description(cipher, cipher_description, sizeof (cipher_description)) == cipher_description) {
2822 if (strstr(cipher_description, dhe_description) != NULL ||
2823 strstr(cipher_description, dhe_export_description) != NULL) {
2824 dhe_found = 1;
2825 break;
2826 }
Remi Gacognec1eab8c2014-06-12 18:20:11 +02002827 }
Remi Gacognef46cd6e2014-06-12 14:58:40 +02002828 }
2829 }
Remi Gacogne23d5d372014-10-10 17:04:26 +02002830 SSL_free(ssl);
2831 ssl = NULL;
Lukas Tribus90132722014-08-18 00:56:33 +02002832 }
Remi Gacognef46cd6e2014-06-12 14:58:40 +02002833
Lukas Tribus90132722014-08-18 00:56:33 +02002834 if (dhe_found) {
2835 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 +02002836 }
2837
2838 global.tune.ssl_default_dh_param = 1024;
2839 }
Remi Gacogne8de54152014-07-15 11:36:40 +02002840
2841#ifndef OPENSSL_NO_DH
2842 if (global.tune.ssl_default_dh_param >= 1024) {
2843 if (local_dh_1024 == NULL) {
2844 local_dh_1024 = ssl_get_dh_1024();
2845 }
2846 if (global.tune.ssl_default_dh_param >= 2048) {
2847 if (local_dh_2048 == NULL) {
2848 local_dh_2048 = ssl_get_dh_2048();
2849 }
2850 if (global.tune.ssl_default_dh_param >= 4096) {
2851 if (local_dh_4096 == NULL) {
2852 local_dh_4096 = ssl_get_dh_4096();
2853 }
Remi Gacogne8de54152014-07-15 11:36:40 +02002854 }
2855 }
2856 }
2857#endif /* OPENSSL_NO_DH */
Remi Gacognef46cd6e2014-06-12 14:58:40 +02002858
Emeric Brunfc0421f2012-09-07 17:30:07 +02002859 SSL_CTX_set_info_callback(ctx, ssl_sock_infocbk);
Willy Tarreau5cbe4ef2014-05-08 22:45:11 +02002860#if OPENSSL_VERSION_NUMBER >= 0x00907000L
Emeric Brun29f037d2014-04-25 19:05:36 +02002861 SSL_CTX_set_msg_callback(ctx, ssl_sock_msgcbk);
Willy Tarreau5cbe4ef2014-05-08 22:45:11 +02002862#endif
Emeric Brun29f037d2014-04-25 19:05:36 +02002863
Willy Tarreau6c9a3d52012-10-18 18:57:14 +02002864#ifdef OPENSSL_NPN_NEGOTIATED
2865 if (bind_conf->npn_str)
2866 SSL_CTX_set_next_protos_advertised_cb(ctx, ssl_sock_advertise_npn_protos, bind_conf);
2867#endif
Dirkjan Bussink48f1c4e2014-02-13 12:29:42 +01002868#ifdef TLSEXT_TYPE_application_layer_protocol_negotiation
Willy Tarreauab861d32013-04-02 02:30:41 +02002869 if (bind_conf->alpn_str)
Dirkjan Bussink48f1c4e2014-02-13 12:29:42 +01002870 SSL_CTX_set_alpn_select_cb(ctx, ssl_sock_advertise_alpn_protos, bind_conf);
Willy Tarreauab861d32013-04-02 02:30:41 +02002871#endif
Willy Tarreau6c9a3d52012-10-18 18:57:14 +02002872
Emeric Brunfc0421f2012-09-07 17:30:07 +02002873#ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME
2874 SSL_CTX_set_tlsext_servername_callback(ctx, ssl_sock_switchctx_cbk);
Willy Tarreau2a65ff02012-09-13 17:54:29 +02002875 SSL_CTX_set_tlsext_servername_arg(ctx, bind_conf);
Emeric Brunfc0421f2012-09-07 17:30:07 +02002876#endif
Emeric Brun2b58d042012-09-20 17:10:03 +02002877#if defined(SSL_CTX_set_tmp_ecdh) && !defined(OPENSSL_NO_ECDH)
Emeric Brun6924ef82013-03-06 14:08:53 +01002878 {
Emeric Brun2b58d042012-09-20 17:10:03 +02002879 int i;
2880 EC_KEY *ecdh;
2881
Emeric Brun6924ef82013-03-06 14:08:53 +01002882 i = OBJ_sn2nid(bind_conf->ecdhe ? bind_conf->ecdhe : ECDHE_DEFAULT_CURVE);
Emeric Brun2b58d042012-09-20 17:10:03 +02002883 if (!i || ((ecdh = EC_KEY_new_by_curve_name(i)) == NULL)) {
2884 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 +01002885 curproxy->id, bind_conf->ecdhe ? bind_conf->ecdhe : ECDHE_DEFAULT_CURVE,
2886 bind_conf->arg, bind_conf->file, bind_conf->line);
Emeric Brun2b58d042012-09-20 17:10:03 +02002887 cfgerr++;
2888 }
2889 else {
2890 SSL_CTX_set_tmp_ecdh(ctx, ecdh);
2891 EC_KEY_free(ecdh);
2892 }
2893 }
2894#endif
2895
Emeric Brunfc0421f2012-09-07 17:30:07 +02002896 return cfgerr;
2897}
2898
Evan Broderbe554312013-06-27 00:05:25 -07002899static int ssl_sock_srv_hostcheck(const char *pattern, const char *hostname)
2900{
2901 const char *pattern_wildcard, *pattern_left_label_end, *hostname_left_label_end;
2902 size_t prefixlen, suffixlen;
2903
2904 /* Trivial case */
2905 if (strcmp(pattern, hostname) == 0)
2906 return 1;
2907
Evan Broderbe554312013-06-27 00:05:25 -07002908 /* The rest of this logic is based on RFC 6125, section 6.4.3
2909 * (http://tools.ietf.org/html/rfc6125#section-6.4.3) */
2910
Emeric Bruna848dae2013-10-08 11:27:28 +02002911 pattern_wildcard = NULL;
2912 pattern_left_label_end = pattern;
2913 while (*pattern_left_label_end != '.') {
2914 switch (*pattern_left_label_end) {
2915 case 0:
2916 /* End of label not found */
2917 return 0;
2918 case '*':
2919 /* If there is more than one wildcards */
2920 if (pattern_wildcard)
2921 return 0;
2922 pattern_wildcard = pattern_left_label_end;
2923 break;
2924 }
2925 pattern_left_label_end++;
2926 }
2927
2928 /* If it's not trivial and there is no wildcard, it can't
2929 * match */
2930 if (!pattern_wildcard)
Evan Broderbe554312013-06-27 00:05:25 -07002931 return 0;
2932
2933 /* Make sure all labels match except the leftmost */
2934 hostname_left_label_end = strchr(hostname, '.');
2935 if (!hostname_left_label_end
2936 || strcmp(pattern_left_label_end, hostname_left_label_end) != 0)
2937 return 0;
2938
2939 /* Make sure the leftmost label of the hostname is long enough
2940 * that the wildcard can match */
Emeric Brun369da852013-10-08 11:39:35 +02002941 if (hostname_left_label_end - hostname < (pattern_left_label_end - pattern) - 1)
Evan Broderbe554312013-06-27 00:05:25 -07002942 return 0;
2943
2944 /* Finally compare the string on either side of the
2945 * wildcard */
2946 prefixlen = pattern_wildcard - pattern;
2947 suffixlen = pattern_left_label_end - (pattern_wildcard + 1);
Emeric Bruna848dae2013-10-08 11:27:28 +02002948 if ((prefixlen && (memcmp(pattern, hostname, prefixlen) != 0))
2949 || (suffixlen && (memcmp(pattern_wildcard + 1, hostname_left_label_end - suffixlen, suffixlen) != 0)))
Evan Broderbe554312013-06-27 00:05:25 -07002950 return 0;
2951
2952 return 1;
2953}
2954
2955static int ssl_sock_srv_verifycbk(int ok, X509_STORE_CTX *ctx)
2956{
2957 SSL *ssl;
2958 struct connection *conn;
2959 char *servername;
2960
2961 int depth;
2962 X509 *cert;
2963 STACK_OF(GENERAL_NAME) *alt_names;
2964 int i;
2965 X509_NAME *cert_subject;
2966 char *str;
2967
2968 if (ok == 0)
2969 return ok;
2970
2971 ssl = X509_STORE_CTX_get_ex_data(ctx, SSL_get_ex_data_X509_STORE_CTX_idx());
Vincent Bernat3c2f2f22016-04-03 13:48:42 +02002972 conn = SSL_get_app_data(ssl);
Evan Broderbe554312013-06-27 00:05:25 -07002973
2974 servername = objt_server(conn->target)->ssl_ctx.verify_host;
2975
2976 /* We only need to verify the CN on the actual server cert,
2977 * not the indirect CAs */
2978 depth = X509_STORE_CTX_get_error_depth(ctx);
2979 if (depth != 0)
2980 return ok;
2981
2982 /* At this point, the cert is *not* OK unless we can find a
2983 * hostname match */
2984 ok = 0;
2985
2986 cert = X509_STORE_CTX_get_current_cert(ctx);
2987 /* It seems like this might happen if verify peer isn't set */
2988 if (!cert)
2989 return ok;
2990
2991 alt_names = X509_get_ext_d2i(cert, NID_subject_alt_name, NULL, NULL);
2992 if (alt_names) {
2993 for (i = 0; !ok && i < sk_GENERAL_NAME_num(alt_names); i++) {
2994 GENERAL_NAME *name = sk_GENERAL_NAME_value(alt_names, i);
2995 if (name->type == GEN_DNS) {
Emeric Bruna33410c2013-09-17 15:47:48 +02002996#if OPENSSL_VERSION_NUMBER < 0x00907000L
2997 if (ASN1_STRING_to_UTF8((unsigned char **)&str, name->d.ia5) >= 0) {
2998#else
Evan Broderbe554312013-06-27 00:05:25 -07002999 if (ASN1_STRING_to_UTF8((unsigned char **)&str, name->d.dNSName) >= 0) {
Emeric Bruna33410c2013-09-17 15:47:48 +02003000#endif
Evan Broderbe554312013-06-27 00:05:25 -07003001 ok = ssl_sock_srv_hostcheck(str, servername);
3002 OPENSSL_free(str);
3003 }
3004 }
3005 }
Emeric Brun4ad50a42013-09-17 15:19:54 +02003006 sk_GENERAL_NAME_pop_free(alt_names, GENERAL_NAME_free);
Evan Broderbe554312013-06-27 00:05:25 -07003007 }
3008
3009 cert_subject = X509_get_subject_name(cert);
3010 i = -1;
3011 while (!ok && (i = X509_NAME_get_index_by_NID(cert_subject, NID_commonName, i)) != -1) {
3012 X509_NAME_ENTRY *entry = X509_NAME_get_entry(cert_subject, i);
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02003013 ASN1_STRING *value;
3014 value = X509_NAME_ENTRY_get_data(entry);
3015 if (ASN1_STRING_to_UTF8((unsigned char **)&str, value) >= 0) {
Evan Broderbe554312013-06-27 00:05:25 -07003016 ok = ssl_sock_srv_hostcheck(str, servername);
3017 OPENSSL_free(str);
3018 }
3019 }
3020
3021 return ok;
3022}
3023
Emeric Brun94324a42012-10-11 14:00:19 +02003024/* prepare ssl context from servers options. Returns an error count */
3025int ssl_sock_prepare_srv_ctx(struct server *srv, struct proxy *curproxy)
3026{
3027 int cfgerr = 0;
Remi Gacogneaf5c3da2014-05-19 10:29:58 +02003028 long options =
Emeric Brun94324a42012-10-11 14:00:19 +02003029 SSL_OP_ALL | /* all known workarounds for bugs */
3030 SSL_OP_NO_SSLv2 |
3031 SSL_OP_NO_COMPRESSION;
Remi Gacogneaf5c3da2014-05-19 10:29:58 +02003032 long mode =
Emeric Brun94324a42012-10-11 14:00:19 +02003033 SSL_MODE_ENABLE_PARTIAL_WRITE |
3034 SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER |
Willy Tarreau396a1862014-11-13 14:06:52 +01003035 SSL_MODE_RELEASE_BUFFERS |
3036 SSL_MODE_SMALL_BUFFERS;
Emeric Brun850efd52014-01-29 12:24:34 +01003037 int verify = SSL_VERIFY_NONE;
Emeric Brun94324a42012-10-11 14:00:19 +02003038
Thierry Fournier383085f2013-01-24 14:15:43 +01003039 /* Make sure openssl opens /dev/urandom before the chroot */
3040 if (!ssl_initialize_random()) {
3041 Alert("OpenSSL random data generator initialization failed.\n");
3042 cfgerr++;
3043 }
3044
Willy Tarreaufce03112015-01-15 21:32:40 +01003045 /* Automatic memory computations need to know we use SSL there */
3046 global.ssl_used_backend = 1;
3047
3048 /* Initiate SSL context for current server */
Emeric Brun94324a42012-10-11 14:00:19 +02003049 srv->ssl_ctx.reused_sess = NULL;
3050 if (srv->use_ssl)
3051 srv->xprt = &ssl_sock;
3052 if (srv->check.use_ssl)
Cyril Bonté9ce13112014-11-15 22:41:27 +01003053 srv->check.xprt = &ssl_sock;
Emeric Brun94324a42012-10-11 14:00:19 +02003054
3055 srv->ssl_ctx.ctx = SSL_CTX_new(SSLv23_client_method());
3056 if (!srv->ssl_ctx.ctx) {
3057 Alert("config : %s '%s', server '%s': unable to allocate ssl context.\n",
3058 proxy_type_str(curproxy), curproxy->id,
3059 srv->id);
3060 cfgerr++;
3061 return cfgerr;
3062 }
Emeric Bruna7aa3092012-10-26 12:58:00 +02003063 if (srv->ssl_ctx.client_crt) {
3064 if (SSL_CTX_use_PrivateKey_file(srv->ssl_ctx.ctx, srv->ssl_ctx.client_crt, SSL_FILETYPE_PEM) <= 0) {
3065 Alert("config : %s '%s', server '%s': unable to load SSL private key from PEM file '%s'.\n",
3066 proxy_type_str(curproxy), curproxy->id,
3067 srv->id, srv->ssl_ctx.client_crt);
3068 cfgerr++;
3069 }
3070 else if (SSL_CTX_use_certificate_chain_file(srv->ssl_ctx.ctx, srv->ssl_ctx.client_crt) <= 0) {
3071 Alert("config : %s '%s', server '%s': unable to load ssl certificate from PEM file '%s'.\n",
3072 proxy_type_str(curproxy), curproxy->id,
3073 srv->id, srv->ssl_ctx.client_crt);
3074 cfgerr++;
3075 }
3076 else if (SSL_CTX_check_private_key(srv->ssl_ctx.ctx) <= 0) {
3077 Alert("config : %s '%s', server '%s': inconsistencies between private key and certificate loaded from PEM file '%s'.\n",
3078 proxy_type_str(curproxy), curproxy->id,
3079 srv->id, srv->ssl_ctx.client_crt);
3080 cfgerr++;
3081 }
3082 }
Emeric Brun94324a42012-10-11 14:00:19 +02003083
3084 if (srv->ssl_ctx.options & SRV_SSL_O_NO_SSLV3)
3085 options |= SSL_OP_NO_SSLv3;
3086 if (srv->ssl_ctx.options & SRV_SSL_O_NO_TLSV10)
3087 options |= SSL_OP_NO_TLSv1;
3088 if (srv->ssl_ctx.options & SRV_SSL_O_NO_TLSV11)
3089 options |= SSL_OP_NO_TLSv1_1;
3090 if (srv->ssl_ctx.options & SRV_SSL_O_NO_TLSV12)
3091 options |= SSL_OP_NO_TLSv1_2;
Emeric Brunf9c5c472012-10-11 15:28:34 +02003092 if (srv->ssl_ctx.options & SRV_SSL_O_NO_TLS_TICKETS)
3093 options |= SSL_OP_NO_TICKET;
Jérémie Courrèges-Anglas17c3f622015-07-25 16:50:52 -06003094 if (srv->ssl_ctx.options & SRV_SSL_O_USE_SSLV3) {
3095#ifndef OPENSSL_NO_SSL3
Emeric Brun94324a42012-10-11 14:00:19 +02003096 SSL_CTX_set_ssl_version(srv->ssl_ctx.ctx, SSLv3_client_method());
Jérémie Courrèges-Anglas17c3f622015-07-25 16:50:52 -06003097#else
Thierry FOURNIERbc965342015-08-26 08:21:26 +02003098 Alert("SSLv3 support requested but unavailable.\n");
Jérémie Courrèges-Anglas17c3f622015-07-25 16:50:52 -06003099 cfgerr++;
3100#endif
3101 }
Emeric Brun94324a42012-10-11 14:00:19 +02003102 if (srv->ssl_ctx.options & SRV_SSL_O_USE_TLSV10)
3103 SSL_CTX_set_ssl_version(srv->ssl_ctx.ctx, TLSv1_client_method());
3104#if SSL_OP_NO_TLSv1_1
3105 if (srv->ssl_ctx.options & SRV_SSL_O_USE_TLSV11)
3106 SSL_CTX_set_ssl_version(srv->ssl_ctx.ctx, TLSv1_1_client_method());
3107#endif
3108#if SSL_OP_NO_TLSv1_2
3109 if (srv->ssl_ctx.options & SRV_SSL_O_USE_TLSV12)
3110 SSL_CTX_set_ssl_version(srv->ssl_ctx.ctx, TLSv1_2_client_method());
3111#endif
3112
3113 SSL_CTX_set_options(srv->ssl_ctx.ctx, options);
3114 SSL_CTX_set_mode(srv->ssl_ctx.ctx, mode);
Emeric Brun850efd52014-01-29 12:24:34 +01003115
3116 if (global.ssl_server_verify == SSL_SERVER_VERIFY_REQUIRED)
3117 verify = SSL_VERIFY_PEER;
3118
3119 switch (srv->ssl_ctx.verify) {
3120 case SSL_SOCK_VERIFY_NONE:
3121 verify = SSL_VERIFY_NONE;
3122 break;
3123 case SSL_SOCK_VERIFY_REQUIRED:
3124 verify = SSL_VERIFY_PEER;
3125 break;
3126 }
Evan Broderbe554312013-06-27 00:05:25 -07003127 SSL_CTX_set_verify(srv->ssl_ctx.ctx,
Emeric Brun850efd52014-01-29 12:24:34 +01003128 verify,
Evan Broderbe554312013-06-27 00:05:25 -07003129 srv->ssl_ctx.verify_host ? ssl_sock_srv_verifycbk : NULL);
Emeric Brun850efd52014-01-29 12:24:34 +01003130 if (verify & SSL_VERIFY_PEER) {
Emeric Brunef42d922012-10-11 16:11:36 +02003131 if (srv->ssl_ctx.ca_file) {
3132 /* load CAfile to verify */
3133 if (!SSL_CTX_load_verify_locations(srv->ssl_ctx.ctx, srv->ssl_ctx.ca_file, NULL)) {
Willy Tarreau07ba08b2014-02-16 19:22:08 +01003134 Alert("Proxy '%s', server '%s' [%s:%d] unable to load CA file '%s'.\n",
Emeric Brunef42d922012-10-11 16:11:36 +02003135 curproxy->id, srv->id,
3136 srv->conf.file, srv->conf.line, srv->ssl_ctx.ca_file);
3137 cfgerr++;
3138 }
3139 }
Emeric Brun850efd52014-01-29 12:24:34 +01003140 else {
3141 if (global.ssl_server_verify == SSL_SERVER_VERIFY_REQUIRED)
Willy Tarreau07ba08b2014-02-16 19:22:08 +01003142 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 +01003143 curproxy->id, srv->id,
3144 srv->conf.file, srv->conf.line);
3145 else
Willy Tarreau07ba08b2014-02-16 19:22:08 +01003146 Alert("Proxy '%s', server '%s' [%s:%d] verify is enabled but no CA file specified.\n",
Emeric Brun850efd52014-01-29 12:24:34 +01003147 curproxy->id, srv->id,
3148 srv->conf.file, srv->conf.line);
3149 cfgerr++;
3150 }
Emeric Brunef42d922012-10-11 16:11:36 +02003151#ifdef X509_V_FLAG_CRL_CHECK
3152 if (srv->ssl_ctx.crl_file) {
3153 X509_STORE *store = SSL_CTX_get_cert_store(srv->ssl_ctx.ctx);
3154
3155 if (!store || !X509_STORE_load_locations(store, srv->ssl_ctx.crl_file, NULL)) {
Willy Tarreau07ba08b2014-02-16 19:22:08 +01003156 Alert("Proxy '%s', server '%s' [%s:%d] unable to configure CRL file '%s'.\n",
Emeric Brunef42d922012-10-11 16:11:36 +02003157 curproxy->id, srv->id,
3158 srv->conf.file, srv->conf.line, srv->ssl_ctx.crl_file);
3159 cfgerr++;
3160 }
3161 else {
3162 X509_STORE_set_flags(store, X509_V_FLAG_CRL_CHECK|X509_V_FLAG_CRL_CHECK_ALL);
3163 }
3164 }
3165#endif
3166 }
3167
Emeric Brun4f65bff2012-11-16 15:11:00 +01003168 if (global.tune.ssllifetime)
3169 SSL_CTX_set_timeout(srv->ssl_ctx.ctx, global.tune.ssllifetime);
3170
Emeric Brun94324a42012-10-11 14:00:19 +02003171 SSL_CTX_set_session_cache_mode(srv->ssl_ctx.ctx, SSL_SESS_CACHE_OFF);
3172 if (srv->ssl_ctx.ciphers &&
3173 !SSL_CTX_set_cipher_list(srv->ssl_ctx.ctx, srv->ssl_ctx.ciphers)) {
3174 Alert("Proxy '%s', server '%s' [%s:%d] : unable to set SSL cipher list to '%s'.\n",
3175 curproxy->id, srv->id,
3176 srv->conf.file, srv->conf.line, srv->ssl_ctx.ciphers);
3177 cfgerr++;
3178 }
3179
3180 return cfgerr;
3181}
3182
Willy Tarreau2a65ff02012-09-13 17:54:29 +02003183/* Walks down the two trees in bind_conf and prepares all certs. The pointer may
Emeric Brunfc0421f2012-09-07 17:30:07 +02003184 * be NULL, in which case nothing is done. Returns the number of errors
3185 * encountered.
3186 */
Willy Tarreau2a65ff02012-09-13 17:54:29 +02003187int ssl_sock_prepare_all_ctx(struct bind_conf *bind_conf, struct proxy *px)
Emeric Brunfc0421f2012-09-07 17:30:07 +02003188{
3189 struct ebmb_node *node;
3190 struct sni_ctx *sni;
3191 int err = 0;
3192
Willy Tarreau2a65ff02012-09-13 17:54:29 +02003193 if (!bind_conf || !bind_conf->is_ssl)
Emeric Brunfc0421f2012-09-07 17:30:07 +02003194 return 0;
3195
Willy Tarreaufce03112015-01-15 21:32:40 +01003196 /* Automatic memory computations need to know we use SSL there */
3197 global.ssl_used_frontend = 1;
3198
Emeric Brun0bed9942014-10-30 19:25:24 +01003199 if (bind_conf->default_ctx)
3200 err += ssl_sock_prepare_ctx(bind_conf, bind_conf->default_ctx, px);
3201
Willy Tarreau2a65ff02012-09-13 17:54:29 +02003202 node = ebmb_first(&bind_conf->sni_ctx);
Emeric Brunfc0421f2012-09-07 17:30:07 +02003203 while (node) {
3204 sni = ebmb_entry(node, struct sni_ctx, name);
Emeric Brun0bed9942014-10-30 19:25:24 +01003205 if (!sni->order && sni->ctx != bind_conf->default_ctx)
3206 /* only initialize the CTX on its first occurrence and
3207 if it is not the default_ctx */
Willy Tarreau2a65ff02012-09-13 17:54:29 +02003208 err += ssl_sock_prepare_ctx(bind_conf, sni->ctx, px);
Emeric Brunfc0421f2012-09-07 17:30:07 +02003209 node = ebmb_next(node);
3210 }
3211
Willy Tarreau2a65ff02012-09-13 17:54:29 +02003212 node = ebmb_first(&bind_conf->sni_w_ctx);
Emeric Brunfc0421f2012-09-07 17:30:07 +02003213 while (node) {
3214 sni = ebmb_entry(node, struct sni_ctx, name);
Emeric Brun0bed9942014-10-30 19:25:24 +01003215 if (!sni->order && sni->ctx != bind_conf->default_ctx)
3216 /* only initialize the CTX on its first occurrence and
3217 if it is not the default_ctx */
Willy Tarreau2a65ff02012-09-13 17:54:29 +02003218 err += ssl_sock_prepare_ctx(bind_conf, sni->ctx, px);
Emeric Brunfc0421f2012-09-07 17:30:07 +02003219 node = ebmb_next(node);
3220 }
3221 return err;
3222}
3223
Christopher Faulet77fe80c2015-07-29 13:02:40 +02003224
3225/* release ssl context allocated for servers. */
3226void ssl_sock_free_srv_ctx(struct server *srv)
3227{
3228 if (srv->ssl_ctx.ctx)
3229 SSL_CTX_free(srv->ssl_ctx.ctx);
3230}
3231
Willy Tarreau2a65ff02012-09-13 17:54:29 +02003232/* Walks down the two trees in bind_conf and frees all the certs. The pointer may
Emeric Brunfc0421f2012-09-07 17:30:07 +02003233 * be NULL, in which case nothing is done. The default_ctx is nullified too.
3234 */
Willy Tarreau2a65ff02012-09-13 17:54:29 +02003235void ssl_sock_free_all_ctx(struct bind_conf *bind_conf)
Emeric Brunfc0421f2012-09-07 17:30:07 +02003236{
3237 struct ebmb_node *node, *back;
3238 struct sni_ctx *sni;
3239
Willy Tarreau2a65ff02012-09-13 17:54:29 +02003240 if (!bind_conf || !bind_conf->is_ssl)
Emeric Brunfc0421f2012-09-07 17:30:07 +02003241 return;
3242
Willy Tarreau2a65ff02012-09-13 17:54:29 +02003243 node = ebmb_first(&bind_conf->sni_ctx);
Emeric Brunfc0421f2012-09-07 17:30:07 +02003244 while (node) {
3245 sni = ebmb_entry(node, struct sni_ctx, name);
3246 back = ebmb_next(node);
3247 ebmb_delete(node);
3248 if (!sni->order) /* only free the CTX on its first occurrence */
3249 SSL_CTX_free(sni->ctx);
3250 free(sni);
3251 node = back;
3252 }
3253
Willy Tarreau2a65ff02012-09-13 17:54:29 +02003254 node = ebmb_first(&bind_conf->sni_w_ctx);
Emeric Brunfc0421f2012-09-07 17:30:07 +02003255 while (node) {
3256 sni = ebmb_entry(node, struct sni_ctx, name);
3257 back = ebmb_next(node);
3258 ebmb_delete(node);
3259 if (!sni->order) /* only free the CTX on its first occurrence */
3260 SSL_CTX_free(sni->ctx);
3261 free(sni);
3262 node = back;
3263 }
3264
Willy Tarreau2a65ff02012-09-13 17:54:29 +02003265 bind_conf->default_ctx = NULL;
Emeric Brune1f38db2012-09-03 20:36:47 +02003266}
3267
Christopher Faulet31af49d2015-06-09 17:29:50 +02003268/* Load CA cert file and private key used to generate certificates */
3269int
3270ssl_sock_load_ca(struct bind_conf *bind_conf, struct proxy *px)
3271{
3272 FILE *fp;
3273 X509 *cacert = NULL;
3274 EVP_PKEY *capkey = NULL;
3275 int err = 0;
3276
3277 if (!bind_conf || !bind_conf->generate_certs)
3278 return err;
3279
Willy Tarreaua84c2672015-10-09 12:10:13 +02003280#ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME
Christopher Fauletd2cab922015-07-28 16:03:47 +02003281 if (global.tune.ssl_ctx_cache)
3282 ssl_ctx_lru_tree = lru64_new(global.tune.ssl_ctx_cache);
3283 ssl_ctx_lru_seed = (unsigned int)time(NULL);
Willy Tarreaua84c2672015-10-09 12:10:13 +02003284#endif
Christopher Fauletd2cab922015-07-28 16:03:47 +02003285
Christopher Faulet31af49d2015-06-09 17:29:50 +02003286 if (!bind_conf->ca_sign_file) {
3287 Alert("Proxy '%s': cannot enable certificate generation, "
3288 "no CA certificate File configured at [%s:%d].\n",
3289 px->id, bind_conf->file, bind_conf->line);
Christopher Faulet31af49d2015-06-09 17:29:50 +02003290 goto load_error;
Christopher Fauletc6f02fb2015-10-09 10:53:31 +02003291 }
Christopher Faulet31af49d2015-06-09 17:29:50 +02003292
3293 /* read in the CA certificate */
3294 if (!(fp = fopen(bind_conf->ca_sign_file, "r"))) {
3295 Alert("Proxy '%s': Failed to read CA certificate file '%s' at [%s:%d].\n",
3296 px->id, bind_conf->ca_sign_file, bind_conf->file, bind_conf->line);
Christopher Faulet31af49d2015-06-09 17:29:50 +02003297 goto load_error;
3298 }
3299 if (!(cacert = PEM_read_X509(fp, NULL, NULL, NULL))) {
3300 Alert("Proxy '%s': Failed to read CA certificate file '%s' at [%s:%d].\n",
3301 px->id, bind_conf->ca_sign_file, bind_conf->file, bind_conf->line);
Christopher Fauletc6f02fb2015-10-09 10:53:31 +02003302 goto read_error;
Christopher Faulet31af49d2015-06-09 17:29:50 +02003303 }
Christopher Fauletc6f02fb2015-10-09 10:53:31 +02003304 rewind(fp);
Christopher Faulet31af49d2015-06-09 17:29:50 +02003305 if (!(capkey = PEM_read_PrivateKey(fp, NULL, NULL, bind_conf->ca_sign_pass))) {
3306 Alert("Proxy '%s': Failed to read CA private key file '%s' at [%s:%d].\n",
3307 px->id, bind_conf->ca_sign_file, bind_conf->file, bind_conf->line);
Christopher Fauletc6f02fb2015-10-09 10:53:31 +02003308 goto read_error;
Christopher Faulet31af49d2015-06-09 17:29:50 +02003309 }
Christopher Faulet31af49d2015-06-09 17:29:50 +02003310
Christopher Fauletc6f02fb2015-10-09 10:53:31 +02003311 fclose (fp);
Christopher Faulet31af49d2015-06-09 17:29:50 +02003312 bind_conf->ca_sign_cert = cacert;
3313 bind_conf->ca_sign_pkey = capkey;
3314 return err;
3315
Christopher Fauletc6f02fb2015-10-09 10:53:31 +02003316 read_error:
3317 fclose (fp);
Christopher Faulet31af49d2015-06-09 17:29:50 +02003318 if (capkey) EVP_PKEY_free(capkey);
3319 if (cacert) X509_free(cacert);
Christopher Fauletc6f02fb2015-10-09 10:53:31 +02003320 load_error:
3321 bind_conf->generate_certs = 0;
3322 err++;
Christopher Faulet31af49d2015-06-09 17:29:50 +02003323 return err;
3324}
3325
3326/* Release CA cert and private key used to generate certificated */
3327void
3328ssl_sock_free_ca(struct bind_conf *bind_conf)
3329{
3330 if (!bind_conf)
3331 return;
3332
3333 if (bind_conf->ca_sign_pkey)
3334 EVP_PKEY_free(bind_conf->ca_sign_pkey);
3335 if (bind_conf->ca_sign_cert)
3336 X509_free(bind_conf->ca_sign_cert);
3337}
3338
Emeric Brun46591952012-05-18 15:47:34 +02003339/*
3340 * This function is called if SSL * context is not yet allocated. The function
3341 * is designed to be called before any other data-layer operation and sets the
3342 * handshake flag on the connection. It is safe to call it multiple times.
3343 * It returns 0 on success and -1 in error case.
3344 */
3345static int ssl_sock_init(struct connection *conn)
3346{
3347 /* already initialized */
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02003348 if (conn->xprt_ctx)
Emeric Brun46591952012-05-18 15:47:34 +02003349 return 0;
3350
Willy Tarreau3c728722014-01-23 13:50:42 +01003351 if (!conn_ctrl_ready(conn))
Willy Tarreauf79c8172013-10-21 16:30:56 +02003352 return 0;
3353
Willy Tarreau20879a02012-12-03 16:32:10 +01003354 if (global.maxsslconn && sslconns >= global.maxsslconn) {
3355 conn->err_code = CO_ER_SSL_TOO_MANY;
Willy Tarreau403edff2012-09-06 11:58:37 +02003356 return -1;
Willy Tarreau20879a02012-12-03 16:32:10 +01003357 }
Willy Tarreau403edff2012-09-06 11:58:37 +02003358
Emeric Brun46591952012-05-18 15:47:34 +02003359 /* If it is in client mode initiate SSL session
3360 in connect state otherwise accept state */
Willy Tarreau3fdb3662012-11-12 00:42:33 +01003361 if (objt_server(conn->target)) {
Willy Tarreaufba03cd2014-11-13 13:48:58 +01003362 int may_retry = 1;
3363
3364 retry_connect:
Emeric Brun46591952012-05-18 15:47:34 +02003365 /* Alloc a new SSL session ctx */
Willy Tarreau3fdb3662012-11-12 00:42:33 +01003366 conn->xprt_ctx = SSL_new(objt_server(conn->target)->ssl_ctx.ctx);
Willy Tarreau20879a02012-12-03 16:32:10 +01003367 if (!conn->xprt_ctx) {
Willy Tarreaufba03cd2014-11-13 13:48:58 +01003368 if (may_retry--) {
3369 pool_gc2();
3370 goto retry_connect;
3371 }
Willy Tarreau20879a02012-12-03 16:32:10 +01003372 conn->err_code = CO_ER_SSL_NO_MEM;
Emeric Brun46591952012-05-18 15:47:34 +02003373 return -1;
Willy Tarreau20879a02012-12-03 16:32:10 +01003374 }
Emeric Brun46591952012-05-18 15:47:34 +02003375
Emeric Brun46591952012-05-18 15:47:34 +02003376 /* set fd on SSL session context */
Emeric Brun55476152014-11-12 17:35:37 +01003377 if (!SSL_set_fd(conn->xprt_ctx, conn->t.sock.fd)) {
3378 SSL_free(conn->xprt_ctx);
3379 conn->xprt_ctx = NULL;
Willy Tarreaufba03cd2014-11-13 13:48:58 +01003380 if (may_retry--) {
3381 pool_gc2();
3382 goto retry_connect;
3383 }
Emeric Brun55476152014-11-12 17:35:37 +01003384 conn->err_code = CO_ER_SSL_NO_MEM;
3385 return -1;
3386 }
Emeric Brun46591952012-05-18 15:47:34 +02003387
Evan Broderbe554312013-06-27 00:05:25 -07003388 /* set connection pointer */
Emeric Brun55476152014-11-12 17:35:37 +01003389 if (!SSL_set_app_data(conn->xprt_ctx, conn)) {
3390 SSL_free(conn->xprt_ctx);
3391 conn->xprt_ctx = NULL;
Willy Tarreaufba03cd2014-11-13 13:48:58 +01003392 if (may_retry--) {
3393 pool_gc2();
3394 goto retry_connect;
3395 }
Emeric Brun55476152014-11-12 17:35:37 +01003396 conn->err_code = CO_ER_SSL_NO_MEM;
3397 return -1;
3398 }
3399
3400 SSL_set_connect_state(conn->xprt_ctx);
3401 if (objt_server(conn->target)->ssl_ctx.reused_sess) {
3402 if(!SSL_set_session(conn->xprt_ctx, objt_server(conn->target)->ssl_ctx.reused_sess)) {
3403 SSL_SESSION_free(objt_server(conn->target)->ssl_ctx.reused_sess);
3404 objt_server(conn->target)->ssl_ctx.reused_sess = NULL;
3405 }
3406 }
Evan Broderbe554312013-06-27 00:05:25 -07003407
Emeric Brun46591952012-05-18 15:47:34 +02003408 /* leave init state and start handshake */
Willy Tarreau05737472012-09-04 08:03:39 +02003409 conn->flags |= CO_FL_SSL_WAIT_HS | CO_FL_WAIT_L6_CONN;
Willy Tarreau403edff2012-09-06 11:58:37 +02003410
3411 sslconns++;
Willy Tarreau71b734c2014-01-28 15:19:44 +01003412 totalsslconns++;
Emeric Brun46591952012-05-18 15:47:34 +02003413 return 0;
3414 }
Willy Tarreau3fdb3662012-11-12 00:42:33 +01003415 else if (objt_listener(conn->target)) {
Willy Tarreaufba03cd2014-11-13 13:48:58 +01003416 int may_retry = 1;
3417
3418 retry_accept:
Emeric Brun46591952012-05-18 15:47:34 +02003419 /* Alloc a new SSL session ctx */
Willy Tarreau3fdb3662012-11-12 00:42:33 +01003420 conn->xprt_ctx = SSL_new(objt_listener(conn->target)->bind_conf->default_ctx);
Willy Tarreau20879a02012-12-03 16:32:10 +01003421 if (!conn->xprt_ctx) {
Willy Tarreaufba03cd2014-11-13 13:48:58 +01003422 if (may_retry--) {
3423 pool_gc2();
3424 goto retry_accept;
3425 }
Willy Tarreau20879a02012-12-03 16:32:10 +01003426 conn->err_code = CO_ER_SSL_NO_MEM;
Emeric Brun46591952012-05-18 15:47:34 +02003427 return -1;
Willy Tarreau20879a02012-12-03 16:32:10 +01003428 }
Emeric Brun46591952012-05-18 15:47:34 +02003429
Emeric Brun46591952012-05-18 15:47:34 +02003430 /* set fd on SSL session context */
Emeric Brun55476152014-11-12 17:35:37 +01003431 if (!SSL_set_fd(conn->xprt_ctx, conn->t.sock.fd)) {
3432 SSL_free(conn->xprt_ctx);
3433 conn->xprt_ctx = NULL;
Willy Tarreaufba03cd2014-11-13 13:48:58 +01003434 if (may_retry--) {
3435 pool_gc2();
3436 goto retry_accept;
3437 }
Emeric Brun55476152014-11-12 17:35:37 +01003438 conn->err_code = CO_ER_SSL_NO_MEM;
3439 return -1;
3440 }
Emeric Brun46591952012-05-18 15:47:34 +02003441
Emeric Brune1f38db2012-09-03 20:36:47 +02003442 /* set connection pointer */
Emeric Brun55476152014-11-12 17:35:37 +01003443 if (!SSL_set_app_data(conn->xprt_ctx, conn)) {
3444 SSL_free(conn->xprt_ctx);
3445 conn->xprt_ctx = NULL;
Willy Tarreaufba03cd2014-11-13 13:48:58 +01003446 if (may_retry--) {
3447 pool_gc2();
3448 goto retry_accept;
3449 }
Emeric Brun55476152014-11-12 17:35:37 +01003450 conn->err_code = CO_ER_SSL_NO_MEM;
3451 return -1;
3452 }
3453
3454 SSL_set_accept_state(conn->xprt_ctx);
Emeric Brune1f38db2012-09-03 20:36:47 +02003455
Emeric Brun46591952012-05-18 15:47:34 +02003456 /* leave init state and start handshake */
Willy Tarreau05737472012-09-04 08:03:39 +02003457 conn->flags |= CO_FL_SSL_WAIT_HS | CO_FL_WAIT_L6_CONN;
Willy Tarreau403edff2012-09-06 11:58:37 +02003458
3459 sslconns++;
Willy Tarreau71b734c2014-01-28 15:19:44 +01003460 totalsslconns++;
Emeric Brun46591952012-05-18 15:47:34 +02003461 return 0;
3462 }
3463 /* don't know how to handle such a target */
Willy Tarreau20879a02012-12-03 16:32:10 +01003464 conn->err_code = CO_ER_SSL_NO_TARGET;
Emeric Brun46591952012-05-18 15:47:34 +02003465 return -1;
3466}
3467
3468
3469/* This is the callback which is used when an SSL handshake is pending. It
3470 * updates the FD status if it wants some polling before being called again.
3471 * It returns 0 if it fails in a fatal way or needs to poll to go further,
3472 * otherwise it returns non-zero and removes itself from the connection's
3473 * flags (the bit is provided in <flag> by the caller).
3474 */
3475int ssl_sock_handshake(struct connection *conn, unsigned int flag)
3476{
3477 int ret;
3478
Willy Tarreau3c728722014-01-23 13:50:42 +01003479 if (!conn_ctrl_ready(conn))
Willy Tarreauf79c8172013-10-21 16:30:56 +02003480 return 0;
3481
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02003482 if (!conn->xprt_ctx)
Emeric Brun46591952012-05-18 15:47:34 +02003483 goto out_error;
3484
Emeric Brun674b7432012-11-08 19:21:55 +01003485 /* If we use SSL_do_handshake to process a reneg initiated by
3486 * the remote peer, it sometimes returns SSL_ERROR_SSL.
3487 * Usually SSL_write and SSL_read are used and process implicitly
3488 * the reneg handshake.
3489 * Here we use SSL_peek as a workaround for reneg.
3490 */
3491 if ((conn->flags & CO_FL_CONNECTED) && SSL_renegotiate_pending(conn->xprt_ctx)) {
3492 char c;
3493
3494 ret = SSL_peek(conn->xprt_ctx, &c, 1);
3495 if (ret <= 0) {
3496 /* handshake may have not been completed, let's find why */
3497 ret = SSL_get_error(conn->xprt_ctx, ret);
3498 if (ret == SSL_ERROR_WANT_WRITE) {
3499 /* SSL handshake needs to write, L4 connection may not be ready */
3500 __conn_sock_stop_recv(conn);
Willy Tarreaue1f50c42014-01-22 20:02:06 +01003501 __conn_sock_want_send(conn);
3502 fd_cant_send(conn->t.sock.fd);
Emeric Brun674b7432012-11-08 19:21:55 +01003503 return 0;
3504 }
3505 else if (ret == SSL_ERROR_WANT_READ) {
3506 /* handshake may have been completed but we have
3507 * no more data to read.
3508 */
3509 if (!SSL_renegotiate_pending(conn->xprt_ctx)) {
3510 ret = 1;
3511 goto reneg_ok;
3512 }
3513 /* SSL handshake needs to read, L4 connection is ready */
3514 if (conn->flags & CO_FL_WAIT_L4_CONN)
3515 conn->flags &= ~CO_FL_WAIT_L4_CONN;
3516 __conn_sock_stop_send(conn);
Willy Tarreaue1f50c42014-01-22 20:02:06 +01003517 __conn_sock_want_recv(conn);
3518 fd_cant_recv(conn->t.sock.fd);
Emeric Brun674b7432012-11-08 19:21:55 +01003519 return 0;
3520 }
3521 else if (ret == SSL_ERROR_SYSCALL) {
3522 /* if errno is null, then connection was successfully established */
3523 if (!errno && conn->flags & CO_FL_WAIT_L4_CONN)
3524 conn->flags &= ~CO_FL_WAIT_L4_CONN;
Willy Tarreau20879a02012-12-03 16:32:10 +01003525 if (!conn->err_code) {
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02003526 int empty_handshake;
Luca Pizzamiglio578b1692016-12-12 10:56:56 +01003527#if (OPENSSL_VERSION_NUMBER >= 0x1010000fL) && !defined(LIBRESSL_VERSION_NUMBER)
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02003528 OSSL_HANDSHAKE_STATE state = SSL_get_state((SSL *)conn->xprt_ctx);
3529 empty_handshake = state == TLS_ST_BEFORE;
3530#else
3531 empty_handshake = !((SSL *)conn->xprt_ctx)->packet_length;
3532#endif
3533
3534 if (empty_handshake) {
Emeric Brun29f037d2014-04-25 19:05:36 +02003535 if (!errno) {
3536 if (conn->xprt_st & SSL_SOCK_RECV_HEARTBEAT)
3537 conn->err_code = CO_ER_SSL_HANDSHAKE_HB;
3538 else
3539 conn->err_code = CO_ER_SSL_EMPTY;
3540 }
3541 else {
3542 if (conn->xprt_st & SSL_SOCK_RECV_HEARTBEAT)
3543 conn->err_code = CO_ER_SSL_HANDSHAKE_HB;
3544 else
3545 conn->err_code = CO_ER_SSL_ABORT;
3546 }
3547 }
3548 else {
3549 if (conn->xprt_st & SSL_SOCK_RECV_HEARTBEAT)
3550 conn->err_code = CO_ER_SSL_HANDSHAKE_HB;
Willy Tarreau20879a02012-12-03 16:32:10 +01003551 else
Emeric Brun29f037d2014-04-25 19:05:36 +02003552 conn->err_code = CO_ER_SSL_HANDSHAKE;
3553 }
Willy Tarreau20879a02012-12-03 16:32:10 +01003554 }
Emeric Brun674b7432012-11-08 19:21:55 +01003555 goto out_error;
3556 }
3557 else {
3558 /* Fail on all other handshake errors */
3559 /* Note: OpenSSL may leave unread bytes in the socket's
3560 * buffer, causing an RST to be emitted upon close() on
3561 * TCP sockets. We first try to drain possibly pending
3562 * data to avoid this as much as possible.
3563 */
Willy Tarreaud85c4852015-03-13 00:40:28 +01003564 conn_sock_drain(conn);
Willy Tarreau20879a02012-12-03 16:32:10 +01003565 if (!conn->err_code)
Willy Tarreauf51c6982014-04-25 20:02:39 +02003566 conn->err_code = (conn->xprt_st & SSL_SOCK_RECV_HEARTBEAT) ?
3567 CO_ER_SSL_KILLED_HB : CO_ER_SSL_HANDSHAKE;
Emeric Brun674b7432012-11-08 19:21:55 +01003568 goto out_error;
3569 }
3570 }
3571 /* read some data: consider handshake completed */
3572 goto reneg_ok;
3573 }
3574
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02003575 ret = SSL_do_handshake(conn->xprt_ctx);
Emeric Brun46591952012-05-18 15:47:34 +02003576 if (ret != 1) {
3577 /* handshake did not complete, let's find why */
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02003578 ret = SSL_get_error(conn->xprt_ctx, ret);
Emeric Brun46591952012-05-18 15:47:34 +02003579
3580 if (ret == SSL_ERROR_WANT_WRITE) {
3581 /* SSL handshake needs to write, L4 connection may not be ready */
3582 __conn_sock_stop_recv(conn);
Willy Tarreaue1f50c42014-01-22 20:02:06 +01003583 __conn_sock_want_send(conn);
3584 fd_cant_send(conn->t.sock.fd);
Emeric Brun46591952012-05-18 15:47:34 +02003585 return 0;
3586 }
3587 else if (ret == SSL_ERROR_WANT_READ) {
3588 /* SSL handshake needs to read, L4 connection is ready */
3589 if (conn->flags & CO_FL_WAIT_L4_CONN)
3590 conn->flags &= ~CO_FL_WAIT_L4_CONN;
3591 __conn_sock_stop_send(conn);
Willy Tarreaue1f50c42014-01-22 20:02:06 +01003592 __conn_sock_want_recv(conn);
3593 fd_cant_recv(conn->t.sock.fd);
Emeric Brun46591952012-05-18 15:47:34 +02003594 return 0;
3595 }
Willy Tarreau89230192012-09-28 20:22:13 +02003596 else if (ret == SSL_ERROR_SYSCALL) {
Luca Pizzamiglio578b1692016-12-12 10:56:56 +01003597#if (OPENSSL_VERSION_NUMBER >= 0x1010000fL) && !defined(LIBRESSL_VERSION_NUMBER)
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02003598 OSSL_HANDSHAKE_STATE state;
3599#endif
3600 int empty_handshake;
Willy Tarreau89230192012-09-28 20:22:13 +02003601 /* if errno is null, then connection was successfully established */
3602 if (!errno && conn->flags & CO_FL_WAIT_L4_CONN)
3603 conn->flags &= ~CO_FL_WAIT_L4_CONN;
Willy Tarreau20879a02012-12-03 16:32:10 +01003604
Luca Pizzamiglio578b1692016-12-12 10:56:56 +01003605#if (OPENSSL_VERSION_NUMBER >= 0x1010000fL) && !defined(LIBRESSL_VERSION_NUMBER)
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02003606 state = SSL_get_state((SSL *)conn->xprt_ctx);
3607 empty_handshake = state == TLS_ST_BEFORE;
3608#else
3609 empty_handshake = !((SSL *)conn->xprt_ctx)->packet_length;
3610#endif
3611 if (empty_handshake) {
Emeric Brun29f037d2014-04-25 19:05:36 +02003612 if (!errno) {
3613 if (conn->xprt_st & SSL_SOCK_RECV_HEARTBEAT)
3614 conn->err_code = CO_ER_SSL_HANDSHAKE_HB;
3615 else
3616 conn->err_code = CO_ER_SSL_EMPTY;
3617 }
3618 else {
3619 if (conn->xprt_st & SSL_SOCK_RECV_HEARTBEAT)
3620 conn->err_code = CO_ER_SSL_HANDSHAKE_HB;
3621 else
3622 conn->err_code = CO_ER_SSL_ABORT;
3623 }
3624 }
3625 else {
3626 if (conn->xprt_st & SSL_SOCK_RECV_HEARTBEAT)
3627 conn->err_code = CO_ER_SSL_HANDSHAKE_HB;
Willy Tarreau20879a02012-12-03 16:32:10 +01003628 else
Emeric Brun29f037d2014-04-25 19:05:36 +02003629 conn->err_code = CO_ER_SSL_HANDSHAKE;
3630 }
Willy Tarreau89230192012-09-28 20:22:13 +02003631 goto out_error;
3632 }
Emeric Brun46591952012-05-18 15:47:34 +02003633 else {
3634 /* Fail on all other handshake errors */
Willy Tarreau566dc552012-10-19 20:52:18 +02003635 /* Note: OpenSSL may leave unread bytes in the socket's
3636 * buffer, causing an RST to be emitted upon close() on
3637 * TCP sockets. We first try to drain possibly pending
3638 * data to avoid this as much as possible.
3639 */
Willy Tarreaud85c4852015-03-13 00:40:28 +01003640 conn_sock_drain(conn);
Willy Tarreau20879a02012-12-03 16:32:10 +01003641 if (!conn->err_code)
Willy Tarreauf51c6982014-04-25 20:02:39 +02003642 conn->err_code = (conn->xprt_st & SSL_SOCK_RECV_HEARTBEAT) ?
3643 CO_ER_SSL_KILLED_HB : CO_ER_SSL_HANDSHAKE;
Emeric Brun46591952012-05-18 15:47:34 +02003644 goto out_error;
3645 }
3646 }
3647
Emeric Brun674b7432012-11-08 19:21:55 +01003648reneg_ok:
Emeric Brun46591952012-05-18 15:47:34 +02003649 /* Handshake succeeded */
Willy Tarreau0c9c2722014-05-28 12:28:58 +02003650 if (!SSL_session_reused(conn->xprt_ctx)) {
3651 if (objt_server(conn->target)) {
3652 update_freq_ctr(&global.ssl_be_keys_per_sec, 1);
3653 if (global.ssl_be_keys_per_sec.curr_ctr > global.ssl_be_keys_max)
3654 global.ssl_be_keys_max = global.ssl_be_keys_per_sec.curr_ctr;
3655
Emeric Brun46591952012-05-18 15:47:34 +02003656 /* check if session was reused, if not store current session on server for reuse */
Willy Tarreau3fdb3662012-11-12 00:42:33 +01003657 if (objt_server(conn->target)->ssl_ctx.reused_sess)
3658 SSL_SESSION_free(objt_server(conn->target)->ssl_ctx.reused_sess);
Emeric Brun46591952012-05-18 15:47:34 +02003659
Willy Tarreau2a3fb1c2015-02-05 16:47:07 +01003660 if (!(objt_server(conn->target)->ssl_ctx.options & SRV_SSL_O_NO_REUSE))
3661 objt_server(conn->target)->ssl_ctx.reused_sess = SSL_get1_session(conn->xprt_ctx);
Emeric Brun46591952012-05-18 15:47:34 +02003662 }
Willy Tarreau0c9c2722014-05-28 12:28:58 +02003663 else {
3664 update_freq_ctr(&global.ssl_fe_keys_per_sec, 1);
3665 if (global.ssl_fe_keys_per_sec.curr_ctr > global.ssl_fe_keys_max)
3666 global.ssl_fe_keys_max = global.ssl_fe_keys_per_sec.curr_ctr;
3667 }
Emeric Brun46591952012-05-18 15:47:34 +02003668 }
3669
3670 /* The connection is now established at both layers, it's time to leave */
3671 conn->flags &= ~(flag | CO_FL_WAIT_L4_CONN | CO_FL_WAIT_L6_CONN);
3672 return 1;
3673
3674 out_error:
Emeric Brun644cde02012-12-14 11:21:13 +01003675 /* Clear openssl global errors stack */
Thierry FOURNIER / OZON.IO8b068c22016-10-10 11:59:50 +02003676 ssl_sock_dump_errors(conn);
Emeric Brun644cde02012-12-14 11:21:13 +01003677 ERR_clear_error();
3678
Emeric Brun9fa89732012-10-04 17:09:56 +02003679 /* free resumed session if exists */
Willy Tarreau3fdb3662012-11-12 00:42:33 +01003680 if (objt_server(conn->target) && objt_server(conn->target)->ssl_ctx.reused_sess) {
3681 SSL_SESSION_free(objt_server(conn->target)->ssl_ctx.reused_sess);
3682 objt_server(conn->target)->ssl_ctx.reused_sess = NULL;
Emeric Brun9fa89732012-10-04 17:09:56 +02003683 }
3684
Emeric Brun46591952012-05-18 15:47:34 +02003685 /* Fail on all other handshake errors */
3686 conn->flags |= CO_FL_ERROR;
Willy Tarreau20879a02012-12-03 16:32:10 +01003687 if (!conn->err_code)
3688 conn->err_code = CO_ER_SSL_HANDSHAKE;
Emeric Brun46591952012-05-18 15:47:34 +02003689 return 0;
3690}
3691
3692/* Receive up to <count> bytes from connection <conn>'s socket and store them
Willy Tarreauabf08d92014-01-14 11:31:27 +01003693 * into buffer <buf>. Only one call to recv() is performed, unless the
Emeric Brun46591952012-05-18 15:47:34 +02003694 * buffer wraps, in which case a second call may be performed. The connection's
3695 * flags are updated with whatever special event is detected (error, read0,
3696 * empty). The caller is responsible for taking care of those events and
3697 * avoiding the call if inappropriate. The function does not call the
3698 * connection's polling update function, so the caller is responsible for this.
3699 */
3700static int ssl_sock_to_buf(struct connection *conn, struct buffer *buf, int count)
3701{
3702 int ret, done = 0;
Willy Tarreauabf08d92014-01-14 11:31:27 +01003703 int try;
Emeric Brun46591952012-05-18 15:47:34 +02003704
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02003705 if (!conn->xprt_ctx)
Emeric Brun46591952012-05-18 15:47:34 +02003706 goto out_error;
3707
3708 if (conn->flags & CO_FL_HANDSHAKE)
3709 /* a handshake was requested */
3710 return 0;
3711
Willy Tarreauabf08d92014-01-14 11:31:27 +01003712 /* let's realign the buffer to optimize I/O */
3713 if (buffer_empty(buf))
Emeric Brun46591952012-05-18 15:47:34 +02003714 buf->p = buf->data;
Emeric Brun46591952012-05-18 15:47:34 +02003715
3716 /* read the largest possible block. For this, we perform only one call
3717 * to recv() unless the buffer wraps and we exactly fill the first hunk,
3718 * in which case we accept to do it once again. A new attempt is made on
3719 * EINTR too.
3720 */
Willy Tarreau00b0fb92014-01-17 11:09:40 +01003721 while (count > 0) {
Willy Tarreauabf08d92014-01-14 11:31:27 +01003722 /* first check if we have some room after p+i */
3723 try = buf->data + buf->size - (buf->p + buf->i);
3724 /* otherwise continue between data and p-o */
3725 if (try <= 0) {
3726 try = buf->p - (buf->data + buf->o);
3727 if (try <= 0)
3728 break;
3729 }
3730 if (try > count)
3731 try = count;
3732
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02003733 ret = SSL_read(conn->xprt_ctx, bi_end(buf), try);
Emeric Brune1f38db2012-09-03 20:36:47 +02003734 if (conn->flags & CO_FL_ERROR) {
3735 /* CO_FL_ERROR may be set by ssl_sock_infocbk */
Emeric Brun644cde02012-12-14 11:21:13 +01003736 goto out_error;
Emeric Brune1f38db2012-09-03 20:36:47 +02003737 }
Emeric Brun46591952012-05-18 15:47:34 +02003738 if (ret > 0) {
3739 buf->i += ret;
3740 done += ret;
3741 if (ret < try)
3742 break;
3743 count -= ret;
Emeric Brun46591952012-05-18 15:47:34 +02003744 }
3745 else if (ret == 0) {
Emeric Brun644cde02012-12-14 11:21:13 +01003746 ret = SSL_get_error(conn->xprt_ctx, ret);
3747 if (ret != SSL_ERROR_ZERO_RETURN) {
Emeric Brun1c646862012-12-14 12:33:41 +01003748 /* error on protocol or underlying transport */
3749 if ((ret != SSL_ERROR_SYSCALL)
3750 || (errno && (errno != EAGAIN)))
3751 conn->flags |= CO_FL_ERROR;
3752
Emeric Brun644cde02012-12-14 11:21:13 +01003753 /* Clear openssl global errors stack */
Thierry FOURNIER / OZON.IO8b068c22016-10-10 11:59:50 +02003754 ssl_sock_dump_errors(conn);
Emeric Brun644cde02012-12-14 11:21:13 +01003755 ERR_clear_error();
3756 }
Emeric Brun46591952012-05-18 15:47:34 +02003757 goto read0;
3758 }
3759 else {
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02003760 ret = SSL_get_error(conn->xprt_ctx, ret);
Emeric Brun46591952012-05-18 15:47:34 +02003761 if (ret == SSL_ERROR_WANT_WRITE) {
Emeric Brun8af8dd12012-11-08 17:56:20 +01003762 /* handshake is running, and it needs to enable write */
Emeric Brun46591952012-05-18 15:47:34 +02003763 conn->flags |= CO_FL_SSL_WAIT_HS;
Emeric Brun8af8dd12012-11-08 17:56:20 +01003764 __conn_sock_want_send(conn);
Emeric Brun46591952012-05-18 15:47:34 +02003765 break;
3766 }
3767 else if (ret == SSL_ERROR_WANT_READ) {
Emeric Brun282a76a2012-11-08 18:02:56 +01003768 if (SSL_renegotiate_pending(conn->xprt_ctx)) {
3769 /* handshake is running, and it may need to re-enable read */
3770 conn->flags |= CO_FL_SSL_WAIT_HS;
3771 __conn_sock_want_recv(conn);
3772 break;
3773 }
Emeric Brun46591952012-05-18 15:47:34 +02003774 /* we need to poll for retry a read later */
Willy Tarreaue1f50c42014-01-22 20:02:06 +01003775 fd_cant_recv(conn->t.sock.fd);
Emeric Brun46591952012-05-18 15:47:34 +02003776 break;
3777 }
3778 /* otherwise it's a real error */
3779 goto out_error;
3780 }
3781 }
3782 return done;
3783
3784 read0:
3785 conn_sock_read0(conn);
3786 return done;
3787 out_error:
Emeric Brun644cde02012-12-14 11:21:13 +01003788 /* Clear openssl global errors stack */
Thierry FOURNIER / OZON.IO8b068c22016-10-10 11:59:50 +02003789 ssl_sock_dump_errors(conn);
Emeric Brun644cde02012-12-14 11:21:13 +01003790 ERR_clear_error();
3791
Emeric Brun46591952012-05-18 15:47:34 +02003792 conn->flags |= CO_FL_ERROR;
3793 return done;
3794}
3795
3796
3797/* Send all pending bytes from buffer <buf> to connection <conn>'s socket.
Willy Tarreau1049b1f2014-02-02 01:51:17 +01003798 * <flags> may contain some CO_SFL_* flags to hint the system about other
3799 * pending data for example, but this flag is ignored at the moment.
Emeric Brun46591952012-05-18 15:47:34 +02003800 * Only one call to send() is performed, unless the buffer wraps, in which case
3801 * a second call may be performed. The connection's flags are updated with
3802 * whatever special event is detected (error, empty). The caller is responsible
3803 * for taking care of those events and avoiding the call if inappropriate. The
3804 * function does not call the connection's polling update function, so the caller
3805 * is responsible for this.
3806 */
3807static int ssl_sock_from_buf(struct connection *conn, struct buffer *buf, int flags)
3808{
3809 int ret, try, done;
3810
3811 done = 0;
3812
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02003813 if (!conn->xprt_ctx)
Emeric Brun46591952012-05-18 15:47:34 +02003814 goto out_error;
3815
3816 if (conn->flags & CO_FL_HANDSHAKE)
3817 /* a handshake was requested */
3818 return 0;
3819
3820 /* send the largest possible block. For this we perform only one call
3821 * to send() unless the buffer wraps and we exactly fill the first hunk,
3822 * in which case we accept to do it once again.
3823 */
3824 while (buf->o) {
Kevin Hestercad82342013-05-30 15:12:41 -07003825 try = bo_contig_data(buf);
Willy Tarreaubfd59462013-02-21 07:46:09 +01003826
Willy Tarreau7bed9452014-02-02 02:00:24 +01003827 if (!(flags & CO_SFL_STREAMER) &&
Willy Tarreau518cedd2014-02-17 15:43:01 +01003828 !(conn->xprt_st & SSL_SOCK_SEND_UNLIMITED) &&
3829 global.tune.ssl_max_record && try > global.tune.ssl_max_record) {
Willy Tarreaubfd59462013-02-21 07:46:09 +01003830 try = global.tune.ssl_max_record;
Willy Tarreau518cedd2014-02-17 15:43:01 +01003831 }
3832 else {
3833 /* we need to keep the information about the fact that
3834 * we're not limiting the upcoming send(), because if it
3835 * fails, we'll have to retry with at least as many data.
3836 */
3837 conn->xprt_st |= SSL_SOCK_SEND_UNLIMITED;
3838 }
Willy Tarreaubfd59462013-02-21 07:46:09 +01003839
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02003840 ret = SSL_write(conn->xprt_ctx, bo_ptr(buf), try);
Willy Tarreau518cedd2014-02-17 15:43:01 +01003841
Emeric Brune1f38db2012-09-03 20:36:47 +02003842 if (conn->flags & CO_FL_ERROR) {
3843 /* CO_FL_ERROR may be set by ssl_sock_infocbk */
Emeric Brun644cde02012-12-14 11:21:13 +01003844 goto out_error;
Emeric Brune1f38db2012-09-03 20:36:47 +02003845 }
Emeric Brun46591952012-05-18 15:47:34 +02003846 if (ret > 0) {
Willy Tarreau518cedd2014-02-17 15:43:01 +01003847 conn->xprt_st &= ~SSL_SOCK_SEND_UNLIMITED;
3848
Emeric Brun46591952012-05-18 15:47:34 +02003849 buf->o -= ret;
3850 done += ret;
3851
Willy Tarreau5fb38032012-12-16 19:39:09 +01003852 if (likely(buffer_empty(buf)))
Emeric Brun46591952012-05-18 15:47:34 +02003853 /* optimize data alignment in the buffer */
3854 buf->p = buf->data;
3855
3856 /* if the system buffer is full, don't insist */
3857 if (ret < try)
3858 break;
3859 }
3860 else {
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02003861 ret = SSL_get_error(conn->xprt_ctx, ret);
Emeric Brun46591952012-05-18 15:47:34 +02003862 if (ret == SSL_ERROR_WANT_WRITE) {
Emeric Brun282a76a2012-11-08 18:02:56 +01003863 if (SSL_renegotiate_pending(conn->xprt_ctx)) {
3864 /* handshake is running, and it may need to re-enable write */
3865 conn->flags |= CO_FL_SSL_WAIT_HS;
3866 __conn_sock_want_send(conn);
3867 break;
3868 }
Emeric Brun46591952012-05-18 15:47:34 +02003869 /* we need to poll to retry a write later */
Willy Tarreaue1f50c42014-01-22 20:02:06 +01003870 fd_cant_send(conn->t.sock.fd);
Emeric Brun46591952012-05-18 15:47:34 +02003871 break;
3872 }
3873 else if (ret == SSL_ERROR_WANT_READ) {
Emeric Brun8af8dd12012-11-08 17:56:20 +01003874 /* handshake is running, and it needs to enable read */
Emeric Brun46591952012-05-18 15:47:34 +02003875 conn->flags |= CO_FL_SSL_WAIT_HS;
Emeric Brun8af8dd12012-11-08 17:56:20 +01003876 __conn_sock_want_recv(conn);
Emeric Brun46591952012-05-18 15:47:34 +02003877 break;
3878 }
3879 goto out_error;
3880 }
3881 }
3882 return done;
3883
3884 out_error:
Emeric Brun644cde02012-12-14 11:21:13 +01003885 /* Clear openssl global errors stack */
Thierry FOURNIER / OZON.IO8b068c22016-10-10 11:59:50 +02003886 ssl_sock_dump_errors(conn);
Emeric Brun644cde02012-12-14 11:21:13 +01003887 ERR_clear_error();
3888
Emeric Brun46591952012-05-18 15:47:34 +02003889 conn->flags |= CO_FL_ERROR;
3890 return done;
3891}
3892
Emeric Brun46591952012-05-18 15:47:34 +02003893static void ssl_sock_close(struct connection *conn) {
3894
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02003895 if (conn->xprt_ctx) {
3896 SSL_free(conn->xprt_ctx);
3897 conn->xprt_ctx = NULL;
Willy Tarreau403edff2012-09-06 11:58:37 +02003898 sslconns--;
Emeric Brun46591952012-05-18 15:47:34 +02003899 }
Emeric Brun46591952012-05-18 15:47:34 +02003900}
3901
3902/* This function tries to perform a clean shutdown on an SSL connection, and in
3903 * any case, flags the connection as reusable if no handshake was in progress.
3904 */
3905static void ssl_sock_shutw(struct connection *conn, int clean)
3906{
3907 if (conn->flags & CO_FL_HANDSHAKE)
3908 return;
3909 /* no handshake was in progress, try a clean ssl shutdown */
Emeric Brun644cde02012-12-14 11:21:13 +01003910 if (clean && (SSL_shutdown(conn->xprt_ctx) <= 0)) {
3911 /* Clear openssl global errors stack */
Thierry FOURNIER / OZON.IO8b068c22016-10-10 11:59:50 +02003912 ssl_sock_dump_errors(conn);
Emeric Brun644cde02012-12-14 11:21:13 +01003913 ERR_clear_error();
3914 }
Emeric Brun46591952012-05-18 15:47:34 +02003915
3916 /* force flag on ssl to keep session in cache regardless shutdown result */
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02003917 SSL_set_shutdown(conn->xprt_ctx, SSL_SENT_SHUTDOWN);
Emeric Brun46591952012-05-18 15:47:34 +02003918}
3919
Willy Tarreauffc3fcd2012-10-12 20:17:54 +02003920/* used for logging, may be changed for a sample fetch later */
3921const char *ssl_sock_get_cipher_name(struct connection *conn)
3922{
3923 if (!conn->xprt && !conn->xprt_ctx)
3924 return NULL;
3925 return SSL_get_cipher_name(conn->xprt_ctx);
3926}
3927
3928/* used for logging, may be changed for a sample fetch later */
3929const char *ssl_sock_get_proto_version(struct connection *conn)
3930{
3931 if (!conn->xprt && !conn->xprt_ctx)
3932 return NULL;
3933 return SSL_get_version(conn->xprt_ctx);
3934}
3935
Willy Tarreau8d598402012-10-22 17:58:39 +02003936/* Extract a serial from a cert, and copy it to a chunk.
3937 * Returns 1 if serial is found and copied, 0 if no serial found and
3938 * -1 if output is not large enough.
3939 */
3940static int
3941ssl_sock_get_serial(X509 *crt, struct chunk *out)
3942{
3943 ASN1_INTEGER *serial;
3944
3945 serial = X509_get_serialNumber(crt);
3946 if (!serial)
3947 return 0;
3948
3949 if (out->size < serial->length)
3950 return -1;
3951
3952 memcpy(out->str, serial->data, serial->length);
3953 out->len = serial->length;
3954 return 1;
3955}
3956
Emeric Brun43e79582014-10-29 19:03:26 +01003957/* Extract a cert to der, and copy it to a chunk.
3958 * Returns 1 if cert is found and copied, 0 on der convertion failure and
3959 * -1 if output is not large enough.
3960 */
3961static int
3962ssl_sock_crt2der(X509 *crt, struct chunk *out)
3963{
3964 int len;
3965 unsigned char *p = (unsigned char *)out->str;;
3966
3967 len =i2d_X509(crt, NULL);
3968 if (len <= 0)
3969 return 1;
3970
3971 if (out->size < len)
3972 return -1;
3973
3974 i2d_X509(crt,&p);
3975 out->len = len;
3976 return 1;
3977}
3978
Emeric Brunce5ad802012-10-22 14:11:22 +02003979
3980/* Copy Date in ASN1_UTCTIME format in struct chunk out.
3981 * Returns 1 if serial is found and copied, 0 if no valid time found
3982 * and -1 if output is not large enough.
3983 */
3984static int
3985ssl_sock_get_time(ASN1_TIME *tm, struct chunk *out)
3986{
3987 if (tm->type == V_ASN1_GENERALIZEDTIME) {
3988 ASN1_GENERALIZEDTIME *gentm = (ASN1_GENERALIZEDTIME *)tm;
3989
3990 if (gentm->length < 12)
3991 return 0;
3992 if (gentm->data[0] != 0x32 || gentm->data[1] != 0x30)
3993 return 0;
3994 if (out->size < gentm->length-2)
3995 return -1;
3996
3997 memcpy(out->str, gentm->data+2, gentm->length-2);
3998 out->len = gentm->length-2;
3999 return 1;
4000 }
4001 else if (tm->type == V_ASN1_UTCTIME) {
4002 ASN1_UTCTIME *utctm = (ASN1_UTCTIME *)tm;
4003
4004 if (utctm->length < 10)
4005 return 0;
4006 if (utctm->data[0] >= 0x35)
4007 return 0;
4008 if (out->size < utctm->length)
4009 return -1;
4010
4011 memcpy(out->str, utctm->data, utctm->length);
4012 out->len = utctm->length;
4013 return 1;
4014 }
4015
4016 return 0;
4017}
4018
Emeric Brun87855892012-10-17 17:39:35 +02004019/* Extract an entry from a X509_NAME and copy its value to an output chunk.
4020 * Returns 1 if entry found, 0 if entry not found, or -1 if output not large enough.
4021 */
4022static int
4023ssl_sock_get_dn_entry(X509_NAME *a, const struct chunk *entry, int pos, struct chunk *out)
4024{
4025 X509_NAME_ENTRY *ne;
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02004026 ASN1_OBJECT *obj;
4027 ASN1_STRING *data;
4028 const unsigned char *data_ptr;
4029 int data_len;
Emeric Brun87855892012-10-17 17:39:35 +02004030 int i, j, n;
4031 int cur = 0;
4032 const char *s;
4033 char tmp[128];
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02004034 int name_count;
4035
4036 name_count = X509_NAME_entry_count(a);
Emeric Brun87855892012-10-17 17:39:35 +02004037
4038 out->len = 0;
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02004039 for (i = 0; i < name_count; i++) {
Emeric Brun87855892012-10-17 17:39:35 +02004040 if (pos < 0)
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02004041 j = (name_count-1) - i;
Emeric Brun87855892012-10-17 17:39:35 +02004042 else
4043 j = i;
4044
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02004045 ne = X509_NAME_get_entry(a, j);
4046 obj = X509_NAME_ENTRY_get_object(ne);
4047 data = X509_NAME_ENTRY_get_data(ne);
4048 data_ptr = ASN1_STRING_get0_data(data);
4049 data_len = ASN1_STRING_length(data);
4050 n = OBJ_obj2nid(obj);
Emeric Brun87855892012-10-17 17:39:35 +02004051 if ((n == NID_undef) || ((s = OBJ_nid2sn(n)) == NULL)) {
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02004052 i2t_ASN1_OBJECT(tmp, sizeof(tmp), obj);
Emeric Brun87855892012-10-17 17:39:35 +02004053 s = tmp;
4054 }
4055
4056 if (chunk_strcasecmp(entry, s) != 0)
4057 continue;
4058
4059 if (pos < 0)
4060 cur--;
4061 else
4062 cur++;
4063
4064 if (cur != pos)
4065 continue;
4066
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02004067 if (data_len > out->size)
Emeric Brun87855892012-10-17 17:39:35 +02004068 return -1;
4069
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02004070 memcpy(out->str, data_ptr, data_len);
4071 out->len = data_len;
Emeric Brun87855892012-10-17 17:39:35 +02004072 return 1;
4073 }
4074
4075 return 0;
4076
4077}
4078
4079/* Extract and format full DN from a X509_NAME and copy result into a chunk
4080 * Returns 1 if dn entries exits, 0 if no dn entry found or -1 if output is not large enough.
4081 */
4082static int
4083ssl_sock_get_dn_oneline(X509_NAME *a, struct chunk *out)
4084{
4085 X509_NAME_ENTRY *ne;
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02004086 ASN1_OBJECT *obj;
4087 ASN1_STRING *data;
4088 const unsigned char *data_ptr;
4089 int data_len;
Emeric Brun87855892012-10-17 17:39:35 +02004090 int i, n, ln;
4091 int l = 0;
4092 const char *s;
4093 char *p;
4094 char tmp[128];
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02004095 int name_count;
4096
4097
4098 name_count = X509_NAME_entry_count(a);
Emeric Brun87855892012-10-17 17:39:35 +02004099
4100 out->len = 0;
4101 p = out->str;
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02004102 for (i = 0; i < name_count; i++) {
4103 ne = X509_NAME_get_entry(a, i);
4104 obj = X509_NAME_ENTRY_get_object(ne);
4105 data = X509_NAME_ENTRY_get_data(ne);
4106 data_ptr = ASN1_STRING_get0_data(data);
4107 data_len = ASN1_STRING_length(data);
4108 n = OBJ_obj2nid(obj);
Emeric Brun87855892012-10-17 17:39:35 +02004109 if ((n == NID_undef) || ((s = OBJ_nid2sn(n)) == NULL)) {
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02004110 i2t_ASN1_OBJECT(tmp, sizeof(tmp), obj);
Emeric Brun87855892012-10-17 17:39:35 +02004111 s = tmp;
4112 }
4113 ln = strlen(s);
4114
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02004115 l += 1 + ln + 1 + data_len;
Emeric Brun87855892012-10-17 17:39:35 +02004116 if (l > out->size)
4117 return -1;
4118 out->len = l;
4119
4120 *(p++)='/';
4121 memcpy(p, s, ln);
4122 p += ln;
4123 *(p++)='=';
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02004124 memcpy(p, data_ptr, data_len);
4125 p += data_len;
Emeric Brun87855892012-10-17 17:39:35 +02004126 }
4127
4128 if (!out->len)
4129 return 0;
4130
4131 return 1;
4132}
4133
David Safb76832014-05-08 23:42:08 -04004134char *ssl_sock_get_version(struct connection *conn)
4135{
4136 if (!ssl_sock_is_ssl(conn))
4137 return NULL;
4138
4139 return (char *)SSL_get_version(conn->xprt_ctx);
4140}
4141
Willy Tarreau63076412015-07-10 11:33:32 +02004142void ssl_sock_set_servername(struct connection *conn, const char *hostname)
4143{
4144#ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME
4145 if (!ssl_sock_is_ssl(conn))
4146 return;
4147
4148 SSL_set_tlsext_host_name(conn->xprt_ctx, hostname);
4149#endif
4150}
4151
Emeric Brun0abf8362014-06-24 18:26:41 +02004152/* Extract peer certificate's common name into the chunk dest
4153 * Returns
4154 * the len of the extracted common name
4155 * or 0 if no CN found in DN
4156 * or -1 on error case (i.e. no peer certificate)
4157 */
4158int ssl_sock_get_remote_common_name(struct connection *conn, struct chunk *dest)
David Safb76832014-05-08 23:42:08 -04004159{
4160 X509 *crt = NULL;
4161 X509_NAME *name;
David Safb76832014-05-08 23:42:08 -04004162 const char find_cn[] = "CN";
4163 const struct chunk find_cn_chunk = {
4164 .str = (char *)&find_cn,
4165 .len = sizeof(find_cn)-1
4166 };
Emeric Brun0abf8362014-06-24 18:26:41 +02004167 int result = -1;
David Safb76832014-05-08 23:42:08 -04004168
4169 if (!ssl_sock_is_ssl(conn))
Emeric Brun0abf8362014-06-24 18:26:41 +02004170 goto out;
David Safb76832014-05-08 23:42:08 -04004171
4172 /* SSL_get_peer_certificate, it increase X509 * ref count */
4173 crt = SSL_get_peer_certificate(conn->xprt_ctx);
4174 if (!crt)
4175 goto out;
4176
4177 name = X509_get_subject_name(crt);
4178 if (!name)
4179 goto out;
David Safb76832014-05-08 23:42:08 -04004180
Emeric Brun0abf8362014-06-24 18:26:41 +02004181 result = ssl_sock_get_dn_entry(name, &find_cn_chunk, 1, dest);
4182out:
David Safb76832014-05-08 23:42:08 -04004183 if (crt)
4184 X509_free(crt);
4185
4186 return result;
4187}
4188
Dave McCowan328fb582014-07-30 10:39:13 -04004189/* returns 1 if client passed a certificate for this session, 0 if not */
4190int ssl_sock_get_cert_used_sess(struct connection *conn)
4191{
4192 X509 *crt = NULL;
4193
4194 if (!ssl_sock_is_ssl(conn))
4195 return 0;
4196
4197 /* SSL_get_peer_certificate, it increase X509 * ref count */
4198 crt = SSL_get_peer_certificate(conn->xprt_ctx);
4199 if (!crt)
4200 return 0;
4201
4202 X509_free(crt);
4203 return 1;
4204}
4205
4206/* returns 1 if client passed a certificate for this connection, 0 if not */
4207int ssl_sock_get_cert_used_conn(struct connection *conn)
David Safb76832014-05-08 23:42:08 -04004208{
4209 if (!ssl_sock_is_ssl(conn))
4210 return 0;
4211
4212 return SSL_SOCK_ST_FL_VERIFY_DONE & conn->xprt_st ? 1 : 0;
4213}
4214
4215/* returns result from SSL verify */
4216unsigned int ssl_sock_get_verify_result(struct connection *conn)
4217{
4218 if (!ssl_sock_is_ssl(conn))
4219 return (unsigned int)X509_V_ERR_APPLICATION_VERIFICATION;
4220
4221 return (unsigned int)SSL_get_verify_result(conn->xprt_ctx);
4222}
4223
Willy Tarreau7875d092012-09-10 08:20:03 +02004224/***** Below are some sample fetching functions for ACL/patterns *****/
4225
Emeric Brune64aef12012-09-21 13:15:06 +02004226/* boolean, returns true if client cert was present */
4227static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02004228smp_fetch_ssl_fc_has_crt(const struct arg *args, struct sample *smp, const char *kw, void *private)
Emeric Brune64aef12012-09-21 13:15:06 +02004229{
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004230 struct connection *conn;
4231
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02004232 conn = objt_conn(smp->sess->origin);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004233 if (!conn || conn->xprt != &ssl_sock)
Emeric Brune64aef12012-09-21 13:15:06 +02004234 return 0;
4235
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004236 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brune64aef12012-09-21 13:15:06 +02004237 smp->flags |= SMP_F_MAY_CHANGE;
4238 return 0;
4239 }
4240
4241 smp->flags = 0;
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02004242 smp->data.type = SMP_T_BOOL;
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02004243 smp->data.u.sint = SSL_SOCK_ST_FL_VERIFY_DONE & conn->xprt_st ? 1 : 0;
Emeric Brune64aef12012-09-21 13:15:06 +02004244
4245 return 1;
4246}
4247
Emeric Brun43e79582014-10-29 19:03:26 +01004248/* binary, returns a certificate in a binary chunk (der/raw).
4249 * The 5th keyword char is used to know if SSL_get_certificate or SSL_get_peer_certificate
4250 * should be use.
4251 */
4252static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02004253smp_fetch_ssl_x_der(const struct arg *args, struct sample *smp, const char *kw, void *private)
Emeric Brun43e79582014-10-29 19:03:26 +01004254{
4255 int cert_peer = (kw[4] == 'c') ? 1 : 0;
4256 X509 *crt = NULL;
4257 int ret = 0;
4258 struct chunk *smp_trash;
4259 struct connection *conn;
4260
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02004261 conn = objt_conn(smp->sess->origin);
Emeric Brun43e79582014-10-29 19:03:26 +01004262 if (!conn || conn->xprt != &ssl_sock)
4263 return 0;
4264
4265 if (!(conn->flags & CO_FL_CONNECTED)) {
4266 smp->flags |= SMP_F_MAY_CHANGE;
4267 return 0;
4268 }
4269
4270 if (cert_peer)
4271 crt = SSL_get_peer_certificate(conn->xprt_ctx);
4272 else
4273 crt = SSL_get_certificate(conn->xprt_ctx);
4274
4275 if (!crt)
4276 goto out;
4277
4278 smp_trash = get_trash_chunk();
4279 if (ssl_sock_crt2der(crt, smp_trash) <= 0)
4280 goto out;
4281
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02004282 smp->data.u.str = *smp_trash;
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02004283 smp->data.type = SMP_T_BIN;
Emeric Brun43e79582014-10-29 19:03:26 +01004284 ret = 1;
4285out:
4286 /* SSL_get_peer_certificate, it increase X509 * ref count */
4287 if (cert_peer && crt)
4288 X509_free(crt);
4289 return ret;
4290}
4291
Emeric Brunba841a12014-04-30 17:05:08 +02004292/* binary, returns serial of certificate in a binary chunk.
4293 * The 5th keyword char is used to know if SSL_get_certificate or SSL_get_peer_certificate
4294 * should be use.
4295 */
Willy Tarreau8d598402012-10-22 17:58:39 +02004296static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02004297smp_fetch_ssl_x_serial(const struct arg *args, struct sample *smp, const char *kw, void *private)
Willy Tarreau8d598402012-10-22 17:58:39 +02004298{
Emeric Brunba841a12014-04-30 17:05:08 +02004299 int cert_peer = (kw[4] == 'c') ? 1 : 0;
Willy Tarreau8d598402012-10-22 17:58:39 +02004300 X509 *crt = NULL;
4301 int ret = 0;
4302 struct chunk *smp_trash;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004303 struct connection *conn;
4304
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02004305 conn = objt_conn(smp->sess->origin);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004306 if (!conn || conn->xprt != &ssl_sock)
Willy Tarreau8d598402012-10-22 17:58:39 +02004307 return 0;
4308
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004309 if (!(conn->flags & CO_FL_CONNECTED)) {
Willy Tarreau8d598402012-10-22 17:58:39 +02004310 smp->flags |= SMP_F_MAY_CHANGE;
4311 return 0;
4312 }
4313
Emeric Brunba841a12014-04-30 17:05:08 +02004314 if (cert_peer)
4315 crt = SSL_get_peer_certificate(conn->xprt_ctx);
4316 else
4317 crt = SSL_get_certificate(conn->xprt_ctx);
4318
Willy Tarreau8d598402012-10-22 17:58:39 +02004319 if (!crt)
4320 goto out;
4321
Willy Tarreau47ca5452012-12-23 20:22:19 +01004322 smp_trash = get_trash_chunk();
Willy Tarreau8d598402012-10-22 17:58:39 +02004323 if (ssl_sock_get_serial(crt, smp_trash) <= 0)
4324 goto out;
4325
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02004326 smp->data.u.str = *smp_trash;
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02004327 smp->data.type = SMP_T_BIN;
Willy Tarreau8d598402012-10-22 17:58:39 +02004328 ret = 1;
4329out:
Emeric Brunba841a12014-04-30 17:05:08 +02004330 /* SSL_get_peer_certificate, it increase X509 * ref count */
4331 if (cert_peer && crt)
Willy Tarreau8d598402012-10-22 17:58:39 +02004332 X509_free(crt);
4333 return ret;
4334}
Emeric Brune64aef12012-09-21 13:15:06 +02004335
Emeric Brunba841a12014-04-30 17:05:08 +02004336/* binary, returns the client certificate's SHA-1 fingerprint (SHA-1 hash of DER-encoded certificate) in a binary chunk.
4337 * The 5th keyword char is used to know if SSL_get_certificate or SSL_get_peer_certificate
4338 * should be use.
4339 */
James Votha051b4a2013-05-14 20:37:59 +02004340static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02004341smp_fetch_ssl_x_sha1(const struct arg *args, struct sample *smp, const char *kw, void *private)
James Votha051b4a2013-05-14 20:37:59 +02004342{
Emeric Brunba841a12014-04-30 17:05:08 +02004343 int cert_peer = (kw[4] == 'c') ? 1 : 0;
James Votha051b4a2013-05-14 20:37:59 +02004344 X509 *crt = NULL;
4345 const EVP_MD *digest;
4346 int ret = 0;
4347 struct chunk *smp_trash;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004348 struct connection *conn;
James Votha051b4a2013-05-14 20:37:59 +02004349
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02004350 conn = objt_conn(smp->sess->origin);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004351 if (!conn || conn->xprt != &ssl_sock)
4352 return 0;
4353
4354 if (!(conn->flags & CO_FL_CONNECTED)) {
James Votha051b4a2013-05-14 20:37:59 +02004355 smp->flags |= SMP_F_MAY_CHANGE;
4356 return 0;
4357 }
4358
Emeric Brunba841a12014-04-30 17:05:08 +02004359 if (cert_peer)
4360 crt = SSL_get_peer_certificate(conn->xprt_ctx);
4361 else
4362 crt = SSL_get_certificate(conn->xprt_ctx);
James Votha051b4a2013-05-14 20:37:59 +02004363 if (!crt)
4364 goto out;
4365
4366 smp_trash = get_trash_chunk();
4367 digest = EVP_sha1();
4368 X509_digest(crt, digest, (unsigned char *)smp_trash->str, (unsigned int *)&smp_trash->len);
4369
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02004370 smp->data.u.str = *smp_trash;
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02004371 smp->data.type = SMP_T_BIN;
James Votha051b4a2013-05-14 20:37:59 +02004372 ret = 1;
4373out:
Emeric Brunba841a12014-04-30 17:05:08 +02004374 /* SSL_get_peer_certificate, it increase X509 * ref count */
4375 if (cert_peer && crt)
James Votha051b4a2013-05-14 20:37:59 +02004376 X509_free(crt);
4377 return ret;
4378}
4379
Emeric Brunba841a12014-04-30 17:05:08 +02004380/* string, returns certificate's notafter date in ASN1_UTCTIME format.
4381 * The 5th keyword char is used to know if SSL_get_certificate or SSL_get_peer_certificate
4382 * should be use.
4383 */
Emeric Brunce5ad802012-10-22 14:11:22 +02004384static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02004385smp_fetch_ssl_x_notafter(const struct arg *args, struct sample *smp, const char *kw, void *private)
Emeric Brunce5ad802012-10-22 14:11:22 +02004386{
Emeric Brunba841a12014-04-30 17:05:08 +02004387 int cert_peer = (kw[4] == 'c') ? 1 : 0;
Emeric Brunce5ad802012-10-22 14:11:22 +02004388 X509 *crt = NULL;
4389 int ret = 0;
4390 struct chunk *smp_trash;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004391 struct connection *conn;
Emeric Brunce5ad802012-10-22 14:11:22 +02004392
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02004393 conn = objt_conn(smp->sess->origin);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004394 if (!conn || conn->xprt != &ssl_sock)
4395 return 0;
4396
4397 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brunce5ad802012-10-22 14:11:22 +02004398 smp->flags |= SMP_F_MAY_CHANGE;
4399 return 0;
4400 }
4401
Emeric Brunba841a12014-04-30 17:05:08 +02004402 if (cert_peer)
4403 crt = SSL_get_peer_certificate(conn->xprt_ctx);
4404 else
4405 crt = SSL_get_certificate(conn->xprt_ctx);
Emeric Brunce5ad802012-10-22 14:11:22 +02004406 if (!crt)
4407 goto out;
4408
Willy Tarreau47ca5452012-12-23 20:22:19 +01004409 smp_trash = get_trash_chunk();
Emeric Brunce5ad802012-10-22 14:11:22 +02004410 if (ssl_sock_get_time(X509_get_notAfter(crt), smp_trash) <= 0)
4411 goto out;
4412
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02004413 smp->data.u.str = *smp_trash;
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02004414 smp->data.type = SMP_T_STR;
Emeric Brunce5ad802012-10-22 14:11:22 +02004415 ret = 1;
4416out:
Emeric Brunba841a12014-04-30 17:05:08 +02004417 /* SSL_get_peer_certificate, it increase X509 * ref count */
4418 if (cert_peer && crt)
Emeric Brunce5ad802012-10-22 14:11:22 +02004419 X509_free(crt);
4420 return ret;
4421}
4422
Emeric Brunba841a12014-04-30 17:05:08 +02004423/* string, returns a string of a formatted full dn \C=..\O=..\OU=.. \CN=.. of certificate's issuer
4424 * The 5th keyword char is used to know if SSL_get_certificate or SSL_get_peer_certificate
4425 * should be use.
4426 */
Emeric Brun87855892012-10-17 17:39:35 +02004427static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02004428smp_fetch_ssl_x_i_dn(const struct arg *args, struct sample *smp, const char *kw, void *private)
Emeric Brun87855892012-10-17 17:39:35 +02004429{
Emeric Brunba841a12014-04-30 17:05:08 +02004430 int cert_peer = (kw[4] == 'c') ? 1 : 0;
Emeric Brun87855892012-10-17 17:39:35 +02004431 X509 *crt = NULL;
4432 X509_NAME *name;
4433 int ret = 0;
4434 struct chunk *smp_trash;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004435 struct connection *conn;
Emeric Brun87855892012-10-17 17:39:35 +02004436
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02004437 conn = objt_conn(smp->sess->origin);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004438 if (!conn || conn->xprt != &ssl_sock)
4439 return 0;
4440
4441 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brun87855892012-10-17 17:39:35 +02004442 smp->flags |= SMP_F_MAY_CHANGE;
4443 return 0;
4444 }
4445
Emeric Brunba841a12014-04-30 17:05:08 +02004446 if (cert_peer)
4447 crt = SSL_get_peer_certificate(conn->xprt_ctx);
4448 else
4449 crt = SSL_get_certificate(conn->xprt_ctx);
Emeric Brun87855892012-10-17 17:39:35 +02004450 if (!crt)
4451 goto out;
4452
4453 name = X509_get_issuer_name(crt);
4454 if (!name)
4455 goto out;
4456
Willy Tarreau47ca5452012-12-23 20:22:19 +01004457 smp_trash = get_trash_chunk();
Emeric Brun87855892012-10-17 17:39:35 +02004458 if (args && args[0].type == ARGT_STR) {
4459 int pos = 1;
4460
4461 if (args[1].type == ARGT_SINT)
4462 pos = args[1].data.sint;
Emeric Brun87855892012-10-17 17:39:35 +02004463
4464 if (ssl_sock_get_dn_entry(name, &args[0].data.str, pos, smp_trash) <= 0)
4465 goto out;
4466 }
4467 else if (ssl_sock_get_dn_oneline(name, smp_trash) <= 0)
4468 goto out;
4469
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02004470 smp->data.type = SMP_T_STR;
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02004471 smp->data.u.str = *smp_trash;
Emeric Brun87855892012-10-17 17:39:35 +02004472 ret = 1;
4473out:
Emeric Brunba841a12014-04-30 17:05:08 +02004474 /* SSL_get_peer_certificate, it increase X509 * ref count */
4475 if (cert_peer && crt)
Emeric Brun87855892012-10-17 17:39:35 +02004476 X509_free(crt);
4477 return ret;
4478}
4479
Emeric Brunba841a12014-04-30 17:05:08 +02004480/* string, returns notbefore date in ASN1_UTCTIME format.
4481 * The 5th keyword char is used to know if SSL_get_certificate or SSL_get_peer_certificate
4482 * should be use.
4483 */
Emeric Brunce5ad802012-10-22 14:11:22 +02004484static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02004485smp_fetch_ssl_x_notbefore(const struct arg *args, struct sample *smp, const char *kw, void *private)
Emeric Brunce5ad802012-10-22 14:11:22 +02004486{
Emeric Brunba841a12014-04-30 17:05:08 +02004487 int cert_peer = (kw[4] == 'c') ? 1 : 0;
Emeric Brunce5ad802012-10-22 14:11:22 +02004488 X509 *crt = NULL;
4489 int ret = 0;
4490 struct chunk *smp_trash;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004491 struct connection *conn;
4492
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02004493 conn = objt_conn(smp->sess->origin);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004494 if (!conn || conn->xprt != &ssl_sock)
Emeric Brunce5ad802012-10-22 14:11:22 +02004495 return 0;
4496
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004497 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brunce5ad802012-10-22 14:11:22 +02004498 smp->flags |= SMP_F_MAY_CHANGE;
4499 return 0;
4500 }
4501
Emeric Brunba841a12014-04-30 17:05:08 +02004502 if (cert_peer)
4503 crt = SSL_get_peer_certificate(conn->xprt_ctx);
4504 else
4505 crt = SSL_get_certificate(conn->xprt_ctx);
Emeric Brunce5ad802012-10-22 14:11:22 +02004506 if (!crt)
4507 goto out;
4508
Willy Tarreau47ca5452012-12-23 20:22:19 +01004509 smp_trash = get_trash_chunk();
Emeric Brunce5ad802012-10-22 14:11:22 +02004510 if (ssl_sock_get_time(X509_get_notBefore(crt), smp_trash) <= 0)
4511 goto out;
4512
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02004513 smp->data.u.str = *smp_trash;
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02004514 smp->data.type = SMP_T_STR;
Emeric Brunce5ad802012-10-22 14:11:22 +02004515 ret = 1;
4516out:
Emeric Brunba841a12014-04-30 17:05:08 +02004517 /* SSL_get_peer_certificate, it increase X509 * ref count */
4518 if (cert_peer && crt)
Emeric Brunce5ad802012-10-22 14:11:22 +02004519 X509_free(crt);
4520 return ret;
4521}
4522
Emeric Brunba841a12014-04-30 17:05:08 +02004523/* string, returns a string of a formatted full dn \C=..\O=..\OU=.. \CN=.. of certificate's subject
4524 * The 5th keyword char is used to know if SSL_get_certificate or SSL_get_peer_certificate
4525 * should be use.
4526 */
Emeric Brun87855892012-10-17 17:39:35 +02004527static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02004528smp_fetch_ssl_x_s_dn(const struct arg *args, struct sample *smp, const char *kw, void *private)
Emeric Brun87855892012-10-17 17:39:35 +02004529{
Emeric Brunba841a12014-04-30 17:05:08 +02004530 int cert_peer = (kw[4] == 'c') ? 1 : 0;
Emeric Brun87855892012-10-17 17:39:35 +02004531 X509 *crt = NULL;
4532 X509_NAME *name;
4533 int ret = 0;
4534 struct chunk *smp_trash;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004535 struct connection *conn;
Emeric Brun87855892012-10-17 17:39:35 +02004536
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02004537 conn = objt_conn(smp->sess->origin);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004538 if (!conn || conn->xprt != &ssl_sock)
4539 return 0;
4540
4541 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brun87855892012-10-17 17:39:35 +02004542 smp->flags |= SMP_F_MAY_CHANGE;
4543 return 0;
4544 }
4545
Emeric Brunba841a12014-04-30 17:05:08 +02004546 if (cert_peer)
4547 crt = SSL_get_peer_certificate(conn->xprt_ctx);
4548 else
4549 crt = SSL_get_certificate(conn->xprt_ctx);
Emeric Brun87855892012-10-17 17:39:35 +02004550 if (!crt)
4551 goto out;
4552
4553 name = X509_get_subject_name(crt);
4554 if (!name)
4555 goto out;
4556
Willy Tarreau47ca5452012-12-23 20:22:19 +01004557 smp_trash = get_trash_chunk();
Emeric Brun87855892012-10-17 17:39:35 +02004558 if (args && args[0].type == ARGT_STR) {
4559 int pos = 1;
4560
4561 if (args[1].type == ARGT_SINT)
4562 pos = args[1].data.sint;
Emeric Brun87855892012-10-17 17:39:35 +02004563
4564 if (ssl_sock_get_dn_entry(name, &args[0].data.str, pos, smp_trash) <= 0)
4565 goto out;
4566 }
4567 else if (ssl_sock_get_dn_oneline(name, smp_trash) <= 0)
4568 goto out;
4569
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02004570 smp->data.type = SMP_T_STR;
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02004571 smp->data.u.str = *smp_trash;
Emeric Brun87855892012-10-17 17:39:35 +02004572 ret = 1;
4573out:
Emeric Brunba841a12014-04-30 17:05:08 +02004574 /* SSL_get_peer_certificate, it increase X509 * ref count */
4575 if (cert_peer && crt)
Emeric Brun87855892012-10-17 17:39:35 +02004576 X509_free(crt);
4577 return ret;
4578}
Emeric Brun9143d372012-12-20 15:44:16 +01004579
4580/* integer, returns true if current session use a client certificate */
4581static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02004582smp_fetch_ssl_c_used(const struct arg *args, struct sample *smp, const char *kw, void *private)
Emeric Brun9143d372012-12-20 15:44:16 +01004583{
4584 X509 *crt;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004585 struct connection *conn;
Emeric Brun9143d372012-12-20 15:44:16 +01004586
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02004587 conn = objt_conn(smp->sess->origin);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004588 if (!conn || conn->xprt != &ssl_sock)
4589 return 0;
4590
4591 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brun9143d372012-12-20 15:44:16 +01004592 smp->flags |= SMP_F_MAY_CHANGE;
4593 return 0;
4594 }
4595
4596 /* SSL_get_peer_certificate returns a ptr on allocated X509 struct */
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004597 crt = SSL_get_peer_certificate(conn->xprt_ctx);
Emeric Brun9143d372012-12-20 15:44:16 +01004598 if (crt) {
4599 X509_free(crt);
4600 }
4601
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02004602 smp->data.type = SMP_T_BOOL;
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02004603 smp->data.u.sint = (crt != NULL);
Emeric Brun9143d372012-12-20 15:44:16 +01004604 return 1;
4605}
4606
Emeric Brunba841a12014-04-30 17:05:08 +02004607/* integer, returns the certificate version
4608 * The 5th keyword char is used to know if SSL_get_certificate or SSL_get_peer_certificate
4609 * should be use.
4610 */
Emeric Bruna7359fd2012-10-17 15:03:11 +02004611static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02004612smp_fetch_ssl_x_version(const struct arg *args, struct sample *smp, const char *kw, void *private)
Emeric Bruna7359fd2012-10-17 15:03:11 +02004613{
Emeric Brunba841a12014-04-30 17:05:08 +02004614 int cert_peer = (kw[4] == 'c') ? 1 : 0;
Emeric Bruna7359fd2012-10-17 15:03:11 +02004615 X509 *crt;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004616 struct connection *conn;
4617
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02004618 conn = objt_conn(smp->sess->origin);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004619 if (!conn || conn->xprt != &ssl_sock)
Emeric Bruna7359fd2012-10-17 15:03:11 +02004620 return 0;
4621
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004622 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Bruna7359fd2012-10-17 15:03:11 +02004623 smp->flags |= SMP_F_MAY_CHANGE;
4624 return 0;
4625 }
4626
Emeric Brunba841a12014-04-30 17:05:08 +02004627 if (cert_peer)
4628 crt = SSL_get_peer_certificate(conn->xprt_ctx);
4629 else
4630 crt = SSL_get_certificate(conn->xprt_ctx);
Emeric Bruna7359fd2012-10-17 15:03:11 +02004631 if (!crt)
4632 return 0;
4633
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02004634 smp->data.u.sint = (unsigned int)(1 + X509_get_version(crt));
Emeric Brunba841a12014-04-30 17:05:08 +02004635 /* SSL_get_peer_certificate increase X509 * ref count */
4636 if (cert_peer)
4637 X509_free(crt);
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02004638 smp->data.type = SMP_T_SINT;
Emeric Bruna7359fd2012-10-17 15:03:11 +02004639
4640 return 1;
4641}
4642
Emeric Brunba841a12014-04-30 17:05:08 +02004643/* string, returns the certificate's signature algorithm.
4644 * The 5th keyword char is used to know if SSL_get_certificate or SSL_get_peer_certificate
4645 * should be use.
4646 */
Emeric Brun7f56e742012-10-19 18:15:40 +02004647static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02004648smp_fetch_ssl_x_sig_alg(const struct arg *args, struct sample *smp, const char *kw, void *private)
Emeric Brun7f56e742012-10-19 18:15:40 +02004649{
Emeric Brunba841a12014-04-30 17:05:08 +02004650 int cert_peer = (kw[4] == 'c') ? 1 : 0;
Emeric Brun7f56e742012-10-19 18:15:40 +02004651 X509 *crt;
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02004652 __OPENSSL_110_CONST__ ASN1_OBJECT *algorithm;
Emeric Brun7f56e742012-10-19 18:15:40 +02004653 int nid;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004654 struct connection *conn;
Emeric Brun7f56e742012-10-19 18:15:40 +02004655
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02004656 conn = objt_conn(smp->sess->origin);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004657 if (!conn || conn->xprt != &ssl_sock)
4658 return 0;
4659
4660 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brun7f56e742012-10-19 18:15:40 +02004661 smp->flags |= SMP_F_MAY_CHANGE;
4662 return 0;
4663 }
4664
Emeric Brunba841a12014-04-30 17:05:08 +02004665 if (cert_peer)
4666 crt = SSL_get_peer_certificate(conn->xprt_ctx);
4667 else
4668 crt = SSL_get_certificate(conn->xprt_ctx);
Emeric Brun7f56e742012-10-19 18:15:40 +02004669 if (!crt)
4670 return 0;
4671
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02004672 X509_ALGOR_get0(&algorithm, NULL, NULL, X509_get0_tbs_sigalg(crt));
4673 nid = OBJ_obj2nid(algorithm);
Emeric Brun7f56e742012-10-19 18:15:40 +02004674
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02004675 smp->data.u.str.str = (char *)OBJ_nid2sn(nid);
4676 if (!smp->data.u.str.str) {
Emeric Brunba841a12014-04-30 17:05:08 +02004677 /* SSL_get_peer_certificate increase X509 * ref count */
4678 if (cert_peer)
4679 X509_free(crt);
Emeric Brun7f56e742012-10-19 18:15:40 +02004680 return 0;
Emeric Brun9bf3ba22013-10-07 14:31:44 +02004681 }
Emeric Brun7f56e742012-10-19 18:15:40 +02004682
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02004683 smp->data.type = SMP_T_STR;
Thierry FOURNIER7654c9f2013-12-17 00:20:33 +01004684 smp->flags |= SMP_F_CONST;
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02004685 smp->data.u.str.len = strlen(smp->data.u.str.str);
Emeric Brunba841a12014-04-30 17:05:08 +02004686 /* SSL_get_peer_certificate increase X509 * ref count */
4687 if (cert_peer)
4688 X509_free(crt);
Emeric Brun7f56e742012-10-19 18:15:40 +02004689
4690 return 1;
4691}
4692
Emeric Brunba841a12014-04-30 17:05:08 +02004693/* string, returns the certificate's key algorithm.
4694 * The 5th keyword char is used to know if SSL_get_certificate or SSL_get_peer_certificate
4695 * should be use.
4696 */
Emeric Brun521a0112012-10-22 12:22:55 +02004697static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02004698smp_fetch_ssl_x_key_alg(const struct arg *args, struct sample *smp, const char *kw, void *private)
Emeric Brun521a0112012-10-22 12:22:55 +02004699{
Emeric Brunba841a12014-04-30 17:05:08 +02004700 int cert_peer = (kw[4] == 'c') ? 1 : 0;
Emeric Brun521a0112012-10-22 12:22:55 +02004701 X509 *crt;
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02004702 ASN1_OBJECT *algorithm;
Emeric Brun521a0112012-10-22 12:22:55 +02004703 int nid;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004704 struct connection *conn;
Emeric Brun521a0112012-10-22 12:22:55 +02004705
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02004706 conn = objt_conn(smp->sess->origin);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004707 if (!conn || conn->xprt != &ssl_sock)
4708 return 0;
4709
4710 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brun521a0112012-10-22 12:22:55 +02004711 smp->flags |= SMP_F_MAY_CHANGE;
4712 return 0;
4713 }
4714
Emeric Brunba841a12014-04-30 17:05:08 +02004715 if (cert_peer)
4716 crt = SSL_get_peer_certificate(conn->xprt_ctx);
4717 else
4718 crt = SSL_get_certificate(conn->xprt_ctx);
Emeric Brun521a0112012-10-22 12:22:55 +02004719 if (!crt)
4720 return 0;
4721
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02004722 X509_PUBKEY_get0_param(&algorithm, NULL, NULL, NULL, X509_get_X509_PUBKEY(crt));
4723 nid = OBJ_obj2nid(algorithm);
Emeric Brun521a0112012-10-22 12:22:55 +02004724
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02004725 smp->data.u.str.str = (char *)OBJ_nid2sn(nid);
4726 if (!smp->data.u.str.str) {
Emeric Brunba841a12014-04-30 17:05:08 +02004727 /* SSL_get_peer_certificate increase X509 * ref count */
4728 if (cert_peer)
4729 X509_free(crt);
Emeric Brun521a0112012-10-22 12:22:55 +02004730 return 0;
Emeric Brun9bf3ba22013-10-07 14:31:44 +02004731 }
Emeric Brun521a0112012-10-22 12:22:55 +02004732
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02004733 smp->data.type = SMP_T_STR;
Thierry FOURNIER7654c9f2013-12-17 00:20:33 +01004734 smp->flags |= SMP_F_CONST;
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02004735 smp->data.u.str.len = strlen(smp->data.u.str.str);
Emeric Brunba841a12014-04-30 17:05:08 +02004736 if (cert_peer)
4737 X509_free(crt);
Emeric Brun521a0112012-10-22 12:22:55 +02004738
4739 return 1;
4740}
4741
Emeric Brun645ae792014-04-30 14:21:06 +02004742/* boolean, returns true if front conn. transport layer is SSL.
4743 * This function is also usable on backend conn if the fetch keyword 5th
4744 * char is 'b'.
4745 */
Willy Tarreau7875d092012-09-10 08:20:03 +02004746static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02004747smp_fetch_ssl_fc(const struct arg *args, struct sample *smp, const char *kw, void *private)
Willy Tarreau7875d092012-09-10 08:20:03 +02004748{
Willy Tarreaue237fe12016-03-10 17:05:28 +01004749 struct connection *conn = objt_conn((kw[4] != 'b') ? smp->sess->origin :
4750 smp->strm ? smp->strm->si[1].end : NULL);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004751
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02004752 smp->data.type = SMP_T_BOOL;
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02004753 smp->data.u.sint = (conn && conn->xprt == &ssl_sock);
Willy Tarreau7875d092012-09-10 08:20:03 +02004754 return 1;
4755}
4756
Emeric Brun2525b6b2012-10-18 15:59:43 +02004757/* boolean, returns true if client present a SNI */
Willy Tarreau7875d092012-09-10 08:20:03 +02004758static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02004759smp_fetch_ssl_fc_has_sni(const struct arg *args, struct sample *smp, const char *kw, void *private)
Willy Tarreau7875d092012-09-10 08:20:03 +02004760{
4761#ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02004762 struct connection *conn = objt_conn(smp->sess->origin);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004763
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02004764 smp->data.type = SMP_T_BOOL;
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02004765 smp->data.u.sint = (conn && conn->xprt == &ssl_sock) &&
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004766 conn->xprt_ctx &&
4767 SSL_get_servername(conn->xprt_ctx, TLSEXT_NAMETYPE_host_name) != NULL;
Willy Tarreau7875d092012-09-10 08:20:03 +02004768 return 1;
4769#else
4770 return 0;
4771#endif
4772}
4773
Nenad Merdanovic26ea8222015-05-18 02:28:57 +02004774/* boolean, returns true if client session has been resumed */
4775static int
4776smp_fetch_ssl_fc_is_resumed(const struct arg *args, struct sample *smp, const char *kw, void *private)
4777{
4778 struct connection *conn = objt_conn(smp->sess->origin);
4779
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02004780 smp->data.type = SMP_T_BOOL;
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02004781 smp->data.u.sint = (conn && conn->xprt == &ssl_sock) &&
Nenad Merdanovic26ea8222015-05-18 02:28:57 +02004782 conn->xprt_ctx &&
4783 SSL_session_reused(conn->xprt_ctx);
4784 return 1;
4785}
4786
Emeric Brun645ae792014-04-30 14:21:06 +02004787/* string, returns the used cipher if front conn. transport layer is SSL.
4788 * This function is also usable on backend conn if the fetch keyword 5th
4789 * char is 'b'.
4790 */
Emeric Brun589fcad2012-10-16 14:13:26 +02004791static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02004792smp_fetch_ssl_fc_cipher(const struct arg *args, struct sample *smp, const char *kw, void *private)
Emeric Brun589fcad2012-10-16 14:13:26 +02004793{
Willy Tarreaue237fe12016-03-10 17:05:28 +01004794 struct connection *conn = objt_conn((kw[4] != 'b') ? smp->sess->origin :
4795 smp->strm ? smp->strm->si[1].end : NULL);
Emeric Brun589fcad2012-10-16 14:13:26 +02004796
Willy Tarreaube508f12016-03-10 11:47:01 +01004797 smp->flags = 0;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004798 if (!conn || !conn->xprt_ctx || conn->xprt != &ssl_sock)
Emeric Brun589fcad2012-10-16 14:13:26 +02004799 return 0;
4800
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02004801 smp->data.u.str.str = (char *)SSL_get_cipher_name(conn->xprt_ctx);
4802 if (!smp->data.u.str.str)
Emeric Brun589fcad2012-10-16 14:13:26 +02004803 return 0;
4804
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02004805 smp->data.type = SMP_T_STR;
Thierry FOURNIER7654c9f2013-12-17 00:20:33 +01004806 smp->flags |= SMP_F_CONST;
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02004807 smp->data.u.str.len = strlen(smp->data.u.str.str);
Emeric Brun589fcad2012-10-16 14:13:26 +02004808
4809 return 1;
4810}
4811
Emeric Brun645ae792014-04-30 14:21:06 +02004812/* integer, returns the algoritm's keysize if front conn. transport layer
4813 * is SSL.
4814 * This function is also usable on backend conn if the fetch keyword 5th
4815 * char is 'b'.
4816 */
Emeric Brun589fcad2012-10-16 14:13:26 +02004817static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02004818smp_fetch_ssl_fc_alg_keysize(const struct arg *args, struct sample *smp, const char *kw, void *private)
Emeric Brun589fcad2012-10-16 14:13:26 +02004819{
Willy Tarreaue237fe12016-03-10 17:05:28 +01004820 struct connection *conn = objt_conn((kw[4] != 'b') ? smp->sess->origin :
4821 smp->strm ? smp->strm->si[1].end : NULL);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004822
Willy Tarreaue237fe12016-03-10 17:05:28 +01004823 int sint;
Willy Tarreaube508f12016-03-10 11:47:01 +01004824
Emeric Brun589fcad2012-10-16 14:13:26 +02004825 smp->flags = 0;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004826 if (!conn || !conn->xprt_ctx || conn->xprt != &ssl_sock)
Emeric Brun589fcad2012-10-16 14:13:26 +02004827 return 0;
4828
Thierry FOURNIER07ee64e2015-07-06 23:43:03 +02004829 if (!SSL_get_cipher_bits(conn->xprt_ctx, &sint))
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004830 return 0;
4831
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02004832 smp->data.u.sint = sint;
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02004833 smp->data.type = SMP_T_SINT;
Emeric Brun589fcad2012-10-16 14:13:26 +02004834
4835 return 1;
4836}
4837
Emeric Brun645ae792014-04-30 14:21:06 +02004838/* integer, returns the used keysize if front conn. transport layer is SSL.
4839 * This function is also usable on backend conn if the fetch keyword 5th
4840 * char is 'b'.
4841 */
Emeric Brun589fcad2012-10-16 14:13:26 +02004842static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02004843smp_fetch_ssl_fc_use_keysize(const struct arg *args, struct sample *smp, const char *kw, void *private)
Emeric Brun589fcad2012-10-16 14:13:26 +02004844{
Willy Tarreaue237fe12016-03-10 17:05:28 +01004845 struct connection *conn = objt_conn((kw[4] != 'b') ? smp->sess->origin :
4846 smp->strm ? smp->strm->si[1].end : NULL);
Willy Tarreaube508f12016-03-10 11:47:01 +01004847
Emeric Brun589fcad2012-10-16 14:13:26 +02004848 smp->flags = 0;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004849 if (!conn || !conn->xprt_ctx || conn->xprt != &ssl_sock)
4850 return 0;
4851
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02004852 smp->data.u.sint = (unsigned int)SSL_get_cipher_bits(conn->xprt_ctx, NULL);
4853 if (!smp->data.u.sint)
Emeric Brun589fcad2012-10-16 14:13:26 +02004854 return 0;
4855
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02004856 smp->data.type = SMP_T_SINT;
Emeric Brun589fcad2012-10-16 14:13:26 +02004857
4858 return 1;
4859}
4860
Willy Tarreau6c9a3d52012-10-18 18:57:14 +02004861#ifdef OPENSSL_NPN_NEGOTIATED
Willy Tarreau7875d092012-09-10 08:20:03 +02004862static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02004863smp_fetch_ssl_fc_npn(const struct arg *args, struct sample *smp, const char *kw, void *private)
Willy Tarreaua33c6542012-10-15 13:19:06 +02004864{
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004865 struct connection *conn;
4866
Thierry FOURNIER7654c9f2013-12-17 00:20:33 +01004867 smp->flags = SMP_F_CONST;
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02004868 smp->data.type = SMP_T_STR;
Willy Tarreaua33c6542012-10-15 13:19:06 +02004869
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02004870 conn = objt_conn(smp->sess->origin);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004871 if (!conn || !conn->xprt_ctx || conn->xprt != &ssl_sock)
4872 return 0;
4873
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02004874 smp->data.u.str.str = NULL;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004875 SSL_get0_next_proto_negotiated(conn->xprt_ctx,
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02004876 (const unsigned char **)&smp->data.u.str.str, (unsigned *)&smp->data.u.str.len);
Willy Tarreaua33c6542012-10-15 13:19:06 +02004877
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02004878 if (!smp->data.u.str.str)
Willy Tarreaua33c6542012-10-15 13:19:06 +02004879 return 0;
4880
4881 return 1;
Willy Tarreaua33c6542012-10-15 13:19:06 +02004882}
Willy Tarreau6c9a3d52012-10-18 18:57:14 +02004883#endif
Willy Tarreaua33c6542012-10-15 13:19:06 +02004884
Dirkjan Bussink48f1c4e2014-02-13 12:29:42 +01004885#ifdef TLSEXT_TYPE_application_layer_protocol_negotiation
Willy Tarreauab861d32013-04-02 02:30:41 +02004886static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02004887smp_fetch_ssl_fc_alpn(const struct arg *args, struct sample *smp, const char *kw, void *private)
Willy Tarreauab861d32013-04-02 02:30:41 +02004888{
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004889 struct connection *conn;
4890
Thierry FOURNIER7654c9f2013-12-17 00:20:33 +01004891 smp->flags = SMP_F_CONST;
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02004892 smp->data.type = SMP_T_STR;
Willy Tarreauab861d32013-04-02 02:30:41 +02004893
Willy Tarreaue26bf052015-05-12 10:30:12 +02004894 conn = objt_conn(smp->sess->origin);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004895 if (!conn || !conn->xprt_ctx || conn->xprt != &ssl_sock)
Willy Tarreauab861d32013-04-02 02:30:41 +02004896 return 0;
4897
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02004898 smp->data.u.str.str = NULL;
Dirkjan Bussink48f1c4e2014-02-13 12:29:42 +01004899 SSL_get0_alpn_selected(conn->xprt_ctx,
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02004900 (const unsigned char **)&smp->data.u.str.str, (unsigned *)&smp->data.u.str.len);
Willy Tarreauab861d32013-04-02 02:30:41 +02004901
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02004902 if (!smp->data.u.str.str)
Willy Tarreauab861d32013-04-02 02:30:41 +02004903 return 0;
4904
4905 return 1;
4906}
4907#endif
4908
Emeric Brun645ae792014-04-30 14:21:06 +02004909/* string, returns the used protocol if front conn. transport layer is SSL.
4910 * This function is also usable on backend conn if the fetch keyword 5th
4911 * char is 'b'.
4912 */
Willy Tarreaua33c6542012-10-15 13:19:06 +02004913static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02004914smp_fetch_ssl_fc_protocol(const struct arg *args, struct sample *smp, const char *kw, void *private)
Emeric Brun589fcad2012-10-16 14:13:26 +02004915{
Willy Tarreaue237fe12016-03-10 17:05:28 +01004916 struct connection *conn = objt_conn((kw[4] != 'b') ? smp->sess->origin :
4917 smp->strm ? smp->strm->si[1].end : NULL);
Willy Tarreaube508f12016-03-10 11:47:01 +01004918
Emeric Brun589fcad2012-10-16 14:13:26 +02004919 smp->flags = 0;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004920 if (!conn || !conn->xprt_ctx || conn->xprt != &ssl_sock)
4921 return 0;
4922
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02004923 smp->data.u.str.str = (char *)SSL_get_version(conn->xprt_ctx);
4924 if (!smp->data.u.str.str)
Emeric Brun589fcad2012-10-16 14:13:26 +02004925 return 0;
4926
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02004927 smp->data.type = SMP_T_STR;
Thierry FOURNIER7654c9f2013-12-17 00:20:33 +01004928 smp->flags = SMP_F_CONST;
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02004929 smp->data.u.str.len = strlen(smp->data.u.str.str);
Emeric Brun589fcad2012-10-16 14:13:26 +02004930
4931 return 1;
4932}
4933
Willy Tarreau87b09662015-04-03 00:22:06 +02004934/* binary, returns the SSL stream id if front conn. transport layer is SSL.
Emeric Brun645ae792014-04-30 14:21:06 +02004935 * This function is also usable on backend conn if the fetch keyword 5th
4936 * char is 'b'.
4937 */
Emeric Brun589fcad2012-10-16 14:13:26 +02004938static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02004939smp_fetch_ssl_fc_session_id(const struct arg *args, struct sample *smp, const char *kw, void *private)
Emeric Brunfe68f682012-10-16 14:59:28 +02004940{
4941#if OPENSSL_VERSION_NUMBER > 0x0090800fL
Willy Tarreaue237fe12016-03-10 17:05:28 +01004942 struct connection *conn = objt_conn((kw[4] != 'b') ? smp->sess->origin :
4943 smp->strm ? smp->strm->si[1].end : NULL);
Emeric Brunfe68f682012-10-16 14:59:28 +02004944
Willy Tarreaue237fe12016-03-10 17:05:28 +01004945 SSL_SESSION *ssl_sess;
Willy Tarreaube508f12016-03-10 11:47:01 +01004946
Thierry FOURNIER7654c9f2013-12-17 00:20:33 +01004947 smp->flags = SMP_F_CONST;
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02004948 smp->data.type = SMP_T_BIN;
Emeric Brunfe68f682012-10-16 14:59:28 +02004949
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004950 if (!conn || !conn->xprt_ctx || conn->xprt != &ssl_sock)
4951 return 0;
4952
Willy Tarreau192252e2015-04-04 01:47:55 +02004953 ssl_sess = SSL_get_session(conn->xprt_ctx);
4954 if (!ssl_sess)
Emeric Brunfe68f682012-10-16 14:59:28 +02004955 return 0;
4956
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02004957 smp->data.u.str.str = (char *)SSL_SESSION_get_id(ssl_sess, (unsigned int *)&smp->data.u.str.len);
4958 if (!smp->data.u.str.str || !smp->data.u.str.len)
Emeric Brunfe68f682012-10-16 14:59:28 +02004959 return 0;
4960
4961 return 1;
4962#else
4963 return 0;
4964#endif
4965}
4966
4967static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02004968smp_fetch_ssl_fc_sni(const struct arg *args, struct sample *smp, const char *kw, void *private)
Willy Tarreau7875d092012-09-10 08:20:03 +02004969{
4970#ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004971 struct connection *conn;
4972
Thierry FOURNIER7654c9f2013-12-17 00:20:33 +01004973 smp->flags = SMP_F_CONST;
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02004974 smp->data.type = SMP_T_STR;
Willy Tarreau7875d092012-09-10 08:20:03 +02004975
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02004976 conn = objt_conn(smp->sess->origin);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004977 if (!conn || !conn->xprt_ctx || conn->xprt != &ssl_sock)
4978 return 0;
4979
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02004980 smp->data.u.str.str = (char *)SSL_get_servername(conn->xprt_ctx, TLSEXT_NAMETYPE_host_name);
4981 if (!smp->data.u.str.str)
Willy Tarreau3e394c92012-09-14 23:56:58 +02004982 return 0;
4983
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02004984 smp->data.u.str.len = strlen(smp->data.u.str.str);
Willy Tarreau7875d092012-09-10 08:20:03 +02004985 return 1;
4986#else
4987 return 0;
4988#endif
4989}
4990
David Sc1ad52e2014-04-08 18:48:47 -04004991static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02004992smp_fetch_ssl_fc_unique_id(const struct arg *args, struct sample *smp, const char *kw, void *private)
David Sc1ad52e2014-04-08 18:48:47 -04004993{
4994#if OPENSSL_VERSION_NUMBER > 0x0090800fL
Willy Tarreaue237fe12016-03-10 17:05:28 +01004995 struct connection *conn = objt_conn((kw[4] != 'b') ? smp->sess->origin :
4996 smp->strm ? smp->strm->si[1].end : NULL);
4997
David Sc1ad52e2014-04-08 18:48:47 -04004998 int finished_len;
David Sc1ad52e2014-04-08 18:48:47 -04004999 struct chunk *finished_trash;
David Sc1ad52e2014-04-08 18:48:47 -04005000
5001 smp->flags = 0;
David Sc1ad52e2014-04-08 18:48:47 -04005002 if (!conn || !conn->xprt_ctx || conn->xprt != &ssl_sock)
5003 return 0;
5004
5005 if (!(conn->flags & CO_FL_CONNECTED)) {
5006 smp->flags |= SMP_F_MAY_CHANGE;
5007 return 0;
5008 }
5009
5010 finished_trash = get_trash_chunk();
5011 if (!SSL_session_reused(conn->xprt_ctx))
5012 finished_len = SSL_get_peer_finished(conn->xprt_ctx, finished_trash->str, finished_trash->size);
5013 else
5014 finished_len = SSL_get_finished(conn->xprt_ctx, finished_trash->str, finished_trash->size);
5015
5016 if (!finished_len)
5017 return 0;
5018
Emeric Brunb73a9b02014-04-30 18:49:19 +02005019 finished_trash->len = finished_len;
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02005020 smp->data.u.str = *finished_trash;
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02005021 smp->data.type = SMP_T_BIN;
David Sc1ad52e2014-04-08 18:48:47 -04005022
5023 return 1;
5024#else
5025 return 0;
5026#endif
5027}
5028
Emeric Brun2525b6b2012-10-18 15:59:43 +02005029/* integer, returns the first verify error in CA chain of client certificate chain. */
Emeric Brunf282a812012-09-21 15:27:54 +02005030static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02005031smp_fetch_ssl_c_ca_err(const struct arg *args, struct sample *smp, const char *kw, void *private)
Emeric Brunf282a812012-09-21 15:27:54 +02005032{
Willy Tarreaub363a1f2013-10-01 10:45:07 +02005033 struct connection *conn;
5034
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02005035 conn = objt_conn(smp->sess->origin);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02005036 if (!conn || conn->xprt != &ssl_sock)
5037 return 0;
5038
5039 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brunf282a812012-09-21 15:27:54 +02005040 smp->flags = SMP_F_MAY_CHANGE;
5041 return 0;
5042 }
5043
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02005044 smp->data.type = SMP_T_SINT;
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02005045 smp->data.u.sint = (unsigned long long int)SSL_SOCK_ST_TO_CA_ERROR(conn->xprt_st);
Emeric Brunf282a812012-09-21 15:27:54 +02005046 smp->flags = 0;
5047
5048 return 1;
5049}
5050
Emeric Brun2525b6b2012-10-18 15:59:43 +02005051/* integer, returns the depth of the first verify error in CA chain of client certificate chain. */
Emeric Brunf282a812012-09-21 15:27:54 +02005052static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02005053smp_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 +02005054{
Willy Tarreaub363a1f2013-10-01 10:45:07 +02005055 struct connection *conn;
5056
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02005057 conn = objt_conn(smp->sess->origin);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02005058 if (!conn || conn->xprt != &ssl_sock)
Emeric Brunf282a812012-09-21 15:27:54 +02005059 return 0;
5060
Willy Tarreaub363a1f2013-10-01 10:45:07 +02005061 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brunf282a812012-09-21 15:27:54 +02005062 smp->flags = SMP_F_MAY_CHANGE;
5063 return 0;
5064 }
5065
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02005066 smp->data.type = SMP_T_SINT;
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02005067 smp->data.u.sint = (long long int)SSL_SOCK_ST_TO_CAEDEPTH(conn->xprt_st);
Emeric Brunf282a812012-09-21 15:27:54 +02005068 smp->flags = 0;
5069
5070 return 1;
5071}
5072
Emeric Brun2525b6b2012-10-18 15:59:43 +02005073/* integer, returns the first verify error on client certificate */
Emeric Brunf282a812012-09-21 15:27:54 +02005074static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02005075smp_fetch_ssl_c_err(const struct arg *args, struct sample *smp, const char *kw, void *private)
Emeric Brunf282a812012-09-21 15:27:54 +02005076{
Willy Tarreaub363a1f2013-10-01 10:45:07 +02005077 struct connection *conn;
5078
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02005079 conn = objt_conn(smp->sess->origin);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02005080 if (!conn || conn->xprt != &ssl_sock)
5081 return 0;
5082
5083 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brunf282a812012-09-21 15:27:54 +02005084 smp->flags = SMP_F_MAY_CHANGE;
5085 return 0;
5086 }
5087
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02005088 smp->data.type = SMP_T_SINT;
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02005089 smp->data.u.sint = (long long int)SSL_SOCK_ST_TO_CRTERROR(conn->xprt_st);
Emeric Brunf282a812012-09-21 15:27:54 +02005090 smp->flags = 0;
5091
5092 return 1;
5093}
5094
Emeric Brun2525b6b2012-10-18 15:59:43 +02005095/* integer, returns the verify result on client cert */
Emeric Brunbaf8ffb2012-09-21 15:27:20 +02005096static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02005097smp_fetch_ssl_c_verify(const struct arg *args, struct sample *smp, const char *kw, void *private)
Emeric Brunbaf8ffb2012-09-21 15:27:20 +02005098{
Willy Tarreaub363a1f2013-10-01 10:45:07 +02005099 struct connection *conn;
5100
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02005101 conn = objt_conn(smp->sess->origin);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02005102 if (!conn || conn->xprt != &ssl_sock)
5103 return 0;
5104
5105 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brunbaf8ffb2012-09-21 15:27:20 +02005106 smp->flags = SMP_F_MAY_CHANGE;
5107 return 0;
5108 }
5109
Willy Tarreaub363a1f2013-10-01 10:45:07 +02005110 if (!conn->xprt_ctx)
Emeric Brunbaf8ffb2012-09-21 15:27:20 +02005111 return 0;
5112
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02005113 smp->data.type = SMP_T_SINT;
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02005114 smp->data.u.sint = (long long int)SSL_get_verify_result(conn->xprt_ctx);
Emeric Brunbaf8ffb2012-09-21 15:27:20 +02005115 smp->flags = 0;
5116
5117 return 1;
5118}
5119
Emeric Brunfb510ea2012-10-05 12:00:26 +02005120/* parse the "ca-file" bind keyword */
5121static 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 +02005122{
5123 if (!*args[cur_arg + 1]) {
5124 if (err)
5125 memprintf(err, "'%s' : missing CAfile path", args[cur_arg]);
5126 return ERR_ALERT | ERR_FATAL;
5127 }
5128
Emeric Brunef42d922012-10-11 16:11:36 +02005129 if ((*args[cur_arg + 1] != '/') && global.ca_base)
5130 memprintf(&conf->ca_file, "%s/%s", global.ca_base, args[cur_arg + 1]);
5131 else
5132 memprintf(&conf->ca_file, "%s", args[cur_arg + 1]);
Emeric Brunc8e8d122012-10-02 18:42:10 +02005133
Emeric Brund94b3fe2012-09-20 18:23:56 +02005134 return 0;
5135}
5136
Christopher Faulet31af49d2015-06-09 17:29:50 +02005137/* parse the "ca-sign-file" bind keyword */
5138static int bind_parse_ca_sign_file(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
5139{
5140 if (!*args[cur_arg + 1]) {
5141 if (err)
5142 memprintf(err, "'%s' : missing CAfile path", args[cur_arg]);
5143 return ERR_ALERT | ERR_FATAL;
5144 }
5145
5146 if ((*args[cur_arg + 1] != '/') && global.ca_base)
5147 memprintf(&conf->ca_sign_file, "%s/%s", global.ca_base, args[cur_arg + 1]);
5148 else
5149 memprintf(&conf->ca_sign_file, "%s", args[cur_arg + 1]);
5150
5151 return 0;
5152}
5153
Bertrand Jacquinff13c062016-11-13 16:37:11 +00005154/* parse the "ca-sign-pass" bind keyword */
Christopher Faulet31af49d2015-06-09 17:29:50 +02005155static int bind_parse_ca_sign_pass(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
5156{
5157 if (!*args[cur_arg + 1]) {
5158 if (err)
5159 memprintf(err, "'%s' : missing CAkey password", args[cur_arg]);
5160 return ERR_ALERT | ERR_FATAL;
5161 }
5162 memprintf(&conf->ca_sign_pass, "%s", args[cur_arg + 1]);
5163 return 0;
5164}
5165
Willy Tarreau79eeafa2012-09-14 07:53:05 +02005166/* parse the "ciphers" bind keyword */
Willy Tarreau4348fad2012-09-20 16:48:07 +02005167static 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 +02005168{
5169 if (!*args[cur_arg + 1]) {
Willy Tarreaueb6cead2012-09-20 19:43:14 +02005170 memprintf(err, "'%s' : missing cipher suite", args[cur_arg]);
Willy Tarreau79eeafa2012-09-14 07:53:05 +02005171 return ERR_ALERT | ERR_FATAL;
5172 }
5173
Emeric Brun76d88952012-10-05 15:47:31 +02005174 free(conf->ciphers);
Willy Tarreau4348fad2012-09-20 16:48:07 +02005175 conf->ciphers = strdup(args[cur_arg + 1]);
Willy Tarreau79eeafa2012-09-14 07:53:05 +02005176 return 0;
5177}
5178
5179/* parse the "crt" bind keyword */
Willy Tarreau4348fad2012-09-20 16:48:07 +02005180static 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 +02005181{
Willy Tarreau38011032013-08-13 16:59:39 +02005182 char path[MAXPATHLEN];
Willy Tarreaub75d6922014-04-14 18:05:41 +02005183
Willy Tarreau79eeafa2012-09-14 07:53:05 +02005184 if (!*args[cur_arg + 1]) {
Willy Tarreaueb6cead2012-09-20 19:43:14 +02005185 memprintf(err, "'%s' : missing certificate location", args[cur_arg]);
Willy Tarreau79eeafa2012-09-14 07:53:05 +02005186 return ERR_ALERT | ERR_FATAL;
5187 }
5188
Emeric Brunc8e8d122012-10-02 18:42:10 +02005189 if ((*args[cur_arg + 1] != '/' ) && global.crt_base) {
Willy Tarreau38011032013-08-13 16:59:39 +02005190 if ((strlen(global.crt_base) + 1 + strlen(args[cur_arg + 1]) + 1) > MAXPATHLEN) {
Emeric Brunc8e8d122012-10-02 18:42:10 +02005191 memprintf(err, "'%s' : path too long", args[cur_arg]);
5192 return ERR_ALERT | ERR_FATAL;
5193 }
Willy Tarreaub75d6922014-04-14 18:05:41 +02005194 snprintf(path, sizeof(path), "%s/%s", global.crt_base, args[cur_arg + 1]);
Emeric Brunc8e8d122012-10-02 18:42:10 +02005195 if (ssl_sock_load_cert(path, conf, px, err) > 0)
5196 return ERR_ALERT | ERR_FATAL;
5197
5198 return 0;
5199 }
5200
Willy Tarreau4348fad2012-09-20 16:48:07 +02005201 if (ssl_sock_load_cert(args[cur_arg + 1], conf, px, err) > 0)
Willy Tarreau79eeafa2012-09-14 07:53:05 +02005202 return ERR_ALERT | ERR_FATAL;
Emeric Brund94b3fe2012-09-20 18:23:56 +02005203
5204 return 0;
5205}
5206
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01005207/* parse the "crt-list" bind keyword */
5208static int bind_parse_crt_list(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
5209{
5210 if (!*args[cur_arg + 1]) {
5211 memprintf(err, "'%s' : missing certificate location", args[cur_arg]);
5212 return ERR_ALERT | ERR_FATAL;
5213 }
5214
Willy Tarreauad1731d2013-04-02 17:35:58 +02005215 if (ssl_sock_load_cert_list_file(args[cur_arg + 1], conf, px, err) > 0) {
5216 memprintf(err, "'%s' : %s", args[cur_arg], *err);
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01005217 return ERR_ALERT | ERR_FATAL;
Willy Tarreauad1731d2013-04-02 17:35:58 +02005218 }
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01005219
5220 return 0;
5221}
5222
Emeric Brunfb510ea2012-10-05 12:00:26 +02005223/* parse the "crl-file" bind keyword */
5224static 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 +02005225{
Emeric Brun051cdab2012-10-02 19:25:50 +02005226#ifndef X509_V_FLAG_CRL_CHECK
5227 if (err)
5228 memprintf(err, "'%s' : library does not support CRL verify", args[cur_arg]);
5229 return ERR_ALERT | ERR_FATAL;
5230#else
Emeric Brund94b3fe2012-09-20 18:23:56 +02005231 if (!*args[cur_arg + 1]) {
5232 if (err)
5233 memprintf(err, "'%s' : missing CRLfile path", args[cur_arg]);
5234 return ERR_ALERT | ERR_FATAL;
5235 }
Emeric Brun2b58d042012-09-20 17:10:03 +02005236
Emeric Brunef42d922012-10-11 16:11:36 +02005237 if ((*args[cur_arg + 1] != '/') && global.ca_base)
5238 memprintf(&conf->crl_file, "%s/%s", global.ca_base, args[cur_arg + 1]);
5239 else
5240 memprintf(&conf->crl_file, "%s", args[cur_arg + 1]);
Emeric Brunc8e8d122012-10-02 18:42:10 +02005241
Emeric Brun2b58d042012-09-20 17:10:03 +02005242 return 0;
Emeric Brun051cdab2012-10-02 19:25:50 +02005243#endif
Emeric Brun2b58d042012-09-20 17:10:03 +02005244}
5245
Bertrand Jacquinff13c062016-11-13 16:37:11 +00005246/* parse the "ecdhe" bind keyword keyword */
Emeric Brun2b58d042012-09-20 17:10:03 +02005247static int bind_parse_ecdhe(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
5248{
5249#if OPENSSL_VERSION_NUMBER < 0x0090800fL
5250 if (err)
5251 memprintf(err, "'%s' : library does not support elliptic curve Diffie-Hellman (too old)", args[cur_arg]);
5252 return ERR_ALERT | ERR_FATAL;
5253#elif defined(OPENSSL_NO_ECDH)
5254 if (err)
5255 memprintf(err, "'%s' : library does not support elliptic curve Diffie-Hellman (disabled via OPENSSL_NO_ECDH)", args[cur_arg]);
5256 return ERR_ALERT | ERR_FATAL;
5257#else
5258 if (!*args[cur_arg + 1]) {
5259 if (err)
5260 memprintf(err, "'%s' : missing named curve", args[cur_arg]);
5261 return ERR_ALERT | ERR_FATAL;
5262 }
5263
5264 conf->ecdhe = strdup(args[cur_arg + 1]);
Willy Tarreau79eeafa2012-09-14 07:53:05 +02005265
5266 return 0;
Emeric Brun2b58d042012-09-20 17:10:03 +02005267#endif
Willy Tarreau79eeafa2012-09-14 07:53:05 +02005268}
5269
Bertrand Jacquinff13c062016-11-13 16:37:11 +00005270/* parse the "crt-ignore-err" and "ca-ignore-err" bind keywords */
Emeric Brun81c00f02012-09-21 14:31:21 +02005271static int bind_parse_ignore_err(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
5272{
5273 int code;
5274 char *p = args[cur_arg + 1];
5275 unsigned long long *ignerr = &conf->crt_ignerr;
5276
5277 if (!*p) {
5278 if (err)
5279 memprintf(err, "'%s' : missing error IDs list", args[cur_arg]);
5280 return ERR_ALERT | ERR_FATAL;
5281 }
5282
5283 if (strcmp(args[cur_arg], "ca-ignore-err") == 0)
5284 ignerr = &conf->ca_ignerr;
5285
5286 if (strcmp(p, "all") == 0) {
5287 *ignerr = ~0ULL;
5288 return 0;
5289 }
5290
5291 while (p) {
5292 code = atoi(p);
5293 if ((code <= 0) || (code > 63)) {
5294 if (err)
5295 memprintf(err, "'%s' : ID '%d' out of range (1..63) in error IDs list '%s'",
5296 args[cur_arg], code, args[cur_arg + 1]);
5297 return ERR_ALERT | ERR_FATAL;
5298 }
5299 *ignerr |= 1ULL << code;
5300 p = strchr(p, ',');
5301 if (p)
5302 p++;
5303 }
5304
Emeric Brun2cb7ae52012-10-05 14:14:21 +02005305 return 0;
5306}
5307
5308/* parse the "force-sslv3" bind keyword */
5309static int bind_parse_force_sslv3(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
5310{
5311 conf->ssl_options |= BC_SSL_O_USE_SSLV3;
5312 return 0;
5313}
5314
5315/* parse the "force-tlsv10" bind keyword */
5316static int bind_parse_force_tlsv10(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
5317{
5318 conf->ssl_options |= BC_SSL_O_USE_TLSV10;
Emeric Brun2d0c4822012-10-02 13:45:20 +02005319 return 0;
5320}
5321
Emeric Brun2cb7ae52012-10-05 14:14:21 +02005322/* parse the "force-tlsv11" bind keyword */
5323static int bind_parse_force_tlsv11(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
5324{
5325#if SSL_OP_NO_TLSv1_1
5326 conf->ssl_options |= BC_SSL_O_USE_TLSV11;
5327 return 0;
5328#else
5329 if (err)
5330 memprintf(err, "'%s' : library does not support protocol TLSv1.1", args[cur_arg]);
5331 return ERR_ALERT | ERR_FATAL;
5332#endif
5333}
5334
5335/* parse the "force-tlsv12" bind keyword */
5336static int bind_parse_force_tlsv12(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
5337{
5338#if SSL_OP_NO_TLSv1_2
5339 conf->ssl_options |= BC_SSL_O_USE_TLSV12;
5340 return 0;
5341#else
5342 if (err)
5343 memprintf(err, "'%s' : library does not support protocol TLSv1.2", args[cur_arg]);
5344 return ERR_ALERT | ERR_FATAL;
5345#endif
5346}
5347
5348
Emeric Brun2d0c4822012-10-02 13:45:20 +02005349/* parse the "no-tls-tickets" bind keyword */
5350static int bind_parse_no_tls_tickets(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
5351{
Emeric Brun89675492012-10-05 13:48:26 +02005352 conf->ssl_options |= BC_SSL_O_NO_TLS_TICKETS;
Emeric Brun81c00f02012-09-21 14:31:21 +02005353 return 0;
5354}
5355
Emeric Brun2d0c4822012-10-02 13:45:20 +02005356
Emeric Brun9b3009b2012-10-05 11:55:06 +02005357/* parse the "no-sslv3" bind keyword */
5358static 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 +02005359{
Emeric Brun89675492012-10-05 13:48:26 +02005360 conf->ssl_options |= BC_SSL_O_NO_SSLV3;
Willy Tarreau79eeafa2012-09-14 07:53:05 +02005361 return 0;
5362}
5363
Emeric Brun9b3009b2012-10-05 11:55:06 +02005364/* parse the "no-tlsv10" bind keyword */
5365static 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 +02005366{
Emeric Brun89675492012-10-05 13:48:26 +02005367 conf->ssl_options |= BC_SSL_O_NO_TLSV10;
Emeric Brunc0ff4922012-09-28 19:37:02 +02005368 return 0;
5369}
5370
Emeric Brun9b3009b2012-10-05 11:55:06 +02005371/* parse the "no-tlsv11" bind keyword */
5372static 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 +02005373{
Emeric Brun89675492012-10-05 13:48:26 +02005374 conf->ssl_options |= BC_SSL_O_NO_TLSV11;
Emeric Brunc0ff4922012-09-28 19:37:02 +02005375 return 0;
5376}
5377
Emeric Brun9b3009b2012-10-05 11:55:06 +02005378/* parse the "no-tlsv12" bind keyword */
5379static 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 +02005380{
Emeric Brun89675492012-10-05 13:48:26 +02005381 conf->ssl_options |= BC_SSL_O_NO_TLSV12;
Willy Tarreau79eeafa2012-09-14 07:53:05 +02005382 return 0;
5383}
5384
Willy Tarreau6c9a3d52012-10-18 18:57:14 +02005385/* parse the "npn" bind keyword */
5386static int bind_parse_npn(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
5387{
5388#ifdef OPENSSL_NPN_NEGOTIATED
5389 char *p1, *p2;
5390
5391 if (!*args[cur_arg + 1]) {
5392 memprintf(err, "'%s' : missing the comma-delimited NPN protocol suite", args[cur_arg]);
5393 return ERR_ALERT | ERR_FATAL;
5394 }
5395
5396 free(conf->npn_str);
5397
Willy Tarreau3724da12016-02-12 17:11:12 +01005398 /* the NPN string is built as a suite of (<len> <name>)*,
5399 * so we reuse each comma to store the next <len> and need
5400 * one more for the end of the string.
5401 */
Willy Tarreau6c9a3d52012-10-18 18:57:14 +02005402 conf->npn_len = strlen(args[cur_arg + 1]) + 1;
Willy Tarreau3724da12016-02-12 17:11:12 +01005403 conf->npn_str = calloc(1, conf->npn_len + 1);
Willy Tarreau6c9a3d52012-10-18 18:57:14 +02005404 memcpy(conf->npn_str + 1, args[cur_arg + 1], conf->npn_len);
5405
5406 /* replace commas with the name length */
5407 p1 = conf->npn_str;
5408 p2 = p1 + 1;
5409 while (1) {
5410 p2 = memchr(p1 + 1, ',', conf->npn_str + conf->npn_len - (p1 + 1));
5411 if (!p2)
5412 p2 = p1 + 1 + strlen(p1 + 1);
5413
5414 if (p2 - (p1 + 1) > 255) {
5415 *p2 = '\0';
5416 memprintf(err, "'%s' : NPN protocol name too long : '%s'", args[cur_arg], p1 + 1);
5417 return ERR_ALERT | ERR_FATAL;
5418 }
5419
5420 *p1 = p2 - (p1 + 1);
5421 p1 = p2;
5422
5423 if (!*p2)
5424 break;
5425
5426 *(p2++) = '\0';
5427 }
5428 return 0;
5429#else
5430 if (err)
5431 memprintf(err, "'%s' : library does not support TLS NPN extension", args[cur_arg]);
5432 return ERR_ALERT | ERR_FATAL;
5433#endif
5434}
5435
Willy Tarreauab861d32013-04-02 02:30:41 +02005436/* parse the "alpn" bind keyword */
5437static int bind_parse_alpn(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
5438{
Dirkjan Bussink48f1c4e2014-02-13 12:29:42 +01005439#ifdef TLSEXT_TYPE_application_layer_protocol_negotiation
Willy Tarreauab861d32013-04-02 02:30:41 +02005440 char *p1, *p2;
5441
5442 if (!*args[cur_arg + 1]) {
5443 memprintf(err, "'%s' : missing the comma-delimited ALPN protocol suite", args[cur_arg]);
5444 return ERR_ALERT | ERR_FATAL;
5445 }
5446
5447 free(conf->alpn_str);
5448
Marcoen Hirschbergbef60912016-02-12 17:05:24 +01005449 /* the ALPN string is built as a suite of (<len> <name>)*,
5450 * so we reuse each comma to store the next <len> and need
5451 * one more for the end of the string.
5452 */
Willy Tarreauab861d32013-04-02 02:30:41 +02005453 conf->alpn_len = strlen(args[cur_arg + 1]) + 1;
Marcoen Hirschbergbef60912016-02-12 17:05:24 +01005454 conf->alpn_str = calloc(1, conf->alpn_len + 1);
Willy Tarreauab861d32013-04-02 02:30:41 +02005455 memcpy(conf->alpn_str + 1, args[cur_arg + 1], conf->alpn_len);
5456
5457 /* replace commas with the name length */
5458 p1 = conf->alpn_str;
5459 p2 = p1 + 1;
5460 while (1) {
5461 p2 = memchr(p1 + 1, ',', conf->alpn_str + conf->alpn_len - (p1 + 1));
5462 if (!p2)
5463 p2 = p1 + 1 + strlen(p1 + 1);
5464
5465 if (p2 - (p1 + 1) > 255) {
5466 *p2 = '\0';
5467 memprintf(err, "'%s' : ALPN protocol name too long : '%s'", args[cur_arg], p1 + 1);
5468 return ERR_ALERT | ERR_FATAL;
5469 }
5470
5471 *p1 = p2 - (p1 + 1);
5472 p1 = p2;
5473
5474 if (!*p2)
5475 break;
5476
5477 *(p2++) = '\0';
5478 }
5479 return 0;
5480#else
5481 if (err)
5482 memprintf(err, "'%s' : library does not support TLS ALPN extension", args[cur_arg]);
5483 return ERR_ALERT | ERR_FATAL;
5484#endif
5485}
5486
Willy Tarreau79eeafa2012-09-14 07:53:05 +02005487/* parse the "ssl" bind keyword */
Willy Tarreau4348fad2012-09-20 16:48:07 +02005488static 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 +02005489{
Willy Tarreau81796be2012-09-22 19:11:47 +02005490 struct listener *l;
5491
Willy Tarreau4348fad2012-09-20 16:48:07 +02005492 conf->is_ssl = 1;
Emeric Brun76d88952012-10-05 15:47:31 +02005493
5494 if (global.listen_default_ciphers && !conf->ciphers)
5495 conf->ciphers = strdup(global.listen_default_ciphers);
Emeric Brun2c86cbf2014-10-30 15:56:50 +01005496 conf->ssl_options |= global.listen_default_ssloptions;
Emeric Brun76d88952012-10-05 15:47:31 +02005497
Willy Tarreau81796be2012-09-22 19:11:47 +02005498 list_for_each_entry(l, &conf->listeners, by_bind)
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02005499 l->xprt = &ssl_sock;
Willy Tarreau81796be2012-09-22 19:11:47 +02005500
Willy Tarreau79eeafa2012-09-14 07:53:05 +02005501 return 0;
5502}
5503
Christopher Faulet31af49d2015-06-09 17:29:50 +02005504/* parse the "generate-certificates" bind keyword */
5505static int bind_parse_generate_certs(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
5506{
5507#ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME
5508 conf->generate_certs = 1;
5509#else
5510 memprintf(err, "%sthis version of openssl cannot generate SSL certificates.\n",
5511 err && *err ? *err : "");
5512#endif
5513 return 0;
5514}
5515
Emmanuel Hocdet65623372013-01-24 17:17:15 +01005516/* parse the "strict-sni" bind keyword */
5517static int bind_parse_strict_sni(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
5518{
5519 conf->strict_sni = 1;
5520 return 0;
Nenad Merdanovic05552d42015-02-27 19:56:49 +01005521}
5522
5523/* parse the "tls-ticket-keys" bind keyword */
5524static int bind_parse_tls_ticket_keys(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
5525{
5526#if (defined SSL_CTRL_SET_TLSEXT_TICKET_KEY_CB && TLS_TICKETS_NO > 0)
5527 FILE *f;
5528 int i = 0;
5529 char thisline[LINESIZE];
Nenad Merdanovic146defa2015-05-09 08:46:00 +02005530 struct tls_keys_ref *keys_ref;
Nenad Merdanovic05552d42015-02-27 19:56:49 +01005531
5532 if (!*args[cur_arg + 1]) {
5533 if (err)
5534 memprintf(err, "'%s' : missing TLS ticket keys file path", args[cur_arg]);
5535 return ERR_ALERT | ERR_FATAL;
5536 }
5537
Nenad Merdanovic200b0fa2015-05-09 08:46:01 +02005538 keys_ref = tlskeys_ref_lookup(args[cur_arg + 1]);
5539 if(keys_ref) {
5540 conf->keys_ref = keys_ref;
5541 return 0;
5542 }
5543
Vincent Bernat02779b62016-04-03 13:48:43 +02005544 keys_ref = malloc(sizeof(*keys_ref));
Nenad Merdanovic146defa2015-05-09 08:46:00 +02005545 keys_ref->tlskeys = malloc(TLS_TICKETS_NO * sizeof(struct tls_sess_key));
Nenad Merdanovic05552d42015-02-27 19:56:49 +01005546
5547 if ((f = fopen(args[cur_arg + 1], "r")) == NULL) {
5548 if (err)
5549 memprintf(err, "'%s' : unable to load ssl tickets keys file", args[cur_arg+1]);
5550 return ERR_ALERT | ERR_FATAL;
5551 }
5552
Nenad Merdanovic146defa2015-05-09 08:46:00 +02005553 keys_ref->filename = strdup(args[cur_arg + 1]);
5554
Nenad Merdanovic05552d42015-02-27 19:56:49 +01005555 while (fgets(thisline, sizeof(thisline), f) != NULL) {
5556 int len = strlen(thisline);
5557 /* Strip newline characters from the end */
5558 if(thisline[len - 1] == '\n')
5559 thisline[--len] = 0;
5560
5561 if(thisline[len - 1] == '\r')
5562 thisline[--len] = 0;
5563
Nenad Merdanovic146defa2015-05-09 08:46:00 +02005564 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 +01005565 if (err)
5566 memprintf(err, "'%s' : unable to decode base64 key on line %d", args[cur_arg+1], i + 1);
mildis16aa0152016-06-22 17:46:29 +02005567 fclose(f);
Nenad Merdanovic05552d42015-02-27 19:56:49 +01005568 return ERR_ALERT | ERR_FATAL;
5569 }
5570 i++;
5571 }
5572
5573 if (i < TLS_TICKETS_NO) {
5574 if (err)
5575 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 +02005576 fclose(f);
Nenad Merdanovic05552d42015-02-27 19:56:49 +01005577 return ERR_ALERT | ERR_FATAL;
5578 }
5579
5580 fclose(f);
5581
5582 /* Use penultimate key for encryption, handle when TLS_TICKETS_NO = 1 */
Nenad Merdanovic17891152016-03-25 22:16:57 +01005583 i -= 2;
5584 keys_ref->tls_ticket_enc_index = i < 0 ? 0 : i % TLS_TICKETS_NO;
Nenad Merdanovic200b0fa2015-05-09 08:46:01 +02005585 keys_ref->unique_id = -1;
Nenad Merdanovic146defa2015-05-09 08:46:00 +02005586 conf->keys_ref = keys_ref;
Nenad Merdanovic05552d42015-02-27 19:56:49 +01005587
Nenad Merdanovic200b0fa2015-05-09 08:46:01 +02005588 LIST_ADD(&tlskeys_reference, &keys_ref->list);
5589
Nenad Merdanovic05552d42015-02-27 19:56:49 +01005590 return 0;
5591#else
5592 if (err)
5593 memprintf(err, "'%s' : TLS ticket callback extension not supported", args[cur_arg]);
5594 return ERR_ALERT | ERR_FATAL;
5595#endif /* SSL_CTRL_SET_TLSEXT_TICKET_KEY_CB */
Emmanuel Hocdet65623372013-01-24 17:17:15 +01005596}
5597
Emeric Brund94b3fe2012-09-20 18:23:56 +02005598/* parse the "verify" bind keyword */
5599static int bind_parse_verify(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
5600{
5601 if (!*args[cur_arg + 1]) {
5602 if (err)
5603 memprintf(err, "'%s' : missing verify method", args[cur_arg]);
5604 return ERR_ALERT | ERR_FATAL;
5605 }
5606
5607 if (strcmp(args[cur_arg + 1], "none") == 0)
Emeric Brun850efd52014-01-29 12:24:34 +01005608 conf->verify = SSL_SOCK_VERIFY_NONE;
Emeric Brund94b3fe2012-09-20 18:23:56 +02005609 else if (strcmp(args[cur_arg + 1], "optional") == 0)
Emeric Brun850efd52014-01-29 12:24:34 +01005610 conf->verify = SSL_SOCK_VERIFY_OPTIONAL;
Emeric Brund94b3fe2012-09-20 18:23:56 +02005611 else if (strcmp(args[cur_arg + 1], "required") == 0)
Emeric Brun850efd52014-01-29 12:24:34 +01005612 conf->verify = SSL_SOCK_VERIFY_REQUIRED;
Emeric Brund94b3fe2012-09-20 18:23:56 +02005613 else {
5614 if (err)
5615 memprintf(err, "'%s' : unknown verify method '%s', only 'none', 'optional', and 'required' are supported\n",
5616 args[cur_arg], args[cur_arg + 1]);
5617 return ERR_ALERT | ERR_FATAL;
5618 }
5619
5620 return 0;
5621}
5622
Willy Tarreau92faadf2012-10-10 23:04:25 +02005623/************** "server" keywords ****************/
5624
Emeric Brunef42d922012-10-11 16:11:36 +02005625/* parse the "ca-file" server keyword */
5626static int srv_parse_ca_file(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
5627{
5628 if (!*args[*cur_arg + 1]) {
5629 if (err)
5630 memprintf(err, "'%s' : missing CAfile path", args[*cur_arg]);
5631 return ERR_ALERT | ERR_FATAL;
5632 }
5633
5634 if ((*args[*cur_arg + 1] != '/') && global.ca_base)
5635 memprintf(&newsrv->ssl_ctx.ca_file, "%s/%s", global.ca_base, args[*cur_arg + 1]);
5636 else
5637 memprintf(&newsrv->ssl_ctx.ca_file, "%s", args[*cur_arg + 1]);
5638
5639 return 0;
5640}
5641
Willy Tarreau92faadf2012-10-10 23:04:25 +02005642/* parse the "check-ssl" server keyword */
5643static int srv_parse_check_ssl(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
5644{
5645 newsrv->check.use_ssl = 1;
5646 if (global.connect_default_ciphers && !newsrv->ssl_ctx.ciphers)
5647 newsrv->ssl_ctx.ciphers = strdup(global.connect_default_ciphers);
Emeric Brun2c86cbf2014-10-30 15:56:50 +01005648 newsrv->ssl_ctx.options |= global.connect_default_ssloptions;
Willy Tarreau92faadf2012-10-10 23:04:25 +02005649 return 0;
5650}
5651
5652/* parse the "ciphers" server keyword */
5653static int srv_parse_ciphers(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
5654{
5655 if (!*args[*cur_arg + 1]) {
5656 memprintf(err, "'%s' : missing cipher suite", args[*cur_arg]);
5657 return ERR_ALERT | ERR_FATAL;
5658 }
5659
5660 free(newsrv->ssl_ctx.ciphers);
5661 newsrv->ssl_ctx.ciphers = strdup(args[*cur_arg + 1]);
5662 return 0;
5663}
5664
Emeric Brunef42d922012-10-11 16:11:36 +02005665/* parse the "crl-file" server keyword */
5666static int srv_parse_crl_file(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
5667{
5668#ifndef X509_V_FLAG_CRL_CHECK
5669 if (err)
5670 memprintf(err, "'%s' : library does not support CRL verify", args[*cur_arg]);
5671 return ERR_ALERT | ERR_FATAL;
5672#else
5673 if (!*args[*cur_arg + 1]) {
5674 if (err)
5675 memprintf(err, "'%s' : missing CRLfile path", args[*cur_arg]);
5676 return ERR_ALERT | ERR_FATAL;
5677 }
5678
5679 if ((*args[*cur_arg + 1] != '/') && global.ca_base)
5680 memprintf(&newsrv->ssl_ctx.crl_file, "%s/%s", global.ca_base, args[*cur_arg + 1]);
5681 else
5682 memprintf(&newsrv->ssl_ctx.crl_file, "%s", args[*cur_arg + 1]);
5683
5684 return 0;
5685#endif
5686}
5687
Emeric Bruna7aa3092012-10-26 12:58:00 +02005688/* parse the "crt" server keyword */
5689static int srv_parse_crt(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
5690{
5691 if (!*args[*cur_arg + 1]) {
5692 if (err)
5693 memprintf(err, "'%s' : missing certificate file path", args[*cur_arg]);
5694 return ERR_ALERT | ERR_FATAL;
5695 }
5696
5697 if ((*args[*cur_arg + 1] != '/') && global.crt_base)
5698 memprintf(&newsrv->ssl_ctx.client_crt, "%s/%s", global.ca_base, args[*cur_arg + 1]);
5699 else
5700 memprintf(&newsrv->ssl_ctx.client_crt, "%s", args[*cur_arg + 1]);
5701
5702 return 0;
5703}
Emeric Brunef42d922012-10-11 16:11:36 +02005704
Willy Tarreau92faadf2012-10-10 23:04:25 +02005705/* parse the "force-sslv3" server keyword */
5706static int srv_parse_force_sslv3(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
5707{
5708 newsrv->ssl_ctx.options |= SRV_SSL_O_USE_SSLV3;
5709 return 0;
5710}
5711
5712/* parse the "force-tlsv10" server keyword */
5713static int srv_parse_force_tlsv10(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
5714{
5715 newsrv->ssl_ctx.options |= SRV_SSL_O_USE_TLSV10;
5716 return 0;
5717}
5718
5719/* parse the "force-tlsv11" server keyword */
5720static int srv_parse_force_tlsv11(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
5721{
5722#if SSL_OP_NO_TLSv1_1
5723 newsrv->ssl_ctx.options |= SRV_SSL_O_USE_TLSV11;
5724 return 0;
5725#else
5726 if (err)
5727 memprintf(err, "'%s' : library does not support protocol TLSv1.1", args[*cur_arg]);
5728 return ERR_ALERT | ERR_FATAL;
5729#endif
5730}
5731
5732/* parse the "force-tlsv12" server keyword */
5733static int srv_parse_force_tlsv12(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
5734{
5735#if SSL_OP_NO_TLSv1_2
5736 newsrv->ssl_ctx.options |= SRV_SSL_O_USE_TLSV12;
5737 return 0;
5738#else
5739 if (err)
5740 memprintf(err, "'%s' : library does not support protocol TLSv1.2", args[*cur_arg]);
5741 return ERR_ALERT | ERR_FATAL;
5742#endif
5743}
5744
Willy Tarreau2a3fb1c2015-02-05 16:47:07 +01005745/* parse the "no-ssl-reuse" server keyword */
5746static int srv_parse_no_ssl_reuse(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
5747{
5748 newsrv->ssl_ctx.options |= SRV_SSL_O_NO_REUSE;
5749 return 0;
5750}
5751
Willy Tarreau92faadf2012-10-10 23:04:25 +02005752/* parse the "no-sslv3" server keyword */
5753static int srv_parse_no_sslv3(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
5754{
5755 newsrv->ssl_ctx.options |= SRV_SSL_O_NO_SSLV3;
5756 return 0;
5757}
5758
5759/* parse the "no-tlsv10" server keyword */
5760static int srv_parse_no_tlsv10(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
5761{
5762 newsrv->ssl_ctx.options |= SRV_SSL_O_NO_TLSV10;
5763 return 0;
5764}
5765
5766/* parse the "no-tlsv11" server keyword */
5767static int srv_parse_no_tlsv11(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
5768{
5769 newsrv->ssl_ctx.options |= SRV_SSL_O_NO_TLSV11;
5770 return 0;
5771}
5772
5773/* parse the "no-tlsv12" server keyword */
5774static int srv_parse_no_tlsv12(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
5775{
5776 newsrv->ssl_ctx.options |= SRV_SSL_O_NO_TLSV12;
5777 return 0;
5778}
5779
Emeric Brunf9c5c472012-10-11 15:28:34 +02005780/* parse the "no-tls-tickets" server keyword */
5781static int srv_parse_no_tls_tickets(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
5782{
5783 newsrv->ssl_ctx.options |= SRV_SSL_O_NO_TLS_TICKETS;
5784 return 0;
5785}
David Safb76832014-05-08 23:42:08 -04005786/* parse the "send-proxy-v2-ssl" server keyword */
5787static int srv_parse_send_proxy_ssl(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
5788{
5789 newsrv->pp_opts |= SRV_PP_V2;
5790 newsrv->pp_opts |= SRV_PP_V2_SSL;
5791 return 0;
5792}
5793
5794/* parse the "send-proxy-v2-ssl-cn" server keyword */
5795static int srv_parse_send_proxy_cn(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
5796{
5797 newsrv->pp_opts |= SRV_PP_V2;
5798 newsrv->pp_opts |= SRV_PP_V2_SSL;
5799 newsrv->pp_opts |= SRV_PP_V2_SSL_CN;
5800 return 0;
5801}
Emeric Brunf9c5c472012-10-11 15:28:34 +02005802
Willy Tarreau732eac42015-07-09 11:40:25 +02005803/* parse the "sni" server keyword */
5804static int srv_parse_sni(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
5805{
5806#ifndef SSL_CTRL_SET_TLSEXT_HOSTNAME
5807 memprintf(err, "'%s' : the current SSL library doesn't support the SNI TLS extension", args[*cur_arg]);
5808 return ERR_ALERT | ERR_FATAL;
5809#else
Cyril Bonté23d19d62016-03-07 22:13:22 +01005810 int idx;
Willy Tarreau732eac42015-07-09 11:40:25 +02005811 struct sample_expr *expr;
5812
5813 if (!*args[*cur_arg + 1]) {
5814 memprintf(err, "'%s' : missing sni expression", args[*cur_arg]);
5815 return ERR_ALERT | ERR_FATAL;
5816 }
5817
Cyril Bonté23d19d62016-03-07 22:13:22 +01005818 idx = (*cur_arg) + 1;
Willy Tarreau732eac42015-07-09 11:40:25 +02005819 proxy->conf.args.ctx = ARGC_SRV;
5820
Cyril Bonté23d19d62016-03-07 22:13:22 +01005821 expr = sample_parse_expr((char **)args, &idx, px->conf.file, px->conf.line, err, &proxy->conf.args);
Willy Tarreau732eac42015-07-09 11:40:25 +02005822 if (!expr) {
5823 memprintf(err, "error detected while parsing sni expression : %s", *err);
5824 return ERR_ALERT | ERR_FATAL;
5825 }
5826
5827 if (!(expr->fetch->val & SMP_VAL_BE_SRV_CON)) {
5828 memprintf(err, "error detected while parsing sni expression : "
5829 " fetch method '%s' extracts information from '%s', none of which is available here.\n",
Cyril Bonté23d19d62016-03-07 22:13:22 +01005830 args[idx-1], sample_src_names(expr->fetch->use));
Willy Tarreau732eac42015-07-09 11:40:25 +02005831 return ERR_ALERT | ERR_FATAL;
5832 }
5833
5834 px->http_needed |= !!(expr->fetch->use & SMP_USE_HTTP_ANY);
5835 newsrv->ssl_ctx.sni = expr;
5836 return 0;
5837#endif
5838}
5839
Willy Tarreau92faadf2012-10-10 23:04:25 +02005840/* parse the "ssl" server keyword */
5841static int srv_parse_ssl(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
5842{
5843 newsrv->use_ssl = 1;
5844 if (global.connect_default_ciphers && !newsrv->ssl_ctx.ciphers)
5845 newsrv->ssl_ctx.ciphers = strdup(global.connect_default_ciphers);
5846 return 0;
5847}
5848
Emeric Brunef42d922012-10-11 16:11:36 +02005849/* parse the "verify" server keyword */
5850static int srv_parse_verify(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
5851{
5852 if (!*args[*cur_arg + 1]) {
5853 if (err)
5854 memprintf(err, "'%s' : missing verify method", args[*cur_arg]);
5855 return ERR_ALERT | ERR_FATAL;
5856 }
5857
5858 if (strcmp(args[*cur_arg + 1], "none") == 0)
Emeric Brun850efd52014-01-29 12:24:34 +01005859 newsrv->ssl_ctx.verify = SSL_SOCK_VERIFY_NONE;
Emeric Brunef42d922012-10-11 16:11:36 +02005860 else if (strcmp(args[*cur_arg + 1], "required") == 0)
Emeric Brun850efd52014-01-29 12:24:34 +01005861 newsrv->ssl_ctx.verify = SSL_SOCK_VERIFY_REQUIRED;
Emeric Brunef42d922012-10-11 16:11:36 +02005862 else {
5863 if (err)
5864 memprintf(err, "'%s' : unknown verify method '%s', only 'none' and 'required' are supported\n",
5865 args[*cur_arg], args[*cur_arg + 1]);
5866 return ERR_ALERT | ERR_FATAL;
5867 }
5868
Evan Broderbe554312013-06-27 00:05:25 -07005869 return 0;
5870}
5871
5872/* parse the "verifyhost" server keyword */
5873static int srv_parse_verifyhost(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
5874{
5875 if (!*args[*cur_arg + 1]) {
5876 if (err)
5877 memprintf(err, "'%s' : missing hostname to verify against", args[*cur_arg]);
5878 return ERR_ALERT | ERR_FATAL;
5879 }
5880
5881 newsrv->ssl_ctx.verify_host = strdup(args[*cur_arg + 1]);
5882
Emeric Brunef42d922012-10-11 16:11:36 +02005883 return 0;
5884}
5885
Emeric Brun2c86cbf2014-10-30 15:56:50 +01005886/* parse the "ssl-default-bind-options" keyword in global section */
5887static int ssl_parse_default_bind_options(char **args, int section_type, struct proxy *curpx,
5888 struct proxy *defpx, const char *file, int line,
5889 char **err) {
5890 int i = 1;
5891
5892 if (*(args[i]) == 0) {
5893 memprintf(err, "global statement '%s' expects an option as an argument.", args[0]);
5894 return -1;
5895 }
5896 while (*(args[i])) {
5897 if (!strcmp(args[i], "no-sslv3"))
5898 global.listen_default_ssloptions |= BC_SSL_O_NO_SSLV3;
5899 else if (!strcmp(args[i], "no-tlsv10"))
5900 global.listen_default_ssloptions |= BC_SSL_O_NO_TLSV10;
5901 else if (!strcmp(args[i], "no-tlsv11"))
5902 global.listen_default_ssloptions |= BC_SSL_O_NO_TLSV11;
5903 else if (!strcmp(args[i], "no-tlsv12"))
5904 global.listen_default_ssloptions |= BC_SSL_O_NO_TLSV12;
5905 else if (!strcmp(args[i], "force-sslv3"))
5906 global.listen_default_ssloptions |= BC_SSL_O_USE_SSLV3;
5907 else if (!strcmp(args[i], "force-tlsv10"))
5908 global.listen_default_ssloptions |= BC_SSL_O_USE_TLSV10;
5909 else if (!strcmp(args[i], "force-tlsv11")) {
5910#if SSL_OP_NO_TLSv1_1
5911 global.listen_default_ssloptions |= BC_SSL_O_USE_TLSV11;
5912#else
5913 memprintf(err, "'%s' '%s': library does not support protocol TLSv1.1", args[0], args[i]);
5914 return -1;
5915#endif
5916 }
5917 else if (!strcmp(args[i], "force-tlsv12")) {
5918#if SSL_OP_NO_TLSv1_2
5919 global.listen_default_ssloptions |= BC_SSL_O_USE_TLSV12;
5920#else
5921 memprintf(err, "'%s' '%s': library does not support protocol TLSv1.2", args[0], args[i]);
5922 return -1;
5923#endif
5924 }
5925 else if (!strcmp(args[i], "no-tls-tickets"))
5926 global.listen_default_ssloptions |= BC_SSL_O_NO_TLS_TICKETS;
5927 else {
5928 memprintf(err, "unknown option '%s' on global statement '%s'.", args[i], args[0]);
5929 return -1;
5930 }
5931 i++;
5932 }
5933 return 0;
5934}
5935
5936/* parse the "ssl-default-server-options" keyword in global section */
5937static int ssl_parse_default_server_options(char **args, int section_type, struct proxy *curpx,
5938 struct proxy *defpx, const char *file, int line,
5939 char **err) {
5940 int i = 1;
5941
5942 if (*(args[i]) == 0) {
5943 memprintf(err, "global statement '%s' expects an option as an argument.", args[0]);
5944 return -1;
5945 }
5946 while (*(args[i])) {
5947 if (!strcmp(args[i], "no-sslv3"))
5948 global.connect_default_ssloptions |= SRV_SSL_O_NO_SSLV3;
5949 else if (!strcmp(args[i], "no-tlsv10"))
5950 global.connect_default_ssloptions |= SRV_SSL_O_NO_TLSV10;
5951 else if (!strcmp(args[i], "no-tlsv11"))
5952 global.connect_default_ssloptions |= SRV_SSL_O_NO_TLSV11;
5953 else if (!strcmp(args[i], "no-tlsv12"))
5954 global.connect_default_ssloptions |= SRV_SSL_O_NO_TLSV12;
5955 else if (!strcmp(args[i], "force-sslv3"))
5956 global.connect_default_ssloptions |= SRV_SSL_O_USE_SSLV3;
5957 else if (!strcmp(args[i], "force-tlsv10"))
5958 global.connect_default_ssloptions |= SRV_SSL_O_USE_TLSV10;
5959 else if (!strcmp(args[i], "force-tlsv11")) {
5960#if SSL_OP_NO_TLSv1_1
5961 global.connect_default_ssloptions |= SRV_SSL_O_USE_TLSV11;
5962#else
5963 memprintf(err, "'%s' '%s': library does not support protocol TLSv1.1", args[0], args[i]);
5964 return -1;
5965#endif
5966 }
5967 else if (!strcmp(args[i], "force-tlsv12")) {
5968#if SSL_OP_NO_TLSv1_2
5969 global.connect_default_ssloptions |= SRV_SSL_O_USE_TLSV12;
5970#else
5971 memprintf(err, "'%s' '%s': library does not support protocol TLSv1.2", args[0], args[i]);
5972 return -1;
5973#endif
5974 }
5975 else if (!strcmp(args[i], "no-tls-tickets"))
5976 global.connect_default_ssloptions |= SRV_SSL_O_NO_TLS_TICKETS;
5977 else {
5978 memprintf(err, "unknown option '%s' on global statement '%s'.", args[i], args[0]);
5979 return -1;
5980 }
5981 i++;
5982 }
5983 return 0;
5984}
5985
William Lallemand32af2032016-10-29 18:09:35 +02005986/* This function is used with TLS ticket keys management. It permits to browse
5987 * each reference. The variable <getnext> must contain the current node,
5988 * <end> point to the root node.
5989 */
5990#if (defined SSL_CTRL_SET_TLSEXT_TICKET_KEY_CB && TLS_TICKETS_NO > 0)
5991static inline
5992struct tls_keys_ref *tlskeys_list_get_next(struct tls_keys_ref *getnext, struct list *end)
5993{
5994 struct tls_keys_ref *ref = getnext;
5995
5996 while (1) {
5997
5998 /* Get next list entry. */
5999 ref = LIST_NEXT(&ref->list, struct tls_keys_ref *, list);
6000
6001 /* If the entry is the last of the list, return NULL. */
6002 if (&ref->list == end)
6003 return NULL;
6004
6005 return ref;
6006 }
6007}
6008
6009static inline
6010struct tls_keys_ref *tlskeys_ref_lookup_ref(const char *reference)
6011{
6012 int id;
6013 char *error;
6014
6015 /* If the reference starts by a '#', this is numeric id. */
6016 if (reference[0] == '#') {
6017 /* Try to convert the numeric id. If the conversion fails, the lookup fails. */
6018 id = strtol(reference + 1, &error, 10);
6019 if (*error != '\0')
6020 return NULL;
6021
6022 /* Perform the unique id lookup. */
6023 return tlskeys_ref_lookupid(id);
6024 }
6025
6026 /* Perform the string lookup. */
6027 return tlskeys_ref_lookup(reference);
6028}
6029#endif
6030
6031
6032#if (defined SSL_CTRL_SET_TLSEXT_TICKET_KEY_CB && TLS_TICKETS_NO > 0)
6033
6034static int cli_io_handler_tlskeys_files(struct appctx *appctx);
6035
6036static inline int cli_io_handler_tlskeys_entries(struct appctx *appctx) {
6037 return cli_io_handler_tlskeys_files(appctx);
6038}
6039
6040static int cli_io_handler_tlskeys_files(struct appctx *appctx) {
6041
6042 struct stream_interface *si = appctx->owner;
6043
6044 switch (appctx->st2) {
6045 case STAT_ST_INIT:
6046 /* Display the column headers. If the message cannot be sent,
6047 * quit the fucntion with returning 0. The function is called
6048 * later and restart at the state "STAT_ST_INIT".
6049 */
6050 chunk_reset(&trash);
6051
6052 if (appctx->io_handler == cli_io_handler_tlskeys_entries)
6053 chunk_appendf(&trash, "# id secret\n");
6054 else
6055 chunk_appendf(&trash, "# id (file)\n");
6056
6057 if (bi_putchk(si_ic(si), &trash) == -1) {
6058 si_applet_cant_put(si);
6059 return 0;
6060 }
6061
6062 appctx->ctx.tlskeys.dump_keys_index = 0;
6063
6064 /* Now, we start the browsing of the references lists.
6065 * Note that the following call to LIST_ELEM return bad pointer. The only
6066 * available field of this pointer is <list>. It is used with the function
6067 * tlskeys_list_get_next() for retruning the first available entry
6068 */
6069 if (appctx->ctx.tlskeys.ref == NULL) {
6070 appctx->ctx.tlskeys.ref = LIST_ELEM(&tlskeys_reference, struct tls_keys_ref *, list);
6071 appctx->ctx.tlskeys.ref = tlskeys_list_get_next(appctx->ctx.tlskeys.ref, &tlskeys_reference);
6072 }
6073
6074 appctx->st2 = STAT_ST_LIST;
6075 /* fall through */
6076
6077 case STAT_ST_LIST:
6078 while (appctx->ctx.tlskeys.ref) {
6079 int head = appctx->ctx.tlskeys.ref->tls_ticket_enc_index;
6080
6081 chunk_reset(&trash);
6082 if (appctx->io_handler == cli_io_handler_tlskeys_entries && appctx->ctx.tlskeys.dump_keys_index == 0)
6083 chunk_appendf(&trash, "# ");
6084 if (appctx->ctx.tlskeys.dump_keys_index == 0)
6085 chunk_appendf(&trash, "%d (%s)\n", appctx->ctx.tlskeys.ref->unique_id,
6086 appctx->ctx.tlskeys.ref->filename);
6087 if (appctx->io_handler == cli_io_handler_tlskeys_entries) {
6088 while (appctx->ctx.tlskeys.dump_keys_index < TLS_TICKETS_NO) {
6089 struct chunk *t2 = get_trash_chunk();
6090
6091 chunk_reset(t2);
6092 /* should never fail here because we dump only a key in the t2 buffer */
6093 t2->len = a2base64((char *)(appctx->ctx.tlskeys.ref->tlskeys + (head + 2 + appctx->ctx.tlskeys.dump_keys_index) % TLS_TICKETS_NO),
6094 sizeof(struct tls_sess_key), t2->str, t2->size);
6095 chunk_appendf(&trash, "%d.%d %s\n", appctx->ctx.tlskeys.ref->unique_id, appctx->ctx.tlskeys.dump_keys_index, t2->str);
6096
6097 if (bi_putchk(si_ic(si), &trash) == -1) {
6098 /* let's try again later from this stream. We add ourselves into
6099 * this stream's users so that it can remove us upon termination.
6100 */
6101 si_applet_cant_put(si);
6102 return 0;
6103 }
6104 appctx->ctx.tlskeys.dump_keys_index++;
6105 }
6106 appctx->ctx.tlskeys.dump_keys_index = 0;
6107 }
6108 if (bi_putchk(si_ic(si), &trash) == -1) {
6109 /* let's try again later from this stream. We add ourselves into
6110 * this stream's users so that it can remove us upon termination.
6111 */
6112 si_applet_cant_put(si);
6113 return 0;
6114 }
6115
6116 if (appctx->ctx.tlskeys.dump_all == 0) /* don't display everything if not necessary */
6117 break;
6118
6119 /* get next list entry and check the end of the list */
6120 appctx->ctx.tlskeys.ref = tlskeys_list_get_next(appctx->ctx.tlskeys.ref, &tlskeys_reference);
6121
6122 }
6123
6124 appctx->st2 = STAT_ST_FIN;
6125 /* fall through */
6126
6127 default:
6128 appctx->st2 = STAT_ST_FIN;
6129 return 1;
6130 }
6131 return 0;
6132}
6133
6134#endif
6135
6136static int cli_parse_show_tlskeys(char **args, struct appctx *appctx, void *private)
6137{
6138 appctx->ctx.tlskeys.dump_all = 0;
6139 /* no parameter, shows only file list */
6140 if (!*args[2]) {
6141 appctx->ctx.tlskeys.dump_all = 1;
William Lallemand32af2032016-10-29 18:09:35 +02006142 appctx->io_handler = cli_io_handler_tlskeys_files;
Willy Tarreau3067bfa2016-12-05 14:50:15 +01006143 return 0;
William Lallemand32af2032016-10-29 18:09:35 +02006144 }
6145
6146 if (args[2][0] == '*') {
6147 /* list every TLS ticket keys */
6148 appctx->ctx.tlskeys.ref = NULL;
6149 appctx->ctx.tlskeys.dump_all = 1;
6150 } else {
6151 appctx->ctx.tlskeys.ref = tlskeys_ref_lookup_ref(args[2]);
Willy Tarreau30e5e182016-11-24 16:45:53 +01006152 if (!appctx->ctx.tlskeys.ref) {
William Lallemand32af2032016-10-29 18:09:35 +02006153 appctx->ctx.cli.msg = "'show tls-keys' unable to locate referenced filename\n";
Willy Tarreau3b6e5472016-11-24 15:53:53 +01006154 appctx->st0 = CLI_ST_PRINT;
William Lallemand32af2032016-10-29 18:09:35 +02006155 return 1;
6156 }
6157 }
William Lallemand32af2032016-10-29 18:09:35 +02006158 appctx->io_handler = cli_io_handler_tlskeys_entries;
Willy Tarreau3067bfa2016-12-05 14:50:15 +01006159 return 0;
William Lallemand32af2032016-10-29 18:09:35 +02006160}
6161
6162
6163static int cli_parse_set_tlskeys(char **args, struct appctx *appctx, void *private)
6164{
6165 /* Expect two parameters: the filename and the new new TLS key in encoding */
6166 if (!*args[3] || !*args[4]) {
6167 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 +01006168 appctx->st0 = CLI_ST_PRINT;
William Lallemand32af2032016-10-29 18:09:35 +02006169 return 1;
6170 }
6171
6172 appctx->ctx.tlskeys.ref = tlskeys_ref_lookup_ref(args[3]);
6173 if(!appctx->ctx.tlskeys.ref) {
6174 appctx->ctx.cli.msg = "'set ssl tls-key' unable to locate referenced filename\n";
Willy Tarreau3b6e5472016-11-24 15:53:53 +01006175 appctx->st0 = CLI_ST_PRINT;
William Lallemand32af2032016-10-29 18:09:35 +02006176 return 1;
6177 }
6178
6179 trash.len = base64dec(args[4], strlen(args[4]), trash.str, trash.size);
6180 if (trash.len != sizeof(struct tls_sess_key)) {
6181 appctx->ctx.cli.msg = "'set ssl tls-key' received invalid base64 encoded TLS key.\n";
Willy Tarreau3b6e5472016-11-24 15:53:53 +01006182 appctx->st0 = CLI_ST_PRINT;
William Lallemand32af2032016-10-29 18:09:35 +02006183 return 1;
6184 }
6185
6186 memcpy(appctx->ctx.tlskeys.ref->tlskeys + ((appctx->ctx.tlskeys.ref->tls_ticket_enc_index + 2) % TLS_TICKETS_NO), trash.str, trash.len);
6187 appctx->ctx.tlskeys.ref->tls_ticket_enc_index = (appctx->ctx.tlskeys.ref->tls_ticket_enc_index + 1) % TLS_TICKETS_NO;
6188
6189 appctx->ctx.cli.msg = "TLS ticket key updated!";
Willy Tarreau3b6e5472016-11-24 15:53:53 +01006190 appctx->st0 = CLI_ST_PRINT;
William Lallemand32af2032016-10-29 18:09:35 +02006191 return 1;
6192
6193}
6194
6195static int cli_parse_set_ocspresponse(char **args, struct appctx *appctx, void *private)
6196{
6197#if (defined SSL_CTRL_SET_TLSEXT_STATUS_REQ_CB && !defined OPENSSL_NO_OCSP)
6198 char *err = NULL;
6199
6200 /* Expect one parameter: the new response in base64 encoding */
6201 if (!*args[3]) {
6202 appctx->ctx.cli.msg = "'set ssl ocsp-response' expects response in base64 encoding.\n";
Willy Tarreau3b6e5472016-11-24 15:53:53 +01006203 appctx->st0 = CLI_ST_PRINT;
William Lallemand32af2032016-10-29 18:09:35 +02006204 return 1;
6205 }
6206
6207 trash.len = base64dec(args[3], strlen(args[3]), trash.str, trash.size);
6208 if (trash.len < 0) {
6209 appctx->ctx.cli.msg = "'set ssl ocsp-response' received invalid base64 encoded response.\n";
Willy Tarreau3b6e5472016-11-24 15:53:53 +01006210 appctx->st0 = CLI_ST_PRINT;
William Lallemand32af2032016-10-29 18:09:35 +02006211 return 1;
6212 }
6213
6214 if (ssl_sock_update_ocsp_response(&trash, &err)) {
6215 if (err) {
6216 memprintf(&err, "%s.\n", err);
6217 appctx->ctx.cli.err = err;
Willy Tarreau3b6e5472016-11-24 15:53:53 +01006218 appctx->st0 = CLI_ST_PRINT_FREE;
William Lallemand32af2032016-10-29 18:09:35 +02006219 }
6220 return 1;
6221 }
6222 appctx->ctx.cli.msg = "OCSP Response updated!";
Willy Tarreau3b6e5472016-11-24 15:53:53 +01006223 appctx->st0 = CLI_ST_PRINT;
William Lallemand32af2032016-10-29 18:09:35 +02006224 return 1;
6225#else
6226 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 +01006227 appctx->st0 = CLI_ST_PRINT;
William Lallemand32af2032016-10-29 18:09:35 +02006228 return 1;
6229#endif
6230
6231}
6232
6233/* register cli keywords */
6234static struct cli_kw_list cli_kws = {{ },{
6235#if (defined SSL_CTRL_SET_TLSEXT_TICKET_KEY_CB && TLS_TICKETS_NO > 0)
6236 { { "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 },
6237 { { "set", "ssl", "tls-keys", NULL }, NULL, cli_parse_set_tlskeys, NULL },
6238 { { "set", "ssl", "ocsp-response", NULL }, NULL, cli_parse_set_ocspresponse, NULL },
6239#endif
6240 { { NULL }, NULL, NULL, NULL }
6241}};
6242
6243
6244
Willy Tarreau7875d092012-09-10 08:20:03 +02006245/* Note: must not be declared <const> as its list will be overwritten.
6246 * Please take care of keeping this list alphabetically sorted.
6247 */
Willy Tarreaudc13c112013-06-21 23:16:39 +02006248static struct sample_fetch_kw_list sample_fetch_keywords = {ILH, {
Emeric Brun645ae792014-04-30 14:21:06 +02006249 { "ssl_bc", smp_fetch_ssl_fc, 0, NULL, SMP_T_BOOL, SMP_USE_L5SRV },
Thierry FOURNIER07ee64e2015-07-06 23:43:03 +02006250 { "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 +02006251 { "ssl_bc_cipher", smp_fetch_ssl_fc_cipher, 0, NULL, SMP_T_STR, SMP_USE_L5SRV },
6252 { "ssl_bc_protocol", smp_fetch_ssl_fc_protocol, 0, NULL, SMP_T_STR, SMP_USE_L5SRV },
Emeric Brunb73a9b02014-04-30 18:49:19 +02006253 { "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 +02006254 { "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 +02006255 { "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 +02006256 { "ssl_c_ca_err", smp_fetch_ssl_c_ca_err, 0, NULL, SMP_T_SINT, SMP_USE_L5CLI },
6257 { "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 +01006258 { "ssl_c_der", smp_fetch_ssl_x_der, 0, NULL, SMP_T_BIN, SMP_USE_L5CLI },
Thierry FOURNIER07ee64e2015-07-06 23:43:03 +02006259 { "ssl_c_err", smp_fetch_ssl_c_err, 0, NULL, SMP_T_SINT, SMP_USE_L5CLI },
Emeric Brunba841a12014-04-30 17:05:08 +02006260 { "ssl_c_i_dn", smp_fetch_ssl_x_i_dn, ARG2(0,STR,SINT), NULL, SMP_T_STR, SMP_USE_L5CLI },
6261 { "ssl_c_key_alg", smp_fetch_ssl_x_key_alg, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
6262 { "ssl_c_notafter", smp_fetch_ssl_x_notafter, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
6263 { "ssl_c_notbefore", smp_fetch_ssl_x_notbefore, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
6264 { "ssl_c_sig_alg", smp_fetch_ssl_x_sig_alg, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
6265 { "ssl_c_s_dn", smp_fetch_ssl_x_s_dn, ARG2(0,STR,SINT), NULL, SMP_T_STR, SMP_USE_L5CLI },
6266 { "ssl_c_serial", smp_fetch_ssl_x_serial, 0, NULL, SMP_T_BIN, SMP_USE_L5CLI },
6267 { "ssl_c_sha1", smp_fetch_ssl_x_sha1, 0, NULL, SMP_T_BIN, SMP_USE_L5CLI },
Willy Tarreau80aca902013-01-07 15:42:20 +01006268 { "ssl_c_used", smp_fetch_ssl_c_used, 0, NULL, SMP_T_BOOL, SMP_USE_L5CLI },
Thierry FOURNIER07ee64e2015-07-06 23:43:03 +02006269 { "ssl_c_verify", smp_fetch_ssl_c_verify, 0, NULL, SMP_T_SINT, SMP_USE_L5CLI },
6270 { "ssl_c_version", smp_fetch_ssl_x_version, 0, NULL, SMP_T_SINT, SMP_USE_L5CLI },
Emeric Brun43e79582014-10-29 19:03:26 +01006271 { "ssl_f_der", smp_fetch_ssl_x_der, 0, NULL, SMP_T_BIN, SMP_USE_L5CLI },
Emeric Brunba841a12014-04-30 17:05:08 +02006272 { "ssl_f_i_dn", smp_fetch_ssl_x_i_dn, ARG2(0,STR,SINT), NULL, SMP_T_STR, SMP_USE_L5CLI },
6273 { "ssl_f_key_alg", smp_fetch_ssl_x_key_alg, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
6274 { "ssl_f_notafter", smp_fetch_ssl_x_notafter, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
6275 { "ssl_f_notbefore", smp_fetch_ssl_x_notbefore, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
6276 { "ssl_f_sig_alg", smp_fetch_ssl_x_sig_alg, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
6277 { "ssl_f_s_dn", smp_fetch_ssl_x_s_dn, ARG2(0,STR,SINT), NULL, SMP_T_STR, SMP_USE_L5CLI },
6278 { "ssl_f_serial", smp_fetch_ssl_x_serial, 0, NULL, SMP_T_BIN, SMP_USE_L5CLI },
Emeric Brun55f4fa82014-04-30 17:11:25 +02006279 { "ssl_f_sha1", smp_fetch_ssl_x_sha1, 0, NULL, SMP_T_BIN, SMP_USE_L5CLI },
Thierry FOURNIER07ee64e2015-07-06 23:43:03 +02006280 { "ssl_f_version", smp_fetch_ssl_x_version, 0, NULL, SMP_T_SINT, SMP_USE_L5CLI },
Willy Tarreau80aca902013-01-07 15:42:20 +01006281 { "ssl_fc", smp_fetch_ssl_fc, 0, NULL, SMP_T_BOOL, SMP_USE_L5CLI },
Thierry FOURNIER07ee64e2015-07-06 23:43:03 +02006282 { "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 +01006283 { "ssl_fc_cipher", smp_fetch_ssl_fc_cipher, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
Willy Tarreau80aca902013-01-07 15:42:20 +01006284 { "ssl_fc_has_crt", smp_fetch_ssl_fc_has_crt, 0, NULL, SMP_T_BOOL, SMP_USE_L5CLI },
6285 { "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 +02006286 { "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 +02006287#ifdef OPENSSL_NPN_NEGOTIATED
Thierry FOURNIER7654c9f2013-12-17 00:20:33 +01006288 { "ssl_fc_npn", smp_fetch_ssl_fc_npn, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
Willy Tarreaua33c6542012-10-15 13:19:06 +02006289#endif
Dirkjan Bussink48f1c4e2014-02-13 12:29:42 +01006290#ifdef TLSEXT_TYPE_application_layer_protocol_negotiation
Thierry FOURNIER7654c9f2013-12-17 00:20:33 +01006291 { "ssl_fc_alpn", smp_fetch_ssl_fc_alpn, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
Willy Tarreauab861d32013-04-02 02:30:41 +02006292#endif
Thierry FOURNIER7654c9f2013-12-17 00:20:33 +01006293 { "ssl_fc_protocol", smp_fetch_ssl_fc_protocol, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
Emeric Brunb73a9b02014-04-30 18:49:19 +02006294 { "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 +02006295 { "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 +01006296 { "ssl_fc_session_id", smp_fetch_ssl_fc_session_id, 0, NULL, SMP_T_BIN, SMP_USE_L5CLI },
6297 { "ssl_fc_sni", smp_fetch_ssl_fc_sni, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
Willy Tarreau7875d092012-09-10 08:20:03 +02006298 { NULL, NULL, 0, 0, 0 },
6299}};
6300
6301/* Note: must not be declared <const> as its list will be overwritten.
6302 * Please take care of keeping this list alphabetically sorted.
6303 */
Willy Tarreaudc13c112013-06-21 23:16:39 +02006304static struct acl_kw_list acl_kws = {ILH, {
Thierry FOURNIERc5a4e982014-03-05 16:07:08 +01006305 { "ssl_fc_sni_end", "ssl_fc_sni", PAT_MATCH_END },
6306 { "ssl_fc_sni_reg", "ssl_fc_sni", PAT_MATCH_REG },
Willy Tarreau8ed669b2013-01-11 15:49:37 +01006307 { /* END */ },
Willy Tarreau7875d092012-09-10 08:20:03 +02006308}};
6309
Willy Tarreau79eeafa2012-09-14 07:53:05 +02006310/* Note: must not be declared <const> as its list will be overwritten.
6311 * Please take care of keeping this list alphabetically sorted, doing so helps
6312 * all code contributors.
6313 * Optional keywords are also declared with a NULL ->parse() function so that
6314 * the config parser can report an appropriate error when a known keyword was
6315 * not enabled.
6316 */
Willy Tarreau51fb7652012-09-18 18:24:39 +02006317static struct bind_kw_list bind_kws = { "SSL", { }, {
Nenad Merdanovic05552d42015-02-27 19:56:49 +01006318 { "alpn", bind_parse_alpn, 1 }, /* set ALPN supported protocols */
6319 { "ca-file", bind_parse_ca_file, 1 }, /* set CAfile to process verify on client cert */
6320 { "ca-ignore-err", bind_parse_ignore_err, 1 }, /* set error IDs to ignore on verify depth > 0 */
Christopher Faulet31af49d2015-06-09 17:29:50 +02006321 { "ca-sign-file", bind_parse_ca_sign_file, 1 }, /* set CAFile used to generate and sign server certs */
6322 { "ca-sign-pass", bind_parse_ca_sign_pass, 1 }, /* set CAKey passphrase */
Nenad Merdanovic05552d42015-02-27 19:56:49 +01006323 { "ciphers", bind_parse_ciphers, 1 }, /* set SSL cipher suite */
6324 { "crl-file", bind_parse_crl_file, 1 }, /* set certificat revocation list file use on client cert verify */
6325 { "crt", bind_parse_crt, 1 }, /* load SSL certificates from this location */
6326 { "crt-ignore-err", bind_parse_ignore_err, 1 }, /* set error IDs to ingore on verify depth == 0 */
6327 { "crt-list", bind_parse_crt_list, 1 }, /* load a list of crt from this location */
6328 { "ecdhe", bind_parse_ecdhe, 1 }, /* defines named curve for elliptic curve Diffie-Hellman */
6329 { "force-sslv3", bind_parse_force_sslv3, 0 }, /* force SSLv3 */
6330 { "force-tlsv10", bind_parse_force_tlsv10, 0 }, /* force TLSv10 */
6331 { "force-tlsv11", bind_parse_force_tlsv11, 0 }, /* force TLSv11 */
6332 { "force-tlsv12", bind_parse_force_tlsv12, 0 }, /* force TLSv12 */
Christopher Faulet31af49d2015-06-09 17:29:50 +02006333 { "generate-certificates", bind_parse_generate_certs, 0 }, /* enable the server certificates generation */
Nenad Merdanovic05552d42015-02-27 19:56:49 +01006334 { "no-sslv3", bind_parse_no_sslv3, 0 }, /* disable SSLv3 */
6335 { "no-tlsv10", bind_parse_no_tlsv10, 0 }, /* disable TLSv10 */
6336 { "no-tlsv11", bind_parse_no_tlsv11, 0 }, /* disable TLSv11 */
6337 { "no-tlsv12", bind_parse_no_tlsv12, 0 }, /* disable TLSv12 */
6338 { "no-tls-tickets", bind_parse_no_tls_tickets, 0 }, /* disable session resumption tickets */
6339 { "ssl", bind_parse_ssl, 0 }, /* enable SSL processing */
6340 { "strict-sni", bind_parse_strict_sni, 0 }, /* refuse negotiation if sni doesn't match a certificate */
6341 { "tls-ticket-keys", bind_parse_tls_ticket_keys, 1 }, /* set file to load TLS ticket keys from */
6342 { "verify", bind_parse_verify, 1 }, /* set SSL verify method */
6343 { "npn", bind_parse_npn, 1 }, /* set NPN supported protocols */
Willy Tarreau79eeafa2012-09-14 07:53:05 +02006344 { NULL, NULL, 0 },
6345}};
Emeric Brun46591952012-05-18 15:47:34 +02006346
Willy Tarreau92faadf2012-10-10 23:04:25 +02006347/* Note: must not be declared <const> as its list will be overwritten.
6348 * Please take care of keeping this list alphabetically sorted, doing so helps
6349 * all code contributors.
6350 * Optional keywords are also declared with a NULL ->parse() function so that
6351 * the config parser can report an appropriate error when a known keyword was
6352 * not enabled.
6353 */
6354static struct srv_kw_list srv_kws = { "SSL", { }, {
Emeric Brunef42d922012-10-11 16:11:36 +02006355 { "ca-file", srv_parse_ca_file, 1, 0 }, /* set CAfile to process verify server cert */
Emeric Brunecc91fe2012-10-11 15:05:10 +02006356 { "check-ssl", srv_parse_check_ssl, 0, 0 }, /* enable SSL for health checks */
6357 { "ciphers", srv_parse_ciphers, 1, 0 }, /* select the cipher suite */
Emeric Brunef42d922012-10-11 16:11:36 +02006358 { "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 +02006359 { "crt", srv_parse_crt, 1, 0 }, /* set client certificate */
Emeric Brunecc91fe2012-10-11 15:05:10 +02006360 { "force-sslv3", srv_parse_force_sslv3, 0, 0 }, /* force SSLv3 */
6361 { "force-tlsv10", srv_parse_force_tlsv10, 0, 0 }, /* force TLSv10 */
6362 { "force-tlsv11", srv_parse_force_tlsv11, 0, 0 }, /* force TLSv11 */
6363 { "force-tlsv12", srv_parse_force_tlsv12, 0, 0 }, /* force TLSv12 */
Willy Tarreau2a3fb1c2015-02-05 16:47:07 +01006364 { "no-ssl-reuse", srv_parse_no_ssl_reuse, 0, 0 }, /* disable session reuse */
Emeric Brunecc91fe2012-10-11 15:05:10 +02006365 { "no-sslv3", srv_parse_no_sslv3, 0, 0 }, /* disable SSLv3 */
6366 { "no-tlsv10", srv_parse_no_tlsv10, 0, 0 }, /* disable TLSv10 */
6367 { "no-tlsv11", srv_parse_no_tlsv11, 0, 0 }, /* disable TLSv11 */
6368 { "no-tlsv12", srv_parse_no_tlsv12, 0, 0 }, /* disable TLSv12 */
Emeric Brunf9c5c472012-10-11 15:28:34 +02006369 { "no-tls-tickets", srv_parse_no_tls_tickets, 0, 0 }, /* disable session resumption tickets */
David Safb76832014-05-08 23:42:08 -04006370 { "send-proxy-v2-ssl", srv_parse_send_proxy_ssl, 0, 0 }, /* send PROXY protocol header v2 with SSL info */
6371 { "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 +02006372 { "sni", srv_parse_sni, 1, 0 }, /* send SNI extension */
Emeric Brunecc91fe2012-10-11 15:05:10 +02006373 { "ssl", srv_parse_ssl, 0, 0 }, /* enable SSL processing */
Emeric Brunef42d922012-10-11 16:11:36 +02006374 { "verify", srv_parse_verify, 1, 0 }, /* set SSL verify method */
Evan Broderbe554312013-06-27 00:05:25 -07006375 { "verifyhost", srv_parse_verifyhost, 1, 0 }, /* require that SSL cert verifies for hostname */
Willy Tarreau92faadf2012-10-10 23:04:25 +02006376 { NULL, NULL, 0, 0 },
6377}};
6378
Emeric Brun2c86cbf2014-10-30 15:56:50 +01006379static struct cfg_kw_list cfg_kws = {ILH, {
6380 { CFG_GLOBAL, "ssl-default-bind-options", ssl_parse_default_bind_options },
6381 { CFG_GLOBAL, "ssl-default-server-options", ssl_parse_default_server_options },
6382 { 0, NULL, NULL },
6383}};
6384
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02006385/* transport-layer operations for SSL sockets */
6386struct xprt_ops ssl_sock = {
Emeric Brun46591952012-05-18 15:47:34 +02006387 .snd_buf = ssl_sock_from_buf,
6388 .rcv_buf = ssl_sock_to_buf,
6389 .rcv_pipe = NULL,
6390 .snd_pipe = NULL,
6391 .shutr = NULL,
6392 .shutw = ssl_sock_shutw,
6393 .close = ssl_sock_close,
6394 .init = ssl_sock_init,
Willy Tarreau8e0bb0a2016-11-24 16:58:12 +01006395 .name = "SSL",
Emeric Brun46591952012-05-18 15:47:34 +02006396};
6397
Daniel Jakots54ffb912015-11-06 20:02:41 +01006398#if (OPENSSL_VERSION_NUMBER >= 0x1000200fL && !defined OPENSSL_NO_TLSEXT && !defined OPENSSL_IS_BORINGSSL && !defined LIBRESSL_VERSION_NUMBER)
Janusz Dziemidowicz2c701b52015-03-07 23:03:59 +01006399
6400static void ssl_sock_sctl_free_func(void *parent, void *ptr, CRYPTO_EX_DATA *ad, int idx, long argl, void *argp)
6401{
6402 if (ptr) {
6403 chunk_destroy(ptr);
6404 free(ptr);
6405 }
6406}
6407
6408#endif
6409
Emeric Brun46591952012-05-18 15:47:34 +02006410__attribute__((constructor))
Willy Tarreau92faadf2012-10-10 23:04:25 +02006411static void __ssl_sock_init(void)
6412{
Emeric Brun46591952012-05-18 15:47:34 +02006413 STACK_OF(SSL_COMP)* cm;
6414
Willy Tarreau610f04b2014-02-13 11:36:41 +01006415#ifdef LISTEN_DEFAULT_CIPHERS
6416 global.listen_default_ciphers = LISTEN_DEFAULT_CIPHERS;
6417#endif
6418#ifdef CONNECT_DEFAULT_CIPHERS
6419 global.connect_default_ciphers = CONNECT_DEFAULT_CIPHERS;
6420#endif
6421 if (global.listen_default_ciphers)
6422 global.listen_default_ciphers = strdup(global.listen_default_ciphers);
6423 if (global.connect_default_ciphers)
6424 global.connect_default_ciphers = strdup(global.connect_default_ciphers);
Emeric Brun2c86cbf2014-10-30 15:56:50 +01006425 global.listen_default_ssloptions = BC_SSL_O_NONE;
6426 global.connect_default_ssloptions = SRV_SSL_O_NONE;
Willy Tarreau610f04b2014-02-13 11:36:41 +01006427
Emeric Brun46591952012-05-18 15:47:34 +02006428 SSL_library_init();
6429 cm = SSL_COMP_get_compression_methods();
6430 sk_SSL_COMP_zero(cm);
Daniel Jakots54ffb912015-11-06 20:02:41 +01006431#if (OPENSSL_VERSION_NUMBER >= 0x1000200fL && !defined OPENSSL_NO_TLSEXT && !defined OPENSSL_IS_BORINGSSL && !defined LIBRESSL_VERSION_NUMBER)
Janusz Dziemidowicz2c701b52015-03-07 23:03:59 +01006432 sctl_ex_index = SSL_CTX_get_ex_new_index(0, NULL, NULL, NULL, ssl_sock_sctl_free_func);
6433#endif
Willy Tarreau7875d092012-09-10 08:20:03 +02006434 sample_register_fetches(&sample_fetch_keywords);
6435 acl_register_keywords(&acl_kws);
Willy Tarreau79eeafa2012-09-14 07:53:05 +02006436 bind_register_keywords(&bind_kws);
Willy Tarreau92faadf2012-10-10 23:04:25 +02006437 srv_register_keywords(&srv_kws);
Emeric Brun2c86cbf2014-10-30 15:56:50 +01006438 cfg_register_keywords(&cfg_kws);
William Lallemand32af2032016-10-29 18:09:35 +02006439 cli_register_kw(&cli_kws);
Willy Tarreaud92aa5c2015-01-15 21:34:39 +01006440
6441 global.ssl_session_max_cost = SSL_SESSION_MAX_COST;
6442 global.ssl_handshake_max_cost = SSL_HANDSHAKE_MAX_COST;
Remi Gacogne4f902b82015-05-28 16:23:00 +02006443
6444#ifndef OPENSSL_NO_DH
6445 ssl_dh_ptr_index = SSL_CTX_get_ex_new_index(0, NULL, NULL, NULL, NULL);
6446#endif
Thierry FOURNIER / OZON.IO8b068c22016-10-10 11:59:50 +02006447
6448 /* Load SSL string for the verbose & debug mode. */
6449 ERR_load_SSL_strings();
Emeric Brun46591952012-05-18 15:47:34 +02006450}
6451
Remi Gacogned3a23c32015-05-28 16:39:47 +02006452__attribute__((destructor))
6453static void __ssl_sock_deinit(void)
6454{
Willy Tarreaua84c2672015-10-09 12:10:13 +02006455#ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME
Christopher Faulet31af49d2015-06-09 17:29:50 +02006456 lru64_destroy(ssl_ctx_lru_tree);
Willy Tarreaua84c2672015-10-09 12:10:13 +02006457#endif
Christopher Faulet31af49d2015-06-09 17:29:50 +02006458
Remi Gacogned3a23c32015-05-28 16:39:47 +02006459#ifndef OPENSSL_NO_DH
6460 if (local_dh_1024) {
6461 DH_free(local_dh_1024);
6462 local_dh_1024 = NULL;
6463 }
6464
6465 if (local_dh_2048) {
6466 DH_free(local_dh_2048);
6467 local_dh_2048 = NULL;
6468 }
6469
6470 if (local_dh_4096) {
6471 DH_free(local_dh_4096);
6472 local_dh_4096 = NULL;
6473 }
6474
Remi Gacogne47783ef2015-05-29 15:53:22 +02006475 if (global_dh) {
6476 DH_free(global_dh);
6477 global_dh = NULL;
6478 }
Remi Gacogned3a23c32015-05-28 16:39:47 +02006479#endif
6480
6481 ERR_remove_state(0);
6482 ERR_free_strings();
6483
6484 EVP_cleanup();
6485
6486#if OPENSSL_VERSION_NUMBER >= 0x00907000L
6487 CRYPTO_cleanup_all_ex_data();
6488#endif
6489}
6490
6491
Emeric Brun46591952012-05-18 15:47:34 +02006492/*
6493 * Local variables:
6494 * c-indent-level: 8
6495 * c-basic-offset: 8
6496 * End:
6497 */