blob: b14bb8a46e1b7489ddece5936519de4d480914f1 [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
72#include <types/global.h>
73#include <types/ssl_sock.h>
74
Willy Tarreau7875d092012-09-10 08:20:03 +020075#include <proto/acl.h>
76#include <proto/arg.h>
Emeric Brun46591952012-05-18 15:47:34 +020077#include <proto/connection.h>
78#include <proto/fd.h>
79#include <proto/freq_ctr.h>
80#include <proto/frontend.h>
Willy Tarreau79eeafa2012-09-14 07:53:05 +020081#include <proto/listener.h>
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +020082#include <proto/openssl-compat.h>
Thierry FOURNIERed66c292013-11-28 11:05:19 +010083#include <proto/pattern.h>
Christopher Faulet31af49d2015-06-09 17:29:50 +020084#include <proto/proto_tcp.h>
Willy Tarreau92faadf2012-10-10 23:04:25 +020085#include <proto/server.h>
Emeric Brun46591952012-05-18 15:47:34 +020086#include <proto/log.h>
Emeric Brun94324a42012-10-11 14:00:19 +020087#include <proto/proxy.h>
Emeric Brunfc0421f2012-09-07 17:30:07 +020088#include <proto/shctx.h>
Emeric Brun46591952012-05-18 15:47:34 +020089#include <proto/ssl_sock.h>
Willy Tarreau9ad7bd42015-04-03 19:19:59 +020090#include <proto/stream.h>
Emeric Brun46591952012-05-18 15:47:34 +020091#include <proto/task.h>
92
Willy Tarreau518cedd2014-02-17 15:43:01 +010093/* Warning, these are bits, not integers! */
Emeric Brune64aef12012-09-21 13:15:06 +020094#define SSL_SOCK_ST_FL_VERIFY_DONE 0x00000001
Emeric Brund8b2bb52014-01-28 15:43:53 +010095#define SSL_SOCK_ST_FL_16K_WBFSIZE 0x00000002
Willy Tarreau518cedd2014-02-17 15:43:01 +010096#define SSL_SOCK_SEND_UNLIMITED 0x00000004
Emeric Brun29f037d2014-04-25 19:05:36 +020097#define SSL_SOCK_RECV_HEARTBEAT 0x00000008
98
Emeric Brunf282a812012-09-21 15:27:54 +020099/* bits 0xFFFF0000 are reserved to store verify errors */
100
101/* Verify errors macros */
102#define SSL_SOCK_CA_ERROR_TO_ST(e) (((e > 63) ? 63 : e) << (16))
103#define SSL_SOCK_CAEDEPTH_TO_ST(d) (((d > 15) ? 15 : d) << (6+16))
104#define SSL_SOCK_CRTERROR_TO_ST(e) (((e > 63) ? 63 : e) << (4+6+16))
105
106#define SSL_SOCK_ST_TO_CA_ERROR(s) ((s >> (16)) & 63)
107#define SSL_SOCK_ST_TO_CAEDEPTH(s) ((s >> (6+16)) & 15)
108#define SSL_SOCK_ST_TO_CRTERROR(s) ((s >> (4+6+16)) & 63)
Emeric Brune64aef12012-09-21 13:15:06 +0200109
Nenad Merdanovic05552d42015-02-27 19:56:49 +0100110/* Supported hash function for TLS tickets */
111#ifdef OPENSSL_NO_SHA256
112#define HASH_FUNCT EVP_sha1
113#else
114#define HASH_FUNCT EVP_sha256
115#endif /* OPENSSL_NO_SHA256 */
116
Emeric Brun850efd52014-01-29 12:24:34 +0100117/* server and bind verify method, it uses a global value as default */
118enum {
119 SSL_SOCK_VERIFY_DEFAULT = 0,
120 SSL_SOCK_VERIFY_REQUIRED = 1,
121 SSL_SOCK_VERIFY_OPTIONAL = 2,
122 SSL_SOCK_VERIFY_NONE = 3,
123};
124
Willy Tarreau71b734c2014-01-28 15:19:44 +0100125int sslconns = 0;
126int totalsslconns = 0;
Emeric Brune1f38db2012-09-03 20:36:47 +0200127
Nenad Merdanovic200b0fa2015-05-09 08:46:01 +0200128#if (defined SSL_CTRL_SET_TLSEXT_TICKET_KEY_CB && TLS_TICKETS_NO > 0)
129struct list tlskeys_reference = LIST_HEAD_INIT(tlskeys_reference);
130#endif
131
Remi Gacogne8de54152014-07-15 11:36:40 +0200132#ifndef OPENSSL_NO_DH
Remi Gacogne4f902b82015-05-28 16:23:00 +0200133static int ssl_dh_ptr_index = -1;
Remi Gacogne47783ef2015-05-29 15:53:22 +0200134static DH *global_dh = NULL;
Remi Gacogne8de54152014-07-15 11:36:40 +0200135static DH *local_dh_1024 = NULL;
136static DH *local_dh_2048 = NULL;
137static DH *local_dh_4096 = NULL;
Remi Gacogne8de54152014-07-15 11:36:40 +0200138#endif /* OPENSSL_NO_DH */
139
Willy Tarreauc8ad3be2015-06-17 15:48:26 +0200140#ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME
Christopher Faulet31af49d2015-06-09 17:29:50 +0200141/* X509V3 Extensions that will be added on generated certificates */
142#define X509V3_EXT_SIZE 5
143static char *x509v3_ext_names[X509V3_EXT_SIZE] = {
144 "basicConstraints",
145 "nsComment",
146 "subjectKeyIdentifier",
147 "authorityKeyIdentifier",
148 "keyUsage",
149};
150static char *x509v3_ext_values[X509V3_EXT_SIZE] = {
151 "CA:FALSE",
152 "\"OpenSSL Generated Certificate\"",
153 "hash",
154 "keyid,issuer:always",
155 "nonRepudiation,digitalSignature,keyEncipherment"
156};
157
158/* LRU cache to store generated certificate */
159static struct lru64_head *ssl_ctx_lru_tree = NULL;
160static unsigned int ssl_ctx_lru_seed = 0;
Willy Tarreauc8ad3be2015-06-17 15:48:26 +0200161#endif // SSL_CTRL_SET_TLSEXT_HOSTNAME
162
yanbzhube2774d2015-12-10 15:07:30 -0500163#if OPENSSL_VERSION_NUMBER >= 0x1000200fL
164/* The order here matters for picking a default context,
165 * keep the most common keytype at the bottom of the list
166 */
167const char *SSL_SOCK_KEYTYPE_NAMES[] = {
168 "dsa",
169 "ecdsa",
170 "rsa"
171};
172#define SSL_SOCK_NUM_KEYTYPES 3
Willy Tarreau30da7ad2015-12-14 11:28:33 +0100173#else
174#define SSL_SOCK_NUM_KEYTYPES 1
yanbzhube2774d2015-12-10 15:07:30 -0500175#endif
176
Willy Tarreauc8ad3be2015-06-17 15:48:26 +0200177#if (defined SSL_CTRL_SET_TLSEXT_STATUS_REQ_CB && !defined OPENSSL_NO_OCSP)
yanbzhube2774d2015-12-10 15:07:30 -0500178/*
179 * struct alignment works here such that the key.key is the same as key_data
180 * Do not change the placement of key_data
181 */
Willy Tarreauc8ad3be2015-06-17 15:48:26 +0200182struct certificate_ocsp {
183 struct ebmb_node key;
184 unsigned char key_data[OCSP_MAX_CERTID_ASN1_LENGTH];
185 struct chunk response;
186 long expire;
187};
Christopher Faulet31af49d2015-06-09 17:29:50 +0200188
yanbzhube2774d2015-12-10 15:07:30 -0500189struct ocsp_cbk_arg {
190 int is_single;
191 int single_kt;
192 union {
193 struct certificate_ocsp *s_ocsp;
194 /*
195 * m_ocsp will have multiple entries dependent on key type
196 * Entry 0 - DSA
197 * Entry 1 - ECDSA
198 * Entry 2 - RSA
199 */
200 struct certificate_ocsp *m_ocsp[SSL_SOCK_NUM_KEYTYPES];
201 };
202};
203
Emeric Brun4f3c87a2014-06-20 15:46:13 +0200204/*
Thierry FOURNIER / OZON.IO8b068c22016-10-10 11:59:50 +0200205 * This function gives the detail of the SSL error. It is used only
206 * if the debug mode and the verbose mode are activated. It dump all
207 * the SSL error until the stack was empty.
208 */
209static forceinline void ssl_sock_dump_errors(struct connection *conn)
210{
211 unsigned long ret;
212
213 if (unlikely(global.mode & MODE_DEBUG)) {
214 while(1) {
215 ret = ERR_get_error();
216 if (ret == 0)
217 return;
218 fprintf(stderr, "fd[%04x] OpenSSL error[0x%lx] %s: %s\n",
219 (unsigned short)conn->t.sock.fd, ret,
220 ERR_func_error_string(ret), ERR_reason_error_string(ret));
221 }
222 }
223}
224
225/*
Emeric Brun4f3c87a2014-06-20 15:46:13 +0200226 * This function returns the number of seconds elapsed
227 * since the Epoch, 1970-01-01 00:00:00 +0000 (UTC) and the
228 * date presented un ASN1_GENERALIZEDTIME.
229 *
230 * In parsing error case, it returns -1.
231 */
232static long asn1_generalizedtime_to_epoch(ASN1_GENERALIZEDTIME *d)
233{
234 long epoch;
235 char *p, *end;
236 const unsigned short month_offset[12] = {
237 0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334
238 };
239 int year, month;
240
241 if (!d || (d->type != V_ASN1_GENERALIZEDTIME)) return -1;
242
243 p = (char *)d->data;
244 end = p + d->length;
245
246 if (end - p < 4) return -1;
247 year = 1000 * (p[0] - '0') + 100 * (p[1] - '0') + 10 * (p[2] - '0') + p[3] - '0';
248 p += 4;
249 if (end - p < 2) return -1;
250 month = 10 * (p[0] - '0') + p[1] - '0';
251 if (month < 1 || month > 12) return -1;
252 /* Compute the number of seconds since 1 jan 1970 and the beginning of current month
253 We consider leap years and the current month (<marsh or not) */
254 epoch = ( ((year - 1970) * 365)
255 + ((year - (month < 3)) / 4 - (year - (month < 3)) / 100 + (year - (month < 3)) / 400)
256 - ((1970 - 1) / 4 - (1970 - 1) / 100 + (1970 - 1) / 400)
257 + month_offset[month-1]
258 ) * 24 * 60 * 60;
259 p += 2;
260 if (end - p < 2) return -1;
261 /* Add the number of seconds of completed days of current month */
262 epoch += (10 * (p[0] - '0') + p[1] - '0' - 1) * 24 * 60 * 60;
263 p += 2;
264 if (end - p < 2) return -1;
265 /* Add the completed hours of the current day */
266 epoch += (10 * (p[0] - '0') + p[1] - '0') * 60 * 60;
267 p += 2;
268 if (end - p < 2) return -1;
269 /* Add the completed minutes of the current hour */
270 epoch += (10 * (p[0] - '0') + p[1] - '0') * 60;
271 p += 2;
272 if (p == end) return -1;
273 /* Test if there is available seconds */
274 if (p[0] < '0' || p[0] > '9')
275 goto nosec;
276 if (end - p < 2) return -1;
277 /* Add the seconds of the current minute */
278 epoch += 10 * (p[0] - '0') + p[1] - '0';
279 p += 2;
280 if (p == end) return -1;
281 /* Ignore seconds float part if present */
282 if (p[0] == '.') {
283 do {
284 if (++p == end) return -1;
285 } while (p[0] >= '0' && p[0] <= '9');
286 }
287
288nosec:
289 if (p[0] == 'Z') {
290 if (end - p != 1) return -1;
291 return epoch;
292 }
293 else if (p[0] == '+') {
294 if (end - p != 5) return -1;
295 /* Apply timezone offset */
296 return epoch - ((10 * (p[1] - '0') + p[2] - '0') * 60 + (10 * (p[3] - '0') + p[4] - '0')) * 60;
297 }
298 else if (p[0] == '-') {
299 if (end - p != 5) return -1;
300 /* Apply timezone offset */
301 return epoch + ((10 * (p[1] - '0') + p[2] - '0') * 60 + (10 * (p[3] - '0') + p[4] - '0')) * 60;
302 }
303
304 return -1;
305}
306
Emeric Brun1d3865b2014-06-20 15:37:32 +0200307static struct eb_root cert_ocsp_tree = EB_ROOT_UNIQUE;
Emeric Brun4147b2e2014-06-16 18:36:30 +0200308
309/* This function starts to check if the OCSP response (in DER format) contained
310 * in chunk 'ocsp_response' is valid (else exits on error).
311 * If 'cid' is not NULL, it will be compared to the OCSP certificate ID
312 * contained in the OCSP Response and exits on error if no match.
313 * If it's a valid OCSP Response:
314 * If 'ocsp' is not NULL, the chunk is copied in the OCSP response's container
315 * pointed by 'ocsp'.
316 * If 'ocsp' is NULL, the function looks up into the OCSP response's
317 * containers tree (using as index the ASN1 form of the OCSP Certificate ID extracted
318 * from the response) and exits on error if not found. Finally, If an OCSP response is
319 * already present in the container, it will be overwritten.
320 *
321 * Note: OCSP response containing more than one OCSP Single response is not
322 * considered valid.
323 *
324 * Returns 0 on success, 1 in error case.
325 */
326static int ssl_sock_load_ocsp_response(struct chunk *ocsp_response, struct certificate_ocsp *ocsp, OCSP_CERTID *cid, char **err)
327{
328 OCSP_RESPONSE *resp;
329 OCSP_BASICRESP *bs = NULL;
330 OCSP_SINGLERESP *sr;
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +0200331 OCSP_CERTID *id;
Emeric Brun4147b2e2014-06-16 18:36:30 +0200332 unsigned char *p = (unsigned char *)ocsp_response->str;
333 int rc , count_sr;
Emeric Brun13a6b482014-06-20 15:44:34 +0200334 ASN1_GENERALIZEDTIME *revtime, *thisupd, *nextupd = NULL;
Emeric Brun4147b2e2014-06-16 18:36:30 +0200335 int reason;
336 int ret = 1;
337
338 resp = d2i_OCSP_RESPONSE(NULL, (const unsigned char **)&p, ocsp_response->len);
339 if (!resp) {
340 memprintf(err, "Unable to parse OCSP response");
341 goto out;
342 }
343
344 rc = OCSP_response_status(resp);
345 if (rc != OCSP_RESPONSE_STATUS_SUCCESSFUL) {
346 memprintf(err, "OCSP response status not successful");
347 goto out;
348 }
349
350 bs = OCSP_response_get1_basic(resp);
351 if (!bs) {
352 memprintf(err, "Failed to get basic response from OCSP Response");
353 goto out;
354 }
355
356 count_sr = OCSP_resp_count(bs);
357 if (count_sr > 1) {
358 memprintf(err, "OCSP response ignored because contains multiple single responses (%d)", count_sr);
359 goto out;
360 }
361
362 sr = OCSP_resp_get0(bs, 0);
363 if (!sr) {
364 memprintf(err, "Failed to get OCSP single response");
365 goto out;
366 }
367
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +0200368 id = (OCSP_CERTID*)OCSP_SINGLERESP_get0_id(sr);
369
Emeric Brun4147b2e2014-06-16 18:36:30 +0200370 rc = OCSP_single_get0_status(sr, &reason, &revtime, &thisupd, &nextupd);
371 if (rc != V_OCSP_CERTSTATUS_GOOD) {
372 memprintf(err, "OCSP single response: certificate status not good");
373 goto out;
374 }
375
Emeric Brun13a6b482014-06-20 15:44:34 +0200376 if (!nextupd) {
377 memprintf(err, "OCSP single response: missing nextupdate");
378 goto out;
379 }
380
Emeric Brunc8b27b62014-06-19 14:16:17 +0200381 rc = OCSP_check_validity(thisupd, nextupd, OCSP_MAX_RESPONSE_TIME_SKEW, -1);
Emeric Brun4147b2e2014-06-16 18:36:30 +0200382 if (!rc) {
383 memprintf(err, "OCSP single response: no longer valid.");
384 goto out;
385 }
386
387 if (cid) {
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +0200388 if (OCSP_id_cmp(id, cid)) {
Emeric Brun4147b2e2014-06-16 18:36:30 +0200389 memprintf(err, "OCSP single response: Certificate ID does not match certificate and issuer");
390 goto out;
391 }
392 }
393
394 if (!ocsp) {
395 unsigned char key[OCSP_MAX_CERTID_ASN1_LENGTH];
396 unsigned char *p;
397
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +0200398 rc = i2d_OCSP_CERTID(id, NULL);
Emeric Brun4147b2e2014-06-16 18:36:30 +0200399 if (!rc) {
400 memprintf(err, "OCSP single response: Unable to encode Certificate ID");
401 goto out;
402 }
403
404 if (rc > OCSP_MAX_CERTID_ASN1_LENGTH) {
405 memprintf(err, "OCSP single response: Certificate ID too long");
406 goto out;
407 }
408
409 p = key;
410 memset(key, 0, OCSP_MAX_CERTID_ASN1_LENGTH);
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +0200411 i2d_OCSP_CERTID(id, &p);
Emeric Brun4147b2e2014-06-16 18:36:30 +0200412 ocsp = (struct certificate_ocsp *)ebmb_lookup(&cert_ocsp_tree, key, OCSP_MAX_CERTID_ASN1_LENGTH);
413 if (!ocsp) {
414 memprintf(err, "OCSP single response: Certificate ID does not match any certificate or issuer");
415 goto out;
416 }
417 }
418
419 /* According to comments on "chunk_dup", the
420 previous chunk buffer will be freed */
421 if (!chunk_dup(&ocsp->response, ocsp_response)) {
422 memprintf(err, "OCSP response: Memory allocation error");
423 goto out;
424 }
425
Emeric Brun4f3c87a2014-06-20 15:46:13 +0200426 ocsp->expire = asn1_generalizedtime_to_epoch(nextupd) - OCSP_MAX_RESPONSE_TIME_SKEW;
427
Emeric Brun4147b2e2014-06-16 18:36:30 +0200428 ret = 0;
429out:
430 if (bs)
431 OCSP_BASICRESP_free(bs);
432
433 if (resp)
434 OCSP_RESPONSE_free(resp);
435
436 return ret;
437}
438/*
439 * External function use to update the OCSP response in the OCSP response's
440 * containers tree. The chunk 'ocsp_response' must contain the OCSP response
441 * to update in DER format.
442 *
443 * Returns 0 on success, 1 in error case.
444 */
445int ssl_sock_update_ocsp_response(struct chunk *ocsp_response, char **err)
446{
447 return ssl_sock_load_ocsp_response(ocsp_response, NULL, NULL, err);
448}
449
450/*
451 * This function load the OCSP Resonse in DER format contained in file at
452 * path 'ocsp_path' and call 'ssl_sock_load_ocsp_response'
453 *
454 * Returns 0 on success, 1 in error case.
455 */
456static int ssl_sock_load_ocsp_response_from_file(const char *ocsp_path, struct certificate_ocsp *ocsp, OCSP_CERTID *cid, char **err)
457{
458 int fd = -1;
459 int r = 0;
460 int ret = 1;
461
462 fd = open(ocsp_path, O_RDONLY);
463 if (fd == -1) {
464 memprintf(err, "Error opening OCSP response file");
465 goto end;
466 }
467
468 trash.len = 0;
469 while (trash.len < trash.size) {
470 r = read(fd, trash.str + trash.len, trash.size - trash.len);
471 if (r < 0) {
472 if (errno == EINTR)
473 continue;
474
475 memprintf(err, "Error reading OCSP response from file");
476 goto end;
477 }
478 else if (r == 0) {
479 break;
480 }
481 trash.len += r;
482 }
483
484 close(fd);
485 fd = -1;
486
487 ret = ssl_sock_load_ocsp_response(&trash, ocsp, cid, err);
488end:
489 if (fd != -1)
490 close(fd);
491
492 return ret;
493}
494
Nenad Merdanovic05552d42015-02-27 19:56:49 +0100495#if (defined SSL_CTRL_SET_TLSEXT_TICKET_KEY_CB && TLS_TICKETS_NO > 0)
496static 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)
497{
498 struct tls_sess_key *keys;
499 struct connection *conn;
500 int head;
501 int i;
502
Vincent Bernat3c2f2f22016-04-03 13:48:42 +0200503 conn = SSL_get_app_data(s);
Nenad Merdanovic146defa2015-05-09 08:46:00 +0200504 keys = objt_listener(conn->target)->bind_conf->keys_ref->tlskeys;
505 head = objt_listener(conn->target)->bind_conf->keys_ref->tls_ticket_enc_index;
Nenad Merdanovic05552d42015-02-27 19:56:49 +0100506
507 if (enc) {
508 memcpy(key_name, keys[head].name, 16);
509
510 if(!RAND_pseudo_bytes(iv, EVP_MAX_IV_LENGTH))
511 return -1;
512
513 if(!EVP_EncryptInit_ex(ectx, EVP_aes_128_cbc(), NULL, keys[head].aes_key, iv))
514 return -1;
515
516 HMAC_Init_ex(hctx, keys[head].hmac_key, 16, HASH_FUNCT(), NULL);
517
518 return 1;
519 } else {
520 for (i = 0; i < TLS_TICKETS_NO; i++) {
521 if (!memcmp(key_name, keys[(head + i) % TLS_TICKETS_NO].name, 16))
522 goto found;
523 }
524 return 0;
525
526 found:
527 HMAC_Init_ex(hctx, keys[(head + i) % TLS_TICKETS_NO].hmac_key, 16, HASH_FUNCT(), NULL);
528 if(!EVP_DecryptInit_ex(ectx, EVP_aes_128_cbc(), NULL, keys[(head + i) % TLS_TICKETS_NO].aes_key, iv))
529 return -1;
530 /* 2 for key renewal, 1 if current key is still valid */
531 return i ? 2 : 1;
532 }
Nenad Merdanovic200b0fa2015-05-09 08:46:01 +0200533}
534
535struct tls_keys_ref *tlskeys_ref_lookup(const char *filename)
536{
537 struct tls_keys_ref *ref;
538
539 list_for_each_entry(ref, &tlskeys_reference, list)
540 if (ref->filename && strcmp(filename, ref->filename) == 0)
541 return ref;
542 return NULL;
543}
544
545struct tls_keys_ref *tlskeys_ref_lookupid(int unique_id)
546{
547 struct tls_keys_ref *ref;
548
549 list_for_each_entry(ref, &tlskeys_reference, list)
550 if (ref->unique_id == unique_id)
551 return ref;
552 return NULL;
553}
554
555int ssl_sock_update_tlskey(char *filename, struct chunk *tlskey, char **err) {
556 struct tls_keys_ref *ref = tlskeys_ref_lookup(filename);
557
558 if(!ref) {
559 memprintf(err, "Unable to locate the referenced filename: %s", filename);
560 return 1;
561 }
562
Pradeep Jindalcc79b002015-08-20 18:25:17 +0530563 memcpy((char *) (ref->tlskeys + ((ref->tls_ticket_enc_index + 2) % TLS_TICKETS_NO)), tlskey->str, tlskey->len);
564 ref->tls_ticket_enc_index = (ref->tls_ticket_enc_index + 1) % TLS_TICKETS_NO;
Nenad Merdanovic200b0fa2015-05-09 08:46:01 +0200565
566 return 0;
Nenad Merdanovic05552d42015-02-27 19:56:49 +0100567}
Nenad Merdanovic200b0fa2015-05-09 08:46:01 +0200568
569/* This function finalize the configuration parsing. Its set all the
570 * automatic ids
571 */
572void tlskeys_finalize_config(void)
573{
574 int i = 0;
575 struct tls_keys_ref *ref, *ref2, *ref3;
576 struct list tkr = LIST_HEAD_INIT(tkr);
577
578 list_for_each_entry(ref, &tlskeys_reference, list) {
579 if (ref->unique_id == -1) {
580 /* Look for the first free id. */
581 while (1) {
582 list_for_each_entry(ref2, &tlskeys_reference, list) {
583 if (ref2->unique_id == i) {
584 i++;
585 break;
586 }
587 }
588 if (&ref2->list == &tlskeys_reference)
589 break;
590 }
591
592 /* Uses the unique id and increment it for the next entry. */
593 ref->unique_id = i;
594 i++;
595 }
596 }
597
598 /* This sort the reference list by id. */
599 list_for_each_entry_safe(ref, ref2, &tlskeys_reference, list) {
600 LIST_DEL(&ref->list);
601 list_for_each_entry(ref3, &tkr, list) {
602 if (ref->unique_id < ref3->unique_id) {
603 LIST_ADDQ(&ref3->list, &ref->list);
604 break;
605 }
606 }
607 if (&ref3->list == &tkr)
608 LIST_ADDQ(&tkr, &ref->list);
609 }
610
611 /* swap root */
612 LIST_ADD(&tkr, &tlskeys_reference);
613 LIST_DEL(&tkr);
614}
615
Nenad Merdanovic05552d42015-02-27 19:56:49 +0100616#endif /* SSL_CTRL_SET_TLSEXT_TICKET_KEY_CB */
617
yanbzhube2774d2015-12-10 15:07:30 -0500618int ssl_sock_get_ocsp_arg_kt_index(int evp_keytype)
619{
620 switch (evp_keytype) {
621 case EVP_PKEY_RSA:
622 return 2;
623 case EVP_PKEY_DSA:
624 return 0;
625 case EVP_PKEY_EC:
626 return 1;
627 }
628
629 return -1;
630}
631
Emeric Brun4147b2e2014-06-16 18:36:30 +0200632/*
633 * Callback used to set OCSP status extension content in server hello.
634 */
635int ssl_sock_ocsp_stapling_cbk(SSL *ssl, void *arg)
636{
yanbzhube2774d2015-12-10 15:07:30 -0500637 struct certificate_ocsp *ocsp;
638 struct ocsp_cbk_arg *ocsp_arg;
639 char *ssl_buf;
640 EVP_PKEY *ssl_pkey;
641 int key_type;
642 int index;
643
Vincent Bernat3c2f2f22016-04-03 13:48:42 +0200644 ocsp_arg = arg;
yanbzhube2774d2015-12-10 15:07:30 -0500645
646 ssl_pkey = SSL_get_privatekey(ssl);
647 if (!ssl_pkey)
648 return SSL_TLSEXT_ERR_NOACK;
649
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +0200650 key_type = EVP_PKEY_base_id(ssl_pkey);
yanbzhube2774d2015-12-10 15:07:30 -0500651
652 if (ocsp_arg->is_single && ocsp_arg->single_kt == key_type)
653 ocsp = ocsp_arg->s_ocsp;
654 else {
655 /* For multiple certs per context, we have to find the correct OCSP response based on
656 * the certificate type
657 */
658 index = ssl_sock_get_ocsp_arg_kt_index(key_type);
659
660 if (index < 0)
661 return SSL_TLSEXT_ERR_NOACK;
662
663 ocsp = ocsp_arg->m_ocsp[index];
664
665 }
Emeric Brun4147b2e2014-06-16 18:36:30 +0200666
667 if (!ocsp ||
668 !ocsp->response.str ||
Emeric Brun4f3c87a2014-06-20 15:46:13 +0200669 !ocsp->response.len ||
670 (ocsp->expire < now.tv_sec))
Emeric Brun4147b2e2014-06-16 18:36:30 +0200671 return SSL_TLSEXT_ERR_NOACK;
672
673 ssl_buf = OPENSSL_malloc(ocsp->response.len);
674 if (!ssl_buf)
675 return SSL_TLSEXT_ERR_NOACK;
676
677 memcpy(ssl_buf, ocsp->response.str, ocsp->response.len);
678 SSL_set_tlsext_status_ocsp_resp(ssl, ssl_buf, ocsp->response.len);
679
680 return SSL_TLSEXT_ERR_OK;
681}
682
683/*
684 * This function enables the handling of OCSP status extension on 'ctx' if a
685 * file name 'cert_path' suffixed using ".ocsp" is present.
686 * To enable OCSP status extension, the issuer's certificate is mandatory.
687 * It should be present in the certificate's extra chain builded from file
688 * 'cert_path'. If not found, the issuer certificate is loaded from a file
689 * named 'cert_path' suffixed using '.issuer'.
690 *
691 * In addition, ".ocsp" file content is loaded as a DER format of an OCSP
692 * response. If file is empty or content is not a valid OCSP response,
693 * OCSP status extension is enabled but OCSP response is ignored (a warning
694 * is displayed).
695 *
696 * Returns 1 if no ".ocsp" file found, 0 if OCSP status extension is
697 * succesfully enabled, or -1 in other error case.
698 */
699static int ssl_sock_load_ocsp(SSL_CTX *ctx, const char *cert_path)
700{
701
702 BIO *in = NULL;
703 X509 *x, *xi = NULL, *issuer = NULL;
704 STACK_OF(X509) *chain = NULL;
705 OCSP_CERTID *cid = NULL;
706 SSL *ssl;
707 char ocsp_path[MAXPATHLEN+1];
708 int i, ret = -1;
709 struct stat st;
710 struct certificate_ocsp *ocsp = NULL, *iocsp;
711 char *warn = NULL;
712 unsigned char *p;
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +0200713 pem_password_cb *passwd_cb;
714 void *passwd_cb_userdata;
715 void (*callback) (void);
Emeric Brun4147b2e2014-06-16 18:36:30 +0200716
717 snprintf(ocsp_path, MAXPATHLEN+1, "%s.ocsp", cert_path);
718
719 if (stat(ocsp_path, &st))
720 return 1;
721
722 ssl = SSL_new(ctx);
723 if (!ssl)
724 goto out;
725
726 x = SSL_get_certificate(ssl);
727 if (!x)
728 goto out;
729
730 /* Try to lookup for issuer in certificate extra chain */
731#ifdef SSL_CTRL_GET_EXTRA_CHAIN_CERTS
732 SSL_CTX_get_extra_chain_certs(ctx, &chain);
733#else
734 chain = ctx->extra_certs;
735#endif
736 for (i = 0; i < sk_X509_num(chain); i++) {
737 issuer = sk_X509_value(chain, i);
738 if (X509_check_issued(issuer, x) == X509_V_OK)
739 break;
740 else
741 issuer = NULL;
742 }
743
744 /* If not found try to load issuer from a suffixed file */
745 if (!issuer) {
746 char issuer_path[MAXPATHLEN+1];
747
748 in = BIO_new(BIO_s_file());
749 if (!in)
750 goto out;
751
752 snprintf(issuer_path, MAXPATHLEN+1, "%s.issuer", cert_path);
753 if (BIO_read_filename(in, issuer_path) <= 0)
754 goto out;
755
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +0200756 passwd_cb = SSL_CTX_get_default_passwd_cb(ctx);
757 passwd_cb_userdata = SSL_CTX_get_default_passwd_cb_userdata(ctx);
758
759 xi = PEM_read_bio_X509_AUX(in, NULL, passwd_cb, passwd_cb_userdata);
Emeric Brun4147b2e2014-06-16 18:36:30 +0200760 if (!xi)
761 goto out;
762
763 if (X509_check_issued(xi, x) != X509_V_OK)
764 goto out;
765
766 issuer = xi;
767 }
768
769 cid = OCSP_cert_to_id(0, x, issuer);
770 if (!cid)
771 goto out;
772
773 i = i2d_OCSP_CERTID(cid, NULL);
774 if (!i || (i > OCSP_MAX_CERTID_ASN1_LENGTH))
775 goto out;
776
Vincent Bernat02779b62016-04-03 13:48:43 +0200777 ocsp = calloc(1, sizeof(*ocsp));
Emeric Brun4147b2e2014-06-16 18:36:30 +0200778 if (!ocsp)
779 goto out;
780
781 p = ocsp->key_data;
782 i2d_OCSP_CERTID(cid, &p);
783
784 iocsp = (struct certificate_ocsp *)ebmb_insert(&cert_ocsp_tree, &ocsp->key, OCSP_MAX_CERTID_ASN1_LENGTH);
785 if (iocsp == ocsp)
786 ocsp = NULL;
787
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +0200788#ifndef SSL_CTX_get_tlsext_status_cb
789# define SSL_CTX_get_tlsext_status_cb(ctx, cb) \
790 *cb = (void (*) (void))ctx->tlsext_status_cb;
791#endif
792 SSL_CTX_get_tlsext_status_cb(ctx, &callback);
793
794 if (!callback) {
Vincent Bernat02779b62016-04-03 13:48:43 +0200795 struct ocsp_cbk_arg *cb_arg = calloc(1, sizeof(*cb_arg));
yanbzhube2774d2015-12-10 15:07:30 -0500796
797 cb_arg->is_single = 1;
798 cb_arg->s_ocsp = iocsp;
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +0200799
800 cb_arg->single_kt = EVP_PKEY_base_id(X509_get_pubkey(x));
yanbzhube2774d2015-12-10 15:07:30 -0500801
802 SSL_CTX_set_tlsext_status_cb(ctx, ssl_sock_ocsp_stapling_cbk);
803 SSL_CTX_set_tlsext_status_arg(ctx, cb_arg);
804 } else {
805 /*
806 * If the ctx has a status CB, then we have previously set an OCSP staple for this ctx
807 * Update that cb_arg with the new cert's staple
808 */
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +0200809 struct ocsp_cbk_arg *cb_arg;
yanbzhube2774d2015-12-10 15:07:30 -0500810 struct certificate_ocsp *tmp_ocsp;
811 int index;
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +0200812 int key_type;
813
814#ifdef SSL_CTX_get_tlsext_status_arg
815 SSL_CTX_ctrl(ctx, SSL_CTRL_GET_TLSEXT_STATUS_REQ_CB_ARG, 0, &cb_arg);
816#else
817 cb_arg = ctx->tlsext_status_arg;
818#endif
yanbzhube2774d2015-12-10 15:07:30 -0500819
820 /*
821 * The following few lines will convert cb_arg from a single ocsp to multi ocsp
822 * the order of operations below matter, take care when changing it
823 */
824 tmp_ocsp = cb_arg->s_ocsp;
825 index = ssl_sock_get_ocsp_arg_kt_index(cb_arg->single_kt);
826 cb_arg->s_ocsp = NULL;
827 cb_arg->m_ocsp[index] = tmp_ocsp;
828 cb_arg->is_single = 0;
829 cb_arg->single_kt = 0;
830
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +0200831 key_type = EVP_PKEY_base_id(X509_get_pubkey(x));
832 index = ssl_sock_get_ocsp_arg_kt_index(key_type);
yanbzhube2774d2015-12-10 15:07:30 -0500833 if (index >= 0 && !cb_arg->m_ocsp[index])
834 cb_arg->m_ocsp[index] = iocsp;
835
836 }
Emeric Brun4147b2e2014-06-16 18:36:30 +0200837
838 ret = 0;
839
840 warn = NULL;
841 if (ssl_sock_load_ocsp_response_from_file(ocsp_path, iocsp, cid, &warn)) {
842 memprintf(&warn, "Loading '%s': %s. Content will be ignored", ocsp_path, warn ? warn : "failure");
843 Warning("%s.\n", warn);
844 }
845
846out:
847 if (ssl)
848 SSL_free(ssl);
849
850 if (in)
851 BIO_free(in);
852
853 if (xi)
854 X509_free(xi);
855
856 if (cid)
857 OCSP_CERTID_free(cid);
858
859 if (ocsp)
860 free(ocsp);
861
862 if (warn)
863 free(warn);
864
865
866 return ret;
867}
868
869#endif
870
Daniel Jakots54ffb912015-11-06 20:02:41 +0100871#if (OPENSSL_VERSION_NUMBER >= 0x1000200fL && !defined OPENSSL_NO_TLSEXT && !defined OPENSSL_IS_BORINGSSL && !defined LIBRESSL_VERSION_NUMBER)
Janusz Dziemidowicz2c701b52015-03-07 23:03:59 +0100872
873#define CT_EXTENSION_TYPE 18
874
875static int sctl_ex_index = -1;
876
877/*
878 * Try to parse Signed Certificate Timestamp List structure. This function
879 * makes only basic test if the data seems like SCTL. No signature validation
880 * is performed.
881 */
882static int ssl_sock_parse_sctl(struct chunk *sctl)
883{
884 int ret = 1;
885 int len, pos, sct_len;
886 unsigned char *data;
887
888 if (sctl->len < 2)
889 goto out;
890
891 data = (unsigned char *)sctl->str;
892 len = (data[0] << 8) | data[1];
893
894 if (len + 2 != sctl->len)
895 goto out;
896
897 data = data + 2;
898 pos = 0;
899 while (pos < len) {
900 if (len - pos < 2)
901 goto out;
902
903 sct_len = (data[pos] << 8) | data[pos + 1];
904 if (pos + sct_len + 2 > len)
905 goto out;
906
907 pos += sct_len + 2;
908 }
909
910 ret = 0;
911
912out:
913 return ret;
914}
915
916static int ssl_sock_load_sctl_from_file(const char *sctl_path, struct chunk **sctl)
917{
918 int fd = -1;
919 int r = 0;
920 int ret = 1;
921
922 *sctl = NULL;
923
924 fd = open(sctl_path, O_RDONLY);
925 if (fd == -1)
926 goto end;
927
928 trash.len = 0;
929 while (trash.len < trash.size) {
930 r = read(fd, trash.str + trash.len, trash.size - trash.len);
931 if (r < 0) {
932 if (errno == EINTR)
933 continue;
934
935 goto end;
936 }
937 else if (r == 0) {
938 break;
939 }
940 trash.len += r;
941 }
942
943 ret = ssl_sock_parse_sctl(&trash);
944 if (ret)
945 goto end;
946
Vincent Bernat02779b62016-04-03 13:48:43 +0200947 *sctl = calloc(1, sizeof(**sctl));
Janusz Dziemidowicz2c701b52015-03-07 23:03:59 +0100948 if (!chunk_dup(*sctl, &trash)) {
949 free(*sctl);
950 *sctl = NULL;
951 goto end;
952 }
953
954end:
955 if (fd != -1)
956 close(fd);
957
958 return ret;
959}
960
961int ssl_sock_sctl_add_cbk(SSL *ssl, unsigned ext_type, const unsigned char **out, size_t *outlen, int *al, void *add_arg)
962{
Vincent Bernat3c2f2f22016-04-03 13:48:42 +0200963 struct chunk *sctl = add_arg;
Janusz Dziemidowicz2c701b52015-03-07 23:03:59 +0100964
965 *out = (unsigned char *)sctl->str;
966 *outlen = sctl->len;
967
968 return 1;
969}
970
971int ssl_sock_sctl_parse_cbk(SSL *s, unsigned int ext_type, const unsigned char *in, size_t inlen, int *al, void *parse_arg)
972{
973 return 1;
974}
975
976static int ssl_sock_load_sctl(SSL_CTX *ctx, const char *cert_path)
977{
978 char sctl_path[MAXPATHLEN+1];
979 int ret = -1;
980 struct stat st;
981 struct chunk *sctl = NULL;
982
983 snprintf(sctl_path, MAXPATHLEN+1, "%s.sctl", cert_path);
984
985 if (stat(sctl_path, &st))
986 return 1;
987
988 if (ssl_sock_load_sctl_from_file(sctl_path, &sctl))
989 goto out;
990
991 if (!SSL_CTX_add_server_custom_ext(ctx, CT_EXTENSION_TYPE, ssl_sock_sctl_add_cbk, NULL, sctl, ssl_sock_sctl_parse_cbk, NULL)) {
992 free(sctl);
993 goto out;
994 }
995
996 SSL_CTX_set_ex_data(ctx, sctl_ex_index, sctl);
997
998 ret = 0;
999
1000out:
1001 return ret;
1002}
1003
1004#endif
1005
Emeric Brune1f38db2012-09-03 20:36:47 +02001006void ssl_sock_infocbk(const SSL *ssl, int where, int ret)
1007{
Vincent Bernat3c2f2f22016-04-03 13:48:42 +02001008 struct connection *conn = SSL_get_app_data(ssl);
Emeric Brund8b2bb52014-01-28 15:43:53 +01001009 BIO *write_bio;
Willy Tarreau622317d2015-02-27 16:36:16 +01001010 (void)ret; /* shut gcc stupid warning */
Emeric Brune1f38db2012-09-03 20:36:47 +02001011
1012 if (where & SSL_CB_HANDSHAKE_START) {
1013 /* Disable renegotiation (CVE-2009-3555) */
Willy Tarreau20879a02012-12-03 16:32:10 +01001014 if (conn->flags & CO_FL_CONNECTED) {
Emeric Brune1f38db2012-09-03 20:36:47 +02001015 conn->flags |= CO_FL_ERROR;
Willy Tarreau20879a02012-12-03 16:32:10 +01001016 conn->err_code = CO_ER_SSL_RENEG;
1017 }
Emeric Brune1f38db2012-09-03 20:36:47 +02001018 }
Emeric Brund8b2bb52014-01-28 15:43:53 +01001019
1020 if ((where & SSL_CB_ACCEPT_LOOP) == SSL_CB_ACCEPT_LOOP) {
1021 if (!(conn->xprt_st & SSL_SOCK_ST_FL_16K_WBFSIZE)) {
1022 /* Long certificate chains optimz
1023 If write and read bios are differents, we
1024 consider that the buffering was activated,
1025 so we rise the output buffer size from 4k
1026 to 16k */
1027 write_bio = SSL_get_wbio(ssl);
1028 if (write_bio != SSL_get_rbio(ssl)) {
1029 BIO_set_write_buffer_size(write_bio, 16384);
1030 conn->xprt_st |= SSL_SOCK_ST_FL_16K_WBFSIZE;
1031 }
1032 }
1033 }
Emeric Brunfc0421f2012-09-07 17:30:07 +02001034}
1035
Emeric Brune64aef12012-09-21 13:15:06 +02001036/* Callback is called for each certificate of the chain during a verify
1037 ok is set to 1 if preverify detect no error on current certificate.
1038 Returns 0 to break the handshake, 1 otherwise. */
Evan Broderbe554312013-06-27 00:05:25 -07001039int ssl_sock_bind_verifycbk(int ok, X509_STORE_CTX *x_store)
Emeric Brune64aef12012-09-21 13:15:06 +02001040{
1041 SSL *ssl;
1042 struct connection *conn;
Emeric Brun81c00f02012-09-21 14:31:21 +02001043 int err, depth;
Emeric Brune64aef12012-09-21 13:15:06 +02001044
1045 ssl = X509_STORE_CTX_get_ex_data(x_store, SSL_get_ex_data_X509_STORE_CTX_idx());
Vincent Bernat3c2f2f22016-04-03 13:48:42 +02001046 conn = SSL_get_app_data(ssl);
Emeric Brune64aef12012-09-21 13:15:06 +02001047
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02001048 conn->xprt_st |= SSL_SOCK_ST_FL_VERIFY_DONE;
Emeric Brune64aef12012-09-21 13:15:06 +02001049
Emeric Brun81c00f02012-09-21 14:31:21 +02001050 if (ok) /* no errors */
1051 return ok;
1052
1053 depth = X509_STORE_CTX_get_error_depth(x_store);
1054 err = X509_STORE_CTX_get_error(x_store);
1055
1056 /* check if CA error needs to be ignored */
1057 if (depth > 0) {
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02001058 if (!SSL_SOCK_ST_TO_CA_ERROR(conn->xprt_st)) {
1059 conn->xprt_st |= SSL_SOCK_CA_ERROR_TO_ST(err);
1060 conn->xprt_st |= SSL_SOCK_CAEDEPTH_TO_ST(depth);
Emeric Brunf282a812012-09-21 15:27:54 +02001061 }
1062
Emeric Brun1eb20ef2012-12-03 13:24:29 +01001063 if (objt_listener(conn->target)->bind_conf->ca_ignerr & (1ULL << err)) {
Thierry FOURNIER / OZON.IO8b068c22016-10-10 11:59:50 +02001064 ssl_sock_dump_errors(conn);
Emeric Brun1eb20ef2012-12-03 13:24:29 +01001065 ERR_clear_error();
Emeric Brun81c00f02012-09-21 14:31:21 +02001066 return 1;
Emeric Brun1eb20ef2012-12-03 13:24:29 +01001067 }
Emeric Brun81c00f02012-09-21 14:31:21 +02001068
Willy Tarreau20879a02012-12-03 16:32:10 +01001069 conn->err_code = CO_ER_SSL_CA_FAIL;
Emeric Brun81c00f02012-09-21 14:31:21 +02001070 return 0;
1071 }
1072
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02001073 if (!SSL_SOCK_ST_TO_CRTERROR(conn->xprt_st))
1074 conn->xprt_st |= SSL_SOCK_CRTERROR_TO_ST(err);
Emeric Brunf282a812012-09-21 15:27:54 +02001075
Emeric Brun81c00f02012-09-21 14:31:21 +02001076 /* check if certificate error needs to be ignored */
Emeric Brun1eb20ef2012-12-03 13:24:29 +01001077 if (objt_listener(conn->target)->bind_conf->crt_ignerr & (1ULL << err)) {
Thierry FOURNIER / OZON.IO8b068c22016-10-10 11:59:50 +02001078 ssl_sock_dump_errors(conn);
Emeric Brun1eb20ef2012-12-03 13:24:29 +01001079 ERR_clear_error();
Emeric Brun81c00f02012-09-21 14:31:21 +02001080 return 1;
Emeric Brun1eb20ef2012-12-03 13:24:29 +01001081 }
Emeric Brun81c00f02012-09-21 14:31:21 +02001082
Willy Tarreau20879a02012-12-03 16:32:10 +01001083 conn->err_code = CO_ER_SSL_CRT_FAIL;
Emeric Brun81c00f02012-09-21 14:31:21 +02001084 return 0;
Emeric Brune64aef12012-09-21 13:15:06 +02001085}
1086
Emeric Brun29f037d2014-04-25 19:05:36 +02001087/* Callback is called for ssl protocol analyse */
1088void ssl_sock_msgcbk(int write_p, int version, int content_type, const void *buf, size_t len, SSL *ssl, void *arg)
1089{
Emeric Brun29f037d2014-04-25 19:05:36 +02001090#ifdef TLS1_RT_HEARTBEAT
1091 /* test heartbeat received (write_p is set to 0
1092 for a received record) */
Willy Tarreauf51c6982014-04-25 20:02:39 +02001093 if ((content_type == TLS1_RT_HEARTBEAT) && (write_p == 0)) {
Vincent Bernat3c2f2f22016-04-03 13:48:42 +02001094 struct connection *conn = SSL_get_app_data(ssl);
Willy Tarreauf51c6982014-04-25 20:02:39 +02001095 const unsigned char *p = buf;
1096 unsigned int payload;
1097
Emeric Brun29f037d2014-04-25 19:05:36 +02001098 conn->xprt_st |= SSL_SOCK_RECV_HEARTBEAT;
Willy Tarreauf51c6982014-04-25 20:02:39 +02001099
1100 /* Check if this is a CVE-2014-0160 exploitation attempt. */
1101 if (*p != TLS1_HB_REQUEST)
1102 return;
1103
Willy Tarreauaeed6722014-04-25 23:59:58 +02001104 if (len < 1 + 2 + 16) /* 1 type + 2 size + 0 payload + 16 padding */
Willy Tarreauf51c6982014-04-25 20:02:39 +02001105 goto kill_it;
1106
1107 payload = (p[1] * 256) + p[2];
Willy Tarreau3b2fdb62014-04-25 23:44:22 +02001108 if (3 + payload + 16 <= len)
Willy Tarreauf51c6982014-04-25 20:02:39 +02001109 return; /* OK no problem */
Willy Tarreauaeed6722014-04-25 23:59:58 +02001110 kill_it:
Willy Tarreau3b2fdb62014-04-25 23:44:22 +02001111 /* We have a clear heartbleed attack (CVE-2014-0160), the
1112 * advertised payload is larger than the advertised packet
1113 * length, so we have garbage in the buffer between the
1114 * payload and the end of the buffer (p+len). We can't know
1115 * if the SSL stack is patched, and we don't know if we can
1116 * safely wipe out the area between p+3+len and payload.
1117 * So instead, we prevent the response from being sent by
1118 * setting the max_send_fragment to 0 and we report an SSL
1119 * error, which will kill this connection. It will be reported
1120 * above as SSL_ERROR_SSL while an other handshake failure with
Willy Tarreauf51c6982014-04-25 20:02:39 +02001121 * a heartbeat message will be reported as SSL_ERROR_SYSCALL.
1122 */
Willy Tarreau3b2fdb62014-04-25 23:44:22 +02001123 ssl->max_send_fragment = 0;
Willy Tarreauf51c6982014-04-25 20:02:39 +02001124 SSLerr(SSL_F_TLS1_HEARTBEAT, SSL_R_SSL_HANDSHAKE_FAILURE);
1125 return;
1126 }
Emeric Brun29f037d2014-04-25 19:05:36 +02001127#endif
1128}
1129
Willy Tarreau6c9a3d52012-10-18 18:57:14 +02001130#ifdef OPENSSL_NPN_NEGOTIATED
1131/* This callback is used so that the server advertises the list of
1132 * negociable protocols for NPN.
1133 */
1134static int ssl_sock_advertise_npn_protos(SSL *s, const unsigned char **data,
1135 unsigned int *len, void *arg)
1136{
1137 struct bind_conf *conf = arg;
1138
1139 *data = (const unsigned char *)conf->npn_str;
1140 *len = conf->npn_len;
1141 return SSL_TLSEXT_ERR_OK;
1142}
1143#endif
1144
Dirkjan Bussink48f1c4e2014-02-13 12:29:42 +01001145#ifdef TLSEXT_TYPE_application_layer_protocol_negotiation
Willy Tarreauab861d32013-04-02 02:30:41 +02001146/* This callback is used so that the server advertises the list of
1147 * negociable protocols for ALPN.
1148 */
Dirkjan Bussink48f1c4e2014-02-13 12:29:42 +01001149static int ssl_sock_advertise_alpn_protos(SSL *s, const unsigned char **out,
1150 unsigned char *outlen,
1151 const unsigned char *server,
1152 unsigned int server_len, void *arg)
Willy Tarreauab861d32013-04-02 02:30:41 +02001153{
1154 struct bind_conf *conf = arg;
1155
Dirkjan Bussink48f1c4e2014-02-13 12:29:42 +01001156 if (SSL_select_next_proto((unsigned char**) out, outlen, (const unsigned char *)conf->alpn_str,
1157 conf->alpn_len, server, server_len) != OPENSSL_NPN_NEGOTIATED) {
1158 return SSL_TLSEXT_ERR_NOACK;
1159 }
Willy Tarreauab861d32013-04-02 02:30:41 +02001160 return SSL_TLSEXT_ERR_OK;
1161}
1162#endif
1163
Willy Tarreauc8ad3be2015-06-17 15:48:26 +02001164#ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME
Christopher Faulet85b5a1a2015-10-09 11:46:32 +02001165static DH *ssl_get_tmp_dh(SSL *ssl, int export, int keylen);
1166
Christopher Faulet30548802015-06-11 13:39:32 +02001167/* Create a X509 certificate with the specified servername and serial. This
1168 * function returns a SSL_CTX object or NULL if an error occurs. */
Christopher Faulet7969a332015-10-09 11:15:03 +02001169static SSL_CTX *
Christopher Faulet635c0ad2015-11-12 11:35:51 +01001170ssl_sock_do_create_cert(const char *servername, struct bind_conf *bind_conf, SSL *ssl)
Christopher Faulet31af49d2015-06-09 17:29:50 +02001171{
Christopher Faulet635c0ad2015-11-12 11:35:51 +01001172 static unsigned int serial = 0;
1173
Christopher Faulet7969a332015-10-09 11:15:03 +02001174 X509 *cacert = bind_conf->ca_sign_cert;
1175 EVP_PKEY *capkey = bind_conf->ca_sign_pkey;
Christopher Faulet31af49d2015-06-09 17:29:50 +02001176 SSL_CTX *ssl_ctx = NULL;
1177 X509 *newcrt = NULL;
1178 EVP_PKEY *pkey = NULL;
Christopher Faulet31af49d2015-06-09 17:29:50 +02001179 X509_NAME *name;
1180 const EVP_MD *digest;
1181 X509V3_CTX ctx;
1182 unsigned int i;
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02001183 int key_type;
Christopher Faulet31af49d2015-06-09 17:29:50 +02001184
Christopher Faulet7969a332015-10-09 11:15:03 +02001185 /* Get the private key of the defautl certificate and use it */
1186 if (!(pkey = SSL_get_privatekey(ssl)))
Christopher Faulet31af49d2015-06-09 17:29:50 +02001187 goto mkcert_error;
1188
1189 /* Create the certificate */
1190 if (!(newcrt = X509_new()))
1191 goto mkcert_error;
1192
1193 /* Set version number for the certificate (X509v3) and the serial
1194 * number */
1195 if (X509_set_version(newcrt, 2L) != 1)
1196 goto mkcert_error;
Christopher Faulet635c0ad2015-11-12 11:35:51 +01001197 if (!serial)
1198 serial = now_ms;
1199 ASN1_INTEGER_set(X509_get_serialNumber(newcrt), serial++);
Christopher Faulet31af49d2015-06-09 17:29:50 +02001200
1201 /* Set duration for the certificate */
1202 if (!X509_gmtime_adj(X509_get_notBefore(newcrt), (long)-60*60*24) ||
1203 !X509_gmtime_adj(X509_get_notAfter(newcrt),(long)60*60*24*365))
1204 goto mkcert_error;
1205
1206 /* set public key in the certificate */
1207 if (X509_set_pubkey(newcrt, pkey) != 1)
1208 goto mkcert_error;
1209
1210 /* Set issuer name from the CA */
1211 if (!(name = X509_get_subject_name(cacert)))
1212 goto mkcert_error;
1213 if (X509_set_issuer_name(newcrt, name) != 1)
1214 goto mkcert_error;
1215
1216 /* Set the subject name using the same, but the CN */
1217 name = X509_NAME_dup(name);
1218 if (X509_NAME_add_entry_by_txt(name, "CN", MBSTRING_ASC,
1219 (const unsigned char *)servername,
1220 -1, -1, 0) != 1) {
1221 X509_NAME_free(name);
1222 goto mkcert_error;
1223 }
1224 if (X509_set_subject_name(newcrt, name) != 1) {
1225 X509_NAME_free(name);
1226 goto mkcert_error;
1227 }
1228 X509_NAME_free(name);
1229
1230 /* Add x509v3 extensions as specified */
1231 X509V3_set_ctx(&ctx, cacert, newcrt, NULL, NULL, 0);
1232 for (i = 0; i < X509V3_EXT_SIZE; i++) {
1233 X509_EXTENSION *ext;
1234
1235 if (!(ext = X509V3_EXT_conf(NULL, &ctx, x509v3_ext_names[i], x509v3_ext_values[i])))
1236 goto mkcert_error;
1237 if (!X509_add_ext(newcrt, ext, -1)) {
1238 X509_EXTENSION_free(ext);
1239 goto mkcert_error;
1240 }
1241 X509_EXTENSION_free(ext);
1242 }
1243
1244 /* Sign the certificate with the CA private key */
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02001245
1246 key_type = EVP_PKEY_base_id(capkey);
1247
1248 if (key_type == EVP_PKEY_DSA)
1249 digest = EVP_sha1();
1250 else if (key_type == EVP_PKEY_RSA)
Christopher Faulet31af49d2015-06-09 17:29:50 +02001251 digest = EVP_sha256();
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02001252 else if (key_type == EVP_PKEY_EC)
Christopher Faulet7969a332015-10-09 11:15:03 +02001253 digest = EVP_sha256();
1254 else {
Christopher Faulete7db2162015-10-19 13:59:24 +02001255#if (OPENSSL_VERSION_NUMBER >= 0x1000000fL)
Christopher Faulet7969a332015-10-09 11:15:03 +02001256 int nid;
1257
1258 if (EVP_PKEY_get_default_digest_nid(capkey, &nid) <= 0)
1259 goto mkcert_error;
1260 if (!(digest = EVP_get_digestbynid(nid)))
1261 goto mkcert_error;
Christopher Faulete7db2162015-10-19 13:59:24 +02001262#else
1263 goto mkcert_error;
1264#endif
Christopher Faulet7969a332015-10-09 11:15:03 +02001265 }
1266
Christopher Faulet31af49d2015-06-09 17:29:50 +02001267 if (!(X509_sign(newcrt, capkey, digest)))
1268 goto mkcert_error;
1269
1270 /* Create and set the new SSL_CTX */
1271 if (!(ssl_ctx = SSL_CTX_new(SSLv23_server_method())))
1272 goto mkcert_error;
1273 if (!SSL_CTX_use_PrivateKey(ssl_ctx, pkey))
1274 goto mkcert_error;
1275 if (!SSL_CTX_use_certificate(ssl_ctx, newcrt))
1276 goto mkcert_error;
1277 if (!SSL_CTX_check_private_key(ssl_ctx))
1278 goto mkcert_error;
1279
1280 if (newcrt) X509_free(newcrt);
Christopher Faulet7969a332015-10-09 11:15:03 +02001281
Christopher Faulet85b5a1a2015-10-09 11:46:32 +02001282 SSL_CTX_set_tmp_dh_callback(ssl_ctx, ssl_get_tmp_dh);
1283#if defined(SSL_CTX_set_tmp_ecdh) && !defined(OPENSSL_NO_ECDH)
1284 {
1285 const char *ecdhe = (bind_conf->ecdhe ? bind_conf->ecdhe : ECDHE_DEFAULT_CURVE);
1286 EC_KEY *ecc;
1287 int nid;
1288
1289 if ((nid = OBJ_sn2nid(ecdhe)) == NID_undef)
1290 goto end;
1291 if (!(ecc = EC_KEY_new_by_curve_name(nid)))
1292 goto end;
1293 SSL_CTX_set_tmp_ecdh(ssl_ctx, ecc);
1294 EC_KEY_free(ecc);
1295 }
1296#endif
1297 end:
Christopher Faulet31af49d2015-06-09 17:29:50 +02001298 return ssl_ctx;
1299
1300 mkcert_error:
1301 if (ssl_ctx) SSL_CTX_free(ssl_ctx);
1302 if (newcrt) X509_free(newcrt);
Christopher Faulet31af49d2015-06-09 17:29:50 +02001303 return NULL;
1304}
1305
Christopher Faulet7969a332015-10-09 11:15:03 +02001306SSL_CTX *
Christopher Faulet635c0ad2015-11-12 11:35:51 +01001307ssl_sock_create_cert(struct connection *conn, const char *servername, unsigned int key)
Christopher Faulet7969a332015-10-09 11:15:03 +02001308{
1309 struct bind_conf *bind_conf = objt_listener(conn->target)->bind_conf;
Christopher Faulet635c0ad2015-11-12 11:35:51 +01001310
1311 return ssl_sock_do_create_cert(servername, bind_conf, conn->xprt_ctx);
Christopher Faulet7969a332015-10-09 11:15:03 +02001312}
1313
Christopher Faulet30548802015-06-11 13:39:32 +02001314/* Do a lookup for a certificate in the LRU cache used to store generated
1315 * certificates. */
1316SSL_CTX *
Christopher Faulet635c0ad2015-11-12 11:35:51 +01001317ssl_sock_get_generated_cert(unsigned int key, struct bind_conf *bind_conf)
Christopher Faulet30548802015-06-11 13:39:32 +02001318{
1319 struct lru64 *lru = NULL;
1320
1321 if (ssl_ctx_lru_tree) {
Christopher Faulet635c0ad2015-11-12 11:35:51 +01001322 lru = lru64_lookup(key, ssl_ctx_lru_tree, bind_conf->ca_sign_cert, 0);
Christopher Faulet30548802015-06-11 13:39:32 +02001323 if (lru && lru->domain)
1324 return (SSL_CTX *)lru->data;
1325 }
1326 return NULL;
1327}
1328
Christopher Fauletd2cab922015-07-28 16:03:47 +02001329/* Set a certificate int the LRU cache used to store generated
1330 * certificate. Return 0 on success, otherwise -1 */
1331int
Christopher Faulet635c0ad2015-11-12 11:35:51 +01001332ssl_sock_set_generated_cert(SSL_CTX *ssl_ctx, unsigned int key, struct bind_conf *bind_conf)
Christopher Faulet30548802015-06-11 13:39:32 +02001333{
1334 struct lru64 *lru = NULL;
1335
1336 if (ssl_ctx_lru_tree) {
Christopher Faulet635c0ad2015-11-12 11:35:51 +01001337 lru = lru64_get(key, ssl_ctx_lru_tree, bind_conf->ca_sign_cert, 0);
Christopher Faulet30548802015-06-11 13:39:32 +02001338 if (!lru)
Christopher Fauletd2cab922015-07-28 16:03:47 +02001339 return -1;
Christopher Faulet30548802015-06-11 13:39:32 +02001340 if (lru->domain && lru->data)
1341 lru->free((SSL_CTX *)lru->data);
Christopher Faulet7969a332015-10-09 11:15:03 +02001342 lru64_commit(lru, ssl_ctx, bind_conf->ca_sign_cert, 0, (void (*)(void *))SSL_CTX_free);
Christopher Fauletd2cab922015-07-28 16:03:47 +02001343 return 0;
Christopher Faulet30548802015-06-11 13:39:32 +02001344 }
Christopher Fauletd2cab922015-07-28 16:03:47 +02001345 return -1;
Christopher Faulet30548802015-06-11 13:39:32 +02001346}
1347
Christopher Faulet635c0ad2015-11-12 11:35:51 +01001348/* Compute the key of the certificate. */
Christopher Faulet30548802015-06-11 13:39:32 +02001349unsigned int
Christopher Faulet635c0ad2015-11-12 11:35:51 +01001350ssl_sock_generated_cert_key(const void *data, size_t len)
Christopher Faulet30548802015-06-11 13:39:32 +02001351{
1352 return XXH32(data, len, ssl_ctx_lru_seed);
1353}
1354
Willy Tarreau2f63ef42015-10-20 15:16:01 +02001355/* Generate a cert and immediately assign it to the SSL session so that the cert's
1356 * refcount is maintained regardless of the cert's presence in the LRU cache.
1357 */
Christopher Faulet31af49d2015-06-09 17:29:50 +02001358static SSL_CTX *
Christopher Faulet7969a332015-10-09 11:15:03 +02001359ssl_sock_generate_certificate(const char *servername, struct bind_conf *bind_conf, SSL *ssl)
Christopher Faulet31af49d2015-06-09 17:29:50 +02001360{
1361 X509 *cacert = bind_conf->ca_sign_cert;
Christopher Faulet31af49d2015-06-09 17:29:50 +02001362 SSL_CTX *ssl_ctx = NULL;
1363 struct lru64 *lru = NULL;
Christopher Faulet635c0ad2015-11-12 11:35:51 +01001364 unsigned int key;
Christopher Faulet31af49d2015-06-09 17:29:50 +02001365
Christopher Faulet635c0ad2015-11-12 11:35:51 +01001366 key = ssl_sock_generated_cert_key(servername, strlen(servername));
Christopher Faulet31af49d2015-06-09 17:29:50 +02001367 if (ssl_ctx_lru_tree) {
Christopher Faulet635c0ad2015-11-12 11:35:51 +01001368 lru = lru64_get(key, ssl_ctx_lru_tree, cacert, 0);
Christopher Faulet31af49d2015-06-09 17:29:50 +02001369 if (lru && lru->domain)
1370 ssl_ctx = (SSL_CTX *)lru->data;
Christopher Fauletd2cab922015-07-28 16:03:47 +02001371 if (!ssl_ctx && lru) {
Christopher Faulet635c0ad2015-11-12 11:35:51 +01001372 ssl_ctx = ssl_sock_do_create_cert(servername, bind_conf, ssl);
Christopher Faulet31af49d2015-06-09 17:29:50 +02001373 lru64_commit(lru, ssl_ctx, cacert, 0, (void (*)(void *))SSL_CTX_free);
Christopher Fauletd2cab922015-07-28 16:03:47 +02001374 }
Willy Tarreau2f63ef42015-10-20 15:16:01 +02001375 SSL_set_SSL_CTX(ssl, ssl_ctx);
Christopher Faulet31af49d2015-06-09 17:29:50 +02001376 }
Willy Tarreau2f63ef42015-10-20 15:16:01 +02001377 else {
Christopher Faulet635c0ad2015-11-12 11:35:51 +01001378 ssl_ctx = ssl_sock_do_create_cert(servername, bind_conf, ssl);
Willy Tarreau2f63ef42015-10-20 15:16:01 +02001379 SSL_set_SSL_CTX(ssl, ssl_ctx);
1380 /* No LRU cache, this CTX will be released as soon as the session dies */
1381 SSL_CTX_free(ssl_ctx);
1382 }
Christopher Faulet31af49d2015-06-09 17:29:50 +02001383 return ssl_ctx;
1384}
1385
Emeric Brunfc0421f2012-09-07 17:30:07 +02001386/* Sets the SSL ctx of <ssl> to match the advertised server name. Returns a
1387 * warning when no match is found, which implies the default (first) cert
1388 * will keep being used.
1389 */
Willy Tarreau2a65ff02012-09-13 17:54:29 +02001390static int ssl_sock_switchctx_cbk(SSL *ssl, int *al, struct bind_conf *s)
Emeric Brunfc0421f2012-09-07 17:30:07 +02001391{
1392 const char *servername;
1393 const char *wildp = NULL;
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +02001394 struct ebmb_node *node, *n;
Emeric Brunfc0421f2012-09-07 17:30:07 +02001395 int i;
1396 (void)al; /* shut gcc stupid warning */
1397
1398 servername = SSL_get_servername(ssl, TLSEXT_NAMETYPE_host_name);
Emmanuel Hocdet65623372013-01-24 17:17:15 +01001399 if (!servername) {
Willy Tarreauf6721452015-07-07 18:04:38 +02001400 if (s->generate_certs) {
Vincent Bernat3c2f2f22016-04-03 13:48:42 +02001401 struct connection *conn = SSL_get_app_data(ssl);
Christopher Faulet635c0ad2015-11-12 11:35:51 +01001402 unsigned int key;
Willy Tarreauf6721452015-07-07 18:04:38 +02001403 SSL_CTX *ctx;
Christopher Faulet30548802015-06-11 13:39:32 +02001404
Willy Tarreauf6721452015-07-07 18:04:38 +02001405 conn_get_to_addr(conn);
1406 if (conn->flags & CO_FL_ADDR_TO_SET) {
Christopher Faulet635c0ad2015-11-12 11:35:51 +01001407 key = ssl_sock_generated_cert_key(&conn->addr.to, get_addr_len(&conn->addr.to));
1408 ctx = ssl_sock_get_generated_cert(key, s);
Willy Tarreauf6721452015-07-07 18:04:38 +02001409 if (ctx) {
1410 /* switch ctx */
1411 SSL_set_SSL_CTX(ssl, ctx);
1412 return SSL_TLSEXT_ERR_OK;
1413 }
Christopher Faulet30548802015-06-11 13:39:32 +02001414 }
1415 }
1416
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +02001417 return (s->strict_sni ?
1418 SSL_TLSEXT_ERR_ALERT_FATAL :
Emmanuel Hocdet79274e22013-05-31 12:47:44 +02001419 SSL_TLSEXT_ERR_NOACK);
Emmanuel Hocdet65623372013-01-24 17:17:15 +01001420 }
Emeric Brunfc0421f2012-09-07 17:30:07 +02001421
Willy Tarreau19d14ef2012-10-29 16:51:55 +01001422 for (i = 0; i < trash.size; i++) {
Emeric Brunfc0421f2012-09-07 17:30:07 +02001423 if (!servername[i])
1424 break;
Willy Tarreau19d14ef2012-10-29 16:51:55 +01001425 trash.str[i] = tolower(servername[i]);
1426 if (!wildp && (trash.str[i] == '.'))
1427 wildp = &trash.str[i];
Emeric Brunfc0421f2012-09-07 17:30:07 +02001428 }
Willy Tarreau19d14ef2012-10-29 16:51:55 +01001429 trash.str[i] = 0;
Emeric Brunfc0421f2012-09-07 17:30:07 +02001430
1431 /* lookup in full qualified names */
Willy Tarreau19d14ef2012-10-29 16:51:55 +01001432 node = ebst_lookup(&s->sni_ctx, trash.str);
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +02001433
1434 /* lookup a not neg filter */
1435 for (n = node; n; n = ebmb_next_dup(n)) {
1436 if (!container_of(n, struct sni_ctx, name)->neg) {
1437 node = n;
1438 break;
Emmanuel Hocdet65623372013-01-24 17:17:15 +01001439 }
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +02001440 }
1441 if (!node && wildp) {
1442 /* lookup in wildcards names */
Emeric Brunfc0421f2012-09-07 17:30:07 +02001443 node = ebst_lookup(&s->sni_w_ctx, wildp);
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +02001444 }
1445 if (!node || container_of(node, struct sni_ctx, name)->neg) {
Christopher Faulet31af49d2015-06-09 17:29:50 +02001446 SSL_CTX *ctx;
Christopher Faulet31af49d2015-06-09 17:29:50 +02001447 if (s->generate_certs &&
Christopher Faulet7969a332015-10-09 11:15:03 +02001448 (ctx = ssl_sock_generate_certificate(servername, s, ssl))) {
Christopher Faulet31af49d2015-06-09 17:29:50 +02001449 /* switch ctx */
Christopher Faulet31af49d2015-06-09 17:29:50 +02001450 return SSL_TLSEXT_ERR_OK;
1451 }
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +02001452 return (s->strict_sni ?
1453 SSL_TLSEXT_ERR_ALERT_FATAL :
1454 SSL_TLSEXT_ERR_ALERT_WARNING);
Emeric Brunfc0421f2012-09-07 17:30:07 +02001455 }
1456
1457 /* switch ctx */
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +02001458 SSL_set_SSL_CTX(ssl, container_of(node, struct sni_ctx, name)->ctx);
Emeric Brunfc0421f2012-09-07 17:30:07 +02001459 return SSL_TLSEXT_ERR_OK;
1460}
1461#endif /* SSL_CTRL_SET_TLSEXT_HOSTNAME */
1462
Emeric Bruna4bcd9a2012-09-20 16:19:02 +02001463#ifndef OPENSSL_NO_DH
Remi Gacognef46cd6e2014-06-12 14:58:40 +02001464
1465static DH * ssl_get_dh_1024(void)
1466{
Remi Gacogned3a341a2015-05-29 16:26:17 +02001467 static unsigned char dh1024_p[]={
1468 0xFA,0xF9,0x2A,0x22,0x2A,0xA7,0x7F,0xE1,0x67,0x4E,0x53,0xF7,
1469 0x56,0x13,0xC3,0xB1,0xE3,0x29,0x6B,0x66,0x31,0x6A,0x7F,0xB3,
1470 0xC2,0x68,0x6B,0xCB,0x1D,0x57,0x39,0x1D,0x1F,0xFF,0x1C,0xC9,
1471 0xA6,0xA4,0x98,0x82,0x31,0x5D,0x25,0xFF,0x8A,0xE0,0x73,0x96,
1472 0x81,0xC8,0x83,0x79,0xC1,0x5A,0x04,0xF8,0x37,0x0D,0xA8,0x3D,
1473 0xAE,0x74,0xBC,0xDB,0xB6,0xA4,0x75,0xD9,0x71,0x8A,0xA0,0x17,
1474 0x9E,0x2D,0xC8,0xA8,0xDF,0x2C,0x5F,0x82,0x95,0xF8,0x92,0x9B,
1475 0xA7,0x33,0x5F,0x89,0x71,0xC8,0x2D,0x6B,0x18,0x86,0xC4,0x94,
1476 0x22,0xA5,0x52,0x8D,0xF6,0xF6,0xD2,0x37,0x92,0x0F,0xA5,0xCC,
1477 0xDB,0x7B,0x1D,0x3D,0xA1,0x31,0xB7,0x80,0x8F,0x0B,0x67,0x5E,
1478 0x36,0xA5,0x60,0x0C,0xF1,0x95,0x33,0x8B,
1479 };
1480 static unsigned char dh1024_g[]={
1481 0x02,
1482 };
1483
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02001484 BIGNUM *p;
1485 BIGNUM *g;
Remi Gacognef46cd6e2014-06-12 14:58:40 +02001486 DH *dh = DH_new();
1487 if (dh) {
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02001488 p = BN_bin2bn(dh1024_p, sizeof dh1024_p, NULL);
1489 g = BN_bin2bn(dh1024_g, sizeof dh1024_g, NULL);
Remi Gacogned3a341a2015-05-29 16:26:17 +02001490
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02001491 if (!p || !g) {
Remi Gacognef46cd6e2014-06-12 14:58:40 +02001492 DH_free(dh);
1493 dh = NULL;
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02001494 } else {
1495 DH_set0_pqg(dh, p, NULL, g);
Remi Gacognef46cd6e2014-06-12 14:58:40 +02001496 }
1497 }
1498 return dh;
1499}
1500
1501static DH *ssl_get_dh_2048(void)
1502{
Remi Gacogned3a341a2015-05-29 16:26:17 +02001503 static unsigned char dh2048_p[]={
1504 0xEC,0x86,0xF8,0x70,0xA0,0x33,0x16,0xEC,0x05,0x1A,0x73,0x59,
1505 0xCD,0x1F,0x8B,0xF8,0x29,0xE4,0xD2,0xCF,0x52,0xDD,0xC2,0x24,
1506 0x8D,0xB5,0x38,0x9A,0xFB,0x5C,0xA4,0xE4,0xB2,0xDA,0xCE,0x66,
1507 0x50,0x74,0xA6,0x85,0x4D,0x4B,0x1D,0x30,0xB8,0x2B,0xF3,0x10,
1508 0xE9,0xA7,0x2D,0x05,0x71,0xE7,0x81,0xDF,0x8B,0x59,0x52,0x3B,
1509 0x5F,0x43,0x0B,0x68,0xF1,0xDB,0x07,0xBE,0x08,0x6B,0x1B,0x23,
1510 0xEE,0x4D,0xCC,0x9E,0x0E,0x43,0xA0,0x1E,0xDF,0x43,0x8C,0xEC,
1511 0xBE,0xBE,0x90,0xB4,0x51,0x54,0xB9,0x2F,0x7B,0x64,0x76,0x4E,
1512 0x5D,0xD4,0x2E,0xAE,0xC2,0x9E,0xAE,0x51,0x43,0x59,0xC7,0x77,
1513 0x9C,0x50,0x3C,0x0E,0xED,0x73,0x04,0x5F,0xF1,0x4C,0x76,0x2A,
1514 0xD8,0xF8,0xCF,0xFC,0x34,0x40,0xD1,0xB4,0x42,0x61,0x84,0x66,
1515 0x42,0x39,0x04,0xF8,0x68,0xB2,0x62,0xD7,0x55,0xED,0x1B,0x74,
1516 0x75,0x91,0xE0,0xC5,0x69,0xC1,0x31,0x5C,0xDB,0x7B,0x44,0x2E,
1517 0xCE,0x84,0x58,0x0D,0x1E,0x66,0x0C,0xC8,0x44,0x9E,0xFD,0x40,
1518 0x08,0x67,0x5D,0xFB,0xA7,0x76,0x8F,0x00,0x11,0x87,0xE9,0x93,
1519 0xF9,0x7D,0xC4,0xBC,0x74,0x55,0x20,0xD4,0x4A,0x41,0x2F,0x43,
1520 0x42,0x1A,0xC1,0xF2,0x97,0x17,0x49,0x27,0x37,0x6B,0x2F,0x88,
1521 0x7E,0x1C,0xA0,0xA1,0x89,0x92,0x27,0xD9,0x56,0x5A,0x71,0xC1,
1522 0x56,0x37,0x7E,0x3A,0x9D,0x05,0xE7,0xEE,0x5D,0x8F,0x82,0x17,
1523 0xBC,0xE9,0xC2,0x93,0x30,0x82,0xF9,0xF4,0xC9,0xAE,0x49,0xDB,
1524 0xD0,0x54,0xB4,0xD9,0x75,0x4D,0xFA,0x06,0xB8,0xD6,0x38,0x41,
1525 0xB7,0x1F,0x77,0xF3,
1526 };
1527 static unsigned char dh2048_g[]={
1528 0x02,
1529 };
1530
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02001531 BIGNUM *p;
1532 BIGNUM *g;
Remi Gacognef46cd6e2014-06-12 14:58:40 +02001533 DH *dh = DH_new();
1534 if (dh) {
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02001535 p = BN_bin2bn(dh2048_p, sizeof dh2048_p, NULL);
1536 g = BN_bin2bn(dh2048_g, sizeof dh2048_g, NULL);
Remi Gacogned3a341a2015-05-29 16:26:17 +02001537
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02001538 if (!p || !g) {
Remi Gacognef46cd6e2014-06-12 14:58:40 +02001539 DH_free(dh);
1540 dh = NULL;
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02001541 } else {
1542 DH_set0_pqg(dh, p, NULL, g);
Remi Gacognef46cd6e2014-06-12 14:58:40 +02001543 }
1544 }
1545 return dh;
1546}
1547
1548static DH *ssl_get_dh_4096(void)
1549{
Remi Gacogned3a341a2015-05-29 16:26:17 +02001550 static unsigned char dh4096_p[]={
1551 0xDE,0x16,0x94,0xCD,0x99,0x58,0x07,0xF1,0xF7,0x32,0x96,0x11,
1552 0x04,0x82,0xD4,0x84,0x72,0x80,0x99,0x06,0xCA,0xF0,0xA3,0x68,
1553 0x07,0xCE,0x64,0x50,0xE7,0x74,0x45,0x20,0x80,0x5E,0x4D,0xAD,
1554 0xA5,0xB6,0xED,0xFA,0x80,0x6C,0x3B,0x35,0xC4,0x9A,0x14,0x6B,
1555 0x32,0xBB,0xFD,0x1F,0x17,0x8E,0xB7,0x1F,0xD6,0xFA,0x3F,0x7B,
1556 0xEE,0x16,0xA5,0x62,0x33,0x0D,0xED,0xBC,0x4E,0x58,0xE5,0x47,
1557 0x4D,0xE9,0xAB,0x8E,0x38,0xD3,0x6E,0x90,0x57,0xE3,0x22,0x15,
1558 0x33,0xBD,0xF6,0x43,0x45,0xB5,0x10,0x0A,0xBE,0x2C,0xB4,0x35,
1559 0xB8,0x53,0x8D,0xAD,0xFB,0xA7,0x1F,0x85,0x58,0x41,0x7A,0x79,
1560 0x20,0x68,0xB3,0xE1,0x3D,0x08,0x76,0xBF,0x86,0x0D,0x49,0xE3,
1561 0x82,0x71,0x8C,0xB4,0x8D,0x81,0x84,0xD4,0xE7,0xBE,0x91,0xDC,
1562 0x26,0x39,0x48,0x0F,0x35,0xC4,0xCA,0x65,0xE3,0x40,0x93,0x52,
1563 0x76,0x58,0x7D,0xDD,0x51,0x75,0xDC,0x69,0x61,0xBF,0x47,0x2C,
1564 0x16,0x68,0x2D,0xC9,0x29,0xD3,0xE6,0xC0,0x99,0x48,0xA0,0x9A,
1565 0xC8,0x78,0xC0,0x6D,0x81,0x67,0x12,0x61,0x3F,0x71,0xBA,0x41,
1566 0x1F,0x6C,0x89,0x44,0x03,0xBA,0x3B,0x39,0x60,0xAA,0x28,0x55,
1567 0x59,0xAE,0xB8,0xFA,0xCB,0x6F,0xA5,0x1A,0xF7,0x2B,0xDD,0x52,
1568 0x8A,0x8B,0xE2,0x71,0xA6,0x5E,0x7E,0xD8,0x2E,0x18,0xE0,0x66,
1569 0xDF,0xDD,0x22,0x21,0x99,0x52,0x73,0xA6,0x33,0x20,0x65,0x0E,
1570 0x53,0xE7,0x6B,0x9B,0xC5,0xA3,0x2F,0x97,0x65,0x76,0xD3,0x47,
1571 0x23,0x77,0x12,0xB6,0x11,0x7B,0x24,0xED,0xF1,0xEF,0xC0,0xE2,
1572 0xA3,0x7E,0x67,0x05,0x3E,0x96,0x4D,0x45,0xC2,0x18,0xD1,0x73,
1573 0x9E,0x07,0xF3,0x81,0x6E,0x52,0x63,0xF6,0x20,0x76,0xB9,0x13,
1574 0xD2,0x65,0x30,0x18,0x16,0x09,0x16,0x9E,0x8F,0xF1,0xD2,0x10,
1575 0x5A,0xD3,0xD4,0xAF,0x16,0x61,0xDA,0x55,0x2E,0x18,0x5E,0x14,
1576 0x08,0x54,0x2E,0x2A,0x25,0xA2,0x1A,0x9B,0x8B,0x32,0xA9,0xFD,
1577 0xC2,0x48,0x96,0xE1,0x80,0xCA,0xE9,0x22,0x17,0xBB,0xCE,0x3E,
1578 0x9E,0xED,0xC7,0xF1,0x1F,0xEC,0x17,0x21,0xDC,0x7B,0x82,0x48,
1579 0x8E,0xBB,0x4B,0x9D,0x5B,0x04,0x04,0xDA,0xDB,0x39,0xDF,0x01,
1580 0x40,0xC3,0xAA,0x26,0x23,0x89,0x75,0xC6,0x0B,0xD0,0xA2,0x60,
1581 0x6A,0xF1,0xCC,0x65,0x18,0x98,0x1B,0x52,0xD2,0x74,0x61,0xCC,
1582 0xBD,0x60,0xAE,0xA3,0xA0,0x66,0x6A,0x16,0x34,0x92,0x3F,0x41,
1583 0x40,0x31,0x29,0xC0,0x2C,0x63,0xB2,0x07,0x8D,0xEB,0x94,0xB8,
1584 0xE8,0x47,0x92,0x52,0x93,0x6A,0x1B,0x7E,0x1A,0x61,0xB3,0x1B,
1585 0xF0,0xD6,0x72,0x9B,0xF1,0xB0,0xAF,0xBF,0x3E,0x65,0xEF,0x23,
1586 0x1D,0x6F,0xFF,0x70,0xCD,0x8A,0x4C,0x8A,0xA0,0x72,0x9D,0xBE,
1587 0xD4,0xBB,0x24,0x47,0x4A,0x68,0xB5,0xF5,0xC6,0xD5,0x7A,0xCD,
1588 0xCA,0x06,0x41,0x07,0xAD,0xC2,0x1E,0xE6,0x54,0xA7,0xAD,0x03,
1589 0xD9,0x12,0xC1,0x9C,0x13,0xB1,0xC9,0x0A,0x43,0x8E,0x1E,0x08,
1590 0xCE,0x50,0x82,0x73,0x5F,0xA7,0x55,0x1D,0xD9,0x59,0xAC,0xB5,
1591 0xEA,0x02,0x7F,0x6C,0x5B,0x74,0x96,0x98,0x67,0x24,0xA3,0x0F,
1592 0x15,0xFC,0xA9,0x7D,0x3E,0x67,0xD1,0x70,0xF8,0x97,0xF3,0x67,
1593 0xC5,0x8C,0x88,0x44,0x08,0x02,0xC7,0x2B,
Remi Gacognef46cd6e2014-06-12 14:58:40 +02001594 };
Remi Gacogned3a341a2015-05-29 16:26:17 +02001595 static unsigned char dh4096_g[]={
1596 0x02,
1597 };
Remi Gacognef46cd6e2014-06-12 14:58:40 +02001598
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02001599 BIGNUM *p;
1600 BIGNUM *g;
Remi Gacognef46cd6e2014-06-12 14:58:40 +02001601 DH *dh = DH_new();
1602 if (dh) {
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02001603 p = BN_bin2bn(dh4096_p, sizeof dh4096_p, NULL);
1604 g = BN_bin2bn(dh4096_g, sizeof dh4096_g, NULL);
Remi Gacogned3a341a2015-05-29 16:26:17 +02001605
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02001606 if (!p || !g) {
Remi Gacognef46cd6e2014-06-12 14:58:40 +02001607 DH_free(dh);
1608 dh = NULL;
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02001609 } else {
1610 DH_set0_pqg(dh, p, NULL, g);
Remi Gacognef46cd6e2014-06-12 14:58:40 +02001611 }
1612 }
1613 return dh;
1614}
1615
1616/* Returns Diffie-Hellman parameters matching the private key length
1617 but not exceeding global.tune.ssl_default_dh_param */
1618static DH *ssl_get_tmp_dh(SSL *ssl, int export, int keylen)
1619{
1620 DH *dh = NULL;
1621 EVP_PKEY *pkey = SSL_get_privatekey(ssl);
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02001622 int type;
1623
1624 type = pkey ? EVP_PKEY_base_id(pkey) : EVP_PKEY_NONE;
Remi Gacognef46cd6e2014-06-12 14:58:40 +02001625
1626 /* The keylen supplied by OpenSSL can only be 512 or 1024.
1627 See ssl3_send_server_key_exchange() in ssl/s3_srvr.c
1628 */
1629 if (type == EVP_PKEY_RSA || type == EVP_PKEY_DSA) {
1630 keylen = EVP_PKEY_bits(pkey);
1631 }
1632
1633 if (keylen > global.tune.ssl_default_dh_param) {
1634 keylen = global.tune.ssl_default_dh_param;
1635 }
1636
Remi Gacogned3a341a2015-05-29 16:26:17 +02001637 if (keylen >= 4096) {
Remi Gacogne8de54152014-07-15 11:36:40 +02001638 dh = local_dh_4096;
Remi Gacognef46cd6e2014-06-12 14:58:40 +02001639 }
1640 else if (keylen >= 2048) {
Remi Gacogne8de54152014-07-15 11:36:40 +02001641 dh = local_dh_2048;
Remi Gacognef46cd6e2014-06-12 14:58:40 +02001642 }
1643 else {
Remi Gacogne8de54152014-07-15 11:36:40 +02001644 dh = local_dh_1024;
Remi Gacognef46cd6e2014-06-12 14:58:40 +02001645 }
1646
1647 return dh;
1648}
1649
Remi Gacogne47783ef2015-05-29 15:53:22 +02001650static DH * ssl_sock_get_dh_from_file(const char *filename)
Emeric Bruna4bcd9a2012-09-20 16:19:02 +02001651{
Emeric Bruna4bcd9a2012-09-20 16:19:02 +02001652 DH *dh = NULL;
Remi Gacogne47783ef2015-05-29 15:53:22 +02001653 BIO *in = BIO_new(BIO_s_file());
Emeric Bruna4bcd9a2012-09-20 16:19:02 +02001654
Emeric Bruna4bcd9a2012-09-20 16:19:02 +02001655 if (in == NULL)
1656 goto end;
1657
Remi Gacogne47783ef2015-05-29 15:53:22 +02001658 if (BIO_read_filename(in, filename) <= 0)
Emeric Bruna4bcd9a2012-09-20 16:19:02 +02001659 goto end;
1660
Remi Gacogne47783ef2015-05-29 15:53:22 +02001661 dh = PEM_read_bio_DHparams(in, NULL, NULL, NULL);
1662
1663end:
1664 if (in)
1665 BIO_free(in);
1666
1667 return dh;
1668}
1669
1670int ssl_sock_load_global_dh_param_from_file(const char *filename)
1671{
1672 global_dh = ssl_sock_get_dh_from_file(filename);
1673
1674 if (global_dh) {
1675 return 0;
1676 }
1677
1678 return -1;
1679}
1680
1681/* Loads Diffie-Hellman parameter from a file. Returns 1 if loaded, else -1
1682 if an error occured, and 0 if parameter not found. */
1683int ssl_sock_load_dh_params(SSL_CTX *ctx, const char *file)
1684{
1685 int ret = -1;
1686 DH *dh = ssl_sock_get_dh_from_file(file);
1687
Remi Gacognef46cd6e2014-06-12 14:58:40 +02001688 if (dh) {
1689 ret = 1;
1690 SSL_CTX_set_tmp_dh(ctx, dh);
Remi Gacogne4f902b82015-05-28 16:23:00 +02001691
1692 if (ssl_dh_ptr_index >= 0) {
1693 /* store a pointer to the DH params to avoid complaining about
1694 ssl-default-dh-param not being set for this SSL_CTX */
1695 SSL_CTX_set_ex_data(ctx, ssl_dh_ptr_index, dh);
1696 }
Remi Gacognef46cd6e2014-06-12 14:58:40 +02001697 }
Remi Gacogne47783ef2015-05-29 15:53:22 +02001698 else if (global_dh) {
1699 SSL_CTX_set_tmp_dh(ctx, global_dh);
1700 ret = 0; /* DH params not found */
1701 }
Remi Gacognef46cd6e2014-06-12 14:58:40 +02001702 else {
Emeric Brun41fdb3c2013-04-26 11:05:44 +02001703 /* Clear openssl global errors stack */
1704 ERR_clear_error();
1705
Remi Gacognef46cd6e2014-06-12 14:58:40 +02001706 if (global.tune.ssl_default_dh_param <= 1024) {
1707 /* we are limited to DH parameter of 1024 bits anyway */
Remi Gacognec7e12632016-07-02 16:26:10 +02001708 if (local_dh_1024 == NULL)
1709 local_dh_1024 = ssl_get_dh_1024();
1710
Remi Gacogne8de54152014-07-15 11:36:40 +02001711 if (local_dh_1024 == NULL)
Remi Gacognef46cd6e2014-06-12 14:58:40 +02001712 goto end;
Willy Tarreau6e774b42014-04-25 21:35:23 +02001713
Remi Gacogne8de54152014-07-15 11:36:40 +02001714 SSL_CTX_set_tmp_dh(ctx, local_dh_1024);
Remi Gacognef46cd6e2014-06-12 14:58:40 +02001715 }
1716 else {
1717 SSL_CTX_set_tmp_dh_callback(ctx, ssl_get_tmp_dh);
1718 }
Willy Tarreau6e774b42014-04-25 21:35:23 +02001719
Emeric Brun41fdb3c2013-04-26 11:05:44 +02001720 ret = 0; /* DH params not found */
Emeric Bruna4bcd9a2012-09-20 16:19:02 +02001721 }
Emeric Brun644cde02012-12-14 11:21:13 +01001722
Emeric Bruna4bcd9a2012-09-20 16:19:02 +02001723end:
1724 if (dh)
1725 DH_free(dh);
1726
Emeric Bruna4bcd9a2012-09-20 16:19:02 +02001727 return ret;
1728}
1729#endif
1730
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +02001731static int ssl_sock_add_cert_sni(SSL_CTX *ctx, struct bind_conf *s, char *name, int order)
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01001732{
1733 struct sni_ctx *sc;
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +02001734 int wild = 0, neg = 0;
Thierry FOURNIER / OZON.IO07c3d782016-10-06 10:56:48 +02001735 struct ebmb_node *node;
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01001736
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +02001737 if (*name == '!') {
1738 neg = 1;
1739 name++;
1740 }
1741 if (*name == '*') {
1742 wild = 1;
1743 name++;
1744 }
1745 /* !* filter is a nop */
1746 if (neg && wild)
1747 return order;
1748 if (*name) {
1749 int j, len;
1750 len = strlen(name);
Thierry FOURNIER / OZON.IO07c3d782016-10-06 10:56:48 +02001751 for (j = 0; j < len && j < trash.size; j++)
1752 trash.str[j] = tolower(name[j]);
1753 if (j >= trash.size)
1754 return order;
1755 trash.str[j] = 0;
1756
1757 /* Check for duplicates. */
1758 if (wild)
1759 node = ebst_lookup(&s->sni_w_ctx, trash.str);
1760 else
1761 node = ebst_lookup(&s->sni_ctx, trash.str);
1762 for (; node; node = ebmb_next_dup(node)) {
1763 sc = ebmb_entry(node, struct sni_ctx, name);
1764 if (sc->ctx == ctx && sc->neg == neg)
1765 return order;
1766 }
1767
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01001768 sc = malloc(sizeof(struct sni_ctx) + len + 1);
Thierry FOURNIER / OZON.IO7a3bd3b2016-10-06 10:35:29 +02001769 if (!sc)
1770 return order;
Thierry FOURNIER / OZON.IO07c3d782016-10-06 10:56:48 +02001771 memcpy(sc->name.key, trash.str, len + 1);
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01001772 sc->ctx = ctx;
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +02001773 sc->order = order++;
1774 sc->neg = neg;
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01001775 if (wild)
1776 ebst_insert(&s->sni_w_ctx, &sc->name);
1777 else
1778 ebst_insert(&s->sni_ctx, &sc->name);
1779 }
1780 return order;
1781}
1782
yanbzhu488a4d22015-12-01 15:16:07 -05001783
1784/* The following code is used for loading multiple crt files into
1785 * SSL_CTX's based on CN/SAN
1786 */
1787#if OPENSSL_VERSION_NUMBER >= 0x1000200fL
1788/* This is used to preload the certifcate, private key
1789 * and Cert Chain of a file passed in via the crt
1790 * argument
1791 *
1792 * This way, we do not have to read the file multiple times
1793 */
1794struct cert_key_and_chain {
1795 X509 *cert;
1796 EVP_PKEY *key;
1797 unsigned int num_chain_certs;
1798 /* This is an array of X509 pointers */
1799 X509 **chain_certs;
1800};
1801
yanbzhu08ce6ab2015-12-02 13:01:29 -05001802#define SSL_SOCK_POSSIBLE_KT_COMBOS (1<<(SSL_SOCK_NUM_KEYTYPES))
1803
1804struct key_combo_ctx {
1805 SSL_CTX *ctx;
1806 int order;
1807};
1808
1809/* Map used for processing multiple keypairs for a single purpose
1810 *
1811 * This maps CN/SNI name to certificate type
1812 */
1813struct sni_keytype {
1814 int keytypes; /* BITMASK for keytypes */
1815 struct ebmb_node name; /* node holding the servername value */
1816};
1817
1818
yanbzhu488a4d22015-12-01 15:16:07 -05001819/* Frees the contents of a cert_key_and_chain
1820 */
1821static void ssl_sock_free_cert_key_and_chain_contents(struct cert_key_and_chain *ckch)
1822{
1823 int i;
1824
1825 if (!ckch)
1826 return;
1827
1828 /* Free the certificate and set pointer to NULL */
1829 if (ckch->cert)
1830 X509_free(ckch->cert);
1831 ckch->cert = NULL;
1832
1833 /* Free the key and set pointer to NULL */
1834 if (ckch->key)
1835 EVP_PKEY_free(ckch->key);
1836 ckch->key = NULL;
1837
1838 /* Free each certificate in the chain */
1839 for (i = 0; i < ckch->num_chain_certs; i++) {
1840 if (ckch->chain_certs[i])
1841 X509_free(ckch->chain_certs[i]);
1842 }
1843
1844 /* Free the chain obj itself and set to NULL */
1845 if (ckch->num_chain_certs > 0) {
1846 free(ckch->chain_certs);
1847 ckch->num_chain_certs = 0;
1848 ckch->chain_certs = NULL;
1849 }
1850
1851}
1852
1853/* checks if a key and cert exists in the ckch
1854 */
1855static int ssl_sock_is_ckch_valid(struct cert_key_and_chain *ckch)
1856{
1857 return (ckch->cert != NULL && ckch->key != NULL);
1858}
1859
1860
1861/* Loads the contents of a crt file (path) into a cert_key_and_chain
1862 * This allows us to carry the contents of the file without having to
1863 * read the file multiple times.
1864 *
1865 * returns:
1866 * 0 on Success
1867 * 1 on SSL Failure
1868 * 2 on file not found
1869 */
1870static int ssl_sock_load_crt_file_into_ckch(const char *path, struct cert_key_and_chain *ckch, char **err)
1871{
1872
1873 BIO *in;
1874 X509 *ca = NULL;
1875 int ret = 1;
1876
1877 ssl_sock_free_cert_key_and_chain_contents(ckch);
1878
1879 in = BIO_new(BIO_s_file());
1880 if (in == NULL)
1881 goto end;
1882
1883 if (BIO_read_filename(in, path) <= 0)
1884 goto end;
1885
yanbzhu488a4d22015-12-01 15:16:07 -05001886 /* Read Private Key */
1887 ckch->key = PEM_read_bio_PrivateKey(in, NULL, NULL, NULL);
1888 if (ckch->key == NULL) {
1889 memprintf(err, "%sunable to load private key from file '%s'.\n",
1890 err && *err ? *err : "", path);
1891 goto end;
1892 }
1893
Willy Tarreaubb137a82016-04-06 19:02:38 +02001894 /* Seek back to beginning of file */
Thierry FOURNIER / OZON.IOd44ea3f2016-10-14 00:49:21 +02001895 if (BIO_reset(in) == -1) {
1896 memprintf(err, "%san error occurred while reading the file '%s'.\n",
1897 err && *err ? *err : "", path);
1898 goto end;
1899 }
Willy Tarreaubb137a82016-04-06 19:02:38 +02001900
1901 /* Read Certificate */
1902 ckch->cert = PEM_read_bio_X509_AUX(in, NULL, NULL, NULL);
1903 if (ckch->cert == NULL) {
1904 memprintf(err, "%sunable to load certificate from file '%s'.\n",
1905 err && *err ? *err : "", path);
1906 goto end;
1907 }
1908
yanbzhu488a4d22015-12-01 15:16:07 -05001909 /* Read Certificate Chain */
1910 while ((ca = PEM_read_bio_X509(in, NULL, NULL, NULL))) {
1911 /* Grow the chain certs */
1912 ckch->num_chain_certs++;
1913 ckch->chain_certs = realloc(ckch->chain_certs, (ckch->num_chain_certs * sizeof(X509 *)));
1914
1915 /* use - 1 here since we just incremented it above */
1916 ckch->chain_certs[ckch->num_chain_certs - 1] = ca;
1917 }
1918 ret = ERR_get_error();
1919 if (ret && (ERR_GET_LIB(ret) != ERR_LIB_PEM && ERR_GET_REASON(ret) != PEM_R_NO_START_LINE)) {
1920 memprintf(err, "%sunable to load certificate chain from file '%s'.\n",
1921 err && *err ? *err : "", path);
1922 ret = 1;
1923 goto end;
1924 }
1925
1926 ret = 0;
1927
1928end:
1929
1930 ERR_clear_error();
1931 if (in)
1932 BIO_free(in);
1933
1934 /* Something went wrong in one of the reads */
1935 if (ret != 0)
1936 ssl_sock_free_cert_key_and_chain_contents(ckch);
1937
1938 return ret;
1939}
1940
1941/* Loads the info in ckch into ctx
1942 * Currently, this does not process any information about ocsp, dhparams or
1943 * sctl
1944 * Returns
1945 * 0 on success
1946 * 1 on failure
1947 */
1948static int ssl_sock_put_ckch_into_ctx(const char *path, const struct cert_key_and_chain *ckch, SSL_CTX *ctx, char **err)
1949{
1950 int i = 0;
1951
1952 if (SSL_CTX_use_PrivateKey(ctx, ckch->key) <= 0) {
1953 memprintf(err, "%sunable to load SSL private key into SSL Context '%s'.\n",
1954 err && *err ? *err : "", path);
1955 return 1;
1956 }
1957
1958 if (!SSL_CTX_use_certificate(ctx, ckch->cert)) {
1959 memprintf(err, "%sunable to load SSL certificate into SSL Context '%s'.\n",
1960 err && *err ? *err : "", path);
1961 return 1;
1962 }
1963
yanbzhu488a4d22015-12-01 15:16:07 -05001964 /* Load all certs in the ckch into the ctx_chain for the ssl_ctx */
1965 for (i = 0; i < ckch->num_chain_certs; i++) {
1966 if (!SSL_CTX_add1_chain_cert(ctx, ckch->chain_certs[i])) {
yanbzhu08ce6ab2015-12-02 13:01:29 -05001967 memprintf(err, "%sunable to load chain certificate #%d into SSL Context '%s'. Make sure you are linking against Openssl >= 1.0.2.\n",
1968 err && *err ? *err : "", (i+1), path);
yanbzhu488a4d22015-12-01 15:16:07 -05001969 return 1;
1970 }
1971 }
1972
1973 if (SSL_CTX_check_private_key(ctx) <= 0) {
1974 memprintf(err, "%sinconsistencies between private key and certificate loaded from PEM file '%s'.\n",
1975 err && *err ? *err : "", path);
1976 return 1;
1977 }
1978
1979 return 0;
1980}
1981
yanbzhu08ce6ab2015-12-02 13:01:29 -05001982
1983static void ssl_sock_populate_sni_keytypes_hplr(const char *str, struct eb_root *sni_keytypes, int key_index)
1984{
1985 struct sni_keytype *s_kt = NULL;
1986 struct ebmb_node *node;
1987 int i;
1988
1989 for (i = 0; i < trash.size; i++) {
1990 if (!str[i])
1991 break;
1992 trash.str[i] = tolower(str[i]);
1993 }
1994 trash.str[i] = 0;
1995 node = ebst_lookup(sni_keytypes, trash.str);
1996 if (!node) {
1997 /* CN not found in tree */
1998 s_kt = malloc(sizeof(struct sni_keytype) + i + 1);
1999 /* Using memcpy here instead of strncpy.
2000 * strncpy will cause sig_abrt errors under certain versions of gcc with -O2
2001 * See: https://gcc.gnu.org/bugzilla/show_bug.cgi?id=60792
2002 */
2003 memcpy(s_kt->name.key, trash.str, i+1);
2004 s_kt->keytypes = 0;
2005 ebst_insert(sni_keytypes, &s_kt->name);
2006 } else {
2007 /* CN found in tree */
2008 s_kt = container_of(node, struct sni_keytype, name);
2009 }
2010
2011 /* Mark that this CN has the keytype of key_index via keytypes mask */
2012 s_kt->keytypes |= 1<<key_index;
2013
2014}
2015
2016
2017/* Given a path that does not exist, try to check for path.rsa, path.dsa and path.ecdsa files.
2018 * If any are found, group these files into a set of SSL_CTX*
2019 * based on shared and unique CN and SAN entries. Add these SSL_CTX* to the SNI tree.
2020 *
2021 * This will allow the user to explictly group multiple cert/keys for a single purpose
2022 *
2023 * Returns
2024 * 0 on success
2025 * 1 on failure
2026 */
Emmanuel Hocdetd294aea2016-05-13 11:14:06 +02002027static 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 -05002028{
2029 char fp[MAXPATHLEN+1] = {0};
2030 int n = 0;
2031 int i = 0;
2032 struct cert_key_and_chain certs_and_keys[SSL_SOCK_NUM_KEYTYPES] = { {0} };
2033 struct eb_root sni_keytypes_map = { {0} };
2034 struct ebmb_node *node;
2035 struct ebmb_node *next;
2036 /* Array of SSL_CTX pointers corresponding to each possible combo
2037 * of keytypes
2038 */
2039 struct key_combo_ctx key_combos[SSL_SOCK_POSSIBLE_KT_COMBOS] = { {0} };
2040 int rv = 0;
2041 X509_NAME *xname = NULL;
2042 char *str = NULL;
2043#ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME
2044 STACK_OF(GENERAL_NAME) *names = NULL;
2045#endif
2046
2047 /* Load all possible certs and keys */
2048 for (n = 0; n < SSL_SOCK_NUM_KEYTYPES; n++) {
2049 struct stat buf;
2050
2051 snprintf(fp, sizeof(fp), "%s.%s", path, SSL_SOCK_KEYTYPE_NAMES[n]);
2052 if (stat(fp, &buf) == 0) {
2053 if (ssl_sock_load_crt_file_into_ckch(fp, &certs_and_keys[n], err) == 1) {
2054 rv = 1;
2055 goto end;
2056 }
2057 }
2058 }
2059
2060 /* Process each ckch and update keytypes for each CN/SAN
2061 * for example, if CN/SAN www.a.com is associated with
2062 * certs with keytype 0 and 2, then at the end of the loop,
2063 * www.a.com will have:
2064 * keyindex = 0 | 1 | 4 = 5
2065 */
2066 for (n = 0; n < SSL_SOCK_NUM_KEYTYPES; n++) {
2067
2068 if (!ssl_sock_is_ckch_valid(&certs_and_keys[n]))
2069 continue;
2070
Emmanuel Hocdetd294aea2016-05-13 11:14:06 +02002071 if (fcount) {
Willy Tarreau24b892f2016-06-20 23:01:57 +02002072 for (i = 0; i < fcount; i++)
Emmanuel Hocdetd294aea2016-05-13 11:14:06 +02002073 ssl_sock_populate_sni_keytypes_hplr(sni_filter[i], &sni_keytypes_map, n);
2074 } else {
2075 /* A lot of the following code is OpenSSL boilerplate for processing CN's and SAN's,
2076 * so the line that contains logic is marked via comments
2077 */
2078 xname = X509_get_subject_name(certs_and_keys[n].cert);
2079 i = -1;
2080 while ((i = X509_NAME_get_index_by_NID(xname, NID_commonName, i)) != -1) {
2081 X509_NAME_ENTRY *entry = X509_NAME_get_entry(xname, i);
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02002082 ASN1_STRING *value;
2083 value = X509_NAME_ENTRY_get_data(entry);
2084 if (ASN1_STRING_to_UTF8((unsigned char **)&str, value) >= 0) {
Emmanuel Hocdetd294aea2016-05-13 11:14:06 +02002085 /* Important line is here */
2086 ssl_sock_populate_sni_keytypes_hplr(str, &sni_keytypes_map, n);
yanbzhu08ce6ab2015-12-02 13:01:29 -05002087
Emmanuel Hocdetd294aea2016-05-13 11:14:06 +02002088 OPENSSL_free(str);
2089 str = NULL;
2090 }
yanbzhu08ce6ab2015-12-02 13:01:29 -05002091 }
yanbzhu08ce6ab2015-12-02 13:01:29 -05002092
Emmanuel Hocdetd294aea2016-05-13 11:14:06 +02002093 /* Do the above logic for each SAN */
yanbzhu08ce6ab2015-12-02 13:01:29 -05002094#ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME
Emmanuel Hocdetd294aea2016-05-13 11:14:06 +02002095 names = X509_get_ext_d2i(certs_and_keys[n].cert, NID_subject_alt_name, NULL, NULL);
2096 if (names) {
2097 for (i = 0; i < sk_GENERAL_NAME_num(names); i++) {
2098 GENERAL_NAME *name = sk_GENERAL_NAME_value(names, i);
yanbzhu08ce6ab2015-12-02 13:01:29 -05002099
Emmanuel Hocdetd294aea2016-05-13 11:14:06 +02002100 if (name->type == GEN_DNS) {
2101 if (ASN1_STRING_to_UTF8((unsigned char **)&str, name->d.dNSName) >= 0) {
2102 /* Important line is here */
2103 ssl_sock_populate_sni_keytypes_hplr(str, &sni_keytypes_map, n);
yanbzhu08ce6ab2015-12-02 13:01:29 -05002104
Emmanuel Hocdetd294aea2016-05-13 11:14:06 +02002105 OPENSSL_free(str);
2106 str = NULL;
2107 }
yanbzhu08ce6ab2015-12-02 13:01:29 -05002108 }
2109 }
2110 }
2111 }
2112#endif /* SSL_CTRL_SET_TLSEXT_HOSTNAME */
2113 }
2114
2115 /* If no files found, return error */
2116 if (eb_is_empty(&sni_keytypes_map)) {
2117 memprintf(err, "%sunable to load SSL certificate file '%s' file does not exist.\n",
2118 err && *err ? *err : "", path);
2119 rv = 1;
2120 goto end;
2121 }
2122
2123 /* We now have a map of CN/SAN to keytypes that are loaded in
2124 * Iterate through the map to create the SSL_CTX's (if needed)
2125 * and add each CTX to the SNI tree
2126 *
2127 * Some math here:
2128 * There are 2^n - 1 possibile combinations, each unique
2129 * combination is denoted by the key in the map. Each key
2130 * has a value between 1 and 2^n - 1. Conveniently, the array
2131 * of SSL_CTX* is sized 2^n. So, we can simply use the i'th
2132 * entry in the array to correspond to the unique combo (key)
2133 * associated with i. This unique key combo (i) will be associated
2134 * with combos[i-1]
2135 */
2136
2137 node = ebmb_first(&sni_keytypes_map);
2138 while (node) {
2139 SSL_CTX *cur_ctx;
2140
2141 str = (char *)container_of(node, struct sni_keytype, name)->name.key;
2142 i = container_of(node, struct sni_keytype, name)->keytypes;
2143 cur_ctx = key_combos[i-1].ctx;
2144
2145 if (cur_ctx == NULL) {
2146 /* need to create SSL_CTX */
2147 cur_ctx = SSL_CTX_new(SSLv23_server_method());
2148 if (cur_ctx == NULL) {
2149 memprintf(err, "%sunable to allocate SSL context.\n",
2150 err && *err ? *err : "");
2151 rv = 1;
2152 goto end;
2153 }
2154
yanbzhube2774d2015-12-10 15:07:30 -05002155 /* Load all required certs/keys/chains/OCSPs info into SSL_CTX */
yanbzhu08ce6ab2015-12-02 13:01:29 -05002156 for (n = 0; n < SSL_SOCK_NUM_KEYTYPES; n++) {
2157 if (i & (1<<n)) {
2158 /* Key combo contains ckch[n] */
2159 snprintf(trash.str, trash.size, "%s.%s", path, SSL_SOCK_KEYTYPE_NAMES[n]);
2160 if (ssl_sock_put_ckch_into_ctx(trash.str, &certs_and_keys[n], cur_ctx, err) != 0) {
2161 SSL_CTX_free(cur_ctx);
2162 rv = 1;
2163 goto end;
2164 }
yanbzhube2774d2015-12-10 15:07:30 -05002165
2166#if (defined SSL_CTRL_SET_TLSEXT_STATUS_REQ_CB && !defined OPENSSL_NO_OCSP)
2167 /* Load OCSP Info into context */
2168 if (ssl_sock_load_ocsp(cur_ctx, trash.str) < 0) {
2169 if (err)
2170 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",
2171 *err ? *err : "", path);
2172 SSL_CTX_free(cur_ctx);
2173 rv = 1;
2174 goto end;
2175 }
2176#endif
yanbzhu08ce6ab2015-12-02 13:01:29 -05002177 }
2178 }
2179
2180 /* Load DH params into the ctx to support DHE keys */
2181#ifndef OPENSSL_NO_DH
2182 if (ssl_dh_ptr_index >= 0)
2183 SSL_CTX_set_ex_data(cur_ctx, ssl_dh_ptr_index, NULL);
2184
2185 rv = ssl_sock_load_dh_params(cur_ctx, NULL);
2186 if (rv < 0) {
2187 if (err)
2188 memprintf(err, "%sunable to load DH parameters from file '%s'.\n",
2189 *err ? *err : "", path);
2190 rv = 1;
2191 goto end;
2192 }
2193#endif
2194
2195 /* Update key_combos */
2196 key_combos[i-1].ctx = cur_ctx;
2197 }
2198
2199 /* Update SNI Tree */
Emmanuel Hocdetd294aea2016-05-13 11:14:06 +02002200 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 -05002201 node = ebmb_next(node);
2202 }
2203
2204
2205 /* Mark a default context if none exists, using the ctx that has the most shared keys */
2206 if (!bind_conf->default_ctx) {
2207 for (i = SSL_SOCK_POSSIBLE_KT_COMBOS - 1; i >= 0; i--) {
2208 if (key_combos[i].ctx) {
2209 bind_conf->default_ctx = key_combos[i].ctx;
2210 break;
2211 }
2212 }
2213 }
2214
2215end:
2216
2217 if (names)
2218 sk_GENERAL_NAME_pop_free(names, GENERAL_NAME_free);
2219
2220 for (n = 0; n < SSL_SOCK_NUM_KEYTYPES; n++)
2221 ssl_sock_free_cert_key_and_chain_contents(&certs_and_keys[n]);
2222
2223 node = ebmb_first(&sni_keytypes_map);
2224 while (node) {
2225 next = ebmb_next(node);
2226 ebmb_delete(node);
2227 node = next;
2228 }
2229
2230 return rv;
2231}
2232#else
2233/* This is a dummy, that just logs an error and returns error */
Emmanuel Hocdetd294aea2016-05-13 11:14:06 +02002234static 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 -05002235{
2236 memprintf(err, "%sunable to stat SSL certificate from file '%s' : %s.\n",
2237 err && *err ? *err : "", path, strerror(errno));
2238 return 1;
2239}
2240
yanbzhu488a4d22015-12-01 15:16:07 -05002241#endif /* #if OPENSSL_VERSION_NUMBER >= 0x1000200fL: Support for loading multiple certs into a single SSL_CTX */
2242
Emeric Brunfc0421f2012-09-07 17:30:07 +02002243/* Loads a certificate key and CA chain from a file. Returns 0 on error, -1 if
2244 * an early error happens and the caller must call SSL_CTX_free() by itelf.
2245 */
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +02002246static 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 +02002247{
2248 BIO *in;
2249 X509 *x = NULL, *ca;
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +02002250 int i, err;
Emeric Brunfc0421f2012-09-07 17:30:07 +02002251 int ret = -1;
2252 int order = 0;
2253 X509_NAME *xname;
2254 char *str;
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02002255 pem_password_cb *passwd_cb;
2256 void *passwd_cb_userdata;
2257
Emeric Brunfc0421f2012-09-07 17:30:07 +02002258#ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME
2259 STACK_OF(GENERAL_NAME) *names;
2260#endif
2261
2262 in = BIO_new(BIO_s_file());
2263 if (in == NULL)
2264 goto end;
2265
2266 if (BIO_read_filename(in, file) <= 0)
2267 goto end;
2268
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02002269
2270 passwd_cb = SSL_CTX_get_default_passwd_cb(ctx);
2271 passwd_cb_userdata = SSL_CTX_get_default_passwd_cb_userdata(ctx);
2272
2273 x = PEM_read_bio_X509_AUX(in, NULL, passwd_cb, passwd_cb_userdata);
Emeric Brunfc0421f2012-09-07 17:30:07 +02002274 if (x == NULL)
2275 goto end;
2276
Emeric Brun50bcecc2013-04-22 13:05:23 +02002277 if (fcount) {
2278 while (fcount--)
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +02002279 order = ssl_sock_add_cert_sni(ctx, s, sni_filter[fcount], order);
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01002280 }
2281 else {
Emeric Brunfc0421f2012-09-07 17:30:07 +02002282#ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01002283 names = X509_get_ext_d2i(x, NID_subject_alt_name, NULL, NULL);
2284 if (names) {
2285 for (i = 0; i < sk_GENERAL_NAME_num(names); i++) {
2286 GENERAL_NAME *name = sk_GENERAL_NAME_value(names, i);
2287 if (name->type == GEN_DNS) {
2288 if (ASN1_STRING_to_UTF8((unsigned char **)&str, name->d.dNSName) >= 0) {
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +02002289 order = ssl_sock_add_cert_sni(ctx, s, str, order);
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01002290 OPENSSL_free(str);
Emeric Brunfc0421f2012-09-07 17:30:07 +02002291 }
Emeric Brunfc0421f2012-09-07 17:30:07 +02002292 }
2293 }
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01002294 sk_GENERAL_NAME_pop_free(names, GENERAL_NAME_free);
Emeric Brunfc0421f2012-09-07 17:30:07 +02002295 }
Emeric Brunfc0421f2012-09-07 17:30:07 +02002296#endif /* SSL_CTRL_SET_TLSEXT_HOSTNAME */
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01002297 xname = X509_get_subject_name(x);
2298 i = -1;
2299 while ((i = X509_NAME_get_index_by_NID(xname, NID_commonName, i)) != -1) {
2300 X509_NAME_ENTRY *entry = X509_NAME_get_entry(xname, i);
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02002301 ASN1_STRING *value;
2302
2303 value = X509_NAME_ENTRY_get_data(entry);
2304 if (ASN1_STRING_to_UTF8((unsigned char **)&str, value) >= 0) {
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +02002305 order = ssl_sock_add_cert_sni(ctx, s, str, order);
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01002306 OPENSSL_free(str);
Emeric Brunfc0421f2012-09-07 17:30:07 +02002307 }
Emeric Brunfc0421f2012-09-07 17:30:07 +02002308 }
2309 }
2310
2311 ret = 0; /* the caller must not free the SSL_CTX argument anymore */
2312 if (!SSL_CTX_use_certificate(ctx, x))
2313 goto end;
2314
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02002315#ifdef SSL_CTX_clear_extra_chain_certs
2316 SSL_CTX_clear_extra_chain_certs(ctx);
2317#else
Emeric Brunfc0421f2012-09-07 17:30:07 +02002318 if (ctx->extra_certs != NULL) {
2319 sk_X509_pop_free(ctx->extra_certs, X509_free);
2320 ctx->extra_certs = NULL;
2321 }
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02002322#endif
Emeric Brunfc0421f2012-09-07 17:30:07 +02002323
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02002324 while ((ca = PEM_read_bio_X509(in, NULL, passwd_cb, passwd_cb_userdata))) {
Emeric Brunfc0421f2012-09-07 17:30:07 +02002325 if (!SSL_CTX_add_extra_chain_cert(ctx, ca)) {
2326 X509_free(ca);
2327 goto end;
2328 }
2329 }
2330
2331 err = ERR_get_error();
2332 if (!err || (ERR_GET_LIB(err) == ERR_LIB_PEM && ERR_GET_REASON(err) == PEM_R_NO_START_LINE)) {
2333 /* we successfully reached the last cert in the file */
2334 ret = 1;
2335 }
2336 ERR_clear_error();
2337
2338end:
2339 if (x)
2340 X509_free(x);
2341
2342 if (in)
2343 BIO_free(in);
2344
2345 return ret;
2346}
2347
Emeric Brun50bcecc2013-04-22 13:05:23 +02002348static 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 +02002349{
2350 int ret;
2351 SSL_CTX *ctx;
2352
2353 ctx = SSL_CTX_new(SSLv23_server_method());
2354 if (!ctx) {
Willy Tarreaueb6cead2012-09-20 19:43:14 +02002355 memprintf(err, "%sunable to allocate SSL context for cert '%s'.\n",
2356 err && *err ? *err : "", path);
Emeric Brunfc0421f2012-09-07 17:30:07 +02002357 return 1;
2358 }
2359
2360 if (SSL_CTX_use_PrivateKey_file(ctx, path, SSL_FILETYPE_PEM) <= 0) {
Willy Tarreaueb6cead2012-09-20 19:43:14 +02002361 memprintf(err, "%sunable to load SSL private key from PEM file '%s'.\n",
2362 err && *err ? *err : "", path);
Emeric Brunfc0421f2012-09-07 17:30:07 +02002363 SSL_CTX_free(ctx);
2364 return 1;
2365 }
2366
Emeric Brun50bcecc2013-04-22 13:05:23 +02002367 ret = ssl_sock_load_cert_chain_file(ctx, path, bind_conf, sni_filter, fcount);
Emeric Brunfc0421f2012-09-07 17:30:07 +02002368 if (ret <= 0) {
Willy Tarreaueb6cead2012-09-20 19:43:14 +02002369 memprintf(err, "%sunable to load SSL certificate from PEM file '%s'.\n",
2370 err && *err ? *err : "", path);
Emeric Brunfc0421f2012-09-07 17:30:07 +02002371 if (ret < 0) /* serious error, must do that ourselves */
2372 SSL_CTX_free(ctx);
2373 return 1;
2374 }
Emeric Brun61694ab2012-10-26 13:35:33 +02002375
2376 if (SSL_CTX_check_private_key(ctx) <= 0) {
2377 memprintf(err, "%sinconsistencies between private key and certificate loaded from PEM file '%s'.\n",
2378 err && *err ? *err : "", path);
2379 return 1;
2380 }
2381
Emeric Brunfc0421f2012-09-07 17:30:07 +02002382 /* we must not free the SSL_CTX anymore below, since it's already in
2383 * the tree, so it will be discovered and cleaned in time.
2384 */
Emeric Bruna4bcd9a2012-09-20 16:19:02 +02002385#ifndef OPENSSL_NO_DH
Remi Gacogne4f902b82015-05-28 16:23:00 +02002386 /* store a NULL pointer to indicate we have not yet loaded
2387 a custom DH param file */
2388 if (ssl_dh_ptr_index >= 0) {
2389 SSL_CTX_set_ex_data(ctx, ssl_dh_ptr_index, NULL);
2390 }
2391
Emeric Bruna4bcd9a2012-09-20 16:19:02 +02002392 ret = ssl_sock_load_dh_params(ctx, path);
2393 if (ret < 0) {
2394 if (err)
2395 memprintf(err, "%sunable to load DH parameters from file '%s'.\n",
2396 *err ? *err : "", path);
2397 return 1;
2398 }
2399#endif
2400
Lukas Tribuse4e30f72014-12-09 16:32:51 +01002401#if (defined SSL_CTRL_SET_TLSEXT_STATUS_REQ_CB && !defined OPENSSL_NO_OCSP)
Emeric Brun4147b2e2014-06-16 18:36:30 +02002402 ret = ssl_sock_load_ocsp(ctx, path);
2403 if (ret < 0) {
2404 if (err)
2405 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",
2406 *err ? *err : "", path);
2407 return 1;
2408 }
2409#endif
2410
Daniel Jakots54ffb912015-11-06 20:02:41 +01002411#if (OPENSSL_VERSION_NUMBER >= 0x1000200fL && !defined OPENSSL_NO_TLSEXT && !defined OPENSSL_IS_BORINGSSL && !defined LIBRESSL_VERSION_NUMBER)
Janusz Dziemidowicz2c701b52015-03-07 23:03:59 +01002412 if (sctl_ex_index >= 0) {
2413 ret = ssl_sock_load_sctl(ctx, path);
2414 if (ret < 0) {
2415 if (err)
2416 memprintf(err, "%s '%s.sctl' is present but cannot be read or parsed'.\n",
2417 *err ? *err : "", path);
2418 return 1;
2419 }
2420 }
2421#endif
2422
Emeric Brunfc0421f2012-09-07 17:30:07 +02002423#ifndef SSL_CTRL_SET_TLSEXT_HOSTNAME
Willy Tarreau2a65ff02012-09-13 17:54:29 +02002424 if (bind_conf->default_ctx) {
Willy Tarreaueb6cead2012-09-20 19:43:14 +02002425 memprintf(err, "%sthis version of openssl cannot load multiple SSL certificates.\n",
2426 err && *err ? *err : "");
Emeric Brunfc0421f2012-09-07 17:30:07 +02002427 return 1;
2428 }
2429#endif
Willy Tarreau2a65ff02012-09-13 17:54:29 +02002430 if (!bind_conf->default_ctx)
2431 bind_conf->default_ctx = ctx;
Emeric Brunfc0421f2012-09-07 17:30:07 +02002432
2433 return 0;
2434}
2435
Willy Tarreau79eeafa2012-09-14 07:53:05 +02002436int ssl_sock_load_cert(char *path, struct bind_conf *bind_conf, struct proxy *curproxy, char **err)
Emeric Brunfc0421f2012-09-07 17:30:07 +02002437{
Cyril Bonté3180f7b2015-01-25 00:16:08 +01002438 struct dirent **de_list;
2439 int i, n;
Emeric Brunfc0421f2012-09-07 17:30:07 +02002440 DIR *dir;
2441 struct stat buf;
Willy Tarreauee2663b2012-12-06 11:36:59 +01002442 char *end;
2443 char fp[MAXPATHLEN+1];
Emeric Brunfc0421f2012-09-07 17:30:07 +02002444 int cfgerr = 0;
yanbzhu63ea8462015-12-09 13:35:14 -05002445#if OPENSSL_VERSION_NUMBER >= 0x1000200fL
2446 int is_bundle;
2447 int j;
2448#endif
Emeric Brunfc0421f2012-09-07 17:30:07 +02002449
yanbzhu08ce6ab2015-12-02 13:01:29 -05002450 if (stat(path, &buf) == 0) {
2451 dir = opendir(path);
2452 if (!dir)
2453 return ssl_sock_load_cert_file(path, bind_conf, curproxy, NULL, 0, err);
Emeric Brunfc0421f2012-09-07 17:30:07 +02002454
yanbzhu08ce6ab2015-12-02 13:01:29 -05002455 /* strip trailing slashes, including first one */
2456 for (end = path + strlen(path) - 1; end >= path && *end == '/'; end--)
2457 *end = 0;
Emeric Brunfc0421f2012-09-07 17:30:07 +02002458
yanbzhu08ce6ab2015-12-02 13:01:29 -05002459 n = scandir(path, &de_list, 0, alphasort);
2460 if (n < 0) {
2461 memprintf(err, "%sunable to scan directory '%s' : %s.\n",
2462 err && *err ? *err : "", path, strerror(errno));
2463 cfgerr++;
2464 }
2465 else {
2466 for (i = 0; i < n; i++) {
2467 struct dirent *de = de_list[i];
Emeric Brun2aab7222014-06-18 18:15:09 +02002468
yanbzhu08ce6ab2015-12-02 13:01:29 -05002469 end = strrchr(de->d_name, '.');
2470 if (end && (!strcmp(end, ".issuer") || !strcmp(end, ".ocsp") || !strcmp(end, ".sctl")))
2471 goto ignore_entry;
Cyril Bonté3180f7b2015-01-25 00:16:08 +01002472
yanbzhu08ce6ab2015-12-02 13:01:29 -05002473 snprintf(fp, sizeof(fp), "%s/%s", path, de->d_name);
2474 if (stat(fp, &buf) != 0) {
2475 memprintf(err, "%sunable to stat SSL certificate from file '%s' : %s.\n",
2476 err && *err ? *err : "", fp, strerror(errno));
2477 cfgerr++;
2478 goto ignore_entry;
2479 }
2480 if (!S_ISREG(buf.st_mode))
2481 goto ignore_entry;
yanbzhu63ea8462015-12-09 13:35:14 -05002482
2483#if OPENSSL_VERSION_NUMBER >= 0x1000200fL
2484 is_bundle = 0;
2485 /* Check if current entry in directory is part of a multi-cert bundle */
2486
2487 if (end) {
2488 for (j = 0; j < SSL_SOCK_NUM_KEYTYPES; j++) {
2489 if (!strcmp(end + 1, SSL_SOCK_KEYTYPE_NAMES[j])) {
2490 is_bundle = 1;
2491 break;
2492 }
2493 }
2494
2495 if (is_bundle) {
2496 char dp[MAXPATHLEN+1] = {0}; /* this will be the filename w/o the keytype */
2497 int dp_len;
2498
2499 dp_len = end - de->d_name;
2500 snprintf(dp, dp_len + 1, "%s", de->d_name);
2501
2502 /* increment i and free de until we get to a non-bundle cert
2503 * Note here that we look at de_list[i + 1] before freeing de
2504 * this is important since ignore_entry will free de
2505 */
2506 while (i + 1 < n && !strncmp(de_list[i + 1]->d_name, dp, dp_len)) {
2507 free(de);
2508 i++;
2509 de = de_list[i];
2510 }
2511
2512 snprintf(fp, sizeof(fp), "%s/%s", path, dp);
Emmanuel Hocdetd294aea2016-05-13 11:14:06 +02002513 ssl_sock_load_multi_cert(fp, bind_conf, curproxy, NULL, 0, err);
yanbzhu63ea8462015-12-09 13:35:14 -05002514
2515 /* Successfully processed the bundle */
2516 goto ignore_entry;
2517 }
2518 }
2519
2520#endif
yanbzhu08ce6ab2015-12-02 13:01:29 -05002521 cfgerr += ssl_sock_load_cert_file(fp, bind_conf, curproxy, NULL, 0, err);
2522ignore_entry:
2523 free(de);
Cyril Bonté3180f7b2015-01-25 00:16:08 +01002524 }
yanbzhu08ce6ab2015-12-02 13:01:29 -05002525 free(de_list);
Emeric Brunfc0421f2012-09-07 17:30:07 +02002526 }
yanbzhu08ce6ab2015-12-02 13:01:29 -05002527 closedir(dir);
2528 return cfgerr;
Emeric Brunfc0421f2012-09-07 17:30:07 +02002529 }
yanbzhu08ce6ab2015-12-02 13:01:29 -05002530
Emmanuel Hocdetd294aea2016-05-13 11:14:06 +02002531 cfgerr = ssl_sock_load_multi_cert(path, bind_conf, curproxy, NULL, 0, err);
yanbzhu08ce6ab2015-12-02 13:01:29 -05002532
Emeric Brunfc0421f2012-09-07 17:30:07 +02002533 return cfgerr;
2534}
2535
Thierry Fournier383085f2013-01-24 14:15:43 +01002536/* Make sure openssl opens /dev/urandom before the chroot. The work is only
2537 * done once. Zero is returned if the operation fails. No error is returned
2538 * if the random is said as not implemented, because we expect that openssl
2539 * will use another method once needed.
2540 */
2541static int ssl_initialize_random()
2542{
2543 unsigned char random;
2544 static int random_initialized = 0;
2545
2546 if (!random_initialized && RAND_bytes(&random, 1) != 0)
2547 random_initialized = 1;
2548
2549 return random_initialized;
2550}
2551
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01002552int ssl_sock_load_cert_list_file(char *file, struct bind_conf *bind_conf, struct proxy *curproxy, char **err)
2553{
Emmanuel Hocdet5e0e6e42016-05-13 11:18:50 +02002554 char thisline[LINESIZE*CRTLIST_FACTOR];
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01002555 FILE *f;
yanbzhu1b04e5b2015-12-02 13:54:14 -05002556 struct stat buf;
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01002557 int linenum = 0;
2558 int cfgerr = 0;
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01002559
Willy Tarreauad1731d2013-04-02 17:35:58 +02002560 if ((f = fopen(file, "r")) == NULL) {
2561 memprintf(err, "cannot open file '%s' : %s", file, strerror(errno));
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01002562 return 1;
Willy Tarreauad1731d2013-04-02 17:35:58 +02002563 }
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01002564
2565 while (fgets(thisline, sizeof(thisline), f) != NULL) {
2566 int arg;
Emeric Brun50bcecc2013-04-22 13:05:23 +02002567 int newarg;
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01002568 char *end;
Emmanuel Hocdet5e0e6e42016-05-13 11:18:50 +02002569 char *args[MAX_LINE_ARGS*CRTLIST_FACTOR + 1];
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01002570 char *line = thisline;
2571
2572 linenum++;
2573 end = line + strlen(line);
2574 if (end-line == sizeof(thisline)-1 && *(end-1) != '\n') {
2575 /* Check if we reached the limit and the last char is not \n.
2576 * Watch out for the last line without the terminating '\n'!
2577 */
Willy Tarreauad1731d2013-04-02 17:35:58 +02002578 memprintf(err, "line %d too long in file '%s', limit is %d characters",
2579 linenum, file, (int)sizeof(thisline)-1);
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01002580 cfgerr = 1;
Willy Tarreauad1731d2013-04-02 17:35:58 +02002581 break;
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01002582 }
2583
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01002584 arg = 0;
Emeric Brun50bcecc2013-04-22 13:05:23 +02002585 newarg = 1;
2586 while (*line) {
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01002587 if (*line == '#' || *line == '\n' || *line == '\r') {
2588 /* end of string, end of loop */
2589 *line = 0;
2590 break;
2591 }
2592 else if (isspace(*line)) {
Emeric Brun50bcecc2013-04-22 13:05:23 +02002593 newarg = 1;
2594 *line = 0;
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01002595 }
Emeric Brun50bcecc2013-04-22 13:05:23 +02002596 else if (newarg) {
Emmanuel Hocdet5e0e6e42016-05-13 11:18:50 +02002597 if (arg == MAX_LINE_ARGS*CRTLIST_FACTOR) {
Emeric Brun50bcecc2013-04-22 13:05:23 +02002598 memprintf(err, "too many args on line %d in file '%s'.",
2599 linenum, file);
2600 cfgerr = 1;
2601 break;
2602 }
2603 newarg = 0;
2604 args[arg++] = line;
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01002605 }
Emeric Brun50bcecc2013-04-22 13:05:23 +02002606 line++;
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01002607 }
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +02002608 if (cfgerr)
2609 break;
Willy Tarreauad1731d2013-04-02 17:35:58 +02002610
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01002611 /* empty line */
Emeric Brun50bcecc2013-04-22 13:05:23 +02002612 if (!arg)
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01002613 continue;
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01002614
yanbzhu1b04e5b2015-12-02 13:54:14 -05002615 if (stat(args[0], &buf) == 0) {
2616 cfgerr = ssl_sock_load_cert_file(args[0], bind_conf, curproxy, &args[1], arg-1, err);
2617 } else {
Emmanuel Hocdetd294aea2016-05-13 11:14:06 +02002618 cfgerr = ssl_sock_load_multi_cert(args[0], bind_conf, curproxy, &args[1], arg-1, err);
yanbzhu1b04e5b2015-12-02 13:54:14 -05002619 }
2620
Willy Tarreauad1731d2013-04-02 17:35:58 +02002621 if (cfgerr) {
2622 memprintf(err, "error processing line %d in file '%s' : %s", linenum, file, *err);
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01002623 break;
Willy Tarreauad1731d2013-04-02 17:35:58 +02002624 }
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01002625 }
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01002626 fclose(f);
2627 return cfgerr;
2628}
2629
Emeric Brunfc0421f2012-09-07 17:30:07 +02002630#ifndef SSL_OP_CIPHER_SERVER_PREFERENCE /* needs OpenSSL >= 0.9.7 */
2631#define SSL_OP_CIPHER_SERVER_PREFERENCE 0
2632#endif
2633
2634#ifndef SSL_OP_NO_SESSION_RESUMPTION_ON_RENEGOTIATION /* needs OpenSSL >= 0.9.7 */
2635#define SSL_OP_NO_SESSION_RESUMPTION_ON_RENEGOTIATION 0
Willy Tarreau7d588ee2012-11-26 18:47:31 +01002636#define SSL_renegotiate_pending(arg) 0
Emeric Brunfc0421f2012-09-07 17:30:07 +02002637#endif
Emeric Brun2b58d042012-09-20 17:10:03 +02002638#ifndef SSL_OP_SINGLE_ECDH_USE /* needs OpenSSL >= 0.9.8 */
2639#define SSL_OP_SINGLE_ECDH_USE 0
2640#endif
Emeric Brun2d0c4822012-10-02 13:45:20 +02002641#ifndef SSL_OP_NO_TICKET /* needs OpenSSL >= 0.9.8 */
2642#define SSL_OP_NO_TICKET 0
2643#endif
Emeric Brunfc0421f2012-09-07 17:30:07 +02002644#ifndef SSL_OP_NO_COMPRESSION /* needs OpenSSL >= 0.9.9 */
2645#define SSL_OP_NO_COMPRESSION 0
2646#endif
Emeric Brunc0ff4922012-09-28 19:37:02 +02002647#ifndef SSL_OP_NO_TLSv1_1 /* needs OpenSSL >= 1.0.1 */
2648#define SSL_OP_NO_TLSv1_1 0
2649#endif
2650#ifndef SSL_OP_NO_TLSv1_2 /* needs OpenSSL >= 1.0.1 */
2651#define SSL_OP_NO_TLSv1_2 0
2652#endif
Emeric Bruna4bcd9a2012-09-20 16:19:02 +02002653#ifndef SSL_OP_SINGLE_DH_USE /* needs OpenSSL >= 0.9.6 */
2654#define SSL_OP_SINGLE_DH_USE 0
2655#endif
Emeric Brun2b58d042012-09-20 17:10:03 +02002656#ifndef SSL_OP_SINGLE_ECDH_USE /* needs OpenSSL >= 1.0.0 */
2657#define SSL_OP_SINGLE_ECDH_USE 0
2658#endif
Emeric Brunfc0421f2012-09-07 17:30:07 +02002659#ifndef SSL_MODE_RELEASE_BUFFERS /* needs OpenSSL >= 1.0.0 */
2660#define SSL_MODE_RELEASE_BUFFERS 0
2661#endif
Willy Tarreau396a1862014-11-13 14:06:52 +01002662#ifndef SSL_MODE_SMALL_BUFFERS /* needs small_records.patch */
2663#define SSL_MODE_SMALL_BUFFERS 0
2664#endif
Remi Gacognef46cd6e2014-06-12 14:58:40 +02002665
Willy Tarreau2a65ff02012-09-13 17:54:29 +02002666int ssl_sock_prepare_ctx(struct bind_conf *bind_conf, SSL_CTX *ctx, struct proxy *curproxy)
Emeric Brunfc0421f2012-09-07 17:30:07 +02002667{
2668 int cfgerr = 0;
Emeric Brun850efd52014-01-29 12:24:34 +01002669 int verify = SSL_VERIFY_NONE;
Remi Gacogneaf5c3da2014-05-19 10:29:58 +02002670 long ssloptions =
Emeric Brunfc0421f2012-09-07 17:30:07 +02002671 SSL_OP_ALL | /* all known workarounds for bugs */
2672 SSL_OP_NO_SSLv2 |
2673 SSL_OP_NO_COMPRESSION |
Emeric Bruna4bcd9a2012-09-20 16:19:02 +02002674 SSL_OP_SINGLE_DH_USE |
Emeric Brun2b58d042012-09-20 17:10:03 +02002675 SSL_OP_SINGLE_ECDH_USE |
Emeric Brun3c4bc6e2012-10-04 18:44:19 +02002676 SSL_OP_NO_SESSION_RESUMPTION_ON_RENEGOTIATION |
2677 SSL_OP_CIPHER_SERVER_PREFERENCE;
Remi Gacogneaf5c3da2014-05-19 10:29:58 +02002678 long sslmode =
Emeric Brunfc0421f2012-09-07 17:30:07 +02002679 SSL_MODE_ENABLE_PARTIAL_WRITE |
2680 SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER |
Willy Tarreau396a1862014-11-13 14:06:52 +01002681 SSL_MODE_RELEASE_BUFFERS |
2682 SSL_MODE_SMALL_BUFFERS;
Remi Gacognef46cd6e2014-06-12 14:58:40 +02002683 STACK_OF(SSL_CIPHER) * ciphers = NULL;
Willy Tarreaua616ba62014-10-26 06:49:19 +01002684 SSL_CIPHER * cipher = NULL;
Remi Gacognec1eab8c2014-06-12 18:20:11 +02002685 char cipher_description[128];
2686 /* The description of ciphers using an Ephemeral Diffie Hellman key exchange
2687 contains " Kx=DH " or " Kx=DH(". Beware of " Kx=DH/",
2688 which is not ephemeral DH. */
2689 const char dhe_description[] = " Kx=DH ";
2690 const char dhe_export_description[] = " Kx=DH(";
Remi Gacognef46cd6e2014-06-12 14:58:40 +02002691 int idx = 0;
2692 int dhe_found = 0;
Remi Gacogne23d5d372014-10-10 17:04:26 +02002693 SSL *ssl = NULL;
Emeric Brunfc0421f2012-09-07 17:30:07 +02002694
Thierry Fournier383085f2013-01-24 14:15:43 +01002695 /* Make sure openssl opens /dev/urandom before the chroot */
2696 if (!ssl_initialize_random()) {
2697 Alert("OpenSSL random data generator initialization failed.\n");
2698 cfgerr++;
2699 }
2700
Emeric Brun89675492012-10-05 13:48:26 +02002701 if (bind_conf->ssl_options & BC_SSL_O_NO_SSLV3)
Emeric Brunfc0421f2012-09-07 17:30:07 +02002702 ssloptions |= SSL_OP_NO_SSLv3;
Emeric Brun89675492012-10-05 13:48:26 +02002703 if (bind_conf->ssl_options & BC_SSL_O_NO_TLSV10)
Emeric Brunfc0421f2012-09-07 17:30:07 +02002704 ssloptions |= SSL_OP_NO_TLSv1;
Emeric Brun89675492012-10-05 13:48:26 +02002705 if (bind_conf->ssl_options & BC_SSL_O_NO_TLSV11)
Emeric Brunc0ff4922012-09-28 19:37:02 +02002706 ssloptions |= SSL_OP_NO_TLSv1_1;
Emeric Brun89675492012-10-05 13:48:26 +02002707 if (bind_conf->ssl_options & BC_SSL_O_NO_TLSV12)
Emeric Brunc0ff4922012-09-28 19:37:02 +02002708 ssloptions |= SSL_OP_NO_TLSv1_2;
Emeric Brun89675492012-10-05 13:48:26 +02002709 if (bind_conf->ssl_options & BC_SSL_O_NO_TLS_TICKETS)
Emeric Brun2d0c4822012-10-02 13:45:20 +02002710 ssloptions |= SSL_OP_NO_TICKET;
Jérémie Courrèges-Anglas17c3f622015-07-25 16:50:52 -06002711 if (bind_conf->ssl_options & BC_SSL_O_USE_SSLV3) {
2712#ifndef OPENSSL_NO_SSL3
Emeric Brun2cb7ae52012-10-05 14:14:21 +02002713 SSL_CTX_set_ssl_version(ctx, SSLv3_server_method());
Jérémie Courrèges-Anglas17c3f622015-07-25 16:50:52 -06002714#else
2715 Alert("SSLv3 support requested but unavailable.\n");
2716 cfgerr++;
2717#endif
2718 }
Emeric Brun2cb7ae52012-10-05 14:14:21 +02002719 if (bind_conf->ssl_options & BC_SSL_O_USE_TLSV10)
2720 SSL_CTX_set_ssl_version(ctx, TLSv1_server_method());
2721#if SSL_OP_NO_TLSv1_1
2722 if (bind_conf->ssl_options & BC_SSL_O_USE_TLSV11)
2723 SSL_CTX_set_ssl_version(ctx, TLSv1_1_server_method());
2724#endif
2725#if SSL_OP_NO_TLSv1_2
2726 if (bind_conf->ssl_options & BC_SSL_O_USE_TLSV12)
2727 SSL_CTX_set_ssl_version(ctx, TLSv1_2_server_method());
2728#endif
Emeric Brunfc0421f2012-09-07 17:30:07 +02002729
2730 SSL_CTX_set_options(ctx, ssloptions);
2731 SSL_CTX_set_mode(ctx, sslmode);
Emeric Brun850efd52014-01-29 12:24:34 +01002732 switch (bind_conf->verify) {
2733 case SSL_SOCK_VERIFY_NONE:
2734 verify = SSL_VERIFY_NONE;
2735 break;
2736 case SSL_SOCK_VERIFY_OPTIONAL:
2737 verify = SSL_VERIFY_PEER;
2738 break;
2739 case SSL_SOCK_VERIFY_REQUIRED:
2740 verify = SSL_VERIFY_PEER|SSL_VERIFY_FAIL_IF_NO_PEER_CERT;
2741 break;
2742 }
2743 SSL_CTX_set_verify(ctx, verify, ssl_sock_bind_verifycbk);
2744 if (verify & SSL_VERIFY_PEER) {
Emeric Brunfb510ea2012-10-05 12:00:26 +02002745 if (bind_conf->ca_file) {
Emeric Brund94b3fe2012-09-20 18:23:56 +02002746 /* load CAfile to verify */
Emeric Brunfb510ea2012-10-05 12:00:26 +02002747 if (!SSL_CTX_load_verify_locations(ctx, bind_conf->ca_file, NULL)) {
Emeric Brund94b3fe2012-09-20 18:23:56 +02002748 Alert("Proxy '%s': unable to load CA file '%s' for bind '%s' at [%s:%d].\n",
Emeric Brunfb510ea2012-10-05 12:00:26 +02002749 curproxy->id, bind_conf->ca_file, bind_conf->arg, bind_conf->file, bind_conf->line);
Emeric Brund94b3fe2012-09-20 18:23:56 +02002750 cfgerr++;
2751 }
2752 /* set CA names fo client cert request, function returns void */
Emeric Brunfb510ea2012-10-05 12:00:26 +02002753 SSL_CTX_set_client_CA_list(ctx, SSL_load_client_CA_file(bind_conf->ca_file));
Emeric Brund94b3fe2012-09-20 18:23:56 +02002754 }
Emeric Brun850efd52014-01-29 12:24:34 +01002755 else {
2756 Alert("Proxy '%s': verify is enabled but no CA file specified for bind '%s' at [%s:%d].\n",
2757 curproxy->id, bind_conf->arg, bind_conf->file, bind_conf->line);
2758 cfgerr++;
2759 }
Emeric Brun051cdab2012-10-02 19:25:50 +02002760#ifdef X509_V_FLAG_CRL_CHECK
Emeric Brunfb510ea2012-10-05 12:00:26 +02002761 if (bind_conf->crl_file) {
Emeric Brund94b3fe2012-09-20 18:23:56 +02002762 X509_STORE *store = SSL_CTX_get_cert_store(ctx);
2763
Emeric Brunfb510ea2012-10-05 12:00:26 +02002764 if (!store || !X509_STORE_load_locations(store, bind_conf->crl_file, NULL)) {
Emeric Brund94b3fe2012-09-20 18:23:56 +02002765 Alert("Proxy '%s': unable to configure CRL file '%s' for bind '%s' at [%s:%d].\n",
Alexander Rigbofc65af02015-04-07 14:02:16 +02002766 curproxy->id, bind_conf->crl_file, bind_conf->arg, bind_conf->file, bind_conf->line);
Emeric Brund94b3fe2012-09-20 18:23:56 +02002767 cfgerr++;
2768 }
Emeric Brun561e5742012-10-02 15:20:55 +02002769 else {
2770 X509_STORE_set_flags(store, X509_V_FLAG_CRL_CHECK|X509_V_FLAG_CRL_CHECK_ALL);
2771 }
Emeric Brund94b3fe2012-09-20 18:23:56 +02002772 }
Emeric Brun051cdab2012-10-02 19:25:50 +02002773#endif
Emeric Brun644cde02012-12-14 11:21:13 +01002774 ERR_clear_error();
Emeric Brund94b3fe2012-09-20 18:23:56 +02002775 }
Emeric Brunfc0421f2012-09-07 17:30:07 +02002776
Nenad Merdanovic05552d42015-02-27 19:56:49 +01002777#if (defined SSL_CTRL_SET_TLSEXT_TICKET_KEY_CB && TLS_TICKETS_NO > 0)
Nenad Merdanovic146defa2015-05-09 08:46:00 +02002778 if(bind_conf->keys_ref) {
Nenad Merdanovic05552d42015-02-27 19:56:49 +01002779 if (!SSL_CTX_set_tlsext_ticket_key_cb(ctx, ssl_tlsext_ticket_key_cb)) {
2780 Alert("Proxy '%s': unable to set callback for TLS ticket validation for bind '%s' at [%s:%d].\n",
2781 curproxy->id, bind_conf->arg, bind_conf->file, bind_conf->line);
2782 cfgerr++;
2783 }
2784 }
2785#endif
2786
Emeric Brun4f65bff2012-11-16 15:11:00 +01002787 if (global.tune.ssllifetime)
2788 SSL_CTX_set_timeout(ctx, global.tune.ssllifetime);
2789
Emeric Brunfc0421f2012-09-07 17:30:07 +02002790 shared_context_set_cache(ctx);
Willy Tarreau2a65ff02012-09-13 17:54:29 +02002791 if (bind_conf->ciphers &&
2792 !SSL_CTX_set_cipher_list(ctx, bind_conf->ciphers)) {
Emeric Brunfc0421f2012-09-07 17:30:07 +02002793 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 +02002794 curproxy->id, bind_conf->ciphers, bind_conf->arg, bind_conf->file, bind_conf->line);
Emeric Brunfc0421f2012-09-07 17:30:07 +02002795 cfgerr++;
2796 }
2797
Remi Gacogne47783ef2015-05-29 15:53:22 +02002798 /* If tune.ssl.default-dh-param has not been set,
2799 neither has ssl-default-dh-file and no static DH
2800 params were in the certificate file. */
Remi Gacogne4f902b82015-05-28 16:23:00 +02002801 if (global.tune.ssl_default_dh_param == 0 &&
Remi Gacogne47783ef2015-05-29 15:53:22 +02002802 global_dh == NULL &&
Remi Gacogne4f902b82015-05-28 16:23:00 +02002803 (ssl_dh_ptr_index == -1 ||
2804 SSL_CTX_get_ex_data(ctx, ssl_dh_ptr_index) == NULL)) {
Lukas Tribus90132722014-08-18 00:56:33 +02002805
Remi Gacogne23d5d372014-10-10 17:04:26 +02002806 ssl = SSL_new(ctx);
Remi Gacognef46cd6e2014-06-12 14:58:40 +02002807
Remi Gacogne23d5d372014-10-10 17:04:26 +02002808 if (ssl) {
2809 ciphers = SSL_get_ciphers(ssl);
2810
2811 if (ciphers) {
2812 for (idx = 0; idx < sk_SSL_CIPHER_num(ciphers); idx++) {
2813 cipher = sk_SSL_CIPHER_value(ciphers, idx);
2814 if (SSL_CIPHER_description(cipher, cipher_description, sizeof (cipher_description)) == cipher_description) {
2815 if (strstr(cipher_description, dhe_description) != NULL ||
2816 strstr(cipher_description, dhe_export_description) != NULL) {
2817 dhe_found = 1;
2818 break;
2819 }
Remi Gacognec1eab8c2014-06-12 18:20:11 +02002820 }
Remi Gacognef46cd6e2014-06-12 14:58:40 +02002821 }
2822 }
Remi Gacogne23d5d372014-10-10 17:04:26 +02002823 SSL_free(ssl);
2824 ssl = NULL;
Lukas Tribus90132722014-08-18 00:56:33 +02002825 }
Remi Gacognef46cd6e2014-06-12 14:58:40 +02002826
Lukas Tribus90132722014-08-18 00:56:33 +02002827 if (dhe_found) {
2828 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 +02002829 }
2830
2831 global.tune.ssl_default_dh_param = 1024;
2832 }
Remi Gacogne8de54152014-07-15 11:36:40 +02002833
2834#ifndef OPENSSL_NO_DH
2835 if (global.tune.ssl_default_dh_param >= 1024) {
2836 if (local_dh_1024 == NULL) {
2837 local_dh_1024 = ssl_get_dh_1024();
2838 }
2839 if (global.tune.ssl_default_dh_param >= 2048) {
2840 if (local_dh_2048 == NULL) {
2841 local_dh_2048 = ssl_get_dh_2048();
2842 }
2843 if (global.tune.ssl_default_dh_param >= 4096) {
2844 if (local_dh_4096 == NULL) {
2845 local_dh_4096 = ssl_get_dh_4096();
2846 }
Remi Gacogne8de54152014-07-15 11:36:40 +02002847 }
2848 }
2849 }
2850#endif /* OPENSSL_NO_DH */
Remi Gacognef46cd6e2014-06-12 14:58:40 +02002851
Emeric Brunfc0421f2012-09-07 17:30:07 +02002852 SSL_CTX_set_info_callback(ctx, ssl_sock_infocbk);
Willy Tarreau5cbe4ef2014-05-08 22:45:11 +02002853#if OPENSSL_VERSION_NUMBER >= 0x00907000L
Emeric Brun29f037d2014-04-25 19:05:36 +02002854 SSL_CTX_set_msg_callback(ctx, ssl_sock_msgcbk);
Willy Tarreau5cbe4ef2014-05-08 22:45:11 +02002855#endif
Emeric Brun29f037d2014-04-25 19:05:36 +02002856
Willy Tarreau6c9a3d52012-10-18 18:57:14 +02002857#ifdef OPENSSL_NPN_NEGOTIATED
2858 if (bind_conf->npn_str)
2859 SSL_CTX_set_next_protos_advertised_cb(ctx, ssl_sock_advertise_npn_protos, bind_conf);
2860#endif
Dirkjan Bussink48f1c4e2014-02-13 12:29:42 +01002861#ifdef TLSEXT_TYPE_application_layer_protocol_negotiation
Willy Tarreauab861d32013-04-02 02:30:41 +02002862 if (bind_conf->alpn_str)
Dirkjan Bussink48f1c4e2014-02-13 12:29:42 +01002863 SSL_CTX_set_alpn_select_cb(ctx, ssl_sock_advertise_alpn_protos, bind_conf);
Willy Tarreauab861d32013-04-02 02:30:41 +02002864#endif
Willy Tarreau6c9a3d52012-10-18 18:57:14 +02002865
Emeric Brunfc0421f2012-09-07 17:30:07 +02002866#ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME
2867 SSL_CTX_set_tlsext_servername_callback(ctx, ssl_sock_switchctx_cbk);
Willy Tarreau2a65ff02012-09-13 17:54:29 +02002868 SSL_CTX_set_tlsext_servername_arg(ctx, bind_conf);
Emeric Brunfc0421f2012-09-07 17:30:07 +02002869#endif
Emeric Brun2b58d042012-09-20 17:10:03 +02002870#if defined(SSL_CTX_set_tmp_ecdh) && !defined(OPENSSL_NO_ECDH)
Emeric Brun6924ef82013-03-06 14:08:53 +01002871 {
Emeric Brun2b58d042012-09-20 17:10:03 +02002872 int i;
2873 EC_KEY *ecdh;
2874
Emeric Brun6924ef82013-03-06 14:08:53 +01002875 i = OBJ_sn2nid(bind_conf->ecdhe ? bind_conf->ecdhe : ECDHE_DEFAULT_CURVE);
Emeric Brun2b58d042012-09-20 17:10:03 +02002876 if (!i || ((ecdh = EC_KEY_new_by_curve_name(i)) == NULL)) {
2877 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 +01002878 curproxy->id, bind_conf->ecdhe ? bind_conf->ecdhe : ECDHE_DEFAULT_CURVE,
2879 bind_conf->arg, bind_conf->file, bind_conf->line);
Emeric Brun2b58d042012-09-20 17:10:03 +02002880 cfgerr++;
2881 }
2882 else {
2883 SSL_CTX_set_tmp_ecdh(ctx, ecdh);
2884 EC_KEY_free(ecdh);
2885 }
2886 }
2887#endif
2888
Emeric Brunfc0421f2012-09-07 17:30:07 +02002889 return cfgerr;
2890}
2891
Evan Broderbe554312013-06-27 00:05:25 -07002892static int ssl_sock_srv_hostcheck(const char *pattern, const char *hostname)
2893{
2894 const char *pattern_wildcard, *pattern_left_label_end, *hostname_left_label_end;
2895 size_t prefixlen, suffixlen;
2896
2897 /* Trivial case */
2898 if (strcmp(pattern, hostname) == 0)
2899 return 1;
2900
Evan Broderbe554312013-06-27 00:05:25 -07002901 /* The rest of this logic is based on RFC 6125, section 6.4.3
2902 * (http://tools.ietf.org/html/rfc6125#section-6.4.3) */
2903
Emeric Bruna848dae2013-10-08 11:27:28 +02002904 pattern_wildcard = NULL;
2905 pattern_left_label_end = pattern;
2906 while (*pattern_left_label_end != '.') {
2907 switch (*pattern_left_label_end) {
2908 case 0:
2909 /* End of label not found */
2910 return 0;
2911 case '*':
2912 /* If there is more than one wildcards */
2913 if (pattern_wildcard)
2914 return 0;
2915 pattern_wildcard = pattern_left_label_end;
2916 break;
2917 }
2918 pattern_left_label_end++;
2919 }
2920
2921 /* If it's not trivial and there is no wildcard, it can't
2922 * match */
2923 if (!pattern_wildcard)
Evan Broderbe554312013-06-27 00:05:25 -07002924 return 0;
2925
2926 /* Make sure all labels match except the leftmost */
2927 hostname_left_label_end = strchr(hostname, '.');
2928 if (!hostname_left_label_end
2929 || strcmp(pattern_left_label_end, hostname_left_label_end) != 0)
2930 return 0;
2931
2932 /* Make sure the leftmost label of the hostname is long enough
2933 * that the wildcard can match */
Emeric Brun369da852013-10-08 11:39:35 +02002934 if (hostname_left_label_end - hostname < (pattern_left_label_end - pattern) - 1)
Evan Broderbe554312013-06-27 00:05:25 -07002935 return 0;
2936
2937 /* Finally compare the string on either side of the
2938 * wildcard */
2939 prefixlen = pattern_wildcard - pattern;
2940 suffixlen = pattern_left_label_end - (pattern_wildcard + 1);
Emeric Bruna848dae2013-10-08 11:27:28 +02002941 if ((prefixlen && (memcmp(pattern, hostname, prefixlen) != 0))
2942 || (suffixlen && (memcmp(pattern_wildcard + 1, hostname_left_label_end - suffixlen, suffixlen) != 0)))
Evan Broderbe554312013-06-27 00:05:25 -07002943 return 0;
2944
2945 return 1;
2946}
2947
2948static int ssl_sock_srv_verifycbk(int ok, X509_STORE_CTX *ctx)
2949{
2950 SSL *ssl;
2951 struct connection *conn;
2952 char *servername;
2953
2954 int depth;
2955 X509 *cert;
2956 STACK_OF(GENERAL_NAME) *alt_names;
2957 int i;
2958 X509_NAME *cert_subject;
2959 char *str;
2960
2961 if (ok == 0)
2962 return ok;
2963
2964 ssl = X509_STORE_CTX_get_ex_data(ctx, SSL_get_ex_data_X509_STORE_CTX_idx());
Vincent Bernat3c2f2f22016-04-03 13:48:42 +02002965 conn = SSL_get_app_data(ssl);
Evan Broderbe554312013-06-27 00:05:25 -07002966
2967 servername = objt_server(conn->target)->ssl_ctx.verify_host;
2968
2969 /* We only need to verify the CN on the actual server cert,
2970 * not the indirect CAs */
2971 depth = X509_STORE_CTX_get_error_depth(ctx);
2972 if (depth != 0)
2973 return ok;
2974
2975 /* At this point, the cert is *not* OK unless we can find a
2976 * hostname match */
2977 ok = 0;
2978
2979 cert = X509_STORE_CTX_get_current_cert(ctx);
2980 /* It seems like this might happen if verify peer isn't set */
2981 if (!cert)
2982 return ok;
2983
2984 alt_names = X509_get_ext_d2i(cert, NID_subject_alt_name, NULL, NULL);
2985 if (alt_names) {
2986 for (i = 0; !ok && i < sk_GENERAL_NAME_num(alt_names); i++) {
2987 GENERAL_NAME *name = sk_GENERAL_NAME_value(alt_names, i);
2988 if (name->type == GEN_DNS) {
Emeric Bruna33410c2013-09-17 15:47:48 +02002989#if OPENSSL_VERSION_NUMBER < 0x00907000L
2990 if (ASN1_STRING_to_UTF8((unsigned char **)&str, name->d.ia5) >= 0) {
2991#else
Evan Broderbe554312013-06-27 00:05:25 -07002992 if (ASN1_STRING_to_UTF8((unsigned char **)&str, name->d.dNSName) >= 0) {
Emeric Bruna33410c2013-09-17 15:47:48 +02002993#endif
Evan Broderbe554312013-06-27 00:05:25 -07002994 ok = ssl_sock_srv_hostcheck(str, servername);
2995 OPENSSL_free(str);
2996 }
2997 }
2998 }
Emeric Brun4ad50a42013-09-17 15:19:54 +02002999 sk_GENERAL_NAME_pop_free(alt_names, GENERAL_NAME_free);
Evan Broderbe554312013-06-27 00:05:25 -07003000 }
3001
3002 cert_subject = X509_get_subject_name(cert);
3003 i = -1;
3004 while (!ok && (i = X509_NAME_get_index_by_NID(cert_subject, NID_commonName, i)) != -1) {
3005 X509_NAME_ENTRY *entry = X509_NAME_get_entry(cert_subject, i);
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02003006 ASN1_STRING *value;
3007 value = X509_NAME_ENTRY_get_data(entry);
3008 if (ASN1_STRING_to_UTF8((unsigned char **)&str, value) >= 0) {
Evan Broderbe554312013-06-27 00:05:25 -07003009 ok = ssl_sock_srv_hostcheck(str, servername);
3010 OPENSSL_free(str);
3011 }
3012 }
3013
3014 return ok;
3015}
3016
Emeric Brun94324a42012-10-11 14:00:19 +02003017/* prepare ssl context from servers options. Returns an error count */
3018int ssl_sock_prepare_srv_ctx(struct server *srv, struct proxy *curproxy)
3019{
3020 int cfgerr = 0;
Remi Gacogneaf5c3da2014-05-19 10:29:58 +02003021 long options =
Emeric Brun94324a42012-10-11 14:00:19 +02003022 SSL_OP_ALL | /* all known workarounds for bugs */
3023 SSL_OP_NO_SSLv2 |
3024 SSL_OP_NO_COMPRESSION;
Remi Gacogneaf5c3da2014-05-19 10:29:58 +02003025 long mode =
Emeric Brun94324a42012-10-11 14:00:19 +02003026 SSL_MODE_ENABLE_PARTIAL_WRITE |
3027 SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER |
Willy Tarreau396a1862014-11-13 14:06:52 +01003028 SSL_MODE_RELEASE_BUFFERS |
3029 SSL_MODE_SMALL_BUFFERS;
Emeric Brun850efd52014-01-29 12:24:34 +01003030 int verify = SSL_VERIFY_NONE;
Emeric Brun94324a42012-10-11 14:00:19 +02003031
Thierry Fournier383085f2013-01-24 14:15:43 +01003032 /* Make sure openssl opens /dev/urandom before the chroot */
3033 if (!ssl_initialize_random()) {
3034 Alert("OpenSSL random data generator initialization failed.\n");
3035 cfgerr++;
3036 }
3037
Willy Tarreaufce03112015-01-15 21:32:40 +01003038 /* Automatic memory computations need to know we use SSL there */
3039 global.ssl_used_backend = 1;
3040
3041 /* Initiate SSL context for current server */
Emeric Brun94324a42012-10-11 14:00:19 +02003042 srv->ssl_ctx.reused_sess = NULL;
3043 if (srv->use_ssl)
3044 srv->xprt = &ssl_sock;
3045 if (srv->check.use_ssl)
Cyril Bonté9ce13112014-11-15 22:41:27 +01003046 srv->check.xprt = &ssl_sock;
Emeric Brun94324a42012-10-11 14:00:19 +02003047
3048 srv->ssl_ctx.ctx = SSL_CTX_new(SSLv23_client_method());
3049 if (!srv->ssl_ctx.ctx) {
3050 Alert("config : %s '%s', server '%s': unable to allocate ssl context.\n",
3051 proxy_type_str(curproxy), curproxy->id,
3052 srv->id);
3053 cfgerr++;
3054 return cfgerr;
3055 }
Emeric Bruna7aa3092012-10-26 12:58:00 +02003056 if (srv->ssl_ctx.client_crt) {
3057 if (SSL_CTX_use_PrivateKey_file(srv->ssl_ctx.ctx, srv->ssl_ctx.client_crt, SSL_FILETYPE_PEM) <= 0) {
3058 Alert("config : %s '%s', server '%s': unable to load SSL private key from PEM file '%s'.\n",
3059 proxy_type_str(curproxy), curproxy->id,
3060 srv->id, srv->ssl_ctx.client_crt);
3061 cfgerr++;
3062 }
3063 else if (SSL_CTX_use_certificate_chain_file(srv->ssl_ctx.ctx, srv->ssl_ctx.client_crt) <= 0) {
3064 Alert("config : %s '%s', server '%s': unable to load ssl certificate from PEM file '%s'.\n",
3065 proxy_type_str(curproxy), curproxy->id,
3066 srv->id, srv->ssl_ctx.client_crt);
3067 cfgerr++;
3068 }
3069 else if (SSL_CTX_check_private_key(srv->ssl_ctx.ctx) <= 0) {
3070 Alert("config : %s '%s', server '%s': inconsistencies between private key and certificate loaded from PEM file '%s'.\n",
3071 proxy_type_str(curproxy), curproxy->id,
3072 srv->id, srv->ssl_ctx.client_crt);
3073 cfgerr++;
3074 }
3075 }
Emeric Brun94324a42012-10-11 14:00:19 +02003076
3077 if (srv->ssl_ctx.options & SRV_SSL_O_NO_SSLV3)
3078 options |= SSL_OP_NO_SSLv3;
3079 if (srv->ssl_ctx.options & SRV_SSL_O_NO_TLSV10)
3080 options |= SSL_OP_NO_TLSv1;
3081 if (srv->ssl_ctx.options & SRV_SSL_O_NO_TLSV11)
3082 options |= SSL_OP_NO_TLSv1_1;
3083 if (srv->ssl_ctx.options & SRV_SSL_O_NO_TLSV12)
3084 options |= SSL_OP_NO_TLSv1_2;
Emeric Brunf9c5c472012-10-11 15:28:34 +02003085 if (srv->ssl_ctx.options & SRV_SSL_O_NO_TLS_TICKETS)
3086 options |= SSL_OP_NO_TICKET;
Jérémie Courrèges-Anglas17c3f622015-07-25 16:50:52 -06003087 if (srv->ssl_ctx.options & SRV_SSL_O_USE_SSLV3) {
3088#ifndef OPENSSL_NO_SSL3
Emeric Brun94324a42012-10-11 14:00:19 +02003089 SSL_CTX_set_ssl_version(srv->ssl_ctx.ctx, SSLv3_client_method());
Jérémie Courrèges-Anglas17c3f622015-07-25 16:50:52 -06003090#else
Thierry FOURNIERbc965342015-08-26 08:21:26 +02003091 Alert("SSLv3 support requested but unavailable.\n");
Jérémie Courrèges-Anglas17c3f622015-07-25 16:50:52 -06003092 cfgerr++;
3093#endif
3094 }
Emeric Brun94324a42012-10-11 14:00:19 +02003095 if (srv->ssl_ctx.options & SRV_SSL_O_USE_TLSV10)
3096 SSL_CTX_set_ssl_version(srv->ssl_ctx.ctx, TLSv1_client_method());
3097#if SSL_OP_NO_TLSv1_1
3098 if (srv->ssl_ctx.options & SRV_SSL_O_USE_TLSV11)
3099 SSL_CTX_set_ssl_version(srv->ssl_ctx.ctx, TLSv1_1_client_method());
3100#endif
3101#if SSL_OP_NO_TLSv1_2
3102 if (srv->ssl_ctx.options & SRV_SSL_O_USE_TLSV12)
3103 SSL_CTX_set_ssl_version(srv->ssl_ctx.ctx, TLSv1_2_client_method());
3104#endif
3105
3106 SSL_CTX_set_options(srv->ssl_ctx.ctx, options);
3107 SSL_CTX_set_mode(srv->ssl_ctx.ctx, mode);
Emeric Brun850efd52014-01-29 12:24:34 +01003108
3109 if (global.ssl_server_verify == SSL_SERVER_VERIFY_REQUIRED)
3110 verify = SSL_VERIFY_PEER;
3111
3112 switch (srv->ssl_ctx.verify) {
3113 case SSL_SOCK_VERIFY_NONE:
3114 verify = SSL_VERIFY_NONE;
3115 break;
3116 case SSL_SOCK_VERIFY_REQUIRED:
3117 verify = SSL_VERIFY_PEER;
3118 break;
3119 }
Evan Broderbe554312013-06-27 00:05:25 -07003120 SSL_CTX_set_verify(srv->ssl_ctx.ctx,
Emeric Brun850efd52014-01-29 12:24:34 +01003121 verify,
Evan Broderbe554312013-06-27 00:05:25 -07003122 srv->ssl_ctx.verify_host ? ssl_sock_srv_verifycbk : NULL);
Emeric Brun850efd52014-01-29 12:24:34 +01003123 if (verify & SSL_VERIFY_PEER) {
Emeric Brunef42d922012-10-11 16:11:36 +02003124 if (srv->ssl_ctx.ca_file) {
3125 /* load CAfile to verify */
3126 if (!SSL_CTX_load_verify_locations(srv->ssl_ctx.ctx, srv->ssl_ctx.ca_file, NULL)) {
Willy Tarreau07ba08b2014-02-16 19:22:08 +01003127 Alert("Proxy '%s', server '%s' [%s:%d] unable to load CA file '%s'.\n",
Emeric Brunef42d922012-10-11 16:11:36 +02003128 curproxy->id, srv->id,
3129 srv->conf.file, srv->conf.line, srv->ssl_ctx.ca_file);
3130 cfgerr++;
3131 }
3132 }
Emeric Brun850efd52014-01-29 12:24:34 +01003133 else {
3134 if (global.ssl_server_verify == SSL_SERVER_VERIFY_REQUIRED)
Willy Tarreau07ba08b2014-02-16 19:22:08 +01003135 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 +01003136 curproxy->id, srv->id,
3137 srv->conf.file, srv->conf.line);
3138 else
Willy Tarreau07ba08b2014-02-16 19:22:08 +01003139 Alert("Proxy '%s', server '%s' [%s:%d] verify is enabled but no CA file specified.\n",
Emeric Brun850efd52014-01-29 12:24:34 +01003140 curproxy->id, srv->id,
3141 srv->conf.file, srv->conf.line);
3142 cfgerr++;
3143 }
Emeric Brunef42d922012-10-11 16:11:36 +02003144#ifdef X509_V_FLAG_CRL_CHECK
3145 if (srv->ssl_ctx.crl_file) {
3146 X509_STORE *store = SSL_CTX_get_cert_store(srv->ssl_ctx.ctx);
3147
3148 if (!store || !X509_STORE_load_locations(store, srv->ssl_ctx.crl_file, NULL)) {
Willy Tarreau07ba08b2014-02-16 19:22:08 +01003149 Alert("Proxy '%s', server '%s' [%s:%d] unable to configure CRL file '%s'.\n",
Emeric Brunef42d922012-10-11 16:11:36 +02003150 curproxy->id, srv->id,
3151 srv->conf.file, srv->conf.line, srv->ssl_ctx.crl_file);
3152 cfgerr++;
3153 }
3154 else {
3155 X509_STORE_set_flags(store, X509_V_FLAG_CRL_CHECK|X509_V_FLAG_CRL_CHECK_ALL);
3156 }
3157 }
3158#endif
3159 }
3160
Emeric Brun4f65bff2012-11-16 15:11:00 +01003161 if (global.tune.ssllifetime)
3162 SSL_CTX_set_timeout(srv->ssl_ctx.ctx, global.tune.ssllifetime);
3163
Emeric Brun94324a42012-10-11 14:00:19 +02003164 SSL_CTX_set_session_cache_mode(srv->ssl_ctx.ctx, SSL_SESS_CACHE_OFF);
3165 if (srv->ssl_ctx.ciphers &&
3166 !SSL_CTX_set_cipher_list(srv->ssl_ctx.ctx, srv->ssl_ctx.ciphers)) {
3167 Alert("Proxy '%s', server '%s' [%s:%d] : unable to set SSL cipher list to '%s'.\n",
3168 curproxy->id, srv->id,
3169 srv->conf.file, srv->conf.line, srv->ssl_ctx.ciphers);
3170 cfgerr++;
3171 }
3172
3173 return cfgerr;
3174}
3175
Willy Tarreau2a65ff02012-09-13 17:54:29 +02003176/* Walks down the two trees in bind_conf and prepares all certs. The pointer may
Emeric Brunfc0421f2012-09-07 17:30:07 +02003177 * be NULL, in which case nothing is done. Returns the number of errors
3178 * encountered.
3179 */
Willy Tarreau2a65ff02012-09-13 17:54:29 +02003180int ssl_sock_prepare_all_ctx(struct bind_conf *bind_conf, struct proxy *px)
Emeric Brunfc0421f2012-09-07 17:30:07 +02003181{
3182 struct ebmb_node *node;
3183 struct sni_ctx *sni;
3184 int err = 0;
3185
Willy Tarreau2a65ff02012-09-13 17:54:29 +02003186 if (!bind_conf || !bind_conf->is_ssl)
Emeric Brunfc0421f2012-09-07 17:30:07 +02003187 return 0;
3188
Willy Tarreaufce03112015-01-15 21:32:40 +01003189 /* Automatic memory computations need to know we use SSL there */
3190 global.ssl_used_frontend = 1;
3191
Emeric Brun0bed9942014-10-30 19:25:24 +01003192 if (bind_conf->default_ctx)
3193 err += ssl_sock_prepare_ctx(bind_conf, bind_conf->default_ctx, px);
3194
Willy Tarreau2a65ff02012-09-13 17:54:29 +02003195 node = ebmb_first(&bind_conf->sni_ctx);
Emeric Brunfc0421f2012-09-07 17:30:07 +02003196 while (node) {
3197 sni = ebmb_entry(node, struct sni_ctx, name);
Emeric Brun0bed9942014-10-30 19:25:24 +01003198 if (!sni->order && sni->ctx != bind_conf->default_ctx)
3199 /* only initialize the CTX on its first occurrence and
3200 if it is not the default_ctx */
Willy Tarreau2a65ff02012-09-13 17:54:29 +02003201 err += ssl_sock_prepare_ctx(bind_conf, sni->ctx, px);
Emeric Brunfc0421f2012-09-07 17:30:07 +02003202 node = ebmb_next(node);
3203 }
3204
Willy Tarreau2a65ff02012-09-13 17:54:29 +02003205 node = ebmb_first(&bind_conf->sni_w_ctx);
Emeric Brunfc0421f2012-09-07 17:30:07 +02003206 while (node) {
3207 sni = ebmb_entry(node, struct sni_ctx, name);
Emeric Brun0bed9942014-10-30 19:25:24 +01003208 if (!sni->order && sni->ctx != bind_conf->default_ctx)
3209 /* only initialize the CTX on its first occurrence and
3210 if it is not the default_ctx */
Willy Tarreau2a65ff02012-09-13 17:54:29 +02003211 err += ssl_sock_prepare_ctx(bind_conf, sni->ctx, px);
Emeric Brunfc0421f2012-09-07 17:30:07 +02003212 node = ebmb_next(node);
3213 }
3214 return err;
3215}
3216
Christopher Faulet77fe80c2015-07-29 13:02:40 +02003217
3218/* release ssl context allocated for servers. */
3219void ssl_sock_free_srv_ctx(struct server *srv)
3220{
3221 if (srv->ssl_ctx.ctx)
3222 SSL_CTX_free(srv->ssl_ctx.ctx);
3223}
3224
Willy Tarreau2a65ff02012-09-13 17:54:29 +02003225/* Walks down the two trees in bind_conf and frees all the certs. The pointer may
Emeric Brunfc0421f2012-09-07 17:30:07 +02003226 * be NULL, in which case nothing is done. The default_ctx is nullified too.
3227 */
Willy Tarreau2a65ff02012-09-13 17:54:29 +02003228void ssl_sock_free_all_ctx(struct bind_conf *bind_conf)
Emeric Brunfc0421f2012-09-07 17:30:07 +02003229{
3230 struct ebmb_node *node, *back;
3231 struct sni_ctx *sni;
3232
Willy Tarreau2a65ff02012-09-13 17:54:29 +02003233 if (!bind_conf || !bind_conf->is_ssl)
Emeric Brunfc0421f2012-09-07 17:30:07 +02003234 return;
3235
Willy Tarreau2a65ff02012-09-13 17:54:29 +02003236 node = ebmb_first(&bind_conf->sni_ctx);
Emeric Brunfc0421f2012-09-07 17:30:07 +02003237 while (node) {
3238 sni = ebmb_entry(node, struct sni_ctx, name);
3239 back = ebmb_next(node);
3240 ebmb_delete(node);
3241 if (!sni->order) /* only free the CTX on its first occurrence */
3242 SSL_CTX_free(sni->ctx);
3243 free(sni);
3244 node = back;
3245 }
3246
Willy Tarreau2a65ff02012-09-13 17:54:29 +02003247 node = ebmb_first(&bind_conf->sni_w_ctx);
Emeric Brunfc0421f2012-09-07 17:30:07 +02003248 while (node) {
3249 sni = ebmb_entry(node, struct sni_ctx, name);
3250 back = ebmb_next(node);
3251 ebmb_delete(node);
3252 if (!sni->order) /* only free the CTX on its first occurrence */
3253 SSL_CTX_free(sni->ctx);
3254 free(sni);
3255 node = back;
3256 }
3257
Willy Tarreau2a65ff02012-09-13 17:54:29 +02003258 bind_conf->default_ctx = NULL;
Emeric Brune1f38db2012-09-03 20:36:47 +02003259}
3260
Christopher Faulet31af49d2015-06-09 17:29:50 +02003261/* Load CA cert file and private key used to generate certificates */
3262int
3263ssl_sock_load_ca(struct bind_conf *bind_conf, struct proxy *px)
3264{
3265 FILE *fp;
3266 X509 *cacert = NULL;
3267 EVP_PKEY *capkey = NULL;
3268 int err = 0;
3269
3270 if (!bind_conf || !bind_conf->generate_certs)
3271 return err;
3272
Willy Tarreaua84c2672015-10-09 12:10:13 +02003273#ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME
Christopher Fauletd2cab922015-07-28 16:03:47 +02003274 if (global.tune.ssl_ctx_cache)
3275 ssl_ctx_lru_tree = lru64_new(global.tune.ssl_ctx_cache);
3276 ssl_ctx_lru_seed = (unsigned int)time(NULL);
Willy Tarreaua84c2672015-10-09 12:10:13 +02003277#endif
Christopher Fauletd2cab922015-07-28 16:03:47 +02003278
Christopher Faulet31af49d2015-06-09 17:29:50 +02003279 if (!bind_conf->ca_sign_file) {
3280 Alert("Proxy '%s': cannot enable certificate generation, "
3281 "no CA certificate File configured at [%s:%d].\n",
3282 px->id, bind_conf->file, bind_conf->line);
Christopher Faulet31af49d2015-06-09 17:29:50 +02003283 goto load_error;
Christopher Fauletc6f02fb2015-10-09 10:53:31 +02003284 }
Christopher Faulet31af49d2015-06-09 17:29:50 +02003285
3286 /* read in the CA certificate */
3287 if (!(fp = fopen(bind_conf->ca_sign_file, "r"))) {
3288 Alert("Proxy '%s': Failed to read CA certificate file '%s' at [%s:%d].\n",
3289 px->id, bind_conf->ca_sign_file, bind_conf->file, bind_conf->line);
Christopher Faulet31af49d2015-06-09 17:29:50 +02003290 goto load_error;
3291 }
3292 if (!(cacert = PEM_read_X509(fp, NULL, NULL, NULL))) {
3293 Alert("Proxy '%s': Failed to read CA certificate file '%s' at [%s:%d].\n",
3294 px->id, bind_conf->ca_sign_file, bind_conf->file, bind_conf->line);
Christopher Fauletc6f02fb2015-10-09 10:53:31 +02003295 goto read_error;
Christopher Faulet31af49d2015-06-09 17:29:50 +02003296 }
Christopher Fauletc6f02fb2015-10-09 10:53:31 +02003297 rewind(fp);
Christopher Faulet31af49d2015-06-09 17:29:50 +02003298 if (!(capkey = PEM_read_PrivateKey(fp, NULL, NULL, bind_conf->ca_sign_pass))) {
3299 Alert("Proxy '%s': Failed to read CA private key file '%s' at [%s:%d].\n",
3300 px->id, bind_conf->ca_sign_file, bind_conf->file, bind_conf->line);
Christopher Fauletc6f02fb2015-10-09 10:53:31 +02003301 goto read_error;
Christopher Faulet31af49d2015-06-09 17:29:50 +02003302 }
Christopher Faulet31af49d2015-06-09 17:29:50 +02003303
Christopher Fauletc6f02fb2015-10-09 10:53:31 +02003304 fclose (fp);
Christopher Faulet31af49d2015-06-09 17:29:50 +02003305 bind_conf->ca_sign_cert = cacert;
3306 bind_conf->ca_sign_pkey = capkey;
3307 return err;
3308
Christopher Fauletc6f02fb2015-10-09 10:53:31 +02003309 read_error:
3310 fclose (fp);
Christopher Faulet31af49d2015-06-09 17:29:50 +02003311 if (capkey) EVP_PKEY_free(capkey);
3312 if (cacert) X509_free(cacert);
Christopher Fauletc6f02fb2015-10-09 10:53:31 +02003313 load_error:
3314 bind_conf->generate_certs = 0;
3315 err++;
Christopher Faulet31af49d2015-06-09 17:29:50 +02003316 return err;
3317}
3318
3319/* Release CA cert and private key used to generate certificated */
3320void
3321ssl_sock_free_ca(struct bind_conf *bind_conf)
3322{
3323 if (!bind_conf)
3324 return;
3325
3326 if (bind_conf->ca_sign_pkey)
3327 EVP_PKEY_free(bind_conf->ca_sign_pkey);
3328 if (bind_conf->ca_sign_cert)
3329 X509_free(bind_conf->ca_sign_cert);
3330}
3331
Emeric Brun46591952012-05-18 15:47:34 +02003332/*
3333 * This function is called if SSL * context is not yet allocated. The function
3334 * is designed to be called before any other data-layer operation and sets the
3335 * handshake flag on the connection. It is safe to call it multiple times.
3336 * It returns 0 on success and -1 in error case.
3337 */
3338static int ssl_sock_init(struct connection *conn)
3339{
3340 /* already initialized */
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02003341 if (conn->xprt_ctx)
Emeric Brun46591952012-05-18 15:47:34 +02003342 return 0;
3343
Willy Tarreau3c728722014-01-23 13:50:42 +01003344 if (!conn_ctrl_ready(conn))
Willy Tarreauf79c8172013-10-21 16:30:56 +02003345 return 0;
3346
Willy Tarreau20879a02012-12-03 16:32:10 +01003347 if (global.maxsslconn && sslconns >= global.maxsslconn) {
3348 conn->err_code = CO_ER_SSL_TOO_MANY;
Willy Tarreau403edff2012-09-06 11:58:37 +02003349 return -1;
Willy Tarreau20879a02012-12-03 16:32:10 +01003350 }
Willy Tarreau403edff2012-09-06 11:58:37 +02003351
Emeric Brun46591952012-05-18 15:47:34 +02003352 /* If it is in client mode initiate SSL session
3353 in connect state otherwise accept state */
Willy Tarreau3fdb3662012-11-12 00:42:33 +01003354 if (objt_server(conn->target)) {
Willy Tarreaufba03cd2014-11-13 13:48:58 +01003355 int may_retry = 1;
3356
3357 retry_connect:
Emeric Brun46591952012-05-18 15:47:34 +02003358 /* Alloc a new SSL session ctx */
Willy Tarreau3fdb3662012-11-12 00:42:33 +01003359 conn->xprt_ctx = SSL_new(objt_server(conn->target)->ssl_ctx.ctx);
Willy Tarreau20879a02012-12-03 16:32:10 +01003360 if (!conn->xprt_ctx) {
Willy Tarreaufba03cd2014-11-13 13:48:58 +01003361 if (may_retry--) {
3362 pool_gc2();
3363 goto retry_connect;
3364 }
Willy Tarreau20879a02012-12-03 16:32:10 +01003365 conn->err_code = CO_ER_SSL_NO_MEM;
Emeric Brun46591952012-05-18 15:47:34 +02003366 return -1;
Willy Tarreau20879a02012-12-03 16:32:10 +01003367 }
Emeric Brun46591952012-05-18 15:47:34 +02003368
Emeric Brun46591952012-05-18 15:47:34 +02003369 /* set fd on SSL session context */
Emeric Brun55476152014-11-12 17:35:37 +01003370 if (!SSL_set_fd(conn->xprt_ctx, conn->t.sock.fd)) {
3371 SSL_free(conn->xprt_ctx);
3372 conn->xprt_ctx = NULL;
Willy Tarreaufba03cd2014-11-13 13:48:58 +01003373 if (may_retry--) {
3374 pool_gc2();
3375 goto retry_connect;
3376 }
Emeric Brun55476152014-11-12 17:35:37 +01003377 conn->err_code = CO_ER_SSL_NO_MEM;
3378 return -1;
3379 }
Emeric Brun46591952012-05-18 15:47:34 +02003380
Evan Broderbe554312013-06-27 00:05:25 -07003381 /* set connection pointer */
Emeric Brun55476152014-11-12 17:35:37 +01003382 if (!SSL_set_app_data(conn->xprt_ctx, conn)) {
3383 SSL_free(conn->xprt_ctx);
3384 conn->xprt_ctx = NULL;
Willy Tarreaufba03cd2014-11-13 13:48:58 +01003385 if (may_retry--) {
3386 pool_gc2();
3387 goto retry_connect;
3388 }
Emeric Brun55476152014-11-12 17:35:37 +01003389 conn->err_code = CO_ER_SSL_NO_MEM;
3390 return -1;
3391 }
3392
3393 SSL_set_connect_state(conn->xprt_ctx);
3394 if (objt_server(conn->target)->ssl_ctx.reused_sess) {
3395 if(!SSL_set_session(conn->xprt_ctx, objt_server(conn->target)->ssl_ctx.reused_sess)) {
3396 SSL_SESSION_free(objt_server(conn->target)->ssl_ctx.reused_sess);
3397 objt_server(conn->target)->ssl_ctx.reused_sess = NULL;
3398 }
3399 }
Evan Broderbe554312013-06-27 00:05:25 -07003400
Emeric Brun46591952012-05-18 15:47:34 +02003401 /* leave init state and start handshake */
Willy Tarreau05737472012-09-04 08:03:39 +02003402 conn->flags |= CO_FL_SSL_WAIT_HS | CO_FL_WAIT_L6_CONN;
Willy Tarreau403edff2012-09-06 11:58:37 +02003403
3404 sslconns++;
Willy Tarreau71b734c2014-01-28 15:19:44 +01003405 totalsslconns++;
Emeric Brun46591952012-05-18 15:47:34 +02003406 return 0;
3407 }
Willy Tarreau3fdb3662012-11-12 00:42:33 +01003408 else if (objt_listener(conn->target)) {
Willy Tarreaufba03cd2014-11-13 13:48:58 +01003409 int may_retry = 1;
3410
3411 retry_accept:
Emeric Brun46591952012-05-18 15:47:34 +02003412 /* Alloc a new SSL session ctx */
Willy Tarreau3fdb3662012-11-12 00:42:33 +01003413 conn->xprt_ctx = SSL_new(objt_listener(conn->target)->bind_conf->default_ctx);
Willy Tarreau20879a02012-12-03 16:32:10 +01003414 if (!conn->xprt_ctx) {
Willy Tarreaufba03cd2014-11-13 13:48:58 +01003415 if (may_retry--) {
3416 pool_gc2();
3417 goto retry_accept;
3418 }
Willy Tarreau20879a02012-12-03 16:32:10 +01003419 conn->err_code = CO_ER_SSL_NO_MEM;
Emeric Brun46591952012-05-18 15:47:34 +02003420 return -1;
Willy Tarreau20879a02012-12-03 16:32:10 +01003421 }
Emeric Brun46591952012-05-18 15:47:34 +02003422
Emeric Brun46591952012-05-18 15:47:34 +02003423 /* set fd on SSL session context */
Emeric Brun55476152014-11-12 17:35:37 +01003424 if (!SSL_set_fd(conn->xprt_ctx, conn->t.sock.fd)) {
3425 SSL_free(conn->xprt_ctx);
3426 conn->xprt_ctx = NULL;
Willy Tarreaufba03cd2014-11-13 13:48:58 +01003427 if (may_retry--) {
3428 pool_gc2();
3429 goto retry_accept;
3430 }
Emeric Brun55476152014-11-12 17:35:37 +01003431 conn->err_code = CO_ER_SSL_NO_MEM;
3432 return -1;
3433 }
Emeric Brun46591952012-05-18 15:47:34 +02003434
Emeric Brune1f38db2012-09-03 20:36:47 +02003435 /* set connection pointer */
Emeric Brun55476152014-11-12 17:35:37 +01003436 if (!SSL_set_app_data(conn->xprt_ctx, conn)) {
3437 SSL_free(conn->xprt_ctx);
3438 conn->xprt_ctx = NULL;
Willy Tarreaufba03cd2014-11-13 13:48:58 +01003439 if (may_retry--) {
3440 pool_gc2();
3441 goto retry_accept;
3442 }
Emeric Brun55476152014-11-12 17:35:37 +01003443 conn->err_code = CO_ER_SSL_NO_MEM;
3444 return -1;
3445 }
3446
3447 SSL_set_accept_state(conn->xprt_ctx);
Emeric Brune1f38db2012-09-03 20:36:47 +02003448
Emeric Brun46591952012-05-18 15:47:34 +02003449 /* leave init state and start handshake */
Willy Tarreau05737472012-09-04 08:03:39 +02003450 conn->flags |= CO_FL_SSL_WAIT_HS | CO_FL_WAIT_L6_CONN;
Willy Tarreau403edff2012-09-06 11:58:37 +02003451
3452 sslconns++;
Willy Tarreau71b734c2014-01-28 15:19:44 +01003453 totalsslconns++;
Emeric Brun46591952012-05-18 15:47:34 +02003454 return 0;
3455 }
3456 /* don't know how to handle such a target */
Willy Tarreau20879a02012-12-03 16:32:10 +01003457 conn->err_code = CO_ER_SSL_NO_TARGET;
Emeric Brun46591952012-05-18 15:47:34 +02003458 return -1;
3459}
3460
3461
3462/* This is the callback which is used when an SSL handshake is pending. It
3463 * updates the FD status if it wants some polling before being called again.
3464 * It returns 0 if it fails in a fatal way or needs to poll to go further,
3465 * otherwise it returns non-zero and removes itself from the connection's
3466 * flags (the bit is provided in <flag> by the caller).
3467 */
3468int ssl_sock_handshake(struct connection *conn, unsigned int flag)
3469{
3470 int ret;
3471
Willy Tarreau3c728722014-01-23 13:50:42 +01003472 if (!conn_ctrl_ready(conn))
Willy Tarreauf79c8172013-10-21 16:30:56 +02003473 return 0;
3474
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02003475 if (!conn->xprt_ctx)
Emeric Brun46591952012-05-18 15:47:34 +02003476 goto out_error;
3477
Emeric Brun674b7432012-11-08 19:21:55 +01003478 /* If we use SSL_do_handshake to process a reneg initiated by
3479 * the remote peer, it sometimes returns SSL_ERROR_SSL.
3480 * Usually SSL_write and SSL_read are used and process implicitly
3481 * the reneg handshake.
3482 * Here we use SSL_peek as a workaround for reneg.
3483 */
3484 if ((conn->flags & CO_FL_CONNECTED) && SSL_renegotiate_pending(conn->xprt_ctx)) {
3485 char c;
3486
3487 ret = SSL_peek(conn->xprt_ctx, &c, 1);
3488 if (ret <= 0) {
3489 /* handshake may have not been completed, let's find why */
3490 ret = SSL_get_error(conn->xprt_ctx, ret);
3491 if (ret == SSL_ERROR_WANT_WRITE) {
3492 /* SSL handshake needs to write, L4 connection may not be ready */
3493 __conn_sock_stop_recv(conn);
Willy Tarreaue1f50c42014-01-22 20:02:06 +01003494 __conn_sock_want_send(conn);
3495 fd_cant_send(conn->t.sock.fd);
Emeric Brun674b7432012-11-08 19:21:55 +01003496 return 0;
3497 }
3498 else if (ret == SSL_ERROR_WANT_READ) {
3499 /* handshake may have been completed but we have
3500 * no more data to read.
3501 */
3502 if (!SSL_renegotiate_pending(conn->xprt_ctx)) {
3503 ret = 1;
3504 goto reneg_ok;
3505 }
3506 /* SSL handshake needs to read, L4 connection is ready */
3507 if (conn->flags & CO_FL_WAIT_L4_CONN)
3508 conn->flags &= ~CO_FL_WAIT_L4_CONN;
3509 __conn_sock_stop_send(conn);
Willy Tarreaue1f50c42014-01-22 20:02:06 +01003510 __conn_sock_want_recv(conn);
3511 fd_cant_recv(conn->t.sock.fd);
Emeric Brun674b7432012-11-08 19:21:55 +01003512 return 0;
3513 }
3514 else if (ret == SSL_ERROR_SYSCALL) {
3515 /* if errno is null, then connection was successfully established */
3516 if (!errno && conn->flags & CO_FL_WAIT_L4_CONN)
3517 conn->flags &= ~CO_FL_WAIT_L4_CONN;
Willy Tarreau20879a02012-12-03 16:32:10 +01003518 if (!conn->err_code) {
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02003519 int empty_handshake;
3520#if (OPENSSL_VERSION_NUMBER >= 0x1010000fL)
3521 OSSL_HANDSHAKE_STATE state = SSL_get_state((SSL *)conn->xprt_ctx);
3522 empty_handshake = state == TLS_ST_BEFORE;
3523#else
3524 empty_handshake = !((SSL *)conn->xprt_ctx)->packet_length;
3525#endif
3526
3527 if (empty_handshake) {
Emeric Brun29f037d2014-04-25 19:05:36 +02003528 if (!errno) {
3529 if (conn->xprt_st & SSL_SOCK_RECV_HEARTBEAT)
3530 conn->err_code = CO_ER_SSL_HANDSHAKE_HB;
3531 else
3532 conn->err_code = CO_ER_SSL_EMPTY;
3533 }
3534 else {
3535 if (conn->xprt_st & SSL_SOCK_RECV_HEARTBEAT)
3536 conn->err_code = CO_ER_SSL_HANDSHAKE_HB;
3537 else
3538 conn->err_code = CO_ER_SSL_ABORT;
3539 }
3540 }
3541 else {
3542 if (conn->xprt_st & SSL_SOCK_RECV_HEARTBEAT)
3543 conn->err_code = CO_ER_SSL_HANDSHAKE_HB;
Willy Tarreau20879a02012-12-03 16:32:10 +01003544 else
Emeric Brun29f037d2014-04-25 19:05:36 +02003545 conn->err_code = CO_ER_SSL_HANDSHAKE;
3546 }
Willy Tarreau20879a02012-12-03 16:32:10 +01003547 }
Emeric Brun674b7432012-11-08 19:21:55 +01003548 goto out_error;
3549 }
3550 else {
3551 /* Fail on all other handshake errors */
3552 /* Note: OpenSSL may leave unread bytes in the socket's
3553 * buffer, causing an RST to be emitted upon close() on
3554 * TCP sockets. We first try to drain possibly pending
3555 * data to avoid this as much as possible.
3556 */
Willy Tarreaud85c4852015-03-13 00:40:28 +01003557 conn_sock_drain(conn);
Willy Tarreau20879a02012-12-03 16:32:10 +01003558 if (!conn->err_code)
Willy Tarreauf51c6982014-04-25 20:02:39 +02003559 conn->err_code = (conn->xprt_st & SSL_SOCK_RECV_HEARTBEAT) ?
3560 CO_ER_SSL_KILLED_HB : CO_ER_SSL_HANDSHAKE;
Emeric Brun674b7432012-11-08 19:21:55 +01003561 goto out_error;
3562 }
3563 }
3564 /* read some data: consider handshake completed */
3565 goto reneg_ok;
3566 }
3567
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02003568 ret = SSL_do_handshake(conn->xprt_ctx);
Emeric Brun46591952012-05-18 15:47:34 +02003569 if (ret != 1) {
3570 /* handshake did not complete, let's find why */
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02003571 ret = SSL_get_error(conn->xprt_ctx, ret);
Emeric Brun46591952012-05-18 15:47:34 +02003572
3573 if (ret == SSL_ERROR_WANT_WRITE) {
3574 /* SSL handshake needs to write, L4 connection may not be ready */
3575 __conn_sock_stop_recv(conn);
Willy Tarreaue1f50c42014-01-22 20:02:06 +01003576 __conn_sock_want_send(conn);
3577 fd_cant_send(conn->t.sock.fd);
Emeric Brun46591952012-05-18 15:47:34 +02003578 return 0;
3579 }
3580 else if (ret == SSL_ERROR_WANT_READ) {
3581 /* SSL handshake needs to read, L4 connection is ready */
3582 if (conn->flags & CO_FL_WAIT_L4_CONN)
3583 conn->flags &= ~CO_FL_WAIT_L4_CONN;
3584 __conn_sock_stop_send(conn);
Willy Tarreaue1f50c42014-01-22 20:02:06 +01003585 __conn_sock_want_recv(conn);
3586 fd_cant_recv(conn->t.sock.fd);
Emeric Brun46591952012-05-18 15:47:34 +02003587 return 0;
3588 }
Willy Tarreau89230192012-09-28 20:22:13 +02003589 else if (ret == SSL_ERROR_SYSCALL) {
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02003590#if (OPENSSL_VERSION_NUMBER >= 0x1010000fL)
3591 OSSL_HANDSHAKE_STATE state;
3592#endif
3593 int empty_handshake;
Willy Tarreau89230192012-09-28 20:22:13 +02003594 /* if errno is null, then connection was successfully established */
3595 if (!errno && conn->flags & CO_FL_WAIT_L4_CONN)
3596 conn->flags &= ~CO_FL_WAIT_L4_CONN;
Willy Tarreau20879a02012-12-03 16:32:10 +01003597
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02003598#if (OPENSSL_VERSION_NUMBER >= 0x1010000fL)
3599 state = SSL_get_state((SSL *)conn->xprt_ctx);
3600 empty_handshake = state == TLS_ST_BEFORE;
3601#else
3602 empty_handshake = !((SSL *)conn->xprt_ctx)->packet_length;
3603#endif
3604 if (empty_handshake) {
Emeric Brun29f037d2014-04-25 19:05:36 +02003605 if (!errno) {
3606 if (conn->xprt_st & SSL_SOCK_RECV_HEARTBEAT)
3607 conn->err_code = CO_ER_SSL_HANDSHAKE_HB;
3608 else
3609 conn->err_code = CO_ER_SSL_EMPTY;
3610 }
3611 else {
3612 if (conn->xprt_st & SSL_SOCK_RECV_HEARTBEAT)
3613 conn->err_code = CO_ER_SSL_HANDSHAKE_HB;
3614 else
3615 conn->err_code = CO_ER_SSL_ABORT;
3616 }
3617 }
3618 else {
3619 if (conn->xprt_st & SSL_SOCK_RECV_HEARTBEAT)
3620 conn->err_code = CO_ER_SSL_HANDSHAKE_HB;
Willy Tarreau20879a02012-12-03 16:32:10 +01003621 else
Emeric Brun29f037d2014-04-25 19:05:36 +02003622 conn->err_code = CO_ER_SSL_HANDSHAKE;
3623 }
Willy Tarreau89230192012-09-28 20:22:13 +02003624 goto out_error;
3625 }
Emeric Brun46591952012-05-18 15:47:34 +02003626 else {
3627 /* Fail on all other handshake errors */
Willy Tarreau566dc552012-10-19 20:52:18 +02003628 /* Note: OpenSSL may leave unread bytes in the socket's
3629 * buffer, causing an RST to be emitted upon close() on
3630 * TCP sockets. We first try to drain possibly pending
3631 * data to avoid this as much as possible.
3632 */
Willy Tarreaud85c4852015-03-13 00:40:28 +01003633 conn_sock_drain(conn);
Willy Tarreau20879a02012-12-03 16:32:10 +01003634 if (!conn->err_code)
Willy Tarreauf51c6982014-04-25 20:02:39 +02003635 conn->err_code = (conn->xprt_st & SSL_SOCK_RECV_HEARTBEAT) ?
3636 CO_ER_SSL_KILLED_HB : CO_ER_SSL_HANDSHAKE;
Emeric Brun46591952012-05-18 15:47:34 +02003637 goto out_error;
3638 }
3639 }
3640
Emeric Brun674b7432012-11-08 19:21:55 +01003641reneg_ok:
Emeric Brun46591952012-05-18 15:47:34 +02003642 /* Handshake succeeded */
Willy Tarreau0c9c2722014-05-28 12:28:58 +02003643 if (!SSL_session_reused(conn->xprt_ctx)) {
3644 if (objt_server(conn->target)) {
3645 update_freq_ctr(&global.ssl_be_keys_per_sec, 1);
3646 if (global.ssl_be_keys_per_sec.curr_ctr > global.ssl_be_keys_max)
3647 global.ssl_be_keys_max = global.ssl_be_keys_per_sec.curr_ctr;
3648
Emeric Brun46591952012-05-18 15:47:34 +02003649 /* check if session was reused, if not store current session on server for reuse */
Willy Tarreau3fdb3662012-11-12 00:42:33 +01003650 if (objt_server(conn->target)->ssl_ctx.reused_sess)
3651 SSL_SESSION_free(objt_server(conn->target)->ssl_ctx.reused_sess);
Emeric Brun46591952012-05-18 15:47:34 +02003652
Willy Tarreau2a3fb1c2015-02-05 16:47:07 +01003653 if (!(objt_server(conn->target)->ssl_ctx.options & SRV_SSL_O_NO_REUSE))
3654 objt_server(conn->target)->ssl_ctx.reused_sess = SSL_get1_session(conn->xprt_ctx);
Emeric Brun46591952012-05-18 15:47:34 +02003655 }
Willy Tarreau0c9c2722014-05-28 12:28:58 +02003656 else {
3657 update_freq_ctr(&global.ssl_fe_keys_per_sec, 1);
3658 if (global.ssl_fe_keys_per_sec.curr_ctr > global.ssl_fe_keys_max)
3659 global.ssl_fe_keys_max = global.ssl_fe_keys_per_sec.curr_ctr;
3660 }
Emeric Brun46591952012-05-18 15:47:34 +02003661 }
3662
3663 /* The connection is now established at both layers, it's time to leave */
3664 conn->flags &= ~(flag | CO_FL_WAIT_L4_CONN | CO_FL_WAIT_L6_CONN);
3665 return 1;
3666
3667 out_error:
Emeric Brun644cde02012-12-14 11:21:13 +01003668 /* Clear openssl global errors stack */
Thierry FOURNIER / OZON.IO8b068c22016-10-10 11:59:50 +02003669 ssl_sock_dump_errors(conn);
Emeric Brun644cde02012-12-14 11:21:13 +01003670 ERR_clear_error();
3671
Emeric Brun9fa89732012-10-04 17:09:56 +02003672 /* free resumed session if exists */
Willy Tarreau3fdb3662012-11-12 00:42:33 +01003673 if (objt_server(conn->target) && objt_server(conn->target)->ssl_ctx.reused_sess) {
3674 SSL_SESSION_free(objt_server(conn->target)->ssl_ctx.reused_sess);
3675 objt_server(conn->target)->ssl_ctx.reused_sess = NULL;
Emeric Brun9fa89732012-10-04 17:09:56 +02003676 }
3677
Emeric Brun46591952012-05-18 15:47:34 +02003678 /* Fail on all other handshake errors */
3679 conn->flags |= CO_FL_ERROR;
Willy Tarreau20879a02012-12-03 16:32:10 +01003680 if (!conn->err_code)
3681 conn->err_code = CO_ER_SSL_HANDSHAKE;
Emeric Brun46591952012-05-18 15:47:34 +02003682 return 0;
3683}
3684
3685/* Receive up to <count> bytes from connection <conn>'s socket and store them
Willy Tarreauabf08d92014-01-14 11:31:27 +01003686 * into buffer <buf>. Only one call to recv() is performed, unless the
Emeric Brun46591952012-05-18 15:47:34 +02003687 * buffer wraps, in which case a second call may be performed. The connection's
3688 * flags are updated with whatever special event is detected (error, read0,
3689 * empty). The caller is responsible for taking care of those events and
3690 * avoiding the call if inappropriate. The function does not call the
3691 * connection's polling update function, so the caller is responsible for this.
3692 */
3693static int ssl_sock_to_buf(struct connection *conn, struct buffer *buf, int count)
3694{
3695 int ret, done = 0;
Willy Tarreauabf08d92014-01-14 11:31:27 +01003696 int try;
Emeric Brun46591952012-05-18 15:47:34 +02003697
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02003698 if (!conn->xprt_ctx)
Emeric Brun46591952012-05-18 15:47:34 +02003699 goto out_error;
3700
3701 if (conn->flags & CO_FL_HANDSHAKE)
3702 /* a handshake was requested */
3703 return 0;
3704
Willy Tarreauabf08d92014-01-14 11:31:27 +01003705 /* let's realign the buffer to optimize I/O */
3706 if (buffer_empty(buf))
Emeric Brun46591952012-05-18 15:47:34 +02003707 buf->p = buf->data;
Emeric Brun46591952012-05-18 15:47:34 +02003708
3709 /* read the largest possible block. For this, we perform only one call
3710 * to recv() unless the buffer wraps and we exactly fill the first hunk,
3711 * in which case we accept to do it once again. A new attempt is made on
3712 * EINTR too.
3713 */
Willy Tarreau00b0fb92014-01-17 11:09:40 +01003714 while (count > 0) {
Willy Tarreauabf08d92014-01-14 11:31:27 +01003715 /* first check if we have some room after p+i */
3716 try = buf->data + buf->size - (buf->p + buf->i);
3717 /* otherwise continue between data and p-o */
3718 if (try <= 0) {
3719 try = buf->p - (buf->data + buf->o);
3720 if (try <= 0)
3721 break;
3722 }
3723 if (try > count)
3724 try = count;
3725
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02003726 ret = SSL_read(conn->xprt_ctx, bi_end(buf), try);
Emeric Brune1f38db2012-09-03 20:36:47 +02003727 if (conn->flags & CO_FL_ERROR) {
3728 /* CO_FL_ERROR may be set by ssl_sock_infocbk */
Emeric Brun644cde02012-12-14 11:21:13 +01003729 goto out_error;
Emeric Brune1f38db2012-09-03 20:36:47 +02003730 }
Emeric Brun46591952012-05-18 15:47:34 +02003731 if (ret > 0) {
3732 buf->i += ret;
3733 done += ret;
3734 if (ret < try)
3735 break;
3736 count -= ret;
Emeric Brun46591952012-05-18 15:47:34 +02003737 }
3738 else if (ret == 0) {
Emeric Brun644cde02012-12-14 11:21:13 +01003739 ret = SSL_get_error(conn->xprt_ctx, ret);
3740 if (ret != SSL_ERROR_ZERO_RETURN) {
Emeric Brun1c646862012-12-14 12:33:41 +01003741 /* error on protocol or underlying transport */
3742 if ((ret != SSL_ERROR_SYSCALL)
3743 || (errno && (errno != EAGAIN)))
3744 conn->flags |= CO_FL_ERROR;
3745
Emeric Brun644cde02012-12-14 11:21:13 +01003746 /* Clear openssl global errors stack */
Thierry FOURNIER / OZON.IO8b068c22016-10-10 11:59:50 +02003747 ssl_sock_dump_errors(conn);
Emeric Brun644cde02012-12-14 11:21:13 +01003748 ERR_clear_error();
3749 }
Emeric Brun46591952012-05-18 15:47:34 +02003750 goto read0;
3751 }
3752 else {
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02003753 ret = SSL_get_error(conn->xprt_ctx, ret);
Emeric Brun46591952012-05-18 15:47:34 +02003754 if (ret == SSL_ERROR_WANT_WRITE) {
Emeric Brun8af8dd12012-11-08 17:56:20 +01003755 /* handshake is running, and it needs to enable write */
Emeric Brun46591952012-05-18 15:47:34 +02003756 conn->flags |= CO_FL_SSL_WAIT_HS;
Emeric Brun8af8dd12012-11-08 17:56:20 +01003757 __conn_sock_want_send(conn);
Emeric Brun46591952012-05-18 15:47:34 +02003758 break;
3759 }
3760 else if (ret == SSL_ERROR_WANT_READ) {
Emeric Brun282a76a2012-11-08 18:02:56 +01003761 if (SSL_renegotiate_pending(conn->xprt_ctx)) {
3762 /* handshake is running, and it may need to re-enable read */
3763 conn->flags |= CO_FL_SSL_WAIT_HS;
3764 __conn_sock_want_recv(conn);
3765 break;
3766 }
Emeric Brun46591952012-05-18 15:47:34 +02003767 /* we need to poll for retry a read later */
Willy Tarreaue1f50c42014-01-22 20:02:06 +01003768 fd_cant_recv(conn->t.sock.fd);
Emeric Brun46591952012-05-18 15:47:34 +02003769 break;
3770 }
3771 /* otherwise it's a real error */
3772 goto out_error;
3773 }
3774 }
3775 return done;
3776
3777 read0:
3778 conn_sock_read0(conn);
3779 return done;
3780 out_error:
Emeric Brun644cde02012-12-14 11:21:13 +01003781 /* Clear openssl global errors stack */
Thierry FOURNIER / OZON.IO8b068c22016-10-10 11:59:50 +02003782 ssl_sock_dump_errors(conn);
Emeric Brun644cde02012-12-14 11:21:13 +01003783 ERR_clear_error();
3784
Emeric Brun46591952012-05-18 15:47:34 +02003785 conn->flags |= CO_FL_ERROR;
3786 return done;
3787}
3788
3789
3790/* Send all pending bytes from buffer <buf> to connection <conn>'s socket.
Willy Tarreau1049b1f2014-02-02 01:51:17 +01003791 * <flags> may contain some CO_SFL_* flags to hint the system about other
3792 * pending data for example, but this flag is ignored at the moment.
Emeric Brun46591952012-05-18 15:47:34 +02003793 * Only one call to send() is performed, unless the buffer wraps, in which case
3794 * a second call may be performed. The connection's flags are updated with
3795 * whatever special event is detected (error, empty). The caller is responsible
3796 * for taking care of those events and avoiding the call if inappropriate. The
3797 * function does not call the connection's polling update function, so the caller
3798 * is responsible for this.
3799 */
3800static int ssl_sock_from_buf(struct connection *conn, struct buffer *buf, int flags)
3801{
3802 int ret, try, done;
3803
3804 done = 0;
3805
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02003806 if (!conn->xprt_ctx)
Emeric Brun46591952012-05-18 15:47:34 +02003807 goto out_error;
3808
3809 if (conn->flags & CO_FL_HANDSHAKE)
3810 /* a handshake was requested */
3811 return 0;
3812
3813 /* send the largest possible block. For this we perform only one call
3814 * to send() unless the buffer wraps and we exactly fill the first hunk,
3815 * in which case we accept to do it once again.
3816 */
3817 while (buf->o) {
Kevin Hestercad82342013-05-30 15:12:41 -07003818 try = bo_contig_data(buf);
Willy Tarreaubfd59462013-02-21 07:46:09 +01003819
Willy Tarreau7bed9452014-02-02 02:00:24 +01003820 if (!(flags & CO_SFL_STREAMER) &&
Willy Tarreau518cedd2014-02-17 15:43:01 +01003821 !(conn->xprt_st & SSL_SOCK_SEND_UNLIMITED) &&
3822 global.tune.ssl_max_record && try > global.tune.ssl_max_record) {
Willy Tarreaubfd59462013-02-21 07:46:09 +01003823 try = global.tune.ssl_max_record;
Willy Tarreau518cedd2014-02-17 15:43:01 +01003824 }
3825 else {
3826 /* we need to keep the information about the fact that
3827 * we're not limiting the upcoming send(), because if it
3828 * fails, we'll have to retry with at least as many data.
3829 */
3830 conn->xprt_st |= SSL_SOCK_SEND_UNLIMITED;
3831 }
Willy Tarreaubfd59462013-02-21 07:46:09 +01003832
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02003833 ret = SSL_write(conn->xprt_ctx, bo_ptr(buf), try);
Willy Tarreau518cedd2014-02-17 15:43:01 +01003834
Emeric Brune1f38db2012-09-03 20:36:47 +02003835 if (conn->flags & CO_FL_ERROR) {
3836 /* CO_FL_ERROR may be set by ssl_sock_infocbk */
Emeric Brun644cde02012-12-14 11:21:13 +01003837 goto out_error;
Emeric Brune1f38db2012-09-03 20:36:47 +02003838 }
Emeric Brun46591952012-05-18 15:47:34 +02003839 if (ret > 0) {
Willy Tarreau518cedd2014-02-17 15:43:01 +01003840 conn->xprt_st &= ~SSL_SOCK_SEND_UNLIMITED;
3841
Emeric Brun46591952012-05-18 15:47:34 +02003842 buf->o -= ret;
3843 done += ret;
3844
Willy Tarreau5fb38032012-12-16 19:39:09 +01003845 if (likely(buffer_empty(buf)))
Emeric Brun46591952012-05-18 15:47:34 +02003846 /* optimize data alignment in the buffer */
3847 buf->p = buf->data;
3848
3849 /* if the system buffer is full, don't insist */
3850 if (ret < try)
3851 break;
3852 }
3853 else {
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02003854 ret = SSL_get_error(conn->xprt_ctx, ret);
Emeric Brun46591952012-05-18 15:47:34 +02003855 if (ret == SSL_ERROR_WANT_WRITE) {
Emeric Brun282a76a2012-11-08 18:02:56 +01003856 if (SSL_renegotiate_pending(conn->xprt_ctx)) {
3857 /* handshake is running, and it may need to re-enable write */
3858 conn->flags |= CO_FL_SSL_WAIT_HS;
3859 __conn_sock_want_send(conn);
3860 break;
3861 }
Emeric Brun46591952012-05-18 15:47:34 +02003862 /* we need to poll to retry a write later */
Willy Tarreaue1f50c42014-01-22 20:02:06 +01003863 fd_cant_send(conn->t.sock.fd);
Emeric Brun46591952012-05-18 15:47:34 +02003864 break;
3865 }
3866 else if (ret == SSL_ERROR_WANT_READ) {
Emeric Brun8af8dd12012-11-08 17:56:20 +01003867 /* handshake is running, and it needs to enable read */
Emeric Brun46591952012-05-18 15:47:34 +02003868 conn->flags |= CO_FL_SSL_WAIT_HS;
Emeric Brun8af8dd12012-11-08 17:56:20 +01003869 __conn_sock_want_recv(conn);
Emeric Brun46591952012-05-18 15:47:34 +02003870 break;
3871 }
3872 goto out_error;
3873 }
3874 }
3875 return done;
3876
3877 out_error:
Emeric Brun644cde02012-12-14 11:21:13 +01003878 /* Clear openssl global errors stack */
Thierry FOURNIER / OZON.IO8b068c22016-10-10 11:59:50 +02003879 ssl_sock_dump_errors(conn);
Emeric Brun644cde02012-12-14 11:21:13 +01003880 ERR_clear_error();
3881
Emeric Brun46591952012-05-18 15:47:34 +02003882 conn->flags |= CO_FL_ERROR;
3883 return done;
3884}
3885
Emeric Brun46591952012-05-18 15:47:34 +02003886static void ssl_sock_close(struct connection *conn) {
3887
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02003888 if (conn->xprt_ctx) {
3889 SSL_free(conn->xprt_ctx);
3890 conn->xprt_ctx = NULL;
Willy Tarreau403edff2012-09-06 11:58:37 +02003891 sslconns--;
Emeric Brun46591952012-05-18 15:47:34 +02003892 }
Emeric Brun46591952012-05-18 15:47:34 +02003893}
3894
3895/* This function tries to perform a clean shutdown on an SSL connection, and in
3896 * any case, flags the connection as reusable if no handshake was in progress.
3897 */
3898static void ssl_sock_shutw(struct connection *conn, int clean)
3899{
3900 if (conn->flags & CO_FL_HANDSHAKE)
3901 return;
3902 /* no handshake was in progress, try a clean ssl shutdown */
Emeric Brun644cde02012-12-14 11:21:13 +01003903 if (clean && (SSL_shutdown(conn->xprt_ctx) <= 0)) {
3904 /* Clear openssl global errors stack */
Thierry FOURNIER / OZON.IO8b068c22016-10-10 11:59:50 +02003905 ssl_sock_dump_errors(conn);
Emeric Brun644cde02012-12-14 11:21:13 +01003906 ERR_clear_error();
3907 }
Emeric Brun46591952012-05-18 15:47:34 +02003908
3909 /* force flag on ssl to keep session in cache regardless shutdown result */
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02003910 SSL_set_shutdown(conn->xprt_ctx, SSL_SENT_SHUTDOWN);
Emeric Brun46591952012-05-18 15:47:34 +02003911}
3912
Willy Tarreauffc3fcd2012-10-12 20:17:54 +02003913/* used for logging, may be changed for a sample fetch later */
3914const char *ssl_sock_get_cipher_name(struct connection *conn)
3915{
3916 if (!conn->xprt && !conn->xprt_ctx)
3917 return NULL;
3918 return SSL_get_cipher_name(conn->xprt_ctx);
3919}
3920
3921/* used for logging, may be changed for a sample fetch later */
3922const char *ssl_sock_get_proto_version(struct connection *conn)
3923{
3924 if (!conn->xprt && !conn->xprt_ctx)
3925 return NULL;
3926 return SSL_get_version(conn->xprt_ctx);
3927}
3928
Willy Tarreau8d598402012-10-22 17:58:39 +02003929/* Extract a serial from a cert, and copy it to a chunk.
3930 * Returns 1 if serial is found and copied, 0 if no serial found and
3931 * -1 if output is not large enough.
3932 */
3933static int
3934ssl_sock_get_serial(X509 *crt, struct chunk *out)
3935{
3936 ASN1_INTEGER *serial;
3937
3938 serial = X509_get_serialNumber(crt);
3939 if (!serial)
3940 return 0;
3941
3942 if (out->size < serial->length)
3943 return -1;
3944
3945 memcpy(out->str, serial->data, serial->length);
3946 out->len = serial->length;
3947 return 1;
3948}
3949
Emeric Brun43e79582014-10-29 19:03:26 +01003950/* Extract a cert to der, and copy it to a chunk.
3951 * Returns 1 if cert is found and copied, 0 on der convertion failure and
3952 * -1 if output is not large enough.
3953 */
3954static int
3955ssl_sock_crt2der(X509 *crt, struct chunk *out)
3956{
3957 int len;
3958 unsigned char *p = (unsigned char *)out->str;;
3959
3960 len =i2d_X509(crt, NULL);
3961 if (len <= 0)
3962 return 1;
3963
3964 if (out->size < len)
3965 return -1;
3966
3967 i2d_X509(crt,&p);
3968 out->len = len;
3969 return 1;
3970}
3971
Emeric Brunce5ad802012-10-22 14:11:22 +02003972
3973/* Copy Date in ASN1_UTCTIME format in struct chunk out.
3974 * Returns 1 if serial is found and copied, 0 if no valid time found
3975 * and -1 if output is not large enough.
3976 */
3977static int
3978ssl_sock_get_time(ASN1_TIME *tm, struct chunk *out)
3979{
3980 if (tm->type == V_ASN1_GENERALIZEDTIME) {
3981 ASN1_GENERALIZEDTIME *gentm = (ASN1_GENERALIZEDTIME *)tm;
3982
3983 if (gentm->length < 12)
3984 return 0;
3985 if (gentm->data[0] != 0x32 || gentm->data[1] != 0x30)
3986 return 0;
3987 if (out->size < gentm->length-2)
3988 return -1;
3989
3990 memcpy(out->str, gentm->data+2, gentm->length-2);
3991 out->len = gentm->length-2;
3992 return 1;
3993 }
3994 else if (tm->type == V_ASN1_UTCTIME) {
3995 ASN1_UTCTIME *utctm = (ASN1_UTCTIME *)tm;
3996
3997 if (utctm->length < 10)
3998 return 0;
3999 if (utctm->data[0] >= 0x35)
4000 return 0;
4001 if (out->size < utctm->length)
4002 return -1;
4003
4004 memcpy(out->str, utctm->data, utctm->length);
4005 out->len = utctm->length;
4006 return 1;
4007 }
4008
4009 return 0;
4010}
4011
Emeric Brun87855892012-10-17 17:39:35 +02004012/* Extract an entry from a X509_NAME and copy its value to an output chunk.
4013 * Returns 1 if entry found, 0 if entry not found, or -1 if output not large enough.
4014 */
4015static int
4016ssl_sock_get_dn_entry(X509_NAME *a, const struct chunk *entry, int pos, struct chunk *out)
4017{
4018 X509_NAME_ENTRY *ne;
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02004019 ASN1_OBJECT *obj;
4020 ASN1_STRING *data;
4021 const unsigned char *data_ptr;
4022 int data_len;
Emeric Brun87855892012-10-17 17:39:35 +02004023 int i, j, n;
4024 int cur = 0;
4025 const char *s;
4026 char tmp[128];
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02004027 int name_count;
4028
4029 name_count = X509_NAME_entry_count(a);
Emeric Brun87855892012-10-17 17:39:35 +02004030
4031 out->len = 0;
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02004032 for (i = 0; i < name_count; i++) {
Emeric Brun87855892012-10-17 17:39:35 +02004033 if (pos < 0)
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02004034 j = (name_count-1) - i;
Emeric Brun87855892012-10-17 17:39:35 +02004035 else
4036 j = i;
4037
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02004038 ne = X509_NAME_get_entry(a, j);
4039 obj = X509_NAME_ENTRY_get_object(ne);
4040 data = X509_NAME_ENTRY_get_data(ne);
4041 data_ptr = ASN1_STRING_get0_data(data);
4042 data_len = ASN1_STRING_length(data);
4043 n = OBJ_obj2nid(obj);
Emeric Brun87855892012-10-17 17:39:35 +02004044 if ((n == NID_undef) || ((s = OBJ_nid2sn(n)) == NULL)) {
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02004045 i2t_ASN1_OBJECT(tmp, sizeof(tmp), obj);
Emeric Brun87855892012-10-17 17:39:35 +02004046 s = tmp;
4047 }
4048
4049 if (chunk_strcasecmp(entry, s) != 0)
4050 continue;
4051
4052 if (pos < 0)
4053 cur--;
4054 else
4055 cur++;
4056
4057 if (cur != pos)
4058 continue;
4059
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02004060 if (data_len > out->size)
Emeric Brun87855892012-10-17 17:39:35 +02004061 return -1;
4062
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02004063 memcpy(out->str, data_ptr, data_len);
4064 out->len = data_len;
Emeric Brun87855892012-10-17 17:39:35 +02004065 return 1;
4066 }
4067
4068 return 0;
4069
4070}
4071
4072/* Extract and format full DN from a X509_NAME and copy result into a chunk
4073 * Returns 1 if dn entries exits, 0 if no dn entry found or -1 if output is not large enough.
4074 */
4075static int
4076ssl_sock_get_dn_oneline(X509_NAME *a, struct chunk *out)
4077{
4078 X509_NAME_ENTRY *ne;
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02004079 ASN1_OBJECT *obj;
4080 ASN1_STRING *data;
4081 const unsigned char *data_ptr;
4082 int data_len;
Emeric Brun87855892012-10-17 17:39:35 +02004083 int i, n, ln;
4084 int l = 0;
4085 const char *s;
4086 char *p;
4087 char tmp[128];
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02004088 int name_count;
4089
4090
4091 name_count = X509_NAME_entry_count(a);
Emeric Brun87855892012-10-17 17:39:35 +02004092
4093 out->len = 0;
4094 p = out->str;
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02004095 for (i = 0; i < name_count; i++) {
4096 ne = X509_NAME_get_entry(a, i);
4097 obj = X509_NAME_ENTRY_get_object(ne);
4098 data = X509_NAME_ENTRY_get_data(ne);
4099 data_ptr = ASN1_STRING_get0_data(data);
4100 data_len = ASN1_STRING_length(data);
4101 n = OBJ_obj2nid(obj);
Emeric Brun87855892012-10-17 17:39:35 +02004102 if ((n == NID_undef) || ((s = OBJ_nid2sn(n)) == NULL)) {
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02004103 i2t_ASN1_OBJECT(tmp, sizeof(tmp), obj);
Emeric Brun87855892012-10-17 17:39:35 +02004104 s = tmp;
4105 }
4106 ln = strlen(s);
4107
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02004108 l += 1 + ln + 1 + data_len;
Emeric Brun87855892012-10-17 17:39:35 +02004109 if (l > out->size)
4110 return -1;
4111 out->len = l;
4112
4113 *(p++)='/';
4114 memcpy(p, s, ln);
4115 p += ln;
4116 *(p++)='=';
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02004117 memcpy(p, data_ptr, data_len);
4118 p += data_len;
Emeric Brun87855892012-10-17 17:39:35 +02004119 }
4120
4121 if (!out->len)
4122 return 0;
4123
4124 return 1;
4125}
4126
David Safb76832014-05-08 23:42:08 -04004127char *ssl_sock_get_version(struct connection *conn)
4128{
4129 if (!ssl_sock_is_ssl(conn))
4130 return NULL;
4131
4132 return (char *)SSL_get_version(conn->xprt_ctx);
4133}
4134
Willy Tarreau63076412015-07-10 11:33:32 +02004135void ssl_sock_set_servername(struct connection *conn, const char *hostname)
4136{
4137#ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME
4138 if (!ssl_sock_is_ssl(conn))
4139 return;
4140
4141 SSL_set_tlsext_host_name(conn->xprt_ctx, hostname);
4142#endif
4143}
4144
Emeric Brun0abf8362014-06-24 18:26:41 +02004145/* Extract peer certificate's common name into the chunk dest
4146 * Returns
4147 * the len of the extracted common name
4148 * or 0 if no CN found in DN
4149 * or -1 on error case (i.e. no peer certificate)
4150 */
4151int ssl_sock_get_remote_common_name(struct connection *conn, struct chunk *dest)
David Safb76832014-05-08 23:42:08 -04004152{
4153 X509 *crt = NULL;
4154 X509_NAME *name;
David Safb76832014-05-08 23:42:08 -04004155 const char find_cn[] = "CN";
4156 const struct chunk find_cn_chunk = {
4157 .str = (char *)&find_cn,
4158 .len = sizeof(find_cn)-1
4159 };
Emeric Brun0abf8362014-06-24 18:26:41 +02004160 int result = -1;
David Safb76832014-05-08 23:42:08 -04004161
4162 if (!ssl_sock_is_ssl(conn))
Emeric Brun0abf8362014-06-24 18:26:41 +02004163 goto out;
David Safb76832014-05-08 23:42:08 -04004164
4165 /* SSL_get_peer_certificate, it increase X509 * ref count */
4166 crt = SSL_get_peer_certificate(conn->xprt_ctx);
4167 if (!crt)
4168 goto out;
4169
4170 name = X509_get_subject_name(crt);
4171 if (!name)
4172 goto out;
David Safb76832014-05-08 23:42:08 -04004173
Emeric Brun0abf8362014-06-24 18:26:41 +02004174 result = ssl_sock_get_dn_entry(name, &find_cn_chunk, 1, dest);
4175out:
David Safb76832014-05-08 23:42:08 -04004176 if (crt)
4177 X509_free(crt);
4178
4179 return result;
4180}
4181
Dave McCowan328fb582014-07-30 10:39:13 -04004182/* returns 1 if client passed a certificate for this session, 0 if not */
4183int ssl_sock_get_cert_used_sess(struct connection *conn)
4184{
4185 X509 *crt = NULL;
4186
4187 if (!ssl_sock_is_ssl(conn))
4188 return 0;
4189
4190 /* SSL_get_peer_certificate, it increase X509 * ref count */
4191 crt = SSL_get_peer_certificate(conn->xprt_ctx);
4192 if (!crt)
4193 return 0;
4194
4195 X509_free(crt);
4196 return 1;
4197}
4198
4199/* returns 1 if client passed a certificate for this connection, 0 if not */
4200int ssl_sock_get_cert_used_conn(struct connection *conn)
David Safb76832014-05-08 23:42:08 -04004201{
4202 if (!ssl_sock_is_ssl(conn))
4203 return 0;
4204
4205 return SSL_SOCK_ST_FL_VERIFY_DONE & conn->xprt_st ? 1 : 0;
4206}
4207
4208/* returns result from SSL verify */
4209unsigned int ssl_sock_get_verify_result(struct connection *conn)
4210{
4211 if (!ssl_sock_is_ssl(conn))
4212 return (unsigned int)X509_V_ERR_APPLICATION_VERIFICATION;
4213
4214 return (unsigned int)SSL_get_verify_result(conn->xprt_ctx);
4215}
4216
Willy Tarreau7875d092012-09-10 08:20:03 +02004217/***** Below are some sample fetching functions for ACL/patterns *****/
4218
Emeric Brune64aef12012-09-21 13:15:06 +02004219/* boolean, returns true if client cert was present */
4220static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02004221smp_fetch_ssl_fc_has_crt(const struct arg *args, struct sample *smp, const char *kw, void *private)
Emeric Brune64aef12012-09-21 13:15:06 +02004222{
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004223 struct connection *conn;
4224
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02004225 conn = objt_conn(smp->sess->origin);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004226 if (!conn || conn->xprt != &ssl_sock)
Emeric Brune64aef12012-09-21 13:15:06 +02004227 return 0;
4228
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004229 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brune64aef12012-09-21 13:15:06 +02004230 smp->flags |= SMP_F_MAY_CHANGE;
4231 return 0;
4232 }
4233
4234 smp->flags = 0;
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02004235 smp->data.type = SMP_T_BOOL;
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02004236 smp->data.u.sint = SSL_SOCK_ST_FL_VERIFY_DONE & conn->xprt_st ? 1 : 0;
Emeric Brune64aef12012-09-21 13:15:06 +02004237
4238 return 1;
4239}
4240
Emeric Brun43e79582014-10-29 19:03:26 +01004241/* binary, returns a certificate in a binary chunk (der/raw).
4242 * The 5th keyword char is used to know if SSL_get_certificate or SSL_get_peer_certificate
4243 * should be use.
4244 */
4245static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02004246smp_fetch_ssl_x_der(const struct arg *args, struct sample *smp, const char *kw, void *private)
Emeric Brun43e79582014-10-29 19:03:26 +01004247{
4248 int cert_peer = (kw[4] == 'c') ? 1 : 0;
4249 X509 *crt = NULL;
4250 int ret = 0;
4251 struct chunk *smp_trash;
4252 struct connection *conn;
4253
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02004254 conn = objt_conn(smp->sess->origin);
Emeric Brun43e79582014-10-29 19:03:26 +01004255 if (!conn || conn->xprt != &ssl_sock)
4256 return 0;
4257
4258 if (!(conn->flags & CO_FL_CONNECTED)) {
4259 smp->flags |= SMP_F_MAY_CHANGE;
4260 return 0;
4261 }
4262
4263 if (cert_peer)
4264 crt = SSL_get_peer_certificate(conn->xprt_ctx);
4265 else
4266 crt = SSL_get_certificate(conn->xprt_ctx);
4267
4268 if (!crt)
4269 goto out;
4270
4271 smp_trash = get_trash_chunk();
4272 if (ssl_sock_crt2der(crt, smp_trash) <= 0)
4273 goto out;
4274
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02004275 smp->data.u.str = *smp_trash;
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02004276 smp->data.type = SMP_T_BIN;
Emeric Brun43e79582014-10-29 19:03:26 +01004277 ret = 1;
4278out:
4279 /* SSL_get_peer_certificate, it increase X509 * ref count */
4280 if (cert_peer && crt)
4281 X509_free(crt);
4282 return ret;
4283}
4284
Emeric Brunba841a12014-04-30 17:05:08 +02004285/* binary, returns serial of certificate in a binary chunk.
4286 * The 5th keyword char is used to know if SSL_get_certificate or SSL_get_peer_certificate
4287 * should be use.
4288 */
Willy Tarreau8d598402012-10-22 17:58:39 +02004289static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02004290smp_fetch_ssl_x_serial(const struct arg *args, struct sample *smp, const char *kw, void *private)
Willy Tarreau8d598402012-10-22 17:58:39 +02004291{
Emeric Brunba841a12014-04-30 17:05:08 +02004292 int cert_peer = (kw[4] == 'c') ? 1 : 0;
Willy Tarreau8d598402012-10-22 17:58:39 +02004293 X509 *crt = NULL;
4294 int ret = 0;
4295 struct chunk *smp_trash;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004296 struct connection *conn;
4297
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02004298 conn = objt_conn(smp->sess->origin);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004299 if (!conn || conn->xprt != &ssl_sock)
Willy Tarreau8d598402012-10-22 17:58:39 +02004300 return 0;
4301
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004302 if (!(conn->flags & CO_FL_CONNECTED)) {
Willy Tarreau8d598402012-10-22 17:58:39 +02004303 smp->flags |= SMP_F_MAY_CHANGE;
4304 return 0;
4305 }
4306
Emeric Brunba841a12014-04-30 17:05:08 +02004307 if (cert_peer)
4308 crt = SSL_get_peer_certificate(conn->xprt_ctx);
4309 else
4310 crt = SSL_get_certificate(conn->xprt_ctx);
4311
Willy Tarreau8d598402012-10-22 17:58:39 +02004312 if (!crt)
4313 goto out;
4314
Willy Tarreau47ca5452012-12-23 20:22:19 +01004315 smp_trash = get_trash_chunk();
Willy Tarreau8d598402012-10-22 17:58:39 +02004316 if (ssl_sock_get_serial(crt, smp_trash) <= 0)
4317 goto out;
4318
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02004319 smp->data.u.str = *smp_trash;
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02004320 smp->data.type = SMP_T_BIN;
Willy Tarreau8d598402012-10-22 17:58:39 +02004321 ret = 1;
4322out:
Emeric Brunba841a12014-04-30 17:05:08 +02004323 /* SSL_get_peer_certificate, it increase X509 * ref count */
4324 if (cert_peer && crt)
Willy Tarreau8d598402012-10-22 17:58:39 +02004325 X509_free(crt);
4326 return ret;
4327}
Emeric Brune64aef12012-09-21 13:15:06 +02004328
Emeric Brunba841a12014-04-30 17:05:08 +02004329/* binary, returns the client certificate's SHA-1 fingerprint (SHA-1 hash of DER-encoded certificate) in a binary chunk.
4330 * The 5th keyword char is used to know if SSL_get_certificate or SSL_get_peer_certificate
4331 * should be use.
4332 */
James Votha051b4a2013-05-14 20:37:59 +02004333static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02004334smp_fetch_ssl_x_sha1(const struct arg *args, struct sample *smp, const char *kw, void *private)
James Votha051b4a2013-05-14 20:37:59 +02004335{
Emeric Brunba841a12014-04-30 17:05:08 +02004336 int cert_peer = (kw[4] == 'c') ? 1 : 0;
James Votha051b4a2013-05-14 20:37:59 +02004337 X509 *crt = NULL;
4338 const EVP_MD *digest;
4339 int ret = 0;
4340 struct chunk *smp_trash;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004341 struct connection *conn;
James Votha051b4a2013-05-14 20:37:59 +02004342
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02004343 conn = objt_conn(smp->sess->origin);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004344 if (!conn || conn->xprt != &ssl_sock)
4345 return 0;
4346
4347 if (!(conn->flags & CO_FL_CONNECTED)) {
James Votha051b4a2013-05-14 20:37:59 +02004348 smp->flags |= SMP_F_MAY_CHANGE;
4349 return 0;
4350 }
4351
Emeric Brunba841a12014-04-30 17:05:08 +02004352 if (cert_peer)
4353 crt = SSL_get_peer_certificate(conn->xprt_ctx);
4354 else
4355 crt = SSL_get_certificate(conn->xprt_ctx);
James Votha051b4a2013-05-14 20:37:59 +02004356 if (!crt)
4357 goto out;
4358
4359 smp_trash = get_trash_chunk();
4360 digest = EVP_sha1();
4361 X509_digest(crt, digest, (unsigned char *)smp_trash->str, (unsigned int *)&smp_trash->len);
4362
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02004363 smp->data.u.str = *smp_trash;
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02004364 smp->data.type = SMP_T_BIN;
James Votha051b4a2013-05-14 20:37:59 +02004365 ret = 1;
4366out:
Emeric Brunba841a12014-04-30 17:05:08 +02004367 /* SSL_get_peer_certificate, it increase X509 * ref count */
4368 if (cert_peer && crt)
James Votha051b4a2013-05-14 20:37:59 +02004369 X509_free(crt);
4370 return ret;
4371}
4372
Emeric Brunba841a12014-04-30 17:05:08 +02004373/* string, returns certificate's notafter date in ASN1_UTCTIME format.
4374 * The 5th keyword char is used to know if SSL_get_certificate or SSL_get_peer_certificate
4375 * should be use.
4376 */
Emeric Brunce5ad802012-10-22 14:11:22 +02004377static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02004378smp_fetch_ssl_x_notafter(const struct arg *args, struct sample *smp, const char *kw, void *private)
Emeric Brunce5ad802012-10-22 14:11:22 +02004379{
Emeric Brunba841a12014-04-30 17:05:08 +02004380 int cert_peer = (kw[4] == 'c') ? 1 : 0;
Emeric Brunce5ad802012-10-22 14:11:22 +02004381 X509 *crt = NULL;
4382 int ret = 0;
4383 struct chunk *smp_trash;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004384 struct connection *conn;
Emeric Brunce5ad802012-10-22 14:11:22 +02004385
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02004386 conn = objt_conn(smp->sess->origin);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004387 if (!conn || conn->xprt != &ssl_sock)
4388 return 0;
4389
4390 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brunce5ad802012-10-22 14:11:22 +02004391 smp->flags |= SMP_F_MAY_CHANGE;
4392 return 0;
4393 }
4394
Emeric Brunba841a12014-04-30 17:05:08 +02004395 if (cert_peer)
4396 crt = SSL_get_peer_certificate(conn->xprt_ctx);
4397 else
4398 crt = SSL_get_certificate(conn->xprt_ctx);
Emeric Brunce5ad802012-10-22 14:11:22 +02004399 if (!crt)
4400 goto out;
4401
Willy Tarreau47ca5452012-12-23 20:22:19 +01004402 smp_trash = get_trash_chunk();
Emeric Brunce5ad802012-10-22 14:11:22 +02004403 if (ssl_sock_get_time(X509_get_notAfter(crt), smp_trash) <= 0)
4404 goto out;
4405
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02004406 smp->data.u.str = *smp_trash;
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02004407 smp->data.type = SMP_T_STR;
Emeric Brunce5ad802012-10-22 14:11:22 +02004408 ret = 1;
4409out:
Emeric Brunba841a12014-04-30 17:05:08 +02004410 /* SSL_get_peer_certificate, it increase X509 * ref count */
4411 if (cert_peer && crt)
Emeric Brunce5ad802012-10-22 14:11:22 +02004412 X509_free(crt);
4413 return ret;
4414}
4415
Emeric Brunba841a12014-04-30 17:05:08 +02004416/* string, returns a string of a formatted full dn \C=..\O=..\OU=.. \CN=.. of certificate's issuer
4417 * The 5th keyword char is used to know if SSL_get_certificate or SSL_get_peer_certificate
4418 * should be use.
4419 */
Emeric Brun87855892012-10-17 17:39:35 +02004420static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02004421smp_fetch_ssl_x_i_dn(const struct arg *args, struct sample *smp, const char *kw, void *private)
Emeric Brun87855892012-10-17 17:39:35 +02004422{
Emeric Brunba841a12014-04-30 17:05:08 +02004423 int cert_peer = (kw[4] == 'c') ? 1 : 0;
Emeric Brun87855892012-10-17 17:39:35 +02004424 X509 *crt = NULL;
4425 X509_NAME *name;
4426 int ret = 0;
4427 struct chunk *smp_trash;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004428 struct connection *conn;
Emeric Brun87855892012-10-17 17:39:35 +02004429
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02004430 conn = objt_conn(smp->sess->origin);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004431 if (!conn || conn->xprt != &ssl_sock)
4432 return 0;
4433
4434 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brun87855892012-10-17 17:39:35 +02004435 smp->flags |= SMP_F_MAY_CHANGE;
4436 return 0;
4437 }
4438
Emeric Brunba841a12014-04-30 17:05:08 +02004439 if (cert_peer)
4440 crt = SSL_get_peer_certificate(conn->xprt_ctx);
4441 else
4442 crt = SSL_get_certificate(conn->xprt_ctx);
Emeric Brun87855892012-10-17 17:39:35 +02004443 if (!crt)
4444 goto out;
4445
4446 name = X509_get_issuer_name(crt);
4447 if (!name)
4448 goto out;
4449
Willy Tarreau47ca5452012-12-23 20:22:19 +01004450 smp_trash = get_trash_chunk();
Emeric Brun87855892012-10-17 17:39:35 +02004451 if (args && args[0].type == ARGT_STR) {
4452 int pos = 1;
4453
4454 if (args[1].type == ARGT_SINT)
4455 pos = args[1].data.sint;
Emeric Brun87855892012-10-17 17:39:35 +02004456
4457 if (ssl_sock_get_dn_entry(name, &args[0].data.str, pos, smp_trash) <= 0)
4458 goto out;
4459 }
4460 else if (ssl_sock_get_dn_oneline(name, smp_trash) <= 0)
4461 goto out;
4462
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02004463 smp->data.type = SMP_T_STR;
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02004464 smp->data.u.str = *smp_trash;
Emeric Brun87855892012-10-17 17:39:35 +02004465 ret = 1;
4466out:
Emeric Brunba841a12014-04-30 17:05:08 +02004467 /* SSL_get_peer_certificate, it increase X509 * ref count */
4468 if (cert_peer && crt)
Emeric Brun87855892012-10-17 17:39:35 +02004469 X509_free(crt);
4470 return ret;
4471}
4472
Emeric Brunba841a12014-04-30 17:05:08 +02004473/* string, returns notbefore date in ASN1_UTCTIME format.
4474 * The 5th keyword char is used to know if SSL_get_certificate or SSL_get_peer_certificate
4475 * should be use.
4476 */
Emeric Brunce5ad802012-10-22 14:11:22 +02004477static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02004478smp_fetch_ssl_x_notbefore(const struct arg *args, struct sample *smp, const char *kw, void *private)
Emeric Brunce5ad802012-10-22 14:11:22 +02004479{
Emeric Brunba841a12014-04-30 17:05:08 +02004480 int cert_peer = (kw[4] == 'c') ? 1 : 0;
Emeric Brunce5ad802012-10-22 14:11:22 +02004481 X509 *crt = NULL;
4482 int ret = 0;
4483 struct chunk *smp_trash;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004484 struct connection *conn;
4485
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02004486 conn = objt_conn(smp->sess->origin);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004487 if (!conn || conn->xprt != &ssl_sock)
Emeric Brunce5ad802012-10-22 14:11:22 +02004488 return 0;
4489
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004490 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brunce5ad802012-10-22 14:11:22 +02004491 smp->flags |= SMP_F_MAY_CHANGE;
4492 return 0;
4493 }
4494
Emeric Brunba841a12014-04-30 17:05:08 +02004495 if (cert_peer)
4496 crt = SSL_get_peer_certificate(conn->xprt_ctx);
4497 else
4498 crt = SSL_get_certificate(conn->xprt_ctx);
Emeric Brunce5ad802012-10-22 14:11:22 +02004499 if (!crt)
4500 goto out;
4501
Willy Tarreau47ca5452012-12-23 20:22:19 +01004502 smp_trash = get_trash_chunk();
Emeric Brunce5ad802012-10-22 14:11:22 +02004503 if (ssl_sock_get_time(X509_get_notBefore(crt), smp_trash) <= 0)
4504 goto out;
4505
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02004506 smp->data.u.str = *smp_trash;
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02004507 smp->data.type = SMP_T_STR;
Emeric Brunce5ad802012-10-22 14:11:22 +02004508 ret = 1;
4509out:
Emeric Brunba841a12014-04-30 17:05:08 +02004510 /* SSL_get_peer_certificate, it increase X509 * ref count */
4511 if (cert_peer && crt)
Emeric Brunce5ad802012-10-22 14:11:22 +02004512 X509_free(crt);
4513 return ret;
4514}
4515
Emeric Brunba841a12014-04-30 17:05:08 +02004516/* string, returns a string of a formatted full dn \C=..\O=..\OU=.. \CN=.. of certificate's subject
4517 * The 5th keyword char is used to know if SSL_get_certificate or SSL_get_peer_certificate
4518 * should be use.
4519 */
Emeric Brun87855892012-10-17 17:39:35 +02004520static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02004521smp_fetch_ssl_x_s_dn(const struct arg *args, struct sample *smp, const char *kw, void *private)
Emeric Brun87855892012-10-17 17:39:35 +02004522{
Emeric Brunba841a12014-04-30 17:05:08 +02004523 int cert_peer = (kw[4] == 'c') ? 1 : 0;
Emeric Brun87855892012-10-17 17:39:35 +02004524 X509 *crt = NULL;
4525 X509_NAME *name;
4526 int ret = 0;
4527 struct chunk *smp_trash;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004528 struct connection *conn;
Emeric Brun87855892012-10-17 17:39:35 +02004529
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02004530 conn = objt_conn(smp->sess->origin);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004531 if (!conn || conn->xprt != &ssl_sock)
4532 return 0;
4533
4534 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brun87855892012-10-17 17:39:35 +02004535 smp->flags |= SMP_F_MAY_CHANGE;
4536 return 0;
4537 }
4538
Emeric Brunba841a12014-04-30 17:05:08 +02004539 if (cert_peer)
4540 crt = SSL_get_peer_certificate(conn->xprt_ctx);
4541 else
4542 crt = SSL_get_certificate(conn->xprt_ctx);
Emeric Brun87855892012-10-17 17:39:35 +02004543 if (!crt)
4544 goto out;
4545
4546 name = X509_get_subject_name(crt);
4547 if (!name)
4548 goto out;
4549
Willy Tarreau47ca5452012-12-23 20:22:19 +01004550 smp_trash = get_trash_chunk();
Emeric Brun87855892012-10-17 17:39:35 +02004551 if (args && args[0].type == ARGT_STR) {
4552 int pos = 1;
4553
4554 if (args[1].type == ARGT_SINT)
4555 pos = args[1].data.sint;
Emeric Brun87855892012-10-17 17:39:35 +02004556
4557 if (ssl_sock_get_dn_entry(name, &args[0].data.str, pos, smp_trash) <= 0)
4558 goto out;
4559 }
4560 else if (ssl_sock_get_dn_oneline(name, smp_trash) <= 0)
4561 goto out;
4562
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02004563 smp->data.type = SMP_T_STR;
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02004564 smp->data.u.str = *smp_trash;
Emeric Brun87855892012-10-17 17:39:35 +02004565 ret = 1;
4566out:
Emeric Brunba841a12014-04-30 17:05:08 +02004567 /* SSL_get_peer_certificate, it increase X509 * ref count */
4568 if (cert_peer && crt)
Emeric Brun87855892012-10-17 17:39:35 +02004569 X509_free(crt);
4570 return ret;
4571}
Emeric Brun9143d372012-12-20 15:44:16 +01004572
4573/* integer, returns true if current session use a client certificate */
4574static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02004575smp_fetch_ssl_c_used(const struct arg *args, struct sample *smp, const char *kw, void *private)
Emeric Brun9143d372012-12-20 15:44:16 +01004576{
4577 X509 *crt;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004578 struct connection *conn;
Emeric Brun9143d372012-12-20 15:44:16 +01004579
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02004580 conn = objt_conn(smp->sess->origin);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004581 if (!conn || conn->xprt != &ssl_sock)
4582 return 0;
4583
4584 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brun9143d372012-12-20 15:44:16 +01004585 smp->flags |= SMP_F_MAY_CHANGE;
4586 return 0;
4587 }
4588
4589 /* SSL_get_peer_certificate returns a ptr on allocated X509 struct */
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004590 crt = SSL_get_peer_certificate(conn->xprt_ctx);
Emeric Brun9143d372012-12-20 15:44:16 +01004591 if (crt) {
4592 X509_free(crt);
4593 }
4594
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02004595 smp->data.type = SMP_T_BOOL;
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02004596 smp->data.u.sint = (crt != NULL);
Emeric Brun9143d372012-12-20 15:44:16 +01004597 return 1;
4598}
4599
Emeric Brunba841a12014-04-30 17:05:08 +02004600/* integer, returns the certificate version
4601 * The 5th keyword char is used to know if SSL_get_certificate or SSL_get_peer_certificate
4602 * should be use.
4603 */
Emeric Bruna7359fd2012-10-17 15:03:11 +02004604static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02004605smp_fetch_ssl_x_version(const struct arg *args, struct sample *smp, const char *kw, void *private)
Emeric Bruna7359fd2012-10-17 15:03:11 +02004606{
Emeric Brunba841a12014-04-30 17:05:08 +02004607 int cert_peer = (kw[4] == 'c') ? 1 : 0;
Emeric Bruna7359fd2012-10-17 15:03:11 +02004608 X509 *crt;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004609 struct connection *conn;
4610
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02004611 conn = objt_conn(smp->sess->origin);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004612 if (!conn || conn->xprt != &ssl_sock)
Emeric Bruna7359fd2012-10-17 15:03:11 +02004613 return 0;
4614
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004615 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Bruna7359fd2012-10-17 15:03:11 +02004616 smp->flags |= SMP_F_MAY_CHANGE;
4617 return 0;
4618 }
4619
Emeric Brunba841a12014-04-30 17:05:08 +02004620 if (cert_peer)
4621 crt = SSL_get_peer_certificate(conn->xprt_ctx);
4622 else
4623 crt = SSL_get_certificate(conn->xprt_ctx);
Emeric Bruna7359fd2012-10-17 15:03:11 +02004624 if (!crt)
4625 return 0;
4626
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02004627 smp->data.u.sint = (unsigned int)(1 + X509_get_version(crt));
Emeric Brunba841a12014-04-30 17:05:08 +02004628 /* SSL_get_peer_certificate increase X509 * ref count */
4629 if (cert_peer)
4630 X509_free(crt);
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02004631 smp->data.type = SMP_T_SINT;
Emeric Bruna7359fd2012-10-17 15:03:11 +02004632
4633 return 1;
4634}
4635
Emeric Brunba841a12014-04-30 17:05:08 +02004636/* string, returns the certificate's signature algorithm.
4637 * The 5th keyword char is used to know if SSL_get_certificate or SSL_get_peer_certificate
4638 * should be use.
4639 */
Emeric Brun7f56e742012-10-19 18:15:40 +02004640static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02004641smp_fetch_ssl_x_sig_alg(const struct arg *args, struct sample *smp, const char *kw, void *private)
Emeric Brun7f56e742012-10-19 18:15:40 +02004642{
Emeric Brunba841a12014-04-30 17:05:08 +02004643 int cert_peer = (kw[4] == 'c') ? 1 : 0;
Emeric Brun7f56e742012-10-19 18:15:40 +02004644 X509 *crt;
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02004645 __OPENSSL_110_CONST__ ASN1_OBJECT *algorithm;
Emeric Brun7f56e742012-10-19 18:15:40 +02004646 int nid;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004647 struct connection *conn;
Emeric Brun7f56e742012-10-19 18:15:40 +02004648
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02004649 conn = objt_conn(smp->sess->origin);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004650 if (!conn || conn->xprt != &ssl_sock)
4651 return 0;
4652
4653 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brun7f56e742012-10-19 18:15:40 +02004654 smp->flags |= SMP_F_MAY_CHANGE;
4655 return 0;
4656 }
4657
Emeric Brunba841a12014-04-30 17:05:08 +02004658 if (cert_peer)
4659 crt = SSL_get_peer_certificate(conn->xprt_ctx);
4660 else
4661 crt = SSL_get_certificate(conn->xprt_ctx);
Emeric Brun7f56e742012-10-19 18:15:40 +02004662 if (!crt)
4663 return 0;
4664
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02004665 X509_ALGOR_get0(&algorithm, NULL, NULL, X509_get0_tbs_sigalg(crt));
4666 nid = OBJ_obj2nid(algorithm);
Emeric Brun7f56e742012-10-19 18:15:40 +02004667
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02004668 smp->data.u.str.str = (char *)OBJ_nid2sn(nid);
4669 if (!smp->data.u.str.str) {
Emeric Brunba841a12014-04-30 17:05:08 +02004670 /* SSL_get_peer_certificate increase X509 * ref count */
4671 if (cert_peer)
4672 X509_free(crt);
Emeric Brun7f56e742012-10-19 18:15:40 +02004673 return 0;
Emeric Brun9bf3ba22013-10-07 14:31:44 +02004674 }
Emeric Brun7f56e742012-10-19 18:15:40 +02004675
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02004676 smp->data.type = SMP_T_STR;
Thierry FOURNIER7654c9f2013-12-17 00:20:33 +01004677 smp->flags |= SMP_F_CONST;
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02004678 smp->data.u.str.len = strlen(smp->data.u.str.str);
Emeric Brunba841a12014-04-30 17:05:08 +02004679 /* SSL_get_peer_certificate increase X509 * ref count */
4680 if (cert_peer)
4681 X509_free(crt);
Emeric Brun7f56e742012-10-19 18:15:40 +02004682
4683 return 1;
4684}
4685
Emeric Brunba841a12014-04-30 17:05:08 +02004686/* string, returns the certificate's key algorithm.
4687 * The 5th keyword char is used to know if SSL_get_certificate or SSL_get_peer_certificate
4688 * should be use.
4689 */
Emeric Brun521a0112012-10-22 12:22:55 +02004690static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02004691smp_fetch_ssl_x_key_alg(const struct arg *args, struct sample *smp, const char *kw, void *private)
Emeric Brun521a0112012-10-22 12:22:55 +02004692{
Emeric Brunba841a12014-04-30 17:05:08 +02004693 int cert_peer = (kw[4] == 'c') ? 1 : 0;
Emeric Brun521a0112012-10-22 12:22:55 +02004694 X509 *crt;
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02004695 ASN1_OBJECT *algorithm;
Emeric Brun521a0112012-10-22 12:22:55 +02004696 int nid;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004697 struct connection *conn;
Emeric Brun521a0112012-10-22 12:22:55 +02004698
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02004699 conn = objt_conn(smp->sess->origin);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004700 if (!conn || conn->xprt != &ssl_sock)
4701 return 0;
4702
4703 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brun521a0112012-10-22 12:22:55 +02004704 smp->flags |= SMP_F_MAY_CHANGE;
4705 return 0;
4706 }
4707
Emeric Brunba841a12014-04-30 17:05:08 +02004708 if (cert_peer)
4709 crt = SSL_get_peer_certificate(conn->xprt_ctx);
4710 else
4711 crt = SSL_get_certificate(conn->xprt_ctx);
Emeric Brun521a0112012-10-22 12:22:55 +02004712 if (!crt)
4713 return 0;
4714
Dirkjan Bussink1866d6d2016-08-29 13:26:37 +02004715 X509_PUBKEY_get0_param(&algorithm, NULL, NULL, NULL, X509_get_X509_PUBKEY(crt));
4716 nid = OBJ_obj2nid(algorithm);
Emeric Brun521a0112012-10-22 12:22:55 +02004717
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02004718 smp->data.u.str.str = (char *)OBJ_nid2sn(nid);
4719 if (!smp->data.u.str.str) {
Emeric Brunba841a12014-04-30 17:05:08 +02004720 /* SSL_get_peer_certificate increase X509 * ref count */
4721 if (cert_peer)
4722 X509_free(crt);
Emeric Brun521a0112012-10-22 12:22:55 +02004723 return 0;
Emeric Brun9bf3ba22013-10-07 14:31:44 +02004724 }
Emeric Brun521a0112012-10-22 12:22:55 +02004725
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02004726 smp->data.type = SMP_T_STR;
Thierry FOURNIER7654c9f2013-12-17 00:20:33 +01004727 smp->flags |= SMP_F_CONST;
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02004728 smp->data.u.str.len = strlen(smp->data.u.str.str);
Emeric Brunba841a12014-04-30 17:05:08 +02004729 if (cert_peer)
4730 X509_free(crt);
Emeric Brun521a0112012-10-22 12:22:55 +02004731
4732 return 1;
4733}
4734
Emeric Brun645ae792014-04-30 14:21:06 +02004735/* boolean, returns true if front conn. transport layer is SSL.
4736 * This function is also usable on backend conn if the fetch keyword 5th
4737 * char is 'b'.
4738 */
Willy Tarreau7875d092012-09-10 08:20:03 +02004739static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02004740smp_fetch_ssl_fc(const struct arg *args, struct sample *smp, const char *kw, void *private)
Willy Tarreau7875d092012-09-10 08:20:03 +02004741{
Willy Tarreaue237fe12016-03-10 17:05:28 +01004742 struct connection *conn = objt_conn((kw[4] != 'b') ? smp->sess->origin :
4743 smp->strm ? smp->strm->si[1].end : NULL);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004744
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02004745 smp->data.type = SMP_T_BOOL;
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02004746 smp->data.u.sint = (conn && conn->xprt == &ssl_sock);
Willy Tarreau7875d092012-09-10 08:20:03 +02004747 return 1;
4748}
4749
Emeric Brun2525b6b2012-10-18 15:59:43 +02004750/* boolean, returns true if client present a SNI */
Willy Tarreau7875d092012-09-10 08:20:03 +02004751static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02004752smp_fetch_ssl_fc_has_sni(const struct arg *args, struct sample *smp, const char *kw, void *private)
Willy Tarreau7875d092012-09-10 08:20:03 +02004753{
4754#ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02004755 struct connection *conn = objt_conn(smp->sess->origin);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004756
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02004757 smp->data.type = SMP_T_BOOL;
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02004758 smp->data.u.sint = (conn && conn->xprt == &ssl_sock) &&
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004759 conn->xprt_ctx &&
4760 SSL_get_servername(conn->xprt_ctx, TLSEXT_NAMETYPE_host_name) != NULL;
Willy Tarreau7875d092012-09-10 08:20:03 +02004761 return 1;
4762#else
4763 return 0;
4764#endif
4765}
4766
Nenad Merdanovic26ea8222015-05-18 02:28:57 +02004767/* boolean, returns true if client session has been resumed */
4768static int
4769smp_fetch_ssl_fc_is_resumed(const struct arg *args, struct sample *smp, const char *kw, void *private)
4770{
4771 struct connection *conn = objt_conn(smp->sess->origin);
4772
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02004773 smp->data.type = SMP_T_BOOL;
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02004774 smp->data.u.sint = (conn && conn->xprt == &ssl_sock) &&
Nenad Merdanovic26ea8222015-05-18 02:28:57 +02004775 conn->xprt_ctx &&
4776 SSL_session_reused(conn->xprt_ctx);
4777 return 1;
4778}
4779
Emeric Brun645ae792014-04-30 14:21:06 +02004780/* string, returns the used cipher if front conn. transport layer is SSL.
4781 * This function is also usable on backend conn if the fetch keyword 5th
4782 * char is 'b'.
4783 */
Emeric Brun589fcad2012-10-16 14:13:26 +02004784static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02004785smp_fetch_ssl_fc_cipher(const struct arg *args, struct sample *smp, const char *kw, void *private)
Emeric Brun589fcad2012-10-16 14:13:26 +02004786{
Willy Tarreaue237fe12016-03-10 17:05:28 +01004787 struct connection *conn = objt_conn((kw[4] != 'b') ? smp->sess->origin :
4788 smp->strm ? smp->strm->si[1].end : NULL);
Emeric Brun589fcad2012-10-16 14:13:26 +02004789
Willy Tarreaube508f12016-03-10 11:47:01 +01004790 smp->flags = 0;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004791 if (!conn || !conn->xprt_ctx || conn->xprt != &ssl_sock)
Emeric Brun589fcad2012-10-16 14:13:26 +02004792 return 0;
4793
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02004794 smp->data.u.str.str = (char *)SSL_get_cipher_name(conn->xprt_ctx);
4795 if (!smp->data.u.str.str)
Emeric Brun589fcad2012-10-16 14:13:26 +02004796 return 0;
4797
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02004798 smp->data.type = SMP_T_STR;
Thierry FOURNIER7654c9f2013-12-17 00:20:33 +01004799 smp->flags |= SMP_F_CONST;
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02004800 smp->data.u.str.len = strlen(smp->data.u.str.str);
Emeric Brun589fcad2012-10-16 14:13:26 +02004801
4802 return 1;
4803}
4804
Emeric Brun645ae792014-04-30 14:21:06 +02004805/* integer, returns the algoritm's keysize if front conn. transport layer
4806 * is SSL.
4807 * This function is also usable on backend conn if the fetch keyword 5th
4808 * char is 'b'.
4809 */
Emeric Brun589fcad2012-10-16 14:13:26 +02004810static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02004811smp_fetch_ssl_fc_alg_keysize(const struct arg *args, struct sample *smp, const char *kw, void *private)
Emeric Brun589fcad2012-10-16 14:13:26 +02004812{
Willy Tarreaue237fe12016-03-10 17:05:28 +01004813 struct connection *conn = objt_conn((kw[4] != 'b') ? smp->sess->origin :
4814 smp->strm ? smp->strm->si[1].end : NULL);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004815
Willy Tarreaue237fe12016-03-10 17:05:28 +01004816 int sint;
Willy Tarreaube508f12016-03-10 11:47:01 +01004817
Emeric Brun589fcad2012-10-16 14:13:26 +02004818 smp->flags = 0;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004819 if (!conn || !conn->xprt_ctx || conn->xprt != &ssl_sock)
Emeric Brun589fcad2012-10-16 14:13:26 +02004820 return 0;
4821
Thierry FOURNIER07ee64e2015-07-06 23:43:03 +02004822 if (!SSL_get_cipher_bits(conn->xprt_ctx, &sint))
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004823 return 0;
4824
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02004825 smp->data.u.sint = sint;
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02004826 smp->data.type = SMP_T_SINT;
Emeric Brun589fcad2012-10-16 14:13:26 +02004827
4828 return 1;
4829}
4830
Emeric Brun645ae792014-04-30 14:21:06 +02004831/* integer, returns the used keysize if front conn. transport layer is SSL.
4832 * This function is also usable on backend conn if the fetch keyword 5th
4833 * char is 'b'.
4834 */
Emeric Brun589fcad2012-10-16 14:13:26 +02004835static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02004836smp_fetch_ssl_fc_use_keysize(const struct arg *args, struct sample *smp, const char *kw, void *private)
Emeric Brun589fcad2012-10-16 14:13:26 +02004837{
Willy Tarreaue237fe12016-03-10 17:05:28 +01004838 struct connection *conn = objt_conn((kw[4] != 'b') ? smp->sess->origin :
4839 smp->strm ? smp->strm->si[1].end : NULL);
Willy Tarreaube508f12016-03-10 11:47:01 +01004840
Emeric Brun589fcad2012-10-16 14:13:26 +02004841 smp->flags = 0;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004842 if (!conn || !conn->xprt_ctx || conn->xprt != &ssl_sock)
4843 return 0;
4844
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02004845 smp->data.u.sint = (unsigned int)SSL_get_cipher_bits(conn->xprt_ctx, NULL);
4846 if (!smp->data.u.sint)
Emeric Brun589fcad2012-10-16 14:13:26 +02004847 return 0;
4848
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02004849 smp->data.type = SMP_T_SINT;
Emeric Brun589fcad2012-10-16 14:13:26 +02004850
4851 return 1;
4852}
4853
Willy Tarreau6c9a3d52012-10-18 18:57:14 +02004854#ifdef OPENSSL_NPN_NEGOTIATED
Willy Tarreau7875d092012-09-10 08:20:03 +02004855static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02004856smp_fetch_ssl_fc_npn(const struct arg *args, struct sample *smp, const char *kw, void *private)
Willy Tarreaua33c6542012-10-15 13:19:06 +02004857{
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004858 struct connection *conn;
4859
Thierry FOURNIER7654c9f2013-12-17 00:20:33 +01004860 smp->flags = SMP_F_CONST;
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02004861 smp->data.type = SMP_T_STR;
Willy Tarreaua33c6542012-10-15 13:19:06 +02004862
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02004863 conn = objt_conn(smp->sess->origin);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004864 if (!conn || !conn->xprt_ctx || conn->xprt != &ssl_sock)
4865 return 0;
4866
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02004867 smp->data.u.str.str = NULL;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004868 SSL_get0_next_proto_negotiated(conn->xprt_ctx,
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02004869 (const unsigned char **)&smp->data.u.str.str, (unsigned *)&smp->data.u.str.len);
Willy Tarreaua33c6542012-10-15 13:19:06 +02004870
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02004871 if (!smp->data.u.str.str)
Willy Tarreaua33c6542012-10-15 13:19:06 +02004872 return 0;
4873
4874 return 1;
Willy Tarreaua33c6542012-10-15 13:19:06 +02004875}
Willy Tarreau6c9a3d52012-10-18 18:57:14 +02004876#endif
Willy Tarreaua33c6542012-10-15 13:19:06 +02004877
Dirkjan Bussink48f1c4e2014-02-13 12:29:42 +01004878#ifdef TLSEXT_TYPE_application_layer_protocol_negotiation
Willy Tarreauab861d32013-04-02 02:30:41 +02004879static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02004880smp_fetch_ssl_fc_alpn(const struct arg *args, struct sample *smp, const char *kw, void *private)
Willy Tarreauab861d32013-04-02 02:30:41 +02004881{
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004882 struct connection *conn;
4883
Thierry FOURNIER7654c9f2013-12-17 00:20:33 +01004884 smp->flags = SMP_F_CONST;
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02004885 smp->data.type = SMP_T_STR;
Willy Tarreauab861d32013-04-02 02:30:41 +02004886
Willy Tarreaue26bf052015-05-12 10:30:12 +02004887 conn = objt_conn(smp->sess->origin);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004888 if (!conn || !conn->xprt_ctx || conn->xprt != &ssl_sock)
Willy Tarreauab861d32013-04-02 02:30:41 +02004889 return 0;
4890
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02004891 smp->data.u.str.str = NULL;
Dirkjan Bussink48f1c4e2014-02-13 12:29:42 +01004892 SSL_get0_alpn_selected(conn->xprt_ctx,
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02004893 (const unsigned char **)&smp->data.u.str.str, (unsigned *)&smp->data.u.str.len);
Willy Tarreauab861d32013-04-02 02:30:41 +02004894
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02004895 if (!smp->data.u.str.str)
Willy Tarreauab861d32013-04-02 02:30:41 +02004896 return 0;
4897
4898 return 1;
4899}
4900#endif
4901
Emeric Brun645ae792014-04-30 14:21:06 +02004902/* string, returns the used protocol if front conn. transport layer is SSL.
4903 * This function is also usable on backend conn if the fetch keyword 5th
4904 * char is 'b'.
4905 */
Willy Tarreaua33c6542012-10-15 13:19:06 +02004906static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02004907smp_fetch_ssl_fc_protocol(const struct arg *args, struct sample *smp, const char *kw, void *private)
Emeric Brun589fcad2012-10-16 14:13:26 +02004908{
Willy Tarreaue237fe12016-03-10 17:05:28 +01004909 struct connection *conn = objt_conn((kw[4] != 'b') ? smp->sess->origin :
4910 smp->strm ? smp->strm->si[1].end : NULL);
Willy Tarreaube508f12016-03-10 11:47:01 +01004911
Emeric Brun589fcad2012-10-16 14:13:26 +02004912 smp->flags = 0;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004913 if (!conn || !conn->xprt_ctx || conn->xprt != &ssl_sock)
4914 return 0;
4915
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02004916 smp->data.u.str.str = (char *)SSL_get_version(conn->xprt_ctx);
4917 if (!smp->data.u.str.str)
Emeric Brun589fcad2012-10-16 14:13:26 +02004918 return 0;
4919
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02004920 smp->data.type = SMP_T_STR;
Thierry FOURNIER7654c9f2013-12-17 00:20:33 +01004921 smp->flags = SMP_F_CONST;
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02004922 smp->data.u.str.len = strlen(smp->data.u.str.str);
Emeric Brun589fcad2012-10-16 14:13:26 +02004923
4924 return 1;
4925}
4926
Willy Tarreau87b09662015-04-03 00:22:06 +02004927/* binary, returns the SSL stream id if front conn. transport layer is SSL.
Emeric Brun645ae792014-04-30 14:21:06 +02004928 * This function is also usable on backend conn if the fetch keyword 5th
4929 * char is 'b'.
4930 */
Emeric Brun589fcad2012-10-16 14:13:26 +02004931static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02004932smp_fetch_ssl_fc_session_id(const struct arg *args, struct sample *smp, const char *kw, void *private)
Emeric Brunfe68f682012-10-16 14:59:28 +02004933{
4934#if OPENSSL_VERSION_NUMBER > 0x0090800fL
Willy Tarreaue237fe12016-03-10 17:05:28 +01004935 struct connection *conn = objt_conn((kw[4] != 'b') ? smp->sess->origin :
4936 smp->strm ? smp->strm->si[1].end : NULL);
Emeric Brunfe68f682012-10-16 14:59:28 +02004937
Willy Tarreaue237fe12016-03-10 17:05:28 +01004938 SSL_SESSION *ssl_sess;
Willy Tarreaube508f12016-03-10 11:47:01 +01004939
Thierry FOURNIER7654c9f2013-12-17 00:20:33 +01004940 smp->flags = SMP_F_CONST;
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02004941 smp->data.type = SMP_T_BIN;
Emeric Brunfe68f682012-10-16 14:59:28 +02004942
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004943 if (!conn || !conn->xprt_ctx || conn->xprt != &ssl_sock)
4944 return 0;
4945
Willy Tarreau192252e2015-04-04 01:47:55 +02004946 ssl_sess = SSL_get_session(conn->xprt_ctx);
4947 if (!ssl_sess)
Emeric Brunfe68f682012-10-16 14:59:28 +02004948 return 0;
4949
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02004950 smp->data.u.str.str = (char *)SSL_SESSION_get_id(ssl_sess, (unsigned int *)&smp->data.u.str.len);
4951 if (!smp->data.u.str.str || !smp->data.u.str.len)
Emeric Brunfe68f682012-10-16 14:59:28 +02004952 return 0;
4953
4954 return 1;
4955#else
4956 return 0;
4957#endif
4958}
4959
4960static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02004961smp_fetch_ssl_fc_sni(const struct arg *args, struct sample *smp, const char *kw, void *private)
Willy Tarreau7875d092012-09-10 08:20:03 +02004962{
4963#ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004964 struct connection *conn;
4965
Thierry FOURNIER7654c9f2013-12-17 00:20:33 +01004966 smp->flags = SMP_F_CONST;
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02004967 smp->data.type = SMP_T_STR;
Willy Tarreau7875d092012-09-10 08:20:03 +02004968
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02004969 conn = objt_conn(smp->sess->origin);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004970 if (!conn || !conn->xprt_ctx || conn->xprt != &ssl_sock)
4971 return 0;
4972
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02004973 smp->data.u.str.str = (char *)SSL_get_servername(conn->xprt_ctx, TLSEXT_NAMETYPE_host_name);
4974 if (!smp->data.u.str.str)
Willy Tarreau3e394c92012-09-14 23:56:58 +02004975 return 0;
4976
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02004977 smp->data.u.str.len = strlen(smp->data.u.str.str);
Willy Tarreau7875d092012-09-10 08:20:03 +02004978 return 1;
4979#else
4980 return 0;
4981#endif
4982}
4983
David Sc1ad52e2014-04-08 18:48:47 -04004984static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02004985smp_fetch_ssl_fc_unique_id(const struct arg *args, struct sample *smp, const char *kw, void *private)
David Sc1ad52e2014-04-08 18:48:47 -04004986{
4987#if OPENSSL_VERSION_NUMBER > 0x0090800fL
Willy Tarreaue237fe12016-03-10 17:05:28 +01004988 struct connection *conn = objt_conn((kw[4] != 'b') ? smp->sess->origin :
4989 smp->strm ? smp->strm->si[1].end : NULL);
4990
David Sc1ad52e2014-04-08 18:48:47 -04004991 int finished_len;
David Sc1ad52e2014-04-08 18:48:47 -04004992 struct chunk *finished_trash;
David Sc1ad52e2014-04-08 18:48:47 -04004993
4994 smp->flags = 0;
David Sc1ad52e2014-04-08 18:48:47 -04004995 if (!conn || !conn->xprt_ctx || conn->xprt != &ssl_sock)
4996 return 0;
4997
4998 if (!(conn->flags & CO_FL_CONNECTED)) {
4999 smp->flags |= SMP_F_MAY_CHANGE;
5000 return 0;
5001 }
5002
5003 finished_trash = get_trash_chunk();
5004 if (!SSL_session_reused(conn->xprt_ctx))
5005 finished_len = SSL_get_peer_finished(conn->xprt_ctx, finished_trash->str, finished_trash->size);
5006 else
5007 finished_len = SSL_get_finished(conn->xprt_ctx, finished_trash->str, finished_trash->size);
5008
5009 if (!finished_len)
5010 return 0;
5011
Emeric Brunb73a9b02014-04-30 18:49:19 +02005012 finished_trash->len = finished_len;
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02005013 smp->data.u.str = *finished_trash;
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02005014 smp->data.type = SMP_T_BIN;
David Sc1ad52e2014-04-08 18:48:47 -04005015
5016 return 1;
5017#else
5018 return 0;
5019#endif
5020}
5021
Emeric Brun2525b6b2012-10-18 15:59:43 +02005022/* integer, returns the first verify error in CA chain of client certificate chain. */
Emeric Brunf282a812012-09-21 15:27:54 +02005023static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02005024smp_fetch_ssl_c_ca_err(const struct arg *args, struct sample *smp, const char *kw, void *private)
Emeric Brunf282a812012-09-21 15:27:54 +02005025{
Willy Tarreaub363a1f2013-10-01 10:45:07 +02005026 struct connection *conn;
5027
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02005028 conn = objt_conn(smp->sess->origin);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02005029 if (!conn || conn->xprt != &ssl_sock)
5030 return 0;
5031
5032 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brunf282a812012-09-21 15:27:54 +02005033 smp->flags = SMP_F_MAY_CHANGE;
5034 return 0;
5035 }
5036
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02005037 smp->data.type = SMP_T_SINT;
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02005038 smp->data.u.sint = (unsigned long long int)SSL_SOCK_ST_TO_CA_ERROR(conn->xprt_st);
Emeric Brunf282a812012-09-21 15:27:54 +02005039 smp->flags = 0;
5040
5041 return 1;
5042}
5043
Emeric Brun2525b6b2012-10-18 15:59:43 +02005044/* integer, returns the depth of the first verify error in CA chain of client certificate chain. */
Emeric Brunf282a812012-09-21 15:27:54 +02005045static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02005046smp_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 +02005047{
Willy Tarreaub363a1f2013-10-01 10:45:07 +02005048 struct connection *conn;
5049
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02005050 conn = objt_conn(smp->sess->origin);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02005051 if (!conn || conn->xprt != &ssl_sock)
Emeric Brunf282a812012-09-21 15:27:54 +02005052 return 0;
5053
Willy Tarreaub363a1f2013-10-01 10:45:07 +02005054 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brunf282a812012-09-21 15:27:54 +02005055 smp->flags = SMP_F_MAY_CHANGE;
5056 return 0;
5057 }
5058
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02005059 smp->data.type = SMP_T_SINT;
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02005060 smp->data.u.sint = (long long int)SSL_SOCK_ST_TO_CAEDEPTH(conn->xprt_st);
Emeric Brunf282a812012-09-21 15:27:54 +02005061 smp->flags = 0;
5062
5063 return 1;
5064}
5065
Emeric Brun2525b6b2012-10-18 15:59:43 +02005066/* integer, returns the first verify error on client certificate */
Emeric Brunf282a812012-09-21 15:27:54 +02005067static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02005068smp_fetch_ssl_c_err(const struct arg *args, struct sample *smp, const char *kw, void *private)
Emeric Brunf282a812012-09-21 15:27:54 +02005069{
Willy Tarreaub363a1f2013-10-01 10:45:07 +02005070 struct connection *conn;
5071
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02005072 conn = objt_conn(smp->sess->origin);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02005073 if (!conn || conn->xprt != &ssl_sock)
5074 return 0;
5075
5076 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brunf282a812012-09-21 15:27:54 +02005077 smp->flags = SMP_F_MAY_CHANGE;
5078 return 0;
5079 }
5080
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02005081 smp->data.type = SMP_T_SINT;
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02005082 smp->data.u.sint = (long long int)SSL_SOCK_ST_TO_CRTERROR(conn->xprt_st);
Emeric Brunf282a812012-09-21 15:27:54 +02005083 smp->flags = 0;
5084
5085 return 1;
5086}
5087
Emeric Brun2525b6b2012-10-18 15:59:43 +02005088/* integer, returns the verify result on client cert */
Emeric Brunbaf8ffb2012-09-21 15:27:20 +02005089static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02005090smp_fetch_ssl_c_verify(const struct arg *args, struct sample *smp, const char *kw, void *private)
Emeric Brunbaf8ffb2012-09-21 15:27:20 +02005091{
Willy Tarreaub363a1f2013-10-01 10:45:07 +02005092 struct connection *conn;
5093
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02005094 conn = objt_conn(smp->sess->origin);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02005095 if (!conn || conn->xprt != &ssl_sock)
5096 return 0;
5097
5098 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brunbaf8ffb2012-09-21 15:27:20 +02005099 smp->flags = SMP_F_MAY_CHANGE;
5100 return 0;
5101 }
5102
Willy Tarreaub363a1f2013-10-01 10:45:07 +02005103 if (!conn->xprt_ctx)
Emeric Brunbaf8ffb2012-09-21 15:27:20 +02005104 return 0;
5105
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02005106 smp->data.type = SMP_T_SINT;
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02005107 smp->data.u.sint = (long long int)SSL_get_verify_result(conn->xprt_ctx);
Emeric Brunbaf8ffb2012-09-21 15:27:20 +02005108 smp->flags = 0;
5109
5110 return 1;
5111}
5112
Emeric Brunfb510ea2012-10-05 12:00:26 +02005113/* parse the "ca-file" bind keyword */
5114static 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 +02005115{
5116 if (!*args[cur_arg + 1]) {
5117 if (err)
5118 memprintf(err, "'%s' : missing CAfile path", args[cur_arg]);
5119 return ERR_ALERT | ERR_FATAL;
5120 }
5121
Emeric Brunef42d922012-10-11 16:11:36 +02005122 if ((*args[cur_arg + 1] != '/') && global.ca_base)
5123 memprintf(&conf->ca_file, "%s/%s", global.ca_base, args[cur_arg + 1]);
5124 else
5125 memprintf(&conf->ca_file, "%s", args[cur_arg + 1]);
Emeric Brunc8e8d122012-10-02 18:42:10 +02005126
Emeric Brund94b3fe2012-09-20 18:23:56 +02005127 return 0;
5128}
5129
Christopher Faulet31af49d2015-06-09 17:29:50 +02005130/* parse the "ca-sign-file" bind keyword */
5131static int bind_parse_ca_sign_file(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
5132{
5133 if (!*args[cur_arg + 1]) {
5134 if (err)
5135 memprintf(err, "'%s' : missing CAfile path", args[cur_arg]);
5136 return ERR_ALERT | ERR_FATAL;
5137 }
5138
5139 if ((*args[cur_arg + 1] != '/') && global.ca_base)
5140 memprintf(&conf->ca_sign_file, "%s/%s", global.ca_base, args[cur_arg + 1]);
5141 else
5142 memprintf(&conf->ca_sign_file, "%s", args[cur_arg + 1]);
5143
5144 return 0;
5145}
5146
5147/* parse the ca-sign-pass bind keyword */
5148
5149static int bind_parse_ca_sign_pass(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
5150{
5151 if (!*args[cur_arg + 1]) {
5152 if (err)
5153 memprintf(err, "'%s' : missing CAkey password", args[cur_arg]);
5154 return ERR_ALERT | ERR_FATAL;
5155 }
5156 memprintf(&conf->ca_sign_pass, "%s", args[cur_arg + 1]);
5157 return 0;
5158}
5159
Willy Tarreau79eeafa2012-09-14 07:53:05 +02005160/* parse the "ciphers" bind keyword */
Willy Tarreau4348fad2012-09-20 16:48:07 +02005161static 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 +02005162{
5163 if (!*args[cur_arg + 1]) {
Willy Tarreaueb6cead2012-09-20 19:43:14 +02005164 memprintf(err, "'%s' : missing cipher suite", args[cur_arg]);
Willy Tarreau79eeafa2012-09-14 07:53:05 +02005165 return ERR_ALERT | ERR_FATAL;
5166 }
5167
Emeric Brun76d88952012-10-05 15:47:31 +02005168 free(conf->ciphers);
Willy Tarreau4348fad2012-09-20 16:48:07 +02005169 conf->ciphers = strdup(args[cur_arg + 1]);
Willy Tarreau79eeafa2012-09-14 07:53:05 +02005170 return 0;
5171}
5172
5173/* parse the "crt" bind keyword */
Willy Tarreau4348fad2012-09-20 16:48:07 +02005174static 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 +02005175{
Willy Tarreau38011032013-08-13 16:59:39 +02005176 char path[MAXPATHLEN];
Willy Tarreaub75d6922014-04-14 18:05:41 +02005177
Willy Tarreau79eeafa2012-09-14 07:53:05 +02005178 if (!*args[cur_arg + 1]) {
Willy Tarreaueb6cead2012-09-20 19:43:14 +02005179 memprintf(err, "'%s' : missing certificate location", args[cur_arg]);
Willy Tarreau79eeafa2012-09-14 07:53:05 +02005180 return ERR_ALERT | ERR_FATAL;
5181 }
5182
Emeric Brunc8e8d122012-10-02 18:42:10 +02005183 if ((*args[cur_arg + 1] != '/' ) && global.crt_base) {
Willy Tarreau38011032013-08-13 16:59:39 +02005184 if ((strlen(global.crt_base) + 1 + strlen(args[cur_arg + 1]) + 1) > MAXPATHLEN) {
Emeric Brunc8e8d122012-10-02 18:42:10 +02005185 memprintf(err, "'%s' : path too long", args[cur_arg]);
5186 return ERR_ALERT | ERR_FATAL;
5187 }
Willy Tarreaub75d6922014-04-14 18:05:41 +02005188 snprintf(path, sizeof(path), "%s/%s", global.crt_base, args[cur_arg + 1]);
Emeric Brunc8e8d122012-10-02 18:42:10 +02005189 if (ssl_sock_load_cert(path, conf, px, err) > 0)
5190 return ERR_ALERT | ERR_FATAL;
5191
5192 return 0;
5193 }
5194
Willy Tarreau4348fad2012-09-20 16:48:07 +02005195 if (ssl_sock_load_cert(args[cur_arg + 1], conf, px, err) > 0)
Willy Tarreau79eeafa2012-09-14 07:53:05 +02005196 return ERR_ALERT | ERR_FATAL;
Emeric Brund94b3fe2012-09-20 18:23:56 +02005197
5198 return 0;
5199}
5200
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01005201/* parse the "crt-list" bind keyword */
5202static int bind_parse_crt_list(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
5203{
5204 if (!*args[cur_arg + 1]) {
5205 memprintf(err, "'%s' : missing certificate location", args[cur_arg]);
5206 return ERR_ALERT | ERR_FATAL;
5207 }
5208
Willy Tarreauad1731d2013-04-02 17:35:58 +02005209 if (ssl_sock_load_cert_list_file(args[cur_arg + 1], conf, px, err) > 0) {
5210 memprintf(err, "'%s' : %s", args[cur_arg], *err);
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01005211 return ERR_ALERT | ERR_FATAL;
Willy Tarreauad1731d2013-04-02 17:35:58 +02005212 }
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01005213
5214 return 0;
5215}
5216
Emeric Brunfb510ea2012-10-05 12:00:26 +02005217/* parse the "crl-file" bind keyword */
5218static 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 +02005219{
Emeric Brun051cdab2012-10-02 19:25:50 +02005220#ifndef X509_V_FLAG_CRL_CHECK
5221 if (err)
5222 memprintf(err, "'%s' : library does not support CRL verify", args[cur_arg]);
5223 return ERR_ALERT | ERR_FATAL;
5224#else
Emeric Brund94b3fe2012-09-20 18:23:56 +02005225 if (!*args[cur_arg + 1]) {
5226 if (err)
5227 memprintf(err, "'%s' : missing CRLfile path", args[cur_arg]);
5228 return ERR_ALERT | ERR_FATAL;
5229 }
Emeric Brun2b58d042012-09-20 17:10:03 +02005230
Emeric Brunef42d922012-10-11 16:11:36 +02005231 if ((*args[cur_arg + 1] != '/') && global.ca_base)
5232 memprintf(&conf->crl_file, "%s/%s", global.ca_base, args[cur_arg + 1]);
5233 else
5234 memprintf(&conf->crl_file, "%s", args[cur_arg + 1]);
Emeric Brunc8e8d122012-10-02 18:42:10 +02005235
Emeric Brun2b58d042012-09-20 17:10:03 +02005236 return 0;
Emeric Brun051cdab2012-10-02 19:25:50 +02005237#endif
Emeric Brun2b58d042012-09-20 17:10:03 +02005238}
5239
5240/* parse the "ecdhe" bind keyword keywords */
5241static int bind_parse_ecdhe(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
5242{
5243#if OPENSSL_VERSION_NUMBER < 0x0090800fL
5244 if (err)
5245 memprintf(err, "'%s' : library does not support elliptic curve Diffie-Hellman (too old)", args[cur_arg]);
5246 return ERR_ALERT | ERR_FATAL;
5247#elif defined(OPENSSL_NO_ECDH)
5248 if (err)
5249 memprintf(err, "'%s' : library does not support elliptic curve Diffie-Hellman (disabled via OPENSSL_NO_ECDH)", args[cur_arg]);
5250 return ERR_ALERT | ERR_FATAL;
5251#else
5252 if (!*args[cur_arg + 1]) {
5253 if (err)
5254 memprintf(err, "'%s' : missing named curve", args[cur_arg]);
5255 return ERR_ALERT | ERR_FATAL;
5256 }
5257
5258 conf->ecdhe = strdup(args[cur_arg + 1]);
Willy Tarreau79eeafa2012-09-14 07:53:05 +02005259
5260 return 0;
Emeric Brun2b58d042012-09-20 17:10:03 +02005261#endif
Willy Tarreau79eeafa2012-09-14 07:53:05 +02005262}
5263
Emeric Brun81c00f02012-09-21 14:31:21 +02005264/* parse the "crt_ignerr" and "ca_ignerr" bind keywords */
5265static int bind_parse_ignore_err(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
5266{
5267 int code;
5268 char *p = args[cur_arg + 1];
5269 unsigned long long *ignerr = &conf->crt_ignerr;
5270
5271 if (!*p) {
5272 if (err)
5273 memprintf(err, "'%s' : missing error IDs list", args[cur_arg]);
5274 return ERR_ALERT | ERR_FATAL;
5275 }
5276
5277 if (strcmp(args[cur_arg], "ca-ignore-err") == 0)
5278 ignerr = &conf->ca_ignerr;
5279
5280 if (strcmp(p, "all") == 0) {
5281 *ignerr = ~0ULL;
5282 return 0;
5283 }
5284
5285 while (p) {
5286 code = atoi(p);
5287 if ((code <= 0) || (code > 63)) {
5288 if (err)
5289 memprintf(err, "'%s' : ID '%d' out of range (1..63) in error IDs list '%s'",
5290 args[cur_arg], code, args[cur_arg + 1]);
5291 return ERR_ALERT | ERR_FATAL;
5292 }
5293 *ignerr |= 1ULL << code;
5294 p = strchr(p, ',');
5295 if (p)
5296 p++;
5297 }
5298
Emeric Brun2cb7ae52012-10-05 14:14:21 +02005299 return 0;
5300}
5301
5302/* parse the "force-sslv3" bind keyword */
5303static int bind_parse_force_sslv3(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
5304{
5305 conf->ssl_options |= BC_SSL_O_USE_SSLV3;
5306 return 0;
5307}
5308
5309/* parse the "force-tlsv10" bind keyword */
5310static int bind_parse_force_tlsv10(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
5311{
5312 conf->ssl_options |= BC_SSL_O_USE_TLSV10;
Emeric Brun2d0c4822012-10-02 13:45:20 +02005313 return 0;
5314}
5315
Emeric Brun2cb7ae52012-10-05 14:14:21 +02005316/* parse the "force-tlsv11" bind keyword */
5317static int bind_parse_force_tlsv11(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
5318{
5319#if SSL_OP_NO_TLSv1_1
5320 conf->ssl_options |= BC_SSL_O_USE_TLSV11;
5321 return 0;
5322#else
5323 if (err)
5324 memprintf(err, "'%s' : library does not support protocol TLSv1.1", args[cur_arg]);
5325 return ERR_ALERT | ERR_FATAL;
5326#endif
5327}
5328
5329/* parse the "force-tlsv12" bind keyword */
5330static int bind_parse_force_tlsv12(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
5331{
5332#if SSL_OP_NO_TLSv1_2
5333 conf->ssl_options |= BC_SSL_O_USE_TLSV12;
5334 return 0;
5335#else
5336 if (err)
5337 memprintf(err, "'%s' : library does not support protocol TLSv1.2", args[cur_arg]);
5338 return ERR_ALERT | ERR_FATAL;
5339#endif
5340}
5341
5342
Emeric Brun2d0c4822012-10-02 13:45:20 +02005343/* parse the "no-tls-tickets" bind keyword */
5344static int bind_parse_no_tls_tickets(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
5345{
Emeric Brun89675492012-10-05 13:48:26 +02005346 conf->ssl_options |= BC_SSL_O_NO_TLS_TICKETS;
Emeric Brun81c00f02012-09-21 14:31:21 +02005347 return 0;
5348}
5349
Emeric Brun2d0c4822012-10-02 13:45:20 +02005350
Emeric Brun9b3009b2012-10-05 11:55:06 +02005351/* parse the "no-sslv3" bind keyword */
5352static 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 +02005353{
Emeric Brun89675492012-10-05 13:48:26 +02005354 conf->ssl_options |= BC_SSL_O_NO_SSLV3;
Willy Tarreau79eeafa2012-09-14 07:53:05 +02005355 return 0;
5356}
5357
Emeric Brun9b3009b2012-10-05 11:55:06 +02005358/* parse the "no-tlsv10" bind keyword */
5359static 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 +02005360{
Emeric Brun89675492012-10-05 13:48:26 +02005361 conf->ssl_options |= BC_SSL_O_NO_TLSV10;
Emeric Brunc0ff4922012-09-28 19:37:02 +02005362 return 0;
5363}
5364
Emeric Brun9b3009b2012-10-05 11:55:06 +02005365/* parse the "no-tlsv11" bind keyword */
5366static 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 +02005367{
Emeric Brun89675492012-10-05 13:48:26 +02005368 conf->ssl_options |= BC_SSL_O_NO_TLSV11;
Emeric Brunc0ff4922012-09-28 19:37:02 +02005369 return 0;
5370}
5371
Emeric Brun9b3009b2012-10-05 11:55:06 +02005372/* parse the "no-tlsv12" bind keyword */
5373static 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 +02005374{
Emeric Brun89675492012-10-05 13:48:26 +02005375 conf->ssl_options |= BC_SSL_O_NO_TLSV12;
Willy Tarreau79eeafa2012-09-14 07:53:05 +02005376 return 0;
5377}
5378
Willy Tarreau6c9a3d52012-10-18 18:57:14 +02005379/* parse the "npn" bind keyword */
5380static int bind_parse_npn(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
5381{
5382#ifdef OPENSSL_NPN_NEGOTIATED
5383 char *p1, *p2;
5384
5385 if (!*args[cur_arg + 1]) {
5386 memprintf(err, "'%s' : missing the comma-delimited NPN protocol suite", args[cur_arg]);
5387 return ERR_ALERT | ERR_FATAL;
5388 }
5389
5390 free(conf->npn_str);
5391
Willy Tarreau3724da12016-02-12 17:11:12 +01005392 /* the NPN string is built as a suite of (<len> <name>)*,
5393 * so we reuse each comma to store the next <len> and need
5394 * one more for the end of the string.
5395 */
Willy Tarreau6c9a3d52012-10-18 18:57:14 +02005396 conf->npn_len = strlen(args[cur_arg + 1]) + 1;
Willy Tarreau3724da12016-02-12 17:11:12 +01005397 conf->npn_str = calloc(1, conf->npn_len + 1);
Willy Tarreau6c9a3d52012-10-18 18:57:14 +02005398 memcpy(conf->npn_str + 1, args[cur_arg + 1], conf->npn_len);
5399
5400 /* replace commas with the name length */
5401 p1 = conf->npn_str;
5402 p2 = p1 + 1;
5403 while (1) {
5404 p2 = memchr(p1 + 1, ',', conf->npn_str + conf->npn_len - (p1 + 1));
5405 if (!p2)
5406 p2 = p1 + 1 + strlen(p1 + 1);
5407
5408 if (p2 - (p1 + 1) > 255) {
5409 *p2 = '\0';
5410 memprintf(err, "'%s' : NPN protocol name too long : '%s'", args[cur_arg], p1 + 1);
5411 return ERR_ALERT | ERR_FATAL;
5412 }
5413
5414 *p1 = p2 - (p1 + 1);
5415 p1 = p2;
5416
5417 if (!*p2)
5418 break;
5419
5420 *(p2++) = '\0';
5421 }
5422 return 0;
5423#else
5424 if (err)
5425 memprintf(err, "'%s' : library does not support TLS NPN extension", args[cur_arg]);
5426 return ERR_ALERT | ERR_FATAL;
5427#endif
5428}
5429
Willy Tarreauab861d32013-04-02 02:30:41 +02005430/* parse the "alpn" bind keyword */
5431static int bind_parse_alpn(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
5432{
Dirkjan Bussink48f1c4e2014-02-13 12:29:42 +01005433#ifdef TLSEXT_TYPE_application_layer_protocol_negotiation
Willy Tarreauab861d32013-04-02 02:30:41 +02005434 char *p1, *p2;
5435
5436 if (!*args[cur_arg + 1]) {
5437 memprintf(err, "'%s' : missing the comma-delimited ALPN protocol suite", args[cur_arg]);
5438 return ERR_ALERT | ERR_FATAL;
5439 }
5440
5441 free(conf->alpn_str);
5442
Marcoen Hirschbergbef60912016-02-12 17:05:24 +01005443 /* the ALPN string is built as a suite of (<len> <name>)*,
5444 * so we reuse each comma to store the next <len> and need
5445 * one more for the end of the string.
5446 */
Willy Tarreauab861d32013-04-02 02:30:41 +02005447 conf->alpn_len = strlen(args[cur_arg + 1]) + 1;
Marcoen Hirschbergbef60912016-02-12 17:05:24 +01005448 conf->alpn_str = calloc(1, conf->alpn_len + 1);
Willy Tarreauab861d32013-04-02 02:30:41 +02005449 memcpy(conf->alpn_str + 1, args[cur_arg + 1], conf->alpn_len);
5450
5451 /* replace commas with the name length */
5452 p1 = conf->alpn_str;
5453 p2 = p1 + 1;
5454 while (1) {
5455 p2 = memchr(p1 + 1, ',', conf->alpn_str + conf->alpn_len - (p1 + 1));
5456 if (!p2)
5457 p2 = p1 + 1 + strlen(p1 + 1);
5458
5459 if (p2 - (p1 + 1) > 255) {
5460 *p2 = '\0';
5461 memprintf(err, "'%s' : ALPN protocol name too long : '%s'", args[cur_arg], p1 + 1);
5462 return ERR_ALERT | ERR_FATAL;
5463 }
5464
5465 *p1 = p2 - (p1 + 1);
5466 p1 = p2;
5467
5468 if (!*p2)
5469 break;
5470
5471 *(p2++) = '\0';
5472 }
5473 return 0;
5474#else
5475 if (err)
5476 memprintf(err, "'%s' : library does not support TLS ALPN extension", args[cur_arg]);
5477 return ERR_ALERT | ERR_FATAL;
5478#endif
5479}
5480
Willy Tarreau79eeafa2012-09-14 07:53:05 +02005481/* parse the "ssl" bind keyword */
Willy Tarreau4348fad2012-09-20 16:48:07 +02005482static 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 +02005483{
Willy Tarreau81796be2012-09-22 19:11:47 +02005484 struct listener *l;
5485
Willy Tarreau4348fad2012-09-20 16:48:07 +02005486 conf->is_ssl = 1;
Emeric Brun76d88952012-10-05 15:47:31 +02005487
5488 if (global.listen_default_ciphers && !conf->ciphers)
5489 conf->ciphers = strdup(global.listen_default_ciphers);
Emeric Brun2c86cbf2014-10-30 15:56:50 +01005490 conf->ssl_options |= global.listen_default_ssloptions;
Emeric Brun76d88952012-10-05 15:47:31 +02005491
Willy Tarreau81796be2012-09-22 19:11:47 +02005492 list_for_each_entry(l, &conf->listeners, by_bind)
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02005493 l->xprt = &ssl_sock;
Willy Tarreau81796be2012-09-22 19:11:47 +02005494
Willy Tarreau79eeafa2012-09-14 07:53:05 +02005495 return 0;
5496}
5497
Christopher Faulet31af49d2015-06-09 17:29:50 +02005498/* parse the "generate-certificates" bind keyword */
5499static int bind_parse_generate_certs(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
5500{
5501#ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME
5502 conf->generate_certs = 1;
5503#else
5504 memprintf(err, "%sthis version of openssl cannot generate SSL certificates.\n",
5505 err && *err ? *err : "");
5506#endif
5507 return 0;
5508}
5509
Emmanuel Hocdet65623372013-01-24 17:17:15 +01005510/* parse the "strict-sni" bind keyword */
5511static int bind_parse_strict_sni(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
5512{
5513 conf->strict_sni = 1;
5514 return 0;
Nenad Merdanovic05552d42015-02-27 19:56:49 +01005515}
5516
5517/* parse the "tls-ticket-keys" bind keyword */
5518static int bind_parse_tls_ticket_keys(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
5519{
5520#if (defined SSL_CTRL_SET_TLSEXT_TICKET_KEY_CB && TLS_TICKETS_NO > 0)
5521 FILE *f;
5522 int i = 0;
5523 char thisline[LINESIZE];
Nenad Merdanovic146defa2015-05-09 08:46:00 +02005524 struct tls_keys_ref *keys_ref;
Nenad Merdanovic05552d42015-02-27 19:56:49 +01005525
5526 if (!*args[cur_arg + 1]) {
5527 if (err)
5528 memprintf(err, "'%s' : missing TLS ticket keys file path", args[cur_arg]);
5529 return ERR_ALERT | ERR_FATAL;
5530 }
5531
Nenad Merdanovic200b0fa2015-05-09 08:46:01 +02005532 keys_ref = tlskeys_ref_lookup(args[cur_arg + 1]);
5533 if(keys_ref) {
5534 conf->keys_ref = keys_ref;
5535 return 0;
5536 }
5537
Vincent Bernat02779b62016-04-03 13:48:43 +02005538 keys_ref = malloc(sizeof(*keys_ref));
Nenad Merdanovic146defa2015-05-09 08:46:00 +02005539 keys_ref->tlskeys = malloc(TLS_TICKETS_NO * sizeof(struct tls_sess_key));
Nenad Merdanovic05552d42015-02-27 19:56:49 +01005540
5541 if ((f = fopen(args[cur_arg + 1], "r")) == NULL) {
5542 if (err)
5543 memprintf(err, "'%s' : unable to load ssl tickets keys file", args[cur_arg+1]);
5544 return ERR_ALERT | ERR_FATAL;
5545 }
5546
Nenad Merdanovic146defa2015-05-09 08:46:00 +02005547 keys_ref->filename = strdup(args[cur_arg + 1]);
5548
Nenad Merdanovic05552d42015-02-27 19:56:49 +01005549 while (fgets(thisline, sizeof(thisline), f) != NULL) {
5550 int len = strlen(thisline);
5551 /* Strip newline characters from the end */
5552 if(thisline[len - 1] == '\n')
5553 thisline[--len] = 0;
5554
5555 if(thisline[len - 1] == '\r')
5556 thisline[--len] = 0;
5557
Nenad Merdanovic146defa2015-05-09 08:46:00 +02005558 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 +01005559 if (err)
5560 memprintf(err, "'%s' : unable to decode base64 key on line %d", args[cur_arg+1], i + 1);
mildis16aa0152016-06-22 17:46:29 +02005561 fclose(f);
Nenad Merdanovic05552d42015-02-27 19:56:49 +01005562 return ERR_ALERT | ERR_FATAL;
5563 }
5564 i++;
5565 }
5566
5567 if (i < TLS_TICKETS_NO) {
5568 if (err)
5569 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 +02005570 fclose(f);
Nenad Merdanovic05552d42015-02-27 19:56:49 +01005571 return ERR_ALERT | ERR_FATAL;
5572 }
5573
5574 fclose(f);
5575
5576 /* Use penultimate key for encryption, handle when TLS_TICKETS_NO = 1 */
Nenad Merdanovic17891152016-03-25 22:16:57 +01005577 i -= 2;
5578 keys_ref->tls_ticket_enc_index = i < 0 ? 0 : i % TLS_TICKETS_NO;
Nenad Merdanovic200b0fa2015-05-09 08:46:01 +02005579 keys_ref->unique_id = -1;
Nenad Merdanovic146defa2015-05-09 08:46:00 +02005580 conf->keys_ref = keys_ref;
Nenad Merdanovic05552d42015-02-27 19:56:49 +01005581
Nenad Merdanovic200b0fa2015-05-09 08:46:01 +02005582 LIST_ADD(&tlskeys_reference, &keys_ref->list);
5583
Nenad Merdanovic05552d42015-02-27 19:56:49 +01005584 return 0;
5585#else
5586 if (err)
5587 memprintf(err, "'%s' : TLS ticket callback extension not supported", args[cur_arg]);
5588 return ERR_ALERT | ERR_FATAL;
5589#endif /* SSL_CTRL_SET_TLSEXT_TICKET_KEY_CB */
Emmanuel Hocdet65623372013-01-24 17:17:15 +01005590}
5591
Emeric Brund94b3fe2012-09-20 18:23:56 +02005592/* parse the "verify" bind keyword */
5593static int bind_parse_verify(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
5594{
5595 if (!*args[cur_arg + 1]) {
5596 if (err)
5597 memprintf(err, "'%s' : missing verify method", args[cur_arg]);
5598 return ERR_ALERT | ERR_FATAL;
5599 }
5600
5601 if (strcmp(args[cur_arg + 1], "none") == 0)
Emeric Brun850efd52014-01-29 12:24:34 +01005602 conf->verify = SSL_SOCK_VERIFY_NONE;
Emeric Brund94b3fe2012-09-20 18:23:56 +02005603 else if (strcmp(args[cur_arg + 1], "optional") == 0)
Emeric Brun850efd52014-01-29 12:24:34 +01005604 conf->verify = SSL_SOCK_VERIFY_OPTIONAL;
Emeric Brund94b3fe2012-09-20 18:23:56 +02005605 else if (strcmp(args[cur_arg + 1], "required") == 0)
Emeric Brun850efd52014-01-29 12:24:34 +01005606 conf->verify = SSL_SOCK_VERIFY_REQUIRED;
Emeric Brund94b3fe2012-09-20 18:23:56 +02005607 else {
5608 if (err)
5609 memprintf(err, "'%s' : unknown verify method '%s', only 'none', 'optional', and 'required' are supported\n",
5610 args[cur_arg], args[cur_arg + 1]);
5611 return ERR_ALERT | ERR_FATAL;
5612 }
5613
5614 return 0;
5615}
5616
Willy Tarreau92faadf2012-10-10 23:04:25 +02005617/************** "server" keywords ****************/
5618
Emeric Brunef42d922012-10-11 16:11:36 +02005619/* parse the "ca-file" server keyword */
5620static int srv_parse_ca_file(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
5621{
5622 if (!*args[*cur_arg + 1]) {
5623 if (err)
5624 memprintf(err, "'%s' : missing CAfile path", args[*cur_arg]);
5625 return ERR_ALERT | ERR_FATAL;
5626 }
5627
5628 if ((*args[*cur_arg + 1] != '/') && global.ca_base)
5629 memprintf(&newsrv->ssl_ctx.ca_file, "%s/%s", global.ca_base, args[*cur_arg + 1]);
5630 else
5631 memprintf(&newsrv->ssl_ctx.ca_file, "%s", args[*cur_arg + 1]);
5632
5633 return 0;
5634}
5635
Willy Tarreau92faadf2012-10-10 23:04:25 +02005636/* parse the "check-ssl" server keyword */
5637static int srv_parse_check_ssl(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
5638{
5639 newsrv->check.use_ssl = 1;
5640 if (global.connect_default_ciphers && !newsrv->ssl_ctx.ciphers)
5641 newsrv->ssl_ctx.ciphers = strdup(global.connect_default_ciphers);
Emeric Brun2c86cbf2014-10-30 15:56:50 +01005642 newsrv->ssl_ctx.options |= global.connect_default_ssloptions;
Willy Tarreau92faadf2012-10-10 23:04:25 +02005643 return 0;
5644}
5645
5646/* parse the "ciphers" server keyword */
5647static int srv_parse_ciphers(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
5648{
5649 if (!*args[*cur_arg + 1]) {
5650 memprintf(err, "'%s' : missing cipher suite", args[*cur_arg]);
5651 return ERR_ALERT | ERR_FATAL;
5652 }
5653
5654 free(newsrv->ssl_ctx.ciphers);
5655 newsrv->ssl_ctx.ciphers = strdup(args[*cur_arg + 1]);
5656 return 0;
5657}
5658
Emeric Brunef42d922012-10-11 16:11:36 +02005659/* parse the "crl-file" server keyword */
5660static int srv_parse_crl_file(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
5661{
5662#ifndef X509_V_FLAG_CRL_CHECK
5663 if (err)
5664 memprintf(err, "'%s' : library does not support CRL verify", args[*cur_arg]);
5665 return ERR_ALERT | ERR_FATAL;
5666#else
5667 if (!*args[*cur_arg + 1]) {
5668 if (err)
5669 memprintf(err, "'%s' : missing CRLfile path", args[*cur_arg]);
5670 return ERR_ALERT | ERR_FATAL;
5671 }
5672
5673 if ((*args[*cur_arg + 1] != '/') && global.ca_base)
5674 memprintf(&newsrv->ssl_ctx.crl_file, "%s/%s", global.ca_base, args[*cur_arg + 1]);
5675 else
5676 memprintf(&newsrv->ssl_ctx.crl_file, "%s", args[*cur_arg + 1]);
5677
5678 return 0;
5679#endif
5680}
5681
Emeric Bruna7aa3092012-10-26 12:58:00 +02005682/* parse the "crt" server keyword */
5683static int srv_parse_crt(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
5684{
5685 if (!*args[*cur_arg + 1]) {
5686 if (err)
5687 memprintf(err, "'%s' : missing certificate file path", args[*cur_arg]);
5688 return ERR_ALERT | ERR_FATAL;
5689 }
5690
5691 if ((*args[*cur_arg + 1] != '/') && global.crt_base)
5692 memprintf(&newsrv->ssl_ctx.client_crt, "%s/%s", global.ca_base, args[*cur_arg + 1]);
5693 else
5694 memprintf(&newsrv->ssl_ctx.client_crt, "%s", args[*cur_arg + 1]);
5695
5696 return 0;
5697}
Emeric Brunef42d922012-10-11 16:11:36 +02005698
Willy Tarreau92faadf2012-10-10 23:04:25 +02005699/* parse the "force-sslv3" server keyword */
5700static int srv_parse_force_sslv3(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
5701{
5702 newsrv->ssl_ctx.options |= SRV_SSL_O_USE_SSLV3;
5703 return 0;
5704}
5705
5706/* parse the "force-tlsv10" server keyword */
5707static int srv_parse_force_tlsv10(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
5708{
5709 newsrv->ssl_ctx.options |= SRV_SSL_O_USE_TLSV10;
5710 return 0;
5711}
5712
5713/* parse the "force-tlsv11" server keyword */
5714static int srv_parse_force_tlsv11(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
5715{
5716#if SSL_OP_NO_TLSv1_1
5717 newsrv->ssl_ctx.options |= SRV_SSL_O_USE_TLSV11;
5718 return 0;
5719#else
5720 if (err)
5721 memprintf(err, "'%s' : library does not support protocol TLSv1.1", args[*cur_arg]);
5722 return ERR_ALERT | ERR_FATAL;
5723#endif
5724}
5725
5726/* parse the "force-tlsv12" server keyword */
5727static int srv_parse_force_tlsv12(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
5728{
5729#if SSL_OP_NO_TLSv1_2
5730 newsrv->ssl_ctx.options |= SRV_SSL_O_USE_TLSV12;
5731 return 0;
5732#else
5733 if (err)
5734 memprintf(err, "'%s' : library does not support protocol TLSv1.2", args[*cur_arg]);
5735 return ERR_ALERT | ERR_FATAL;
5736#endif
5737}
5738
Willy Tarreau2a3fb1c2015-02-05 16:47:07 +01005739/* parse the "no-ssl-reuse" server keyword */
5740static int srv_parse_no_ssl_reuse(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
5741{
5742 newsrv->ssl_ctx.options |= SRV_SSL_O_NO_REUSE;
5743 return 0;
5744}
5745
Willy Tarreau92faadf2012-10-10 23:04:25 +02005746/* parse the "no-sslv3" server keyword */
5747static int srv_parse_no_sslv3(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
5748{
5749 newsrv->ssl_ctx.options |= SRV_SSL_O_NO_SSLV3;
5750 return 0;
5751}
5752
5753/* parse the "no-tlsv10" server keyword */
5754static int srv_parse_no_tlsv10(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
5755{
5756 newsrv->ssl_ctx.options |= SRV_SSL_O_NO_TLSV10;
5757 return 0;
5758}
5759
5760/* parse the "no-tlsv11" server keyword */
5761static int srv_parse_no_tlsv11(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
5762{
5763 newsrv->ssl_ctx.options |= SRV_SSL_O_NO_TLSV11;
5764 return 0;
5765}
5766
5767/* parse the "no-tlsv12" server keyword */
5768static int srv_parse_no_tlsv12(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
5769{
5770 newsrv->ssl_ctx.options |= SRV_SSL_O_NO_TLSV12;
5771 return 0;
5772}
5773
Emeric Brunf9c5c472012-10-11 15:28:34 +02005774/* parse the "no-tls-tickets" server keyword */
5775static int srv_parse_no_tls_tickets(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
5776{
5777 newsrv->ssl_ctx.options |= SRV_SSL_O_NO_TLS_TICKETS;
5778 return 0;
5779}
David Safb76832014-05-08 23:42:08 -04005780/* parse the "send-proxy-v2-ssl" server keyword */
5781static int srv_parse_send_proxy_ssl(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
5782{
5783 newsrv->pp_opts |= SRV_PP_V2;
5784 newsrv->pp_opts |= SRV_PP_V2_SSL;
5785 return 0;
5786}
5787
5788/* parse the "send-proxy-v2-ssl-cn" server keyword */
5789static int srv_parse_send_proxy_cn(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
5790{
5791 newsrv->pp_opts |= SRV_PP_V2;
5792 newsrv->pp_opts |= SRV_PP_V2_SSL;
5793 newsrv->pp_opts |= SRV_PP_V2_SSL_CN;
5794 return 0;
5795}
Emeric Brunf9c5c472012-10-11 15:28:34 +02005796
Willy Tarreau732eac42015-07-09 11:40:25 +02005797/* parse the "sni" server keyword */
5798static int srv_parse_sni(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
5799{
5800#ifndef SSL_CTRL_SET_TLSEXT_HOSTNAME
5801 memprintf(err, "'%s' : the current SSL library doesn't support the SNI TLS extension", args[*cur_arg]);
5802 return ERR_ALERT | ERR_FATAL;
5803#else
Cyril Bonté23d19d62016-03-07 22:13:22 +01005804 int idx;
Willy Tarreau732eac42015-07-09 11:40:25 +02005805 struct sample_expr *expr;
5806
5807 if (!*args[*cur_arg + 1]) {
5808 memprintf(err, "'%s' : missing sni expression", args[*cur_arg]);
5809 return ERR_ALERT | ERR_FATAL;
5810 }
5811
Cyril Bonté23d19d62016-03-07 22:13:22 +01005812 idx = (*cur_arg) + 1;
Willy Tarreau732eac42015-07-09 11:40:25 +02005813 proxy->conf.args.ctx = ARGC_SRV;
5814
Cyril Bonté23d19d62016-03-07 22:13:22 +01005815 expr = sample_parse_expr((char **)args, &idx, px->conf.file, px->conf.line, err, &proxy->conf.args);
Willy Tarreau732eac42015-07-09 11:40:25 +02005816 if (!expr) {
5817 memprintf(err, "error detected while parsing sni expression : %s", *err);
5818 return ERR_ALERT | ERR_FATAL;
5819 }
5820
5821 if (!(expr->fetch->val & SMP_VAL_BE_SRV_CON)) {
5822 memprintf(err, "error detected while parsing sni expression : "
5823 " fetch method '%s' extracts information from '%s', none of which is available here.\n",
Cyril Bonté23d19d62016-03-07 22:13:22 +01005824 args[idx-1], sample_src_names(expr->fetch->use));
Willy Tarreau732eac42015-07-09 11:40:25 +02005825 return ERR_ALERT | ERR_FATAL;
5826 }
5827
5828 px->http_needed |= !!(expr->fetch->use & SMP_USE_HTTP_ANY);
5829 newsrv->ssl_ctx.sni = expr;
5830 return 0;
5831#endif
5832}
5833
Willy Tarreau92faadf2012-10-10 23:04:25 +02005834/* parse the "ssl" server keyword */
5835static int srv_parse_ssl(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
5836{
5837 newsrv->use_ssl = 1;
5838 if (global.connect_default_ciphers && !newsrv->ssl_ctx.ciphers)
5839 newsrv->ssl_ctx.ciphers = strdup(global.connect_default_ciphers);
5840 return 0;
5841}
5842
Emeric Brunef42d922012-10-11 16:11:36 +02005843/* parse the "verify" server keyword */
5844static int srv_parse_verify(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
5845{
5846 if (!*args[*cur_arg + 1]) {
5847 if (err)
5848 memprintf(err, "'%s' : missing verify method", args[*cur_arg]);
5849 return ERR_ALERT | ERR_FATAL;
5850 }
5851
5852 if (strcmp(args[*cur_arg + 1], "none") == 0)
Emeric Brun850efd52014-01-29 12:24:34 +01005853 newsrv->ssl_ctx.verify = SSL_SOCK_VERIFY_NONE;
Emeric Brunef42d922012-10-11 16:11:36 +02005854 else if (strcmp(args[*cur_arg + 1], "required") == 0)
Emeric Brun850efd52014-01-29 12:24:34 +01005855 newsrv->ssl_ctx.verify = SSL_SOCK_VERIFY_REQUIRED;
Emeric Brunef42d922012-10-11 16:11:36 +02005856 else {
5857 if (err)
5858 memprintf(err, "'%s' : unknown verify method '%s', only 'none' and 'required' are supported\n",
5859 args[*cur_arg], args[*cur_arg + 1]);
5860 return ERR_ALERT | ERR_FATAL;
5861 }
5862
Evan Broderbe554312013-06-27 00:05:25 -07005863 return 0;
5864}
5865
5866/* parse the "verifyhost" server keyword */
5867static int srv_parse_verifyhost(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
5868{
5869 if (!*args[*cur_arg + 1]) {
5870 if (err)
5871 memprintf(err, "'%s' : missing hostname to verify against", args[*cur_arg]);
5872 return ERR_ALERT | ERR_FATAL;
5873 }
5874
5875 newsrv->ssl_ctx.verify_host = strdup(args[*cur_arg + 1]);
5876
Emeric Brunef42d922012-10-11 16:11:36 +02005877 return 0;
5878}
5879
Emeric Brun2c86cbf2014-10-30 15:56:50 +01005880/* parse the "ssl-default-bind-options" keyword in global section */
5881static int ssl_parse_default_bind_options(char **args, int section_type, struct proxy *curpx,
5882 struct proxy *defpx, const char *file, int line,
5883 char **err) {
5884 int i = 1;
5885
5886 if (*(args[i]) == 0) {
5887 memprintf(err, "global statement '%s' expects an option as an argument.", args[0]);
5888 return -1;
5889 }
5890 while (*(args[i])) {
5891 if (!strcmp(args[i], "no-sslv3"))
5892 global.listen_default_ssloptions |= BC_SSL_O_NO_SSLV3;
5893 else if (!strcmp(args[i], "no-tlsv10"))
5894 global.listen_default_ssloptions |= BC_SSL_O_NO_TLSV10;
5895 else if (!strcmp(args[i], "no-tlsv11"))
5896 global.listen_default_ssloptions |= BC_SSL_O_NO_TLSV11;
5897 else if (!strcmp(args[i], "no-tlsv12"))
5898 global.listen_default_ssloptions |= BC_SSL_O_NO_TLSV12;
5899 else if (!strcmp(args[i], "force-sslv3"))
5900 global.listen_default_ssloptions |= BC_SSL_O_USE_SSLV3;
5901 else if (!strcmp(args[i], "force-tlsv10"))
5902 global.listen_default_ssloptions |= BC_SSL_O_USE_TLSV10;
5903 else if (!strcmp(args[i], "force-tlsv11")) {
5904#if SSL_OP_NO_TLSv1_1
5905 global.listen_default_ssloptions |= BC_SSL_O_USE_TLSV11;
5906#else
5907 memprintf(err, "'%s' '%s': library does not support protocol TLSv1.1", args[0], args[i]);
5908 return -1;
5909#endif
5910 }
5911 else if (!strcmp(args[i], "force-tlsv12")) {
5912#if SSL_OP_NO_TLSv1_2
5913 global.listen_default_ssloptions |= BC_SSL_O_USE_TLSV12;
5914#else
5915 memprintf(err, "'%s' '%s': library does not support protocol TLSv1.2", args[0], args[i]);
5916 return -1;
5917#endif
5918 }
5919 else if (!strcmp(args[i], "no-tls-tickets"))
5920 global.listen_default_ssloptions |= BC_SSL_O_NO_TLS_TICKETS;
5921 else {
5922 memprintf(err, "unknown option '%s' on global statement '%s'.", args[i], args[0]);
5923 return -1;
5924 }
5925 i++;
5926 }
5927 return 0;
5928}
5929
5930/* parse the "ssl-default-server-options" keyword in global section */
5931static int ssl_parse_default_server_options(char **args, int section_type, struct proxy *curpx,
5932 struct proxy *defpx, const char *file, int line,
5933 char **err) {
5934 int i = 1;
5935
5936 if (*(args[i]) == 0) {
5937 memprintf(err, "global statement '%s' expects an option as an argument.", args[0]);
5938 return -1;
5939 }
5940 while (*(args[i])) {
5941 if (!strcmp(args[i], "no-sslv3"))
5942 global.connect_default_ssloptions |= SRV_SSL_O_NO_SSLV3;
5943 else if (!strcmp(args[i], "no-tlsv10"))
5944 global.connect_default_ssloptions |= SRV_SSL_O_NO_TLSV10;
5945 else if (!strcmp(args[i], "no-tlsv11"))
5946 global.connect_default_ssloptions |= SRV_SSL_O_NO_TLSV11;
5947 else if (!strcmp(args[i], "no-tlsv12"))
5948 global.connect_default_ssloptions |= SRV_SSL_O_NO_TLSV12;
5949 else if (!strcmp(args[i], "force-sslv3"))
5950 global.connect_default_ssloptions |= SRV_SSL_O_USE_SSLV3;
5951 else if (!strcmp(args[i], "force-tlsv10"))
5952 global.connect_default_ssloptions |= SRV_SSL_O_USE_TLSV10;
5953 else if (!strcmp(args[i], "force-tlsv11")) {
5954#if SSL_OP_NO_TLSv1_1
5955 global.connect_default_ssloptions |= SRV_SSL_O_USE_TLSV11;
5956#else
5957 memprintf(err, "'%s' '%s': library does not support protocol TLSv1.1", args[0], args[i]);
5958 return -1;
5959#endif
5960 }
5961 else if (!strcmp(args[i], "force-tlsv12")) {
5962#if SSL_OP_NO_TLSv1_2
5963 global.connect_default_ssloptions |= SRV_SSL_O_USE_TLSV12;
5964#else
5965 memprintf(err, "'%s' '%s': library does not support protocol TLSv1.2", args[0], args[i]);
5966 return -1;
5967#endif
5968 }
5969 else if (!strcmp(args[i], "no-tls-tickets"))
5970 global.connect_default_ssloptions |= SRV_SSL_O_NO_TLS_TICKETS;
5971 else {
5972 memprintf(err, "unknown option '%s' on global statement '%s'.", args[i], args[0]);
5973 return -1;
5974 }
5975 i++;
5976 }
5977 return 0;
5978}
5979
Willy Tarreau7875d092012-09-10 08:20:03 +02005980/* Note: must not be declared <const> as its list will be overwritten.
5981 * Please take care of keeping this list alphabetically sorted.
5982 */
Willy Tarreaudc13c112013-06-21 23:16:39 +02005983static struct sample_fetch_kw_list sample_fetch_keywords = {ILH, {
Emeric Brun645ae792014-04-30 14:21:06 +02005984 { "ssl_bc", smp_fetch_ssl_fc, 0, NULL, SMP_T_BOOL, SMP_USE_L5SRV },
Thierry FOURNIER07ee64e2015-07-06 23:43:03 +02005985 { "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 +02005986 { "ssl_bc_cipher", smp_fetch_ssl_fc_cipher, 0, NULL, SMP_T_STR, SMP_USE_L5SRV },
5987 { "ssl_bc_protocol", smp_fetch_ssl_fc_protocol, 0, NULL, SMP_T_STR, SMP_USE_L5SRV },
Emeric Brunb73a9b02014-04-30 18:49:19 +02005988 { "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 +02005989 { "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 +02005990 { "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 +02005991 { "ssl_c_ca_err", smp_fetch_ssl_c_ca_err, 0, NULL, SMP_T_SINT, SMP_USE_L5CLI },
5992 { "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 +01005993 { "ssl_c_der", smp_fetch_ssl_x_der, 0, NULL, SMP_T_BIN, SMP_USE_L5CLI },
Thierry FOURNIER07ee64e2015-07-06 23:43:03 +02005994 { "ssl_c_err", smp_fetch_ssl_c_err, 0, NULL, SMP_T_SINT, SMP_USE_L5CLI },
Emeric Brunba841a12014-04-30 17:05:08 +02005995 { "ssl_c_i_dn", smp_fetch_ssl_x_i_dn, ARG2(0,STR,SINT), NULL, SMP_T_STR, SMP_USE_L5CLI },
5996 { "ssl_c_key_alg", smp_fetch_ssl_x_key_alg, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
5997 { "ssl_c_notafter", smp_fetch_ssl_x_notafter, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
5998 { "ssl_c_notbefore", smp_fetch_ssl_x_notbefore, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
5999 { "ssl_c_sig_alg", smp_fetch_ssl_x_sig_alg, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
6000 { "ssl_c_s_dn", smp_fetch_ssl_x_s_dn, ARG2(0,STR,SINT), NULL, SMP_T_STR, SMP_USE_L5CLI },
6001 { "ssl_c_serial", smp_fetch_ssl_x_serial, 0, NULL, SMP_T_BIN, SMP_USE_L5CLI },
6002 { "ssl_c_sha1", smp_fetch_ssl_x_sha1, 0, NULL, SMP_T_BIN, SMP_USE_L5CLI },
Willy Tarreau80aca902013-01-07 15:42:20 +01006003 { "ssl_c_used", smp_fetch_ssl_c_used, 0, NULL, SMP_T_BOOL, SMP_USE_L5CLI },
Thierry FOURNIER07ee64e2015-07-06 23:43:03 +02006004 { "ssl_c_verify", smp_fetch_ssl_c_verify, 0, NULL, SMP_T_SINT, SMP_USE_L5CLI },
6005 { "ssl_c_version", smp_fetch_ssl_x_version, 0, NULL, SMP_T_SINT, SMP_USE_L5CLI },
Emeric Brun43e79582014-10-29 19:03:26 +01006006 { "ssl_f_der", smp_fetch_ssl_x_der, 0, NULL, SMP_T_BIN, SMP_USE_L5CLI },
Emeric Brunba841a12014-04-30 17:05:08 +02006007 { "ssl_f_i_dn", smp_fetch_ssl_x_i_dn, ARG2(0,STR,SINT), NULL, SMP_T_STR, SMP_USE_L5CLI },
6008 { "ssl_f_key_alg", smp_fetch_ssl_x_key_alg, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
6009 { "ssl_f_notafter", smp_fetch_ssl_x_notafter, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
6010 { "ssl_f_notbefore", smp_fetch_ssl_x_notbefore, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
6011 { "ssl_f_sig_alg", smp_fetch_ssl_x_sig_alg, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
6012 { "ssl_f_s_dn", smp_fetch_ssl_x_s_dn, ARG2(0,STR,SINT), NULL, SMP_T_STR, SMP_USE_L5CLI },
6013 { "ssl_f_serial", smp_fetch_ssl_x_serial, 0, NULL, SMP_T_BIN, SMP_USE_L5CLI },
Emeric Brun55f4fa82014-04-30 17:11:25 +02006014 { "ssl_f_sha1", smp_fetch_ssl_x_sha1, 0, NULL, SMP_T_BIN, SMP_USE_L5CLI },
Thierry FOURNIER07ee64e2015-07-06 23:43:03 +02006015 { "ssl_f_version", smp_fetch_ssl_x_version, 0, NULL, SMP_T_SINT, SMP_USE_L5CLI },
Willy Tarreau80aca902013-01-07 15:42:20 +01006016 { "ssl_fc", smp_fetch_ssl_fc, 0, NULL, SMP_T_BOOL, SMP_USE_L5CLI },
Thierry FOURNIER07ee64e2015-07-06 23:43:03 +02006017 { "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 +01006018 { "ssl_fc_cipher", smp_fetch_ssl_fc_cipher, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
Willy Tarreau80aca902013-01-07 15:42:20 +01006019 { "ssl_fc_has_crt", smp_fetch_ssl_fc_has_crt, 0, NULL, SMP_T_BOOL, SMP_USE_L5CLI },
6020 { "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 +02006021 { "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 +02006022#ifdef OPENSSL_NPN_NEGOTIATED
Thierry FOURNIER7654c9f2013-12-17 00:20:33 +01006023 { "ssl_fc_npn", smp_fetch_ssl_fc_npn, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
Willy Tarreaua33c6542012-10-15 13:19:06 +02006024#endif
Dirkjan Bussink48f1c4e2014-02-13 12:29:42 +01006025#ifdef TLSEXT_TYPE_application_layer_protocol_negotiation
Thierry FOURNIER7654c9f2013-12-17 00:20:33 +01006026 { "ssl_fc_alpn", smp_fetch_ssl_fc_alpn, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
Willy Tarreauab861d32013-04-02 02:30:41 +02006027#endif
Thierry FOURNIER7654c9f2013-12-17 00:20:33 +01006028 { "ssl_fc_protocol", smp_fetch_ssl_fc_protocol, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
Emeric Brunb73a9b02014-04-30 18:49:19 +02006029 { "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 +02006030 { "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 +01006031 { "ssl_fc_session_id", smp_fetch_ssl_fc_session_id, 0, NULL, SMP_T_BIN, SMP_USE_L5CLI },
6032 { "ssl_fc_sni", smp_fetch_ssl_fc_sni, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
Willy Tarreau7875d092012-09-10 08:20:03 +02006033 { NULL, NULL, 0, 0, 0 },
6034}};
6035
6036/* Note: must not be declared <const> as its list will be overwritten.
6037 * Please take care of keeping this list alphabetically sorted.
6038 */
Willy Tarreaudc13c112013-06-21 23:16:39 +02006039static struct acl_kw_list acl_kws = {ILH, {
Thierry FOURNIERc5a4e982014-03-05 16:07:08 +01006040 { "ssl_fc_sni_end", "ssl_fc_sni", PAT_MATCH_END },
6041 { "ssl_fc_sni_reg", "ssl_fc_sni", PAT_MATCH_REG },
Willy Tarreau8ed669b2013-01-11 15:49:37 +01006042 { /* END */ },
Willy Tarreau7875d092012-09-10 08:20:03 +02006043}};
6044
Willy Tarreau79eeafa2012-09-14 07:53:05 +02006045/* Note: must not be declared <const> as its list will be overwritten.
6046 * Please take care of keeping this list alphabetically sorted, doing so helps
6047 * all code contributors.
6048 * Optional keywords are also declared with a NULL ->parse() function so that
6049 * the config parser can report an appropriate error when a known keyword was
6050 * not enabled.
6051 */
Willy Tarreau51fb7652012-09-18 18:24:39 +02006052static struct bind_kw_list bind_kws = { "SSL", { }, {
Nenad Merdanovic05552d42015-02-27 19:56:49 +01006053 { "alpn", bind_parse_alpn, 1 }, /* set ALPN supported protocols */
6054 { "ca-file", bind_parse_ca_file, 1 }, /* set CAfile to process verify on client cert */
6055 { "ca-ignore-err", bind_parse_ignore_err, 1 }, /* set error IDs to ignore on verify depth > 0 */
Christopher Faulet31af49d2015-06-09 17:29:50 +02006056 { "ca-sign-file", bind_parse_ca_sign_file, 1 }, /* set CAFile used to generate and sign server certs */
6057 { "ca-sign-pass", bind_parse_ca_sign_pass, 1 }, /* set CAKey passphrase */
Nenad Merdanovic05552d42015-02-27 19:56:49 +01006058 { "ciphers", bind_parse_ciphers, 1 }, /* set SSL cipher suite */
6059 { "crl-file", bind_parse_crl_file, 1 }, /* set certificat revocation list file use on client cert verify */
6060 { "crt", bind_parse_crt, 1 }, /* load SSL certificates from this location */
6061 { "crt-ignore-err", bind_parse_ignore_err, 1 }, /* set error IDs to ingore on verify depth == 0 */
6062 { "crt-list", bind_parse_crt_list, 1 }, /* load a list of crt from this location */
6063 { "ecdhe", bind_parse_ecdhe, 1 }, /* defines named curve for elliptic curve Diffie-Hellman */
6064 { "force-sslv3", bind_parse_force_sslv3, 0 }, /* force SSLv3 */
6065 { "force-tlsv10", bind_parse_force_tlsv10, 0 }, /* force TLSv10 */
6066 { "force-tlsv11", bind_parse_force_tlsv11, 0 }, /* force TLSv11 */
6067 { "force-tlsv12", bind_parse_force_tlsv12, 0 }, /* force TLSv12 */
Christopher Faulet31af49d2015-06-09 17:29:50 +02006068 { "generate-certificates", bind_parse_generate_certs, 0 }, /* enable the server certificates generation */
Nenad Merdanovic05552d42015-02-27 19:56:49 +01006069 { "no-sslv3", bind_parse_no_sslv3, 0 }, /* disable SSLv3 */
6070 { "no-tlsv10", bind_parse_no_tlsv10, 0 }, /* disable TLSv10 */
6071 { "no-tlsv11", bind_parse_no_tlsv11, 0 }, /* disable TLSv11 */
6072 { "no-tlsv12", bind_parse_no_tlsv12, 0 }, /* disable TLSv12 */
6073 { "no-tls-tickets", bind_parse_no_tls_tickets, 0 }, /* disable session resumption tickets */
6074 { "ssl", bind_parse_ssl, 0 }, /* enable SSL processing */
6075 { "strict-sni", bind_parse_strict_sni, 0 }, /* refuse negotiation if sni doesn't match a certificate */
6076 { "tls-ticket-keys", bind_parse_tls_ticket_keys, 1 }, /* set file to load TLS ticket keys from */
6077 { "verify", bind_parse_verify, 1 }, /* set SSL verify method */
6078 { "npn", bind_parse_npn, 1 }, /* set NPN supported protocols */
Willy Tarreau79eeafa2012-09-14 07:53:05 +02006079 { NULL, NULL, 0 },
6080}};
Emeric Brun46591952012-05-18 15:47:34 +02006081
Willy Tarreau92faadf2012-10-10 23:04:25 +02006082/* Note: must not be declared <const> as its list will be overwritten.
6083 * Please take care of keeping this list alphabetically sorted, doing so helps
6084 * all code contributors.
6085 * Optional keywords are also declared with a NULL ->parse() function so that
6086 * the config parser can report an appropriate error when a known keyword was
6087 * not enabled.
6088 */
6089static struct srv_kw_list srv_kws = { "SSL", { }, {
Emeric Brunef42d922012-10-11 16:11:36 +02006090 { "ca-file", srv_parse_ca_file, 1, 0 }, /* set CAfile to process verify server cert */
Emeric Brunecc91fe2012-10-11 15:05:10 +02006091 { "check-ssl", srv_parse_check_ssl, 0, 0 }, /* enable SSL for health checks */
6092 { "ciphers", srv_parse_ciphers, 1, 0 }, /* select the cipher suite */
Emeric Brunef42d922012-10-11 16:11:36 +02006093 { "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 +02006094 { "crt", srv_parse_crt, 1, 0 }, /* set client certificate */
Emeric Brunecc91fe2012-10-11 15:05:10 +02006095 { "force-sslv3", srv_parse_force_sslv3, 0, 0 }, /* force SSLv3 */
6096 { "force-tlsv10", srv_parse_force_tlsv10, 0, 0 }, /* force TLSv10 */
6097 { "force-tlsv11", srv_parse_force_tlsv11, 0, 0 }, /* force TLSv11 */
6098 { "force-tlsv12", srv_parse_force_tlsv12, 0, 0 }, /* force TLSv12 */
Willy Tarreau2a3fb1c2015-02-05 16:47:07 +01006099 { "no-ssl-reuse", srv_parse_no_ssl_reuse, 0, 0 }, /* disable session reuse */
Emeric Brunecc91fe2012-10-11 15:05:10 +02006100 { "no-sslv3", srv_parse_no_sslv3, 0, 0 }, /* disable SSLv3 */
6101 { "no-tlsv10", srv_parse_no_tlsv10, 0, 0 }, /* disable TLSv10 */
6102 { "no-tlsv11", srv_parse_no_tlsv11, 0, 0 }, /* disable TLSv11 */
6103 { "no-tlsv12", srv_parse_no_tlsv12, 0, 0 }, /* disable TLSv12 */
Emeric Brunf9c5c472012-10-11 15:28:34 +02006104 { "no-tls-tickets", srv_parse_no_tls_tickets, 0, 0 }, /* disable session resumption tickets */
David Safb76832014-05-08 23:42:08 -04006105 { "send-proxy-v2-ssl", srv_parse_send_proxy_ssl, 0, 0 }, /* send PROXY protocol header v2 with SSL info */
6106 { "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 +02006107 { "sni", srv_parse_sni, 1, 0 }, /* send SNI extension */
Emeric Brunecc91fe2012-10-11 15:05:10 +02006108 { "ssl", srv_parse_ssl, 0, 0 }, /* enable SSL processing */
Emeric Brunef42d922012-10-11 16:11:36 +02006109 { "verify", srv_parse_verify, 1, 0 }, /* set SSL verify method */
Evan Broderbe554312013-06-27 00:05:25 -07006110 { "verifyhost", srv_parse_verifyhost, 1, 0 }, /* require that SSL cert verifies for hostname */
Willy Tarreau92faadf2012-10-10 23:04:25 +02006111 { NULL, NULL, 0, 0 },
6112}};
6113
Emeric Brun2c86cbf2014-10-30 15:56:50 +01006114static struct cfg_kw_list cfg_kws = {ILH, {
6115 { CFG_GLOBAL, "ssl-default-bind-options", ssl_parse_default_bind_options },
6116 { CFG_GLOBAL, "ssl-default-server-options", ssl_parse_default_server_options },
6117 { 0, NULL, NULL },
6118}};
6119
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02006120/* transport-layer operations for SSL sockets */
6121struct xprt_ops ssl_sock = {
Emeric Brun46591952012-05-18 15:47:34 +02006122 .snd_buf = ssl_sock_from_buf,
6123 .rcv_buf = ssl_sock_to_buf,
6124 .rcv_pipe = NULL,
6125 .snd_pipe = NULL,
6126 .shutr = NULL,
6127 .shutw = ssl_sock_shutw,
6128 .close = ssl_sock_close,
6129 .init = ssl_sock_init,
6130};
6131
Daniel Jakots54ffb912015-11-06 20:02:41 +01006132#if (OPENSSL_VERSION_NUMBER >= 0x1000200fL && !defined OPENSSL_NO_TLSEXT && !defined OPENSSL_IS_BORINGSSL && !defined LIBRESSL_VERSION_NUMBER)
Janusz Dziemidowicz2c701b52015-03-07 23:03:59 +01006133
6134static void ssl_sock_sctl_free_func(void *parent, void *ptr, CRYPTO_EX_DATA *ad, int idx, long argl, void *argp)
6135{
6136 if (ptr) {
6137 chunk_destroy(ptr);
6138 free(ptr);
6139 }
6140}
6141
6142#endif
6143
Emeric Brun46591952012-05-18 15:47:34 +02006144__attribute__((constructor))
Willy Tarreau92faadf2012-10-10 23:04:25 +02006145static void __ssl_sock_init(void)
6146{
Emeric Brun46591952012-05-18 15:47:34 +02006147 STACK_OF(SSL_COMP)* cm;
6148
Willy Tarreau610f04b2014-02-13 11:36:41 +01006149#ifdef LISTEN_DEFAULT_CIPHERS
6150 global.listen_default_ciphers = LISTEN_DEFAULT_CIPHERS;
6151#endif
6152#ifdef CONNECT_DEFAULT_CIPHERS
6153 global.connect_default_ciphers = CONNECT_DEFAULT_CIPHERS;
6154#endif
6155 if (global.listen_default_ciphers)
6156 global.listen_default_ciphers = strdup(global.listen_default_ciphers);
6157 if (global.connect_default_ciphers)
6158 global.connect_default_ciphers = strdup(global.connect_default_ciphers);
Emeric Brun2c86cbf2014-10-30 15:56:50 +01006159 global.listen_default_ssloptions = BC_SSL_O_NONE;
6160 global.connect_default_ssloptions = SRV_SSL_O_NONE;
Willy Tarreau610f04b2014-02-13 11:36:41 +01006161
Emeric Brun46591952012-05-18 15:47:34 +02006162 SSL_library_init();
6163 cm = SSL_COMP_get_compression_methods();
6164 sk_SSL_COMP_zero(cm);
Daniel Jakots54ffb912015-11-06 20:02:41 +01006165#if (OPENSSL_VERSION_NUMBER >= 0x1000200fL && !defined OPENSSL_NO_TLSEXT && !defined OPENSSL_IS_BORINGSSL && !defined LIBRESSL_VERSION_NUMBER)
Janusz Dziemidowicz2c701b52015-03-07 23:03:59 +01006166 sctl_ex_index = SSL_CTX_get_ex_new_index(0, NULL, NULL, NULL, ssl_sock_sctl_free_func);
6167#endif
Willy Tarreau7875d092012-09-10 08:20:03 +02006168 sample_register_fetches(&sample_fetch_keywords);
6169 acl_register_keywords(&acl_kws);
Willy Tarreau79eeafa2012-09-14 07:53:05 +02006170 bind_register_keywords(&bind_kws);
Willy Tarreau92faadf2012-10-10 23:04:25 +02006171 srv_register_keywords(&srv_kws);
Emeric Brun2c86cbf2014-10-30 15:56:50 +01006172 cfg_register_keywords(&cfg_kws);
Willy Tarreaud92aa5c2015-01-15 21:34:39 +01006173
6174 global.ssl_session_max_cost = SSL_SESSION_MAX_COST;
6175 global.ssl_handshake_max_cost = SSL_HANDSHAKE_MAX_COST;
Remi Gacogne4f902b82015-05-28 16:23:00 +02006176
6177#ifndef OPENSSL_NO_DH
6178 ssl_dh_ptr_index = SSL_CTX_get_ex_new_index(0, NULL, NULL, NULL, NULL);
6179#endif
Thierry FOURNIER / OZON.IO8b068c22016-10-10 11:59:50 +02006180
6181 /* Load SSL string for the verbose & debug mode. */
6182 ERR_load_SSL_strings();
Emeric Brun46591952012-05-18 15:47:34 +02006183}
6184
Remi Gacogned3a23c32015-05-28 16:39:47 +02006185__attribute__((destructor))
6186static void __ssl_sock_deinit(void)
6187{
Willy Tarreaua84c2672015-10-09 12:10:13 +02006188#ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME
Christopher Faulet31af49d2015-06-09 17:29:50 +02006189 lru64_destroy(ssl_ctx_lru_tree);
Willy Tarreaua84c2672015-10-09 12:10:13 +02006190#endif
Christopher Faulet31af49d2015-06-09 17:29:50 +02006191
Remi Gacogned3a23c32015-05-28 16:39:47 +02006192#ifndef OPENSSL_NO_DH
6193 if (local_dh_1024) {
6194 DH_free(local_dh_1024);
6195 local_dh_1024 = NULL;
6196 }
6197
6198 if (local_dh_2048) {
6199 DH_free(local_dh_2048);
6200 local_dh_2048 = NULL;
6201 }
6202
6203 if (local_dh_4096) {
6204 DH_free(local_dh_4096);
6205 local_dh_4096 = NULL;
6206 }
6207
Remi Gacogne47783ef2015-05-29 15:53:22 +02006208 if (global_dh) {
6209 DH_free(global_dh);
6210 global_dh = NULL;
6211 }
Remi Gacogned3a23c32015-05-28 16:39:47 +02006212#endif
6213
6214 ERR_remove_state(0);
6215 ERR_free_strings();
6216
6217 EVP_cleanup();
6218
6219#if OPENSSL_VERSION_NUMBER >= 0x00907000L
6220 CRYPTO_cleanup_all_ex_data();
6221#endif
6222}
6223
6224
Emeric Brun46591952012-05-18 15:47:34 +02006225/*
6226 * Local variables:
6227 * c-indent-level: 8
6228 * c-basic-offset: 8
6229 * End:
6230 */