blob: e5a6f0a5617bbbdb93e8fcf262809ce46ac5fc0e [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
42#include <openssl/ssl.h>
Emeric Brunfc0421f2012-09-07 17:30:07 +020043#include <openssl/x509.h>
44#include <openssl/x509v3.h>
45#include <openssl/x509.h>
46#include <openssl/err.h>
Thierry Fournier383085f2013-01-24 14:15:43 +010047#include <openssl/rand.h>
Lukas Tribuse4e30f72014-12-09 16:32:51 +010048#if (defined SSL_CTRL_SET_TLSEXT_STATUS_REQ_CB && !defined OPENSSL_NO_OCSP)
Emeric Brun4147b2e2014-06-16 18:36:30 +020049#include <openssl/ocsp.h>
50#endif
Remi Gacogne4f902b82015-05-28 16:23:00 +020051#ifndef OPENSSL_NO_DH
52#include <openssl/dh.h>
53#endif
Emeric Brun46591952012-05-18 15:47:34 +020054
Christopher Faulet31af49d2015-06-09 17:29:50 +020055#include <import/lru.h>
56#include <import/xxhash.h>
57
Emeric Brun46591952012-05-18 15:47:34 +020058#include <common/buffer.h>
59#include <common/compat.h>
60#include <common/config.h>
61#include <common/debug.h>
Willy Tarreau79eeafa2012-09-14 07:53:05 +020062#include <common/errors.h>
Emeric Brun46591952012-05-18 15:47:34 +020063#include <common/standard.h>
64#include <common/ticks.h>
65#include <common/time.h>
Emeric Brun2c86cbf2014-10-30 15:56:50 +010066#include <common/cfgparse.h>
Nenad Merdanovic05552d42015-02-27 19:56:49 +010067#include <common/base64.h>
Emeric Brun46591952012-05-18 15:47:34 +020068
Emeric Brunfc0421f2012-09-07 17:30:07 +020069#include <ebsttree.h>
70
71#include <types/global.h>
72#include <types/ssl_sock.h>
73
Willy Tarreau7875d092012-09-10 08:20:03 +020074#include <proto/acl.h>
75#include <proto/arg.h>
Emeric Brun46591952012-05-18 15:47:34 +020076#include <proto/connection.h>
77#include <proto/fd.h>
78#include <proto/freq_ctr.h>
79#include <proto/frontend.h>
Willy Tarreau79eeafa2012-09-14 07:53:05 +020080#include <proto/listener.h>
Thierry FOURNIERed66c292013-11-28 11:05:19 +010081#include <proto/pattern.h>
Christopher Faulet31af49d2015-06-09 17:29:50 +020082#include <proto/proto_tcp.h>
Willy Tarreau92faadf2012-10-10 23:04:25 +020083#include <proto/server.h>
Emeric Brun46591952012-05-18 15:47:34 +020084#include <proto/log.h>
Emeric Brun94324a42012-10-11 14:00:19 +020085#include <proto/proxy.h>
Emeric Brunfc0421f2012-09-07 17:30:07 +020086#include <proto/shctx.h>
Emeric Brun46591952012-05-18 15:47:34 +020087#include <proto/ssl_sock.h>
Willy Tarreau9ad7bd42015-04-03 19:19:59 +020088#include <proto/stream.h>
Emeric Brun46591952012-05-18 15:47:34 +020089#include <proto/task.h>
90
Willy Tarreau518cedd2014-02-17 15:43:01 +010091/* Warning, these are bits, not integers! */
Emeric Brune64aef12012-09-21 13:15:06 +020092#define SSL_SOCK_ST_FL_VERIFY_DONE 0x00000001
Emeric Brund8b2bb52014-01-28 15:43:53 +010093#define SSL_SOCK_ST_FL_16K_WBFSIZE 0x00000002
Willy Tarreau518cedd2014-02-17 15:43:01 +010094#define SSL_SOCK_SEND_UNLIMITED 0x00000004
Emeric Brun29f037d2014-04-25 19:05:36 +020095#define SSL_SOCK_RECV_HEARTBEAT 0x00000008
96
Emeric Brunf282a812012-09-21 15:27:54 +020097/* bits 0xFFFF0000 are reserved to store verify errors */
98
99/* Verify errors macros */
100#define SSL_SOCK_CA_ERROR_TO_ST(e) (((e > 63) ? 63 : e) << (16))
101#define SSL_SOCK_CAEDEPTH_TO_ST(d) (((d > 15) ? 15 : d) << (6+16))
102#define SSL_SOCK_CRTERROR_TO_ST(e) (((e > 63) ? 63 : e) << (4+6+16))
103
104#define SSL_SOCK_ST_TO_CA_ERROR(s) ((s >> (16)) & 63)
105#define SSL_SOCK_ST_TO_CAEDEPTH(s) ((s >> (6+16)) & 15)
106#define SSL_SOCK_ST_TO_CRTERROR(s) ((s >> (4+6+16)) & 63)
Emeric Brune64aef12012-09-21 13:15:06 +0200107
Nenad Merdanovic05552d42015-02-27 19:56:49 +0100108/* Supported hash function for TLS tickets */
109#ifdef OPENSSL_NO_SHA256
110#define HASH_FUNCT EVP_sha1
111#else
112#define HASH_FUNCT EVP_sha256
113#endif /* OPENSSL_NO_SHA256 */
114
Emeric Brun850efd52014-01-29 12:24:34 +0100115/* server and bind verify method, it uses a global value as default */
116enum {
117 SSL_SOCK_VERIFY_DEFAULT = 0,
118 SSL_SOCK_VERIFY_REQUIRED = 1,
119 SSL_SOCK_VERIFY_OPTIONAL = 2,
120 SSL_SOCK_VERIFY_NONE = 3,
121};
122
Willy Tarreau71b734c2014-01-28 15:19:44 +0100123int sslconns = 0;
124int totalsslconns = 0;
Emeric Brune1f38db2012-09-03 20:36:47 +0200125
Nenad Merdanovic200b0fa2015-05-09 08:46:01 +0200126#if (defined SSL_CTRL_SET_TLSEXT_TICKET_KEY_CB && TLS_TICKETS_NO > 0)
127struct list tlskeys_reference = LIST_HEAD_INIT(tlskeys_reference);
128#endif
129
Remi Gacogne8de54152014-07-15 11:36:40 +0200130#ifndef OPENSSL_NO_DH
Remi Gacogne4f902b82015-05-28 16:23:00 +0200131static int ssl_dh_ptr_index = -1;
Remi Gacogne47783ef2015-05-29 15:53:22 +0200132static DH *global_dh = NULL;
Remi Gacogne8de54152014-07-15 11:36:40 +0200133static DH *local_dh_1024 = NULL;
134static DH *local_dh_2048 = NULL;
135static DH *local_dh_4096 = NULL;
Remi Gacogne8de54152014-07-15 11:36:40 +0200136#endif /* OPENSSL_NO_DH */
137
Willy Tarreauc8ad3be2015-06-17 15:48:26 +0200138#ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME
Christopher Faulet31af49d2015-06-09 17:29:50 +0200139/* X509V3 Extensions that will be added on generated certificates */
140#define X509V3_EXT_SIZE 5
141static char *x509v3_ext_names[X509V3_EXT_SIZE] = {
142 "basicConstraints",
143 "nsComment",
144 "subjectKeyIdentifier",
145 "authorityKeyIdentifier",
146 "keyUsage",
147};
148static char *x509v3_ext_values[X509V3_EXT_SIZE] = {
149 "CA:FALSE",
150 "\"OpenSSL Generated Certificate\"",
151 "hash",
152 "keyid,issuer:always",
153 "nonRepudiation,digitalSignature,keyEncipherment"
154};
155
156/* LRU cache to store generated certificate */
157static struct lru64_head *ssl_ctx_lru_tree = NULL;
158static unsigned int ssl_ctx_lru_seed = 0;
Willy Tarreauc8ad3be2015-06-17 15:48:26 +0200159#endif // SSL_CTRL_SET_TLSEXT_HOSTNAME
160
yanbzhube2774d2015-12-10 15:07:30 -0500161#if OPENSSL_VERSION_NUMBER >= 0x1000200fL
162/* The order here matters for picking a default context,
163 * keep the most common keytype at the bottom of the list
164 */
165const char *SSL_SOCK_KEYTYPE_NAMES[] = {
166 "dsa",
167 "ecdsa",
168 "rsa"
169};
170#define SSL_SOCK_NUM_KEYTYPES 3
Willy Tarreau30da7ad2015-12-14 11:28:33 +0100171#else
172#define SSL_SOCK_NUM_KEYTYPES 1
yanbzhube2774d2015-12-10 15:07:30 -0500173#endif
174
Willy Tarreauc8ad3be2015-06-17 15:48:26 +0200175#if (defined SSL_CTRL_SET_TLSEXT_STATUS_REQ_CB && !defined OPENSSL_NO_OCSP)
yanbzhube2774d2015-12-10 15:07:30 -0500176/*
177 * struct alignment works here such that the key.key is the same as key_data
178 * Do not change the placement of key_data
179 */
Willy Tarreauc8ad3be2015-06-17 15:48:26 +0200180struct certificate_ocsp {
181 struct ebmb_node key;
182 unsigned char key_data[OCSP_MAX_CERTID_ASN1_LENGTH];
183 struct chunk response;
184 long expire;
185};
Christopher Faulet31af49d2015-06-09 17:29:50 +0200186
yanbzhube2774d2015-12-10 15:07:30 -0500187struct ocsp_cbk_arg {
188 int is_single;
189 int single_kt;
190 union {
191 struct certificate_ocsp *s_ocsp;
192 /*
193 * m_ocsp will have multiple entries dependent on key type
194 * Entry 0 - DSA
195 * Entry 1 - ECDSA
196 * Entry 2 - RSA
197 */
198 struct certificate_ocsp *m_ocsp[SSL_SOCK_NUM_KEYTYPES];
199 };
200};
201
Emeric Brun4f3c87a2014-06-20 15:46:13 +0200202/*
203 * This function returns the number of seconds elapsed
204 * since the Epoch, 1970-01-01 00:00:00 +0000 (UTC) and the
205 * date presented un ASN1_GENERALIZEDTIME.
206 *
207 * In parsing error case, it returns -1.
208 */
209static long asn1_generalizedtime_to_epoch(ASN1_GENERALIZEDTIME *d)
210{
211 long epoch;
212 char *p, *end;
213 const unsigned short month_offset[12] = {
214 0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334
215 };
216 int year, month;
217
218 if (!d || (d->type != V_ASN1_GENERALIZEDTIME)) return -1;
219
220 p = (char *)d->data;
221 end = p + d->length;
222
223 if (end - p < 4) return -1;
224 year = 1000 * (p[0] - '0') + 100 * (p[1] - '0') + 10 * (p[2] - '0') + p[3] - '0';
225 p += 4;
226 if (end - p < 2) return -1;
227 month = 10 * (p[0] - '0') + p[1] - '0';
228 if (month < 1 || month > 12) return -1;
229 /* Compute the number of seconds since 1 jan 1970 and the beginning of current month
230 We consider leap years and the current month (<marsh or not) */
231 epoch = ( ((year - 1970) * 365)
232 + ((year - (month < 3)) / 4 - (year - (month < 3)) / 100 + (year - (month < 3)) / 400)
233 - ((1970 - 1) / 4 - (1970 - 1) / 100 + (1970 - 1) / 400)
234 + month_offset[month-1]
235 ) * 24 * 60 * 60;
236 p += 2;
237 if (end - p < 2) return -1;
238 /* Add the number of seconds of completed days of current month */
239 epoch += (10 * (p[0] - '0') + p[1] - '0' - 1) * 24 * 60 * 60;
240 p += 2;
241 if (end - p < 2) return -1;
242 /* Add the completed hours of the current day */
243 epoch += (10 * (p[0] - '0') + p[1] - '0') * 60 * 60;
244 p += 2;
245 if (end - p < 2) return -1;
246 /* Add the completed minutes of the current hour */
247 epoch += (10 * (p[0] - '0') + p[1] - '0') * 60;
248 p += 2;
249 if (p == end) return -1;
250 /* Test if there is available seconds */
251 if (p[0] < '0' || p[0] > '9')
252 goto nosec;
253 if (end - p < 2) return -1;
254 /* Add the seconds of the current minute */
255 epoch += 10 * (p[0] - '0') + p[1] - '0';
256 p += 2;
257 if (p == end) return -1;
258 /* Ignore seconds float part if present */
259 if (p[0] == '.') {
260 do {
261 if (++p == end) return -1;
262 } while (p[0] >= '0' && p[0] <= '9');
263 }
264
265nosec:
266 if (p[0] == 'Z') {
267 if (end - p != 1) return -1;
268 return epoch;
269 }
270 else if (p[0] == '+') {
271 if (end - p != 5) return -1;
272 /* Apply timezone offset */
273 return epoch - ((10 * (p[1] - '0') + p[2] - '0') * 60 + (10 * (p[3] - '0') + p[4] - '0')) * 60;
274 }
275 else if (p[0] == '-') {
276 if (end - p != 5) return -1;
277 /* Apply timezone offset */
278 return epoch + ((10 * (p[1] - '0') + p[2] - '0') * 60 + (10 * (p[3] - '0') + p[4] - '0')) * 60;
279 }
280
281 return -1;
282}
283
Emeric Brun1d3865b2014-06-20 15:37:32 +0200284static struct eb_root cert_ocsp_tree = EB_ROOT_UNIQUE;
Emeric Brun4147b2e2014-06-16 18:36:30 +0200285
286/* This function starts to check if the OCSP response (in DER format) contained
287 * in chunk 'ocsp_response' is valid (else exits on error).
288 * If 'cid' is not NULL, it will be compared to the OCSP certificate ID
289 * contained in the OCSP Response and exits on error if no match.
290 * If it's a valid OCSP Response:
291 * If 'ocsp' is not NULL, the chunk is copied in the OCSP response's container
292 * pointed by 'ocsp'.
293 * If 'ocsp' is NULL, the function looks up into the OCSP response's
294 * containers tree (using as index the ASN1 form of the OCSP Certificate ID extracted
295 * from the response) and exits on error if not found. Finally, If an OCSP response is
296 * already present in the container, it will be overwritten.
297 *
298 * Note: OCSP response containing more than one OCSP Single response is not
299 * considered valid.
300 *
301 * Returns 0 on success, 1 in error case.
302 */
303static int ssl_sock_load_ocsp_response(struct chunk *ocsp_response, struct certificate_ocsp *ocsp, OCSP_CERTID *cid, char **err)
304{
305 OCSP_RESPONSE *resp;
306 OCSP_BASICRESP *bs = NULL;
307 OCSP_SINGLERESP *sr;
308 unsigned char *p = (unsigned char *)ocsp_response->str;
309 int rc , count_sr;
Emeric Brun13a6b482014-06-20 15:44:34 +0200310 ASN1_GENERALIZEDTIME *revtime, *thisupd, *nextupd = NULL;
Emeric Brun4147b2e2014-06-16 18:36:30 +0200311 int reason;
312 int ret = 1;
313
314 resp = d2i_OCSP_RESPONSE(NULL, (const unsigned char **)&p, ocsp_response->len);
315 if (!resp) {
316 memprintf(err, "Unable to parse OCSP response");
317 goto out;
318 }
319
320 rc = OCSP_response_status(resp);
321 if (rc != OCSP_RESPONSE_STATUS_SUCCESSFUL) {
322 memprintf(err, "OCSP response status not successful");
323 goto out;
324 }
325
326 bs = OCSP_response_get1_basic(resp);
327 if (!bs) {
328 memprintf(err, "Failed to get basic response from OCSP Response");
329 goto out;
330 }
331
332 count_sr = OCSP_resp_count(bs);
333 if (count_sr > 1) {
334 memprintf(err, "OCSP response ignored because contains multiple single responses (%d)", count_sr);
335 goto out;
336 }
337
338 sr = OCSP_resp_get0(bs, 0);
339 if (!sr) {
340 memprintf(err, "Failed to get OCSP single response");
341 goto out;
342 }
343
344 rc = OCSP_single_get0_status(sr, &reason, &revtime, &thisupd, &nextupd);
345 if (rc != V_OCSP_CERTSTATUS_GOOD) {
346 memprintf(err, "OCSP single response: certificate status not good");
347 goto out;
348 }
349
Emeric Brun13a6b482014-06-20 15:44:34 +0200350 if (!nextupd) {
351 memprintf(err, "OCSP single response: missing nextupdate");
352 goto out;
353 }
354
Emeric Brunc8b27b62014-06-19 14:16:17 +0200355 rc = OCSP_check_validity(thisupd, nextupd, OCSP_MAX_RESPONSE_TIME_SKEW, -1);
Emeric Brun4147b2e2014-06-16 18:36:30 +0200356 if (!rc) {
357 memprintf(err, "OCSP single response: no longer valid.");
358 goto out;
359 }
360
361 if (cid) {
362 if (OCSP_id_cmp(sr->certId, cid)) {
363 memprintf(err, "OCSP single response: Certificate ID does not match certificate and issuer");
364 goto out;
365 }
366 }
367
368 if (!ocsp) {
369 unsigned char key[OCSP_MAX_CERTID_ASN1_LENGTH];
370 unsigned char *p;
371
372 rc = i2d_OCSP_CERTID(sr->certId, NULL);
373 if (!rc) {
374 memprintf(err, "OCSP single response: Unable to encode Certificate ID");
375 goto out;
376 }
377
378 if (rc > OCSP_MAX_CERTID_ASN1_LENGTH) {
379 memprintf(err, "OCSP single response: Certificate ID too long");
380 goto out;
381 }
382
383 p = key;
384 memset(key, 0, OCSP_MAX_CERTID_ASN1_LENGTH);
385 i2d_OCSP_CERTID(sr->certId, &p);
386 ocsp = (struct certificate_ocsp *)ebmb_lookup(&cert_ocsp_tree, key, OCSP_MAX_CERTID_ASN1_LENGTH);
387 if (!ocsp) {
388 memprintf(err, "OCSP single response: Certificate ID does not match any certificate or issuer");
389 goto out;
390 }
391 }
392
393 /* According to comments on "chunk_dup", the
394 previous chunk buffer will be freed */
395 if (!chunk_dup(&ocsp->response, ocsp_response)) {
396 memprintf(err, "OCSP response: Memory allocation error");
397 goto out;
398 }
399
Emeric Brun4f3c87a2014-06-20 15:46:13 +0200400 ocsp->expire = asn1_generalizedtime_to_epoch(nextupd) - OCSP_MAX_RESPONSE_TIME_SKEW;
401
Emeric Brun4147b2e2014-06-16 18:36:30 +0200402 ret = 0;
403out:
404 if (bs)
405 OCSP_BASICRESP_free(bs);
406
407 if (resp)
408 OCSP_RESPONSE_free(resp);
409
410 return ret;
411}
412/*
413 * External function use to update the OCSP response in the OCSP response's
414 * containers tree. The chunk 'ocsp_response' must contain the OCSP response
415 * to update in DER format.
416 *
417 * Returns 0 on success, 1 in error case.
418 */
419int ssl_sock_update_ocsp_response(struct chunk *ocsp_response, char **err)
420{
421 return ssl_sock_load_ocsp_response(ocsp_response, NULL, NULL, err);
422}
423
424/*
425 * This function load the OCSP Resonse in DER format contained in file at
426 * path 'ocsp_path' and call 'ssl_sock_load_ocsp_response'
427 *
428 * Returns 0 on success, 1 in error case.
429 */
430static int ssl_sock_load_ocsp_response_from_file(const char *ocsp_path, struct certificate_ocsp *ocsp, OCSP_CERTID *cid, char **err)
431{
432 int fd = -1;
433 int r = 0;
434 int ret = 1;
435
436 fd = open(ocsp_path, O_RDONLY);
437 if (fd == -1) {
438 memprintf(err, "Error opening OCSP response file");
439 goto end;
440 }
441
442 trash.len = 0;
443 while (trash.len < trash.size) {
444 r = read(fd, trash.str + trash.len, trash.size - trash.len);
445 if (r < 0) {
446 if (errno == EINTR)
447 continue;
448
449 memprintf(err, "Error reading OCSP response from file");
450 goto end;
451 }
452 else if (r == 0) {
453 break;
454 }
455 trash.len += r;
456 }
457
458 close(fd);
459 fd = -1;
460
461 ret = ssl_sock_load_ocsp_response(&trash, ocsp, cid, err);
462end:
463 if (fd != -1)
464 close(fd);
465
466 return ret;
467}
468
Nenad Merdanovic05552d42015-02-27 19:56:49 +0100469#if (defined SSL_CTRL_SET_TLSEXT_TICKET_KEY_CB && TLS_TICKETS_NO > 0)
470static 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)
471{
472 struct tls_sess_key *keys;
473 struct connection *conn;
474 int head;
475 int i;
476
Vincent Bernat3c2f2f22016-04-03 13:48:42 +0200477 conn = SSL_get_app_data(s);
Nenad Merdanovic146defa2015-05-09 08:46:00 +0200478 keys = objt_listener(conn->target)->bind_conf->keys_ref->tlskeys;
479 head = objt_listener(conn->target)->bind_conf->keys_ref->tls_ticket_enc_index;
Nenad Merdanovic05552d42015-02-27 19:56:49 +0100480
481 if (enc) {
482 memcpy(key_name, keys[head].name, 16);
483
484 if(!RAND_pseudo_bytes(iv, EVP_MAX_IV_LENGTH))
485 return -1;
486
487 if(!EVP_EncryptInit_ex(ectx, EVP_aes_128_cbc(), NULL, keys[head].aes_key, iv))
488 return -1;
489
490 HMAC_Init_ex(hctx, keys[head].hmac_key, 16, HASH_FUNCT(), NULL);
491
492 return 1;
493 } else {
494 for (i = 0; i < TLS_TICKETS_NO; i++) {
495 if (!memcmp(key_name, keys[(head + i) % TLS_TICKETS_NO].name, 16))
496 goto found;
497 }
498 return 0;
499
500 found:
501 HMAC_Init_ex(hctx, keys[(head + i) % TLS_TICKETS_NO].hmac_key, 16, HASH_FUNCT(), NULL);
502 if(!EVP_DecryptInit_ex(ectx, EVP_aes_128_cbc(), NULL, keys[(head + i) % TLS_TICKETS_NO].aes_key, iv))
503 return -1;
504 /* 2 for key renewal, 1 if current key is still valid */
505 return i ? 2 : 1;
506 }
Nenad Merdanovic200b0fa2015-05-09 08:46:01 +0200507}
508
509struct tls_keys_ref *tlskeys_ref_lookup(const char *filename)
510{
511 struct tls_keys_ref *ref;
512
513 list_for_each_entry(ref, &tlskeys_reference, list)
514 if (ref->filename && strcmp(filename, ref->filename) == 0)
515 return ref;
516 return NULL;
517}
518
519struct tls_keys_ref *tlskeys_ref_lookupid(int unique_id)
520{
521 struct tls_keys_ref *ref;
522
523 list_for_each_entry(ref, &tlskeys_reference, list)
524 if (ref->unique_id == unique_id)
525 return ref;
526 return NULL;
527}
528
529int ssl_sock_update_tlskey(char *filename, struct chunk *tlskey, char **err) {
530 struct tls_keys_ref *ref = tlskeys_ref_lookup(filename);
531
532 if(!ref) {
533 memprintf(err, "Unable to locate the referenced filename: %s", filename);
534 return 1;
535 }
536
Pradeep Jindalcc79b002015-08-20 18:25:17 +0530537 memcpy((char *) (ref->tlskeys + ((ref->tls_ticket_enc_index + 2) % TLS_TICKETS_NO)), tlskey->str, tlskey->len);
538 ref->tls_ticket_enc_index = (ref->tls_ticket_enc_index + 1) % TLS_TICKETS_NO;
Nenad Merdanovic200b0fa2015-05-09 08:46:01 +0200539
540 return 0;
Nenad Merdanovic05552d42015-02-27 19:56:49 +0100541}
Nenad Merdanovic200b0fa2015-05-09 08:46:01 +0200542
543/* This function finalize the configuration parsing. Its set all the
544 * automatic ids
545 */
546void tlskeys_finalize_config(void)
547{
548 int i = 0;
549 struct tls_keys_ref *ref, *ref2, *ref3;
550 struct list tkr = LIST_HEAD_INIT(tkr);
551
552 list_for_each_entry(ref, &tlskeys_reference, list) {
553 if (ref->unique_id == -1) {
554 /* Look for the first free id. */
555 while (1) {
556 list_for_each_entry(ref2, &tlskeys_reference, list) {
557 if (ref2->unique_id == i) {
558 i++;
559 break;
560 }
561 }
562 if (&ref2->list == &tlskeys_reference)
563 break;
564 }
565
566 /* Uses the unique id and increment it for the next entry. */
567 ref->unique_id = i;
568 i++;
569 }
570 }
571
572 /* This sort the reference list by id. */
573 list_for_each_entry_safe(ref, ref2, &tlskeys_reference, list) {
574 LIST_DEL(&ref->list);
575 list_for_each_entry(ref3, &tkr, list) {
576 if (ref->unique_id < ref3->unique_id) {
577 LIST_ADDQ(&ref3->list, &ref->list);
578 break;
579 }
580 }
581 if (&ref3->list == &tkr)
582 LIST_ADDQ(&tkr, &ref->list);
583 }
584
585 /* swap root */
586 LIST_ADD(&tkr, &tlskeys_reference);
587 LIST_DEL(&tkr);
588}
589
Nenad Merdanovic05552d42015-02-27 19:56:49 +0100590#endif /* SSL_CTRL_SET_TLSEXT_TICKET_KEY_CB */
591
yanbzhube2774d2015-12-10 15:07:30 -0500592int ssl_sock_get_ocsp_arg_kt_index(int evp_keytype)
593{
594 switch (evp_keytype) {
595 case EVP_PKEY_RSA:
596 return 2;
597 case EVP_PKEY_DSA:
598 return 0;
599 case EVP_PKEY_EC:
600 return 1;
601 }
602
603 return -1;
604}
605
Emeric Brun4147b2e2014-06-16 18:36:30 +0200606/*
607 * Callback used to set OCSP status extension content in server hello.
608 */
609int ssl_sock_ocsp_stapling_cbk(SSL *ssl, void *arg)
610{
yanbzhube2774d2015-12-10 15:07:30 -0500611 struct certificate_ocsp *ocsp;
612 struct ocsp_cbk_arg *ocsp_arg;
613 char *ssl_buf;
614 EVP_PKEY *ssl_pkey;
615 int key_type;
616 int index;
617
Vincent Bernat3c2f2f22016-04-03 13:48:42 +0200618 ocsp_arg = arg;
yanbzhube2774d2015-12-10 15:07:30 -0500619
620 ssl_pkey = SSL_get_privatekey(ssl);
621 if (!ssl_pkey)
622 return SSL_TLSEXT_ERR_NOACK;
623
624 key_type = EVP_PKEY_type(ssl_pkey->type);
625
626 if (ocsp_arg->is_single && ocsp_arg->single_kt == key_type)
627 ocsp = ocsp_arg->s_ocsp;
628 else {
629 /* For multiple certs per context, we have to find the correct OCSP response based on
630 * the certificate type
631 */
632 index = ssl_sock_get_ocsp_arg_kt_index(key_type);
633
634 if (index < 0)
635 return SSL_TLSEXT_ERR_NOACK;
636
637 ocsp = ocsp_arg->m_ocsp[index];
638
639 }
Emeric Brun4147b2e2014-06-16 18:36:30 +0200640
641 if (!ocsp ||
642 !ocsp->response.str ||
Emeric Brun4f3c87a2014-06-20 15:46:13 +0200643 !ocsp->response.len ||
644 (ocsp->expire < now.tv_sec))
Emeric Brun4147b2e2014-06-16 18:36:30 +0200645 return SSL_TLSEXT_ERR_NOACK;
646
647 ssl_buf = OPENSSL_malloc(ocsp->response.len);
648 if (!ssl_buf)
649 return SSL_TLSEXT_ERR_NOACK;
650
651 memcpy(ssl_buf, ocsp->response.str, ocsp->response.len);
652 SSL_set_tlsext_status_ocsp_resp(ssl, ssl_buf, ocsp->response.len);
653
654 return SSL_TLSEXT_ERR_OK;
655}
656
657/*
658 * This function enables the handling of OCSP status extension on 'ctx' if a
659 * file name 'cert_path' suffixed using ".ocsp" is present.
660 * To enable OCSP status extension, the issuer's certificate is mandatory.
661 * It should be present in the certificate's extra chain builded from file
662 * 'cert_path'. If not found, the issuer certificate is loaded from a file
663 * named 'cert_path' suffixed using '.issuer'.
664 *
665 * In addition, ".ocsp" file content is loaded as a DER format of an OCSP
666 * response. If file is empty or content is not a valid OCSP response,
667 * OCSP status extension is enabled but OCSP response is ignored (a warning
668 * is displayed).
669 *
670 * Returns 1 if no ".ocsp" file found, 0 if OCSP status extension is
671 * succesfully enabled, or -1 in other error case.
672 */
673static int ssl_sock_load_ocsp(SSL_CTX *ctx, const char *cert_path)
674{
675
676 BIO *in = NULL;
677 X509 *x, *xi = NULL, *issuer = NULL;
678 STACK_OF(X509) *chain = NULL;
679 OCSP_CERTID *cid = NULL;
680 SSL *ssl;
681 char ocsp_path[MAXPATHLEN+1];
682 int i, ret = -1;
683 struct stat st;
684 struct certificate_ocsp *ocsp = NULL, *iocsp;
685 char *warn = NULL;
686 unsigned char *p;
687
688 snprintf(ocsp_path, MAXPATHLEN+1, "%s.ocsp", cert_path);
689
690 if (stat(ocsp_path, &st))
691 return 1;
692
693 ssl = SSL_new(ctx);
694 if (!ssl)
695 goto out;
696
697 x = SSL_get_certificate(ssl);
698 if (!x)
699 goto out;
700
701 /* Try to lookup for issuer in certificate extra chain */
702#ifdef SSL_CTRL_GET_EXTRA_CHAIN_CERTS
703 SSL_CTX_get_extra_chain_certs(ctx, &chain);
704#else
705 chain = ctx->extra_certs;
706#endif
707 for (i = 0; i < sk_X509_num(chain); i++) {
708 issuer = sk_X509_value(chain, i);
709 if (X509_check_issued(issuer, x) == X509_V_OK)
710 break;
711 else
712 issuer = NULL;
713 }
714
715 /* If not found try to load issuer from a suffixed file */
716 if (!issuer) {
717 char issuer_path[MAXPATHLEN+1];
718
719 in = BIO_new(BIO_s_file());
720 if (!in)
721 goto out;
722
723 snprintf(issuer_path, MAXPATHLEN+1, "%s.issuer", cert_path);
724 if (BIO_read_filename(in, issuer_path) <= 0)
725 goto out;
726
727 xi = PEM_read_bio_X509_AUX(in, NULL, ctx->default_passwd_callback, ctx->default_passwd_callback_userdata);
728 if (!xi)
729 goto out;
730
731 if (X509_check_issued(xi, x) != X509_V_OK)
732 goto out;
733
734 issuer = xi;
735 }
736
737 cid = OCSP_cert_to_id(0, x, issuer);
738 if (!cid)
739 goto out;
740
741 i = i2d_OCSP_CERTID(cid, NULL);
742 if (!i || (i > OCSP_MAX_CERTID_ASN1_LENGTH))
743 goto out;
744
Vincent Bernat02779b62016-04-03 13:48:43 +0200745 ocsp = calloc(1, sizeof(*ocsp));
Emeric Brun4147b2e2014-06-16 18:36:30 +0200746 if (!ocsp)
747 goto out;
748
749 p = ocsp->key_data;
750 i2d_OCSP_CERTID(cid, &p);
751
752 iocsp = (struct certificate_ocsp *)ebmb_insert(&cert_ocsp_tree, &ocsp->key, OCSP_MAX_CERTID_ASN1_LENGTH);
753 if (iocsp == ocsp)
754 ocsp = NULL;
755
yanbzhube2774d2015-12-10 15:07:30 -0500756 if (!ctx->tlsext_status_cb) {
Vincent Bernat02779b62016-04-03 13:48:43 +0200757 struct ocsp_cbk_arg *cb_arg = calloc(1, sizeof(*cb_arg));
yanbzhube2774d2015-12-10 15:07:30 -0500758
759 cb_arg->is_single = 1;
760 cb_arg->s_ocsp = iocsp;
761 cb_arg->single_kt = EVP_PKEY_type(X509_get_pubkey(x)->type);
762
763 SSL_CTX_set_tlsext_status_cb(ctx, ssl_sock_ocsp_stapling_cbk);
764 SSL_CTX_set_tlsext_status_arg(ctx, cb_arg);
765 } else {
766 /*
767 * If the ctx has a status CB, then we have previously set an OCSP staple for this ctx
768 * Update that cb_arg with the new cert's staple
769 */
Vincent Bernat3c2f2f22016-04-03 13:48:42 +0200770 struct ocsp_cbk_arg *cb_arg = ctx->tlsext_status_arg;
yanbzhube2774d2015-12-10 15:07:30 -0500771 struct certificate_ocsp *tmp_ocsp;
772 int index;
773
774 /*
775 * The following few lines will convert cb_arg from a single ocsp to multi ocsp
776 * the order of operations below matter, take care when changing it
777 */
778 tmp_ocsp = cb_arg->s_ocsp;
779 index = ssl_sock_get_ocsp_arg_kt_index(cb_arg->single_kt);
780 cb_arg->s_ocsp = NULL;
781 cb_arg->m_ocsp[index] = tmp_ocsp;
782 cb_arg->is_single = 0;
783 cb_arg->single_kt = 0;
784
785 index = ssl_sock_get_ocsp_arg_kt_index(EVP_PKEY_type(X509_get_pubkey(x)->type));
786 if (index >= 0 && !cb_arg->m_ocsp[index])
787 cb_arg->m_ocsp[index] = iocsp;
788
789 }
Emeric Brun4147b2e2014-06-16 18:36:30 +0200790
791 ret = 0;
792
793 warn = NULL;
794 if (ssl_sock_load_ocsp_response_from_file(ocsp_path, iocsp, cid, &warn)) {
795 memprintf(&warn, "Loading '%s': %s. Content will be ignored", ocsp_path, warn ? warn : "failure");
796 Warning("%s.\n", warn);
797 }
798
799out:
800 if (ssl)
801 SSL_free(ssl);
802
803 if (in)
804 BIO_free(in);
805
806 if (xi)
807 X509_free(xi);
808
809 if (cid)
810 OCSP_CERTID_free(cid);
811
812 if (ocsp)
813 free(ocsp);
814
815 if (warn)
816 free(warn);
817
818
819 return ret;
820}
821
822#endif
823
Daniel Jakots54ffb912015-11-06 20:02:41 +0100824#if (OPENSSL_VERSION_NUMBER >= 0x1000200fL && !defined OPENSSL_NO_TLSEXT && !defined OPENSSL_IS_BORINGSSL && !defined LIBRESSL_VERSION_NUMBER)
Janusz Dziemidowicz2c701b52015-03-07 23:03:59 +0100825
826#define CT_EXTENSION_TYPE 18
827
828static int sctl_ex_index = -1;
829
830/*
831 * Try to parse Signed Certificate Timestamp List structure. This function
832 * makes only basic test if the data seems like SCTL. No signature validation
833 * is performed.
834 */
835static int ssl_sock_parse_sctl(struct chunk *sctl)
836{
837 int ret = 1;
838 int len, pos, sct_len;
839 unsigned char *data;
840
841 if (sctl->len < 2)
842 goto out;
843
844 data = (unsigned char *)sctl->str;
845 len = (data[0] << 8) | data[1];
846
847 if (len + 2 != sctl->len)
848 goto out;
849
850 data = data + 2;
851 pos = 0;
852 while (pos < len) {
853 if (len - pos < 2)
854 goto out;
855
856 sct_len = (data[pos] << 8) | data[pos + 1];
857 if (pos + sct_len + 2 > len)
858 goto out;
859
860 pos += sct_len + 2;
861 }
862
863 ret = 0;
864
865out:
866 return ret;
867}
868
869static int ssl_sock_load_sctl_from_file(const char *sctl_path, struct chunk **sctl)
870{
871 int fd = -1;
872 int r = 0;
873 int ret = 1;
874
875 *sctl = NULL;
876
877 fd = open(sctl_path, O_RDONLY);
878 if (fd == -1)
879 goto end;
880
881 trash.len = 0;
882 while (trash.len < trash.size) {
883 r = read(fd, trash.str + trash.len, trash.size - trash.len);
884 if (r < 0) {
885 if (errno == EINTR)
886 continue;
887
888 goto end;
889 }
890 else if (r == 0) {
891 break;
892 }
893 trash.len += r;
894 }
895
896 ret = ssl_sock_parse_sctl(&trash);
897 if (ret)
898 goto end;
899
Vincent Bernat02779b62016-04-03 13:48:43 +0200900 *sctl = calloc(1, sizeof(**sctl));
Janusz Dziemidowicz2c701b52015-03-07 23:03:59 +0100901 if (!chunk_dup(*sctl, &trash)) {
902 free(*sctl);
903 *sctl = NULL;
904 goto end;
905 }
906
907end:
908 if (fd != -1)
909 close(fd);
910
911 return ret;
912}
913
914int ssl_sock_sctl_add_cbk(SSL *ssl, unsigned ext_type, const unsigned char **out, size_t *outlen, int *al, void *add_arg)
915{
Vincent Bernat3c2f2f22016-04-03 13:48:42 +0200916 struct chunk *sctl = add_arg;
Janusz Dziemidowicz2c701b52015-03-07 23:03:59 +0100917
918 *out = (unsigned char *)sctl->str;
919 *outlen = sctl->len;
920
921 return 1;
922}
923
924int ssl_sock_sctl_parse_cbk(SSL *s, unsigned int ext_type, const unsigned char *in, size_t inlen, int *al, void *parse_arg)
925{
926 return 1;
927}
928
929static int ssl_sock_load_sctl(SSL_CTX *ctx, const char *cert_path)
930{
931 char sctl_path[MAXPATHLEN+1];
932 int ret = -1;
933 struct stat st;
934 struct chunk *sctl = NULL;
935
936 snprintf(sctl_path, MAXPATHLEN+1, "%s.sctl", cert_path);
937
938 if (stat(sctl_path, &st))
939 return 1;
940
941 if (ssl_sock_load_sctl_from_file(sctl_path, &sctl))
942 goto out;
943
944 if (!SSL_CTX_add_server_custom_ext(ctx, CT_EXTENSION_TYPE, ssl_sock_sctl_add_cbk, NULL, sctl, ssl_sock_sctl_parse_cbk, NULL)) {
945 free(sctl);
946 goto out;
947 }
948
949 SSL_CTX_set_ex_data(ctx, sctl_ex_index, sctl);
950
951 ret = 0;
952
953out:
954 return ret;
955}
956
957#endif
958
Emeric Brune1f38db2012-09-03 20:36:47 +0200959void ssl_sock_infocbk(const SSL *ssl, int where, int ret)
960{
Vincent Bernat3c2f2f22016-04-03 13:48:42 +0200961 struct connection *conn = SSL_get_app_data(ssl);
Emeric Brund8b2bb52014-01-28 15:43:53 +0100962 BIO *write_bio;
Willy Tarreau622317d2015-02-27 16:36:16 +0100963 (void)ret; /* shut gcc stupid warning */
Emeric Brune1f38db2012-09-03 20:36:47 +0200964
965 if (where & SSL_CB_HANDSHAKE_START) {
966 /* Disable renegotiation (CVE-2009-3555) */
Willy Tarreau20879a02012-12-03 16:32:10 +0100967 if (conn->flags & CO_FL_CONNECTED) {
Emeric Brune1f38db2012-09-03 20:36:47 +0200968 conn->flags |= CO_FL_ERROR;
Willy Tarreau20879a02012-12-03 16:32:10 +0100969 conn->err_code = CO_ER_SSL_RENEG;
970 }
Emeric Brune1f38db2012-09-03 20:36:47 +0200971 }
Emeric Brund8b2bb52014-01-28 15:43:53 +0100972
973 if ((where & SSL_CB_ACCEPT_LOOP) == SSL_CB_ACCEPT_LOOP) {
974 if (!(conn->xprt_st & SSL_SOCK_ST_FL_16K_WBFSIZE)) {
975 /* Long certificate chains optimz
976 If write and read bios are differents, we
977 consider that the buffering was activated,
978 so we rise the output buffer size from 4k
979 to 16k */
980 write_bio = SSL_get_wbio(ssl);
981 if (write_bio != SSL_get_rbio(ssl)) {
982 BIO_set_write_buffer_size(write_bio, 16384);
983 conn->xprt_st |= SSL_SOCK_ST_FL_16K_WBFSIZE;
984 }
985 }
986 }
Emeric Brunfc0421f2012-09-07 17:30:07 +0200987}
988
Emeric Brune64aef12012-09-21 13:15:06 +0200989/* Callback is called for each certificate of the chain during a verify
990 ok is set to 1 if preverify detect no error on current certificate.
991 Returns 0 to break the handshake, 1 otherwise. */
Evan Broderbe554312013-06-27 00:05:25 -0700992int ssl_sock_bind_verifycbk(int ok, X509_STORE_CTX *x_store)
Emeric Brune64aef12012-09-21 13:15:06 +0200993{
994 SSL *ssl;
995 struct connection *conn;
Emeric Brun81c00f02012-09-21 14:31:21 +0200996 int err, depth;
Emeric Brune64aef12012-09-21 13:15:06 +0200997
998 ssl = X509_STORE_CTX_get_ex_data(x_store, SSL_get_ex_data_X509_STORE_CTX_idx());
Vincent Bernat3c2f2f22016-04-03 13:48:42 +0200999 conn = SSL_get_app_data(ssl);
Emeric Brune64aef12012-09-21 13:15:06 +02001000
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02001001 conn->xprt_st |= SSL_SOCK_ST_FL_VERIFY_DONE;
Emeric Brune64aef12012-09-21 13:15:06 +02001002
Emeric Brun81c00f02012-09-21 14:31:21 +02001003 if (ok) /* no errors */
1004 return ok;
1005
1006 depth = X509_STORE_CTX_get_error_depth(x_store);
1007 err = X509_STORE_CTX_get_error(x_store);
1008
1009 /* check if CA error needs to be ignored */
1010 if (depth > 0) {
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02001011 if (!SSL_SOCK_ST_TO_CA_ERROR(conn->xprt_st)) {
1012 conn->xprt_st |= SSL_SOCK_CA_ERROR_TO_ST(err);
1013 conn->xprt_st |= SSL_SOCK_CAEDEPTH_TO_ST(depth);
Emeric Brunf282a812012-09-21 15:27:54 +02001014 }
1015
Emeric Brun1eb20ef2012-12-03 13:24:29 +01001016 if (objt_listener(conn->target)->bind_conf->ca_ignerr & (1ULL << err)) {
1017 ERR_clear_error();
Emeric Brun81c00f02012-09-21 14:31:21 +02001018 return 1;
Emeric Brun1eb20ef2012-12-03 13:24:29 +01001019 }
Emeric Brun81c00f02012-09-21 14:31:21 +02001020
Willy Tarreau20879a02012-12-03 16:32:10 +01001021 conn->err_code = CO_ER_SSL_CA_FAIL;
Emeric Brun81c00f02012-09-21 14:31:21 +02001022 return 0;
1023 }
1024
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02001025 if (!SSL_SOCK_ST_TO_CRTERROR(conn->xprt_st))
1026 conn->xprt_st |= SSL_SOCK_CRTERROR_TO_ST(err);
Emeric Brunf282a812012-09-21 15:27:54 +02001027
Emeric Brun81c00f02012-09-21 14:31:21 +02001028 /* check if certificate error needs to be ignored */
Emeric Brun1eb20ef2012-12-03 13:24:29 +01001029 if (objt_listener(conn->target)->bind_conf->crt_ignerr & (1ULL << err)) {
1030 ERR_clear_error();
Emeric Brun81c00f02012-09-21 14:31:21 +02001031 return 1;
Emeric Brun1eb20ef2012-12-03 13:24:29 +01001032 }
Emeric Brun81c00f02012-09-21 14:31:21 +02001033
Willy Tarreau20879a02012-12-03 16:32:10 +01001034 conn->err_code = CO_ER_SSL_CRT_FAIL;
Emeric Brun81c00f02012-09-21 14:31:21 +02001035 return 0;
Emeric Brune64aef12012-09-21 13:15:06 +02001036}
1037
Emeric Brun29f037d2014-04-25 19:05:36 +02001038/* Callback is called for ssl protocol analyse */
1039void ssl_sock_msgcbk(int write_p, int version, int content_type, const void *buf, size_t len, SSL *ssl, void *arg)
1040{
Emeric Brun29f037d2014-04-25 19:05:36 +02001041#ifdef TLS1_RT_HEARTBEAT
1042 /* test heartbeat received (write_p is set to 0
1043 for a received record) */
Willy Tarreauf51c6982014-04-25 20:02:39 +02001044 if ((content_type == TLS1_RT_HEARTBEAT) && (write_p == 0)) {
Vincent Bernat3c2f2f22016-04-03 13:48:42 +02001045 struct connection *conn = SSL_get_app_data(ssl);
Willy Tarreauf51c6982014-04-25 20:02:39 +02001046 const unsigned char *p = buf;
1047 unsigned int payload;
1048
Emeric Brun29f037d2014-04-25 19:05:36 +02001049 conn->xprt_st |= SSL_SOCK_RECV_HEARTBEAT;
Willy Tarreauf51c6982014-04-25 20:02:39 +02001050
1051 /* Check if this is a CVE-2014-0160 exploitation attempt. */
1052 if (*p != TLS1_HB_REQUEST)
1053 return;
1054
Willy Tarreauaeed6722014-04-25 23:59:58 +02001055 if (len < 1 + 2 + 16) /* 1 type + 2 size + 0 payload + 16 padding */
Willy Tarreauf51c6982014-04-25 20:02:39 +02001056 goto kill_it;
1057
1058 payload = (p[1] * 256) + p[2];
Willy Tarreau3b2fdb62014-04-25 23:44:22 +02001059 if (3 + payload + 16 <= len)
Willy Tarreauf51c6982014-04-25 20:02:39 +02001060 return; /* OK no problem */
Willy Tarreauaeed6722014-04-25 23:59:58 +02001061 kill_it:
Willy Tarreau3b2fdb62014-04-25 23:44:22 +02001062 /* We have a clear heartbleed attack (CVE-2014-0160), the
1063 * advertised payload is larger than the advertised packet
1064 * length, so we have garbage in the buffer between the
1065 * payload and the end of the buffer (p+len). We can't know
1066 * if the SSL stack is patched, and we don't know if we can
1067 * safely wipe out the area between p+3+len and payload.
1068 * So instead, we prevent the response from being sent by
1069 * setting the max_send_fragment to 0 and we report an SSL
1070 * error, which will kill this connection. It will be reported
1071 * above as SSL_ERROR_SSL while an other handshake failure with
Willy Tarreauf51c6982014-04-25 20:02:39 +02001072 * a heartbeat message will be reported as SSL_ERROR_SYSCALL.
1073 */
Willy Tarreau3b2fdb62014-04-25 23:44:22 +02001074 ssl->max_send_fragment = 0;
Willy Tarreauf51c6982014-04-25 20:02:39 +02001075 SSLerr(SSL_F_TLS1_HEARTBEAT, SSL_R_SSL_HANDSHAKE_FAILURE);
1076 return;
1077 }
Emeric Brun29f037d2014-04-25 19:05:36 +02001078#endif
1079}
1080
Willy Tarreau6c9a3d52012-10-18 18:57:14 +02001081#ifdef OPENSSL_NPN_NEGOTIATED
1082/* This callback is used so that the server advertises the list of
1083 * negociable protocols for NPN.
1084 */
1085static int ssl_sock_advertise_npn_protos(SSL *s, const unsigned char **data,
1086 unsigned int *len, void *arg)
1087{
1088 struct bind_conf *conf = arg;
1089
1090 *data = (const unsigned char *)conf->npn_str;
1091 *len = conf->npn_len;
1092 return SSL_TLSEXT_ERR_OK;
1093}
1094#endif
1095
Dirkjan Bussink48f1c4e2014-02-13 12:29:42 +01001096#ifdef TLSEXT_TYPE_application_layer_protocol_negotiation
Willy Tarreauab861d32013-04-02 02:30:41 +02001097/* This callback is used so that the server advertises the list of
1098 * negociable protocols for ALPN.
1099 */
Dirkjan Bussink48f1c4e2014-02-13 12:29:42 +01001100static int ssl_sock_advertise_alpn_protos(SSL *s, const unsigned char **out,
1101 unsigned char *outlen,
1102 const unsigned char *server,
1103 unsigned int server_len, void *arg)
Willy Tarreauab861d32013-04-02 02:30:41 +02001104{
1105 struct bind_conf *conf = arg;
1106
Dirkjan Bussink48f1c4e2014-02-13 12:29:42 +01001107 if (SSL_select_next_proto((unsigned char**) out, outlen, (const unsigned char *)conf->alpn_str,
1108 conf->alpn_len, server, server_len) != OPENSSL_NPN_NEGOTIATED) {
1109 return SSL_TLSEXT_ERR_NOACK;
1110 }
Willy Tarreauab861d32013-04-02 02:30:41 +02001111 return SSL_TLSEXT_ERR_OK;
1112}
1113#endif
1114
Willy Tarreauc8ad3be2015-06-17 15:48:26 +02001115#ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME
Christopher Faulet85b5a1a2015-10-09 11:46:32 +02001116static DH *ssl_get_tmp_dh(SSL *ssl, int export, int keylen);
1117
Christopher Faulet30548802015-06-11 13:39:32 +02001118/* Create a X509 certificate with the specified servername and serial. This
1119 * function returns a SSL_CTX object or NULL if an error occurs. */
Christopher Faulet7969a332015-10-09 11:15:03 +02001120static SSL_CTX *
Christopher Faulet635c0ad2015-11-12 11:35:51 +01001121ssl_sock_do_create_cert(const char *servername, struct bind_conf *bind_conf, SSL *ssl)
Christopher Faulet31af49d2015-06-09 17:29:50 +02001122{
Christopher Faulet635c0ad2015-11-12 11:35:51 +01001123 static unsigned int serial = 0;
1124
Christopher Faulet7969a332015-10-09 11:15:03 +02001125 X509 *cacert = bind_conf->ca_sign_cert;
1126 EVP_PKEY *capkey = bind_conf->ca_sign_pkey;
Christopher Faulet31af49d2015-06-09 17:29:50 +02001127 SSL_CTX *ssl_ctx = NULL;
1128 X509 *newcrt = NULL;
1129 EVP_PKEY *pkey = NULL;
Christopher Faulet31af49d2015-06-09 17:29:50 +02001130 X509_NAME *name;
1131 const EVP_MD *digest;
1132 X509V3_CTX ctx;
1133 unsigned int i;
1134
Christopher Faulet7969a332015-10-09 11:15:03 +02001135 /* Get the private key of the defautl certificate and use it */
1136 if (!(pkey = SSL_get_privatekey(ssl)))
Christopher Faulet31af49d2015-06-09 17:29:50 +02001137 goto mkcert_error;
1138
1139 /* Create the certificate */
1140 if (!(newcrt = X509_new()))
1141 goto mkcert_error;
1142
1143 /* Set version number for the certificate (X509v3) and the serial
1144 * number */
1145 if (X509_set_version(newcrt, 2L) != 1)
1146 goto mkcert_error;
Christopher Faulet635c0ad2015-11-12 11:35:51 +01001147 if (!serial)
1148 serial = now_ms;
1149 ASN1_INTEGER_set(X509_get_serialNumber(newcrt), serial++);
Christopher Faulet31af49d2015-06-09 17:29:50 +02001150
1151 /* Set duration for the certificate */
1152 if (!X509_gmtime_adj(X509_get_notBefore(newcrt), (long)-60*60*24) ||
1153 !X509_gmtime_adj(X509_get_notAfter(newcrt),(long)60*60*24*365))
1154 goto mkcert_error;
1155
1156 /* set public key in the certificate */
1157 if (X509_set_pubkey(newcrt, pkey) != 1)
1158 goto mkcert_error;
1159
1160 /* Set issuer name from the CA */
1161 if (!(name = X509_get_subject_name(cacert)))
1162 goto mkcert_error;
1163 if (X509_set_issuer_name(newcrt, name) != 1)
1164 goto mkcert_error;
1165
1166 /* Set the subject name using the same, but the CN */
1167 name = X509_NAME_dup(name);
1168 if (X509_NAME_add_entry_by_txt(name, "CN", MBSTRING_ASC,
1169 (const unsigned char *)servername,
1170 -1, -1, 0) != 1) {
1171 X509_NAME_free(name);
1172 goto mkcert_error;
1173 }
1174 if (X509_set_subject_name(newcrt, name) != 1) {
1175 X509_NAME_free(name);
1176 goto mkcert_error;
1177 }
1178 X509_NAME_free(name);
1179
1180 /* Add x509v3 extensions as specified */
1181 X509V3_set_ctx(&ctx, cacert, newcrt, NULL, NULL, 0);
1182 for (i = 0; i < X509V3_EXT_SIZE; i++) {
1183 X509_EXTENSION *ext;
1184
1185 if (!(ext = X509V3_EXT_conf(NULL, &ctx, x509v3_ext_names[i], x509v3_ext_values[i])))
1186 goto mkcert_error;
1187 if (!X509_add_ext(newcrt, ext, -1)) {
1188 X509_EXTENSION_free(ext);
1189 goto mkcert_error;
1190 }
1191 X509_EXTENSION_free(ext);
1192 }
1193
1194 /* Sign the certificate with the CA private key */
1195 if (EVP_PKEY_type(capkey->type) == EVP_PKEY_DSA)
1196 digest = EVP_dss1();
1197 else if (EVP_PKEY_type (capkey->type) == EVP_PKEY_RSA)
1198 digest = EVP_sha256();
Christopher Faulet7969a332015-10-09 11:15:03 +02001199 else if (EVP_PKEY_type (capkey->type) == EVP_PKEY_EC)
1200 digest = EVP_sha256();
1201 else {
Christopher Faulete7db2162015-10-19 13:59:24 +02001202#if (OPENSSL_VERSION_NUMBER >= 0x1000000fL)
Christopher Faulet7969a332015-10-09 11:15:03 +02001203 int nid;
1204
1205 if (EVP_PKEY_get_default_digest_nid(capkey, &nid) <= 0)
1206 goto mkcert_error;
1207 if (!(digest = EVP_get_digestbynid(nid)))
1208 goto mkcert_error;
Christopher Faulete7db2162015-10-19 13:59:24 +02001209#else
1210 goto mkcert_error;
1211#endif
Christopher Faulet7969a332015-10-09 11:15:03 +02001212 }
1213
Christopher Faulet31af49d2015-06-09 17:29:50 +02001214 if (!(X509_sign(newcrt, capkey, digest)))
1215 goto mkcert_error;
1216
1217 /* Create and set the new SSL_CTX */
1218 if (!(ssl_ctx = SSL_CTX_new(SSLv23_server_method())))
1219 goto mkcert_error;
1220 if (!SSL_CTX_use_PrivateKey(ssl_ctx, pkey))
1221 goto mkcert_error;
1222 if (!SSL_CTX_use_certificate(ssl_ctx, newcrt))
1223 goto mkcert_error;
1224 if (!SSL_CTX_check_private_key(ssl_ctx))
1225 goto mkcert_error;
1226
1227 if (newcrt) X509_free(newcrt);
Christopher Faulet7969a332015-10-09 11:15:03 +02001228
Christopher Faulet85b5a1a2015-10-09 11:46:32 +02001229 SSL_CTX_set_tmp_dh_callback(ssl_ctx, ssl_get_tmp_dh);
1230#if defined(SSL_CTX_set_tmp_ecdh) && !defined(OPENSSL_NO_ECDH)
1231 {
1232 const char *ecdhe = (bind_conf->ecdhe ? bind_conf->ecdhe : ECDHE_DEFAULT_CURVE);
1233 EC_KEY *ecc;
1234 int nid;
1235
1236 if ((nid = OBJ_sn2nid(ecdhe)) == NID_undef)
1237 goto end;
1238 if (!(ecc = EC_KEY_new_by_curve_name(nid)))
1239 goto end;
1240 SSL_CTX_set_tmp_ecdh(ssl_ctx, ecc);
1241 EC_KEY_free(ecc);
1242 }
1243#endif
1244 end:
Christopher Faulet31af49d2015-06-09 17:29:50 +02001245 return ssl_ctx;
1246
1247 mkcert_error:
1248 if (ssl_ctx) SSL_CTX_free(ssl_ctx);
1249 if (newcrt) X509_free(newcrt);
Christopher Faulet31af49d2015-06-09 17:29:50 +02001250 return NULL;
1251}
1252
Christopher Faulet7969a332015-10-09 11:15:03 +02001253SSL_CTX *
Christopher Faulet635c0ad2015-11-12 11:35:51 +01001254ssl_sock_create_cert(struct connection *conn, const char *servername, unsigned int key)
Christopher Faulet7969a332015-10-09 11:15:03 +02001255{
1256 struct bind_conf *bind_conf = objt_listener(conn->target)->bind_conf;
Christopher Faulet635c0ad2015-11-12 11:35:51 +01001257
1258 return ssl_sock_do_create_cert(servername, bind_conf, conn->xprt_ctx);
Christopher Faulet7969a332015-10-09 11:15:03 +02001259}
1260
Christopher Faulet30548802015-06-11 13:39:32 +02001261/* Do a lookup for a certificate in the LRU cache used to store generated
1262 * certificates. */
1263SSL_CTX *
Christopher Faulet635c0ad2015-11-12 11:35:51 +01001264ssl_sock_get_generated_cert(unsigned int key, struct bind_conf *bind_conf)
Christopher Faulet30548802015-06-11 13:39:32 +02001265{
1266 struct lru64 *lru = NULL;
1267
1268 if (ssl_ctx_lru_tree) {
Christopher Faulet635c0ad2015-11-12 11:35:51 +01001269 lru = lru64_lookup(key, ssl_ctx_lru_tree, bind_conf->ca_sign_cert, 0);
Christopher Faulet30548802015-06-11 13:39:32 +02001270 if (lru && lru->domain)
1271 return (SSL_CTX *)lru->data;
1272 }
1273 return NULL;
1274}
1275
Christopher Fauletd2cab922015-07-28 16:03:47 +02001276/* Set a certificate int the LRU cache used to store generated
1277 * certificate. Return 0 on success, otherwise -1 */
1278int
Christopher Faulet635c0ad2015-11-12 11:35:51 +01001279ssl_sock_set_generated_cert(SSL_CTX *ssl_ctx, unsigned int key, struct bind_conf *bind_conf)
Christopher Faulet30548802015-06-11 13:39:32 +02001280{
1281 struct lru64 *lru = NULL;
1282
1283 if (ssl_ctx_lru_tree) {
Christopher Faulet635c0ad2015-11-12 11:35:51 +01001284 lru = lru64_get(key, ssl_ctx_lru_tree, bind_conf->ca_sign_cert, 0);
Christopher Faulet30548802015-06-11 13:39:32 +02001285 if (!lru)
Christopher Fauletd2cab922015-07-28 16:03:47 +02001286 return -1;
Christopher Faulet30548802015-06-11 13:39:32 +02001287 if (lru->domain && lru->data)
1288 lru->free((SSL_CTX *)lru->data);
Christopher Faulet7969a332015-10-09 11:15:03 +02001289 lru64_commit(lru, ssl_ctx, bind_conf->ca_sign_cert, 0, (void (*)(void *))SSL_CTX_free);
Christopher Fauletd2cab922015-07-28 16:03:47 +02001290 return 0;
Christopher Faulet30548802015-06-11 13:39:32 +02001291 }
Christopher Fauletd2cab922015-07-28 16:03:47 +02001292 return -1;
Christopher Faulet30548802015-06-11 13:39:32 +02001293}
1294
Christopher Faulet635c0ad2015-11-12 11:35:51 +01001295/* Compute the key of the certificate. */
Christopher Faulet30548802015-06-11 13:39:32 +02001296unsigned int
Christopher Faulet635c0ad2015-11-12 11:35:51 +01001297ssl_sock_generated_cert_key(const void *data, size_t len)
Christopher Faulet30548802015-06-11 13:39:32 +02001298{
1299 return XXH32(data, len, ssl_ctx_lru_seed);
1300}
1301
Willy Tarreau2f63ef42015-10-20 15:16:01 +02001302/* Generate a cert and immediately assign it to the SSL session so that the cert's
1303 * refcount is maintained regardless of the cert's presence in the LRU cache.
1304 */
Christopher Faulet31af49d2015-06-09 17:29:50 +02001305static SSL_CTX *
Christopher Faulet7969a332015-10-09 11:15:03 +02001306ssl_sock_generate_certificate(const char *servername, struct bind_conf *bind_conf, SSL *ssl)
Christopher Faulet31af49d2015-06-09 17:29:50 +02001307{
1308 X509 *cacert = bind_conf->ca_sign_cert;
Christopher Faulet31af49d2015-06-09 17:29:50 +02001309 SSL_CTX *ssl_ctx = NULL;
1310 struct lru64 *lru = NULL;
Christopher Faulet635c0ad2015-11-12 11:35:51 +01001311 unsigned int key;
Christopher Faulet31af49d2015-06-09 17:29:50 +02001312
Christopher Faulet635c0ad2015-11-12 11:35:51 +01001313 key = ssl_sock_generated_cert_key(servername, strlen(servername));
Christopher Faulet31af49d2015-06-09 17:29:50 +02001314 if (ssl_ctx_lru_tree) {
Christopher Faulet635c0ad2015-11-12 11:35:51 +01001315 lru = lru64_get(key, ssl_ctx_lru_tree, cacert, 0);
Christopher Faulet31af49d2015-06-09 17:29:50 +02001316 if (lru && lru->domain)
1317 ssl_ctx = (SSL_CTX *)lru->data;
Christopher Fauletd2cab922015-07-28 16:03:47 +02001318 if (!ssl_ctx && lru) {
Christopher Faulet635c0ad2015-11-12 11:35:51 +01001319 ssl_ctx = ssl_sock_do_create_cert(servername, bind_conf, ssl);
Christopher Faulet31af49d2015-06-09 17:29:50 +02001320 lru64_commit(lru, ssl_ctx, cacert, 0, (void (*)(void *))SSL_CTX_free);
Christopher Fauletd2cab922015-07-28 16:03:47 +02001321 }
Willy Tarreau2f63ef42015-10-20 15:16:01 +02001322 SSL_set_SSL_CTX(ssl, ssl_ctx);
Christopher Faulet31af49d2015-06-09 17:29:50 +02001323 }
Willy Tarreau2f63ef42015-10-20 15:16:01 +02001324 else {
Christopher Faulet635c0ad2015-11-12 11:35:51 +01001325 ssl_ctx = ssl_sock_do_create_cert(servername, bind_conf, ssl);
Willy Tarreau2f63ef42015-10-20 15:16:01 +02001326 SSL_set_SSL_CTX(ssl, ssl_ctx);
1327 /* No LRU cache, this CTX will be released as soon as the session dies */
1328 SSL_CTX_free(ssl_ctx);
1329 }
Christopher Faulet31af49d2015-06-09 17:29:50 +02001330 return ssl_ctx;
1331}
1332
Emeric Brunfc0421f2012-09-07 17:30:07 +02001333/* Sets the SSL ctx of <ssl> to match the advertised server name. Returns a
1334 * warning when no match is found, which implies the default (first) cert
1335 * will keep being used.
1336 */
Willy Tarreau2a65ff02012-09-13 17:54:29 +02001337static int ssl_sock_switchctx_cbk(SSL *ssl, int *al, struct bind_conf *s)
Emeric Brunfc0421f2012-09-07 17:30:07 +02001338{
1339 const char *servername;
1340 const char *wildp = NULL;
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +02001341 struct ebmb_node *node, *n;
Emeric Brunfc0421f2012-09-07 17:30:07 +02001342 int i;
1343 (void)al; /* shut gcc stupid warning */
1344
1345 servername = SSL_get_servername(ssl, TLSEXT_NAMETYPE_host_name);
Emmanuel Hocdet65623372013-01-24 17:17:15 +01001346 if (!servername) {
Willy Tarreauf6721452015-07-07 18:04:38 +02001347 if (s->generate_certs) {
Vincent Bernat3c2f2f22016-04-03 13:48:42 +02001348 struct connection *conn = SSL_get_app_data(ssl);
Christopher Faulet635c0ad2015-11-12 11:35:51 +01001349 unsigned int key;
Willy Tarreauf6721452015-07-07 18:04:38 +02001350 SSL_CTX *ctx;
Christopher Faulet30548802015-06-11 13:39:32 +02001351
Willy Tarreauf6721452015-07-07 18:04:38 +02001352 conn_get_to_addr(conn);
1353 if (conn->flags & CO_FL_ADDR_TO_SET) {
Christopher Faulet635c0ad2015-11-12 11:35:51 +01001354 key = ssl_sock_generated_cert_key(&conn->addr.to, get_addr_len(&conn->addr.to));
1355 ctx = ssl_sock_get_generated_cert(key, s);
Willy Tarreauf6721452015-07-07 18:04:38 +02001356 if (ctx) {
1357 /* switch ctx */
1358 SSL_set_SSL_CTX(ssl, ctx);
1359 return SSL_TLSEXT_ERR_OK;
1360 }
Christopher Faulet30548802015-06-11 13:39:32 +02001361 }
1362 }
1363
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +02001364 return (s->strict_sni ?
1365 SSL_TLSEXT_ERR_ALERT_FATAL :
Emmanuel Hocdet79274e22013-05-31 12:47:44 +02001366 SSL_TLSEXT_ERR_NOACK);
Emmanuel Hocdet65623372013-01-24 17:17:15 +01001367 }
Emeric Brunfc0421f2012-09-07 17:30:07 +02001368
Willy Tarreau19d14ef2012-10-29 16:51:55 +01001369 for (i = 0; i < trash.size; i++) {
Emeric Brunfc0421f2012-09-07 17:30:07 +02001370 if (!servername[i])
1371 break;
Willy Tarreau19d14ef2012-10-29 16:51:55 +01001372 trash.str[i] = tolower(servername[i]);
1373 if (!wildp && (trash.str[i] == '.'))
1374 wildp = &trash.str[i];
Emeric Brunfc0421f2012-09-07 17:30:07 +02001375 }
Willy Tarreau19d14ef2012-10-29 16:51:55 +01001376 trash.str[i] = 0;
Emeric Brunfc0421f2012-09-07 17:30:07 +02001377
1378 /* lookup in full qualified names */
Willy Tarreau19d14ef2012-10-29 16:51:55 +01001379 node = ebst_lookup(&s->sni_ctx, trash.str);
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +02001380
1381 /* lookup a not neg filter */
1382 for (n = node; n; n = ebmb_next_dup(n)) {
1383 if (!container_of(n, struct sni_ctx, name)->neg) {
1384 node = n;
1385 break;
Emmanuel Hocdet65623372013-01-24 17:17:15 +01001386 }
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +02001387 }
1388 if (!node && wildp) {
1389 /* lookup in wildcards names */
Emeric Brunfc0421f2012-09-07 17:30:07 +02001390 node = ebst_lookup(&s->sni_w_ctx, wildp);
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +02001391 }
1392 if (!node || container_of(node, struct sni_ctx, name)->neg) {
Christopher Faulet31af49d2015-06-09 17:29:50 +02001393 SSL_CTX *ctx;
Christopher Faulet31af49d2015-06-09 17:29:50 +02001394 if (s->generate_certs &&
Christopher Faulet7969a332015-10-09 11:15:03 +02001395 (ctx = ssl_sock_generate_certificate(servername, s, ssl))) {
Christopher Faulet31af49d2015-06-09 17:29:50 +02001396 /* switch ctx */
Christopher Faulet31af49d2015-06-09 17:29:50 +02001397 return SSL_TLSEXT_ERR_OK;
1398 }
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +02001399 return (s->strict_sni ?
1400 SSL_TLSEXT_ERR_ALERT_FATAL :
1401 SSL_TLSEXT_ERR_ALERT_WARNING);
Emeric Brunfc0421f2012-09-07 17:30:07 +02001402 }
1403
1404 /* switch ctx */
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +02001405 SSL_set_SSL_CTX(ssl, container_of(node, struct sni_ctx, name)->ctx);
Emeric Brunfc0421f2012-09-07 17:30:07 +02001406 return SSL_TLSEXT_ERR_OK;
1407}
1408#endif /* SSL_CTRL_SET_TLSEXT_HOSTNAME */
1409
Emeric Bruna4bcd9a2012-09-20 16:19:02 +02001410#ifndef OPENSSL_NO_DH
Remi Gacognef46cd6e2014-06-12 14:58:40 +02001411
1412static DH * ssl_get_dh_1024(void)
1413{
Remi Gacogned3a341a2015-05-29 16:26:17 +02001414 static unsigned char dh1024_p[]={
1415 0xFA,0xF9,0x2A,0x22,0x2A,0xA7,0x7F,0xE1,0x67,0x4E,0x53,0xF7,
1416 0x56,0x13,0xC3,0xB1,0xE3,0x29,0x6B,0x66,0x31,0x6A,0x7F,0xB3,
1417 0xC2,0x68,0x6B,0xCB,0x1D,0x57,0x39,0x1D,0x1F,0xFF,0x1C,0xC9,
1418 0xA6,0xA4,0x98,0x82,0x31,0x5D,0x25,0xFF,0x8A,0xE0,0x73,0x96,
1419 0x81,0xC8,0x83,0x79,0xC1,0x5A,0x04,0xF8,0x37,0x0D,0xA8,0x3D,
1420 0xAE,0x74,0xBC,0xDB,0xB6,0xA4,0x75,0xD9,0x71,0x8A,0xA0,0x17,
1421 0x9E,0x2D,0xC8,0xA8,0xDF,0x2C,0x5F,0x82,0x95,0xF8,0x92,0x9B,
1422 0xA7,0x33,0x5F,0x89,0x71,0xC8,0x2D,0x6B,0x18,0x86,0xC4,0x94,
1423 0x22,0xA5,0x52,0x8D,0xF6,0xF6,0xD2,0x37,0x92,0x0F,0xA5,0xCC,
1424 0xDB,0x7B,0x1D,0x3D,0xA1,0x31,0xB7,0x80,0x8F,0x0B,0x67,0x5E,
1425 0x36,0xA5,0x60,0x0C,0xF1,0x95,0x33,0x8B,
1426 };
1427 static unsigned char dh1024_g[]={
1428 0x02,
1429 };
1430
Remi Gacognef46cd6e2014-06-12 14:58:40 +02001431 DH *dh = DH_new();
1432 if (dh) {
Remi Gacogned3a341a2015-05-29 16:26:17 +02001433 dh->p = BN_bin2bn(dh1024_p, sizeof dh1024_p, NULL);
1434 dh->g = BN_bin2bn(dh1024_g, sizeof dh1024_g, NULL);
1435
Remi Gacognef46cd6e2014-06-12 14:58:40 +02001436 if (!dh->p || !dh->g) {
1437 DH_free(dh);
1438 dh = NULL;
1439 }
1440 }
1441 return dh;
1442}
1443
1444static DH *ssl_get_dh_2048(void)
1445{
Remi Gacogned3a341a2015-05-29 16:26:17 +02001446 static unsigned char dh2048_p[]={
1447 0xEC,0x86,0xF8,0x70,0xA0,0x33,0x16,0xEC,0x05,0x1A,0x73,0x59,
1448 0xCD,0x1F,0x8B,0xF8,0x29,0xE4,0xD2,0xCF,0x52,0xDD,0xC2,0x24,
1449 0x8D,0xB5,0x38,0x9A,0xFB,0x5C,0xA4,0xE4,0xB2,0xDA,0xCE,0x66,
1450 0x50,0x74,0xA6,0x85,0x4D,0x4B,0x1D,0x30,0xB8,0x2B,0xF3,0x10,
1451 0xE9,0xA7,0x2D,0x05,0x71,0xE7,0x81,0xDF,0x8B,0x59,0x52,0x3B,
1452 0x5F,0x43,0x0B,0x68,0xF1,0xDB,0x07,0xBE,0x08,0x6B,0x1B,0x23,
1453 0xEE,0x4D,0xCC,0x9E,0x0E,0x43,0xA0,0x1E,0xDF,0x43,0x8C,0xEC,
1454 0xBE,0xBE,0x90,0xB4,0x51,0x54,0xB9,0x2F,0x7B,0x64,0x76,0x4E,
1455 0x5D,0xD4,0x2E,0xAE,0xC2,0x9E,0xAE,0x51,0x43,0x59,0xC7,0x77,
1456 0x9C,0x50,0x3C,0x0E,0xED,0x73,0x04,0x5F,0xF1,0x4C,0x76,0x2A,
1457 0xD8,0xF8,0xCF,0xFC,0x34,0x40,0xD1,0xB4,0x42,0x61,0x84,0x66,
1458 0x42,0x39,0x04,0xF8,0x68,0xB2,0x62,0xD7,0x55,0xED,0x1B,0x74,
1459 0x75,0x91,0xE0,0xC5,0x69,0xC1,0x31,0x5C,0xDB,0x7B,0x44,0x2E,
1460 0xCE,0x84,0x58,0x0D,0x1E,0x66,0x0C,0xC8,0x44,0x9E,0xFD,0x40,
1461 0x08,0x67,0x5D,0xFB,0xA7,0x76,0x8F,0x00,0x11,0x87,0xE9,0x93,
1462 0xF9,0x7D,0xC4,0xBC,0x74,0x55,0x20,0xD4,0x4A,0x41,0x2F,0x43,
1463 0x42,0x1A,0xC1,0xF2,0x97,0x17,0x49,0x27,0x37,0x6B,0x2F,0x88,
1464 0x7E,0x1C,0xA0,0xA1,0x89,0x92,0x27,0xD9,0x56,0x5A,0x71,0xC1,
1465 0x56,0x37,0x7E,0x3A,0x9D,0x05,0xE7,0xEE,0x5D,0x8F,0x82,0x17,
1466 0xBC,0xE9,0xC2,0x93,0x30,0x82,0xF9,0xF4,0xC9,0xAE,0x49,0xDB,
1467 0xD0,0x54,0xB4,0xD9,0x75,0x4D,0xFA,0x06,0xB8,0xD6,0x38,0x41,
1468 0xB7,0x1F,0x77,0xF3,
1469 };
1470 static unsigned char dh2048_g[]={
1471 0x02,
1472 };
1473
Remi Gacognef46cd6e2014-06-12 14:58:40 +02001474 DH *dh = DH_new();
1475 if (dh) {
Remi Gacogned3a341a2015-05-29 16:26:17 +02001476 dh->p = BN_bin2bn(dh2048_p, sizeof dh2048_p, NULL);
1477 dh->g = BN_bin2bn(dh2048_g, sizeof dh2048_g, NULL);
1478
Remi Gacognef46cd6e2014-06-12 14:58:40 +02001479 if (!dh->p || !dh->g) {
1480 DH_free(dh);
1481 dh = NULL;
1482 }
1483 }
1484 return dh;
1485}
1486
1487static DH *ssl_get_dh_4096(void)
1488{
Remi Gacogned3a341a2015-05-29 16:26:17 +02001489 static unsigned char dh4096_p[]={
1490 0xDE,0x16,0x94,0xCD,0x99,0x58,0x07,0xF1,0xF7,0x32,0x96,0x11,
1491 0x04,0x82,0xD4,0x84,0x72,0x80,0x99,0x06,0xCA,0xF0,0xA3,0x68,
1492 0x07,0xCE,0x64,0x50,0xE7,0x74,0x45,0x20,0x80,0x5E,0x4D,0xAD,
1493 0xA5,0xB6,0xED,0xFA,0x80,0x6C,0x3B,0x35,0xC4,0x9A,0x14,0x6B,
1494 0x32,0xBB,0xFD,0x1F,0x17,0x8E,0xB7,0x1F,0xD6,0xFA,0x3F,0x7B,
1495 0xEE,0x16,0xA5,0x62,0x33,0x0D,0xED,0xBC,0x4E,0x58,0xE5,0x47,
1496 0x4D,0xE9,0xAB,0x8E,0x38,0xD3,0x6E,0x90,0x57,0xE3,0x22,0x15,
1497 0x33,0xBD,0xF6,0x43,0x45,0xB5,0x10,0x0A,0xBE,0x2C,0xB4,0x35,
1498 0xB8,0x53,0x8D,0xAD,0xFB,0xA7,0x1F,0x85,0x58,0x41,0x7A,0x79,
1499 0x20,0x68,0xB3,0xE1,0x3D,0x08,0x76,0xBF,0x86,0x0D,0x49,0xE3,
1500 0x82,0x71,0x8C,0xB4,0x8D,0x81,0x84,0xD4,0xE7,0xBE,0x91,0xDC,
1501 0x26,0x39,0x48,0x0F,0x35,0xC4,0xCA,0x65,0xE3,0x40,0x93,0x52,
1502 0x76,0x58,0x7D,0xDD,0x51,0x75,0xDC,0x69,0x61,0xBF,0x47,0x2C,
1503 0x16,0x68,0x2D,0xC9,0x29,0xD3,0xE6,0xC0,0x99,0x48,0xA0,0x9A,
1504 0xC8,0x78,0xC0,0x6D,0x81,0x67,0x12,0x61,0x3F,0x71,0xBA,0x41,
1505 0x1F,0x6C,0x89,0x44,0x03,0xBA,0x3B,0x39,0x60,0xAA,0x28,0x55,
1506 0x59,0xAE,0xB8,0xFA,0xCB,0x6F,0xA5,0x1A,0xF7,0x2B,0xDD,0x52,
1507 0x8A,0x8B,0xE2,0x71,0xA6,0x5E,0x7E,0xD8,0x2E,0x18,0xE0,0x66,
1508 0xDF,0xDD,0x22,0x21,0x99,0x52,0x73,0xA6,0x33,0x20,0x65,0x0E,
1509 0x53,0xE7,0x6B,0x9B,0xC5,0xA3,0x2F,0x97,0x65,0x76,0xD3,0x47,
1510 0x23,0x77,0x12,0xB6,0x11,0x7B,0x24,0xED,0xF1,0xEF,0xC0,0xE2,
1511 0xA3,0x7E,0x67,0x05,0x3E,0x96,0x4D,0x45,0xC2,0x18,0xD1,0x73,
1512 0x9E,0x07,0xF3,0x81,0x6E,0x52,0x63,0xF6,0x20,0x76,0xB9,0x13,
1513 0xD2,0x65,0x30,0x18,0x16,0x09,0x16,0x9E,0x8F,0xF1,0xD2,0x10,
1514 0x5A,0xD3,0xD4,0xAF,0x16,0x61,0xDA,0x55,0x2E,0x18,0x5E,0x14,
1515 0x08,0x54,0x2E,0x2A,0x25,0xA2,0x1A,0x9B,0x8B,0x32,0xA9,0xFD,
1516 0xC2,0x48,0x96,0xE1,0x80,0xCA,0xE9,0x22,0x17,0xBB,0xCE,0x3E,
1517 0x9E,0xED,0xC7,0xF1,0x1F,0xEC,0x17,0x21,0xDC,0x7B,0x82,0x48,
1518 0x8E,0xBB,0x4B,0x9D,0x5B,0x04,0x04,0xDA,0xDB,0x39,0xDF,0x01,
1519 0x40,0xC3,0xAA,0x26,0x23,0x89,0x75,0xC6,0x0B,0xD0,0xA2,0x60,
1520 0x6A,0xF1,0xCC,0x65,0x18,0x98,0x1B,0x52,0xD2,0x74,0x61,0xCC,
1521 0xBD,0x60,0xAE,0xA3,0xA0,0x66,0x6A,0x16,0x34,0x92,0x3F,0x41,
1522 0x40,0x31,0x29,0xC0,0x2C,0x63,0xB2,0x07,0x8D,0xEB,0x94,0xB8,
1523 0xE8,0x47,0x92,0x52,0x93,0x6A,0x1B,0x7E,0x1A,0x61,0xB3,0x1B,
1524 0xF0,0xD6,0x72,0x9B,0xF1,0xB0,0xAF,0xBF,0x3E,0x65,0xEF,0x23,
1525 0x1D,0x6F,0xFF,0x70,0xCD,0x8A,0x4C,0x8A,0xA0,0x72,0x9D,0xBE,
1526 0xD4,0xBB,0x24,0x47,0x4A,0x68,0xB5,0xF5,0xC6,0xD5,0x7A,0xCD,
1527 0xCA,0x06,0x41,0x07,0xAD,0xC2,0x1E,0xE6,0x54,0xA7,0xAD,0x03,
1528 0xD9,0x12,0xC1,0x9C,0x13,0xB1,0xC9,0x0A,0x43,0x8E,0x1E,0x08,
1529 0xCE,0x50,0x82,0x73,0x5F,0xA7,0x55,0x1D,0xD9,0x59,0xAC,0xB5,
1530 0xEA,0x02,0x7F,0x6C,0x5B,0x74,0x96,0x98,0x67,0x24,0xA3,0x0F,
1531 0x15,0xFC,0xA9,0x7D,0x3E,0x67,0xD1,0x70,0xF8,0x97,0xF3,0x67,
1532 0xC5,0x8C,0x88,0x44,0x08,0x02,0xC7,0x2B,
Remi Gacognef46cd6e2014-06-12 14:58:40 +02001533 };
Remi Gacogned3a341a2015-05-29 16:26:17 +02001534 static unsigned char dh4096_g[]={
1535 0x02,
1536 };
Remi Gacognef46cd6e2014-06-12 14:58:40 +02001537
Remi Gacognef46cd6e2014-06-12 14:58:40 +02001538 DH *dh = DH_new();
1539 if (dh) {
Remi Gacogned3a341a2015-05-29 16:26:17 +02001540 dh->p = BN_bin2bn(dh4096_p, sizeof dh4096_p, NULL);
1541 dh->g = BN_bin2bn(dh4096_g, sizeof dh4096_g, NULL);
1542
Remi Gacognef46cd6e2014-06-12 14:58:40 +02001543 if (!dh->p || !dh->g) {
1544 DH_free(dh);
1545 dh = NULL;
1546 }
1547 }
1548 return dh;
1549}
1550
1551/* Returns Diffie-Hellman parameters matching the private key length
1552 but not exceeding global.tune.ssl_default_dh_param */
1553static DH *ssl_get_tmp_dh(SSL *ssl, int export, int keylen)
1554{
1555 DH *dh = NULL;
1556 EVP_PKEY *pkey = SSL_get_privatekey(ssl);
1557 int type = pkey ? EVP_PKEY_type(pkey->type) : EVP_PKEY_NONE;
1558
1559 /* The keylen supplied by OpenSSL can only be 512 or 1024.
1560 See ssl3_send_server_key_exchange() in ssl/s3_srvr.c
1561 */
1562 if (type == EVP_PKEY_RSA || type == EVP_PKEY_DSA) {
1563 keylen = EVP_PKEY_bits(pkey);
1564 }
1565
1566 if (keylen > global.tune.ssl_default_dh_param) {
1567 keylen = global.tune.ssl_default_dh_param;
1568 }
1569
Remi Gacogned3a341a2015-05-29 16:26:17 +02001570 if (keylen >= 4096) {
Remi Gacogne8de54152014-07-15 11:36:40 +02001571 dh = local_dh_4096;
Remi Gacognef46cd6e2014-06-12 14:58:40 +02001572 }
1573 else if (keylen >= 2048) {
Remi Gacogne8de54152014-07-15 11:36:40 +02001574 dh = local_dh_2048;
Remi Gacognef46cd6e2014-06-12 14:58:40 +02001575 }
1576 else {
Remi Gacogne8de54152014-07-15 11:36:40 +02001577 dh = local_dh_1024;
Remi Gacognef46cd6e2014-06-12 14:58:40 +02001578 }
1579
1580 return dh;
1581}
1582
Remi Gacogne47783ef2015-05-29 15:53:22 +02001583static DH * ssl_sock_get_dh_from_file(const char *filename)
Emeric Bruna4bcd9a2012-09-20 16:19:02 +02001584{
Emeric Bruna4bcd9a2012-09-20 16:19:02 +02001585 DH *dh = NULL;
Remi Gacogne47783ef2015-05-29 15:53:22 +02001586 BIO *in = BIO_new(BIO_s_file());
Emeric Bruna4bcd9a2012-09-20 16:19:02 +02001587
Emeric Bruna4bcd9a2012-09-20 16:19:02 +02001588 if (in == NULL)
1589 goto end;
1590
Remi Gacogne47783ef2015-05-29 15:53:22 +02001591 if (BIO_read_filename(in, filename) <= 0)
Emeric Bruna4bcd9a2012-09-20 16:19:02 +02001592 goto end;
1593
Remi Gacogne47783ef2015-05-29 15:53:22 +02001594 dh = PEM_read_bio_DHparams(in, NULL, NULL, NULL);
1595
1596end:
1597 if (in)
1598 BIO_free(in);
1599
1600 return dh;
1601}
1602
1603int ssl_sock_load_global_dh_param_from_file(const char *filename)
1604{
1605 global_dh = ssl_sock_get_dh_from_file(filename);
1606
1607 if (global_dh) {
1608 return 0;
1609 }
1610
1611 return -1;
1612}
1613
1614/* Loads Diffie-Hellman parameter from a file. Returns 1 if loaded, else -1
1615 if an error occured, and 0 if parameter not found. */
1616int ssl_sock_load_dh_params(SSL_CTX *ctx, const char *file)
1617{
1618 int ret = -1;
1619 DH *dh = ssl_sock_get_dh_from_file(file);
1620
Remi Gacognef46cd6e2014-06-12 14:58:40 +02001621 if (dh) {
1622 ret = 1;
1623 SSL_CTX_set_tmp_dh(ctx, dh);
Remi Gacogne4f902b82015-05-28 16:23:00 +02001624
1625 if (ssl_dh_ptr_index >= 0) {
1626 /* store a pointer to the DH params to avoid complaining about
1627 ssl-default-dh-param not being set for this SSL_CTX */
1628 SSL_CTX_set_ex_data(ctx, ssl_dh_ptr_index, dh);
1629 }
Remi Gacognef46cd6e2014-06-12 14:58:40 +02001630 }
Remi Gacogne47783ef2015-05-29 15:53:22 +02001631 else if (global_dh) {
1632 SSL_CTX_set_tmp_dh(ctx, global_dh);
1633 ret = 0; /* DH params not found */
1634 }
Remi Gacognef46cd6e2014-06-12 14:58:40 +02001635 else {
Emeric Brun41fdb3c2013-04-26 11:05:44 +02001636 /* Clear openssl global errors stack */
1637 ERR_clear_error();
1638
Remi Gacognef46cd6e2014-06-12 14:58:40 +02001639 if (global.tune.ssl_default_dh_param <= 1024) {
1640 /* we are limited to DH parameter of 1024 bits anyway */
Remi Gacognec7e12632016-07-02 16:26:10 +02001641 if (local_dh_1024 == NULL)
1642 local_dh_1024 = ssl_get_dh_1024();
1643
Remi Gacogne8de54152014-07-15 11:36:40 +02001644 if (local_dh_1024 == NULL)
Remi Gacognef46cd6e2014-06-12 14:58:40 +02001645 goto end;
Willy Tarreau6e774b42014-04-25 21:35:23 +02001646
Remi Gacogne8de54152014-07-15 11:36:40 +02001647 SSL_CTX_set_tmp_dh(ctx, local_dh_1024);
Remi Gacognef46cd6e2014-06-12 14:58:40 +02001648 }
1649 else {
1650 SSL_CTX_set_tmp_dh_callback(ctx, ssl_get_tmp_dh);
1651 }
Willy Tarreau6e774b42014-04-25 21:35:23 +02001652
Emeric Brun41fdb3c2013-04-26 11:05:44 +02001653 ret = 0; /* DH params not found */
Emeric Bruna4bcd9a2012-09-20 16:19:02 +02001654 }
Emeric Brun644cde02012-12-14 11:21:13 +01001655
Emeric Bruna4bcd9a2012-09-20 16:19:02 +02001656end:
1657 if (dh)
1658 DH_free(dh);
1659
Emeric Bruna4bcd9a2012-09-20 16:19:02 +02001660 return ret;
1661}
1662#endif
1663
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +02001664static int ssl_sock_add_cert_sni(SSL_CTX *ctx, struct bind_conf *s, char *name, int order)
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01001665{
1666 struct sni_ctx *sc;
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +02001667 int wild = 0, neg = 0;
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01001668
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +02001669 if (*name == '!') {
1670 neg = 1;
1671 name++;
1672 }
1673 if (*name == '*') {
1674 wild = 1;
1675 name++;
1676 }
1677 /* !* filter is a nop */
1678 if (neg && wild)
1679 return order;
1680 if (*name) {
1681 int j, len;
1682 len = strlen(name);
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01001683 sc = malloc(sizeof(struct sni_ctx) + len + 1);
1684 for (j = 0; j < len; j++)
1685 sc->name.key[j] = tolower(name[j]);
1686 sc->name.key[len] = 0;
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01001687 sc->ctx = ctx;
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +02001688 sc->order = order++;
1689 sc->neg = neg;
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01001690 if (wild)
1691 ebst_insert(&s->sni_w_ctx, &sc->name);
1692 else
1693 ebst_insert(&s->sni_ctx, &sc->name);
1694 }
1695 return order;
1696}
1697
yanbzhu488a4d22015-12-01 15:16:07 -05001698
1699/* The following code is used for loading multiple crt files into
1700 * SSL_CTX's based on CN/SAN
1701 */
1702#if OPENSSL_VERSION_NUMBER >= 0x1000200fL
1703/* This is used to preload the certifcate, private key
1704 * and Cert Chain of a file passed in via the crt
1705 * argument
1706 *
1707 * This way, we do not have to read the file multiple times
1708 */
1709struct cert_key_and_chain {
1710 X509 *cert;
1711 EVP_PKEY *key;
1712 unsigned int num_chain_certs;
1713 /* This is an array of X509 pointers */
1714 X509 **chain_certs;
1715};
1716
yanbzhu08ce6ab2015-12-02 13:01:29 -05001717#define SSL_SOCK_POSSIBLE_KT_COMBOS (1<<(SSL_SOCK_NUM_KEYTYPES))
1718
1719struct key_combo_ctx {
1720 SSL_CTX *ctx;
1721 int order;
1722};
1723
1724/* Map used for processing multiple keypairs for a single purpose
1725 *
1726 * This maps CN/SNI name to certificate type
1727 */
1728struct sni_keytype {
1729 int keytypes; /* BITMASK for keytypes */
1730 struct ebmb_node name; /* node holding the servername value */
1731};
1732
1733
yanbzhu488a4d22015-12-01 15:16:07 -05001734/* Frees the contents of a cert_key_and_chain
1735 */
1736static void ssl_sock_free_cert_key_and_chain_contents(struct cert_key_and_chain *ckch)
1737{
1738 int i;
1739
1740 if (!ckch)
1741 return;
1742
1743 /* Free the certificate and set pointer to NULL */
1744 if (ckch->cert)
1745 X509_free(ckch->cert);
1746 ckch->cert = NULL;
1747
1748 /* Free the key and set pointer to NULL */
1749 if (ckch->key)
1750 EVP_PKEY_free(ckch->key);
1751 ckch->key = NULL;
1752
1753 /* Free each certificate in the chain */
1754 for (i = 0; i < ckch->num_chain_certs; i++) {
1755 if (ckch->chain_certs[i])
1756 X509_free(ckch->chain_certs[i]);
1757 }
1758
1759 /* Free the chain obj itself and set to NULL */
1760 if (ckch->num_chain_certs > 0) {
1761 free(ckch->chain_certs);
1762 ckch->num_chain_certs = 0;
1763 ckch->chain_certs = NULL;
1764 }
1765
1766}
1767
1768/* checks if a key and cert exists in the ckch
1769 */
1770static int ssl_sock_is_ckch_valid(struct cert_key_and_chain *ckch)
1771{
1772 return (ckch->cert != NULL && ckch->key != NULL);
1773}
1774
1775
1776/* Loads the contents of a crt file (path) into a cert_key_and_chain
1777 * This allows us to carry the contents of the file without having to
1778 * read the file multiple times.
1779 *
1780 * returns:
1781 * 0 on Success
1782 * 1 on SSL Failure
1783 * 2 on file not found
1784 */
1785static int ssl_sock_load_crt_file_into_ckch(const char *path, struct cert_key_and_chain *ckch, char **err)
1786{
1787
1788 BIO *in;
1789 X509 *ca = NULL;
1790 int ret = 1;
1791
1792 ssl_sock_free_cert_key_and_chain_contents(ckch);
1793
1794 in = BIO_new(BIO_s_file());
1795 if (in == NULL)
1796 goto end;
1797
1798 if (BIO_read_filename(in, path) <= 0)
1799 goto end;
1800
yanbzhu488a4d22015-12-01 15:16:07 -05001801 /* Read Private Key */
1802 ckch->key = PEM_read_bio_PrivateKey(in, NULL, NULL, NULL);
1803 if (ckch->key == NULL) {
1804 memprintf(err, "%sunable to load private key from file '%s'.\n",
1805 err && *err ? *err : "", path);
1806 goto end;
1807 }
1808
Willy Tarreaubb137a82016-04-06 19:02:38 +02001809 /* Seek back to beginning of file */
1810 BIO_reset(in);
1811
1812 /* Read Certificate */
1813 ckch->cert = PEM_read_bio_X509_AUX(in, NULL, NULL, NULL);
1814 if (ckch->cert == NULL) {
1815 memprintf(err, "%sunable to load certificate from file '%s'.\n",
1816 err && *err ? *err : "", path);
1817 goto end;
1818 }
1819
yanbzhu488a4d22015-12-01 15:16:07 -05001820 /* Read Certificate Chain */
1821 while ((ca = PEM_read_bio_X509(in, NULL, NULL, NULL))) {
1822 /* Grow the chain certs */
1823 ckch->num_chain_certs++;
1824 ckch->chain_certs = realloc(ckch->chain_certs, (ckch->num_chain_certs * sizeof(X509 *)));
1825
1826 /* use - 1 here since we just incremented it above */
1827 ckch->chain_certs[ckch->num_chain_certs - 1] = ca;
1828 }
1829 ret = ERR_get_error();
1830 if (ret && (ERR_GET_LIB(ret) != ERR_LIB_PEM && ERR_GET_REASON(ret) != PEM_R_NO_START_LINE)) {
1831 memprintf(err, "%sunable to load certificate chain from file '%s'.\n",
1832 err && *err ? *err : "", path);
1833 ret = 1;
1834 goto end;
1835 }
1836
1837 ret = 0;
1838
1839end:
1840
1841 ERR_clear_error();
1842 if (in)
1843 BIO_free(in);
1844
1845 /* Something went wrong in one of the reads */
1846 if (ret != 0)
1847 ssl_sock_free_cert_key_and_chain_contents(ckch);
1848
1849 return ret;
1850}
1851
1852/* Loads the info in ckch into ctx
1853 * Currently, this does not process any information about ocsp, dhparams or
1854 * sctl
1855 * Returns
1856 * 0 on success
1857 * 1 on failure
1858 */
1859static int ssl_sock_put_ckch_into_ctx(const char *path, const struct cert_key_and_chain *ckch, SSL_CTX *ctx, char **err)
1860{
1861 int i = 0;
1862
1863 if (SSL_CTX_use_PrivateKey(ctx, ckch->key) <= 0) {
1864 memprintf(err, "%sunable to load SSL private key into SSL Context '%s'.\n",
1865 err && *err ? *err : "", path);
1866 return 1;
1867 }
1868
1869 if (!SSL_CTX_use_certificate(ctx, ckch->cert)) {
1870 memprintf(err, "%sunable to load SSL certificate into SSL Context '%s'.\n",
1871 err && *err ? *err : "", path);
1872 return 1;
1873 }
1874
yanbzhu488a4d22015-12-01 15:16:07 -05001875 /* Load all certs in the ckch into the ctx_chain for the ssl_ctx */
1876 for (i = 0; i < ckch->num_chain_certs; i++) {
1877 if (!SSL_CTX_add1_chain_cert(ctx, ckch->chain_certs[i])) {
yanbzhu08ce6ab2015-12-02 13:01:29 -05001878 memprintf(err, "%sunable to load chain certificate #%d into SSL Context '%s'. Make sure you are linking against Openssl >= 1.0.2.\n",
1879 err && *err ? *err : "", (i+1), path);
yanbzhu488a4d22015-12-01 15:16:07 -05001880 return 1;
1881 }
1882 }
1883
1884 if (SSL_CTX_check_private_key(ctx) <= 0) {
1885 memprintf(err, "%sinconsistencies between private key and certificate loaded from PEM file '%s'.\n",
1886 err && *err ? *err : "", path);
1887 return 1;
1888 }
1889
1890 return 0;
1891}
1892
yanbzhu08ce6ab2015-12-02 13:01:29 -05001893
1894static void ssl_sock_populate_sni_keytypes_hplr(const char *str, struct eb_root *sni_keytypes, int key_index)
1895{
1896 struct sni_keytype *s_kt = NULL;
1897 struct ebmb_node *node;
1898 int i;
1899
1900 for (i = 0; i < trash.size; i++) {
1901 if (!str[i])
1902 break;
1903 trash.str[i] = tolower(str[i]);
1904 }
1905 trash.str[i] = 0;
1906 node = ebst_lookup(sni_keytypes, trash.str);
1907 if (!node) {
1908 /* CN not found in tree */
1909 s_kt = malloc(sizeof(struct sni_keytype) + i + 1);
1910 /* Using memcpy here instead of strncpy.
1911 * strncpy will cause sig_abrt errors under certain versions of gcc with -O2
1912 * See: https://gcc.gnu.org/bugzilla/show_bug.cgi?id=60792
1913 */
1914 memcpy(s_kt->name.key, trash.str, i+1);
1915 s_kt->keytypes = 0;
1916 ebst_insert(sni_keytypes, &s_kt->name);
1917 } else {
1918 /* CN found in tree */
1919 s_kt = container_of(node, struct sni_keytype, name);
1920 }
1921
1922 /* Mark that this CN has the keytype of key_index via keytypes mask */
1923 s_kt->keytypes |= 1<<key_index;
1924
1925}
1926
1927
1928/* Given a path that does not exist, try to check for path.rsa, path.dsa and path.ecdsa files.
1929 * If any are found, group these files into a set of SSL_CTX*
1930 * based on shared and unique CN and SAN entries. Add these SSL_CTX* to the SNI tree.
1931 *
1932 * This will allow the user to explictly group multiple cert/keys for a single purpose
1933 *
1934 * Returns
1935 * 0 on success
1936 * 1 on failure
1937 */
Emmanuel Hocdetd294aea2016-05-13 11:14:06 +02001938static 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 -05001939{
1940 char fp[MAXPATHLEN+1] = {0};
1941 int n = 0;
1942 int i = 0;
1943 struct cert_key_and_chain certs_and_keys[SSL_SOCK_NUM_KEYTYPES] = { {0} };
1944 struct eb_root sni_keytypes_map = { {0} };
1945 struct ebmb_node *node;
1946 struct ebmb_node *next;
1947 /* Array of SSL_CTX pointers corresponding to each possible combo
1948 * of keytypes
1949 */
1950 struct key_combo_ctx key_combos[SSL_SOCK_POSSIBLE_KT_COMBOS] = { {0} };
1951 int rv = 0;
1952 X509_NAME *xname = NULL;
1953 char *str = NULL;
1954#ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME
1955 STACK_OF(GENERAL_NAME) *names = NULL;
1956#endif
1957
1958 /* Load all possible certs and keys */
1959 for (n = 0; n < SSL_SOCK_NUM_KEYTYPES; n++) {
1960 struct stat buf;
1961
1962 snprintf(fp, sizeof(fp), "%s.%s", path, SSL_SOCK_KEYTYPE_NAMES[n]);
1963 if (stat(fp, &buf) == 0) {
1964 if (ssl_sock_load_crt_file_into_ckch(fp, &certs_and_keys[n], err) == 1) {
1965 rv = 1;
1966 goto end;
1967 }
1968 }
1969 }
1970
1971 /* Process each ckch and update keytypes for each CN/SAN
1972 * for example, if CN/SAN www.a.com is associated with
1973 * certs with keytype 0 and 2, then at the end of the loop,
1974 * www.a.com will have:
1975 * keyindex = 0 | 1 | 4 = 5
1976 */
1977 for (n = 0; n < SSL_SOCK_NUM_KEYTYPES; n++) {
1978
1979 if (!ssl_sock_is_ckch_valid(&certs_and_keys[n]))
1980 continue;
1981
Emmanuel Hocdetd294aea2016-05-13 11:14:06 +02001982 if (fcount) {
Willy Tarreau24b892f2016-06-20 23:01:57 +02001983 for (i = 0; i < fcount; i++)
Emmanuel Hocdetd294aea2016-05-13 11:14:06 +02001984 ssl_sock_populate_sni_keytypes_hplr(sni_filter[i], &sni_keytypes_map, n);
1985 } else {
1986 /* A lot of the following code is OpenSSL boilerplate for processing CN's and SAN's,
1987 * so the line that contains logic is marked via comments
1988 */
1989 xname = X509_get_subject_name(certs_and_keys[n].cert);
1990 i = -1;
1991 while ((i = X509_NAME_get_index_by_NID(xname, NID_commonName, i)) != -1) {
1992 X509_NAME_ENTRY *entry = X509_NAME_get_entry(xname, i);
yanbzhu08ce6ab2015-12-02 13:01:29 -05001993
Emmanuel Hocdetd294aea2016-05-13 11:14:06 +02001994 if (ASN1_STRING_to_UTF8((unsigned char **)&str, entry->value) >= 0) {
1995 /* Important line is here */
1996 ssl_sock_populate_sni_keytypes_hplr(str, &sni_keytypes_map, n);
yanbzhu08ce6ab2015-12-02 13:01:29 -05001997
Emmanuel Hocdetd294aea2016-05-13 11:14:06 +02001998 OPENSSL_free(str);
1999 str = NULL;
2000 }
yanbzhu08ce6ab2015-12-02 13:01:29 -05002001 }
yanbzhu08ce6ab2015-12-02 13:01:29 -05002002
Emmanuel Hocdetd294aea2016-05-13 11:14:06 +02002003 /* Do the above logic for each SAN */
yanbzhu08ce6ab2015-12-02 13:01:29 -05002004#ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME
Emmanuel Hocdetd294aea2016-05-13 11:14:06 +02002005 names = X509_get_ext_d2i(certs_and_keys[n].cert, NID_subject_alt_name, NULL, NULL);
2006 if (names) {
2007 for (i = 0; i < sk_GENERAL_NAME_num(names); i++) {
2008 GENERAL_NAME *name = sk_GENERAL_NAME_value(names, i);
yanbzhu08ce6ab2015-12-02 13:01:29 -05002009
Emmanuel Hocdetd294aea2016-05-13 11:14:06 +02002010 if (name->type == GEN_DNS) {
2011 if (ASN1_STRING_to_UTF8((unsigned char **)&str, name->d.dNSName) >= 0) {
2012 /* Important line is here */
2013 ssl_sock_populate_sni_keytypes_hplr(str, &sni_keytypes_map, n);
yanbzhu08ce6ab2015-12-02 13:01:29 -05002014
Emmanuel Hocdetd294aea2016-05-13 11:14:06 +02002015 OPENSSL_free(str);
2016 str = NULL;
2017 }
yanbzhu08ce6ab2015-12-02 13:01:29 -05002018 }
2019 }
2020 }
2021 }
2022#endif /* SSL_CTRL_SET_TLSEXT_HOSTNAME */
2023 }
2024
2025 /* If no files found, return error */
2026 if (eb_is_empty(&sni_keytypes_map)) {
2027 memprintf(err, "%sunable to load SSL certificate file '%s' file does not exist.\n",
2028 err && *err ? *err : "", path);
2029 rv = 1;
2030 goto end;
2031 }
2032
2033 /* We now have a map of CN/SAN to keytypes that are loaded in
2034 * Iterate through the map to create the SSL_CTX's (if needed)
2035 * and add each CTX to the SNI tree
2036 *
2037 * Some math here:
2038 * There are 2^n - 1 possibile combinations, each unique
2039 * combination is denoted by the key in the map. Each key
2040 * has a value between 1 and 2^n - 1. Conveniently, the array
2041 * of SSL_CTX* is sized 2^n. So, we can simply use the i'th
2042 * entry in the array to correspond to the unique combo (key)
2043 * associated with i. This unique key combo (i) will be associated
2044 * with combos[i-1]
2045 */
2046
2047 node = ebmb_first(&sni_keytypes_map);
2048 while (node) {
2049 SSL_CTX *cur_ctx;
2050
2051 str = (char *)container_of(node, struct sni_keytype, name)->name.key;
2052 i = container_of(node, struct sni_keytype, name)->keytypes;
2053 cur_ctx = key_combos[i-1].ctx;
2054
2055 if (cur_ctx == NULL) {
2056 /* need to create SSL_CTX */
2057 cur_ctx = SSL_CTX_new(SSLv23_server_method());
2058 if (cur_ctx == NULL) {
2059 memprintf(err, "%sunable to allocate SSL context.\n",
2060 err && *err ? *err : "");
2061 rv = 1;
2062 goto end;
2063 }
2064
yanbzhube2774d2015-12-10 15:07:30 -05002065 /* Load all required certs/keys/chains/OCSPs info into SSL_CTX */
yanbzhu08ce6ab2015-12-02 13:01:29 -05002066 for (n = 0; n < SSL_SOCK_NUM_KEYTYPES; n++) {
2067 if (i & (1<<n)) {
2068 /* Key combo contains ckch[n] */
2069 snprintf(trash.str, trash.size, "%s.%s", path, SSL_SOCK_KEYTYPE_NAMES[n]);
2070 if (ssl_sock_put_ckch_into_ctx(trash.str, &certs_and_keys[n], cur_ctx, err) != 0) {
2071 SSL_CTX_free(cur_ctx);
2072 rv = 1;
2073 goto end;
2074 }
yanbzhube2774d2015-12-10 15:07:30 -05002075
2076#if (defined SSL_CTRL_SET_TLSEXT_STATUS_REQ_CB && !defined OPENSSL_NO_OCSP)
2077 /* Load OCSP Info into context */
2078 if (ssl_sock_load_ocsp(cur_ctx, trash.str) < 0) {
2079 if (err)
2080 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",
2081 *err ? *err : "", path);
2082 SSL_CTX_free(cur_ctx);
2083 rv = 1;
2084 goto end;
2085 }
2086#endif
yanbzhu08ce6ab2015-12-02 13:01:29 -05002087 }
2088 }
2089
2090 /* Load DH params into the ctx to support DHE keys */
2091#ifndef OPENSSL_NO_DH
2092 if (ssl_dh_ptr_index >= 0)
2093 SSL_CTX_set_ex_data(cur_ctx, ssl_dh_ptr_index, NULL);
2094
2095 rv = ssl_sock_load_dh_params(cur_ctx, NULL);
2096 if (rv < 0) {
2097 if (err)
2098 memprintf(err, "%sunable to load DH parameters from file '%s'.\n",
2099 *err ? *err : "", path);
2100 rv = 1;
2101 goto end;
2102 }
2103#endif
2104
2105 /* Update key_combos */
2106 key_combos[i-1].ctx = cur_ctx;
2107 }
2108
2109 /* Update SNI Tree */
Emmanuel Hocdetd294aea2016-05-13 11:14:06 +02002110 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 -05002111 node = ebmb_next(node);
2112 }
2113
2114
2115 /* Mark a default context if none exists, using the ctx that has the most shared keys */
2116 if (!bind_conf->default_ctx) {
2117 for (i = SSL_SOCK_POSSIBLE_KT_COMBOS - 1; i >= 0; i--) {
2118 if (key_combos[i].ctx) {
2119 bind_conf->default_ctx = key_combos[i].ctx;
2120 break;
2121 }
2122 }
2123 }
2124
2125end:
2126
2127 if (names)
2128 sk_GENERAL_NAME_pop_free(names, GENERAL_NAME_free);
2129
2130 for (n = 0; n < SSL_SOCK_NUM_KEYTYPES; n++)
2131 ssl_sock_free_cert_key_and_chain_contents(&certs_and_keys[n]);
2132
2133 node = ebmb_first(&sni_keytypes_map);
2134 while (node) {
2135 next = ebmb_next(node);
2136 ebmb_delete(node);
2137 node = next;
2138 }
2139
2140 return rv;
2141}
2142#else
2143/* This is a dummy, that just logs an error and returns error */
Emmanuel Hocdetd294aea2016-05-13 11:14:06 +02002144static 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 -05002145{
2146 memprintf(err, "%sunable to stat SSL certificate from file '%s' : %s.\n",
2147 err && *err ? *err : "", path, strerror(errno));
2148 return 1;
2149}
2150
yanbzhu488a4d22015-12-01 15:16:07 -05002151#endif /* #if OPENSSL_VERSION_NUMBER >= 0x1000200fL: Support for loading multiple certs into a single SSL_CTX */
2152
Emeric Brunfc0421f2012-09-07 17:30:07 +02002153/* Loads a certificate key and CA chain from a file. Returns 0 on error, -1 if
2154 * an early error happens and the caller must call SSL_CTX_free() by itelf.
2155 */
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +02002156static 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 +02002157{
2158 BIO *in;
2159 X509 *x = NULL, *ca;
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +02002160 int i, err;
Emeric Brunfc0421f2012-09-07 17:30:07 +02002161 int ret = -1;
2162 int order = 0;
2163 X509_NAME *xname;
2164 char *str;
Emeric Brunfc0421f2012-09-07 17:30:07 +02002165#ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME
2166 STACK_OF(GENERAL_NAME) *names;
2167#endif
2168
2169 in = BIO_new(BIO_s_file());
2170 if (in == NULL)
2171 goto end;
2172
2173 if (BIO_read_filename(in, file) <= 0)
2174 goto end;
2175
2176 x = PEM_read_bio_X509_AUX(in, NULL, ctx->default_passwd_callback, ctx->default_passwd_callback_userdata);
2177 if (x == NULL)
2178 goto end;
2179
Emeric Brun50bcecc2013-04-22 13:05:23 +02002180 if (fcount) {
2181 while (fcount--)
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +02002182 order = ssl_sock_add_cert_sni(ctx, s, sni_filter[fcount], order);
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01002183 }
2184 else {
Emeric Brunfc0421f2012-09-07 17:30:07 +02002185#ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01002186 names = X509_get_ext_d2i(x, NID_subject_alt_name, NULL, NULL);
2187 if (names) {
2188 for (i = 0; i < sk_GENERAL_NAME_num(names); i++) {
2189 GENERAL_NAME *name = sk_GENERAL_NAME_value(names, i);
2190 if (name->type == GEN_DNS) {
2191 if (ASN1_STRING_to_UTF8((unsigned char **)&str, name->d.dNSName) >= 0) {
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +02002192 order = ssl_sock_add_cert_sni(ctx, s, str, order);
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01002193 OPENSSL_free(str);
Emeric Brunfc0421f2012-09-07 17:30:07 +02002194 }
Emeric Brunfc0421f2012-09-07 17:30:07 +02002195 }
2196 }
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01002197 sk_GENERAL_NAME_pop_free(names, GENERAL_NAME_free);
Emeric Brunfc0421f2012-09-07 17:30:07 +02002198 }
Emeric Brunfc0421f2012-09-07 17:30:07 +02002199#endif /* SSL_CTRL_SET_TLSEXT_HOSTNAME */
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01002200 xname = X509_get_subject_name(x);
2201 i = -1;
2202 while ((i = X509_NAME_get_index_by_NID(xname, NID_commonName, i)) != -1) {
2203 X509_NAME_ENTRY *entry = X509_NAME_get_entry(xname, i);
2204 if (ASN1_STRING_to_UTF8((unsigned char **)&str, entry->value) >= 0) {
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +02002205 order = ssl_sock_add_cert_sni(ctx, s, str, order);
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01002206 OPENSSL_free(str);
Emeric Brunfc0421f2012-09-07 17:30:07 +02002207 }
Emeric Brunfc0421f2012-09-07 17:30:07 +02002208 }
2209 }
2210
2211 ret = 0; /* the caller must not free the SSL_CTX argument anymore */
2212 if (!SSL_CTX_use_certificate(ctx, x))
2213 goto end;
2214
2215 if (ctx->extra_certs != NULL) {
2216 sk_X509_pop_free(ctx->extra_certs, X509_free);
2217 ctx->extra_certs = NULL;
2218 }
2219
2220 while ((ca = PEM_read_bio_X509(in, NULL, ctx->default_passwd_callback, ctx->default_passwd_callback_userdata))) {
2221 if (!SSL_CTX_add_extra_chain_cert(ctx, ca)) {
2222 X509_free(ca);
2223 goto end;
2224 }
2225 }
2226
2227 err = ERR_get_error();
2228 if (!err || (ERR_GET_LIB(err) == ERR_LIB_PEM && ERR_GET_REASON(err) == PEM_R_NO_START_LINE)) {
2229 /* we successfully reached the last cert in the file */
2230 ret = 1;
2231 }
2232 ERR_clear_error();
2233
2234end:
2235 if (x)
2236 X509_free(x);
2237
2238 if (in)
2239 BIO_free(in);
2240
2241 return ret;
2242}
2243
Emeric Brun50bcecc2013-04-22 13:05:23 +02002244static 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 +02002245{
2246 int ret;
2247 SSL_CTX *ctx;
2248
2249 ctx = SSL_CTX_new(SSLv23_server_method());
2250 if (!ctx) {
Willy Tarreaueb6cead2012-09-20 19:43:14 +02002251 memprintf(err, "%sunable to allocate SSL context for cert '%s'.\n",
2252 err && *err ? *err : "", path);
Emeric Brunfc0421f2012-09-07 17:30:07 +02002253 return 1;
2254 }
2255
2256 if (SSL_CTX_use_PrivateKey_file(ctx, path, SSL_FILETYPE_PEM) <= 0) {
Willy Tarreaueb6cead2012-09-20 19:43:14 +02002257 memprintf(err, "%sunable to load SSL private key from PEM file '%s'.\n",
2258 err && *err ? *err : "", path);
Emeric Brunfc0421f2012-09-07 17:30:07 +02002259 SSL_CTX_free(ctx);
2260 return 1;
2261 }
2262
Emeric Brun50bcecc2013-04-22 13:05:23 +02002263 ret = ssl_sock_load_cert_chain_file(ctx, path, bind_conf, sni_filter, fcount);
Emeric Brunfc0421f2012-09-07 17:30:07 +02002264 if (ret <= 0) {
Willy Tarreaueb6cead2012-09-20 19:43:14 +02002265 memprintf(err, "%sunable to load SSL certificate from PEM file '%s'.\n",
2266 err && *err ? *err : "", path);
Emeric Brunfc0421f2012-09-07 17:30:07 +02002267 if (ret < 0) /* serious error, must do that ourselves */
2268 SSL_CTX_free(ctx);
2269 return 1;
2270 }
Emeric Brun61694ab2012-10-26 13:35:33 +02002271
2272 if (SSL_CTX_check_private_key(ctx) <= 0) {
2273 memprintf(err, "%sinconsistencies between private key and certificate loaded from PEM file '%s'.\n",
2274 err && *err ? *err : "", path);
2275 return 1;
2276 }
2277
Emeric Brunfc0421f2012-09-07 17:30:07 +02002278 /* we must not free the SSL_CTX anymore below, since it's already in
2279 * the tree, so it will be discovered and cleaned in time.
2280 */
Emeric Bruna4bcd9a2012-09-20 16:19:02 +02002281#ifndef OPENSSL_NO_DH
Remi Gacogne4f902b82015-05-28 16:23:00 +02002282 /* store a NULL pointer to indicate we have not yet loaded
2283 a custom DH param file */
2284 if (ssl_dh_ptr_index >= 0) {
2285 SSL_CTX_set_ex_data(ctx, ssl_dh_ptr_index, NULL);
2286 }
2287
Emeric Bruna4bcd9a2012-09-20 16:19:02 +02002288 ret = ssl_sock_load_dh_params(ctx, path);
2289 if (ret < 0) {
2290 if (err)
2291 memprintf(err, "%sunable to load DH parameters from file '%s'.\n",
2292 *err ? *err : "", path);
2293 return 1;
2294 }
2295#endif
2296
Lukas Tribuse4e30f72014-12-09 16:32:51 +01002297#if (defined SSL_CTRL_SET_TLSEXT_STATUS_REQ_CB && !defined OPENSSL_NO_OCSP)
Emeric Brun4147b2e2014-06-16 18:36:30 +02002298 ret = ssl_sock_load_ocsp(ctx, path);
2299 if (ret < 0) {
2300 if (err)
2301 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",
2302 *err ? *err : "", path);
2303 return 1;
2304 }
2305#endif
2306
Daniel Jakots54ffb912015-11-06 20:02:41 +01002307#if (OPENSSL_VERSION_NUMBER >= 0x1000200fL && !defined OPENSSL_NO_TLSEXT && !defined OPENSSL_IS_BORINGSSL && !defined LIBRESSL_VERSION_NUMBER)
Janusz Dziemidowicz2c701b52015-03-07 23:03:59 +01002308 if (sctl_ex_index >= 0) {
2309 ret = ssl_sock_load_sctl(ctx, path);
2310 if (ret < 0) {
2311 if (err)
2312 memprintf(err, "%s '%s.sctl' is present but cannot be read or parsed'.\n",
2313 *err ? *err : "", path);
2314 return 1;
2315 }
2316 }
2317#endif
2318
Emeric Brunfc0421f2012-09-07 17:30:07 +02002319#ifndef SSL_CTRL_SET_TLSEXT_HOSTNAME
Willy Tarreau2a65ff02012-09-13 17:54:29 +02002320 if (bind_conf->default_ctx) {
Willy Tarreaueb6cead2012-09-20 19:43:14 +02002321 memprintf(err, "%sthis version of openssl cannot load multiple SSL certificates.\n",
2322 err && *err ? *err : "");
Emeric Brunfc0421f2012-09-07 17:30:07 +02002323 return 1;
2324 }
2325#endif
Willy Tarreau2a65ff02012-09-13 17:54:29 +02002326 if (!bind_conf->default_ctx)
2327 bind_conf->default_ctx = ctx;
Emeric Brunfc0421f2012-09-07 17:30:07 +02002328
2329 return 0;
2330}
2331
Willy Tarreau79eeafa2012-09-14 07:53:05 +02002332int ssl_sock_load_cert(char *path, struct bind_conf *bind_conf, struct proxy *curproxy, char **err)
Emeric Brunfc0421f2012-09-07 17:30:07 +02002333{
Cyril Bonté3180f7b2015-01-25 00:16:08 +01002334 struct dirent **de_list;
2335 int i, n;
Emeric Brunfc0421f2012-09-07 17:30:07 +02002336 DIR *dir;
2337 struct stat buf;
Willy Tarreauee2663b2012-12-06 11:36:59 +01002338 char *end;
2339 char fp[MAXPATHLEN+1];
Emeric Brunfc0421f2012-09-07 17:30:07 +02002340 int cfgerr = 0;
yanbzhu63ea8462015-12-09 13:35:14 -05002341#if OPENSSL_VERSION_NUMBER >= 0x1000200fL
2342 int is_bundle;
2343 int j;
2344#endif
Emeric Brunfc0421f2012-09-07 17:30:07 +02002345
yanbzhu08ce6ab2015-12-02 13:01:29 -05002346 if (stat(path, &buf) == 0) {
2347 dir = opendir(path);
2348 if (!dir)
2349 return ssl_sock_load_cert_file(path, bind_conf, curproxy, NULL, 0, err);
Emeric Brunfc0421f2012-09-07 17:30:07 +02002350
yanbzhu08ce6ab2015-12-02 13:01:29 -05002351 /* strip trailing slashes, including first one */
2352 for (end = path + strlen(path) - 1; end >= path && *end == '/'; end--)
2353 *end = 0;
Emeric Brunfc0421f2012-09-07 17:30:07 +02002354
yanbzhu08ce6ab2015-12-02 13:01:29 -05002355 n = scandir(path, &de_list, 0, alphasort);
2356 if (n < 0) {
2357 memprintf(err, "%sunable to scan directory '%s' : %s.\n",
2358 err && *err ? *err : "", path, strerror(errno));
2359 cfgerr++;
2360 }
2361 else {
2362 for (i = 0; i < n; i++) {
2363 struct dirent *de = de_list[i];
Emeric Brun2aab7222014-06-18 18:15:09 +02002364
yanbzhu08ce6ab2015-12-02 13:01:29 -05002365 end = strrchr(de->d_name, '.');
2366 if (end && (!strcmp(end, ".issuer") || !strcmp(end, ".ocsp") || !strcmp(end, ".sctl")))
2367 goto ignore_entry;
Cyril Bonté3180f7b2015-01-25 00:16:08 +01002368
yanbzhu08ce6ab2015-12-02 13:01:29 -05002369 snprintf(fp, sizeof(fp), "%s/%s", path, de->d_name);
2370 if (stat(fp, &buf) != 0) {
2371 memprintf(err, "%sunable to stat SSL certificate from file '%s' : %s.\n",
2372 err && *err ? *err : "", fp, strerror(errno));
2373 cfgerr++;
2374 goto ignore_entry;
2375 }
2376 if (!S_ISREG(buf.st_mode))
2377 goto ignore_entry;
yanbzhu63ea8462015-12-09 13:35:14 -05002378
2379#if OPENSSL_VERSION_NUMBER >= 0x1000200fL
2380 is_bundle = 0;
2381 /* Check if current entry in directory is part of a multi-cert bundle */
2382
2383 if (end) {
2384 for (j = 0; j < SSL_SOCK_NUM_KEYTYPES; j++) {
2385 if (!strcmp(end + 1, SSL_SOCK_KEYTYPE_NAMES[j])) {
2386 is_bundle = 1;
2387 break;
2388 }
2389 }
2390
2391 if (is_bundle) {
2392 char dp[MAXPATHLEN+1] = {0}; /* this will be the filename w/o the keytype */
2393 int dp_len;
2394
2395 dp_len = end - de->d_name;
2396 snprintf(dp, dp_len + 1, "%s", de->d_name);
2397
2398 /* increment i and free de until we get to a non-bundle cert
2399 * Note here that we look at de_list[i + 1] before freeing de
2400 * this is important since ignore_entry will free de
2401 */
2402 while (i + 1 < n && !strncmp(de_list[i + 1]->d_name, dp, dp_len)) {
2403 free(de);
2404 i++;
2405 de = de_list[i];
2406 }
2407
2408 snprintf(fp, sizeof(fp), "%s/%s", path, dp);
Emmanuel Hocdetd294aea2016-05-13 11:14:06 +02002409 ssl_sock_load_multi_cert(fp, bind_conf, curproxy, NULL, 0, err);
yanbzhu63ea8462015-12-09 13:35:14 -05002410
2411 /* Successfully processed the bundle */
2412 goto ignore_entry;
2413 }
2414 }
2415
2416#endif
yanbzhu08ce6ab2015-12-02 13:01:29 -05002417 cfgerr += ssl_sock_load_cert_file(fp, bind_conf, curproxy, NULL, 0, err);
2418ignore_entry:
2419 free(de);
Cyril Bonté3180f7b2015-01-25 00:16:08 +01002420 }
yanbzhu08ce6ab2015-12-02 13:01:29 -05002421 free(de_list);
Emeric Brunfc0421f2012-09-07 17:30:07 +02002422 }
yanbzhu08ce6ab2015-12-02 13:01:29 -05002423 closedir(dir);
2424 return cfgerr;
Emeric Brunfc0421f2012-09-07 17:30:07 +02002425 }
yanbzhu08ce6ab2015-12-02 13:01:29 -05002426
Emmanuel Hocdetd294aea2016-05-13 11:14:06 +02002427 cfgerr = ssl_sock_load_multi_cert(path, bind_conf, curproxy, NULL, 0, err);
yanbzhu08ce6ab2015-12-02 13:01:29 -05002428
Emeric Brunfc0421f2012-09-07 17:30:07 +02002429 return cfgerr;
2430}
2431
Thierry Fournier383085f2013-01-24 14:15:43 +01002432/* Make sure openssl opens /dev/urandom before the chroot. The work is only
2433 * done once. Zero is returned if the operation fails. No error is returned
2434 * if the random is said as not implemented, because we expect that openssl
2435 * will use another method once needed.
2436 */
2437static int ssl_initialize_random()
2438{
2439 unsigned char random;
2440 static int random_initialized = 0;
2441
2442 if (!random_initialized && RAND_bytes(&random, 1) != 0)
2443 random_initialized = 1;
2444
2445 return random_initialized;
2446}
2447
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01002448int ssl_sock_load_cert_list_file(char *file, struct bind_conf *bind_conf, struct proxy *curproxy, char **err)
2449{
Emmanuel Hocdet5e0e6e42016-05-13 11:18:50 +02002450 char thisline[LINESIZE*CRTLIST_FACTOR];
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01002451 FILE *f;
yanbzhu1b04e5b2015-12-02 13:54:14 -05002452 struct stat buf;
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01002453 int linenum = 0;
2454 int cfgerr = 0;
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01002455
Willy Tarreauad1731d2013-04-02 17:35:58 +02002456 if ((f = fopen(file, "r")) == NULL) {
2457 memprintf(err, "cannot open file '%s' : %s", file, strerror(errno));
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01002458 return 1;
Willy Tarreauad1731d2013-04-02 17:35:58 +02002459 }
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01002460
2461 while (fgets(thisline, sizeof(thisline), f) != NULL) {
2462 int arg;
Emeric Brun50bcecc2013-04-22 13:05:23 +02002463 int newarg;
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01002464 char *end;
Emmanuel Hocdet5e0e6e42016-05-13 11:18:50 +02002465 char *args[MAX_LINE_ARGS*CRTLIST_FACTOR + 1];
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01002466 char *line = thisline;
2467
2468 linenum++;
2469 end = line + strlen(line);
2470 if (end-line == sizeof(thisline)-1 && *(end-1) != '\n') {
2471 /* Check if we reached the limit and the last char is not \n.
2472 * Watch out for the last line without the terminating '\n'!
2473 */
Willy Tarreauad1731d2013-04-02 17:35:58 +02002474 memprintf(err, "line %d too long in file '%s', limit is %d characters",
2475 linenum, file, (int)sizeof(thisline)-1);
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01002476 cfgerr = 1;
Willy Tarreauad1731d2013-04-02 17:35:58 +02002477 break;
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01002478 }
2479
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01002480 arg = 0;
Emeric Brun50bcecc2013-04-22 13:05:23 +02002481 newarg = 1;
2482 while (*line) {
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01002483 if (*line == '#' || *line == '\n' || *line == '\r') {
2484 /* end of string, end of loop */
2485 *line = 0;
2486 break;
2487 }
2488 else if (isspace(*line)) {
Emeric Brun50bcecc2013-04-22 13:05:23 +02002489 newarg = 1;
2490 *line = 0;
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01002491 }
Emeric Brun50bcecc2013-04-22 13:05:23 +02002492 else if (newarg) {
Emmanuel Hocdet5e0e6e42016-05-13 11:18:50 +02002493 if (arg == MAX_LINE_ARGS*CRTLIST_FACTOR) {
Emeric Brun50bcecc2013-04-22 13:05:23 +02002494 memprintf(err, "too many args on line %d in file '%s'.",
2495 linenum, file);
2496 cfgerr = 1;
2497 break;
2498 }
2499 newarg = 0;
2500 args[arg++] = line;
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01002501 }
Emeric Brun50bcecc2013-04-22 13:05:23 +02002502 line++;
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01002503 }
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +02002504 if (cfgerr)
2505 break;
Willy Tarreauad1731d2013-04-02 17:35:58 +02002506
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01002507 /* empty line */
Emeric Brun50bcecc2013-04-22 13:05:23 +02002508 if (!arg)
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01002509 continue;
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01002510
yanbzhu1b04e5b2015-12-02 13:54:14 -05002511 if (stat(args[0], &buf) == 0) {
2512 cfgerr = ssl_sock_load_cert_file(args[0], bind_conf, curproxy, &args[1], arg-1, err);
2513 } else {
Emmanuel Hocdetd294aea2016-05-13 11:14:06 +02002514 cfgerr = ssl_sock_load_multi_cert(args[0], bind_conf, curproxy, &args[1], arg-1, err);
yanbzhu1b04e5b2015-12-02 13:54:14 -05002515 }
2516
Willy Tarreauad1731d2013-04-02 17:35:58 +02002517 if (cfgerr) {
2518 memprintf(err, "error processing line %d in file '%s' : %s", linenum, file, *err);
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01002519 break;
Willy Tarreauad1731d2013-04-02 17:35:58 +02002520 }
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01002521 }
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01002522 fclose(f);
2523 return cfgerr;
2524}
2525
Emeric Brunfc0421f2012-09-07 17:30:07 +02002526#ifndef SSL_OP_CIPHER_SERVER_PREFERENCE /* needs OpenSSL >= 0.9.7 */
2527#define SSL_OP_CIPHER_SERVER_PREFERENCE 0
2528#endif
2529
2530#ifndef SSL_OP_NO_SESSION_RESUMPTION_ON_RENEGOTIATION /* needs OpenSSL >= 0.9.7 */
2531#define SSL_OP_NO_SESSION_RESUMPTION_ON_RENEGOTIATION 0
Willy Tarreau7d588ee2012-11-26 18:47:31 +01002532#define SSL_renegotiate_pending(arg) 0
Emeric Brunfc0421f2012-09-07 17:30:07 +02002533#endif
Emeric Brun2b58d042012-09-20 17:10:03 +02002534#ifndef SSL_OP_SINGLE_ECDH_USE /* needs OpenSSL >= 0.9.8 */
2535#define SSL_OP_SINGLE_ECDH_USE 0
2536#endif
Emeric Brun2d0c4822012-10-02 13:45:20 +02002537#ifndef SSL_OP_NO_TICKET /* needs OpenSSL >= 0.9.8 */
2538#define SSL_OP_NO_TICKET 0
2539#endif
Emeric Brunfc0421f2012-09-07 17:30:07 +02002540#ifndef SSL_OP_NO_COMPRESSION /* needs OpenSSL >= 0.9.9 */
2541#define SSL_OP_NO_COMPRESSION 0
2542#endif
Emeric Brunc0ff4922012-09-28 19:37:02 +02002543#ifndef SSL_OP_NO_TLSv1_1 /* needs OpenSSL >= 1.0.1 */
2544#define SSL_OP_NO_TLSv1_1 0
2545#endif
2546#ifndef SSL_OP_NO_TLSv1_2 /* needs OpenSSL >= 1.0.1 */
2547#define SSL_OP_NO_TLSv1_2 0
2548#endif
Emeric Bruna4bcd9a2012-09-20 16:19:02 +02002549#ifndef SSL_OP_SINGLE_DH_USE /* needs OpenSSL >= 0.9.6 */
2550#define SSL_OP_SINGLE_DH_USE 0
2551#endif
Emeric Brun2b58d042012-09-20 17:10:03 +02002552#ifndef SSL_OP_SINGLE_ECDH_USE /* needs OpenSSL >= 1.0.0 */
2553#define SSL_OP_SINGLE_ECDH_USE 0
2554#endif
Emeric Brunfc0421f2012-09-07 17:30:07 +02002555#ifndef SSL_MODE_RELEASE_BUFFERS /* needs OpenSSL >= 1.0.0 */
2556#define SSL_MODE_RELEASE_BUFFERS 0
2557#endif
Willy Tarreau396a1862014-11-13 14:06:52 +01002558#ifndef SSL_MODE_SMALL_BUFFERS /* needs small_records.patch */
2559#define SSL_MODE_SMALL_BUFFERS 0
2560#endif
Remi Gacognef46cd6e2014-06-12 14:58:40 +02002561
Willy Tarreau2a65ff02012-09-13 17:54:29 +02002562int ssl_sock_prepare_ctx(struct bind_conf *bind_conf, SSL_CTX *ctx, struct proxy *curproxy)
Emeric Brunfc0421f2012-09-07 17:30:07 +02002563{
2564 int cfgerr = 0;
Emeric Brun850efd52014-01-29 12:24:34 +01002565 int verify = SSL_VERIFY_NONE;
Remi Gacogneaf5c3da2014-05-19 10:29:58 +02002566 long ssloptions =
Emeric Brunfc0421f2012-09-07 17:30:07 +02002567 SSL_OP_ALL | /* all known workarounds for bugs */
2568 SSL_OP_NO_SSLv2 |
2569 SSL_OP_NO_COMPRESSION |
Emeric Bruna4bcd9a2012-09-20 16:19:02 +02002570 SSL_OP_SINGLE_DH_USE |
Emeric Brun2b58d042012-09-20 17:10:03 +02002571 SSL_OP_SINGLE_ECDH_USE |
Emeric Brun3c4bc6e2012-10-04 18:44:19 +02002572 SSL_OP_NO_SESSION_RESUMPTION_ON_RENEGOTIATION |
2573 SSL_OP_CIPHER_SERVER_PREFERENCE;
Remi Gacogneaf5c3da2014-05-19 10:29:58 +02002574 long sslmode =
Emeric Brunfc0421f2012-09-07 17:30:07 +02002575 SSL_MODE_ENABLE_PARTIAL_WRITE |
2576 SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER |
Willy Tarreau396a1862014-11-13 14:06:52 +01002577 SSL_MODE_RELEASE_BUFFERS |
2578 SSL_MODE_SMALL_BUFFERS;
Remi Gacognef46cd6e2014-06-12 14:58:40 +02002579 STACK_OF(SSL_CIPHER) * ciphers = NULL;
Willy Tarreaua616ba62014-10-26 06:49:19 +01002580 SSL_CIPHER * cipher = NULL;
Remi Gacognec1eab8c2014-06-12 18:20:11 +02002581 char cipher_description[128];
2582 /* The description of ciphers using an Ephemeral Diffie Hellman key exchange
2583 contains " Kx=DH " or " Kx=DH(". Beware of " Kx=DH/",
2584 which is not ephemeral DH. */
2585 const char dhe_description[] = " Kx=DH ";
2586 const char dhe_export_description[] = " Kx=DH(";
Remi Gacognef46cd6e2014-06-12 14:58:40 +02002587 int idx = 0;
2588 int dhe_found = 0;
Remi Gacogne23d5d372014-10-10 17:04:26 +02002589 SSL *ssl = NULL;
Emeric Brunfc0421f2012-09-07 17:30:07 +02002590
Thierry Fournier383085f2013-01-24 14:15:43 +01002591 /* Make sure openssl opens /dev/urandom before the chroot */
2592 if (!ssl_initialize_random()) {
2593 Alert("OpenSSL random data generator initialization failed.\n");
2594 cfgerr++;
2595 }
2596
Emeric Brun89675492012-10-05 13:48:26 +02002597 if (bind_conf->ssl_options & BC_SSL_O_NO_SSLV3)
Emeric Brunfc0421f2012-09-07 17:30:07 +02002598 ssloptions |= SSL_OP_NO_SSLv3;
Emeric Brun89675492012-10-05 13:48:26 +02002599 if (bind_conf->ssl_options & BC_SSL_O_NO_TLSV10)
Emeric Brunfc0421f2012-09-07 17:30:07 +02002600 ssloptions |= SSL_OP_NO_TLSv1;
Emeric Brun89675492012-10-05 13:48:26 +02002601 if (bind_conf->ssl_options & BC_SSL_O_NO_TLSV11)
Emeric Brunc0ff4922012-09-28 19:37:02 +02002602 ssloptions |= SSL_OP_NO_TLSv1_1;
Emeric Brun89675492012-10-05 13:48:26 +02002603 if (bind_conf->ssl_options & BC_SSL_O_NO_TLSV12)
Emeric Brunc0ff4922012-09-28 19:37:02 +02002604 ssloptions |= SSL_OP_NO_TLSv1_2;
Emeric Brun89675492012-10-05 13:48:26 +02002605 if (bind_conf->ssl_options & BC_SSL_O_NO_TLS_TICKETS)
Emeric Brun2d0c4822012-10-02 13:45:20 +02002606 ssloptions |= SSL_OP_NO_TICKET;
Jérémie Courrèges-Anglas17c3f622015-07-25 16:50:52 -06002607 if (bind_conf->ssl_options & BC_SSL_O_USE_SSLV3) {
2608#ifndef OPENSSL_NO_SSL3
Emeric Brun2cb7ae52012-10-05 14:14:21 +02002609 SSL_CTX_set_ssl_version(ctx, SSLv3_server_method());
Jérémie Courrèges-Anglas17c3f622015-07-25 16:50:52 -06002610#else
2611 Alert("SSLv3 support requested but unavailable.\n");
2612 cfgerr++;
2613#endif
2614 }
Emeric Brun2cb7ae52012-10-05 14:14:21 +02002615 if (bind_conf->ssl_options & BC_SSL_O_USE_TLSV10)
2616 SSL_CTX_set_ssl_version(ctx, TLSv1_server_method());
2617#if SSL_OP_NO_TLSv1_1
2618 if (bind_conf->ssl_options & BC_SSL_O_USE_TLSV11)
2619 SSL_CTX_set_ssl_version(ctx, TLSv1_1_server_method());
2620#endif
2621#if SSL_OP_NO_TLSv1_2
2622 if (bind_conf->ssl_options & BC_SSL_O_USE_TLSV12)
2623 SSL_CTX_set_ssl_version(ctx, TLSv1_2_server_method());
2624#endif
Emeric Brunfc0421f2012-09-07 17:30:07 +02002625
2626 SSL_CTX_set_options(ctx, ssloptions);
2627 SSL_CTX_set_mode(ctx, sslmode);
Emeric Brun850efd52014-01-29 12:24:34 +01002628 switch (bind_conf->verify) {
2629 case SSL_SOCK_VERIFY_NONE:
2630 verify = SSL_VERIFY_NONE;
2631 break;
2632 case SSL_SOCK_VERIFY_OPTIONAL:
2633 verify = SSL_VERIFY_PEER;
2634 break;
2635 case SSL_SOCK_VERIFY_REQUIRED:
2636 verify = SSL_VERIFY_PEER|SSL_VERIFY_FAIL_IF_NO_PEER_CERT;
2637 break;
2638 }
2639 SSL_CTX_set_verify(ctx, verify, ssl_sock_bind_verifycbk);
2640 if (verify & SSL_VERIFY_PEER) {
Emeric Brunfb510ea2012-10-05 12:00:26 +02002641 if (bind_conf->ca_file) {
Emeric Brund94b3fe2012-09-20 18:23:56 +02002642 /* load CAfile to verify */
Emeric Brunfb510ea2012-10-05 12:00:26 +02002643 if (!SSL_CTX_load_verify_locations(ctx, bind_conf->ca_file, NULL)) {
Emeric Brund94b3fe2012-09-20 18:23:56 +02002644 Alert("Proxy '%s': unable to load CA file '%s' for bind '%s' at [%s:%d].\n",
Emeric Brunfb510ea2012-10-05 12:00:26 +02002645 curproxy->id, bind_conf->ca_file, bind_conf->arg, bind_conf->file, bind_conf->line);
Emeric Brund94b3fe2012-09-20 18:23:56 +02002646 cfgerr++;
2647 }
2648 /* set CA names fo client cert request, function returns void */
Emeric Brunfb510ea2012-10-05 12:00:26 +02002649 SSL_CTX_set_client_CA_list(ctx, SSL_load_client_CA_file(bind_conf->ca_file));
Emeric Brund94b3fe2012-09-20 18:23:56 +02002650 }
Emeric Brun850efd52014-01-29 12:24:34 +01002651 else {
2652 Alert("Proxy '%s': verify is enabled but no CA file specified for bind '%s' at [%s:%d].\n",
2653 curproxy->id, bind_conf->arg, bind_conf->file, bind_conf->line);
2654 cfgerr++;
2655 }
Emeric Brun051cdab2012-10-02 19:25:50 +02002656#ifdef X509_V_FLAG_CRL_CHECK
Emeric Brunfb510ea2012-10-05 12:00:26 +02002657 if (bind_conf->crl_file) {
Emeric Brund94b3fe2012-09-20 18:23:56 +02002658 X509_STORE *store = SSL_CTX_get_cert_store(ctx);
2659
Emeric Brunfb510ea2012-10-05 12:00:26 +02002660 if (!store || !X509_STORE_load_locations(store, bind_conf->crl_file, NULL)) {
Emeric Brund94b3fe2012-09-20 18:23:56 +02002661 Alert("Proxy '%s': unable to configure CRL file '%s' for bind '%s' at [%s:%d].\n",
Alexander Rigbofc65af02015-04-07 14:02:16 +02002662 curproxy->id, bind_conf->crl_file, bind_conf->arg, bind_conf->file, bind_conf->line);
Emeric Brund94b3fe2012-09-20 18:23:56 +02002663 cfgerr++;
2664 }
Emeric Brun561e5742012-10-02 15:20:55 +02002665 else {
2666 X509_STORE_set_flags(store, X509_V_FLAG_CRL_CHECK|X509_V_FLAG_CRL_CHECK_ALL);
2667 }
Emeric Brund94b3fe2012-09-20 18:23:56 +02002668 }
Emeric Brun051cdab2012-10-02 19:25:50 +02002669#endif
Emeric Brun644cde02012-12-14 11:21:13 +01002670 ERR_clear_error();
Emeric Brund94b3fe2012-09-20 18:23:56 +02002671 }
Emeric Brunfc0421f2012-09-07 17:30:07 +02002672
Nenad Merdanovic05552d42015-02-27 19:56:49 +01002673#if (defined SSL_CTRL_SET_TLSEXT_TICKET_KEY_CB && TLS_TICKETS_NO > 0)
Nenad Merdanovic146defa2015-05-09 08:46:00 +02002674 if(bind_conf->keys_ref) {
Nenad Merdanovic05552d42015-02-27 19:56:49 +01002675 if (!SSL_CTX_set_tlsext_ticket_key_cb(ctx, ssl_tlsext_ticket_key_cb)) {
2676 Alert("Proxy '%s': unable to set callback for TLS ticket validation for bind '%s' at [%s:%d].\n",
2677 curproxy->id, bind_conf->arg, bind_conf->file, bind_conf->line);
2678 cfgerr++;
2679 }
2680 }
2681#endif
2682
Emeric Brun4f65bff2012-11-16 15:11:00 +01002683 if (global.tune.ssllifetime)
2684 SSL_CTX_set_timeout(ctx, global.tune.ssllifetime);
2685
Emeric Brunfc0421f2012-09-07 17:30:07 +02002686 shared_context_set_cache(ctx);
Willy Tarreau2a65ff02012-09-13 17:54:29 +02002687 if (bind_conf->ciphers &&
2688 !SSL_CTX_set_cipher_list(ctx, bind_conf->ciphers)) {
Emeric Brunfc0421f2012-09-07 17:30:07 +02002689 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 +02002690 curproxy->id, bind_conf->ciphers, bind_conf->arg, bind_conf->file, bind_conf->line);
Emeric Brunfc0421f2012-09-07 17:30:07 +02002691 cfgerr++;
2692 }
2693
Remi Gacogne47783ef2015-05-29 15:53:22 +02002694 /* If tune.ssl.default-dh-param has not been set,
2695 neither has ssl-default-dh-file and no static DH
2696 params were in the certificate file. */
Remi Gacogne4f902b82015-05-28 16:23:00 +02002697 if (global.tune.ssl_default_dh_param == 0 &&
Remi Gacogne47783ef2015-05-29 15:53:22 +02002698 global_dh == NULL &&
Remi Gacogne4f902b82015-05-28 16:23:00 +02002699 (ssl_dh_ptr_index == -1 ||
2700 SSL_CTX_get_ex_data(ctx, ssl_dh_ptr_index) == NULL)) {
Lukas Tribus90132722014-08-18 00:56:33 +02002701
Remi Gacogne23d5d372014-10-10 17:04:26 +02002702 ssl = SSL_new(ctx);
Remi Gacognef46cd6e2014-06-12 14:58:40 +02002703
Remi Gacogne23d5d372014-10-10 17:04:26 +02002704 if (ssl) {
2705 ciphers = SSL_get_ciphers(ssl);
2706
2707 if (ciphers) {
2708 for (idx = 0; idx < sk_SSL_CIPHER_num(ciphers); idx++) {
2709 cipher = sk_SSL_CIPHER_value(ciphers, idx);
2710 if (SSL_CIPHER_description(cipher, cipher_description, sizeof (cipher_description)) == cipher_description) {
2711 if (strstr(cipher_description, dhe_description) != NULL ||
2712 strstr(cipher_description, dhe_export_description) != NULL) {
2713 dhe_found = 1;
2714 break;
2715 }
Remi Gacognec1eab8c2014-06-12 18:20:11 +02002716 }
Remi Gacognef46cd6e2014-06-12 14:58:40 +02002717 }
2718 }
Remi Gacogne23d5d372014-10-10 17:04:26 +02002719 SSL_free(ssl);
2720 ssl = NULL;
Lukas Tribus90132722014-08-18 00:56:33 +02002721 }
Remi Gacognef46cd6e2014-06-12 14:58:40 +02002722
Lukas Tribus90132722014-08-18 00:56:33 +02002723 if (dhe_found) {
2724 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 +02002725 }
2726
2727 global.tune.ssl_default_dh_param = 1024;
2728 }
Remi Gacogne8de54152014-07-15 11:36:40 +02002729
2730#ifndef OPENSSL_NO_DH
2731 if (global.tune.ssl_default_dh_param >= 1024) {
2732 if (local_dh_1024 == NULL) {
2733 local_dh_1024 = ssl_get_dh_1024();
2734 }
2735 if (global.tune.ssl_default_dh_param >= 2048) {
2736 if (local_dh_2048 == NULL) {
2737 local_dh_2048 = ssl_get_dh_2048();
2738 }
2739 if (global.tune.ssl_default_dh_param >= 4096) {
2740 if (local_dh_4096 == NULL) {
2741 local_dh_4096 = ssl_get_dh_4096();
2742 }
Remi Gacogne8de54152014-07-15 11:36:40 +02002743 }
2744 }
2745 }
2746#endif /* OPENSSL_NO_DH */
Remi Gacognef46cd6e2014-06-12 14:58:40 +02002747
Emeric Brunfc0421f2012-09-07 17:30:07 +02002748 SSL_CTX_set_info_callback(ctx, ssl_sock_infocbk);
Willy Tarreau5cbe4ef2014-05-08 22:45:11 +02002749#if OPENSSL_VERSION_NUMBER >= 0x00907000L
Emeric Brun29f037d2014-04-25 19:05:36 +02002750 SSL_CTX_set_msg_callback(ctx, ssl_sock_msgcbk);
Willy Tarreau5cbe4ef2014-05-08 22:45:11 +02002751#endif
Emeric Brun29f037d2014-04-25 19:05:36 +02002752
Willy Tarreau6c9a3d52012-10-18 18:57:14 +02002753#ifdef OPENSSL_NPN_NEGOTIATED
2754 if (bind_conf->npn_str)
2755 SSL_CTX_set_next_protos_advertised_cb(ctx, ssl_sock_advertise_npn_protos, bind_conf);
2756#endif
Dirkjan Bussink48f1c4e2014-02-13 12:29:42 +01002757#ifdef TLSEXT_TYPE_application_layer_protocol_negotiation
Willy Tarreauab861d32013-04-02 02:30:41 +02002758 if (bind_conf->alpn_str)
Dirkjan Bussink48f1c4e2014-02-13 12:29:42 +01002759 SSL_CTX_set_alpn_select_cb(ctx, ssl_sock_advertise_alpn_protos, bind_conf);
Willy Tarreauab861d32013-04-02 02:30:41 +02002760#endif
Willy Tarreau6c9a3d52012-10-18 18:57:14 +02002761
Emeric Brunfc0421f2012-09-07 17:30:07 +02002762#ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME
2763 SSL_CTX_set_tlsext_servername_callback(ctx, ssl_sock_switchctx_cbk);
Willy Tarreau2a65ff02012-09-13 17:54:29 +02002764 SSL_CTX_set_tlsext_servername_arg(ctx, bind_conf);
Emeric Brunfc0421f2012-09-07 17:30:07 +02002765#endif
Emeric Brun2b58d042012-09-20 17:10:03 +02002766#if defined(SSL_CTX_set_tmp_ecdh) && !defined(OPENSSL_NO_ECDH)
Emeric Brun6924ef82013-03-06 14:08:53 +01002767 {
Emeric Brun2b58d042012-09-20 17:10:03 +02002768 int i;
2769 EC_KEY *ecdh;
2770
Emeric Brun6924ef82013-03-06 14:08:53 +01002771 i = OBJ_sn2nid(bind_conf->ecdhe ? bind_conf->ecdhe : ECDHE_DEFAULT_CURVE);
Emeric Brun2b58d042012-09-20 17:10:03 +02002772 if (!i || ((ecdh = EC_KEY_new_by_curve_name(i)) == NULL)) {
2773 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 +01002774 curproxy->id, bind_conf->ecdhe ? bind_conf->ecdhe : ECDHE_DEFAULT_CURVE,
2775 bind_conf->arg, bind_conf->file, bind_conf->line);
Emeric Brun2b58d042012-09-20 17:10:03 +02002776 cfgerr++;
2777 }
2778 else {
2779 SSL_CTX_set_tmp_ecdh(ctx, ecdh);
2780 EC_KEY_free(ecdh);
2781 }
2782 }
2783#endif
2784
Emeric Brunfc0421f2012-09-07 17:30:07 +02002785 return cfgerr;
2786}
2787
Evan Broderbe554312013-06-27 00:05:25 -07002788static int ssl_sock_srv_hostcheck(const char *pattern, const char *hostname)
2789{
2790 const char *pattern_wildcard, *pattern_left_label_end, *hostname_left_label_end;
2791 size_t prefixlen, suffixlen;
2792
2793 /* Trivial case */
2794 if (strcmp(pattern, hostname) == 0)
2795 return 1;
2796
Evan Broderbe554312013-06-27 00:05:25 -07002797 /* The rest of this logic is based on RFC 6125, section 6.4.3
2798 * (http://tools.ietf.org/html/rfc6125#section-6.4.3) */
2799
Emeric Bruna848dae2013-10-08 11:27:28 +02002800 pattern_wildcard = NULL;
2801 pattern_left_label_end = pattern;
2802 while (*pattern_left_label_end != '.') {
2803 switch (*pattern_left_label_end) {
2804 case 0:
2805 /* End of label not found */
2806 return 0;
2807 case '*':
2808 /* If there is more than one wildcards */
2809 if (pattern_wildcard)
2810 return 0;
2811 pattern_wildcard = pattern_left_label_end;
2812 break;
2813 }
2814 pattern_left_label_end++;
2815 }
2816
2817 /* If it's not trivial and there is no wildcard, it can't
2818 * match */
2819 if (!pattern_wildcard)
Evan Broderbe554312013-06-27 00:05:25 -07002820 return 0;
2821
2822 /* Make sure all labels match except the leftmost */
2823 hostname_left_label_end = strchr(hostname, '.');
2824 if (!hostname_left_label_end
2825 || strcmp(pattern_left_label_end, hostname_left_label_end) != 0)
2826 return 0;
2827
2828 /* Make sure the leftmost label of the hostname is long enough
2829 * that the wildcard can match */
Emeric Brun369da852013-10-08 11:39:35 +02002830 if (hostname_left_label_end - hostname < (pattern_left_label_end - pattern) - 1)
Evan Broderbe554312013-06-27 00:05:25 -07002831 return 0;
2832
2833 /* Finally compare the string on either side of the
2834 * wildcard */
2835 prefixlen = pattern_wildcard - pattern;
2836 suffixlen = pattern_left_label_end - (pattern_wildcard + 1);
Emeric Bruna848dae2013-10-08 11:27:28 +02002837 if ((prefixlen && (memcmp(pattern, hostname, prefixlen) != 0))
2838 || (suffixlen && (memcmp(pattern_wildcard + 1, hostname_left_label_end - suffixlen, suffixlen) != 0)))
Evan Broderbe554312013-06-27 00:05:25 -07002839 return 0;
2840
2841 return 1;
2842}
2843
2844static int ssl_sock_srv_verifycbk(int ok, X509_STORE_CTX *ctx)
2845{
2846 SSL *ssl;
2847 struct connection *conn;
2848 char *servername;
2849
2850 int depth;
2851 X509 *cert;
2852 STACK_OF(GENERAL_NAME) *alt_names;
2853 int i;
2854 X509_NAME *cert_subject;
2855 char *str;
2856
2857 if (ok == 0)
2858 return ok;
2859
2860 ssl = X509_STORE_CTX_get_ex_data(ctx, SSL_get_ex_data_X509_STORE_CTX_idx());
Vincent Bernat3c2f2f22016-04-03 13:48:42 +02002861 conn = SSL_get_app_data(ssl);
Evan Broderbe554312013-06-27 00:05:25 -07002862
2863 servername = objt_server(conn->target)->ssl_ctx.verify_host;
2864
2865 /* We only need to verify the CN on the actual server cert,
2866 * not the indirect CAs */
2867 depth = X509_STORE_CTX_get_error_depth(ctx);
2868 if (depth != 0)
2869 return ok;
2870
2871 /* At this point, the cert is *not* OK unless we can find a
2872 * hostname match */
2873 ok = 0;
2874
2875 cert = X509_STORE_CTX_get_current_cert(ctx);
2876 /* It seems like this might happen if verify peer isn't set */
2877 if (!cert)
2878 return ok;
2879
2880 alt_names = X509_get_ext_d2i(cert, NID_subject_alt_name, NULL, NULL);
2881 if (alt_names) {
2882 for (i = 0; !ok && i < sk_GENERAL_NAME_num(alt_names); i++) {
2883 GENERAL_NAME *name = sk_GENERAL_NAME_value(alt_names, i);
2884 if (name->type == GEN_DNS) {
Emeric Bruna33410c2013-09-17 15:47:48 +02002885#if OPENSSL_VERSION_NUMBER < 0x00907000L
2886 if (ASN1_STRING_to_UTF8((unsigned char **)&str, name->d.ia5) >= 0) {
2887#else
Evan Broderbe554312013-06-27 00:05:25 -07002888 if (ASN1_STRING_to_UTF8((unsigned char **)&str, name->d.dNSName) >= 0) {
Emeric Bruna33410c2013-09-17 15:47:48 +02002889#endif
Evan Broderbe554312013-06-27 00:05:25 -07002890 ok = ssl_sock_srv_hostcheck(str, servername);
2891 OPENSSL_free(str);
2892 }
2893 }
2894 }
Emeric Brun4ad50a42013-09-17 15:19:54 +02002895 sk_GENERAL_NAME_pop_free(alt_names, GENERAL_NAME_free);
Evan Broderbe554312013-06-27 00:05:25 -07002896 }
2897
2898 cert_subject = X509_get_subject_name(cert);
2899 i = -1;
2900 while (!ok && (i = X509_NAME_get_index_by_NID(cert_subject, NID_commonName, i)) != -1) {
2901 X509_NAME_ENTRY *entry = X509_NAME_get_entry(cert_subject, i);
2902 if (ASN1_STRING_to_UTF8((unsigned char **)&str, entry->value) >= 0) {
2903 ok = ssl_sock_srv_hostcheck(str, servername);
2904 OPENSSL_free(str);
2905 }
2906 }
2907
2908 return ok;
2909}
2910
Emeric Brun94324a42012-10-11 14:00:19 +02002911/* prepare ssl context from servers options. Returns an error count */
2912int ssl_sock_prepare_srv_ctx(struct server *srv, struct proxy *curproxy)
2913{
2914 int cfgerr = 0;
Remi Gacogneaf5c3da2014-05-19 10:29:58 +02002915 long options =
Emeric Brun94324a42012-10-11 14:00:19 +02002916 SSL_OP_ALL | /* all known workarounds for bugs */
2917 SSL_OP_NO_SSLv2 |
2918 SSL_OP_NO_COMPRESSION;
Remi Gacogneaf5c3da2014-05-19 10:29:58 +02002919 long mode =
Emeric Brun94324a42012-10-11 14:00:19 +02002920 SSL_MODE_ENABLE_PARTIAL_WRITE |
2921 SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER |
Willy Tarreau396a1862014-11-13 14:06:52 +01002922 SSL_MODE_RELEASE_BUFFERS |
2923 SSL_MODE_SMALL_BUFFERS;
Emeric Brun850efd52014-01-29 12:24:34 +01002924 int verify = SSL_VERIFY_NONE;
Emeric Brun94324a42012-10-11 14:00:19 +02002925
Thierry Fournier383085f2013-01-24 14:15:43 +01002926 /* Make sure openssl opens /dev/urandom before the chroot */
2927 if (!ssl_initialize_random()) {
2928 Alert("OpenSSL random data generator initialization failed.\n");
2929 cfgerr++;
2930 }
2931
Willy Tarreaufce03112015-01-15 21:32:40 +01002932 /* Automatic memory computations need to know we use SSL there */
2933 global.ssl_used_backend = 1;
2934
2935 /* Initiate SSL context for current server */
Emeric Brun94324a42012-10-11 14:00:19 +02002936 srv->ssl_ctx.reused_sess = NULL;
2937 if (srv->use_ssl)
2938 srv->xprt = &ssl_sock;
2939 if (srv->check.use_ssl)
Cyril Bonté9ce13112014-11-15 22:41:27 +01002940 srv->check.xprt = &ssl_sock;
Emeric Brun94324a42012-10-11 14:00:19 +02002941
2942 srv->ssl_ctx.ctx = SSL_CTX_new(SSLv23_client_method());
2943 if (!srv->ssl_ctx.ctx) {
2944 Alert("config : %s '%s', server '%s': unable to allocate ssl context.\n",
2945 proxy_type_str(curproxy), curproxy->id,
2946 srv->id);
2947 cfgerr++;
2948 return cfgerr;
2949 }
Emeric Bruna7aa3092012-10-26 12:58:00 +02002950 if (srv->ssl_ctx.client_crt) {
2951 if (SSL_CTX_use_PrivateKey_file(srv->ssl_ctx.ctx, srv->ssl_ctx.client_crt, SSL_FILETYPE_PEM) <= 0) {
2952 Alert("config : %s '%s', server '%s': unable to load SSL private key from PEM file '%s'.\n",
2953 proxy_type_str(curproxy), curproxy->id,
2954 srv->id, srv->ssl_ctx.client_crt);
2955 cfgerr++;
2956 }
2957 else if (SSL_CTX_use_certificate_chain_file(srv->ssl_ctx.ctx, srv->ssl_ctx.client_crt) <= 0) {
2958 Alert("config : %s '%s', server '%s': unable to load ssl certificate from PEM file '%s'.\n",
2959 proxy_type_str(curproxy), curproxy->id,
2960 srv->id, srv->ssl_ctx.client_crt);
2961 cfgerr++;
2962 }
2963 else if (SSL_CTX_check_private_key(srv->ssl_ctx.ctx) <= 0) {
2964 Alert("config : %s '%s', server '%s': inconsistencies between private key and certificate loaded from PEM file '%s'.\n",
2965 proxy_type_str(curproxy), curproxy->id,
2966 srv->id, srv->ssl_ctx.client_crt);
2967 cfgerr++;
2968 }
2969 }
Emeric Brun94324a42012-10-11 14:00:19 +02002970
2971 if (srv->ssl_ctx.options & SRV_SSL_O_NO_SSLV3)
2972 options |= SSL_OP_NO_SSLv3;
2973 if (srv->ssl_ctx.options & SRV_SSL_O_NO_TLSV10)
2974 options |= SSL_OP_NO_TLSv1;
2975 if (srv->ssl_ctx.options & SRV_SSL_O_NO_TLSV11)
2976 options |= SSL_OP_NO_TLSv1_1;
2977 if (srv->ssl_ctx.options & SRV_SSL_O_NO_TLSV12)
2978 options |= SSL_OP_NO_TLSv1_2;
Emeric Brunf9c5c472012-10-11 15:28:34 +02002979 if (srv->ssl_ctx.options & SRV_SSL_O_NO_TLS_TICKETS)
2980 options |= SSL_OP_NO_TICKET;
Jérémie Courrèges-Anglas17c3f622015-07-25 16:50:52 -06002981 if (srv->ssl_ctx.options & SRV_SSL_O_USE_SSLV3) {
2982#ifndef OPENSSL_NO_SSL3
Emeric Brun94324a42012-10-11 14:00:19 +02002983 SSL_CTX_set_ssl_version(srv->ssl_ctx.ctx, SSLv3_client_method());
Jérémie Courrèges-Anglas17c3f622015-07-25 16:50:52 -06002984#else
Thierry FOURNIERbc965342015-08-26 08:21:26 +02002985 Alert("SSLv3 support requested but unavailable.\n");
Jérémie Courrèges-Anglas17c3f622015-07-25 16:50:52 -06002986 cfgerr++;
2987#endif
2988 }
Emeric Brun94324a42012-10-11 14:00:19 +02002989 if (srv->ssl_ctx.options & SRV_SSL_O_USE_TLSV10)
2990 SSL_CTX_set_ssl_version(srv->ssl_ctx.ctx, TLSv1_client_method());
2991#if SSL_OP_NO_TLSv1_1
2992 if (srv->ssl_ctx.options & SRV_SSL_O_USE_TLSV11)
2993 SSL_CTX_set_ssl_version(srv->ssl_ctx.ctx, TLSv1_1_client_method());
2994#endif
2995#if SSL_OP_NO_TLSv1_2
2996 if (srv->ssl_ctx.options & SRV_SSL_O_USE_TLSV12)
2997 SSL_CTX_set_ssl_version(srv->ssl_ctx.ctx, TLSv1_2_client_method());
2998#endif
2999
3000 SSL_CTX_set_options(srv->ssl_ctx.ctx, options);
3001 SSL_CTX_set_mode(srv->ssl_ctx.ctx, mode);
Emeric Brun850efd52014-01-29 12:24:34 +01003002
3003 if (global.ssl_server_verify == SSL_SERVER_VERIFY_REQUIRED)
3004 verify = SSL_VERIFY_PEER;
3005
3006 switch (srv->ssl_ctx.verify) {
3007 case SSL_SOCK_VERIFY_NONE:
3008 verify = SSL_VERIFY_NONE;
3009 break;
3010 case SSL_SOCK_VERIFY_REQUIRED:
3011 verify = SSL_VERIFY_PEER;
3012 break;
3013 }
Evan Broderbe554312013-06-27 00:05:25 -07003014 SSL_CTX_set_verify(srv->ssl_ctx.ctx,
Emeric Brun850efd52014-01-29 12:24:34 +01003015 verify,
Evan Broderbe554312013-06-27 00:05:25 -07003016 srv->ssl_ctx.verify_host ? ssl_sock_srv_verifycbk : NULL);
Emeric Brun850efd52014-01-29 12:24:34 +01003017 if (verify & SSL_VERIFY_PEER) {
Emeric Brunef42d922012-10-11 16:11:36 +02003018 if (srv->ssl_ctx.ca_file) {
3019 /* load CAfile to verify */
3020 if (!SSL_CTX_load_verify_locations(srv->ssl_ctx.ctx, srv->ssl_ctx.ca_file, NULL)) {
Willy Tarreau07ba08b2014-02-16 19:22:08 +01003021 Alert("Proxy '%s', server '%s' [%s:%d] unable to load CA file '%s'.\n",
Emeric Brunef42d922012-10-11 16:11:36 +02003022 curproxy->id, srv->id,
3023 srv->conf.file, srv->conf.line, srv->ssl_ctx.ca_file);
3024 cfgerr++;
3025 }
3026 }
Emeric Brun850efd52014-01-29 12:24:34 +01003027 else {
3028 if (global.ssl_server_verify == SSL_SERVER_VERIFY_REQUIRED)
Willy Tarreau07ba08b2014-02-16 19:22:08 +01003029 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 +01003030 curproxy->id, srv->id,
3031 srv->conf.file, srv->conf.line);
3032 else
Willy Tarreau07ba08b2014-02-16 19:22:08 +01003033 Alert("Proxy '%s', server '%s' [%s:%d] verify is enabled but no CA file specified.\n",
Emeric Brun850efd52014-01-29 12:24:34 +01003034 curproxy->id, srv->id,
3035 srv->conf.file, srv->conf.line);
3036 cfgerr++;
3037 }
Emeric Brunef42d922012-10-11 16:11:36 +02003038#ifdef X509_V_FLAG_CRL_CHECK
3039 if (srv->ssl_ctx.crl_file) {
3040 X509_STORE *store = SSL_CTX_get_cert_store(srv->ssl_ctx.ctx);
3041
3042 if (!store || !X509_STORE_load_locations(store, srv->ssl_ctx.crl_file, NULL)) {
Willy Tarreau07ba08b2014-02-16 19:22:08 +01003043 Alert("Proxy '%s', server '%s' [%s:%d] unable to configure CRL file '%s'.\n",
Emeric Brunef42d922012-10-11 16:11:36 +02003044 curproxy->id, srv->id,
3045 srv->conf.file, srv->conf.line, srv->ssl_ctx.crl_file);
3046 cfgerr++;
3047 }
3048 else {
3049 X509_STORE_set_flags(store, X509_V_FLAG_CRL_CHECK|X509_V_FLAG_CRL_CHECK_ALL);
3050 }
3051 }
3052#endif
3053 }
3054
Emeric Brun4f65bff2012-11-16 15:11:00 +01003055 if (global.tune.ssllifetime)
3056 SSL_CTX_set_timeout(srv->ssl_ctx.ctx, global.tune.ssllifetime);
3057
Emeric Brun94324a42012-10-11 14:00:19 +02003058 SSL_CTX_set_session_cache_mode(srv->ssl_ctx.ctx, SSL_SESS_CACHE_OFF);
3059 if (srv->ssl_ctx.ciphers &&
3060 !SSL_CTX_set_cipher_list(srv->ssl_ctx.ctx, srv->ssl_ctx.ciphers)) {
3061 Alert("Proxy '%s', server '%s' [%s:%d] : unable to set SSL cipher list to '%s'.\n",
3062 curproxy->id, srv->id,
3063 srv->conf.file, srv->conf.line, srv->ssl_ctx.ciphers);
3064 cfgerr++;
3065 }
3066
3067 return cfgerr;
3068}
3069
Willy Tarreau2a65ff02012-09-13 17:54:29 +02003070/* Walks down the two trees in bind_conf and prepares all certs. The pointer may
Emeric Brunfc0421f2012-09-07 17:30:07 +02003071 * be NULL, in which case nothing is done. Returns the number of errors
3072 * encountered.
3073 */
Willy Tarreau2a65ff02012-09-13 17:54:29 +02003074int ssl_sock_prepare_all_ctx(struct bind_conf *bind_conf, struct proxy *px)
Emeric Brunfc0421f2012-09-07 17:30:07 +02003075{
3076 struct ebmb_node *node;
3077 struct sni_ctx *sni;
3078 int err = 0;
3079
Willy Tarreau2a65ff02012-09-13 17:54:29 +02003080 if (!bind_conf || !bind_conf->is_ssl)
Emeric Brunfc0421f2012-09-07 17:30:07 +02003081 return 0;
3082
Willy Tarreaufce03112015-01-15 21:32:40 +01003083 /* Automatic memory computations need to know we use SSL there */
3084 global.ssl_used_frontend = 1;
3085
Emeric Brun0bed9942014-10-30 19:25:24 +01003086 if (bind_conf->default_ctx)
3087 err += ssl_sock_prepare_ctx(bind_conf, bind_conf->default_ctx, px);
3088
Willy Tarreau2a65ff02012-09-13 17:54:29 +02003089 node = ebmb_first(&bind_conf->sni_ctx);
Emeric Brunfc0421f2012-09-07 17:30:07 +02003090 while (node) {
3091 sni = ebmb_entry(node, struct sni_ctx, name);
Emeric Brun0bed9942014-10-30 19:25:24 +01003092 if (!sni->order && sni->ctx != bind_conf->default_ctx)
3093 /* only initialize the CTX on its first occurrence and
3094 if it is not the default_ctx */
Willy Tarreau2a65ff02012-09-13 17:54:29 +02003095 err += ssl_sock_prepare_ctx(bind_conf, sni->ctx, px);
Emeric Brunfc0421f2012-09-07 17:30:07 +02003096 node = ebmb_next(node);
3097 }
3098
Willy Tarreau2a65ff02012-09-13 17:54:29 +02003099 node = ebmb_first(&bind_conf->sni_w_ctx);
Emeric Brunfc0421f2012-09-07 17:30:07 +02003100 while (node) {
3101 sni = ebmb_entry(node, struct sni_ctx, name);
Emeric Brun0bed9942014-10-30 19:25:24 +01003102 if (!sni->order && sni->ctx != bind_conf->default_ctx)
3103 /* only initialize the CTX on its first occurrence and
3104 if it is not the default_ctx */
Willy Tarreau2a65ff02012-09-13 17:54:29 +02003105 err += ssl_sock_prepare_ctx(bind_conf, sni->ctx, px);
Emeric Brunfc0421f2012-09-07 17:30:07 +02003106 node = ebmb_next(node);
3107 }
3108 return err;
3109}
3110
Christopher Faulet77fe80c2015-07-29 13:02:40 +02003111
3112/* release ssl context allocated for servers. */
3113void ssl_sock_free_srv_ctx(struct server *srv)
3114{
3115 if (srv->ssl_ctx.ctx)
3116 SSL_CTX_free(srv->ssl_ctx.ctx);
3117}
3118
Willy Tarreau2a65ff02012-09-13 17:54:29 +02003119/* Walks down the two trees in bind_conf and frees all the certs. The pointer may
Emeric Brunfc0421f2012-09-07 17:30:07 +02003120 * be NULL, in which case nothing is done. The default_ctx is nullified too.
3121 */
Willy Tarreau2a65ff02012-09-13 17:54:29 +02003122void ssl_sock_free_all_ctx(struct bind_conf *bind_conf)
Emeric Brunfc0421f2012-09-07 17:30:07 +02003123{
3124 struct ebmb_node *node, *back;
3125 struct sni_ctx *sni;
3126
Willy Tarreau2a65ff02012-09-13 17:54:29 +02003127 if (!bind_conf || !bind_conf->is_ssl)
Emeric Brunfc0421f2012-09-07 17:30:07 +02003128 return;
3129
Willy Tarreau2a65ff02012-09-13 17:54:29 +02003130 node = ebmb_first(&bind_conf->sni_ctx);
Emeric Brunfc0421f2012-09-07 17:30:07 +02003131 while (node) {
3132 sni = ebmb_entry(node, struct sni_ctx, name);
3133 back = ebmb_next(node);
3134 ebmb_delete(node);
3135 if (!sni->order) /* only free the CTX on its first occurrence */
3136 SSL_CTX_free(sni->ctx);
3137 free(sni);
3138 node = back;
3139 }
3140
Willy Tarreau2a65ff02012-09-13 17:54:29 +02003141 node = ebmb_first(&bind_conf->sni_w_ctx);
Emeric Brunfc0421f2012-09-07 17:30:07 +02003142 while (node) {
3143 sni = ebmb_entry(node, struct sni_ctx, name);
3144 back = ebmb_next(node);
3145 ebmb_delete(node);
3146 if (!sni->order) /* only free the CTX on its first occurrence */
3147 SSL_CTX_free(sni->ctx);
3148 free(sni);
3149 node = back;
3150 }
3151
Willy Tarreau2a65ff02012-09-13 17:54:29 +02003152 bind_conf->default_ctx = NULL;
Emeric Brune1f38db2012-09-03 20:36:47 +02003153}
3154
Christopher Faulet31af49d2015-06-09 17:29:50 +02003155/* Load CA cert file and private key used to generate certificates */
3156int
3157ssl_sock_load_ca(struct bind_conf *bind_conf, struct proxy *px)
3158{
3159 FILE *fp;
3160 X509 *cacert = NULL;
3161 EVP_PKEY *capkey = NULL;
3162 int err = 0;
3163
3164 if (!bind_conf || !bind_conf->generate_certs)
3165 return err;
3166
Willy Tarreaua84c2672015-10-09 12:10:13 +02003167#ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME
Christopher Fauletd2cab922015-07-28 16:03:47 +02003168 if (global.tune.ssl_ctx_cache)
3169 ssl_ctx_lru_tree = lru64_new(global.tune.ssl_ctx_cache);
3170 ssl_ctx_lru_seed = (unsigned int)time(NULL);
Willy Tarreaua84c2672015-10-09 12:10:13 +02003171#endif
Christopher Fauletd2cab922015-07-28 16:03:47 +02003172
Christopher Faulet31af49d2015-06-09 17:29:50 +02003173 if (!bind_conf->ca_sign_file) {
3174 Alert("Proxy '%s': cannot enable certificate generation, "
3175 "no CA certificate File configured at [%s:%d].\n",
3176 px->id, bind_conf->file, bind_conf->line);
Christopher Faulet31af49d2015-06-09 17:29:50 +02003177 goto load_error;
Christopher Fauletc6f02fb2015-10-09 10:53:31 +02003178 }
Christopher Faulet31af49d2015-06-09 17:29:50 +02003179
3180 /* read in the CA certificate */
3181 if (!(fp = fopen(bind_conf->ca_sign_file, "r"))) {
3182 Alert("Proxy '%s': Failed to read CA certificate file '%s' at [%s:%d].\n",
3183 px->id, bind_conf->ca_sign_file, bind_conf->file, bind_conf->line);
Christopher Faulet31af49d2015-06-09 17:29:50 +02003184 goto load_error;
3185 }
3186 if (!(cacert = PEM_read_X509(fp, NULL, NULL, NULL))) {
3187 Alert("Proxy '%s': Failed to read CA certificate file '%s' at [%s:%d].\n",
3188 px->id, bind_conf->ca_sign_file, bind_conf->file, bind_conf->line);
Christopher Fauletc6f02fb2015-10-09 10:53:31 +02003189 goto read_error;
Christopher Faulet31af49d2015-06-09 17:29:50 +02003190 }
Christopher Fauletc6f02fb2015-10-09 10:53:31 +02003191 rewind(fp);
Christopher Faulet31af49d2015-06-09 17:29:50 +02003192 if (!(capkey = PEM_read_PrivateKey(fp, NULL, NULL, bind_conf->ca_sign_pass))) {
3193 Alert("Proxy '%s': Failed to read CA private key file '%s' at [%s:%d].\n",
3194 px->id, bind_conf->ca_sign_file, bind_conf->file, bind_conf->line);
Christopher Fauletc6f02fb2015-10-09 10:53:31 +02003195 goto read_error;
Christopher Faulet31af49d2015-06-09 17:29:50 +02003196 }
Christopher Faulet31af49d2015-06-09 17:29:50 +02003197
Christopher Fauletc6f02fb2015-10-09 10:53:31 +02003198 fclose (fp);
Christopher Faulet31af49d2015-06-09 17:29:50 +02003199 bind_conf->ca_sign_cert = cacert;
3200 bind_conf->ca_sign_pkey = capkey;
3201 return err;
3202
Christopher Fauletc6f02fb2015-10-09 10:53:31 +02003203 read_error:
3204 fclose (fp);
Christopher Faulet31af49d2015-06-09 17:29:50 +02003205 if (capkey) EVP_PKEY_free(capkey);
3206 if (cacert) X509_free(cacert);
Christopher Fauletc6f02fb2015-10-09 10:53:31 +02003207 load_error:
3208 bind_conf->generate_certs = 0;
3209 err++;
Christopher Faulet31af49d2015-06-09 17:29:50 +02003210 return err;
3211}
3212
3213/* Release CA cert and private key used to generate certificated */
3214void
3215ssl_sock_free_ca(struct bind_conf *bind_conf)
3216{
3217 if (!bind_conf)
3218 return;
3219
3220 if (bind_conf->ca_sign_pkey)
3221 EVP_PKEY_free(bind_conf->ca_sign_pkey);
3222 if (bind_conf->ca_sign_cert)
3223 X509_free(bind_conf->ca_sign_cert);
3224}
3225
Emeric Brun46591952012-05-18 15:47:34 +02003226/*
3227 * This function is called if SSL * context is not yet allocated. The function
3228 * is designed to be called before any other data-layer operation and sets the
3229 * handshake flag on the connection. It is safe to call it multiple times.
3230 * It returns 0 on success and -1 in error case.
3231 */
3232static int ssl_sock_init(struct connection *conn)
3233{
3234 /* already initialized */
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02003235 if (conn->xprt_ctx)
Emeric Brun46591952012-05-18 15:47:34 +02003236 return 0;
3237
Willy Tarreau3c728722014-01-23 13:50:42 +01003238 if (!conn_ctrl_ready(conn))
Willy Tarreauf79c8172013-10-21 16:30:56 +02003239 return 0;
3240
Willy Tarreau20879a02012-12-03 16:32:10 +01003241 if (global.maxsslconn && sslconns >= global.maxsslconn) {
3242 conn->err_code = CO_ER_SSL_TOO_MANY;
Willy Tarreau403edff2012-09-06 11:58:37 +02003243 return -1;
Willy Tarreau20879a02012-12-03 16:32:10 +01003244 }
Willy Tarreau403edff2012-09-06 11:58:37 +02003245
Emeric Brun46591952012-05-18 15:47:34 +02003246 /* If it is in client mode initiate SSL session
3247 in connect state otherwise accept state */
Willy Tarreau3fdb3662012-11-12 00:42:33 +01003248 if (objt_server(conn->target)) {
Willy Tarreaufba03cd2014-11-13 13:48:58 +01003249 int may_retry = 1;
3250
3251 retry_connect:
Emeric Brun46591952012-05-18 15:47:34 +02003252 /* Alloc a new SSL session ctx */
Willy Tarreau3fdb3662012-11-12 00:42:33 +01003253 conn->xprt_ctx = SSL_new(objt_server(conn->target)->ssl_ctx.ctx);
Willy Tarreau20879a02012-12-03 16:32:10 +01003254 if (!conn->xprt_ctx) {
Willy Tarreaufba03cd2014-11-13 13:48:58 +01003255 if (may_retry--) {
3256 pool_gc2();
3257 goto retry_connect;
3258 }
Willy Tarreau20879a02012-12-03 16:32:10 +01003259 conn->err_code = CO_ER_SSL_NO_MEM;
Emeric Brun46591952012-05-18 15:47:34 +02003260 return -1;
Willy Tarreau20879a02012-12-03 16:32:10 +01003261 }
Emeric Brun46591952012-05-18 15:47:34 +02003262
Emeric Brun46591952012-05-18 15:47:34 +02003263 /* set fd on SSL session context */
Emeric Brun55476152014-11-12 17:35:37 +01003264 if (!SSL_set_fd(conn->xprt_ctx, conn->t.sock.fd)) {
3265 SSL_free(conn->xprt_ctx);
3266 conn->xprt_ctx = NULL;
Willy Tarreaufba03cd2014-11-13 13:48:58 +01003267 if (may_retry--) {
3268 pool_gc2();
3269 goto retry_connect;
3270 }
Emeric Brun55476152014-11-12 17:35:37 +01003271 conn->err_code = CO_ER_SSL_NO_MEM;
3272 return -1;
3273 }
Emeric Brun46591952012-05-18 15:47:34 +02003274
Evan Broderbe554312013-06-27 00:05:25 -07003275 /* set connection pointer */
Emeric Brun55476152014-11-12 17:35:37 +01003276 if (!SSL_set_app_data(conn->xprt_ctx, conn)) {
3277 SSL_free(conn->xprt_ctx);
3278 conn->xprt_ctx = NULL;
Willy Tarreaufba03cd2014-11-13 13:48:58 +01003279 if (may_retry--) {
3280 pool_gc2();
3281 goto retry_connect;
3282 }
Emeric Brun55476152014-11-12 17:35:37 +01003283 conn->err_code = CO_ER_SSL_NO_MEM;
3284 return -1;
3285 }
3286
3287 SSL_set_connect_state(conn->xprt_ctx);
3288 if (objt_server(conn->target)->ssl_ctx.reused_sess) {
3289 if(!SSL_set_session(conn->xprt_ctx, objt_server(conn->target)->ssl_ctx.reused_sess)) {
3290 SSL_SESSION_free(objt_server(conn->target)->ssl_ctx.reused_sess);
3291 objt_server(conn->target)->ssl_ctx.reused_sess = NULL;
3292 }
3293 }
Evan Broderbe554312013-06-27 00:05:25 -07003294
Emeric Brun46591952012-05-18 15:47:34 +02003295 /* leave init state and start handshake */
Willy Tarreau05737472012-09-04 08:03:39 +02003296 conn->flags |= CO_FL_SSL_WAIT_HS | CO_FL_WAIT_L6_CONN;
Willy Tarreau403edff2012-09-06 11:58:37 +02003297
3298 sslconns++;
Willy Tarreau71b734c2014-01-28 15:19:44 +01003299 totalsslconns++;
Emeric Brun46591952012-05-18 15:47:34 +02003300 return 0;
3301 }
Willy Tarreau3fdb3662012-11-12 00:42:33 +01003302 else if (objt_listener(conn->target)) {
Willy Tarreaufba03cd2014-11-13 13:48:58 +01003303 int may_retry = 1;
3304
3305 retry_accept:
Emeric Brun46591952012-05-18 15:47:34 +02003306 /* Alloc a new SSL session ctx */
Willy Tarreau3fdb3662012-11-12 00:42:33 +01003307 conn->xprt_ctx = SSL_new(objt_listener(conn->target)->bind_conf->default_ctx);
Willy Tarreau20879a02012-12-03 16:32:10 +01003308 if (!conn->xprt_ctx) {
Willy Tarreaufba03cd2014-11-13 13:48:58 +01003309 if (may_retry--) {
3310 pool_gc2();
3311 goto retry_accept;
3312 }
Willy Tarreau20879a02012-12-03 16:32:10 +01003313 conn->err_code = CO_ER_SSL_NO_MEM;
Emeric Brun46591952012-05-18 15:47:34 +02003314 return -1;
Willy Tarreau20879a02012-12-03 16:32:10 +01003315 }
Emeric Brun46591952012-05-18 15:47:34 +02003316
Emeric Brun46591952012-05-18 15:47:34 +02003317 /* set fd on SSL session context */
Emeric Brun55476152014-11-12 17:35:37 +01003318 if (!SSL_set_fd(conn->xprt_ctx, conn->t.sock.fd)) {
3319 SSL_free(conn->xprt_ctx);
3320 conn->xprt_ctx = NULL;
Willy Tarreaufba03cd2014-11-13 13:48:58 +01003321 if (may_retry--) {
3322 pool_gc2();
3323 goto retry_accept;
3324 }
Emeric Brun55476152014-11-12 17:35:37 +01003325 conn->err_code = CO_ER_SSL_NO_MEM;
3326 return -1;
3327 }
Emeric Brun46591952012-05-18 15:47:34 +02003328
Emeric Brune1f38db2012-09-03 20:36:47 +02003329 /* set connection pointer */
Emeric Brun55476152014-11-12 17:35:37 +01003330 if (!SSL_set_app_data(conn->xprt_ctx, conn)) {
3331 SSL_free(conn->xprt_ctx);
3332 conn->xprt_ctx = NULL;
Willy Tarreaufba03cd2014-11-13 13:48:58 +01003333 if (may_retry--) {
3334 pool_gc2();
3335 goto retry_accept;
3336 }
Emeric Brun55476152014-11-12 17:35:37 +01003337 conn->err_code = CO_ER_SSL_NO_MEM;
3338 return -1;
3339 }
3340
3341 SSL_set_accept_state(conn->xprt_ctx);
Emeric Brune1f38db2012-09-03 20:36:47 +02003342
Emeric Brun46591952012-05-18 15:47:34 +02003343 /* leave init state and start handshake */
Willy Tarreau05737472012-09-04 08:03:39 +02003344 conn->flags |= CO_FL_SSL_WAIT_HS | CO_FL_WAIT_L6_CONN;
Willy Tarreau403edff2012-09-06 11:58:37 +02003345
3346 sslconns++;
Willy Tarreau71b734c2014-01-28 15:19:44 +01003347 totalsslconns++;
Emeric Brun46591952012-05-18 15:47:34 +02003348 return 0;
3349 }
3350 /* don't know how to handle such a target */
Willy Tarreau20879a02012-12-03 16:32:10 +01003351 conn->err_code = CO_ER_SSL_NO_TARGET;
Emeric Brun46591952012-05-18 15:47:34 +02003352 return -1;
3353}
3354
3355
3356/* This is the callback which is used when an SSL handshake is pending. It
3357 * updates the FD status if it wants some polling before being called again.
3358 * It returns 0 if it fails in a fatal way or needs to poll to go further,
3359 * otherwise it returns non-zero and removes itself from the connection's
3360 * flags (the bit is provided in <flag> by the caller).
3361 */
3362int ssl_sock_handshake(struct connection *conn, unsigned int flag)
3363{
3364 int ret;
3365
Willy Tarreau3c728722014-01-23 13:50:42 +01003366 if (!conn_ctrl_ready(conn))
Willy Tarreauf79c8172013-10-21 16:30:56 +02003367 return 0;
3368
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02003369 if (!conn->xprt_ctx)
Emeric Brun46591952012-05-18 15:47:34 +02003370 goto out_error;
3371
Emeric Brun674b7432012-11-08 19:21:55 +01003372 /* If we use SSL_do_handshake to process a reneg initiated by
3373 * the remote peer, it sometimes returns SSL_ERROR_SSL.
3374 * Usually SSL_write and SSL_read are used and process implicitly
3375 * the reneg handshake.
3376 * Here we use SSL_peek as a workaround for reneg.
3377 */
3378 if ((conn->flags & CO_FL_CONNECTED) && SSL_renegotiate_pending(conn->xprt_ctx)) {
3379 char c;
3380
3381 ret = SSL_peek(conn->xprt_ctx, &c, 1);
3382 if (ret <= 0) {
3383 /* handshake may have not been completed, let's find why */
3384 ret = SSL_get_error(conn->xprt_ctx, ret);
3385 if (ret == SSL_ERROR_WANT_WRITE) {
3386 /* SSL handshake needs to write, L4 connection may not be ready */
3387 __conn_sock_stop_recv(conn);
Willy Tarreaue1f50c42014-01-22 20:02:06 +01003388 __conn_sock_want_send(conn);
3389 fd_cant_send(conn->t.sock.fd);
Emeric Brun674b7432012-11-08 19:21:55 +01003390 return 0;
3391 }
3392 else if (ret == SSL_ERROR_WANT_READ) {
3393 /* handshake may have been completed but we have
3394 * no more data to read.
3395 */
3396 if (!SSL_renegotiate_pending(conn->xprt_ctx)) {
3397 ret = 1;
3398 goto reneg_ok;
3399 }
3400 /* SSL handshake needs to read, L4 connection is ready */
3401 if (conn->flags & CO_FL_WAIT_L4_CONN)
3402 conn->flags &= ~CO_FL_WAIT_L4_CONN;
3403 __conn_sock_stop_send(conn);
Willy Tarreaue1f50c42014-01-22 20:02:06 +01003404 __conn_sock_want_recv(conn);
3405 fd_cant_recv(conn->t.sock.fd);
Emeric Brun674b7432012-11-08 19:21:55 +01003406 return 0;
3407 }
3408 else if (ret == SSL_ERROR_SYSCALL) {
3409 /* if errno is null, then connection was successfully established */
3410 if (!errno && conn->flags & CO_FL_WAIT_L4_CONN)
3411 conn->flags &= ~CO_FL_WAIT_L4_CONN;
Willy Tarreau20879a02012-12-03 16:32:10 +01003412 if (!conn->err_code) {
Emeric Brun29f037d2014-04-25 19:05:36 +02003413 if (!((SSL *)conn->xprt_ctx)->packet_length) {
3414 if (!errno) {
3415 if (conn->xprt_st & SSL_SOCK_RECV_HEARTBEAT)
3416 conn->err_code = CO_ER_SSL_HANDSHAKE_HB;
3417 else
3418 conn->err_code = CO_ER_SSL_EMPTY;
3419 }
3420 else {
3421 if (conn->xprt_st & SSL_SOCK_RECV_HEARTBEAT)
3422 conn->err_code = CO_ER_SSL_HANDSHAKE_HB;
3423 else
3424 conn->err_code = CO_ER_SSL_ABORT;
3425 }
3426 }
3427 else {
3428 if (conn->xprt_st & SSL_SOCK_RECV_HEARTBEAT)
3429 conn->err_code = CO_ER_SSL_HANDSHAKE_HB;
Willy Tarreau20879a02012-12-03 16:32:10 +01003430 else
Emeric Brun29f037d2014-04-25 19:05:36 +02003431 conn->err_code = CO_ER_SSL_HANDSHAKE;
3432 }
Willy Tarreau20879a02012-12-03 16:32:10 +01003433 }
Emeric Brun674b7432012-11-08 19:21:55 +01003434 goto out_error;
3435 }
3436 else {
3437 /* Fail on all other handshake errors */
3438 /* Note: OpenSSL may leave unread bytes in the socket's
3439 * buffer, causing an RST to be emitted upon close() on
3440 * TCP sockets. We first try to drain possibly pending
3441 * data to avoid this as much as possible.
3442 */
Willy Tarreaud85c4852015-03-13 00:40:28 +01003443 conn_sock_drain(conn);
Willy Tarreau20879a02012-12-03 16:32:10 +01003444 if (!conn->err_code)
Willy Tarreauf51c6982014-04-25 20:02:39 +02003445 conn->err_code = (conn->xprt_st & SSL_SOCK_RECV_HEARTBEAT) ?
3446 CO_ER_SSL_KILLED_HB : CO_ER_SSL_HANDSHAKE;
Emeric Brun674b7432012-11-08 19:21:55 +01003447 goto out_error;
3448 }
3449 }
3450 /* read some data: consider handshake completed */
3451 goto reneg_ok;
3452 }
3453
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02003454 ret = SSL_do_handshake(conn->xprt_ctx);
Emeric Brun46591952012-05-18 15:47:34 +02003455 if (ret != 1) {
3456 /* handshake did not complete, let's find why */
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02003457 ret = SSL_get_error(conn->xprt_ctx, ret);
Emeric Brun46591952012-05-18 15:47:34 +02003458
3459 if (ret == SSL_ERROR_WANT_WRITE) {
3460 /* SSL handshake needs to write, L4 connection may not be ready */
3461 __conn_sock_stop_recv(conn);
Willy Tarreaue1f50c42014-01-22 20:02:06 +01003462 __conn_sock_want_send(conn);
3463 fd_cant_send(conn->t.sock.fd);
Emeric Brun46591952012-05-18 15:47:34 +02003464 return 0;
3465 }
3466 else if (ret == SSL_ERROR_WANT_READ) {
3467 /* SSL handshake needs to read, L4 connection is ready */
3468 if (conn->flags & CO_FL_WAIT_L4_CONN)
3469 conn->flags &= ~CO_FL_WAIT_L4_CONN;
3470 __conn_sock_stop_send(conn);
Willy Tarreaue1f50c42014-01-22 20:02:06 +01003471 __conn_sock_want_recv(conn);
3472 fd_cant_recv(conn->t.sock.fd);
Emeric Brun46591952012-05-18 15:47:34 +02003473 return 0;
3474 }
Willy Tarreau89230192012-09-28 20:22:13 +02003475 else if (ret == SSL_ERROR_SYSCALL) {
3476 /* if errno is null, then connection was successfully established */
3477 if (!errno && conn->flags & CO_FL_WAIT_L4_CONN)
3478 conn->flags &= ~CO_FL_WAIT_L4_CONN;
Willy Tarreau20879a02012-12-03 16:32:10 +01003479
Emeric Brun29f037d2014-04-25 19:05:36 +02003480 if (!((SSL *)conn->xprt_ctx)->packet_length) {
3481 if (!errno) {
3482 if (conn->xprt_st & SSL_SOCK_RECV_HEARTBEAT)
3483 conn->err_code = CO_ER_SSL_HANDSHAKE_HB;
3484 else
3485 conn->err_code = CO_ER_SSL_EMPTY;
3486 }
3487 else {
3488 if (conn->xprt_st & SSL_SOCK_RECV_HEARTBEAT)
3489 conn->err_code = CO_ER_SSL_HANDSHAKE_HB;
3490 else
3491 conn->err_code = CO_ER_SSL_ABORT;
3492 }
3493 }
3494 else {
3495 if (conn->xprt_st & SSL_SOCK_RECV_HEARTBEAT)
3496 conn->err_code = CO_ER_SSL_HANDSHAKE_HB;
Willy Tarreau20879a02012-12-03 16:32:10 +01003497 else
Emeric Brun29f037d2014-04-25 19:05:36 +02003498 conn->err_code = CO_ER_SSL_HANDSHAKE;
3499 }
Willy Tarreau89230192012-09-28 20:22:13 +02003500 goto out_error;
3501 }
Emeric Brun46591952012-05-18 15:47:34 +02003502 else {
3503 /* Fail on all other handshake errors */
Willy Tarreau566dc552012-10-19 20:52:18 +02003504 /* Note: OpenSSL may leave unread bytes in the socket's
3505 * buffer, causing an RST to be emitted upon close() on
3506 * TCP sockets. We first try to drain possibly pending
3507 * data to avoid this as much as possible.
3508 */
Willy Tarreaud85c4852015-03-13 00:40:28 +01003509 conn_sock_drain(conn);
Willy Tarreau20879a02012-12-03 16:32:10 +01003510 if (!conn->err_code)
Willy Tarreauf51c6982014-04-25 20:02:39 +02003511 conn->err_code = (conn->xprt_st & SSL_SOCK_RECV_HEARTBEAT) ?
3512 CO_ER_SSL_KILLED_HB : CO_ER_SSL_HANDSHAKE;
Emeric Brun46591952012-05-18 15:47:34 +02003513 goto out_error;
3514 }
3515 }
3516
Emeric Brun674b7432012-11-08 19:21:55 +01003517reneg_ok:
Emeric Brun46591952012-05-18 15:47:34 +02003518 /* Handshake succeeded */
Willy Tarreau0c9c2722014-05-28 12:28:58 +02003519 if (!SSL_session_reused(conn->xprt_ctx)) {
3520 if (objt_server(conn->target)) {
3521 update_freq_ctr(&global.ssl_be_keys_per_sec, 1);
3522 if (global.ssl_be_keys_per_sec.curr_ctr > global.ssl_be_keys_max)
3523 global.ssl_be_keys_max = global.ssl_be_keys_per_sec.curr_ctr;
3524
Emeric Brun46591952012-05-18 15:47:34 +02003525 /* check if session was reused, if not store current session on server for reuse */
Willy Tarreau3fdb3662012-11-12 00:42:33 +01003526 if (objt_server(conn->target)->ssl_ctx.reused_sess)
3527 SSL_SESSION_free(objt_server(conn->target)->ssl_ctx.reused_sess);
Emeric Brun46591952012-05-18 15:47:34 +02003528
Willy Tarreau2a3fb1c2015-02-05 16:47:07 +01003529 if (!(objt_server(conn->target)->ssl_ctx.options & SRV_SSL_O_NO_REUSE))
3530 objt_server(conn->target)->ssl_ctx.reused_sess = SSL_get1_session(conn->xprt_ctx);
Emeric Brun46591952012-05-18 15:47:34 +02003531 }
Willy Tarreau0c9c2722014-05-28 12:28:58 +02003532 else {
3533 update_freq_ctr(&global.ssl_fe_keys_per_sec, 1);
3534 if (global.ssl_fe_keys_per_sec.curr_ctr > global.ssl_fe_keys_max)
3535 global.ssl_fe_keys_max = global.ssl_fe_keys_per_sec.curr_ctr;
3536 }
Emeric Brun46591952012-05-18 15:47:34 +02003537 }
3538
3539 /* The connection is now established at both layers, it's time to leave */
3540 conn->flags &= ~(flag | CO_FL_WAIT_L4_CONN | CO_FL_WAIT_L6_CONN);
3541 return 1;
3542
3543 out_error:
Emeric Brun644cde02012-12-14 11:21:13 +01003544 /* Clear openssl global errors stack */
3545 ERR_clear_error();
3546
Emeric Brun9fa89732012-10-04 17:09:56 +02003547 /* free resumed session if exists */
Willy Tarreau3fdb3662012-11-12 00:42:33 +01003548 if (objt_server(conn->target) && objt_server(conn->target)->ssl_ctx.reused_sess) {
3549 SSL_SESSION_free(objt_server(conn->target)->ssl_ctx.reused_sess);
3550 objt_server(conn->target)->ssl_ctx.reused_sess = NULL;
Emeric Brun9fa89732012-10-04 17:09:56 +02003551 }
3552
Emeric Brun46591952012-05-18 15:47:34 +02003553 /* Fail on all other handshake errors */
3554 conn->flags |= CO_FL_ERROR;
Willy Tarreau20879a02012-12-03 16:32:10 +01003555 if (!conn->err_code)
3556 conn->err_code = CO_ER_SSL_HANDSHAKE;
Emeric Brun46591952012-05-18 15:47:34 +02003557 return 0;
3558}
3559
3560/* Receive up to <count> bytes from connection <conn>'s socket and store them
Willy Tarreauabf08d92014-01-14 11:31:27 +01003561 * into buffer <buf>. Only one call to recv() is performed, unless the
Emeric Brun46591952012-05-18 15:47:34 +02003562 * buffer wraps, in which case a second call may be performed. The connection's
3563 * flags are updated with whatever special event is detected (error, read0,
3564 * empty). The caller is responsible for taking care of those events and
3565 * avoiding the call if inappropriate. The function does not call the
3566 * connection's polling update function, so the caller is responsible for this.
3567 */
3568static int ssl_sock_to_buf(struct connection *conn, struct buffer *buf, int count)
3569{
3570 int ret, done = 0;
Willy Tarreauabf08d92014-01-14 11:31:27 +01003571 int try;
Emeric Brun46591952012-05-18 15:47:34 +02003572
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02003573 if (!conn->xprt_ctx)
Emeric Brun46591952012-05-18 15:47:34 +02003574 goto out_error;
3575
3576 if (conn->flags & CO_FL_HANDSHAKE)
3577 /* a handshake was requested */
3578 return 0;
3579
Willy Tarreauabf08d92014-01-14 11:31:27 +01003580 /* let's realign the buffer to optimize I/O */
3581 if (buffer_empty(buf))
Emeric Brun46591952012-05-18 15:47:34 +02003582 buf->p = buf->data;
Emeric Brun46591952012-05-18 15:47:34 +02003583
3584 /* read the largest possible block. For this, we perform only one call
3585 * to recv() unless the buffer wraps and we exactly fill the first hunk,
3586 * in which case we accept to do it once again. A new attempt is made on
3587 * EINTR too.
3588 */
Willy Tarreau00b0fb92014-01-17 11:09:40 +01003589 while (count > 0) {
Willy Tarreauabf08d92014-01-14 11:31:27 +01003590 /* first check if we have some room after p+i */
3591 try = buf->data + buf->size - (buf->p + buf->i);
3592 /* otherwise continue between data and p-o */
3593 if (try <= 0) {
3594 try = buf->p - (buf->data + buf->o);
3595 if (try <= 0)
3596 break;
3597 }
3598 if (try > count)
3599 try = count;
3600
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02003601 ret = SSL_read(conn->xprt_ctx, bi_end(buf), try);
Emeric Brune1f38db2012-09-03 20:36:47 +02003602 if (conn->flags & CO_FL_ERROR) {
3603 /* CO_FL_ERROR may be set by ssl_sock_infocbk */
Emeric Brun644cde02012-12-14 11:21:13 +01003604 goto out_error;
Emeric Brune1f38db2012-09-03 20:36:47 +02003605 }
Emeric Brun46591952012-05-18 15:47:34 +02003606 if (ret > 0) {
3607 buf->i += ret;
3608 done += ret;
3609 if (ret < try)
3610 break;
3611 count -= ret;
Emeric Brun46591952012-05-18 15:47:34 +02003612 }
3613 else if (ret == 0) {
Emeric Brun644cde02012-12-14 11:21:13 +01003614 ret = SSL_get_error(conn->xprt_ctx, ret);
3615 if (ret != SSL_ERROR_ZERO_RETURN) {
Emeric Brun1c646862012-12-14 12:33:41 +01003616 /* error on protocol or underlying transport */
3617 if ((ret != SSL_ERROR_SYSCALL)
3618 || (errno && (errno != EAGAIN)))
3619 conn->flags |= CO_FL_ERROR;
3620
Emeric Brun644cde02012-12-14 11:21:13 +01003621 /* Clear openssl global errors stack */
3622 ERR_clear_error();
3623 }
Emeric Brun46591952012-05-18 15:47:34 +02003624 goto read0;
3625 }
3626 else {
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02003627 ret = SSL_get_error(conn->xprt_ctx, ret);
Emeric Brun46591952012-05-18 15:47:34 +02003628 if (ret == SSL_ERROR_WANT_WRITE) {
Emeric Brun8af8dd12012-11-08 17:56:20 +01003629 /* handshake is running, and it needs to enable write */
Emeric Brun46591952012-05-18 15:47:34 +02003630 conn->flags |= CO_FL_SSL_WAIT_HS;
Emeric Brun8af8dd12012-11-08 17:56:20 +01003631 __conn_sock_want_send(conn);
Emeric Brun46591952012-05-18 15:47:34 +02003632 break;
3633 }
3634 else if (ret == SSL_ERROR_WANT_READ) {
Emeric Brun282a76a2012-11-08 18:02:56 +01003635 if (SSL_renegotiate_pending(conn->xprt_ctx)) {
3636 /* handshake is running, and it may need to re-enable read */
3637 conn->flags |= CO_FL_SSL_WAIT_HS;
3638 __conn_sock_want_recv(conn);
3639 break;
3640 }
Emeric Brun46591952012-05-18 15:47:34 +02003641 /* we need to poll for retry a read later */
Willy Tarreaue1f50c42014-01-22 20:02:06 +01003642 fd_cant_recv(conn->t.sock.fd);
Emeric Brun46591952012-05-18 15:47:34 +02003643 break;
3644 }
3645 /* otherwise it's a real error */
3646 goto out_error;
3647 }
3648 }
3649 return done;
3650
3651 read0:
3652 conn_sock_read0(conn);
3653 return done;
3654 out_error:
Emeric Brun644cde02012-12-14 11:21:13 +01003655 /* Clear openssl global errors stack */
3656 ERR_clear_error();
3657
Emeric Brun46591952012-05-18 15:47:34 +02003658 conn->flags |= CO_FL_ERROR;
3659 return done;
3660}
3661
3662
3663/* Send all pending bytes from buffer <buf> to connection <conn>'s socket.
Willy Tarreau1049b1f2014-02-02 01:51:17 +01003664 * <flags> may contain some CO_SFL_* flags to hint the system about other
3665 * pending data for example, but this flag is ignored at the moment.
Emeric Brun46591952012-05-18 15:47:34 +02003666 * Only one call to send() is performed, unless the buffer wraps, in which case
3667 * a second call may be performed. The connection's flags are updated with
3668 * whatever special event is detected (error, empty). The caller is responsible
3669 * for taking care of those events and avoiding the call if inappropriate. The
3670 * function does not call the connection's polling update function, so the caller
3671 * is responsible for this.
3672 */
3673static int ssl_sock_from_buf(struct connection *conn, struct buffer *buf, int flags)
3674{
3675 int ret, try, done;
3676
3677 done = 0;
3678
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02003679 if (!conn->xprt_ctx)
Emeric Brun46591952012-05-18 15:47:34 +02003680 goto out_error;
3681
3682 if (conn->flags & CO_FL_HANDSHAKE)
3683 /* a handshake was requested */
3684 return 0;
3685
3686 /* send the largest possible block. For this we perform only one call
3687 * to send() unless the buffer wraps and we exactly fill the first hunk,
3688 * in which case we accept to do it once again.
3689 */
3690 while (buf->o) {
Kevin Hestercad82342013-05-30 15:12:41 -07003691 try = bo_contig_data(buf);
Willy Tarreaubfd59462013-02-21 07:46:09 +01003692
Willy Tarreau7bed9452014-02-02 02:00:24 +01003693 if (!(flags & CO_SFL_STREAMER) &&
Willy Tarreau518cedd2014-02-17 15:43:01 +01003694 !(conn->xprt_st & SSL_SOCK_SEND_UNLIMITED) &&
3695 global.tune.ssl_max_record && try > global.tune.ssl_max_record) {
Willy Tarreaubfd59462013-02-21 07:46:09 +01003696 try = global.tune.ssl_max_record;
Willy Tarreau518cedd2014-02-17 15:43:01 +01003697 }
3698 else {
3699 /* we need to keep the information about the fact that
3700 * we're not limiting the upcoming send(), because if it
3701 * fails, we'll have to retry with at least as many data.
3702 */
3703 conn->xprt_st |= SSL_SOCK_SEND_UNLIMITED;
3704 }
Willy Tarreaubfd59462013-02-21 07:46:09 +01003705
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02003706 ret = SSL_write(conn->xprt_ctx, bo_ptr(buf), try);
Willy Tarreau518cedd2014-02-17 15:43:01 +01003707
Emeric Brune1f38db2012-09-03 20:36:47 +02003708 if (conn->flags & CO_FL_ERROR) {
3709 /* CO_FL_ERROR may be set by ssl_sock_infocbk */
Emeric Brun644cde02012-12-14 11:21:13 +01003710 goto out_error;
Emeric Brune1f38db2012-09-03 20:36:47 +02003711 }
Emeric Brun46591952012-05-18 15:47:34 +02003712 if (ret > 0) {
Willy Tarreau518cedd2014-02-17 15:43:01 +01003713 conn->xprt_st &= ~SSL_SOCK_SEND_UNLIMITED;
3714
Emeric Brun46591952012-05-18 15:47:34 +02003715 buf->o -= ret;
3716 done += ret;
3717
Willy Tarreau5fb38032012-12-16 19:39:09 +01003718 if (likely(buffer_empty(buf)))
Emeric Brun46591952012-05-18 15:47:34 +02003719 /* optimize data alignment in the buffer */
3720 buf->p = buf->data;
3721
3722 /* if the system buffer is full, don't insist */
3723 if (ret < try)
3724 break;
3725 }
3726 else {
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02003727 ret = SSL_get_error(conn->xprt_ctx, ret);
Emeric Brun46591952012-05-18 15:47:34 +02003728 if (ret == SSL_ERROR_WANT_WRITE) {
Emeric Brun282a76a2012-11-08 18:02:56 +01003729 if (SSL_renegotiate_pending(conn->xprt_ctx)) {
3730 /* handshake is running, and it may need to re-enable write */
3731 conn->flags |= CO_FL_SSL_WAIT_HS;
3732 __conn_sock_want_send(conn);
3733 break;
3734 }
Emeric Brun46591952012-05-18 15:47:34 +02003735 /* we need to poll to retry a write later */
Willy Tarreaue1f50c42014-01-22 20:02:06 +01003736 fd_cant_send(conn->t.sock.fd);
Emeric Brun46591952012-05-18 15:47:34 +02003737 break;
3738 }
3739 else if (ret == SSL_ERROR_WANT_READ) {
Emeric Brun8af8dd12012-11-08 17:56:20 +01003740 /* handshake is running, and it needs to enable read */
Emeric Brun46591952012-05-18 15:47:34 +02003741 conn->flags |= CO_FL_SSL_WAIT_HS;
Emeric Brun8af8dd12012-11-08 17:56:20 +01003742 __conn_sock_want_recv(conn);
Emeric Brun46591952012-05-18 15:47:34 +02003743 break;
3744 }
3745 goto out_error;
3746 }
3747 }
3748 return done;
3749
3750 out_error:
Emeric Brun644cde02012-12-14 11:21:13 +01003751 /* Clear openssl global errors stack */
3752 ERR_clear_error();
3753
Emeric Brun46591952012-05-18 15:47:34 +02003754 conn->flags |= CO_FL_ERROR;
3755 return done;
3756}
3757
Emeric Brun46591952012-05-18 15:47:34 +02003758static void ssl_sock_close(struct connection *conn) {
3759
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02003760 if (conn->xprt_ctx) {
3761 SSL_free(conn->xprt_ctx);
3762 conn->xprt_ctx = NULL;
Willy Tarreau403edff2012-09-06 11:58:37 +02003763 sslconns--;
Emeric Brun46591952012-05-18 15:47:34 +02003764 }
Emeric Brun46591952012-05-18 15:47:34 +02003765}
3766
3767/* This function tries to perform a clean shutdown on an SSL connection, and in
3768 * any case, flags the connection as reusable if no handshake was in progress.
3769 */
3770static void ssl_sock_shutw(struct connection *conn, int clean)
3771{
3772 if (conn->flags & CO_FL_HANDSHAKE)
3773 return;
3774 /* no handshake was in progress, try a clean ssl shutdown */
Emeric Brun644cde02012-12-14 11:21:13 +01003775 if (clean && (SSL_shutdown(conn->xprt_ctx) <= 0)) {
3776 /* Clear openssl global errors stack */
3777 ERR_clear_error();
3778 }
Emeric Brun46591952012-05-18 15:47:34 +02003779
3780 /* force flag on ssl to keep session in cache regardless shutdown result */
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02003781 SSL_set_shutdown(conn->xprt_ctx, SSL_SENT_SHUTDOWN);
Emeric Brun46591952012-05-18 15:47:34 +02003782}
3783
Willy Tarreauffc3fcd2012-10-12 20:17:54 +02003784/* used for logging, may be changed for a sample fetch later */
3785const char *ssl_sock_get_cipher_name(struct connection *conn)
3786{
3787 if (!conn->xprt && !conn->xprt_ctx)
3788 return NULL;
3789 return SSL_get_cipher_name(conn->xprt_ctx);
3790}
3791
3792/* used for logging, may be changed for a sample fetch later */
3793const char *ssl_sock_get_proto_version(struct connection *conn)
3794{
3795 if (!conn->xprt && !conn->xprt_ctx)
3796 return NULL;
3797 return SSL_get_version(conn->xprt_ctx);
3798}
3799
Willy Tarreau8d598402012-10-22 17:58:39 +02003800/* Extract a serial from a cert, and copy it to a chunk.
3801 * Returns 1 if serial is found and copied, 0 if no serial found and
3802 * -1 if output is not large enough.
3803 */
3804static int
3805ssl_sock_get_serial(X509 *crt, struct chunk *out)
3806{
3807 ASN1_INTEGER *serial;
3808
3809 serial = X509_get_serialNumber(crt);
3810 if (!serial)
3811 return 0;
3812
3813 if (out->size < serial->length)
3814 return -1;
3815
3816 memcpy(out->str, serial->data, serial->length);
3817 out->len = serial->length;
3818 return 1;
3819}
3820
Emeric Brun43e79582014-10-29 19:03:26 +01003821/* Extract a cert to der, and copy it to a chunk.
3822 * Returns 1 if cert is found and copied, 0 on der convertion failure and
3823 * -1 if output is not large enough.
3824 */
3825static int
3826ssl_sock_crt2der(X509 *crt, struct chunk *out)
3827{
3828 int len;
3829 unsigned char *p = (unsigned char *)out->str;;
3830
3831 len =i2d_X509(crt, NULL);
3832 if (len <= 0)
3833 return 1;
3834
3835 if (out->size < len)
3836 return -1;
3837
3838 i2d_X509(crt,&p);
3839 out->len = len;
3840 return 1;
3841}
3842
Emeric Brunce5ad802012-10-22 14:11:22 +02003843
3844/* Copy Date in ASN1_UTCTIME format in struct chunk out.
3845 * Returns 1 if serial is found and copied, 0 if no valid time found
3846 * and -1 if output is not large enough.
3847 */
3848static int
3849ssl_sock_get_time(ASN1_TIME *tm, struct chunk *out)
3850{
3851 if (tm->type == V_ASN1_GENERALIZEDTIME) {
3852 ASN1_GENERALIZEDTIME *gentm = (ASN1_GENERALIZEDTIME *)tm;
3853
3854 if (gentm->length < 12)
3855 return 0;
3856 if (gentm->data[0] != 0x32 || gentm->data[1] != 0x30)
3857 return 0;
3858 if (out->size < gentm->length-2)
3859 return -1;
3860
3861 memcpy(out->str, gentm->data+2, gentm->length-2);
3862 out->len = gentm->length-2;
3863 return 1;
3864 }
3865 else if (tm->type == V_ASN1_UTCTIME) {
3866 ASN1_UTCTIME *utctm = (ASN1_UTCTIME *)tm;
3867
3868 if (utctm->length < 10)
3869 return 0;
3870 if (utctm->data[0] >= 0x35)
3871 return 0;
3872 if (out->size < utctm->length)
3873 return -1;
3874
3875 memcpy(out->str, utctm->data, utctm->length);
3876 out->len = utctm->length;
3877 return 1;
3878 }
3879
3880 return 0;
3881}
3882
Emeric Brun87855892012-10-17 17:39:35 +02003883/* Extract an entry from a X509_NAME and copy its value to an output chunk.
3884 * Returns 1 if entry found, 0 if entry not found, or -1 if output not large enough.
3885 */
3886static int
3887ssl_sock_get_dn_entry(X509_NAME *a, const struct chunk *entry, int pos, struct chunk *out)
3888{
3889 X509_NAME_ENTRY *ne;
3890 int i, j, n;
3891 int cur = 0;
3892 const char *s;
3893 char tmp[128];
3894
3895 out->len = 0;
3896 for (i = 0; i < sk_X509_NAME_ENTRY_num(a->entries); i++) {
3897 if (pos < 0)
3898 j = (sk_X509_NAME_ENTRY_num(a->entries)-1) - i;
3899 else
3900 j = i;
3901
3902 ne = sk_X509_NAME_ENTRY_value(a->entries, j);
3903 n = OBJ_obj2nid(ne->object);
3904 if ((n == NID_undef) || ((s = OBJ_nid2sn(n)) == NULL)) {
3905 i2t_ASN1_OBJECT(tmp, sizeof(tmp), ne->object);
3906 s = tmp;
3907 }
3908
3909 if (chunk_strcasecmp(entry, s) != 0)
3910 continue;
3911
3912 if (pos < 0)
3913 cur--;
3914 else
3915 cur++;
3916
3917 if (cur != pos)
3918 continue;
3919
3920 if (ne->value->length > out->size)
3921 return -1;
3922
3923 memcpy(out->str, ne->value->data, ne->value->length);
3924 out->len = ne->value->length;
3925 return 1;
3926 }
3927
3928 return 0;
3929
3930}
3931
3932/* Extract and format full DN from a X509_NAME and copy result into a chunk
3933 * Returns 1 if dn entries exits, 0 if no dn entry found or -1 if output is not large enough.
3934 */
3935static int
3936ssl_sock_get_dn_oneline(X509_NAME *a, struct chunk *out)
3937{
3938 X509_NAME_ENTRY *ne;
3939 int i, n, ln;
3940 int l = 0;
3941 const char *s;
3942 char *p;
3943 char tmp[128];
3944
3945 out->len = 0;
3946 p = out->str;
3947 for (i = 0; i < sk_X509_NAME_ENTRY_num(a->entries); i++) {
3948 ne = sk_X509_NAME_ENTRY_value(a->entries, i);
3949 n = OBJ_obj2nid(ne->object);
3950 if ((n == NID_undef) || ((s = OBJ_nid2sn(n)) == NULL)) {
3951 i2t_ASN1_OBJECT(tmp, sizeof(tmp), ne->object);
3952 s = tmp;
3953 }
3954 ln = strlen(s);
3955
3956 l += 1 + ln + 1 + ne->value->length;
3957 if (l > out->size)
3958 return -1;
3959 out->len = l;
3960
3961 *(p++)='/';
3962 memcpy(p, s, ln);
3963 p += ln;
3964 *(p++)='=';
3965 memcpy(p, ne->value->data, ne->value->length);
3966 p += ne->value->length;
3967 }
3968
3969 if (!out->len)
3970 return 0;
3971
3972 return 1;
3973}
3974
David Safb76832014-05-08 23:42:08 -04003975char *ssl_sock_get_version(struct connection *conn)
3976{
3977 if (!ssl_sock_is_ssl(conn))
3978 return NULL;
3979
3980 return (char *)SSL_get_version(conn->xprt_ctx);
3981}
3982
Willy Tarreau63076412015-07-10 11:33:32 +02003983void ssl_sock_set_servername(struct connection *conn, const char *hostname)
3984{
3985#ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME
3986 if (!ssl_sock_is_ssl(conn))
3987 return;
3988
3989 SSL_set_tlsext_host_name(conn->xprt_ctx, hostname);
3990#endif
3991}
3992
Emeric Brun0abf8362014-06-24 18:26:41 +02003993/* Extract peer certificate's common name into the chunk dest
3994 * Returns
3995 * the len of the extracted common name
3996 * or 0 if no CN found in DN
3997 * or -1 on error case (i.e. no peer certificate)
3998 */
3999int ssl_sock_get_remote_common_name(struct connection *conn, struct chunk *dest)
David Safb76832014-05-08 23:42:08 -04004000{
4001 X509 *crt = NULL;
4002 X509_NAME *name;
David Safb76832014-05-08 23:42:08 -04004003 const char find_cn[] = "CN";
4004 const struct chunk find_cn_chunk = {
4005 .str = (char *)&find_cn,
4006 .len = sizeof(find_cn)-1
4007 };
Emeric Brun0abf8362014-06-24 18:26:41 +02004008 int result = -1;
David Safb76832014-05-08 23:42:08 -04004009
4010 if (!ssl_sock_is_ssl(conn))
Emeric Brun0abf8362014-06-24 18:26:41 +02004011 goto out;
David Safb76832014-05-08 23:42:08 -04004012
4013 /* SSL_get_peer_certificate, it increase X509 * ref count */
4014 crt = SSL_get_peer_certificate(conn->xprt_ctx);
4015 if (!crt)
4016 goto out;
4017
4018 name = X509_get_subject_name(crt);
4019 if (!name)
4020 goto out;
David Safb76832014-05-08 23:42:08 -04004021
Emeric Brun0abf8362014-06-24 18:26:41 +02004022 result = ssl_sock_get_dn_entry(name, &find_cn_chunk, 1, dest);
4023out:
David Safb76832014-05-08 23:42:08 -04004024 if (crt)
4025 X509_free(crt);
4026
4027 return result;
4028}
4029
Dave McCowan328fb582014-07-30 10:39:13 -04004030/* returns 1 if client passed a certificate for this session, 0 if not */
4031int ssl_sock_get_cert_used_sess(struct connection *conn)
4032{
4033 X509 *crt = NULL;
4034
4035 if (!ssl_sock_is_ssl(conn))
4036 return 0;
4037
4038 /* SSL_get_peer_certificate, it increase X509 * ref count */
4039 crt = SSL_get_peer_certificate(conn->xprt_ctx);
4040 if (!crt)
4041 return 0;
4042
4043 X509_free(crt);
4044 return 1;
4045}
4046
4047/* returns 1 if client passed a certificate for this connection, 0 if not */
4048int ssl_sock_get_cert_used_conn(struct connection *conn)
David Safb76832014-05-08 23:42:08 -04004049{
4050 if (!ssl_sock_is_ssl(conn))
4051 return 0;
4052
4053 return SSL_SOCK_ST_FL_VERIFY_DONE & conn->xprt_st ? 1 : 0;
4054}
4055
4056/* returns result from SSL verify */
4057unsigned int ssl_sock_get_verify_result(struct connection *conn)
4058{
4059 if (!ssl_sock_is_ssl(conn))
4060 return (unsigned int)X509_V_ERR_APPLICATION_VERIFICATION;
4061
4062 return (unsigned int)SSL_get_verify_result(conn->xprt_ctx);
4063}
4064
Willy Tarreau7875d092012-09-10 08:20:03 +02004065/***** Below are some sample fetching functions for ACL/patterns *****/
4066
Emeric Brune64aef12012-09-21 13:15:06 +02004067/* boolean, returns true if client cert was present */
4068static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02004069smp_fetch_ssl_fc_has_crt(const struct arg *args, struct sample *smp, const char *kw, void *private)
Emeric Brune64aef12012-09-21 13:15:06 +02004070{
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004071 struct connection *conn;
4072
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02004073 conn = objt_conn(smp->sess->origin);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004074 if (!conn || conn->xprt != &ssl_sock)
Emeric Brune64aef12012-09-21 13:15:06 +02004075 return 0;
4076
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004077 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brune64aef12012-09-21 13:15:06 +02004078 smp->flags |= SMP_F_MAY_CHANGE;
4079 return 0;
4080 }
4081
4082 smp->flags = 0;
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02004083 smp->data.type = SMP_T_BOOL;
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02004084 smp->data.u.sint = SSL_SOCK_ST_FL_VERIFY_DONE & conn->xprt_st ? 1 : 0;
Emeric Brune64aef12012-09-21 13:15:06 +02004085
4086 return 1;
4087}
4088
Emeric Brun43e79582014-10-29 19:03:26 +01004089/* binary, returns a certificate in a binary chunk (der/raw).
4090 * The 5th keyword char is used to know if SSL_get_certificate or SSL_get_peer_certificate
4091 * should be use.
4092 */
4093static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02004094smp_fetch_ssl_x_der(const struct arg *args, struct sample *smp, const char *kw, void *private)
Emeric Brun43e79582014-10-29 19:03:26 +01004095{
4096 int cert_peer = (kw[4] == 'c') ? 1 : 0;
4097 X509 *crt = NULL;
4098 int ret = 0;
4099 struct chunk *smp_trash;
4100 struct connection *conn;
4101
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02004102 conn = objt_conn(smp->sess->origin);
Emeric Brun43e79582014-10-29 19:03:26 +01004103 if (!conn || conn->xprt != &ssl_sock)
4104 return 0;
4105
4106 if (!(conn->flags & CO_FL_CONNECTED)) {
4107 smp->flags |= SMP_F_MAY_CHANGE;
4108 return 0;
4109 }
4110
4111 if (cert_peer)
4112 crt = SSL_get_peer_certificate(conn->xprt_ctx);
4113 else
4114 crt = SSL_get_certificate(conn->xprt_ctx);
4115
4116 if (!crt)
4117 goto out;
4118
4119 smp_trash = get_trash_chunk();
4120 if (ssl_sock_crt2der(crt, smp_trash) <= 0)
4121 goto out;
4122
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02004123 smp->data.u.str = *smp_trash;
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02004124 smp->data.type = SMP_T_BIN;
Emeric Brun43e79582014-10-29 19:03:26 +01004125 ret = 1;
4126out:
4127 /* SSL_get_peer_certificate, it increase X509 * ref count */
4128 if (cert_peer && crt)
4129 X509_free(crt);
4130 return ret;
4131}
4132
Emeric Brunba841a12014-04-30 17:05:08 +02004133/* binary, returns serial of certificate in a binary chunk.
4134 * The 5th keyword char is used to know if SSL_get_certificate or SSL_get_peer_certificate
4135 * should be use.
4136 */
Willy Tarreau8d598402012-10-22 17:58:39 +02004137static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02004138smp_fetch_ssl_x_serial(const struct arg *args, struct sample *smp, const char *kw, void *private)
Willy Tarreau8d598402012-10-22 17:58:39 +02004139{
Emeric Brunba841a12014-04-30 17:05:08 +02004140 int cert_peer = (kw[4] == 'c') ? 1 : 0;
Willy Tarreau8d598402012-10-22 17:58:39 +02004141 X509 *crt = NULL;
4142 int ret = 0;
4143 struct chunk *smp_trash;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004144 struct connection *conn;
4145
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02004146 conn = objt_conn(smp->sess->origin);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004147 if (!conn || conn->xprt != &ssl_sock)
Willy Tarreau8d598402012-10-22 17:58:39 +02004148 return 0;
4149
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004150 if (!(conn->flags & CO_FL_CONNECTED)) {
Willy Tarreau8d598402012-10-22 17:58:39 +02004151 smp->flags |= SMP_F_MAY_CHANGE;
4152 return 0;
4153 }
4154
Emeric Brunba841a12014-04-30 17:05:08 +02004155 if (cert_peer)
4156 crt = SSL_get_peer_certificate(conn->xprt_ctx);
4157 else
4158 crt = SSL_get_certificate(conn->xprt_ctx);
4159
Willy Tarreau8d598402012-10-22 17:58:39 +02004160 if (!crt)
4161 goto out;
4162
Willy Tarreau47ca5452012-12-23 20:22:19 +01004163 smp_trash = get_trash_chunk();
Willy Tarreau8d598402012-10-22 17:58:39 +02004164 if (ssl_sock_get_serial(crt, smp_trash) <= 0)
4165 goto out;
4166
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02004167 smp->data.u.str = *smp_trash;
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02004168 smp->data.type = SMP_T_BIN;
Willy Tarreau8d598402012-10-22 17:58:39 +02004169 ret = 1;
4170out:
Emeric Brunba841a12014-04-30 17:05:08 +02004171 /* SSL_get_peer_certificate, it increase X509 * ref count */
4172 if (cert_peer && crt)
Willy Tarreau8d598402012-10-22 17:58:39 +02004173 X509_free(crt);
4174 return ret;
4175}
Emeric Brune64aef12012-09-21 13:15:06 +02004176
Emeric Brunba841a12014-04-30 17:05:08 +02004177/* binary, returns the client certificate's SHA-1 fingerprint (SHA-1 hash of DER-encoded certificate) in a binary chunk.
4178 * The 5th keyword char is used to know if SSL_get_certificate or SSL_get_peer_certificate
4179 * should be use.
4180 */
James Votha051b4a2013-05-14 20:37:59 +02004181static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02004182smp_fetch_ssl_x_sha1(const struct arg *args, struct sample *smp, const char *kw, void *private)
James Votha051b4a2013-05-14 20:37:59 +02004183{
Emeric Brunba841a12014-04-30 17:05:08 +02004184 int cert_peer = (kw[4] == 'c') ? 1 : 0;
James Votha051b4a2013-05-14 20:37:59 +02004185 X509 *crt = NULL;
4186 const EVP_MD *digest;
4187 int ret = 0;
4188 struct chunk *smp_trash;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004189 struct connection *conn;
James Votha051b4a2013-05-14 20:37:59 +02004190
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02004191 conn = objt_conn(smp->sess->origin);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004192 if (!conn || conn->xprt != &ssl_sock)
4193 return 0;
4194
4195 if (!(conn->flags & CO_FL_CONNECTED)) {
James Votha051b4a2013-05-14 20:37:59 +02004196 smp->flags |= SMP_F_MAY_CHANGE;
4197 return 0;
4198 }
4199
Emeric Brunba841a12014-04-30 17:05:08 +02004200 if (cert_peer)
4201 crt = SSL_get_peer_certificate(conn->xprt_ctx);
4202 else
4203 crt = SSL_get_certificate(conn->xprt_ctx);
James Votha051b4a2013-05-14 20:37:59 +02004204 if (!crt)
4205 goto out;
4206
4207 smp_trash = get_trash_chunk();
4208 digest = EVP_sha1();
4209 X509_digest(crt, digest, (unsigned char *)smp_trash->str, (unsigned int *)&smp_trash->len);
4210
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02004211 smp->data.u.str = *smp_trash;
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02004212 smp->data.type = SMP_T_BIN;
James Votha051b4a2013-05-14 20:37:59 +02004213 ret = 1;
4214out:
Emeric Brunba841a12014-04-30 17:05:08 +02004215 /* SSL_get_peer_certificate, it increase X509 * ref count */
4216 if (cert_peer && crt)
James Votha051b4a2013-05-14 20:37:59 +02004217 X509_free(crt);
4218 return ret;
4219}
4220
Emeric Brunba841a12014-04-30 17:05:08 +02004221/* string, returns certificate's notafter date in ASN1_UTCTIME format.
4222 * The 5th keyword char is used to know if SSL_get_certificate or SSL_get_peer_certificate
4223 * should be use.
4224 */
Emeric Brunce5ad802012-10-22 14:11:22 +02004225static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02004226smp_fetch_ssl_x_notafter(const struct arg *args, struct sample *smp, const char *kw, void *private)
Emeric Brunce5ad802012-10-22 14:11:22 +02004227{
Emeric Brunba841a12014-04-30 17:05:08 +02004228 int cert_peer = (kw[4] == 'c') ? 1 : 0;
Emeric Brunce5ad802012-10-22 14:11:22 +02004229 X509 *crt = NULL;
4230 int ret = 0;
4231 struct chunk *smp_trash;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004232 struct connection *conn;
Emeric Brunce5ad802012-10-22 14:11:22 +02004233
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02004234 conn = objt_conn(smp->sess->origin);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004235 if (!conn || conn->xprt != &ssl_sock)
4236 return 0;
4237
4238 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brunce5ad802012-10-22 14:11:22 +02004239 smp->flags |= SMP_F_MAY_CHANGE;
4240 return 0;
4241 }
4242
Emeric Brunba841a12014-04-30 17:05:08 +02004243 if (cert_peer)
4244 crt = SSL_get_peer_certificate(conn->xprt_ctx);
4245 else
4246 crt = SSL_get_certificate(conn->xprt_ctx);
Emeric Brunce5ad802012-10-22 14:11:22 +02004247 if (!crt)
4248 goto out;
4249
Willy Tarreau47ca5452012-12-23 20:22:19 +01004250 smp_trash = get_trash_chunk();
Emeric Brunce5ad802012-10-22 14:11:22 +02004251 if (ssl_sock_get_time(X509_get_notAfter(crt), smp_trash) <= 0)
4252 goto out;
4253
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02004254 smp->data.u.str = *smp_trash;
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02004255 smp->data.type = SMP_T_STR;
Emeric Brunce5ad802012-10-22 14:11:22 +02004256 ret = 1;
4257out:
Emeric Brunba841a12014-04-30 17:05:08 +02004258 /* SSL_get_peer_certificate, it increase X509 * ref count */
4259 if (cert_peer && crt)
Emeric Brunce5ad802012-10-22 14:11:22 +02004260 X509_free(crt);
4261 return ret;
4262}
4263
Emeric Brunba841a12014-04-30 17:05:08 +02004264/* string, returns a string of a formatted full dn \C=..\O=..\OU=.. \CN=.. of certificate's issuer
4265 * The 5th keyword char is used to know if SSL_get_certificate or SSL_get_peer_certificate
4266 * should be use.
4267 */
Emeric Brun87855892012-10-17 17:39:35 +02004268static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02004269smp_fetch_ssl_x_i_dn(const struct arg *args, struct sample *smp, const char *kw, void *private)
Emeric Brun87855892012-10-17 17:39:35 +02004270{
Emeric Brunba841a12014-04-30 17:05:08 +02004271 int cert_peer = (kw[4] == 'c') ? 1 : 0;
Emeric Brun87855892012-10-17 17:39:35 +02004272 X509 *crt = NULL;
4273 X509_NAME *name;
4274 int ret = 0;
4275 struct chunk *smp_trash;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004276 struct connection *conn;
Emeric Brun87855892012-10-17 17:39:35 +02004277
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02004278 conn = objt_conn(smp->sess->origin);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004279 if (!conn || conn->xprt != &ssl_sock)
4280 return 0;
4281
4282 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brun87855892012-10-17 17:39:35 +02004283 smp->flags |= SMP_F_MAY_CHANGE;
4284 return 0;
4285 }
4286
Emeric Brunba841a12014-04-30 17:05:08 +02004287 if (cert_peer)
4288 crt = SSL_get_peer_certificate(conn->xprt_ctx);
4289 else
4290 crt = SSL_get_certificate(conn->xprt_ctx);
Emeric Brun87855892012-10-17 17:39:35 +02004291 if (!crt)
4292 goto out;
4293
4294 name = X509_get_issuer_name(crt);
4295 if (!name)
4296 goto out;
4297
Willy Tarreau47ca5452012-12-23 20:22:19 +01004298 smp_trash = get_trash_chunk();
Emeric Brun87855892012-10-17 17:39:35 +02004299 if (args && args[0].type == ARGT_STR) {
4300 int pos = 1;
4301
4302 if (args[1].type == ARGT_SINT)
4303 pos = args[1].data.sint;
Emeric Brun87855892012-10-17 17:39:35 +02004304
4305 if (ssl_sock_get_dn_entry(name, &args[0].data.str, pos, smp_trash) <= 0)
4306 goto out;
4307 }
4308 else if (ssl_sock_get_dn_oneline(name, smp_trash) <= 0)
4309 goto out;
4310
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02004311 smp->data.type = SMP_T_STR;
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02004312 smp->data.u.str = *smp_trash;
Emeric Brun87855892012-10-17 17:39:35 +02004313 ret = 1;
4314out:
Emeric Brunba841a12014-04-30 17:05:08 +02004315 /* SSL_get_peer_certificate, it increase X509 * ref count */
4316 if (cert_peer && crt)
Emeric Brun87855892012-10-17 17:39:35 +02004317 X509_free(crt);
4318 return ret;
4319}
4320
Emeric Brunba841a12014-04-30 17:05:08 +02004321/* string, returns notbefore date in ASN1_UTCTIME format.
4322 * The 5th keyword char is used to know if SSL_get_certificate or SSL_get_peer_certificate
4323 * should be use.
4324 */
Emeric Brunce5ad802012-10-22 14:11:22 +02004325static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02004326smp_fetch_ssl_x_notbefore(const struct arg *args, struct sample *smp, const char *kw, void *private)
Emeric Brunce5ad802012-10-22 14:11:22 +02004327{
Emeric Brunba841a12014-04-30 17:05:08 +02004328 int cert_peer = (kw[4] == 'c') ? 1 : 0;
Emeric Brunce5ad802012-10-22 14:11:22 +02004329 X509 *crt = NULL;
4330 int ret = 0;
4331 struct chunk *smp_trash;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004332 struct connection *conn;
4333
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02004334 conn = objt_conn(smp->sess->origin);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004335 if (!conn || conn->xprt != &ssl_sock)
Emeric Brunce5ad802012-10-22 14:11:22 +02004336 return 0;
4337
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004338 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brunce5ad802012-10-22 14:11:22 +02004339 smp->flags |= SMP_F_MAY_CHANGE;
4340 return 0;
4341 }
4342
Emeric Brunba841a12014-04-30 17:05:08 +02004343 if (cert_peer)
4344 crt = SSL_get_peer_certificate(conn->xprt_ctx);
4345 else
4346 crt = SSL_get_certificate(conn->xprt_ctx);
Emeric Brunce5ad802012-10-22 14:11:22 +02004347 if (!crt)
4348 goto out;
4349
Willy Tarreau47ca5452012-12-23 20:22:19 +01004350 smp_trash = get_trash_chunk();
Emeric Brunce5ad802012-10-22 14:11:22 +02004351 if (ssl_sock_get_time(X509_get_notBefore(crt), smp_trash) <= 0)
4352 goto out;
4353
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02004354 smp->data.u.str = *smp_trash;
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02004355 smp->data.type = SMP_T_STR;
Emeric Brunce5ad802012-10-22 14:11:22 +02004356 ret = 1;
4357out:
Emeric Brunba841a12014-04-30 17:05:08 +02004358 /* SSL_get_peer_certificate, it increase X509 * ref count */
4359 if (cert_peer && crt)
Emeric Brunce5ad802012-10-22 14:11:22 +02004360 X509_free(crt);
4361 return ret;
4362}
4363
Emeric Brunba841a12014-04-30 17:05:08 +02004364/* string, returns a string of a formatted full dn \C=..\O=..\OU=.. \CN=.. of certificate's subject
4365 * The 5th keyword char is used to know if SSL_get_certificate or SSL_get_peer_certificate
4366 * should be use.
4367 */
Emeric Brun87855892012-10-17 17:39:35 +02004368static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02004369smp_fetch_ssl_x_s_dn(const struct arg *args, struct sample *smp, const char *kw, void *private)
Emeric Brun87855892012-10-17 17:39:35 +02004370{
Emeric Brunba841a12014-04-30 17:05:08 +02004371 int cert_peer = (kw[4] == 'c') ? 1 : 0;
Emeric Brun87855892012-10-17 17:39:35 +02004372 X509 *crt = NULL;
4373 X509_NAME *name;
4374 int ret = 0;
4375 struct chunk *smp_trash;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004376 struct connection *conn;
Emeric Brun87855892012-10-17 17:39:35 +02004377
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02004378 conn = objt_conn(smp->sess->origin);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004379 if (!conn || conn->xprt != &ssl_sock)
4380 return 0;
4381
4382 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brun87855892012-10-17 17:39:35 +02004383 smp->flags |= SMP_F_MAY_CHANGE;
4384 return 0;
4385 }
4386
Emeric Brunba841a12014-04-30 17:05:08 +02004387 if (cert_peer)
4388 crt = SSL_get_peer_certificate(conn->xprt_ctx);
4389 else
4390 crt = SSL_get_certificate(conn->xprt_ctx);
Emeric Brun87855892012-10-17 17:39:35 +02004391 if (!crt)
4392 goto out;
4393
4394 name = X509_get_subject_name(crt);
4395 if (!name)
4396 goto out;
4397
Willy Tarreau47ca5452012-12-23 20:22:19 +01004398 smp_trash = get_trash_chunk();
Emeric Brun87855892012-10-17 17:39:35 +02004399 if (args && args[0].type == ARGT_STR) {
4400 int pos = 1;
4401
4402 if (args[1].type == ARGT_SINT)
4403 pos = args[1].data.sint;
Emeric Brun87855892012-10-17 17:39:35 +02004404
4405 if (ssl_sock_get_dn_entry(name, &args[0].data.str, pos, smp_trash) <= 0)
4406 goto out;
4407 }
4408 else if (ssl_sock_get_dn_oneline(name, smp_trash) <= 0)
4409 goto out;
4410
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02004411 smp->data.type = SMP_T_STR;
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02004412 smp->data.u.str = *smp_trash;
Emeric Brun87855892012-10-17 17:39:35 +02004413 ret = 1;
4414out:
Emeric Brunba841a12014-04-30 17:05:08 +02004415 /* SSL_get_peer_certificate, it increase X509 * ref count */
4416 if (cert_peer && crt)
Emeric Brun87855892012-10-17 17:39:35 +02004417 X509_free(crt);
4418 return ret;
4419}
Emeric Brun9143d372012-12-20 15:44:16 +01004420
4421/* integer, returns true if current session use a client certificate */
4422static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02004423smp_fetch_ssl_c_used(const struct arg *args, struct sample *smp, const char *kw, void *private)
Emeric Brun9143d372012-12-20 15:44:16 +01004424{
4425 X509 *crt;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004426 struct connection *conn;
Emeric Brun9143d372012-12-20 15:44:16 +01004427
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02004428 conn = objt_conn(smp->sess->origin);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004429 if (!conn || conn->xprt != &ssl_sock)
4430 return 0;
4431
4432 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brun9143d372012-12-20 15:44:16 +01004433 smp->flags |= SMP_F_MAY_CHANGE;
4434 return 0;
4435 }
4436
4437 /* SSL_get_peer_certificate returns a ptr on allocated X509 struct */
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004438 crt = SSL_get_peer_certificate(conn->xprt_ctx);
Emeric Brun9143d372012-12-20 15:44:16 +01004439 if (crt) {
4440 X509_free(crt);
4441 }
4442
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02004443 smp->data.type = SMP_T_BOOL;
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02004444 smp->data.u.sint = (crt != NULL);
Emeric Brun9143d372012-12-20 15:44:16 +01004445 return 1;
4446}
4447
Emeric Brunba841a12014-04-30 17:05:08 +02004448/* integer, returns the certificate version
4449 * The 5th keyword char is used to know if SSL_get_certificate or SSL_get_peer_certificate
4450 * should be use.
4451 */
Emeric Bruna7359fd2012-10-17 15:03:11 +02004452static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02004453smp_fetch_ssl_x_version(const struct arg *args, struct sample *smp, const char *kw, void *private)
Emeric Bruna7359fd2012-10-17 15:03:11 +02004454{
Emeric Brunba841a12014-04-30 17:05:08 +02004455 int cert_peer = (kw[4] == 'c') ? 1 : 0;
Emeric Bruna7359fd2012-10-17 15:03:11 +02004456 X509 *crt;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004457 struct connection *conn;
4458
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02004459 conn = objt_conn(smp->sess->origin);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004460 if (!conn || conn->xprt != &ssl_sock)
Emeric Bruna7359fd2012-10-17 15:03:11 +02004461 return 0;
4462
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004463 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Bruna7359fd2012-10-17 15:03:11 +02004464 smp->flags |= SMP_F_MAY_CHANGE;
4465 return 0;
4466 }
4467
Emeric Brunba841a12014-04-30 17:05:08 +02004468 if (cert_peer)
4469 crt = SSL_get_peer_certificate(conn->xprt_ctx);
4470 else
4471 crt = SSL_get_certificate(conn->xprt_ctx);
Emeric Bruna7359fd2012-10-17 15:03:11 +02004472 if (!crt)
4473 return 0;
4474
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02004475 smp->data.u.sint = (unsigned int)(1 + X509_get_version(crt));
Emeric Brunba841a12014-04-30 17:05:08 +02004476 /* SSL_get_peer_certificate increase X509 * ref count */
4477 if (cert_peer)
4478 X509_free(crt);
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02004479 smp->data.type = SMP_T_SINT;
Emeric Bruna7359fd2012-10-17 15:03:11 +02004480
4481 return 1;
4482}
4483
Emeric Brunba841a12014-04-30 17:05:08 +02004484/* string, returns the certificate's signature algorithm.
4485 * The 5th keyword char is used to know if SSL_get_certificate or SSL_get_peer_certificate
4486 * should be use.
4487 */
Emeric Brun7f56e742012-10-19 18:15:40 +02004488static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02004489smp_fetch_ssl_x_sig_alg(const struct arg *args, struct sample *smp, const char *kw, void *private)
Emeric Brun7f56e742012-10-19 18:15:40 +02004490{
Emeric Brunba841a12014-04-30 17:05:08 +02004491 int cert_peer = (kw[4] == 'c') ? 1 : 0;
Emeric Brun7f56e742012-10-19 18:15:40 +02004492 X509 *crt;
4493 int nid;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004494 struct connection *conn;
Emeric Brun7f56e742012-10-19 18:15:40 +02004495
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02004496 conn = objt_conn(smp->sess->origin);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004497 if (!conn || conn->xprt != &ssl_sock)
4498 return 0;
4499
4500 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brun7f56e742012-10-19 18:15:40 +02004501 smp->flags |= SMP_F_MAY_CHANGE;
4502 return 0;
4503 }
4504
Emeric Brunba841a12014-04-30 17:05:08 +02004505 if (cert_peer)
4506 crt = SSL_get_peer_certificate(conn->xprt_ctx);
4507 else
4508 crt = SSL_get_certificate(conn->xprt_ctx);
Emeric Brun7f56e742012-10-19 18:15:40 +02004509 if (!crt)
4510 return 0;
4511
4512 nid = OBJ_obj2nid((ASN1_OBJECT *)(crt->cert_info->signature->algorithm));
4513
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02004514 smp->data.u.str.str = (char *)OBJ_nid2sn(nid);
4515 if (!smp->data.u.str.str) {
Emeric Brunba841a12014-04-30 17:05:08 +02004516 /* SSL_get_peer_certificate increase X509 * ref count */
4517 if (cert_peer)
4518 X509_free(crt);
Emeric Brun7f56e742012-10-19 18:15:40 +02004519 return 0;
Emeric Brun9bf3ba22013-10-07 14:31:44 +02004520 }
Emeric Brun7f56e742012-10-19 18:15:40 +02004521
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02004522 smp->data.type = SMP_T_STR;
Thierry FOURNIER7654c9f2013-12-17 00:20:33 +01004523 smp->flags |= SMP_F_CONST;
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02004524 smp->data.u.str.len = strlen(smp->data.u.str.str);
Emeric Brunba841a12014-04-30 17:05:08 +02004525 /* SSL_get_peer_certificate increase X509 * ref count */
4526 if (cert_peer)
4527 X509_free(crt);
Emeric Brun7f56e742012-10-19 18:15:40 +02004528
4529 return 1;
4530}
4531
Emeric Brunba841a12014-04-30 17:05:08 +02004532/* string, returns the certificate's key algorithm.
4533 * The 5th keyword char is used to know if SSL_get_certificate or SSL_get_peer_certificate
4534 * should be use.
4535 */
Emeric Brun521a0112012-10-22 12:22:55 +02004536static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02004537smp_fetch_ssl_x_key_alg(const struct arg *args, struct sample *smp, const char *kw, void *private)
Emeric Brun521a0112012-10-22 12:22:55 +02004538{
Emeric Brunba841a12014-04-30 17:05:08 +02004539 int cert_peer = (kw[4] == 'c') ? 1 : 0;
Emeric Brun521a0112012-10-22 12:22:55 +02004540 X509 *crt;
4541 int nid;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004542 struct connection *conn;
Emeric Brun521a0112012-10-22 12:22:55 +02004543
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02004544 conn = objt_conn(smp->sess->origin);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004545 if (!conn || conn->xprt != &ssl_sock)
4546 return 0;
4547
4548 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brun521a0112012-10-22 12:22:55 +02004549 smp->flags |= SMP_F_MAY_CHANGE;
4550 return 0;
4551 }
4552
Emeric Brunba841a12014-04-30 17:05:08 +02004553 if (cert_peer)
4554 crt = SSL_get_peer_certificate(conn->xprt_ctx);
4555 else
4556 crt = SSL_get_certificate(conn->xprt_ctx);
Emeric Brun521a0112012-10-22 12:22:55 +02004557 if (!crt)
4558 return 0;
4559
4560 nid = OBJ_obj2nid((ASN1_OBJECT *)(crt->cert_info->key->algor->algorithm));
4561
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02004562 smp->data.u.str.str = (char *)OBJ_nid2sn(nid);
4563 if (!smp->data.u.str.str) {
Emeric Brunba841a12014-04-30 17:05:08 +02004564 /* SSL_get_peer_certificate increase X509 * ref count */
4565 if (cert_peer)
4566 X509_free(crt);
Emeric Brun521a0112012-10-22 12:22:55 +02004567 return 0;
Emeric Brun9bf3ba22013-10-07 14:31:44 +02004568 }
Emeric Brun521a0112012-10-22 12:22:55 +02004569
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02004570 smp->data.type = SMP_T_STR;
Thierry FOURNIER7654c9f2013-12-17 00:20:33 +01004571 smp->flags |= SMP_F_CONST;
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02004572 smp->data.u.str.len = strlen(smp->data.u.str.str);
Emeric Brunba841a12014-04-30 17:05:08 +02004573 if (cert_peer)
4574 X509_free(crt);
Emeric Brun521a0112012-10-22 12:22:55 +02004575
4576 return 1;
4577}
4578
Emeric Brun645ae792014-04-30 14:21:06 +02004579/* boolean, returns true if front conn. transport layer is SSL.
4580 * This function is also usable on backend conn if the fetch keyword 5th
4581 * char is 'b'.
4582 */
Willy Tarreau7875d092012-09-10 08:20:03 +02004583static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02004584smp_fetch_ssl_fc(const struct arg *args, struct sample *smp, const char *kw, void *private)
Willy Tarreau7875d092012-09-10 08:20:03 +02004585{
Willy Tarreaue237fe12016-03-10 17:05:28 +01004586 struct connection *conn = objt_conn((kw[4] != 'b') ? smp->sess->origin :
4587 smp->strm ? smp->strm->si[1].end : NULL);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004588
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02004589 smp->data.type = SMP_T_BOOL;
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02004590 smp->data.u.sint = (conn && conn->xprt == &ssl_sock);
Willy Tarreau7875d092012-09-10 08:20:03 +02004591 return 1;
4592}
4593
Emeric Brun2525b6b2012-10-18 15:59:43 +02004594/* boolean, returns true if client present a SNI */
Willy Tarreau7875d092012-09-10 08:20:03 +02004595static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02004596smp_fetch_ssl_fc_has_sni(const struct arg *args, struct sample *smp, const char *kw, void *private)
Willy Tarreau7875d092012-09-10 08:20:03 +02004597{
4598#ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02004599 struct connection *conn = objt_conn(smp->sess->origin);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004600
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02004601 smp->data.type = SMP_T_BOOL;
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02004602 smp->data.u.sint = (conn && conn->xprt == &ssl_sock) &&
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004603 conn->xprt_ctx &&
4604 SSL_get_servername(conn->xprt_ctx, TLSEXT_NAMETYPE_host_name) != NULL;
Willy Tarreau7875d092012-09-10 08:20:03 +02004605 return 1;
4606#else
4607 return 0;
4608#endif
4609}
4610
Nenad Merdanovic26ea8222015-05-18 02:28:57 +02004611/* boolean, returns true if client session has been resumed */
4612static int
4613smp_fetch_ssl_fc_is_resumed(const struct arg *args, struct sample *smp, const char *kw, void *private)
4614{
4615 struct connection *conn = objt_conn(smp->sess->origin);
4616
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02004617 smp->data.type = SMP_T_BOOL;
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02004618 smp->data.u.sint = (conn && conn->xprt == &ssl_sock) &&
Nenad Merdanovic26ea8222015-05-18 02:28:57 +02004619 conn->xprt_ctx &&
4620 SSL_session_reused(conn->xprt_ctx);
4621 return 1;
4622}
4623
Emeric Brun645ae792014-04-30 14:21:06 +02004624/* string, returns the used cipher if front conn. transport layer is SSL.
4625 * This function is also usable on backend conn if the fetch keyword 5th
4626 * char is 'b'.
4627 */
Emeric Brun589fcad2012-10-16 14:13:26 +02004628static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02004629smp_fetch_ssl_fc_cipher(const struct arg *args, struct sample *smp, const char *kw, void *private)
Emeric Brun589fcad2012-10-16 14:13:26 +02004630{
Willy Tarreaue237fe12016-03-10 17:05:28 +01004631 struct connection *conn = objt_conn((kw[4] != 'b') ? smp->sess->origin :
4632 smp->strm ? smp->strm->si[1].end : NULL);
Emeric Brun589fcad2012-10-16 14:13:26 +02004633
Willy Tarreaube508f12016-03-10 11:47:01 +01004634 smp->flags = 0;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004635 if (!conn || !conn->xprt_ctx || conn->xprt != &ssl_sock)
Emeric Brun589fcad2012-10-16 14:13:26 +02004636 return 0;
4637
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02004638 smp->data.u.str.str = (char *)SSL_get_cipher_name(conn->xprt_ctx);
4639 if (!smp->data.u.str.str)
Emeric Brun589fcad2012-10-16 14:13:26 +02004640 return 0;
4641
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02004642 smp->data.type = SMP_T_STR;
Thierry FOURNIER7654c9f2013-12-17 00:20:33 +01004643 smp->flags |= SMP_F_CONST;
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02004644 smp->data.u.str.len = strlen(smp->data.u.str.str);
Emeric Brun589fcad2012-10-16 14:13:26 +02004645
4646 return 1;
4647}
4648
Emeric Brun645ae792014-04-30 14:21:06 +02004649/* integer, returns the algoritm's keysize if front conn. transport layer
4650 * is SSL.
4651 * This function is also usable on backend conn if the fetch keyword 5th
4652 * char is 'b'.
4653 */
Emeric Brun589fcad2012-10-16 14:13:26 +02004654static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02004655smp_fetch_ssl_fc_alg_keysize(const struct arg *args, struct sample *smp, const char *kw, void *private)
Emeric Brun589fcad2012-10-16 14:13:26 +02004656{
Willy Tarreaue237fe12016-03-10 17:05:28 +01004657 struct connection *conn = objt_conn((kw[4] != 'b') ? smp->sess->origin :
4658 smp->strm ? smp->strm->si[1].end : NULL);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004659
Willy Tarreaue237fe12016-03-10 17:05:28 +01004660 int sint;
Willy Tarreaube508f12016-03-10 11:47:01 +01004661
Emeric Brun589fcad2012-10-16 14:13:26 +02004662 smp->flags = 0;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004663 if (!conn || !conn->xprt_ctx || conn->xprt != &ssl_sock)
Emeric Brun589fcad2012-10-16 14:13:26 +02004664 return 0;
4665
Thierry FOURNIER07ee64e2015-07-06 23:43:03 +02004666 if (!SSL_get_cipher_bits(conn->xprt_ctx, &sint))
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004667 return 0;
4668
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02004669 smp->data.u.sint = sint;
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02004670 smp->data.type = SMP_T_SINT;
Emeric Brun589fcad2012-10-16 14:13:26 +02004671
4672 return 1;
4673}
4674
Emeric Brun645ae792014-04-30 14:21:06 +02004675/* integer, returns the used keysize if front conn. transport layer is SSL.
4676 * This function is also usable on backend conn if the fetch keyword 5th
4677 * char is 'b'.
4678 */
Emeric Brun589fcad2012-10-16 14:13:26 +02004679static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02004680smp_fetch_ssl_fc_use_keysize(const struct arg *args, struct sample *smp, const char *kw, void *private)
Emeric Brun589fcad2012-10-16 14:13:26 +02004681{
Willy Tarreaue237fe12016-03-10 17:05:28 +01004682 struct connection *conn = objt_conn((kw[4] != 'b') ? smp->sess->origin :
4683 smp->strm ? smp->strm->si[1].end : NULL);
Willy Tarreaube508f12016-03-10 11:47:01 +01004684
Emeric Brun589fcad2012-10-16 14:13:26 +02004685 smp->flags = 0;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004686 if (!conn || !conn->xprt_ctx || conn->xprt != &ssl_sock)
4687 return 0;
4688
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02004689 smp->data.u.sint = (unsigned int)SSL_get_cipher_bits(conn->xprt_ctx, NULL);
4690 if (!smp->data.u.sint)
Emeric Brun589fcad2012-10-16 14:13:26 +02004691 return 0;
4692
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02004693 smp->data.type = SMP_T_SINT;
Emeric Brun589fcad2012-10-16 14:13:26 +02004694
4695 return 1;
4696}
4697
Willy Tarreau6c9a3d52012-10-18 18:57:14 +02004698#ifdef OPENSSL_NPN_NEGOTIATED
Willy Tarreau7875d092012-09-10 08:20:03 +02004699static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02004700smp_fetch_ssl_fc_npn(const struct arg *args, struct sample *smp, const char *kw, void *private)
Willy Tarreaua33c6542012-10-15 13:19:06 +02004701{
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004702 struct connection *conn;
4703
Thierry FOURNIER7654c9f2013-12-17 00:20:33 +01004704 smp->flags = SMP_F_CONST;
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02004705 smp->data.type = SMP_T_STR;
Willy Tarreaua33c6542012-10-15 13:19:06 +02004706
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02004707 conn = objt_conn(smp->sess->origin);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004708 if (!conn || !conn->xprt_ctx || conn->xprt != &ssl_sock)
4709 return 0;
4710
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02004711 smp->data.u.str.str = NULL;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004712 SSL_get0_next_proto_negotiated(conn->xprt_ctx,
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02004713 (const unsigned char **)&smp->data.u.str.str, (unsigned *)&smp->data.u.str.len);
Willy Tarreaua33c6542012-10-15 13:19:06 +02004714
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02004715 if (!smp->data.u.str.str)
Willy Tarreaua33c6542012-10-15 13:19:06 +02004716 return 0;
4717
4718 return 1;
Willy Tarreaua33c6542012-10-15 13:19:06 +02004719}
Willy Tarreau6c9a3d52012-10-18 18:57:14 +02004720#endif
Willy Tarreaua33c6542012-10-15 13:19:06 +02004721
Dirkjan Bussink48f1c4e2014-02-13 12:29:42 +01004722#ifdef TLSEXT_TYPE_application_layer_protocol_negotiation
Willy Tarreauab861d32013-04-02 02:30:41 +02004723static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02004724smp_fetch_ssl_fc_alpn(const struct arg *args, struct sample *smp, const char *kw, void *private)
Willy Tarreauab861d32013-04-02 02:30:41 +02004725{
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004726 struct connection *conn;
4727
Thierry FOURNIER7654c9f2013-12-17 00:20:33 +01004728 smp->flags = SMP_F_CONST;
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02004729 smp->data.type = SMP_T_STR;
Willy Tarreauab861d32013-04-02 02:30:41 +02004730
Willy Tarreaue26bf052015-05-12 10:30:12 +02004731 conn = objt_conn(smp->sess->origin);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004732 if (!conn || !conn->xprt_ctx || conn->xprt != &ssl_sock)
Willy Tarreauab861d32013-04-02 02:30:41 +02004733 return 0;
4734
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02004735 smp->data.u.str.str = NULL;
Dirkjan Bussink48f1c4e2014-02-13 12:29:42 +01004736 SSL_get0_alpn_selected(conn->xprt_ctx,
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02004737 (const unsigned char **)&smp->data.u.str.str, (unsigned *)&smp->data.u.str.len);
Willy Tarreauab861d32013-04-02 02:30:41 +02004738
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02004739 if (!smp->data.u.str.str)
Willy Tarreauab861d32013-04-02 02:30:41 +02004740 return 0;
4741
4742 return 1;
4743}
4744#endif
4745
Emeric Brun645ae792014-04-30 14:21:06 +02004746/* string, returns the used protocol if front conn. transport layer is SSL.
4747 * This function is also usable on backend conn if the fetch keyword 5th
4748 * char is 'b'.
4749 */
Willy Tarreaua33c6542012-10-15 13:19:06 +02004750static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02004751smp_fetch_ssl_fc_protocol(const struct arg *args, struct sample *smp, const char *kw, void *private)
Emeric Brun589fcad2012-10-16 14:13:26 +02004752{
Willy Tarreaue237fe12016-03-10 17:05:28 +01004753 struct connection *conn = objt_conn((kw[4] != 'b') ? smp->sess->origin :
4754 smp->strm ? smp->strm->si[1].end : NULL);
Willy Tarreaube508f12016-03-10 11:47:01 +01004755
Emeric Brun589fcad2012-10-16 14:13:26 +02004756 smp->flags = 0;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004757 if (!conn || !conn->xprt_ctx || conn->xprt != &ssl_sock)
4758 return 0;
4759
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02004760 smp->data.u.str.str = (char *)SSL_get_version(conn->xprt_ctx);
4761 if (!smp->data.u.str.str)
Emeric Brun589fcad2012-10-16 14:13:26 +02004762 return 0;
4763
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02004764 smp->data.type = SMP_T_STR;
Thierry FOURNIER7654c9f2013-12-17 00:20:33 +01004765 smp->flags = SMP_F_CONST;
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02004766 smp->data.u.str.len = strlen(smp->data.u.str.str);
Emeric Brun589fcad2012-10-16 14:13:26 +02004767
4768 return 1;
4769}
4770
Willy Tarreau87b09662015-04-03 00:22:06 +02004771/* binary, returns the SSL stream id if front conn. transport layer is SSL.
Emeric Brun645ae792014-04-30 14:21:06 +02004772 * This function is also usable on backend conn if the fetch keyword 5th
4773 * char is 'b'.
4774 */
Emeric Brun589fcad2012-10-16 14:13:26 +02004775static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02004776smp_fetch_ssl_fc_session_id(const struct arg *args, struct sample *smp, const char *kw, void *private)
Emeric Brunfe68f682012-10-16 14:59:28 +02004777{
4778#if OPENSSL_VERSION_NUMBER > 0x0090800fL
Willy Tarreaue237fe12016-03-10 17:05:28 +01004779 struct connection *conn = objt_conn((kw[4] != 'b') ? smp->sess->origin :
4780 smp->strm ? smp->strm->si[1].end : NULL);
Emeric Brunfe68f682012-10-16 14:59:28 +02004781
Willy Tarreaue237fe12016-03-10 17:05:28 +01004782 SSL_SESSION *ssl_sess;
Willy Tarreaube508f12016-03-10 11:47:01 +01004783
Thierry FOURNIER7654c9f2013-12-17 00:20:33 +01004784 smp->flags = SMP_F_CONST;
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02004785 smp->data.type = SMP_T_BIN;
Emeric Brunfe68f682012-10-16 14:59:28 +02004786
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004787 if (!conn || !conn->xprt_ctx || conn->xprt != &ssl_sock)
4788 return 0;
4789
Willy Tarreau192252e2015-04-04 01:47:55 +02004790 ssl_sess = SSL_get_session(conn->xprt_ctx);
4791 if (!ssl_sess)
Emeric Brunfe68f682012-10-16 14:59:28 +02004792 return 0;
4793
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02004794 smp->data.u.str.str = (char *)SSL_SESSION_get_id(ssl_sess, (unsigned int *)&smp->data.u.str.len);
4795 if (!smp->data.u.str.str || !smp->data.u.str.len)
Emeric Brunfe68f682012-10-16 14:59:28 +02004796 return 0;
4797
4798 return 1;
4799#else
4800 return 0;
4801#endif
4802}
4803
4804static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02004805smp_fetch_ssl_fc_sni(const struct arg *args, struct sample *smp, const char *kw, void *private)
Willy Tarreau7875d092012-09-10 08:20:03 +02004806{
4807#ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004808 struct connection *conn;
4809
Thierry FOURNIER7654c9f2013-12-17 00:20:33 +01004810 smp->flags = SMP_F_CONST;
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02004811 smp->data.type = SMP_T_STR;
Willy Tarreau7875d092012-09-10 08:20:03 +02004812
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02004813 conn = objt_conn(smp->sess->origin);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004814 if (!conn || !conn->xprt_ctx || conn->xprt != &ssl_sock)
4815 return 0;
4816
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02004817 smp->data.u.str.str = (char *)SSL_get_servername(conn->xprt_ctx, TLSEXT_NAMETYPE_host_name);
4818 if (!smp->data.u.str.str)
Willy Tarreau3e394c92012-09-14 23:56:58 +02004819 return 0;
4820
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02004821 smp->data.u.str.len = strlen(smp->data.u.str.str);
Willy Tarreau7875d092012-09-10 08:20:03 +02004822 return 1;
4823#else
4824 return 0;
4825#endif
4826}
4827
David Sc1ad52e2014-04-08 18:48:47 -04004828static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02004829smp_fetch_ssl_fc_unique_id(const struct arg *args, struct sample *smp, const char *kw, void *private)
David Sc1ad52e2014-04-08 18:48:47 -04004830{
4831#if OPENSSL_VERSION_NUMBER > 0x0090800fL
Willy Tarreaue237fe12016-03-10 17:05:28 +01004832 struct connection *conn = objt_conn((kw[4] != 'b') ? smp->sess->origin :
4833 smp->strm ? smp->strm->si[1].end : NULL);
4834
David Sc1ad52e2014-04-08 18:48:47 -04004835 int finished_len;
David Sc1ad52e2014-04-08 18:48:47 -04004836 struct chunk *finished_trash;
David Sc1ad52e2014-04-08 18:48:47 -04004837
4838 smp->flags = 0;
David Sc1ad52e2014-04-08 18:48:47 -04004839 if (!conn || !conn->xprt_ctx || conn->xprt != &ssl_sock)
4840 return 0;
4841
4842 if (!(conn->flags & CO_FL_CONNECTED)) {
4843 smp->flags |= SMP_F_MAY_CHANGE;
4844 return 0;
4845 }
4846
4847 finished_trash = get_trash_chunk();
4848 if (!SSL_session_reused(conn->xprt_ctx))
4849 finished_len = SSL_get_peer_finished(conn->xprt_ctx, finished_trash->str, finished_trash->size);
4850 else
4851 finished_len = SSL_get_finished(conn->xprt_ctx, finished_trash->str, finished_trash->size);
4852
4853 if (!finished_len)
4854 return 0;
4855
Emeric Brunb73a9b02014-04-30 18:49:19 +02004856 finished_trash->len = finished_len;
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02004857 smp->data.u.str = *finished_trash;
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02004858 smp->data.type = SMP_T_BIN;
David Sc1ad52e2014-04-08 18:48:47 -04004859
4860 return 1;
4861#else
4862 return 0;
4863#endif
4864}
4865
Emeric Brun2525b6b2012-10-18 15:59:43 +02004866/* integer, returns the first verify error in CA chain of client certificate chain. */
Emeric Brunf282a812012-09-21 15:27:54 +02004867static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02004868smp_fetch_ssl_c_ca_err(const struct arg *args, struct sample *smp, const char *kw, void *private)
Emeric Brunf282a812012-09-21 15:27:54 +02004869{
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004870 struct connection *conn;
4871
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02004872 conn = objt_conn(smp->sess->origin);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004873 if (!conn || conn->xprt != &ssl_sock)
4874 return 0;
4875
4876 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brunf282a812012-09-21 15:27:54 +02004877 smp->flags = SMP_F_MAY_CHANGE;
4878 return 0;
4879 }
4880
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02004881 smp->data.type = SMP_T_SINT;
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02004882 smp->data.u.sint = (unsigned long long int)SSL_SOCK_ST_TO_CA_ERROR(conn->xprt_st);
Emeric Brunf282a812012-09-21 15:27:54 +02004883 smp->flags = 0;
4884
4885 return 1;
4886}
4887
Emeric Brun2525b6b2012-10-18 15:59:43 +02004888/* integer, returns the depth of the first verify error in CA chain of client certificate chain. */
Emeric Brunf282a812012-09-21 15:27:54 +02004889static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02004890smp_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 +02004891{
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004892 struct connection *conn;
4893
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02004894 conn = objt_conn(smp->sess->origin);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004895 if (!conn || conn->xprt != &ssl_sock)
Emeric Brunf282a812012-09-21 15:27:54 +02004896 return 0;
4897
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004898 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brunf282a812012-09-21 15:27:54 +02004899 smp->flags = SMP_F_MAY_CHANGE;
4900 return 0;
4901 }
4902
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02004903 smp->data.type = SMP_T_SINT;
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02004904 smp->data.u.sint = (long long int)SSL_SOCK_ST_TO_CAEDEPTH(conn->xprt_st);
Emeric Brunf282a812012-09-21 15:27:54 +02004905 smp->flags = 0;
4906
4907 return 1;
4908}
4909
Emeric Brun2525b6b2012-10-18 15:59:43 +02004910/* integer, returns the first verify error on client certificate */
Emeric Brunf282a812012-09-21 15:27:54 +02004911static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02004912smp_fetch_ssl_c_err(const struct arg *args, struct sample *smp, const char *kw, void *private)
Emeric Brunf282a812012-09-21 15:27:54 +02004913{
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004914 struct connection *conn;
4915
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02004916 conn = objt_conn(smp->sess->origin);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004917 if (!conn || conn->xprt != &ssl_sock)
4918 return 0;
4919
4920 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brunf282a812012-09-21 15:27:54 +02004921 smp->flags = SMP_F_MAY_CHANGE;
4922 return 0;
4923 }
4924
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02004925 smp->data.type = SMP_T_SINT;
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02004926 smp->data.u.sint = (long long int)SSL_SOCK_ST_TO_CRTERROR(conn->xprt_st);
Emeric Brunf282a812012-09-21 15:27:54 +02004927 smp->flags = 0;
4928
4929 return 1;
4930}
4931
Emeric Brun2525b6b2012-10-18 15:59:43 +02004932/* integer, returns the verify result on client cert */
Emeric Brunbaf8ffb2012-09-21 15:27:20 +02004933static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02004934smp_fetch_ssl_c_verify(const struct arg *args, struct sample *smp, const char *kw, void *private)
Emeric Brunbaf8ffb2012-09-21 15:27:20 +02004935{
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004936 struct connection *conn;
4937
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02004938 conn = objt_conn(smp->sess->origin);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004939 if (!conn || conn->xprt != &ssl_sock)
4940 return 0;
4941
4942 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brunbaf8ffb2012-09-21 15:27:20 +02004943 smp->flags = SMP_F_MAY_CHANGE;
4944 return 0;
4945 }
4946
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004947 if (!conn->xprt_ctx)
Emeric Brunbaf8ffb2012-09-21 15:27:20 +02004948 return 0;
4949
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02004950 smp->data.type = SMP_T_SINT;
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02004951 smp->data.u.sint = (long long int)SSL_get_verify_result(conn->xprt_ctx);
Emeric Brunbaf8ffb2012-09-21 15:27:20 +02004952 smp->flags = 0;
4953
4954 return 1;
4955}
4956
Emeric Brunfb510ea2012-10-05 12:00:26 +02004957/* parse the "ca-file" bind keyword */
4958static 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 +02004959{
4960 if (!*args[cur_arg + 1]) {
4961 if (err)
4962 memprintf(err, "'%s' : missing CAfile path", args[cur_arg]);
4963 return ERR_ALERT | ERR_FATAL;
4964 }
4965
Emeric Brunef42d922012-10-11 16:11:36 +02004966 if ((*args[cur_arg + 1] != '/') && global.ca_base)
4967 memprintf(&conf->ca_file, "%s/%s", global.ca_base, args[cur_arg + 1]);
4968 else
4969 memprintf(&conf->ca_file, "%s", args[cur_arg + 1]);
Emeric Brunc8e8d122012-10-02 18:42:10 +02004970
Emeric Brund94b3fe2012-09-20 18:23:56 +02004971 return 0;
4972}
4973
Christopher Faulet31af49d2015-06-09 17:29:50 +02004974/* parse the "ca-sign-file" bind keyword */
4975static int bind_parse_ca_sign_file(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
4976{
4977 if (!*args[cur_arg + 1]) {
4978 if (err)
4979 memprintf(err, "'%s' : missing CAfile path", args[cur_arg]);
4980 return ERR_ALERT | ERR_FATAL;
4981 }
4982
4983 if ((*args[cur_arg + 1] != '/') && global.ca_base)
4984 memprintf(&conf->ca_sign_file, "%s/%s", global.ca_base, args[cur_arg + 1]);
4985 else
4986 memprintf(&conf->ca_sign_file, "%s", args[cur_arg + 1]);
4987
4988 return 0;
4989}
4990
4991/* parse the ca-sign-pass bind keyword */
4992
4993static int bind_parse_ca_sign_pass(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
4994{
4995 if (!*args[cur_arg + 1]) {
4996 if (err)
4997 memprintf(err, "'%s' : missing CAkey password", args[cur_arg]);
4998 return ERR_ALERT | ERR_FATAL;
4999 }
5000 memprintf(&conf->ca_sign_pass, "%s", args[cur_arg + 1]);
5001 return 0;
5002}
5003
Willy Tarreau79eeafa2012-09-14 07:53:05 +02005004/* parse the "ciphers" bind keyword */
Willy Tarreau4348fad2012-09-20 16:48:07 +02005005static 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 +02005006{
5007 if (!*args[cur_arg + 1]) {
Willy Tarreaueb6cead2012-09-20 19:43:14 +02005008 memprintf(err, "'%s' : missing cipher suite", args[cur_arg]);
Willy Tarreau79eeafa2012-09-14 07:53:05 +02005009 return ERR_ALERT | ERR_FATAL;
5010 }
5011
Emeric Brun76d88952012-10-05 15:47:31 +02005012 free(conf->ciphers);
Willy Tarreau4348fad2012-09-20 16:48:07 +02005013 conf->ciphers = strdup(args[cur_arg + 1]);
Willy Tarreau79eeafa2012-09-14 07:53:05 +02005014 return 0;
5015}
5016
5017/* parse the "crt" bind keyword */
Willy Tarreau4348fad2012-09-20 16:48:07 +02005018static 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 +02005019{
Willy Tarreau38011032013-08-13 16:59:39 +02005020 char path[MAXPATHLEN];
Willy Tarreaub75d6922014-04-14 18:05:41 +02005021
Willy Tarreau79eeafa2012-09-14 07:53:05 +02005022 if (!*args[cur_arg + 1]) {
Willy Tarreaueb6cead2012-09-20 19:43:14 +02005023 memprintf(err, "'%s' : missing certificate location", args[cur_arg]);
Willy Tarreau79eeafa2012-09-14 07:53:05 +02005024 return ERR_ALERT | ERR_FATAL;
5025 }
5026
Emeric Brunc8e8d122012-10-02 18:42:10 +02005027 if ((*args[cur_arg + 1] != '/' ) && global.crt_base) {
Willy Tarreau38011032013-08-13 16:59:39 +02005028 if ((strlen(global.crt_base) + 1 + strlen(args[cur_arg + 1]) + 1) > MAXPATHLEN) {
Emeric Brunc8e8d122012-10-02 18:42:10 +02005029 memprintf(err, "'%s' : path too long", args[cur_arg]);
5030 return ERR_ALERT | ERR_FATAL;
5031 }
Willy Tarreaub75d6922014-04-14 18:05:41 +02005032 snprintf(path, sizeof(path), "%s/%s", global.crt_base, args[cur_arg + 1]);
Emeric Brunc8e8d122012-10-02 18:42:10 +02005033 if (ssl_sock_load_cert(path, conf, px, err) > 0)
5034 return ERR_ALERT | ERR_FATAL;
5035
5036 return 0;
5037 }
5038
Willy Tarreau4348fad2012-09-20 16:48:07 +02005039 if (ssl_sock_load_cert(args[cur_arg + 1], conf, px, err) > 0)
Willy Tarreau79eeafa2012-09-14 07:53:05 +02005040 return ERR_ALERT | ERR_FATAL;
Emeric Brund94b3fe2012-09-20 18:23:56 +02005041
5042 return 0;
5043}
5044
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01005045/* parse the "crt-list" bind keyword */
5046static int bind_parse_crt_list(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
5047{
5048 if (!*args[cur_arg + 1]) {
5049 memprintf(err, "'%s' : missing certificate location", args[cur_arg]);
5050 return ERR_ALERT | ERR_FATAL;
5051 }
5052
Willy Tarreauad1731d2013-04-02 17:35:58 +02005053 if (ssl_sock_load_cert_list_file(args[cur_arg + 1], conf, px, err) > 0) {
5054 memprintf(err, "'%s' : %s", args[cur_arg], *err);
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01005055 return ERR_ALERT | ERR_FATAL;
Willy Tarreauad1731d2013-04-02 17:35:58 +02005056 }
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01005057
5058 return 0;
5059}
5060
Emeric Brunfb510ea2012-10-05 12:00:26 +02005061/* parse the "crl-file" bind keyword */
5062static 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 +02005063{
Emeric Brun051cdab2012-10-02 19:25:50 +02005064#ifndef X509_V_FLAG_CRL_CHECK
5065 if (err)
5066 memprintf(err, "'%s' : library does not support CRL verify", args[cur_arg]);
5067 return ERR_ALERT | ERR_FATAL;
5068#else
Emeric Brund94b3fe2012-09-20 18:23:56 +02005069 if (!*args[cur_arg + 1]) {
5070 if (err)
5071 memprintf(err, "'%s' : missing CRLfile path", args[cur_arg]);
5072 return ERR_ALERT | ERR_FATAL;
5073 }
Emeric Brun2b58d042012-09-20 17:10:03 +02005074
Emeric Brunef42d922012-10-11 16:11:36 +02005075 if ((*args[cur_arg + 1] != '/') && global.ca_base)
5076 memprintf(&conf->crl_file, "%s/%s", global.ca_base, args[cur_arg + 1]);
5077 else
5078 memprintf(&conf->crl_file, "%s", args[cur_arg + 1]);
Emeric Brunc8e8d122012-10-02 18:42:10 +02005079
Emeric Brun2b58d042012-09-20 17:10:03 +02005080 return 0;
Emeric Brun051cdab2012-10-02 19:25:50 +02005081#endif
Emeric Brun2b58d042012-09-20 17:10:03 +02005082}
5083
5084/* parse the "ecdhe" bind keyword keywords */
5085static int bind_parse_ecdhe(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
5086{
5087#if OPENSSL_VERSION_NUMBER < 0x0090800fL
5088 if (err)
5089 memprintf(err, "'%s' : library does not support elliptic curve Diffie-Hellman (too old)", args[cur_arg]);
5090 return ERR_ALERT | ERR_FATAL;
5091#elif defined(OPENSSL_NO_ECDH)
5092 if (err)
5093 memprintf(err, "'%s' : library does not support elliptic curve Diffie-Hellman (disabled via OPENSSL_NO_ECDH)", args[cur_arg]);
5094 return ERR_ALERT | ERR_FATAL;
5095#else
5096 if (!*args[cur_arg + 1]) {
5097 if (err)
5098 memprintf(err, "'%s' : missing named curve", args[cur_arg]);
5099 return ERR_ALERT | ERR_FATAL;
5100 }
5101
5102 conf->ecdhe = strdup(args[cur_arg + 1]);
Willy Tarreau79eeafa2012-09-14 07:53:05 +02005103
5104 return 0;
Emeric Brun2b58d042012-09-20 17:10:03 +02005105#endif
Willy Tarreau79eeafa2012-09-14 07:53:05 +02005106}
5107
Emeric Brun81c00f02012-09-21 14:31:21 +02005108/* parse the "crt_ignerr" and "ca_ignerr" bind keywords */
5109static int bind_parse_ignore_err(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
5110{
5111 int code;
5112 char *p = args[cur_arg + 1];
5113 unsigned long long *ignerr = &conf->crt_ignerr;
5114
5115 if (!*p) {
5116 if (err)
5117 memprintf(err, "'%s' : missing error IDs list", args[cur_arg]);
5118 return ERR_ALERT | ERR_FATAL;
5119 }
5120
5121 if (strcmp(args[cur_arg], "ca-ignore-err") == 0)
5122 ignerr = &conf->ca_ignerr;
5123
5124 if (strcmp(p, "all") == 0) {
5125 *ignerr = ~0ULL;
5126 return 0;
5127 }
5128
5129 while (p) {
5130 code = atoi(p);
5131 if ((code <= 0) || (code > 63)) {
5132 if (err)
5133 memprintf(err, "'%s' : ID '%d' out of range (1..63) in error IDs list '%s'",
5134 args[cur_arg], code, args[cur_arg + 1]);
5135 return ERR_ALERT | ERR_FATAL;
5136 }
5137 *ignerr |= 1ULL << code;
5138 p = strchr(p, ',');
5139 if (p)
5140 p++;
5141 }
5142
Emeric Brun2cb7ae52012-10-05 14:14:21 +02005143 return 0;
5144}
5145
5146/* parse the "force-sslv3" bind keyword */
5147static int bind_parse_force_sslv3(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
5148{
5149 conf->ssl_options |= BC_SSL_O_USE_SSLV3;
5150 return 0;
5151}
5152
5153/* parse the "force-tlsv10" bind keyword */
5154static int bind_parse_force_tlsv10(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
5155{
5156 conf->ssl_options |= BC_SSL_O_USE_TLSV10;
Emeric Brun2d0c4822012-10-02 13:45:20 +02005157 return 0;
5158}
5159
Emeric Brun2cb7ae52012-10-05 14:14:21 +02005160/* parse the "force-tlsv11" bind keyword */
5161static int bind_parse_force_tlsv11(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
5162{
5163#if SSL_OP_NO_TLSv1_1
5164 conf->ssl_options |= BC_SSL_O_USE_TLSV11;
5165 return 0;
5166#else
5167 if (err)
5168 memprintf(err, "'%s' : library does not support protocol TLSv1.1", args[cur_arg]);
5169 return ERR_ALERT | ERR_FATAL;
5170#endif
5171}
5172
5173/* parse the "force-tlsv12" bind keyword */
5174static int bind_parse_force_tlsv12(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
5175{
5176#if SSL_OP_NO_TLSv1_2
5177 conf->ssl_options |= BC_SSL_O_USE_TLSV12;
5178 return 0;
5179#else
5180 if (err)
5181 memprintf(err, "'%s' : library does not support protocol TLSv1.2", args[cur_arg]);
5182 return ERR_ALERT | ERR_FATAL;
5183#endif
5184}
5185
5186
Emeric Brun2d0c4822012-10-02 13:45:20 +02005187/* parse the "no-tls-tickets" bind keyword */
5188static int bind_parse_no_tls_tickets(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
5189{
Emeric Brun89675492012-10-05 13:48:26 +02005190 conf->ssl_options |= BC_SSL_O_NO_TLS_TICKETS;
Emeric Brun81c00f02012-09-21 14:31:21 +02005191 return 0;
5192}
5193
Emeric Brun2d0c4822012-10-02 13:45:20 +02005194
Emeric Brun9b3009b2012-10-05 11:55:06 +02005195/* parse the "no-sslv3" bind keyword */
5196static 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 +02005197{
Emeric Brun89675492012-10-05 13:48:26 +02005198 conf->ssl_options |= BC_SSL_O_NO_SSLV3;
Willy Tarreau79eeafa2012-09-14 07:53:05 +02005199 return 0;
5200}
5201
Emeric Brun9b3009b2012-10-05 11:55:06 +02005202/* parse the "no-tlsv10" bind keyword */
5203static 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 +02005204{
Emeric Brun89675492012-10-05 13:48:26 +02005205 conf->ssl_options |= BC_SSL_O_NO_TLSV10;
Emeric Brunc0ff4922012-09-28 19:37:02 +02005206 return 0;
5207}
5208
Emeric Brun9b3009b2012-10-05 11:55:06 +02005209/* parse the "no-tlsv11" bind keyword */
5210static 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 +02005211{
Emeric Brun89675492012-10-05 13:48:26 +02005212 conf->ssl_options |= BC_SSL_O_NO_TLSV11;
Emeric Brunc0ff4922012-09-28 19:37:02 +02005213 return 0;
5214}
5215
Emeric Brun9b3009b2012-10-05 11:55:06 +02005216/* parse the "no-tlsv12" bind keyword */
5217static 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 +02005218{
Emeric Brun89675492012-10-05 13:48:26 +02005219 conf->ssl_options |= BC_SSL_O_NO_TLSV12;
Willy Tarreau79eeafa2012-09-14 07:53:05 +02005220 return 0;
5221}
5222
Willy Tarreau6c9a3d52012-10-18 18:57:14 +02005223/* parse the "npn" bind keyword */
5224static int bind_parse_npn(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
5225{
5226#ifdef OPENSSL_NPN_NEGOTIATED
5227 char *p1, *p2;
5228
5229 if (!*args[cur_arg + 1]) {
5230 memprintf(err, "'%s' : missing the comma-delimited NPN protocol suite", args[cur_arg]);
5231 return ERR_ALERT | ERR_FATAL;
5232 }
5233
5234 free(conf->npn_str);
5235
Willy Tarreau3724da12016-02-12 17:11:12 +01005236 /* the NPN string is built as a suite of (<len> <name>)*,
5237 * so we reuse each comma to store the next <len> and need
5238 * one more for the end of the string.
5239 */
Willy Tarreau6c9a3d52012-10-18 18:57:14 +02005240 conf->npn_len = strlen(args[cur_arg + 1]) + 1;
Willy Tarreau3724da12016-02-12 17:11:12 +01005241 conf->npn_str = calloc(1, conf->npn_len + 1);
Willy Tarreau6c9a3d52012-10-18 18:57:14 +02005242 memcpy(conf->npn_str + 1, args[cur_arg + 1], conf->npn_len);
5243
5244 /* replace commas with the name length */
5245 p1 = conf->npn_str;
5246 p2 = p1 + 1;
5247 while (1) {
5248 p2 = memchr(p1 + 1, ',', conf->npn_str + conf->npn_len - (p1 + 1));
5249 if (!p2)
5250 p2 = p1 + 1 + strlen(p1 + 1);
5251
5252 if (p2 - (p1 + 1) > 255) {
5253 *p2 = '\0';
5254 memprintf(err, "'%s' : NPN protocol name too long : '%s'", args[cur_arg], p1 + 1);
5255 return ERR_ALERT | ERR_FATAL;
5256 }
5257
5258 *p1 = p2 - (p1 + 1);
5259 p1 = p2;
5260
5261 if (!*p2)
5262 break;
5263
5264 *(p2++) = '\0';
5265 }
5266 return 0;
5267#else
5268 if (err)
5269 memprintf(err, "'%s' : library does not support TLS NPN extension", args[cur_arg]);
5270 return ERR_ALERT | ERR_FATAL;
5271#endif
5272}
5273
Willy Tarreauab861d32013-04-02 02:30:41 +02005274/* parse the "alpn" bind keyword */
5275static int bind_parse_alpn(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
5276{
Dirkjan Bussink48f1c4e2014-02-13 12:29:42 +01005277#ifdef TLSEXT_TYPE_application_layer_protocol_negotiation
Willy Tarreauab861d32013-04-02 02:30:41 +02005278 char *p1, *p2;
5279
5280 if (!*args[cur_arg + 1]) {
5281 memprintf(err, "'%s' : missing the comma-delimited ALPN protocol suite", args[cur_arg]);
5282 return ERR_ALERT | ERR_FATAL;
5283 }
5284
5285 free(conf->alpn_str);
5286
Marcoen Hirschbergbef60912016-02-12 17:05:24 +01005287 /* the ALPN string is built as a suite of (<len> <name>)*,
5288 * so we reuse each comma to store the next <len> and need
5289 * one more for the end of the string.
5290 */
Willy Tarreauab861d32013-04-02 02:30:41 +02005291 conf->alpn_len = strlen(args[cur_arg + 1]) + 1;
Marcoen Hirschbergbef60912016-02-12 17:05:24 +01005292 conf->alpn_str = calloc(1, conf->alpn_len + 1);
Willy Tarreauab861d32013-04-02 02:30:41 +02005293 memcpy(conf->alpn_str + 1, args[cur_arg + 1], conf->alpn_len);
5294
5295 /* replace commas with the name length */
5296 p1 = conf->alpn_str;
5297 p2 = p1 + 1;
5298 while (1) {
5299 p2 = memchr(p1 + 1, ',', conf->alpn_str + conf->alpn_len - (p1 + 1));
5300 if (!p2)
5301 p2 = p1 + 1 + strlen(p1 + 1);
5302
5303 if (p2 - (p1 + 1) > 255) {
5304 *p2 = '\0';
5305 memprintf(err, "'%s' : ALPN protocol name too long : '%s'", args[cur_arg], p1 + 1);
5306 return ERR_ALERT | ERR_FATAL;
5307 }
5308
5309 *p1 = p2 - (p1 + 1);
5310 p1 = p2;
5311
5312 if (!*p2)
5313 break;
5314
5315 *(p2++) = '\0';
5316 }
5317 return 0;
5318#else
5319 if (err)
5320 memprintf(err, "'%s' : library does not support TLS ALPN extension", args[cur_arg]);
5321 return ERR_ALERT | ERR_FATAL;
5322#endif
5323}
5324
Willy Tarreau79eeafa2012-09-14 07:53:05 +02005325/* parse the "ssl" bind keyword */
Willy Tarreau4348fad2012-09-20 16:48:07 +02005326static 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 +02005327{
Willy Tarreau81796be2012-09-22 19:11:47 +02005328 struct listener *l;
5329
Willy Tarreau4348fad2012-09-20 16:48:07 +02005330 conf->is_ssl = 1;
Emeric Brun76d88952012-10-05 15:47:31 +02005331
5332 if (global.listen_default_ciphers && !conf->ciphers)
5333 conf->ciphers = strdup(global.listen_default_ciphers);
Emeric Brun2c86cbf2014-10-30 15:56:50 +01005334 conf->ssl_options |= global.listen_default_ssloptions;
Emeric Brun76d88952012-10-05 15:47:31 +02005335
Willy Tarreau81796be2012-09-22 19:11:47 +02005336 list_for_each_entry(l, &conf->listeners, by_bind)
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02005337 l->xprt = &ssl_sock;
Willy Tarreau81796be2012-09-22 19:11:47 +02005338
Willy Tarreau79eeafa2012-09-14 07:53:05 +02005339 return 0;
5340}
5341
Christopher Faulet31af49d2015-06-09 17:29:50 +02005342/* parse the "generate-certificates" bind keyword */
5343static int bind_parse_generate_certs(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
5344{
5345#ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME
5346 conf->generate_certs = 1;
5347#else
5348 memprintf(err, "%sthis version of openssl cannot generate SSL certificates.\n",
5349 err && *err ? *err : "");
5350#endif
5351 return 0;
5352}
5353
Emmanuel Hocdet65623372013-01-24 17:17:15 +01005354/* parse the "strict-sni" bind keyword */
5355static int bind_parse_strict_sni(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
5356{
5357 conf->strict_sni = 1;
5358 return 0;
Nenad Merdanovic05552d42015-02-27 19:56:49 +01005359}
5360
5361/* parse the "tls-ticket-keys" bind keyword */
5362static int bind_parse_tls_ticket_keys(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
5363{
5364#if (defined SSL_CTRL_SET_TLSEXT_TICKET_KEY_CB && TLS_TICKETS_NO > 0)
5365 FILE *f;
5366 int i = 0;
5367 char thisline[LINESIZE];
Nenad Merdanovic146defa2015-05-09 08:46:00 +02005368 struct tls_keys_ref *keys_ref;
Nenad Merdanovic05552d42015-02-27 19:56:49 +01005369
5370 if (!*args[cur_arg + 1]) {
5371 if (err)
5372 memprintf(err, "'%s' : missing TLS ticket keys file path", args[cur_arg]);
5373 return ERR_ALERT | ERR_FATAL;
5374 }
5375
Nenad Merdanovic200b0fa2015-05-09 08:46:01 +02005376 keys_ref = tlskeys_ref_lookup(args[cur_arg + 1]);
5377 if(keys_ref) {
5378 conf->keys_ref = keys_ref;
5379 return 0;
5380 }
5381
Vincent Bernat02779b62016-04-03 13:48:43 +02005382 keys_ref = malloc(sizeof(*keys_ref));
Nenad Merdanovic146defa2015-05-09 08:46:00 +02005383 keys_ref->tlskeys = malloc(TLS_TICKETS_NO * sizeof(struct tls_sess_key));
Nenad Merdanovic05552d42015-02-27 19:56:49 +01005384
5385 if ((f = fopen(args[cur_arg + 1], "r")) == NULL) {
5386 if (err)
5387 memprintf(err, "'%s' : unable to load ssl tickets keys file", args[cur_arg+1]);
5388 return ERR_ALERT | ERR_FATAL;
5389 }
5390
Nenad Merdanovic146defa2015-05-09 08:46:00 +02005391 keys_ref->filename = strdup(args[cur_arg + 1]);
5392
Nenad Merdanovic05552d42015-02-27 19:56:49 +01005393 while (fgets(thisline, sizeof(thisline), f) != NULL) {
5394 int len = strlen(thisline);
5395 /* Strip newline characters from the end */
5396 if(thisline[len - 1] == '\n')
5397 thisline[--len] = 0;
5398
5399 if(thisline[len - 1] == '\r')
5400 thisline[--len] = 0;
5401
Nenad Merdanovic146defa2015-05-09 08:46:00 +02005402 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 +01005403 if (err)
5404 memprintf(err, "'%s' : unable to decode base64 key on line %d", args[cur_arg+1], i + 1);
mildis16aa0152016-06-22 17:46:29 +02005405 fclose(f);
Nenad Merdanovic05552d42015-02-27 19:56:49 +01005406 return ERR_ALERT | ERR_FATAL;
5407 }
5408 i++;
5409 }
5410
5411 if (i < TLS_TICKETS_NO) {
5412 if (err)
5413 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 +02005414 fclose(f);
Nenad Merdanovic05552d42015-02-27 19:56:49 +01005415 return ERR_ALERT | ERR_FATAL;
5416 }
5417
5418 fclose(f);
5419
5420 /* Use penultimate key for encryption, handle when TLS_TICKETS_NO = 1 */
Nenad Merdanovic17891152016-03-25 22:16:57 +01005421 i -= 2;
5422 keys_ref->tls_ticket_enc_index = i < 0 ? 0 : i % TLS_TICKETS_NO;
Nenad Merdanovic200b0fa2015-05-09 08:46:01 +02005423 keys_ref->unique_id = -1;
Nenad Merdanovic146defa2015-05-09 08:46:00 +02005424 conf->keys_ref = keys_ref;
Nenad Merdanovic05552d42015-02-27 19:56:49 +01005425
Nenad Merdanovic200b0fa2015-05-09 08:46:01 +02005426 LIST_ADD(&tlskeys_reference, &keys_ref->list);
5427
Nenad Merdanovic05552d42015-02-27 19:56:49 +01005428 return 0;
5429#else
5430 if (err)
5431 memprintf(err, "'%s' : TLS ticket callback extension not supported", args[cur_arg]);
5432 return ERR_ALERT | ERR_FATAL;
5433#endif /* SSL_CTRL_SET_TLSEXT_TICKET_KEY_CB */
Emmanuel Hocdet65623372013-01-24 17:17:15 +01005434}
5435
Emeric Brund94b3fe2012-09-20 18:23:56 +02005436/* parse the "verify" bind keyword */
5437static int bind_parse_verify(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
5438{
5439 if (!*args[cur_arg + 1]) {
5440 if (err)
5441 memprintf(err, "'%s' : missing verify method", args[cur_arg]);
5442 return ERR_ALERT | ERR_FATAL;
5443 }
5444
5445 if (strcmp(args[cur_arg + 1], "none") == 0)
Emeric Brun850efd52014-01-29 12:24:34 +01005446 conf->verify = SSL_SOCK_VERIFY_NONE;
Emeric Brund94b3fe2012-09-20 18:23:56 +02005447 else if (strcmp(args[cur_arg + 1], "optional") == 0)
Emeric Brun850efd52014-01-29 12:24:34 +01005448 conf->verify = SSL_SOCK_VERIFY_OPTIONAL;
Emeric Brund94b3fe2012-09-20 18:23:56 +02005449 else if (strcmp(args[cur_arg + 1], "required") == 0)
Emeric Brun850efd52014-01-29 12:24:34 +01005450 conf->verify = SSL_SOCK_VERIFY_REQUIRED;
Emeric Brund94b3fe2012-09-20 18:23:56 +02005451 else {
5452 if (err)
5453 memprintf(err, "'%s' : unknown verify method '%s', only 'none', 'optional', and 'required' are supported\n",
5454 args[cur_arg], args[cur_arg + 1]);
5455 return ERR_ALERT | ERR_FATAL;
5456 }
5457
5458 return 0;
5459}
5460
Willy Tarreau92faadf2012-10-10 23:04:25 +02005461/************** "server" keywords ****************/
5462
Emeric Brunef42d922012-10-11 16:11:36 +02005463/* parse the "ca-file" server keyword */
5464static int srv_parse_ca_file(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
5465{
5466 if (!*args[*cur_arg + 1]) {
5467 if (err)
5468 memprintf(err, "'%s' : missing CAfile path", args[*cur_arg]);
5469 return ERR_ALERT | ERR_FATAL;
5470 }
5471
5472 if ((*args[*cur_arg + 1] != '/') && global.ca_base)
5473 memprintf(&newsrv->ssl_ctx.ca_file, "%s/%s", global.ca_base, args[*cur_arg + 1]);
5474 else
5475 memprintf(&newsrv->ssl_ctx.ca_file, "%s", args[*cur_arg + 1]);
5476
5477 return 0;
5478}
5479
Willy Tarreau92faadf2012-10-10 23:04:25 +02005480/* parse the "check-ssl" server keyword */
5481static int srv_parse_check_ssl(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
5482{
5483 newsrv->check.use_ssl = 1;
5484 if (global.connect_default_ciphers && !newsrv->ssl_ctx.ciphers)
5485 newsrv->ssl_ctx.ciphers = strdup(global.connect_default_ciphers);
Emeric Brun2c86cbf2014-10-30 15:56:50 +01005486 newsrv->ssl_ctx.options |= global.connect_default_ssloptions;
Willy Tarreau92faadf2012-10-10 23:04:25 +02005487 return 0;
5488}
5489
5490/* parse the "ciphers" server keyword */
5491static int srv_parse_ciphers(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
5492{
5493 if (!*args[*cur_arg + 1]) {
5494 memprintf(err, "'%s' : missing cipher suite", args[*cur_arg]);
5495 return ERR_ALERT | ERR_FATAL;
5496 }
5497
5498 free(newsrv->ssl_ctx.ciphers);
5499 newsrv->ssl_ctx.ciphers = strdup(args[*cur_arg + 1]);
5500 return 0;
5501}
5502
Emeric Brunef42d922012-10-11 16:11:36 +02005503/* parse the "crl-file" server keyword */
5504static int srv_parse_crl_file(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
5505{
5506#ifndef X509_V_FLAG_CRL_CHECK
5507 if (err)
5508 memprintf(err, "'%s' : library does not support CRL verify", args[*cur_arg]);
5509 return ERR_ALERT | ERR_FATAL;
5510#else
5511 if (!*args[*cur_arg + 1]) {
5512 if (err)
5513 memprintf(err, "'%s' : missing CRLfile path", args[*cur_arg]);
5514 return ERR_ALERT | ERR_FATAL;
5515 }
5516
5517 if ((*args[*cur_arg + 1] != '/') && global.ca_base)
5518 memprintf(&newsrv->ssl_ctx.crl_file, "%s/%s", global.ca_base, args[*cur_arg + 1]);
5519 else
5520 memprintf(&newsrv->ssl_ctx.crl_file, "%s", args[*cur_arg + 1]);
5521
5522 return 0;
5523#endif
5524}
5525
Emeric Bruna7aa3092012-10-26 12:58:00 +02005526/* parse the "crt" server keyword */
5527static int srv_parse_crt(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
5528{
5529 if (!*args[*cur_arg + 1]) {
5530 if (err)
5531 memprintf(err, "'%s' : missing certificate file path", args[*cur_arg]);
5532 return ERR_ALERT | ERR_FATAL;
5533 }
5534
5535 if ((*args[*cur_arg + 1] != '/') && global.crt_base)
5536 memprintf(&newsrv->ssl_ctx.client_crt, "%s/%s", global.ca_base, args[*cur_arg + 1]);
5537 else
5538 memprintf(&newsrv->ssl_ctx.client_crt, "%s", args[*cur_arg + 1]);
5539
5540 return 0;
5541}
Emeric Brunef42d922012-10-11 16:11:36 +02005542
Willy Tarreau92faadf2012-10-10 23:04:25 +02005543/* parse the "force-sslv3" server keyword */
5544static int srv_parse_force_sslv3(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
5545{
5546 newsrv->ssl_ctx.options |= SRV_SSL_O_USE_SSLV3;
5547 return 0;
5548}
5549
5550/* parse the "force-tlsv10" server keyword */
5551static int srv_parse_force_tlsv10(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
5552{
5553 newsrv->ssl_ctx.options |= SRV_SSL_O_USE_TLSV10;
5554 return 0;
5555}
5556
5557/* parse the "force-tlsv11" server keyword */
5558static int srv_parse_force_tlsv11(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
5559{
5560#if SSL_OP_NO_TLSv1_1
5561 newsrv->ssl_ctx.options |= SRV_SSL_O_USE_TLSV11;
5562 return 0;
5563#else
5564 if (err)
5565 memprintf(err, "'%s' : library does not support protocol TLSv1.1", args[*cur_arg]);
5566 return ERR_ALERT | ERR_FATAL;
5567#endif
5568}
5569
5570/* parse the "force-tlsv12" server keyword */
5571static int srv_parse_force_tlsv12(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
5572{
5573#if SSL_OP_NO_TLSv1_2
5574 newsrv->ssl_ctx.options |= SRV_SSL_O_USE_TLSV12;
5575 return 0;
5576#else
5577 if (err)
5578 memprintf(err, "'%s' : library does not support protocol TLSv1.2", args[*cur_arg]);
5579 return ERR_ALERT | ERR_FATAL;
5580#endif
5581}
5582
Willy Tarreau2a3fb1c2015-02-05 16:47:07 +01005583/* parse the "no-ssl-reuse" server keyword */
5584static int srv_parse_no_ssl_reuse(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
5585{
5586 newsrv->ssl_ctx.options |= SRV_SSL_O_NO_REUSE;
5587 return 0;
5588}
5589
Willy Tarreau92faadf2012-10-10 23:04:25 +02005590/* parse the "no-sslv3" server keyword */
5591static int srv_parse_no_sslv3(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
5592{
5593 newsrv->ssl_ctx.options |= SRV_SSL_O_NO_SSLV3;
5594 return 0;
5595}
5596
5597/* parse the "no-tlsv10" server keyword */
5598static int srv_parse_no_tlsv10(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
5599{
5600 newsrv->ssl_ctx.options |= SRV_SSL_O_NO_TLSV10;
5601 return 0;
5602}
5603
5604/* parse the "no-tlsv11" server keyword */
5605static int srv_parse_no_tlsv11(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
5606{
5607 newsrv->ssl_ctx.options |= SRV_SSL_O_NO_TLSV11;
5608 return 0;
5609}
5610
5611/* parse the "no-tlsv12" server keyword */
5612static int srv_parse_no_tlsv12(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
5613{
5614 newsrv->ssl_ctx.options |= SRV_SSL_O_NO_TLSV12;
5615 return 0;
5616}
5617
Emeric Brunf9c5c472012-10-11 15:28:34 +02005618/* parse the "no-tls-tickets" server keyword */
5619static int srv_parse_no_tls_tickets(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
5620{
5621 newsrv->ssl_ctx.options |= SRV_SSL_O_NO_TLS_TICKETS;
5622 return 0;
5623}
David Safb76832014-05-08 23:42:08 -04005624/* parse the "send-proxy-v2-ssl" server keyword */
5625static int srv_parse_send_proxy_ssl(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
5626{
5627 newsrv->pp_opts |= SRV_PP_V2;
5628 newsrv->pp_opts |= SRV_PP_V2_SSL;
5629 return 0;
5630}
5631
5632/* parse the "send-proxy-v2-ssl-cn" server keyword */
5633static int srv_parse_send_proxy_cn(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
5634{
5635 newsrv->pp_opts |= SRV_PP_V2;
5636 newsrv->pp_opts |= SRV_PP_V2_SSL;
5637 newsrv->pp_opts |= SRV_PP_V2_SSL_CN;
5638 return 0;
5639}
Emeric Brunf9c5c472012-10-11 15:28:34 +02005640
Willy Tarreau732eac42015-07-09 11:40:25 +02005641/* parse the "sni" server keyword */
5642static int srv_parse_sni(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
5643{
5644#ifndef SSL_CTRL_SET_TLSEXT_HOSTNAME
5645 memprintf(err, "'%s' : the current SSL library doesn't support the SNI TLS extension", args[*cur_arg]);
5646 return ERR_ALERT | ERR_FATAL;
5647#else
Cyril Bonté23d19d62016-03-07 22:13:22 +01005648 int idx;
Willy Tarreau732eac42015-07-09 11:40:25 +02005649 struct sample_expr *expr;
5650
5651 if (!*args[*cur_arg + 1]) {
5652 memprintf(err, "'%s' : missing sni expression", args[*cur_arg]);
5653 return ERR_ALERT | ERR_FATAL;
5654 }
5655
Cyril Bonté23d19d62016-03-07 22:13:22 +01005656 idx = (*cur_arg) + 1;
Willy Tarreau732eac42015-07-09 11:40:25 +02005657 proxy->conf.args.ctx = ARGC_SRV;
5658
Cyril Bonté23d19d62016-03-07 22:13:22 +01005659 expr = sample_parse_expr((char **)args, &idx, px->conf.file, px->conf.line, err, &proxy->conf.args);
Willy Tarreau732eac42015-07-09 11:40:25 +02005660 if (!expr) {
5661 memprintf(err, "error detected while parsing sni expression : %s", *err);
5662 return ERR_ALERT | ERR_FATAL;
5663 }
5664
5665 if (!(expr->fetch->val & SMP_VAL_BE_SRV_CON)) {
5666 memprintf(err, "error detected while parsing sni expression : "
5667 " fetch method '%s' extracts information from '%s', none of which is available here.\n",
Cyril Bonté23d19d62016-03-07 22:13:22 +01005668 args[idx-1], sample_src_names(expr->fetch->use));
Willy Tarreau732eac42015-07-09 11:40:25 +02005669 return ERR_ALERT | ERR_FATAL;
5670 }
5671
5672 px->http_needed |= !!(expr->fetch->use & SMP_USE_HTTP_ANY);
5673 newsrv->ssl_ctx.sni = expr;
5674 return 0;
5675#endif
5676}
5677
Willy Tarreau92faadf2012-10-10 23:04:25 +02005678/* parse the "ssl" server keyword */
5679static int srv_parse_ssl(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
5680{
5681 newsrv->use_ssl = 1;
5682 if (global.connect_default_ciphers && !newsrv->ssl_ctx.ciphers)
5683 newsrv->ssl_ctx.ciphers = strdup(global.connect_default_ciphers);
5684 return 0;
5685}
5686
Emeric Brunef42d922012-10-11 16:11:36 +02005687/* parse the "verify" server keyword */
5688static int srv_parse_verify(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
5689{
5690 if (!*args[*cur_arg + 1]) {
5691 if (err)
5692 memprintf(err, "'%s' : missing verify method", args[*cur_arg]);
5693 return ERR_ALERT | ERR_FATAL;
5694 }
5695
5696 if (strcmp(args[*cur_arg + 1], "none") == 0)
Emeric Brun850efd52014-01-29 12:24:34 +01005697 newsrv->ssl_ctx.verify = SSL_SOCK_VERIFY_NONE;
Emeric Brunef42d922012-10-11 16:11:36 +02005698 else if (strcmp(args[*cur_arg + 1], "required") == 0)
Emeric Brun850efd52014-01-29 12:24:34 +01005699 newsrv->ssl_ctx.verify = SSL_SOCK_VERIFY_REQUIRED;
Emeric Brunef42d922012-10-11 16:11:36 +02005700 else {
5701 if (err)
5702 memprintf(err, "'%s' : unknown verify method '%s', only 'none' and 'required' are supported\n",
5703 args[*cur_arg], args[*cur_arg + 1]);
5704 return ERR_ALERT | ERR_FATAL;
5705 }
5706
Evan Broderbe554312013-06-27 00:05:25 -07005707 return 0;
5708}
5709
5710/* parse the "verifyhost" server keyword */
5711static int srv_parse_verifyhost(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
5712{
5713 if (!*args[*cur_arg + 1]) {
5714 if (err)
5715 memprintf(err, "'%s' : missing hostname to verify against", args[*cur_arg]);
5716 return ERR_ALERT | ERR_FATAL;
5717 }
5718
5719 newsrv->ssl_ctx.verify_host = strdup(args[*cur_arg + 1]);
5720
Emeric Brunef42d922012-10-11 16:11:36 +02005721 return 0;
5722}
5723
Emeric Brun2c86cbf2014-10-30 15:56:50 +01005724/* parse the "ssl-default-bind-options" keyword in global section */
5725static int ssl_parse_default_bind_options(char **args, int section_type, struct proxy *curpx,
5726 struct proxy *defpx, const char *file, int line,
5727 char **err) {
5728 int i = 1;
5729
5730 if (*(args[i]) == 0) {
5731 memprintf(err, "global statement '%s' expects an option as an argument.", args[0]);
5732 return -1;
5733 }
5734 while (*(args[i])) {
5735 if (!strcmp(args[i], "no-sslv3"))
5736 global.listen_default_ssloptions |= BC_SSL_O_NO_SSLV3;
5737 else if (!strcmp(args[i], "no-tlsv10"))
5738 global.listen_default_ssloptions |= BC_SSL_O_NO_TLSV10;
5739 else if (!strcmp(args[i], "no-tlsv11"))
5740 global.listen_default_ssloptions |= BC_SSL_O_NO_TLSV11;
5741 else if (!strcmp(args[i], "no-tlsv12"))
5742 global.listen_default_ssloptions |= BC_SSL_O_NO_TLSV12;
5743 else if (!strcmp(args[i], "force-sslv3"))
5744 global.listen_default_ssloptions |= BC_SSL_O_USE_SSLV3;
5745 else if (!strcmp(args[i], "force-tlsv10"))
5746 global.listen_default_ssloptions |= BC_SSL_O_USE_TLSV10;
5747 else if (!strcmp(args[i], "force-tlsv11")) {
5748#if SSL_OP_NO_TLSv1_1
5749 global.listen_default_ssloptions |= BC_SSL_O_USE_TLSV11;
5750#else
5751 memprintf(err, "'%s' '%s': library does not support protocol TLSv1.1", args[0], args[i]);
5752 return -1;
5753#endif
5754 }
5755 else if (!strcmp(args[i], "force-tlsv12")) {
5756#if SSL_OP_NO_TLSv1_2
5757 global.listen_default_ssloptions |= BC_SSL_O_USE_TLSV12;
5758#else
5759 memprintf(err, "'%s' '%s': library does not support protocol TLSv1.2", args[0], args[i]);
5760 return -1;
5761#endif
5762 }
5763 else if (!strcmp(args[i], "no-tls-tickets"))
5764 global.listen_default_ssloptions |= BC_SSL_O_NO_TLS_TICKETS;
5765 else {
5766 memprintf(err, "unknown option '%s' on global statement '%s'.", args[i], args[0]);
5767 return -1;
5768 }
5769 i++;
5770 }
5771 return 0;
5772}
5773
5774/* parse the "ssl-default-server-options" keyword in global section */
5775static int ssl_parse_default_server_options(char **args, int section_type, struct proxy *curpx,
5776 struct proxy *defpx, const char *file, int line,
5777 char **err) {
5778 int i = 1;
5779
5780 if (*(args[i]) == 0) {
5781 memprintf(err, "global statement '%s' expects an option as an argument.", args[0]);
5782 return -1;
5783 }
5784 while (*(args[i])) {
5785 if (!strcmp(args[i], "no-sslv3"))
5786 global.connect_default_ssloptions |= SRV_SSL_O_NO_SSLV3;
5787 else if (!strcmp(args[i], "no-tlsv10"))
5788 global.connect_default_ssloptions |= SRV_SSL_O_NO_TLSV10;
5789 else if (!strcmp(args[i], "no-tlsv11"))
5790 global.connect_default_ssloptions |= SRV_SSL_O_NO_TLSV11;
5791 else if (!strcmp(args[i], "no-tlsv12"))
5792 global.connect_default_ssloptions |= SRV_SSL_O_NO_TLSV12;
5793 else if (!strcmp(args[i], "force-sslv3"))
5794 global.connect_default_ssloptions |= SRV_SSL_O_USE_SSLV3;
5795 else if (!strcmp(args[i], "force-tlsv10"))
5796 global.connect_default_ssloptions |= SRV_SSL_O_USE_TLSV10;
5797 else if (!strcmp(args[i], "force-tlsv11")) {
5798#if SSL_OP_NO_TLSv1_1
5799 global.connect_default_ssloptions |= SRV_SSL_O_USE_TLSV11;
5800#else
5801 memprintf(err, "'%s' '%s': library does not support protocol TLSv1.1", args[0], args[i]);
5802 return -1;
5803#endif
5804 }
5805 else if (!strcmp(args[i], "force-tlsv12")) {
5806#if SSL_OP_NO_TLSv1_2
5807 global.connect_default_ssloptions |= SRV_SSL_O_USE_TLSV12;
5808#else
5809 memprintf(err, "'%s' '%s': library does not support protocol TLSv1.2", args[0], args[i]);
5810 return -1;
5811#endif
5812 }
5813 else if (!strcmp(args[i], "no-tls-tickets"))
5814 global.connect_default_ssloptions |= SRV_SSL_O_NO_TLS_TICKETS;
5815 else {
5816 memprintf(err, "unknown option '%s' on global statement '%s'.", args[i], args[0]);
5817 return -1;
5818 }
5819 i++;
5820 }
5821 return 0;
5822}
5823
Willy Tarreau7875d092012-09-10 08:20:03 +02005824/* Note: must not be declared <const> as its list will be overwritten.
5825 * Please take care of keeping this list alphabetically sorted.
5826 */
Willy Tarreaudc13c112013-06-21 23:16:39 +02005827static struct sample_fetch_kw_list sample_fetch_keywords = {ILH, {
Emeric Brun645ae792014-04-30 14:21:06 +02005828 { "ssl_bc", smp_fetch_ssl_fc, 0, NULL, SMP_T_BOOL, SMP_USE_L5SRV },
Thierry FOURNIER07ee64e2015-07-06 23:43:03 +02005829 { "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 +02005830 { "ssl_bc_cipher", smp_fetch_ssl_fc_cipher, 0, NULL, SMP_T_STR, SMP_USE_L5SRV },
5831 { "ssl_bc_protocol", smp_fetch_ssl_fc_protocol, 0, NULL, SMP_T_STR, SMP_USE_L5SRV },
Emeric Brunb73a9b02014-04-30 18:49:19 +02005832 { "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 +02005833 { "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 +02005834 { "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 +02005835 { "ssl_c_ca_err", smp_fetch_ssl_c_ca_err, 0, NULL, SMP_T_SINT, SMP_USE_L5CLI },
5836 { "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 +01005837 { "ssl_c_der", smp_fetch_ssl_x_der, 0, NULL, SMP_T_BIN, SMP_USE_L5CLI },
Thierry FOURNIER07ee64e2015-07-06 23:43:03 +02005838 { "ssl_c_err", smp_fetch_ssl_c_err, 0, NULL, SMP_T_SINT, SMP_USE_L5CLI },
Emeric Brunba841a12014-04-30 17:05:08 +02005839 { "ssl_c_i_dn", smp_fetch_ssl_x_i_dn, ARG2(0,STR,SINT), NULL, SMP_T_STR, SMP_USE_L5CLI },
5840 { "ssl_c_key_alg", smp_fetch_ssl_x_key_alg, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
5841 { "ssl_c_notafter", smp_fetch_ssl_x_notafter, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
5842 { "ssl_c_notbefore", smp_fetch_ssl_x_notbefore, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
5843 { "ssl_c_sig_alg", smp_fetch_ssl_x_sig_alg, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
5844 { "ssl_c_s_dn", smp_fetch_ssl_x_s_dn, ARG2(0,STR,SINT), NULL, SMP_T_STR, SMP_USE_L5CLI },
5845 { "ssl_c_serial", smp_fetch_ssl_x_serial, 0, NULL, SMP_T_BIN, SMP_USE_L5CLI },
5846 { "ssl_c_sha1", smp_fetch_ssl_x_sha1, 0, NULL, SMP_T_BIN, SMP_USE_L5CLI },
Willy Tarreau80aca902013-01-07 15:42:20 +01005847 { "ssl_c_used", smp_fetch_ssl_c_used, 0, NULL, SMP_T_BOOL, SMP_USE_L5CLI },
Thierry FOURNIER07ee64e2015-07-06 23:43:03 +02005848 { "ssl_c_verify", smp_fetch_ssl_c_verify, 0, NULL, SMP_T_SINT, SMP_USE_L5CLI },
5849 { "ssl_c_version", smp_fetch_ssl_x_version, 0, NULL, SMP_T_SINT, SMP_USE_L5CLI },
Emeric Brun43e79582014-10-29 19:03:26 +01005850 { "ssl_f_der", smp_fetch_ssl_x_der, 0, NULL, SMP_T_BIN, SMP_USE_L5CLI },
Emeric Brunba841a12014-04-30 17:05:08 +02005851 { "ssl_f_i_dn", smp_fetch_ssl_x_i_dn, ARG2(0,STR,SINT), NULL, SMP_T_STR, SMP_USE_L5CLI },
5852 { "ssl_f_key_alg", smp_fetch_ssl_x_key_alg, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
5853 { "ssl_f_notafter", smp_fetch_ssl_x_notafter, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
5854 { "ssl_f_notbefore", smp_fetch_ssl_x_notbefore, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
5855 { "ssl_f_sig_alg", smp_fetch_ssl_x_sig_alg, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
5856 { "ssl_f_s_dn", smp_fetch_ssl_x_s_dn, ARG2(0,STR,SINT), NULL, SMP_T_STR, SMP_USE_L5CLI },
5857 { "ssl_f_serial", smp_fetch_ssl_x_serial, 0, NULL, SMP_T_BIN, SMP_USE_L5CLI },
Emeric Brun55f4fa82014-04-30 17:11:25 +02005858 { "ssl_f_sha1", smp_fetch_ssl_x_sha1, 0, NULL, SMP_T_BIN, SMP_USE_L5CLI },
Thierry FOURNIER07ee64e2015-07-06 23:43:03 +02005859 { "ssl_f_version", smp_fetch_ssl_x_version, 0, NULL, SMP_T_SINT, SMP_USE_L5CLI },
Willy Tarreau80aca902013-01-07 15:42:20 +01005860 { "ssl_fc", smp_fetch_ssl_fc, 0, NULL, SMP_T_BOOL, SMP_USE_L5CLI },
Thierry FOURNIER07ee64e2015-07-06 23:43:03 +02005861 { "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 +01005862 { "ssl_fc_cipher", smp_fetch_ssl_fc_cipher, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
Willy Tarreau80aca902013-01-07 15:42:20 +01005863 { "ssl_fc_has_crt", smp_fetch_ssl_fc_has_crt, 0, NULL, SMP_T_BOOL, SMP_USE_L5CLI },
5864 { "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 +02005865 { "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 +02005866#ifdef OPENSSL_NPN_NEGOTIATED
Thierry FOURNIER7654c9f2013-12-17 00:20:33 +01005867 { "ssl_fc_npn", smp_fetch_ssl_fc_npn, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
Willy Tarreaua33c6542012-10-15 13:19:06 +02005868#endif
Dirkjan Bussink48f1c4e2014-02-13 12:29:42 +01005869#ifdef TLSEXT_TYPE_application_layer_protocol_negotiation
Thierry FOURNIER7654c9f2013-12-17 00:20:33 +01005870 { "ssl_fc_alpn", smp_fetch_ssl_fc_alpn, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
Willy Tarreauab861d32013-04-02 02:30:41 +02005871#endif
Thierry FOURNIER7654c9f2013-12-17 00:20:33 +01005872 { "ssl_fc_protocol", smp_fetch_ssl_fc_protocol, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
Emeric Brunb73a9b02014-04-30 18:49:19 +02005873 { "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 +02005874 { "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 +01005875 { "ssl_fc_session_id", smp_fetch_ssl_fc_session_id, 0, NULL, SMP_T_BIN, SMP_USE_L5CLI },
5876 { "ssl_fc_sni", smp_fetch_ssl_fc_sni, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
Willy Tarreau7875d092012-09-10 08:20:03 +02005877 { NULL, NULL, 0, 0, 0 },
5878}};
5879
5880/* Note: must not be declared <const> as its list will be overwritten.
5881 * Please take care of keeping this list alphabetically sorted.
5882 */
Willy Tarreaudc13c112013-06-21 23:16:39 +02005883static struct acl_kw_list acl_kws = {ILH, {
Thierry FOURNIERc5a4e982014-03-05 16:07:08 +01005884 { "ssl_fc_sni_end", "ssl_fc_sni", PAT_MATCH_END },
5885 { "ssl_fc_sni_reg", "ssl_fc_sni", PAT_MATCH_REG },
Willy Tarreau8ed669b2013-01-11 15:49:37 +01005886 { /* END */ },
Willy Tarreau7875d092012-09-10 08:20:03 +02005887}};
5888
Willy Tarreau79eeafa2012-09-14 07:53:05 +02005889/* Note: must not be declared <const> as its list will be overwritten.
5890 * Please take care of keeping this list alphabetically sorted, doing so helps
5891 * all code contributors.
5892 * Optional keywords are also declared with a NULL ->parse() function so that
5893 * the config parser can report an appropriate error when a known keyword was
5894 * not enabled.
5895 */
Willy Tarreau51fb7652012-09-18 18:24:39 +02005896static struct bind_kw_list bind_kws = { "SSL", { }, {
Nenad Merdanovic05552d42015-02-27 19:56:49 +01005897 { "alpn", bind_parse_alpn, 1 }, /* set ALPN supported protocols */
5898 { "ca-file", bind_parse_ca_file, 1 }, /* set CAfile to process verify on client cert */
5899 { "ca-ignore-err", bind_parse_ignore_err, 1 }, /* set error IDs to ignore on verify depth > 0 */
Christopher Faulet31af49d2015-06-09 17:29:50 +02005900 { "ca-sign-file", bind_parse_ca_sign_file, 1 }, /* set CAFile used to generate and sign server certs */
5901 { "ca-sign-pass", bind_parse_ca_sign_pass, 1 }, /* set CAKey passphrase */
Nenad Merdanovic05552d42015-02-27 19:56:49 +01005902 { "ciphers", bind_parse_ciphers, 1 }, /* set SSL cipher suite */
5903 { "crl-file", bind_parse_crl_file, 1 }, /* set certificat revocation list file use on client cert verify */
5904 { "crt", bind_parse_crt, 1 }, /* load SSL certificates from this location */
5905 { "crt-ignore-err", bind_parse_ignore_err, 1 }, /* set error IDs to ingore on verify depth == 0 */
5906 { "crt-list", bind_parse_crt_list, 1 }, /* load a list of crt from this location */
5907 { "ecdhe", bind_parse_ecdhe, 1 }, /* defines named curve for elliptic curve Diffie-Hellman */
5908 { "force-sslv3", bind_parse_force_sslv3, 0 }, /* force SSLv3 */
5909 { "force-tlsv10", bind_parse_force_tlsv10, 0 }, /* force TLSv10 */
5910 { "force-tlsv11", bind_parse_force_tlsv11, 0 }, /* force TLSv11 */
5911 { "force-tlsv12", bind_parse_force_tlsv12, 0 }, /* force TLSv12 */
Christopher Faulet31af49d2015-06-09 17:29:50 +02005912 { "generate-certificates", bind_parse_generate_certs, 0 }, /* enable the server certificates generation */
Nenad Merdanovic05552d42015-02-27 19:56:49 +01005913 { "no-sslv3", bind_parse_no_sslv3, 0 }, /* disable SSLv3 */
5914 { "no-tlsv10", bind_parse_no_tlsv10, 0 }, /* disable TLSv10 */
5915 { "no-tlsv11", bind_parse_no_tlsv11, 0 }, /* disable TLSv11 */
5916 { "no-tlsv12", bind_parse_no_tlsv12, 0 }, /* disable TLSv12 */
5917 { "no-tls-tickets", bind_parse_no_tls_tickets, 0 }, /* disable session resumption tickets */
5918 { "ssl", bind_parse_ssl, 0 }, /* enable SSL processing */
5919 { "strict-sni", bind_parse_strict_sni, 0 }, /* refuse negotiation if sni doesn't match a certificate */
5920 { "tls-ticket-keys", bind_parse_tls_ticket_keys, 1 }, /* set file to load TLS ticket keys from */
5921 { "verify", bind_parse_verify, 1 }, /* set SSL verify method */
5922 { "npn", bind_parse_npn, 1 }, /* set NPN supported protocols */
Willy Tarreau79eeafa2012-09-14 07:53:05 +02005923 { NULL, NULL, 0 },
5924}};
Emeric Brun46591952012-05-18 15:47:34 +02005925
Willy Tarreau92faadf2012-10-10 23:04:25 +02005926/* Note: must not be declared <const> as its list will be overwritten.
5927 * Please take care of keeping this list alphabetically sorted, doing so helps
5928 * all code contributors.
5929 * Optional keywords are also declared with a NULL ->parse() function so that
5930 * the config parser can report an appropriate error when a known keyword was
5931 * not enabled.
5932 */
5933static struct srv_kw_list srv_kws = { "SSL", { }, {
Emeric Brunef42d922012-10-11 16:11:36 +02005934 { "ca-file", srv_parse_ca_file, 1, 0 }, /* set CAfile to process verify server cert */
Emeric Brunecc91fe2012-10-11 15:05:10 +02005935 { "check-ssl", srv_parse_check_ssl, 0, 0 }, /* enable SSL for health checks */
5936 { "ciphers", srv_parse_ciphers, 1, 0 }, /* select the cipher suite */
Emeric Brunef42d922012-10-11 16:11:36 +02005937 { "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 +02005938 { "crt", srv_parse_crt, 1, 0 }, /* set client certificate */
Emeric Brunecc91fe2012-10-11 15:05:10 +02005939 { "force-sslv3", srv_parse_force_sslv3, 0, 0 }, /* force SSLv3 */
5940 { "force-tlsv10", srv_parse_force_tlsv10, 0, 0 }, /* force TLSv10 */
5941 { "force-tlsv11", srv_parse_force_tlsv11, 0, 0 }, /* force TLSv11 */
5942 { "force-tlsv12", srv_parse_force_tlsv12, 0, 0 }, /* force TLSv12 */
Willy Tarreau2a3fb1c2015-02-05 16:47:07 +01005943 { "no-ssl-reuse", srv_parse_no_ssl_reuse, 0, 0 }, /* disable session reuse */
Emeric Brunecc91fe2012-10-11 15:05:10 +02005944 { "no-sslv3", srv_parse_no_sslv3, 0, 0 }, /* disable SSLv3 */
5945 { "no-tlsv10", srv_parse_no_tlsv10, 0, 0 }, /* disable TLSv10 */
5946 { "no-tlsv11", srv_parse_no_tlsv11, 0, 0 }, /* disable TLSv11 */
5947 { "no-tlsv12", srv_parse_no_tlsv12, 0, 0 }, /* disable TLSv12 */
Emeric Brunf9c5c472012-10-11 15:28:34 +02005948 { "no-tls-tickets", srv_parse_no_tls_tickets, 0, 0 }, /* disable session resumption tickets */
David Safb76832014-05-08 23:42:08 -04005949 { "send-proxy-v2-ssl", srv_parse_send_proxy_ssl, 0, 0 }, /* send PROXY protocol header v2 with SSL info */
5950 { "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 +02005951 { "sni", srv_parse_sni, 1, 0 }, /* send SNI extension */
Emeric Brunecc91fe2012-10-11 15:05:10 +02005952 { "ssl", srv_parse_ssl, 0, 0 }, /* enable SSL processing */
Emeric Brunef42d922012-10-11 16:11:36 +02005953 { "verify", srv_parse_verify, 1, 0 }, /* set SSL verify method */
Evan Broderbe554312013-06-27 00:05:25 -07005954 { "verifyhost", srv_parse_verifyhost, 1, 0 }, /* require that SSL cert verifies for hostname */
Willy Tarreau92faadf2012-10-10 23:04:25 +02005955 { NULL, NULL, 0, 0 },
5956}};
5957
Emeric Brun2c86cbf2014-10-30 15:56:50 +01005958static struct cfg_kw_list cfg_kws = {ILH, {
5959 { CFG_GLOBAL, "ssl-default-bind-options", ssl_parse_default_bind_options },
5960 { CFG_GLOBAL, "ssl-default-server-options", ssl_parse_default_server_options },
5961 { 0, NULL, NULL },
5962}};
5963
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02005964/* transport-layer operations for SSL sockets */
5965struct xprt_ops ssl_sock = {
Emeric Brun46591952012-05-18 15:47:34 +02005966 .snd_buf = ssl_sock_from_buf,
5967 .rcv_buf = ssl_sock_to_buf,
5968 .rcv_pipe = NULL,
5969 .snd_pipe = NULL,
5970 .shutr = NULL,
5971 .shutw = ssl_sock_shutw,
5972 .close = ssl_sock_close,
5973 .init = ssl_sock_init,
5974};
5975
Daniel Jakots54ffb912015-11-06 20:02:41 +01005976#if (OPENSSL_VERSION_NUMBER >= 0x1000200fL && !defined OPENSSL_NO_TLSEXT && !defined OPENSSL_IS_BORINGSSL && !defined LIBRESSL_VERSION_NUMBER)
Janusz Dziemidowicz2c701b52015-03-07 23:03:59 +01005977
5978static void ssl_sock_sctl_free_func(void *parent, void *ptr, CRYPTO_EX_DATA *ad, int idx, long argl, void *argp)
5979{
5980 if (ptr) {
5981 chunk_destroy(ptr);
5982 free(ptr);
5983 }
5984}
5985
5986#endif
5987
Emeric Brun46591952012-05-18 15:47:34 +02005988__attribute__((constructor))
Willy Tarreau92faadf2012-10-10 23:04:25 +02005989static void __ssl_sock_init(void)
5990{
Emeric Brun46591952012-05-18 15:47:34 +02005991 STACK_OF(SSL_COMP)* cm;
5992
Willy Tarreau610f04b2014-02-13 11:36:41 +01005993#ifdef LISTEN_DEFAULT_CIPHERS
5994 global.listen_default_ciphers = LISTEN_DEFAULT_CIPHERS;
5995#endif
5996#ifdef CONNECT_DEFAULT_CIPHERS
5997 global.connect_default_ciphers = CONNECT_DEFAULT_CIPHERS;
5998#endif
5999 if (global.listen_default_ciphers)
6000 global.listen_default_ciphers = strdup(global.listen_default_ciphers);
6001 if (global.connect_default_ciphers)
6002 global.connect_default_ciphers = strdup(global.connect_default_ciphers);
Emeric Brun2c86cbf2014-10-30 15:56:50 +01006003 global.listen_default_ssloptions = BC_SSL_O_NONE;
6004 global.connect_default_ssloptions = SRV_SSL_O_NONE;
Willy Tarreau610f04b2014-02-13 11:36:41 +01006005
Emeric Brun46591952012-05-18 15:47:34 +02006006 SSL_library_init();
6007 cm = SSL_COMP_get_compression_methods();
6008 sk_SSL_COMP_zero(cm);
Daniel Jakots54ffb912015-11-06 20:02:41 +01006009#if (OPENSSL_VERSION_NUMBER >= 0x1000200fL && !defined OPENSSL_NO_TLSEXT && !defined OPENSSL_IS_BORINGSSL && !defined LIBRESSL_VERSION_NUMBER)
Janusz Dziemidowicz2c701b52015-03-07 23:03:59 +01006010 sctl_ex_index = SSL_CTX_get_ex_new_index(0, NULL, NULL, NULL, ssl_sock_sctl_free_func);
6011#endif
Willy Tarreau7875d092012-09-10 08:20:03 +02006012 sample_register_fetches(&sample_fetch_keywords);
6013 acl_register_keywords(&acl_kws);
Willy Tarreau79eeafa2012-09-14 07:53:05 +02006014 bind_register_keywords(&bind_kws);
Willy Tarreau92faadf2012-10-10 23:04:25 +02006015 srv_register_keywords(&srv_kws);
Emeric Brun2c86cbf2014-10-30 15:56:50 +01006016 cfg_register_keywords(&cfg_kws);
Willy Tarreaud92aa5c2015-01-15 21:34:39 +01006017
6018 global.ssl_session_max_cost = SSL_SESSION_MAX_COST;
6019 global.ssl_handshake_max_cost = SSL_HANDSHAKE_MAX_COST;
Remi Gacogne4f902b82015-05-28 16:23:00 +02006020
6021#ifndef OPENSSL_NO_DH
6022 ssl_dh_ptr_index = SSL_CTX_get_ex_new_index(0, NULL, NULL, NULL, NULL);
6023#endif
Emeric Brun46591952012-05-18 15:47:34 +02006024}
6025
Remi Gacogned3a23c32015-05-28 16:39:47 +02006026__attribute__((destructor))
6027static void __ssl_sock_deinit(void)
6028{
Willy Tarreaua84c2672015-10-09 12:10:13 +02006029#ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME
Christopher Faulet31af49d2015-06-09 17:29:50 +02006030 lru64_destroy(ssl_ctx_lru_tree);
Willy Tarreaua84c2672015-10-09 12:10:13 +02006031#endif
Christopher Faulet31af49d2015-06-09 17:29:50 +02006032
Remi Gacogned3a23c32015-05-28 16:39:47 +02006033#ifndef OPENSSL_NO_DH
6034 if (local_dh_1024) {
6035 DH_free(local_dh_1024);
6036 local_dh_1024 = NULL;
6037 }
6038
6039 if (local_dh_2048) {
6040 DH_free(local_dh_2048);
6041 local_dh_2048 = NULL;
6042 }
6043
6044 if (local_dh_4096) {
6045 DH_free(local_dh_4096);
6046 local_dh_4096 = NULL;
6047 }
6048
Remi Gacogne47783ef2015-05-29 15:53:22 +02006049 if (global_dh) {
6050 DH_free(global_dh);
6051 global_dh = NULL;
6052 }
Remi Gacogned3a23c32015-05-28 16:39:47 +02006053#endif
6054
6055 ERR_remove_state(0);
6056 ERR_free_strings();
6057
6058 EVP_cleanup();
6059
6060#if OPENSSL_VERSION_NUMBER >= 0x00907000L
6061 CRYPTO_cleanup_all_ex_data();
6062#endif
6063}
6064
6065
Emeric Brun46591952012-05-18 15:47:34 +02006066/*
6067 * Local variables:
6068 * c-indent-level: 8
6069 * c-basic-offset: 8
6070 * End:
6071 */