blob: 0d35c298dcca4cb99eb1df15764dab4bb4d744c0 [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);
Remi Gacognef46cd6e2014-06-12 14:58:40 +02001646 }
1647 else {
1648 SSL_CTX_set_tmp_dh_callback(ctx, ssl_get_tmp_dh);
1649 }
Willy Tarreau6e774b42014-04-25 21:35:23 +02001650
Emeric Brun41fdb3c2013-04-26 11:05:44 +02001651 ret = 0; /* DH params not found */
Emeric Bruna4bcd9a2012-09-20 16:19:02 +02001652 }
Emeric Brun644cde02012-12-14 11:21:13 +01001653
Emeric Bruna4bcd9a2012-09-20 16:19:02 +02001654end:
1655 if (dh)
1656 DH_free(dh);
1657
Emeric Bruna4bcd9a2012-09-20 16:19:02 +02001658 return ret;
1659}
1660#endif
1661
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +02001662static int ssl_sock_add_cert_sni(SSL_CTX *ctx, struct bind_conf *s, char *name, int order)
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01001663{
1664 struct sni_ctx *sc;
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +02001665 int wild = 0, neg = 0;
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01001666
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +02001667 if (*name == '!') {
1668 neg = 1;
1669 name++;
1670 }
1671 if (*name == '*') {
1672 wild = 1;
1673 name++;
1674 }
1675 /* !* filter is a nop */
1676 if (neg && wild)
1677 return order;
1678 if (*name) {
1679 int j, len;
1680 len = strlen(name);
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01001681 sc = malloc(sizeof(struct sni_ctx) + len + 1);
1682 for (j = 0; j < len; j++)
1683 sc->name.key[j] = tolower(name[j]);
1684 sc->name.key[len] = 0;
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01001685 sc->ctx = ctx;
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +02001686 sc->order = order++;
1687 sc->neg = neg;
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01001688 if (wild)
1689 ebst_insert(&s->sni_w_ctx, &sc->name);
1690 else
1691 ebst_insert(&s->sni_ctx, &sc->name);
1692 }
1693 return order;
1694}
1695
yanbzhu488a4d22015-12-01 15:16:07 -05001696
1697/* The following code is used for loading multiple crt files into
1698 * SSL_CTX's based on CN/SAN
1699 */
1700#if OPENSSL_VERSION_NUMBER >= 0x1000200fL
1701/* This is used to preload the certifcate, private key
1702 * and Cert Chain of a file passed in via the crt
1703 * argument
1704 *
1705 * This way, we do not have to read the file multiple times
1706 */
1707struct cert_key_and_chain {
1708 X509 *cert;
1709 EVP_PKEY *key;
1710 unsigned int num_chain_certs;
1711 /* This is an array of X509 pointers */
1712 X509 **chain_certs;
1713};
1714
yanbzhu08ce6ab2015-12-02 13:01:29 -05001715#define SSL_SOCK_POSSIBLE_KT_COMBOS (1<<(SSL_SOCK_NUM_KEYTYPES))
1716
1717struct key_combo_ctx {
1718 SSL_CTX *ctx;
1719 int order;
1720};
1721
1722/* Map used for processing multiple keypairs for a single purpose
1723 *
1724 * This maps CN/SNI name to certificate type
1725 */
1726struct sni_keytype {
1727 int keytypes; /* BITMASK for keytypes */
1728 struct ebmb_node name; /* node holding the servername value */
1729};
1730
1731
yanbzhu488a4d22015-12-01 15:16:07 -05001732/* Frees the contents of a cert_key_and_chain
1733 */
1734static void ssl_sock_free_cert_key_and_chain_contents(struct cert_key_and_chain *ckch)
1735{
1736 int i;
1737
1738 if (!ckch)
1739 return;
1740
1741 /* Free the certificate and set pointer to NULL */
1742 if (ckch->cert)
1743 X509_free(ckch->cert);
1744 ckch->cert = NULL;
1745
1746 /* Free the key and set pointer to NULL */
1747 if (ckch->key)
1748 EVP_PKEY_free(ckch->key);
1749 ckch->key = NULL;
1750
1751 /* Free each certificate in the chain */
1752 for (i = 0; i < ckch->num_chain_certs; i++) {
1753 if (ckch->chain_certs[i])
1754 X509_free(ckch->chain_certs[i]);
1755 }
1756
1757 /* Free the chain obj itself and set to NULL */
1758 if (ckch->num_chain_certs > 0) {
1759 free(ckch->chain_certs);
1760 ckch->num_chain_certs = 0;
1761 ckch->chain_certs = NULL;
1762 }
1763
1764}
1765
1766/* checks if a key and cert exists in the ckch
1767 */
1768static int ssl_sock_is_ckch_valid(struct cert_key_and_chain *ckch)
1769{
1770 return (ckch->cert != NULL && ckch->key != NULL);
1771}
1772
1773
1774/* Loads the contents of a crt file (path) into a cert_key_and_chain
1775 * This allows us to carry the contents of the file without having to
1776 * read the file multiple times.
1777 *
1778 * returns:
1779 * 0 on Success
1780 * 1 on SSL Failure
1781 * 2 on file not found
1782 */
1783static int ssl_sock_load_crt_file_into_ckch(const char *path, struct cert_key_and_chain *ckch, char **err)
1784{
1785
1786 BIO *in;
1787 X509 *ca = NULL;
1788 int ret = 1;
1789
1790 ssl_sock_free_cert_key_and_chain_contents(ckch);
1791
1792 in = BIO_new(BIO_s_file());
1793 if (in == NULL)
1794 goto end;
1795
1796 if (BIO_read_filename(in, path) <= 0)
1797 goto end;
1798
yanbzhu488a4d22015-12-01 15:16:07 -05001799 /* Read Private Key */
1800 ckch->key = PEM_read_bio_PrivateKey(in, NULL, NULL, NULL);
1801 if (ckch->key == NULL) {
1802 memprintf(err, "%sunable to load private key from file '%s'.\n",
1803 err && *err ? *err : "", path);
1804 goto end;
1805 }
1806
Willy Tarreaubb137a82016-04-06 19:02:38 +02001807 /* Seek back to beginning of file */
1808 BIO_reset(in);
1809
1810 /* Read Certificate */
1811 ckch->cert = PEM_read_bio_X509_AUX(in, NULL, NULL, NULL);
1812 if (ckch->cert == NULL) {
1813 memprintf(err, "%sunable to load certificate from file '%s'.\n",
1814 err && *err ? *err : "", path);
1815 goto end;
1816 }
1817
yanbzhu488a4d22015-12-01 15:16:07 -05001818 /* Read Certificate Chain */
1819 while ((ca = PEM_read_bio_X509(in, NULL, NULL, NULL))) {
1820 /* Grow the chain certs */
1821 ckch->num_chain_certs++;
1822 ckch->chain_certs = realloc(ckch->chain_certs, (ckch->num_chain_certs * sizeof(X509 *)));
1823
1824 /* use - 1 here since we just incremented it above */
1825 ckch->chain_certs[ckch->num_chain_certs - 1] = ca;
1826 }
1827 ret = ERR_get_error();
1828 if (ret && (ERR_GET_LIB(ret) != ERR_LIB_PEM && ERR_GET_REASON(ret) != PEM_R_NO_START_LINE)) {
1829 memprintf(err, "%sunable to load certificate chain from file '%s'.\n",
1830 err && *err ? *err : "", path);
1831 ret = 1;
1832 goto end;
1833 }
1834
1835 ret = 0;
1836
1837end:
1838
1839 ERR_clear_error();
1840 if (in)
1841 BIO_free(in);
1842
1843 /* Something went wrong in one of the reads */
1844 if (ret != 0)
1845 ssl_sock_free_cert_key_and_chain_contents(ckch);
1846
1847 return ret;
1848}
1849
1850/* Loads the info in ckch into ctx
1851 * Currently, this does not process any information about ocsp, dhparams or
1852 * sctl
1853 * Returns
1854 * 0 on success
1855 * 1 on failure
1856 */
1857static int ssl_sock_put_ckch_into_ctx(const char *path, const struct cert_key_and_chain *ckch, SSL_CTX *ctx, char **err)
1858{
1859 int i = 0;
1860
1861 if (SSL_CTX_use_PrivateKey(ctx, ckch->key) <= 0) {
1862 memprintf(err, "%sunable to load SSL private key into SSL Context '%s'.\n",
1863 err && *err ? *err : "", path);
1864 return 1;
1865 }
1866
1867 if (!SSL_CTX_use_certificate(ctx, ckch->cert)) {
1868 memprintf(err, "%sunable to load SSL certificate into SSL Context '%s'.\n",
1869 err && *err ? *err : "", path);
1870 return 1;
1871 }
1872
yanbzhu488a4d22015-12-01 15:16:07 -05001873 /* Load all certs in the ckch into the ctx_chain for the ssl_ctx */
1874 for (i = 0; i < ckch->num_chain_certs; i++) {
1875 if (!SSL_CTX_add1_chain_cert(ctx, ckch->chain_certs[i])) {
yanbzhu08ce6ab2015-12-02 13:01:29 -05001876 memprintf(err, "%sunable to load chain certificate #%d into SSL Context '%s'. Make sure you are linking against Openssl >= 1.0.2.\n",
1877 err && *err ? *err : "", (i+1), path);
yanbzhu488a4d22015-12-01 15:16:07 -05001878 return 1;
1879 }
1880 }
1881
1882 if (SSL_CTX_check_private_key(ctx) <= 0) {
1883 memprintf(err, "%sinconsistencies between private key and certificate loaded from PEM file '%s'.\n",
1884 err && *err ? *err : "", path);
1885 return 1;
1886 }
1887
1888 return 0;
1889}
1890
yanbzhu08ce6ab2015-12-02 13:01:29 -05001891
1892static void ssl_sock_populate_sni_keytypes_hplr(const char *str, struct eb_root *sni_keytypes, int key_index)
1893{
1894 struct sni_keytype *s_kt = NULL;
1895 struct ebmb_node *node;
1896 int i;
1897
1898 for (i = 0; i < trash.size; i++) {
1899 if (!str[i])
1900 break;
1901 trash.str[i] = tolower(str[i]);
1902 }
1903 trash.str[i] = 0;
1904 node = ebst_lookup(sni_keytypes, trash.str);
1905 if (!node) {
1906 /* CN not found in tree */
1907 s_kt = malloc(sizeof(struct sni_keytype) + i + 1);
1908 /* Using memcpy here instead of strncpy.
1909 * strncpy will cause sig_abrt errors under certain versions of gcc with -O2
1910 * See: https://gcc.gnu.org/bugzilla/show_bug.cgi?id=60792
1911 */
1912 memcpy(s_kt->name.key, trash.str, i+1);
1913 s_kt->keytypes = 0;
1914 ebst_insert(sni_keytypes, &s_kt->name);
1915 } else {
1916 /* CN found in tree */
1917 s_kt = container_of(node, struct sni_keytype, name);
1918 }
1919
1920 /* Mark that this CN has the keytype of key_index via keytypes mask */
1921 s_kt->keytypes |= 1<<key_index;
1922
1923}
1924
1925
1926/* Given a path that does not exist, try to check for path.rsa, path.dsa and path.ecdsa files.
1927 * If any are found, group these files into a set of SSL_CTX*
1928 * based on shared and unique CN and SAN entries. Add these SSL_CTX* to the SNI tree.
1929 *
1930 * This will allow the user to explictly group multiple cert/keys for a single purpose
1931 *
1932 * Returns
1933 * 0 on success
1934 * 1 on failure
1935 */
1936static int ssl_sock_load_multi_cert(const char *path, struct bind_conf *bind_conf, struct proxy *curproxy, char **sni_filter, char **err)
1937{
1938 char fp[MAXPATHLEN+1] = {0};
1939 int n = 0;
1940 int i = 0;
1941 struct cert_key_and_chain certs_and_keys[SSL_SOCK_NUM_KEYTYPES] = { {0} };
1942 struct eb_root sni_keytypes_map = { {0} };
1943 struct ebmb_node *node;
1944 struct ebmb_node *next;
1945 /* Array of SSL_CTX pointers corresponding to each possible combo
1946 * of keytypes
1947 */
1948 struct key_combo_ctx key_combos[SSL_SOCK_POSSIBLE_KT_COMBOS] = { {0} };
1949 int rv = 0;
1950 X509_NAME *xname = NULL;
1951 char *str = NULL;
1952#ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME
1953 STACK_OF(GENERAL_NAME) *names = NULL;
1954#endif
1955
1956 /* Load all possible certs and keys */
1957 for (n = 0; n < SSL_SOCK_NUM_KEYTYPES; n++) {
1958 struct stat buf;
1959
1960 snprintf(fp, sizeof(fp), "%s.%s", path, SSL_SOCK_KEYTYPE_NAMES[n]);
1961 if (stat(fp, &buf) == 0) {
1962 if (ssl_sock_load_crt_file_into_ckch(fp, &certs_and_keys[n], err) == 1) {
1963 rv = 1;
1964 goto end;
1965 }
1966 }
1967 }
1968
1969 /* Process each ckch and update keytypes for each CN/SAN
1970 * for example, if CN/SAN www.a.com is associated with
1971 * certs with keytype 0 and 2, then at the end of the loop,
1972 * www.a.com will have:
1973 * keyindex = 0 | 1 | 4 = 5
1974 */
1975 for (n = 0; n < SSL_SOCK_NUM_KEYTYPES; n++) {
1976
1977 if (!ssl_sock_is_ckch_valid(&certs_and_keys[n]))
1978 continue;
1979
1980 /* A lot of the following code is OpenSSL boilerplate for processing CN's and SAN's,
1981 * so the line that contains logic is marked via comments
1982 */
1983 xname = X509_get_subject_name(certs_and_keys[n].cert);
1984 i = -1;
1985 while ((i = X509_NAME_get_index_by_NID(xname, NID_commonName, i)) != -1) {
1986 X509_NAME_ENTRY *entry = X509_NAME_get_entry(xname, i);
1987
1988 if (ASN1_STRING_to_UTF8((unsigned char **)&str, entry->value) >= 0) {
1989 /* Important line is here */
1990 ssl_sock_populate_sni_keytypes_hplr(str, &sni_keytypes_map, n);
1991
1992 OPENSSL_free(str);
1993 str = NULL;
1994 }
1995 }
1996
1997 /* Do the above logic for each SAN */
1998#ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME
1999 names = X509_get_ext_d2i(certs_and_keys[n].cert, NID_subject_alt_name, NULL, NULL);
2000 if (names) {
2001 for (i = 0; i < sk_GENERAL_NAME_num(names); i++) {
2002 GENERAL_NAME *name = sk_GENERAL_NAME_value(names, i);
2003
2004 if (name->type == GEN_DNS) {
2005 if (ASN1_STRING_to_UTF8((unsigned char **)&str, name->d.dNSName) >= 0) {
2006 /* Important line is here */
2007 ssl_sock_populate_sni_keytypes_hplr(str, &sni_keytypes_map, n);
2008
2009 OPENSSL_free(str);
2010 str = NULL;
2011 }
2012 }
2013 }
2014 }
2015#endif /* SSL_CTRL_SET_TLSEXT_HOSTNAME */
2016 }
2017
2018 /* If no files found, return error */
2019 if (eb_is_empty(&sni_keytypes_map)) {
2020 memprintf(err, "%sunable to load SSL certificate file '%s' file does not exist.\n",
2021 err && *err ? *err : "", path);
2022 rv = 1;
2023 goto end;
2024 }
2025
2026 /* We now have a map of CN/SAN to keytypes that are loaded in
2027 * Iterate through the map to create the SSL_CTX's (if needed)
2028 * and add each CTX to the SNI tree
2029 *
2030 * Some math here:
2031 * There are 2^n - 1 possibile combinations, each unique
2032 * combination is denoted by the key in the map. Each key
2033 * has a value between 1 and 2^n - 1. Conveniently, the array
2034 * of SSL_CTX* is sized 2^n. So, we can simply use the i'th
2035 * entry in the array to correspond to the unique combo (key)
2036 * associated with i. This unique key combo (i) will be associated
2037 * with combos[i-1]
2038 */
2039
2040 node = ebmb_first(&sni_keytypes_map);
2041 while (node) {
2042 SSL_CTX *cur_ctx;
2043
2044 str = (char *)container_of(node, struct sni_keytype, name)->name.key;
2045 i = container_of(node, struct sni_keytype, name)->keytypes;
2046 cur_ctx = key_combos[i-1].ctx;
2047
2048 if (cur_ctx == NULL) {
2049 /* need to create SSL_CTX */
2050 cur_ctx = SSL_CTX_new(SSLv23_server_method());
2051 if (cur_ctx == NULL) {
2052 memprintf(err, "%sunable to allocate SSL context.\n",
2053 err && *err ? *err : "");
2054 rv = 1;
2055 goto end;
2056 }
2057
yanbzhube2774d2015-12-10 15:07:30 -05002058 /* Load all required certs/keys/chains/OCSPs info into SSL_CTX */
yanbzhu08ce6ab2015-12-02 13:01:29 -05002059 for (n = 0; n < SSL_SOCK_NUM_KEYTYPES; n++) {
2060 if (i & (1<<n)) {
2061 /* Key combo contains ckch[n] */
2062 snprintf(trash.str, trash.size, "%s.%s", path, SSL_SOCK_KEYTYPE_NAMES[n]);
2063 if (ssl_sock_put_ckch_into_ctx(trash.str, &certs_and_keys[n], cur_ctx, err) != 0) {
2064 SSL_CTX_free(cur_ctx);
2065 rv = 1;
2066 goto end;
2067 }
yanbzhube2774d2015-12-10 15:07:30 -05002068
2069#if (defined SSL_CTRL_SET_TLSEXT_STATUS_REQ_CB && !defined OPENSSL_NO_OCSP)
2070 /* Load OCSP Info into context */
2071 if (ssl_sock_load_ocsp(cur_ctx, trash.str) < 0) {
2072 if (err)
2073 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",
2074 *err ? *err : "", path);
2075 SSL_CTX_free(cur_ctx);
2076 rv = 1;
2077 goto end;
2078 }
2079#endif
yanbzhu08ce6ab2015-12-02 13:01:29 -05002080 }
2081 }
2082
2083 /* Load DH params into the ctx to support DHE keys */
2084#ifndef OPENSSL_NO_DH
2085 if (ssl_dh_ptr_index >= 0)
2086 SSL_CTX_set_ex_data(cur_ctx, ssl_dh_ptr_index, NULL);
2087
2088 rv = ssl_sock_load_dh_params(cur_ctx, NULL);
2089 if (rv < 0) {
2090 if (err)
2091 memprintf(err, "%sunable to load DH parameters from file '%s'.\n",
2092 *err ? *err : "", path);
2093 rv = 1;
2094 goto end;
2095 }
2096#endif
2097
2098 /* Update key_combos */
2099 key_combos[i-1].ctx = cur_ctx;
2100 }
2101
2102 /* Update SNI Tree */
2103 ssl_sock_add_cert_sni(cur_ctx, bind_conf, str, key_combos[i-1].order++);
2104 node = ebmb_next(node);
2105 }
2106
2107
2108 /* Mark a default context if none exists, using the ctx that has the most shared keys */
2109 if (!bind_conf->default_ctx) {
2110 for (i = SSL_SOCK_POSSIBLE_KT_COMBOS - 1; i >= 0; i--) {
2111 if (key_combos[i].ctx) {
2112 bind_conf->default_ctx = key_combos[i].ctx;
2113 break;
2114 }
2115 }
2116 }
2117
2118end:
2119
2120 if (names)
2121 sk_GENERAL_NAME_pop_free(names, GENERAL_NAME_free);
2122
2123 for (n = 0; n < SSL_SOCK_NUM_KEYTYPES; n++)
2124 ssl_sock_free_cert_key_and_chain_contents(&certs_and_keys[n]);
2125
2126 node = ebmb_first(&sni_keytypes_map);
2127 while (node) {
2128 next = ebmb_next(node);
2129 ebmb_delete(node);
2130 node = next;
2131 }
2132
2133 return rv;
2134}
2135#else
2136/* This is a dummy, that just logs an error and returns error */
2137static int ssl_sock_load_multi_cert(const char *path, struct bind_conf *bind_conf, struct proxy *curproxy, char **sni_filter, char **err)
2138{
2139 memprintf(err, "%sunable to stat SSL certificate from file '%s' : %s.\n",
2140 err && *err ? *err : "", path, strerror(errno));
2141 return 1;
2142}
2143
yanbzhu488a4d22015-12-01 15:16:07 -05002144#endif /* #if OPENSSL_VERSION_NUMBER >= 0x1000200fL: Support for loading multiple certs into a single SSL_CTX */
2145
Emeric Brunfc0421f2012-09-07 17:30:07 +02002146/* Loads a certificate key and CA chain from a file. Returns 0 on error, -1 if
2147 * an early error happens and the caller must call SSL_CTX_free() by itelf.
2148 */
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +02002149static 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 +02002150{
2151 BIO *in;
2152 X509 *x = NULL, *ca;
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +02002153 int i, err;
Emeric Brunfc0421f2012-09-07 17:30:07 +02002154 int ret = -1;
2155 int order = 0;
2156 X509_NAME *xname;
2157 char *str;
Emeric Brunfc0421f2012-09-07 17:30:07 +02002158#ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME
2159 STACK_OF(GENERAL_NAME) *names;
2160#endif
2161
2162 in = BIO_new(BIO_s_file());
2163 if (in == NULL)
2164 goto end;
2165
2166 if (BIO_read_filename(in, file) <= 0)
2167 goto end;
2168
2169 x = PEM_read_bio_X509_AUX(in, NULL, ctx->default_passwd_callback, ctx->default_passwd_callback_userdata);
2170 if (x == NULL)
2171 goto end;
2172
Emeric Brun50bcecc2013-04-22 13:05:23 +02002173 if (fcount) {
2174 while (fcount--)
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +02002175 order = ssl_sock_add_cert_sni(ctx, s, sni_filter[fcount], order);
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01002176 }
2177 else {
Emeric Brunfc0421f2012-09-07 17:30:07 +02002178#ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01002179 names = X509_get_ext_d2i(x, NID_subject_alt_name, NULL, NULL);
2180 if (names) {
2181 for (i = 0; i < sk_GENERAL_NAME_num(names); i++) {
2182 GENERAL_NAME *name = sk_GENERAL_NAME_value(names, i);
2183 if (name->type == GEN_DNS) {
2184 if (ASN1_STRING_to_UTF8((unsigned char **)&str, name->d.dNSName) >= 0) {
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +02002185 order = ssl_sock_add_cert_sni(ctx, s, str, order);
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01002186 OPENSSL_free(str);
Emeric Brunfc0421f2012-09-07 17:30:07 +02002187 }
Emeric Brunfc0421f2012-09-07 17:30:07 +02002188 }
2189 }
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01002190 sk_GENERAL_NAME_pop_free(names, GENERAL_NAME_free);
Emeric Brunfc0421f2012-09-07 17:30:07 +02002191 }
Emeric Brunfc0421f2012-09-07 17:30:07 +02002192#endif /* SSL_CTRL_SET_TLSEXT_HOSTNAME */
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01002193 xname = X509_get_subject_name(x);
2194 i = -1;
2195 while ((i = X509_NAME_get_index_by_NID(xname, NID_commonName, i)) != -1) {
2196 X509_NAME_ENTRY *entry = X509_NAME_get_entry(xname, i);
2197 if (ASN1_STRING_to_UTF8((unsigned char **)&str, entry->value) >= 0) {
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +02002198 order = ssl_sock_add_cert_sni(ctx, s, str, order);
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01002199 OPENSSL_free(str);
Emeric Brunfc0421f2012-09-07 17:30:07 +02002200 }
Emeric Brunfc0421f2012-09-07 17:30:07 +02002201 }
2202 }
2203
2204 ret = 0; /* the caller must not free the SSL_CTX argument anymore */
2205 if (!SSL_CTX_use_certificate(ctx, x))
2206 goto end;
2207
2208 if (ctx->extra_certs != NULL) {
2209 sk_X509_pop_free(ctx->extra_certs, X509_free);
2210 ctx->extra_certs = NULL;
2211 }
2212
2213 while ((ca = PEM_read_bio_X509(in, NULL, ctx->default_passwd_callback, ctx->default_passwd_callback_userdata))) {
2214 if (!SSL_CTX_add_extra_chain_cert(ctx, ca)) {
2215 X509_free(ca);
2216 goto end;
2217 }
2218 }
2219
2220 err = ERR_get_error();
2221 if (!err || (ERR_GET_LIB(err) == ERR_LIB_PEM && ERR_GET_REASON(err) == PEM_R_NO_START_LINE)) {
2222 /* we successfully reached the last cert in the file */
2223 ret = 1;
2224 }
2225 ERR_clear_error();
2226
2227end:
2228 if (x)
2229 X509_free(x);
2230
2231 if (in)
2232 BIO_free(in);
2233
2234 return ret;
2235}
2236
Emeric Brun50bcecc2013-04-22 13:05:23 +02002237static 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 +02002238{
2239 int ret;
2240 SSL_CTX *ctx;
2241
2242 ctx = SSL_CTX_new(SSLv23_server_method());
2243 if (!ctx) {
Willy Tarreaueb6cead2012-09-20 19:43:14 +02002244 memprintf(err, "%sunable to allocate SSL context for cert '%s'.\n",
2245 err && *err ? *err : "", path);
Emeric Brunfc0421f2012-09-07 17:30:07 +02002246 return 1;
2247 }
2248
2249 if (SSL_CTX_use_PrivateKey_file(ctx, path, SSL_FILETYPE_PEM) <= 0) {
Willy Tarreaueb6cead2012-09-20 19:43:14 +02002250 memprintf(err, "%sunable to load SSL private key from PEM file '%s'.\n",
2251 err && *err ? *err : "", path);
Emeric Brunfc0421f2012-09-07 17:30:07 +02002252 SSL_CTX_free(ctx);
2253 return 1;
2254 }
2255
Emeric Brun50bcecc2013-04-22 13:05:23 +02002256 ret = ssl_sock_load_cert_chain_file(ctx, path, bind_conf, sni_filter, fcount);
Emeric Brunfc0421f2012-09-07 17:30:07 +02002257 if (ret <= 0) {
Willy Tarreaueb6cead2012-09-20 19:43:14 +02002258 memprintf(err, "%sunable to load SSL certificate from PEM file '%s'.\n",
2259 err && *err ? *err : "", path);
Emeric Brunfc0421f2012-09-07 17:30:07 +02002260 if (ret < 0) /* serious error, must do that ourselves */
2261 SSL_CTX_free(ctx);
2262 return 1;
2263 }
Emeric Brun61694ab2012-10-26 13:35:33 +02002264
2265 if (SSL_CTX_check_private_key(ctx) <= 0) {
2266 memprintf(err, "%sinconsistencies between private key and certificate loaded from PEM file '%s'.\n",
2267 err && *err ? *err : "", path);
2268 return 1;
2269 }
2270
Emeric Brunfc0421f2012-09-07 17:30:07 +02002271 /* we must not free the SSL_CTX anymore below, since it's already in
2272 * the tree, so it will be discovered and cleaned in time.
2273 */
Emeric Bruna4bcd9a2012-09-20 16:19:02 +02002274#ifndef OPENSSL_NO_DH
Remi Gacogne4f902b82015-05-28 16:23:00 +02002275 /* store a NULL pointer to indicate we have not yet loaded
2276 a custom DH param file */
2277 if (ssl_dh_ptr_index >= 0) {
2278 SSL_CTX_set_ex_data(ctx, ssl_dh_ptr_index, NULL);
2279 }
2280
Emeric Bruna4bcd9a2012-09-20 16:19:02 +02002281 ret = ssl_sock_load_dh_params(ctx, path);
2282 if (ret < 0) {
2283 if (err)
2284 memprintf(err, "%sunable to load DH parameters from file '%s'.\n",
2285 *err ? *err : "", path);
2286 return 1;
2287 }
2288#endif
2289
Lukas Tribuse4e30f72014-12-09 16:32:51 +01002290#if (defined SSL_CTRL_SET_TLSEXT_STATUS_REQ_CB && !defined OPENSSL_NO_OCSP)
Emeric Brun4147b2e2014-06-16 18:36:30 +02002291 ret = ssl_sock_load_ocsp(ctx, path);
2292 if (ret < 0) {
2293 if (err)
2294 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",
2295 *err ? *err : "", path);
2296 return 1;
2297 }
2298#endif
2299
Daniel Jakots54ffb912015-11-06 20:02:41 +01002300#if (OPENSSL_VERSION_NUMBER >= 0x1000200fL && !defined OPENSSL_NO_TLSEXT && !defined OPENSSL_IS_BORINGSSL && !defined LIBRESSL_VERSION_NUMBER)
Janusz Dziemidowicz2c701b52015-03-07 23:03:59 +01002301 if (sctl_ex_index >= 0) {
2302 ret = ssl_sock_load_sctl(ctx, path);
2303 if (ret < 0) {
2304 if (err)
2305 memprintf(err, "%s '%s.sctl' is present but cannot be read or parsed'.\n",
2306 *err ? *err : "", path);
2307 return 1;
2308 }
2309 }
2310#endif
2311
Emeric Brunfc0421f2012-09-07 17:30:07 +02002312#ifndef SSL_CTRL_SET_TLSEXT_HOSTNAME
Willy Tarreau2a65ff02012-09-13 17:54:29 +02002313 if (bind_conf->default_ctx) {
Willy Tarreaueb6cead2012-09-20 19:43:14 +02002314 memprintf(err, "%sthis version of openssl cannot load multiple SSL certificates.\n",
2315 err && *err ? *err : "");
Emeric Brunfc0421f2012-09-07 17:30:07 +02002316 return 1;
2317 }
2318#endif
Willy Tarreau2a65ff02012-09-13 17:54:29 +02002319 if (!bind_conf->default_ctx)
2320 bind_conf->default_ctx = ctx;
Emeric Brunfc0421f2012-09-07 17:30:07 +02002321
2322 return 0;
2323}
2324
Willy Tarreau79eeafa2012-09-14 07:53:05 +02002325int ssl_sock_load_cert(char *path, struct bind_conf *bind_conf, struct proxy *curproxy, char **err)
Emeric Brunfc0421f2012-09-07 17:30:07 +02002326{
Cyril Bonté3180f7b2015-01-25 00:16:08 +01002327 struct dirent **de_list;
2328 int i, n;
Emeric Brunfc0421f2012-09-07 17:30:07 +02002329 DIR *dir;
2330 struct stat buf;
Willy Tarreauee2663b2012-12-06 11:36:59 +01002331 char *end;
2332 char fp[MAXPATHLEN+1];
Emeric Brunfc0421f2012-09-07 17:30:07 +02002333 int cfgerr = 0;
yanbzhu63ea8462015-12-09 13:35:14 -05002334#if OPENSSL_VERSION_NUMBER >= 0x1000200fL
2335 int is_bundle;
2336 int j;
2337#endif
Emeric Brunfc0421f2012-09-07 17:30:07 +02002338
yanbzhu08ce6ab2015-12-02 13:01:29 -05002339 if (stat(path, &buf) == 0) {
2340 dir = opendir(path);
2341 if (!dir)
2342 return ssl_sock_load_cert_file(path, bind_conf, curproxy, NULL, 0, err);
Emeric Brunfc0421f2012-09-07 17:30:07 +02002343
yanbzhu08ce6ab2015-12-02 13:01:29 -05002344 /* strip trailing slashes, including first one */
2345 for (end = path + strlen(path) - 1; end >= path && *end == '/'; end--)
2346 *end = 0;
Emeric Brunfc0421f2012-09-07 17:30:07 +02002347
yanbzhu08ce6ab2015-12-02 13:01:29 -05002348 n = scandir(path, &de_list, 0, alphasort);
2349 if (n < 0) {
2350 memprintf(err, "%sunable to scan directory '%s' : %s.\n",
2351 err && *err ? *err : "", path, strerror(errno));
2352 cfgerr++;
2353 }
2354 else {
2355 for (i = 0; i < n; i++) {
2356 struct dirent *de = de_list[i];
Emeric Brun2aab7222014-06-18 18:15:09 +02002357
yanbzhu08ce6ab2015-12-02 13:01:29 -05002358 end = strrchr(de->d_name, '.');
2359 if (end && (!strcmp(end, ".issuer") || !strcmp(end, ".ocsp") || !strcmp(end, ".sctl")))
2360 goto ignore_entry;
Cyril Bonté3180f7b2015-01-25 00:16:08 +01002361
yanbzhu08ce6ab2015-12-02 13:01:29 -05002362 snprintf(fp, sizeof(fp), "%s/%s", path, de->d_name);
2363 if (stat(fp, &buf) != 0) {
2364 memprintf(err, "%sunable to stat SSL certificate from file '%s' : %s.\n",
2365 err && *err ? *err : "", fp, strerror(errno));
2366 cfgerr++;
2367 goto ignore_entry;
2368 }
2369 if (!S_ISREG(buf.st_mode))
2370 goto ignore_entry;
yanbzhu63ea8462015-12-09 13:35:14 -05002371
2372#if OPENSSL_VERSION_NUMBER >= 0x1000200fL
2373 is_bundle = 0;
2374 /* Check if current entry in directory is part of a multi-cert bundle */
2375
2376 if (end) {
2377 for (j = 0; j < SSL_SOCK_NUM_KEYTYPES; j++) {
2378 if (!strcmp(end + 1, SSL_SOCK_KEYTYPE_NAMES[j])) {
2379 is_bundle = 1;
2380 break;
2381 }
2382 }
2383
2384 if (is_bundle) {
2385 char dp[MAXPATHLEN+1] = {0}; /* this will be the filename w/o the keytype */
2386 int dp_len;
2387
2388 dp_len = end - de->d_name;
2389 snprintf(dp, dp_len + 1, "%s", de->d_name);
2390
2391 /* increment i and free de until we get to a non-bundle cert
2392 * Note here that we look at de_list[i + 1] before freeing de
2393 * this is important since ignore_entry will free de
2394 */
2395 while (i + 1 < n && !strncmp(de_list[i + 1]->d_name, dp, dp_len)) {
2396 free(de);
2397 i++;
2398 de = de_list[i];
2399 }
2400
2401 snprintf(fp, sizeof(fp), "%s/%s", path, dp);
2402 ssl_sock_load_multi_cert(fp, bind_conf, curproxy, NULL, err);
2403
2404 /* Successfully processed the bundle */
2405 goto ignore_entry;
2406 }
2407 }
2408
2409#endif
yanbzhu08ce6ab2015-12-02 13:01:29 -05002410 cfgerr += ssl_sock_load_cert_file(fp, bind_conf, curproxy, NULL, 0, err);
2411ignore_entry:
2412 free(de);
Cyril Bonté3180f7b2015-01-25 00:16:08 +01002413 }
yanbzhu08ce6ab2015-12-02 13:01:29 -05002414 free(de_list);
Emeric Brunfc0421f2012-09-07 17:30:07 +02002415 }
yanbzhu08ce6ab2015-12-02 13:01:29 -05002416 closedir(dir);
2417 return cfgerr;
Emeric Brunfc0421f2012-09-07 17:30:07 +02002418 }
yanbzhu08ce6ab2015-12-02 13:01:29 -05002419
2420 cfgerr = ssl_sock_load_multi_cert(path, bind_conf, curproxy, NULL, err);
2421
Emeric Brunfc0421f2012-09-07 17:30:07 +02002422 return cfgerr;
2423}
2424
Thierry Fournier383085f2013-01-24 14:15:43 +01002425/* Make sure openssl opens /dev/urandom before the chroot. The work is only
2426 * done once. Zero is returned if the operation fails. No error is returned
2427 * if the random is said as not implemented, because we expect that openssl
2428 * will use another method once needed.
2429 */
2430static int ssl_initialize_random()
2431{
2432 unsigned char random;
2433 static int random_initialized = 0;
2434
2435 if (!random_initialized && RAND_bytes(&random, 1) != 0)
2436 random_initialized = 1;
2437
2438 return random_initialized;
2439}
2440
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01002441int ssl_sock_load_cert_list_file(char *file, struct bind_conf *bind_conf, struct proxy *curproxy, char **err)
2442{
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +02002443 char thisline[LINESIZE];
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01002444 FILE *f;
yanbzhu1b04e5b2015-12-02 13:54:14 -05002445 struct stat buf;
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01002446 int linenum = 0;
2447 int cfgerr = 0;
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01002448
Willy Tarreauad1731d2013-04-02 17:35:58 +02002449 if ((f = fopen(file, "r")) == NULL) {
2450 memprintf(err, "cannot open file '%s' : %s", file, strerror(errno));
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01002451 return 1;
Willy Tarreauad1731d2013-04-02 17:35:58 +02002452 }
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01002453
2454 while (fgets(thisline, sizeof(thisline), f) != NULL) {
2455 int arg;
Emeric Brun50bcecc2013-04-22 13:05:23 +02002456 int newarg;
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01002457 char *end;
2458 char *args[MAX_LINE_ARGS + 1];
2459 char *line = thisline;
2460
2461 linenum++;
2462 end = line + strlen(line);
2463 if (end-line == sizeof(thisline)-1 && *(end-1) != '\n') {
2464 /* Check if we reached the limit and the last char is not \n.
2465 * Watch out for the last line without the terminating '\n'!
2466 */
Willy Tarreauad1731d2013-04-02 17:35:58 +02002467 memprintf(err, "line %d too long in file '%s', limit is %d characters",
2468 linenum, file, (int)sizeof(thisline)-1);
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01002469 cfgerr = 1;
Willy Tarreauad1731d2013-04-02 17:35:58 +02002470 break;
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01002471 }
2472
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01002473 arg = 0;
Emeric Brun50bcecc2013-04-22 13:05:23 +02002474 newarg = 1;
2475 while (*line) {
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01002476 if (*line == '#' || *line == '\n' || *line == '\r') {
2477 /* end of string, end of loop */
2478 *line = 0;
2479 break;
2480 }
2481 else if (isspace(*line)) {
Emeric Brun50bcecc2013-04-22 13:05:23 +02002482 newarg = 1;
2483 *line = 0;
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01002484 }
Emeric Brun50bcecc2013-04-22 13:05:23 +02002485 else if (newarg) {
2486 if (arg == MAX_LINE_ARGS) {
2487 memprintf(err, "too many args on line %d in file '%s'.",
2488 linenum, file);
2489 cfgerr = 1;
2490 break;
2491 }
2492 newarg = 0;
2493 args[arg++] = line;
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01002494 }
Emeric Brun50bcecc2013-04-22 13:05:23 +02002495 line++;
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01002496 }
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +02002497 if (cfgerr)
2498 break;
Willy Tarreauad1731d2013-04-02 17:35:58 +02002499
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01002500 /* empty line */
Emeric Brun50bcecc2013-04-22 13:05:23 +02002501 if (!arg)
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01002502 continue;
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01002503
yanbzhu1b04e5b2015-12-02 13:54:14 -05002504 if (stat(args[0], &buf) == 0) {
2505 cfgerr = ssl_sock_load_cert_file(args[0], bind_conf, curproxy, &args[1], arg-1, err);
2506 } else {
2507 cfgerr = ssl_sock_load_multi_cert(args[0], bind_conf, curproxy, NULL, err);
2508 }
2509
Willy Tarreauad1731d2013-04-02 17:35:58 +02002510 if (cfgerr) {
2511 memprintf(err, "error processing line %d in file '%s' : %s", linenum, file, *err);
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01002512 break;
Willy Tarreauad1731d2013-04-02 17:35:58 +02002513 }
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01002514 }
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01002515 fclose(f);
2516 return cfgerr;
2517}
2518
Emeric Brunfc0421f2012-09-07 17:30:07 +02002519#ifndef SSL_OP_CIPHER_SERVER_PREFERENCE /* needs OpenSSL >= 0.9.7 */
2520#define SSL_OP_CIPHER_SERVER_PREFERENCE 0
2521#endif
2522
2523#ifndef SSL_OP_NO_SESSION_RESUMPTION_ON_RENEGOTIATION /* needs OpenSSL >= 0.9.7 */
2524#define SSL_OP_NO_SESSION_RESUMPTION_ON_RENEGOTIATION 0
Willy Tarreau7d588ee2012-11-26 18:47:31 +01002525#define SSL_renegotiate_pending(arg) 0
Emeric Brunfc0421f2012-09-07 17:30:07 +02002526#endif
Emeric Brun2b58d042012-09-20 17:10:03 +02002527#ifndef SSL_OP_SINGLE_ECDH_USE /* needs OpenSSL >= 0.9.8 */
2528#define SSL_OP_SINGLE_ECDH_USE 0
2529#endif
Emeric Brun2d0c4822012-10-02 13:45:20 +02002530#ifndef SSL_OP_NO_TICKET /* needs OpenSSL >= 0.9.8 */
2531#define SSL_OP_NO_TICKET 0
2532#endif
Emeric Brunfc0421f2012-09-07 17:30:07 +02002533#ifndef SSL_OP_NO_COMPRESSION /* needs OpenSSL >= 0.9.9 */
2534#define SSL_OP_NO_COMPRESSION 0
2535#endif
Emeric Brunc0ff4922012-09-28 19:37:02 +02002536#ifndef SSL_OP_NO_TLSv1_1 /* needs OpenSSL >= 1.0.1 */
2537#define SSL_OP_NO_TLSv1_1 0
2538#endif
2539#ifndef SSL_OP_NO_TLSv1_2 /* needs OpenSSL >= 1.0.1 */
2540#define SSL_OP_NO_TLSv1_2 0
2541#endif
Emeric Bruna4bcd9a2012-09-20 16:19:02 +02002542#ifndef SSL_OP_SINGLE_DH_USE /* needs OpenSSL >= 0.9.6 */
2543#define SSL_OP_SINGLE_DH_USE 0
2544#endif
Emeric Brun2b58d042012-09-20 17:10:03 +02002545#ifndef SSL_OP_SINGLE_ECDH_USE /* needs OpenSSL >= 1.0.0 */
2546#define SSL_OP_SINGLE_ECDH_USE 0
2547#endif
Emeric Brunfc0421f2012-09-07 17:30:07 +02002548#ifndef SSL_MODE_RELEASE_BUFFERS /* needs OpenSSL >= 1.0.0 */
2549#define SSL_MODE_RELEASE_BUFFERS 0
2550#endif
Willy Tarreau396a1862014-11-13 14:06:52 +01002551#ifndef SSL_MODE_SMALL_BUFFERS /* needs small_records.patch */
2552#define SSL_MODE_SMALL_BUFFERS 0
2553#endif
Remi Gacognef46cd6e2014-06-12 14:58:40 +02002554
Willy Tarreau2a65ff02012-09-13 17:54:29 +02002555int ssl_sock_prepare_ctx(struct bind_conf *bind_conf, SSL_CTX *ctx, struct proxy *curproxy)
Emeric Brunfc0421f2012-09-07 17:30:07 +02002556{
2557 int cfgerr = 0;
Emeric Brun850efd52014-01-29 12:24:34 +01002558 int verify = SSL_VERIFY_NONE;
Remi Gacogneaf5c3da2014-05-19 10:29:58 +02002559 long ssloptions =
Emeric Brunfc0421f2012-09-07 17:30:07 +02002560 SSL_OP_ALL | /* all known workarounds for bugs */
2561 SSL_OP_NO_SSLv2 |
2562 SSL_OP_NO_COMPRESSION |
Emeric Bruna4bcd9a2012-09-20 16:19:02 +02002563 SSL_OP_SINGLE_DH_USE |
Emeric Brun2b58d042012-09-20 17:10:03 +02002564 SSL_OP_SINGLE_ECDH_USE |
Emeric Brun3c4bc6e2012-10-04 18:44:19 +02002565 SSL_OP_NO_SESSION_RESUMPTION_ON_RENEGOTIATION |
2566 SSL_OP_CIPHER_SERVER_PREFERENCE;
Remi Gacogneaf5c3da2014-05-19 10:29:58 +02002567 long sslmode =
Emeric Brunfc0421f2012-09-07 17:30:07 +02002568 SSL_MODE_ENABLE_PARTIAL_WRITE |
2569 SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER |
Willy Tarreau396a1862014-11-13 14:06:52 +01002570 SSL_MODE_RELEASE_BUFFERS |
2571 SSL_MODE_SMALL_BUFFERS;
Remi Gacognef46cd6e2014-06-12 14:58:40 +02002572 STACK_OF(SSL_CIPHER) * ciphers = NULL;
Willy Tarreaua616ba62014-10-26 06:49:19 +01002573 SSL_CIPHER * cipher = NULL;
Remi Gacognec1eab8c2014-06-12 18:20:11 +02002574 char cipher_description[128];
2575 /* The description of ciphers using an Ephemeral Diffie Hellman key exchange
2576 contains " Kx=DH " or " Kx=DH(". Beware of " Kx=DH/",
2577 which is not ephemeral DH. */
2578 const char dhe_description[] = " Kx=DH ";
2579 const char dhe_export_description[] = " Kx=DH(";
Remi Gacognef46cd6e2014-06-12 14:58:40 +02002580 int idx = 0;
2581 int dhe_found = 0;
Remi Gacogne23d5d372014-10-10 17:04:26 +02002582 SSL *ssl = NULL;
Emeric Brunfc0421f2012-09-07 17:30:07 +02002583
Thierry Fournier383085f2013-01-24 14:15:43 +01002584 /* Make sure openssl opens /dev/urandom before the chroot */
2585 if (!ssl_initialize_random()) {
2586 Alert("OpenSSL random data generator initialization failed.\n");
2587 cfgerr++;
2588 }
2589
Emeric Brun89675492012-10-05 13:48:26 +02002590 if (bind_conf->ssl_options & BC_SSL_O_NO_SSLV3)
Emeric Brunfc0421f2012-09-07 17:30:07 +02002591 ssloptions |= SSL_OP_NO_SSLv3;
Emeric Brun89675492012-10-05 13:48:26 +02002592 if (bind_conf->ssl_options & BC_SSL_O_NO_TLSV10)
Emeric Brunfc0421f2012-09-07 17:30:07 +02002593 ssloptions |= SSL_OP_NO_TLSv1;
Emeric Brun89675492012-10-05 13:48:26 +02002594 if (bind_conf->ssl_options & BC_SSL_O_NO_TLSV11)
Emeric Brunc0ff4922012-09-28 19:37:02 +02002595 ssloptions |= SSL_OP_NO_TLSv1_1;
Emeric Brun89675492012-10-05 13:48:26 +02002596 if (bind_conf->ssl_options & BC_SSL_O_NO_TLSV12)
Emeric Brunc0ff4922012-09-28 19:37:02 +02002597 ssloptions |= SSL_OP_NO_TLSv1_2;
Emeric Brun89675492012-10-05 13:48:26 +02002598 if (bind_conf->ssl_options & BC_SSL_O_NO_TLS_TICKETS)
Emeric Brun2d0c4822012-10-02 13:45:20 +02002599 ssloptions |= SSL_OP_NO_TICKET;
Jérémie Courrèges-Anglas17c3f622015-07-25 16:50:52 -06002600 if (bind_conf->ssl_options & BC_SSL_O_USE_SSLV3) {
2601#ifndef OPENSSL_NO_SSL3
Emeric Brun2cb7ae52012-10-05 14:14:21 +02002602 SSL_CTX_set_ssl_version(ctx, SSLv3_server_method());
Jérémie Courrèges-Anglas17c3f622015-07-25 16:50:52 -06002603#else
2604 Alert("SSLv3 support requested but unavailable.\n");
2605 cfgerr++;
2606#endif
2607 }
Emeric Brun2cb7ae52012-10-05 14:14:21 +02002608 if (bind_conf->ssl_options & BC_SSL_O_USE_TLSV10)
2609 SSL_CTX_set_ssl_version(ctx, TLSv1_server_method());
2610#if SSL_OP_NO_TLSv1_1
2611 if (bind_conf->ssl_options & BC_SSL_O_USE_TLSV11)
2612 SSL_CTX_set_ssl_version(ctx, TLSv1_1_server_method());
2613#endif
2614#if SSL_OP_NO_TLSv1_2
2615 if (bind_conf->ssl_options & BC_SSL_O_USE_TLSV12)
2616 SSL_CTX_set_ssl_version(ctx, TLSv1_2_server_method());
2617#endif
Emeric Brunfc0421f2012-09-07 17:30:07 +02002618
2619 SSL_CTX_set_options(ctx, ssloptions);
2620 SSL_CTX_set_mode(ctx, sslmode);
Emeric Brun850efd52014-01-29 12:24:34 +01002621 switch (bind_conf->verify) {
2622 case SSL_SOCK_VERIFY_NONE:
2623 verify = SSL_VERIFY_NONE;
2624 break;
2625 case SSL_SOCK_VERIFY_OPTIONAL:
2626 verify = SSL_VERIFY_PEER;
2627 break;
2628 case SSL_SOCK_VERIFY_REQUIRED:
2629 verify = SSL_VERIFY_PEER|SSL_VERIFY_FAIL_IF_NO_PEER_CERT;
2630 break;
2631 }
2632 SSL_CTX_set_verify(ctx, verify, ssl_sock_bind_verifycbk);
2633 if (verify & SSL_VERIFY_PEER) {
Emeric Brunfb510ea2012-10-05 12:00:26 +02002634 if (bind_conf->ca_file) {
Emeric Brund94b3fe2012-09-20 18:23:56 +02002635 /* load CAfile to verify */
Emeric Brunfb510ea2012-10-05 12:00:26 +02002636 if (!SSL_CTX_load_verify_locations(ctx, bind_conf->ca_file, NULL)) {
Emeric Brund94b3fe2012-09-20 18:23:56 +02002637 Alert("Proxy '%s': unable to load CA file '%s' for bind '%s' at [%s:%d].\n",
Emeric Brunfb510ea2012-10-05 12:00:26 +02002638 curproxy->id, bind_conf->ca_file, bind_conf->arg, bind_conf->file, bind_conf->line);
Emeric Brund94b3fe2012-09-20 18:23:56 +02002639 cfgerr++;
2640 }
2641 /* set CA names fo client cert request, function returns void */
Emeric Brunfb510ea2012-10-05 12:00:26 +02002642 SSL_CTX_set_client_CA_list(ctx, SSL_load_client_CA_file(bind_conf->ca_file));
Emeric Brund94b3fe2012-09-20 18:23:56 +02002643 }
Emeric Brun850efd52014-01-29 12:24:34 +01002644 else {
2645 Alert("Proxy '%s': verify is enabled but no CA file specified for bind '%s' at [%s:%d].\n",
2646 curproxy->id, bind_conf->arg, bind_conf->file, bind_conf->line);
2647 cfgerr++;
2648 }
Emeric Brun051cdab2012-10-02 19:25:50 +02002649#ifdef X509_V_FLAG_CRL_CHECK
Emeric Brunfb510ea2012-10-05 12:00:26 +02002650 if (bind_conf->crl_file) {
Emeric Brund94b3fe2012-09-20 18:23:56 +02002651 X509_STORE *store = SSL_CTX_get_cert_store(ctx);
2652
Emeric Brunfb510ea2012-10-05 12:00:26 +02002653 if (!store || !X509_STORE_load_locations(store, bind_conf->crl_file, NULL)) {
Emeric Brund94b3fe2012-09-20 18:23:56 +02002654 Alert("Proxy '%s': unable to configure CRL file '%s' for bind '%s' at [%s:%d].\n",
Alexander Rigbofc65af02015-04-07 14:02:16 +02002655 curproxy->id, bind_conf->crl_file, bind_conf->arg, bind_conf->file, bind_conf->line);
Emeric Brund94b3fe2012-09-20 18:23:56 +02002656 cfgerr++;
2657 }
Emeric Brun561e5742012-10-02 15:20:55 +02002658 else {
2659 X509_STORE_set_flags(store, X509_V_FLAG_CRL_CHECK|X509_V_FLAG_CRL_CHECK_ALL);
2660 }
Emeric Brund94b3fe2012-09-20 18:23:56 +02002661 }
Emeric Brun051cdab2012-10-02 19:25:50 +02002662#endif
Emeric Brun644cde02012-12-14 11:21:13 +01002663 ERR_clear_error();
Emeric Brund94b3fe2012-09-20 18:23:56 +02002664 }
Emeric Brunfc0421f2012-09-07 17:30:07 +02002665
Nenad Merdanovic05552d42015-02-27 19:56:49 +01002666#if (defined SSL_CTRL_SET_TLSEXT_TICKET_KEY_CB && TLS_TICKETS_NO > 0)
Nenad Merdanovic146defa2015-05-09 08:46:00 +02002667 if(bind_conf->keys_ref) {
Nenad Merdanovic05552d42015-02-27 19:56:49 +01002668 if (!SSL_CTX_set_tlsext_ticket_key_cb(ctx, ssl_tlsext_ticket_key_cb)) {
2669 Alert("Proxy '%s': unable to set callback for TLS ticket validation for bind '%s' at [%s:%d].\n",
2670 curproxy->id, bind_conf->arg, bind_conf->file, bind_conf->line);
2671 cfgerr++;
2672 }
2673 }
2674#endif
2675
Emeric Brun4f65bff2012-11-16 15:11:00 +01002676 if (global.tune.ssllifetime)
2677 SSL_CTX_set_timeout(ctx, global.tune.ssllifetime);
2678
Emeric Brunfc0421f2012-09-07 17:30:07 +02002679 shared_context_set_cache(ctx);
Willy Tarreau2a65ff02012-09-13 17:54:29 +02002680 if (bind_conf->ciphers &&
2681 !SSL_CTX_set_cipher_list(ctx, bind_conf->ciphers)) {
Emeric Brunfc0421f2012-09-07 17:30:07 +02002682 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 +02002683 curproxy->id, bind_conf->ciphers, bind_conf->arg, bind_conf->file, bind_conf->line);
Emeric Brunfc0421f2012-09-07 17:30:07 +02002684 cfgerr++;
2685 }
2686
Remi Gacogne47783ef2015-05-29 15:53:22 +02002687 /* If tune.ssl.default-dh-param has not been set,
2688 neither has ssl-default-dh-file and no static DH
2689 params were in the certificate file. */
Remi Gacogne4f902b82015-05-28 16:23:00 +02002690 if (global.tune.ssl_default_dh_param == 0 &&
Remi Gacogne47783ef2015-05-29 15:53:22 +02002691 global_dh == NULL &&
Remi Gacogne4f902b82015-05-28 16:23:00 +02002692 (ssl_dh_ptr_index == -1 ||
2693 SSL_CTX_get_ex_data(ctx, ssl_dh_ptr_index) == NULL)) {
Lukas Tribus90132722014-08-18 00:56:33 +02002694
Remi Gacogne23d5d372014-10-10 17:04:26 +02002695 ssl = SSL_new(ctx);
Remi Gacognef46cd6e2014-06-12 14:58:40 +02002696
Remi Gacogne23d5d372014-10-10 17:04:26 +02002697 if (ssl) {
2698 ciphers = SSL_get_ciphers(ssl);
2699
2700 if (ciphers) {
2701 for (idx = 0; idx < sk_SSL_CIPHER_num(ciphers); idx++) {
2702 cipher = sk_SSL_CIPHER_value(ciphers, idx);
2703 if (SSL_CIPHER_description(cipher, cipher_description, sizeof (cipher_description)) == cipher_description) {
2704 if (strstr(cipher_description, dhe_description) != NULL ||
2705 strstr(cipher_description, dhe_export_description) != NULL) {
2706 dhe_found = 1;
2707 break;
2708 }
Remi Gacognec1eab8c2014-06-12 18:20:11 +02002709 }
Remi Gacognef46cd6e2014-06-12 14:58:40 +02002710 }
2711 }
Remi Gacogne23d5d372014-10-10 17:04:26 +02002712 SSL_free(ssl);
2713 ssl = NULL;
Lukas Tribus90132722014-08-18 00:56:33 +02002714 }
Remi Gacognef46cd6e2014-06-12 14:58:40 +02002715
Lukas Tribus90132722014-08-18 00:56:33 +02002716 if (dhe_found) {
2717 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 +02002718 }
2719
2720 global.tune.ssl_default_dh_param = 1024;
2721 }
Remi Gacogne8de54152014-07-15 11:36:40 +02002722
2723#ifndef OPENSSL_NO_DH
2724 if (global.tune.ssl_default_dh_param >= 1024) {
2725 if (local_dh_1024 == NULL) {
2726 local_dh_1024 = ssl_get_dh_1024();
2727 }
2728 if (global.tune.ssl_default_dh_param >= 2048) {
2729 if (local_dh_2048 == NULL) {
2730 local_dh_2048 = ssl_get_dh_2048();
2731 }
2732 if (global.tune.ssl_default_dh_param >= 4096) {
2733 if (local_dh_4096 == NULL) {
2734 local_dh_4096 = ssl_get_dh_4096();
2735 }
Remi Gacogne8de54152014-07-15 11:36:40 +02002736 }
2737 }
2738 }
2739#endif /* OPENSSL_NO_DH */
Remi Gacognef46cd6e2014-06-12 14:58:40 +02002740
Emeric Brunfc0421f2012-09-07 17:30:07 +02002741 SSL_CTX_set_info_callback(ctx, ssl_sock_infocbk);
Willy Tarreau5cbe4ef2014-05-08 22:45:11 +02002742#if OPENSSL_VERSION_NUMBER >= 0x00907000L
Emeric Brun29f037d2014-04-25 19:05:36 +02002743 SSL_CTX_set_msg_callback(ctx, ssl_sock_msgcbk);
Willy Tarreau5cbe4ef2014-05-08 22:45:11 +02002744#endif
Emeric Brun29f037d2014-04-25 19:05:36 +02002745
Willy Tarreau6c9a3d52012-10-18 18:57:14 +02002746#ifdef OPENSSL_NPN_NEGOTIATED
2747 if (bind_conf->npn_str)
2748 SSL_CTX_set_next_protos_advertised_cb(ctx, ssl_sock_advertise_npn_protos, bind_conf);
2749#endif
Dirkjan Bussink48f1c4e2014-02-13 12:29:42 +01002750#ifdef TLSEXT_TYPE_application_layer_protocol_negotiation
Willy Tarreauab861d32013-04-02 02:30:41 +02002751 if (bind_conf->alpn_str)
Dirkjan Bussink48f1c4e2014-02-13 12:29:42 +01002752 SSL_CTX_set_alpn_select_cb(ctx, ssl_sock_advertise_alpn_protos, bind_conf);
Willy Tarreauab861d32013-04-02 02:30:41 +02002753#endif
Willy Tarreau6c9a3d52012-10-18 18:57:14 +02002754
Emeric Brunfc0421f2012-09-07 17:30:07 +02002755#ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME
2756 SSL_CTX_set_tlsext_servername_callback(ctx, ssl_sock_switchctx_cbk);
Willy Tarreau2a65ff02012-09-13 17:54:29 +02002757 SSL_CTX_set_tlsext_servername_arg(ctx, bind_conf);
Emeric Brunfc0421f2012-09-07 17:30:07 +02002758#endif
Emeric Brun2b58d042012-09-20 17:10:03 +02002759#if defined(SSL_CTX_set_tmp_ecdh) && !defined(OPENSSL_NO_ECDH)
Emeric Brun6924ef82013-03-06 14:08:53 +01002760 {
Emeric Brun2b58d042012-09-20 17:10:03 +02002761 int i;
2762 EC_KEY *ecdh;
2763
Emeric Brun6924ef82013-03-06 14:08:53 +01002764 i = OBJ_sn2nid(bind_conf->ecdhe ? bind_conf->ecdhe : ECDHE_DEFAULT_CURVE);
Emeric Brun2b58d042012-09-20 17:10:03 +02002765 if (!i || ((ecdh = EC_KEY_new_by_curve_name(i)) == NULL)) {
2766 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 +01002767 curproxy->id, bind_conf->ecdhe ? bind_conf->ecdhe : ECDHE_DEFAULT_CURVE,
2768 bind_conf->arg, bind_conf->file, bind_conf->line);
Emeric Brun2b58d042012-09-20 17:10:03 +02002769 cfgerr++;
2770 }
2771 else {
2772 SSL_CTX_set_tmp_ecdh(ctx, ecdh);
2773 EC_KEY_free(ecdh);
2774 }
2775 }
2776#endif
2777
Emeric Brunfc0421f2012-09-07 17:30:07 +02002778 return cfgerr;
2779}
2780
Evan Broderbe554312013-06-27 00:05:25 -07002781static int ssl_sock_srv_hostcheck(const char *pattern, const char *hostname)
2782{
2783 const char *pattern_wildcard, *pattern_left_label_end, *hostname_left_label_end;
2784 size_t prefixlen, suffixlen;
2785
2786 /* Trivial case */
2787 if (strcmp(pattern, hostname) == 0)
2788 return 1;
2789
Evan Broderbe554312013-06-27 00:05:25 -07002790 /* The rest of this logic is based on RFC 6125, section 6.4.3
2791 * (http://tools.ietf.org/html/rfc6125#section-6.4.3) */
2792
Emeric Bruna848dae2013-10-08 11:27:28 +02002793 pattern_wildcard = NULL;
2794 pattern_left_label_end = pattern;
2795 while (*pattern_left_label_end != '.') {
2796 switch (*pattern_left_label_end) {
2797 case 0:
2798 /* End of label not found */
2799 return 0;
2800 case '*':
2801 /* If there is more than one wildcards */
2802 if (pattern_wildcard)
2803 return 0;
2804 pattern_wildcard = pattern_left_label_end;
2805 break;
2806 }
2807 pattern_left_label_end++;
2808 }
2809
2810 /* If it's not trivial and there is no wildcard, it can't
2811 * match */
2812 if (!pattern_wildcard)
Evan Broderbe554312013-06-27 00:05:25 -07002813 return 0;
2814
2815 /* Make sure all labels match except the leftmost */
2816 hostname_left_label_end = strchr(hostname, '.');
2817 if (!hostname_left_label_end
2818 || strcmp(pattern_left_label_end, hostname_left_label_end) != 0)
2819 return 0;
2820
2821 /* Make sure the leftmost label of the hostname is long enough
2822 * that the wildcard can match */
Emeric Brun369da852013-10-08 11:39:35 +02002823 if (hostname_left_label_end - hostname < (pattern_left_label_end - pattern) - 1)
Evan Broderbe554312013-06-27 00:05:25 -07002824 return 0;
2825
2826 /* Finally compare the string on either side of the
2827 * wildcard */
2828 prefixlen = pattern_wildcard - pattern;
2829 suffixlen = pattern_left_label_end - (pattern_wildcard + 1);
Emeric Bruna848dae2013-10-08 11:27:28 +02002830 if ((prefixlen && (memcmp(pattern, hostname, prefixlen) != 0))
2831 || (suffixlen && (memcmp(pattern_wildcard + 1, hostname_left_label_end - suffixlen, suffixlen) != 0)))
Evan Broderbe554312013-06-27 00:05:25 -07002832 return 0;
2833
2834 return 1;
2835}
2836
2837static int ssl_sock_srv_verifycbk(int ok, X509_STORE_CTX *ctx)
2838{
2839 SSL *ssl;
2840 struct connection *conn;
2841 char *servername;
2842
2843 int depth;
2844 X509 *cert;
2845 STACK_OF(GENERAL_NAME) *alt_names;
2846 int i;
2847 X509_NAME *cert_subject;
2848 char *str;
2849
2850 if (ok == 0)
2851 return ok;
2852
2853 ssl = X509_STORE_CTX_get_ex_data(ctx, SSL_get_ex_data_X509_STORE_CTX_idx());
Vincent Bernat3c2f2f22016-04-03 13:48:42 +02002854 conn = SSL_get_app_data(ssl);
Evan Broderbe554312013-06-27 00:05:25 -07002855
2856 servername = objt_server(conn->target)->ssl_ctx.verify_host;
2857
2858 /* We only need to verify the CN on the actual server cert,
2859 * not the indirect CAs */
2860 depth = X509_STORE_CTX_get_error_depth(ctx);
2861 if (depth != 0)
2862 return ok;
2863
2864 /* At this point, the cert is *not* OK unless we can find a
2865 * hostname match */
2866 ok = 0;
2867
2868 cert = X509_STORE_CTX_get_current_cert(ctx);
2869 /* It seems like this might happen if verify peer isn't set */
2870 if (!cert)
2871 return ok;
2872
2873 alt_names = X509_get_ext_d2i(cert, NID_subject_alt_name, NULL, NULL);
2874 if (alt_names) {
2875 for (i = 0; !ok && i < sk_GENERAL_NAME_num(alt_names); i++) {
2876 GENERAL_NAME *name = sk_GENERAL_NAME_value(alt_names, i);
2877 if (name->type == GEN_DNS) {
Emeric Bruna33410c2013-09-17 15:47:48 +02002878#if OPENSSL_VERSION_NUMBER < 0x00907000L
2879 if (ASN1_STRING_to_UTF8((unsigned char **)&str, name->d.ia5) >= 0) {
2880#else
Evan Broderbe554312013-06-27 00:05:25 -07002881 if (ASN1_STRING_to_UTF8((unsigned char **)&str, name->d.dNSName) >= 0) {
Emeric Bruna33410c2013-09-17 15:47:48 +02002882#endif
Evan Broderbe554312013-06-27 00:05:25 -07002883 ok = ssl_sock_srv_hostcheck(str, servername);
2884 OPENSSL_free(str);
2885 }
2886 }
2887 }
Emeric Brun4ad50a42013-09-17 15:19:54 +02002888 sk_GENERAL_NAME_pop_free(alt_names, GENERAL_NAME_free);
Evan Broderbe554312013-06-27 00:05:25 -07002889 }
2890
2891 cert_subject = X509_get_subject_name(cert);
2892 i = -1;
2893 while (!ok && (i = X509_NAME_get_index_by_NID(cert_subject, NID_commonName, i)) != -1) {
2894 X509_NAME_ENTRY *entry = X509_NAME_get_entry(cert_subject, i);
2895 if (ASN1_STRING_to_UTF8((unsigned char **)&str, entry->value) >= 0) {
2896 ok = ssl_sock_srv_hostcheck(str, servername);
2897 OPENSSL_free(str);
2898 }
2899 }
2900
2901 return ok;
2902}
2903
Emeric Brun94324a42012-10-11 14:00:19 +02002904/* prepare ssl context from servers options. Returns an error count */
2905int ssl_sock_prepare_srv_ctx(struct server *srv, struct proxy *curproxy)
2906{
2907 int cfgerr = 0;
Remi Gacogneaf5c3da2014-05-19 10:29:58 +02002908 long options =
Emeric Brun94324a42012-10-11 14:00:19 +02002909 SSL_OP_ALL | /* all known workarounds for bugs */
2910 SSL_OP_NO_SSLv2 |
2911 SSL_OP_NO_COMPRESSION;
Remi Gacogneaf5c3da2014-05-19 10:29:58 +02002912 long mode =
Emeric Brun94324a42012-10-11 14:00:19 +02002913 SSL_MODE_ENABLE_PARTIAL_WRITE |
2914 SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER |
Willy Tarreau396a1862014-11-13 14:06:52 +01002915 SSL_MODE_RELEASE_BUFFERS |
2916 SSL_MODE_SMALL_BUFFERS;
Emeric Brun850efd52014-01-29 12:24:34 +01002917 int verify = SSL_VERIFY_NONE;
Emeric Brun94324a42012-10-11 14:00:19 +02002918
Thierry Fournier383085f2013-01-24 14:15:43 +01002919 /* Make sure openssl opens /dev/urandom before the chroot */
2920 if (!ssl_initialize_random()) {
2921 Alert("OpenSSL random data generator initialization failed.\n");
2922 cfgerr++;
2923 }
2924
Willy Tarreaufce03112015-01-15 21:32:40 +01002925 /* Automatic memory computations need to know we use SSL there */
2926 global.ssl_used_backend = 1;
2927
2928 /* Initiate SSL context for current server */
Emeric Brun94324a42012-10-11 14:00:19 +02002929 srv->ssl_ctx.reused_sess = NULL;
2930 if (srv->use_ssl)
2931 srv->xprt = &ssl_sock;
2932 if (srv->check.use_ssl)
Cyril Bonté9ce13112014-11-15 22:41:27 +01002933 srv->check.xprt = &ssl_sock;
Emeric Brun94324a42012-10-11 14:00:19 +02002934
2935 srv->ssl_ctx.ctx = SSL_CTX_new(SSLv23_client_method());
2936 if (!srv->ssl_ctx.ctx) {
2937 Alert("config : %s '%s', server '%s': unable to allocate ssl context.\n",
2938 proxy_type_str(curproxy), curproxy->id,
2939 srv->id);
2940 cfgerr++;
2941 return cfgerr;
2942 }
Emeric Bruna7aa3092012-10-26 12:58:00 +02002943 if (srv->ssl_ctx.client_crt) {
2944 if (SSL_CTX_use_PrivateKey_file(srv->ssl_ctx.ctx, srv->ssl_ctx.client_crt, SSL_FILETYPE_PEM) <= 0) {
2945 Alert("config : %s '%s', server '%s': unable to load SSL private key from PEM file '%s'.\n",
2946 proxy_type_str(curproxy), curproxy->id,
2947 srv->id, srv->ssl_ctx.client_crt);
2948 cfgerr++;
2949 }
2950 else if (SSL_CTX_use_certificate_chain_file(srv->ssl_ctx.ctx, srv->ssl_ctx.client_crt) <= 0) {
2951 Alert("config : %s '%s', server '%s': unable to load ssl certificate 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_check_private_key(srv->ssl_ctx.ctx) <= 0) {
2957 Alert("config : %s '%s', server '%s': inconsistencies between private key and certificate loaded from PEM file '%s'.\n",
2958 proxy_type_str(curproxy), curproxy->id,
2959 srv->id, srv->ssl_ctx.client_crt);
2960 cfgerr++;
2961 }
2962 }
Emeric Brun94324a42012-10-11 14:00:19 +02002963
2964 if (srv->ssl_ctx.options & SRV_SSL_O_NO_SSLV3)
2965 options |= SSL_OP_NO_SSLv3;
2966 if (srv->ssl_ctx.options & SRV_SSL_O_NO_TLSV10)
2967 options |= SSL_OP_NO_TLSv1;
2968 if (srv->ssl_ctx.options & SRV_SSL_O_NO_TLSV11)
2969 options |= SSL_OP_NO_TLSv1_1;
2970 if (srv->ssl_ctx.options & SRV_SSL_O_NO_TLSV12)
2971 options |= SSL_OP_NO_TLSv1_2;
Emeric Brunf9c5c472012-10-11 15:28:34 +02002972 if (srv->ssl_ctx.options & SRV_SSL_O_NO_TLS_TICKETS)
2973 options |= SSL_OP_NO_TICKET;
Jérémie Courrèges-Anglas17c3f622015-07-25 16:50:52 -06002974 if (srv->ssl_ctx.options & SRV_SSL_O_USE_SSLV3) {
2975#ifndef OPENSSL_NO_SSL3
Emeric Brun94324a42012-10-11 14:00:19 +02002976 SSL_CTX_set_ssl_version(srv->ssl_ctx.ctx, SSLv3_client_method());
Jérémie Courrèges-Anglas17c3f622015-07-25 16:50:52 -06002977#else
Thierry FOURNIERbc965342015-08-26 08:21:26 +02002978 Alert("SSLv3 support requested but unavailable.\n");
Jérémie Courrèges-Anglas17c3f622015-07-25 16:50:52 -06002979 cfgerr++;
2980#endif
2981 }
Emeric Brun94324a42012-10-11 14:00:19 +02002982 if (srv->ssl_ctx.options & SRV_SSL_O_USE_TLSV10)
2983 SSL_CTX_set_ssl_version(srv->ssl_ctx.ctx, TLSv1_client_method());
2984#if SSL_OP_NO_TLSv1_1
2985 if (srv->ssl_ctx.options & SRV_SSL_O_USE_TLSV11)
2986 SSL_CTX_set_ssl_version(srv->ssl_ctx.ctx, TLSv1_1_client_method());
2987#endif
2988#if SSL_OP_NO_TLSv1_2
2989 if (srv->ssl_ctx.options & SRV_SSL_O_USE_TLSV12)
2990 SSL_CTX_set_ssl_version(srv->ssl_ctx.ctx, TLSv1_2_client_method());
2991#endif
2992
2993 SSL_CTX_set_options(srv->ssl_ctx.ctx, options);
2994 SSL_CTX_set_mode(srv->ssl_ctx.ctx, mode);
Emeric Brun850efd52014-01-29 12:24:34 +01002995
2996 if (global.ssl_server_verify == SSL_SERVER_VERIFY_REQUIRED)
2997 verify = SSL_VERIFY_PEER;
2998
2999 switch (srv->ssl_ctx.verify) {
3000 case SSL_SOCK_VERIFY_NONE:
3001 verify = SSL_VERIFY_NONE;
3002 break;
3003 case SSL_SOCK_VERIFY_REQUIRED:
3004 verify = SSL_VERIFY_PEER;
3005 break;
3006 }
Evan Broderbe554312013-06-27 00:05:25 -07003007 SSL_CTX_set_verify(srv->ssl_ctx.ctx,
Emeric Brun850efd52014-01-29 12:24:34 +01003008 verify,
Evan Broderbe554312013-06-27 00:05:25 -07003009 srv->ssl_ctx.verify_host ? ssl_sock_srv_verifycbk : NULL);
Emeric Brun850efd52014-01-29 12:24:34 +01003010 if (verify & SSL_VERIFY_PEER) {
Emeric Brunef42d922012-10-11 16:11:36 +02003011 if (srv->ssl_ctx.ca_file) {
3012 /* load CAfile to verify */
3013 if (!SSL_CTX_load_verify_locations(srv->ssl_ctx.ctx, srv->ssl_ctx.ca_file, NULL)) {
Willy Tarreau07ba08b2014-02-16 19:22:08 +01003014 Alert("Proxy '%s', server '%s' [%s:%d] unable to load CA file '%s'.\n",
Emeric Brunef42d922012-10-11 16:11:36 +02003015 curproxy->id, srv->id,
3016 srv->conf.file, srv->conf.line, srv->ssl_ctx.ca_file);
3017 cfgerr++;
3018 }
3019 }
Emeric Brun850efd52014-01-29 12:24:34 +01003020 else {
3021 if (global.ssl_server_verify == SSL_SERVER_VERIFY_REQUIRED)
Willy Tarreau07ba08b2014-02-16 19:22:08 +01003022 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 +01003023 curproxy->id, srv->id,
3024 srv->conf.file, srv->conf.line);
3025 else
Willy Tarreau07ba08b2014-02-16 19:22:08 +01003026 Alert("Proxy '%s', server '%s' [%s:%d] verify is enabled but no CA file specified.\n",
Emeric Brun850efd52014-01-29 12:24:34 +01003027 curproxy->id, srv->id,
3028 srv->conf.file, srv->conf.line);
3029 cfgerr++;
3030 }
Emeric Brunef42d922012-10-11 16:11:36 +02003031#ifdef X509_V_FLAG_CRL_CHECK
3032 if (srv->ssl_ctx.crl_file) {
3033 X509_STORE *store = SSL_CTX_get_cert_store(srv->ssl_ctx.ctx);
3034
3035 if (!store || !X509_STORE_load_locations(store, srv->ssl_ctx.crl_file, NULL)) {
Willy Tarreau07ba08b2014-02-16 19:22:08 +01003036 Alert("Proxy '%s', server '%s' [%s:%d] unable to configure CRL file '%s'.\n",
Emeric Brunef42d922012-10-11 16:11:36 +02003037 curproxy->id, srv->id,
3038 srv->conf.file, srv->conf.line, srv->ssl_ctx.crl_file);
3039 cfgerr++;
3040 }
3041 else {
3042 X509_STORE_set_flags(store, X509_V_FLAG_CRL_CHECK|X509_V_FLAG_CRL_CHECK_ALL);
3043 }
3044 }
3045#endif
3046 }
3047
Emeric Brun4f65bff2012-11-16 15:11:00 +01003048 if (global.tune.ssllifetime)
3049 SSL_CTX_set_timeout(srv->ssl_ctx.ctx, global.tune.ssllifetime);
3050
Emeric Brun94324a42012-10-11 14:00:19 +02003051 SSL_CTX_set_session_cache_mode(srv->ssl_ctx.ctx, SSL_SESS_CACHE_OFF);
3052 if (srv->ssl_ctx.ciphers &&
3053 !SSL_CTX_set_cipher_list(srv->ssl_ctx.ctx, srv->ssl_ctx.ciphers)) {
3054 Alert("Proxy '%s', server '%s' [%s:%d] : unable to set SSL cipher list to '%s'.\n",
3055 curproxy->id, srv->id,
3056 srv->conf.file, srv->conf.line, srv->ssl_ctx.ciphers);
3057 cfgerr++;
3058 }
3059
3060 return cfgerr;
3061}
3062
Willy Tarreau2a65ff02012-09-13 17:54:29 +02003063/* Walks down the two trees in bind_conf and prepares all certs. The pointer may
Emeric Brunfc0421f2012-09-07 17:30:07 +02003064 * be NULL, in which case nothing is done. Returns the number of errors
3065 * encountered.
3066 */
Willy Tarreau2a65ff02012-09-13 17:54:29 +02003067int ssl_sock_prepare_all_ctx(struct bind_conf *bind_conf, struct proxy *px)
Emeric Brunfc0421f2012-09-07 17:30:07 +02003068{
3069 struct ebmb_node *node;
3070 struct sni_ctx *sni;
3071 int err = 0;
3072
Willy Tarreau2a65ff02012-09-13 17:54:29 +02003073 if (!bind_conf || !bind_conf->is_ssl)
Emeric Brunfc0421f2012-09-07 17:30:07 +02003074 return 0;
3075
Willy Tarreaufce03112015-01-15 21:32:40 +01003076 /* Automatic memory computations need to know we use SSL there */
3077 global.ssl_used_frontend = 1;
3078
Emeric Brun0bed9942014-10-30 19:25:24 +01003079 if (bind_conf->default_ctx)
3080 err += ssl_sock_prepare_ctx(bind_conf, bind_conf->default_ctx, px);
3081
Willy Tarreau2a65ff02012-09-13 17:54:29 +02003082 node = ebmb_first(&bind_conf->sni_ctx);
Emeric Brunfc0421f2012-09-07 17:30:07 +02003083 while (node) {
3084 sni = ebmb_entry(node, struct sni_ctx, name);
Emeric Brun0bed9942014-10-30 19:25:24 +01003085 if (!sni->order && sni->ctx != bind_conf->default_ctx)
3086 /* only initialize the CTX on its first occurrence and
3087 if it is not the default_ctx */
Willy Tarreau2a65ff02012-09-13 17:54:29 +02003088 err += ssl_sock_prepare_ctx(bind_conf, sni->ctx, px);
Emeric Brunfc0421f2012-09-07 17:30:07 +02003089 node = ebmb_next(node);
3090 }
3091
Willy Tarreau2a65ff02012-09-13 17:54:29 +02003092 node = ebmb_first(&bind_conf->sni_w_ctx);
Emeric Brunfc0421f2012-09-07 17:30:07 +02003093 while (node) {
3094 sni = ebmb_entry(node, struct sni_ctx, name);
Emeric Brun0bed9942014-10-30 19:25:24 +01003095 if (!sni->order && sni->ctx != bind_conf->default_ctx)
3096 /* only initialize the CTX on its first occurrence and
3097 if it is not the default_ctx */
Willy Tarreau2a65ff02012-09-13 17:54:29 +02003098 err += ssl_sock_prepare_ctx(bind_conf, sni->ctx, px);
Emeric Brunfc0421f2012-09-07 17:30:07 +02003099 node = ebmb_next(node);
3100 }
3101 return err;
3102}
3103
Christopher Faulet77fe80c2015-07-29 13:02:40 +02003104
3105/* release ssl context allocated for servers. */
3106void ssl_sock_free_srv_ctx(struct server *srv)
3107{
3108 if (srv->ssl_ctx.ctx)
3109 SSL_CTX_free(srv->ssl_ctx.ctx);
3110}
3111
Willy Tarreau2a65ff02012-09-13 17:54:29 +02003112/* Walks down the two trees in bind_conf and frees all the certs. The pointer may
Emeric Brunfc0421f2012-09-07 17:30:07 +02003113 * be NULL, in which case nothing is done. The default_ctx is nullified too.
3114 */
Willy Tarreau2a65ff02012-09-13 17:54:29 +02003115void ssl_sock_free_all_ctx(struct bind_conf *bind_conf)
Emeric Brunfc0421f2012-09-07 17:30:07 +02003116{
3117 struct ebmb_node *node, *back;
3118 struct sni_ctx *sni;
3119
Willy Tarreau2a65ff02012-09-13 17:54:29 +02003120 if (!bind_conf || !bind_conf->is_ssl)
Emeric Brunfc0421f2012-09-07 17:30:07 +02003121 return;
3122
Willy Tarreau2a65ff02012-09-13 17:54:29 +02003123 node = ebmb_first(&bind_conf->sni_ctx);
Emeric Brunfc0421f2012-09-07 17:30:07 +02003124 while (node) {
3125 sni = ebmb_entry(node, struct sni_ctx, name);
3126 back = ebmb_next(node);
3127 ebmb_delete(node);
3128 if (!sni->order) /* only free the CTX on its first occurrence */
3129 SSL_CTX_free(sni->ctx);
3130 free(sni);
3131 node = back;
3132 }
3133
Willy Tarreau2a65ff02012-09-13 17:54:29 +02003134 node = ebmb_first(&bind_conf->sni_w_ctx);
Emeric Brunfc0421f2012-09-07 17:30:07 +02003135 while (node) {
3136 sni = ebmb_entry(node, struct sni_ctx, name);
3137 back = ebmb_next(node);
3138 ebmb_delete(node);
3139 if (!sni->order) /* only free the CTX on its first occurrence */
3140 SSL_CTX_free(sni->ctx);
3141 free(sni);
3142 node = back;
3143 }
3144
Willy Tarreau2a65ff02012-09-13 17:54:29 +02003145 bind_conf->default_ctx = NULL;
Emeric Brune1f38db2012-09-03 20:36:47 +02003146}
3147
Christopher Faulet31af49d2015-06-09 17:29:50 +02003148/* Load CA cert file and private key used to generate certificates */
3149int
3150ssl_sock_load_ca(struct bind_conf *bind_conf, struct proxy *px)
3151{
3152 FILE *fp;
3153 X509 *cacert = NULL;
3154 EVP_PKEY *capkey = NULL;
3155 int err = 0;
3156
3157 if (!bind_conf || !bind_conf->generate_certs)
3158 return err;
3159
Willy Tarreaua84c2672015-10-09 12:10:13 +02003160#ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME
Christopher Fauletd2cab922015-07-28 16:03:47 +02003161 if (global.tune.ssl_ctx_cache)
3162 ssl_ctx_lru_tree = lru64_new(global.tune.ssl_ctx_cache);
3163 ssl_ctx_lru_seed = (unsigned int)time(NULL);
Willy Tarreaua84c2672015-10-09 12:10:13 +02003164#endif
Christopher Fauletd2cab922015-07-28 16:03:47 +02003165
Christopher Faulet31af49d2015-06-09 17:29:50 +02003166 if (!bind_conf->ca_sign_file) {
3167 Alert("Proxy '%s': cannot enable certificate generation, "
3168 "no CA certificate File configured at [%s:%d].\n",
3169 px->id, bind_conf->file, bind_conf->line);
Christopher Faulet31af49d2015-06-09 17:29:50 +02003170 goto load_error;
Christopher Fauletc6f02fb2015-10-09 10:53:31 +02003171 }
Christopher Faulet31af49d2015-06-09 17:29:50 +02003172
3173 /* read in the CA certificate */
3174 if (!(fp = fopen(bind_conf->ca_sign_file, "r"))) {
3175 Alert("Proxy '%s': Failed to read CA certificate file '%s' at [%s:%d].\n",
3176 px->id, bind_conf->ca_sign_file, bind_conf->file, bind_conf->line);
Christopher Faulet31af49d2015-06-09 17:29:50 +02003177 goto load_error;
3178 }
3179 if (!(cacert = PEM_read_X509(fp, NULL, NULL, NULL))) {
3180 Alert("Proxy '%s': Failed to read CA certificate file '%s' at [%s:%d].\n",
3181 px->id, bind_conf->ca_sign_file, bind_conf->file, bind_conf->line);
Christopher Fauletc6f02fb2015-10-09 10:53:31 +02003182 goto read_error;
Christopher Faulet31af49d2015-06-09 17:29:50 +02003183 }
Christopher Fauletc6f02fb2015-10-09 10:53:31 +02003184 rewind(fp);
Christopher Faulet31af49d2015-06-09 17:29:50 +02003185 if (!(capkey = PEM_read_PrivateKey(fp, NULL, NULL, bind_conf->ca_sign_pass))) {
3186 Alert("Proxy '%s': Failed to read CA private key 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 Faulet31af49d2015-06-09 17:29:50 +02003190
Christopher Fauletc6f02fb2015-10-09 10:53:31 +02003191 fclose (fp);
Christopher Faulet31af49d2015-06-09 17:29:50 +02003192 bind_conf->ca_sign_cert = cacert;
3193 bind_conf->ca_sign_pkey = capkey;
3194 return err;
3195
Christopher Fauletc6f02fb2015-10-09 10:53:31 +02003196 read_error:
3197 fclose (fp);
Christopher Faulet31af49d2015-06-09 17:29:50 +02003198 if (capkey) EVP_PKEY_free(capkey);
3199 if (cacert) X509_free(cacert);
Christopher Fauletc6f02fb2015-10-09 10:53:31 +02003200 load_error:
3201 bind_conf->generate_certs = 0;
3202 err++;
Christopher Faulet31af49d2015-06-09 17:29:50 +02003203 return err;
3204}
3205
3206/* Release CA cert and private key used to generate certificated */
3207void
3208ssl_sock_free_ca(struct bind_conf *bind_conf)
3209{
3210 if (!bind_conf)
3211 return;
3212
3213 if (bind_conf->ca_sign_pkey)
3214 EVP_PKEY_free(bind_conf->ca_sign_pkey);
3215 if (bind_conf->ca_sign_cert)
3216 X509_free(bind_conf->ca_sign_cert);
3217}
3218
Emeric Brun46591952012-05-18 15:47:34 +02003219/*
3220 * This function is called if SSL * context is not yet allocated. The function
3221 * is designed to be called before any other data-layer operation and sets the
3222 * handshake flag on the connection. It is safe to call it multiple times.
3223 * It returns 0 on success and -1 in error case.
3224 */
3225static int ssl_sock_init(struct connection *conn)
3226{
3227 /* already initialized */
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02003228 if (conn->xprt_ctx)
Emeric Brun46591952012-05-18 15:47:34 +02003229 return 0;
3230
Willy Tarreau3c728722014-01-23 13:50:42 +01003231 if (!conn_ctrl_ready(conn))
Willy Tarreauf79c8172013-10-21 16:30:56 +02003232 return 0;
3233
Willy Tarreau20879a02012-12-03 16:32:10 +01003234 if (global.maxsslconn && sslconns >= global.maxsslconn) {
3235 conn->err_code = CO_ER_SSL_TOO_MANY;
Willy Tarreau403edff2012-09-06 11:58:37 +02003236 return -1;
Willy Tarreau20879a02012-12-03 16:32:10 +01003237 }
Willy Tarreau403edff2012-09-06 11:58:37 +02003238
Emeric Brun46591952012-05-18 15:47:34 +02003239 /* If it is in client mode initiate SSL session
3240 in connect state otherwise accept state */
Willy Tarreau3fdb3662012-11-12 00:42:33 +01003241 if (objt_server(conn->target)) {
Willy Tarreaufba03cd2014-11-13 13:48:58 +01003242 int may_retry = 1;
3243
3244 retry_connect:
Emeric Brun46591952012-05-18 15:47:34 +02003245 /* Alloc a new SSL session ctx */
Willy Tarreau3fdb3662012-11-12 00:42:33 +01003246 conn->xprt_ctx = SSL_new(objt_server(conn->target)->ssl_ctx.ctx);
Willy Tarreau20879a02012-12-03 16:32:10 +01003247 if (!conn->xprt_ctx) {
Willy Tarreaufba03cd2014-11-13 13:48:58 +01003248 if (may_retry--) {
3249 pool_gc2();
3250 goto retry_connect;
3251 }
Willy Tarreau20879a02012-12-03 16:32:10 +01003252 conn->err_code = CO_ER_SSL_NO_MEM;
Emeric Brun46591952012-05-18 15:47:34 +02003253 return -1;
Willy Tarreau20879a02012-12-03 16:32:10 +01003254 }
Emeric Brun46591952012-05-18 15:47:34 +02003255
Emeric Brun46591952012-05-18 15:47:34 +02003256 /* set fd on SSL session context */
Emeric Brun55476152014-11-12 17:35:37 +01003257 if (!SSL_set_fd(conn->xprt_ctx, conn->t.sock.fd)) {
3258 SSL_free(conn->xprt_ctx);
3259 conn->xprt_ctx = NULL;
Willy Tarreaufba03cd2014-11-13 13:48:58 +01003260 if (may_retry--) {
3261 pool_gc2();
3262 goto retry_connect;
3263 }
Emeric Brun55476152014-11-12 17:35:37 +01003264 conn->err_code = CO_ER_SSL_NO_MEM;
3265 return -1;
3266 }
Emeric Brun46591952012-05-18 15:47:34 +02003267
Evan Broderbe554312013-06-27 00:05:25 -07003268 /* set connection pointer */
Emeric Brun55476152014-11-12 17:35:37 +01003269 if (!SSL_set_app_data(conn->xprt_ctx, conn)) {
3270 SSL_free(conn->xprt_ctx);
3271 conn->xprt_ctx = NULL;
Willy Tarreaufba03cd2014-11-13 13:48:58 +01003272 if (may_retry--) {
3273 pool_gc2();
3274 goto retry_connect;
3275 }
Emeric Brun55476152014-11-12 17:35:37 +01003276 conn->err_code = CO_ER_SSL_NO_MEM;
3277 return -1;
3278 }
3279
3280 SSL_set_connect_state(conn->xprt_ctx);
3281 if (objt_server(conn->target)->ssl_ctx.reused_sess) {
3282 if(!SSL_set_session(conn->xprt_ctx, objt_server(conn->target)->ssl_ctx.reused_sess)) {
3283 SSL_SESSION_free(objt_server(conn->target)->ssl_ctx.reused_sess);
3284 objt_server(conn->target)->ssl_ctx.reused_sess = NULL;
3285 }
3286 }
Evan Broderbe554312013-06-27 00:05:25 -07003287
Emeric Brun46591952012-05-18 15:47:34 +02003288 /* leave init state and start handshake */
Willy Tarreau05737472012-09-04 08:03:39 +02003289 conn->flags |= CO_FL_SSL_WAIT_HS | CO_FL_WAIT_L6_CONN;
Willy Tarreau403edff2012-09-06 11:58:37 +02003290
3291 sslconns++;
Willy Tarreau71b734c2014-01-28 15:19:44 +01003292 totalsslconns++;
Emeric Brun46591952012-05-18 15:47:34 +02003293 return 0;
3294 }
Willy Tarreau3fdb3662012-11-12 00:42:33 +01003295 else if (objt_listener(conn->target)) {
Willy Tarreaufba03cd2014-11-13 13:48:58 +01003296 int may_retry = 1;
3297
3298 retry_accept:
Emeric Brun46591952012-05-18 15:47:34 +02003299 /* Alloc a new SSL session ctx */
Willy Tarreau3fdb3662012-11-12 00:42:33 +01003300 conn->xprt_ctx = SSL_new(objt_listener(conn->target)->bind_conf->default_ctx);
Willy Tarreau20879a02012-12-03 16:32:10 +01003301 if (!conn->xprt_ctx) {
Willy Tarreaufba03cd2014-11-13 13:48:58 +01003302 if (may_retry--) {
3303 pool_gc2();
3304 goto retry_accept;
3305 }
Willy Tarreau20879a02012-12-03 16:32:10 +01003306 conn->err_code = CO_ER_SSL_NO_MEM;
Emeric Brun46591952012-05-18 15:47:34 +02003307 return -1;
Willy Tarreau20879a02012-12-03 16:32:10 +01003308 }
Emeric Brun46591952012-05-18 15:47:34 +02003309
Emeric Brun46591952012-05-18 15:47:34 +02003310 /* set fd on SSL session context */
Emeric Brun55476152014-11-12 17:35:37 +01003311 if (!SSL_set_fd(conn->xprt_ctx, conn->t.sock.fd)) {
3312 SSL_free(conn->xprt_ctx);
3313 conn->xprt_ctx = NULL;
Willy Tarreaufba03cd2014-11-13 13:48:58 +01003314 if (may_retry--) {
3315 pool_gc2();
3316 goto retry_accept;
3317 }
Emeric Brun55476152014-11-12 17:35:37 +01003318 conn->err_code = CO_ER_SSL_NO_MEM;
3319 return -1;
3320 }
Emeric Brun46591952012-05-18 15:47:34 +02003321
Emeric Brune1f38db2012-09-03 20:36:47 +02003322 /* set connection pointer */
Emeric Brun55476152014-11-12 17:35:37 +01003323 if (!SSL_set_app_data(conn->xprt_ctx, conn)) {
3324 SSL_free(conn->xprt_ctx);
3325 conn->xprt_ctx = NULL;
Willy Tarreaufba03cd2014-11-13 13:48:58 +01003326 if (may_retry--) {
3327 pool_gc2();
3328 goto retry_accept;
3329 }
Emeric Brun55476152014-11-12 17:35:37 +01003330 conn->err_code = CO_ER_SSL_NO_MEM;
3331 return -1;
3332 }
3333
3334 SSL_set_accept_state(conn->xprt_ctx);
Emeric Brune1f38db2012-09-03 20:36:47 +02003335
Emeric Brun46591952012-05-18 15:47:34 +02003336 /* leave init state and start handshake */
Willy Tarreau05737472012-09-04 08:03:39 +02003337 conn->flags |= CO_FL_SSL_WAIT_HS | CO_FL_WAIT_L6_CONN;
Willy Tarreau403edff2012-09-06 11:58:37 +02003338
3339 sslconns++;
Willy Tarreau71b734c2014-01-28 15:19:44 +01003340 totalsslconns++;
Emeric Brun46591952012-05-18 15:47:34 +02003341 return 0;
3342 }
3343 /* don't know how to handle such a target */
Willy Tarreau20879a02012-12-03 16:32:10 +01003344 conn->err_code = CO_ER_SSL_NO_TARGET;
Emeric Brun46591952012-05-18 15:47:34 +02003345 return -1;
3346}
3347
3348
3349/* This is the callback which is used when an SSL handshake is pending. It
3350 * updates the FD status if it wants some polling before being called again.
3351 * It returns 0 if it fails in a fatal way or needs to poll to go further,
3352 * otherwise it returns non-zero and removes itself from the connection's
3353 * flags (the bit is provided in <flag> by the caller).
3354 */
3355int ssl_sock_handshake(struct connection *conn, unsigned int flag)
3356{
3357 int ret;
3358
Willy Tarreau3c728722014-01-23 13:50:42 +01003359 if (!conn_ctrl_ready(conn))
Willy Tarreauf79c8172013-10-21 16:30:56 +02003360 return 0;
3361
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02003362 if (!conn->xprt_ctx)
Emeric Brun46591952012-05-18 15:47:34 +02003363 goto out_error;
3364
Emeric Brun674b7432012-11-08 19:21:55 +01003365 /* If we use SSL_do_handshake to process a reneg initiated by
3366 * the remote peer, it sometimes returns SSL_ERROR_SSL.
3367 * Usually SSL_write and SSL_read are used and process implicitly
3368 * the reneg handshake.
3369 * Here we use SSL_peek as a workaround for reneg.
3370 */
3371 if ((conn->flags & CO_FL_CONNECTED) && SSL_renegotiate_pending(conn->xprt_ctx)) {
3372 char c;
3373
3374 ret = SSL_peek(conn->xprt_ctx, &c, 1);
3375 if (ret <= 0) {
3376 /* handshake may have not been completed, let's find why */
3377 ret = SSL_get_error(conn->xprt_ctx, ret);
3378 if (ret == SSL_ERROR_WANT_WRITE) {
3379 /* SSL handshake needs to write, L4 connection may not be ready */
3380 __conn_sock_stop_recv(conn);
Willy Tarreaue1f50c42014-01-22 20:02:06 +01003381 __conn_sock_want_send(conn);
3382 fd_cant_send(conn->t.sock.fd);
Emeric Brun674b7432012-11-08 19:21:55 +01003383 return 0;
3384 }
3385 else if (ret == SSL_ERROR_WANT_READ) {
3386 /* handshake may have been completed but we have
3387 * no more data to read.
3388 */
3389 if (!SSL_renegotiate_pending(conn->xprt_ctx)) {
3390 ret = 1;
3391 goto reneg_ok;
3392 }
3393 /* SSL handshake needs to read, L4 connection is ready */
3394 if (conn->flags & CO_FL_WAIT_L4_CONN)
3395 conn->flags &= ~CO_FL_WAIT_L4_CONN;
3396 __conn_sock_stop_send(conn);
Willy Tarreaue1f50c42014-01-22 20:02:06 +01003397 __conn_sock_want_recv(conn);
3398 fd_cant_recv(conn->t.sock.fd);
Emeric Brun674b7432012-11-08 19:21:55 +01003399 return 0;
3400 }
3401 else if (ret == SSL_ERROR_SYSCALL) {
3402 /* if errno is null, then connection was successfully established */
3403 if (!errno && conn->flags & CO_FL_WAIT_L4_CONN)
3404 conn->flags &= ~CO_FL_WAIT_L4_CONN;
Willy Tarreau20879a02012-12-03 16:32:10 +01003405 if (!conn->err_code) {
Emeric Brun29f037d2014-04-25 19:05:36 +02003406 if (!((SSL *)conn->xprt_ctx)->packet_length) {
3407 if (!errno) {
3408 if (conn->xprt_st & SSL_SOCK_RECV_HEARTBEAT)
3409 conn->err_code = CO_ER_SSL_HANDSHAKE_HB;
3410 else
3411 conn->err_code = CO_ER_SSL_EMPTY;
3412 }
3413 else {
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_ABORT;
3418 }
3419 }
3420 else {
3421 if (conn->xprt_st & SSL_SOCK_RECV_HEARTBEAT)
3422 conn->err_code = CO_ER_SSL_HANDSHAKE_HB;
Willy Tarreau20879a02012-12-03 16:32:10 +01003423 else
Emeric Brun29f037d2014-04-25 19:05:36 +02003424 conn->err_code = CO_ER_SSL_HANDSHAKE;
3425 }
Willy Tarreau20879a02012-12-03 16:32:10 +01003426 }
Emeric Brun674b7432012-11-08 19:21:55 +01003427 goto out_error;
3428 }
3429 else {
3430 /* Fail on all other handshake errors */
3431 /* Note: OpenSSL may leave unread bytes in the socket's
3432 * buffer, causing an RST to be emitted upon close() on
3433 * TCP sockets. We first try to drain possibly pending
3434 * data to avoid this as much as possible.
3435 */
Willy Tarreaud85c4852015-03-13 00:40:28 +01003436 conn_sock_drain(conn);
Willy Tarreau20879a02012-12-03 16:32:10 +01003437 if (!conn->err_code)
Willy Tarreauf51c6982014-04-25 20:02:39 +02003438 conn->err_code = (conn->xprt_st & SSL_SOCK_RECV_HEARTBEAT) ?
3439 CO_ER_SSL_KILLED_HB : CO_ER_SSL_HANDSHAKE;
Emeric Brun674b7432012-11-08 19:21:55 +01003440 goto out_error;
3441 }
3442 }
3443 /* read some data: consider handshake completed */
3444 goto reneg_ok;
3445 }
3446
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02003447 ret = SSL_do_handshake(conn->xprt_ctx);
Emeric Brun46591952012-05-18 15:47:34 +02003448 if (ret != 1) {
3449 /* handshake did not complete, let's find why */
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02003450 ret = SSL_get_error(conn->xprt_ctx, ret);
Emeric Brun46591952012-05-18 15:47:34 +02003451
3452 if (ret == SSL_ERROR_WANT_WRITE) {
3453 /* SSL handshake needs to write, L4 connection may not be ready */
3454 __conn_sock_stop_recv(conn);
Willy Tarreaue1f50c42014-01-22 20:02:06 +01003455 __conn_sock_want_send(conn);
3456 fd_cant_send(conn->t.sock.fd);
Emeric Brun46591952012-05-18 15:47:34 +02003457 return 0;
3458 }
3459 else if (ret == SSL_ERROR_WANT_READ) {
3460 /* SSL handshake needs to read, L4 connection is ready */
3461 if (conn->flags & CO_FL_WAIT_L4_CONN)
3462 conn->flags &= ~CO_FL_WAIT_L4_CONN;
3463 __conn_sock_stop_send(conn);
Willy Tarreaue1f50c42014-01-22 20:02:06 +01003464 __conn_sock_want_recv(conn);
3465 fd_cant_recv(conn->t.sock.fd);
Emeric Brun46591952012-05-18 15:47:34 +02003466 return 0;
3467 }
Willy Tarreau89230192012-09-28 20:22:13 +02003468 else if (ret == SSL_ERROR_SYSCALL) {
3469 /* if errno is null, then connection was successfully established */
3470 if (!errno && conn->flags & CO_FL_WAIT_L4_CONN)
3471 conn->flags &= ~CO_FL_WAIT_L4_CONN;
Willy Tarreau20879a02012-12-03 16:32:10 +01003472
Emeric Brun29f037d2014-04-25 19:05:36 +02003473 if (!((SSL *)conn->xprt_ctx)->packet_length) {
3474 if (!errno) {
3475 if (conn->xprt_st & SSL_SOCK_RECV_HEARTBEAT)
3476 conn->err_code = CO_ER_SSL_HANDSHAKE_HB;
3477 else
3478 conn->err_code = CO_ER_SSL_EMPTY;
3479 }
3480 else {
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_ABORT;
3485 }
3486 }
3487 else {
3488 if (conn->xprt_st & SSL_SOCK_RECV_HEARTBEAT)
3489 conn->err_code = CO_ER_SSL_HANDSHAKE_HB;
Willy Tarreau20879a02012-12-03 16:32:10 +01003490 else
Emeric Brun29f037d2014-04-25 19:05:36 +02003491 conn->err_code = CO_ER_SSL_HANDSHAKE;
3492 }
Willy Tarreau89230192012-09-28 20:22:13 +02003493 goto out_error;
3494 }
Emeric Brun46591952012-05-18 15:47:34 +02003495 else {
3496 /* Fail on all other handshake errors */
Willy Tarreau566dc552012-10-19 20:52:18 +02003497 /* Note: OpenSSL may leave unread bytes in the socket's
3498 * buffer, causing an RST to be emitted upon close() on
3499 * TCP sockets. We first try to drain possibly pending
3500 * data to avoid this as much as possible.
3501 */
Willy Tarreaud85c4852015-03-13 00:40:28 +01003502 conn_sock_drain(conn);
Willy Tarreau20879a02012-12-03 16:32:10 +01003503 if (!conn->err_code)
Willy Tarreauf51c6982014-04-25 20:02:39 +02003504 conn->err_code = (conn->xprt_st & SSL_SOCK_RECV_HEARTBEAT) ?
3505 CO_ER_SSL_KILLED_HB : CO_ER_SSL_HANDSHAKE;
Emeric Brun46591952012-05-18 15:47:34 +02003506 goto out_error;
3507 }
3508 }
3509
Emeric Brun674b7432012-11-08 19:21:55 +01003510reneg_ok:
Emeric Brun46591952012-05-18 15:47:34 +02003511 /* Handshake succeeded */
Willy Tarreau0c9c2722014-05-28 12:28:58 +02003512 if (!SSL_session_reused(conn->xprt_ctx)) {
3513 if (objt_server(conn->target)) {
3514 update_freq_ctr(&global.ssl_be_keys_per_sec, 1);
3515 if (global.ssl_be_keys_per_sec.curr_ctr > global.ssl_be_keys_max)
3516 global.ssl_be_keys_max = global.ssl_be_keys_per_sec.curr_ctr;
3517
Emeric Brun46591952012-05-18 15:47:34 +02003518 /* check if session was reused, if not store current session on server for reuse */
Willy Tarreau3fdb3662012-11-12 00:42:33 +01003519 if (objt_server(conn->target)->ssl_ctx.reused_sess)
3520 SSL_SESSION_free(objt_server(conn->target)->ssl_ctx.reused_sess);
Emeric Brun46591952012-05-18 15:47:34 +02003521
Willy Tarreau2a3fb1c2015-02-05 16:47:07 +01003522 if (!(objt_server(conn->target)->ssl_ctx.options & SRV_SSL_O_NO_REUSE))
3523 objt_server(conn->target)->ssl_ctx.reused_sess = SSL_get1_session(conn->xprt_ctx);
Emeric Brun46591952012-05-18 15:47:34 +02003524 }
Willy Tarreau0c9c2722014-05-28 12:28:58 +02003525 else {
3526 update_freq_ctr(&global.ssl_fe_keys_per_sec, 1);
3527 if (global.ssl_fe_keys_per_sec.curr_ctr > global.ssl_fe_keys_max)
3528 global.ssl_fe_keys_max = global.ssl_fe_keys_per_sec.curr_ctr;
3529 }
Emeric Brun46591952012-05-18 15:47:34 +02003530 }
3531
3532 /* The connection is now established at both layers, it's time to leave */
3533 conn->flags &= ~(flag | CO_FL_WAIT_L4_CONN | CO_FL_WAIT_L6_CONN);
3534 return 1;
3535
3536 out_error:
Emeric Brun644cde02012-12-14 11:21:13 +01003537 /* Clear openssl global errors stack */
3538 ERR_clear_error();
3539
Emeric Brun9fa89732012-10-04 17:09:56 +02003540 /* free resumed session if exists */
Willy Tarreau3fdb3662012-11-12 00:42:33 +01003541 if (objt_server(conn->target) && objt_server(conn->target)->ssl_ctx.reused_sess) {
3542 SSL_SESSION_free(objt_server(conn->target)->ssl_ctx.reused_sess);
3543 objt_server(conn->target)->ssl_ctx.reused_sess = NULL;
Emeric Brun9fa89732012-10-04 17:09:56 +02003544 }
3545
Emeric Brun46591952012-05-18 15:47:34 +02003546 /* Fail on all other handshake errors */
3547 conn->flags |= CO_FL_ERROR;
Willy Tarreau20879a02012-12-03 16:32:10 +01003548 if (!conn->err_code)
3549 conn->err_code = CO_ER_SSL_HANDSHAKE;
Emeric Brun46591952012-05-18 15:47:34 +02003550 return 0;
3551}
3552
3553/* Receive up to <count> bytes from connection <conn>'s socket and store them
Willy Tarreauabf08d92014-01-14 11:31:27 +01003554 * into buffer <buf>. Only one call to recv() is performed, unless the
Emeric Brun46591952012-05-18 15:47:34 +02003555 * buffer wraps, in which case a second call may be performed. The connection's
3556 * flags are updated with whatever special event is detected (error, read0,
3557 * empty). The caller is responsible for taking care of those events and
3558 * avoiding the call if inappropriate. The function does not call the
3559 * connection's polling update function, so the caller is responsible for this.
3560 */
3561static int ssl_sock_to_buf(struct connection *conn, struct buffer *buf, int count)
3562{
3563 int ret, done = 0;
Willy Tarreauabf08d92014-01-14 11:31:27 +01003564 int try;
Emeric Brun46591952012-05-18 15:47:34 +02003565
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02003566 if (!conn->xprt_ctx)
Emeric Brun46591952012-05-18 15:47:34 +02003567 goto out_error;
3568
3569 if (conn->flags & CO_FL_HANDSHAKE)
3570 /* a handshake was requested */
3571 return 0;
3572
Willy Tarreauabf08d92014-01-14 11:31:27 +01003573 /* let's realign the buffer to optimize I/O */
3574 if (buffer_empty(buf))
Emeric Brun46591952012-05-18 15:47:34 +02003575 buf->p = buf->data;
Emeric Brun46591952012-05-18 15:47:34 +02003576
3577 /* read the largest possible block. For this, we perform only one call
3578 * to recv() unless the buffer wraps and we exactly fill the first hunk,
3579 * in which case we accept to do it once again. A new attempt is made on
3580 * EINTR too.
3581 */
Willy Tarreau00b0fb92014-01-17 11:09:40 +01003582 while (count > 0) {
Willy Tarreauabf08d92014-01-14 11:31:27 +01003583 /* first check if we have some room after p+i */
3584 try = buf->data + buf->size - (buf->p + buf->i);
3585 /* otherwise continue between data and p-o */
3586 if (try <= 0) {
3587 try = buf->p - (buf->data + buf->o);
3588 if (try <= 0)
3589 break;
3590 }
3591 if (try > count)
3592 try = count;
3593
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02003594 ret = SSL_read(conn->xprt_ctx, bi_end(buf), try);
Emeric Brune1f38db2012-09-03 20:36:47 +02003595 if (conn->flags & CO_FL_ERROR) {
3596 /* CO_FL_ERROR may be set by ssl_sock_infocbk */
Emeric Brun644cde02012-12-14 11:21:13 +01003597 goto out_error;
Emeric Brune1f38db2012-09-03 20:36:47 +02003598 }
Emeric Brun46591952012-05-18 15:47:34 +02003599 if (ret > 0) {
3600 buf->i += ret;
3601 done += ret;
3602 if (ret < try)
3603 break;
3604 count -= ret;
Emeric Brun46591952012-05-18 15:47:34 +02003605 }
3606 else if (ret == 0) {
Emeric Brun644cde02012-12-14 11:21:13 +01003607 ret = SSL_get_error(conn->xprt_ctx, ret);
3608 if (ret != SSL_ERROR_ZERO_RETURN) {
Emeric Brun1c646862012-12-14 12:33:41 +01003609 /* error on protocol or underlying transport */
3610 if ((ret != SSL_ERROR_SYSCALL)
3611 || (errno && (errno != EAGAIN)))
3612 conn->flags |= CO_FL_ERROR;
3613
Emeric Brun644cde02012-12-14 11:21:13 +01003614 /* Clear openssl global errors stack */
3615 ERR_clear_error();
3616 }
Emeric Brun46591952012-05-18 15:47:34 +02003617 goto read0;
3618 }
3619 else {
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02003620 ret = SSL_get_error(conn->xprt_ctx, ret);
Emeric Brun46591952012-05-18 15:47:34 +02003621 if (ret == SSL_ERROR_WANT_WRITE) {
Emeric Brun8af8dd12012-11-08 17:56:20 +01003622 /* handshake is running, and it needs to enable write */
Emeric Brun46591952012-05-18 15:47:34 +02003623 conn->flags |= CO_FL_SSL_WAIT_HS;
Emeric Brun8af8dd12012-11-08 17:56:20 +01003624 __conn_sock_want_send(conn);
Emeric Brun46591952012-05-18 15:47:34 +02003625 break;
3626 }
3627 else if (ret == SSL_ERROR_WANT_READ) {
Emeric Brun282a76a2012-11-08 18:02:56 +01003628 if (SSL_renegotiate_pending(conn->xprt_ctx)) {
3629 /* handshake is running, and it may need to re-enable read */
3630 conn->flags |= CO_FL_SSL_WAIT_HS;
3631 __conn_sock_want_recv(conn);
3632 break;
3633 }
Emeric Brun46591952012-05-18 15:47:34 +02003634 /* we need to poll for retry a read later */
Willy Tarreaue1f50c42014-01-22 20:02:06 +01003635 fd_cant_recv(conn->t.sock.fd);
Emeric Brun46591952012-05-18 15:47:34 +02003636 break;
3637 }
3638 /* otherwise it's a real error */
3639 goto out_error;
3640 }
3641 }
3642 return done;
3643
3644 read0:
3645 conn_sock_read0(conn);
3646 return done;
3647 out_error:
Emeric Brun644cde02012-12-14 11:21:13 +01003648 /* Clear openssl global errors stack */
3649 ERR_clear_error();
3650
Emeric Brun46591952012-05-18 15:47:34 +02003651 conn->flags |= CO_FL_ERROR;
3652 return done;
3653}
3654
3655
3656/* Send all pending bytes from buffer <buf> to connection <conn>'s socket.
Willy Tarreau1049b1f2014-02-02 01:51:17 +01003657 * <flags> may contain some CO_SFL_* flags to hint the system about other
3658 * pending data for example, but this flag is ignored at the moment.
Emeric Brun46591952012-05-18 15:47:34 +02003659 * Only one call to send() is performed, unless the buffer wraps, in which case
3660 * a second call may be performed. The connection's flags are updated with
3661 * whatever special event is detected (error, empty). The caller is responsible
3662 * for taking care of those events and avoiding the call if inappropriate. The
3663 * function does not call the connection's polling update function, so the caller
3664 * is responsible for this.
3665 */
3666static int ssl_sock_from_buf(struct connection *conn, struct buffer *buf, int flags)
3667{
3668 int ret, try, done;
3669
3670 done = 0;
3671
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02003672 if (!conn->xprt_ctx)
Emeric Brun46591952012-05-18 15:47:34 +02003673 goto out_error;
3674
3675 if (conn->flags & CO_FL_HANDSHAKE)
3676 /* a handshake was requested */
3677 return 0;
3678
3679 /* send the largest possible block. For this we perform only one call
3680 * to send() unless the buffer wraps and we exactly fill the first hunk,
3681 * in which case we accept to do it once again.
3682 */
3683 while (buf->o) {
Kevin Hestercad82342013-05-30 15:12:41 -07003684 try = bo_contig_data(buf);
Willy Tarreaubfd59462013-02-21 07:46:09 +01003685
Willy Tarreau7bed9452014-02-02 02:00:24 +01003686 if (!(flags & CO_SFL_STREAMER) &&
Willy Tarreau518cedd2014-02-17 15:43:01 +01003687 !(conn->xprt_st & SSL_SOCK_SEND_UNLIMITED) &&
3688 global.tune.ssl_max_record && try > global.tune.ssl_max_record) {
Willy Tarreaubfd59462013-02-21 07:46:09 +01003689 try = global.tune.ssl_max_record;
Willy Tarreau518cedd2014-02-17 15:43:01 +01003690 }
3691 else {
3692 /* we need to keep the information about the fact that
3693 * we're not limiting the upcoming send(), because if it
3694 * fails, we'll have to retry with at least as many data.
3695 */
3696 conn->xprt_st |= SSL_SOCK_SEND_UNLIMITED;
3697 }
Willy Tarreaubfd59462013-02-21 07:46:09 +01003698
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02003699 ret = SSL_write(conn->xprt_ctx, bo_ptr(buf), try);
Willy Tarreau518cedd2014-02-17 15:43:01 +01003700
Emeric Brune1f38db2012-09-03 20:36:47 +02003701 if (conn->flags & CO_FL_ERROR) {
3702 /* CO_FL_ERROR may be set by ssl_sock_infocbk */
Emeric Brun644cde02012-12-14 11:21:13 +01003703 goto out_error;
Emeric Brune1f38db2012-09-03 20:36:47 +02003704 }
Emeric Brun46591952012-05-18 15:47:34 +02003705 if (ret > 0) {
Willy Tarreau518cedd2014-02-17 15:43:01 +01003706 conn->xprt_st &= ~SSL_SOCK_SEND_UNLIMITED;
3707
Emeric Brun46591952012-05-18 15:47:34 +02003708 buf->o -= ret;
3709 done += ret;
3710
Willy Tarreau5fb38032012-12-16 19:39:09 +01003711 if (likely(buffer_empty(buf)))
Emeric Brun46591952012-05-18 15:47:34 +02003712 /* optimize data alignment in the buffer */
3713 buf->p = buf->data;
3714
3715 /* if the system buffer is full, don't insist */
3716 if (ret < try)
3717 break;
3718 }
3719 else {
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02003720 ret = SSL_get_error(conn->xprt_ctx, ret);
Emeric Brun46591952012-05-18 15:47:34 +02003721 if (ret == SSL_ERROR_WANT_WRITE) {
Emeric Brun282a76a2012-11-08 18:02:56 +01003722 if (SSL_renegotiate_pending(conn->xprt_ctx)) {
3723 /* handshake is running, and it may need to re-enable write */
3724 conn->flags |= CO_FL_SSL_WAIT_HS;
3725 __conn_sock_want_send(conn);
3726 break;
3727 }
Emeric Brun46591952012-05-18 15:47:34 +02003728 /* we need to poll to retry a write later */
Willy Tarreaue1f50c42014-01-22 20:02:06 +01003729 fd_cant_send(conn->t.sock.fd);
Emeric Brun46591952012-05-18 15:47:34 +02003730 break;
3731 }
3732 else if (ret == SSL_ERROR_WANT_READ) {
Emeric Brun8af8dd12012-11-08 17:56:20 +01003733 /* handshake is running, and it needs to enable read */
Emeric Brun46591952012-05-18 15:47:34 +02003734 conn->flags |= CO_FL_SSL_WAIT_HS;
Emeric Brun8af8dd12012-11-08 17:56:20 +01003735 __conn_sock_want_recv(conn);
Emeric Brun46591952012-05-18 15:47:34 +02003736 break;
3737 }
3738 goto out_error;
3739 }
3740 }
3741 return done;
3742
3743 out_error:
Emeric Brun644cde02012-12-14 11:21:13 +01003744 /* Clear openssl global errors stack */
3745 ERR_clear_error();
3746
Emeric Brun46591952012-05-18 15:47:34 +02003747 conn->flags |= CO_FL_ERROR;
3748 return done;
3749}
3750
Emeric Brun46591952012-05-18 15:47:34 +02003751static void ssl_sock_close(struct connection *conn) {
3752
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02003753 if (conn->xprt_ctx) {
3754 SSL_free(conn->xprt_ctx);
3755 conn->xprt_ctx = NULL;
Willy Tarreau403edff2012-09-06 11:58:37 +02003756 sslconns--;
Emeric Brun46591952012-05-18 15:47:34 +02003757 }
Emeric Brun46591952012-05-18 15:47:34 +02003758}
3759
3760/* This function tries to perform a clean shutdown on an SSL connection, and in
3761 * any case, flags the connection as reusable if no handshake was in progress.
3762 */
3763static void ssl_sock_shutw(struct connection *conn, int clean)
3764{
3765 if (conn->flags & CO_FL_HANDSHAKE)
3766 return;
3767 /* no handshake was in progress, try a clean ssl shutdown */
Emeric Brun644cde02012-12-14 11:21:13 +01003768 if (clean && (SSL_shutdown(conn->xprt_ctx) <= 0)) {
3769 /* Clear openssl global errors stack */
3770 ERR_clear_error();
3771 }
Emeric Brun46591952012-05-18 15:47:34 +02003772
3773 /* force flag on ssl to keep session in cache regardless shutdown result */
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02003774 SSL_set_shutdown(conn->xprt_ctx, SSL_SENT_SHUTDOWN);
Emeric Brun46591952012-05-18 15:47:34 +02003775}
3776
Willy Tarreauffc3fcd2012-10-12 20:17:54 +02003777/* used for logging, may be changed for a sample fetch later */
3778const char *ssl_sock_get_cipher_name(struct connection *conn)
3779{
3780 if (!conn->xprt && !conn->xprt_ctx)
3781 return NULL;
3782 return SSL_get_cipher_name(conn->xprt_ctx);
3783}
3784
3785/* used for logging, may be changed for a sample fetch later */
3786const char *ssl_sock_get_proto_version(struct connection *conn)
3787{
3788 if (!conn->xprt && !conn->xprt_ctx)
3789 return NULL;
3790 return SSL_get_version(conn->xprt_ctx);
3791}
3792
Willy Tarreau8d598402012-10-22 17:58:39 +02003793/* Extract a serial from a cert, and copy it to a chunk.
3794 * Returns 1 if serial is found and copied, 0 if no serial found and
3795 * -1 if output is not large enough.
3796 */
3797static int
3798ssl_sock_get_serial(X509 *crt, struct chunk *out)
3799{
3800 ASN1_INTEGER *serial;
3801
3802 serial = X509_get_serialNumber(crt);
3803 if (!serial)
3804 return 0;
3805
3806 if (out->size < serial->length)
3807 return -1;
3808
3809 memcpy(out->str, serial->data, serial->length);
3810 out->len = serial->length;
3811 return 1;
3812}
3813
Emeric Brun43e79582014-10-29 19:03:26 +01003814/* Extract a cert to der, and copy it to a chunk.
3815 * Returns 1 if cert is found and copied, 0 on der convertion failure and
3816 * -1 if output is not large enough.
3817 */
3818static int
3819ssl_sock_crt2der(X509 *crt, struct chunk *out)
3820{
3821 int len;
3822 unsigned char *p = (unsigned char *)out->str;;
3823
3824 len =i2d_X509(crt, NULL);
3825 if (len <= 0)
3826 return 1;
3827
3828 if (out->size < len)
3829 return -1;
3830
3831 i2d_X509(crt,&p);
3832 out->len = len;
3833 return 1;
3834}
3835
Emeric Brunce5ad802012-10-22 14:11:22 +02003836
3837/* Copy Date in ASN1_UTCTIME format in struct chunk out.
3838 * Returns 1 if serial is found and copied, 0 if no valid time found
3839 * and -1 if output is not large enough.
3840 */
3841static int
3842ssl_sock_get_time(ASN1_TIME *tm, struct chunk *out)
3843{
3844 if (tm->type == V_ASN1_GENERALIZEDTIME) {
3845 ASN1_GENERALIZEDTIME *gentm = (ASN1_GENERALIZEDTIME *)tm;
3846
3847 if (gentm->length < 12)
3848 return 0;
3849 if (gentm->data[0] != 0x32 || gentm->data[1] != 0x30)
3850 return 0;
3851 if (out->size < gentm->length-2)
3852 return -1;
3853
3854 memcpy(out->str, gentm->data+2, gentm->length-2);
3855 out->len = gentm->length-2;
3856 return 1;
3857 }
3858 else if (tm->type == V_ASN1_UTCTIME) {
3859 ASN1_UTCTIME *utctm = (ASN1_UTCTIME *)tm;
3860
3861 if (utctm->length < 10)
3862 return 0;
3863 if (utctm->data[0] >= 0x35)
3864 return 0;
3865 if (out->size < utctm->length)
3866 return -1;
3867
3868 memcpy(out->str, utctm->data, utctm->length);
3869 out->len = utctm->length;
3870 return 1;
3871 }
3872
3873 return 0;
3874}
3875
Emeric Brun87855892012-10-17 17:39:35 +02003876/* Extract an entry from a X509_NAME and copy its value to an output chunk.
3877 * Returns 1 if entry found, 0 if entry not found, or -1 if output not large enough.
3878 */
3879static int
3880ssl_sock_get_dn_entry(X509_NAME *a, const struct chunk *entry, int pos, struct chunk *out)
3881{
3882 X509_NAME_ENTRY *ne;
3883 int i, j, n;
3884 int cur = 0;
3885 const char *s;
3886 char tmp[128];
3887
3888 out->len = 0;
3889 for (i = 0; i < sk_X509_NAME_ENTRY_num(a->entries); i++) {
3890 if (pos < 0)
3891 j = (sk_X509_NAME_ENTRY_num(a->entries)-1) - i;
3892 else
3893 j = i;
3894
3895 ne = sk_X509_NAME_ENTRY_value(a->entries, j);
3896 n = OBJ_obj2nid(ne->object);
3897 if ((n == NID_undef) || ((s = OBJ_nid2sn(n)) == NULL)) {
3898 i2t_ASN1_OBJECT(tmp, sizeof(tmp), ne->object);
3899 s = tmp;
3900 }
3901
3902 if (chunk_strcasecmp(entry, s) != 0)
3903 continue;
3904
3905 if (pos < 0)
3906 cur--;
3907 else
3908 cur++;
3909
3910 if (cur != pos)
3911 continue;
3912
3913 if (ne->value->length > out->size)
3914 return -1;
3915
3916 memcpy(out->str, ne->value->data, ne->value->length);
3917 out->len = ne->value->length;
3918 return 1;
3919 }
3920
3921 return 0;
3922
3923}
3924
3925/* Extract and format full DN from a X509_NAME and copy result into a chunk
3926 * Returns 1 if dn entries exits, 0 if no dn entry found or -1 if output is not large enough.
3927 */
3928static int
3929ssl_sock_get_dn_oneline(X509_NAME *a, struct chunk *out)
3930{
3931 X509_NAME_ENTRY *ne;
3932 int i, n, ln;
3933 int l = 0;
3934 const char *s;
3935 char *p;
3936 char tmp[128];
3937
3938 out->len = 0;
3939 p = out->str;
3940 for (i = 0; i < sk_X509_NAME_ENTRY_num(a->entries); i++) {
3941 ne = sk_X509_NAME_ENTRY_value(a->entries, i);
3942 n = OBJ_obj2nid(ne->object);
3943 if ((n == NID_undef) || ((s = OBJ_nid2sn(n)) == NULL)) {
3944 i2t_ASN1_OBJECT(tmp, sizeof(tmp), ne->object);
3945 s = tmp;
3946 }
3947 ln = strlen(s);
3948
3949 l += 1 + ln + 1 + ne->value->length;
3950 if (l > out->size)
3951 return -1;
3952 out->len = l;
3953
3954 *(p++)='/';
3955 memcpy(p, s, ln);
3956 p += ln;
3957 *(p++)='=';
3958 memcpy(p, ne->value->data, ne->value->length);
3959 p += ne->value->length;
3960 }
3961
3962 if (!out->len)
3963 return 0;
3964
3965 return 1;
3966}
3967
David Safb76832014-05-08 23:42:08 -04003968char *ssl_sock_get_version(struct connection *conn)
3969{
3970 if (!ssl_sock_is_ssl(conn))
3971 return NULL;
3972
3973 return (char *)SSL_get_version(conn->xprt_ctx);
3974}
3975
Willy Tarreau63076412015-07-10 11:33:32 +02003976void ssl_sock_set_servername(struct connection *conn, const char *hostname)
3977{
3978#ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME
3979 if (!ssl_sock_is_ssl(conn))
3980 return;
3981
3982 SSL_set_tlsext_host_name(conn->xprt_ctx, hostname);
3983#endif
3984}
3985
Emeric Brun0abf8362014-06-24 18:26:41 +02003986/* Extract peer certificate's common name into the chunk dest
3987 * Returns
3988 * the len of the extracted common name
3989 * or 0 if no CN found in DN
3990 * or -1 on error case (i.e. no peer certificate)
3991 */
3992int ssl_sock_get_remote_common_name(struct connection *conn, struct chunk *dest)
David Safb76832014-05-08 23:42:08 -04003993{
3994 X509 *crt = NULL;
3995 X509_NAME *name;
David Safb76832014-05-08 23:42:08 -04003996 const char find_cn[] = "CN";
3997 const struct chunk find_cn_chunk = {
3998 .str = (char *)&find_cn,
3999 .len = sizeof(find_cn)-1
4000 };
Emeric Brun0abf8362014-06-24 18:26:41 +02004001 int result = -1;
David Safb76832014-05-08 23:42:08 -04004002
4003 if (!ssl_sock_is_ssl(conn))
Emeric Brun0abf8362014-06-24 18:26:41 +02004004 goto out;
David Safb76832014-05-08 23:42:08 -04004005
4006 /* SSL_get_peer_certificate, it increase X509 * ref count */
4007 crt = SSL_get_peer_certificate(conn->xprt_ctx);
4008 if (!crt)
4009 goto out;
4010
4011 name = X509_get_subject_name(crt);
4012 if (!name)
4013 goto out;
David Safb76832014-05-08 23:42:08 -04004014
Emeric Brun0abf8362014-06-24 18:26:41 +02004015 result = ssl_sock_get_dn_entry(name, &find_cn_chunk, 1, dest);
4016out:
David Safb76832014-05-08 23:42:08 -04004017 if (crt)
4018 X509_free(crt);
4019
4020 return result;
4021}
4022
Dave McCowan328fb582014-07-30 10:39:13 -04004023/* returns 1 if client passed a certificate for this session, 0 if not */
4024int ssl_sock_get_cert_used_sess(struct connection *conn)
4025{
4026 X509 *crt = NULL;
4027
4028 if (!ssl_sock_is_ssl(conn))
4029 return 0;
4030
4031 /* SSL_get_peer_certificate, it increase X509 * ref count */
4032 crt = SSL_get_peer_certificate(conn->xprt_ctx);
4033 if (!crt)
4034 return 0;
4035
4036 X509_free(crt);
4037 return 1;
4038}
4039
4040/* returns 1 if client passed a certificate for this connection, 0 if not */
4041int ssl_sock_get_cert_used_conn(struct connection *conn)
David Safb76832014-05-08 23:42:08 -04004042{
4043 if (!ssl_sock_is_ssl(conn))
4044 return 0;
4045
4046 return SSL_SOCK_ST_FL_VERIFY_DONE & conn->xprt_st ? 1 : 0;
4047}
4048
4049/* returns result from SSL verify */
4050unsigned int ssl_sock_get_verify_result(struct connection *conn)
4051{
4052 if (!ssl_sock_is_ssl(conn))
4053 return (unsigned int)X509_V_ERR_APPLICATION_VERIFICATION;
4054
4055 return (unsigned int)SSL_get_verify_result(conn->xprt_ctx);
4056}
4057
Willy Tarreau7875d092012-09-10 08:20:03 +02004058/***** Below are some sample fetching functions for ACL/patterns *****/
4059
Emeric Brune64aef12012-09-21 13:15:06 +02004060/* boolean, returns true if client cert was present */
4061static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02004062smp_fetch_ssl_fc_has_crt(const struct arg *args, struct sample *smp, const char *kw, void *private)
Emeric Brune64aef12012-09-21 13:15:06 +02004063{
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004064 struct connection *conn;
4065
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02004066 conn = objt_conn(smp->sess->origin);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004067 if (!conn || conn->xprt != &ssl_sock)
Emeric Brune64aef12012-09-21 13:15:06 +02004068 return 0;
4069
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004070 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brune64aef12012-09-21 13:15:06 +02004071 smp->flags |= SMP_F_MAY_CHANGE;
4072 return 0;
4073 }
4074
4075 smp->flags = 0;
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02004076 smp->data.type = SMP_T_BOOL;
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02004077 smp->data.u.sint = SSL_SOCK_ST_FL_VERIFY_DONE & conn->xprt_st ? 1 : 0;
Emeric Brune64aef12012-09-21 13:15:06 +02004078
4079 return 1;
4080}
4081
Emeric Brun43e79582014-10-29 19:03:26 +01004082/* binary, returns a certificate in a binary chunk (der/raw).
4083 * The 5th keyword char is used to know if SSL_get_certificate or SSL_get_peer_certificate
4084 * should be use.
4085 */
4086static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02004087smp_fetch_ssl_x_der(const struct arg *args, struct sample *smp, const char *kw, void *private)
Emeric Brun43e79582014-10-29 19:03:26 +01004088{
4089 int cert_peer = (kw[4] == 'c') ? 1 : 0;
4090 X509 *crt = NULL;
4091 int ret = 0;
4092 struct chunk *smp_trash;
4093 struct connection *conn;
4094
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02004095 conn = objt_conn(smp->sess->origin);
Emeric Brun43e79582014-10-29 19:03:26 +01004096 if (!conn || conn->xprt != &ssl_sock)
4097 return 0;
4098
4099 if (!(conn->flags & CO_FL_CONNECTED)) {
4100 smp->flags |= SMP_F_MAY_CHANGE;
4101 return 0;
4102 }
4103
4104 if (cert_peer)
4105 crt = SSL_get_peer_certificate(conn->xprt_ctx);
4106 else
4107 crt = SSL_get_certificate(conn->xprt_ctx);
4108
4109 if (!crt)
4110 goto out;
4111
4112 smp_trash = get_trash_chunk();
4113 if (ssl_sock_crt2der(crt, smp_trash) <= 0)
4114 goto out;
4115
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02004116 smp->data.u.str = *smp_trash;
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02004117 smp->data.type = SMP_T_BIN;
Emeric Brun43e79582014-10-29 19:03:26 +01004118 ret = 1;
4119out:
4120 /* SSL_get_peer_certificate, it increase X509 * ref count */
4121 if (cert_peer && crt)
4122 X509_free(crt);
4123 return ret;
4124}
4125
Emeric Brunba841a12014-04-30 17:05:08 +02004126/* binary, returns serial of certificate in a binary chunk.
4127 * The 5th keyword char is used to know if SSL_get_certificate or SSL_get_peer_certificate
4128 * should be use.
4129 */
Willy Tarreau8d598402012-10-22 17:58:39 +02004130static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02004131smp_fetch_ssl_x_serial(const struct arg *args, struct sample *smp, const char *kw, void *private)
Willy Tarreau8d598402012-10-22 17:58:39 +02004132{
Emeric Brunba841a12014-04-30 17:05:08 +02004133 int cert_peer = (kw[4] == 'c') ? 1 : 0;
Willy Tarreau8d598402012-10-22 17:58:39 +02004134 X509 *crt = NULL;
4135 int ret = 0;
4136 struct chunk *smp_trash;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004137 struct connection *conn;
4138
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02004139 conn = objt_conn(smp->sess->origin);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004140 if (!conn || conn->xprt != &ssl_sock)
Willy Tarreau8d598402012-10-22 17:58:39 +02004141 return 0;
4142
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004143 if (!(conn->flags & CO_FL_CONNECTED)) {
Willy Tarreau8d598402012-10-22 17:58:39 +02004144 smp->flags |= SMP_F_MAY_CHANGE;
4145 return 0;
4146 }
4147
Emeric Brunba841a12014-04-30 17:05:08 +02004148 if (cert_peer)
4149 crt = SSL_get_peer_certificate(conn->xprt_ctx);
4150 else
4151 crt = SSL_get_certificate(conn->xprt_ctx);
4152
Willy Tarreau8d598402012-10-22 17:58:39 +02004153 if (!crt)
4154 goto out;
4155
Willy Tarreau47ca5452012-12-23 20:22:19 +01004156 smp_trash = get_trash_chunk();
Willy Tarreau8d598402012-10-22 17:58:39 +02004157 if (ssl_sock_get_serial(crt, smp_trash) <= 0)
4158 goto out;
4159
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02004160 smp->data.u.str = *smp_trash;
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02004161 smp->data.type = SMP_T_BIN;
Willy Tarreau8d598402012-10-22 17:58:39 +02004162 ret = 1;
4163out:
Emeric Brunba841a12014-04-30 17:05:08 +02004164 /* SSL_get_peer_certificate, it increase X509 * ref count */
4165 if (cert_peer && crt)
Willy Tarreau8d598402012-10-22 17:58:39 +02004166 X509_free(crt);
4167 return ret;
4168}
Emeric Brune64aef12012-09-21 13:15:06 +02004169
Emeric Brunba841a12014-04-30 17:05:08 +02004170/* binary, returns the client certificate's SHA-1 fingerprint (SHA-1 hash of DER-encoded certificate) in a binary chunk.
4171 * The 5th keyword char is used to know if SSL_get_certificate or SSL_get_peer_certificate
4172 * should be use.
4173 */
James Votha051b4a2013-05-14 20:37:59 +02004174static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02004175smp_fetch_ssl_x_sha1(const struct arg *args, struct sample *smp, const char *kw, void *private)
James Votha051b4a2013-05-14 20:37:59 +02004176{
Emeric Brunba841a12014-04-30 17:05:08 +02004177 int cert_peer = (kw[4] == 'c') ? 1 : 0;
James Votha051b4a2013-05-14 20:37:59 +02004178 X509 *crt = NULL;
4179 const EVP_MD *digest;
4180 int ret = 0;
4181 struct chunk *smp_trash;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004182 struct connection *conn;
James Votha051b4a2013-05-14 20:37:59 +02004183
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02004184 conn = objt_conn(smp->sess->origin);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004185 if (!conn || conn->xprt != &ssl_sock)
4186 return 0;
4187
4188 if (!(conn->flags & CO_FL_CONNECTED)) {
James Votha051b4a2013-05-14 20:37:59 +02004189 smp->flags |= SMP_F_MAY_CHANGE;
4190 return 0;
4191 }
4192
Emeric Brunba841a12014-04-30 17:05:08 +02004193 if (cert_peer)
4194 crt = SSL_get_peer_certificate(conn->xprt_ctx);
4195 else
4196 crt = SSL_get_certificate(conn->xprt_ctx);
James Votha051b4a2013-05-14 20:37:59 +02004197 if (!crt)
4198 goto out;
4199
4200 smp_trash = get_trash_chunk();
4201 digest = EVP_sha1();
4202 X509_digest(crt, digest, (unsigned char *)smp_trash->str, (unsigned int *)&smp_trash->len);
4203
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02004204 smp->data.u.str = *smp_trash;
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02004205 smp->data.type = SMP_T_BIN;
James Votha051b4a2013-05-14 20:37:59 +02004206 ret = 1;
4207out:
Emeric Brunba841a12014-04-30 17:05:08 +02004208 /* SSL_get_peer_certificate, it increase X509 * ref count */
4209 if (cert_peer && crt)
James Votha051b4a2013-05-14 20:37:59 +02004210 X509_free(crt);
4211 return ret;
4212}
4213
Emeric Brunba841a12014-04-30 17:05:08 +02004214/* string, returns certificate's notafter date in ASN1_UTCTIME format.
4215 * The 5th keyword char is used to know if SSL_get_certificate or SSL_get_peer_certificate
4216 * should be use.
4217 */
Emeric Brunce5ad802012-10-22 14:11:22 +02004218static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02004219smp_fetch_ssl_x_notafter(const struct arg *args, struct sample *smp, const char *kw, void *private)
Emeric Brunce5ad802012-10-22 14:11:22 +02004220{
Emeric Brunba841a12014-04-30 17:05:08 +02004221 int cert_peer = (kw[4] == 'c') ? 1 : 0;
Emeric Brunce5ad802012-10-22 14:11:22 +02004222 X509 *crt = NULL;
4223 int ret = 0;
4224 struct chunk *smp_trash;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004225 struct connection *conn;
Emeric Brunce5ad802012-10-22 14:11:22 +02004226
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02004227 conn = objt_conn(smp->sess->origin);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004228 if (!conn || conn->xprt != &ssl_sock)
4229 return 0;
4230
4231 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brunce5ad802012-10-22 14:11:22 +02004232 smp->flags |= SMP_F_MAY_CHANGE;
4233 return 0;
4234 }
4235
Emeric Brunba841a12014-04-30 17:05:08 +02004236 if (cert_peer)
4237 crt = SSL_get_peer_certificate(conn->xprt_ctx);
4238 else
4239 crt = SSL_get_certificate(conn->xprt_ctx);
Emeric Brunce5ad802012-10-22 14:11:22 +02004240 if (!crt)
4241 goto out;
4242
Willy Tarreau47ca5452012-12-23 20:22:19 +01004243 smp_trash = get_trash_chunk();
Emeric Brunce5ad802012-10-22 14:11:22 +02004244 if (ssl_sock_get_time(X509_get_notAfter(crt), smp_trash) <= 0)
4245 goto out;
4246
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02004247 smp->data.u.str = *smp_trash;
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02004248 smp->data.type = SMP_T_STR;
Emeric Brunce5ad802012-10-22 14:11:22 +02004249 ret = 1;
4250out:
Emeric Brunba841a12014-04-30 17:05:08 +02004251 /* SSL_get_peer_certificate, it increase X509 * ref count */
4252 if (cert_peer && crt)
Emeric Brunce5ad802012-10-22 14:11:22 +02004253 X509_free(crt);
4254 return ret;
4255}
4256
Emeric Brunba841a12014-04-30 17:05:08 +02004257/* string, returns a string of a formatted full dn \C=..\O=..\OU=.. \CN=.. of certificate's issuer
4258 * The 5th keyword char is used to know if SSL_get_certificate or SSL_get_peer_certificate
4259 * should be use.
4260 */
Emeric Brun87855892012-10-17 17:39:35 +02004261static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02004262smp_fetch_ssl_x_i_dn(const struct arg *args, struct sample *smp, const char *kw, void *private)
Emeric Brun87855892012-10-17 17:39:35 +02004263{
Emeric Brunba841a12014-04-30 17:05:08 +02004264 int cert_peer = (kw[4] == 'c') ? 1 : 0;
Emeric Brun87855892012-10-17 17:39:35 +02004265 X509 *crt = NULL;
4266 X509_NAME *name;
4267 int ret = 0;
4268 struct chunk *smp_trash;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004269 struct connection *conn;
Emeric Brun87855892012-10-17 17:39:35 +02004270
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02004271 conn = objt_conn(smp->sess->origin);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004272 if (!conn || conn->xprt != &ssl_sock)
4273 return 0;
4274
4275 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brun87855892012-10-17 17:39:35 +02004276 smp->flags |= SMP_F_MAY_CHANGE;
4277 return 0;
4278 }
4279
Emeric Brunba841a12014-04-30 17:05:08 +02004280 if (cert_peer)
4281 crt = SSL_get_peer_certificate(conn->xprt_ctx);
4282 else
4283 crt = SSL_get_certificate(conn->xprt_ctx);
Emeric Brun87855892012-10-17 17:39:35 +02004284 if (!crt)
4285 goto out;
4286
4287 name = X509_get_issuer_name(crt);
4288 if (!name)
4289 goto out;
4290
Willy Tarreau47ca5452012-12-23 20:22:19 +01004291 smp_trash = get_trash_chunk();
Emeric Brun87855892012-10-17 17:39:35 +02004292 if (args && args[0].type == ARGT_STR) {
4293 int pos = 1;
4294
4295 if (args[1].type == ARGT_SINT)
4296 pos = args[1].data.sint;
Emeric Brun87855892012-10-17 17:39:35 +02004297
4298 if (ssl_sock_get_dn_entry(name, &args[0].data.str, pos, smp_trash) <= 0)
4299 goto out;
4300 }
4301 else if (ssl_sock_get_dn_oneline(name, smp_trash) <= 0)
4302 goto out;
4303
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02004304 smp->data.type = SMP_T_STR;
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02004305 smp->data.u.str = *smp_trash;
Emeric Brun87855892012-10-17 17:39:35 +02004306 ret = 1;
4307out:
Emeric Brunba841a12014-04-30 17:05:08 +02004308 /* SSL_get_peer_certificate, it increase X509 * ref count */
4309 if (cert_peer && crt)
Emeric Brun87855892012-10-17 17:39:35 +02004310 X509_free(crt);
4311 return ret;
4312}
4313
Emeric Brunba841a12014-04-30 17:05:08 +02004314/* string, returns notbefore date in ASN1_UTCTIME format.
4315 * The 5th keyword char is used to know if SSL_get_certificate or SSL_get_peer_certificate
4316 * should be use.
4317 */
Emeric Brunce5ad802012-10-22 14:11:22 +02004318static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02004319smp_fetch_ssl_x_notbefore(const struct arg *args, struct sample *smp, const char *kw, void *private)
Emeric Brunce5ad802012-10-22 14:11:22 +02004320{
Emeric Brunba841a12014-04-30 17:05:08 +02004321 int cert_peer = (kw[4] == 'c') ? 1 : 0;
Emeric Brunce5ad802012-10-22 14:11:22 +02004322 X509 *crt = NULL;
4323 int ret = 0;
4324 struct chunk *smp_trash;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004325 struct connection *conn;
4326
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02004327 conn = objt_conn(smp->sess->origin);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004328 if (!conn || conn->xprt != &ssl_sock)
Emeric Brunce5ad802012-10-22 14:11:22 +02004329 return 0;
4330
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004331 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brunce5ad802012-10-22 14:11:22 +02004332 smp->flags |= SMP_F_MAY_CHANGE;
4333 return 0;
4334 }
4335
Emeric Brunba841a12014-04-30 17:05:08 +02004336 if (cert_peer)
4337 crt = SSL_get_peer_certificate(conn->xprt_ctx);
4338 else
4339 crt = SSL_get_certificate(conn->xprt_ctx);
Emeric Brunce5ad802012-10-22 14:11:22 +02004340 if (!crt)
4341 goto out;
4342
Willy Tarreau47ca5452012-12-23 20:22:19 +01004343 smp_trash = get_trash_chunk();
Emeric Brunce5ad802012-10-22 14:11:22 +02004344 if (ssl_sock_get_time(X509_get_notBefore(crt), smp_trash) <= 0)
4345 goto out;
4346
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02004347 smp->data.u.str = *smp_trash;
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02004348 smp->data.type = SMP_T_STR;
Emeric Brunce5ad802012-10-22 14:11:22 +02004349 ret = 1;
4350out:
Emeric Brunba841a12014-04-30 17:05:08 +02004351 /* SSL_get_peer_certificate, it increase X509 * ref count */
4352 if (cert_peer && crt)
Emeric Brunce5ad802012-10-22 14:11:22 +02004353 X509_free(crt);
4354 return ret;
4355}
4356
Emeric Brunba841a12014-04-30 17:05:08 +02004357/* string, returns a string of a formatted full dn \C=..\O=..\OU=.. \CN=.. of certificate's subject
4358 * The 5th keyword char is used to know if SSL_get_certificate or SSL_get_peer_certificate
4359 * should be use.
4360 */
Emeric Brun87855892012-10-17 17:39:35 +02004361static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02004362smp_fetch_ssl_x_s_dn(const struct arg *args, struct sample *smp, const char *kw, void *private)
Emeric Brun87855892012-10-17 17:39:35 +02004363{
Emeric Brunba841a12014-04-30 17:05:08 +02004364 int cert_peer = (kw[4] == 'c') ? 1 : 0;
Emeric Brun87855892012-10-17 17:39:35 +02004365 X509 *crt = NULL;
4366 X509_NAME *name;
4367 int ret = 0;
4368 struct chunk *smp_trash;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004369 struct connection *conn;
Emeric Brun87855892012-10-17 17:39:35 +02004370
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02004371 conn = objt_conn(smp->sess->origin);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004372 if (!conn || conn->xprt != &ssl_sock)
4373 return 0;
4374
4375 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brun87855892012-10-17 17:39:35 +02004376 smp->flags |= SMP_F_MAY_CHANGE;
4377 return 0;
4378 }
4379
Emeric Brunba841a12014-04-30 17:05:08 +02004380 if (cert_peer)
4381 crt = SSL_get_peer_certificate(conn->xprt_ctx);
4382 else
4383 crt = SSL_get_certificate(conn->xprt_ctx);
Emeric Brun87855892012-10-17 17:39:35 +02004384 if (!crt)
4385 goto out;
4386
4387 name = X509_get_subject_name(crt);
4388 if (!name)
4389 goto out;
4390
Willy Tarreau47ca5452012-12-23 20:22:19 +01004391 smp_trash = get_trash_chunk();
Emeric Brun87855892012-10-17 17:39:35 +02004392 if (args && args[0].type == ARGT_STR) {
4393 int pos = 1;
4394
4395 if (args[1].type == ARGT_SINT)
4396 pos = args[1].data.sint;
Emeric Brun87855892012-10-17 17:39:35 +02004397
4398 if (ssl_sock_get_dn_entry(name, &args[0].data.str, pos, smp_trash) <= 0)
4399 goto out;
4400 }
4401 else if (ssl_sock_get_dn_oneline(name, smp_trash) <= 0)
4402 goto out;
4403
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02004404 smp->data.type = SMP_T_STR;
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02004405 smp->data.u.str = *smp_trash;
Emeric Brun87855892012-10-17 17:39:35 +02004406 ret = 1;
4407out:
Emeric Brunba841a12014-04-30 17:05:08 +02004408 /* SSL_get_peer_certificate, it increase X509 * ref count */
4409 if (cert_peer && crt)
Emeric Brun87855892012-10-17 17:39:35 +02004410 X509_free(crt);
4411 return ret;
4412}
Emeric Brun9143d372012-12-20 15:44:16 +01004413
4414/* integer, returns true if current session use a client certificate */
4415static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02004416smp_fetch_ssl_c_used(const struct arg *args, struct sample *smp, const char *kw, void *private)
Emeric Brun9143d372012-12-20 15:44:16 +01004417{
4418 X509 *crt;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004419 struct connection *conn;
Emeric Brun9143d372012-12-20 15:44:16 +01004420
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02004421 conn = objt_conn(smp->sess->origin);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004422 if (!conn || conn->xprt != &ssl_sock)
4423 return 0;
4424
4425 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brun9143d372012-12-20 15:44:16 +01004426 smp->flags |= SMP_F_MAY_CHANGE;
4427 return 0;
4428 }
4429
4430 /* SSL_get_peer_certificate returns a ptr on allocated X509 struct */
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004431 crt = SSL_get_peer_certificate(conn->xprt_ctx);
Emeric Brun9143d372012-12-20 15:44:16 +01004432 if (crt) {
4433 X509_free(crt);
4434 }
4435
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02004436 smp->data.type = SMP_T_BOOL;
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02004437 smp->data.u.sint = (crt != NULL);
Emeric Brun9143d372012-12-20 15:44:16 +01004438 return 1;
4439}
4440
Emeric Brunba841a12014-04-30 17:05:08 +02004441/* integer, returns the certificate version
4442 * The 5th keyword char is used to know if SSL_get_certificate or SSL_get_peer_certificate
4443 * should be use.
4444 */
Emeric Bruna7359fd2012-10-17 15:03:11 +02004445static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02004446smp_fetch_ssl_x_version(const struct arg *args, struct sample *smp, const char *kw, void *private)
Emeric Bruna7359fd2012-10-17 15:03:11 +02004447{
Emeric Brunba841a12014-04-30 17:05:08 +02004448 int cert_peer = (kw[4] == 'c') ? 1 : 0;
Emeric Bruna7359fd2012-10-17 15:03:11 +02004449 X509 *crt;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004450 struct connection *conn;
4451
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02004452 conn = objt_conn(smp->sess->origin);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004453 if (!conn || conn->xprt != &ssl_sock)
Emeric Bruna7359fd2012-10-17 15:03:11 +02004454 return 0;
4455
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004456 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Bruna7359fd2012-10-17 15:03:11 +02004457 smp->flags |= SMP_F_MAY_CHANGE;
4458 return 0;
4459 }
4460
Emeric Brunba841a12014-04-30 17:05:08 +02004461 if (cert_peer)
4462 crt = SSL_get_peer_certificate(conn->xprt_ctx);
4463 else
4464 crt = SSL_get_certificate(conn->xprt_ctx);
Emeric Bruna7359fd2012-10-17 15:03:11 +02004465 if (!crt)
4466 return 0;
4467
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02004468 smp->data.u.sint = (unsigned int)(1 + X509_get_version(crt));
Emeric Brunba841a12014-04-30 17:05:08 +02004469 /* SSL_get_peer_certificate increase X509 * ref count */
4470 if (cert_peer)
4471 X509_free(crt);
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02004472 smp->data.type = SMP_T_SINT;
Emeric Bruna7359fd2012-10-17 15:03:11 +02004473
4474 return 1;
4475}
4476
Emeric Brunba841a12014-04-30 17:05:08 +02004477/* string, returns the certificate's signature algorithm.
4478 * The 5th keyword char is used to know if SSL_get_certificate or SSL_get_peer_certificate
4479 * should be use.
4480 */
Emeric Brun7f56e742012-10-19 18:15:40 +02004481static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02004482smp_fetch_ssl_x_sig_alg(const struct arg *args, struct sample *smp, const char *kw, void *private)
Emeric Brun7f56e742012-10-19 18:15:40 +02004483{
Emeric Brunba841a12014-04-30 17:05:08 +02004484 int cert_peer = (kw[4] == 'c') ? 1 : 0;
Emeric Brun7f56e742012-10-19 18:15:40 +02004485 X509 *crt;
4486 int nid;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004487 struct connection *conn;
Emeric Brun7f56e742012-10-19 18:15:40 +02004488
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02004489 conn = objt_conn(smp->sess->origin);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004490 if (!conn || conn->xprt != &ssl_sock)
4491 return 0;
4492
4493 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brun7f56e742012-10-19 18:15:40 +02004494 smp->flags |= SMP_F_MAY_CHANGE;
4495 return 0;
4496 }
4497
Emeric Brunba841a12014-04-30 17:05:08 +02004498 if (cert_peer)
4499 crt = SSL_get_peer_certificate(conn->xprt_ctx);
4500 else
4501 crt = SSL_get_certificate(conn->xprt_ctx);
Emeric Brun7f56e742012-10-19 18:15:40 +02004502 if (!crt)
4503 return 0;
4504
4505 nid = OBJ_obj2nid((ASN1_OBJECT *)(crt->cert_info->signature->algorithm));
4506
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02004507 smp->data.u.str.str = (char *)OBJ_nid2sn(nid);
4508 if (!smp->data.u.str.str) {
Emeric Brunba841a12014-04-30 17:05:08 +02004509 /* SSL_get_peer_certificate increase X509 * ref count */
4510 if (cert_peer)
4511 X509_free(crt);
Emeric Brun7f56e742012-10-19 18:15:40 +02004512 return 0;
Emeric Brun9bf3ba22013-10-07 14:31:44 +02004513 }
Emeric Brun7f56e742012-10-19 18:15:40 +02004514
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02004515 smp->data.type = SMP_T_STR;
Thierry FOURNIER7654c9f2013-12-17 00:20:33 +01004516 smp->flags |= SMP_F_CONST;
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02004517 smp->data.u.str.len = strlen(smp->data.u.str.str);
Emeric Brunba841a12014-04-30 17:05:08 +02004518 /* SSL_get_peer_certificate increase X509 * ref count */
4519 if (cert_peer)
4520 X509_free(crt);
Emeric Brun7f56e742012-10-19 18:15:40 +02004521
4522 return 1;
4523}
4524
Emeric Brunba841a12014-04-30 17:05:08 +02004525/* string, returns the certificate's key algorithm.
4526 * The 5th keyword char is used to know if SSL_get_certificate or SSL_get_peer_certificate
4527 * should be use.
4528 */
Emeric Brun521a0112012-10-22 12:22:55 +02004529static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02004530smp_fetch_ssl_x_key_alg(const struct arg *args, struct sample *smp, const char *kw, void *private)
Emeric Brun521a0112012-10-22 12:22:55 +02004531{
Emeric Brunba841a12014-04-30 17:05:08 +02004532 int cert_peer = (kw[4] == 'c') ? 1 : 0;
Emeric Brun521a0112012-10-22 12:22:55 +02004533 X509 *crt;
4534 int nid;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004535 struct connection *conn;
Emeric Brun521a0112012-10-22 12:22:55 +02004536
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02004537 conn = objt_conn(smp->sess->origin);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004538 if (!conn || conn->xprt != &ssl_sock)
4539 return 0;
4540
4541 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brun521a0112012-10-22 12:22:55 +02004542 smp->flags |= SMP_F_MAY_CHANGE;
4543 return 0;
4544 }
4545
Emeric Brunba841a12014-04-30 17:05:08 +02004546 if (cert_peer)
4547 crt = SSL_get_peer_certificate(conn->xprt_ctx);
4548 else
4549 crt = SSL_get_certificate(conn->xprt_ctx);
Emeric Brun521a0112012-10-22 12:22:55 +02004550 if (!crt)
4551 return 0;
4552
4553 nid = OBJ_obj2nid((ASN1_OBJECT *)(crt->cert_info->key->algor->algorithm));
4554
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02004555 smp->data.u.str.str = (char *)OBJ_nid2sn(nid);
4556 if (!smp->data.u.str.str) {
Emeric Brunba841a12014-04-30 17:05:08 +02004557 /* SSL_get_peer_certificate increase X509 * ref count */
4558 if (cert_peer)
4559 X509_free(crt);
Emeric Brun521a0112012-10-22 12:22:55 +02004560 return 0;
Emeric Brun9bf3ba22013-10-07 14:31:44 +02004561 }
Emeric Brun521a0112012-10-22 12:22:55 +02004562
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02004563 smp->data.type = SMP_T_STR;
Thierry FOURNIER7654c9f2013-12-17 00:20:33 +01004564 smp->flags |= SMP_F_CONST;
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02004565 smp->data.u.str.len = strlen(smp->data.u.str.str);
Emeric Brunba841a12014-04-30 17:05:08 +02004566 if (cert_peer)
4567 X509_free(crt);
Emeric Brun521a0112012-10-22 12:22:55 +02004568
4569 return 1;
4570}
4571
Emeric Brun645ae792014-04-30 14:21:06 +02004572/* boolean, returns true if front conn. transport layer is SSL.
4573 * This function is also usable on backend conn if the fetch keyword 5th
4574 * char is 'b'.
4575 */
Willy Tarreau7875d092012-09-10 08:20:03 +02004576static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02004577smp_fetch_ssl_fc(const struct arg *args, struct sample *smp, const char *kw, void *private)
Willy Tarreau7875d092012-09-10 08:20:03 +02004578{
Willy Tarreaue237fe12016-03-10 17:05:28 +01004579 struct connection *conn = objt_conn((kw[4] != 'b') ? smp->sess->origin :
4580 smp->strm ? smp->strm->si[1].end : NULL);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004581
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02004582 smp->data.type = SMP_T_BOOL;
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02004583 smp->data.u.sint = (conn && conn->xprt == &ssl_sock);
Willy Tarreau7875d092012-09-10 08:20:03 +02004584 return 1;
4585}
4586
Emeric Brun2525b6b2012-10-18 15:59:43 +02004587/* boolean, returns true if client present a SNI */
Willy Tarreau7875d092012-09-10 08:20:03 +02004588static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02004589smp_fetch_ssl_fc_has_sni(const struct arg *args, struct sample *smp, const char *kw, void *private)
Willy Tarreau7875d092012-09-10 08:20:03 +02004590{
4591#ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02004592 struct connection *conn = objt_conn(smp->sess->origin);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004593
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02004594 smp->data.type = SMP_T_BOOL;
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02004595 smp->data.u.sint = (conn && conn->xprt == &ssl_sock) &&
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004596 conn->xprt_ctx &&
4597 SSL_get_servername(conn->xprt_ctx, TLSEXT_NAMETYPE_host_name) != NULL;
Willy Tarreau7875d092012-09-10 08:20:03 +02004598 return 1;
4599#else
4600 return 0;
4601#endif
4602}
4603
Nenad Merdanovic26ea8222015-05-18 02:28:57 +02004604/* boolean, returns true if client session has been resumed */
4605static int
4606smp_fetch_ssl_fc_is_resumed(const struct arg *args, struct sample *smp, const char *kw, void *private)
4607{
4608 struct connection *conn = objt_conn(smp->sess->origin);
4609
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02004610 smp->data.type = SMP_T_BOOL;
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02004611 smp->data.u.sint = (conn && conn->xprt == &ssl_sock) &&
Nenad Merdanovic26ea8222015-05-18 02:28:57 +02004612 conn->xprt_ctx &&
4613 SSL_session_reused(conn->xprt_ctx);
4614 return 1;
4615}
4616
Emeric Brun645ae792014-04-30 14:21:06 +02004617/* string, returns the used cipher if front conn. transport layer is SSL.
4618 * This function is also usable on backend conn if the fetch keyword 5th
4619 * char is 'b'.
4620 */
Emeric Brun589fcad2012-10-16 14:13:26 +02004621static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02004622smp_fetch_ssl_fc_cipher(const struct arg *args, struct sample *smp, const char *kw, void *private)
Emeric Brun589fcad2012-10-16 14:13:26 +02004623{
Willy Tarreaue237fe12016-03-10 17:05:28 +01004624 struct connection *conn = objt_conn((kw[4] != 'b') ? smp->sess->origin :
4625 smp->strm ? smp->strm->si[1].end : NULL);
Emeric Brun589fcad2012-10-16 14:13:26 +02004626
Willy Tarreaube508f12016-03-10 11:47:01 +01004627 smp->flags = 0;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004628 if (!conn || !conn->xprt_ctx || conn->xprt != &ssl_sock)
Emeric Brun589fcad2012-10-16 14:13:26 +02004629 return 0;
4630
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02004631 smp->data.u.str.str = (char *)SSL_get_cipher_name(conn->xprt_ctx);
4632 if (!smp->data.u.str.str)
Emeric Brun589fcad2012-10-16 14:13:26 +02004633 return 0;
4634
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02004635 smp->data.type = SMP_T_STR;
Thierry FOURNIER7654c9f2013-12-17 00:20:33 +01004636 smp->flags |= SMP_F_CONST;
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02004637 smp->data.u.str.len = strlen(smp->data.u.str.str);
Emeric Brun589fcad2012-10-16 14:13:26 +02004638
4639 return 1;
4640}
4641
Emeric Brun645ae792014-04-30 14:21:06 +02004642/* integer, returns the algoritm's keysize if front conn. transport layer
4643 * is SSL.
4644 * This function is also usable on backend conn if the fetch keyword 5th
4645 * char is 'b'.
4646 */
Emeric Brun589fcad2012-10-16 14:13:26 +02004647static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02004648smp_fetch_ssl_fc_alg_keysize(const struct arg *args, struct sample *smp, const char *kw, void *private)
Emeric Brun589fcad2012-10-16 14:13:26 +02004649{
Willy Tarreaue237fe12016-03-10 17:05:28 +01004650 struct connection *conn = objt_conn((kw[4] != 'b') ? smp->sess->origin :
4651 smp->strm ? smp->strm->si[1].end : NULL);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004652
Willy Tarreaue237fe12016-03-10 17:05:28 +01004653 int sint;
Willy Tarreaube508f12016-03-10 11:47:01 +01004654
Emeric Brun589fcad2012-10-16 14:13:26 +02004655 smp->flags = 0;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004656 if (!conn || !conn->xprt_ctx || conn->xprt != &ssl_sock)
Emeric Brun589fcad2012-10-16 14:13:26 +02004657 return 0;
4658
Thierry FOURNIER07ee64e2015-07-06 23:43:03 +02004659 if (!SSL_get_cipher_bits(conn->xprt_ctx, &sint))
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004660 return 0;
4661
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02004662 smp->data.u.sint = sint;
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02004663 smp->data.type = SMP_T_SINT;
Emeric Brun589fcad2012-10-16 14:13:26 +02004664
4665 return 1;
4666}
4667
Emeric Brun645ae792014-04-30 14:21:06 +02004668/* integer, returns the used keysize if front conn. transport layer is SSL.
4669 * This function is also usable on backend conn if the fetch keyword 5th
4670 * char is 'b'.
4671 */
Emeric Brun589fcad2012-10-16 14:13:26 +02004672static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02004673smp_fetch_ssl_fc_use_keysize(const struct arg *args, struct sample *smp, const char *kw, void *private)
Emeric Brun589fcad2012-10-16 14:13:26 +02004674{
Willy Tarreaue237fe12016-03-10 17:05:28 +01004675 struct connection *conn = objt_conn((kw[4] != 'b') ? smp->sess->origin :
4676 smp->strm ? smp->strm->si[1].end : NULL);
Willy Tarreaube508f12016-03-10 11:47:01 +01004677
Emeric Brun589fcad2012-10-16 14:13:26 +02004678 smp->flags = 0;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004679 if (!conn || !conn->xprt_ctx || conn->xprt != &ssl_sock)
4680 return 0;
4681
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02004682 smp->data.u.sint = (unsigned int)SSL_get_cipher_bits(conn->xprt_ctx, NULL);
4683 if (!smp->data.u.sint)
Emeric Brun589fcad2012-10-16 14:13:26 +02004684 return 0;
4685
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02004686 smp->data.type = SMP_T_SINT;
Emeric Brun589fcad2012-10-16 14:13:26 +02004687
4688 return 1;
4689}
4690
Willy Tarreau6c9a3d52012-10-18 18:57:14 +02004691#ifdef OPENSSL_NPN_NEGOTIATED
Willy Tarreau7875d092012-09-10 08:20:03 +02004692static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02004693smp_fetch_ssl_fc_npn(const struct arg *args, struct sample *smp, const char *kw, void *private)
Willy Tarreaua33c6542012-10-15 13:19:06 +02004694{
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004695 struct connection *conn;
4696
Thierry FOURNIER7654c9f2013-12-17 00:20:33 +01004697 smp->flags = SMP_F_CONST;
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02004698 smp->data.type = SMP_T_STR;
Willy Tarreaua33c6542012-10-15 13:19:06 +02004699
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02004700 conn = objt_conn(smp->sess->origin);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004701 if (!conn || !conn->xprt_ctx || conn->xprt != &ssl_sock)
4702 return 0;
4703
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02004704 smp->data.u.str.str = NULL;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004705 SSL_get0_next_proto_negotiated(conn->xprt_ctx,
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02004706 (const unsigned char **)&smp->data.u.str.str, (unsigned *)&smp->data.u.str.len);
Willy Tarreaua33c6542012-10-15 13:19:06 +02004707
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02004708 if (!smp->data.u.str.str)
Willy Tarreaua33c6542012-10-15 13:19:06 +02004709 return 0;
4710
4711 return 1;
Willy Tarreaua33c6542012-10-15 13:19:06 +02004712}
Willy Tarreau6c9a3d52012-10-18 18:57:14 +02004713#endif
Willy Tarreaua33c6542012-10-15 13:19:06 +02004714
Dirkjan Bussink48f1c4e2014-02-13 12:29:42 +01004715#ifdef TLSEXT_TYPE_application_layer_protocol_negotiation
Willy Tarreauab861d32013-04-02 02:30:41 +02004716static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02004717smp_fetch_ssl_fc_alpn(const struct arg *args, struct sample *smp, const char *kw, void *private)
Willy Tarreauab861d32013-04-02 02:30:41 +02004718{
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004719 struct connection *conn;
4720
Thierry FOURNIER7654c9f2013-12-17 00:20:33 +01004721 smp->flags = SMP_F_CONST;
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02004722 smp->data.type = SMP_T_STR;
Willy Tarreauab861d32013-04-02 02:30:41 +02004723
Willy Tarreaue26bf052015-05-12 10:30:12 +02004724 conn = objt_conn(smp->sess->origin);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004725 if (!conn || !conn->xprt_ctx || conn->xprt != &ssl_sock)
Willy Tarreauab861d32013-04-02 02:30:41 +02004726 return 0;
4727
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02004728 smp->data.u.str.str = NULL;
Dirkjan Bussink48f1c4e2014-02-13 12:29:42 +01004729 SSL_get0_alpn_selected(conn->xprt_ctx,
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02004730 (const unsigned char **)&smp->data.u.str.str, (unsigned *)&smp->data.u.str.len);
Willy Tarreauab861d32013-04-02 02:30:41 +02004731
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02004732 if (!smp->data.u.str.str)
Willy Tarreauab861d32013-04-02 02:30:41 +02004733 return 0;
4734
4735 return 1;
4736}
4737#endif
4738
Emeric Brun645ae792014-04-30 14:21:06 +02004739/* string, returns the used protocol if front conn. transport layer is SSL.
4740 * This function is also usable on backend conn if the fetch keyword 5th
4741 * char is 'b'.
4742 */
Willy Tarreaua33c6542012-10-15 13:19:06 +02004743static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02004744smp_fetch_ssl_fc_protocol(const struct arg *args, struct sample *smp, const char *kw, void *private)
Emeric Brun589fcad2012-10-16 14:13:26 +02004745{
Willy Tarreaue237fe12016-03-10 17:05:28 +01004746 struct connection *conn = objt_conn((kw[4] != 'b') ? smp->sess->origin :
4747 smp->strm ? smp->strm->si[1].end : NULL);
Willy Tarreaube508f12016-03-10 11:47:01 +01004748
Emeric Brun589fcad2012-10-16 14:13:26 +02004749 smp->flags = 0;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004750 if (!conn || !conn->xprt_ctx || conn->xprt != &ssl_sock)
4751 return 0;
4752
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02004753 smp->data.u.str.str = (char *)SSL_get_version(conn->xprt_ctx);
4754 if (!smp->data.u.str.str)
Emeric Brun589fcad2012-10-16 14:13:26 +02004755 return 0;
4756
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02004757 smp->data.type = SMP_T_STR;
Thierry FOURNIER7654c9f2013-12-17 00:20:33 +01004758 smp->flags = SMP_F_CONST;
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02004759 smp->data.u.str.len = strlen(smp->data.u.str.str);
Emeric Brun589fcad2012-10-16 14:13:26 +02004760
4761 return 1;
4762}
4763
Willy Tarreau87b09662015-04-03 00:22:06 +02004764/* binary, returns the SSL stream id if front conn. transport layer is SSL.
Emeric Brun645ae792014-04-30 14:21:06 +02004765 * This function is also usable on backend conn if the fetch keyword 5th
4766 * char is 'b'.
4767 */
Emeric Brun589fcad2012-10-16 14:13:26 +02004768static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02004769smp_fetch_ssl_fc_session_id(const struct arg *args, struct sample *smp, const char *kw, void *private)
Emeric Brunfe68f682012-10-16 14:59:28 +02004770{
4771#if OPENSSL_VERSION_NUMBER > 0x0090800fL
Willy Tarreaue237fe12016-03-10 17:05:28 +01004772 struct connection *conn = objt_conn((kw[4] != 'b') ? smp->sess->origin :
4773 smp->strm ? smp->strm->si[1].end : NULL);
Emeric Brunfe68f682012-10-16 14:59:28 +02004774
Willy Tarreaue237fe12016-03-10 17:05:28 +01004775 SSL_SESSION *ssl_sess;
Willy Tarreaube508f12016-03-10 11:47:01 +01004776
Thierry FOURNIER7654c9f2013-12-17 00:20:33 +01004777 smp->flags = SMP_F_CONST;
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02004778 smp->data.type = SMP_T_BIN;
Emeric Brunfe68f682012-10-16 14:59:28 +02004779
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004780 if (!conn || !conn->xprt_ctx || conn->xprt != &ssl_sock)
4781 return 0;
4782
Willy Tarreau192252e2015-04-04 01:47:55 +02004783 ssl_sess = SSL_get_session(conn->xprt_ctx);
4784 if (!ssl_sess)
Emeric Brunfe68f682012-10-16 14:59:28 +02004785 return 0;
4786
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02004787 smp->data.u.str.str = (char *)SSL_SESSION_get_id(ssl_sess, (unsigned int *)&smp->data.u.str.len);
4788 if (!smp->data.u.str.str || !smp->data.u.str.len)
Emeric Brunfe68f682012-10-16 14:59:28 +02004789 return 0;
4790
4791 return 1;
4792#else
4793 return 0;
4794#endif
4795}
4796
4797static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02004798smp_fetch_ssl_fc_sni(const struct arg *args, struct sample *smp, const char *kw, void *private)
Willy Tarreau7875d092012-09-10 08:20:03 +02004799{
4800#ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004801 struct connection *conn;
4802
Thierry FOURNIER7654c9f2013-12-17 00:20:33 +01004803 smp->flags = SMP_F_CONST;
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02004804 smp->data.type = SMP_T_STR;
Willy Tarreau7875d092012-09-10 08:20:03 +02004805
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02004806 conn = objt_conn(smp->sess->origin);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004807 if (!conn || !conn->xprt_ctx || conn->xprt != &ssl_sock)
4808 return 0;
4809
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02004810 smp->data.u.str.str = (char *)SSL_get_servername(conn->xprt_ctx, TLSEXT_NAMETYPE_host_name);
4811 if (!smp->data.u.str.str)
Willy Tarreau3e394c92012-09-14 23:56:58 +02004812 return 0;
4813
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02004814 smp->data.u.str.len = strlen(smp->data.u.str.str);
Willy Tarreau7875d092012-09-10 08:20:03 +02004815 return 1;
4816#else
4817 return 0;
4818#endif
4819}
4820
David Sc1ad52e2014-04-08 18:48:47 -04004821static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02004822smp_fetch_ssl_fc_unique_id(const struct arg *args, struct sample *smp, const char *kw, void *private)
David Sc1ad52e2014-04-08 18:48:47 -04004823{
4824#if OPENSSL_VERSION_NUMBER > 0x0090800fL
Willy Tarreaue237fe12016-03-10 17:05:28 +01004825 struct connection *conn = objt_conn((kw[4] != 'b') ? smp->sess->origin :
4826 smp->strm ? smp->strm->si[1].end : NULL);
4827
David Sc1ad52e2014-04-08 18:48:47 -04004828 int finished_len;
David Sc1ad52e2014-04-08 18:48:47 -04004829 struct chunk *finished_trash;
David Sc1ad52e2014-04-08 18:48:47 -04004830
4831 smp->flags = 0;
David Sc1ad52e2014-04-08 18:48:47 -04004832 if (!conn || !conn->xprt_ctx || conn->xprt != &ssl_sock)
4833 return 0;
4834
4835 if (!(conn->flags & CO_FL_CONNECTED)) {
4836 smp->flags |= SMP_F_MAY_CHANGE;
4837 return 0;
4838 }
4839
4840 finished_trash = get_trash_chunk();
4841 if (!SSL_session_reused(conn->xprt_ctx))
4842 finished_len = SSL_get_peer_finished(conn->xprt_ctx, finished_trash->str, finished_trash->size);
4843 else
4844 finished_len = SSL_get_finished(conn->xprt_ctx, finished_trash->str, finished_trash->size);
4845
4846 if (!finished_len)
4847 return 0;
4848
Emeric Brunb73a9b02014-04-30 18:49:19 +02004849 finished_trash->len = finished_len;
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02004850 smp->data.u.str = *finished_trash;
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02004851 smp->data.type = SMP_T_BIN;
David Sc1ad52e2014-04-08 18:48:47 -04004852
4853 return 1;
4854#else
4855 return 0;
4856#endif
4857}
4858
Emeric Brun2525b6b2012-10-18 15:59:43 +02004859/* integer, returns the first verify error in CA chain of client certificate chain. */
Emeric Brunf282a812012-09-21 15:27:54 +02004860static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02004861smp_fetch_ssl_c_ca_err(const struct arg *args, struct sample *smp, const char *kw, void *private)
Emeric Brunf282a812012-09-21 15:27:54 +02004862{
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004863 struct connection *conn;
4864
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02004865 conn = objt_conn(smp->sess->origin);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004866 if (!conn || conn->xprt != &ssl_sock)
4867 return 0;
4868
4869 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brunf282a812012-09-21 15:27:54 +02004870 smp->flags = SMP_F_MAY_CHANGE;
4871 return 0;
4872 }
4873
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02004874 smp->data.type = SMP_T_SINT;
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02004875 smp->data.u.sint = (unsigned long long int)SSL_SOCK_ST_TO_CA_ERROR(conn->xprt_st);
Emeric Brunf282a812012-09-21 15:27:54 +02004876 smp->flags = 0;
4877
4878 return 1;
4879}
4880
Emeric Brun2525b6b2012-10-18 15:59:43 +02004881/* integer, returns the depth of the first verify error in CA chain of client certificate chain. */
Emeric Brunf282a812012-09-21 15:27:54 +02004882static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02004883smp_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 +02004884{
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004885 struct connection *conn;
4886
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02004887 conn = objt_conn(smp->sess->origin);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004888 if (!conn || conn->xprt != &ssl_sock)
Emeric Brunf282a812012-09-21 15:27:54 +02004889 return 0;
4890
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004891 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brunf282a812012-09-21 15:27:54 +02004892 smp->flags = SMP_F_MAY_CHANGE;
4893 return 0;
4894 }
4895
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02004896 smp->data.type = SMP_T_SINT;
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02004897 smp->data.u.sint = (long long int)SSL_SOCK_ST_TO_CAEDEPTH(conn->xprt_st);
Emeric Brunf282a812012-09-21 15:27:54 +02004898 smp->flags = 0;
4899
4900 return 1;
4901}
4902
Emeric Brun2525b6b2012-10-18 15:59:43 +02004903/* integer, returns the first verify error on client certificate */
Emeric Brunf282a812012-09-21 15:27:54 +02004904static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02004905smp_fetch_ssl_c_err(const struct arg *args, struct sample *smp, const char *kw, void *private)
Emeric Brunf282a812012-09-21 15:27:54 +02004906{
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004907 struct connection *conn;
4908
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02004909 conn = objt_conn(smp->sess->origin);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004910 if (!conn || conn->xprt != &ssl_sock)
4911 return 0;
4912
4913 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brunf282a812012-09-21 15:27:54 +02004914 smp->flags = SMP_F_MAY_CHANGE;
4915 return 0;
4916 }
4917
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02004918 smp->data.type = SMP_T_SINT;
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02004919 smp->data.u.sint = (long long int)SSL_SOCK_ST_TO_CRTERROR(conn->xprt_st);
Emeric Brunf282a812012-09-21 15:27:54 +02004920 smp->flags = 0;
4921
4922 return 1;
4923}
4924
Emeric Brun2525b6b2012-10-18 15:59:43 +02004925/* integer, returns the verify result on client cert */
Emeric Brunbaf8ffb2012-09-21 15:27:20 +02004926static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02004927smp_fetch_ssl_c_verify(const struct arg *args, struct sample *smp, const char *kw, void *private)
Emeric Brunbaf8ffb2012-09-21 15:27:20 +02004928{
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004929 struct connection *conn;
4930
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02004931 conn = objt_conn(smp->sess->origin);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004932 if (!conn || conn->xprt != &ssl_sock)
4933 return 0;
4934
4935 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brunbaf8ffb2012-09-21 15:27:20 +02004936 smp->flags = SMP_F_MAY_CHANGE;
4937 return 0;
4938 }
4939
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004940 if (!conn->xprt_ctx)
Emeric Brunbaf8ffb2012-09-21 15:27:20 +02004941 return 0;
4942
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02004943 smp->data.type = SMP_T_SINT;
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02004944 smp->data.u.sint = (long long int)SSL_get_verify_result(conn->xprt_ctx);
Emeric Brunbaf8ffb2012-09-21 15:27:20 +02004945 smp->flags = 0;
4946
4947 return 1;
4948}
4949
Emeric Brunfb510ea2012-10-05 12:00:26 +02004950/* parse the "ca-file" bind keyword */
4951static 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 +02004952{
4953 if (!*args[cur_arg + 1]) {
4954 if (err)
4955 memprintf(err, "'%s' : missing CAfile path", args[cur_arg]);
4956 return ERR_ALERT | ERR_FATAL;
4957 }
4958
Emeric Brunef42d922012-10-11 16:11:36 +02004959 if ((*args[cur_arg + 1] != '/') && global.ca_base)
4960 memprintf(&conf->ca_file, "%s/%s", global.ca_base, args[cur_arg + 1]);
4961 else
4962 memprintf(&conf->ca_file, "%s", args[cur_arg + 1]);
Emeric Brunc8e8d122012-10-02 18:42:10 +02004963
Emeric Brund94b3fe2012-09-20 18:23:56 +02004964 return 0;
4965}
4966
Christopher Faulet31af49d2015-06-09 17:29:50 +02004967/* parse the "ca-sign-file" bind keyword */
4968static int bind_parse_ca_sign_file(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
4969{
4970 if (!*args[cur_arg + 1]) {
4971 if (err)
4972 memprintf(err, "'%s' : missing CAfile path", args[cur_arg]);
4973 return ERR_ALERT | ERR_FATAL;
4974 }
4975
4976 if ((*args[cur_arg + 1] != '/') && global.ca_base)
4977 memprintf(&conf->ca_sign_file, "%s/%s", global.ca_base, args[cur_arg + 1]);
4978 else
4979 memprintf(&conf->ca_sign_file, "%s", args[cur_arg + 1]);
4980
4981 return 0;
4982}
4983
4984/* parse the ca-sign-pass bind keyword */
4985
4986static int bind_parse_ca_sign_pass(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
4987{
4988 if (!*args[cur_arg + 1]) {
4989 if (err)
4990 memprintf(err, "'%s' : missing CAkey password", args[cur_arg]);
4991 return ERR_ALERT | ERR_FATAL;
4992 }
4993 memprintf(&conf->ca_sign_pass, "%s", args[cur_arg + 1]);
4994 return 0;
4995}
4996
Willy Tarreau79eeafa2012-09-14 07:53:05 +02004997/* parse the "ciphers" bind keyword */
Willy Tarreau4348fad2012-09-20 16:48:07 +02004998static 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 +02004999{
5000 if (!*args[cur_arg + 1]) {
Willy Tarreaueb6cead2012-09-20 19:43:14 +02005001 memprintf(err, "'%s' : missing cipher suite", args[cur_arg]);
Willy Tarreau79eeafa2012-09-14 07:53:05 +02005002 return ERR_ALERT | ERR_FATAL;
5003 }
5004
Emeric Brun76d88952012-10-05 15:47:31 +02005005 free(conf->ciphers);
Willy Tarreau4348fad2012-09-20 16:48:07 +02005006 conf->ciphers = strdup(args[cur_arg + 1]);
Willy Tarreau79eeafa2012-09-14 07:53:05 +02005007 return 0;
5008}
5009
5010/* parse the "crt" bind keyword */
Willy Tarreau4348fad2012-09-20 16:48:07 +02005011static 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 +02005012{
Willy Tarreau38011032013-08-13 16:59:39 +02005013 char path[MAXPATHLEN];
Willy Tarreaub75d6922014-04-14 18:05:41 +02005014
Willy Tarreau79eeafa2012-09-14 07:53:05 +02005015 if (!*args[cur_arg + 1]) {
Willy Tarreaueb6cead2012-09-20 19:43:14 +02005016 memprintf(err, "'%s' : missing certificate location", args[cur_arg]);
Willy Tarreau79eeafa2012-09-14 07:53:05 +02005017 return ERR_ALERT | ERR_FATAL;
5018 }
5019
Emeric Brunc8e8d122012-10-02 18:42:10 +02005020 if ((*args[cur_arg + 1] != '/' ) && global.crt_base) {
Willy Tarreau38011032013-08-13 16:59:39 +02005021 if ((strlen(global.crt_base) + 1 + strlen(args[cur_arg + 1]) + 1) > MAXPATHLEN) {
Emeric Brunc8e8d122012-10-02 18:42:10 +02005022 memprintf(err, "'%s' : path too long", args[cur_arg]);
5023 return ERR_ALERT | ERR_FATAL;
5024 }
Willy Tarreaub75d6922014-04-14 18:05:41 +02005025 snprintf(path, sizeof(path), "%s/%s", global.crt_base, args[cur_arg + 1]);
Emeric Brunc8e8d122012-10-02 18:42:10 +02005026 if (ssl_sock_load_cert(path, conf, px, err) > 0)
5027 return ERR_ALERT | ERR_FATAL;
5028
5029 return 0;
5030 }
5031
Willy Tarreau4348fad2012-09-20 16:48:07 +02005032 if (ssl_sock_load_cert(args[cur_arg + 1], conf, px, err) > 0)
Willy Tarreau79eeafa2012-09-14 07:53:05 +02005033 return ERR_ALERT | ERR_FATAL;
Emeric Brund94b3fe2012-09-20 18:23:56 +02005034
5035 return 0;
5036}
5037
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01005038/* parse the "crt-list" bind keyword */
5039static int bind_parse_crt_list(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
5040{
5041 if (!*args[cur_arg + 1]) {
5042 memprintf(err, "'%s' : missing certificate location", args[cur_arg]);
5043 return ERR_ALERT | ERR_FATAL;
5044 }
5045
Willy Tarreauad1731d2013-04-02 17:35:58 +02005046 if (ssl_sock_load_cert_list_file(args[cur_arg + 1], conf, px, err) > 0) {
5047 memprintf(err, "'%s' : %s", args[cur_arg], *err);
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01005048 return ERR_ALERT | ERR_FATAL;
Willy Tarreauad1731d2013-04-02 17:35:58 +02005049 }
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01005050
5051 return 0;
5052}
5053
Emeric Brunfb510ea2012-10-05 12:00:26 +02005054/* parse the "crl-file" bind keyword */
5055static 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 +02005056{
Emeric Brun051cdab2012-10-02 19:25:50 +02005057#ifndef X509_V_FLAG_CRL_CHECK
5058 if (err)
5059 memprintf(err, "'%s' : library does not support CRL verify", args[cur_arg]);
5060 return ERR_ALERT | ERR_FATAL;
5061#else
Emeric Brund94b3fe2012-09-20 18:23:56 +02005062 if (!*args[cur_arg + 1]) {
5063 if (err)
5064 memprintf(err, "'%s' : missing CRLfile path", args[cur_arg]);
5065 return ERR_ALERT | ERR_FATAL;
5066 }
Emeric Brun2b58d042012-09-20 17:10:03 +02005067
Emeric Brunef42d922012-10-11 16:11:36 +02005068 if ((*args[cur_arg + 1] != '/') && global.ca_base)
5069 memprintf(&conf->crl_file, "%s/%s", global.ca_base, args[cur_arg + 1]);
5070 else
5071 memprintf(&conf->crl_file, "%s", args[cur_arg + 1]);
Emeric Brunc8e8d122012-10-02 18:42:10 +02005072
Emeric Brun2b58d042012-09-20 17:10:03 +02005073 return 0;
Emeric Brun051cdab2012-10-02 19:25:50 +02005074#endif
Emeric Brun2b58d042012-09-20 17:10:03 +02005075}
5076
5077/* parse the "ecdhe" bind keyword keywords */
5078static int bind_parse_ecdhe(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
5079{
5080#if OPENSSL_VERSION_NUMBER < 0x0090800fL
5081 if (err)
5082 memprintf(err, "'%s' : library does not support elliptic curve Diffie-Hellman (too old)", args[cur_arg]);
5083 return ERR_ALERT | ERR_FATAL;
5084#elif defined(OPENSSL_NO_ECDH)
5085 if (err)
5086 memprintf(err, "'%s' : library does not support elliptic curve Diffie-Hellman (disabled via OPENSSL_NO_ECDH)", args[cur_arg]);
5087 return ERR_ALERT | ERR_FATAL;
5088#else
5089 if (!*args[cur_arg + 1]) {
5090 if (err)
5091 memprintf(err, "'%s' : missing named curve", args[cur_arg]);
5092 return ERR_ALERT | ERR_FATAL;
5093 }
5094
5095 conf->ecdhe = strdup(args[cur_arg + 1]);
Willy Tarreau79eeafa2012-09-14 07:53:05 +02005096
5097 return 0;
Emeric Brun2b58d042012-09-20 17:10:03 +02005098#endif
Willy Tarreau79eeafa2012-09-14 07:53:05 +02005099}
5100
Emeric Brun81c00f02012-09-21 14:31:21 +02005101/* parse the "crt_ignerr" and "ca_ignerr" bind keywords */
5102static int bind_parse_ignore_err(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
5103{
5104 int code;
5105 char *p = args[cur_arg + 1];
5106 unsigned long long *ignerr = &conf->crt_ignerr;
5107
5108 if (!*p) {
5109 if (err)
5110 memprintf(err, "'%s' : missing error IDs list", args[cur_arg]);
5111 return ERR_ALERT | ERR_FATAL;
5112 }
5113
5114 if (strcmp(args[cur_arg], "ca-ignore-err") == 0)
5115 ignerr = &conf->ca_ignerr;
5116
5117 if (strcmp(p, "all") == 0) {
5118 *ignerr = ~0ULL;
5119 return 0;
5120 }
5121
5122 while (p) {
5123 code = atoi(p);
5124 if ((code <= 0) || (code > 63)) {
5125 if (err)
5126 memprintf(err, "'%s' : ID '%d' out of range (1..63) in error IDs list '%s'",
5127 args[cur_arg], code, args[cur_arg + 1]);
5128 return ERR_ALERT | ERR_FATAL;
5129 }
5130 *ignerr |= 1ULL << code;
5131 p = strchr(p, ',');
5132 if (p)
5133 p++;
5134 }
5135
Emeric Brun2cb7ae52012-10-05 14:14:21 +02005136 return 0;
5137}
5138
5139/* parse the "force-sslv3" bind keyword */
5140static int bind_parse_force_sslv3(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
5141{
5142 conf->ssl_options |= BC_SSL_O_USE_SSLV3;
5143 return 0;
5144}
5145
5146/* parse the "force-tlsv10" bind keyword */
5147static int bind_parse_force_tlsv10(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
5148{
5149 conf->ssl_options |= BC_SSL_O_USE_TLSV10;
Emeric Brun2d0c4822012-10-02 13:45:20 +02005150 return 0;
5151}
5152
Emeric Brun2cb7ae52012-10-05 14:14:21 +02005153/* parse the "force-tlsv11" bind keyword */
5154static int bind_parse_force_tlsv11(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
5155{
5156#if SSL_OP_NO_TLSv1_1
5157 conf->ssl_options |= BC_SSL_O_USE_TLSV11;
5158 return 0;
5159#else
5160 if (err)
5161 memprintf(err, "'%s' : library does not support protocol TLSv1.1", args[cur_arg]);
5162 return ERR_ALERT | ERR_FATAL;
5163#endif
5164}
5165
5166/* parse the "force-tlsv12" bind keyword */
5167static int bind_parse_force_tlsv12(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
5168{
5169#if SSL_OP_NO_TLSv1_2
5170 conf->ssl_options |= BC_SSL_O_USE_TLSV12;
5171 return 0;
5172#else
5173 if (err)
5174 memprintf(err, "'%s' : library does not support protocol TLSv1.2", args[cur_arg]);
5175 return ERR_ALERT | ERR_FATAL;
5176#endif
5177}
5178
5179
Emeric Brun2d0c4822012-10-02 13:45:20 +02005180/* parse the "no-tls-tickets" bind keyword */
5181static int bind_parse_no_tls_tickets(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
5182{
Emeric Brun89675492012-10-05 13:48:26 +02005183 conf->ssl_options |= BC_SSL_O_NO_TLS_TICKETS;
Emeric Brun81c00f02012-09-21 14:31:21 +02005184 return 0;
5185}
5186
Emeric Brun2d0c4822012-10-02 13:45:20 +02005187
Emeric Brun9b3009b2012-10-05 11:55:06 +02005188/* parse the "no-sslv3" bind keyword */
5189static 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 +02005190{
Emeric Brun89675492012-10-05 13:48:26 +02005191 conf->ssl_options |= BC_SSL_O_NO_SSLV3;
Willy Tarreau79eeafa2012-09-14 07:53:05 +02005192 return 0;
5193}
5194
Emeric Brun9b3009b2012-10-05 11:55:06 +02005195/* parse the "no-tlsv10" bind keyword */
5196static 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 +02005197{
Emeric Brun89675492012-10-05 13:48:26 +02005198 conf->ssl_options |= BC_SSL_O_NO_TLSV10;
Emeric Brunc0ff4922012-09-28 19:37:02 +02005199 return 0;
5200}
5201
Emeric Brun9b3009b2012-10-05 11:55:06 +02005202/* parse the "no-tlsv11" bind keyword */
5203static 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 +02005204{
Emeric Brun89675492012-10-05 13:48:26 +02005205 conf->ssl_options |= BC_SSL_O_NO_TLSV11;
Emeric Brunc0ff4922012-09-28 19:37:02 +02005206 return 0;
5207}
5208
Emeric Brun9b3009b2012-10-05 11:55:06 +02005209/* parse the "no-tlsv12" bind keyword */
5210static 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 +02005211{
Emeric Brun89675492012-10-05 13:48:26 +02005212 conf->ssl_options |= BC_SSL_O_NO_TLSV12;
Willy Tarreau79eeafa2012-09-14 07:53:05 +02005213 return 0;
5214}
5215
Willy Tarreau6c9a3d52012-10-18 18:57:14 +02005216/* parse the "npn" bind keyword */
5217static int bind_parse_npn(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
5218{
5219#ifdef OPENSSL_NPN_NEGOTIATED
5220 char *p1, *p2;
5221
5222 if (!*args[cur_arg + 1]) {
5223 memprintf(err, "'%s' : missing the comma-delimited NPN protocol suite", args[cur_arg]);
5224 return ERR_ALERT | ERR_FATAL;
5225 }
5226
5227 free(conf->npn_str);
5228
Willy Tarreau3724da12016-02-12 17:11:12 +01005229 /* the NPN string is built as a suite of (<len> <name>)*,
5230 * so we reuse each comma to store the next <len> and need
5231 * one more for the end of the string.
5232 */
Willy Tarreau6c9a3d52012-10-18 18:57:14 +02005233 conf->npn_len = strlen(args[cur_arg + 1]) + 1;
Willy Tarreau3724da12016-02-12 17:11:12 +01005234 conf->npn_str = calloc(1, conf->npn_len + 1);
Willy Tarreau6c9a3d52012-10-18 18:57:14 +02005235 memcpy(conf->npn_str + 1, args[cur_arg + 1], conf->npn_len);
5236
5237 /* replace commas with the name length */
5238 p1 = conf->npn_str;
5239 p2 = p1 + 1;
5240 while (1) {
5241 p2 = memchr(p1 + 1, ',', conf->npn_str + conf->npn_len - (p1 + 1));
5242 if (!p2)
5243 p2 = p1 + 1 + strlen(p1 + 1);
5244
5245 if (p2 - (p1 + 1) > 255) {
5246 *p2 = '\0';
5247 memprintf(err, "'%s' : NPN protocol name too long : '%s'", args[cur_arg], p1 + 1);
5248 return ERR_ALERT | ERR_FATAL;
5249 }
5250
5251 *p1 = p2 - (p1 + 1);
5252 p1 = p2;
5253
5254 if (!*p2)
5255 break;
5256
5257 *(p2++) = '\0';
5258 }
5259 return 0;
5260#else
5261 if (err)
5262 memprintf(err, "'%s' : library does not support TLS NPN extension", args[cur_arg]);
5263 return ERR_ALERT | ERR_FATAL;
5264#endif
5265}
5266
Willy Tarreauab861d32013-04-02 02:30:41 +02005267/* parse the "alpn" bind keyword */
5268static int bind_parse_alpn(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
5269{
Dirkjan Bussink48f1c4e2014-02-13 12:29:42 +01005270#ifdef TLSEXT_TYPE_application_layer_protocol_negotiation
Willy Tarreauab861d32013-04-02 02:30:41 +02005271 char *p1, *p2;
5272
5273 if (!*args[cur_arg + 1]) {
5274 memprintf(err, "'%s' : missing the comma-delimited ALPN protocol suite", args[cur_arg]);
5275 return ERR_ALERT | ERR_FATAL;
5276 }
5277
5278 free(conf->alpn_str);
5279
Marcoen Hirschbergbef60912016-02-12 17:05:24 +01005280 /* the ALPN string is built as a suite of (<len> <name>)*,
5281 * so we reuse each comma to store the next <len> and need
5282 * one more for the end of the string.
5283 */
Willy Tarreauab861d32013-04-02 02:30:41 +02005284 conf->alpn_len = strlen(args[cur_arg + 1]) + 1;
Marcoen Hirschbergbef60912016-02-12 17:05:24 +01005285 conf->alpn_str = calloc(1, conf->alpn_len + 1);
Willy Tarreauab861d32013-04-02 02:30:41 +02005286 memcpy(conf->alpn_str + 1, args[cur_arg + 1], conf->alpn_len);
5287
5288 /* replace commas with the name length */
5289 p1 = conf->alpn_str;
5290 p2 = p1 + 1;
5291 while (1) {
5292 p2 = memchr(p1 + 1, ',', conf->alpn_str + conf->alpn_len - (p1 + 1));
5293 if (!p2)
5294 p2 = p1 + 1 + strlen(p1 + 1);
5295
5296 if (p2 - (p1 + 1) > 255) {
5297 *p2 = '\0';
5298 memprintf(err, "'%s' : ALPN protocol name too long : '%s'", args[cur_arg], p1 + 1);
5299 return ERR_ALERT | ERR_FATAL;
5300 }
5301
5302 *p1 = p2 - (p1 + 1);
5303 p1 = p2;
5304
5305 if (!*p2)
5306 break;
5307
5308 *(p2++) = '\0';
5309 }
5310 return 0;
5311#else
5312 if (err)
5313 memprintf(err, "'%s' : library does not support TLS ALPN extension", args[cur_arg]);
5314 return ERR_ALERT | ERR_FATAL;
5315#endif
5316}
5317
Willy Tarreau79eeafa2012-09-14 07:53:05 +02005318/* parse the "ssl" bind keyword */
Willy Tarreau4348fad2012-09-20 16:48:07 +02005319static 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 +02005320{
Willy Tarreau81796be2012-09-22 19:11:47 +02005321 struct listener *l;
5322
Willy Tarreau4348fad2012-09-20 16:48:07 +02005323 conf->is_ssl = 1;
Emeric Brun76d88952012-10-05 15:47:31 +02005324
5325 if (global.listen_default_ciphers && !conf->ciphers)
5326 conf->ciphers = strdup(global.listen_default_ciphers);
Emeric Brun2c86cbf2014-10-30 15:56:50 +01005327 conf->ssl_options |= global.listen_default_ssloptions;
Emeric Brun76d88952012-10-05 15:47:31 +02005328
Willy Tarreau81796be2012-09-22 19:11:47 +02005329 list_for_each_entry(l, &conf->listeners, by_bind)
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02005330 l->xprt = &ssl_sock;
Willy Tarreau81796be2012-09-22 19:11:47 +02005331
Willy Tarreau79eeafa2012-09-14 07:53:05 +02005332 return 0;
5333}
5334
Christopher Faulet31af49d2015-06-09 17:29:50 +02005335/* parse the "generate-certificates" bind keyword */
5336static int bind_parse_generate_certs(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
5337{
5338#ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME
5339 conf->generate_certs = 1;
5340#else
5341 memprintf(err, "%sthis version of openssl cannot generate SSL certificates.\n",
5342 err && *err ? *err : "");
5343#endif
5344 return 0;
5345}
5346
Emmanuel Hocdet65623372013-01-24 17:17:15 +01005347/* parse the "strict-sni" bind keyword */
5348static int bind_parse_strict_sni(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
5349{
5350 conf->strict_sni = 1;
5351 return 0;
Nenad Merdanovic05552d42015-02-27 19:56:49 +01005352}
5353
5354/* parse the "tls-ticket-keys" bind keyword */
5355static int bind_parse_tls_ticket_keys(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
5356{
5357#if (defined SSL_CTRL_SET_TLSEXT_TICKET_KEY_CB && TLS_TICKETS_NO > 0)
5358 FILE *f;
5359 int i = 0;
5360 char thisline[LINESIZE];
Nenad Merdanovic146defa2015-05-09 08:46:00 +02005361 struct tls_keys_ref *keys_ref;
Nenad Merdanovic05552d42015-02-27 19:56:49 +01005362
5363 if (!*args[cur_arg + 1]) {
5364 if (err)
5365 memprintf(err, "'%s' : missing TLS ticket keys file path", args[cur_arg]);
5366 return ERR_ALERT | ERR_FATAL;
5367 }
5368
Nenad Merdanovic200b0fa2015-05-09 08:46:01 +02005369 keys_ref = tlskeys_ref_lookup(args[cur_arg + 1]);
5370 if(keys_ref) {
5371 conf->keys_ref = keys_ref;
5372 return 0;
5373 }
5374
Vincent Bernat02779b62016-04-03 13:48:43 +02005375 keys_ref = malloc(sizeof(*keys_ref));
Nenad Merdanovic146defa2015-05-09 08:46:00 +02005376 keys_ref->tlskeys = malloc(TLS_TICKETS_NO * sizeof(struct tls_sess_key));
Nenad Merdanovic05552d42015-02-27 19:56:49 +01005377
5378 if ((f = fopen(args[cur_arg + 1], "r")) == NULL) {
5379 if (err)
5380 memprintf(err, "'%s' : unable to load ssl tickets keys file", args[cur_arg+1]);
5381 return ERR_ALERT | ERR_FATAL;
5382 }
5383
Nenad Merdanovic146defa2015-05-09 08:46:00 +02005384 keys_ref->filename = strdup(args[cur_arg + 1]);
5385
Nenad Merdanovic05552d42015-02-27 19:56:49 +01005386 while (fgets(thisline, sizeof(thisline), f) != NULL) {
5387 int len = strlen(thisline);
5388 /* Strip newline characters from the end */
5389 if(thisline[len - 1] == '\n')
5390 thisline[--len] = 0;
5391
5392 if(thisline[len - 1] == '\r')
5393 thisline[--len] = 0;
5394
Nenad Merdanovic146defa2015-05-09 08:46:00 +02005395 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 +01005396 if (err)
5397 memprintf(err, "'%s' : unable to decode base64 key on line %d", args[cur_arg+1], i + 1);
5398 return ERR_ALERT | ERR_FATAL;
5399 }
5400 i++;
5401 }
5402
5403 if (i < TLS_TICKETS_NO) {
5404 if (err)
5405 memprintf(err, "'%s' : please supply at least %d keys in the tls-tickets-file", args[cur_arg+1], TLS_TICKETS_NO);
5406 return ERR_ALERT | ERR_FATAL;
5407 }
5408
5409 fclose(f);
5410
5411 /* Use penultimate key for encryption, handle when TLS_TICKETS_NO = 1 */
Nenad Merdanovic17891152016-03-25 22:16:57 +01005412 i -= 2;
5413 keys_ref->tls_ticket_enc_index = i < 0 ? 0 : i % TLS_TICKETS_NO;
Nenad Merdanovic200b0fa2015-05-09 08:46:01 +02005414 keys_ref->unique_id = -1;
Nenad Merdanovic146defa2015-05-09 08:46:00 +02005415 conf->keys_ref = keys_ref;
Nenad Merdanovic05552d42015-02-27 19:56:49 +01005416
Nenad Merdanovic200b0fa2015-05-09 08:46:01 +02005417 LIST_ADD(&tlskeys_reference, &keys_ref->list);
5418
Nenad Merdanovic05552d42015-02-27 19:56:49 +01005419 return 0;
5420#else
5421 if (err)
5422 memprintf(err, "'%s' : TLS ticket callback extension not supported", args[cur_arg]);
5423 return ERR_ALERT | ERR_FATAL;
5424#endif /* SSL_CTRL_SET_TLSEXT_TICKET_KEY_CB */
Emmanuel Hocdet65623372013-01-24 17:17:15 +01005425}
5426
Emeric Brund94b3fe2012-09-20 18:23:56 +02005427/* parse the "verify" bind keyword */
5428static int bind_parse_verify(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
5429{
5430 if (!*args[cur_arg + 1]) {
5431 if (err)
5432 memprintf(err, "'%s' : missing verify method", args[cur_arg]);
5433 return ERR_ALERT | ERR_FATAL;
5434 }
5435
5436 if (strcmp(args[cur_arg + 1], "none") == 0)
Emeric Brun850efd52014-01-29 12:24:34 +01005437 conf->verify = SSL_SOCK_VERIFY_NONE;
Emeric Brund94b3fe2012-09-20 18:23:56 +02005438 else if (strcmp(args[cur_arg + 1], "optional") == 0)
Emeric Brun850efd52014-01-29 12:24:34 +01005439 conf->verify = SSL_SOCK_VERIFY_OPTIONAL;
Emeric Brund94b3fe2012-09-20 18:23:56 +02005440 else if (strcmp(args[cur_arg + 1], "required") == 0)
Emeric Brun850efd52014-01-29 12:24:34 +01005441 conf->verify = SSL_SOCK_VERIFY_REQUIRED;
Emeric Brund94b3fe2012-09-20 18:23:56 +02005442 else {
5443 if (err)
5444 memprintf(err, "'%s' : unknown verify method '%s', only 'none', 'optional', and 'required' are supported\n",
5445 args[cur_arg], args[cur_arg + 1]);
5446 return ERR_ALERT | ERR_FATAL;
5447 }
5448
5449 return 0;
5450}
5451
Willy Tarreau92faadf2012-10-10 23:04:25 +02005452/************** "server" keywords ****************/
5453
Emeric Brunef42d922012-10-11 16:11:36 +02005454/* parse the "ca-file" server keyword */
5455static int srv_parse_ca_file(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
5456{
5457 if (!*args[*cur_arg + 1]) {
5458 if (err)
5459 memprintf(err, "'%s' : missing CAfile path", args[*cur_arg]);
5460 return ERR_ALERT | ERR_FATAL;
5461 }
5462
5463 if ((*args[*cur_arg + 1] != '/') && global.ca_base)
5464 memprintf(&newsrv->ssl_ctx.ca_file, "%s/%s", global.ca_base, args[*cur_arg + 1]);
5465 else
5466 memprintf(&newsrv->ssl_ctx.ca_file, "%s", args[*cur_arg + 1]);
5467
5468 return 0;
5469}
5470
Willy Tarreau92faadf2012-10-10 23:04:25 +02005471/* parse the "check-ssl" server keyword */
5472static int srv_parse_check_ssl(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
5473{
5474 newsrv->check.use_ssl = 1;
5475 if (global.connect_default_ciphers && !newsrv->ssl_ctx.ciphers)
5476 newsrv->ssl_ctx.ciphers = strdup(global.connect_default_ciphers);
Emeric Brun2c86cbf2014-10-30 15:56:50 +01005477 newsrv->ssl_ctx.options |= global.connect_default_ssloptions;
Willy Tarreau92faadf2012-10-10 23:04:25 +02005478 return 0;
5479}
5480
5481/* parse the "ciphers" server keyword */
5482static int srv_parse_ciphers(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
5483{
5484 if (!*args[*cur_arg + 1]) {
5485 memprintf(err, "'%s' : missing cipher suite", args[*cur_arg]);
5486 return ERR_ALERT | ERR_FATAL;
5487 }
5488
5489 free(newsrv->ssl_ctx.ciphers);
5490 newsrv->ssl_ctx.ciphers = strdup(args[*cur_arg + 1]);
5491 return 0;
5492}
5493
Emeric Brunef42d922012-10-11 16:11:36 +02005494/* parse the "crl-file" server keyword */
5495static int srv_parse_crl_file(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
5496{
5497#ifndef X509_V_FLAG_CRL_CHECK
5498 if (err)
5499 memprintf(err, "'%s' : library does not support CRL verify", args[*cur_arg]);
5500 return ERR_ALERT | ERR_FATAL;
5501#else
5502 if (!*args[*cur_arg + 1]) {
5503 if (err)
5504 memprintf(err, "'%s' : missing CRLfile path", args[*cur_arg]);
5505 return ERR_ALERT | ERR_FATAL;
5506 }
5507
5508 if ((*args[*cur_arg + 1] != '/') && global.ca_base)
5509 memprintf(&newsrv->ssl_ctx.crl_file, "%s/%s", global.ca_base, args[*cur_arg + 1]);
5510 else
5511 memprintf(&newsrv->ssl_ctx.crl_file, "%s", args[*cur_arg + 1]);
5512
5513 return 0;
5514#endif
5515}
5516
Emeric Bruna7aa3092012-10-26 12:58:00 +02005517/* parse the "crt" server keyword */
5518static int srv_parse_crt(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
5519{
5520 if (!*args[*cur_arg + 1]) {
5521 if (err)
5522 memprintf(err, "'%s' : missing certificate file path", args[*cur_arg]);
5523 return ERR_ALERT | ERR_FATAL;
5524 }
5525
5526 if ((*args[*cur_arg + 1] != '/') && global.crt_base)
5527 memprintf(&newsrv->ssl_ctx.client_crt, "%s/%s", global.ca_base, args[*cur_arg + 1]);
5528 else
5529 memprintf(&newsrv->ssl_ctx.client_crt, "%s", args[*cur_arg + 1]);
5530
5531 return 0;
5532}
Emeric Brunef42d922012-10-11 16:11:36 +02005533
Willy Tarreau92faadf2012-10-10 23:04:25 +02005534/* parse the "force-sslv3" server keyword */
5535static int srv_parse_force_sslv3(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
5536{
5537 newsrv->ssl_ctx.options |= SRV_SSL_O_USE_SSLV3;
5538 return 0;
5539}
5540
5541/* parse the "force-tlsv10" server keyword */
5542static int srv_parse_force_tlsv10(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
5543{
5544 newsrv->ssl_ctx.options |= SRV_SSL_O_USE_TLSV10;
5545 return 0;
5546}
5547
5548/* parse the "force-tlsv11" server keyword */
5549static int srv_parse_force_tlsv11(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
5550{
5551#if SSL_OP_NO_TLSv1_1
5552 newsrv->ssl_ctx.options |= SRV_SSL_O_USE_TLSV11;
5553 return 0;
5554#else
5555 if (err)
5556 memprintf(err, "'%s' : library does not support protocol TLSv1.1", args[*cur_arg]);
5557 return ERR_ALERT | ERR_FATAL;
5558#endif
5559}
5560
5561/* parse the "force-tlsv12" server keyword */
5562static int srv_parse_force_tlsv12(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
5563{
5564#if SSL_OP_NO_TLSv1_2
5565 newsrv->ssl_ctx.options |= SRV_SSL_O_USE_TLSV12;
5566 return 0;
5567#else
5568 if (err)
5569 memprintf(err, "'%s' : library does not support protocol TLSv1.2", args[*cur_arg]);
5570 return ERR_ALERT | ERR_FATAL;
5571#endif
5572}
5573
Willy Tarreau2a3fb1c2015-02-05 16:47:07 +01005574/* parse the "no-ssl-reuse" server keyword */
5575static int srv_parse_no_ssl_reuse(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
5576{
5577 newsrv->ssl_ctx.options |= SRV_SSL_O_NO_REUSE;
5578 return 0;
5579}
5580
Willy Tarreau92faadf2012-10-10 23:04:25 +02005581/* parse the "no-sslv3" server keyword */
5582static int srv_parse_no_sslv3(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
5583{
5584 newsrv->ssl_ctx.options |= SRV_SSL_O_NO_SSLV3;
5585 return 0;
5586}
5587
5588/* parse the "no-tlsv10" server keyword */
5589static int srv_parse_no_tlsv10(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
5590{
5591 newsrv->ssl_ctx.options |= SRV_SSL_O_NO_TLSV10;
5592 return 0;
5593}
5594
5595/* parse the "no-tlsv11" server keyword */
5596static int srv_parse_no_tlsv11(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
5597{
5598 newsrv->ssl_ctx.options |= SRV_SSL_O_NO_TLSV11;
5599 return 0;
5600}
5601
5602/* parse the "no-tlsv12" server keyword */
5603static int srv_parse_no_tlsv12(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
5604{
5605 newsrv->ssl_ctx.options |= SRV_SSL_O_NO_TLSV12;
5606 return 0;
5607}
5608
Emeric Brunf9c5c472012-10-11 15:28:34 +02005609/* parse the "no-tls-tickets" server keyword */
5610static int srv_parse_no_tls_tickets(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
5611{
5612 newsrv->ssl_ctx.options |= SRV_SSL_O_NO_TLS_TICKETS;
5613 return 0;
5614}
David Safb76832014-05-08 23:42:08 -04005615/* parse the "send-proxy-v2-ssl" server keyword */
5616static int srv_parse_send_proxy_ssl(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
5617{
5618 newsrv->pp_opts |= SRV_PP_V2;
5619 newsrv->pp_opts |= SRV_PP_V2_SSL;
5620 return 0;
5621}
5622
5623/* parse the "send-proxy-v2-ssl-cn" server keyword */
5624static int srv_parse_send_proxy_cn(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
5625{
5626 newsrv->pp_opts |= SRV_PP_V2;
5627 newsrv->pp_opts |= SRV_PP_V2_SSL;
5628 newsrv->pp_opts |= SRV_PP_V2_SSL_CN;
5629 return 0;
5630}
Emeric Brunf9c5c472012-10-11 15:28:34 +02005631
Willy Tarreau732eac42015-07-09 11:40:25 +02005632/* parse the "sni" server keyword */
5633static int srv_parse_sni(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
5634{
5635#ifndef SSL_CTRL_SET_TLSEXT_HOSTNAME
5636 memprintf(err, "'%s' : the current SSL library doesn't support the SNI TLS extension", args[*cur_arg]);
5637 return ERR_ALERT | ERR_FATAL;
5638#else
Cyril Bonté23d19d62016-03-07 22:13:22 +01005639 int idx;
Willy Tarreau732eac42015-07-09 11:40:25 +02005640 struct sample_expr *expr;
5641
5642 if (!*args[*cur_arg + 1]) {
5643 memprintf(err, "'%s' : missing sni expression", args[*cur_arg]);
5644 return ERR_ALERT | ERR_FATAL;
5645 }
5646
Cyril Bonté23d19d62016-03-07 22:13:22 +01005647 idx = (*cur_arg) + 1;
Willy Tarreau732eac42015-07-09 11:40:25 +02005648 proxy->conf.args.ctx = ARGC_SRV;
5649
Cyril Bonté23d19d62016-03-07 22:13:22 +01005650 expr = sample_parse_expr((char **)args, &idx, px->conf.file, px->conf.line, err, &proxy->conf.args);
Willy Tarreau732eac42015-07-09 11:40:25 +02005651 if (!expr) {
5652 memprintf(err, "error detected while parsing sni expression : %s", *err);
5653 return ERR_ALERT | ERR_FATAL;
5654 }
5655
5656 if (!(expr->fetch->val & SMP_VAL_BE_SRV_CON)) {
5657 memprintf(err, "error detected while parsing sni expression : "
5658 " fetch method '%s' extracts information from '%s', none of which is available here.\n",
Cyril Bonté23d19d62016-03-07 22:13:22 +01005659 args[idx-1], sample_src_names(expr->fetch->use));
Willy Tarreau732eac42015-07-09 11:40:25 +02005660 return ERR_ALERT | ERR_FATAL;
5661 }
5662
5663 px->http_needed |= !!(expr->fetch->use & SMP_USE_HTTP_ANY);
5664 newsrv->ssl_ctx.sni = expr;
5665 return 0;
5666#endif
5667}
5668
Willy Tarreau92faadf2012-10-10 23:04:25 +02005669/* parse the "ssl" server keyword */
5670static int srv_parse_ssl(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
5671{
5672 newsrv->use_ssl = 1;
5673 if (global.connect_default_ciphers && !newsrv->ssl_ctx.ciphers)
5674 newsrv->ssl_ctx.ciphers = strdup(global.connect_default_ciphers);
5675 return 0;
5676}
5677
Emeric Brunef42d922012-10-11 16:11:36 +02005678/* parse the "verify" server keyword */
5679static int srv_parse_verify(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
5680{
5681 if (!*args[*cur_arg + 1]) {
5682 if (err)
5683 memprintf(err, "'%s' : missing verify method", args[*cur_arg]);
5684 return ERR_ALERT | ERR_FATAL;
5685 }
5686
5687 if (strcmp(args[*cur_arg + 1], "none") == 0)
Emeric Brun850efd52014-01-29 12:24:34 +01005688 newsrv->ssl_ctx.verify = SSL_SOCK_VERIFY_NONE;
Emeric Brunef42d922012-10-11 16:11:36 +02005689 else if (strcmp(args[*cur_arg + 1], "required") == 0)
Emeric Brun850efd52014-01-29 12:24:34 +01005690 newsrv->ssl_ctx.verify = SSL_SOCK_VERIFY_REQUIRED;
Emeric Brunef42d922012-10-11 16:11:36 +02005691 else {
5692 if (err)
5693 memprintf(err, "'%s' : unknown verify method '%s', only 'none' and 'required' are supported\n",
5694 args[*cur_arg], args[*cur_arg + 1]);
5695 return ERR_ALERT | ERR_FATAL;
5696 }
5697
Evan Broderbe554312013-06-27 00:05:25 -07005698 return 0;
5699}
5700
5701/* parse the "verifyhost" server keyword */
5702static int srv_parse_verifyhost(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
5703{
5704 if (!*args[*cur_arg + 1]) {
5705 if (err)
5706 memprintf(err, "'%s' : missing hostname to verify against", args[*cur_arg]);
5707 return ERR_ALERT | ERR_FATAL;
5708 }
5709
5710 newsrv->ssl_ctx.verify_host = strdup(args[*cur_arg + 1]);
5711
Emeric Brunef42d922012-10-11 16:11:36 +02005712 return 0;
5713}
5714
Emeric Brun2c86cbf2014-10-30 15:56:50 +01005715/* parse the "ssl-default-bind-options" keyword in global section */
5716static int ssl_parse_default_bind_options(char **args, int section_type, struct proxy *curpx,
5717 struct proxy *defpx, const char *file, int line,
5718 char **err) {
5719 int i = 1;
5720
5721 if (*(args[i]) == 0) {
5722 memprintf(err, "global statement '%s' expects an option as an argument.", args[0]);
5723 return -1;
5724 }
5725 while (*(args[i])) {
5726 if (!strcmp(args[i], "no-sslv3"))
5727 global.listen_default_ssloptions |= BC_SSL_O_NO_SSLV3;
5728 else if (!strcmp(args[i], "no-tlsv10"))
5729 global.listen_default_ssloptions |= BC_SSL_O_NO_TLSV10;
5730 else if (!strcmp(args[i], "no-tlsv11"))
5731 global.listen_default_ssloptions |= BC_SSL_O_NO_TLSV11;
5732 else if (!strcmp(args[i], "no-tlsv12"))
5733 global.listen_default_ssloptions |= BC_SSL_O_NO_TLSV12;
5734 else if (!strcmp(args[i], "force-sslv3"))
5735 global.listen_default_ssloptions |= BC_SSL_O_USE_SSLV3;
5736 else if (!strcmp(args[i], "force-tlsv10"))
5737 global.listen_default_ssloptions |= BC_SSL_O_USE_TLSV10;
5738 else if (!strcmp(args[i], "force-tlsv11")) {
5739#if SSL_OP_NO_TLSv1_1
5740 global.listen_default_ssloptions |= BC_SSL_O_USE_TLSV11;
5741#else
5742 memprintf(err, "'%s' '%s': library does not support protocol TLSv1.1", args[0], args[i]);
5743 return -1;
5744#endif
5745 }
5746 else if (!strcmp(args[i], "force-tlsv12")) {
5747#if SSL_OP_NO_TLSv1_2
5748 global.listen_default_ssloptions |= BC_SSL_O_USE_TLSV12;
5749#else
5750 memprintf(err, "'%s' '%s': library does not support protocol TLSv1.2", args[0], args[i]);
5751 return -1;
5752#endif
5753 }
5754 else if (!strcmp(args[i], "no-tls-tickets"))
5755 global.listen_default_ssloptions |= BC_SSL_O_NO_TLS_TICKETS;
5756 else {
5757 memprintf(err, "unknown option '%s' on global statement '%s'.", args[i], args[0]);
5758 return -1;
5759 }
5760 i++;
5761 }
5762 return 0;
5763}
5764
5765/* parse the "ssl-default-server-options" keyword in global section */
5766static int ssl_parse_default_server_options(char **args, int section_type, struct proxy *curpx,
5767 struct proxy *defpx, const char *file, int line,
5768 char **err) {
5769 int i = 1;
5770
5771 if (*(args[i]) == 0) {
5772 memprintf(err, "global statement '%s' expects an option as an argument.", args[0]);
5773 return -1;
5774 }
5775 while (*(args[i])) {
5776 if (!strcmp(args[i], "no-sslv3"))
5777 global.connect_default_ssloptions |= SRV_SSL_O_NO_SSLV3;
5778 else if (!strcmp(args[i], "no-tlsv10"))
5779 global.connect_default_ssloptions |= SRV_SSL_O_NO_TLSV10;
5780 else if (!strcmp(args[i], "no-tlsv11"))
5781 global.connect_default_ssloptions |= SRV_SSL_O_NO_TLSV11;
5782 else if (!strcmp(args[i], "no-tlsv12"))
5783 global.connect_default_ssloptions |= SRV_SSL_O_NO_TLSV12;
5784 else if (!strcmp(args[i], "force-sslv3"))
5785 global.connect_default_ssloptions |= SRV_SSL_O_USE_SSLV3;
5786 else if (!strcmp(args[i], "force-tlsv10"))
5787 global.connect_default_ssloptions |= SRV_SSL_O_USE_TLSV10;
5788 else if (!strcmp(args[i], "force-tlsv11")) {
5789#if SSL_OP_NO_TLSv1_1
5790 global.connect_default_ssloptions |= SRV_SSL_O_USE_TLSV11;
5791#else
5792 memprintf(err, "'%s' '%s': library does not support protocol TLSv1.1", args[0], args[i]);
5793 return -1;
5794#endif
5795 }
5796 else if (!strcmp(args[i], "force-tlsv12")) {
5797#if SSL_OP_NO_TLSv1_2
5798 global.connect_default_ssloptions |= SRV_SSL_O_USE_TLSV12;
5799#else
5800 memprintf(err, "'%s' '%s': library does not support protocol TLSv1.2", args[0], args[i]);
5801 return -1;
5802#endif
5803 }
5804 else if (!strcmp(args[i], "no-tls-tickets"))
5805 global.connect_default_ssloptions |= SRV_SSL_O_NO_TLS_TICKETS;
5806 else {
5807 memprintf(err, "unknown option '%s' on global statement '%s'.", args[i], args[0]);
5808 return -1;
5809 }
5810 i++;
5811 }
5812 return 0;
5813}
5814
Willy Tarreau7875d092012-09-10 08:20:03 +02005815/* Note: must not be declared <const> as its list will be overwritten.
5816 * Please take care of keeping this list alphabetically sorted.
5817 */
Willy Tarreaudc13c112013-06-21 23:16:39 +02005818static struct sample_fetch_kw_list sample_fetch_keywords = {ILH, {
Emeric Brun645ae792014-04-30 14:21:06 +02005819 { "ssl_bc", smp_fetch_ssl_fc, 0, NULL, SMP_T_BOOL, SMP_USE_L5SRV },
Thierry FOURNIER07ee64e2015-07-06 23:43:03 +02005820 { "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 +02005821 { "ssl_bc_cipher", smp_fetch_ssl_fc_cipher, 0, NULL, SMP_T_STR, SMP_USE_L5SRV },
5822 { "ssl_bc_protocol", smp_fetch_ssl_fc_protocol, 0, NULL, SMP_T_STR, SMP_USE_L5SRV },
Emeric Brunb73a9b02014-04-30 18:49:19 +02005823 { "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 +02005824 { "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 +02005825 { "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 +02005826 { "ssl_c_ca_err", smp_fetch_ssl_c_ca_err, 0, NULL, SMP_T_SINT, SMP_USE_L5CLI },
5827 { "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 +01005828 { "ssl_c_der", smp_fetch_ssl_x_der, 0, NULL, SMP_T_BIN, SMP_USE_L5CLI },
Thierry FOURNIER07ee64e2015-07-06 23:43:03 +02005829 { "ssl_c_err", smp_fetch_ssl_c_err, 0, NULL, SMP_T_SINT, SMP_USE_L5CLI },
Emeric Brunba841a12014-04-30 17:05:08 +02005830 { "ssl_c_i_dn", smp_fetch_ssl_x_i_dn, ARG2(0,STR,SINT), NULL, SMP_T_STR, SMP_USE_L5CLI },
5831 { "ssl_c_key_alg", smp_fetch_ssl_x_key_alg, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
5832 { "ssl_c_notafter", smp_fetch_ssl_x_notafter, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
5833 { "ssl_c_notbefore", smp_fetch_ssl_x_notbefore, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
5834 { "ssl_c_sig_alg", smp_fetch_ssl_x_sig_alg, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
5835 { "ssl_c_s_dn", smp_fetch_ssl_x_s_dn, ARG2(0,STR,SINT), NULL, SMP_T_STR, SMP_USE_L5CLI },
5836 { "ssl_c_serial", smp_fetch_ssl_x_serial, 0, NULL, SMP_T_BIN, SMP_USE_L5CLI },
5837 { "ssl_c_sha1", smp_fetch_ssl_x_sha1, 0, NULL, SMP_T_BIN, SMP_USE_L5CLI },
Willy Tarreau80aca902013-01-07 15:42:20 +01005838 { "ssl_c_used", smp_fetch_ssl_c_used, 0, NULL, SMP_T_BOOL, SMP_USE_L5CLI },
Thierry FOURNIER07ee64e2015-07-06 23:43:03 +02005839 { "ssl_c_verify", smp_fetch_ssl_c_verify, 0, NULL, SMP_T_SINT, SMP_USE_L5CLI },
5840 { "ssl_c_version", smp_fetch_ssl_x_version, 0, NULL, SMP_T_SINT, SMP_USE_L5CLI },
Emeric Brun43e79582014-10-29 19:03:26 +01005841 { "ssl_f_der", smp_fetch_ssl_x_der, 0, NULL, SMP_T_BIN, SMP_USE_L5CLI },
Emeric Brunba841a12014-04-30 17:05:08 +02005842 { "ssl_f_i_dn", smp_fetch_ssl_x_i_dn, ARG2(0,STR,SINT), NULL, SMP_T_STR, SMP_USE_L5CLI },
5843 { "ssl_f_key_alg", smp_fetch_ssl_x_key_alg, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
5844 { "ssl_f_notafter", smp_fetch_ssl_x_notafter, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
5845 { "ssl_f_notbefore", smp_fetch_ssl_x_notbefore, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
5846 { "ssl_f_sig_alg", smp_fetch_ssl_x_sig_alg, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
5847 { "ssl_f_s_dn", smp_fetch_ssl_x_s_dn, ARG2(0,STR,SINT), NULL, SMP_T_STR, SMP_USE_L5CLI },
5848 { "ssl_f_serial", smp_fetch_ssl_x_serial, 0, NULL, SMP_T_BIN, SMP_USE_L5CLI },
Emeric Brun55f4fa82014-04-30 17:11:25 +02005849 { "ssl_f_sha1", smp_fetch_ssl_x_sha1, 0, NULL, SMP_T_BIN, SMP_USE_L5CLI },
Thierry FOURNIER07ee64e2015-07-06 23:43:03 +02005850 { "ssl_f_version", smp_fetch_ssl_x_version, 0, NULL, SMP_T_SINT, SMP_USE_L5CLI },
Willy Tarreau80aca902013-01-07 15:42:20 +01005851 { "ssl_fc", smp_fetch_ssl_fc, 0, NULL, SMP_T_BOOL, SMP_USE_L5CLI },
Thierry FOURNIER07ee64e2015-07-06 23:43:03 +02005852 { "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 +01005853 { "ssl_fc_cipher", smp_fetch_ssl_fc_cipher, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
Willy Tarreau80aca902013-01-07 15:42:20 +01005854 { "ssl_fc_has_crt", smp_fetch_ssl_fc_has_crt, 0, NULL, SMP_T_BOOL, SMP_USE_L5CLI },
5855 { "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 +02005856 { "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 +02005857#ifdef OPENSSL_NPN_NEGOTIATED
Thierry FOURNIER7654c9f2013-12-17 00:20:33 +01005858 { "ssl_fc_npn", smp_fetch_ssl_fc_npn, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
Willy Tarreaua33c6542012-10-15 13:19:06 +02005859#endif
Dirkjan Bussink48f1c4e2014-02-13 12:29:42 +01005860#ifdef TLSEXT_TYPE_application_layer_protocol_negotiation
Thierry FOURNIER7654c9f2013-12-17 00:20:33 +01005861 { "ssl_fc_alpn", smp_fetch_ssl_fc_alpn, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
Willy Tarreauab861d32013-04-02 02:30:41 +02005862#endif
Thierry FOURNIER7654c9f2013-12-17 00:20:33 +01005863 { "ssl_fc_protocol", smp_fetch_ssl_fc_protocol, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
Emeric Brunb73a9b02014-04-30 18:49:19 +02005864 { "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 +02005865 { "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 +01005866 { "ssl_fc_session_id", smp_fetch_ssl_fc_session_id, 0, NULL, SMP_T_BIN, SMP_USE_L5CLI },
5867 { "ssl_fc_sni", smp_fetch_ssl_fc_sni, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
Willy Tarreau7875d092012-09-10 08:20:03 +02005868 { NULL, NULL, 0, 0, 0 },
5869}};
5870
5871/* Note: must not be declared <const> as its list will be overwritten.
5872 * Please take care of keeping this list alphabetically sorted.
5873 */
Willy Tarreaudc13c112013-06-21 23:16:39 +02005874static struct acl_kw_list acl_kws = {ILH, {
Thierry FOURNIERc5a4e982014-03-05 16:07:08 +01005875 { "ssl_fc_sni_end", "ssl_fc_sni", PAT_MATCH_END },
5876 { "ssl_fc_sni_reg", "ssl_fc_sni", PAT_MATCH_REG },
Willy Tarreau8ed669b2013-01-11 15:49:37 +01005877 { /* END */ },
Willy Tarreau7875d092012-09-10 08:20:03 +02005878}};
5879
Willy Tarreau79eeafa2012-09-14 07:53:05 +02005880/* Note: must not be declared <const> as its list will be overwritten.
5881 * Please take care of keeping this list alphabetically sorted, doing so helps
5882 * all code contributors.
5883 * Optional keywords are also declared with a NULL ->parse() function so that
5884 * the config parser can report an appropriate error when a known keyword was
5885 * not enabled.
5886 */
Willy Tarreau51fb7652012-09-18 18:24:39 +02005887static struct bind_kw_list bind_kws = { "SSL", { }, {
Nenad Merdanovic05552d42015-02-27 19:56:49 +01005888 { "alpn", bind_parse_alpn, 1 }, /* set ALPN supported protocols */
5889 { "ca-file", bind_parse_ca_file, 1 }, /* set CAfile to process verify on client cert */
5890 { "ca-ignore-err", bind_parse_ignore_err, 1 }, /* set error IDs to ignore on verify depth > 0 */
Christopher Faulet31af49d2015-06-09 17:29:50 +02005891 { "ca-sign-file", bind_parse_ca_sign_file, 1 }, /* set CAFile used to generate and sign server certs */
5892 { "ca-sign-pass", bind_parse_ca_sign_pass, 1 }, /* set CAKey passphrase */
Nenad Merdanovic05552d42015-02-27 19:56:49 +01005893 { "ciphers", bind_parse_ciphers, 1 }, /* set SSL cipher suite */
5894 { "crl-file", bind_parse_crl_file, 1 }, /* set certificat revocation list file use on client cert verify */
5895 { "crt", bind_parse_crt, 1 }, /* load SSL certificates from this location */
5896 { "crt-ignore-err", bind_parse_ignore_err, 1 }, /* set error IDs to ingore on verify depth == 0 */
5897 { "crt-list", bind_parse_crt_list, 1 }, /* load a list of crt from this location */
5898 { "ecdhe", bind_parse_ecdhe, 1 }, /* defines named curve for elliptic curve Diffie-Hellman */
5899 { "force-sslv3", bind_parse_force_sslv3, 0 }, /* force SSLv3 */
5900 { "force-tlsv10", bind_parse_force_tlsv10, 0 }, /* force TLSv10 */
5901 { "force-tlsv11", bind_parse_force_tlsv11, 0 }, /* force TLSv11 */
5902 { "force-tlsv12", bind_parse_force_tlsv12, 0 }, /* force TLSv12 */
Christopher Faulet31af49d2015-06-09 17:29:50 +02005903 { "generate-certificates", bind_parse_generate_certs, 0 }, /* enable the server certificates generation */
Nenad Merdanovic05552d42015-02-27 19:56:49 +01005904 { "no-sslv3", bind_parse_no_sslv3, 0 }, /* disable SSLv3 */
5905 { "no-tlsv10", bind_parse_no_tlsv10, 0 }, /* disable TLSv10 */
5906 { "no-tlsv11", bind_parse_no_tlsv11, 0 }, /* disable TLSv11 */
5907 { "no-tlsv12", bind_parse_no_tlsv12, 0 }, /* disable TLSv12 */
5908 { "no-tls-tickets", bind_parse_no_tls_tickets, 0 }, /* disable session resumption tickets */
5909 { "ssl", bind_parse_ssl, 0 }, /* enable SSL processing */
5910 { "strict-sni", bind_parse_strict_sni, 0 }, /* refuse negotiation if sni doesn't match a certificate */
5911 { "tls-ticket-keys", bind_parse_tls_ticket_keys, 1 }, /* set file to load TLS ticket keys from */
5912 { "verify", bind_parse_verify, 1 }, /* set SSL verify method */
5913 { "npn", bind_parse_npn, 1 }, /* set NPN supported protocols */
Willy Tarreau79eeafa2012-09-14 07:53:05 +02005914 { NULL, NULL, 0 },
5915}};
Emeric Brun46591952012-05-18 15:47:34 +02005916
Willy Tarreau92faadf2012-10-10 23:04:25 +02005917/* Note: must not be declared <const> as its list will be overwritten.
5918 * Please take care of keeping this list alphabetically sorted, doing so helps
5919 * all code contributors.
5920 * Optional keywords are also declared with a NULL ->parse() function so that
5921 * the config parser can report an appropriate error when a known keyword was
5922 * not enabled.
5923 */
5924static struct srv_kw_list srv_kws = { "SSL", { }, {
Emeric Brunef42d922012-10-11 16:11:36 +02005925 { "ca-file", srv_parse_ca_file, 1, 0 }, /* set CAfile to process verify server cert */
Emeric Brunecc91fe2012-10-11 15:05:10 +02005926 { "check-ssl", srv_parse_check_ssl, 0, 0 }, /* enable SSL for health checks */
5927 { "ciphers", srv_parse_ciphers, 1, 0 }, /* select the cipher suite */
Emeric Brunef42d922012-10-11 16:11:36 +02005928 { "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 +02005929 { "crt", srv_parse_crt, 1, 0 }, /* set client certificate */
Emeric Brunecc91fe2012-10-11 15:05:10 +02005930 { "force-sslv3", srv_parse_force_sslv3, 0, 0 }, /* force SSLv3 */
5931 { "force-tlsv10", srv_parse_force_tlsv10, 0, 0 }, /* force TLSv10 */
5932 { "force-tlsv11", srv_parse_force_tlsv11, 0, 0 }, /* force TLSv11 */
5933 { "force-tlsv12", srv_parse_force_tlsv12, 0, 0 }, /* force TLSv12 */
Willy Tarreau2a3fb1c2015-02-05 16:47:07 +01005934 { "no-ssl-reuse", srv_parse_no_ssl_reuse, 0, 0 }, /* disable session reuse */
Emeric Brunecc91fe2012-10-11 15:05:10 +02005935 { "no-sslv3", srv_parse_no_sslv3, 0, 0 }, /* disable SSLv3 */
5936 { "no-tlsv10", srv_parse_no_tlsv10, 0, 0 }, /* disable TLSv10 */
5937 { "no-tlsv11", srv_parse_no_tlsv11, 0, 0 }, /* disable TLSv11 */
5938 { "no-tlsv12", srv_parse_no_tlsv12, 0, 0 }, /* disable TLSv12 */
Emeric Brunf9c5c472012-10-11 15:28:34 +02005939 { "no-tls-tickets", srv_parse_no_tls_tickets, 0, 0 }, /* disable session resumption tickets */
David Safb76832014-05-08 23:42:08 -04005940 { "send-proxy-v2-ssl", srv_parse_send_proxy_ssl, 0, 0 }, /* send PROXY protocol header v2 with SSL info */
5941 { "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 +02005942 { "sni", srv_parse_sni, 1, 0 }, /* send SNI extension */
Emeric Brunecc91fe2012-10-11 15:05:10 +02005943 { "ssl", srv_parse_ssl, 0, 0 }, /* enable SSL processing */
Emeric Brunef42d922012-10-11 16:11:36 +02005944 { "verify", srv_parse_verify, 1, 0 }, /* set SSL verify method */
Evan Broderbe554312013-06-27 00:05:25 -07005945 { "verifyhost", srv_parse_verifyhost, 1, 0 }, /* require that SSL cert verifies for hostname */
Willy Tarreau92faadf2012-10-10 23:04:25 +02005946 { NULL, NULL, 0, 0 },
5947}};
5948
Emeric Brun2c86cbf2014-10-30 15:56:50 +01005949static struct cfg_kw_list cfg_kws = {ILH, {
5950 { CFG_GLOBAL, "ssl-default-bind-options", ssl_parse_default_bind_options },
5951 { CFG_GLOBAL, "ssl-default-server-options", ssl_parse_default_server_options },
5952 { 0, NULL, NULL },
5953}};
5954
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02005955/* transport-layer operations for SSL sockets */
5956struct xprt_ops ssl_sock = {
Emeric Brun46591952012-05-18 15:47:34 +02005957 .snd_buf = ssl_sock_from_buf,
5958 .rcv_buf = ssl_sock_to_buf,
5959 .rcv_pipe = NULL,
5960 .snd_pipe = NULL,
5961 .shutr = NULL,
5962 .shutw = ssl_sock_shutw,
5963 .close = ssl_sock_close,
5964 .init = ssl_sock_init,
5965};
5966
Daniel Jakots54ffb912015-11-06 20:02:41 +01005967#if (OPENSSL_VERSION_NUMBER >= 0x1000200fL && !defined OPENSSL_NO_TLSEXT && !defined OPENSSL_IS_BORINGSSL && !defined LIBRESSL_VERSION_NUMBER)
Janusz Dziemidowicz2c701b52015-03-07 23:03:59 +01005968
5969static void ssl_sock_sctl_free_func(void *parent, void *ptr, CRYPTO_EX_DATA *ad, int idx, long argl, void *argp)
5970{
5971 if (ptr) {
5972 chunk_destroy(ptr);
5973 free(ptr);
5974 }
5975}
5976
5977#endif
5978
Emeric Brun46591952012-05-18 15:47:34 +02005979__attribute__((constructor))
Willy Tarreau92faadf2012-10-10 23:04:25 +02005980static void __ssl_sock_init(void)
5981{
Emeric Brun46591952012-05-18 15:47:34 +02005982 STACK_OF(SSL_COMP)* cm;
5983
Willy Tarreau610f04b2014-02-13 11:36:41 +01005984#ifdef LISTEN_DEFAULT_CIPHERS
5985 global.listen_default_ciphers = LISTEN_DEFAULT_CIPHERS;
5986#endif
5987#ifdef CONNECT_DEFAULT_CIPHERS
5988 global.connect_default_ciphers = CONNECT_DEFAULT_CIPHERS;
5989#endif
5990 if (global.listen_default_ciphers)
5991 global.listen_default_ciphers = strdup(global.listen_default_ciphers);
5992 if (global.connect_default_ciphers)
5993 global.connect_default_ciphers = strdup(global.connect_default_ciphers);
Emeric Brun2c86cbf2014-10-30 15:56:50 +01005994 global.listen_default_ssloptions = BC_SSL_O_NONE;
5995 global.connect_default_ssloptions = SRV_SSL_O_NONE;
Willy Tarreau610f04b2014-02-13 11:36:41 +01005996
Emeric Brun46591952012-05-18 15:47:34 +02005997 SSL_library_init();
5998 cm = SSL_COMP_get_compression_methods();
5999 sk_SSL_COMP_zero(cm);
Daniel Jakots54ffb912015-11-06 20:02:41 +01006000#if (OPENSSL_VERSION_NUMBER >= 0x1000200fL && !defined OPENSSL_NO_TLSEXT && !defined OPENSSL_IS_BORINGSSL && !defined LIBRESSL_VERSION_NUMBER)
Janusz Dziemidowicz2c701b52015-03-07 23:03:59 +01006001 sctl_ex_index = SSL_CTX_get_ex_new_index(0, NULL, NULL, NULL, ssl_sock_sctl_free_func);
6002#endif
Willy Tarreau7875d092012-09-10 08:20:03 +02006003 sample_register_fetches(&sample_fetch_keywords);
6004 acl_register_keywords(&acl_kws);
Willy Tarreau79eeafa2012-09-14 07:53:05 +02006005 bind_register_keywords(&bind_kws);
Willy Tarreau92faadf2012-10-10 23:04:25 +02006006 srv_register_keywords(&srv_kws);
Emeric Brun2c86cbf2014-10-30 15:56:50 +01006007 cfg_register_keywords(&cfg_kws);
Willy Tarreaud92aa5c2015-01-15 21:34:39 +01006008
6009 global.ssl_session_max_cost = SSL_SESSION_MAX_COST;
6010 global.ssl_handshake_max_cost = SSL_HANDSHAKE_MAX_COST;
Remi Gacogne4f902b82015-05-28 16:23:00 +02006011
6012#ifndef OPENSSL_NO_DH
6013 ssl_dh_ptr_index = SSL_CTX_get_ex_new_index(0, NULL, NULL, NULL, NULL);
6014#endif
Emeric Brun46591952012-05-18 15:47:34 +02006015}
6016
Remi Gacogned3a23c32015-05-28 16:39:47 +02006017__attribute__((destructor))
6018static void __ssl_sock_deinit(void)
6019{
Willy Tarreaua84c2672015-10-09 12:10:13 +02006020#ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME
Christopher Faulet31af49d2015-06-09 17:29:50 +02006021 lru64_destroy(ssl_ctx_lru_tree);
Willy Tarreaua84c2672015-10-09 12:10:13 +02006022#endif
Christopher Faulet31af49d2015-06-09 17:29:50 +02006023
Remi Gacogned3a23c32015-05-28 16:39:47 +02006024#ifndef OPENSSL_NO_DH
6025 if (local_dh_1024) {
6026 DH_free(local_dh_1024);
6027 local_dh_1024 = NULL;
6028 }
6029
6030 if (local_dh_2048) {
6031 DH_free(local_dh_2048);
6032 local_dh_2048 = NULL;
6033 }
6034
6035 if (local_dh_4096) {
6036 DH_free(local_dh_4096);
6037 local_dh_4096 = NULL;
6038 }
6039
Remi Gacogne47783ef2015-05-29 15:53:22 +02006040 if (global_dh) {
6041 DH_free(global_dh);
6042 global_dh = NULL;
6043 }
Remi Gacogned3a23c32015-05-28 16:39:47 +02006044#endif
6045
6046 ERR_remove_state(0);
6047 ERR_free_strings();
6048
6049 EVP_cleanup();
6050
6051#if OPENSSL_VERSION_NUMBER >= 0x00907000L
6052 CRYPTO_cleanup_all_ex_data();
6053#endif
6054}
6055
6056
Emeric Brun46591952012-05-18 15:47:34 +02006057/*
6058 * Local variables:
6059 * c-indent-level: 8
6060 * c-basic-offset: 8
6061 * End:
6062 */