blob: 957bc9790adf1dbdb850b8ea8a706242fb92b966 [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 Gacogne8de54152014-07-15 11:36:40 +02001641 local_dh_1024 = ssl_get_dh_1024();
1642 if (local_dh_1024 == NULL)
Remi Gacognef46cd6e2014-06-12 14:58:40 +02001643 goto end;
Willy Tarreau6e774b42014-04-25 21:35:23 +02001644
Remi Gacogne8de54152014-07-15 11:36:40 +02001645 SSL_CTX_set_tmp_dh(ctx, local_dh_1024);
Roberto Guimaraes0ea4c232016-06-11 15:58:10 -07001646 DH_free(local_dh_1024);
Remi Gacognef46cd6e2014-06-12 14:58:40 +02001647 }
1648 else {
1649 SSL_CTX_set_tmp_dh_callback(ctx, ssl_get_tmp_dh);
1650 }
Willy Tarreau6e774b42014-04-25 21:35:23 +02001651
Emeric Brun41fdb3c2013-04-26 11:05:44 +02001652 ret = 0; /* DH params not found */
Emeric Bruna4bcd9a2012-09-20 16:19:02 +02001653 }
Emeric Brun644cde02012-12-14 11:21:13 +01001654
Emeric Bruna4bcd9a2012-09-20 16:19:02 +02001655end:
1656 if (dh)
1657 DH_free(dh);
1658
Emeric Bruna4bcd9a2012-09-20 16:19:02 +02001659 return ret;
1660}
1661#endif
1662
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +02001663static int ssl_sock_add_cert_sni(SSL_CTX *ctx, struct bind_conf *s, char *name, int order)
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01001664{
1665 struct sni_ctx *sc;
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +02001666 int wild = 0, neg = 0;
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01001667
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +02001668 if (*name == '!') {
1669 neg = 1;
1670 name++;
1671 }
1672 if (*name == '*') {
1673 wild = 1;
1674 name++;
1675 }
1676 /* !* filter is a nop */
1677 if (neg && wild)
1678 return order;
1679 if (*name) {
1680 int j, len;
1681 len = strlen(name);
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01001682 sc = malloc(sizeof(struct sni_ctx) + len + 1);
1683 for (j = 0; j < len; j++)
1684 sc->name.key[j] = tolower(name[j]);
1685 sc->name.key[len] = 0;
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01001686 sc->ctx = ctx;
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +02001687 sc->order = order++;
1688 sc->neg = neg;
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01001689 if (wild)
1690 ebst_insert(&s->sni_w_ctx, &sc->name);
1691 else
1692 ebst_insert(&s->sni_ctx, &sc->name);
1693 }
1694 return order;
1695}
1696
yanbzhu488a4d22015-12-01 15:16:07 -05001697
1698/* The following code is used for loading multiple crt files into
1699 * SSL_CTX's based on CN/SAN
1700 */
1701#if OPENSSL_VERSION_NUMBER >= 0x1000200fL
1702/* This is used to preload the certifcate, private key
1703 * and Cert Chain of a file passed in via the crt
1704 * argument
1705 *
1706 * This way, we do not have to read the file multiple times
1707 */
1708struct cert_key_and_chain {
1709 X509 *cert;
1710 EVP_PKEY *key;
1711 unsigned int num_chain_certs;
1712 /* This is an array of X509 pointers */
1713 X509 **chain_certs;
1714};
1715
yanbzhu08ce6ab2015-12-02 13:01:29 -05001716#define SSL_SOCK_POSSIBLE_KT_COMBOS (1<<(SSL_SOCK_NUM_KEYTYPES))
1717
1718struct key_combo_ctx {
1719 SSL_CTX *ctx;
1720 int order;
1721};
1722
1723/* Map used for processing multiple keypairs for a single purpose
1724 *
1725 * This maps CN/SNI name to certificate type
1726 */
1727struct sni_keytype {
1728 int keytypes; /* BITMASK for keytypes */
1729 struct ebmb_node name; /* node holding the servername value */
1730};
1731
1732
yanbzhu488a4d22015-12-01 15:16:07 -05001733/* Frees the contents of a cert_key_and_chain
1734 */
1735static void ssl_sock_free_cert_key_and_chain_contents(struct cert_key_and_chain *ckch)
1736{
1737 int i;
1738
1739 if (!ckch)
1740 return;
1741
1742 /* Free the certificate and set pointer to NULL */
1743 if (ckch->cert)
1744 X509_free(ckch->cert);
1745 ckch->cert = NULL;
1746
1747 /* Free the key and set pointer to NULL */
1748 if (ckch->key)
1749 EVP_PKEY_free(ckch->key);
1750 ckch->key = NULL;
1751
1752 /* Free each certificate in the chain */
1753 for (i = 0; i < ckch->num_chain_certs; i++) {
1754 if (ckch->chain_certs[i])
1755 X509_free(ckch->chain_certs[i]);
1756 }
1757
1758 /* Free the chain obj itself and set to NULL */
1759 if (ckch->num_chain_certs > 0) {
1760 free(ckch->chain_certs);
1761 ckch->num_chain_certs = 0;
1762 ckch->chain_certs = NULL;
1763 }
1764
1765}
1766
1767/* checks if a key and cert exists in the ckch
1768 */
1769static int ssl_sock_is_ckch_valid(struct cert_key_and_chain *ckch)
1770{
1771 return (ckch->cert != NULL && ckch->key != NULL);
1772}
1773
1774
1775/* Loads the contents of a crt file (path) into a cert_key_and_chain
1776 * This allows us to carry the contents of the file without having to
1777 * read the file multiple times.
1778 *
1779 * returns:
1780 * 0 on Success
1781 * 1 on SSL Failure
1782 * 2 on file not found
1783 */
1784static int ssl_sock_load_crt_file_into_ckch(const char *path, struct cert_key_and_chain *ckch, char **err)
1785{
1786
1787 BIO *in;
1788 X509 *ca = NULL;
1789 int ret = 1;
1790
1791 ssl_sock_free_cert_key_and_chain_contents(ckch);
1792
1793 in = BIO_new(BIO_s_file());
1794 if (in == NULL)
1795 goto end;
1796
1797 if (BIO_read_filename(in, path) <= 0)
1798 goto end;
1799
yanbzhu488a4d22015-12-01 15:16:07 -05001800 /* Read Private Key */
1801 ckch->key = PEM_read_bio_PrivateKey(in, NULL, NULL, NULL);
1802 if (ckch->key == NULL) {
1803 memprintf(err, "%sunable to load private key from file '%s'.\n",
1804 err && *err ? *err : "", path);
1805 goto end;
1806 }
1807
Willy Tarreaubb137a82016-04-06 19:02:38 +02001808 /* Seek back to beginning of file */
1809 BIO_reset(in);
1810
1811 /* Read Certificate */
1812 ckch->cert = PEM_read_bio_X509_AUX(in, NULL, NULL, NULL);
1813 if (ckch->cert == NULL) {
1814 memprintf(err, "%sunable to load certificate from file '%s'.\n",
1815 err && *err ? *err : "", path);
1816 goto end;
1817 }
1818
yanbzhu488a4d22015-12-01 15:16:07 -05001819 /* Read Certificate Chain */
1820 while ((ca = PEM_read_bio_X509(in, NULL, NULL, NULL))) {
1821 /* Grow the chain certs */
1822 ckch->num_chain_certs++;
1823 ckch->chain_certs = realloc(ckch->chain_certs, (ckch->num_chain_certs * sizeof(X509 *)));
1824
1825 /* use - 1 here since we just incremented it above */
1826 ckch->chain_certs[ckch->num_chain_certs - 1] = ca;
1827 }
1828 ret = ERR_get_error();
1829 if (ret && (ERR_GET_LIB(ret) != ERR_LIB_PEM && ERR_GET_REASON(ret) != PEM_R_NO_START_LINE)) {
1830 memprintf(err, "%sunable to load certificate chain from file '%s'.\n",
1831 err && *err ? *err : "", path);
1832 ret = 1;
1833 goto end;
1834 }
1835
1836 ret = 0;
1837
1838end:
1839
1840 ERR_clear_error();
1841 if (in)
1842 BIO_free(in);
1843
1844 /* Something went wrong in one of the reads */
1845 if (ret != 0)
1846 ssl_sock_free_cert_key_and_chain_contents(ckch);
1847
1848 return ret;
1849}
1850
1851/* Loads the info in ckch into ctx
1852 * Currently, this does not process any information about ocsp, dhparams or
1853 * sctl
1854 * Returns
1855 * 0 on success
1856 * 1 on failure
1857 */
1858static int ssl_sock_put_ckch_into_ctx(const char *path, const struct cert_key_and_chain *ckch, SSL_CTX *ctx, char **err)
1859{
1860 int i = 0;
1861
1862 if (SSL_CTX_use_PrivateKey(ctx, ckch->key) <= 0) {
1863 memprintf(err, "%sunable to load SSL private key into SSL Context '%s'.\n",
1864 err && *err ? *err : "", path);
1865 return 1;
1866 }
1867
1868 if (!SSL_CTX_use_certificate(ctx, ckch->cert)) {
1869 memprintf(err, "%sunable to load SSL certificate into SSL Context '%s'.\n",
1870 err && *err ? *err : "", path);
1871 return 1;
1872 }
1873
yanbzhu488a4d22015-12-01 15:16:07 -05001874 /* Load all certs in the ckch into the ctx_chain for the ssl_ctx */
1875 for (i = 0; i < ckch->num_chain_certs; i++) {
1876 if (!SSL_CTX_add1_chain_cert(ctx, ckch->chain_certs[i])) {
yanbzhu08ce6ab2015-12-02 13:01:29 -05001877 memprintf(err, "%sunable to load chain certificate #%d into SSL Context '%s'. Make sure you are linking against Openssl >= 1.0.2.\n",
1878 err && *err ? *err : "", (i+1), path);
yanbzhu488a4d22015-12-01 15:16:07 -05001879 return 1;
1880 }
1881 }
1882
1883 if (SSL_CTX_check_private_key(ctx) <= 0) {
1884 memprintf(err, "%sinconsistencies between private key and certificate loaded from PEM file '%s'.\n",
1885 err && *err ? *err : "", path);
1886 return 1;
1887 }
1888
1889 return 0;
1890}
1891
yanbzhu08ce6ab2015-12-02 13:01:29 -05001892
1893static void ssl_sock_populate_sni_keytypes_hplr(const char *str, struct eb_root *sni_keytypes, int key_index)
1894{
1895 struct sni_keytype *s_kt = NULL;
1896 struct ebmb_node *node;
1897 int i;
1898
1899 for (i = 0; i < trash.size; i++) {
1900 if (!str[i])
1901 break;
1902 trash.str[i] = tolower(str[i]);
1903 }
1904 trash.str[i] = 0;
1905 node = ebst_lookup(sni_keytypes, trash.str);
1906 if (!node) {
1907 /* CN not found in tree */
1908 s_kt = malloc(sizeof(struct sni_keytype) + i + 1);
1909 /* Using memcpy here instead of strncpy.
1910 * strncpy will cause sig_abrt errors under certain versions of gcc with -O2
1911 * See: https://gcc.gnu.org/bugzilla/show_bug.cgi?id=60792
1912 */
1913 memcpy(s_kt->name.key, trash.str, i+1);
1914 s_kt->keytypes = 0;
1915 ebst_insert(sni_keytypes, &s_kt->name);
1916 } else {
1917 /* CN found in tree */
1918 s_kt = container_of(node, struct sni_keytype, name);
1919 }
1920
1921 /* Mark that this CN has the keytype of key_index via keytypes mask */
1922 s_kt->keytypes |= 1<<key_index;
1923
1924}
1925
1926
1927/* Given a path that does not exist, try to check for path.rsa, path.dsa and path.ecdsa files.
1928 * If any are found, group these files into a set of SSL_CTX*
1929 * based on shared and unique CN and SAN entries. Add these SSL_CTX* to the SNI tree.
1930 *
1931 * This will allow the user to explictly group multiple cert/keys for a single purpose
1932 *
1933 * Returns
1934 * 0 on success
1935 * 1 on failure
1936 */
Emmanuel Hocdetd294aea2016-05-13 11:14:06 +02001937static 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 -05001938{
1939 char fp[MAXPATHLEN+1] = {0};
1940 int n = 0;
1941 int i = 0;
1942 struct cert_key_and_chain certs_and_keys[SSL_SOCK_NUM_KEYTYPES] = { {0} };
1943 struct eb_root sni_keytypes_map = { {0} };
1944 struct ebmb_node *node;
1945 struct ebmb_node *next;
1946 /* Array of SSL_CTX pointers corresponding to each possible combo
1947 * of keytypes
1948 */
1949 struct key_combo_ctx key_combos[SSL_SOCK_POSSIBLE_KT_COMBOS] = { {0} };
1950 int rv = 0;
1951 X509_NAME *xname = NULL;
1952 char *str = NULL;
1953#ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME
1954 STACK_OF(GENERAL_NAME) *names = NULL;
1955#endif
1956
1957 /* Load all possible certs and keys */
1958 for (n = 0; n < SSL_SOCK_NUM_KEYTYPES; n++) {
1959 struct stat buf;
1960
1961 snprintf(fp, sizeof(fp), "%s.%s", path, SSL_SOCK_KEYTYPE_NAMES[n]);
1962 if (stat(fp, &buf) == 0) {
1963 if (ssl_sock_load_crt_file_into_ckch(fp, &certs_and_keys[n], err) == 1) {
1964 rv = 1;
1965 goto end;
1966 }
1967 }
1968 }
1969
1970 /* Process each ckch and update keytypes for each CN/SAN
1971 * for example, if CN/SAN www.a.com is associated with
1972 * certs with keytype 0 and 2, then at the end of the loop,
1973 * www.a.com will have:
1974 * keyindex = 0 | 1 | 4 = 5
1975 */
1976 for (n = 0; n < SSL_SOCK_NUM_KEYTYPES; n++) {
1977
1978 if (!ssl_sock_is_ckch_valid(&certs_and_keys[n]))
1979 continue;
1980
Emmanuel Hocdetd294aea2016-05-13 11:14:06 +02001981 if (fcount) {
1982 for (i = 0; i < fcount, i++)
1983 ssl_sock_populate_sni_keytypes_hplr(sni_filter[i], &sni_keytypes_map, n);
1984 } else {
1985 /* A lot of the following code is OpenSSL boilerplate for processing CN's and SAN's,
1986 * so the line that contains logic is marked via comments
1987 */
1988 xname = X509_get_subject_name(certs_and_keys[n].cert);
1989 i = -1;
1990 while ((i = X509_NAME_get_index_by_NID(xname, NID_commonName, i)) != -1) {
1991 X509_NAME_ENTRY *entry = X509_NAME_get_entry(xname, i);
yanbzhu08ce6ab2015-12-02 13:01:29 -05001992
Emmanuel Hocdetd294aea2016-05-13 11:14:06 +02001993 if (ASN1_STRING_to_UTF8((unsigned char **)&str, entry->value) >= 0) {
1994 /* Important line is here */
1995 ssl_sock_populate_sni_keytypes_hplr(str, &sni_keytypes_map, n);
yanbzhu08ce6ab2015-12-02 13:01:29 -05001996
Emmanuel Hocdetd294aea2016-05-13 11:14:06 +02001997 OPENSSL_free(str);
1998 str = NULL;
1999 }
yanbzhu08ce6ab2015-12-02 13:01:29 -05002000 }
yanbzhu08ce6ab2015-12-02 13:01:29 -05002001
Emmanuel Hocdetd294aea2016-05-13 11:14:06 +02002002 /* Do the above logic for each SAN */
yanbzhu08ce6ab2015-12-02 13:01:29 -05002003#ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME
Emmanuel Hocdetd294aea2016-05-13 11:14:06 +02002004 names = X509_get_ext_d2i(certs_and_keys[n].cert, NID_subject_alt_name, NULL, NULL);
2005 if (names) {
2006 for (i = 0; i < sk_GENERAL_NAME_num(names); i++) {
2007 GENERAL_NAME *name = sk_GENERAL_NAME_value(names, i);
yanbzhu08ce6ab2015-12-02 13:01:29 -05002008
Emmanuel Hocdetd294aea2016-05-13 11:14:06 +02002009 if (name->type == GEN_DNS) {
2010 if (ASN1_STRING_to_UTF8((unsigned char **)&str, name->d.dNSName) >= 0) {
2011 /* Important line is here */
2012 ssl_sock_populate_sni_keytypes_hplr(str, &sni_keytypes_map, n);
yanbzhu08ce6ab2015-12-02 13:01:29 -05002013
Emmanuel Hocdetd294aea2016-05-13 11:14:06 +02002014 OPENSSL_free(str);
2015 str = NULL;
2016 }
yanbzhu08ce6ab2015-12-02 13:01:29 -05002017 }
2018 }
2019 }
2020 }
2021#endif /* SSL_CTRL_SET_TLSEXT_HOSTNAME */
2022 }
2023
2024 /* If no files found, return error */
2025 if (eb_is_empty(&sni_keytypes_map)) {
2026 memprintf(err, "%sunable to load SSL certificate file '%s' file does not exist.\n",
2027 err && *err ? *err : "", path);
2028 rv = 1;
2029 goto end;
2030 }
2031
2032 /* We now have a map of CN/SAN to keytypes that are loaded in
2033 * Iterate through the map to create the SSL_CTX's (if needed)
2034 * and add each CTX to the SNI tree
2035 *
2036 * Some math here:
2037 * There are 2^n - 1 possibile combinations, each unique
2038 * combination is denoted by the key in the map. Each key
2039 * has a value between 1 and 2^n - 1. Conveniently, the array
2040 * of SSL_CTX* is sized 2^n. So, we can simply use the i'th
2041 * entry in the array to correspond to the unique combo (key)
2042 * associated with i. This unique key combo (i) will be associated
2043 * with combos[i-1]
2044 */
2045
2046 node = ebmb_first(&sni_keytypes_map);
2047 while (node) {
2048 SSL_CTX *cur_ctx;
2049
2050 str = (char *)container_of(node, struct sni_keytype, name)->name.key;
2051 i = container_of(node, struct sni_keytype, name)->keytypes;
2052 cur_ctx = key_combos[i-1].ctx;
2053
2054 if (cur_ctx == NULL) {
2055 /* need to create SSL_CTX */
2056 cur_ctx = SSL_CTX_new(SSLv23_server_method());
2057 if (cur_ctx == NULL) {
2058 memprintf(err, "%sunable to allocate SSL context.\n",
2059 err && *err ? *err : "");
2060 rv = 1;
2061 goto end;
2062 }
2063
yanbzhube2774d2015-12-10 15:07:30 -05002064 /* Load all required certs/keys/chains/OCSPs info into SSL_CTX */
yanbzhu08ce6ab2015-12-02 13:01:29 -05002065 for (n = 0; n < SSL_SOCK_NUM_KEYTYPES; n++) {
2066 if (i & (1<<n)) {
2067 /* Key combo contains ckch[n] */
2068 snprintf(trash.str, trash.size, "%s.%s", path, SSL_SOCK_KEYTYPE_NAMES[n]);
2069 if (ssl_sock_put_ckch_into_ctx(trash.str, &certs_and_keys[n], cur_ctx, err) != 0) {
2070 SSL_CTX_free(cur_ctx);
2071 rv = 1;
2072 goto end;
2073 }
yanbzhube2774d2015-12-10 15:07:30 -05002074
2075#if (defined SSL_CTRL_SET_TLSEXT_STATUS_REQ_CB && !defined OPENSSL_NO_OCSP)
2076 /* Load OCSP Info into context */
2077 if (ssl_sock_load_ocsp(cur_ctx, trash.str) < 0) {
2078 if (err)
2079 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",
2080 *err ? *err : "", path);
2081 SSL_CTX_free(cur_ctx);
2082 rv = 1;
2083 goto end;
2084 }
2085#endif
yanbzhu08ce6ab2015-12-02 13:01:29 -05002086 }
2087 }
2088
2089 /* Load DH params into the ctx to support DHE keys */
2090#ifndef OPENSSL_NO_DH
2091 if (ssl_dh_ptr_index >= 0)
2092 SSL_CTX_set_ex_data(cur_ctx, ssl_dh_ptr_index, NULL);
2093
2094 rv = ssl_sock_load_dh_params(cur_ctx, NULL);
2095 if (rv < 0) {
2096 if (err)
2097 memprintf(err, "%sunable to load DH parameters from file '%s'.\n",
2098 *err ? *err : "", path);
2099 rv = 1;
2100 goto end;
2101 }
2102#endif
2103
2104 /* Update key_combos */
2105 key_combos[i-1].ctx = cur_ctx;
2106 }
2107
2108 /* Update SNI Tree */
Emmanuel Hocdetd294aea2016-05-13 11:14:06 +02002109 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 -05002110 node = ebmb_next(node);
2111 }
2112
2113
2114 /* Mark a default context if none exists, using the ctx that has the most shared keys */
2115 if (!bind_conf->default_ctx) {
2116 for (i = SSL_SOCK_POSSIBLE_KT_COMBOS - 1; i >= 0; i--) {
2117 if (key_combos[i].ctx) {
2118 bind_conf->default_ctx = key_combos[i].ctx;
2119 break;
2120 }
2121 }
2122 }
2123
2124end:
2125
2126 if (names)
2127 sk_GENERAL_NAME_pop_free(names, GENERAL_NAME_free);
2128
2129 for (n = 0; n < SSL_SOCK_NUM_KEYTYPES; n++)
2130 ssl_sock_free_cert_key_and_chain_contents(&certs_and_keys[n]);
2131
2132 node = ebmb_first(&sni_keytypes_map);
2133 while (node) {
2134 next = ebmb_next(node);
2135 ebmb_delete(node);
2136 node = next;
2137 }
2138
2139 return rv;
2140}
2141#else
2142/* This is a dummy, that just logs an error and returns error */
Emmanuel Hocdetd294aea2016-05-13 11:14:06 +02002143static 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 -05002144{
2145 memprintf(err, "%sunable to stat SSL certificate from file '%s' : %s.\n",
2146 err && *err ? *err : "", path, strerror(errno));
2147 return 1;
2148}
2149
yanbzhu488a4d22015-12-01 15:16:07 -05002150#endif /* #if OPENSSL_VERSION_NUMBER >= 0x1000200fL: Support for loading multiple certs into a single SSL_CTX */
2151
Emeric Brunfc0421f2012-09-07 17:30:07 +02002152/* Loads a certificate key and CA chain from a file. Returns 0 on error, -1 if
2153 * an early error happens and the caller must call SSL_CTX_free() by itelf.
2154 */
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +02002155static 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 +02002156{
2157 BIO *in;
2158 X509 *x = NULL, *ca;
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +02002159 int i, err;
Emeric Brunfc0421f2012-09-07 17:30:07 +02002160 int ret = -1;
2161 int order = 0;
2162 X509_NAME *xname;
2163 char *str;
Emeric Brunfc0421f2012-09-07 17:30:07 +02002164#ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME
2165 STACK_OF(GENERAL_NAME) *names;
2166#endif
2167
2168 in = BIO_new(BIO_s_file());
2169 if (in == NULL)
2170 goto end;
2171
2172 if (BIO_read_filename(in, file) <= 0)
2173 goto end;
2174
2175 x = PEM_read_bio_X509_AUX(in, NULL, ctx->default_passwd_callback, ctx->default_passwd_callback_userdata);
2176 if (x == NULL)
2177 goto end;
2178
Emeric Brun50bcecc2013-04-22 13:05:23 +02002179 if (fcount) {
2180 while (fcount--)
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +02002181 order = ssl_sock_add_cert_sni(ctx, s, sni_filter[fcount], order);
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01002182 }
2183 else {
Emeric Brunfc0421f2012-09-07 17:30:07 +02002184#ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01002185 names = X509_get_ext_d2i(x, NID_subject_alt_name, NULL, NULL);
2186 if (names) {
2187 for (i = 0; i < sk_GENERAL_NAME_num(names); i++) {
2188 GENERAL_NAME *name = sk_GENERAL_NAME_value(names, i);
2189 if (name->type == GEN_DNS) {
2190 if (ASN1_STRING_to_UTF8((unsigned char **)&str, name->d.dNSName) >= 0) {
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +02002191 order = ssl_sock_add_cert_sni(ctx, s, str, order);
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01002192 OPENSSL_free(str);
Emeric Brunfc0421f2012-09-07 17:30:07 +02002193 }
Emeric Brunfc0421f2012-09-07 17:30:07 +02002194 }
2195 }
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01002196 sk_GENERAL_NAME_pop_free(names, GENERAL_NAME_free);
Emeric Brunfc0421f2012-09-07 17:30:07 +02002197 }
Emeric Brunfc0421f2012-09-07 17:30:07 +02002198#endif /* SSL_CTRL_SET_TLSEXT_HOSTNAME */
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01002199 xname = X509_get_subject_name(x);
2200 i = -1;
2201 while ((i = X509_NAME_get_index_by_NID(xname, NID_commonName, i)) != -1) {
2202 X509_NAME_ENTRY *entry = X509_NAME_get_entry(xname, i);
2203 if (ASN1_STRING_to_UTF8((unsigned char **)&str, entry->value) >= 0) {
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +02002204 order = ssl_sock_add_cert_sni(ctx, s, str, order);
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01002205 OPENSSL_free(str);
Emeric Brunfc0421f2012-09-07 17:30:07 +02002206 }
Emeric Brunfc0421f2012-09-07 17:30:07 +02002207 }
2208 }
2209
2210 ret = 0; /* the caller must not free the SSL_CTX argument anymore */
2211 if (!SSL_CTX_use_certificate(ctx, x))
2212 goto end;
2213
2214 if (ctx->extra_certs != NULL) {
2215 sk_X509_pop_free(ctx->extra_certs, X509_free);
2216 ctx->extra_certs = NULL;
2217 }
2218
2219 while ((ca = PEM_read_bio_X509(in, NULL, ctx->default_passwd_callback, ctx->default_passwd_callback_userdata))) {
2220 if (!SSL_CTX_add_extra_chain_cert(ctx, ca)) {
2221 X509_free(ca);
2222 goto end;
2223 }
2224 }
2225
2226 err = ERR_get_error();
2227 if (!err || (ERR_GET_LIB(err) == ERR_LIB_PEM && ERR_GET_REASON(err) == PEM_R_NO_START_LINE)) {
2228 /* we successfully reached the last cert in the file */
2229 ret = 1;
2230 }
2231 ERR_clear_error();
2232
2233end:
2234 if (x)
2235 X509_free(x);
2236
2237 if (in)
2238 BIO_free(in);
2239
2240 return ret;
2241}
2242
Emeric Brun50bcecc2013-04-22 13:05:23 +02002243static 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 +02002244{
2245 int ret;
2246 SSL_CTX *ctx;
2247
2248 ctx = SSL_CTX_new(SSLv23_server_method());
2249 if (!ctx) {
Willy Tarreaueb6cead2012-09-20 19:43:14 +02002250 memprintf(err, "%sunable to allocate SSL context for cert '%s'.\n",
2251 err && *err ? *err : "", path);
Emeric Brunfc0421f2012-09-07 17:30:07 +02002252 return 1;
2253 }
2254
2255 if (SSL_CTX_use_PrivateKey_file(ctx, path, SSL_FILETYPE_PEM) <= 0) {
Willy Tarreaueb6cead2012-09-20 19:43:14 +02002256 memprintf(err, "%sunable to load SSL private key from PEM file '%s'.\n",
2257 err && *err ? *err : "", path);
Emeric Brunfc0421f2012-09-07 17:30:07 +02002258 SSL_CTX_free(ctx);
2259 return 1;
2260 }
2261
Emeric Brun50bcecc2013-04-22 13:05:23 +02002262 ret = ssl_sock_load_cert_chain_file(ctx, path, bind_conf, sni_filter, fcount);
Emeric Brunfc0421f2012-09-07 17:30:07 +02002263 if (ret <= 0) {
Willy Tarreaueb6cead2012-09-20 19:43:14 +02002264 memprintf(err, "%sunable to load SSL certificate from PEM file '%s'.\n",
2265 err && *err ? *err : "", path);
Emeric Brunfc0421f2012-09-07 17:30:07 +02002266 if (ret < 0) /* serious error, must do that ourselves */
2267 SSL_CTX_free(ctx);
2268 return 1;
2269 }
Emeric Brun61694ab2012-10-26 13:35:33 +02002270
2271 if (SSL_CTX_check_private_key(ctx) <= 0) {
2272 memprintf(err, "%sinconsistencies between private key and certificate loaded from PEM file '%s'.\n",
2273 err && *err ? *err : "", path);
2274 return 1;
2275 }
2276
Emeric Brunfc0421f2012-09-07 17:30:07 +02002277 /* we must not free the SSL_CTX anymore below, since it's already in
2278 * the tree, so it will be discovered and cleaned in time.
2279 */
Emeric Bruna4bcd9a2012-09-20 16:19:02 +02002280#ifndef OPENSSL_NO_DH
Remi Gacogne4f902b82015-05-28 16:23:00 +02002281 /* store a NULL pointer to indicate we have not yet loaded
2282 a custom DH param file */
2283 if (ssl_dh_ptr_index >= 0) {
2284 SSL_CTX_set_ex_data(ctx, ssl_dh_ptr_index, NULL);
2285 }
2286
Emeric Bruna4bcd9a2012-09-20 16:19:02 +02002287 ret = ssl_sock_load_dh_params(ctx, path);
2288 if (ret < 0) {
2289 if (err)
2290 memprintf(err, "%sunable to load DH parameters from file '%s'.\n",
2291 *err ? *err : "", path);
2292 return 1;
2293 }
2294#endif
2295
Lukas Tribuse4e30f72014-12-09 16:32:51 +01002296#if (defined SSL_CTRL_SET_TLSEXT_STATUS_REQ_CB && !defined OPENSSL_NO_OCSP)
Emeric Brun4147b2e2014-06-16 18:36:30 +02002297 ret = ssl_sock_load_ocsp(ctx, path);
2298 if (ret < 0) {
2299 if (err)
2300 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",
2301 *err ? *err : "", path);
2302 return 1;
2303 }
2304#endif
2305
Daniel Jakots54ffb912015-11-06 20:02:41 +01002306#if (OPENSSL_VERSION_NUMBER >= 0x1000200fL && !defined OPENSSL_NO_TLSEXT && !defined OPENSSL_IS_BORINGSSL && !defined LIBRESSL_VERSION_NUMBER)
Janusz Dziemidowicz2c701b52015-03-07 23:03:59 +01002307 if (sctl_ex_index >= 0) {
2308 ret = ssl_sock_load_sctl(ctx, path);
2309 if (ret < 0) {
2310 if (err)
2311 memprintf(err, "%s '%s.sctl' is present but cannot be read or parsed'.\n",
2312 *err ? *err : "", path);
2313 return 1;
2314 }
2315 }
2316#endif
2317
Emeric Brunfc0421f2012-09-07 17:30:07 +02002318#ifndef SSL_CTRL_SET_TLSEXT_HOSTNAME
Willy Tarreau2a65ff02012-09-13 17:54:29 +02002319 if (bind_conf->default_ctx) {
Willy Tarreaueb6cead2012-09-20 19:43:14 +02002320 memprintf(err, "%sthis version of openssl cannot load multiple SSL certificates.\n",
2321 err && *err ? *err : "");
Emeric Brunfc0421f2012-09-07 17:30:07 +02002322 return 1;
2323 }
2324#endif
Willy Tarreau2a65ff02012-09-13 17:54:29 +02002325 if (!bind_conf->default_ctx)
2326 bind_conf->default_ctx = ctx;
Emeric Brunfc0421f2012-09-07 17:30:07 +02002327
2328 return 0;
2329}
2330
Willy Tarreau79eeafa2012-09-14 07:53:05 +02002331int ssl_sock_load_cert(char *path, struct bind_conf *bind_conf, struct proxy *curproxy, char **err)
Emeric Brunfc0421f2012-09-07 17:30:07 +02002332{
Cyril Bonté3180f7b2015-01-25 00:16:08 +01002333 struct dirent **de_list;
2334 int i, n;
Emeric Brunfc0421f2012-09-07 17:30:07 +02002335 DIR *dir;
2336 struct stat buf;
Willy Tarreauee2663b2012-12-06 11:36:59 +01002337 char *end;
2338 char fp[MAXPATHLEN+1];
Emeric Brunfc0421f2012-09-07 17:30:07 +02002339 int cfgerr = 0;
yanbzhu63ea8462015-12-09 13:35:14 -05002340#if OPENSSL_VERSION_NUMBER >= 0x1000200fL
2341 int is_bundle;
2342 int j;
2343#endif
Emeric Brunfc0421f2012-09-07 17:30:07 +02002344
yanbzhu08ce6ab2015-12-02 13:01:29 -05002345 if (stat(path, &buf) == 0) {
2346 dir = opendir(path);
2347 if (!dir)
2348 return ssl_sock_load_cert_file(path, bind_conf, curproxy, NULL, 0, err);
Emeric Brunfc0421f2012-09-07 17:30:07 +02002349
yanbzhu08ce6ab2015-12-02 13:01:29 -05002350 /* strip trailing slashes, including first one */
2351 for (end = path + strlen(path) - 1; end >= path && *end == '/'; end--)
2352 *end = 0;
Emeric Brunfc0421f2012-09-07 17:30:07 +02002353
yanbzhu08ce6ab2015-12-02 13:01:29 -05002354 n = scandir(path, &de_list, 0, alphasort);
2355 if (n < 0) {
2356 memprintf(err, "%sunable to scan directory '%s' : %s.\n",
2357 err && *err ? *err : "", path, strerror(errno));
2358 cfgerr++;
2359 }
2360 else {
2361 for (i = 0; i < n; i++) {
2362 struct dirent *de = de_list[i];
Emeric Brun2aab7222014-06-18 18:15:09 +02002363
yanbzhu08ce6ab2015-12-02 13:01:29 -05002364 end = strrchr(de->d_name, '.');
2365 if (end && (!strcmp(end, ".issuer") || !strcmp(end, ".ocsp") || !strcmp(end, ".sctl")))
2366 goto ignore_entry;
Cyril Bonté3180f7b2015-01-25 00:16:08 +01002367
yanbzhu08ce6ab2015-12-02 13:01:29 -05002368 snprintf(fp, sizeof(fp), "%s/%s", path, de->d_name);
2369 if (stat(fp, &buf) != 0) {
2370 memprintf(err, "%sunable to stat SSL certificate from file '%s' : %s.\n",
2371 err && *err ? *err : "", fp, strerror(errno));
2372 cfgerr++;
2373 goto ignore_entry;
2374 }
2375 if (!S_ISREG(buf.st_mode))
2376 goto ignore_entry;
yanbzhu63ea8462015-12-09 13:35:14 -05002377
2378#if OPENSSL_VERSION_NUMBER >= 0x1000200fL
2379 is_bundle = 0;
2380 /* Check if current entry in directory is part of a multi-cert bundle */
2381
2382 if (end) {
2383 for (j = 0; j < SSL_SOCK_NUM_KEYTYPES; j++) {
2384 if (!strcmp(end + 1, SSL_SOCK_KEYTYPE_NAMES[j])) {
2385 is_bundle = 1;
2386 break;
2387 }
2388 }
2389
2390 if (is_bundle) {
2391 char dp[MAXPATHLEN+1] = {0}; /* this will be the filename w/o the keytype */
2392 int dp_len;
2393
2394 dp_len = end - de->d_name;
2395 snprintf(dp, dp_len + 1, "%s", de->d_name);
2396
2397 /* increment i and free de until we get to a non-bundle cert
2398 * Note here that we look at de_list[i + 1] before freeing de
2399 * this is important since ignore_entry will free de
2400 */
2401 while (i + 1 < n && !strncmp(de_list[i + 1]->d_name, dp, dp_len)) {
2402 free(de);
2403 i++;
2404 de = de_list[i];
2405 }
2406
2407 snprintf(fp, sizeof(fp), "%s/%s", path, dp);
Emmanuel Hocdetd294aea2016-05-13 11:14:06 +02002408 ssl_sock_load_multi_cert(fp, bind_conf, curproxy, NULL, 0, err);
yanbzhu63ea8462015-12-09 13:35:14 -05002409
2410 /* Successfully processed the bundle */
2411 goto ignore_entry;
2412 }
2413 }
2414
2415#endif
yanbzhu08ce6ab2015-12-02 13:01:29 -05002416 cfgerr += ssl_sock_load_cert_file(fp, bind_conf, curproxy, NULL, 0, err);
2417ignore_entry:
2418 free(de);
Cyril Bonté3180f7b2015-01-25 00:16:08 +01002419 }
yanbzhu08ce6ab2015-12-02 13:01:29 -05002420 free(de_list);
Emeric Brunfc0421f2012-09-07 17:30:07 +02002421 }
yanbzhu08ce6ab2015-12-02 13:01:29 -05002422 closedir(dir);
2423 return cfgerr;
Emeric Brunfc0421f2012-09-07 17:30:07 +02002424 }
yanbzhu08ce6ab2015-12-02 13:01:29 -05002425
Emmanuel Hocdetd294aea2016-05-13 11:14:06 +02002426 cfgerr = ssl_sock_load_multi_cert(path, bind_conf, curproxy, NULL, 0, err);
yanbzhu08ce6ab2015-12-02 13:01:29 -05002427
Emeric Brunfc0421f2012-09-07 17:30:07 +02002428 return cfgerr;
2429}
2430
Thierry Fournier383085f2013-01-24 14:15:43 +01002431/* Make sure openssl opens /dev/urandom before the chroot. The work is only
2432 * done once. Zero is returned if the operation fails. No error is returned
2433 * if the random is said as not implemented, because we expect that openssl
2434 * will use another method once needed.
2435 */
2436static int ssl_initialize_random()
2437{
2438 unsigned char random;
2439 static int random_initialized = 0;
2440
2441 if (!random_initialized && RAND_bytes(&random, 1) != 0)
2442 random_initialized = 1;
2443
2444 return random_initialized;
2445}
2446
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01002447int ssl_sock_load_cert_list_file(char *file, struct bind_conf *bind_conf, struct proxy *curproxy, char **err)
2448{
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +02002449 char thisline[LINESIZE];
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01002450 FILE *f;
yanbzhu1b04e5b2015-12-02 13:54:14 -05002451 struct stat buf;
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01002452 int linenum = 0;
2453 int cfgerr = 0;
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01002454
Willy Tarreauad1731d2013-04-02 17:35:58 +02002455 if ((f = fopen(file, "r")) == NULL) {
2456 memprintf(err, "cannot open file '%s' : %s", file, strerror(errno));
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01002457 return 1;
Willy Tarreauad1731d2013-04-02 17:35:58 +02002458 }
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01002459
2460 while (fgets(thisline, sizeof(thisline), f) != NULL) {
2461 int arg;
Emeric Brun50bcecc2013-04-22 13:05:23 +02002462 int newarg;
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01002463 char *end;
2464 char *args[MAX_LINE_ARGS + 1];
2465 char *line = thisline;
2466
2467 linenum++;
2468 end = line + strlen(line);
2469 if (end-line == sizeof(thisline)-1 && *(end-1) != '\n') {
2470 /* Check if we reached the limit and the last char is not \n.
2471 * Watch out for the last line without the terminating '\n'!
2472 */
Willy Tarreauad1731d2013-04-02 17:35:58 +02002473 memprintf(err, "line %d too long in file '%s', limit is %d characters",
2474 linenum, file, (int)sizeof(thisline)-1);
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01002475 cfgerr = 1;
Willy Tarreauad1731d2013-04-02 17:35:58 +02002476 break;
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01002477 }
2478
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01002479 arg = 0;
Emeric Brun50bcecc2013-04-22 13:05:23 +02002480 newarg = 1;
2481 while (*line) {
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01002482 if (*line == '#' || *line == '\n' || *line == '\r') {
2483 /* end of string, end of loop */
2484 *line = 0;
2485 break;
2486 }
2487 else if (isspace(*line)) {
Emeric Brun50bcecc2013-04-22 13:05:23 +02002488 newarg = 1;
2489 *line = 0;
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01002490 }
Emeric Brun50bcecc2013-04-22 13:05:23 +02002491 else if (newarg) {
2492 if (arg == MAX_LINE_ARGS) {
2493 memprintf(err, "too many args on line %d in file '%s'.",
2494 linenum, file);
2495 cfgerr = 1;
2496 break;
2497 }
2498 newarg = 0;
2499 args[arg++] = line;
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01002500 }
Emeric Brun50bcecc2013-04-22 13:05:23 +02002501 line++;
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01002502 }
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +02002503 if (cfgerr)
2504 break;
Willy Tarreauad1731d2013-04-02 17:35:58 +02002505
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01002506 /* empty line */
Emeric Brun50bcecc2013-04-22 13:05:23 +02002507 if (!arg)
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01002508 continue;
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01002509
yanbzhu1b04e5b2015-12-02 13:54:14 -05002510 if (stat(args[0], &buf) == 0) {
2511 cfgerr = ssl_sock_load_cert_file(args[0], bind_conf, curproxy, &args[1], arg-1, err);
2512 } else {
Emmanuel Hocdetd294aea2016-05-13 11:14:06 +02002513 cfgerr = ssl_sock_load_multi_cert(args[0], bind_conf, curproxy, &args[1], arg-1, err);
yanbzhu1b04e5b2015-12-02 13:54:14 -05002514 }
2515
Willy Tarreauad1731d2013-04-02 17:35:58 +02002516 if (cfgerr) {
2517 memprintf(err, "error processing line %d in file '%s' : %s", linenum, file, *err);
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01002518 break;
Willy Tarreauad1731d2013-04-02 17:35:58 +02002519 }
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01002520 }
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01002521 fclose(f);
2522 return cfgerr;
2523}
2524
Emeric Brunfc0421f2012-09-07 17:30:07 +02002525#ifndef SSL_OP_CIPHER_SERVER_PREFERENCE /* needs OpenSSL >= 0.9.7 */
2526#define SSL_OP_CIPHER_SERVER_PREFERENCE 0
2527#endif
2528
2529#ifndef SSL_OP_NO_SESSION_RESUMPTION_ON_RENEGOTIATION /* needs OpenSSL >= 0.9.7 */
2530#define SSL_OP_NO_SESSION_RESUMPTION_ON_RENEGOTIATION 0
Willy Tarreau7d588ee2012-11-26 18:47:31 +01002531#define SSL_renegotiate_pending(arg) 0
Emeric Brunfc0421f2012-09-07 17:30:07 +02002532#endif
Emeric Brun2b58d042012-09-20 17:10:03 +02002533#ifndef SSL_OP_SINGLE_ECDH_USE /* needs OpenSSL >= 0.9.8 */
2534#define SSL_OP_SINGLE_ECDH_USE 0
2535#endif
Emeric Brun2d0c4822012-10-02 13:45:20 +02002536#ifndef SSL_OP_NO_TICKET /* needs OpenSSL >= 0.9.8 */
2537#define SSL_OP_NO_TICKET 0
2538#endif
Emeric Brunfc0421f2012-09-07 17:30:07 +02002539#ifndef SSL_OP_NO_COMPRESSION /* needs OpenSSL >= 0.9.9 */
2540#define SSL_OP_NO_COMPRESSION 0
2541#endif
Emeric Brunc0ff4922012-09-28 19:37:02 +02002542#ifndef SSL_OP_NO_TLSv1_1 /* needs OpenSSL >= 1.0.1 */
2543#define SSL_OP_NO_TLSv1_1 0
2544#endif
2545#ifndef SSL_OP_NO_TLSv1_2 /* needs OpenSSL >= 1.0.1 */
2546#define SSL_OP_NO_TLSv1_2 0
2547#endif
Emeric Bruna4bcd9a2012-09-20 16:19:02 +02002548#ifndef SSL_OP_SINGLE_DH_USE /* needs OpenSSL >= 0.9.6 */
2549#define SSL_OP_SINGLE_DH_USE 0
2550#endif
Emeric Brun2b58d042012-09-20 17:10:03 +02002551#ifndef SSL_OP_SINGLE_ECDH_USE /* needs OpenSSL >= 1.0.0 */
2552#define SSL_OP_SINGLE_ECDH_USE 0
2553#endif
Emeric Brunfc0421f2012-09-07 17:30:07 +02002554#ifndef SSL_MODE_RELEASE_BUFFERS /* needs OpenSSL >= 1.0.0 */
2555#define SSL_MODE_RELEASE_BUFFERS 0
2556#endif
Willy Tarreau396a1862014-11-13 14:06:52 +01002557#ifndef SSL_MODE_SMALL_BUFFERS /* needs small_records.patch */
2558#define SSL_MODE_SMALL_BUFFERS 0
2559#endif
Remi Gacognef46cd6e2014-06-12 14:58:40 +02002560
Willy Tarreau2a65ff02012-09-13 17:54:29 +02002561int ssl_sock_prepare_ctx(struct bind_conf *bind_conf, SSL_CTX *ctx, struct proxy *curproxy)
Emeric Brunfc0421f2012-09-07 17:30:07 +02002562{
2563 int cfgerr = 0;
Emeric Brun850efd52014-01-29 12:24:34 +01002564 int verify = SSL_VERIFY_NONE;
Remi Gacogneaf5c3da2014-05-19 10:29:58 +02002565 long ssloptions =
Emeric Brunfc0421f2012-09-07 17:30:07 +02002566 SSL_OP_ALL | /* all known workarounds for bugs */
2567 SSL_OP_NO_SSLv2 |
2568 SSL_OP_NO_COMPRESSION |
Emeric Bruna4bcd9a2012-09-20 16:19:02 +02002569 SSL_OP_SINGLE_DH_USE |
Emeric Brun2b58d042012-09-20 17:10:03 +02002570 SSL_OP_SINGLE_ECDH_USE |
Emeric Brun3c4bc6e2012-10-04 18:44:19 +02002571 SSL_OP_NO_SESSION_RESUMPTION_ON_RENEGOTIATION |
2572 SSL_OP_CIPHER_SERVER_PREFERENCE;
Remi Gacogneaf5c3da2014-05-19 10:29:58 +02002573 long sslmode =
Emeric Brunfc0421f2012-09-07 17:30:07 +02002574 SSL_MODE_ENABLE_PARTIAL_WRITE |
2575 SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER |
Willy Tarreau396a1862014-11-13 14:06:52 +01002576 SSL_MODE_RELEASE_BUFFERS |
2577 SSL_MODE_SMALL_BUFFERS;
Remi Gacognef46cd6e2014-06-12 14:58:40 +02002578 STACK_OF(SSL_CIPHER) * ciphers = NULL;
Willy Tarreaua616ba62014-10-26 06:49:19 +01002579 SSL_CIPHER * cipher = NULL;
Remi Gacognec1eab8c2014-06-12 18:20:11 +02002580 char cipher_description[128];
2581 /* The description of ciphers using an Ephemeral Diffie Hellman key exchange
2582 contains " Kx=DH " or " Kx=DH(". Beware of " Kx=DH/",
2583 which is not ephemeral DH. */
2584 const char dhe_description[] = " Kx=DH ";
2585 const char dhe_export_description[] = " Kx=DH(";
Remi Gacognef46cd6e2014-06-12 14:58:40 +02002586 int idx = 0;
2587 int dhe_found = 0;
Remi Gacogne23d5d372014-10-10 17:04:26 +02002588 SSL *ssl = NULL;
Emeric Brunfc0421f2012-09-07 17:30:07 +02002589
Thierry Fournier383085f2013-01-24 14:15:43 +01002590 /* Make sure openssl opens /dev/urandom before the chroot */
2591 if (!ssl_initialize_random()) {
2592 Alert("OpenSSL random data generator initialization failed.\n");
2593 cfgerr++;
2594 }
2595
Emeric Brun89675492012-10-05 13:48:26 +02002596 if (bind_conf->ssl_options & BC_SSL_O_NO_SSLV3)
Emeric Brunfc0421f2012-09-07 17:30:07 +02002597 ssloptions |= SSL_OP_NO_SSLv3;
Emeric Brun89675492012-10-05 13:48:26 +02002598 if (bind_conf->ssl_options & BC_SSL_O_NO_TLSV10)
Emeric Brunfc0421f2012-09-07 17:30:07 +02002599 ssloptions |= SSL_OP_NO_TLSv1;
Emeric Brun89675492012-10-05 13:48:26 +02002600 if (bind_conf->ssl_options & BC_SSL_O_NO_TLSV11)
Emeric Brunc0ff4922012-09-28 19:37:02 +02002601 ssloptions |= SSL_OP_NO_TLSv1_1;
Emeric Brun89675492012-10-05 13:48:26 +02002602 if (bind_conf->ssl_options & BC_SSL_O_NO_TLSV12)
Emeric Brunc0ff4922012-09-28 19:37:02 +02002603 ssloptions |= SSL_OP_NO_TLSv1_2;
Emeric Brun89675492012-10-05 13:48:26 +02002604 if (bind_conf->ssl_options & BC_SSL_O_NO_TLS_TICKETS)
Emeric Brun2d0c4822012-10-02 13:45:20 +02002605 ssloptions |= SSL_OP_NO_TICKET;
Jérémie Courrèges-Anglas17c3f622015-07-25 16:50:52 -06002606 if (bind_conf->ssl_options & BC_SSL_O_USE_SSLV3) {
2607#ifndef OPENSSL_NO_SSL3
Emeric Brun2cb7ae52012-10-05 14:14:21 +02002608 SSL_CTX_set_ssl_version(ctx, SSLv3_server_method());
Jérémie Courrèges-Anglas17c3f622015-07-25 16:50:52 -06002609#else
2610 Alert("SSLv3 support requested but unavailable.\n");
2611 cfgerr++;
2612#endif
2613 }
Emeric Brun2cb7ae52012-10-05 14:14:21 +02002614 if (bind_conf->ssl_options & BC_SSL_O_USE_TLSV10)
2615 SSL_CTX_set_ssl_version(ctx, TLSv1_server_method());
2616#if SSL_OP_NO_TLSv1_1
2617 if (bind_conf->ssl_options & BC_SSL_O_USE_TLSV11)
2618 SSL_CTX_set_ssl_version(ctx, TLSv1_1_server_method());
2619#endif
2620#if SSL_OP_NO_TLSv1_2
2621 if (bind_conf->ssl_options & BC_SSL_O_USE_TLSV12)
2622 SSL_CTX_set_ssl_version(ctx, TLSv1_2_server_method());
2623#endif
Emeric Brunfc0421f2012-09-07 17:30:07 +02002624
2625 SSL_CTX_set_options(ctx, ssloptions);
2626 SSL_CTX_set_mode(ctx, sslmode);
Emeric Brun850efd52014-01-29 12:24:34 +01002627 switch (bind_conf->verify) {
2628 case SSL_SOCK_VERIFY_NONE:
2629 verify = SSL_VERIFY_NONE;
2630 break;
2631 case SSL_SOCK_VERIFY_OPTIONAL:
2632 verify = SSL_VERIFY_PEER;
2633 break;
2634 case SSL_SOCK_VERIFY_REQUIRED:
2635 verify = SSL_VERIFY_PEER|SSL_VERIFY_FAIL_IF_NO_PEER_CERT;
2636 break;
2637 }
2638 SSL_CTX_set_verify(ctx, verify, ssl_sock_bind_verifycbk);
2639 if (verify & SSL_VERIFY_PEER) {
Emeric Brunfb510ea2012-10-05 12:00:26 +02002640 if (bind_conf->ca_file) {
Emeric Brund94b3fe2012-09-20 18:23:56 +02002641 /* load CAfile to verify */
Emeric Brunfb510ea2012-10-05 12:00:26 +02002642 if (!SSL_CTX_load_verify_locations(ctx, bind_conf->ca_file, NULL)) {
Emeric Brund94b3fe2012-09-20 18:23:56 +02002643 Alert("Proxy '%s': unable to load CA file '%s' for bind '%s' at [%s:%d].\n",
Emeric Brunfb510ea2012-10-05 12:00:26 +02002644 curproxy->id, bind_conf->ca_file, bind_conf->arg, bind_conf->file, bind_conf->line);
Emeric Brund94b3fe2012-09-20 18:23:56 +02002645 cfgerr++;
2646 }
2647 /* set CA names fo client cert request, function returns void */
Emeric Brunfb510ea2012-10-05 12:00:26 +02002648 SSL_CTX_set_client_CA_list(ctx, SSL_load_client_CA_file(bind_conf->ca_file));
Emeric Brund94b3fe2012-09-20 18:23:56 +02002649 }
Emeric Brun850efd52014-01-29 12:24:34 +01002650 else {
2651 Alert("Proxy '%s': verify is enabled but no CA file specified for bind '%s' at [%s:%d].\n",
2652 curproxy->id, bind_conf->arg, bind_conf->file, bind_conf->line);
2653 cfgerr++;
2654 }
Emeric Brun051cdab2012-10-02 19:25:50 +02002655#ifdef X509_V_FLAG_CRL_CHECK
Emeric Brunfb510ea2012-10-05 12:00:26 +02002656 if (bind_conf->crl_file) {
Emeric Brund94b3fe2012-09-20 18:23:56 +02002657 X509_STORE *store = SSL_CTX_get_cert_store(ctx);
2658
Emeric Brunfb510ea2012-10-05 12:00:26 +02002659 if (!store || !X509_STORE_load_locations(store, bind_conf->crl_file, NULL)) {
Emeric Brund94b3fe2012-09-20 18:23:56 +02002660 Alert("Proxy '%s': unable to configure CRL file '%s' for bind '%s' at [%s:%d].\n",
Alexander Rigbofc65af02015-04-07 14:02:16 +02002661 curproxy->id, bind_conf->crl_file, bind_conf->arg, bind_conf->file, bind_conf->line);
Emeric Brund94b3fe2012-09-20 18:23:56 +02002662 cfgerr++;
2663 }
Emeric Brun561e5742012-10-02 15:20:55 +02002664 else {
2665 X509_STORE_set_flags(store, X509_V_FLAG_CRL_CHECK|X509_V_FLAG_CRL_CHECK_ALL);
2666 }
Emeric Brund94b3fe2012-09-20 18:23:56 +02002667 }
Emeric Brun051cdab2012-10-02 19:25:50 +02002668#endif
Emeric Brun644cde02012-12-14 11:21:13 +01002669 ERR_clear_error();
Emeric Brund94b3fe2012-09-20 18:23:56 +02002670 }
Emeric Brunfc0421f2012-09-07 17:30:07 +02002671
Nenad Merdanovic05552d42015-02-27 19:56:49 +01002672#if (defined SSL_CTRL_SET_TLSEXT_TICKET_KEY_CB && TLS_TICKETS_NO > 0)
Nenad Merdanovic146defa2015-05-09 08:46:00 +02002673 if(bind_conf->keys_ref) {
Nenad Merdanovic05552d42015-02-27 19:56:49 +01002674 if (!SSL_CTX_set_tlsext_ticket_key_cb(ctx, ssl_tlsext_ticket_key_cb)) {
2675 Alert("Proxy '%s': unable to set callback for TLS ticket validation for bind '%s' at [%s:%d].\n",
2676 curproxy->id, bind_conf->arg, bind_conf->file, bind_conf->line);
2677 cfgerr++;
2678 }
2679 }
2680#endif
2681
Emeric Brun4f65bff2012-11-16 15:11:00 +01002682 if (global.tune.ssllifetime)
2683 SSL_CTX_set_timeout(ctx, global.tune.ssllifetime);
2684
Emeric Brunfc0421f2012-09-07 17:30:07 +02002685 shared_context_set_cache(ctx);
Willy Tarreau2a65ff02012-09-13 17:54:29 +02002686 if (bind_conf->ciphers &&
2687 !SSL_CTX_set_cipher_list(ctx, bind_conf->ciphers)) {
Emeric Brunfc0421f2012-09-07 17:30:07 +02002688 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 +02002689 curproxy->id, bind_conf->ciphers, bind_conf->arg, bind_conf->file, bind_conf->line);
Emeric Brunfc0421f2012-09-07 17:30:07 +02002690 cfgerr++;
2691 }
2692
Remi Gacogne47783ef2015-05-29 15:53:22 +02002693 /* If tune.ssl.default-dh-param has not been set,
2694 neither has ssl-default-dh-file and no static DH
2695 params were in the certificate file. */
Remi Gacogne4f902b82015-05-28 16:23:00 +02002696 if (global.tune.ssl_default_dh_param == 0 &&
Remi Gacogne47783ef2015-05-29 15:53:22 +02002697 global_dh == NULL &&
Remi Gacogne4f902b82015-05-28 16:23:00 +02002698 (ssl_dh_ptr_index == -1 ||
2699 SSL_CTX_get_ex_data(ctx, ssl_dh_ptr_index) == NULL)) {
Lukas Tribus90132722014-08-18 00:56:33 +02002700
Remi Gacogne23d5d372014-10-10 17:04:26 +02002701 ssl = SSL_new(ctx);
Remi Gacognef46cd6e2014-06-12 14:58:40 +02002702
Remi Gacogne23d5d372014-10-10 17:04:26 +02002703 if (ssl) {
2704 ciphers = SSL_get_ciphers(ssl);
2705
2706 if (ciphers) {
2707 for (idx = 0; idx < sk_SSL_CIPHER_num(ciphers); idx++) {
2708 cipher = sk_SSL_CIPHER_value(ciphers, idx);
2709 if (SSL_CIPHER_description(cipher, cipher_description, sizeof (cipher_description)) == cipher_description) {
2710 if (strstr(cipher_description, dhe_description) != NULL ||
2711 strstr(cipher_description, dhe_export_description) != NULL) {
2712 dhe_found = 1;
2713 break;
2714 }
Remi Gacognec1eab8c2014-06-12 18:20:11 +02002715 }
Remi Gacognef46cd6e2014-06-12 14:58:40 +02002716 }
2717 }
Remi Gacogne23d5d372014-10-10 17:04:26 +02002718 SSL_free(ssl);
2719 ssl = NULL;
Lukas Tribus90132722014-08-18 00:56:33 +02002720 }
Remi Gacognef46cd6e2014-06-12 14:58:40 +02002721
Lukas Tribus90132722014-08-18 00:56:33 +02002722 if (dhe_found) {
2723 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 +02002724 }
2725
2726 global.tune.ssl_default_dh_param = 1024;
2727 }
Remi Gacogne8de54152014-07-15 11:36:40 +02002728
2729#ifndef OPENSSL_NO_DH
2730 if (global.tune.ssl_default_dh_param >= 1024) {
2731 if (local_dh_1024 == NULL) {
2732 local_dh_1024 = ssl_get_dh_1024();
2733 }
2734 if (global.tune.ssl_default_dh_param >= 2048) {
2735 if (local_dh_2048 == NULL) {
2736 local_dh_2048 = ssl_get_dh_2048();
2737 }
2738 if (global.tune.ssl_default_dh_param >= 4096) {
2739 if (local_dh_4096 == NULL) {
2740 local_dh_4096 = ssl_get_dh_4096();
2741 }
Remi Gacogne8de54152014-07-15 11:36:40 +02002742 }
2743 }
2744 }
2745#endif /* OPENSSL_NO_DH */
Remi Gacognef46cd6e2014-06-12 14:58:40 +02002746
Emeric Brunfc0421f2012-09-07 17:30:07 +02002747 SSL_CTX_set_info_callback(ctx, ssl_sock_infocbk);
Willy Tarreau5cbe4ef2014-05-08 22:45:11 +02002748#if OPENSSL_VERSION_NUMBER >= 0x00907000L
Emeric Brun29f037d2014-04-25 19:05:36 +02002749 SSL_CTX_set_msg_callback(ctx, ssl_sock_msgcbk);
Willy Tarreau5cbe4ef2014-05-08 22:45:11 +02002750#endif
Emeric Brun29f037d2014-04-25 19:05:36 +02002751
Willy Tarreau6c9a3d52012-10-18 18:57:14 +02002752#ifdef OPENSSL_NPN_NEGOTIATED
2753 if (bind_conf->npn_str)
2754 SSL_CTX_set_next_protos_advertised_cb(ctx, ssl_sock_advertise_npn_protos, bind_conf);
2755#endif
Dirkjan Bussink48f1c4e2014-02-13 12:29:42 +01002756#ifdef TLSEXT_TYPE_application_layer_protocol_negotiation
Willy Tarreauab861d32013-04-02 02:30:41 +02002757 if (bind_conf->alpn_str)
Dirkjan Bussink48f1c4e2014-02-13 12:29:42 +01002758 SSL_CTX_set_alpn_select_cb(ctx, ssl_sock_advertise_alpn_protos, bind_conf);
Willy Tarreauab861d32013-04-02 02:30:41 +02002759#endif
Willy Tarreau6c9a3d52012-10-18 18:57:14 +02002760
Emeric Brunfc0421f2012-09-07 17:30:07 +02002761#ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME
2762 SSL_CTX_set_tlsext_servername_callback(ctx, ssl_sock_switchctx_cbk);
Willy Tarreau2a65ff02012-09-13 17:54:29 +02002763 SSL_CTX_set_tlsext_servername_arg(ctx, bind_conf);
Emeric Brunfc0421f2012-09-07 17:30:07 +02002764#endif
Emeric Brun2b58d042012-09-20 17:10:03 +02002765#if defined(SSL_CTX_set_tmp_ecdh) && !defined(OPENSSL_NO_ECDH)
Emeric Brun6924ef82013-03-06 14:08:53 +01002766 {
Emeric Brun2b58d042012-09-20 17:10:03 +02002767 int i;
2768 EC_KEY *ecdh;
2769
Emeric Brun6924ef82013-03-06 14:08:53 +01002770 i = OBJ_sn2nid(bind_conf->ecdhe ? bind_conf->ecdhe : ECDHE_DEFAULT_CURVE);
Emeric Brun2b58d042012-09-20 17:10:03 +02002771 if (!i || ((ecdh = EC_KEY_new_by_curve_name(i)) == NULL)) {
2772 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 +01002773 curproxy->id, bind_conf->ecdhe ? bind_conf->ecdhe : ECDHE_DEFAULT_CURVE,
2774 bind_conf->arg, bind_conf->file, bind_conf->line);
Emeric Brun2b58d042012-09-20 17:10:03 +02002775 cfgerr++;
2776 }
2777 else {
2778 SSL_CTX_set_tmp_ecdh(ctx, ecdh);
2779 EC_KEY_free(ecdh);
2780 }
2781 }
2782#endif
2783
Emeric Brunfc0421f2012-09-07 17:30:07 +02002784 return cfgerr;
2785}
2786
Evan Broderbe554312013-06-27 00:05:25 -07002787static int ssl_sock_srv_hostcheck(const char *pattern, const char *hostname)
2788{
2789 const char *pattern_wildcard, *pattern_left_label_end, *hostname_left_label_end;
2790 size_t prefixlen, suffixlen;
2791
2792 /* Trivial case */
2793 if (strcmp(pattern, hostname) == 0)
2794 return 1;
2795
Evan Broderbe554312013-06-27 00:05:25 -07002796 /* The rest of this logic is based on RFC 6125, section 6.4.3
2797 * (http://tools.ietf.org/html/rfc6125#section-6.4.3) */
2798
Emeric Bruna848dae2013-10-08 11:27:28 +02002799 pattern_wildcard = NULL;
2800 pattern_left_label_end = pattern;
2801 while (*pattern_left_label_end != '.') {
2802 switch (*pattern_left_label_end) {
2803 case 0:
2804 /* End of label not found */
2805 return 0;
2806 case '*':
2807 /* If there is more than one wildcards */
2808 if (pattern_wildcard)
2809 return 0;
2810 pattern_wildcard = pattern_left_label_end;
2811 break;
2812 }
2813 pattern_left_label_end++;
2814 }
2815
2816 /* If it's not trivial and there is no wildcard, it can't
2817 * match */
2818 if (!pattern_wildcard)
Evan Broderbe554312013-06-27 00:05:25 -07002819 return 0;
2820
2821 /* Make sure all labels match except the leftmost */
2822 hostname_left_label_end = strchr(hostname, '.');
2823 if (!hostname_left_label_end
2824 || strcmp(pattern_left_label_end, hostname_left_label_end) != 0)
2825 return 0;
2826
2827 /* Make sure the leftmost label of the hostname is long enough
2828 * that the wildcard can match */
Emeric Brun369da852013-10-08 11:39:35 +02002829 if (hostname_left_label_end - hostname < (pattern_left_label_end - pattern) - 1)
Evan Broderbe554312013-06-27 00:05:25 -07002830 return 0;
2831
2832 /* Finally compare the string on either side of the
2833 * wildcard */
2834 prefixlen = pattern_wildcard - pattern;
2835 suffixlen = pattern_left_label_end - (pattern_wildcard + 1);
Emeric Bruna848dae2013-10-08 11:27:28 +02002836 if ((prefixlen && (memcmp(pattern, hostname, prefixlen) != 0))
2837 || (suffixlen && (memcmp(pattern_wildcard + 1, hostname_left_label_end - suffixlen, suffixlen) != 0)))
Evan Broderbe554312013-06-27 00:05:25 -07002838 return 0;
2839
2840 return 1;
2841}
2842
2843static int ssl_sock_srv_verifycbk(int ok, X509_STORE_CTX *ctx)
2844{
2845 SSL *ssl;
2846 struct connection *conn;
2847 char *servername;
2848
2849 int depth;
2850 X509 *cert;
2851 STACK_OF(GENERAL_NAME) *alt_names;
2852 int i;
2853 X509_NAME *cert_subject;
2854 char *str;
2855
2856 if (ok == 0)
2857 return ok;
2858
2859 ssl = X509_STORE_CTX_get_ex_data(ctx, SSL_get_ex_data_X509_STORE_CTX_idx());
Vincent Bernat3c2f2f22016-04-03 13:48:42 +02002860 conn = SSL_get_app_data(ssl);
Evan Broderbe554312013-06-27 00:05:25 -07002861
2862 servername = objt_server(conn->target)->ssl_ctx.verify_host;
2863
2864 /* We only need to verify the CN on the actual server cert,
2865 * not the indirect CAs */
2866 depth = X509_STORE_CTX_get_error_depth(ctx);
2867 if (depth != 0)
2868 return ok;
2869
2870 /* At this point, the cert is *not* OK unless we can find a
2871 * hostname match */
2872 ok = 0;
2873
2874 cert = X509_STORE_CTX_get_current_cert(ctx);
2875 /* It seems like this might happen if verify peer isn't set */
2876 if (!cert)
2877 return ok;
2878
2879 alt_names = X509_get_ext_d2i(cert, NID_subject_alt_name, NULL, NULL);
2880 if (alt_names) {
2881 for (i = 0; !ok && i < sk_GENERAL_NAME_num(alt_names); i++) {
2882 GENERAL_NAME *name = sk_GENERAL_NAME_value(alt_names, i);
2883 if (name->type == GEN_DNS) {
Emeric Bruna33410c2013-09-17 15:47:48 +02002884#if OPENSSL_VERSION_NUMBER < 0x00907000L
2885 if (ASN1_STRING_to_UTF8((unsigned char **)&str, name->d.ia5) >= 0) {
2886#else
Evan Broderbe554312013-06-27 00:05:25 -07002887 if (ASN1_STRING_to_UTF8((unsigned char **)&str, name->d.dNSName) >= 0) {
Emeric Bruna33410c2013-09-17 15:47:48 +02002888#endif
Evan Broderbe554312013-06-27 00:05:25 -07002889 ok = ssl_sock_srv_hostcheck(str, servername);
2890 OPENSSL_free(str);
2891 }
2892 }
2893 }
Emeric Brun4ad50a42013-09-17 15:19:54 +02002894 sk_GENERAL_NAME_pop_free(alt_names, GENERAL_NAME_free);
Evan Broderbe554312013-06-27 00:05:25 -07002895 }
2896
2897 cert_subject = X509_get_subject_name(cert);
2898 i = -1;
2899 while (!ok && (i = X509_NAME_get_index_by_NID(cert_subject, NID_commonName, i)) != -1) {
2900 X509_NAME_ENTRY *entry = X509_NAME_get_entry(cert_subject, i);
2901 if (ASN1_STRING_to_UTF8((unsigned char **)&str, entry->value) >= 0) {
2902 ok = ssl_sock_srv_hostcheck(str, servername);
2903 OPENSSL_free(str);
2904 }
2905 }
2906
2907 return ok;
2908}
2909
Emeric Brun94324a42012-10-11 14:00:19 +02002910/* prepare ssl context from servers options. Returns an error count */
2911int ssl_sock_prepare_srv_ctx(struct server *srv, struct proxy *curproxy)
2912{
2913 int cfgerr = 0;
Remi Gacogneaf5c3da2014-05-19 10:29:58 +02002914 long options =
Emeric Brun94324a42012-10-11 14:00:19 +02002915 SSL_OP_ALL | /* all known workarounds for bugs */
2916 SSL_OP_NO_SSLv2 |
2917 SSL_OP_NO_COMPRESSION;
Remi Gacogneaf5c3da2014-05-19 10:29:58 +02002918 long mode =
Emeric Brun94324a42012-10-11 14:00:19 +02002919 SSL_MODE_ENABLE_PARTIAL_WRITE |
2920 SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER |
Willy Tarreau396a1862014-11-13 14:06:52 +01002921 SSL_MODE_RELEASE_BUFFERS |
2922 SSL_MODE_SMALL_BUFFERS;
Emeric Brun850efd52014-01-29 12:24:34 +01002923 int verify = SSL_VERIFY_NONE;
Emeric Brun94324a42012-10-11 14:00:19 +02002924
Thierry Fournier383085f2013-01-24 14:15:43 +01002925 /* Make sure openssl opens /dev/urandom before the chroot */
2926 if (!ssl_initialize_random()) {
2927 Alert("OpenSSL random data generator initialization failed.\n");
2928 cfgerr++;
2929 }
2930
Willy Tarreaufce03112015-01-15 21:32:40 +01002931 /* Automatic memory computations need to know we use SSL there */
2932 global.ssl_used_backend = 1;
2933
2934 /* Initiate SSL context for current server */
Emeric Brun94324a42012-10-11 14:00:19 +02002935 srv->ssl_ctx.reused_sess = NULL;
2936 if (srv->use_ssl)
2937 srv->xprt = &ssl_sock;
2938 if (srv->check.use_ssl)
Cyril Bonté9ce13112014-11-15 22:41:27 +01002939 srv->check.xprt = &ssl_sock;
Emeric Brun94324a42012-10-11 14:00:19 +02002940
2941 srv->ssl_ctx.ctx = SSL_CTX_new(SSLv23_client_method());
2942 if (!srv->ssl_ctx.ctx) {
2943 Alert("config : %s '%s', server '%s': unable to allocate ssl context.\n",
2944 proxy_type_str(curproxy), curproxy->id,
2945 srv->id);
2946 cfgerr++;
2947 return cfgerr;
2948 }
Emeric Bruna7aa3092012-10-26 12:58:00 +02002949 if (srv->ssl_ctx.client_crt) {
2950 if (SSL_CTX_use_PrivateKey_file(srv->ssl_ctx.ctx, srv->ssl_ctx.client_crt, SSL_FILETYPE_PEM) <= 0) {
2951 Alert("config : %s '%s', server '%s': unable to load SSL private key from PEM file '%s'.\n",
2952 proxy_type_str(curproxy), curproxy->id,
2953 srv->id, srv->ssl_ctx.client_crt);
2954 cfgerr++;
2955 }
2956 else if (SSL_CTX_use_certificate_chain_file(srv->ssl_ctx.ctx, srv->ssl_ctx.client_crt) <= 0) {
2957 Alert("config : %s '%s', server '%s': unable to load ssl certificate from PEM file '%s'.\n",
2958 proxy_type_str(curproxy), curproxy->id,
2959 srv->id, srv->ssl_ctx.client_crt);
2960 cfgerr++;
2961 }
2962 else if (SSL_CTX_check_private_key(srv->ssl_ctx.ctx) <= 0) {
2963 Alert("config : %s '%s', server '%s': inconsistencies between private key and certificate loaded from PEM file '%s'.\n",
2964 proxy_type_str(curproxy), curproxy->id,
2965 srv->id, srv->ssl_ctx.client_crt);
2966 cfgerr++;
2967 }
2968 }
Emeric Brun94324a42012-10-11 14:00:19 +02002969
2970 if (srv->ssl_ctx.options & SRV_SSL_O_NO_SSLV3)
2971 options |= SSL_OP_NO_SSLv3;
2972 if (srv->ssl_ctx.options & SRV_SSL_O_NO_TLSV10)
2973 options |= SSL_OP_NO_TLSv1;
2974 if (srv->ssl_ctx.options & SRV_SSL_O_NO_TLSV11)
2975 options |= SSL_OP_NO_TLSv1_1;
2976 if (srv->ssl_ctx.options & SRV_SSL_O_NO_TLSV12)
2977 options |= SSL_OP_NO_TLSv1_2;
Emeric Brunf9c5c472012-10-11 15:28:34 +02002978 if (srv->ssl_ctx.options & SRV_SSL_O_NO_TLS_TICKETS)
2979 options |= SSL_OP_NO_TICKET;
Jérémie Courrèges-Anglas17c3f622015-07-25 16:50:52 -06002980 if (srv->ssl_ctx.options & SRV_SSL_O_USE_SSLV3) {
2981#ifndef OPENSSL_NO_SSL3
Emeric Brun94324a42012-10-11 14:00:19 +02002982 SSL_CTX_set_ssl_version(srv->ssl_ctx.ctx, SSLv3_client_method());
Jérémie Courrèges-Anglas17c3f622015-07-25 16:50:52 -06002983#else
Thierry FOURNIERbc965342015-08-26 08:21:26 +02002984 Alert("SSLv3 support requested but unavailable.\n");
Jérémie Courrèges-Anglas17c3f622015-07-25 16:50:52 -06002985 cfgerr++;
2986#endif
2987 }
Emeric Brun94324a42012-10-11 14:00:19 +02002988 if (srv->ssl_ctx.options & SRV_SSL_O_USE_TLSV10)
2989 SSL_CTX_set_ssl_version(srv->ssl_ctx.ctx, TLSv1_client_method());
2990#if SSL_OP_NO_TLSv1_1
2991 if (srv->ssl_ctx.options & SRV_SSL_O_USE_TLSV11)
2992 SSL_CTX_set_ssl_version(srv->ssl_ctx.ctx, TLSv1_1_client_method());
2993#endif
2994#if SSL_OP_NO_TLSv1_2
2995 if (srv->ssl_ctx.options & SRV_SSL_O_USE_TLSV12)
2996 SSL_CTX_set_ssl_version(srv->ssl_ctx.ctx, TLSv1_2_client_method());
2997#endif
2998
2999 SSL_CTX_set_options(srv->ssl_ctx.ctx, options);
3000 SSL_CTX_set_mode(srv->ssl_ctx.ctx, mode);
Emeric Brun850efd52014-01-29 12:24:34 +01003001
3002 if (global.ssl_server_verify == SSL_SERVER_VERIFY_REQUIRED)
3003 verify = SSL_VERIFY_PEER;
3004
3005 switch (srv->ssl_ctx.verify) {
3006 case SSL_SOCK_VERIFY_NONE:
3007 verify = SSL_VERIFY_NONE;
3008 break;
3009 case SSL_SOCK_VERIFY_REQUIRED:
3010 verify = SSL_VERIFY_PEER;
3011 break;
3012 }
Evan Broderbe554312013-06-27 00:05:25 -07003013 SSL_CTX_set_verify(srv->ssl_ctx.ctx,
Emeric Brun850efd52014-01-29 12:24:34 +01003014 verify,
Evan Broderbe554312013-06-27 00:05:25 -07003015 srv->ssl_ctx.verify_host ? ssl_sock_srv_verifycbk : NULL);
Emeric Brun850efd52014-01-29 12:24:34 +01003016 if (verify & SSL_VERIFY_PEER) {
Emeric Brunef42d922012-10-11 16:11:36 +02003017 if (srv->ssl_ctx.ca_file) {
3018 /* load CAfile to verify */
3019 if (!SSL_CTX_load_verify_locations(srv->ssl_ctx.ctx, srv->ssl_ctx.ca_file, NULL)) {
Willy Tarreau07ba08b2014-02-16 19:22:08 +01003020 Alert("Proxy '%s', server '%s' [%s:%d] unable to load CA file '%s'.\n",
Emeric Brunef42d922012-10-11 16:11:36 +02003021 curproxy->id, srv->id,
3022 srv->conf.file, srv->conf.line, srv->ssl_ctx.ca_file);
3023 cfgerr++;
3024 }
3025 }
Emeric Brun850efd52014-01-29 12:24:34 +01003026 else {
3027 if (global.ssl_server_verify == SSL_SERVER_VERIFY_REQUIRED)
Willy Tarreau07ba08b2014-02-16 19:22:08 +01003028 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 +01003029 curproxy->id, srv->id,
3030 srv->conf.file, srv->conf.line);
3031 else
Willy Tarreau07ba08b2014-02-16 19:22:08 +01003032 Alert("Proxy '%s', server '%s' [%s:%d] verify is enabled but no CA file specified.\n",
Emeric Brun850efd52014-01-29 12:24:34 +01003033 curproxy->id, srv->id,
3034 srv->conf.file, srv->conf.line);
3035 cfgerr++;
3036 }
Emeric Brunef42d922012-10-11 16:11:36 +02003037#ifdef X509_V_FLAG_CRL_CHECK
3038 if (srv->ssl_ctx.crl_file) {
3039 X509_STORE *store = SSL_CTX_get_cert_store(srv->ssl_ctx.ctx);
3040
3041 if (!store || !X509_STORE_load_locations(store, srv->ssl_ctx.crl_file, NULL)) {
Willy Tarreau07ba08b2014-02-16 19:22:08 +01003042 Alert("Proxy '%s', server '%s' [%s:%d] unable to configure CRL file '%s'.\n",
Emeric Brunef42d922012-10-11 16:11:36 +02003043 curproxy->id, srv->id,
3044 srv->conf.file, srv->conf.line, srv->ssl_ctx.crl_file);
3045 cfgerr++;
3046 }
3047 else {
3048 X509_STORE_set_flags(store, X509_V_FLAG_CRL_CHECK|X509_V_FLAG_CRL_CHECK_ALL);
3049 }
3050 }
3051#endif
3052 }
3053
Emeric Brun4f65bff2012-11-16 15:11:00 +01003054 if (global.tune.ssllifetime)
3055 SSL_CTX_set_timeout(srv->ssl_ctx.ctx, global.tune.ssllifetime);
3056
Emeric Brun94324a42012-10-11 14:00:19 +02003057 SSL_CTX_set_session_cache_mode(srv->ssl_ctx.ctx, SSL_SESS_CACHE_OFF);
3058 if (srv->ssl_ctx.ciphers &&
3059 !SSL_CTX_set_cipher_list(srv->ssl_ctx.ctx, srv->ssl_ctx.ciphers)) {
3060 Alert("Proxy '%s', server '%s' [%s:%d] : unable to set SSL cipher list to '%s'.\n",
3061 curproxy->id, srv->id,
3062 srv->conf.file, srv->conf.line, srv->ssl_ctx.ciphers);
3063 cfgerr++;
3064 }
3065
3066 return cfgerr;
3067}
3068
Willy Tarreau2a65ff02012-09-13 17:54:29 +02003069/* Walks down the two trees in bind_conf and prepares all certs. The pointer may
Emeric Brunfc0421f2012-09-07 17:30:07 +02003070 * be NULL, in which case nothing is done. Returns the number of errors
3071 * encountered.
3072 */
Willy Tarreau2a65ff02012-09-13 17:54:29 +02003073int ssl_sock_prepare_all_ctx(struct bind_conf *bind_conf, struct proxy *px)
Emeric Brunfc0421f2012-09-07 17:30:07 +02003074{
3075 struct ebmb_node *node;
3076 struct sni_ctx *sni;
3077 int err = 0;
3078
Willy Tarreau2a65ff02012-09-13 17:54:29 +02003079 if (!bind_conf || !bind_conf->is_ssl)
Emeric Brunfc0421f2012-09-07 17:30:07 +02003080 return 0;
3081
Willy Tarreaufce03112015-01-15 21:32:40 +01003082 /* Automatic memory computations need to know we use SSL there */
3083 global.ssl_used_frontend = 1;
3084
Emeric Brun0bed9942014-10-30 19:25:24 +01003085 if (bind_conf->default_ctx)
3086 err += ssl_sock_prepare_ctx(bind_conf, bind_conf->default_ctx, px);
3087
Willy Tarreau2a65ff02012-09-13 17:54:29 +02003088 node = ebmb_first(&bind_conf->sni_ctx);
Emeric Brunfc0421f2012-09-07 17:30:07 +02003089 while (node) {
3090 sni = ebmb_entry(node, struct sni_ctx, name);
Emeric Brun0bed9942014-10-30 19:25:24 +01003091 if (!sni->order && sni->ctx != bind_conf->default_ctx)
3092 /* only initialize the CTX on its first occurrence and
3093 if it is not the default_ctx */
Willy Tarreau2a65ff02012-09-13 17:54:29 +02003094 err += ssl_sock_prepare_ctx(bind_conf, sni->ctx, px);
Emeric Brunfc0421f2012-09-07 17:30:07 +02003095 node = ebmb_next(node);
3096 }
3097
Willy Tarreau2a65ff02012-09-13 17:54:29 +02003098 node = ebmb_first(&bind_conf->sni_w_ctx);
Emeric Brunfc0421f2012-09-07 17:30:07 +02003099 while (node) {
3100 sni = ebmb_entry(node, struct sni_ctx, name);
Emeric Brun0bed9942014-10-30 19:25:24 +01003101 if (!sni->order && sni->ctx != bind_conf->default_ctx)
3102 /* only initialize the CTX on its first occurrence and
3103 if it is not the default_ctx */
Willy Tarreau2a65ff02012-09-13 17:54:29 +02003104 err += ssl_sock_prepare_ctx(bind_conf, sni->ctx, px);
Emeric Brunfc0421f2012-09-07 17:30:07 +02003105 node = ebmb_next(node);
3106 }
3107 return err;
3108}
3109
Christopher Faulet77fe80c2015-07-29 13:02:40 +02003110
3111/* release ssl context allocated for servers. */
3112void ssl_sock_free_srv_ctx(struct server *srv)
3113{
3114 if (srv->ssl_ctx.ctx)
3115 SSL_CTX_free(srv->ssl_ctx.ctx);
3116}
3117
Willy Tarreau2a65ff02012-09-13 17:54:29 +02003118/* Walks down the two trees in bind_conf and frees all the certs. The pointer may
Emeric Brunfc0421f2012-09-07 17:30:07 +02003119 * be NULL, in which case nothing is done. The default_ctx is nullified too.
3120 */
Willy Tarreau2a65ff02012-09-13 17:54:29 +02003121void ssl_sock_free_all_ctx(struct bind_conf *bind_conf)
Emeric Brunfc0421f2012-09-07 17:30:07 +02003122{
3123 struct ebmb_node *node, *back;
3124 struct sni_ctx *sni;
3125
Willy Tarreau2a65ff02012-09-13 17:54:29 +02003126 if (!bind_conf || !bind_conf->is_ssl)
Emeric Brunfc0421f2012-09-07 17:30:07 +02003127 return;
3128
Willy Tarreau2a65ff02012-09-13 17:54:29 +02003129 node = ebmb_first(&bind_conf->sni_ctx);
Emeric Brunfc0421f2012-09-07 17:30:07 +02003130 while (node) {
3131 sni = ebmb_entry(node, struct sni_ctx, name);
3132 back = ebmb_next(node);
3133 ebmb_delete(node);
3134 if (!sni->order) /* only free the CTX on its first occurrence */
3135 SSL_CTX_free(sni->ctx);
3136 free(sni);
3137 node = back;
3138 }
3139
Willy Tarreau2a65ff02012-09-13 17:54:29 +02003140 node = ebmb_first(&bind_conf->sni_w_ctx);
Emeric Brunfc0421f2012-09-07 17:30:07 +02003141 while (node) {
3142 sni = ebmb_entry(node, struct sni_ctx, name);
3143 back = ebmb_next(node);
3144 ebmb_delete(node);
3145 if (!sni->order) /* only free the CTX on its first occurrence */
3146 SSL_CTX_free(sni->ctx);
3147 free(sni);
3148 node = back;
3149 }
3150
Willy Tarreau2a65ff02012-09-13 17:54:29 +02003151 bind_conf->default_ctx = NULL;
Emeric Brune1f38db2012-09-03 20:36:47 +02003152}
3153
Christopher Faulet31af49d2015-06-09 17:29:50 +02003154/* Load CA cert file and private key used to generate certificates */
3155int
3156ssl_sock_load_ca(struct bind_conf *bind_conf, struct proxy *px)
3157{
3158 FILE *fp;
3159 X509 *cacert = NULL;
3160 EVP_PKEY *capkey = NULL;
3161 int err = 0;
3162
3163 if (!bind_conf || !bind_conf->generate_certs)
3164 return err;
3165
Willy Tarreaua84c2672015-10-09 12:10:13 +02003166#ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME
Christopher Fauletd2cab922015-07-28 16:03:47 +02003167 if (global.tune.ssl_ctx_cache)
3168 ssl_ctx_lru_tree = lru64_new(global.tune.ssl_ctx_cache);
3169 ssl_ctx_lru_seed = (unsigned int)time(NULL);
Willy Tarreaua84c2672015-10-09 12:10:13 +02003170#endif
Christopher Fauletd2cab922015-07-28 16:03:47 +02003171
Christopher Faulet31af49d2015-06-09 17:29:50 +02003172 if (!bind_conf->ca_sign_file) {
3173 Alert("Proxy '%s': cannot enable certificate generation, "
3174 "no CA certificate File configured at [%s:%d].\n",
3175 px->id, bind_conf->file, bind_conf->line);
Christopher Faulet31af49d2015-06-09 17:29:50 +02003176 goto load_error;
Christopher Fauletc6f02fb2015-10-09 10:53:31 +02003177 }
Christopher Faulet31af49d2015-06-09 17:29:50 +02003178
3179 /* read in the CA certificate */
3180 if (!(fp = fopen(bind_conf->ca_sign_file, "r"))) {
3181 Alert("Proxy '%s': Failed to read CA certificate file '%s' at [%s:%d].\n",
3182 px->id, bind_conf->ca_sign_file, bind_conf->file, bind_conf->line);
Christopher Faulet31af49d2015-06-09 17:29:50 +02003183 goto load_error;
3184 }
3185 if (!(cacert = PEM_read_X509(fp, NULL, NULL, NULL))) {
3186 Alert("Proxy '%s': Failed to read CA certificate file '%s' at [%s:%d].\n",
3187 px->id, bind_conf->ca_sign_file, bind_conf->file, bind_conf->line);
Christopher Fauletc6f02fb2015-10-09 10:53:31 +02003188 goto read_error;
Christopher Faulet31af49d2015-06-09 17:29:50 +02003189 }
Christopher Fauletc6f02fb2015-10-09 10:53:31 +02003190 rewind(fp);
Christopher Faulet31af49d2015-06-09 17:29:50 +02003191 if (!(capkey = PEM_read_PrivateKey(fp, NULL, NULL, bind_conf->ca_sign_pass))) {
3192 Alert("Proxy '%s': Failed to read CA private key file '%s' at [%s:%d].\n",
3193 px->id, bind_conf->ca_sign_file, bind_conf->file, bind_conf->line);
Christopher Fauletc6f02fb2015-10-09 10:53:31 +02003194 goto read_error;
Christopher Faulet31af49d2015-06-09 17:29:50 +02003195 }
Christopher Faulet31af49d2015-06-09 17:29:50 +02003196
Christopher Fauletc6f02fb2015-10-09 10:53:31 +02003197 fclose (fp);
Christopher Faulet31af49d2015-06-09 17:29:50 +02003198 bind_conf->ca_sign_cert = cacert;
3199 bind_conf->ca_sign_pkey = capkey;
3200 return err;
3201
Christopher Fauletc6f02fb2015-10-09 10:53:31 +02003202 read_error:
3203 fclose (fp);
Christopher Faulet31af49d2015-06-09 17:29:50 +02003204 if (capkey) EVP_PKEY_free(capkey);
3205 if (cacert) X509_free(cacert);
Christopher Fauletc6f02fb2015-10-09 10:53:31 +02003206 load_error:
3207 bind_conf->generate_certs = 0;
3208 err++;
Christopher Faulet31af49d2015-06-09 17:29:50 +02003209 return err;
3210}
3211
3212/* Release CA cert and private key used to generate certificated */
3213void
3214ssl_sock_free_ca(struct bind_conf *bind_conf)
3215{
3216 if (!bind_conf)
3217 return;
3218
3219 if (bind_conf->ca_sign_pkey)
3220 EVP_PKEY_free(bind_conf->ca_sign_pkey);
3221 if (bind_conf->ca_sign_cert)
3222 X509_free(bind_conf->ca_sign_cert);
3223}
3224
Emeric Brun46591952012-05-18 15:47:34 +02003225/*
3226 * This function is called if SSL * context is not yet allocated. The function
3227 * is designed to be called before any other data-layer operation and sets the
3228 * handshake flag on the connection. It is safe to call it multiple times.
3229 * It returns 0 on success and -1 in error case.
3230 */
3231static int ssl_sock_init(struct connection *conn)
3232{
3233 /* already initialized */
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02003234 if (conn->xprt_ctx)
Emeric Brun46591952012-05-18 15:47:34 +02003235 return 0;
3236
Willy Tarreau3c728722014-01-23 13:50:42 +01003237 if (!conn_ctrl_ready(conn))
Willy Tarreauf79c8172013-10-21 16:30:56 +02003238 return 0;
3239
Willy Tarreau20879a02012-12-03 16:32:10 +01003240 if (global.maxsslconn && sslconns >= global.maxsslconn) {
3241 conn->err_code = CO_ER_SSL_TOO_MANY;
Willy Tarreau403edff2012-09-06 11:58:37 +02003242 return -1;
Willy Tarreau20879a02012-12-03 16:32:10 +01003243 }
Willy Tarreau403edff2012-09-06 11:58:37 +02003244
Emeric Brun46591952012-05-18 15:47:34 +02003245 /* If it is in client mode initiate SSL session
3246 in connect state otherwise accept state */
Willy Tarreau3fdb3662012-11-12 00:42:33 +01003247 if (objt_server(conn->target)) {
Willy Tarreaufba03cd2014-11-13 13:48:58 +01003248 int may_retry = 1;
3249
3250 retry_connect:
Emeric Brun46591952012-05-18 15:47:34 +02003251 /* Alloc a new SSL session ctx */
Willy Tarreau3fdb3662012-11-12 00:42:33 +01003252 conn->xprt_ctx = SSL_new(objt_server(conn->target)->ssl_ctx.ctx);
Willy Tarreau20879a02012-12-03 16:32:10 +01003253 if (!conn->xprt_ctx) {
Willy Tarreaufba03cd2014-11-13 13:48:58 +01003254 if (may_retry--) {
3255 pool_gc2();
3256 goto retry_connect;
3257 }
Willy Tarreau20879a02012-12-03 16:32:10 +01003258 conn->err_code = CO_ER_SSL_NO_MEM;
Emeric Brun46591952012-05-18 15:47:34 +02003259 return -1;
Willy Tarreau20879a02012-12-03 16:32:10 +01003260 }
Emeric Brun46591952012-05-18 15:47:34 +02003261
Emeric Brun46591952012-05-18 15:47:34 +02003262 /* set fd on SSL session context */
Emeric Brun55476152014-11-12 17:35:37 +01003263 if (!SSL_set_fd(conn->xprt_ctx, conn->t.sock.fd)) {
3264 SSL_free(conn->xprt_ctx);
3265 conn->xprt_ctx = NULL;
Willy Tarreaufba03cd2014-11-13 13:48:58 +01003266 if (may_retry--) {
3267 pool_gc2();
3268 goto retry_connect;
3269 }
Emeric Brun55476152014-11-12 17:35:37 +01003270 conn->err_code = CO_ER_SSL_NO_MEM;
3271 return -1;
3272 }
Emeric Brun46591952012-05-18 15:47:34 +02003273
Evan Broderbe554312013-06-27 00:05:25 -07003274 /* set connection pointer */
Emeric Brun55476152014-11-12 17:35:37 +01003275 if (!SSL_set_app_data(conn->xprt_ctx, conn)) {
3276 SSL_free(conn->xprt_ctx);
3277 conn->xprt_ctx = NULL;
Willy Tarreaufba03cd2014-11-13 13:48:58 +01003278 if (may_retry--) {
3279 pool_gc2();
3280 goto retry_connect;
3281 }
Emeric Brun55476152014-11-12 17:35:37 +01003282 conn->err_code = CO_ER_SSL_NO_MEM;
3283 return -1;
3284 }
3285
3286 SSL_set_connect_state(conn->xprt_ctx);
3287 if (objt_server(conn->target)->ssl_ctx.reused_sess) {
3288 if(!SSL_set_session(conn->xprt_ctx, objt_server(conn->target)->ssl_ctx.reused_sess)) {
3289 SSL_SESSION_free(objt_server(conn->target)->ssl_ctx.reused_sess);
3290 objt_server(conn->target)->ssl_ctx.reused_sess = NULL;
3291 }
3292 }
Evan Broderbe554312013-06-27 00:05:25 -07003293
Emeric Brun46591952012-05-18 15:47:34 +02003294 /* leave init state and start handshake */
Willy Tarreau05737472012-09-04 08:03:39 +02003295 conn->flags |= CO_FL_SSL_WAIT_HS | CO_FL_WAIT_L6_CONN;
Willy Tarreau403edff2012-09-06 11:58:37 +02003296
3297 sslconns++;
Willy Tarreau71b734c2014-01-28 15:19:44 +01003298 totalsslconns++;
Emeric Brun46591952012-05-18 15:47:34 +02003299 return 0;
3300 }
Willy Tarreau3fdb3662012-11-12 00:42:33 +01003301 else if (objt_listener(conn->target)) {
Willy Tarreaufba03cd2014-11-13 13:48:58 +01003302 int may_retry = 1;
3303
3304 retry_accept:
Emeric Brun46591952012-05-18 15:47:34 +02003305 /* Alloc a new SSL session ctx */
Willy Tarreau3fdb3662012-11-12 00:42:33 +01003306 conn->xprt_ctx = SSL_new(objt_listener(conn->target)->bind_conf->default_ctx);
Willy Tarreau20879a02012-12-03 16:32:10 +01003307 if (!conn->xprt_ctx) {
Willy Tarreaufba03cd2014-11-13 13:48:58 +01003308 if (may_retry--) {
3309 pool_gc2();
3310 goto retry_accept;
3311 }
Willy Tarreau20879a02012-12-03 16:32:10 +01003312 conn->err_code = CO_ER_SSL_NO_MEM;
Emeric Brun46591952012-05-18 15:47:34 +02003313 return -1;
Willy Tarreau20879a02012-12-03 16:32:10 +01003314 }
Emeric Brun46591952012-05-18 15:47:34 +02003315
Emeric Brun46591952012-05-18 15:47:34 +02003316 /* set fd on SSL session context */
Emeric Brun55476152014-11-12 17:35:37 +01003317 if (!SSL_set_fd(conn->xprt_ctx, conn->t.sock.fd)) {
3318 SSL_free(conn->xprt_ctx);
3319 conn->xprt_ctx = NULL;
Willy Tarreaufba03cd2014-11-13 13:48:58 +01003320 if (may_retry--) {
3321 pool_gc2();
3322 goto retry_accept;
3323 }
Emeric Brun55476152014-11-12 17:35:37 +01003324 conn->err_code = CO_ER_SSL_NO_MEM;
3325 return -1;
3326 }
Emeric Brun46591952012-05-18 15:47:34 +02003327
Emeric Brune1f38db2012-09-03 20:36:47 +02003328 /* set connection pointer */
Emeric Brun55476152014-11-12 17:35:37 +01003329 if (!SSL_set_app_data(conn->xprt_ctx, conn)) {
3330 SSL_free(conn->xprt_ctx);
3331 conn->xprt_ctx = NULL;
Willy Tarreaufba03cd2014-11-13 13:48:58 +01003332 if (may_retry--) {
3333 pool_gc2();
3334 goto retry_accept;
3335 }
Emeric Brun55476152014-11-12 17:35:37 +01003336 conn->err_code = CO_ER_SSL_NO_MEM;
3337 return -1;
3338 }
3339
3340 SSL_set_accept_state(conn->xprt_ctx);
Emeric Brune1f38db2012-09-03 20:36:47 +02003341
Emeric Brun46591952012-05-18 15:47:34 +02003342 /* leave init state and start handshake */
Willy Tarreau05737472012-09-04 08:03:39 +02003343 conn->flags |= CO_FL_SSL_WAIT_HS | CO_FL_WAIT_L6_CONN;
Willy Tarreau403edff2012-09-06 11:58:37 +02003344
3345 sslconns++;
Willy Tarreau71b734c2014-01-28 15:19:44 +01003346 totalsslconns++;
Emeric Brun46591952012-05-18 15:47:34 +02003347 return 0;
3348 }
3349 /* don't know how to handle such a target */
Willy Tarreau20879a02012-12-03 16:32:10 +01003350 conn->err_code = CO_ER_SSL_NO_TARGET;
Emeric Brun46591952012-05-18 15:47:34 +02003351 return -1;
3352}
3353
3354
3355/* This is the callback which is used when an SSL handshake is pending. It
3356 * updates the FD status if it wants some polling before being called again.
3357 * It returns 0 if it fails in a fatal way or needs to poll to go further,
3358 * otherwise it returns non-zero and removes itself from the connection's
3359 * flags (the bit is provided in <flag> by the caller).
3360 */
3361int ssl_sock_handshake(struct connection *conn, unsigned int flag)
3362{
3363 int ret;
3364
Willy Tarreau3c728722014-01-23 13:50:42 +01003365 if (!conn_ctrl_ready(conn))
Willy Tarreauf79c8172013-10-21 16:30:56 +02003366 return 0;
3367
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02003368 if (!conn->xprt_ctx)
Emeric Brun46591952012-05-18 15:47:34 +02003369 goto out_error;
3370
Emeric Brun674b7432012-11-08 19:21:55 +01003371 /* If we use SSL_do_handshake to process a reneg initiated by
3372 * the remote peer, it sometimes returns SSL_ERROR_SSL.
3373 * Usually SSL_write and SSL_read are used and process implicitly
3374 * the reneg handshake.
3375 * Here we use SSL_peek as a workaround for reneg.
3376 */
3377 if ((conn->flags & CO_FL_CONNECTED) && SSL_renegotiate_pending(conn->xprt_ctx)) {
3378 char c;
3379
3380 ret = SSL_peek(conn->xprt_ctx, &c, 1);
3381 if (ret <= 0) {
3382 /* handshake may have not been completed, let's find why */
3383 ret = SSL_get_error(conn->xprt_ctx, ret);
3384 if (ret == SSL_ERROR_WANT_WRITE) {
3385 /* SSL handshake needs to write, L4 connection may not be ready */
3386 __conn_sock_stop_recv(conn);
Willy Tarreaue1f50c42014-01-22 20:02:06 +01003387 __conn_sock_want_send(conn);
3388 fd_cant_send(conn->t.sock.fd);
Emeric Brun674b7432012-11-08 19:21:55 +01003389 return 0;
3390 }
3391 else if (ret == SSL_ERROR_WANT_READ) {
3392 /* handshake may have been completed but we have
3393 * no more data to read.
3394 */
3395 if (!SSL_renegotiate_pending(conn->xprt_ctx)) {
3396 ret = 1;
3397 goto reneg_ok;
3398 }
3399 /* SSL handshake needs to read, L4 connection is ready */
3400 if (conn->flags & CO_FL_WAIT_L4_CONN)
3401 conn->flags &= ~CO_FL_WAIT_L4_CONN;
3402 __conn_sock_stop_send(conn);
Willy Tarreaue1f50c42014-01-22 20:02:06 +01003403 __conn_sock_want_recv(conn);
3404 fd_cant_recv(conn->t.sock.fd);
Emeric Brun674b7432012-11-08 19:21:55 +01003405 return 0;
3406 }
3407 else if (ret == SSL_ERROR_SYSCALL) {
3408 /* if errno is null, then connection was successfully established */
3409 if (!errno && conn->flags & CO_FL_WAIT_L4_CONN)
3410 conn->flags &= ~CO_FL_WAIT_L4_CONN;
Willy Tarreau20879a02012-12-03 16:32:10 +01003411 if (!conn->err_code) {
Emeric Brun29f037d2014-04-25 19:05:36 +02003412 if (!((SSL *)conn->xprt_ctx)->packet_length) {
3413 if (!errno) {
3414 if (conn->xprt_st & SSL_SOCK_RECV_HEARTBEAT)
3415 conn->err_code = CO_ER_SSL_HANDSHAKE_HB;
3416 else
3417 conn->err_code = CO_ER_SSL_EMPTY;
3418 }
3419 else {
3420 if (conn->xprt_st & SSL_SOCK_RECV_HEARTBEAT)
3421 conn->err_code = CO_ER_SSL_HANDSHAKE_HB;
3422 else
3423 conn->err_code = CO_ER_SSL_ABORT;
3424 }
3425 }
3426 else {
3427 if (conn->xprt_st & SSL_SOCK_RECV_HEARTBEAT)
3428 conn->err_code = CO_ER_SSL_HANDSHAKE_HB;
Willy Tarreau20879a02012-12-03 16:32:10 +01003429 else
Emeric Brun29f037d2014-04-25 19:05:36 +02003430 conn->err_code = CO_ER_SSL_HANDSHAKE;
3431 }
Willy Tarreau20879a02012-12-03 16:32:10 +01003432 }
Emeric Brun674b7432012-11-08 19:21:55 +01003433 goto out_error;
3434 }
3435 else {
3436 /* Fail on all other handshake errors */
3437 /* Note: OpenSSL may leave unread bytes in the socket's
3438 * buffer, causing an RST to be emitted upon close() on
3439 * TCP sockets. We first try to drain possibly pending
3440 * data to avoid this as much as possible.
3441 */
Willy Tarreaud85c4852015-03-13 00:40:28 +01003442 conn_sock_drain(conn);
Willy Tarreau20879a02012-12-03 16:32:10 +01003443 if (!conn->err_code)
Willy Tarreauf51c6982014-04-25 20:02:39 +02003444 conn->err_code = (conn->xprt_st & SSL_SOCK_RECV_HEARTBEAT) ?
3445 CO_ER_SSL_KILLED_HB : CO_ER_SSL_HANDSHAKE;
Emeric Brun674b7432012-11-08 19:21:55 +01003446 goto out_error;
3447 }
3448 }
3449 /* read some data: consider handshake completed */
3450 goto reneg_ok;
3451 }
3452
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02003453 ret = SSL_do_handshake(conn->xprt_ctx);
Emeric Brun46591952012-05-18 15:47:34 +02003454 if (ret != 1) {
3455 /* handshake did not complete, let's find why */
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02003456 ret = SSL_get_error(conn->xprt_ctx, ret);
Emeric Brun46591952012-05-18 15:47:34 +02003457
3458 if (ret == SSL_ERROR_WANT_WRITE) {
3459 /* SSL handshake needs to write, L4 connection may not be ready */
3460 __conn_sock_stop_recv(conn);
Willy Tarreaue1f50c42014-01-22 20:02:06 +01003461 __conn_sock_want_send(conn);
3462 fd_cant_send(conn->t.sock.fd);
Emeric Brun46591952012-05-18 15:47:34 +02003463 return 0;
3464 }
3465 else if (ret == SSL_ERROR_WANT_READ) {
3466 /* SSL handshake needs to read, L4 connection is ready */
3467 if (conn->flags & CO_FL_WAIT_L4_CONN)
3468 conn->flags &= ~CO_FL_WAIT_L4_CONN;
3469 __conn_sock_stop_send(conn);
Willy Tarreaue1f50c42014-01-22 20:02:06 +01003470 __conn_sock_want_recv(conn);
3471 fd_cant_recv(conn->t.sock.fd);
Emeric Brun46591952012-05-18 15:47:34 +02003472 return 0;
3473 }
Willy Tarreau89230192012-09-28 20:22:13 +02003474 else if (ret == SSL_ERROR_SYSCALL) {
3475 /* if errno is null, then connection was successfully established */
3476 if (!errno && conn->flags & CO_FL_WAIT_L4_CONN)
3477 conn->flags &= ~CO_FL_WAIT_L4_CONN;
Willy Tarreau20879a02012-12-03 16:32:10 +01003478
Emeric Brun29f037d2014-04-25 19:05:36 +02003479 if (!((SSL *)conn->xprt_ctx)->packet_length) {
3480 if (!errno) {
3481 if (conn->xprt_st & SSL_SOCK_RECV_HEARTBEAT)
3482 conn->err_code = CO_ER_SSL_HANDSHAKE_HB;
3483 else
3484 conn->err_code = CO_ER_SSL_EMPTY;
3485 }
3486 else {
3487 if (conn->xprt_st & SSL_SOCK_RECV_HEARTBEAT)
3488 conn->err_code = CO_ER_SSL_HANDSHAKE_HB;
3489 else
3490 conn->err_code = CO_ER_SSL_ABORT;
3491 }
3492 }
3493 else {
3494 if (conn->xprt_st & SSL_SOCK_RECV_HEARTBEAT)
3495 conn->err_code = CO_ER_SSL_HANDSHAKE_HB;
Willy Tarreau20879a02012-12-03 16:32:10 +01003496 else
Emeric Brun29f037d2014-04-25 19:05:36 +02003497 conn->err_code = CO_ER_SSL_HANDSHAKE;
3498 }
Willy Tarreau89230192012-09-28 20:22:13 +02003499 goto out_error;
3500 }
Emeric Brun46591952012-05-18 15:47:34 +02003501 else {
3502 /* Fail on all other handshake errors */
Willy Tarreau566dc552012-10-19 20:52:18 +02003503 /* Note: OpenSSL may leave unread bytes in the socket's
3504 * buffer, causing an RST to be emitted upon close() on
3505 * TCP sockets. We first try to drain possibly pending
3506 * data to avoid this as much as possible.
3507 */
Willy Tarreaud85c4852015-03-13 00:40:28 +01003508 conn_sock_drain(conn);
Willy Tarreau20879a02012-12-03 16:32:10 +01003509 if (!conn->err_code)
Willy Tarreauf51c6982014-04-25 20:02:39 +02003510 conn->err_code = (conn->xprt_st & SSL_SOCK_RECV_HEARTBEAT) ?
3511 CO_ER_SSL_KILLED_HB : CO_ER_SSL_HANDSHAKE;
Emeric Brun46591952012-05-18 15:47:34 +02003512 goto out_error;
3513 }
3514 }
3515
Emeric Brun674b7432012-11-08 19:21:55 +01003516reneg_ok:
Emeric Brun46591952012-05-18 15:47:34 +02003517 /* Handshake succeeded */
Willy Tarreau0c9c2722014-05-28 12:28:58 +02003518 if (!SSL_session_reused(conn->xprt_ctx)) {
3519 if (objt_server(conn->target)) {
3520 update_freq_ctr(&global.ssl_be_keys_per_sec, 1);
3521 if (global.ssl_be_keys_per_sec.curr_ctr > global.ssl_be_keys_max)
3522 global.ssl_be_keys_max = global.ssl_be_keys_per_sec.curr_ctr;
3523
Emeric Brun46591952012-05-18 15:47:34 +02003524 /* check if session was reused, if not store current session on server for reuse */
Willy Tarreau3fdb3662012-11-12 00:42:33 +01003525 if (objt_server(conn->target)->ssl_ctx.reused_sess)
3526 SSL_SESSION_free(objt_server(conn->target)->ssl_ctx.reused_sess);
Emeric Brun46591952012-05-18 15:47:34 +02003527
Willy Tarreau2a3fb1c2015-02-05 16:47:07 +01003528 if (!(objt_server(conn->target)->ssl_ctx.options & SRV_SSL_O_NO_REUSE))
3529 objt_server(conn->target)->ssl_ctx.reused_sess = SSL_get1_session(conn->xprt_ctx);
Emeric Brun46591952012-05-18 15:47:34 +02003530 }
Willy Tarreau0c9c2722014-05-28 12:28:58 +02003531 else {
3532 update_freq_ctr(&global.ssl_fe_keys_per_sec, 1);
3533 if (global.ssl_fe_keys_per_sec.curr_ctr > global.ssl_fe_keys_max)
3534 global.ssl_fe_keys_max = global.ssl_fe_keys_per_sec.curr_ctr;
3535 }
Emeric Brun46591952012-05-18 15:47:34 +02003536 }
3537
3538 /* The connection is now established at both layers, it's time to leave */
3539 conn->flags &= ~(flag | CO_FL_WAIT_L4_CONN | CO_FL_WAIT_L6_CONN);
3540 return 1;
3541
3542 out_error:
Emeric Brun644cde02012-12-14 11:21:13 +01003543 /* Clear openssl global errors stack */
3544 ERR_clear_error();
3545
Emeric Brun9fa89732012-10-04 17:09:56 +02003546 /* free resumed session if exists */
Willy Tarreau3fdb3662012-11-12 00:42:33 +01003547 if (objt_server(conn->target) && objt_server(conn->target)->ssl_ctx.reused_sess) {
3548 SSL_SESSION_free(objt_server(conn->target)->ssl_ctx.reused_sess);
3549 objt_server(conn->target)->ssl_ctx.reused_sess = NULL;
Emeric Brun9fa89732012-10-04 17:09:56 +02003550 }
3551
Emeric Brun46591952012-05-18 15:47:34 +02003552 /* Fail on all other handshake errors */
3553 conn->flags |= CO_FL_ERROR;
Willy Tarreau20879a02012-12-03 16:32:10 +01003554 if (!conn->err_code)
3555 conn->err_code = CO_ER_SSL_HANDSHAKE;
Emeric Brun46591952012-05-18 15:47:34 +02003556 return 0;
3557}
3558
3559/* Receive up to <count> bytes from connection <conn>'s socket and store them
Willy Tarreauabf08d92014-01-14 11:31:27 +01003560 * into buffer <buf>. Only one call to recv() is performed, unless the
Emeric Brun46591952012-05-18 15:47:34 +02003561 * buffer wraps, in which case a second call may be performed. The connection's
3562 * flags are updated with whatever special event is detected (error, read0,
3563 * empty). The caller is responsible for taking care of those events and
3564 * avoiding the call if inappropriate. The function does not call the
3565 * connection's polling update function, so the caller is responsible for this.
3566 */
3567static int ssl_sock_to_buf(struct connection *conn, struct buffer *buf, int count)
3568{
3569 int ret, done = 0;
Willy Tarreauabf08d92014-01-14 11:31:27 +01003570 int try;
Emeric Brun46591952012-05-18 15:47:34 +02003571
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02003572 if (!conn->xprt_ctx)
Emeric Brun46591952012-05-18 15:47:34 +02003573 goto out_error;
3574
3575 if (conn->flags & CO_FL_HANDSHAKE)
3576 /* a handshake was requested */
3577 return 0;
3578
Willy Tarreauabf08d92014-01-14 11:31:27 +01003579 /* let's realign the buffer to optimize I/O */
3580 if (buffer_empty(buf))
Emeric Brun46591952012-05-18 15:47:34 +02003581 buf->p = buf->data;
Emeric Brun46591952012-05-18 15:47:34 +02003582
3583 /* read the largest possible block. For this, we perform only one call
3584 * to recv() unless the buffer wraps and we exactly fill the first hunk,
3585 * in which case we accept to do it once again. A new attempt is made on
3586 * EINTR too.
3587 */
Willy Tarreau00b0fb92014-01-17 11:09:40 +01003588 while (count > 0) {
Willy Tarreauabf08d92014-01-14 11:31:27 +01003589 /* first check if we have some room after p+i */
3590 try = buf->data + buf->size - (buf->p + buf->i);
3591 /* otherwise continue between data and p-o */
3592 if (try <= 0) {
3593 try = buf->p - (buf->data + buf->o);
3594 if (try <= 0)
3595 break;
3596 }
3597 if (try > count)
3598 try = count;
3599
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02003600 ret = SSL_read(conn->xprt_ctx, bi_end(buf), try);
Emeric Brune1f38db2012-09-03 20:36:47 +02003601 if (conn->flags & CO_FL_ERROR) {
3602 /* CO_FL_ERROR may be set by ssl_sock_infocbk */
Emeric Brun644cde02012-12-14 11:21:13 +01003603 goto out_error;
Emeric Brune1f38db2012-09-03 20:36:47 +02003604 }
Emeric Brun46591952012-05-18 15:47:34 +02003605 if (ret > 0) {
3606 buf->i += ret;
3607 done += ret;
3608 if (ret < try)
3609 break;
3610 count -= ret;
Emeric Brun46591952012-05-18 15:47:34 +02003611 }
3612 else if (ret == 0) {
Emeric Brun644cde02012-12-14 11:21:13 +01003613 ret = SSL_get_error(conn->xprt_ctx, ret);
3614 if (ret != SSL_ERROR_ZERO_RETURN) {
Emeric Brun1c646862012-12-14 12:33:41 +01003615 /* error on protocol or underlying transport */
3616 if ((ret != SSL_ERROR_SYSCALL)
3617 || (errno && (errno != EAGAIN)))
3618 conn->flags |= CO_FL_ERROR;
3619
Emeric Brun644cde02012-12-14 11:21:13 +01003620 /* Clear openssl global errors stack */
3621 ERR_clear_error();
3622 }
Emeric Brun46591952012-05-18 15:47:34 +02003623 goto read0;
3624 }
3625 else {
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02003626 ret = SSL_get_error(conn->xprt_ctx, ret);
Emeric Brun46591952012-05-18 15:47:34 +02003627 if (ret == SSL_ERROR_WANT_WRITE) {
Emeric Brun8af8dd12012-11-08 17:56:20 +01003628 /* handshake is running, and it needs to enable write */
Emeric Brun46591952012-05-18 15:47:34 +02003629 conn->flags |= CO_FL_SSL_WAIT_HS;
Emeric Brun8af8dd12012-11-08 17:56:20 +01003630 __conn_sock_want_send(conn);
Emeric Brun46591952012-05-18 15:47:34 +02003631 break;
3632 }
3633 else if (ret == SSL_ERROR_WANT_READ) {
Emeric Brun282a76a2012-11-08 18:02:56 +01003634 if (SSL_renegotiate_pending(conn->xprt_ctx)) {
3635 /* handshake is running, and it may need to re-enable read */
3636 conn->flags |= CO_FL_SSL_WAIT_HS;
3637 __conn_sock_want_recv(conn);
3638 break;
3639 }
Emeric Brun46591952012-05-18 15:47:34 +02003640 /* we need to poll for retry a read later */
Willy Tarreaue1f50c42014-01-22 20:02:06 +01003641 fd_cant_recv(conn->t.sock.fd);
Emeric Brun46591952012-05-18 15:47:34 +02003642 break;
3643 }
3644 /* otherwise it's a real error */
3645 goto out_error;
3646 }
3647 }
3648 return done;
3649
3650 read0:
3651 conn_sock_read0(conn);
3652 return done;
3653 out_error:
Emeric Brun644cde02012-12-14 11:21:13 +01003654 /* Clear openssl global errors stack */
3655 ERR_clear_error();
3656
Emeric Brun46591952012-05-18 15:47:34 +02003657 conn->flags |= CO_FL_ERROR;
3658 return done;
3659}
3660
3661
3662/* Send all pending bytes from buffer <buf> to connection <conn>'s socket.
Willy Tarreau1049b1f2014-02-02 01:51:17 +01003663 * <flags> may contain some CO_SFL_* flags to hint the system about other
3664 * pending data for example, but this flag is ignored at the moment.
Emeric Brun46591952012-05-18 15:47:34 +02003665 * Only one call to send() is performed, unless the buffer wraps, in which case
3666 * a second call may be performed. The connection's flags are updated with
3667 * whatever special event is detected (error, empty). The caller is responsible
3668 * for taking care of those events and avoiding the call if inappropriate. The
3669 * function does not call the connection's polling update function, so the caller
3670 * is responsible for this.
3671 */
3672static int ssl_sock_from_buf(struct connection *conn, struct buffer *buf, int flags)
3673{
3674 int ret, try, done;
3675
3676 done = 0;
3677
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02003678 if (!conn->xprt_ctx)
Emeric Brun46591952012-05-18 15:47:34 +02003679 goto out_error;
3680
3681 if (conn->flags & CO_FL_HANDSHAKE)
3682 /* a handshake was requested */
3683 return 0;
3684
3685 /* send the largest possible block. For this we perform only one call
3686 * to send() unless the buffer wraps and we exactly fill the first hunk,
3687 * in which case we accept to do it once again.
3688 */
3689 while (buf->o) {
Kevin Hestercad82342013-05-30 15:12:41 -07003690 try = bo_contig_data(buf);
Willy Tarreaubfd59462013-02-21 07:46:09 +01003691
Willy Tarreau7bed9452014-02-02 02:00:24 +01003692 if (!(flags & CO_SFL_STREAMER) &&
Willy Tarreau518cedd2014-02-17 15:43:01 +01003693 !(conn->xprt_st & SSL_SOCK_SEND_UNLIMITED) &&
3694 global.tune.ssl_max_record && try > global.tune.ssl_max_record) {
Willy Tarreaubfd59462013-02-21 07:46:09 +01003695 try = global.tune.ssl_max_record;
Willy Tarreau518cedd2014-02-17 15:43:01 +01003696 }
3697 else {
3698 /* we need to keep the information about the fact that
3699 * we're not limiting the upcoming send(), because if it
3700 * fails, we'll have to retry with at least as many data.
3701 */
3702 conn->xprt_st |= SSL_SOCK_SEND_UNLIMITED;
3703 }
Willy Tarreaubfd59462013-02-21 07:46:09 +01003704
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02003705 ret = SSL_write(conn->xprt_ctx, bo_ptr(buf), try);
Willy Tarreau518cedd2014-02-17 15:43:01 +01003706
Emeric Brune1f38db2012-09-03 20:36:47 +02003707 if (conn->flags & CO_FL_ERROR) {
3708 /* CO_FL_ERROR may be set by ssl_sock_infocbk */
Emeric Brun644cde02012-12-14 11:21:13 +01003709 goto out_error;
Emeric Brune1f38db2012-09-03 20:36:47 +02003710 }
Emeric Brun46591952012-05-18 15:47:34 +02003711 if (ret > 0) {
Willy Tarreau518cedd2014-02-17 15:43:01 +01003712 conn->xprt_st &= ~SSL_SOCK_SEND_UNLIMITED;
3713
Emeric Brun46591952012-05-18 15:47:34 +02003714 buf->o -= ret;
3715 done += ret;
3716
Willy Tarreau5fb38032012-12-16 19:39:09 +01003717 if (likely(buffer_empty(buf)))
Emeric Brun46591952012-05-18 15:47:34 +02003718 /* optimize data alignment in the buffer */
3719 buf->p = buf->data;
3720
3721 /* if the system buffer is full, don't insist */
3722 if (ret < try)
3723 break;
3724 }
3725 else {
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02003726 ret = SSL_get_error(conn->xprt_ctx, ret);
Emeric Brun46591952012-05-18 15:47:34 +02003727 if (ret == SSL_ERROR_WANT_WRITE) {
Emeric Brun282a76a2012-11-08 18:02:56 +01003728 if (SSL_renegotiate_pending(conn->xprt_ctx)) {
3729 /* handshake is running, and it may need to re-enable write */
3730 conn->flags |= CO_FL_SSL_WAIT_HS;
3731 __conn_sock_want_send(conn);
3732 break;
3733 }
Emeric Brun46591952012-05-18 15:47:34 +02003734 /* we need to poll to retry a write later */
Willy Tarreaue1f50c42014-01-22 20:02:06 +01003735 fd_cant_send(conn->t.sock.fd);
Emeric Brun46591952012-05-18 15:47:34 +02003736 break;
3737 }
3738 else if (ret == SSL_ERROR_WANT_READ) {
Emeric Brun8af8dd12012-11-08 17:56:20 +01003739 /* handshake is running, and it needs to enable read */
Emeric Brun46591952012-05-18 15:47:34 +02003740 conn->flags |= CO_FL_SSL_WAIT_HS;
Emeric Brun8af8dd12012-11-08 17:56:20 +01003741 __conn_sock_want_recv(conn);
Emeric Brun46591952012-05-18 15:47:34 +02003742 break;
3743 }
3744 goto out_error;
3745 }
3746 }
3747 return done;
3748
3749 out_error:
Emeric Brun644cde02012-12-14 11:21:13 +01003750 /* Clear openssl global errors stack */
3751 ERR_clear_error();
3752
Emeric Brun46591952012-05-18 15:47:34 +02003753 conn->flags |= CO_FL_ERROR;
3754 return done;
3755}
3756
Emeric Brun46591952012-05-18 15:47:34 +02003757static void ssl_sock_close(struct connection *conn) {
3758
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02003759 if (conn->xprt_ctx) {
3760 SSL_free(conn->xprt_ctx);
3761 conn->xprt_ctx = NULL;
Willy Tarreau403edff2012-09-06 11:58:37 +02003762 sslconns--;
Emeric Brun46591952012-05-18 15:47:34 +02003763 }
Emeric Brun46591952012-05-18 15:47:34 +02003764}
3765
3766/* This function tries to perform a clean shutdown on an SSL connection, and in
3767 * any case, flags the connection as reusable if no handshake was in progress.
3768 */
3769static void ssl_sock_shutw(struct connection *conn, int clean)
3770{
3771 if (conn->flags & CO_FL_HANDSHAKE)
3772 return;
3773 /* no handshake was in progress, try a clean ssl shutdown */
Emeric Brun644cde02012-12-14 11:21:13 +01003774 if (clean && (SSL_shutdown(conn->xprt_ctx) <= 0)) {
3775 /* Clear openssl global errors stack */
3776 ERR_clear_error();
3777 }
Emeric Brun46591952012-05-18 15:47:34 +02003778
3779 /* force flag on ssl to keep session in cache regardless shutdown result */
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02003780 SSL_set_shutdown(conn->xprt_ctx, SSL_SENT_SHUTDOWN);
Emeric Brun46591952012-05-18 15:47:34 +02003781}
3782
Willy Tarreauffc3fcd2012-10-12 20:17:54 +02003783/* used for logging, may be changed for a sample fetch later */
3784const char *ssl_sock_get_cipher_name(struct connection *conn)
3785{
3786 if (!conn->xprt && !conn->xprt_ctx)
3787 return NULL;
3788 return SSL_get_cipher_name(conn->xprt_ctx);
3789}
3790
3791/* used for logging, may be changed for a sample fetch later */
3792const char *ssl_sock_get_proto_version(struct connection *conn)
3793{
3794 if (!conn->xprt && !conn->xprt_ctx)
3795 return NULL;
3796 return SSL_get_version(conn->xprt_ctx);
3797}
3798
Willy Tarreau8d598402012-10-22 17:58:39 +02003799/* Extract a serial from a cert, and copy it to a chunk.
3800 * Returns 1 if serial is found and copied, 0 if no serial found and
3801 * -1 if output is not large enough.
3802 */
3803static int
3804ssl_sock_get_serial(X509 *crt, struct chunk *out)
3805{
3806 ASN1_INTEGER *serial;
3807
3808 serial = X509_get_serialNumber(crt);
3809 if (!serial)
3810 return 0;
3811
3812 if (out->size < serial->length)
3813 return -1;
3814
3815 memcpy(out->str, serial->data, serial->length);
3816 out->len = serial->length;
3817 return 1;
3818}
3819
Emeric Brun43e79582014-10-29 19:03:26 +01003820/* Extract a cert to der, and copy it to a chunk.
3821 * Returns 1 if cert is found and copied, 0 on der convertion failure and
3822 * -1 if output is not large enough.
3823 */
3824static int
3825ssl_sock_crt2der(X509 *crt, struct chunk *out)
3826{
3827 int len;
3828 unsigned char *p = (unsigned char *)out->str;;
3829
3830 len =i2d_X509(crt, NULL);
3831 if (len <= 0)
3832 return 1;
3833
3834 if (out->size < len)
3835 return -1;
3836
3837 i2d_X509(crt,&p);
3838 out->len = len;
3839 return 1;
3840}
3841
Emeric Brunce5ad802012-10-22 14:11:22 +02003842
3843/* Copy Date in ASN1_UTCTIME format in struct chunk out.
3844 * Returns 1 if serial is found and copied, 0 if no valid time found
3845 * and -1 if output is not large enough.
3846 */
3847static int
3848ssl_sock_get_time(ASN1_TIME *tm, struct chunk *out)
3849{
3850 if (tm->type == V_ASN1_GENERALIZEDTIME) {
3851 ASN1_GENERALIZEDTIME *gentm = (ASN1_GENERALIZEDTIME *)tm;
3852
3853 if (gentm->length < 12)
3854 return 0;
3855 if (gentm->data[0] != 0x32 || gentm->data[1] != 0x30)
3856 return 0;
3857 if (out->size < gentm->length-2)
3858 return -1;
3859
3860 memcpy(out->str, gentm->data+2, gentm->length-2);
3861 out->len = gentm->length-2;
3862 return 1;
3863 }
3864 else if (tm->type == V_ASN1_UTCTIME) {
3865 ASN1_UTCTIME *utctm = (ASN1_UTCTIME *)tm;
3866
3867 if (utctm->length < 10)
3868 return 0;
3869 if (utctm->data[0] >= 0x35)
3870 return 0;
3871 if (out->size < utctm->length)
3872 return -1;
3873
3874 memcpy(out->str, utctm->data, utctm->length);
3875 out->len = utctm->length;
3876 return 1;
3877 }
3878
3879 return 0;
3880}
3881
Emeric Brun87855892012-10-17 17:39:35 +02003882/* Extract an entry from a X509_NAME and copy its value to an output chunk.
3883 * Returns 1 if entry found, 0 if entry not found, or -1 if output not large enough.
3884 */
3885static int
3886ssl_sock_get_dn_entry(X509_NAME *a, const struct chunk *entry, int pos, struct chunk *out)
3887{
3888 X509_NAME_ENTRY *ne;
3889 int i, j, n;
3890 int cur = 0;
3891 const char *s;
3892 char tmp[128];
3893
3894 out->len = 0;
3895 for (i = 0; i < sk_X509_NAME_ENTRY_num(a->entries); i++) {
3896 if (pos < 0)
3897 j = (sk_X509_NAME_ENTRY_num(a->entries)-1) - i;
3898 else
3899 j = i;
3900
3901 ne = sk_X509_NAME_ENTRY_value(a->entries, j);
3902 n = OBJ_obj2nid(ne->object);
3903 if ((n == NID_undef) || ((s = OBJ_nid2sn(n)) == NULL)) {
3904 i2t_ASN1_OBJECT(tmp, sizeof(tmp), ne->object);
3905 s = tmp;
3906 }
3907
3908 if (chunk_strcasecmp(entry, s) != 0)
3909 continue;
3910
3911 if (pos < 0)
3912 cur--;
3913 else
3914 cur++;
3915
3916 if (cur != pos)
3917 continue;
3918
3919 if (ne->value->length > out->size)
3920 return -1;
3921
3922 memcpy(out->str, ne->value->data, ne->value->length);
3923 out->len = ne->value->length;
3924 return 1;
3925 }
3926
3927 return 0;
3928
3929}
3930
3931/* Extract and format full DN from a X509_NAME and copy result into a chunk
3932 * Returns 1 if dn entries exits, 0 if no dn entry found or -1 if output is not large enough.
3933 */
3934static int
3935ssl_sock_get_dn_oneline(X509_NAME *a, struct chunk *out)
3936{
3937 X509_NAME_ENTRY *ne;
3938 int i, n, ln;
3939 int l = 0;
3940 const char *s;
3941 char *p;
3942 char tmp[128];
3943
3944 out->len = 0;
3945 p = out->str;
3946 for (i = 0; i < sk_X509_NAME_ENTRY_num(a->entries); i++) {
3947 ne = sk_X509_NAME_ENTRY_value(a->entries, i);
3948 n = OBJ_obj2nid(ne->object);
3949 if ((n == NID_undef) || ((s = OBJ_nid2sn(n)) == NULL)) {
3950 i2t_ASN1_OBJECT(tmp, sizeof(tmp), ne->object);
3951 s = tmp;
3952 }
3953 ln = strlen(s);
3954
3955 l += 1 + ln + 1 + ne->value->length;
3956 if (l > out->size)
3957 return -1;
3958 out->len = l;
3959
3960 *(p++)='/';
3961 memcpy(p, s, ln);
3962 p += ln;
3963 *(p++)='=';
3964 memcpy(p, ne->value->data, ne->value->length);
3965 p += ne->value->length;
3966 }
3967
3968 if (!out->len)
3969 return 0;
3970
3971 return 1;
3972}
3973
David Safb76832014-05-08 23:42:08 -04003974char *ssl_sock_get_version(struct connection *conn)
3975{
3976 if (!ssl_sock_is_ssl(conn))
3977 return NULL;
3978
3979 return (char *)SSL_get_version(conn->xprt_ctx);
3980}
3981
Willy Tarreau63076412015-07-10 11:33:32 +02003982void ssl_sock_set_servername(struct connection *conn, const char *hostname)
3983{
3984#ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME
3985 if (!ssl_sock_is_ssl(conn))
3986 return;
3987
3988 SSL_set_tlsext_host_name(conn->xprt_ctx, hostname);
3989#endif
3990}
3991
Emeric Brun0abf8362014-06-24 18:26:41 +02003992/* Extract peer certificate's common name into the chunk dest
3993 * Returns
3994 * the len of the extracted common name
3995 * or 0 if no CN found in DN
3996 * or -1 on error case (i.e. no peer certificate)
3997 */
3998int ssl_sock_get_remote_common_name(struct connection *conn, struct chunk *dest)
David Safb76832014-05-08 23:42:08 -04003999{
4000 X509 *crt = NULL;
4001 X509_NAME *name;
David Safb76832014-05-08 23:42:08 -04004002 const char find_cn[] = "CN";
4003 const struct chunk find_cn_chunk = {
4004 .str = (char *)&find_cn,
4005 .len = sizeof(find_cn)-1
4006 };
Emeric Brun0abf8362014-06-24 18:26:41 +02004007 int result = -1;
David Safb76832014-05-08 23:42:08 -04004008
4009 if (!ssl_sock_is_ssl(conn))
Emeric Brun0abf8362014-06-24 18:26:41 +02004010 goto out;
David Safb76832014-05-08 23:42:08 -04004011
4012 /* SSL_get_peer_certificate, it increase X509 * ref count */
4013 crt = SSL_get_peer_certificate(conn->xprt_ctx);
4014 if (!crt)
4015 goto out;
4016
4017 name = X509_get_subject_name(crt);
4018 if (!name)
4019 goto out;
David Safb76832014-05-08 23:42:08 -04004020
Emeric Brun0abf8362014-06-24 18:26:41 +02004021 result = ssl_sock_get_dn_entry(name, &find_cn_chunk, 1, dest);
4022out:
David Safb76832014-05-08 23:42:08 -04004023 if (crt)
4024 X509_free(crt);
4025
4026 return result;
4027}
4028
Dave McCowan328fb582014-07-30 10:39:13 -04004029/* returns 1 if client passed a certificate for this session, 0 if not */
4030int ssl_sock_get_cert_used_sess(struct connection *conn)
4031{
4032 X509 *crt = NULL;
4033
4034 if (!ssl_sock_is_ssl(conn))
4035 return 0;
4036
4037 /* SSL_get_peer_certificate, it increase X509 * ref count */
4038 crt = SSL_get_peer_certificate(conn->xprt_ctx);
4039 if (!crt)
4040 return 0;
4041
4042 X509_free(crt);
4043 return 1;
4044}
4045
4046/* returns 1 if client passed a certificate for this connection, 0 if not */
4047int ssl_sock_get_cert_used_conn(struct connection *conn)
David Safb76832014-05-08 23:42:08 -04004048{
4049 if (!ssl_sock_is_ssl(conn))
4050 return 0;
4051
4052 return SSL_SOCK_ST_FL_VERIFY_DONE & conn->xprt_st ? 1 : 0;
4053}
4054
4055/* returns result from SSL verify */
4056unsigned int ssl_sock_get_verify_result(struct connection *conn)
4057{
4058 if (!ssl_sock_is_ssl(conn))
4059 return (unsigned int)X509_V_ERR_APPLICATION_VERIFICATION;
4060
4061 return (unsigned int)SSL_get_verify_result(conn->xprt_ctx);
4062}
4063
Willy Tarreau7875d092012-09-10 08:20:03 +02004064/***** Below are some sample fetching functions for ACL/patterns *****/
4065
Emeric Brune64aef12012-09-21 13:15:06 +02004066/* boolean, returns true if client cert was present */
4067static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02004068smp_fetch_ssl_fc_has_crt(const struct arg *args, struct sample *smp, const char *kw, void *private)
Emeric Brune64aef12012-09-21 13:15:06 +02004069{
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004070 struct connection *conn;
4071
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02004072 conn = objt_conn(smp->sess->origin);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004073 if (!conn || conn->xprt != &ssl_sock)
Emeric Brune64aef12012-09-21 13:15:06 +02004074 return 0;
4075
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004076 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brune64aef12012-09-21 13:15:06 +02004077 smp->flags |= SMP_F_MAY_CHANGE;
4078 return 0;
4079 }
4080
4081 smp->flags = 0;
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02004082 smp->data.type = SMP_T_BOOL;
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02004083 smp->data.u.sint = SSL_SOCK_ST_FL_VERIFY_DONE & conn->xprt_st ? 1 : 0;
Emeric Brune64aef12012-09-21 13:15:06 +02004084
4085 return 1;
4086}
4087
Emeric Brun43e79582014-10-29 19:03:26 +01004088/* binary, returns a certificate in a binary chunk (der/raw).
4089 * The 5th keyword char is used to know if SSL_get_certificate or SSL_get_peer_certificate
4090 * should be use.
4091 */
4092static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02004093smp_fetch_ssl_x_der(const struct arg *args, struct sample *smp, const char *kw, void *private)
Emeric Brun43e79582014-10-29 19:03:26 +01004094{
4095 int cert_peer = (kw[4] == 'c') ? 1 : 0;
4096 X509 *crt = NULL;
4097 int ret = 0;
4098 struct chunk *smp_trash;
4099 struct connection *conn;
4100
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02004101 conn = objt_conn(smp->sess->origin);
Emeric Brun43e79582014-10-29 19:03:26 +01004102 if (!conn || conn->xprt != &ssl_sock)
4103 return 0;
4104
4105 if (!(conn->flags & CO_FL_CONNECTED)) {
4106 smp->flags |= SMP_F_MAY_CHANGE;
4107 return 0;
4108 }
4109
4110 if (cert_peer)
4111 crt = SSL_get_peer_certificate(conn->xprt_ctx);
4112 else
4113 crt = SSL_get_certificate(conn->xprt_ctx);
4114
4115 if (!crt)
4116 goto out;
4117
4118 smp_trash = get_trash_chunk();
4119 if (ssl_sock_crt2der(crt, smp_trash) <= 0)
4120 goto out;
4121
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02004122 smp->data.u.str = *smp_trash;
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02004123 smp->data.type = SMP_T_BIN;
Emeric Brun43e79582014-10-29 19:03:26 +01004124 ret = 1;
4125out:
4126 /* SSL_get_peer_certificate, it increase X509 * ref count */
4127 if (cert_peer && crt)
4128 X509_free(crt);
4129 return ret;
4130}
4131
Emeric Brunba841a12014-04-30 17:05:08 +02004132/* binary, returns serial of certificate in a binary chunk.
4133 * The 5th keyword char is used to know if SSL_get_certificate or SSL_get_peer_certificate
4134 * should be use.
4135 */
Willy Tarreau8d598402012-10-22 17:58:39 +02004136static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02004137smp_fetch_ssl_x_serial(const struct arg *args, struct sample *smp, const char *kw, void *private)
Willy Tarreau8d598402012-10-22 17:58:39 +02004138{
Emeric Brunba841a12014-04-30 17:05:08 +02004139 int cert_peer = (kw[4] == 'c') ? 1 : 0;
Willy Tarreau8d598402012-10-22 17:58:39 +02004140 X509 *crt = NULL;
4141 int ret = 0;
4142 struct chunk *smp_trash;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004143 struct connection *conn;
4144
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02004145 conn = objt_conn(smp->sess->origin);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004146 if (!conn || conn->xprt != &ssl_sock)
Willy Tarreau8d598402012-10-22 17:58:39 +02004147 return 0;
4148
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004149 if (!(conn->flags & CO_FL_CONNECTED)) {
Willy Tarreau8d598402012-10-22 17:58:39 +02004150 smp->flags |= SMP_F_MAY_CHANGE;
4151 return 0;
4152 }
4153
Emeric Brunba841a12014-04-30 17:05:08 +02004154 if (cert_peer)
4155 crt = SSL_get_peer_certificate(conn->xprt_ctx);
4156 else
4157 crt = SSL_get_certificate(conn->xprt_ctx);
4158
Willy Tarreau8d598402012-10-22 17:58:39 +02004159 if (!crt)
4160 goto out;
4161
Willy Tarreau47ca5452012-12-23 20:22:19 +01004162 smp_trash = get_trash_chunk();
Willy Tarreau8d598402012-10-22 17:58:39 +02004163 if (ssl_sock_get_serial(crt, smp_trash) <= 0)
4164 goto out;
4165
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02004166 smp->data.u.str = *smp_trash;
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02004167 smp->data.type = SMP_T_BIN;
Willy Tarreau8d598402012-10-22 17:58:39 +02004168 ret = 1;
4169out:
Emeric Brunba841a12014-04-30 17:05:08 +02004170 /* SSL_get_peer_certificate, it increase X509 * ref count */
4171 if (cert_peer && crt)
Willy Tarreau8d598402012-10-22 17:58:39 +02004172 X509_free(crt);
4173 return ret;
4174}
Emeric Brune64aef12012-09-21 13:15:06 +02004175
Emeric Brunba841a12014-04-30 17:05:08 +02004176/* binary, returns the client certificate's SHA-1 fingerprint (SHA-1 hash of DER-encoded certificate) in a binary chunk.
4177 * The 5th keyword char is used to know if SSL_get_certificate or SSL_get_peer_certificate
4178 * should be use.
4179 */
James Votha051b4a2013-05-14 20:37:59 +02004180static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02004181smp_fetch_ssl_x_sha1(const struct arg *args, struct sample *smp, const char *kw, void *private)
James Votha051b4a2013-05-14 20:37:59 +02004182{
Emeric Brunba841a12014-04-30 17:05:08 +02004183 int cert_peer = (kw[4] == 'c') ? 1 : 0;
James Votha051b4a2013-05-14 20:37:59 +02004184 X509 *crt = NULL;
4185 const EVP_MD *digest;
4186 int ret = 0;
4187 struct chunk *smp_trash;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004188 struct connection *conn;
James Votha051b4a2013-05-14 20:37:59 +02004189
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02004190 conn = objt_conn(smp->sess->origin);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004191 if (!conn || conn->xprt != &ssl_sock)
4192 return 0;
4193
4194 if (!(conn->flags & CO_FL_CONNECTED)) {
James Votha051b4a2013-05-14 20:37:59 +02004195 smp->flags |= SMP_F_MAY_CHANGE;
4196 return 0;
4197 }
4198
Emeric Brunba841a12014-04-30 17:05:08 +02004199 if (cert_peer)
4200 crt = SSL_get_peer_certificate(conn->xprt_ctx);
4201 else
4202 crt = SSL_get_certificate(conn->xprt_ctx);
James Votha051b4a2013-05-14 20:37:59 +02004203 if (!crt)
4204 goto out;
4205
4206 smp_trash = get_trash_chunk();
4207 digest = EVP_sha1();
4208 X509_digest(crt, digest, (unsigned char *)smp_trash->str, (unsigned int *)&smp_trash->len);
4209
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02004210 smp->data.u.str = *smp_trash;
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02004211 smp->data.type = SMP_T_BIN;
James Votha051b4a2013-05-14 20:37:59 +02004212 ret = 1;
4213out:
Emeric Brunba841a12014-04-30 17:05:08 +02004214 /* SSL_get_peer_certificate, it increase X509 * ref count */
4215 if (cert_peer && crt)
James Votha051b4a2013-05-14 20:37:59 +02004216 X509_free(crt);
4217 return ret;
4218}
4219
Emeric Brunba841a12014-04-30 17:05:08 +02004220/* string, returns certificate's notafter date in ASN1_UTCTIME format.
4221 * The 5th keyword char is used to know if SSL_get_certificate or SSL_get_peer_certificate
4222 * should be use.
4223 */
Emeric Brunce5ad802012-10-22 14:11:22 +02004224static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02004225smp_fetch_ssl_x_notafter(const struct arg *args, struct sample *smp, const char *kw, void *private)
Emeric Brunce5ad802012-10-22 14:11:22 +02004226{
Emeric Brunba841a12014-04-30 17:05:08 +02004227 int cert_peer = (kw[4] == 'c') ? 1 : 0;
Emeric Brunce5ad802012-10-22 14:11:22 +02004228 X509 *crt = NULL;
4229 int ret = 0;
4230 struct chunk *smp_trash;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004231 struct connection *conn;
Emeric Brunce5ad802012-10-22 14:11:22 +02004232
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02004233 conn = objt_conn(smp->sess->origin);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004234 if (!conn || conn->xprt != &ssl_sock)
4235 return 0;
4236
4237 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brunce5ad802012-10-22 14:11:22 +02004238 smp->flags |= SMP_F_MAY_CHANGE;
4239 return 0;
4240 }
4241
Emeric Brunba841a12014-04-30 17:05:08 +02004242 if (cert_peer)
4243 crt = SSL_get_peer_certificate(conn->xprt_ctx);
4244 else
4245 crt = SSL_get_certificate(conn->xprt_ctx);
Emeric Brunce5ad802012-10-22 14:11:22 +02004246 if (!crt)
4247 goto out;
4248
Willy Tarreau47ca5452012-12-23 20:22:19 +01004249 smp_trash = get_trash_chunk();
Emeric Brunce5ad802012-10-22 14:11:22 +02004250 if (ssl_sock_get_time(X509_get_notAfter(crt), smp_trash) <= 0)
4251 goto out;
4252
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02004253 smp->data.u.str = *smp_trash;
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02004254 smp->data.type = SMP_T_STR;
Emeric Brunce5ad802012-10-22 14:11:22 +02004255 ret = 1;
4256out:
Emeric Brunba841a12014-04-30 17:05:08 +02004257 /* SSL_get_peer_certificate, it increase X509 * ref count */
4258 if (cert_peer && crt)
Emeric Brunce5ad802012-10-22 14:11:22 +02004259 X509_free(crt);
4260 return ret;
4261}
4262
Emeric Brunba841a12014-04-30 17:05:08 +02004263/* string, returns a string of a formatted full dn \C=..\O=..\OU=.. \CN=.. of certificate's issuer
4264 * The 5th keyword char is used to know if SSL_get_certificate or SSL_get_peer_certificate
4265 * should be use.
4266 */
Emeric Brun87855892012-10-17 17:39:35 +02004267static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02004268smp_fetch_ssl_x_i_dn(const struct arg *args, struct sample *smp, const char *kw, void *private)
Emeric Brun87855892012-10-17 17:39:35 +02004269{
Emeric Brunba841a12014-04-30 17:05:08 +02004270 int cert_peer = (kw[4] == 'c') ? 1 : 0;
Emeric Brun87855892012-10-17 17:39:35 +02004271 X509 *crt = NULL;
4272 X509_NAME *name;
4273 int ret = 0;
4274 struct chunk *smp_trash;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004275 struct connection *conn;
Emeric Brun87855892012-10-17 17:39:35 +02004276
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02004277 conn = objt_conn(smp->sess->origin);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004278 if (!conn || conn->xprt != &ssl_sock)
4279 return 0;
4280
4281 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brun87855892012-10-17 17:39:35 +02004282 smp->flags |= SMP_F_MAY_CHANGE;
4283 return 0;
4284 }
4285
Emeric Brunba841a12014-04-30 17:05:08 +02004286 if (cert_peer)
4287 crt = SSL_get_peer_certificate(conn->xprt_ctx);
4288 else
4289 crt = SSL_get_certificate(conn->xprt_ctx);
Emeric Brun87855892012-10-17 17:39:35 +02004290 if (!crt)
4291 goto out;
4292
4293 name = X509_get_issuer_name(crt);
4294 if (!name)
4295 goto out;
4296
Willy Tarreau47ca5452012-12-23 20:22:19 +01004297 smp_trash = get_trash_chunk();
Emeric Brun87855892012-10-17 17:39:35 +02004298 if (args && args[0].type == ARGT_STR) {
4299 int pos = 1;
4300
4301 if (args[1].type == ARGT_SINT)
4302 pos = args[1].data.sint;
Emeric Brun87855892012-10-17 17:39:35 +02004303
4304 if (ssl_sock_get_dn_entry(name, &args[0].data.str, pos, smp_trash) <= 0)
4305 goto out;
4306 }
4307 else if (ssl_sock_get_dn_oneline(name, smp_trash) <= 0)
4308 goto out;
4309
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02004310 smp->data.type = SMP_T_STR;
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02004311 smp->data.u.str = *smp_trash;
Emeric Brun87855892012-10-17 17:39:35 +02004312 ret = 1;
4313out:
Emeric Brunba841a12014-04-30 17:05:08 +02004314 /* SSL_get_peer_certificate, it increase X509 * ref count */
4315 if (cert_peer && crt)
Emeric Brun87855892012-10-17 17:39:35 +02004316 X509_free(crt);
4317 return ret;
4318}
4319
Emeric Brunba841a12014-04-30 17:05:08 +02004320/* string, returns notbefore date in ASN1_UTCTIME format.
4321 * The 5th keyword char is used to know if SSL_get_certificate or SSL_get_peer_certificate
4322 * should be use.
4323 */
Emeric Brunce5ad802012-10-22 14:11:22 +02004324static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02004325smp_fetch_ssl_x_notbefore(const struct arg *args, struct sample *smp, const char *kw, void *private)
Emeric Brunce5ad802012-10-22 14:11:22 +02004326{
Emeric Brunba841a12014-04-30 17:05:08 +02004327 int cert_peer = (kw[4] == 'c') ? 1 : 0;
Emeric Brunce5ad802012-10-22 14:11:22 +02004328 X509 *crt = NULL;
4329 int ret = 0;
4330 struct chunk *smp_trash;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004331 struct connection *conn;
4332
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02004333 conn = objt_conn(smp->sess->origin);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004334 if (!conn || conn->xprt != &ssl_sock)
Emeric Brunce5ad802012-10-22 14:11:22 +02004335 return 0;
4336
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004337 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brunce5ad802012-10-22 14:11:22 +02004338 smp->flags |= SMP_F_MAY_CHANGE;
4339 return 0;
4340 }
4341
Emeric Brunba841a12014-04-30 17:05:08 +02004342 if (cert_peer)
4343 crt = SSL_get_peer_certificate(conn->xprt_ctx);
4344 else
4345 crt = SSL_get_certificate(conn->xprt_ctx);
Emeric Brunce5ad802012-10-22 14:11:22 +02004346 if (!crt)
4347 goto out;
4348
Willy Tarreau47ca5452012-12-23 20:22:19 +01004349 smp_trash = get_trash_chunk();
Emeric Brunce5ad802012-10-22 14:11:22 +02004350 if (ssl_sock_get_time(X509_get_notBefore(crt), smp_trash) <= 0)
4351 goto out;
4352
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02004353 smp->data.u.str = *smp_trash;
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02004354 smp->data.type = SMP_T_STR;
Emeric Brunce5ad802012-10-22 14:11:22 +02004355 ret = 1;
4356out:
Emeric Brunba841a12014-04-30 17:05:08 +02004357 /* SSL_get_peer_certificate, it increase X509 * ref count */
4358 if (cert_peer && crt)
Emeric Brunce5ad802012-10-22 14:11:22 +02004359 X509_free(crt);
4360 return ret;
4361}
4362
Emeric Brunba841a12014-04-30 17:05:08 +02004363/* string, returns a string of a formatted full dn \C=..\O=..\OU=.. \CN=.. of certificate's subject
4364 * The 5th keyword char is used to know if SSL_get_certificate or SSL_get_peer_certificate
4365 * should be use.
4366 */
Emeric Brun87855892012-10-17 17:39:35 +02004367static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02004368smp_fetch_ssl_x_s_dn(const struct arg *args, struct sample *smp, const char *kw, void *private)
Emeric Brun87855892012-10-17 17:39:35 +02004369{
Emeric Brunba841a12014-04-30 17:05:08 +02004370 int cert_peer = (kw[4] == 'c') ? 1 : 0;
Emeric Brun87855892012-10-17 17:39:35 +02004371 X509 *crt = NULL;
4372 X509_NAME *name;
4373 int ret = 0;
4374 struct chunk *smp_trash;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004375 struct connection *conn;
Emeric Brun87855892012-10-17 17:39:35 +02004376
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02004377 conn = objt_conn(smp->sess->origin);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004378 if (!conn || conn->xprt != &ssl_sock)
4379 return 0;
4380
4381 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brun87855892012-10-17 17:39:35 +02004382 smp->flags |= SMP_F_MAY_CHANGE;
4383 return 0;
4384 }
4385
Emeric Brunba841a12014-04-30 17:05:08 +02004386 if (cert_peer)
4387 crt = SSL_get_peer_certificate(conn->xprt_ctx);
4388 else
4389 crt = SSL_get_certificate(conn->xprt_ctx);
Emeric Brun87855892012-10-17 17:39:35 +02004390 if (!crt)
4391 goto out;
4392
4393 name = X509_get_subject_name(crt);
4394 if (!name)
4395 goto out;
4396
Willy Tarreau47ca5452012-12-23 20:22:19 +01004397 smp_trash = get_trash_chunk();
Emeric Brun87855892012-10-17 17:39:35 +02004398 if (args && args[0].type == ARGT_STR) {
4399 int pos = 1;
4400
4401 if (args[1].type == ARGT_SINT)
4402 pos = args[1].data.sint;
Emeric Brun87855892012-10-17 17:39:35 +02004403
4404 if (ssl_sock_get_dn_entry(name, &args[0].data.str, pos, smp_trash) <= 0)
4405 goto out;
4406 }
4407 else if (ssl_sock_get_dn_oneline(name, smp_trash) <= 0)
4408 goto out;
4409
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02004410 smp->data.type = SMP_T_STR;
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02004411 smp->data.u.str = *smp_trash;
Emeric Brun87855892012-10-17 17:39:35 +02004412 ret = 1;
4413out:
Emeric Brunba841a12014-04-30 17:05:08 +02004414 /* SSL_get_peer_certificate, it increase X509 * ref count */
4415 if (cert_peer && crt)
Emeric Brun87855892012-10-17 17:39:35 +02004416 X509_free(crt);
4417 return ret;
4418}
Emeric Brun9143d372012-12-20 15:44:16 +01004419
4420/* integer, returns true if current session use a client certificate */
4421static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02004422smp_fetch_ssl_c_used(const struct arg *args, struct sample *smp, const char *kw, void *private)
Emeric Brun9143d372012-12-20 15:44:16 +01004423{
4424 X509 *crt;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004425 struct connection *conn;
Emeric Brun9143d372012-12-20 15:44:16 +01004426
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02004427 conn = objt_conn(smp->sess->origin);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004428 if (!conn || conn->xprt != &ssl_sock)
4429 return 0;
4430
4431 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brun9143d372012-12-20 15:44:16 +01004432 smp->flags |= SMP_F_MAY_CHANGE;
4433 return 0;
4434 }
4435
4436 /* SSL_get_peer_certificate returns a ptr on allocated X509 struct */
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004437 crt = SSL_get_peer_certificate(conn->xprt_ctx);
Emeric Brun9143d372012-12-20 15:44:16 +01004438 if (crt) {
4439 X509_free(crt);
4440 }
4441
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02004442 smp->data.type = SMP_T_BOOL;
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02004443 smp->data.u.sint = (crt != NULL);
Emeric Brun9143d372012-12-20 15:44:16 +01004444 return 1;
4445}
4446
Emeric Brunba841a12014-04-30 17:05:08 +02004447/* integer, returns the certificate version
4448 * The 5th keyword char is used to know if SSL_get_certificate or SSL_get_peer_certificate
4449 * should be use.
4450 */
Emeric Bruna7359fd2012-10-17 15:03:11 +02004451static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02004452smp_fetch_ssl_x_version(const struct arg *args, struct sample *smp, const char *kw, void *private)
Emeric Bruna7359fd2012-10-17 15:03:11 +02004453{
Emeric Brunba841a12014-04-30 17:05:08 +02004454 int cert_peer = (kw[4] == 'c') ? 1 : 0;
Emeric Bruna7359fd2012-10-17 15:03:11 +02004455 X509 *crt;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004456 struct connection *conn;
4457
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02004458 conn = objt_conn(smp->sess->origin);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004459 if (!conn || conn->xprt != &ssl_sock)
Emeric Bruna7359fd2012-10-17 15:03:11 +02004460 return 0;
4461
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004462 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Bruna7359fd2012-10-17 15:03:11 +02004463 smp->flags |= SMP_F_MAY_CHANGE;
4464 return 0;
4465 }
4466
Emeric Brunba841a12014-04-30 17:05:08 +02004467 if (cert_peer)
4468 crt = SSL_get_peer_certificate(conn->xprt_ctx);
4469 else
4470 crt = SSL_get_certificate(conn->xprt_ctx);
Emeric Bruna7359fd2012-10-17 15:03:11 +02004471 if (!crt)
4472 return 0;
4473
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02004474 smp->data.u.sint = (unsigned int)(1 + X509_get_version(crt));
Emeric Brunba841a12014-04-30 17:05:08 +02004475 /* SSL_get_peer_certificate increase X509 * ref count */
4476 if (cert_peer)
4477 X509_free(crt);
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02004478 smp->data.type = SMP_T_SINT;
Emeric Bruna7359fd2012-10-17 15:03:11 +02004479
4480 return 1;
4481}
4482
Emeric Brunba841a12014-04-30 17:05:08 +02004483/* string, returns the certificate's signature algorithm.
4484 * The 5th keyword char is used to know if SSL_get_certificate or SSL_get_peer_certificate
4485 * should be use.
4486 */
Emeric Brun7f56e742012-10-19 18:15:40 +02004487static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02004488smp_fetch_ssl_x_sig_alg(const struct arg *args, struct sample *smp, const char *kw, void *private)
Emeric Brun7f56e742012-10-19 18:15:40 +02004489{
Emeric Brunba841a12014-04-30 17:05:08 +02004490 int cert_peer = (kw[4] == 'c') ? 1 : 0;
Emeric Brun7f56e742012-10-19 18:15:40 +02004491 X509 *crt;
4492 int nid;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004493 struct connection *conn;
Emeric Brun7f56e742012-10-19 18:15:40 +02004494
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02004495 conn = objt_conn(smp->sess->origin);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004496 if (!conn || conn->xprt != &ssl_sock)
4497 return 0;
4498
4499 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brun7f56e742012-10-19 18:15:40 +02004500 smp->flags |= SMP_F_MAY_CHANGE;
4501 return 0;
4502 }
4503
Emeric Brunba841a12014-04-30 17:05:08 +02004504 if (cert_peer)
4505 crt = SSL_get_peer_certificate(conn->xprt_ctx);
4506 else
4507 crt = SSL_get_certificate(conn->xprt_ctx);
Emeric Brun7f56e742012-10-19 18:15:40 +02004508 if (!crt)
4509 return 0;
4510
4511 nid = OBJ_obj2nid((ASN1_OBJECT *)(crt->cert_info->signature->algorithm));
4512
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02004513 smp->data.u.str.str = (char *)OBJ_nid2sn(nid);
4514 if (!smp->data.u.str.str) {
Emeric Brunba841a12014-04-30 17:05:08 +02004515 /* SSL_get_peer_certificate increase X509 * ref count */
4516 if (cert_peer)
4517 X509_free(crt);
Emeric Brun7f56e742012-10-19 18:15:40 +02004518 return 0;
Emeric Brun9bf3ba22013-10-07 14:31:44 +02004519 }
Emeric Brun7f56e742012-10-19 18:15:40 +02004520
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02004521 smp->data.type = SMP_T_STR;
Thierry FOURNIER7654c9f2013-12-17 00:20:33 +01004522 smp->flags |= SMP_F_CONST;
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02004523 smp->data.u.str.len = strlen(smp->data.u.str.str);
Emeric Brunba841a12014-04-30 17:05:08 +02004524 /* SSL_get_peer_certificate increase X509 * ref count */
4525 if (cert_peer)
4526 X509_free(crt);
Emeric Brun7f56e742012-10-19 18:15:40 +02004527
4528 return 1;
4529}
4530
Emeric Brunba841a12014-04-30 17:05:08 +02004531/* string, returns the certificate's key algorithm.
4532 * The 5th keyword char is used to know if SSL_get_certificate or SSL_get_peer_certificate
4533 * should be use.
4534 */
Emeric Brun521a0112012-10-22 12:22:55 +02004535static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02004536smp_fetch_ssl_x_key_alg(const struct arg *args, struct sample *smp, const char *kw, void *private)
Emeric Brun521a0112012-10-22 12:22:55 +02004537{
Emeric Brunba841a12014-04-30 17:05:08 +02004538 int cert_peer = (kw[4] == 'c') ? 1 : 0;
Emeric Brun521a0112012-10-22 12:22:55 +02004539 X509 *crt;
4540 int nid;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004541 struct connection *conn;
Emeric Brun521a0112012-10-22 12:22:55 +02004542
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02004543 conn = objt_conn(smp->sess->origin);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004544 if (!conn || conn->xprt != &ssl_sock)
4545 return 0;
4546
4547 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brun521a0112012-10-22 12:22:55 +02004548 smp->flags |= SMP_F_MAY_CHANGE;
4549 return 0;
4550 }
4551
Emeric Brunba841a12014-04-30 17:05:08 +02004552 if (cert_peer)
4553 crt = SSL_get_peer_certificate(conn->xprt_ctx);
4554 else
4555 crt = SSL_get_certificate(conn->xprt_ctx);
Emeric Brun521a0112012-10-22 12:22:55 +02004556 if (!crt)
4557 return 0;
4558
4559 nid = OBJ_obj2nid((ASN1_OBJECT *)(crt->cert_info->key->algor->algorithm));
4560
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02004561 smp->data.u.str.str = (char *)OBJ_nid2sn(nid);
4562 if (!smp->data.u.str.str) {
Emeric Brunba841a12014-04-30 17:05:08 +02004563 /* SSL_get_peer_certificate increase X509 * ref count */
4564 if (cert_peer)
4565 X509_free(crt);
Emeric Brun521a0112012-10-22 12:22:55 +02004566 return 0;
Emeric Brun9bf3ba22013-10-07 14:31:44 +02004567 }
Emeric Brun521a0112012-10-22 12:22:55 +02004568
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02004569 smp->data.type = SMP_T_STR;
Thierry FOURNIER7654c9f2013-12-17 00:20:33 +01004570 smp->flags |= SMP_F_CONST;
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02004571 smp->data.u.str.len = strlen(smp->data.u.str.str);
Emeric Brunba841a12014-04-30 17:05:08 +02004572 if (cert_peer)
4573 X509_free(crt);
Emeric Brun521a0112012-10-22 12:22:55 +02004574
4575 return 1;
4576}
4577
Emeric Brun645ae792014-04-30 14:21:06 +02004578/* boolean, returns true if front conn. transport layer is SSL.
4579 * This function is also usable on backend conn if the fetch keyword 5th
4580 * char is 'b'.
4581 */
Willy Tarreau7875d092012-09-10 08:20:03 +02004582static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02004583smp_fetch_ssl_fc(const struct arg *args, struct sample *smp, const char *kw, void *private)
Willy Tarreau7875d092012-09-10 08:20:03 +02004584{
Willy Tarreaue237fe12016-03-10 17:05:28 +01004585 struct connection *conn = objt_conn((kw[4] != 'b') ? smp->sess->origin :
4586 smp->strm ? smp->strm->si[1].end : NULL);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004587
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02004588 smp->data.type = SMP_T_BOOL;
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02004589 smp->data.u.sint = (conn && conn->xprt == &ssl_sock);
Willy Tarreau7875d092012-09-10 08:20:03 +02004590 return 1;
4591}
4592
Emeric Brun2525b6b2012-10-18 15:59:43 +02004593/* boolean, returns true if client present a SNI */
Willy Tarreau7875d092012-09-10 08:20:03 +02004594static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02004595smp_fetch_ssl_fc_has_sni(const struct arg *args, struct sample *smp, const char *kw, void *private)
Willy Tarreau7875d092012-09-10 08:20:03 +02004596{
4597#ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02004598 struct connection *conn = objt_conn(smp->sess->origin);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004599
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02004600 smp->data.type = SMP_T_BOOL;
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02004601 smp->data.u.sint = (conn && conn->xprt == &ssl_sock) &&
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004602 conn->xprt_ctx &&
4603 SSL_get_servername(conn->xprt_ctx, TLSEXT_NAMETYPE_host_name) != NULL;
Willy Tarreau7875d092012-09-10 08:20:03 +02004604 return 1;
4605#else
4606 return 0;
4607#endif
4608}
4609
Nenad Merdanovic26ea8222015-05-18 02:28:57 +02004610/* boolean, returns true if client session has been resumed */
4611static int
4612smp_fetch_ssl_fc_is_resumed(const struct arg *args, struct sample *smp, const char *kw, void *private)
4613{
4614 struct connection *conn = objt_conn(smp->sess->origin);
4615
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02004616 smp->data.type = SMP_T_BOOL;
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02004617 smp->data.u.sint = (conn && conn->xprt == &ssl_sock) &&
Nenad Merdanovic26ea8222015-05-18 02:28:57 +02004618 conn->xprt_ctx &&
4619 SSL_session_reused(conn->xprt_ctx);
4620 return 1;
4621}
4622
Emeric Brun645ae792014-04-30 14:21:06 +02004623/* string, returns the used cipher if front conn. transport layer is SSL.
4624 * This function is also usable on backend conn if the fetch keyword 5th
4625 * char is 'b'.
4626 */
Emeric Brun589fcad2012-10-16 14:13:26 +02004627static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02004628smp_fetch_ssl_fc_cipher(const struct arg *args, struct sample *smp, const char *kw, void *private)
Emeric Brun589fcad2012-10-16 14:13:26 +02004629{
Willy Tarreaue237fe12016-03-10 17:05:28 +01004630 struct connection *conn = objt_conn((kw[4] != 'b') ? smp->sess->origin :
4631 smp->strm ? smp->strm->si[1].end : NULL);
Emeric Brun589fcad2012-10-16 14:13:26 +02004632
Willy Tarreaube508f12016-03-10 11:47:01 +01004633 smp->flags = 0;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004634 if (!conn || !conn->xprt_ctx || conn->xprt != &ssl_sock)
Emeric Brun589fcad2012-10-16 14:13:26 +02004635 return 0;
4636
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02004637 smp->data.u.str.str = (char *)SSL_get_cipher_name(conn->xprt_ctx);
4638 if (!smp->data.u.str.str)
Emeric Brun589fcad2012-10-16 14:13:26 +02004639 return 0;
4640
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02004641 smp->data.type = SMP_T_STR;
Thierry FOURNIER7654c9f2013-12-17 00:20:33 +01004642 smp->flags |= SMP_F_CONST;
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02004643 smp->data.u.str.len = strlen(smp->data.u.str.str);
Emeric Brun589fcad2012-10-16 14:13:26 +02004644
4645 return 1;
4646}
4647
Emeric Brun645ae792014-04-30 14:21:06 +02004648/* integer, returns the algoritm's keysize if front conn. transport layer
4649 * is SSL.
4650 * This function is also usable on backend conn if the fetch keyword 5th
4651 * char is 'b'.
4652 */
Emeric Brun589fcad2012-10-16 14:13:26 +02004653static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02004654smp_fetch_ssl_fc_alg_keysize(const struct arg *args, struct sample *smp, const char *kw, void *private)
Emeric Brun589fcad2012-10-16 14:13:26 +02004655{
Willy Tarreaue237fe12016-03-10 17:05:28 +01004656 struct connection *conn = objt_conn((kw[4] != 'b') ? smp->sess->origin :
4657 smp->strm ? smp->strm->si[1].end : NULL);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004658
Willy Tarreaue237fe12016-03-10 17:05:28 +01004659 int sint;
Willy Tarreaube508f12016-03-10 11:47:01 +01004660
Emeric Brun589fcad2012-10-16 14:13:26 +02004661 smp->flags = 0;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004662 if (!conn || !conn->xprt_ctx || conn->xprt != &ssl_sock)
Emeric Brun589fcad2012-10-16 14:13:26 +02004663 return 0;
4664
Thierry FOURNIER07ee64e2015-07-06 23:43:03 +02004665 if (!SSL_get_cipher_bits(conn->xprt_ctx, &sint))
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004666 return 0;
4667
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02004668 smp->data.u.sint = sint;
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02004669 smp->data.type = SMP_T_SINT;
Emeric Brun589fcad2012-10-16 14:13:26 +02004670
4671 return 1;
4672}
4673
Emeric Brun645ae792014-04-30 14:21:06 +02004674/* integer, returns the used keysize if front conn. transport layer is SSL.
4675 * This function is also usable on backend conn if the fetch keyword 5th
4676 * char is 'b'.
4677 */
Emeric Brun589fcad2012-10-16 14:13:26 +02004678static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02004679smp_fetch_ssl_fc_use_keysize(const struct arg *args, struct sample *smp, const char *kw, void *private)
Emeric Brun589fcad2012-10-16 14:13:26 +02004680{
Willy Tarreaue237fe12016-03-10 17:05:28 +01004681 struct connection *conn = objt_conn((kw[4] != 'b') ? smp->sess->origin :
4682 smp->strm ? smp->strm->si[1].end : NULL);
Willy Tarreaube508f12016-03-10 11:47:01 +01004683
Emeric Brun589fcad2012-10-16 14:13:26 +02004684 smp->flags = 0;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004685 if (!conn || !conn->xprt_ctx || conn->xprt != &ssl_sock)
4686 return 0;
4687
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02004688 smp->data.u.sint = (unsigned int)SSL_get_cipher_bits(conn->xprt_ctx, NULL);
4689 if (!smp->data.u.sint)
Emeric Brun589fcad2012-10-16 14:13:26 +02004690 return 0;
4691
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02004692 smp->data.type = SMP_T_SINT;
Emeric Brun589fcad2012-10-16 14:13:26 +02004693
4694 return 1;
4695}
4696
Willy Tarreau6c9a3d52012-10-18 18:57:14 +02004697#ifdef OPENSSL_NPN_NEGOTIATED
Willy Tarreau7875d092012-09-10 08:20:03 +02004698static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02004699smp_fetch_ssl_fc_npn(const struct arg *args, struct sample *smp, const char *kw, void *private)
Willy Tarreaua33c6542012-10-15 13:19:06 +02004700{
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004701 struct connection *conn;
4702
Thierry FOURNIER7654c9f2013-12-17 00:20:33 +01004703 smp->flags = SMP_F_CONST;
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02004704 smp->data.type = SMP_T_STR;
Willy Tarreaua33c6542012-10-15 13:19:06 +02004705
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02004706 conn = objt_conn(smp->sess->origin);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004707 if (!conn || !conn->xprt_ctx || conn->xprt != &ssl_sock)
4708 return 0;
4709
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02004710 smp->data.u.str.str = NULL;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004711 SSL_get0_next_proto_negotiated(conn->xprt_ctx,
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02004712 (const unsigned char **)&smp->data.u.str.str, (unsigned *)&smp->data.u.str.len);
Willy Tarreaua33c6542012-10-15 13:19:06 +02004713
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02004714 if (!smp->data.u.str.str)
Willy Tarreaua33c6542012-10-15 13:19:06 +02004715 return 0;
4716
4717 return 1;
Willy Tarreaua33c6542012-10-15 13:19:06 +02004718}
Willy Tarreau6c9a3d52012-10-18 18:57:14 +02004719#endif
Willy Tarreaua33c6542012-10-15 13:19:06 +02004720
Dirkjan Bussink48f1c4e2014-02-13 12:29:42 +01004721#ifdef TLSEXT_TYPE_application_layer_protocol_negotiation
Willy Tarreauab861d32013-04-02 02:30:41 +02004722static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02004723smp_fetch_ssl_fc_alpn(const struct arg *args, struct sample *smp, const char *kw, void *private)
Willy Tarreauab861d32013-04-02 02:30:41 +02004724{
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004725 struct connection *conn;
4726
Thierry FOURNIER7654c9f2013-12-17 00:20:33 +01004727 smp->flags = SMP_F_CONST;
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02004728 smp->data.type = SMP_T_STR;
Willy Tarreauab861d32013-04-02 02:30:41 +02004729
Willy Tarreaue26bf052015-05-12 10:30:12 +02004730 conn = objt_conn(smp->sess->origin);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004731 if (!conn || !conn->xprt_ctx || conn->xprt != &ssl_sock)
Willy Tarreauab861d32013-04-02 02:30:41 +02004732 return 0;
4733
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02004734 smp->data.u.str.str = NULL;
Dirkjan Bussink48f1c4e2014-02-13 12:29:42 +01004735 SSL_get0_alpn_selected(conn->xprt_ctx,
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02004736 (const unsigned char **)&smp->data.u.str.str, (unsigned *)&smp->data.u.str.len);
Willy Tarreauab861d32013-04-02 02:30:41 +02004737
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02004738 if (!smp->data.u.str.str)
Willy Tarreauab861d32013-04-02 02:30:41 +02004739 return 0;
4740
4741 return 1;
4742}
4743#endif
4744
Emeric Brun645ae792014-04-30 14:21:06 +02004745/* string, returns the used protocol if front conn. transport layer is SSL.
4746 * This function is also usable on backend conn if the fetch keyword 5th
4747 * char is 'b'.
4748 */
Willy Tarreaua33c6542012-10-15 13:19:06 +02004749static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02004750smp_fetch_ssl_fc_protocol(const struct arg *args, struct sample *smp, const char *kw, void *private)
Emeric Brun589fcad2012-10-16 14:13:26 +02004751{
Willy Tarreaue237fe12016-03-10 17:05:28 +01004752 struct connection *conn = objt_conn((kw[4] != 'b') ? smp->sess->origin :
4753 smp->strm ? smp->strm->si[1].end : NULL);
Willy Tarreaube508f12016-03-10 11:47:01 +01004754
Emeric Brun589fcad2012-10-16 14:13:26 +02004755 smp->flags = 0;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004756 if (!conn || !conn->xprt_ctx || conn->xprt != &ssl_sock)
4757 return 0;
4758
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02004759 smp->data.u.str.str = (char *)SSL_get_version(conn->xprt_ctx);
4760 if (!smp->data.u.str.str)
Emeric Brun589fcad2012-10-16 14:13:26 +02004761 return 0;
4762
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02004763 smp->data.type = SMP_T_STR;
Thierry FOURNIER7654c9f2013-12-17 00:20:33 +01004764 smp->flags = SMP_F_CONST;
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02004765 smp->data.u.str.len = strlen(smp->data.u.str.str);
Emeric Brun589fcad2012-10-16 14:13:26 +02004766
4767 return 1;
4768}
4769
Willy Tarreau87b09662015-04-03 00:22:06 +02004770/* binary, returns the SSL stream id if front conn. transport layer is SSL.
Emeric Brun645ae792014-04-30 14:21:06 +02004771 * This function is also usable on backend conn if the fetch keyword 5th
4772 * char is 'b'.
4773 */
Emeric Brun589fcad2012-10-16 14:13:26 +02004774static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02004775smp_fetch_ssl_fc_session_id(const struct arg *args, struct sample *smp, const char *kw, void *private)
Emeric Brunfe68f682012-10-16 14:59:28 +02004776{
4777#if OPENSSL_VERSION_NUMBER > 0x0090800fL
Willy Tarreaue237fe12016-03-10 17:05:28 +01004778 struct connection *conn = objt_conn((kw[4] != 'b') ? smp->sess->origin :
4779 smp->strm ? smp->strm->si[1].end : NULL);
Emeric Brunfe68f682012-10-16 14:59:28 +02004780
Willy Tarreaue237fe12016-03-10 17:05:28 +01004781 SSL_SESSION *ssl_sess;
Willy Tarreaube508f12016-03-10 11:47:01 +01004782
Thierry FOURNIER7654c9f2013-12-17 00:20:33 +01004783 smp->flags = SMP_F_CONST;
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02004784 smp->data.type = SMP_T_BIN;
Emeric Brunfe68f682012-10-16 14:59:28 +02004785
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004786 if (!conn || !conn->xprt_ctx || conn->xprt != &ssl_sock)
4787 return 0;
4788
Willy Tarreau192252e2015-04-04 01:47:55 +02004789 ssl_sess = SSL_get_session(conn->xprt_ctx);
4790 if (!ssl_sess)
Emeric Brunfe68f682012-10-16 14:59:28 +02004791 return 0;
4792
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02004793 smp->data.u.str.str = (char *)SSL_SESSION_get_id(ssl_sess, (unsigned int *)&smp->data.u.str.len);
4794 if (!smp->data.u.str.str || !smp->data.u.str.len)
Emeric Brunfe68f682012-10-16 14:59:28 +02004795 return 0;
4796
4797 return 1;
4798#else
4799 return 0;
4800#endif
4801}
4802
4803static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02004804smp_fetch_ssl_fc_sni(const struct arg *args, struct sample *smp, const char *kw, void *private)
Willy Tarreau7875d092012-09-10 08:20:03 +02004805{
4806#ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004807 struct connection *conn;
4808
Thierry FOURNIER7654c9f2013-12-17 00:20:33 +01004809 smp->flags = SMP_F_CONST;
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02004810 smp->data.type = SMP_T_STR;
Willy Tarreau7875d092012-09-10 08:20:03 +02004811
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02004812 conn = objt_conn(smp->sess->origin);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004813 if (!conn || !conn->xprt_ctx || conn->xprt != &ssl_sock)
4814 return 0;
4815
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02004816 smp->data.u.str.str = (char *)SSL_get_servername(conn->xprt_ctx, TLSEXT_NAMETYPE_host_name);
4817 if (!smp->data.u.str.str)
Willy Tarreau3e394c92012-09-14 23:56:58 +02004818 return 0;
4819
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02004820 smp->data.u.str.len = strlen(smp->data.u.str.str);
Willy Tarreau7875d092012-09-10 08:20:03 +02004821 return 1;
4822#else
4823 return 0;
4824#endif
4825}
4826
David Sc1ad52e2014-04-08 18:48:47 -04004827static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02004828smp_fetch_ssl_fc_unique_id(const struct arg *args, struct sample *smp, const char *kw, void *private)
David Sc1ad52e2014-04-08 18:48:47 -04004829{
4830#if OPENSSL_VERSION_NUMBER > 0x0090800fL
Willy Tarreaue237fe12016-03-10 17:05:28 +01004831 struct connection *conn = objt_conn((kw[4] != 'b') ? smp->sess->origin :
4832 smp->strm ? smp->strm->si[1].end : NULL);
4833
David Sc1ad52e2014-04-08 18:48:47 -04004834 int finished_len;
David Sc1ad52e2014-04-08 18:48:47 -04004835 struct chunk *finished_trash;
David Sc1ad52e2014-04-08 18:48:47 -04004836
4837 smp->flags = 0;
David Sc1ad52e2014-04-08 18:48:47 -04004838 if (!conn || !conn->xprt_ctx || conn->xprt != &ssl_sock)
4839 return 0;
4840
4841 if (!(conn->flags & CO_FL_CONNECTED)) {
4842 smp->flags |= SMP_F_MAY_CHANGE;
4843 return 0;
4844 }
4845
4846 finished_trash = get_trash_chunk();
4847 if (!SSL_session_reused(conn->xprt_ctx))
4848 finished_len = SSL_get_peer_finished(conn->xprt_ctx, finished_trash->str, finished_trash->size);
4849 else
4850 finished_len = SSL_get_finished(conn->xprt_ctx, finished_trash->str, finished_trash->size);
4851
4852 if (!finished_len)
4853 return 0;
4854
Emeric Brunb73a9b02014-04-30 18:49:19 +02004855 finished_trash->len = finished_len;
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02004856 smp->data.u.str = *finished_trash;
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02004857 smp->data.type = SMP_T_BIN;
David Sc1ad52e2014-04-08 18:48:47 -04004858
4859 return 1;
4860#else
4861 return 0;
4862#endif
4863}
4864
Emeric Brun2525b6b2012-10-18 15:59:43 +02004865/* integer, returns the first verify error in CA chain of client certificate chain. */
Emeric Brunf282a812012-09-21 15:27:54 +02004866static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02004867smp_fetch_ssl_c_ca_err(const struct arg *args, struct sample *smp, const char *kw, void *private)
Emeric Brunf282a812012-09-21 15:27:54 +02004868{
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004869 struct connection *conn;
4870
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02004871 conn = objt_conn(smp->sess->origin);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004872 if (!conn || conn->xprt != &ssl_sock)
4873 return 0;
4874
4875 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brunf282a812012-09-21 15:27:54 +02004876 smp->flags = SMP_F_MAY_CHANGE;
4877 return 0;
4878 }
4879
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02004880 smp->data.type = SMP_T_SINT;
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02004881 smp->data.u.sint = (unsigned long long int)SSL_SOCK_ST_TO_CA_ERROR(conn->xprt_st);
Emeric Brunf282a812012-09-21 15:27:54 +02004882 smp->flags = 0;
4883
4884 return 1;
4885}
4886
Emeric Brun2525b6b2012-10-18 15:59:43 +02004887/* integer, returns the depth of the first verify error in CA chain of client certificate chain. */
Emeric Brunf282a812012-09-21 15:27:54 +02004888static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02004889smp_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 +02004890{
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004891 struct connection *conn;
4892
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02004893 conn = objt_conn(smp->sess->origin);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004894 if (!conn || conn->xprt != &ssl_sock)
Emeric Brunf282a812012-09-21 15:27:54 +02004895 return 0;
4896
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004897 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brunf282a812012-09-21 15:27:54 +02004898 smp->flags = SMP_F_MAY_CHANGE;
4899 return 0;
4900 }
4901
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02004902 smp->data.type = SMP_T_SINT;
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02004903 smp->data.u.sint = (long long int)SSL_SOCK_ST_TO_CAEDEPTH(conn->xprt_st);
Emeric Brunf282a812012-09-21 15:27:54 +02004904 smp->flags = 0;
4905
4906 return 1;
4907}
4908
Emeric Brun2525b6b2012-10-18 15:59:43 +02004909/* integer, returns the first verify error on client certificate */
Emeric Brunf282a812012-09-21 15:27:54 +02004910static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02004911smp_fetch_ssl_c_err(const struct arg *args, struct sample *smp, const char *kw, void *private)
Emeric Brunf282a812012-09-21 15:27:54 +02004912{
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004913 struct connection *conn;
4914
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02004915 conn = objt_conn(smp->sess->origin);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004916 if (!conn || conn->xprt != &ssl_sock)
4917 return 0;
4918
4919 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brunf282a812012-09-21 15:27:54 +02004920 smp->flags = SMP_F_MAY_CHANGE;
4921 return 0;
4922 }
4923
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02004924 smp->data.type = SMP_T_SINT;
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02004925 smp->data.u.sint = (long long int)SSL_SOCK_ST_TO_CRTERROR(conn->xprt_st);
Emeric Brunf282a812012-09-21 15:27:54 +02004926 smp->flags = 0;
4927
4928 return 1;
4929}
4930
Emeric Brun2525b6b2012-10-18 15:59:43 +02004931/* integer, returns the verify result on client cert */
Emeric Brunbaf8ffb2012-09-21 15:27:20 +02004932static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02004933smp_fetch_ssl_c_verify(const struct arg *args, struct sample *smp, const char *kw, void *private)
Emeric Brunbaf8ffb2012-09-21 15:27:20 +02004934{
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004935 struct connection *conn;
4936
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02004937 conn = objt_conn(smp->sess->origin);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004938 if (!conn || conn->xprt != &ssl_sock)
4939 return 0;
4940
4941 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brunbaf8ffb2012-09-21 15:27:20 +02004942 smp->flags = SMP_F_MAY_CHANGE;
4943 return 0;
4944 }
4945
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004946 if (!conn->xprt_ctx)
Emeric Brunbaf8ffb2012-09-21 15:27:20 +02004947 return 0;
4948
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02004949 smp->data.type = SMP_T_SINT;
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02004950 smp->data.u.sint = (long long int)SSL_get_verify_result(conn->xprt_ctx);
Emeric Brunbaf8ffb2012-09-21 15:27:20 +02004951 smp->flags = 0;
4952
4953 return 1;
4954}
4955
Emeric Brunfb510ea2012-10-05 12:00:26 +02004956/* parse the "ca-file" bind keyword */
4957static 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 +02004958{
4959 if (!*args[cur_arg + 1]) {
4960 if (err)
4961 memprintf(err, "'%s' : missing CAfile path", args[cur_arg]);
4962 return ERR_ALERT | ERR_FATAL;
4963 }
4964
Emeric Brunef42d922012-10-11 16:11:36 +02004965 if ((*args[cur_arg + 1] != '/') && global.ca_base)
4966 memprintf(&conf->ca_file, "%s/%s", global.ca_base, args[cur_arg + 1]);
4967 else
4968 memprintf(&conf->ca_file, "%s", args[cur_arg + 1]);
Emeric Brunc8e8d122012-10-02 18:42:10 +02004969
Emeric Brund94b3fe2012-09-20 18:23:56 +02004970 return 0;
4971}
4972
Christopher Faulet31af49d2015-06-09 17:29:50 +02004973/* parse the "ca-sign-file" bind keyword */
4974static int bind_parse_ca_sign_file(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
4975{
4976 if (!*args[cur_arg + 1]) {
4977 if (err)
4978 memprintf(err, "'%s' : missing CAfile path", args[cur_arg]);
4979 return ERR_ALERT | ERR_FATAL;
4980 }
4981
4982 if ((*args[cur_arg + 1] != '/') && global.ca_base)
4983 memprintf(&conf->ca_sign_file, "%s/%s", global.ca_base, args[cur_arg + 1]);
4984 else
4985 memprintf(&conf->ca_sign_file, "%s", args[cur_arg + 1]);
4986
4987 return 0;
4988}
4989
4990/* parse the ca-sign-pass bind keyword */
4991
4992static int bind_parse_ca_sign_pass(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
4993{
4994 if (!*args[cur_arg + 1]) {
4995 if (err)
4996 memprintf(err, "'%s' : missing CAkey password", args[cur_arg]);
4997 return ERR_ALERT | ERR_FATAL;
4998 }
4999 memprintf(&conf->ca_sign_pass, "%s", args[cur_arg + 1]);
5000 return 0;
5001}
5002
Willy Tarreau79eeafa2012-09-14 07:53:05 +02005003/* parse the "ciphers" bind keyword */
Willy Tarreau4348fad2012-09-20 16:48:07 +02005004static 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 +02005005{
5006 if (!*args[cur_arg + 1]) {
Willy Tarreaueb6cead2012-09-20 19:43:14 +02005007 memprintf(err, "'%s' : missing cipher suite", args[cur_arg]);
Willy Tarreau79eeafa2012-09-14 07:53:05 +02005008 return ERR_ALERT | ERR_FATAL;
5009 }
5010
Emeric Brun76d88952012-10-05 15:47:31 +02005011 free(conf->ciphers);
Willy Tarreau4348fad2012-09-20 16:48:07 +02005012 conf->ciphers = strdup(args[cur_arg + 1]);
Willy Tarreau79eeafa2012-09-14 07:53:05 +02005013 return 0;
5014}
5015
5016/* parse the "crt" bind keyword */
Willy Tarreau4348fad2012-09-20 16:48:07 +02005017static 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 +02005018{
Willy Tarreau38011032013-08-13 16:59:39 +02005019 char path[MAXPATHLEN];
Willy Tarreaub75d6922014-04-14 18:05:41 +02005020
Willy Tarreau79eeafa2012-09-14 07:53:05 +02005021 if (!*args[cur_arg + 1]) {
Willy Tarreaueb6cead2012-09-20 19:43:14 +02005022 memprintf(err, "'%s' : missing certificate location", args[cur_arg]);
Willy Tarreau79eeafa2012-09-14 07:53:05 +02005023 return ERR_ALERT | ERR_FATAL;
5024 }
5025
Emeric Brunc8e8d122012-10-02 18:42:10 +02005026 if ((*args[cur_arg + 1] != '/' ) && global.crt_base) {
Willy Tarreau38011032013-08-13 16:59:39 +02005027 if ((strlen(global.crt_base) + 1 + strlen(args[cur_arg + 1]) + 1) > MAXPATHLEN) {
Emeric Brunc8e8d122012-10-02 18:42:10 +02005028 memprintf(err, "'%s' : path too long", args[cur_arg]);
5029 return ERR_ALERT | ERR_FATAL;
5030 }
Willy Tarreaub75d6922014-04-14 18:05:41 +02005031 snprintf(path, sizeof(path), "%s/%s", global.crt_base, args[cur_arg + 1]);
Emeric Brunc8e8d122012-10-02 18:42:10 +02005032 if (ssl_sock_load_cert(path, conf, px, err) > 0)
5033 return ERR_ALERT | ERR_FATAL;
5034
5035 return 0;
5036 }
5037
Willy Tarreau4348fad2012-09-20 16:48:07 +02005038 if (ssl_sock_load_cert(args[cur_arg + 1], conf, px, err) > 0)
Willy Tarreau79eeafa2012-09-14 07:53:05 +02005039 return ERR_ALERT | ERR_FATAL;
Emeric Brund94b3fe2012-09-20 18:23:56 +02005040
5041 return 0;
5042}
5043
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01005044/* parse the "crt-list" bind keyword */
5045static int bind_parse_crt_list(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
5046{
5047 if (!*args[cur_arg + 1]) {
5048 memprintf(err, "'%s' : missing certificate location", args[cur_arg]);
5049 return ERR_ALERT | ERR_FATAL;
5050 }
5051
Willy Tarreauad1731d2013-04-02 17:35:58 +02005052 if (ssl_sock_load_cert_list_file(args[cur_arg + 1], conf, px, err) > 0) {
5053 memprintf(err, "'%s' : %s", args[cur_arg], *err);
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01005054 return ERR_ALERT | ERR_FATAL;
Willy Tarreauad1731d2013-04-02 17:35:58 +02005055 }
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01005056
5057 return 0;
5058}
5059
Emeric Brunfb510ea2012-10-05 12:00:26 +02005060/* parse the "crl-file" bind keyword */
5061static 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 +02005062{
Emeric Brun051cdab2012-10-02 19:25:50 +02005063#ifndef X509_V_FLAG_CRL_CHECK
5064 if (err)
5065 memprintf(err, "'%s' : library does not support CRL verify", args[cur_arg]);
5066 return ERR_ALERT | ERR_FATAL;
5067#else
Emeric Brund94b3fe2012-09-20 18:23:56 +02005068 if (!*args[cur_arg + 1]) {
5069 if (err)
5070 memprintf(err, "'%s' : missing CRLfile path", args[cur_arg]);
5071 return ERR_ALERT | ERR_FATAL;
5072 }
Emeric Brun2b58d042012-09-20 17:10:03 +02005073
Emeric Brunef42d922012-10-11 16:11:36 +02005074 if ((*args[cur_arg + 1] != '/') && global.ca_base)
5075 memprintf(&conf->crl_file, "%s/%s", global.ca_base, args[cur_arg + 1]);
5076 else
5077 memprintf(&conf->crl_file, "%s", args[cur_arg + 1]);
Emeric Brunc8e8d122012-10-02 18:42:10 +02005078
Emeric Brun2b58d042012-09-20 17:10:03 +02005079 return 0;
Emeric Brun051cdab2012-10-02 19:25:50 +02005080#endif
Emeric Brun2b58d042012-09-20 17:10:03 +02005081}
5082
5083/* parse the "ecdhe" bind keyword keywords */
5084static int bind_parse_ecdhe(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
5085{
5086#if OPENSSL_VERSION_NUMBER < 0x0090800fL
5087 if (err)
5088 memprintf(err, "'%s' : library does not support elliptic curve Diffie-Hellman (too old)", args[cur_arg]);
5089 return ERR_ALERT | ERR_FATAL;
5090#elif defined(OPENSSL_NO_ECDH)
5091 if (err)
5092 memprintf(err, "'%s' : library does not support elliptic curve Diffie-Hellman (disabled via OPENSSL_NO_ECDH)", args[cur_arg]);
5093 return ERR_ALERT | ERR_FATAL;
5094#else
5095 if (!*args[cur_arg + 1]) {
5096 if (err)
5097 memprintf(err, "'%s' : missing named curve", args[cur_arg]);
5098 return ERR_ALERT | ERR_FATAL;
5099 }
5100
5101 conf->ecdhe = strdup(args[cur_arg + 1]);
Willy Tarreau79eeafa2012-09-14 07:53:05 +02005102
5103 return 0;
Emeric Brun2b58d042012-09-20 17:10:03 +02005104#endif
Willy Tarreau79eeafa2012-09-14 07:53:05 +02005105}
5106
Emeric Brun81c00f02012-09-21 14:31:21 +02005107/* parse the "crt_ignerr" and "ca_ignerr" bind keywords */
5108static int bind_parse_ignore_err(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
5109{
5110 int code;
5111 char *p = args[cur_arg + 1];
5112 unsigned long long *ignerr = &conf->crt_ignerr;
5113
5114 if (!*p) {
5115 if (err)
5116 memprintf(err, "'%s' : missing error IDs list", args[cur_arg]);
5117 return ERR_ALERT | ERR_FATAL;
5118 }
5119
5120 if (strcmp(args[cur_arg], "ca-ignore-err") == 0)
5121 ignerr = &conf->ca_ignerr;
5122
5123 if (strcmp(p, "all") == 0) {
5124 *ignerr = ~0ULL;
5125 return 0;
5126 }
5127
5128 while (p) {
5129 code = atoi(p);
5130 if ((code <= 0) || (code > 63)) {
5131 if (err)
5132 memprintf(err, "'%s' : ID '%d' out of range (1..63) in error IDs list '%s'",
5133 args[cur_arg], code, args[cur_arg + 1]);
5134 return ERR_ALERT | ERR_FATAL;
5135 }
5136 *ignerr |= 1ULL << code;
5137 p = strchr(p, ',');
5138 if (p)
5139 p++;
5140 }
5141
Emeric Brun2cb7ae52012-10-05 14:14:21 +02005142 return 0;
5143}
5144
5145/* parse the "force-sslv3" bind keyword */
5146static int bind_parse_force_sslv3(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
5147{
5148 conf->ssl_options |= BC_SSL_O_USE_SSLV3;
5149 return 0;
5150}
5151
5152/* parse the "force-tlsv10" bind keyword */
5153static int bind_parse_force_tlsv10(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
5154{
5155 conf->ssl_options |= BC_SSL_O_USE_TLSV10;
Emeric Brun2d0c4822012-10-02 13:45:20 +02005156 return 0;
5157}
5158
Emeric Brun2cb7ae52012-10-05 14:14:21 +02005159/* parse the "force-tlsv11" bind keyword */
5160static int bind_parse_force_tlsv11(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
5161{
5162#if SSL_OP_NO_TLSv1_1
5163 conf->ssl_options |= BC_SSL_O_USE_TLSV11;
5164 return 0;
5165#else
5166 if (err)
5167 memprintf(err, "'%s' : library does not support protocol TLSv1.1", args[cur_arg]);
5168 return ERR_ALERT | ERR_FATAL;
5169#endif
5170}
5171
5172/* parse the "force-tlsv12" bind keyword */
5173static int bind_parse_force_tlsv12(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
5174{
5175#if SSL_OP_NO_TLSv1_2
5176 conf->ssl_options |= BC_SSL_O_USE_TLSV12;
5177 return 0;
5178#else
5179 if (err)
5180 memprintf(err, "'%s' : library does not support protocol TLSv1.2", args[cur_arg]);
5181 return ERR_ALERT | ERR_FATAL;
5182#endif
5183}
5184
5185
Emeric Brun2d0c4822012-10-02 13:45:20 +02005186/* parse the "no-tls-tickets" bind keyword */
5187static int bind_parse_no_tls_tickets(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
5188{
Emeric Brun89675492012-10-05 13:48:26 +02005189 conf->ssl_options |= BC_SSL_O_NO_TLS_TICKETS;
Emeric Brun81c00f02012-09-21 14:31:21 +02005190 return 0;
5191}
5192
Emeric Brun2d0c4822012-10-02 13:45:20 +02005193
Emeric Brun9b3009b2012-10-05 11:55:06 +02005194/* parse the "no-sslv3" bind keyword */
5195static 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 +02005196{
Emeric Brun89675492012-10-05 13:48:26 +02005197 conf->ssl_options |= BC_SSL_O_NO_SSLV3;
Willy Tarreau79eeafa2012-09-14 07:53:05 +02005198 return 0;
5199}
5200
Emeric Brun9b3009b2012-10-05 11:55:06 +02005201/* parse the "no-tlsv10" bind keyword */
5202static 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 +02005203{
Emeric Brun89675492012-10-05 13:48:26 +02005204 conf->ssl_options |= BC_SSL_O_NO_TLSV10;
Emeric Brunc0ff4922012-09-28 19:37:02 +02005205 return 0;
5206}
5207
Emeric Brun9b3009b2012-10-05 11:55:06 +02005208/* parse the "no-tlsv11" bind keyword */
5209static 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 +02005210{
Emeric Brun89675492012-10-05 13:48:26 +02005211 conf->ssl_options |= BC_SSL_O_NO_TLSV11;
Emeric Brunc0ff4922012-09-28 19:37:02 +02005212 return 0;
5213}
5214
Emeric Brun9b3009b2012-10-05 11:55:06 +02005215/* parse the "no-tlsv12" bind keyword */
5216static 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 +02005217{
Emeric Brun89675492012-10-05 13:48:26 +02005218 conf->ssl_options |= BC_SSL_O_NO_TLSV12;
Willy Tarreau79eeafa2012-09-14 07:53:05 +02005219 return 0;
5220}
5221
Willy Tarreau6c9a3d52012-10-18 18:57:14 +02005222/* parse the "npn" bind keyword */
5223static int bind_parse_npn(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
5224{
5225#ifdef OPENSSL_NPN_NEGOTIATED
5226 char *p1, *p2;
5227
5228 if (!*args[cur_arg + 1]) {
5229 memprintf(err, "'%s' : missing the comma-delimited NPN protocol suite", args[cur_arg]);
5230 return ERR_ALERT | ERR_FATAL;
5231 }
5232
5233 free(conf->npn_str);
5234
Willy Tarreau3724da12016-02-12 17:11:12 +01005235 /* the NPN string is built as a suite of (<len> <name>)*,
5236 * so we reuse each comma to store the next <len> and need
5237 * one more for the end of the string.
5238 */
Willy Tarreau6c9a3d52012-10-18 18:57:14 +02005239 conf->npn_len = strlen(args[cur_arg + 1]) + 1;
Willy Tarreau3724da12016-02-12 17:11:12 +01005240 conf->npn_str = calloc(1, conf->npn_len + 1);
Willy Tarreau6c9a3d52012-10-18 18:57:14 +02005241 memcpy(conf->npn_str + 1, args[cur_arg + 1], conf->npn_len);
5242
5243 /* replace commas with the name length */
5244 p1 = conf->npn_str;
5245 p2 = p1 + 1;
5246 while (1) {
5247 p2 = memchr(p1 + 1, ',', conf->npn_str + conf->npn_len - (p1 + 1));
5248 if (!p2)
5249 p2 = p1 + 1 + strlen(p1 + 1);
5250
5251 if (p2 - (p1 + 1) > 255) {
5252 *p2 = '\0';
5253 memprintf(err, "'%s' : NPN protocol name too long : '%s'", args[cur_arg], p1 + 1);
5254 return ERR_ALERT | ERR_FATAL;
5255 }
5256
5257 *p1 = p2 - (p1 + 1);
5258 p1 = p2;
5259
5260 if (!*p2)
5261 break;
5262
5263 *(p2++) = '\0';
5264 }
5265 return 0;
5266#else
5267 if (err)
5268 memprintf(err, "'%s' : library does not support TLS NPN extension", args[cur_arg]);
5269 return ERR_ALERT | ERR_FATAL;
5270#endif
5271}
5272
Willy Tarreauab861d32013-04-02 02:30:41 +02005273/* parse the "alpn" bind keyword */
5274static int bind_parse_alpn(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
5275{
Dirkjan Bussink48f1c4e2014-02-13 12:29:42 +01005276#ifdef TLSEXT_TYPE_application_layer_protocol_negotiation
Willy Tarreauab861d32013-04-02 02:30:41 +02005277 char *p1, *p2;
5278
5279 if (!*args[cur_arg + 1]) {
5280 memprintf(err, "'%s' : missing the comma-delimited ALPN protocol suite", args[cur_arg]);
5281 return ERR_ALERT | ERR_FATAL;
5282 }
5283
5284 free(conf->alpn_str);
5285
Marcoen Hirschbergbef60912016-02-12 17:05:24 +01005286 /* the ALPN string is built as a suite of (<len> <name>)*,
5287 * so we reuse each comma to store the next <len> and need
5288 * one more for the end of the string.
5289 */
Willy Tarreauab861d32013-04-02 02:30:41 +02005290 conf->alpn_len = strlen(args[cur_arg + 1]) + 1;
Marcoen Hirschbergbef60912016-02-12 17:05:24 +01005291 conf->alpn_str = calloc(1, conf->alpn_len + 1);
Willy Tarreauab861d32013-04-02 02:30:41 +02005292 memcpy(conf->alpn_str + 1, args[cur_arg + 1], conf->alpn_len);
5293
5294 /* replace commas with the name length */
5295 p1 = conf->alpn_str;
5296 p2 = p1 + 1;
5297 while (1) {
5298 p2 = memchr(p1 + 1, ',', conf->alpn_str + conf->alpn_len - (p1 + 1));
5299 if (!p2)
5300 p2 = p1 + 1 + strlen(p1 + 1);
5301
5302 if (p2 - (p1 + 1) > 255) {
5303 *p2 = '\0';
5304 memprintf(err, "'%s' : ALPN protocol name too long : '%s'", args[cur_arg], p1 + 1);
5305 return ERR_ALERT | ERR_FATAL;
5306 }
5307
5308 *p1 = p2 - (p1 + 1);
5309 p1 = p2;
5310
5311 if (!*p2)
5312 break;
5313
5314 *(p2++) = '\0';
5315 }
5316 return 0;
5317#else
5318 if (err)
5319 memprintf(err, "'%s' : library does not support TLS ALPN extension", args[cur_arg]);
5320 return ERR_ALERT | ERR_FATAL;
5321#endif
5322}
5323
Willy Tarreau79eeafa2012-09-14 07:53:05 +02005324/* parse the "ssl" bind keyword */
Willy Tarreau4348fad2012-09-20 16:48:07 +02005325static 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 +02005326{
Willy Tarreau81796be2012-09-22 19:11:47 +02005327 struct listener *l;
5328
Willy Tarreau4348fad2012-09-20 16:48:07 +02005329 conf->is_ssl = 1;
Emeric Brun76d88952012-10-05 15:47:31 +02005330
5331 if (global.listen_default_ciphers && !conf->ciphers)
5332 conf->ciphers = strdup(global.listen_default_ciphers);
Emeric Brun2c86cbf2014-10-30 15:56:50 +01005333 conf->ssl_options |= global.listen_default_ssloptions;
Emeric Brun76d88952012-10-05 15:47:31 +02005334
Willy Tarreau81796be2012-09-22 19:11:47 +02005335 list_for_each_entry(l, &conf->listeners, by_bind)
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02005336 l->xprt = &ssl_sock;
Willy Tarreau81796be2012-09-22 19:11:47 +02005337
Willy Tarreau79eeafa2012-09-14 07:53:05 +02005338 return 0;
5339}
5340
Christopher Faulet31af49d2015-06-09 17:29:50 +02005341/* parse the "generate-certificates" bind keyword */
5342static int bind_parse_generate_certs(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
5343{
5344#ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME
5345 conf->generate_certs = 1;
5346#else
5347 memprintf(err, "%sthis version of openssl cannot generate SSL certificates.\n",
5348 err && *err ? *err : "");
5349#endif
5350 return 0;
5351}
5352
Emmanuel Hocdet65623372013-01-24 17:17:15 +01005353/* parse the "strict-sni" bind keyword */
5354static int bind_parse_strict_sni(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
5355{
5356 conf->strict_sni = 1;
5357 return 0;
Nenad Merdanovic05552d42015-02-27 19:56:49 +01005358}
5359
5360/* parse the "tls-ticket-keys" bind keyword */
5361static int bind_parse_tls_ticket_keys(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
5362{
5363#if (defined SSL_CTRL_SET_TLSEXT_TICKET_KEY_CB && TLS_TICKETS_NO > 0)
5364 FILE *f;
5365 int i = 0;
5366 char thisline[LINESIZE];
Nenad Merdanovic146defa2015-05-09 08:46:00 +02005367 struct tls_keys_ref *keys_ref;
Nenad Merdanovic05552d42015-02-27 19:56:49 +01005368
5369 if (!*args[cur_arg + 1]) {
5370 if (err)
5371 memprintf(err, "'%s' : missing TLS ticket keys file path", args[cur_arg]);
5372 return ERR_ALERT | ERR_FATAL;
5373 }
5374
Nenad Merdanovic200b0fa2015-05-09 08:46:01 +02005375 keys_ref = tlskeys_ref_lookup(args[cur_arg + 1]);
5376 if(keys_ref) {
5377 conf->keys_ref = keys_ref;
5378 return 0;
5379 }
5380
Vincent Bernat02779b62016-04-03 13:48:43 +02005381 keys_ref = malloc(sizeof(*keys_ref));
Nenad Merdanovic146defa2015-05-09 08:46:00 +02005382 keys_ref->tlskeys = malloc(TLS_TICKETS_NO * sizeof(struct tls_sess_key));
Nenad Merdanovic05552d42015-02-27 19:56:49 +01005383
5384 if ((f = fopen(args[cur_arg + 1], "r")) == NULL) {
5385 if (err)
5386 memprintf(err, "'%s' : unable to load ssl tickets keys file", args[cur_arg+1]);
5387 return ERR_ALERT | ERR_FATAL;
5388 }
5389
Nenad Merdanovic146defa2015-05-09 08:46:00 +02005390 keys_ref->filename = strdup(args[cur_arg + 1]);
5391
Nenad Merdanovic05552d42015-02-27 19:56:49 +01005392 while (fgets(thisline, sizeof(thisline), f) != NULL) {
5393 int len = strlen(thisline);
5394 /* Strip newline characters from the end */
5395 if(thisline[len - 1] == '\n')
5396 thisline[--len] = 0;
5397
5398 if(thisline[len - 1] == '\r')
5399 thisline[--len] = 0;
5400
Nenad Merdanovic146defa2015-05-09 08:46:00 +02005401 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 +01005402 if (err)
5403 memprintf(err, "'%s' : unable to decode base64 key on line %d", args[cur_arg+1], i + 1);
5404 return ERR_ALERT | ERR_FATAL;
5405 }
5406 i++;
5407 }
5408
5409 if (i < TLS_TICKETS_NO) {
5410 if (err)
5411 memprintf(err, "'%s' : please supply at least %d keys in the tls-tickets-file", args[cur_arg+1], TLS_TICKETS_NO);
5412 return ERR_ALERT | ERR_FATAL;
5413 }
5414
5415 fclose(f);
5416
5417 /* Use penultimate key for encryption, handle when TLS_TICKETS_NO = 1 */
Nenad Merdanovic17891152016-03-25 22:16:57 +01005418 i -= 2;
5419 keys_ref->tls_ticket_enc_index = i < 0 ? 0 : i % TLS_TICKETS_NO;
Nenad Merdanovic200b0fa2015-05-09 08:46:01 +02005420 keys_ref->unique_id = -1;
Nenad Merdanovic146defa2015-05-09 08:46:00 +02005421 conf->keys_ref = keys_ref;
Nenad Merdanovic05552d42015-02-27 19:56:49 +01005422
Nenad Merdanovic200b0fa2015-05-09 08:46:01 +02005423 LIST_ADD(&tlskeys_reference, &keys_ref->list);
5424
Nenad Merdanovic05552d42015-02-27 19:56:49 +01005425 return 0;
5426#else
5427 if (err)
5428 memprintf(err, "'%s' : TLS ticket callback extension not supported", args[cur_arg]);
5429 return ERR_ALERT | ERR_FATAL;
5430#endif /* SSL_CTRL_SET_TLSEXT_TICKET_KEY_CB */
Emmanuel Hocdet65623372013-01-24 17:17:15 +01005431}
5432
Emeric Brund94b3fe2012-09-20 18:23:56 +02005433/* parse the "verify" bind keyword */
5434static int bind_parse_verify(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
5435{
5436 if (!*args[cur_arg + 1]) {
5437 if (err)
5438 memprintf(err, "'%s' : missing verify method", args[cur_arg]);
5439 return ERR_ALERT | ERR_FATAL;
5440 }
5441
5442 if (strcmp(args[cur_arg + 1], "none") == 0)
Emeric Brun850efd52014-01-29 12:24:34 +01005443 conf->verify = SSL_SOCK_VERIFY_NONE;
Emeric Brund94b3fe2012-09-20 18:23:56 +02005444 else if (strcmp(args[cur_arg + 1], "optional") == 0)
Emeric Brun850efd52014-01-29 12:24:34 +01005445 conf->verify = SSL_SOCK_VERIFY_OPTIONAL;
Emeric Brund94b3fe2012-09-20 18:23:56 +02005446 else if (strcmp(args[cur_arg + 1], "required") == 0)
Emeric Brun850efd52014-01-29 12:24:34 +01005447 conf->verify = SSL_SOCK_VERIFY_REQUIRED;
Emeric Brund94b3fe2012-09-20 18:23:56 +02005448 else {
5449 if (err)
5450 memprintf(err, "'%s' : unknown verify method '%s', only 'none', 'optional', and 'required' are supported\n",
5451 args[cur_arg], args[cur_arg + 1]);
5452 return ERR_ALERT | ERR_FATAL;
5453 }
5454
5455 return 0;
5456}
5457
Willy Tarreau92faadf2012-10-10 23:04:25 +02005458/************** "server" keywords ****************/
5459
Emeric Brunef42d922012-10-11 16:11:36 +02005460/* parse the "ca-file" server keyword */
5461static int srv_parse_ca_file(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
5462{
5463 if (!*args[*cur_arg + 1]) {
5464 if (err)
5465 memprintf(err, "'%s' : missing CAfile path", args[*cur_arg]);
5466 return ERR_ALERT | ERR_FATAL;
5467 }
5468
5469 if ((*args[*cur_arg + 1] != '/') && global.ca_base)
5470 memprintf(&newsrv->ssl_ctx.ca_file, "%s/%s", global.ca_base, args[*cur_arg + 1]);
5471 else
5472 memprintf(&newsrv->ssl_ctx.ca_file, "%s", args[*cur_arg + 1]);
5473
5474 return 0;
5475}
5476
Willy Tarreau92faadf2012-10-10 23:04:25 +02005477/* parse the "check-ssl" server keyword */
5478static int srv_parse_check_ssl(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
5479{
5480 newsrv->check.use_ssl = 1;
5481 if (global.connect_default_ciphers && !newsrv->ssl_ctx.ciphers)
5482 newsrv->ssl_ctx.ciphers = strdup(global.connect_default_ciphers);
Emeric Brun2c86cbf2014-10-30 15:56:50 +01005483 newsrv->ssl_ctx.options |= global.connect_default_ssloptions;
Willy Tarreau92faadf2012-10-10 23:04:25 +02005484 return 0;
5485}
5486
5487/* parse the "ciphers" server keyword */
5488static int srv_parse_ciphers(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
5489{
5490 if (!*args[*cur_arg + 1]) {
5491 memprintf(err, "'%s' : missing cipher suite", args[*cur_arg]);
5492 return ERR_ALERT | ERR_FATAL;
5493 }
5494
5495 free(newsrv->ssl_ctx.ciphers);
5496 newsrv->ssl_ctx.ciphers = strdup(args[*cur_arg + 1]);
5497 return 0;
5498}
5499
Emeric Brunef42d922012-10-11 16:11:36 +02005500/* parse the "crl-file" server keyword */
5501static int srv_parse_crl_file(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
5502{
5503#ifndef X509_V_FLAG_CRL_CHECK
5504 if (err)
5505 memprintf(err, "'%s' : library does not support CRL verify", args[*cur_arg]);
5506 return ERR_ALERT | ERR_FATAL;
5507#else
5508 if (!*args[*cur_arg + 1]) {
5509 if (err)
5510 memprintf(err, "'%s' : missing CRLfile path", args[*cur_arg]);
5511 return ERR_ALERT | ERR_FATAL;
5512 }
5513
5514 if ((*args[*cur_arg + 1] != '/') && global.ca_base)
5515 memprintf(&newsrv->ssl_ctx.crl_file, "%s/%s", global.ca_base, args[*cur_arg + 1]);
5516 else
5517 memprintf(&newsrv->ssl_ctx.crl_file, "%s", args[*cur_arg + 1]);
5518
5519 return 0;
5520#endif
5521}
5522
Emeric Bruna7aa3092012-10-26 12:58:00 +02005523/* parse the "crt" server keyword */
5524static int srv_parse_crt(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
5525{
5526 if (!*args[*cur_arg + 1]) {
5527 if (err)
5528 memprintf(err, "'%s' : missing certificate file path", args[*cur_arg]);
5529 return ERR_ALERT | ERR_FATAL;
5530 }
5531
5532 if ((*args[*cur_arg + 1] != '/') && global.crt_base)
5533 memprintf(&newsrv->ssl_ctx.client_crt, "%s/%s", global.ca_base, args[*cur_arg + 1]);
5534 else
5535 memprintf(&newsrv->ssl_ctx.client_crt, "%s", args[*cur_arg + 1]);
5536
5537 return 0;
5538}
Emeric Brunef42d922012-10-11 16:11:36 +02005539
Willy Tarreau92faadf2012-10-10 23:04:25 +02005540/* parse the "force-sslv3" server keyword */
5541static int srv_parse_force_sslv3(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
5542{
5543 newsrv->ssl_ctx.options |= SRV_SSL_O_USE_SSLV3;
5544 return 0;
5545}
5546
5547/* parse the "force-tlsv10" server keyword */
5548static int srv_parse_force_tlsv10(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
5549{
5550 newsrv->ssl_ctx.options |= SRV_SSL_O_USE_TLSV10;
5551 return 0;
5552}
5553
5554/* parse the "force-tlsv11" server keyword */
5555static int srv_parse_force_tlsv11(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
5556{
5557#if SSL_OP_NO_TLSv1_1
5558 newsrv->ssl_ctx.options |= SRV_SSL_O_USE_TLSV11;
5559 return 0;
5560#else
5561 if (err)
5562 memprintf(err, "'%s' : library does not support protocol TLSv1.1", args[*cur_arg]);
5563 return ERR_ALERT | ERR_FATAL;
5564#endif
5565}
5566
5567/* parse the "force-tlsv12" server keyword */
5568static int srv_parse_force_tlsv12(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
5569{
5570#if SSL_OP_NO_TLSv1_2
5571 newsrv->ssl_ctx.options |= SRV_SSL_O_USE_TLSV12;
5572 return 0;
5573#else
5574 if (err)
5575 memprintf(err, "'%s' : library does not support protocol TLSv1.2", args[*cur_arg]);
5576 return ERR_ALERT | ERR_FATAL;
5577#endif
5578}
5579
Willy Tarreau2a3fb1c2015-02-05 16:47:07 +01005580/* parse the "no-ssl-reuse" server keyword */
5581static int srv_parse_no_ssl_reuse(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
5582{
5583 newsrv->ssl_ctx.options |= SRV_SSL_O_NO_REUSE;
5584 return 0;
5585}
5586
Willy Tarreau92faadf2012-10-10 23:04:25 +02005587/* parse the "no-sslv3" server keyword */
5588static int srv_parse_no_sslv3(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
5589{
5590 newsrv->ssl_ctx.options |= SRV_SSL_O_NO_SSLV3;
5591 return 0;
5592}
5593
5594/* parse the "no-tlsv10" server keyword */
5595static int srv_parse_no_tlsv10(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
5596{
5597 newsrv->ssl_ctx.options |= SRV_SSL_O_NO_TLSV10;
5598 return 0;
5599}
5600
5601/* parse the "no-tlsv11" server keyword */
5602static int srv_parse_no_tlsv11(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
5603{
5604 newsrv->ssl_ctx.options |= SRV_SSL_O_NO_TLSV11;
5605 return 0;
5606}
5607
5608/* parse the "no-tlsv12" server keyword */
5609static int srv_parse_no_tlsv12(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
5610{
5611 newsrv->ssl_ctx.options |= SRV_SSL_O_NO_TLSV12;
5612 return 0;
5613}
5614
Emeric Brunf9c5c472012-10-11 15:28:34 +02005615/* parse the "no-tls-tickets" server keyword */
5616static int srv_parse_no_tls_tickets(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
5617{
5618 newsrv->ssl_ctx.options |= SRV_SSL_O_NO_TLS_TICKETS;
5619 return 0;
5620}
David Safb76832014-05-08 23:42:08 -04005621/* parse the "send-proxy-v2-ssl" server keyword */
5622static int srv_parse_send_proxy_ssl(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
5623{
5624 newsrv->pp_opts |= SRV_PP_V2;
5625 newsrv->pp_opts |= SRV_PP_V2_SSL;
5626 return 0;
5627}
5628
5629/* parse the "send-proxy-v2-ssl-cn" server keyword */
5630static int srv_parse_send_proxy_cn(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
5631{
5632 newsrv->pp_opts |= SRV_PP_V2;
5633 newsrv->pp_opts |= SRV_PP_V2_SSL;
5634 newsrv->pp_opts |= SRV_PP_V2_SSL_CN;
5635 return 0;
5636}
Emeric Brunf9c5c472012-10-11 15:28:34 +02005637
Willy Tarreau732eac42015-07-09 11:40:25 +02005638/* parse the "sni" server keyword */
5639static int srv_parse_sni(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
5640{
5641#ifndef SSL_CTRL_SET_TLSEXT_HOSTNAME
5642 memprintf(err, "'%s' : the current SSL library doesn't support the SNI TLS extension", args[*cur_arg]);
5643 return ERR_ALERT | ERR_FATAL;
5644#else
Cyril Bonté23d19d62016-03-07 22:13:22 +01005645 int idx;
Willy Tarreau732eac42015-07-09 11:40:25 +02005646 struct sample_expr *expr;
5647
5648 if (!*args[*cur_arg + 1]) {
5649 memprintf(err, "'%s' : missing sni expression", args[*cur_arg]);
5650 return ERR_ALERT | ERR_FATAL;
5651 }
5652
Cyril Bonté23d19d62016-03-07 22:13:22 +01005653 idx = (*cur_arg) + 1;
Willy Tarreau732eac42015-07-09 11:40:25 +02005654 proxy->conf.args.ctx = ARGC_SRV;
5655
Cyril Bonté23d19d62016-03-07 22:13:22 +01005656 expr = sample_parse_expr((char **)args, &idx, px->conf.file, px->conf.line, err, &proxy->conf.args);
Willy Tarreau732eac42015-07-09 11:40:25 +02005657 if (!expr) {
5658 memprintf(err, "error detected while parsing sni expression : %s", *err);
5659 return ERR_ALERT | ERR_FATAL;
5660 }
5661
5662 if (!(expr->fetch->val & SMP_VAL_BE_SRV_CON)) {
5663 memprintf(err, "error detected while parsing sni expression : "
5664 " fetch method '%s' extracts information from '%s', none of which is available here.\n",
Cyril Bonté23d19d62016-03-07 22:13:22 +01005665 args[idx-1], sample_src_names(expr->fetch->use));
Willy Tarreau732eac42015-07-09 11:40:25 +02005666 return ERR_ALERT | ERR_FATAL;
5667 }
5668
5669 px->http_needed |= !!(expr->fetch->use & SMP_USE_HTTP_ANY);
5670 newsrv->ssl_ctx.sni = expr;
5671 return 0;
5672#endif
5673}
5674
Willy Tarreau92faadf2012-10-10 23:04:25 +02005675/* parse the "ssl" server keyword */
5676static int srv_parse_ssl(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
5677{
5678 newsrv->use_ssl = 1;
5679 if (global.connect_default_ciphers && !newsrv->ssl_ctx.ciphers)
5680 newsrv->ssl_ctx.ciphers = strdup(global.connect_default_ciphers);
5681 return 0;
5682}
5683
Emeric Brunef42d922012-10-11 16:11:36 +02005684/* parse the "verify" server keyword */
5685static int srv_parse_verify(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
5686{
5687 if (!*args[*cur_arg + 1]) {
5688 if (err)
5689 memprintf(err, "'%s' : missing verify method", args[*cur_arg]);
5690 return ERR_ALERT | ERR_FATAL;
5691 }
5692
5693 if (strcmp(args[*cur_arg + 1], "none") == 0)
Emeric Brun850efd52014-01-29 12:24:34 +01005694 newsrv->ssl_ctx.verify = SSL_SOCK_VERIFY_NONE;
Emeric Brunef42d922012-10-11 16:11:36 +02005695 else if (strcmp(args[*cur_arg + 1], "required") == 0)
Emeric Brun850efd52014-01-29 12:24:34 +01005696 newsrv->ssl_ctx.verify = SSL_SOCK_VERIFY_REQUIRED;
Emeric Brunef42d922012-10-11 16:11:36 +02005697 else {
5698 if (err)
5699 memprintf(err, "'%s' : unknown verify method '%s', only 'none' and 'required' are supported\n",
5700 args[*cur_arg], args[*cur_arg + 1]);
5701 return ERR_ALERT | ERR_FATAL;
5702 }
5703
Evan Broderbe554312013-06-27 00:05:25 -07005704 return 0;
5705}
5706
5707/* parse the "verifyhost" server keyword */
5708static int srv_parse_verifyhost(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
5709{
5710 if (!*args[*cur_arg + 1]) {
5711 if (err)
5712 memprintf(err, "'%s' : missing hostname to verify against", args[*cur_arg]);
5713 return ERR_ALERT | ERR_FATAL;
5714 }
5715
5716 newsrv->ssl_ctx.verify_host = strdup(args[*cur_arg + 1]);
5717
Emeric Brunef42d922012-10-11 16:11:36 +02005718 return 0;
5719}
5720
Emeric Brun2c86cbf2014-10-30 15:56:50 +01005721/* parse the "ssl-default-bind-options" keyword in global section */
5722static int ssl_parse_default_bind_options(char **args, int section_type, struct proxy *curpx,
5723 struct proxy *defpx, const char *file, int line,
5724 char **err) {
5725 int i = 1;
5726
5727 if (*(args[i]) == 0) {
5728 memprintf(err, "global statement '%s' expects an option as an argument.", args[0]);
5729 return -1;
5730 }
5731 while (*(args[i])) {
5732 if (!strcmp(args[i], "no-sslv3"))
5733 global.listen_default_ssloptions |= BC_SSL_O_NO_SSLV3;
5734 else if (!strcmp(args[i], "no-tlsv10"))
5735 global.listen_default_ssloptions |= BC_SSL_O_NO_TLSV10;
5736 else if (!strcmp(args[i], "no-tlsv11"))
5737 global.listen_default_ssloptions |= BC_SSL_O_NO_TLSV11;
5738 else if (!strcmp(args[i], "no-tlsv12"))
5739 global.listen_default_ssloptions |= BC_SSL_O_NO_TLSV12;
5740 else if (!strcmp(args[i], "force-sslv3"))
5741 global.listen_default_ssloptions |= BC_SSL_O_USE_SSLV3;
5742 else if (!strcmp(args[i], "force-tlsv10"))
5743 global.listen_default_ssloptions |= BC_SSL_O_USE_TLSV10;
5744 else if (!strcmp(args[i], "force-tlsv11")) {
5745#if SSL_OP_NO_TLSv1_1
5746 global.listen_default_ssloptions |= BC_SSL_O_USE_TLSV11;
5747#else
5748 memprintf(err, "'%s' '%s': library does not support protocol TLSv1.1", args[0], args[i]);
5749 return -1;
5750#endif
5751 }
5752 else if (!strcmp(args[i], "force-tlsv12")) {
5753#if SSL_OP_NO_TLSv1_2
5754 global.listen_default_ssloptions |= BC_SSL_O_USE_TLSV12;
5755#else
5756 memprintf(err, "'%s' '%s': library does not support protocol TLSv1.2", args[0], args[i]);
5757 return -1;
5758#endif
5759 }
5760 else if (!strcmp(args[i], "no-tls-tickets"))
5761 global.listen_default_ssloptions |= BC_SSL_O_NO_TLS_TICKETS;
5762 else {
5763 memprintf(err, "unknown option '%s' on global statement '%s'.", args[i], args[0]);
5764 return -1;
5765 }
5766 i++;
5767 }
5768 return 0;
5769}
5770
5771/* parse the "ssl-default-server-options" keyword in global section */
5772static int ssl_parse_default_server_options(char **args, int section_type, struct proxy *curpx,
5773 struct proxy *defpx, const char *file, int line,
5774 char **err) {
5775 int i = 1;
5776
5777 if (*(args[i]) == 0) {
5778 memprintf(err, "global statement '%s' expects an option as an argument.", args[0]);
5779 return -1;
5780 }
5781 while (*(args[i])) {
5782 if (!strcmp(args[i], "no-sslv3"))
5783 global.connect_default_ssloptions |= SRV_SSL_O_NO_SSLV3;
5784 else if (!strcmp(args[i], "no-tlsv10"))
5785 global.connect_default_ssloptions |= SRV_SSL_O_NO_TLSV10;
5786 else if (!strcmp(args[i], "no-tlsv11"))
5787 global.connect_default_ssloptions |= SRV_SSL_O_NO_TLSV11;
5788 else if (!strcmp(args[i], "no-tlsv12"))
5789 global.connect_default_ssloptions |= SRV_SSL_O_NO_TLSV12;
5790 else if (!strcmp(args[i], "force-sslv3"))
5791 global.connect_default_ssloptions |= SRV_SSL_O_USE_SSLV3;
5792 else if (!strcmp(args[i], "force-tlsv10"))
5793 global.connect_default_ssloptions |= SRV_SSL_O_USE_TLSV10;
5794 else if (!strcmp(args[i], "force-tlsv11")) {
5795#if SSL_OP_NO_TLSv1_1
5796 global.connect_default_ssloptions |= SRV_SSL_O_USE_TLSV11;
5797#else
5798 memprintf(err, "'%s' '%s': library does not support protocol TLSv1.1", args[0], args[i]);
5799 return -1;
5800#endif
5801 }
5802 else if (!strcmp(args[i], "force-tlsv12")) {
5803#if SSL_OP_NO_TLSv1_2
5804 global.connect_default_ssloptions |= SRV_SSL_O_USE_TLSV12;
5805#else
5806 memprintf(err, "'%s' '%s': library does not support protocol TLSv1.2", args[0], args[i]);
5807 return -1;
5808#endif
5809 }
5810 else if (!strcmp(args[i], "no-tls-tickets"))
5811 global.connect_default_ssloptions |= SRV_SSL_O_NO_TLS_TICKETS;
5812 else {
5813 memprintf(err, "unknown option '%s' on global statement '%s'.", args[i], args[0]);
5814 return -1;
5815 }
5816 i++;
5817 }
5818 return 0;
5819}
5820
Willy Tarreau7875d092012-09-10 08:20:03 +02005821/* Note: must not be declared <const> as its list will be overwritten.
5822 * Please take care of keeping this list alphabetically sorted.
5823 */
Willy Tarreaudc13c112013-06-21 23:16:39 +02005824static struct sample_fetch_kw_list sample_fetch_keywords = {ILH, {
Emeric Brun645ae792014-04-30 14:21:06 +02005825 { "ssl_bc", smp_fetch_ssl_fc, 0, NULL, SMP_T_BOOL, SMP_USE_L5SRV },
Thierry FOURNIER07ee64e2015-07-06 23:43:03 +02005826 { "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 +02005827 { "ssl_bc_cipher", smp_fetch_ssl_fc_cipher, 0, NULL, SMP_T_STR, SMP_USE_L5SRV },
5828 { "ssl_bc_protocol", smp_fetch_ssl_fc_protocol, 0, NULL, SMP_T_STR, SMP_USE_L5SRV },
Emeric Brunb73a9b02014-04-30 18:49:19 +02005829 { "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 +02005830 { "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 +02005831 { "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 +02005832 { "ssl_c_ca_err", smp_fetch_ssl_c_ca_err, 0, NULL, SMP_T_SINT, SMP_USE_L5CLI },
5833 { "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 +01005834 { "ssl_c_der", smp_fetch_ssl_x_der, 0, NULL, SMP_T_BIN, SMP_USE_L5CLI },
Thierry FOURNIER07ee64e2015-07-06 23:43:03 +02005835 { "ssl_c_err", smp_fetch_ssl_c_err, 0, NULL, SMP_T_SINT, SMP_USE_L5CLI },
Emeric Brunba841a12014-04-30 17:05:08 +02005836 { "ssl_c_i_dn", smp_fetch_ssl_x_i_dn, ARG2(0,STR,SINT), NULL, SMP_T_STR, SMP_USE_L5CLI },
5837 { "ssl_c_key_alg", smp_fetch_ssl_x_key_alg, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
5838 { "ssl_c_notafter", smp_fetch_ssl_x_notafter, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
5839 { "ssl_c_notbefore", smp_fetch_ssl_x_notbefore, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
5840 { "ssl_c_sig_alg", smp_fetch_ssl_x_sig_alg, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
5841 { "ssl_c_s_dn", smp_fetch_ssl_x_s_dn, ARG2(0,STR,SINT), NULL, SMP_T_STR, SMP_USE_L5CLI },
5842 { "ssl_c_serial", smp_fetch_ssl_x_serial, 0, NULL, SMP_T_BIN, SMP_USE_L5CLI },
5843 { "ssl_c_sha1", smp_fetch_ssl_x_sha1, 0, NULL, SMP_T_BIN, SMP_USE_L5CLI },
Willy Tarreau80aca902013-01-07 15:42:20 +01005844 { "ssl_c_used", smp_fetch_ssl_c_used, 0, NULL, SMP_T_BOOL, SMP_USE_L5CLI },
Thierry FOURNIER07ee64e2015-07-06 23:43:03 +02005845 { "ssl_c_verify", smp_fetch_ssl_c_verify, 0, NULL, SMP_T_SINT, SMP_USE_L5CLI },
5846 { "ssl_c_version", smp_fetch_ssl_x_version, 0, NULL, SMP_T_SINT, SMP_USE_L5CLI },
Emeric Brun43e79582014-10-29 19:03:26 +01005847 { "ssl_f_der", smp_fetch_ssl_x_der, 0, NULL, SMP_T_BIN, SMP_USE_L5CLI },
Emeric Brunba841a12014-04-30 17:05:08 +02005848 { "ssl_f_i_dn", smp_fetch_ssl_x_i_dn, ARG2(0,STR,SINT), NULL, SMP_T_STR, SMP_USE_L5CLI },
5849 { "ssl_f_key_alg", smp_fetch_ssl_x_key_alg, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
5850 { "ssl_f_notafter", smp_fetch_ssl_x_notafter, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
5851 { "ssl_f_notbefore", smp_fetch_ssl_x_notbefore, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
5852 { "ssl_f_sig_alg", smp_fetch_ssl_x_sig_alg, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
5853 { "ssl_f_s_dn", smp_fetch_ssl_x_s_dn, ARG2(0,STR,SINT), NULL, SMP_T_STR, SMP_USE_L5CLI },
5854 { "ssl_f_serial", smp_fetch_ssl_x_serial, 0, NULL, SMP_T_BIN, SMP_USE_L5CLI },
Emeric Brun55f4fa82014-04-30 17:11:25 +02005855 { "ssl_f_sha1", smp_fetch_ssl_x_sha1, 0, NULL, SMP_T_BIN, SMP_USE_L5CLI },
Thierry FOURNIER07ee64e2015-07-06 23:43:03 +02005856 { "ssl_f_version", smp_fetch_ssl_x_version, 0, NULL, SMP_T_SINT, SMP_USE_L5CLI },
Willy Tarreau80aca902013-01-07 15:42:20 +01005857 { "ssl_fc", smp_fetch_ssl_fc, 0, NULL, SMP_T_BOOL, SMP_USE_L5CLI },
Thierry FOURNIER07ee64e2015-07-06 23:43:03 +02005858 { "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 +01005859 { "ssl_fc_cipher", smp_fetch_ssl_fc_cipher, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
Willy Tarreau80aca902013-01-07 15:42:20 +01005860 { "ssl_fc_has_crt", smp_fetch_ssl_fc_has_crt, 0, NULL, SMP_T_BOOL, SMP_USE_L5CLI },
5861 { "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 +02005862 { "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 +02005863#ifdef OPENSSL_NPN_NEGOTIATED
Thierry FOURNIER7654c9f2013-12-17 00:20:33 +01005864 { "ssl_fc_npn", smp_fetch_ssl_fc_npn, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
Willy Tarreaua33c6542012-10-15 13:19:06 +02005865#endif
Dirkjan Bussink48f1c4e2014-02-13 12:29:42 +01005866#ifdef TLSEXT_TYPE_application_layer_protocol_negotiation
Thierry FOURNIER7654c9f2013-12-17 00:20:33 +01005867 { "ssl_fc_alpn", smp_fetch_ssl_fc_alpn, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
Willy Tarreauab861d32013-04-02 02:30:41 +02005868#endif
Thierry FOURNIER7654c9f2013-12-17 00:20:33 +01005869 { "ssl_fc_protocol", smp_fetch_ssl_fc_protocol, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
Emeric Brunb73a9b02014-04-30 18:49:19 +02005870 { "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 +02005871 { "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 +01005872 { "ssl_fc_session_id", smp_fetch_ssl_fc_session_id, 0, NULL, SMP_T_BIN, SMP_USE_L5CLI },
5873 { "ssl_fc_sni", smp_fetch_ssl_fc_sni, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
Willy Tarreau7875d092012-09-10 08:20:03 +02005874 { NULL, NULL, 0, 0, 0 },
5875}};
5876
5877/* Note: must not be declared <const> as its list will be overwritten.
5878 * Please take care of keeping this list alphabetically sorted.
5879 */
Willy Tarreaudc13c112013-06-21 23:16:39 +02005880static struct acl_kw_list acl_kws = {ILH, {
Thierry FOURNIERc5a4e982014-03-05 16:07:08 +01005881 { "ssl_fc_sni_end", "ssl_fc_sni", PAT_MATCH_END },
5882 { "ssl_fc_sni_reg", "ssl_fc_sni", PAT_MATCH_REG },
Willy Tarreau8ed669b2013-01-11 15:49:37 +01005883 { /* END */ },
Willy Tarreau7875d092012-09-10 08:20:03 +02005884}};
5885
Willy Tarreau79eeafa2012-09-14 07:53:05 +02005886/* Note: must not be declared <const> as its list will be overwritten.
5887 * Please take care of keeping this list alphabetically sorted, doing so helps
5888 * all code contributors.
5889 * Optional keywords are also declared with a NULL ->parse() function so that
5890 * the config parser can report an appropriate error when a known keyword was
5891 * not enabled.
5892 */
Willy Tarreau51fb7652012-09-18 18:24:39 +02005893static struct bind_kw_list bind_kws = { "SSL", { }, {
Nenad Merdanovic05552d42015-02-27 19:56:49 +01005894 { "alpn", bind_parse_alpn, 1 }, /* set ALPN supported protocols */
5895 { "ca-file", bind_parse_ca_file, 1 }, /* set CAfile to process verify on client cert */
5896 { "ca-ignore-err", bind_parse_ignore_err, 1 }, /* set error IDs to ignore on verify depth > 0 */
Christopher Faulet31af49d2015-06-09 17:29:50 +02005897 { "ca-sign-file", bind_parse_ca_sign_file, 1 }, /* set CAFile used to generate and sign server certs */
5898 { "ca-sign-pass", bind_parse_ca_sign_pass, 1 }, /* set CAKey passphrase */
Nenad Merdanovic05552d42015-02-27 19:56:49 +01005899 { "ciphers", bind_parse_ciphers, 1 }, /* set SSL cipher suite */
5900 { "crl-file", bind_parse_crl_file, 1 }, /* set certificat revocation list file use on client cert verify */
5901 { "crt", bind_parse_crt, 1 }, /* load SSL certificates from this location */
5902 { "crt-ignore-err", bind_parse_ignore_err, 1 }, /* set error IDs to ingore on verify depth == 0 */
5903 { "crt-list", bind_parse_crt_list, 1 }, /* load a list of crt from this location */
5904 { "ecdhe", bind_parse_ecdhe, 1 }, /* defines named curve for elliptic curve Diffie-Hellman */
5905 { "force-sslv3", bind_parse_force_sslv3, 0 }, /* force SSLv3 */
5906 { "force-tlsv10", bind_parse_force_tlsv10, 0 }, /* force TLSv10 */
5907 { "force-tlsv11", bind_parse_force_tlsv11, 0 }, /* force TLSv11 */
5908 { "force-tlsv12", bind_parse_force_tlsv12, 0 }, /* force TLSv12 */
Christopher Faulet31af49d2015-06-09 17:29:50 +02005909 { "generate-certificates", bind_parse_generate_certs, 0 }, /* enable the server certificates generation */
Nenad Merdanovic05552d42015-02-27 19:56:49 +01005910 { "no-sslv3", bind_parse_no_sslv3, 0 }, /* disable SSLv3 */
5911 { "no-tlsv10", bind_parse_no_tlsv10, 0 }, /* disable TLSv10 */
5912 { "no-tlsv11", bind_parse_no_tlsv11, 0 }, /* disable TLSv11 */
5913 { "no-tlsv12", bind_parse_no_tlsv12, 0 }, /* disable TLSv12 */
5914 { "no-tls-tickets", bind_parse_no_tls_tickets, 0 }, /* disable session resumption tickets */
5915 { "ssl", bind_parse_ssl, 0 }, /* enable SSL processing */
5916 { "strict-sni", bind_parse_strict_sni, 0 }, /* refuse negotiation if sni doesn't match a certificate */
5917 { "tls-ticket-keys", bind_parse_tls_ticket_keys, 1 }, /* set file to load TLS ticket keys from */
5918 { "verify", bind_parse_verify, 1 }, /* set SSL verify method */
5919 { "npn", bind_parse_npn, 1 }, /* set NPN supported protocols */
Willy Tarreau79eeafa2012-09-14 07:53:05 +02005920 { NULL, NULL, 0 },
5921}};
Emeric Brun46591952012-05-18 15:47:34 +02005922
Willy Tarreau92faadf2012-10-10 23:04:25 +02005923/* Note: must not be declared <const> as its list will be overwritten.
5924 * Please take care of keeping this list alphabetically sorted, doing so helps
5925 * all code contributors.
5926 * Optional keywords are also declared with a NULL ->parse() function so that
5927 * the config parser can report an appropriate error when a known keyword was
5928 * not enabled.
5929 */
5930static struct srv_kw_list srv_kws = { "SSL", { }, {
Emeric Brunef42d922012-10-11 16:11:36 +02005931 { "ca-file", srv_parse_ca_file, 1, 0 }, /* set CAfile to process verify server cert */
Emeric Brunecc91fe2012-10-11 15:05:10 +02005932 { "check-ssl", srv_parse_check_ssl, 0, 0 }, /* enable SSL for health checks */
5933 { "ciphers", srv_parse_ciphers, 1, 0 }, /* select the cipher suite */
Emeric Brunef42d922012-10-11 16:11:36 +02005934 { "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 +02005935 { "crt", srv_parse_crt, 1, 0 }, /* set client certificate */
Emeric Brunecc91fe2012-10-11 15:05:10 +02005936 { "force-sslv3", srv_parse_force_sslv3, 0, 0 }, /* force SSLv3 */
5937 { "force-tlsv10", srv_parse_force_tlsv10, 0, 0 }, /* force TLSv10 */
5938 { "force-tlsv11", srv_parse_force_tlsv11, 0, 0 }, /* force TLSv11 */
5939 { "force-tlsv12", srv_parse_force_tlsv12, 0, 0 }, /* force TLSv12 */
Willy Tarreau2a3fb1c2015-02-05 16:47:07 +01005940 { "no-ssl-reuse", srv_parse_no_ssl_reuse, 0, 0 }, /* disable session reuse */
Emeric Brunecc91fe2012-10-11 15:05:10 +02005941 { "no-sslv3", srv_parse_no_sslv3, 0, 0 }, /* disable SSLv3 */
5942 { "no-tlsv10", srv_parse_no_tlsv10, 0, 0 }, /* disable TLSv10 */
5943 { "no-tlsv11", srv_parse_no_tlsv11, 0, 0 }, /* disable TLSv11 */
5944 { "no-tlsv12", srv_parse_no_tlsv12, 0, 0 }, /* disable TLSv12 */
Emeric Brunf9c5c472012-10-11 15:28:34 +02005945 { "no-tls-tickets", srv_parse_no_tls_tickets, 0, 0 }, /* disable session resumption tickets */
David Safb76832014-05-08 23:42:08 -04005946 { "send-proxy-v2-ssl", srv_parse_send_proxy_ssl, 0, 0 }, /* send PROXY protocol header v2 with SSL info */
5947 { "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 +02005948 { "sni", srv_parse_sni, 1, 0 }, /* send SNI extension */
Emeric Brunecc91fe2012-10-11 15:05:10 +02005949 { "ssl", srv_parse_ssl, 0, 0 }, /* enable SSL processing */
Emeric Brunef42d922012-10-11 16:11:36 +02005950 { "verify", srv_parse_verify, 1, 0 }, /* set SSL verify method */
Evan Broderbe554312013-06-27 00:05:25 -07005951 { "verifyhost", srv_parse_verifyhost, 1, 0 }, /* require that SSL cert verifies for hostname */
Willy Tarreau92faadf2012-10-10 23:04:25 +02005952 { NULL, NULL, 0, 0 },
5953}};
5954
Emeric Brun2c86cbf2014-10-30 15:56:50 +01005955static struct cfg_kw_list cfg_kws = {ILH, {
5956 { CFG_GLOBAL, "ssl-default-bind-options", ssl_parse_default_bind_options },
5957 { CFG_GLOBAL, "ssl-default-server-options", ssl_parse_default_server_options },
5958 { 0, NULL, NULL },
5959}};
5960
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02005961/* transport-layer operations for SSL sockets */
5962struct xprt_ops ssl_sock = {
Emeric Brun46591952012-05-18 15:47:34 +02005963 .snd_buf = ssl_sock_from_buf,
5964 .rcv_buf = ssl_sock_to_buf,
5965 .rcv_pipe = NULL,
5966 .snd_pipe = NULL,
5967 .shutr = NULL,
5968 .shutw = ssl_sock_shutw,
5969 .close = ssl_sock_close,
5970 .init = ssl_sock_init,
5971};
5972
Daniel Jakots54ffb912015-11-06 20:02:41 +01005973#if (OPENSSL_VERSION_NUMBER >= 0x1000200fL && !defined OPENSSL_NO_TLSEXT && !defined OPENSSL_IS_BORINGSSL && !defined LIBRESSL_VERSION_NUMBER)
Janusz Dziemidowicz2c701b52015-03-07 23:03:59 +01005974
5975static void ssl_sock_sctl_free_func(void *parent, void *ptr, CRYPTO_EX_DATA *ad, int idx, long argl, void *argp)
5976{
5977 if (ptr) {
5978 chunk_destroy(ptr);
5979 free(ptr);
5980 }
5981}
5982
5983#endif
5984
Emeric Brun46591952012-05-18 15:47:34 +02005985__attribute__((constructor))
Willy Tarreau92faadf2012-10-10 23:04:25 +02005986static void __ssl_sock_init(void)
5987{
Emeric Brun46591952012-05-18 15:47:34 +02005988 STACK_OF(SSL_COMP)* cm;
5989
Willy Tarreau610f04b2014-02-13 11:36:41 +01005990#ifdef LISTEN_DEFAULT_CIPHERS
5991 global.listen_default_ciphers = LISTEN_DEFAULT_CIPHERS;
5992#endif
5993#ifdef CONNECT_DEFAULT_CIPHERS
5994 global.connect_default_ciphers = CONNECT_DEFAULT_CIPHERS;
5995#endif
5996 if (global.listen_default_ciphers)
5997 global.listen_default_ciphers = strdup(global.listen_default_ciphers);
5998 if (global.connect_default_ciphers)
5999 global.connect_default_ciphers = strdup(global.connect_default_ciphers);
Emeric Brun2c86cbf2014-10-30 15:56:50 +01006000 global.listen_default_ssloptions = BC_SSL_O_NONE;
6001 global.connect_default_ssloptions = SRV_SSL_O_NONE;
Willy Tarreau610f04b2014-02-13 11:36:41 +01006002
Emeric Brun46591952012-05-18 15:47:34 +02006003 SSL_library_init();
6004 cm = SSL_COMP_get_compression_methods();
6005 sk_SSL_COMP_zero(cm);
Daniel Jakots54ffb912015-11-06 20:02:41 +01006006#if (OPENSSL_VERSION_NUMBER >= 0x1000200fL && !defined OPENSSL_NO_TLSEXT && !defined OPENSSL_IS_BORINGSSL && !defined LIBRESSL_VERSION_NUMBER)
Janusz Dziemidowicz2c701b52015-03-07 23:03:59 +01006007 sctl_ex_index = SSL_CTX_get_ex_new_index(0, NULL, NULL, NULL, ssl_sock_sctl_free_func);
6008#endif
Willy Tarreau7875d092012-09-10 08:20:03 +02006009 sample_register_fetches(&sample_fetch_keywords);
6010 acl_register_keywords(&acl_kws);
Willy Tarreau79eeafa2012-09-14 07:53:05 +02006011 bind_register_keywords(&bind_kws);
Willy Tarreau92faadf2012-10-10 23:04:25 +02006012 srv_register_keywords(&srv_kws);
Emeric Brun2c86cbf2014-10-30 15:56:50 +01006013 cfg_register_keywords(&cfg_kws);
Willy Tarreaud92aa5c2015-01-15 21:34:39 +01006014
6015 global.ssl_session_max_cost = SSL_SESSION_MAX_COST;
6016 global.ssl_handshake_max_cost = SSL_HANDSHAKE_MAX_COST;
Remi Gacogne4f902b82015-05-28 16:23:00 +02006017
6018#ifndef OPENSSL_NO_DH
6019 ssl_dh_ptr_index = SSL_CTX_get_ex_new_index(0, NULL, NULL, NULL, NULL);
6020#endif
Emeric Brun46591952012-05-18 15:47:34 +02006021}
6022
Remi Gacogned3a23c32015-05-28 16:39:47 +02006023__attribute__((destructor))
6024static void __ssl_sock_deinit(void)
6025{
Willy Tarreaua84c2672015-10-09 12:10:13 +02006026#ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME
Christopher Faulet31af49d2015-06-09 17:29:50 +02006027 lru64_destroy(ssl_ctx_lru_tree);
Willy Tarreaua84c2672015-10-09 12:10:13 +02006028#endif
Christopher Faulet31af49d2015-06-09 17:29:50 +02006029
Remi Gacogned3a23c32015-05-28 16:39:47 +02006030#ifndef OPENSSL_NO_DH
6031 if (local_dh_1024) {
6032 DH_free(local_dh_1024);
6033 local_dh_1024 = NULL;
6034 }
6035
6036 if (local_dh_2048) {
6037 DH_free(local_dh_2048);
6038 local_dh_2048 = NULL;
6039 }
6040
6041 if (local_dh_4096) {
6042 DH_free(local_dh_4096);
6043 local_dh_4096 = NULL;
6044 }
6045
Remi Gacogne47783ef2015-05-29 15:53:22 +02006046 if (global_dh) {
6047 DH_free(global_dh);
6048 global_dh = NULL;
6049 }
Remi Gacogned3a23c32015-05-28 16:39:47 +02006050#endif
6051
6052 ERR_remove_state(0);
6053 ERR_free_strings();
6054
6055 EVP_cleanup();
6056
6057#if OPENSSL_VERSION_NUMBER >= 0x00907000L
6058 CRYPTO_cleanup_all_ex_data();
6059#endif
6060}
6061
6062
Emeric Brun46591952012-05-18 15:47:34 +02006063/*
6064 * Local variables:
6065 * c-indent-level: 8
6066 * c-basic-offset: 8
6067 * End:
6068 */