blob: 994cdcc640b608c1f2d7595c952bc753b00962b0 [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
477 conn = (struct connection *)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
618 ocsp_arg = (struct ocsp_cbk_arg *)arg;
619
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
745 ocsp = calloc(1, sizeof(struct certificate_ocsp));
746 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) {
757 struct ocsp_cbk_arg *cb_arg = calloc(1, sizeof(struct ocsp_cbk_arg));
758
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 */
770 struct ocsp_cbk_arg *cb_arg = (struct ocsp_cbk_arg *) ctx->tlsext_status_arg;
771 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
900 *sctl = calloc(1, sizeof(struct chunk));
901 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{
916 struct chunk *sctl = (struct chunk *)add_arg;
917
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{
961 struct connection *conn = (struct connection *)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());
999 conn = (struct connection *)SSL_get_app_data(ssl);
1000
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)) {
Willy Tarreau84815002014-04-25 21:40:27 +02001045 struct connection *conn = (struct connection *)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) {
1348 struct connection *conn = (struct connection *)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
1799 /* Read Certificate */
1800 ckch->cert = PEM_read_bio_X509_AUX(in, NULL, NULL, NULL);
1801 if (ckch->cert == NULL) {
1802 memprintf(err, "%sunable to load certificate from file '%s'.\n",
1803 err && *err ? *err : "", path);
1804 goto end;
1805 }
1806
1807 /* Read Private Key */
1808 ckch->key = PEM_read_bio_PrivateKey(in, NULL, NULL, NULL);
1809 if (ckch->key == NULL) {
1810 memprintf(err, "%sunable to load private key from file '%s'.\n",
1811 err && *err ? *err : "", path);
1812 goto end;
1813 }
1814
1815 /* Read Certificate Chain */
1816 while ((ca = PEM_read_bio_X509(in, NULL, NULL, NULL))) {
1817 /* Grow the chain certs */
1818 ckch->num_chain_certs++;
1819 ckch->chain_certs = realloc(ckch->chain_certs, (ckch->num_chain_certs * sizeof(X509 *)));
1820
1821 /* use - 1 here since we just incremented it above */
1822 ckch->chain_certs[ckch->num_chain_certs - 1] = ca;
1823 }
1824 ret = ERR_get_error();
1825 if (ret && (ERR_GET_LIB(ret) != ERR_LIB_PEM && ERR_GET_REASON(ret) != PEM_R_NO_START_LINE)) {
1826 memprintf(err, "%sunable to load certificate chain from file '%s'.\n",
1827 err && *err ? *err : "", path);
1828 ret = 1;
1829 goto end;
1830 }
1831
1832 ret = 0;
1833
1834end:
1835
1836 ERR_clear_error();
1837 if (in)
1838 BIO_free(in);
1839
1840 /* Something went wrong in one of the reads */
1841 if (ret != 0)
1842 ssl_sock_free_cert_key_and_chain_contents(ckch);
1843
1844 return ret;
1845}
1846
1847/* Loads the info in ckch into ctx
1848 * Currently, this does not process any information about ocsp, dhparams or
1849 * sctl
1850 * Returns
1851 * 0 on success
1852 * 1 on failure
1853 */
1854static int ssl_sock_put_ckch_into_ctx(const char *path, const struct cert_key_and_chain *ckch, SSL_CTX *ctx, char **err)
1855{
1856 int i = 0;
1857
1858 if (SSL_CTX_use_PrivateKey(ctx, ckch->key) <= 0) {
1859 memprintf(err, "%sunable to load SSL private key into SSL Context '%s'.\n",
1860 err && *err ? *err : "", path);
1861 return 1;
1862 }
1863
1864 if (!SSL_CTX_use_certificate(ctx, ckch->cert)) {
1865 memprintf(err, "%sunable to load SSL certificate into SSL Context '%s'.\n",
1866 err && *err ? *err : "", path);
1867 return 1;
1868 }
1869
yanbzhu488a4d22015-12-01 15:16:07 -05001870 /* Load all certs in the ckch into the ctx_chain for the ssl_ctx */
1871 for (i = 0; i < ckch->num_chain_certs; i++) {
1872 if (!SSL_CTX_add1_chain_cert(ctx, ckch->chain_certs[i])) {
yanbzhu08ce6ab2015-12-02 13:01:29 -05001873 memprintf(err, "%sunable to load chain certificate #%d into SSL Context '%s'. Make sure you are linking against Openssl >= 1.0.2.\n",
1874 err && *err ? *err : "", (i+1), path);
yanbzhu488a4d22015-12-01 15:16:07 -05001875 return 1;
1876 }
1877 }
1878
1879 if (SSL_CTX_check_private_key(ctx) <= 0) {
1880 memprintf(err, "%sinconsistencies between private key and certificate loaded from PEM file '%s'.\n",
1881 err && *err ? *err : "", path);
1882 return 1;
1883 }
1884
1885 return 0;
1886}
1887
yanbzhu08ce6ab2015-12-02 13:01:29 -05001888
1889static void ssl_sock_populate_sni_keytypes_hplr(const char *str, struct eb_root *sni_keytypes, int key_index)
1890{
1891 struct sni_keytype *s_kt = NULL;
1892 struct ebmb_node *node;
1893 int i;
1894
1895 for (i = 0; i < trash.size; i++) {
1896 if (!str[i])
1897 break;
1898 trash.str[i] = tolower(str[i]);
1899 }
1900 trash.str[i] = 0;
1901 node = ebst_lookup(sni_keytypes, trash.str);
1902 if (!node) {
1903 /* CN not found in tree */
1904 s_kt = malloc(sizeof(struct sni_keytype) + i + 1);
1905 /* Using memcpy here instead of strncpy.
1906 * strncpy will cause sig_abrt errors under certain versions of gcc with -O2
1907 * See: https://gcc.gnu.org/bugzilla/show_bug.cgi?id=60792
1908 */
1909 memcpy(s_kt->name.key, trash.str, i+1);
1910 s_kt->keytypes = 0;
1911 ebst_insert(sni_keytypes, &s_kt->name);
1912 } else {
1913 /* CN found in tree */
1914 s_kt = container_of(node, struct sni_keytype, name);
1915 }
1916
1917 /* Mark that this CN has the keytype of key_index via keytypes mask */
1918 s_kt->keytypes |= 1<<key_index;
1919
1920}
1921
1922
1923/* Given a path that does not exist, try to check for path.rsa, path.dsa and path.ecdsa files.
1924 * If any are found, group these files into a set of SSL_CTX*
1925 * based on shared and unique CN and SAN entries. Add these SSL_CTX* to the SNI tree.
1926 *
1927 * This will allow the user to explictly group multiple cert/keys for a single purpose
1928 *
1929 * Returns
1930 * 0 on success
1931 * 1 on failure
1932 */
1933static int ssl_sock_load_multi_cert(const char *path, struct bind_conf *bind_conf, struct proxy *curproxy, char **sni_filter, char **err)
1934{
1935 char fp[MAXPATHLEN+1] = {0};
1936 int n = 0;
1937 int i = 0;
1938 struct cert_key_and_chain certs_and_keys[SSL_SOCK_NUM_KEYTYPES] = { {0} };
1939 struct eb_root sni_keytypes_map = { {0} };
1940 struct ebmb_node *node;
1941 struct ebmb_node *next;
1942 /* Array of SSL_CTX pointers corresponding to each possible combo
1943 * of keytypes
1944 */
1945 struct key_combo_ctx key_combos[SSL_SOCK_POSSIBLE_KT_COMBOS] = { {0} };
1946 int rv = 0;
1947 X509_NAME *xname = NULL;
1948 char *str = NULL;
1949#ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME
1950 STACK_OF(GENERAL_NAME) *names = NULL;
1951#endif
1952
1953 /* Load all possible certs and keys */
1954 for (n = 0; n < SSL_SOCK_NUM_KEYTYPES; n++) {
1955 struct stat buf;
1956
1957 snprintf(fp, sizeof(fp), "%s.%s", path, SSL_SOCK_KEYTYPE_NAMES[n]);
1958 if (stat(fp, &buf) == 0) {
1959 if (ssl_sock_load_crt_file_into_ckch(fp, &certs_and_keys[n], err) == 1) {
1960 rv = 1;
1961 goto end;
1962 }
1963 }
1964 }
1965
1966 /* Process each ckch and update keytypes for each CN/SAN
1967 * for example, if CN/SAN www.a.com is associated with
1968 * certs with keytype 0 and 2, then at the end of the loop,
1969 * www.a.com will have:
1970 * keyindex = 0 | 1 | 4 = 5
1971 */
1972 for (n = 0; n < SSL_SOCK_NUM_KEYTYPES; n++) {
1973
1974 if (!ssl_sock_is_ckch_valid(&certs_and_keys[n]))
1975 continue;
1976
1977 /* A lot of the following code is OpenSSL boilerplate for processing CN's and SAN's,
1978 * so the line that contains logic is marked via comments
1979 */
1980 xname = X509_get_subject_name(certs_and_keys[n].cert);
1981 i = -1;
1982 while ((i = X509_NAME_get_index_by_NID(xname, NID_commonName, i)) != -1) {
1983 X509_NAME_ENTRY *entry = X509_NAME_get_entry(xname, i);
1984
1985 if (ASN1_STRING_to_UTF8((unsigned char **)&str, entry->value) >= 0) {
1986 /* Important line is here */
1987 ssl_sock_populate_sni_keytypes_hplr(str, &sni_keytypes_map, n);
1988
1989 OPENSSL_free(str);
1990 str = NULL;
1991 }
1992 }
1993
1994 /* Do the above logic for each SAN */
1995#ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME
1996 names = X509_get_ext_d2i(certs_and_keys[n].cert, NID_subject_alt_name, NULL, NULL);
1997 if (names) {
1998 for (i = 0; i < sk_GENERAL_NAME_num(names); i++) {
1999 GENERAL_NAME *name = sk_GENERAL_NAME_value(names, i);
2000
2001 if (name->type == GEN_DNS) {
2002 if (ASN1_STRING_to_UTF8((unsigned char **)&str, name->d.dNSName) >= 0) {
2003 /* Important line is here */
2004 ssl_sock_populate_sni_keytypes_hplr(str, &sni_keytypes_map, n);
2005
2006 OPENSSL_free(str);
2007 str = NULL;
2008 }
2009 }
2010 }
2011 }
2012#endif /* SSL_CTRL_SET_TLSEXT_HOSTNAME */
2013 }
2014
2015 /* If no files found, return error */
2016 if (eb_is_empty(&sni_keytypes_map)) {
2017 memprintf(err, "%sunable to load SSL certificate file '%s' file does not exist.\n",
2018 err && *err ? *err : "", path);
2019 rv = 1;
2020 goto end;
2021 }
2022
2023 /* We now have a map of CN/SAN to keytypes that are loaded in
2024 * Iterate through the map to create the SSL_CTX's (if needed)
2025 * and add each CTX to the SNI tree
2026 *
2027 * Some math here:
2028 * There are 2^n - 1 possibile combinations, each unique
2029 * combination is denoted by the key in the map. Each key
2030 * has a value between 1 and 2^n - 1. Conveniently, the array
2031 * of SSL_CTX* is sized 2^n. So, we can simply use the i'th
2032 * entry in the array to correspond to the unique combo (key)
2033 * associated with i. This unique key combo (i) will be associated
2034 * with combos[i-1]
2035 */
2036
2037 node = ebmb_first(&sni_keytypes_map);
2038 while (node) {
2039 SSL_CTX *cur_ctx;
2040
2041 str = (char *)container_of(node, struct sni_keytype, name)->name.key;
2042 i = container_of(node, struct sni_keytype, name)->keytypes;
2043 cur_ctx = key_combos[i-1].ctx;
2044
2045 if (cur_ctx == NULL) {
2046 /* need to create SSL_CTX */
2047 cur_ctx = SSL_CTX_new(SSLv23_server_method());
2048 if (cur_ctx == NULL) {
2049 memprintf(err, "%sunable to allocate SSL context.\n",
2050 err && *err ? *err : "");
2051 rv = 1;
2052 goto end;
2053 }
2054
yanbzhube2774d2015-12-10 15:07:30 -05002055 /* Load all required certs/keys/chains/OCSPs info into SSL_CTX */
yanbzhu08ce6ab2015-12-02 13:01:29 -05002056 for (n = 0; n < SSL_SOCK_NUM_KEYTYPES; n++) {
2057 if (i & (1<<n)) {
2058 /* Key combo contains ckch[n] */
2059 snprintf(trash.str, trash.size, "%s.%s", path, SSL_SOCK_KEYTYPE_NAMES[n]);
2060 if (ssl_sock_put_ckch_into_ctx(trash.str, &certs_and_keys[n], cur_ctx, err) != 0) {
2061 SSL_CTX_free(cur_ctx);
2062 rv = 1;
2063 goto end;
2064 }
yanbzhube2774d2015-12-10 15:07:30 -05002065
2066#if (defined SSL_CTRL_SET_TLSEXT_STATUS_REQ_CB && !defined OPENSSL_NO_OCSP)
2067 /* Load OCSP Info into context */
2068 if (ssl_sock_load_ocsp(cur_ctx, trash.str) < 0) {
2069 if (err)
2070 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",
2071 *err ? *err : "", path);
2072 SSL_CTX_free(cur_ctx);
2073 rv = 1;
2074 goto end;
2075 }
2076#endif
yanbzhu08ce6ab2015-12-02 13:01:29 -05002077 }
2078 }
2079
2080 /* Load DH params into the ctx to support DHE keys */
2081#ifndef OPENSSL_NO_DH
2082 if (ssl_dh_ptr_index >= 0)
2083 SSL_CTX_set_ex_data(cur_ctx, ssl_dh_ptr_index, NULL);
2084
2085 rv = ssl_sock_load_dh_params(cur_ctx, NULL);
2086 if (rv < 0) {
2087 if (err)
2088 memprintf(err, "%sunable to load DH parameters from file '%s'.\n",
2089 *err ? *err : "", path);
2090 rv = 1;
2091 goto end;
2092 }
2093#endif
2094
2095 /* Update key_combos */
2096 key_combos[i-1].ctx = cur_ctx;
2097 }
2098
2099 /* Update SNI Tree */
2100 ssl_sock_add_cert_sni(cur_ctx, bind_conf, str, key_combos[i-1].order++);
2101 node = ebmb_next(node);
2102 }
2103
2104
2105 /* Mark a default context if none exists, using the ctx that has the most shared keys */
2106 if (!bind_conf->default_ctx) {
2107 for (i = SSL_SOCK_POSSIBLE_KT_COMBOS - 1; i >= 0; i--) {
2108 if (key_combos[i].ctx) {
2109 bind_conf->default_ctx = key_combos[i].ctx;
2110 break;
2111 }
2112 }
2113 }
2114
2115end:
2116
2117 if (names)
2118 sk_GENERAL_NAME_pop_free(names, GENERAL_NAME_free);
2119
2120 for (n = 0; n < SSL_SOCK_NUM_KEYTYPES; n++)
2121 ssl_sock_free_cert_key_and_chain_contents(&certs_and_keys[n]);
2122
2123 node = ebmb_first(&sni_keytypes_map);
2124 while (node) {
2125 next = ebmb_next(node);
2126 ebmb_delete(node);
2127 node = next;
2128 }
2129
2130 return rv;
2131}
2132#else
2133/* This is a dummy, that just logs an error and returns error */
2134static int ssl_sock_load_multi_cert(const char *path, struct bind_conf *bind_conf, struct proxy *curproxy, char **sni_filter, char **err)
2135{
2136 memprintf(err, "%sunable to stat SSL certificate from file '%s' : %s.\n",
2137 err && *err ? *err : "", path, strerror(errno));
2138 return 1;
2139}
2140
yanbzhu488a4d22015-12-01 15:16:07 -05002141#endif /* #if OPENSSL_VERSION_NUMBER >= 0x1000200fL: Support for loading multiple certs into a single SSL_CTX */
2142
Emeric Brunfc0421f2012-09-07 17:30:07 +02002143/* Loads a certificate key and CA chain from a file. Returns 0 on error, -1 if
2144 * an early error happens and the caller must call SSL_CTX_free() by itelf.
2145 */
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +02002146static 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 +02002147{
2148 BIO *in;
2149 X509 *x = NULL, *ca;
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +02002150 int i, err;
Emeric Brunfc0421f2012-09-07 17:30:07 +02002151 int ret = -1;
2152 int order = 0;
2153 X509_NAME *xname;
2154 char *str;
Emeric Brunfc0421f2012-09-07 17:30:07 +02002155#ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME
2156 STACK_OF(GENERAL_NAME) *names;
2157#endif
2158
2159 in = BIO_new(BIO_s_file());
2160 if (in == NULL)
2161 goto end;
2162
2163 if (BIO_read_filename(in, file) <= 0)
2164 goto end;
2165
2166 x = PEM_read_bio_X509_AUX(in, NULL, ctx->default_passwd_callback, ctx->default_passwd_callback_userdata);
2167 if (x == NULL)
2168 goto end;
2169
Emeric Brun50bcecc2013-04-22 13:05:23 +02002170 if (fcount) {
2171 while (fcount--)
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +02002172 order = ssl_sock_add_cert_sni(ctx, s, sni_filter[fcount], order);
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01002173 }
2174 else {
Emeric Brunfc0421f2012-09-07 17:30:07 +02002175#ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01002176 names = X509_get_ext_d2i(x, NID_subject_alt_name, NULL, NULL);
2177 if (names) {
2178 for (i = 0; i < sk_GENERAL_NAME_num(names); i++) {
2179 GENERAL_NAME *name = sk_GENERAL_NAME_value(names, i);
2180 if (name->type == GEN_DNS) {
2181 if (ASN1_STRING_to_UTF8((unsigned char **)&str, name->d.dNSName) >= 0) {
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +02002182 order = ssl_sock_add_cert_sni(ctx, s, str, order);
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01002183 OPENSSL_free(str);
Emeric Brunfc0421f2012-09-07 17:30:07 +02002184 }
Emeric Brunfc0421f2012-09-07 17:30:07 +02002185 }
2186 }
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01002187 sk_GENERAL_NAME_pop_free(names, GENERAL_NAME_free);
Emeric Brunfc0421f2012-09-07 17:30:07 +02002188 }
Emeric Brunfc0421f2012-09-07 17:30:07 +02002189#endif /* SSL_CTRL_SET_TLSEXT_HOSTNAME */
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01002190 xname = X509_get_subject_name(x);
2191 i = -1;
2192 while ((i = X509_NAME_get_index_by_NID(xname, NID_commonName, i)) != -1) {
2193 X509_NAME_ENTRY *entry = X509_NAME_get_entry(xname, i);
2194 if (ASN1_STRING_to_UTF8((unsigned char **)&str, entry->value) >= 0) {
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +02002195 order = ssl_sock_add_cert_sni(ctx, s, str, order);
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01002196 OPENSSL_free(str);
Emeric Brunfc0421f2012-09-07 17:30:07 +02002197 }
Emeric Brunfc0421f2012-09-07 17:30:07 +02002198 }
2199 }
2200
2201 ret = 0; /* the caller must not free the SSL_CTX argument anymore */
2202 if (!SSL_CTX_use_certificate(ctx, x))
2203 goto end;
2204
2205 if (ctx->extra_certs != NULL) {
2206 sk_X509_pop_free(ctx->extra_certs, X509_free);
2207 ctx->extra_certs = NULL;
2208 }
2209
2210 while ((ca = PEM_read_bio_X509(in, NULL, ctx->default_passwd_callback, ctx->default_passwd_callback_userdata))) {
2211 if (!SSL_CTX_add_extra_chain_cert(ctx, ca)) {
2212 X509_free(ca);
2213 goto end;
2214 }
2215 }
2216
2217 err = ERR_get_error();
2218 if (!err || (ERR_GET_LIB(err) == ERR_LIB_PEM && ERR_GET_REASON(err) == PEM_R_NO_START_LINE)) {
2219 /* we successfully reached the last cert in the file */
2220 ret = 1;
2221 }
2222 ERR_clear_error();
2223
2224end:
2225 if (x)
2226 X509_free(x);
2227
2228 if (in)
2229 BIO_free(in);
2230
2231 return ret;
2232}
2233
Emeric Brun50bcecc2013-04-22 13:05:23 +02002234static 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 +02002235{
2236 int ret;
2237 SSL_CTX *ctx;
2238
2239 ctx = SSL_CTX_new(SSLv23_server_method());
2240 if (!ctx) {
Willy Tarreaueb6cead2012-09-20 19:43:14 +02002241 memprintf(err, "%sunable to allocate SSL context for cert '%s'.\n",
2242 err && *err ? *err : "", path);
Emeric Brunfc0421f2012-09-07 17:30:07 +02002243 return 1;
2244 }
2245
2246 if (SSL_CTX_use_PrivateKey_file(ctx, path, SSL_FILETYPE_PEM) <= 0) {
Willy Tarreaueb6cead2012-09-20 19:43:14 +02002247 memprintf(err, "%sunable to load SSL private key from PEM file '%s'.\n",
2248 err && *err ? *err : "", path);
Emeric Brunfc0421f2012-09-07 17:30:07 +02002249 SSL_CTX_free(ctx);
2250 return 1;
2251 }
2252
Emeric Brun50bcecc2013-04-22 13:05:23 +02002253 ret = ssl_sock_load_cert_chain_file(ctx, path, bind_conf, sni_filter, fcount);
Emeric Brunfc0421f2012-09-07 17:30:07 +02002254 if (ret <= 0) {
Willy Tarreaueb6cead2012-09-20 19:43:14 +02002255 memprintf(err, "%sunable to load SSL certificate from PEM file '%s'.\n",
2256 err && *err ? *err : "", path);
Emeric Brunfc0421f2012-09-07 17:30:07 +02002257 if (ret < 0) /* serious error, must do that ourselves */
2258 SSL_CTX_free(ctx);
2259 return 1;
2260 }
Emeric Brun61694ab2012-10-26 13:35:33 +02002261
2262 if (SSL_CTX_check_private_key(ctx) <= 0) {
2263 memprintf(err, "%sinconsistencies between private key and certificate loaded from PEM file '%s'.\n",
2264 err && *err ? *err : "", path);
2265 return 1;
2266 }
2267
Emeric Brunfc0421f2012-09-07 17:30:07 +02002268 /* we must not free the SSL_CTX anymore below, since it's already in
2269 * the tree, so it will be discovered and cleaned in time.
2270 */
Emeric Bruna4bcd9a2012-09-20 16:19:02 +02002271#ifndef OPENSSL_NO_DH
Remi Gacogne4f902b82015-05-28 16:23:00 +02002272 /* store a NULL pointer to indicate we have not yet loaded
2273 a custom DH param file */
2274 if (ssl_dh_ptr_index >= 0) {
2275 SSL_CTX_set_ex_data(ctx, ssl_dh_ptr_index, NULL);
2276 }
2277
Emeric Bruna4bcd9a2012-09-20 16:19:02 +02002278 ret = ssl_sock_load_dh_params(ctx, path);
2279 if (ret < 0) {
2280 if (err)
2281 memprintf(err, "%sunable to load DH parameters from file '%s'.\n",
2282 *err ? *err : "", path);
2283 return 1;
2284 }
2285#endif
2286
Lukas Tribuse4e30f72014-12-09 16:32:51 +01002287#if (defined SSL_CTRL_SET_TLSEXT_STATUS_REQ_CB && !defined OPENSSL_NO_OCSP)
Emeric Brun4147b2e2014-06-16 18:36:30 +02002288 ret = ssl_sock_load_ocsp(ctx, path);
2289 if (ret < 0) {
2290 if (err)
2291 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",
2292 *err ? *err : "", path);
2293 return 1;
2294 }
2295#endif
2296
Daniel Jakots54ffb912015-11-06 20:02:41 +01002297#if (OPENSSL_VERSION_NUMBER >= 0x1000200fL && !defined OPENSSL_NO_TLSEXT && !defined OPENSSL_IS_BORINGSSL && !defined LIBRESSL_VERSION_NUMBER)
Janusz Dziemidowicz2c701b52015-03-07 23:03:59 +01002298 if (sctl_ex_index >= 0) {
2299 ret = ssl_sock_load_sctl(ctx, path);
2300 if (ret < 0) {
2301 if (err)
2302 memprintf(err, "%s '%s.sctl' is present but cannot be read or parsed'.\n",
2303 *err ? *err : "", path);
2304 return 1;
2305 }
2306 }
2307#endif
2308
Emeric Brunfc0421f2012-09-07 17:30:07 +02002309#ifndef SSL_CTRL_SET_TLSEXT_HOSTNAME
Willy Tarreau2a65ff02012-09-13 17:54:29 +02002310 if (bind_conf->default_ctx) {
Willy Tarreaueb6cead2012-09-20 19:43:14 +02002311 memprintf(err, "%sthis version of openssl cannot load multiple SSL certificates.\n",
2312 err && *err ? *err : "");
Emeric Brunfc0421f2012-09-07 17:30:07 +02002313 return 1;
2314 }
2315#endif
Willy Tarreau2a65ff02012-09-13 17:54:29 +02002316 if (!bind_conf->default_ctx)
2317 bind_conf->default_ctx = ctx;
Emeric Brunfc0421f2012-09-07 17:30:07 +02002318
2319 return 0;
2320}
2321
Willy Tarreau79eeafa2012-09-14 07:53:05 +02002322int ssl_sock_load_cert(char *path, struct bind_conf *bind_conf, struct proxy *curproxy, char **err)
Emeric Brunfc0421f2012-09-07 17:30:07 +02002323{
Cyril Bonté3180f7b2015-01-25 00:16:08 +01002324 struct dirent **de_list;
2325 int i, n;
Emeric Brunfc0421f2012-09-07 17:30:07 +02002326 DIR *dir;
2327 struct stat buf;
Willy Tarreauee2663b2012-12-06 11:36:59 +01002328 char *end;
2329 char fp[MAXPATHLEN+1];
Emeric Brunfc0421f2012-09-07 17:30:07 +02002330 int cfgerr = 0;
yanbzhu63ea8462015-12-09 13:35:14 -05002331#if OPENSSL_VERSION_NUMBER >= 0x1000200fL
2332 int is_bundle;
2333 int j;
2334#endif
Emeric Brunfc0421f2012-09-07 17:30:07 +02002335
yanbzhu08ce6ab2015-12-02 13:01:29 -05002336 if (stat(path, &buf) == 0) {
2337 dir = opendir(path);
2338 if (!dir)
2339 return ssl_sock_load_cert_file(path, bind_conf, curproxy, NULL, 0, err);
Emeric Brunfc0421f2012-09-07 17:30:07 +02002340
yanbzhu08ce6ab2015-12-02 13:01:29 -05002341 /* strip trailing slashes, including first one */
2342 for (end = path + strlen(path) - 1; end >= path && *end == '/'; end--)
2343 *end = 0;
Emeric Brunfc0421f2012-09-07 17:30:07 +02002344
yanbzhu08ce6ab2015-12-02 13:01:29 -05002345 n = scandir(path, &de_list, 0, alphasort);
2346 if (n < 0) {
2347 memprintf(err, "%sunable to scan directory '%s' : %s.\n",
2348 err && *err ? *err : "", path, strerror(errno));
2349 cfgerr++;
2350 }
2351 else {
2352 for (i = 0; i < n; i++) {
2353 struct dirent *de = de_list[i];
Emeric Brun2aab7222014-06-18 18:15:09 +02002354
yanbzhu08ce6ab2015-12-02 13:01:29 -05002355 end = strrchr(de->d_name, '.');
2356 if (end && (!strcmp(end, ".issuer") || !strcmp(end, ".ocsp") || !strcmp(end, ".sctl")))
2357 goto ignore_entry;
Cyril Bonté3180f7b2015-01-25 00:16:08 +01002358
yanbzhu08ce6ab2015-12-02 13:01:29 -05002359 snprintf(fp, sizeof(fp), "%s/%s", path, de->d_name);
2360 if (stat(fp, &buf) != 0) {
2361 memprintf(err, "%sunable to stat SSL certificate from file '%s' : %s.\n",
2362 err && *err ? *err : "", fp, strerror(errno));
2363 cfgerr++;
2364 goto ignore_entry;
2365 }
2366 if (!S_ISREG(buf.st_mode))
2367 goto ignore_entry;
yanbzhu63ea8462015-12-09 13:35:14 -05002368
2369#if OPENSSL_VERSION_NUMBER >= 0x1000200fL
2370 is_bundle = 0;
2371 /* Check if current entry in directory is part of a multi-cert bundle */
2372
2373 if (end) {
2374 for (j = 0; j < SSL_SOCK_NUM_KEYTYPES; j++) {
2375 if (!strcmp(end + 1, SSL_SOCK_KEYTYPE_NAMES[j])) {
2376 is_bundle = 1;
2377 break;
2378 }
2379 }
2380
2381 if (is_bundle) {
2382 char dp[MAXPATHLEN+1] = {0}; /* this will be the filename w/o the keytype */
2383 int dp_len;
2384
2385 dp_len = end - de->d_name;
2386 snprintf(dp, dp_len + 1, "%s", de->d_name);
2387
2388 /* increment i and free de until we get to a non-bundle cert
2389 * Note here that we look at de_list[i + 1] before freeing de
2390 * this is important since ignore_entry will free de
2391 */
2392 while (i + 1 < n && !strncmp(de_list[i + 1]->d_name, dp, dp_len)) {
2393 free(de);
2394 i++;
2395 de = de_list[i];
2396 }
2397
2398 snprintf(fp, sizeof(fp), "%s/%s", path, dp);
2399 ssl_sock_load_multi_cert(fp, bind_conf, curproxy, NULL, err);
2400
2401 /* Successfully processed the bundle */
2402 goto ignore_entry;
2403 }
2404 }
2405
2406#endif
yanbzhu08ce6ab2015-12-02 13:01:29 -05002407 cfgerr += ssl_sock_load_cert_file(fp, bind_conf, curproxy, NULL, 0, err);
2408ignore_entry:
2409 free(de);
Cyril Bonté3180f7b2015-01-25 00:16:08 +01002410 }
yanbzhu08ce6ab2015-12-02 13:01:29 -05002411 free(de_list);
Emeric Brunfc0421f2012-09-07 17:30:07 +02002412 }
yanbzhu08ce6ab2015-12-02 13:01:29 -05002413 closedir(dir);
2414 return cfgerr;
Emeric Brunfc0421f2012-09-07 17:30:07 +02002415 }
yanbzhu08ce6ab2015-12-02 13:01:29 -05002416
2417 cfgerr = ssl_sock_load_multi_cert(path, bind_conf, curproxy, NULL, err);
2418
Emeric Brunfc0421f2012-09-07 17:30:07 +02002419 return cfgerr;
2420}
2421
Thierry Fournier383085f2013-01-24 14:15:43 +01002422/* Make sure openssl opens /dev/urandom before the chroot. The work is only
2423 * done once. Zero is returned if the operation fails. No error is returned
2424 * if the random is said as not implemented, because we expect that openssl
2425 * will use another method once needed.
2426 */
2427static int ssl_initialize_random()
2428{
2429 unsigned char random;
2430 static int random_initialized = 0;
2431
2432 if (!random_initialized && RAND_bytes(&random, 1) != 0)
2433 random_initialized = 1;
2434
2435 return random_initialized;
2436}
2437
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01002438int ssl_sock_load_cert_list_file(char *file, struct bind_conf *bind_conf, struct proxy *curproxy, char **err)
2439{
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +02002440 char thisline[LINESIZE];
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01002441 FILE *f;
yanbzhu1b04e5b2015-12-02 13:54:14 -05002442 struct stat buf;
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01002443 int linenum = 0;
2444 int cfgerr = 0;
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01002445
Willy Tarreauad1731d2013-04-02 17:35:58 +02002446 if ((f = fopen(file, "r")) == NULL) {
2447 memprintf(err, "cannot open file '%s' : %s", file, strerror(errno));
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01002448 return 1;
Willy Tarreauad1731d2013-04-02 17:35:58 +02002449 }
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01002450
2451 while (fgets(thisline, sizeof(thisline), f) != NULL) {
2452 int arg;
Emeric Brun50bcecc2013-04-22 13:05:23 +02002453 int newarg;
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01002454 char *end;
2455 char *args[MAX_LINE_ARGS + 1];
2456 char *line = thisline;
2457
2458 linenum++;
2459 end = line + strlen(line);
2460 if (end-line == sizeof(thisline)-1 && *(end-1) != '\n') {
2461 /* Check if we reached the limit and the last char is not \n.
2462 * Watch out for the last line without the terminating '\n'!
2463 */
Willy Tarreauad1731d2013-04-02 17:35:58 +02002464 memprintf(err, "line %d too long in file '%s', limit is %d characters",
2465 linenum, file, (int)sizeof(thisline)-1);
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01002466 cfgerr = 1;
Willy Tarreauad1731d2013-04-02 17:35:58 +02002467 break;
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01002468 }
2469
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01002470 arg = 0;
Emeric Brun50bcecc2013-04-22 13:05:23 +02002471 newarg = 1;
2472 while (*line) {
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01002473 if (*line == '#' || *line == '\n' || *line == '\r') {
2474 /* end of string, end of loop */
2475 *line = 0;
2476 break;
2477 }
2478 else if (isspace(*line)) {
Emeric Brun50bcecc2013-04-22 13:05:23 +02002479 newarg = 1;
2480 *line = 0;
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01002481 }
Emeric Brun50bcecc2013-04-22 13:05:23 +02002482 else if (newarg) {
2483 if (arg == MAX_LINE_ARGS) {
2484 memprintf(err, "too many args on line %d in file '%s'.",
2485 linenum, file);
2486 cfgerr = 1;
2487 break;
2488 }
2489 newarg = 0;
2490 args[arg++] = line;
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01002491 }
Emeric Brun50bcecc2013-04-22 13:05:23 +02002492 line++;
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01002493 }
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +02002494 if (cfgerr)
2495 break;
Willy Tarreauad1731d2013-04-02 17:35:58 +02002496
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01002497 /* empty line */
Emeric Brun50bcecc2013-04-22 13:05:23 +02002498 if (!arg)
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01002499 continue;
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01002500
yanbzhu1b04e5b2015-12-02 13:54:14 -05002501 if (stat(args[0], &buf) == 0) {
2502 cfgerr = ssl_sock_load_cert_file(args[0], bind_conf, curproxy, &args[1], arg-1, err);
2503 } else {
2504 cfgerr = ssl_sock_load_multi_cert(args[0], bind_conf, curproxy, NULL, err);
2505 }
2506
Willy Tarreauad1731d2013-04-02 17:35:58 +02002507 if (cfgerr) {
2508 memprintf(err, "error processing line %d in file '%s' : %s", linenum, file, *err);
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01002509 break;
Willy Tarreauad1731d2013-04-02 17:35:58 +02002510 }
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01002511 }
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01002512 fclose(f);
2513 return cfgerr;
2514}
2515
Emeric Brunfc0421f2012-09-07 17:30:07 +02002516#ifndef SSL_OP_CIPHER_SERVER_PREFERENCE /* needs OpenSSL >= 0.9.7 */
2517#define SSL_OP_CIPHER_SERVER_PREFERENCE 0
2518#endif
2519
2520#ifndef SSL_OP_NO_SESSION_RESUMPTION_ON_RENEGOTIATION /* needs OpenSSL >= 0.9.7 */
2521#define SSL_OP_NO_SESSION_RESUMPTION_ON_RENEGOTIATION 0
Willy Tarreau7d588ee2012-11-26 18:47:31 +01002522#define SSL_renegotiate_pending(arg) 0
Emeric Brunfc0421f2012-09-07 17:30:07 +02002523#endif
Emeric Brun2b58d042012-09-20 17:10:03 +02002524#ifndef SSL_OP_SINGLE_ECDH_USE /* needs OpenSSL >= 0.9.8 */
2525#define SSL_OP_SINGLE_ECDH_USE 0
2526#endif
Emeric Brun2d0c4822012-10-02 13:45:20 +02002527#ifndef SSL_OP_NO_TICKET /* needs OpenSSL >= 0.9.8 */
2528#define SSL_OP_NO_TICKET 0
2529#endif
Emeric Brunfc0421f2012-09-07 17:30:07 +02002530#ifndef SSL_OP_NO_COMPRESSION /* needs OpenSSL >= 0.9.9 */
2531#define SSL_OP_NO_COMPRESSION 0
2532#endif
Emeric Brunc0ff4922012-09-28 19:37:02 +02002533#ifndef SSL_OP_NO_TLSv1_1 /* needs OpenSSL >= 1.0.1 */
2534#define SSL_OP_NO_TLSv1_1 0
2535#endif
2536#ifndef SSL_OP_NO_TLSv1_2 /* needs OpenSSL >= 1.0.1 */
2537#define SSL_OP_NO_TLSv1_2 0
2538#endif
Emeric Bruna4bcd9a2012-09-20 16:19:02 +02002539#ifndef SSL_OP_SINGLE_DH_USE /* needs OpenSSL >= 0.9.6 */
2540#define SSL_OP_SINGLE_DH_USE 0
2541#endif
Emeric Brun2b58d042012-09-20 17:10:03 +02002542#ifndef SSL_OP_SINGLE_ECDH_USE /* needs OpenSSL >= 1.0.0 */
2543#define SSL_OP_SINGLE_ECDH_USE 0
2544#endif
Emeric Brunfc0421f2012-09-07 17:30:07 +02002545#ifndef SSL_MODE_RELEASE_BUFFERS /* needs OpenSSL >= 1.0.0 */
2546#define SSL_MODE_RELEASE_BUFFERS 0
2547#endif
Willy Tarreau396a1862014-11-13 14:06:52 +01002548#ifndef SSL_MODE_SMALL_BUFFERS /* needs small_records.patch */
2549#define SSL_MODE_SMALL_BUFFERS 0
2550#endif
Remi Gacognef46cd6e2014-06-12 14:58:40 +02002551
Willy Tarreau2a65ff02012-09-13 17:54:29 +02002552int ssl_sock_prepare_ctx(struct bind_conf *bind_conf, SSL_CTX *ctx, struct proxy *curproxy)
Emeric Brunfc0421f2012-09-07 17:30:07 +02002553{
2554 int cfgerr = 0;
Emeric Brun850efd52014-01-29 12:24:34 +01002555 int verify = SSL_VERIFY_NONE;
Remi Gacogneaf5c3da2014-05-19 10:29:58 +02002556 long ssloptions =
Emeric Brunfc0421f2012-09-07 17:30:07 +02002557 SSL_OP_ALL | /* all known workarounds for bugs */
2558 SSL_OP_NO_SSLv2 |
2559 SSL_OP_NO_COMPRESSION |
Emeric Bruna4bcd9a2012-09-20 16:19:02 +02002560 SSL_OP_SINGLE_DH_USE |
Emeric Brun2b58d042012-09-20 17:10:03 +02002561 SSL_OP_SINGLE_ECDH_USE |
Emeric Brun3c4bc6e2012-10-04 18:44:19 +02002562 SSL_OP_NO_SESSION_RESUMPTION_ON_RENEGOTIATION |
2563 SSL_OP_CIPHER_SERVER_PREFERENCE;
Remi Gacogneaf5c3da2014-05-19 10:29:58 +02002564 long sslmode =
Emeric Brunfc0421f2012-09-07 17:30:07 +02002565 SSL_MODE_ENABLE_PARTIAL_WRITE |
2566 SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER |
Willy Tarreau396a1862014-11-13 14:06:52 +01002567 SSL_MODE_RELEASE_BUFFERS |
2568 SSL_MODE_SMALL_BUFFERS;
Remi Gacognef46cd6e2014-06-12 14:58:40 +02002569 STACK_OF(SSL_CIPHER) * ciphers = NULL;
Willy Tarreaua616ba62014-10-26 06:49:19 +01002570 SSL_CIPHER * cipher = NULL;
Remi Gacognec1eab8c2014-06-12 18:20:11 +02002571 char cipher_description[128];
2572 /* The description of ciphers using an Ephemeral Diffie Hellman key exchange
2573 contains " Kx=DH " or " Kx=DH(". Beware of " Kx=DH/",
2574 which is not ephemeral DH. */
2575 const char dhe_description[] = " Kx=DH ";
2576 const char dhe_export_description[] = " Kx=DH(";
Remi Gacognef46cd6e2014-06-12 14:58:40 +02002577 int idx = 0;
2578 int dhe_found = 0;
Remi Gacogne23d5d372014-10-10 17:04:26 +02002579 SSL *ssl = NULL;
Emeric Brunfc0421f2012-09-07 17:30:07 +02002580
Thierry Fournier383085f2013-01-24 14:15:43 +01002581 /* Make sure openssl opens /dev/urandom before the chroot */
2582 if (!ssl_initialize_random()) {
2583 Alert("OpenSSL random data generator initialization failed.\n");
2584 cfgerr++;
2585 }
2586
Emeric Brun89675492012-10-05 13:48:26 +02002587 if (bind_conf->ssl_options & BC_SSL_O_NO_SSLV3)
Emeric Brunfc0421f2012-09-07 17:30:07 +02002588 ssloptions |= SSL_OP_NO_SSLv3;
Emeric Brun89675492012-10-05 13:48:26 +02002589 if (bind_conf->ssl_options & BC_SSL_O_NO_TLSV10)
Emeric Brunfc0421f2012-09-07 17:30:07 +02002590 ssloptions |= SSL_OP_NO_TLSv1;
Emeric Brun89675492012-10-05 13:48:26 +02002591 if (bind_conf->ssl_options & BC_SSL_O_NO_TLSV11)
Emeric Brunc0ff4922012-09-28 19:37:02 +02002592 ssloptions |= SSL_OP_NO_TLSv1_1;
Emeric Brun89675492012-10-05 13:48:26 +02002593 if (bind_conf->ssl_options & BC_SSL_O_NO_TLSV12)
Emeric Brunc0ff4922012-09-28 19:37:02 +02002594 ssloptions |= SSL_OP_NO_TLSv1_2;
Emeric Brun89675492012-10-05 13:48:26 +02002595 if (bind_conf->ssl_options & BC_SSL_O_NO_TLS_TICKETS)
Emeric Brun2d0c4822012-10-02 13:45:20 +02002596 ssloptions |= SSL_OP_NO_TICKET;
Jérémie Courrèges-Anglas17c3f622015-07-25 16:50:52 -06002597 if (bind_conf->ssl_options & BC_SSL_O_USE_SSLV3) {
2598#ifndef OPENSSL_NO_SSL3
Emeric Brun2cb7ae52012-10-05 14:14:21 +02002599 SSL_CTX_set_ssl_version(ctx, SSLv3_server_method());
Jérémie Courrèges-Anglas17c3f622015-07-25 16:50:52 -06002600#else
2601 Alert("SSLv3 support requested but unavailable.\n");
2602 cfgerr++;
2603#endif
2604 }
Emeric Brun2cb7ae52012-10-05 14:14:21 +02002605 if (bind_conf->ssl_options & BC_SSL_O_USE_TLSV10)
2606 SSL_CTX_set_ssl_version(ctx, TLSv1_server_method());
2607#if SSL_OP_NO_TLSv1_1
2608 if (bind_conf->ssl_options & BC_SSL_O_USE_TLSV11)
2609 SSL_CTX_set_ssl_version(ctx, TLSv1_1_server_method());
2610#endif
2611#if SSL_OP_NO_TLSv1_2
2612 if (bind_conf->ssl_options & BC_SSL_O_USE_TLSV12)
2613 SSL_CTX_set_ssl_version(ctx, TLSv1_2_server_method());
2614#endif
Emeric Brunfc0421f2012-09-07 17:30:07 +02002615
2616 SSL_CTX_set_options(ctx, ssloptions);
2617 SSL_CTX_set_mode(ctx, sslmode);
Emeric Brun850efd52014-01-29 12:24:34 +01002618 switch (bind_conf->verify) {
2619 case SSL_SOCK_VERIFY_NONE:
2620 verify = SSL_VERIFY_NONE;
2621 break;
2622 case SSL_SOCK_VERIFY_OPTIONAL:
2623 verify = SSL_VERIFY_PEER;
2624 break;
2625 case SSL_SOCK_VERIFY_REQUIRED:
2626 verify = SSL_VERIFY_PEER|SSL_VERIFY_FAIL_IF_NO_PEER_CERT;
2627 break;
2628 }
2629 SSL_CTX_set_verify(ctx, verify, ssl_sock_bind_verifycbk);
2630 if (verify & SSL_VERIFY_PEER) {
Emeric Brunfb510ea2012-10-05 12:00:26 +02002631 if (bind_conf->ca_file) {
Emeric Brund94b3fe2012-09-20 18:23:56 +02002632 /* load CAfile to verify */
Emeric Brunfb510ea2012-10-05 12:00:26 +02002633 if (!SSL_CTX_load_verify_locations(ctx, bind_conf->ca_file, NULL)) {
Emeric Brund94b3fe2012-09-20 18:23:56 +02002634 Alert("Proxy '%s': unable to load CA file '%s' for bind '%s' at [%s:%d].\n",
Emeric Brunfb510ea2012-10-05 12:00:26 +02002635 curproxy->id, bind_conf->ca_file, bind_conf->arg, bind_conf->file, bind_conf->line);
Emeric Brund94b3fe2012-09-20 18:23:56 +02002636 cfgerr++;
2637 }
2638 /* set CA names fo client cert request, function returns void */
Emeric Brunfb510ea2012-10-05 12:00:26 +02002639 SSL_CTX_set_client_CA_list(ctx, SSL_load_client_CA_file(bind_conf->ca_file));
Emeric Brund94b3fe2012-09-20 18:23:56 +02002640 }
Emeric Brun850efd52014-01-29 12:24:34 +01002641 else {
2642 Alert("Proxy '%s': verify is enabled but no CA file specified for bind '%s' at [%s:%d].\n",
2643 curproxy->id, bind_conf->arg, bind_conf->file, bind_conf->line);
2644 cfgerr++;
2645 }
Emeric Brun051cdab2012-10-02 19:25:50 +02002646#ifdef X509_V_FLAG_CRL_CHECK
Emeric Brunfb510ea2012-10-05 12:00:26 +02002647 if (bind_conf->crl_file) {
Emeric Brund94b3fe2012-09-20 18:23:56 +02002648 X509_STORE *store = SSL_CTX_get_cert_store(ctx);
2649
Emeric Brunfb510ea2012-10-05 12:00:26 +02002650 if (!store || !X509_STORE_load_locations(store, bind_conf->crl_file, NULL)) {
Emeric Brund94b3fe2012-09-20 18:23:56 +02002651 Alert("Proxy '%s': unable to configure CRL file '%s' for bind '%s' at [%s:%d].\n",
Alexander Rigbofc65af02015-04-07 14:02:16 +02002652 curproxy->id, bind_conf->crl_file, bind_conf->arg, bind_conf->file, bind_conf->line);
Emeric Brund94b3fe2012-09-20 18:23:56 +02002653 cfgerr++;
2654 }
Emeric Brun561e5742012-10-02 15:20:55 +02002655 else {
2656 X509_STORE_set_flags(store, X509_V_FLAG_CRL_CHECK|X509_V_FLAG_CRL_CHECK_ALL);
2657 }
Emeric Brund94b3fe2012-09-20 18:23:56 +02002658 }
Emeric Brun051cdab2012-10-02 19:25:50 +02002659#endif
Emeric Brun644cde02012-12-14 11:21:13 +01002660 ERR_clear_error();
Emeric Brund94b3fe2012-09-20 18:23:56 +02002661 }
Emeric Brunfc0421f2012-09-07 17:30:07 +02002662
Nenad Merdanovic05552d42015-02-27 19:56:49 +01002663#if (defined SSL_CTRL_SET_TLSEXT_TICKET_KEY_CB && TLS_TICKETS_NO > 0)
Nenad Merdanovic146defa2015-05-09 08:46:00 +02002664 if(bind_conf->keys_ref) {
Nenad Merdanovic05552d42015-02-27 19:56:49 +01002665 if (!SSL_CTX_set_tlsext_ticket_key_cb(ctx, ssl_tlsext_ticket_key_cb)) {
2666 Alert("Proxy '%s': unable to set callback for TLS ticket validation for bind '%s' at [%s:%d].\n",
2667 curproxy->id, bind_conf->arg, bind_conf->file, bind_conf->line);
2668 cfgerr++;
2669 }
2670 }
2671#endif
2672
Emeric Brun4f65bff2012-11-16 15:11:00 +01002673 if (global.tune.ssllifetime)
2674 SSL_CTX_set_timeout(ctx, global.tune.ssllifetime);
2675
Emeric Brunfc0421f2012-09-07 17:30:07 +02002676 shared_context_set_cache(ctx);
Willy Tarreau2a65ff02012-09-13 17:54:29 +02002677 if (bind_conf->ciphers &&
2678 !SSL_CTX_set_cipher_list(ctx, bind_conf->ciphers)) {
Emeric Brunfc0421f2012-09-07 17:30:07 +02002679 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 +02002680 curproxy->id, bind_conf->ciphers, bind_conf->arg, bind_conf->file, bind_conf->line);
Emeric Brunfc0421f2012-09-07 17:30:07 +02002681 cfgerr++;
2682 }
2683
Remi Gacogne47783ef2015-05-29 15:53:22 +02002684 /* If tune.ssl.default-dh-param has not been set,
2685 neither has ssl-default-dh-file and no static DH
2686 params were in the certificate file. */
Remi Gacogne4f902b82015-05-28 16:23:00 +02002687 if (global.tune.ssl_default_dh_param == 0 &&
Remi Gacogne47783ef2015-05-29 15:53:22 +02002688 global_dh == NULL &&
Remi Gacogne4f902b82015-05-28 16:23:00 +02002689 (ssl_dh_ptr_index == -1 ||
2690 SSL_CTX_get_ex_data(ctx, ssl_dh_ptr_index) == NULL)) {
Lukas Tribus90132722014-08-18 00:56:33 +02002691
Remi Gacogne23d5d372014-10-10 17:04:26 +02002692 ssl = SSL_new(ctx);
Remi Gacognef46cd6e2014-06-12 14:58:40 +02002693
Remi Gacogne23d5d372014-10-10 17:04:26 +02002694 if (ssl) {
2695 ciphers = SSL_get_ciphers(ssl);
2696
2697 if (ciphers) {
2698 for (idx = 0; idx < sk_SSL_CIPHER_num(ciphers); idx++) {
2699 cipher = sk_SSL_CIPHER_value(ciphers, idx);
2700 if (SSL_CIPHER_description(cipher, cipher_description, sizeof (cipher_description)) == cipher_description) {
2701 if (strstr(cipher_description, dhe_description) != NULL ||
2702 strstr(cipher_description, dhe_export_description) != NULL) {
2703 dhe_found = 1;
2704 break;
2705 }
Remi Gacognec1eab8c2014-06-12 18:20:11 +02002706 }
Remi Gacognef46cd6e2014-06-12 14:58:40 +02002707 }
2708 }
Remi Gacogne23d5d372014-10-10 17:04:26 +02002709 SSL_free(ssl);
2710 ssl = NULL;
Lukas Tribus90132722014-08-18 00:56:33 +02002711 }
Remi Gacognef46cd6e2014-06-12 14:58:40 +02002712
Lukas Tribus90132722014-08-18 00:56:33 +02002713 if (dhe_found) {
2714 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 +02002715 }
2716
2717 global.tune.ssl_default_dh_param = 1024;
2718 }
Remi Gacogne8de54152014-07-15 11:36:40 +02002719
2720#ifndef OPENSSL_NO_DH
2721 if (global.tune.ssl_default_dh_param >= 1024) {
2722 if (local_dh_1024 == NULL) {
2723 local_dh_1024 = ssl_get_dh_1024();
2724 }
2725 if (global.tune.ssl_default_dh_param >= 2048) {
2726 if (local_dh_2048 == NULL) {
2727 local_dh_2048 = ssl_get_dh_2048();
2728 }
2729 if (global.tune.ssl_default_dh_param >= 4096) {
2730 if (local_dh_4096 == NULL) {
2731 local_dh_4096 = ssl_get_dh_4096();
2732 }
Remi Gacogne8de54152014-07-15 11:36:40 +02002733 }
2734 }
2735 }
2736#endif /* OPENSSL_NO_DH */
Remi Gacognef46cd6e2014-06-12 14:58:40 +02002737
Emeric Brunfc0421f2012-09-07 17:30:07 +02002738 SSL_CTX_set_info_callback(ctx, ssl_sock_infocbk);
Willy Tarreau5cbe4ef2014-05-08 22:45:11 +02002739#if OPENSSL_VERSION_NUMBER >= 0x00907000L
Emeric Brun29f037d2014-04-25 19:05:36 +02002740 SSL_CTX_set_msg_callback(ctx, ssl_sock_msgcbk);
Willy Tarreau5cbe4ef2014-05-08 22:45:11 +02002741#endif
Emeric Brun29f037d2014-04-25 19:05:36 +02002742
Willy Tarreau6c9a3d52012-10-18 18:57:14 +02002743#ifdef OPENSSL_NPN_NEGOTIATED
2744 if (bind_conf->npn_str)
2745 SSL_CTX_set_next_protos_advertised_cb(ctx, ssl_sock_advertise_npn_protos, bind_conf);
2746#endif
Dirkjan Bussink48f1c4e2014-02-13 12:29:42 +01002747#ifdef TLSEXT_TYPE_application_layer_protocol_negotiation
Willy Tarreauab861d32013-04-02 02:30:41 +02002748 if (bind_conf->alpn_str)
Dirkjan Bussink48f1c4e2014-02-13 12:29:42 +01002749 SSL_CTX_set_alpn_select_cb(ctx, ssl_sock_advertise_alpn_protos, bind_conf);
Willy Tarreauab861d32013-04-02 02:30:41 +02002750#endif
Willy Tarreau6c9a3d52012-10-18 18:57:14 +02002751
Emeric Brunfc0421f2012-09-07 17:30:07 +02002752#ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME
2753 SSL_CTX_set_tlsext_servername_callback(ctx, ssl_sock_switchctx_cbk);
Willy Tarreau2a65ff02012-09-13 17:54:29 +02002754 SSL_CTX_set_tlsext_servername_arg(ctx, bind_conf);
Emeric Brunfc0421f2012-09-07 17:30:07 +02002755#endif
Emeric Brun2b58d042012-09-20 17:10:03 +02002756#if defined(SSL_CTX_set_tmp_ecdh) && !defined(OPENSSL_NO_ECDH)
Emeric Brun6924ef82013-03-06 14:08:53 +01002757 {
Emeric Brun2b58d042012-09-20 17:10:03 +02002758 int i;
2759 EC_KEY *ecdh;
2760
Emeric Brun6924ef82013-03-06 14:08:53 +01002761 i = OBJ_sn2nid(bind_conf->ecdhe ? bind_conf->ecdhe : ECDHE_DEFAULT_CURVE);
Emeric Brun2b58d042012-09-20 17:10:03 +02002762 if (!i || ((ecdh = EC_KEY_new_by_curve_name(i)) == NULL)) {
2763 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 +01002764 curproxy->id, bind_conf->ecdhe ? bind_conf->ecdhe : ECDHE_DEFAULT_CURVE,
2765 bind_conf->arg, bind_conf->file, bind_conf->line);
Emeric Brun2b58d042012-09-20 17:10:03 +02002766 cfgerr++;
2767 }
2768 else {
2769 SSL_CTX_set_tmp_ecdh(ctx, ecdh);
2770 EC_KEY_free(ecdh);
2771 }
2772 }
2773#endif
2774
Emeric Brunfc0421f2012-09-07 17:30:07 +02002775 return cfgerr;
2776}
2777
Evan Broderbe554312013-06-27 00:05:25 -07002778static int ssl_sock_srv_hostcheck(const char *pattern, const char *hostname)
2779{
2780 const char *pattern_wildcard, *pattern_left_label_end, *hostname_left_label_end;
2781 size_t prefixlen, suffixlen;
2782
2783 /* Trivial case */
2784 if (strcmp(pattern, hostname) == 0)
2785 return 1;
2786
Evan Broderbe554312013-06-27 00:05:25 -07002787 /* The rest of this logic is based on RFC 6125, section 6.4.3
2788 * (http://tools.ietf.org/html/rfc6125#section-6.4.3) */
2789
Emeric Bruna848dae2013-10-08 11:27:28 +02002790 pattern_wildcard = NULL;
2791 pattern_left_label_end = pattern;
2792 while (*pattern_left_label_end != '.') {
2793 switch (*pattern_left_label_end) {
2794 case 0:
2795 /* End of label not found */
2796 return 0;
2797 case '*':
2798 /* If there is more than one wildcards */
2799 if (pattern_wildcard)
2800 return 0;
2801 pattern_wildcard = pattern_left_label_end;
2802 break;
2803 }
2804 pattern_left_label_end++;
2805 }
2806
2807 /* If it's not trivial and there is no wildcard, it can't
2808 * match */
2809 if (!pattern_wildcard)
Evan Broderbe554312013-06-27 00:05:25 -07002810 return 0;
2811
2812 /* Make sure all labels match except the leftmost */
2813 hostname_left_label_end = strchr(hostname, '.');
2814 if (!hostname_left_label_end
2815 || strcmp(pattern_left_label_end, hostname_left_label_end) != 0)
2816 return 0;
2817
2818 /* Make sure the leftmost label of the hostname is long enough
2819 * that the wildcard can match */
Emeric Brun369da852013-10-08 11:39:35 +02002820 if (hostname_left_label_end - hostname < (pattern_left_label_end - pattern) - 1)
Evan Broderbe554312013-06-27 00:05:25 -07002821 return 0;
2822
2823 /* Finally compare the string on either side of the
2824 * wildcard */
2825 prefixlen = pattern_wildcard - pattern;
2826 suffixlen = pattern_left_label_end - (pattern_wildcard + 1);
Emeric Bruna848dae2013-10-08 11:27:28 +02002827 if ((prefixlen && (memcmp(pattern, hostname, prefixlen) != 0))
2828 || (suffixlen && (memcmp(pattern_wildcard + 1, hostname_left_label_end - suffixlen, suffixlen) != 0)))
Evan Broderbe554312013-06-27 00:05:25 -07002829 return 0;
2830
2831 return 1;
2832}
2833
2834static int ssl_sock_srv_verifycbk(int ok, X509_STORE_CTX *ctx)
2835{
2836 SSL *ssl;
2837 struct connection *conn;
2838 char *servername;
2839
2840 int depth;
2841 X509 *cert;
2842 STACK_OF(GENERAL_NAME) *alt_names;
2843 int i;
2844 X509_NAME *cert_subject;
2845 char *str;
2846
2847 if (ok == 0)
2848 return ok;
2849
2850 ssl = X509_STORE_CTX_get_ex_data(ctx, SSL_get_ex_data_X509_STORE_CTX_idx());
2851 conn = (struct connection *)SSL_get_app_data(ssl);
2852
2853 servername = objt_server(conn->target)->ssl_ctx.verify_host;
2854
2855 /* We only need to verify the CN on the actual server cert,
2856 * not the indirect CAs */
2857 depth = X509_STORE_CTX_get_error_depth(ctx);
2858 if (depth != 0)
2859 return ok;
2860
2861 /* At this point, the cert is *not* OK unless we can find a
2862 * hostname match */
2863 ok = 0;
2864
2865 cert = X509_STORE_CTX_get_current_cert(ctx);
2866 /* It seems like this might happen if verify peer isn't set */
2867 if (!cert)
2868 return ok;
2869
2870 alt_names = X509_get_ext_d2i(cert, NID_subject_alt_name, NULL, NULL);
2871 if (alt_names) {
2872 for (i = 0; !ok && i < sk_GENERAL_NAME_num(alt_names); i++) {
2873 GENERAL_NAME *name = sk_GENERAL_NAME_value(alt_names, i);
2874 if (name->type == GEN_DNS) {
Emeric Bruna33410c2013-09-17 15:47:48 +02002875#if OPENSSL_VERSION_NUMBER < 0x00907000L
2876 if (ASN1_STRING_to_UTF8((unsigned char **)&str, name->d.ia5) >= 0) {
2877#else
Evan Broderbe554312013-06-27 00:05:25 -07002878 if (ASN1_STRING_to_UTF8((unsigned char **)&str, name->d.dNSName) >= 0) {
Emeric Bruna33410c2013-09-17 15:47:48 +02002879#endif
Evan Broderbe554312013-06-27 00:05:25 -07002880 ok = ssl_sock_srv_hostcheck(str, servername);
2881 OPENSSL_free(str);
2882 }
2883 }
2884 }
Emeric Brun4ad50a42013-09-17 15:19:54 +02002885 sk_GENERAL_NAME_pop_free(alt_names, GENERAL_NAME_free);
Evan Broderbe554312013-06-27 00:05:25 -07002886 }
2887
2888 cert_subject = X509_get_subject_name(cert);
2889 i = -1;
2890 while (!ok && (i = X509_NAME_get_index_by_NID(cert_subject, NID_commonName, i)) != -1) {
2891 X509_NAME_ENTRY *entry = X509_NAME_get_entry(cert_subject, i);
2892 if (ASN1_STRING_to_UTF8((unsigned char **)&str, entry->value) >= 0) {
2893 ok = ssl_sock_srv_hostcheck(str, servername);
2894 OPENSSL_free(str);
2895 }
2896 }
2897
2898 return ok;
2899}
2900
Emeric Brun94324a42012-10-11 14:00:19 +02002901/* prepare ssl context from servers options. Returns an error count */
2902int ssl_sock_prepare_srv_ctx(struct server *srv, struct proxy *curproxy)
2903{
2904 int cfgerr = 0;
Remi Gacogneaf5c3da2014-05-19 10:29:58 +02002905 long options =
Emeric Brun94324a42012-10-11 14:00:19 +02002906 SSL_OP_ALL | /* all known workarounds for bugs */
2907 SSL_OP_NO_SSLv2 |
2908 SSL_OP_NO_COMPRESSION;
Remi Gacogneaf5c3da2014-05-19 10:29:58 +02002909 long mode =
Emeric Brun94324a42012-10-11 14:00:19 +02002910 SSL_MODE_ENABLE_PARTIAL_WRITE |
2911 SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER |
Willy Tarreau396a1862014-11-13 14:06:52 +01002912 SSL_MODE_RELEASE_BUFFERS |
2913 SSL_MODE_SMALL_BUFFERS;
Emeric Brun850efd52014-01-29 12:24:34 +01002914 int verify = SSL_VERIFY_NONE;
Emeric Brun94324a42012-10-11 14:00:19 +02002915
Thierry Fournier383085f2013-01-24 14:15:43 +01002916 /* Make sure openssl opens /dev/urandom before the chroot */
2917 if (!ssl_initialize_random()) {
2918 Alert("OpenSSL random data generator initialization failed.\n");
2919 cfgerr++;
2920 }
2921
Willy Tarreaufce03112015-01-15 21:32:40 +01002922 /* Automatic memory computations need to know we use SSL there */
2923 global.ssl_used_backend = 1;
2924
2925 /* Initiate SSL context for current server */
Emeric Brun94324a42012-10-11 14:00:19 +02002926 srv->ssl_ctx.reused_sess = NULL;
2927 if (srv->use_ssl)
2928 srv->xprt = &ssl_sock;
2929 if (srv->check.use_ssl)
Cyril Bonté9ce13112014-11-15 22:41:27 +01002930 srv->check.xprt = &ssl_sock;
Emeric Brun94324a42012-10-11 14:00:19 +02002931
2932 srv->ssl_ctx.ctx = SSL_CTX_new(SSLv23_client_method());
2933 if (!srv->ssl_ctx.ctx) {
2934 Alert("config : %s '%s', server '%s': unable to allocate ssl context.\n",
2935 proxy_type_str(curproxy), curproxy->id,
2936 srv->id);
2937 cfgerr++;
2938 return cfgerr;
2939 }
Emeric Bruna7aa3092012-10-26 12:58:00 +02002940 if (srv->ssl_ctx.client_crt) {
2941 if (SSL_CTX_use_PrivateKey_file(srv->ssl_ctx.ctx, srv->ssl_ctx.client_crt, SSL_FILETYPE_PEM) <= 0) {
2942 Alert("config : %s '%s', server '%s': unable to load SSL private key from PEM file '%s'.\n",
2943 proxy_type_str(curproxy), curproxy->id,
2944 srv->id, srv->ssl_ctx.client_crt);
2945 cfgerr++;
2946 }
2947 else if (SSL_CTX_use_certificate_chain_file(srv->ssl_ctx.ctx, srv->ssl_ctx.client_crt) <= 0) {
2948 Alert("config : %s '%s', server '%s': unable to load ssl certificate from PEM file '%s'.\n",
2949 proxy_type_str(curproxy), curproxy->id,
2950 srv->id, srv->ssl_ctx.client_crt);
2951 cfgerr++;
2952 }
2953 else if (SSL_CTX_check_private_key(srv->ssl_ctx.ctx) <= 0) {
2954 Alert("config : %s '%s', server '%s': inconsistencies between private key and certificate loaded from PEM file '%s'.\n",
2955 proxy_type_str(curproxy), curproxy->id,
2956 srv->id, srv->ssl_ctx.client_crt);
2957 cfgerr++;
2958 }
2959 }
Emeric Brun94324a42012-10-11 14:00:19 +02002960
2961 if (srv->ssl_ctx.options & SRV_SSL_O_NO_SSLV3)
2962 options |= SSL_OP_NO_SSLv3;
2963 if (srv->ssl_ctx.options & SRV_SSL_O_NO_TLSV10)
2964 options |= SSL_OP_NO_TLSv1;
2965 if (srv->ssl_ctx.options & SRV_SSL_O_NO_TLSV11)
2966 options |= SSL_OP_NO_TLSv1_1;
2967 if (srv->ssl_ctx.options & SRV_SSL_O_NO_TLSV12)
2968 options |= SSL_OP_NO_TLSv1_2;
Emeric Brunf9c5c472012-10-11 15:28:34 +02002969 if (srv->ssl_ctx.options & SRV_SSL_O_NO_TLS_TICKETS)
2970 options |= SSL_OP_NO_TICKET;
Jérémie Courrèges-Anglas17c3f622015-07-25 16:50:52 -06002971 if (srv->ssl_ctx.options & SRV_SSL_O_USE_SSLV3) {
2972#ifndef OPENSSL_NO_SSL3
Emeric Brun94324a42012-10-11 14:00:19 +02002973 SSL_CTX_set_ssl_version(srv->ssl_ctx.ctx, SSLv3_client_method());
Jérémie Courrèges-Anglas17c3f622015-07-25 16:50:52 -06002974#else
Thierry FOURNIERbc965342015-08-26 08:21:26 +02002975 Alert("SSLv3 support requested but unavailable.\n");
Jérémie Courrèges-Anglas17c3f622015-07-25 16:50:52 -06002976 cfgerr++;
2977#endif
2978 }
Emeric Brun94324a42012-10-11 14:00:19 +02002979 if (srv->ssl_ctx.options & SRV_SSL_O_USE_TLSV10)
2980 SSL_CTX_set_ssl_version(srv->ssl_ctx.ctx, TLSv1_client_method());
2981#if SSL_OP_NO_TLSv1_1
2982 if (srv->ssl_ctx.options & SRV_SSL_O_USE_TLSV11)
2983 SSL_CTX_set_ssl_version(srv->ssl_ctx.ctx, TLSv1_1_client_method());
2984#endif
2985#if SSL_OP_NO_TLSv1_2
2986 if (srv->ssl_ctx.options & SRV_SSL_O_USE_TLSV12)
2987 SSL_CTX_set_ssl_version(srv->ssl_ctx.ctx, TLSv1_2_client_method());
2988#endif
2989
2990 SSL_CTX_set_options(srv->ssl_ctx.ctx, options);
2991 SSL_CTX_set_mode(srv->ssl_ctx.ctx, mode);
Emeric Brun850efd52014-01-29 12:24:34 +01002992
2993 if (global.ssl_server_verify == SSL_SERVER_VERIFY_REQUIRED)
2994 verify = SSL_VERIFY_PEER;
2995
2996 switch (srv->ssl_ctx.verify) {
2997 case SSL_SOCK_VERIFY_NONE:
2998 verify = SSL_VERIFY_NONE;
2999 break;
3000 case SSL_SOCK_VERIFY_REQUIRED:
3001 verify = SSL_VERIFY_PEER;
3002 break;
3003 }
Evan Broderbe554312013-06-27 00:05:25 -07003004 SSL_CTX_set_verify(srv->ssl_ctx.ctx,
Emeric Brun850efd52014-01-29 12:24:34 +01003005 verify,
Evan Broderbe554312013-06-27 00:05:25 -07003006 srv->ssl_ctx.verify_host ? ssl_sock_srv_verifycbk : NULL);
Emeric Brun850efd52014-01-29 12:24:34 +01003007 if (verify & SSL_VERIFY_PEER) {
Emeric Brunef42d922012-10-11 16:11:36 +02003008 if (srv->ssl_ctx.ca_file) {
3009 /* load CAfile to verify */
3010 if (!SSL_CTX_load_verify_locations(srv->ssl_ctx.ctx, srv->ssl_ctx.ca_file, NULL)) {
Willy Tarreau07ba08b2014-02-16 19:22:08 +01003011 Alert("Proxy '%s', server '%s' [%s:%d] unable to load CA file '%s'.\n",
Emeric Brunef42d922012-10-11 16:11:36 +02003012 curproxy->id, srv->id,
3013 srv->conf.file, srv->conf.line, srv->ssl_ctx.ca_file);
3014 cfgerr++;
3015 }
3016 }
Emeric Brun850efd52014-01-29 12:24:34 +01003017 else {
3018 if (global.ssl_server_verify == SSL_SERVER_VERIFY_REQUIRED)
Willy Tarreau07ba08b2014-02-16 19:22:08 +01003019 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 +01003020 curproxy->id, srv->id,
3021 srv->conf.file, srv->conf.line);
3022 else
Willy Tarreau07ba08b2014-02-16 19:22:08 +01003023 Alert("Proxy '%s', server '%s' [%s:%d] verify is enabled but no CA file specified.\n",
Emeric Brun850efd52014-01-29 12:24:34 +01003024 curproxy->id, srv->id,
3025 srv->conf.file, srv->conf.line);
3026 cfgerr++;
3027 }
Emeric Brunef42d922012-10-11 16:11:36 +02003028#ifdef X509_V_FLAG_CRL_CHECK
3029 if (srv->ssl_ctx.crl_file) {
3030 X509_STORE *store = SSL_CTX_get_cert_store(srv->ssl_ctx.ctx);
3031
3032 if (!store || !X509_STORE_load_locations(store, srv->ssl_ctx.crl_file, NULL)) {
Willy Tarreau07ba08b2014-02-16 19:22:08 +01003033 Alert("Proxy '%s', server '%s' [%s:%d] unable to configure CRL file '%s'.\n",
Emeric Brunef42d922012-10-11 16:11:36 +02003034 curproxy->id, srv->id,
3035 srv->conf.file, srv->conf.line, srv->ssl_ctx.crl_file);
3036 cfgerr++;
3037 }
3038 else {
3039 X509_STORE_set_flags(store, X509_V_FLAG_CRL_CHECK|X509_V_FLAG_CRL_CHECK_ALL);
3040 }
3041 }
3042#endif
3043 }
3044
Emeric Brun4f65bff2012-11-16 15:11:00 +01003045 if (global.tune.ssllifetime)
3046 SSL_CTX_set_timeout(srv->ssl_ctx.ctx, global.tune.ssllifetime);
3047
Emeric Brun94324a42012-10-11 14:00:19 +02003048 SSL_CTX_set_session_cache_mode(srv->ssl_ctx.ctx, SSL_SESS_CACHE_OFF);
3049 if (srv->ssl_ctx.ciphers &&
3050 !SSL_CTX_set_cipher_list(srv->ssl_ctx.ctx, srv->ssl_ctx.ciphers)) {
3051 Alert("Proxy '%s', server '%s' [%s:%d] : unable to set SSL cipher list to '%s'.\n",
3052 curproxy->id, srv->id,
3053 srv->conf.file, srv->conf.line, srv->ssl_ctx.ciphers);
3054 cfgerr++;
3055 }
3056
3057 return cfgerr;
3058}
3059
Willy Tarreau2a65ff02012-09-13 17:54:29 +02003060/* Walks down the two trees in bind_conf and prepares all certs. The pointer may
Emeric Brunfc0421f2012-09-07 17:30:07 +02003061 * be NULL, in which case nothing is done. Returns the number of errors
3062 * encountered.
3063 */
Willy Tarreau2a65ff02012-09-13 17:54:29 +02003064int ssl_sock_prepare_all_ctx(struct bind_conf *bind_conf, struct proxy *px)
Emeric Brunfc0421f2012-09-07 17:30:07 +02003065{
3066 struct ebmb_node *node;
3067 struct sni_ctx *sni;
3068 int err = 0;
3069
Willy Tarreau2a65ff02012-09-13 17:54:29 +02003070 if (!bind_conf || !bind_conf->is_ssl)
Emeric Brunfc0421f2012-09-07 17:30:07 +02003071 return 0;
3072
Willy Tarreaufce03112015-01-15 21:32:40 +01003073 /* Automatic memory computations need to know we use SSL there */
3074 global.ssl_used_frontend = 1;
3075
Emeric Brun0bed9942014-10-30 19:25:24 +01003076 if (bind_conf->default_ctx)
3077 err += ssl_sock_prepare_ctx(bind_conf, bind_conf->default_ctx, px);
3078
Willy Tarreau2a65ff02012-09-13 17:54:29 +02003079 node = ebmb_first(&bind_conf->sni_ctx);
Emeric Brunfc0421f2012-09-07 17:30:07 +02003080 while (node) {
3081 sni = ebmb_entry(node, struct sni_ctx, name);
Emeric Brun0bed9942014-10-30 19:25:24 +01003082 if (!sni->order && sni->ctx != bind_conf->default_ctx)
3083 /* only initialize the CTX on its first occurrence and
3084 if it is not the default_ctx */
Willy Tarreau2a65ff02012-09-13 17:54:29 +02003085 err += ssl_sock_prepare_ctx(bind_conf, sni->ctx, px);
Emeric Brunfc0421f2012-09-07 17:30:07 +02003086 node = ebmb_next(node);
3087 }
3088
Willy Tarreau2a65ff02012-09-13 17:54:29 +02003089 node = ebmb_first(&bind_conf->sni_w_ctx);
Emeric Brunfc0421f2012-09-07 17:30:07 +02003090 while (node) {
3091 sni = ebmb_entry(node, struct sni_ctx, name);
Emeric Brun0bed9942014-10-30 19:25:24 +01003092 if (!sni->order && sni->ctx != bind_conf->default_ctx)
3093 /* only initialize the CTX on its first occurrence and
3094 if it is not the default_ctx */
Willy Tarreau2a65ff02012-09-13 17:54:29 +02003095 err += ssl_sock_prepare_ctx(bind_conf, sni->ctx, px);
Emeric Brunfc0421f2012-09-07 17:30:07 +02003096 node = ebmb_next(node);
3097 }
3098 return err;
3099}
3100
Christopher Faulet77fe80c2015-07-29 13:02:40 +02003101
3102/* release ssl context allocated for servers. */
3103void ssl_sock_free_srv_ctx(struct server *srv)
3104{
3105 if (srv->ssl_ctx.ctx)
3106 SSL_CTX_free(srv->ssl_ctx.ctx);
3107}
3108
Willy Tarreau2a65ff02012-09-13 17:54:29 +02003109/* Walks down the two trees in bind_conf and frees all the certs. The pointer may
Emeric Brunfc0421f2012-09-07 17:30:07 +02003110 * be NULL, in which case nothing is done. The default_ctx is nullified too.
3111 */
Willy Tarreau2a65ff02012-09-13 17:54:29 +02003112void ssl_sock_free_all_ctx(struct bind_conf *bind_conf)
Emeric Brunfc0421f2012-09-07 17:30:07 +02003113{
3114 struct ebmb_node *node, *back;
3115 struct sni_ctx *sni;
3116
Willy Tarreau2a65ff02012-09-13 17:54:29 +02003117 if (!bind_conf || !bind_conf->is_ssl)
Emeric Brunfc0421f2012-09-07 17:30:07 +02003118 return;
3119
Willy Tarreau2a65ff02012-09-13 17:54:29 +02003120 node = ebmb_first(&bind_conf->sni_ctx);
Emeric Brunfc0421f2012-09-07 17:30:07 +02003121 while (node) {
3122 sni = ebmb_entry(node, struct sni_ctx, name);
3123 back = ebmb_next(node);
3124 ebmb_delete(node);
3125 if (!sni->order) /* only free the CTX on its first occurrence */
3126 SSL_CTX_free(sni->ctx);
3127 free(sni);
3128 node = back;
3129 }
3130
Willy Tarreau2a65ff02012-09-13 17:54:29 +02003131 node = ebmb_first(&bind_conf->sni_w_ctx);
Emeric Brunfc0421f2012-09-07 17:30:07 +02003132 while (node) {
3133 sni = ebmb_entry(node, struct sni_ctx, name);
3134 back = ebmb_next(node);
3135 ebmb_delete(node);
3136 if (!sni->order) /* only free the CTX on its first occurrence */
3137 SSL_CTX_free(sni->ctx);
3138 free(sni);
3139 node = back;
3140 }
3141
Willy Tarreau2a65ff02012-09-13 17:54:29 +02003142 bind_conf->default_ctx = NULL;
Emeric Brune1f38db2012-09-03 20:36:47 +02003143}
3144
Christopher Faulet31af49d2015-06-09 17:29:50 +02003145/* Load CA cert file and private key used to generate certificates */
3146int
3147ssl_sock_load_ca(struct bind_conf *bind_conf, struct proxy *px)
3148{
3149 FILE *fp;
3150 X509 *cacert = NULL;
3151 EVP_PKEY *capkey = NULL;
3152 int err = 0;
3153
3154 if (!bind_conf || !bind_conf->generate_certs)
3155 return err;
3156
Willy Tarreaua84c2672015-10-09 12:10:13 +02003157#ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME
Christopher Fauletd2cab922015-07-28 16:03:47 +02003158 if (global.tune.ssl_ctx_cache)
3159 ssl_ctx_lru_tree = lru64_new(global.tune.ssl_ctx_cache);
3160 ssl_ctx_lru_seed = (unsigned int)time(NULL);
Willy Tarreaua84c2672015-10-09 12:10:13 +02003161#endif
Christopher Fauletd2cab922015-07-28 16:03:47 +02003162
Christopher Faulet31af49d2015-06-09 17:29:50 +02003163 if (!bind_conf->ca_sign_file) {
3164 Alert("Proxy '%s': cannot enable certificate generation, "
3165 "no CA certificate File configured at [%s:%d].\n",
3166 px->id, bind_conf->file, bind_conf->line);
Christopher Faulet31af49d2015-06-09 17:29:50 +02003167 goto load_error;
Christopher Fauletc6f02fb2015-10-09 10:53:31 +02003168 }
Christopher Faulet31af49d2015-06-09 17:29:50 +02003169
3170 /* read in the CA certificate */
3171 if (!(fp = fopen(bind_conf->ca_sign_file, "r"))) {
3172 Alert("Proxy '%s': Failed to read CA certificate file '%s' at [%s:%d].\n",
3173 px->id, bind_conf->ca_sign_file, bind_conf->file, bind_conf->line);
Christopher Faulet31af49d2015-06-09 17:29:50 +02003174 goto load_error;
3175 }
3176 if (!(cacert = PEM_read_X509(fp, NULL, NULL, NULL))) {
3177 Alert("Proxy '%s': Failed to read CA certificate file '%s' at [%s:%d].\n",
3178 px->id, bind_conf->ca_sign_file, bind_conf->file, bind_conf->line);
Christopher Fauletc6f02fb2015-10-09 10:53:31 +02003179 goto read_error;
Christopher Faulet31af49d2015-06-09 17:29:50 +02003180 }
Christopher Fauletc6f02fb2015-10-09 10:53:31 +02003181 rewind(fp);
Christopher Faulet31af49d2015-06-09 17:29:50 +02003182 if (!(capkey = PEM_read_PrivateKey(fp, NULL, NULL, bind_conf->ca_sign_pass))) {
3183 Alert("Proxy '%s': Failed to read CA private key file '%s' at [%s:%d].\n",
3184 px->id, bind_conf->ca_sign_file, bind_conf->file, bind_conf->line);
Christopher Fauletc6f02fb2015-10-09 10:53:31 +02003185 goto read_error;
Christopher Faulet31af49d2015-06-09 17:29:50 +02003186 }
Christopher Faulet31af49d2015-06-09 17:29:50 +02003187
Christopher Fauletc6f02fb2015-10-09 10:53:31 +02003188 fclose (fp);
Christopher Faulet31af49d2015-06-09 17:29:50 +02003189 bind_conf->ca_sign_cert = cacert;
3190 bind_conf->ca_sign_pkey = capkey;
3191 return err;
3192
Christopher Fauletc6f02fb2015-10-09 10:53:31 +02003193 read_error:
3194 fclose (fp);
Christopher Faulet31af49d2015-06-09 17:29:50 +02003195 if (capkey) EVP_PKEY_free(capkey);
3196 if (cacert) X509_free(cacert);
Christopher Fauletc6f02fb2015-10-09 10:53:31 +02003197 load_error:
3198 bind_conf->generate_certs = 0;
3199 err++;
Christopher Faulet31af49d2015-06-09 17:29:50 +02003200 return err;
3201}
3202
3203/* Release CA cert and private key used to generate certificated */
3204void
3205ssl_sock_free_ca(struct bind_conf *bind_conf)
3206{
3207 if (!bind_conf)
3208 return;
3209
3210 if (bind_conf->ca_sign_pkey)
3211 EVP_PKEY_free(bind_conf->ca_sign_pkey);
3212 if (bind_conf->ca_sign_cert)
3213 X509_free(bind_conf->ca_sign_cert);
3214}
3215
Emeric Brun46591952012-05-18 15:47:34 +02003216/*
3217 * This function is called if SSL * context is not yet allocated. The function
3218 * is designed to be called before any other data-layer operation and sets the
3219 * handshake flag on the connection. It is safe to call it multiple times.
3220 * It returns 0 on success and -1 in error case.
3221 */
3222static int ssl_sock_init(struct connection *conn)
3223{
3224 /* already initialized */
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02003225 if (conn->xprt_ctx)
Emeric Brun46591952012-05-18 15:47:34 +02003226 return 0;
3227
Willy Tarreau3c728722014-01-23 13:50:42 +01003228 if (!conn_ctrl_ready(conn))
Willy Tarreauf79c8172013-10-21 16:30:56 +02003229 return 0;
3230
Willy Tarreau20879a02012-12-03 16:32:10 +01003231 if (global.maxsslconn && sslconns >= global.maxsslconn) {
3232 conn->err_code = CO_ER_SSL_TOO_MANY;
Willy Tarreau403edff2012-09-06 11:58:37 +02003233 return -1;
Willy Tarreau20879a02012-12-03 16:32:10 +01003234 }
Willy Tarreau403edff2012-09-06 11:58:37 +02003235
Emeric Brun46591952012-05-18 15:47:34 +02003236 /* If it is in client mode initiate SSL session
3237 in connect state otherwise accept state */
Willy Tarreau3fdb3662012-11-12 00:42:33 +01003238 if (objt_server(conn->target)) {
Willy Tarreaufba03cd2014-11-13 13:48:58 +01003239 int may_retry = 1;
3240
3241 retry_connect:
Emeric Brun46591952012-05-18 15:47:34 +02003242 /* Alloc a new SSL session ctx */
Willy Tarreau3fdb3662012-11-12 00:42:33 +01003243 conn->xprt_ctx = SSL_new(objt_server(conn->target)->ssl_ctx.ctx);
Willy Tarreau20879a02012-12-03 16:32:10 +01003244 if (!conn->xprt_ctx) {
Willy Tarreaufba03cd2014-11-13 13:48:58 +01003245 if (may_retry--) {
3246 pool_gc2();
3247 goto retry_connect;
3248 }
Willy Tarreau20879a02012-12-03 16:32:10 +01003249 conn->err_code = CO_ER_SSL_NO_MEM;
Emeric Brun46591952012-05-18 15:47:34 +02003250 return -1;
Willy Tarreau20879a02012-12-03 16:32:10 +01003251 }
Emeric Brun46591952012-05-18 15:47:34 +02003252
Emeric Brun46591952012-05-18 15:47:34 +02003253 /* set fd on SSL session context */
Emeric Brun55476152014-11-12 17:35:37 +01003254 if (!SSL_set_fd(conn->xprt_ctx, conn->t.sock.fd)) {
3255 SSL_free(conn->xprt_ctx);
3256 conn->xprt_ctx = NULL;
Willy Tarreaufba03cd2014-11-13 13:48:58 +01003257 if (may_retry--) {
3258 pool_gc2();
3259 goto retry_connect;
3260 }
Emeric Brun55476152014-11-12 17:35:37 +01003261 conn->err_code = CO_ER_SSL_NO_MEM;
3262 return -1;
3263 }
Emeric Brun46591952012-05-18 15:47:34 +02003264
Evan Broderbe554312013-06-27 00:05:25 -07003265 /* set connection pointer */
Emeric Brun55476152014-11-12 17:35:37 +01003266 if (!SSL_set_app_data(conn->xprt_ctx, conn)) {
3267 SSL_free(conn->xprt_ctx);
3268 conn->xprt_ctx = NULL;
Willy Tarreaufba03cd2014-11-13 13:48:58 +01003269 if (may_retry--) {
3270 pool_gc2();
3271 goto retry_connect;
3272 }
Emeric Brun55476152014-11-12 17:35:37 +01003273 conn->err_code = CO_ER_SSL_NO_MEM;
3274 return -1;
3275 }
3276
3277 SSL_set_connect_state(conn->xprt_ctx);
3278 if (objt_server(conn->target)->ssl_ctx.reused_sess) {
3279 if(!SSL_set_session(conn->xprt_ctx, objt_server(conn->target)->ssl_ctx.reused_sess)) {
3280 SSL_SESSION_free(objt_server(conn->target)->ssl_ctx.reused_sess);
3281 objt_server(conn->target)->ssl_ctx.reused_sess = NULL;
3282 }
3283 }
Evan Broderbe554312013-06-27 00:05:25 -07003284
Emeric Brun46591952012-05-18 15:47:34 +02003285 /* leave init state and start handshake */
Willy Tarreau05737472012-09-04 08:03:39 +02003286 conn->flags |= CO_FL_SSL_WAIT_HS | CO_FL_WAIT_L6_CONN;
Willy Tarreau403edff2012-09-06 11:58:37 +02003287
3288 sslconns++;
Willy Tarreau71b734c2014-01-28 15:19:44 +01003289 totalsslconns++;
Emeric Brun46591952012-05-18 15:47:34 +02003290 return 0;
3291 }
Willy Tarreau3fdb3662012-11-12 00:42:33 +01003292 else if (objt_listener(conn->target)) {
Willy Tarreaufba03cd2014-11-13 13:48:58 +01003293 int may_retry = 1;
3294
3295 retry_accept:
Emeric Brun46591952012-05-18 15:47:34 +02003296 /* Alloc a new SSL session ctx */
Willy Tarreau3fdb3662012-11-12 00:42:33 +01003297 conn->xprt_ctx = SSL_new(objt_listener(conn->target)->bind_conf->default_ctx);
Willy Tarreau20879a02012-12-03 16:32:10 +01003298 if (!conn->xprt_ctx) {
Willy Tarreaufba03cd2014-11-13 13:48:58 +01003299 if (may_retry--) {
3300 pool_gc2();
3301 goto retry_accept;
3302 }
Willy Tarreau20879a02012-12-03 16:32:10 +01003303 conn->err_code = CO_ER_SSL_NO_MEM;
Emeric Brun46591952012-05-18 15:47:34 +02003304 return -1;
Willy Tarreau20879a02012-12-03 16:32:10 +01003305 }
Emeric Brun46591952012-05-18 15:47:34 +02003306
Emeric Brun46591952012-05-18 15:47:34 +02003307 /* set fd on SSL session context */
Emeric Brun55476152014-11-12 17:35:37 +01003308 if (!SSL_set_fd(conn->xprt_ctx, conn->t.sock.fd)) {
3309 SSL_free(conn->xprt_ctx);
3310 conn->xprt_ctx = NULL;
Willy Tarreaufba03cd2014-11-13 13:48:58 +01003311 if (may_retry--) {
3312 pool_gc2();
3313 goto retry_accept;
3314 }
Emeric Brun55476152014-11-12 17:35:37 +01003315 conn->err_code = CO_ER_SSL_NO_MEM;
3316 return -1;
3317 }
Emeric Brun46591952012-05-18 15:47:34 +02003318
Emeric Brune1f38db2012-09-03 20:36:47 +02003319 /* set connection pointer */
Emeric Brun55476152014-11-12 17:35:37 +01003320 if (!SSL_set_app_data(conn->xprt_ctx, conn)) {
3321 SSL_free(conn->xprt_ctx);
3322 conn->xprt_ctx = NULL;
Willy Tarreaufba03cd2014-11-13 13:48:58 +01003323 if (may_retry--) {
3324 pool_gc2();
3325 goto retry_accept;
3326 }
Emeric Brun55476152014-11-12 17:35:37 +01003327 conn->err_code = CO_ER_SSL_NO_MEM;
3328 return -1;
3329 }
3330
3331 SSL_set_accept_state(conn->xprt_ctx);
Emeric Brune1f38db2012-09-03 20:36:47 +02003332
Emeric Brun46591952012-05-18 15:47:34 +02003333 /* leave init state and start handshake */
Willy Tarreau05737472012-09-04 08:03:39 +02003334 conn->flags |= CO_FL_SSL_WAIT_HS | CO_FL_WAIT_L6_CONN;
Willy Tarreau403edff2012-09-06 11:58:37 +02003335
3336 sslconns++;
Willy Tarreau71b734c2014-01-28 15:19:44 +01003337 totalsslconns++;
Emeric Brun46591952012-05-18 15:47:34 +02003338 return 0;
3339 }
3340 /* don't know how to handle such a target */
Willy Tarreau20879a02012-12-03 16:32:10 +01003341 conn->err_code = CO_ER_SSL_NO_TARGET;
Emeric Brun46591952012-05-18 15:47:34 +02003342 return -1;
3343}
3344
3345
3346/* This is the callback which is used when an SSL handshake is pending. It
3347 * updates the FD status if it wants some polling before being called again.
3348 * It returns 0 if it fails in a fatal way or needs to poll to go further,
3349 * otherwise it returns non-zero and removes itself from the connection's
3350 * flags (the bit is provided in <flag> by the caller).
3351 */
3352int ssl_sock_handshake(struct connection *conn, unsigned int flag)
3353{
3354 int ret;
3355
Willy Tarreau3c728722014-01-23 13:50:42 +01003356 if (!conn_ctrl_ready(conn))
Willy Tarreauf79c8172013-10-21 16:30:56 +02003357 return 0;
3358
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02003359 if (!conn->xprt_ctx)
Emeric Brun46591952012-05-18 15:47:34 +02003360 goto out_error;
3361
Emeric Brun674b7432012-11-08 19:21:55 +01003362 /* If we use SSL_do_handshake to process a reneg initiated by
3363 * the remote peer, it sometimes returns SSL_ERROR_SSL.
3364 * Usually SSL_write and SSL_read are used and process implicitly
3365 * the reneg handshake.
3366 * Here we use SSL_peek as a workaround for reneg.
3367 */
3368 if ((conn->flags & CO_FL_CONNECTED) && SSL_renegotiate_pending(conn->xprt_ctx)) {
3369 char c;
3370
3371 ret = SSL_peek(conn->xprt_ctx, &c, 1);
3372 if (ret <= 0) {
3373 /* handshake may have not been completed, let's find why */
3374 ret = SSL_get_error(conn->xprt_ctx, ret);
3375 if (ret == SSL_ERROR_WANT_WRITE) {
3376 /* SSL handshake needs to write, L4 connection may not be ready */
3377 __conn_sock_stop_recv(conn);
Willy Tarreaue1f50c42014-01-22 20:02:06 +01003378 __conn_sock_want_send(conn);
3379 fd_cant_send(conn->t.sock.fd);
Emeric Brun674b7432012-11-08 19:21:55 +01003380 return 0;
3381 }
3382 else if (ret == SSL_ERROR_WANT_READ) {
3383 /* handshake may have been completed but we have
3384 * no more data to read.
3385 */
3386 if (!SSL_renegotiate_pending(conn->xprt_ctx)) {
3387 ret = 1;
3388 goto reneg_ok;
3389 }
3390 /* SSL handshake needs to read, L4 connection is ready */
3391 if (conn->flags & CO_FL_WAIT_L4_CONN)
3392 conn->flags &= ~CO_FL_WAIT_L4_CONN;
3393 __conn_sock_stop_send(conn);
Willy Tarreaue1f50c42014-01-22 20:02:06 +01003394 __conn_sock_want_recv(conn);
3395 fd_cant_recv(conn->t.sock.fd);
Emeric Brun674b7432012-11-08 19:21:55 +01003396 return 0;
3397 }
3398 else if (ret == SSL_ERROR_SYSCALL) {
3399 /* if errno is null, then connection was successfully established */
3400 if (!errno && conn->flags & CO_FL_WAIT_L4_CONN)
3401 conn->flags &= ~CO_FL_WAIT_L4_CONN;
Willy Tarreau20879a02012-12-03 16:32:10 +01003402 if (!conn->err_code) {
Emeric Brun29f037d2014-04-25 19:05:36 +02003403 if (!((SSL *)conn->xprt_ctx)->packet_length) {
3404 if (!errno) {
3405 if (conn->xprt_st & SSL_SOCK_RECV_HEARTBEAT)
3406 conn->err_code = CO_ER_SSL_HANDSHAKE_HB;
3407 else
3408 conn->err_code = CO_ER_SSL_EMPTY;
3409 }
3410 else {
3411 if (conn->xprt_st & SSL_SOCK_RECV_HEARTBEAT)
3412 conn->err_code = CO_ER_SSL_HANDSHAKE_HB;
3413 else
3414 conn->err_code = CO_ER_SSL_ABORT;
3415 }
3416 }
3417 else {
3418 if (conn->xprt_st & SSL_SOCK_RECV_HEARTBEAT)
3419 conn->err_code = CO_ER_SSL_HANDSHAKE_HB;
Willy Tarreau20879a02012-12-03 16:32:10 +01003420 else
Emeric Brun29f037d2014-04-25 19:05:36 +02003421 conn->err_code = CO_ER_SSL_HANDSHAKE;
3422 }
Willy Tarreau20879a02012-12-03 16:32:10 +01003423 }
Emeric Brun674b7432012-11-08 19:21:55 +01003424 goto out_error;
3425 }
3426 else {
3427 /* Fail on all other handshake errors */
3428 /* Note: OpenSSL may leave unread bytes in the socket's
3429 * buffer, causing an RST to be emitted upon close() on
3430 * TCP sockets. We first try to drain possibly pending
3431 * data to avoid this as much as possible.
3432 */
Willy Tarreaud85c4852015-03-13 00:40:28 +01003433 conn_sock_drain(conn);
Willy Tarreau20879a02012-12-03 16:32:10 +01003434 if (!conn->err_code)
Willy Tarreauf51c6982014-04-25 20:02:39 +02003435 conn->err_code = (conn->xprt_st & SSL_SOCK_RECV_HEARTBEAT) ?
3436 CO_ER_SSL_KILLED_HB : CO_ER_SSL_HANDSHAKE;
Emeric Brun674b7432012-11-08 19:21:55 +01003437 goto out_error;
3438 }
3439 }
3440 /* read some data: consider handshake completed */
3441 goto reneg_ok;
3442 }
3443
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02003444 ret = SSL_do_handshake(conn->xprt_ctx);
Emeric Brun46591952012-05-18 15:47:34 +02003445 if (ret != 1) {
3446 /* handshake did not complete, let's find why */
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02003447 ret = SSL_get_error(conn->xprt_ctx, ret);
Emeric Brun46591952012-05-18 15:47:34 +02003448
3449 if (ret == SSL_ERROR_WANT_WRITE) {
3450 /* SSL handshake needs to write, L4 connection may not be ready */
3451 __conn_sock_stop_recv(conn);
Willy Tarreaue1f50c42014-01-22 20:02:06 +01003452 __conn_sock_want_send(conn);
3453 fd_cant_send(conn->t.sock.fd);
Emeric Brun46591952012-05-18 15:47:34 +02003454 return 0;
3455 }
3456 else if (ret == SSL_ERROR_WANT_READ) {
3457 /* SSL handshake needs to read, L4 connection is ready */
3458 if (conn->flags & CO_FL_WAIT_L4_CONN)
3459 conn->flags &= ~CO_FL_WAIT_L4_CONN;
3460 __conn_sock_stop_send(conn);
Willy Tarreaue1f50c42014-01-22 20:02:06 +01003461 __conn_sock_want_recv(conn);
3462 fd_cant_recv(conn->t.sock.fd);
Emeric Brun46591952012-05-18 15:47:34 +02003463 return 0;
3464 }
Willy Tarreau89230192012-09-28 20:22:13 +02003465 else if (ret == SSL_ERROR_SYSCALL) {
3466 /* if errno is null, then connection was successfully established */
3467 if (!errno && conn->flags & CO_FL_WAIT_L4_CONN)
3468 conn->flags &= ~CO_FL_WAIT_L4_CONN;
Willy Tarreau20879a02012-12-03 16:32:10 +01003469
Emeric Brun29f037d2014-04-25 19:05:36 +02003470 if (!((SSL *)conn->xprt_ctx)->packet_length) {
3471 if (!errno) {
3472 if (conn->xprt_st & SSL_SOCK_RECV_HEARTBEAT)
3473 conn->err_code = CO_ER_SSL_HANDSHAKE_HB;
3474 else
3475 conn->err_code = CO_ER_SSL_EMPTY;
3476 }
3477 else {
3478 if (conn->xprt_st & SSL_SOCK_RECV_HEARTBEAT)
3479 conn->err_code = CO_ER_SSL_HANDSHAKE_HB;
3480 else
3481 conn->err_code = CO_ER_SSL_ABORT;
3482 }
3483 }
3484 else {
3485 if (conn->xprt_st & SSL_SOCK_RECV_HEARTBEAT)
3486 conn->err_code = CO_ER_SSL_HANDSHAKE_HB;
Willy Tarreau20879a02012-12-03 16:32:10 +01003487 else
Emeric Brun29f037d2014-04-25 19:05:36 +02003488 conn->err_code = CO_ER_SSL_HANDSHAKE;
3489 }
Willy Tarreau89230192012-09-28 20:22:13 +02003490 goto out_error;
3491 }
Emeric Brun46591952012-05-18 15:47:34 +02003492 else {
3493 /* Fail on all other handshake errors */
Willy Tarreau566dc552012-10-19 20:52:18 +02003494 /* Note: OpenSSL may leave unread bytes in the socket's
3495 * buffer, causing an RST to be emitted upon close() on
3496 * TCP sockets. We first try to drain possibly pending
3497 * data to avoid this as much as possible.
3498 */
Willy Tarreaud85c4852015-03-13 00:40:28 +01003499 conn_sock_drain(conn);
Willy Tarreau20879a02012-12-03 16:32:10 +01003500 if (!conn->err_code)
Willy Tarreauf51c6982014-04-25 20:02:39 +02003501 conn->err_code = (conn->xprt_st & SSL_SOCK_RECV_HEARTBEAT) ?
3502 CO_ER_SSL_KILLED_HB : CO_ER_SSL_HANDSHAKE;
Emeric Brun46591952012-05-18 15:47:34 +02003503 goto out_error;
3504 }
3505 }
3506
Emeric Brun674b7432012-11-08 19:21:55 +01003507reneg_ok:
Emeric Brun46591952012-05-18 15:47:34 +02003508 /* Handshake succeeded */
Willy Tarreau0c9c2722014-05-28 12:28:58 +02003509 if (!SSL_session_reused(conn->xprt_ctx)) {
3510 if (objt_server(conn->target)) {
3511 update_freq_ctr(&global.ssl_be_keys_per_sec, 1);
3512 if (global.ssl_be_keys_per_sec.curr_ctr > global.ssl_be_keys_max)
3513 global.ssl_be_keys_max = global.ssl_be_keys_per_sec.curr_ctr;
3514
Emeric Brun46591952012-05-18 15:47:34 +02003515 /* check if session was reused, if not store current session on server for reuse */
Willy Tarreau3fdb3662012-11-12 00:42:33 +01003516 if (objt_server(conn->target)->ssl_ctx.reused_sess)
3517 SSL_SESSION_free(objt_server(conn->target)->ssl_ctx.reused_sess);
Emeric Brun46591952012-05-18 15:47:34 +02003518
Willy Tarreau2a3fb1c2015-02-05 16:47:07 +01003519 if (!(objt_server(conn->target)->ssl_ctx.options & SRV_SSL_O_NO_REUSE))
3520 objt_server(conn->target)->ssl_ctx.reused_sess = SSL_get1_session(conn->xprt_ctx);
Emeric Brun46591952012-05-18 15:47:34 +02003521 }
Willy Tarreau0c9c2722014-05-28 12:28:58 +02003522 else {
3523 update_freq_ctr(&global.ssl_fe_keys_per_sec, 1);
3524 if (global.ssl_fe_keys_per_sec.curr_ctr > global.ssl_fe_keys_max)
3525 global.ssl_fe_keys_max = global.ssl_fe_keys_per_sec.curr_ctr;
3526 }
Emeric Brun46591952012-05-18 15:47:34 +02003527 }
3528
3529 /* The connection is now established at both layers, it's time to leave */
3530 conn->flags &= ~(flag | CO_FL_WAIT_L4_CONN | CO_FL_WAIT_L6_CONN);
3531 return 1;
3532
3533 out_error:
Emeric Brun644cde02012-12-14 11:21:13 +01003534 /* Clear openssl global errors stack */
3535 ERR_clear_error();
3536
Emeric Brun9fa89732012-10-04 17:09:56 +02003537 /* free resumed session if exists */
Willy Tarreau3fdb3662012-11-12 00:42:33 +01003538 if (objt_server(conn->target) && objt_server(conn->target)->ssl_ctx.reused_sess) {
3539 SSL_SESSION_free(objt_server(conn->target)->ssl_ctx.reused_sess);
3540 objt_server(conn->target)->ssl_ctx.reused_sess = NULL;
Emeric Brun9fa89732012-10-04 17:09:56 +02003541 }
3542
Emeric Brun46591952012-05-18 15:47:34 +02003543 /* Fail on all other handshake errors */
3544 conn->flags |= CO_FL_ERROR;
Willy Tarreau20879a02012-12-03 16:32:10 +01003545 if (!conn->err_code)
3546 conn->err_code = CO_ER_SSL_HANDSHAKE;
Emeric Brun46591952012-05-18 15:47:34 +02003547 return 0;
3548}
3549
3550/* Receive up to <count> bytes from connection <conn>'s socket and store them
Willy Tarreauabf08d92014-01-14 11:31:27 +01003551 * into buffer <buf>. Only one call to recv() is performed, unless the
Emeric Brun46591952012-05-18 15:47:34 +02003552 * buffer wraps, in which case a second call may be performed. The connection's
3553 * flags are updated with whatever special event is detected (error, read0,
3554 * empty). The caller is responsible for taking care of those events and
3555 * avoiding the call if inappropriate. The function does not call the
3556 * connection's polling update function, so the caller is responsible for this.
3557 */
3558static int ssl_sock_to_buf(struct connection *conn, struct buffer *buf, int count)
3559{
3560 int ret, done = 0;
Willy Tarreauabf08d92014-01-14 11:31:27 +01003561 int try;
Emeric Brun46591952012-05-18 15:47:34 +02003562
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02003563 if (!conn->xprt_ctx)
Emeric Brun46591952012-05-18 15:47:34 +02003564 goto out_error;
3565
3566 if (conn->flags & CO_FL_HANDSHAKE)
3567 /* a handshake was requested */
3568 return 0;
3569
Willy Tarreauabf08d92014-01-14 11:31:27 +01003570 /* let's realign the buffer to optimize I/O */
3571 if (buffer_empty(buf))
Emeric Brun46591952012-05-18 15:47:34 +02003572 buf->p = buf->data;
Emeric Brun46591952012-05-18 15:47:34 +02003573
3574 /* read the largest possible block. For this, we perform only one call
3575 * to recv() unless the buffer wraps and we exactly fill the first hunk,
3576 * in which case we accept to do it once again. A new attempt is made on
3577 * EINTR too.
3578 */
Willy Tarreau00b0fb92014-01-17 11:09:40 +01003579 while (count > 0) {
Willy Tarreauabf08d92014-01-14 11:31:27 +01003580 /* first check if we have some room after p+i */
3581 try = buf->data + buf->size - (buf->p + buf->i);
3582 /* otherwise continue between data and p-o */
3583 if (try <= 0) {
3584 try = buf->p - (buf->data + buf->o);
3585 if (try <= 0)
3586 break;
3587 }
3588 if (try > count)
3589 try = count;
3590
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02003591 ret = SSL_read(conn->xprt_ctx, bi_end(buf), try);
Emeric Brune1f38db2012-09-03 20:36:47 +02003592 if (conn->flags & CO_FL_ERROR) {
3593 /* CO_FL_ERROR may be set by ssl_sock_infocbk */
Emeric Brun644cde02012-12-14 11:21:13 +01003594 goto out_error;
Emeric Brune1f38db2012-09-03 20:36:47 +02003595 }
Emeric Brun46591952012-05-18 15:47:34 +02003596 if (ret > 0) {
3597 buf->i += ret;
3598 done += ret;
3599 if (ret < try)
3600 break;
3601 count -= ret;
Emeric Brun46591952012-05-18 15:47:34 +02003602 }
3603 else if (ret == 0) {
Emeric Brun644cde02012-12-14 11:21:13 +01003604 ret = SSL_get_error(conn->xprt_ctx, ret);
3605 if (ret != SSL_ERROR_ZERO_RETURN) {
Emeric Brun1c646862012-12-14 12:33:41 +01003606 /* error on protocol or underlying transport */
3607 if ((ret != SSL_ERROR_SYSCALL)
3608 || (errno && (errno != EAGAIN)))
3609 conn->flags |= CO_FL_ERROR;
3610
Emeric Brun644cde02012-12-14 11:21:13 +01003611 /* Clear openssl global errors stack */
3612 ERR_clear_error();
3613 }
Emeric Brun46591952012-05-18 15:47:34 +02003614 goto read0;
3615 }
3616 else {
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02003617 ret = SSL_get_error(conn->xprt_ctx, ret);
Emeric Brun46591952012-05-18 15:47:34 +02003618 if (ret == SSL_ERROR_WANT_WRITE) {
Emeric Brun8af8dd12012-11-08 17:56:20 +01003619 /* handshake is running, and it needs to enable write */
Emeric Brun46591952012-05-18 15:47:34 +02003620 conn->flags |= CO_FL_SSL_WAIT_HS;
Emeric Brun8af8dd12012-11-08 17:56:20 +01003621 __conn_sock_want_send(conn);
Emeric Brun46591952012-05-18 15:47:34 +02003622 break;
3623 }
3624 else if (ret == SSL_ERROR_WANT_READ) {
Emeric Brun282a76a2012-11-08 18:02:56 +01003625 if (SSL_renegotiate_pending(conn->xprt_ctx)) {
3626 /* handshake is running, and it may need to re-enable read */
3627 conn->flags |= CO_FL_SSL_WAIT_HS;
3628 __conn_sock_want_recv(conn);
3629 break;
3630 }
Emeric Brun46591952012-05-18 15:47:34 +02003631 /* we need to poll for retry a read later */
Willy Tarreaue1f50c42014-01-22 20:02:06 +01003632 fd_cant_recv(conn->t.sock.fd);
Emeric Brun46591952012-05-18 15:47:34 +02003633 break;
3634 }
3635 /* otherwise it's a real error */
3636 goto out_error;
3637 }
3638 }
3639 return done;
3640
3641 read0:
3642 conn_sock_read0(conn);
3643 return done;
3644 out_error:
Emeric Brun644cde02012-12-14 11:21:13 +01003645 /* Clear openssl global errors stack */
3646 ERR_clear_error();
3647
Emeric Brun46591952012-05-18 15:47:34 +02003648 conn->flags |= CO_FL_ERROR;
3649 return done;
3650}
3651
3652
3653/* Send all pending bytes from buffer <buf> to connection <conn>'s socket.
Willy Tarreau1049b1f2014-02-02 01:51:17 +01003654 * <flags> may contain some CO_SFL_* flags to hint the system about other
3655 * pending data for example, but this flag is ignored at the moment.
Emeric Brun46591952012-05-18 15:47:34 +02003656 * Only one call to send() is performed, unless the buffer wraps, in which case
3657 * a second call may be performed. The connection's flags are updated with
3658 * whatever special event is detected (error, empty). The caller is responsible
3659 * for taking care of those events and avoiding the call if inappropriate. The
3660 * function does not call the connection's polling update function, so the caller
3661 * is responsible for this.
3662 */
3663static int ssl_sock_from_buf(struct connection *conn, struct buffer *buf, int flags)
3664{
3665 int ret, try, done;
3666
3667 done = 0;
3668
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02003669 if (!conn->xprt_ctx)
Emeric Brun46591952012-05-18 15:47:34 +02003670 goto out_error;
3671
3672 if (conn->flags & CO_FL_HANDSHAKE)
3673 /* a handshake was requested */
3674 return 0;
3675
3676 /* send the largest possible block. For this we perform only one call
3677 * to send() unless the buffer wraps and we exactly fill the first hunk,
3678 * in which case we accept to do it once again.
3679 */
3680 while (buf->o) {
Kevin Hestercad82342013-05-30 15:12:41 -07003681 try = bo_contig_data(buf);
Willy Tarreaubfd59462013-02-21 07:46:09 +01003682
Willy Tarreau7bed9452014-02-02 02:00:24 +01003683 if (!(flags & CO_SFL_STREAMER) &&
Willy Tarreau518cedd2014-02-17 15:43:01 +01003684 !(conn->xprt_st & SSL_SOCK_SEND_UNLIMITED) &&
3685 global.tune.ssl_max_record && try > global.tune.ssl_max_record) {
Willy Tarreaubfd59462013-02-21 07:46:09 +01003686 try = global.tune.ssl_max_record;
Willy Tarreau518cedd2014-02-17 15:43:01 +01003687 }
3688 else {
3689 /* we need to keep the information about the fact that
3690 * we're not limiting the upcoming send(), because if it
3691 * fails, we'll have to retry with at least as many data.
3692 */
3693 conn->xprt_st |= SSL_SOCK_SEND_UNLIMITED;
3694 }
Willy Tarreaubfd59462013-02-21 07:46:09 +01003695
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02003696 ret = SSL_write(conn->xprt_ctx, bo_ptr(buf), try);
Willy Tarreau518cedd2014-02-17 15:43:01 +01003697
Emeric Brune1f38db2012-09-03 20:36:47 +02003698 if (conn->flags & CO_FL_ERROR) {
3699 /* CO_FL_ERROR may be set by ssl_sock_infocbk */
Emeric Brun644cde02012-12-14 11:21:13 +01003700 goto out_error;
Emeric Brune1f38db2012-09-03 20:36:47 +02003701 }
Emeric Brun46591952012-05-18 15:47:34 +02003702 if (ret > 0) {
Willy Tarreau518cedd2014-02-17 15:43:01 +01003703 conn->xprt_st &= ~SSL_SOCK_SEND_UNLIMITED;
3704
Emeric Brun46591952012-05-18 15:47:34 +02003705 buf->o -= ret;
3706 done += ret;
3707
Willy Tarreau5fb38032012-12-16 19:39:09 +01003708 if (likely(buffer_empty(buf)))
Emeric Brun46591952012-05-18 15:47:34 +02003709 /* optimize data alignment in the buffer */
3710 buf->p = buf->data;
3711
3712 /* if the system buffer is full, don't insist */
3713 if (ret < try)
3714 break;
3715 }
3716 else {
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02003717 ret = SSL_get_error(conn->xprt_ctx, ret);
Emeric Brun46591952012-05-18 15:47:34 +02003718 if (ret == SSL_ERROR_WANT_WRITE) {
Emeric Brun282a76a2012-11-08 18:02:56 +01003719 if (SSL_renegotiate_pending(conn->xprt_ctx)) {
3720 /* handshake is running, and it may need to re-enable write */
3721 conn->flags |= CO_FL_SSL_WAIT_HS;
3722 __conn_sock_want_send(conn);
3723 break;
3724 }
Emeric Brun46591952012-05-18 15:47:34 +02003725 /* we need to poll to retry a write later */
Willy Tarreaue1f50c42014-01-22 20:02:06 +01003726 fd_cant_send(conn->t.sock.fd);
Emeric Brun46591952012-05-18 15:47:34 +02003727 break;
3728 }
3729 else if (ret == SSL_ERROR_WANT_READ) {
Emeric Brun8af8dd12012-11-08 17:56:20 +01003730 /* handshake is running, and it needs to enable read */
Emeric Brun46591952012-05-18 15:47:34 +02003731 conn->flags |= CO_FL_SSL_WAIT_HS;
Emeric Brun8af8dd12012-11-08 17:56:20 +01003732 __conn_sock_want_recv(conn);
Emeric Brun46591952012-05-18 15:47:34 +02003733 break;
3734 }
3735 goto out_error;
3736 }
3737 }
3738 return done;
3739
3740 out_error:
Emeric Brun644cde02012-12-14 11:21:13 +01003741 /* Clear openssl global errors stack */
3742 ERR_clear_error();
3743
Emeric Brun46591952012-05-18 15:47:34 +02003744 conn->flags |= CO_FL_ERROR;
3745 return done;
3746}
3747
Emeric Brun46591952012-05-18 15:47:34 +02003748static void ssl_sock_close(struct connection *conn) {
3749
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02003750 if (conn->xprt_ctx) {
3751 SSL_free(conn->xprt_ctx);
3752 conn->xprt_ctx = NULL;
Willy Tarreau403edff2012-09-06 11:58:37 +02003753 sslconns--;
Emeric Brun46591952012-05-18 15:47:34 +02003754 }
Emeric Brun46591952012-05-18 15:47:34 +02003755}
3756
3757/* This function tries to perform a clean shutdown on an SSL connection, and in
3758 * any case, flags the connection as reusable if no handshake was in progress.
3759 */
3760static void ssl_sock_shutw(struct connection *conn, int clean)
3761{
3762 if (conn->flags & CO_FL_HANDSHAKE)
3763 return;
3764 /* no handshake was in progress, try a clean ssl shutdown */
Emeric Brun644cde02012-12-14 11:21:13 +01003765 if (clean && (SSL_shutdown(conn->xprt_ctx) <= 0)) {
3766 /* Clear openssl global errors stack */
3767 ERR_clear_error();
3768 }
Emeric Brun46591952012-05-18 15:47:34 +02003769
3770 /* force flag on ssl to keep session in cache regardless shutdown result */
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02003771 SSL_set_shutdown(conn->xprt_ctx, SSL_SENT_SHUTDOWN);
Emeric Brun46591952012-05-18 15:47:34 +02003772}
3773
Willy Tarreauffc3fcd2012-10-12 20:17:54 +02003774/* used for logging, may be changed for a sample fetch later */
3775const char *ssl_sock_get_cipher_name(struct connection *conn)
3776{
3777 if (!conn->xprt && !conn->xprt_ctx)
3778 return NULL;
3779 return SSL_get_cipher_name(conn->xprt_ctx);
3780}
3781
3782/* used for logging, may be changed for a sample fetch later */
3783const char *ssl_sock_get_proto_version(struct connection *conn)
3784{
3785 if (!conn->xprt && !conn->xprt_ctx)
3786 return NULL;
3787 return SSL_get_version(conn->xprt_ctx);
3788}
3789
Willy Tarreau8d598402012-10-22 17:58:39 +02003790/* Extract a serial from a cert, and copy it to a chunk.
3791 * Returns 1 if serial is found and copied, 0 if no serial found and
3792 * -1 if output is not large enough.
3793 */
3794static int
3795ssl_sock_get_serial(X509 *crt, struct chunk *out)
3796{
3797 ASN1_INTEGER *serial;
3798
3799 serial = X509_get_serialNumber(crt);
3800 if (!serial)
3801 return 0;
3802
3803 if (out->size < serial->length)
3804 return -1;
3805
3806 memcpy(out->str, serial->data, serial->length);
3807 out->len = serial->length;
3808 return 1;
3809}
3810
Emeric Brun43e79582014-10-29 19:03:26 +01003811/* Extract a cert to der, and copy it to a chunk.
3812 * Returns 1 if cert is found and copied, 0 on der convertion failure and
3813 * -1 if output is not large enough.
3814 */
3815static int
3816ssl_sock_crt2der(X509 *crt, struct chunk *out)
3817{
3818 int len;
3819 unsigned char *p = (unsigned char *)out->str;;
3820
3821 len =i2d_X509(crt, NULL);
3822 if (len <= 0)
3823 return 1;
3824
3825 if (out->size < len)
3826 return -1;
3827
3828 i2d_X509(crt,&p);
3829 out->len = len;
3830 return 1;
3831}
3832
Emeric Brunce5ad802012-10-22 14:11:22 +02003833
3834/* Copy Date in ASN1_UTCTIME format in struct chunk out.
3835 * Returns 1 if serial is found and copied, 0 if no valid time found
3836 * and -1 if output is not large enough.
3837 */
3838static int
3839ssl_sock_get_time(ASN1_TIME *tm, struct chunk *out)
3840{
3841 if (tm->type == V_ASN1_GENERALIZEDTIME) {
3842 ASN1_GENERALIZEDTIME *gentm = (ASN1_GENERALIZEDTIME *)tm;
3843
3844 if (gentm->length < 12)
3845 return 0;
3846 if (gentm->data[0] != 0x32 || gentm->data[1] != 0x30)
3847 return 0;
3848 if (out->size < gentm->length-2)
3849 return -1;
3850
3851 memcpy(out->str, gentm->data+2, gentm->length-2);
3852 out->len = gentm->length-2;
3853 return 1;
3854 }
3855 else if (tm->type == V_ASN1_UTCTIME) {
3856 ASN1_UTCTIME *utctm = (ASN1_UTCTIME *)tm;
3857
3858 if (utctm->length < 10)
3859 return 0;
3860 if (utctm->data[0] >= 0x35)
3861 return 0;
3862 if (out->size < utctm->length)
3863 return -1;
3864
3865 memcpy(out->str, utctm->data, utctm->length);
3866 out->len = utctm->length;
3867 return 1;
3868 }
3869
3870 return 0;
3871}
3872
Emeric Brun87855892012-10-17 17:39:35 +02003873/* Extract an entry from a X509_NAME and copy its value to an output chunk.
3874 * Returns 1 if entry found, 0 if entry not found, or -1 if output not large enough.
3875 */
3876static int
3877ssl_sock_get_dn_entry(X509_NAME *a, const struct chunk *entry, int pos, struct chunk *out)
3878{
3879 X509_NAME_ENTRY *ne;
3880 int i, j, n;
3881 int cur = 0;
3882 const char *s;
3883 char tmp[128];
3884
3885 out->len = 0;
3886 for (i = 0; i < sk_X509_NAME_ENTRY_num(a->entries); i++) {
3887 if (pos < 0)
3888 j = (sk_X509_NAME_ENTRY_num(a->entries)-1) - i;
3889 else
3890 j = i;
3891
3892 ne = sk_X509_NAME_ENTRY_value(a->entries, j);
3893 n = OBJ_obj2nid(ne->object);
3894 if ((n == NID_undef) || ((s = OBJ_nid2sn(n)) == NULL)) {
3895 i2t_ASN1_OBJECT(tmp, sizeof(tmp), ne->object);
3896 s = tmp;
3897 }
3898
3899 if (chunk_strcasecmp(entry, s) != 0)
3900 continue;
3901
3902 if (pos < 0)
3903 cur--;
3904 else
3905 cur++;
3906
3907 if (cur != pos)
3908 continue;
3909
3910 if (ne->value->length > out->size)
3911 return -1;
3912
3913 memcpy(out->str, ne->value->data, ne->value->length);
3914 out->len = ne->value->length;
3915 return 1;
3916 }
3917
3918 return 0;
3919
3920}
3921
3922/* Extract and format full DN from a X509_NAME and copy result into a chunk
3923 * Returns 1 if dn entries exits, 0 if no dn entry found or -1 if output is not large enough.
3924 */
3925static int
3926ssl_sock_get_dn_oneline(X509_NAME *a, struct chunk *out)
3927{
3928 X509_NAME_ENTRY *ne;
3929 int i, n, ln;
3930 int l = 0;
3931 const char *s;
3932 char *p;
3933 char tmp[128];
3934
3935 out->len = 0;
3936 p = out->str;
3937 for (i = 0; i < sk_X509_NAME_ENTRY_num(a->entries); i++) {
3938 ne = sk_X509_NAME_ENTRY_value(a->entries, i);
3939 n = OBJ_obj2nid(ne->object);
3940 if ((n == NID_undef) || ((s = OBJ_nid2sn(n)) == NULL)) {
3941 i2t_ASN1_OBJECT(tmp, sizeof(tmp), ne->object);
3942 s = tmp;
3943 }
3944 ln = strlen(s);
3945
3946 l += 1 + ln + 1 + ne->value->length;
3947 if (l > out->size)
3948 return -1;
3949 out->len = l;
3950
3951 *(p++)='/';
3952 memcpy(p, s, ln);
3953 p += ln;
3954 *(p++)='=';
3955 memcpy(p, ne->value->data, ne->value->length);
3956 p += ne->value->length;
3957 }
3958
3959 if (!out->len)
3960 return 0;
3961
3962 return 1;
3963}
3964
David Safb76832014-05-08 23:42:08 -04003965char *ssl_sock_get_version(struct connection *conn)
3966{
3967 if (!ssl_sock_is_ssl(conn))
3968 return NULL;
3969
3970 return (char *)SSL_get_version(conn->xprt_ctx);
3971}
3972
Willy Tarreau63076412015-07-10 11:33:32 +02003973void ssl_sock_set_servername(struct connection *conn, const char *hostname)
3974{
3975#ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME
3976 if (!ssl_sock_is_ssl(conn))
3977 return;
3978
3979 SSL_set_tlsext_host_name(conn->xprt_ctx, hostname);
3980#endif
3981}
3982
Emeric Brun0abf8362014-06-24 18:26:41 +02003983/* Extract peer certificate's common name into the chunk dest
3984 * Returns
3985 * the len of the extracted common name
3986 * or 0 if no CN found in DN
3987 * or -1 on error case (i.e. no peer certificate)
3988 */
3989int ssl_sock_get_remote_common_name(struct connection *conn, struct chunk *dest)
David Safb76832014-05-08 23:42:08 -04003990{
3991 X509 *crt = NULL;
3992 X509_NAME *name;
David Safb76832014-05-08 23:42:08 -04003993 const char find_cn[] = "CN";
3994 const struct chunk find_cn_chunk = {
3995 .str = (char *)&find_cn,
3996 .len = sizeof(find_cn)-1
3997 };
Emeric Brun0abf8362014-06-24 18:26:41 +02003998 int result = -1;
David Safb76832014-05-08 23:42:08 -04003999
4000 if (!ssl_sock_is_ssl(conn))
Emeric Brun0abf8362014-06-24 18:26:41 +02004001 goto out;
David Safb76832014-05-08 23:42:08 -04004002
4003 /* SSL_get_peer_certificate, it increase X509 * ref count */
4004 crt = SSL_get_peer_certificate(conn->xprt_ctx);
4005 if (!crt)
4006 goto out;
4007
4008 name = X509_get_subject_name(crt);
4009 if (!name)
4010 goto out;
David Safb76832014-05-08 23:42:08 -04004011
Emeric Brun0abf8362014-06-24 18:26:41 +02004012 result = ssl_sock_get_dn_entry(name, &find_cn_chunk, 1, dest);
4013out:
David Safb76832014-05-08 23:42:08 -04004014 if (crt)
4015 X509_free(crt);
4016
4017 return result;
4018}
4019
Dave McCowan328fb582014-07-30 10:39:13 -04004020/* returns 1 if client passed a certificate for this session, 0 if not */
4021int ssl_sock_get_cert_used_sess(struct connection *conn)
4022{
4023 X509 *crt = NULL;
4024
4025 if (!ssl_sock_is_ssl(conn))
4026 return 0;
4027
4028 /* SSL_get_peer_certificate, it increase X509 * ref count */
4029 crt = SSL_get_peer_certificate(conn->xprt_ctx);
4030 if (!crt)
4031 return 0;
4032
4033 X509_free(crt);
4034 return 1;
4035}
4036
4037/* returns 1 if client passed a certificate for this connection, 0 if not */
4038int ssl_sock_get_cert_used_conn(struct connection *conn)
David Safb76832014-05-08 23:42:08 -04004039{
4040 if (!ssl_sock_is_ssl(conn))
4041 return 0;
4042
4043 return SSL_SOCK_ST_FL_VERIFY_DONE & conn->xprt_st ? 1 : 0;
4044}
4045
4046/* returns result from SSL verify */
4047unsigned int ssl_sock_get_verify_result(struct connection *conn)
4048{
4049 if (!ssl_sock_is_ssl(conn))
4050 return (unsigned int)X509_V_ERR_APPLICATION_VERIFICATION;
4051
4052 return (unsigned int)SSL_get_verify_result(conn->xprt_ctx);
4053}
4054
Willy Tarreau7875d092012-09-10 08:20:03 +02004055/***** Below are some sample fetching functions for ACL/patterns *****/
4056
Emeric Brune64aef12012-09-21 13:15:06 +02004057/* boolean, returns true if client cert was present */
4058static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02004059smp_fetch_ssl_fc_has_crt(const struct arg *args, struct sample *smp, const char *kw, void *private)
Emeric Brune64aef12012-09-21 13:15:06 +02004060{
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004061 struct connection *conn;
4062
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02004063 conn = objt_conn(smp->sess->origin);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004064 if (!conn || conn->xprt != &ssl_sock)
Emeric Brune64aef12012-09-21 13:15:06 +02004065 return 0;
4066
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004067 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brune64aef12012-09-21 13:15:06 +02004068 smp->flags |= SMP_F_MAY_CHANGE;
4069 return 0;
4070 }
4071
4072 smp->flags = 0;
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02004073 smp->data.type = SMP_T_BOOL;
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02004074 smp->data.u.sint = SSL_SOCK_ST_FL_VERIFY_DONE & conn->xprt_st ? 1 : 0;
Emeric Brune64aef12012-09-21 13:15:06 +02004075
4076 return 1;
4077}
4078
Emeric Brun43e79582014-10-29 19:03:26 +01004079/* binary, returns a certificate in a binary chunk (der/raw).
4080 * The 5th keyword char is used to know if SSL_get_certificate or SSL_get_peer_certificate
4081 * should be use.
4082 */
4083static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02004084smp_fetch_ssl_x_der(const struct arg *args, struct sample *smp, const char *kw, void *private)
Emeric Brun43e79582014-10-29 19:03:26 +01004085{
4086 int cert_peer = (kw[4] == 'c') ? 1 : 0;
4087 X509 *crt = NULL;
4088 int ret = 0;
4089 struct chunk *smp_trash;
4090 struct connection *conn;
4091
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02004092 conn = objt_conn(smp->sess->origin);
Emeric Brun43e79582014-10-29 19:03:26 +01004093 if (!conn || conn->xprt != &ssl_sock)
4094 return 0;
4095
4096 if (!(conn->flags & CO_FL_CONNECTED)) {
4097 smp->flags |= SMP_F_MAY_CHANGE;
4098 return 0;
4099 }
4100
4101 if (cert_peer)
4102 crt = SSL_get_peer_certificate(conn->xprt_ctx);
4103 else
4104 crt = SSL_get_certificate(conn->xprt_ctx);
4105
4106 if (!crt)
4107 goto out;
4108
4109 smp_trash = get_trash_chunk();
4110 if (ssl_sock_crt2der(crt, smp_trash) <= 0)
4111 goto out;
4112
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02004113 smp->data.u.str = *smp_trash;
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02004114 smp->data.type = SMP_T_BIN;
Emeric Brun43e79582014-10-29 19:03:26 +01004115 ret = 1;
4116out:
4117 /* SSL_get_peer_certificate, it increase X509 * ref count */
4118 if (cert_peer && crt)
4119 X509_free(crt);
4120 return ret;
4121}
4122
Emeric Brunba841a12014-04-30 17:05:08 +02004123/* binary, returns serial of certificate in a binary chunk.
4124 * The 5th keyword char is used to know if SSL_get_certificate or SSL_get_peer_certificate
4125 * should be use.
4126 */
Willy Tarreau8d598402012-10-22 17:58:39 +02004127static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02004128smp_fetch_ssl_x_serial(const struct arg *args, struct sample *smp, const char *kw, void *private)
Willy Tarreau8d598402012-10-22 17:58:39 +02004129{
Emeric Brunba841a12014-04-30 17:05:08 +02004130 int cert_peer = (kw[4] == 'c') ? 1 : 0;
Willy Tarreau8d598402012-10-22 17:58:39 +02004131 X509 *crt = NULL;
4132 int ret = 0;
4133 struct chunk *smp_trash;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004134 struct connection *conn;
4135
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02004136 conn = objt_conn(smp->sess->origin);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004137 if (!conn || conn->xprt != &ssl_sock)
Willy Tarreau8d598402012-10-22 17:58:39 +02004138 return 0;
4139
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004140 if (!(conn->flags & CO_FL_CONNECTED)) {
Willy Tarreau8d598402012-10-22 17:58:39 +02004141 smp->flags |= SMP_F_MAY_CHANGE;
4142 return 0;
4143 }
4144
Emeric Brunba841a12014-04-30 17:05:08 +02004145 if (cert_peer)
4146 crt = SSL_get_peer_certificate(conn->xprt_ctx);
4147 else
4148 crt = SSL_get_certificate(conn->xprt_ctx);
4149
Willy Tarreau8d598402012-10-22 17:58:39 +02004150 if (!crt)
4151 goto out;
4152
Willy Tarreau47ca5452012-12-23 20:22:19 +01004153 smp_trash = get_trash_chunk();
Willy Tarreau8d598402012-10-22 17:58:39 +02004154 if (ssl_sock_get_serial(crt, smp_trash) <= 0)
4155 goto out;
4156
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02004157 smp->data.u.str = *smp_trash;
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02004158 smp->data.type = SMP_T_BIN;
Willy Tarreau8d598402012-10-22 17:58:39 +02004159 ret = 1;
4160out:
Emeric Brunba841a12014-04-30 17:05:08 +02004161 /* SSL_get_peer_certificate, it increase X509 * ref count */
4162 if (cert_peer && crt)
Willy Tarreau8d598402012-10-22 17:58:39 +02004163 X509_free(crt);
4164 return ret;
4165}
Emeric Brune64aef12012-09-21 13:15:06 +02004166
Emeric Brunba841a12014-04-30 17:05:08 +02004167/* binary, returns the client certificate's SHA-1 fingerprint (SHA-1 hash of DER-encoded certificate) in a binary chunk.
4168 * The 5th keyword char is used to know if SSL_get_certificate or SSL_get_peer_certificate
4169 * should be use.
4170 */
James Votha051b4a2013-05-14 20:37:59 +02004171static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02004172smp_fetch_ssl_x_sha1(const struct arg *args, struct sample *smp, const char *kw, void *private)
James Votha051b4a2013-05-14 20:37:59 +02004173{
Emeric Brunba841a12014-04-30 17:05:08 +02004174 int cert_peer = (kw[4] == 'c') ? 1 : 0;
James Votha051b4a2013-05-14 20:37:59 +02004175 X509 *crt = NULL;
4176 const EVP_MD *digest;
4177 int ret = 0;
4178 struct chunk *smp_trash;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004179 struct connection *conn;
James Votha051b4a2013-05-14 20:37:59 +02004180
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02004181 conn = objt_conn(smp->sess->origin);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004182 if (!conn || conn->xprt != &ssl_sock)
4183 return 0;
4184
4185 if (!(conn->flags & CO_FL_CONNECTED)) {
James Votha051b4a2013-05-14 20:37:59 +02004186 smp->flags |= SMP_F_MAY_CHANGE;
4187 return 0;
4188 }
4189
Emeric Brunba841a12014-04-30 17:05:08 +02004190 if (cert_peer)
4191 crt = SSL_get_peer_certificate(conn->xprt_ctx);
4192 else
4193 crt = SSL_get_certificate(conn->xprt_ctx);
James Votha051b4a2013-05-14 20:37:59 +02004194 if (!crt)
4195 goto out;
4196
4197 smp_trash = get_trash_chunk();
4198 digest = EVP_sha1();
4199 X509_digest(crt, digest, (unsigned char *)smp_trash->str, (unsigned int *)&smp_trash->len);
4200
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02004201 smp->data.u.str = *smp_trash;
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02004202 smp->data.type = SMP_T_BIN;
James Votha051b4a2013-05-14 20:37:59 +02004203 ret = 1;
4204out:
Emeric Brunba841a12014-04-30 17:05:08 +02004205 /* SSL_get_peer_certificate, it increase X509 * ref count */
4206 if (cert_peer && crt)
James Votha051b4a2013-05-14 20:37:59 +02004207 X509_free(crt);
4208 return ret;
4209}
4210
Emeric Brunba841a12014-04-30 17:05:08 +02004211/* string, returns certificate's notafter date in ASN1_UTCTIME format.
4212 * The 5th keyword char is used to know if SSL_get_certificate or SSL_get_peer_certificate
4213 * should be use.
4214 */
Emeric Brunce5ad802012-10-22 14:11:22 +02004215static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02004216smp_fetch_ssl_x_notafter(const struct arg *args, struct sample *smp, const char *kw, void *private)
Emeric Brunce5ad802012-10-22 14:11:22 +02004217{
Emeric Brunba841a12014-04-30 17:05:08 +02004218 int cert_peer = (kw[4] == 'c') ? 1 : 0;
Emeric Brunce5ad802012-10-22 14:11:22 +02004219 X509 *crt = NULL;
4220 int ret = 0;
4221 struct chunk *smp_trash;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004222 struct connection *conn;
Emeric Brunce5ad802012-10-22 14:11:22 +02004223
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02004224 conn = objt_conn(smp->sess->origin);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004225 if (!conn || conn->xprt != &ssl_sock)
4226 return 0;
4227
4228 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brunce5ad802012-10-22 14:11:22 +02004229 smp->flags |= SMP_F_MAY_CHANGE;
4230 return 0;
4231 }
4232
Emeric Brunba841a12014-04-30 17:05:08 +02004233 if (cert_peer)
4234 crt = SSL_get_peer_certificate(conn->xprt_ctx);
4235 else
4236 crt = SSL_get_certificate(conn->xprt_ctx);
Emeric Brunce5ad802012-10-22 14:11:22 +02004237 if (!crt)
4238 goto out;
4239
Willy Tarreau47ca5452012-12-23 20:22:19 +01004240 smp_trash = get_trash_chunk();
Emeric Brunce5ad802012-10-22 14:11:22 +02004241 if (ssl_sock_get_time(X509_get_notAfter(crt), smp_trash) <= 0)
4242 goto out;
4243
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02004244 smp->data.u.str = *smp_trash;
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02004245 smp->data.type = SMP_T_STR;
Emeric Brunce5ad802012-10-22 14:11:22 +02004246 ret = 1;
4247out:
Emeric Brunba841a12014-04-30 17:05:08 +02004248 /* SSL_get_peer_certificate, it increase X509 * ref count */
4249 if (cert_peer && crt)
Emeric Brunce5ad802012-10-22 14:11:22 +02004250 X509_free(crt);
4251 return ret;
4252}
4253
Emeric Brunba841a12014-04-30 17:05:08 +02004254/* string, returns a string of a formatted full dn \C=..\O=..\OU=.. \CN=.. of certificate's issuer
4255 * The 5th keyword char is used to know if SSL_get_certificate or SSL_get_peer_certificate
4256 * should be use.
4257 */
Emeric Brun87855892012-10-17 17:39:35 +02004258static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02004259smp_fetch_ssl_x_i_dn(const struct arg *args, struct sample *smp, const char *kw, void *private)
Emeric Brun87855892012-10-17 17:39:35 +02004260{
Emeric Brunba841a12014-04-30 17:05:08 +02004261 int cert_peer = (kw[4] == 'c') ? 1 : 0;
Emeric Brun87855892012-10-17 17:39:35 +02004262 X509 *crt = NULL;
4263 X509_NAME *name;
4264 int ret = 0;
4265 struct chunk *smp_trash;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004266 struct connection *conn;
Emeric Brun87855892012-10-17 17:39:35 +02004267
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02004268 conn = objt_conn(smp->sess->origin);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004269 if (!conn || conn->xprt != &ssl_sock)
4270 return 0;
4271
4272 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brun87855892012-10-17 17:39:35 +02004273 smp->flags |= SMP_F_MAY_CHANGE;
4274 return 0;
4275 }
4276
Emeric Brunba841a12014-04-30 17:05:08 +02004277 if (cert_peer)
4278 crt = SSL_get_peer_certificate(conn->xprt_ctx);
4279 else
4280 crt = SSL_get_certificate(conn->xprt_ctx);
Emeric Brun87855892012-10-17 17:39:35 +02004281 if (!crt)
4282 goto out;
4283
4284 name = X509_get_issuer_name(crt);
4285 if (!name)
4286 goto out;
4287
Willy Tarreau47ca5452012-12-23 20:22:19 +01004288 smp_trash = get_trash_chunk();
Emeric Brun87855892012-10-17 17:39:35 +02004289 if (args && args[0].type == ARGT_STR) {
4290 int pos = 1;
4291
4292 if (args[1].type == ARGT_SINT)
4293 pos = args[1].data.sint;
Emeric Brun87855892012-10-17 17:39:35 +02004294
4295 if (ssl_sock_get_dn_entry(name, &args[0].data.str, pos, smp_trash) <= 0)
4296 goto out;
4297 }
4298 else if (ssl_sock_get_dn_oneline(name, smp_trash) <= 0)
4299 goto out;
4300
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02004301 smp->data.type = SMP_T_STR;
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02004302 smp->data.u.str = *smp_trash;
Emeric Brun87855892012-10-17 17:39:35 +02004303 ret = 1;
4304out:
Emeric Brunba841a12014-04-30 17:05:08 +02004305 /* SSL_get_peer_certificate, it increase X509 * ref count */
4306 if (cert_peer && crt)
Emeric Brun87855892012-10-17 17:39:35 +02004307 X509_free(crt);
4308 return ret;
4309}
4310
Emeric Brunba841a12014-04-30 17:05:08 +02004311/* string, returns notbefore date in ASN1_UTCTIME format.
4312 * The 5th keyword char is used to know if SSL_get_certificate or SSL_get_peer_certificate
4313 * should be use.
4314 */
Emeric Brunce5ad802012-10-22 14:11:22 +02004315static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02004316smp_fetch_ssl_x_notbefore(const struct arg *args, struct sample *smp, const char *kw, void *private)
Emeric Brunce5ad802012-10-22 14:11:22 +02004317{
Emeric Brunba841a12014-04-30 17:05:08 +02004318 int cert_peer = (kw[4] == 'c') ? 1 : 0;
Emeric Brunce5ad802012-10-22 14:11:22 +02004319 X509 *crt = NULL;
4320 int ret = 0;
4321 struct chunk *smp_trash;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004322 struct connection *conn;
4323
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02004324 conn = objt_conn(smp->sess->origin);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004325 if (!conn || conn->xprt != &ssl_sock)
Emeric Brunce5ad802012-10-22 14:11:22 +02004326 return 0;
4327
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004328 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brunce5ad802012-10-22 14:11:22 +02004329 smp->flags |= SMP_F_MAY_CHANGE;
4330 return 0;
4331 }
4332
Emeric Brunba841a12014-04-30 17:05:08 +02004333 if (cert_peer)
4334 crt = SSL_get_peer_certificate(conn->xprt_ctx);
4335 else
4336 crt = SSL_get_certificate(conn->xprt_ctx);
Emeric Brunce5ad802012-10-22 14:11:22 +02004337 if (!crt)
4338 goto out;
4339
Willy Tarreau47ca5452012-12-23 20:22:19 +01004340 smp_trash = get_trash_chunk();
Emeric Brunce5ad802012-10-22 14:11:22 +02004341 if (ssl_sock_get_time(X509_get_notBefore(crt), smp_trash) <= 0)
4342 goto out;
4343
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02004344 smp->data.u.str = *smp_trash;
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02004345 smp->data.type = SMP_T_STR;
Emeric Brunce5ad802012-10-22 14:11:22 +02004346 ret = 1;
4347out:
Emeric Brunba841a12014-04-30 17:05:08 +02004348 /* SSL_get_peer_certificate, it increase X509 * ref count */
4349 if (cert_peer && crt)
Emeric Brunce5ad802012-10-22 14:11:22 +02004350 X509_free(crt);
4351 return ret;
4352}
4353
Emeric Brunba841a12014-04-30 17:05:08 +02004354/* string, returns a string of a formatted full dn \C=..\O=..\OU=.. \CN=.. of certificate's subject
4355 * The 5th keyword char is used to know if SSL_get_certificate or SSL_get_peer_certificate
4356 * should be use.
4357 */
Emeric Brun87855892012-10-17 17:39:35 +02004358static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02004359smp_fetch_ssl_x_s_dn(const struct arg *args, struct sample *smp, const char *kw, void *private)
Emeric Brun87855892012-10-17 17:39:35 +02004360{
Emeric Brunba841a12014-04-30 17:05:08 +02004361 int cert_peer = (kw[4] == 'c') ? 1 : 0;
Emeric Brun87855892012-10-17 17:39:35 +02004362 X509 *crt = NULL;
4363 X509_NAME *name;
4364 int ret = 0;
4365 struct chunk *smp_trash;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004366 struct connection *conn;
Emeric Brun87855892012-10-17 17:39:35 +02004367
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02004368 conn = objt_conn(smp->sess->origin);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004369 if (!conn || conn->xprt != &ssl_sock)
4370 return 0;
4371
4372 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brun87855892012-10-17 17:39:35 +02004373 smp->flags |= SMP_F_MAY_CHANGE;
4374 return 0;
4375 }
4376
Emeric Brunba841a12014-04-30 17:05:08 +02004377 if (cert_peer)
4378 crt = SSL_get_peer_certificate(conn->xprt_ctx);
4379 else
4380 crt = SSL_get_certificate(conn->xprt_ctx);
Emeric Brun87855892012-10-17 17:39:35 +02004381 if (!crt)
4382 goto out;
4383
4384 name = X509_get_subject_name(crt);
4385 if (!name)
4386 goto out;
4387
Willy Tarreau47ca5452012-12-23 20:22:19 +01004388 smp_trash = get_trash_chunk();
Emeric Brun87855892012-10-17 17:39:35 +02004389 if (args && args[0].type == ARGT_STR) {
4390 int pos = 1;
4391
4392 if (args[1].type == ARGT_SINT)
4393 pos = args[1].data.sint;
Emeric Brun87855892012-10-17 17:39:35 +02004394
4395 if (ssl_sock_get_dn_entry(name, &args[0].data.str, pos, smp_trash) <= 0)
4396 goto out;
4397 }
4398 else if (ssl_sock_get_dn_oneline(name, smp_trash) <= 0)
4399 goto out;
4400
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02004401 smp->data.type = SMP_T_STR;
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02004402 smp->data.u.str = *smp_trash;
Emeric Brun87855892012-10-17 17:39:35 +02004403 ret = 1;
4404out:
Emeric Brunba841a12014-04-30 17:05:08 +02004405 /* SSL_get_peer_certificate, it increase X509 * ref count */
4406 if (cert_peer && crt)
Emeric Brun87855892012-10-17 17:39:35 +02004407 X509_free(crt);
4408 return ret;
4409}
Emeric Brun9143d372012-12-20 15:44:16 +01004410
4411/* integer, returns true if current session use a client certificate */
4412static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02004413smp_fetch_ssl_c_used(const struct arg *args, struct sample *smp, const char *kw, void *private)
Emeric Brun9143d372012-12-20 15:44:16 +01004414{
4415 X509 *crt;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004416 struct connection *conn;
Emeric Brun9143d372012-12-20 15:44:16 +01004417
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02004418 conn = objt_conn(smp->sess->origin);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004419 if (!conn || conn->xprt != &ssl_sock)
4420 return 0;
4421
4422 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brun9143d372012-12-20 15:44:16 +01004423 smp->flags |= SMP_F_MAY_CHANGE;
4424 return 0;
4425 }
4426
4427 /* SSL_get_peer_certificate returns a ptr on allocated X509 struct */
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004428 crt = SSL_get_peer_certificate(conn->xprt_ctx);
Emeric Brun9143d372012-12-20 15:44:16 +01004429 if (crt) {
4430 X509_free(crt);
4431 }
4432
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02004433 smp->data.type = SMP_T_BOOL;
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02004434 smp->data.u.sint = (crt != NULL);
Emeric Brun9143d372012-12-20 15:44:16 +01004435 return 1;
4436}
4437
Emeric Brunba841a12014-04-30 17:05:08 +02004438/* integer, returns the certificate version
4439 * The 5th keyword char is used to know if SSL_get_certificate or SSL_get_peer_certificate
4440 * should be use.
4441 */
Emeric Bruna7359fd2012-10-17 15:03:11 +02004442static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02004443smp_fetch_ssl_x_version(const struct arg *args, struct sample *smp, const char *kw, void *private)
Emeric Bruna7359fd2012-10-17 15:03:11 +02004444{
Emeric Brunba841a12014-04-30 17:05:08 +02004445 int cert_peer = (kw[4] == 'c') ? 1 : 0;
Emeric Bruna7359fd2012-10-17 15:03:11 +02004446 X509 *crt;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004447 struct connection *conn;
4448
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02004449 conn = objt_conn(smp->sess->origin);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004450 if (!conn || conn->xprt != &ssl_sock)
Emeric Bruna7359fd2012-10-17 15:03:11 +02004451 return 0;
4452
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004453 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Bruna7359fd2012-10-17 15:03:11 +02004454 smp->flags |= SMP_F_MAY_CHANGE;
4455 return 0;
4456 }
4457
Emeric Brunba841a12014-04-30 17:05:08 +02004458 if (cert_peer)
4459 crt = SSL_get_peer_certificate(conn->xprt_ctx);
4460 else
4461 crt = SSL_get_certificate(conn->xprt_ctx);
Emeric Bruna7359fd2012-10-17 15:03:11 +02004462 if (!crt)
4463 return 0;
4464
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02004465 smp->data.u.sint = (unsigned int)(1 + X509_get_version(crt));
Emeric Brunba841a12014-04-30 17:05:08 +02004466 /* SSL_get_peer_certificate increase X509 * ref count */
4467 if (cert_peer)
4468 X509_free(crt);
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02004469 smp->data.type = SMP_T_SINT;
Emeric Bruna7359fd2012-10-17 15:03:11 +02004470
4471 return 1;
4472}
4473
Emeric Brunba841a12014-04-30 17:05:08 +02004474/* string, returns the certificate's signature algorithm.
4475 * The 5th keyword char is used to know if SSL_get_certificate or SSL_get_peer_certificate
4476 * should be use.
4477 */
Emeric Brun7f56e742012-10-19 18:15:40 +02004478static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02004479smp_fetch_ssl_x_sig_alg(const struct arg *args, struct sample *smp, const char *kw, void *private)
Emeric Brun7f56e742012-10-19 18:15:40 +02004480{
Emeric Brunba841a12014-04-30 17:05:08 +02004481 int cert_peer = (kw[4] == 'c') ? 1 : 0;
Emeric Brun7f56e742012-10-19 18:15:40 +02004482 X509 *crt;
4483 int nid;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004484 struct connection *conn;
Emeric Brun7f56e742012-10-19 18:15:40 +02004485
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02004486 conn = objt_conn(smp->sess->origin);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004487 if (!conn || conn->xprt != &ssl_sock)
4488 return 0;
4489
4490 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brun7f56e742012-10-19 18:15:40 +02004491 smp->flags |= SMP_F_MAY_CHANGE;
4492 return 0;
4493 }
4494
Emeric Brunba841a12014-04-30 17:05:08 +02004495 if (cert_peer)
4496 crt = SSL_get_peer_certificate(conn->xprt_ctx);
4497 else
4498 crt = SSL_get_certificate(conn->xprt_ctx);
Emeric Brun7f56e742012-10-19 18:15:40 +02004499 if (!crt)
4500 return 0;
4501
4502 nid = OBJ_obj2nid((ASN1_OBJECT *)(crt->cert_info->signature->algorithm));
4503
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02004504 smp->data.u.str.str = (char *)OBJ_nid2sn(nid);
4505 if (!smp->data.u.str.str) {
Emeric Brunba841a12014-04-30 17:05:08 +02004506 /* SSL_get_peer_certificate increase X509 * ref count */
4507 if (cert_peer)
4508 X509_free(crt);
Emeric Brun7f56e742012-10-19 18:15:40 +02004509 return 0;
Emeric Brun9bf3ba22013-10-07 14:31:44 +02004510 }
Emeric Brun7f56e742012-10-19 18:15:40 +02004511
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02004512 smp->data.type = SMP_T_STR;
Thierry FOURNIER7654c9f2013-12-17 00:20:33 +01004513 smp->flags |= SMP_F_CONST;
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02004514 smp->data.u.str.len = strlen(smp->data.u.str.str);
Emeric Brunba841a12014-04-30 17:05:08 +02004515 /* SSL_get_peer_certificate increase X509 * ref count */
4516 if (cert_peer)
4517 X509_free(crt);
Emeric Brun7f56e742012-10-19 18:15:40 +02004518
4519 return 1;
4520}
4521
Emeric Brunba841a12014-04-30 17:05:08 +02004522/* string, returns the certificate's key algorithm.
4523 * The 5th keyword char is used to know if SSL_get_certificate or SSL_get_peer_certificate
4524 * should be use.
4525 */
Emeric Brun521a0112012-10-22 12:22:55 +02004526static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02004527smp_fetch_ssl_x_key_alg(const struct arg *args, struct sample *smp, const char *kw, void *private)
Emeric Brun521a0112012-10-22 12:22:55 +02004528{
Emeric Brunba841a12014-04-30 17:05:08 +02004529 int cert_peer = (kw[4] == 'c') ? 1 : 0;
Emeric Brun521a0112012-10-22 12:22:55 +02004530 X509 *crt;
4531 int nid;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004532 struct connection *conn;
Emeric Brun521a0112012-10-22 12:22:55 +02004533
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02004534 conn = objt_conn(smp->sess->origin);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004535 if (!conn || conn->xprt != &ssl_sock)
4536 return 0;
4537
4538 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brun521a0112012-10-22 12:22:55 +02004539 smp->flags |= SMP_F_MAY_CHANGE;
4540 return 0;
4541 }
4542
Emeric Brunba841a12014-04-30 17:05:08 +02004543 if (cert_peer)
4544 crt = SSL_get_peer_certificate(conn->xprt_ctx);
4545 else
4546 crt = SSL_get_certificate(conn->xprt_ctx);
Emeric Brun521a0112012-10-22 12:22:55 +02004547 if (!crt)
4548 return 0;
4549
4550 nid = OBJ_obj2nid((ASN1_OBJECT *)(crt->cert_info->key->algor->algorithm));
4551
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02004552 smp->data.u.str.str = (char *)OBJ_nid2sn(nid);
4553 if (!smp->data.u.str.str) {
Emeric Brunba841a12014-04-30 17:05:08 +02004554 /* SSL_get_peer_certificate increase X509 * ref count */
4555 if (cert_peer)
4556 X509_free(crt);
Emeric Brun521a0112012-10-22 12:22:55 +02004557 return 0;
Emeric Brun9bf3ba22013-10-07 14:31:44 +02004558 }
Emeric Brun521a0112012-10-22 12:22:55 +02004559
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02004560 smp->data.type = SMP_T_STR;
Thierry FOURNIER7654c9f2013-12-17 00:20:33 +01004561 smp->flags |= SMP_F_CONST;
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02004562 smp->data.u.str.len = strlen(smp->data.u.str.str);
Emeric Brunba841a12014-04-30 17:05:08 +02004563 if (cert_peer)
4564 X509_free(crt);
Emeric Brun521a0112012-10-22 12:22:55 +02004565
4566 return 1;
4567}
4568
Emeric Brun645ae792014-04-30 14:21:06 +02004569/* boolean, returns true if front conn. transport layer is SSL.
4570 * This function is also usable on backend conn if the fetch keyword 5th
4571 * char is 'b'.
4572 */
Willy Tarreau7875d092012-09-10 08:20:03 +02004573static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02004574smp_fetch_ssl_fc(const struct arg *args, struct sample *smp, const char *kw, void *private)
Willy Tarreau7875d092012-09-10 08:20:03 +02004575{
Willy Tarreaue237fe12016-03-10 17:05:28 +01004576 struct connection *conn = objt_conn((kw[4] != 'b') ? smp->sess->origin :
4577 smp->strm ? smp->strm->si[1].end : NULL);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004578
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02004579 smp->data.type = SMP_T_BOOL;
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02004580 smp->data.u.sint = (conn && conn->xprt == &ssl_sock);
Willy Tarreau7875d092012-09-10 08:20:03 +02004581 return 1;
4582}
4583
Emeric Brun2525b6b2012-10-18 15:59:43 +02004584/* boolean, returns true if client present a SNI */
Willy Tarreau7875d092012-09-10 08:20:03 +02004585static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02004586smp_fetch_ssl_fc_has_sni(const struct arg *args, struct sample *smp, const char *kw, void *private)
Willy Tarreau7875d092012-09-10 08:20:03 +02004587{
4588#ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02004589 struct connection *conn = objt_conn(smp->sess->origin);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004590
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02004591 smp->data.type = SMP_T_BOOL;
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02004592 smp->data.u.sint = (conn && conn->xprt == &ssl_sock) &&
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004593 conn->xprt_ctx &&
4594 SSL_get_servername(conn->xprt_ctx, TLSEXT_NAMETYPE_host_name) != NULL;
Willy Tarreau7875d092012-09-10 08:20:03 +02004595 return 1;
4596#else
4597 return 0;
4598#endif
4599}
4600
Nenad Merdanovic26ea8222015-05-18 02:28:57 +02004601/* boolean, returns true if client session has been resumed */
4602static int
4603smp_fetch_ssl_fc_is_resumed(const struct arg *args, struct sample *smp, const char *kw, void *private)
4604{
4605 struct connection *conn = objt_conn(smp->sess->origin);
4606
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02004607 smp->data.type = SMP_T_BOOL;
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02004608 smp->data.u.sint = (conn && conn->xprt == &ssl_sock) &&
Nenad Merdanovic26ea8222015-05-18 02:28:57 +02004609 conn->xprt_ctx &&
4610 SSL_session_reused(conn->xprt_ctx);
4611 return 1;
4612}
4613
Emeric Brun645ae792014-04-30 14:21:06 +02004614/* string, returns the used cipher if front conn. transport layer is SSL.
4615 * This function is also usable on backend conn if the fetch keyword 5th
4616 * char is 'b'.
4617 */
Emeric Brun589fcad2012-10-16 14:13:26 +02004618static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02004619smp_fetch_ssl_fc_cipher(const struct arg *args, struct sample *smp, const char *kw, void *private)
Emeric Brun589fcad2012-10-16 14:13:26 +02004620{
Willy Tarreaue237fe12016-03-10 17:05:28 +01004621 struct connection *conn = objt_conn((kw[4] != 'b') ? smp->sess->origin :
4622 smp->strm ? smp->strm->si[1].end : NULL);
Emeric Brun589fcad2012-10-16 14:13:26 +02004623
Willy Tarreaube508f12016-03-10 11:47:01 +01004624 smp->flags = 0;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004625 if (!conn || !conn->xprt_ctx || conn->xprt != &ssl_sock)
Emeric Brun589fcad2012-10-16 14:13:26 +02004626 return 0;
4627
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02004628 smp->data.u.str.str = (char *)SSL_get_cipher_name(conn->xprt_ctx);
4629 if (!smp->data.u.str.str)
Emeric Brun589fcad2012-10-16 14:13:26 +02004630 return 0;
4631
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02004632 smp->data.type = SMP_T_STR;
Thierry FOURNIER7654c9f2013-12-17 00:20:33 +01004633 smp->flags |= SMP_F_CONST;
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02004634 smp->data.u.str.len = strlen(smp->data.u.str.str);
Emeric Brun589fcad2012-10-16 14:13:26 +02004635
4636 return 1;
4637}
4638
Emeric Brun645ae792014-04-30 14:21:06 +02004639/* integer, returns the algoritm's keysize if front conn. transport layer
4640 * is SSL.
4641 * This function is also usable on backend conn if the fetch keyword 5th
4642 * char is 'b'.
4643 */
Emeric Brun589fcad2012-10-16 14:13:26 +02004644static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02004645smp_fetch_ssl_fc_alg_keysize(const struct arg *args, struct sample *smp, const char *kw, void *private)
Emeric Brun589fcad2012-10-16 14:13:26 +02004646{
Willy Tarreaue237fe12016-03-10 17:05:28 +01004647 struct connection *conn = objt_conn((kw[4] != 'b') ? smp->sess->origin :
4648 smp->strm ? smp->strm->si[1].end : NULL);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004649
Willy Tarreaue237fe12016-03-10 17:05:28 +01004650 int sint;
Willy Tarreaube508f12016-03-10 11:47:01 +01004651
Emeric Brun589fcad2012-10-16 14:13:26 +02004652 smp->flags = 0;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004653 if (!conn || !conn->xprt_ctx || conn->xprt != &ssl_sock)
Emeric Brun589fcad2012-10-16 14:13:26 +02004654 return 0;
4655
Thierry FOURNIER07ee64e2015-07-06 23:43:03 +02004656 if (!SSL_get_cipher_bits(conn->xprt_ctx, &sint))
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004657 return 0;
4658
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02004659 smp->data.u.sint = sint;
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02004660 smp->data.type = SMP_T_SINT;
Emeric Brun589fcad2012-10-16 14:13:26 +02004661
4662 return 1;
4663}
4664
Emeric Brun645ae792014-04-30 14:21:06 +02004665/* integer, returns the used keysize if front conn. transport layer is SSL.
4666 * This function is also usable on backend conn if the fetch keyword 5th
4667 * char is 'b'.
4668 */
Emeric Brun589fcad2012-10-16 14:13:26 +02004669static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02004670smp_fetch_ssl_fc_use_keysize(const struct arg *args, struct sample *smp, const char *kw, void *private)
Emeric Brun589fcad2012-10-16 14:13:26 +02004671{
Willy Tarreaue237fe12016-03-10 17:05:28 +01004672 struct connection *conn = objt_conn((kw[4] != 'b') ? smp->sess->origin :
4673 smp->strm ? smp->strm->si[1].end : NULL);
Willy Tarreaube508f12016-03-10 11:47:01 +01004674
Emeric Brun589fcad2012-10-16 14:13:26 +02004675 smp->flags = 0;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004676 if (!conn || !conn->xprt_ctx || conn->xprt != &ssl_sock)
4677 return 0;
4678
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02004679 smp->data.u.sint = (unsigned int)SSL_get_cipher_bits(conn->xprt_ctx, NULL);
4680 if (!smp->data.u.sint)
Emeric Brun589fcad2012-10-16 14:13:26 +02004681 return 0;
4682
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02004683 smp->data.type = SMP_T_SINT;
Emeric Brun589fcad2012-10-16 14:13:26 +02004684
4685 return 1;
4686}
4687
Willy Tarreau6c9a3d52012-10-18 18:57:14 +02004688#ifdef OPENSSL_NPN_NEGOTIATED
Willy Tarreau7875d092012-09-10 08:20:03 +02004689static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02004690smp_fetch_ssl_fc_npn(const struct arg *args, struct sample *smp, const char *kw, void *private)
Willy Tarreaua33c6542012-10-15 13:19:06 +02004691{
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004692 struct connection *conn;
4693
Thierry FOURNIER7654c9f2013-12-17 00:20:33 +01004694 smp->flags = SMP_F_CONST;
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02004695 smp->data.type = SMP_T_STR;
Willy Tarreaua33c6542012-10-15 13:19:06 +02004696
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02004697 conn = objt_conn(smp->sess->origin);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004698 if (!conn || !conn->xprt_ctx || conn->xprt != &ssl_sock)
4699 return 0;
4700
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02004701 smp->data.u.str.str = NULL;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004702 SSL_get0_next_proto_negotiated(conn->xprt_ctx,
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02004703 (const unsigned char **)&smp->data.u.str.str, (unsigned *)&smp->data.u.str.len);
Willy Tarreaua33c6542012-10-15 13:19:06 +02004704
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02004705 if (!smp->data.u.str.str)
Willy Tarreaua33c6542012-10-15 13:19:06 +02004706 return 0;
4707
4708 return 1;
Willy Tarreaua33c6542012-10-15 13:19:06 +02004709}
Willy Tarreau6c9a3d52012-10-18 18:57:14 +02004710#endif
Willy Tarreaua33c6542012-10-15 13:19:06 +02004711
Dirkjan Bussink48f1c4e2014-02-13 12:29:42 +01004712#ifdef TLSEXT_TYPE_application_layer_protocol_negotiation
Willy Tarreauab861d32013-04-02 02:30:41 +02004713static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02004714smp_fetch_ssl_fc_alpn(const struct arg *args, struct sample *smp, const char *kw, void *private)
Willy Tarreauab861d32013-04-02 02:30:41 +02004715{
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004716 struct connection *conn;
4717
Thierry FOURNIER7654c9f2013-12-17 00:20:33 +01004718 smp->flags = SMP_F_CONST;
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02004719 smp->data.type = SMP_T_STR;
Willy Tarreauab861d32013-04-02 02:30:41 +02004720
Willy Tarreaue26bf052015-05-12 10:30:12 +02004721 conn = objt_conn(smp->sess->origin);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004722 if (!conn || !conn->xprt_ctx || conn->xprt != &ssl_sock)
Willy Tarreauab861d32013-04-02 02:30:41 +02004723 return 0;
4724
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02004725 smp->data.u.str.str = NULL;
Dirkjan Bussink48f1c4e2014-02-13 12:29:42 +01004726 SSL_get0_alpn_selected(conn->xprt_ctx,
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02004727 (const unsigned char **)&smp->data.u.str.str, (unsigned *)&smp->data.u.str.len);
Willy Tarreauab861d32013-04-02 02:30:41 +02004728
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02004729 if (!smp->data.u.str.str)
Willy Tarreauab861d32013-04-02 02:30:41 +02004730 return 0;
4731
4732 return 1;
4733}
4734#endif
4735
Emeric Brun645ae792014-04-30 14:21:06 +02004736/* string, returns the used protocol if front conn. transport layer is SSL.
4737 * This function is also usable on backend conn if the fetch keyword 5th
4738 * char is 'b'.
4739 */
Willy Tarreaua33c6542012-10-15 13:19:06 +02004740static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02004741smp_fetch_ssl_fc_protocol(const struct arg *args, struct sample *smp, const char *kw, void *private)
Emeric Brun589fcad2012-10-16 14:13:26 +02004742{
Willy Tarreaue237fe12016-03-10 17:05:28 +01004743 struct connection *conn = objt_conn((kw[4] != 'b') ? smp->sess->origin :
4744 smp->strm ? smp->strm->si[1].end : NULL);
Willy Tarreaube508f12016-03-10 11:47:01 +01004745
Emeric Brun589fcad2012-10-16 14:13:26 +02004746 smp->flags = 0;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004747 if (!conn || !conn->xprt_ctx || conn->xprt != &ssl_sock)
4748 return 0;
4749
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02004750 smp->data.u.str.str = (char *)SSL_get_version(conn->xprt_ctx);
4751 if (!smp->data.u.str.str)
Emeric Brun589fcad2012-10-16 14:13:26 +02004752 return 0;
4753
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02004754 smp->data.type = SMP_T_STR;
Thierry FOURNIER7654c9f2013-12-17 00:20:33 +01004755 smp->flags = SMP_F_CONST;
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02004756 smp->data.u.str.len = strlen(smp->data.u.str.str);
Emeric Brun589fcad2012-10-16 14:13:26 +02004757
4758 return 1;
4759}
4760
Willy Tarreau87b09662015-04-03 00:22:06 +02004761/* binary, returns the SSL stream id if front conn. transport layer is SSL.
Emeric Brun645ae792014-04-30 14:21:06 +02004762 * This function is also usable on backend conn if the fetch keyword 5th
4763 * char is 'b'.
4764 */
Emeric Brun589fcad2012-10-16 14:13:26 +02004765static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02004766smp_fetch_ssl_fc_session_id(const struct arg *args, struct sample *smp, const char *kw, void *private)
Emeric Brunfe68f682012-10-16 14:59:28 +02004767{
4768#if OPENSSL_VERSION_NUMBER > 0x0090800fL
Willy Tarreaue237fe12016-03-10 17:05:28 +01004769 struct connection *conn = objt_conn((kw[4] != 'b') ? smp->sess->origin :
4770 smp->strm ? smp->strm->si[1].end : NULL);
Emeric Brunfe68f682012-10-16 14:59:28 +02004771
Willy Tarreaue237fe12016-03-10 17:05:28 +01004772 SSL_SESSION *ssl_sess;
Willy Tarreaube508f12016-03-10 11:47:01 +01004773
Thierry FOURNIER7654c9f2013-12-17 00:20:33 +01004774 smp->flags = SMP_F_CONST;
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02004775 smp->data.type = SMP_T_BIN;
Emeric Brunfe68f682012-10-16 14:59:28 +02004776
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004777 if (!conn || !conn->xprt_ctx || conn->xprt != &ssl_sock)
4778 return 0;
4779
Willy Tarreau192252e2015-04-04 01:47:55 +02004780 ssl_sess = SSL_get_session(conn->xprt_ctx);
4781 if (!ssl_sess)
Emeric Brunfe68f682012-10-16 14:59:28 +02004782 return 0;
4783
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02004784 smp->data.u.str.str = (char *)SSL_SESSION_get_id(ssl_sess, (unsigned int *)&smp->data.u.str.len);
4785 if (!smp->data.u.str.str || !smp->data.u.str.len)
Emeric Brunfe68f682012-10-16 14:59:28 +02004786 return 0;
4787
4788 return 1;
4789#else
4790 return 0;
4791#endif
4792}
4793
4794static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02004795smp_fetch_ssl_fc_sni(const struct arg *args, struct sample *smp, const char *kw, void *private)
Willy Tarreau7875d092012-09-10 08:20:03 +02004796{
4797#ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004798 struct connection *conn;
4799
Thierry FOURNIER7654c9f2013-12-17 00:20:33 +01004800 smp->flags = SMP_F_CONST;
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02004801 smp->data.type = SMP_T_STR;
Willy Tarreau7875d092012-09-10 08:20:03 +02004802
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02004803 conn = objt_conn(smp->sess->origin);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004804 if (!conn || !conn->xprt_ctx || conn->xprt != &ssl_sock)
4805 return 0;
4806
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02004807 smp->data.u.str.str = (char *)SSL_get_servername(conn->xprt_ctx, TLSEXT_NAMETYPE_host_name);
4808 if (!smp->data.u.str.str)
Willy Tarreau3e394c92012-09-14 23:56:58 +02004809 return 0;
4810
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02004811 smp->data.u.str.len = strlen(smp->data.u.str.str);
Willy Tarreau7875d092012-09-10 08:20:03 +02004812 return 1;
4813#else
4814 return 0;
4815#endif
4816}
4817
David Sc1ad52e2014-04-08 18:48:47 -04004818static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02004819smp_fetch_ssl_fc_unique_id(const struct arg *args, struct sample *smp, const char *kw, void *private)
David Sc1ad52e2014-04-08 18:48:47 -04004820{
4821#if OPENSSL_VERSION_NUMBER > 0x0090800fL
Willy Tarreaue237fe12016-03-10 17:05:28 +01004822 struct connection *conn = objt_conn((kw[4] != 'b') ? smp->sess->origin :
4823 smp->strm ? smp->strm->si[1].end : NULL);
4824
David Sc1ad52e2014-04-08 18:48:47 -04004825 int finished_len;
David Sc1ad52e2014-04-08 18:48:47 -04004826 struct chunk *finished_trash;
David Sc1ad52e2014-04-08 18:48:47 -04004827
4828 smp->flags = 0;
David Sc1ad52e2014-04-08 18:48:47 -04004829 if (!conn || !conn->xprt_ctx || conn->xprt != &ssl_sock)
4830 return 0;
4831
4832 if (!(conn->flags & CO_FL_CONNECTED)) {
4833 smp->flags |= SMP_F_MAY_CHANGE;
4834 return 0;
4835 }
4836
4837 finished_trash = get_trash_chunk();
4838 if (!SSL_session_reused(conn->xprt_ctx))
4839 finished_len = SSL_get_peer_finished(conn->xprt_ctx, finished_trash->str, finished_trash->size);
4840 else
4841 finished_len = SSL_get_finished(conn->xprt_ctx, finished_trash->str, finished_trash->size);
4842
4843 if (!finished_len)
4844 return 0;
4845
Emeric Brunb73a9b02014-04-30 18:49:19 +02004846 finished_trash->len = finished_len;
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02004847 smp->data.u.str = *finished_trash;
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02004848 smp->data.type = SMP_T_BIN;
David Sc1ad52e2014-04-08 18:48:47 -04004849
4850 return 1;
4851#else
4852 return 0;
4853#endif
4854}
4855
Emeric Brun2525b6b2012-10-18 15:59:43 +02004856/* integer, returns the first verify error in CA chain of client certificate chain. */
Emeric Brunf282a812012-09-21 15:27:54 +02004857static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02004858smp_fetch_ssl_c_ca_err(const struct arg *args, struct sample *smp, const char *kw, void *private)
Emeric Brunf282a812012-09-21 15:27:54 +02004859{
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004860 struct connection *conn;
4861
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02004862 conn = objt_conn(smp->sess->origin);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004863 if (!conn || conn->xprt != &ssl_sock)
4864 return 0;
4865
4866 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brunf282a812012-09-21 15:27:54 +02004867 smp->flags = SMP_F_MAY_CHANGE;
4868 return 0;
4869 }
4870
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02004871 smp->data.type = SMP_T_SINT;
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02004872 smp->data.u.sint = (unsigned long long int)SSL_SOCK_ST_TO_CA_ERROR(conn->xprt_st);
Emeric Brunf282a812012-09-21 15:27:54 +02004873 smp->flags = 0;
4874
4875 return 1;
4876}
4877
Emeric Brun2525b6b2012-10-18 15:59:43 +02004878/* integer, returns the depth of the first verify error in CA chain of client certificate chain. */
Emeric Brunf282a812012-09-21 15:27:54 +02004879static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02004880smp_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 +02004881{
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004882 struct connection *conn;
4883
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02004884 conn = objt_conn(smp->sess->origin);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004885 if (!conn || conn->xprt != &ssl_sock)
Emeric Brunf282a812012-09-21 15:27:54 +02004886 return 0;
4887
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004888 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brunf282a812012-09-21 15:27:54 +02004889 smp->flags = SMP_F_MAY_CHANGE;
4890 return 0;
4891 }
4892
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02004893 smp->data.type = SMP_T_SINT;
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02004894 smp->data.u.sint = (long long int)SSL_SOCK_ST_TO_CAEDEPTH(conn->xprt_st);
Emeric Brunf282a812012-09-21 15:27:54 +02004895 smp->flags = 0;
4896
4897 return 1;
4898}
4899
Emeric Brun2525b6b2012-10-18 15:59:43 +02004900/* integer, returns the first verify error on client certificate */
Emeric Brunf282a812012-09-21 15:27:54 +02004901static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02004902smp_fetch_ssl_c_err(const struct arg *args, struct sample *smp, const char *kw, void *private)
Emeric Brunf282a812012-09-21 15:27:54 +02004903{
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004904 struct connection *conn;
4905
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02004906 conn = objt_conn(smp->sess->origin);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004907 if (!conn || conn->xprt != &ssl_sock)
4908 return 0;
4909
4910 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brunf282a812012-09-21 15:27:54 +02004911 smp->flags = SMP_F_MAY_CHANGE;
4912 return 0;
4913 }
4914
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02004915 smp->data.type = SMP_T_SINT;
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02004916 smp->data.u.sint = (long long int)SSL_SOCK_ST_TO_CRTERROR(conn->xprt_st);
Emeric Brunf282a812012-09-21 15:27:54 +02004917 smp->flags = 0;
4918
4919 return 1;
4920}
4921
Emeric Brun2525b6b2012-10-18 15:59:43 +02004922/* integer, returns the verify result on client cert */
Emeric Brunbaf8ffb2012-09-21 15:27:20 +02004923static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02004924smp_fetch_ssl_c_verify(const struct arg *args, struct sample *smp, const char *kw, void *private)
Emeric Brunbaf8ffb2012-09-21 15:27:20 +02004925{
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004926 struct connection *conn;
4927
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02004928 conn = objt_conn(smp->sess->origin);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004929 if (!conn || conn->xprt != &ssl_sock)
4930 return 0;
4931
4932 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brunbaf8ffb2012-09-21 15:27:20 +02004933 smp->flags = SMP_F_MAY_CHANGE;
4934 return 0;
4935 }
4936
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004937 if (!conn->xprt_ctx)
Emeric Brunbaf8ffb2012-09-21 15:27:20 +02004938 return 0;
4939
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02004940 smp->data.type = SMP_T_SINT;
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02004941 smp->data.u.sint = (long long int)SSL_get_verify_result(conn->xprt_ctx);
Emeric Brunbaf8ffb2012-09-21 15:27:20 +02004942 smp->flags = 0;
4943
4944 return 1;
4945}
4946
Emeric Brunfb510ea2012-10-05 12:00:26 +02004947/* parse the "ca-file" bind keyword */
4948static 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 +02004949{
4950 if (!*args[cur_arg + 1]) {
4951 if (err)
4952 memprintf(err, "'%s' : missing CAfile path", args[cur_arg]);
4953 return ERR_ALERT | ERR_FATAL;
4954 }
4955
Emeric Brunef42d922012-10-11 16:11:36 +02004956 if ((*args[cur_arg + 1] != '/') && global.ca_base)
4957 memprintf(&conf->ca_file, "%s/%s", global.ca_base, args[cur_arg + 1]);
4958 else
4959 memprintf(&conf->ca_file, "%s", args[cur_arg + 1]);
Emeric Brunc8e8d122012-10-02 18:42:10 +02004960
Emeric Brund94b3fe2012-09-20 18:23:56 +02004961 return 0;
4962}
4963
Christopher Faulet31af49d2015-06-09 17:29:50 +02004964/* parse the "ca-sign-file" bind keyword */
4965static int bind_parse_ca_sign_file(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
4966{
4967 if (!*args[cur_arg + 1]) {
4968 if (err)
4969 memprintf(err, "'%s' : missing CAfile path", args[cur_arg]);
4970 return ERR_ALERT | ERR_FATAL;
4971 }
4972
4973 if ((*args[cur_arg + 1] != '/') && global.ca_base)
4974 memprintf(&conf->ca_sign_file, "%s/%s", global.ca_base, args[cur_arg + 1]);
4975 else
4976 memprintf(&conf->ca_sign_file, "%s", args[cur_arg + 1]);
4977
4978 return 0;
4979}
4980
4981/* parse the ca-sign-pass bind keyword */
4982
4983static int bind_parse_ca_sign_pass(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
4984{
4985 if (!*args[cur_arg + 1]) {
4986 if (err)
4987 memprintf(err, "'%s' : missing CAkey password", args[cur_arg]);
4988 return ERR_ALERT | ERR_FATAL;
4989 }
4990 memprintf(&conf->ca_sign_pass, "%s", args[cur_arg + 1]);
4991 return 0;
4992}
4993
Willy Tarreau79eeafa2012-09-14 07:53:05 +02004994/* parse the "ciphers" bind keyword */
Willy Tarreau4348fad2012-09-20 16:48:07 +02004995static 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 +02004996{
4997 if (!*args[cur_arg + 1]) {
Willy Tarreaueb6cead2012-09-20 19:43:14 +02004998 memprintf(err, "'%s' : missing cipher suite", args[cur_arg]);
Willy Tarreau79eeafa2012-09-14 07:53:05 +02004999 return ERR_ALERT | ERR_FATAL;
5000 }
5001
Emeric Brun76d88952012-10-05 15:47:31 +02005002 free(conf->ciphers);
Willy Tarreau4348fad2012-09-20 16:48:07 +02005003 conf->ciphers = strdup(args[cur_arg + 1]);
Willy Tarreau79eeafa2012-09-14 07:53:05 +02005004 return 0;
5005}
5006
5007/* parse the "crt" bind keyword */
Willy Tarreau4348fad2012-09-20 16:48:07 +02005008static 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 +02005009{
Willy Tarreau38011032013-08-13 16:59:39 +02005010 char path[MAXPATHLEN];
Willy Tarreaub75d6922014-04-14 18:05:41 +02005011
Willy Tarreau79eeafa2012-09-14 07:53:05 +02005012 if (!*args[cur_arg + 1]) {
Willy Tarreaueb6cead2012-09-20 19:43:14 +02005013 memprintf(err, "'%s' : missing certificate location", args[cur_arg]);
Willy Tarreau79eeafa2012-09-14 07:53:05 +02005014 return ERR_ALERT | ERR_FATAL;
5015 }
5016
Emeric Brunc8e8d122012-10-02 18:42:10 +02005017 if ((*args[cur_arg + 1] != '/' ) && global.crt_base) {
Willy Tarreau38011032013-08-13 16:59:39 +02005018 if ((strlen(global.crt_base) + 1 + strlen(args[cur_arg + 1]) + 1) > MAXPATHLEN) {
Emeric Brunc8e8d122012-10-02 18:42:10 +02005019 memprintf(err, "'%s' : path too long", args[cur_arg]);
5020 return ERR_ALERT | ERR_FATAL;
5021 }
Willy Tarreaub75d6922014-04-14 18:05:41 +02005022 snprintf(path, sizeof(path), "%s/%s", global.crt_base, args[cur_arg + 1]);
Emeric Brunc8e8d122012-10-02 18:42:10 +02005023 if (ssl_sock_load_cert(path, conf, px, err) > 0)
5024 return ERR_ALERT | ERR_FATAL;
5025
5026 return 0;
5027 }
5028
Willy Tarreau4348fad2012-09-20 16:48:07 +02005029 if (ssl_sock_load_cert(args[cur_arg + 1], conf, px, err) > 0)
Willy Tarreau79eeafa2012-09-14 07:53:05 +02005030 return ERR_ALERT | ERR_FATAL;
Emeric Brund94b3fe2012-09-20 18:23:56 +02005031
5032 return 0;
5033}
5034
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01005035/* parse the "crt-list" bind keyword */
5036static int bind_parse_crt_list(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
5037{
5038 if (!*args[cur_arg + 1]) {
5039 memprintf(err, "'%s' : missing certificate location", args[cur_arg]);
5040 return ERR_ALERT | ERR_FATAL;
5041 }
5042
Willy Tarreauad1731d2013-04-02 17:35:58 +02005043 if (ssl_sock_load_cert_list_file(args[cur_arg + 1], conf, px, err) > 0) {
5044 memprintf(err, "'%s' : %s", args[cur_arg], *err);
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01005045 return ERR_ALERT | ERR_FATAL;
Willy Tarreauad1731d2013-04-02 17:35:58 +02005046 }
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01005047
5048 return 0;
5049}
5050
Emeric Brunfb510ea2012-10-05 12:00:26 +02005051/* parse the "crl-file" bind keyword */
5052static 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 +02005053{
Emeric Brun051cdab2012-10-02 19:25:50 +02005054#ifndef X509_V_FLAG_CRL_CHECK
5055 if (err)
5056 memprintf(err, "'%s' : library does not support CRL verify", args[cur_arg]);
5057 return ERR_ALERT | ERR_FATAL;
5058#else
Emeric Brund94b3fe2012-09-20 18:23:56 +02005059 if (!*args[cur_arg + 1]) {
5060 if (err)
5061 memprintf(err, "'%s' : missing CRLfile path", args[cur_arg]);
5062 return ERR_ALERT | ERR_FATAL;
5063 }
Emeric Brun2b58d042012-09-20 17:10:03 +02005064
Emeric Brunef42d922012-10-11 16:11:36 +02005065 if ((*args[cur_arg + 1] != '/') && global.ca_base)
5066 memprintf(&conf->crl_file, "%s/%s", global.ca_base, args[cur_arg + 1]);
5067 else
5068 memprintf(&conf->crl_file, "%s", args[cur_arg + 1]);
Emeric Brunc8e8d122012-10-02 18:42:10 +02005069
Emeric Brun2b58d042012-09-20 17:10:03 +02005070 return 0;
Emeric Brun051cdab2012-10-02 19:25:50 +02005071#endif
Emeric Brun2b58d042012-09-20 17:10:03 +02005072}
5073
5074/* parse the "ecdhe" bind keyword keywords */
5075static int bind_parse_ecdhe(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
5076{
5077#if OPENSSL_VERSION_NUMBER < 0x0090800fL
5078 if (err)
5079 memprintf(err, "'%s' : library does not support elliptic curve Diffie-Hellman (too old)", args[cur_arg]);
5080 return ERR_ALERT | ERR_FATAL;
5081#elif defined(OPENSSL_NO_ECDH)
5082 if (err)
5083 memprintf(err, "'%s' : library does not support elliptic curve Diffie-Hellman (disabled via OPENSSL_NO_ECDH)", args[cur_arg]);
5084 return ERR_ALERT | ERR_FATAL;
5085#else
5086 if (!*args[cur_arg + 1]) {
5087 if (err)
5088 memprintf(err, "'%s' : missing named curve", args[cur_arg]);
5089 return ERR_ALERT | ERR_FATAL;
5090 }
5091
5092 conf->ecdhe = strdup(args[cur_arg + 1]);
Willy Tarreau79eeafa2012-09-14 07:53:05 +02005093
5094 return 0;
Emeric Brun2b58d042012-09-20 17:10:03 +02005095#endif
Willy Tarreau79eeafa2012-09-14 07:53:05 +02005096}
5097
Emeric Brun81c00f02012-09-21 14:31:21 +02005098/* parse the "crt_ignerr" and "ca_ignerr" bind keywords */
5099static int bind_parse_ignore_err(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
5100{
5101 int code;
5102 char *p = args[cur_arg + 1];
5103 unsigned long long *ignerr = &conf->crt_ignerr;
5104
5105 if (!*p) {
5106 if (err)
5107 memprintf(err, "'%s' : missing error IDs list", args[cur_arg]);
5108 return ERR_ALERT | ERR_FATAL;
5109 }
5110
5111 if (strcmp(args[cur_arg], "ca-ignore-err") == 0)
5112 ignerr = &conf->ca_ignerr;
5113
5114 if (strcmp(p, "all") == 0) {
5115 *ignerr = ~0ULL;
5116 return 0;
5117 }
5118
5119 while (p) {
5120 code = atoi(p);
5121 if ((code <= 0) || (code > 63)) {
5122 if (err)
5123 memprintf(err, "'%s' : ID '%d' out of range (1..63) in error IDs list '%s'",
5124 args[cur_arg], code, args[cur_arg + 1]);
5125 return ERR_ALERT | ERR_FATAL;
5126 }
5127 *ignerr |= 1ULL << code;
5128 p = strchr(p, ',');
5129 if (p)
5130 p++;
5131 }
5132
Emeric Brun2cb7ae52012-10-05 14:14:21 +02005133 return 0;
5134}
5135
5136/* parse the "force-sslv3" bind keyword */
5137static int bind_parse_force_sslv3(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
5138{
5139 conf->ssl_options |= BC_SSL_O_USE_SSLV3;
5140 return 0;
5141}
5142
5143/* parse the "force-tlsv10" bind keyword */
5144static int bind_parse_force_tlsv10(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
5145{
5146 conf->ssl_options |= BC_SSL_O_USE_TLSV10;
Emeric Brun2d0c4822012-10-02 13:45:20 +02005147 return 0;
5148}
5149
Emeric Brun2cb7ae52012-10-05 14:14:21 +02005150/* parse the "force-tlsv11" bind keyword */
5151static int bind_parse_force_tlsv11(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
5152{
5153#if SSL_OP_NO_TLSv1_1
5154 conf->ssl_options |= BC_SSL_O_USE_TLSV11;
5155 return 0;
5156#else
5157 if (err)
5158 memprintf(err, "'%s' : library does not support protocol TLSv1.1", args[cur_arg]);
5159 return ERR_ALERT | ERR_FATAL;
5160#endif
5161}
5162
5163/* parse the "force-tlsv12" bind keyword */
5164static int bind_parse_force_tlsv12(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
5165{
5166#if SSL_OP_NO_TLSv1_2
5167 conf->ssl_options |= BC_SSL_O_USE_TLSV12;
5168 return 0;
5169#else
5170 if (err)
5171 memprintf(err, "'%s' : library does not support protocol TLSv1.2", args[cur_arg]);
5172 return ERR_ALERT | ERR_FATAL;
5173#endif
5174}
5175
5176
Emeric Brun2d0c4822012-10-02 13:45:20 +02005177/* parse the "no-tls-tickets" bind keyword */
5178static int bind_parse_no_tls_tickets(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
5179{
Emeric Brun89675492012-10-05 13:48:26 +02005180 conf->ssl_options |= BC_SSL_O_NO_TLS_TICKETS;
Emeric Brun81c00f02012-09-21 14:31:21 +02005181 return 0;
5182}
5183
Emeric Brun2d0c4822012-10-02 13:45:20 +02005184
Emeric Brun9b3009b2012-10-05 11:55:06 +02005185/* parse the "no-sslv3" bind keyword */
5186static 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 +02005187{
Emeric Brun89675492012-10-05 13:48:26 +02005188 conf->ssl_options |= BC_SSL_O_NO_SSLV3;
Willy Tarreau79eeafa2012-09-14 07:53:05 +02005189 return 0;
5190}
5191
Emeric Brun9b3009b2012-10-05 11:55:06 +02005192/* parse the "no-tlsv10" bind keyword */
5193static 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 +02005194{
Emeric Brun89675492012-10-05 13:48:26 +02005195 conf->ssl_options |= BC_SSL_O_NO_TLSV10;
Emeric Brunc0ff4922012-09-28 19:37:02 +02005196 return 0;
5197}
5198
Emeric Brun9b3009b2012-10-05 11:55:06 +02005199/* parse the "no-tlsv11" bind keyword */
5200static 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 +02005201{
Emeric Brun89675492012-10-05 13:48:26 +02005202 conf->ssl_options |= BC_SSL_O_NO_TLSV11;
Emeric Brunc0ff4922012-09-28 19:37:02 +02005203 return 0;
5204}
5205
Emeric Brun9b3009b2012-10-05 11:55:06 +02005206/* parse the "no-tlsv12" bind keyword */
5207static 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 +02005208{
Emeric Brun89675492012-10-05 13:48:26 +02005209 conf->ssl_options |= BC_SSL_O_NO_TLSV12;
Willy Tarreau79eeafa2012-09-14 07:53:05 +02005210 return 0;
5211}
5212
Willy Tarreau6c9a3d52012-10-18 18:57:14 +02005213/* parse the "npn" bind keyword */
5214static int bind_parse_npn(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
5215{
5216#ifdef OPENSSL_NPN_NEGOTIATED
5217 char *p1, *p2;
5218
5219 if (!*args[cur_arg + 1]) {
5220 memprintf(err, "'%s' : missing the comma-delimited NPN protocol suite", args[cur_arg]);
5221 return ERR_ALERT | ERR_FATAL;
5222 }
5223
5224 free(conf->npn_str);
5225
Willy Tarreau3724da12016-02-12 17:11:12 +01005226 /* the NPN string is built as a suite of (<len> <name>)*,
5227 * so we reuse each comma to store the next <len> and need
5228 * one more for the end of the string.
5229 */
Willy Tarreau6c9a3d52012-10-18 18:57:14 +02005230 conf->npn_len = strlen(args[cur_arg + 1]) + 1;
Willy Tarreau3724da12016-02-12 17:11:12 +01005231 conf->npn_str = calloc(1, conf->npn_len + 1);
Willy Tarreau6c9a3d52012-10-18 18:57:14 +02005232 memcpy(conf->npn_str + 1, args[cur_arg + 1], conf->npn_len);
5233
5234 /* replace commas with the name length */
5235 p1 = conf->npn_str;
5236 p2 = p1 + 1;
5237 while (1) {
5238 p2 = memchr(p1 + 1, ',', conf->npn_str + conf->npn_len - (p1 + 1));
5239 if (!p2)
5240 p2 = p1 + 1 + strlen(p1 + 1);
5241
5242 if (p2 - (p1 + 1) > 255) {
5243 *p2 = '\0';
5244 memprintf(err, "'%s' : NPN protocol name too long : '%s'", args[cur_arg], p1 + 1);
5245 return ERR_ALERT | ERR_FATAL;
5246 }
5247
5248 *p1 = p2 - (p1 + 1);
5249 p1 = p2;
5250
5251 if (!*p2)
5252 break;
5253
5254 *(p2++) = '\0';
5255 }
5256 return 0;
5257#else
5258 if (err)
5259 memprintf(err, "'%s' : library does not support TLS NPN extension", args[cur_arg]);
5260 return ERR_ALERT | ERR_FATAL;
5261#endif
5262}
5263
Willy Tarreauab861d32013-04-02 02:30:41 +02005264/* parse the "alpn" bind keyword */
5265static int bind_parse_alpn(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
5266{
Dirkjan Bussink48f1c4e2014-02-13 12:29:42 +01005267#ifdef TLSEXT_TYPE_application_layer_protocol_negotiation
Willy Tarreauab861d32013-04-02 02:30:41 +02005268 char *p1, *p2;
5269
5270 if (!*args[cur_arg + 1]) {
5271 memprintf(err, "'%s' : missing the comma-delimited ALPN protocol suite", args[cur_arg]);
5272 return ERR_ALERT | ERR_FATAL;
5273 }
5274
5275 free(conf->alpn_str);
5276
Marcoen Hirschbergbef60912016-02-12 17:05:24 +01005277 /* the ALPN string is built as a suite of (<len> <name>)*,
5278 * so we reuse each comma to store the next <len> and need
5279 * one more for the end of the string.
5280 */
Willy Tarreauab861d32013-04-02 02:30:41 +02005281 conf->alpn_len = strlen(args[cur_arg + 1]) + 1;
Marcoen Hirschbergbef60912016-02-12 17:05:24 +01005282 conf->alpn_str = calloc(1, conf->alpn_len + 1);
Willy Tarreauab861d32013-04-02 02:30:41 +02005283 memcpy(conf->alpn_str + 1, args[cur_arg + 1], conf->alpn_len);
5284
5285 /* replace commas with the name length */
5286 p1 = conf->alpn_str;
5287 p2 = p1 + 1;
5288 while (1) {
5289 p2 = memchr(p1 + 1, ',', conf->alpn_str + conf->alpn_len - (p1 + 1));
5290 if (!p2)
5291 p2 = p1 + 1 + strlen(p1 + 1);
5292
5293 if (p2 - (p1 + 1) > 255) {
5294 *p2 = '\0';
5295 memprintf(err, "'%s' : ALPN protocol name too long : '%s'", args[cur_arg], p1 + 1);
5296 return ERR_ALERT | ERR_FATAL;
5297 }
5298
5299 *p1 = p2 - (p1 + 1);
5300 p1 = p2;
5301
5302 if (!*p2)
5303 break;
5304
5305 *(p2++) = '\0';
5306 }
5307 return 0;
5308#else
5309 if (err)
5310 memprintf(err, "'%s' : library does not support TLS ALPN extension", args[cur_arg]);
5311 return ERR_ALERT | ERR_FATAL;
5312#endif
5313}
5314
Willy Tarreau79eeafa2012-09-14 07:53:05 +02005315/* parse the "ssl" bind keyword */
Willy Tarreau4348fad2012-09-20 16:48:07 +02005316static 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 +02005317{
Willy Tarreau81796be2012-09-22 19:11:47 +02005318 struct listener *l;
5319
Willy Tarreau4348fad2012-09-20 16:48:07 +02005320 conf->is_ssl = 1;
Emeric Brun76d88952012-10-05 15:47:31 +02005321
5322 if (global.listen_default_ciphers && !conf->ciphers)
5323 conf->ciphers = strdup(global.listen_default_ciphers);
Emeric Brun2c86cbf2014-10-30 15:56:50 +01005324 conf->ssl_options |= global.listen_default_ssloptions;
Emeric Brun76d88952012-10-05 15:47:31 +02005325
Willy Tarreau81796be2012-09-22 19:11:47 +02005326 list_for_each_entry(l, &conf->listeners, by_bind)
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02005327 l->xprt = &ssl_sock;
Willy Tarreau81796be2012-09-22 19:11:47 +02005328
Willy Tarreau79eeafa2012-09-14 07:53:05 +02005329 return 0;
5330}
5331
Christopher Faulet31af49d2015-06-09 17:29:50 +02005332/* parse the "generate-certificates" bind keyword */
5333static int bind_parse_generate_certs(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
5334{
5335#ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME
5336 conf->generate_certs = 1;
5337#else
5338 memprintf(err, "%sthis version of openssl cannot generate SSL certificates.\n",
5339 err && *err ? *err : "");
5340#endif
5341 return 0;
5342}
5343
Emmanuel Hocdet65623372013-01-24 17:17:15 +01005344/* parse the "strict-sni" bind keyword */
5345static int bind_parse_strict_sni(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
5346{
5347 conf->strict_sni = 1;
5348 return 0;
Nenad Merdanovic05552d42015-02-27 19:56:49 +01005349}
5350
5351/* parse the "tls-ticket-keys" bind keyword */
5352static int bind_parse_tls_ticket_keys(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
5353{
5354#if (defined SSL_CTRL_SET_TLSEXT_TICKET_KEY_CB && TLS_TICKETS_NO > 0)
5355 FILE *f;
5356 int i = 0;
5357 char thisline[LINESIZE];
Nenad Merdanovic146defa2015-05-09 08:46:00 +02005358 struct tls_keys_ref *keys_ref;
Nenad Merdanovic05552d42015-02-27 19:56:49 +01005359
5360 if (!*args[cur_arg + 1]) {
5361 if (err)
5362 memprintf(err, "'%s' : missing TLS ticket keys file path", args[cur_arg]);
5363 return ERR_ALERT | ERR_FATAL;
5364 }
5365
Nenad Merdanovic200b0fa2015-05-09 08:46:01 +02005366 keys_ref = tlskeys_ref_lookup(args[cur_arg + 1]);
5367 if(keys_ref) {
5368 conf->keys_ref = keys_ref;
5369 return 0;
5370 }
5371
Nenad Merdanovic146defa2015-05-09 08:46:00 +02005372 keys_ref = malloc(sizeof(struct tls_keys_ref));
5373 keys_ref->tlskeys = malloc(TLS_TICKETS_NO * sizeof(struct tls_sess_key));
Nenad Merdanovic05552d42015-02-27 19:56:49 +01005374
5375 if ((f = fopen(args[cur_arg + 1], "r")) == NULL) {
5376 if (err)
5377 memprintf(err, "'%s' : unable to load ssl tickets keys file", args[cur_arg+1]);
5378 return ERR_ALERT | ERR_FATAL;
5379 }
5380
Nenad Merdanovic146defa2015-05-09 08:46:00 +02005381 keys_ref->filename = strdup(args[cur_arg + 1]);
5382
Nenad Merdanovic05552d42015-02-27 19:56:49 +01005383 while (fgets(thisline, sizeof(thisline), f) != NULL) {
5384 int len = strlen(thisline);
5385 /* Strip newline characters from the end */
5386 if(thisline[len - 1] == '\n')
5387 thisline[--len] = 0;
5388
5389 if(thisline[len - 1] == '\r')
5390 thisline[--len] = 0;
5391
Nenad Merdanovic146defa2015-05-09 08:46:00 +02005392 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 +01005393 if (err)
5394 memprintf(err, "'%s' : unable to decode base64 key on line %d", args[cur_arg+1], i + 1);
5395 return ERR_ALERT | ERR_FATAL;
5396 }
5397 i++;
5398 }
5399
5400 if (i < TLS_TICKETS_NO) {
5401 if (err)
5402 memprintf(err, "'%s' : please supply at least %d keys in the tls-tickets-file", args[cur_arg+1], TLS_TICKETS_NO);
5403 return ERR_ALERT | ERR_FATAL;
5404 }
5405
5406 fclose(f);
5407
5408 /* Use penultimate key for encryption, handle when TLS_TICKETS_NO = 1 */
Nenad Merdanovic17891152016-03-25 22:16:57 +01005409 i -= 2;
5410 keys_ref->tls_ticket_enc_index = i < 0 ? 0 : i % TLS_TICKETS_NO;
Nenad Merdanovic200b0fa2015-05-09 08:46:01 +02005411 keys_ref->unique_id = -1;
Nenad Merdanovic146defa2015-05-09 08:46:00 +02005412 conf->keys_ref = keys_ref;
Nenad Merdanovic05552d42015-02-27 19:56:49 +01005413
Nenad Merdanovic200b0fa2015-05-09 08:46:01 +02005414 LIST_ADD(&tlskeys_reference, &keys_ref->list);
5415
Nenad Merdanovic05552d42015-02-27 19:56:49 +01005416 return 0;
5417#else
5418 if (err)
5419 memprintf(err, "'%s' : TLS ticket callback extension not supported", args[cur_arg]);
5420 return ERR_ALERT | ERR_FATAL;
5421#endif /* SSL_CTRL_SET_TLSEXT_TICKET_KEY_CB */
Emmanuel Hocdet65623372013-01-24 17:17:15 +01005422}
5423
Emeric Brund94b3fe2012-09-20 18:23:56 +02005424/* parse the "verify" bind keyword */
5425static int bind_parse_verify(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
5426{
5427 if (!*args[cur_arg + 1]) {
5428 if (err)
5429 memprintf(err, "'%s' : missing verify method", args[cur_arg]);
5430 return ERR_ALERT | ERR_FATAL;
5431 }
5432
5433 if (strcmp(args[cur_arg + 1], "none") == 0)
Emeric Brun850efd52014-01-29 12:24:34 +01005434 conf->verify = SSL_SOCK_VERIFY_NONE;
Emeric Brund94b3fe2012-09-20 18:23:56 +02005435 else if (strcmp(args[cur_arg + 1], "optional") == 0)
Emeric Brun850efd52014-01-29 12:24:34 +01005436 conf->verify = SSL_SOCK_VERIFY_OPTIONAL;
Emeric Brund94b3fe2012-09-20 18:23:56 +02005437 else if (strcmp(args[cur_arg + 1], "required") == 0)
Emeric Brun850efd52014-01-29 12:24:34 +01005438 conf->verify = SSL_SOCK_VERIFY_REQUIRED;
Emeric Brund94b3fe2012-09-20 18:23:56 +02005439 else {
5440 if (err)
5441 memprintf(err, "'%s' : unknown verify method '%s', only 'none', 'optional', and 'required' are supported\n",
5442 args[cur_arg], args[cur_arg + 1]);
5443 return ERR_ALERT | ERR_FATAL;
5444 }
5445
5446 return 0;
5447}
5448
Willy Tarreau92faadf2012-10-10 23:04:25 +02005449/************** "server" keywords ****************/
5450
Emeric Brunef42d922012-10-11 16:11:36 +02005451/* parse the "ca-file" server keyword */
5452static int srv_parse_ca_file(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
5453{
5454 if (!*args[*cur_arg + 1]) {
5455 if (err)
5456 memprintf(err, "'%s' : missing CAfile path", args[*cur_arg]);
5457 return ERR_ALERT | ERR_FATAL;
5458 }
5459
5460 if ((*args[*cur_arg + 1] != '/') && global.ca_base)
5461 memprintf(&newsrv->ssl_ctx.ca_file, "%s/%s", global.ca_base, args[*cur_arg + 1]);
5462 else
5463 memprintf(&newsrv->ssl_ctx.ca_file, "%s", args[*cur_arg + 1]);
5464
5465 return 0;
5466}
5467
Willy Tarreau92faadf2012-10-10 23:04:25 +02005468/* parse the "check-ssl" server keyword */
5469static int srv_parse_check_ssl(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
5470{
5471 newsrv->check.use_ssl = 1;
5472 if (global.connect_default_ciphers && !newsrv->ssl_ctx.ciphers)
5473 newsrv->ssl_ctx.ciphers = strdup(global.connect_default_ciphers);
Emeric Brun2c86cbf2014-10-30 15:56:50 +01005474 newsrv->ssl_ctx.options |= global.connect_default_ssloptions;
Willy Tarreau92faadf2012-10-10 23:04:25 +02005475 return 0;
5476}
5477
5478/* parse the "ciphers" server keyword */
5479static int srv_parse_ciphers(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
5480{
5481 if (!*args[*cur_arg + 1]) {
5482 memprintf(err, "'%s' : missing cipher suite", args[*cur_arg]);
5483 return ERR_ALERT | ERR_FATAL;
5484 }
5485
5486 free(newsrv->ssl_ctx.ciphers);
5487 newsrv->ssl_ctx.ciphers = strdup(args[*cur_arg + 1]);
5488 return 0;
5489}
5490
Emeric Brunef42d922012-10-11 16:11:36 +02005491/* parse the "crl-file" server keyword */
5492static int srv_parse_crl_file(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
5493{
5494#ifndef X509_V_FLAG_CRL_CHECK
5495 if (err)
5496 memprintf(err, "'%s' : library does not support CRL verify", args[*cur_arg]);
5497 return ERR_ALERT | ERR_FATAL;
5498#else
5499 if (!*args[*cur_arg + 1]) {
5500 if (err)
5501 memprintf(err, "'%s' : missing CRLfile path", args[*cur_arg]);
5502 return ERR_ALERT | ERR_FATAL;
5503 }
5504
5505 if ((*args[*cur_arg + 1] != '/') && global.ca_base)
5506 memprintf(&newsrv->ssl_ctx.crl_file, "%s/%s", global.ca_base, args[*cur_arg + 1]);
5507 else
5508 memprintf(&newsrv->ssl_ctx.crl_file, "%s", args[*cur_arg + 1]);
5509
5510 return 0;
5511#endif
5512}
5513
Emeric Bruna7aa3092012-10-26 12:58:00 +02005514/* parse the "crt" server keyword */
5515static int srv_parse_crt(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
5516{
5517 if (!*args[*cur_arg + 1]) {
5518 if (err)
5519 memprintf(err, "'%s' : missing certificate file path", args[*cur_arg]);
5520 return ERR_ALERT | ERR_FATAL;
5521 }
5522
5523 if ((*args[*cur_arg + 1] != '/') && global.crt_base)
5524 memprintf(&newsrv->ssl_ctx.client_crt, "%s/%s", global.ca_base, args[*cur_arg + 1]);
5525 else
5526 memprintf(&newsrv->ssl_ctx.client_crt, "%s", args[*cur_arg + 1]);
5527
5528 return 0;
5529}
Emeric Brunef42d922012-10-11 16:11:36 +02005530
Willy Tarreau92faadf2012-10-10 23:04:25 +02005531/* parse the "force-sslv3" server keyword */
5532static int srv_parse_force_sslv3(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
5533{
5534 newsrv->ssl_ctx.options |= SRV_SSL_O_USE_SSLV3;
5535 return 0;
5536}
5537
5538/* parse the "force-tlsv10" server keyword */
5539static int srv_parse_force_tlsv10(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
5540{
5541 newsrv->ssl_ctx.options |= SRV_SSL_O_USE_TLSV10;
5542 return 0;
5543}
5544
5545/* parse the "force-tlsv11" server keyword */
5546static int srv_parse_force_tlsv11(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
5547{
5548#if SSL_OP_NO_TLSv1_1
5549 newsrv->ssl_ctx.options |= SRV_SSL_O_USE_TLSV11;
5550 return 0;
5551#else
5552 if (err)
5553 memprintf(err, "'%s' : library does not support protocol TLSv1.1", args[*cur_arg]);
5554 return ERR_ALERT | ERR_FATAL;
5555#endif
5556}
5557
5558/* parse the "force-tlsv12" server keyword */
5559static int srv_parse_force_tlsv12(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
5560{
5561#if SSL_OP_NO_TLSv1_2
5562 newsrv->ssl_ctx.options |= SRV_SSL_O_USE_TLSV12;
5563 return 0;
5564#else
5565 if (err)
5566 memprintf(err, "'%s' : library does not support protocol TLSv1.2", args[*cur_arg]);
5567 return ERR_ALERT | ERR_FATAL;
5568#endif
5569}
5570
Willy Tarreau2a3fb1c2015-02-05 16:47:07 +01005571/* parse the "no-ssl-reuse" server keyword */
5572static int srv_parse_no_ssl_reuse(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
5573{
5574 newsrv->ssl_ctx.options |= SRV_SSL_O_NO_REUSE;
5575 return 0;
5576}
5577
Willy Tarreau92faadf2012-10-10 23:04:25 +02005578/* parse the "no-sslv3" server keyword */
5579static int srv_parse_no_sslv3(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
5580{
5581 newsrv->ssl_ctx.options |= SRV_SSL_O_NO_SSLV3;
5582 return 0;
5583}
5584
5585/* parse the "no-tlsv10" server keyword */
5586static int srv_parse_no_tlsv10(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
5587{
5588 newsrv->ssl_ctx.options |= SRV_SSL_O_NO_TLSV10;
5589 return 0;
5590}
5591
5592/* parse the "no-tlsv11" server keyword */
5593static int srv_parse_no_tlsv11(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
5594{
5595 newsrv->ssl_ctx.options |= SRV_SSL_O_NO_TLSV11;
5596 return 0;
5597}
5598
5599/* parse the "no-tlsv12" server keyword */
5600static int srv_parse_no_tlsv12(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
5601{
5602 newsrv->ssl_ctx.options |= SRV_SSL_O_NO_TLSV12;
5603 return 0;
5604}
5605
Emeric Brunf9c5c472012-10-11 15:28:34 +02005606/* parse the "no-tls-tickets" server keyword */
5607static int srv_parse_no_tls_tickets(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
5608{
5609 newsrv->ssl_ctx.options |= SRV_SSL_O_NO_TLS_TICKETS;
5610 return 0;
5611}
David Safb76832014-05-08 23:42:08 -04005612/* parse the "send-proxy-v2-ssl" server keyword */
5613static int srv_parse_send_proxy_ssl(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
5614{
5615 newsrv->pp_opts |= SRV_PP_V2;
5616 newsrv->pp_opts |= SRV_PP_V2_SSL;
5617 return 0;
5618}
5619
5620/* parse the "send-proxy-v2-ssl-cn" server keyword */
5621static int srv_parse_send_proxy_cn(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
5622{
5623 newsrv->pp_opts |= SRV_PP_V2;
5624 newsrv->pp_opts |= SRV_PP_V2_SSL;
5625 newsrv->pp_opts |= SRV_PP_V2_SSL_CN;
5626 return 0;
5627}
Emeric Brunf9c5c472012-10-11 15:28:34 +02005628
Willy Tarreau732eac42015-07-09 11:40:25 +02005629/* parse the "sni" server keyword */
5630static int srv_parse_sni(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
5631{
5632#ifndef SSL_CTRL_SET_TLSEXT_HOSTNAME
5633 memprintf(err, "'%s' : the current SSL library doesn't support the SNI TLS extension", args[*cur_arg]);
5634 return ERR_ALERT | ERR_FATAL;
5635#else
Cyril Bonté23d19d62016-03-07 22:13:22 +01005636 int idx;
Willy Tarreau732eac42015-07-09 11:40:25 +02005637 struct sample_expr *expr;
5638
5639 if (!*args[*cur_arg + 1]) {
5640 memprintf(err, "'%s' : missing sni expression", args[*cur_arg]);
5641 return ERR_ALERT | ERR_FATAL;
5642 }
5643
Cyril Bonté23d19d62016-03-07 22:13:22 +01005644 idx = (*cur_arg) + 1;
Willy Tarreau732eac42015-07-09 11:40:25 +02005645 proxy->conf.args.ctx = ARGC_SRV;
5646
Cyril Bonté23d19d62016-03-07 22:13:22 +01005647 expr = sample_parse_expr((char **)args, &idx, px->conf.file, px->conf.line, err, &proxy->conf.args);
Willy Tarreau732eac42015-07-09 11:40:25 +02005648 if (!expr) {
5649 memprintf(err, "error detected while parsing sni expression : %s", *err);
5650 return ERR_ALERT | ERR_FATAL;
5651 }
5652
5653 if (!(expr->fetch->val & SMP_VAL_BE_SRV_CON)) {
5654 memprintf(err, "error detected while parsing sni expression : "
5655 " fetch method '%s' extracts information from '%s', none of which is available here.\n",
Cyril Bonté23d19d62016-03-07 22:13:22 +01005656 args[idx-1], sample_src_names(expr->fetch->use));
Willy Tarreau732eac42015-07-09 11:40:25 +02005657 return ERR_ALERT | ERR_FATAL;
5658 }
5659
5660 px->http_needed |= !!(expr->fetch->use & SMP_USE_HTTP_ANY);
5661 newsrv->ssl_ctx.sni = expr;
5662 return 0;
5663#endif
5664}
5665
Willy Tarreau92faadf2012-10-10 23:04:25 +02005666/* parse the "ssl" server keyword */
5667static int srv_parse_ssl(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
5668{
5669 newsrv->use_ssl = 1;
5670 if (global.connect_default_ciphers && !newsrv->ssl_ctx.ciphers)
5671 newsrv->ssl_ctx.ciphers = strdup(global.connect_default_ciphers);
5672 return 0;
5673}
5674
Emeric Brunef42d922012-10-11 16:11:36 +02005675/* parse the "verify" server keyword */
5676static int srv_parse_verify(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
5677{
5678 if (!*args[*cur_arg + 1]) {
5679 if (err)
5680 memprintf(err, "'%s' : missing verify method", args[*cur_arg]);
5681 return ERR_ALERT | ERR_FATAL;
5682 }
5683
5684 if (strcmp(args[*cur_arg + 1], "none") == 0)
Emeric Brun850efd52014-01-29 12:24:34 +01005685 newsrv->ssl_ctx.verify = SSL_SOCK_VERIFY_NONE;
Emeric Brunef42d922012-10-11 16:11:36 +02005686 else if (strcmp(args[*cur_arg + 1], "required") == 0)
Emeric Brun850efd52014-01-29 12:24:34 +01005687 newsrv->ssl_ctx.verify = SSL_SOCK_VERIFY_REQUIRED;
Emeric Brunef42d922012-10-11 16:11:36 +02005688 else {
5689 if (err)
5690 memprintf(err, "'%s' : unknown verify method '%s', only 'none' and 'required' are supported\n",
5691 args[*cur_arg], args[*cur_arg + 1]);
5692 return ERR_ALERT | ERR_FATAL;
5693 }
5694
Evan Broderbe554312013-06-27 00:05:25 -07005695 return 0;
5696}
5697
5698/* parse the "verifyhost" server keyword */
5699static int srv_parse_verifyhost(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
5700{
5701 if (!*args[*cur_arg + 1]) {
5702 if (err)
5703 memprintf(err, "'%s' : missing hostname to verify against", args[*cur_arg]);
5704 return ERR_ALERT | ERR_FATAL;
5705 }
5706
5707 newsrv->ssl_ctx.verify_host = strdup(args[*cur_arg + 1]);
5708
Emeric Brunef42d922012-10-11 16:11:36 +02005709 return 0;
5710}
5711
Emeric Brun2c86cbf2014-10-30 15:56:50 +01005712/* parse the "ssl-default-bind-options" keyword in global section */
5713static int ssl_parse_default_bind_options(char **args, int section_type, struct proxy *curpx,
5714 struct proxy *defpx, const char *file, int line,
5715 char **err) {
5716 int i = 1;
5717
5718 if (*(args[i]) == 0) {
5719 memprintf(err, "global statement '%s' expects an option as an argument.", args[0]);
5720 return -1;
5721 }
5722 while (*(args[i])) {
5723 if (!strcmp(args[i], "no-sslv3"))
5724 global.listen_default_ssloptions |= BC_SSL_O_NO_SSLV3;
5725 else if (!strcmp(args[i], "no-tlsv10"))
5726 global.listen_default_ssloptions |= BC_SSL_O_NO_TLSV10;
5727 else if (!strcmp(args[i], "no-tlsv11"))
5728 global.listen_default_ssloptions |= BC_SSL_O_NO_TLSV11;
5729 else if (!strcmp(args[i], "no-tlsv12"))
5730 global.listen_default_ssloptions |= BC_SSL_O_NO_TLSV12;
5731 else if (!strcmp(args[i], "force-sslv3"))
5732 global.listen_default_ssloptions |= BC_SSL_O_USE_SSLV3;
5733 else if (!strcmp(args[i], "force-tlsv10"))
5734 global.listen_default_ssloptions |= BC_SSL_O_USE_TLSV10;
5735 else if (!strcmp(args[i], "force-tlsv11")) {
5736#if SSL_OP_NO_TLSv1_1
5737 global.listen_default_ssloptions |= BC_SSL_O_USE_TLSV11;
5738#else
5739 memprintf(err, "'%s' '%s': library does not support protocol TLSv1.1", args[0], args[i]);
5740 return -1;
5741#endif
5742 }
5743 else if (!strcmp(args[i], "force-tlsv12")) {
5744#if SSL_OP_NO_TLSv1_2
5745 global.listen_default_ssloptions |= BC_SSL_O_USE_TLSV12;
5746#else
5747 memprintf(err, "'%s' '%s': library does not support protocol TLSv1.2", args[0], args[i]);
5748 return -1;
5749#endif
5750 }
5751 else if (!strcmp(args[i], "no-tls-tickets"))
5752 global.listen_default_ssloptions |= BC_SSL_O_NO_TLS_TICKETS;
5753 else {
5754 memprintf(err, "unknown option '%s' on global statement '%s'.", args[i], args[0]);
5755 return -1;
5756 }
5757 i++;
5758 }
5759 return 0;
5760}
5761
5762/* parse the "ssl-default-server-options" keyword in global section */
5763static int ssl_parse_default_server_options(char **args, int section_type, struct proxy *curpx,
5764 struct proxy *defpx, const char *file, int line,
5765 char **err) {
5766 int i = 1;
5767
5768 if (*(args[i]) == 0) {
5769 memprintf(err, "global statement '%s' expects an option as an argument.", args[0]);
5770 return -1;
5771 }
5772 while (*(args[i])) {
5773 if (!strcmp(args[i], "no-sslv3"))
5774 global.connect_default_ssloptions |= SRV_SSL_O_NO_SSLV3;
5775 else if (!strcmp(args[i], "no-tlsv10"))
5776 global.connect_default_ssloptions |= SRV_SSL_O_NO_TLSV10;
5777 else if (!strcmp(args[i], "no-tlsv11"))
5778 global.connect_default_ssloptions |= SRV_SSL_O_NO_TLSV11;
5779 else if (!strcmp(args[i], "no-tlsv12"))
5780 global.connect_default_ssloptions |= SRV_SSL_O_NO_TLSV12;
5781 else if (!strcmp(args[i], "force-sslv3"))
5782 global.connect_default_ssloptions |= SRV_SSL_O_USE_SSLV3;
5783 else if (!strcmp(args[i], "force-tlsv10"))
5784 global.connect_default_ssloptions |= SRV_SSL_O_USE_TLSV10;
5785 else if (!strcmp(args[i], "force-tlsv11")) {
5786#if SSL_OP_NO_TLSv1_1
5787 global.connect_default_ssloptions |= SRV_SSL_O_USE_TLSV11;
5788#else
5789 memprintf(err, "'%s' '%s': library does not support protocol TLSv1.1", args[0], args[i]);
5790 return -1;
5791#endif
5792 }
5793 else if (!strcmp(args[i], "force-tlsv12")) {
5794#if SSL_OP_NO_TLSv1_2
5795 global.connect_default_ssloptions |= SRV_SSL_O_USE_TLSV12;
5796#else
5797 memprintf(err, "'%s' '%s': library does not support protocol TLSv1.2", args[0], args[i]);
5798 return -1;
5799#endif
5800 }
5801 else if (!strcmp(args[i], "no-tls-tickets"))
5802 global.connect_default_ssloptions |= SRV_SSL_O_NO_TLS_TICKETS;
5803 else {
5804 memprintf(err, "unknown option '%s' on global statement '%s'.", args[i], args[0]);
5805 return -1;
5806 }
5807 i++;
5808 }
5809 return 0;
5810}
5811
Willy Tarreau7875d092012-09-10 08:20:03 +02005812/* Note: must not be declared <const> as its list will be overwritten.
5813 * Please take care of keeping this list alphabetically sorted.
5814 */
Willy Tarreaudc13c112013-06-21 23:16:39 +02005815static struct sample_fetch_kw_list sample_fetch_keywords = {ILH, {
Emeric Brun645ae792014-04-30 14:21:06 +02005816 { "ssl_bc", smp_fetch_ssl_fc, 0, NULL, SMP_T_BOOL, SMP_USE_L5SRV },
Thierry FOURNIER07ee64e2015-07-06 23:43:03 +02005817 { "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 +02005818 { "ssl_bc_cipher", smp_fetch_ssl_fc_cipher, 0, NULL, SMP_T_STR, SMP_USE_L5SRV },
5819 { "ssl_bc_protocol", smp_fetch_ssl_fc_protocol, 0, NULL, SMP_T_STR, SMP_USE_L5SRV },
Emeric Brunb73a9b02014-04-30 18:49:19 +02005820 { "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 +02005821 { "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 +02005822 { "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 +02005823 { "ssl_c_ca_err", smp_fetch_ssl_c_ca_err, 0, NULL, SMP_T_SINT, SMP_USE_L5CLI },
5824 { "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 +01005825 { "ssl_c_der", smp_fetch_ssl_x_der, 0, NULL, SMP_T_BIN, SMP_USE_L5CLI },
Thierry FOURNIER07ee64e2015-07-06 23:43:03 +02005826 { "ssl_c_err", smp_fetch_ssl_c_err, 0, NULL, SMP_T_SINT, SMP_USE_L5CLI },
Emeric Brunba841a12014-04-30 17:05:08 +02005827 { "ssl_c_i_dn", smp_fetch_ssl_x_i_dn, ARG2(0,STR,SINT), NULL, SMP_T_STR, SMP_USE_L5CLI },
5828 { "ssl_c_key_alg", smp_fetch_ssl_x_key_alg, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
5829 { "ssl_c_notafter", smp_fetch_ssl_x_notafter, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
5830 { "ssl_c_notbefore", smp_fetch_ssl_x_notbefore, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
5831 { "ssl_c_sig_alg", smp_fetch_ssl_x_sig_alg, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
5832 { "ssl_c_s_dn", smp_fetch_ssl_x_s_dn, ARG2(0,STR,SINT), NULL, SMP_T_STR, SMP_USE_L5CLI },
5833 { "ssl_c_serial", smp_fetch_ssl_x_serial, 0, NULL, SMP_T_BIN, SMP_USE_L5CLI },
5834 { "ssl_c_sha1", smp_fetch_ssl_x_sha1, 0, NULL, SMP_T_BIN, SMP_USE_L5CLI },
Willy Tarreau80aca902013-01-07 15:42:20 +01005835 { "ssl_c_used", smp_fetch_ssl_c_used, 0, NULL, SMP_T_BOOL, SMP_USE_L5CLI },
Thierry FOURNIER07ee64e2015-07-06 23:43:03 +02005836 { "ssl_c_verify", smp_fetch_ssl_c_verify, 0, NULL, SMP_T_SINT, SMP_USE_L5CLI },
5837 { "ssl_c_version", smp_fetch_ssl_x_version, 0, NULL, SMP_T_SINT, SMP_USE_L5CLI },
Emeric Brun43e79582014-10-29 19:03:26 +01005838 { "ssl_f_der", smp_fetch_ssl_x_der, 0, NULL, SMP_T_BIN, SMP_USE_L5CLI },
Emeric Brunba841a12014-04-30 17:05:08 +02005839 { "ssl_f_i_dn", smp_fetch_ssl_x_i_dn, ARG2(0,STR,SINT), NULL, SMP_T_STR, SMP_USE_L5CLI },
5840 { "ssl_f_key_alg", smp_fetch_ssl_x_key_alg, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
5841 { "ssl_f_notafter", smp_fetch_ssl_x_notafter, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
5842 { "ssl_f_notbefore", smp_fetch_ssl_x_notbefore, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
5843 { "ssl_f_sig_alg", smp_fetch_ssl_x_sig_alg, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
5844 { "ssl_f_s_dn", smp_fetch_ssl_x_s_dn, ARG2(0,STR,SINT), NULL, SMP_T_STR, SMP_USE_L5CLI },
5845 { "ssl_f_serial", smp_fetch_ssl_x_serial, 0, NULL, SMP_T_BIN, SMP_USE_L5CLI },
Emeric Brun55f4fa82014-04-30 17:11:25 +02005846 { "ssl_f_sha1", smp_fetch_ssl_x_sha1, 0, NULL, SMP_T_BIN, SMP_USE_L5CLI },
Thierry FOURNIER07ee64e2015-07-06 23:43:03 +02005847 { "ssl_f_version", smp_fetch_ssl_x_version, 0, NULL, SMP_T_SINT, SMP_USE_L5CLI },
Willy Tarreau80aca902013-01-07 15:42:20 +01005848 { "ssl_fc", smp_fetch_ssl_fc, 0, NULL, SMP_T_BOOL, SMP_USE_L5CLI },
Thierry FOURNIER07ee64e2015-07-06 23:43:03 +02005849 { "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 +01005850 { "ssl_fc_cipher", smp_fetch_ssl_fc_cipher, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
Willy Tarreau80aca902013-01-07 15:42:20 +01005851 { "ssl_fc_has_crt", smp_fetch_ssl_fc_has_crt, 0, NULL, SMP_T_BOOL, SMP_USE_L5CLI },
5852 { "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 +02005853 { "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 +02005854#ifdef OPENSSL_NPN_NEGOTIATED
Thierry FOURNIER7654c9f2013-12-17 00:20:33 +01005855 { "ssl_fc_npn", smp_fetch_ssl_fc_npn, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
Willy Tarreaua33c6542012-10-15 13:19:06 +02005856#endif
Dirkjan Bussink48f1c4e2014-02-13 12:29:42 +01005857#ifdef TLSEXT_TYPE_application_layer_protocol_negotiation
Thierry FOURNIER7654c9f2013-12-17 00:20:33 +01005858 { "ssl_fc_alpn", smp_fetch_ssl_fc_alpn, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
Willy Tarreauab861d32013-04-02 02:30:41 +02005859#endif
Thierry FOURNIER7654c9f2013-12-17 00:20:33 +01005860 { "ssl_fc_protocol", smp_fetch_ssl_fc_protocol, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
Emeric Brunb73a9b02014-04-30 18:49:19 +02005861 { "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 +02005862 { "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 +01005863 { "ssl_fc_session_id", smp_fetch_ssl_fc_session_id, 0, NULL, SMP_T_BIN, SMP_USE_L5CLI },
5864 { "ssl_fc_sni", smp_fetch_ssl_fc_sni, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
Willy Tarreau7875d092012-09-10 08:20:03 +02005865 { NULL, NULL, 0, 0, 0 },
5866}};
5867
5868/* Note: must not be declared <const> as its list will be overwritten.
5869 * Please take care of keeping this list alphabetically sorted.
5870 */
Willy Tarreaudc13c112013-06-21 23:16:39 +02005871static struct acl_kw_list acl_kws = {ILH, {
Thierry FOURNIERc5a4e982014-03-05 16:07:08 +01005872 { "ssl_fc_sni_end", "ssl_fc_sni", PAT_MATCH_END },
5873 { "ssl_fc_sni_reg", "ssl_fc_sni", PAT_MATCH_REG },
Willy Tarreau8ed669b2013-01-11 15:49:37 +01005874 { /* END */ },
Willy Tarreau7875d092012-09-10 08:20:03 +02005875}};
5876
Willy Tarreau79eeafa2012-09-14 07:53:05 +02005877/* Note: must not be declared <const> as its list will be overwritten.
5878 * Please take care of keeping this list alphabetically sorted, doing so helps
5879 * all code contributors.
5880 * Optional keywords are also declared with a NULL ->parse() function so that
5881 * the config parser can report an appropriate error when a known keyword was
5882 * not enabled.
5883 */
Willy Tarreau51fb7652012-09-18 18:24:39 +02005884static struct bind_kw_list bind_kws = { "SSL", { }, {
Nenad Merdanovic05552d42015-02-27 19:56:49 +01005885 { "alpn", bind_parse_alpn, 1 }, /* set ALPN supported protocols */
5886 { "ca-file", bind_parse_ca_file, 1 }, /* set CAfile to process verify on client cert */
5887 { "ca-ignore-err", bind_parse_ignore_err, 1 }, /* set error IDs to ignore on verify depth > 0 */
Christopher Faulet31af49d2015-06-09 17:29:50 +02005888 { "ca-sign-file", bind_parse_ca_sign_file, 1 }, /* set CAFile used to generate and sign server certs */
5889 { "ca-sign-pass", bind_parse_ca_sign_pass, 1 }, /* set CAKey passphrase */
Nenad Merdanovic05552d42015-02-27 19:56:49 +01005890 { "ciphers", bind_parse_ciphers, 1 }, /* set SSL cipher suite */
5891 { "crl-file", bind_parse_crl_file, 1 }, /* set certificat revocation list file use on client cert verify */
5892 { "crt", bind_parse_crt, 1 }, /* load SSL certificates from this location */
5893 { "crt-ignore-err", bind_parse_ignore_err, 1 }, /* set error IDs to ingore on verify depth == 0 */
5894 { "crt-list", bind_parse_crt_list, 1 }, /* load a list of crt from this location */
5895 { "ecdhe", bind_parse_ecdhe, 1 }, /* defines named curve for elliptic curve Diffie-Hellman */
5896 { "force-sslv3", bind_parse_force_sslv3, 0 }, /* force SSLv3 */
5897 { "force-tlsv10", bind_parse_force_tlsv10, 0 }, /* force TLSv10 */
5898 { "force-tlsv11", bind_parse_force_tlsv11, 0 }, /* force TLSv11 */
5899 { "force-tlsv12", bind_parse_force_tlsv12, 0 }, /* force TLSv12 */
Christopher Faulet31af49d2015-06-09 17:29:50 +02005900 { "generate-certificates", bind_parse_generate_certs, 0 }, /* enable the server certificates generation */
Nenad Merdanovic05552d42015-02-27 19:56:49 +01005901 { "no-sslv3", bind_parse_no_sslv3, 0 }, /* disable SSLv3 */
5902 { "no-tlsv10", bind_parse_no_tlsv10, 0 }, /* disable TLSv10 */
5903 { "no-tlsv11", bind_parse_no_tlsv11, 0 }, /* disable TLSv11 */
5904 { "no-tlsv12", bind_parse_no_tlsv12, 0 }, /* disable TLSv12 */
5905 { "no-tls-tickets", bind_parse_no_tls_tickets, 0 }, /* disable session resumption tickets */
5906 { "ssl", bind_parse_ssl, 0 }, /* enable SSL processing */
5907 { "strict-sni", bind_parse_strict_sni, 0 }, /* refuse negotiation if sni doesn't match a certificate */
5908 { "tls-ticket-keys", bind_parse_tls_ticket_keys, 1 }, /* set file to load TLS ticket keys from */
5909 { "verify", bind_parse_verify, 1 }, /* set SSL verify method */
5910 { "npn", bind_parse_npn, 1 }, /* set NPN supported protocols */
Willy Tarreau79eeafa2012-09-14 07:53:05 +02005911 { NULL, NULL, 0 },
5912}};
Emeric Brun46591952012-05-18 15:47:34 +02005913
Willy Tarreau92faadf2012-10-10 23:04:25 +02005914/* Note: must not be declared <const> as its list will be overwritten.
5915 * Please take care of keeping this list alphabetically sorted, doing so helps
5916 * all code contributors.
5917 * Optional keywords are also declared with a NULL ->parse() function so that
5918 * the config parser can report an appropriate error when a known keyword was
5919 * not enabled.
5920 */
5921static struct srv_kw_list srv_kws = { "SSL", { }, {
Emeric Brunef42d922012-10-11 16:11:36 +02005922 { "ca-file", srv_parse_ca_file, 1, 0 }, /* set CAfile to process verify server cert */
Emeric Brunecc91fe2012-10-11 15:05:10 +02005923 { "check-ssl", srv_parse_check_ssl, 0, 0 }, /* enable SSL for health checks */
5924 { "ciphers", srv_parse_ciphers, 1, 0 }, /* select the cipher suite */
Emeric Brunef42d922012-10-11 16:11:36 +02005925 { "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 +02005926 { "crt", srv_parse_crt, 1, 0 }, /* set client certificate */
Emeric Brunecc91fe2012-10-11 15:05:10 +02005927 { "force-sslv3", srv_parse_force_sslv3, 0, 0 }, /* force SSLv3 */
5928 { "force-tlsv10", srv_parse_force_tlsv10, 0, 0 }, /* force TLSv10 */
5929 { "force-tlsv11", srv_parse_force_tlsv11, 0, 0 }, /* force TLSv11 */
5930 { "force-tlsv12", srv_parse_force_tlsv12, 0, 0 }, /* force TLSv12 */
Willy Tarreau2a3fb1c2015-02-05 16:47:07 +01005931 { "no-ssl-reuse", srv_parse_no_ssl_reuse, 0, 0 }, /* disable session reuse */
Emeric Brunecc91fe2012-10-11 15:05:10 +02005932 { "no-sslv3", srv_parse_no_sslv3, 0, 0 }, /* disable SSLv3 */
5933 { "no-tlsv10", srv_parse_no_tlsv10, 0, 0 }, /* disable TLSv10 */
5934 { "no-tlsv11", srv_parse_no_tlsv11, 0, 0 }, /* disable TLSv11 */
5935 { "no-tlsv12", srv_parse_no_tlsv12, 0, 0 }, /* disable TLSv12 */
Emeric Brunf9c5c472012-10-11 15:28:34 +02005936 { "no-tls-tickets", srv_parse_no_tls_tickets, 0, 0 }, /* disable session resumption tickets */
David Safb76832014-05-08 23:42:08 -04005937 { "send-proxy-v2-ssl", srv_parse_send_proxy_ssl, 0, 0 }, /* send PROXY protocol header v2 with SSL info */
5938 { "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 +02005939 { "sni", srv_parse_sni, 1, 0 }, /* send SNI extension */
Emeric Brunecc91fe2012-10-11 15:05:10 +02005940 { "ssl", srv_parse_ssl, 0, 0 }, /* enable SSL processing */
Emeric Brunef42d922012-10-11 16:11:36 +02005941 { "verify", srv_parse_verify, 1, 0 }, /* set SSL verify method */
Evan Broderbe554312013-06-27 00:05:25 -07005942 { "verifyhost", srv_parse_verifyhost, 1, 0 }, /* require that SSL cert verifies for hostname */
Willy Tarreau92faadf2012-10-10 23:04:25 +02005943 { NULL, NULL, 0, 0 },
5944}};
5945
Emeric Brun2c86cbf2014-10-30 15:56:50 +01005946static struct cfg_kw_list cfg_kws = {ILH, {
5947 { CFG_GLOBAL, "ssl-default-bind-options", ssl_parse_default_bind_options },
5948 { CFG_GLOBAL, "ssl-default-server-options", ssl_parse_default_server_options },
5949 { 0, NULL, NULL },
5950}};
5951
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02005952/* transport-layer operations for SSL sockets */
5953struct xprt_ops ssl_sock = {
Emeric Brun46591952012-05-18 15:47:34 +02005954 .snd_buf = ssl_sock_from_buf,
5955 .rcv_buf = ssl_sock_to_buf,
5956 .rcv_pipe = NULL,
5957 .snd_pipe = NULL,
5958 .shutr = NULL,
5959 .shutw = ssl_sock_shutw,
5960 .close = ssl_sock_close,
5961 .init = ssl_sock_init,
5962};
5963
Daniel Jakots54ffb912015-11-06 20:02:41 +01005964#if (OPENSSL_VERSION_NUMBER >= 0x1000200fL && !defined OPENSSL_NO_TLSEXT && !defined OPENSSL_IS_BORINGSSL && !defined LIBRESSL_VERSION_NUMBER)
Janusz Dziemidowicz2c701b52015-03-07 23:03:59 +01005965
5966static void ssl_sock_sctl_free_func(void *parent, void *ptr, CRYPTO_EX_DATA *ad, int idx, long argl, void *argp)
5967{
5968 if (ptr) {
5969 chunk_destroy(ptr);
5970 free(ptr);
5971 }
5972}
5973
5974#endif
5975
Emeric Brun46591952012-05-18 15:47:34 +02005976__attribute__((constructor))
Willy Tarreau92faadf2012-10-10 23:04:25 +02005977static void __ssl_sock_init(void)
5978{
Emeric Brun46591952012-05-18 15:47:34 +02005979 STACK_OF(SSL_COMP)* cm;
5980
Willy Tarreau610f04b2014-02-13 11:36:41 +01005981#ifdef LISTEN_DEFAULT_CIPHERS
5982 global.listen_default_ciphers = LISTEN_DEFAULT_CIPHERS;
5983#endif
5984#ifdef CONNECT_DEFAULT_CIPHERS
5985 global.connect_default_ciphers = CONNECT_DEFAULT_CIPHERS;
5986#endif
5987 if (global.listen_default_ciphers)
5988 global.listen_default_ciphers = strdup(global.listen_default_ciphers);
5989 if (global.connect_default_ciphers)
5990 global.connect_default_ciphers = strdup(global.connect_default_ciphers);
Emeric Brun2c86cbf2014-10-30 15:56:50 +01005991 global.listen_default_ssloptions = BC_SSL_O_NONE;
5992 global.connect_default_ssloptions = SRV_SSL_O_NONE;
Willy Tarreau610f04b2014-02-13 11:36:41 +01005993
Emeric Brun46591952012-05-18 15:47:34 +02005994 SSL_library_init();
5995 cm = SSL_COMP_get_compression_methods();
5996 sk_SSL_COMP_zero(cm);
Daniel Jakots54ffb912015-11-06 20:02:41 +01005997#if (OPENSSL_VERSION_NUMBER >= 0x1000200fL && !defined OPENSSL_NO_TLSEXT && !defined OPENSSL_IS_BORINGSSL && !defined LIBRESSL_VERSION_NUMBER)
Janusz Dziemidowicz2c701b52015-03-07 23:03:59 +01005998 sctl_ex_index = SSL_CTX_get_ex_new_index(0, NULL, NULL, NULL, ssl_sock_sctl_free_func);
5999#endif
Willy Tarreau7875d092012-09-10 08:20:03 +02006000 sample_register_fetches(&sample_fetch_keywords);
6001 acl_register_keywords(&acl_kws);
Willy Tarreau79eeafa2012-09-14 07:53:05 +02006002 bind_register_keywords(&bind_kws);
Willy Tarreau92faadf2012-10-10 23:04:25 +02006003 srv_register_keywords(&srv_kws);
Emeric Brun2c86cbf2014-10-30 15:56:50 +01006004 cfg_register_keywords(&cfg_kws);
Willy Tarreaud92aa5c2015-01-15 21:34:39 +01006005
6006 global.ssl_session_max_cost = SSL_SESSION_MAX_COST;
6007 global.ssl_handshake_max_cost = SSL_HANDSHAKE_MAX_COST;
Remi Gacogne4f902b82015-05-28 16:23:00 +02006008
6009#ifndef OPENSSL_NO_DH
6010 ssl_dh_ptr_index = SSL_CTX_get_ex_new_index(0, NULL, NULL, NULL, NULL);
6011#endif
Emeric Brun46591952012-05-18 15:47:34 +02006012}
6013
Remi Gacogned3a23c32015-05-28 16:39:47 +02006014__attribute__((destructor))
6015static void __ssl_sock_deinit(void)
6016{
Willy Tarreaua84c2672015-10-09 12:10:13 +02006017#ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME
Christopher Faulet31af49d2015-06-09 17:29:50 +02006018 lru64_destroy(ssl_ctx_lru_tree);
Willy Tarreaua84c2672015-10-09 12:10:13 +02006019#endif
Christopher Faulet31af49d2015-06-09 17:29:50 +02006020
Remi Gacogned3a23c32015-05-28 16:39:47 +02006021#ifndef OPENSSL_NO_DH
6022 if (local_dh_1024) {
6023 DH_free(local_dh_1024);
6024 local_dh_1024 = NULL;
6025 }
6026
6027 if (local_dh_2048) {
6028 DH_free(local_dh_2048);
6029 local_dh_2048 = NULL;
6030 }
6031
6032 if (local_dh_4096) {
6033 DH_free(local_dh_4096);
6034 local_dh_4096 = NULL;
6035 }
6036
Remi Gacogne47783ef2015-05-29 15:53:22 +02006037 if (global_dh) {
6038 DH_free(global_dh);
6039 global_dh = NULL;
6040 }
Remi Gacogned3a23c32015-05-28 16:39:47 +02006041#endif
6042
6043 ERR_remove_state(0);
6044 ERR_free_strings();
6045
6046 EVP_cleanup();
6047
6048#if OPENSSL_VERSION_NUMBER >= 0x00907000L
6049 CRYPTO_cleanup_all_ex_data();
6050#endif
6051}
6052
6053
Emeric Brun46591952012-05-18 15:47:34 +02006054/*
6055 * Local variables:
6056 * c-indent-level: 8
6057 * c-basic-offset: 8
6058 * End:
6059 */