blob: 5226a496258e1e1fa5f7da7c9a6b0501e99169bd [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
161#if (defined SSL_CTRL_SET_TLSEXT_STATUS_REQ_CB && !defined OPENSSL_NO_OCSP)
162struct certificate_ocsp {
163 struct ebmb_node key;
164 unsigned char key_data[OCSP_MAX_CERTID_ASN1_LENGTH];
165 struct chunk response;
166 long expire;
167};
Christopher Faulet31af49d2015-06-09 17:29:50 +0200168
Emeric Brun4f3c87a2014-06-20 15:46:13 +0200169/*
170 * This function returns the number of seconds elapsed
171 * since the Epoch, 1970-01-01 00:00:00 +0000 (UTC) and the
172 * date presented un ASN1_GENERALIZEDTIME.
173 *
174 * In parsing error case, it returns -1.
175 */
176static long asn1_generalizedtime_to_epoch(ASN1_GENERALIZEDTIME *d)
177{
178 long epoch;
179 char *p, *end;
180 const unsigned short month_offset[12] = {
181 0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334
182 };
183 int year, month;
184
185 if (!d || (d->type != V_ASN1_GENERALIZEDTIME)) return -1;
186
187 p = (char *)d->data;
188 end = p + d->length;
189
190 if (end - p < 4) return -1;
191 year = 1000 * (p[0] - '0') + 100 * (p[1] - '0') + 10 * (p[2] - '0') + p[3] - '0';
192 p += 4;
193 if (end - p < 2) return -1;
194 month = 10 * (p[0] - '0') + p[1] - '0';
195 if (month < 1 || month > 12) return -1;
196 /* Compute the number of seconds since 1 jan 1970 and the beginning of current month
197 We consider leap years and the current month (<marsh or not) */
198 epoch = ( ((year - 1970) * 365)
199 + ((year - (month < 3)) / 4 - (year - (month < 3)) / 100 + (year - (month < 3)) / 400)
200 - ((1970 - 1) / 4 - (1970 - 1) / 100 + (1970 - 1) / 400)
201 + month_offset[month-1]
202 ) * 24 * 60 * 60;
203 p += 2;
204 if (end - p < 2) return -1;
205 /* Add the number of seconds of completed days of current month */
206 epoch += (10 * (p[0] - '0') + p[1] - '0' - 1) * 24 * 60 * 60;
207 p += 2;
208 if (end - p < 2) return -1;
209 /* Add the completed hours of the current day */
210 epoch += (10 * (p[0] - '0') + p[1] - '0') * 60 * 60;
211 p += 2;
212 if (end - p < 2) return -1;
213 /* Add the completed minutes of the current hour */
214 epoch += (10 * (p[0] - '0') + p[1] - '0') * 60;
215 p += 2;
216 if (p == end) return -1;
217 /* Test if there is available seconds */
218 if (p[0] < '0' || p[0] > '9')
219 goto nosec;
220 if (end - p < 2) return -1;
221 /* Add the seconds of the current minute */
222 epoch += 10 * (p[0] - '0') + p[1] - '0';
223 p += 2;
224 if (p == end) return -1;
225 /* Ignore seconds float part if present */
226 if (p[0] == '.') {
227 do {
228 if (++p == end) return -1;
229 } while (p[0] >= '0' && p[0] <= '9');
230 }
231
232nosec:
233 if (p[0] == 'Z') {
234 if (end - p != 1) return -1;
235 return epoch;
236 }
237 else if (p[0] == '+') {
238 if (end - p != 5) return -1;
239 /* Apply timezone offset */
240 return epoch - ((10 * (p[1] - '0') + p[2] - '0') * 60 + (10 * (p[3] - '0') + p[4] - '0')) * 60;
241 }
242 else if (p[0] == '-') {
243 if (end - p != 5) return -1;
244 /* Apply timezone offset */
245 return epoch + ((10 * (p[1] - '0') + p[2] - '0') * 60 + (10 * (p[3] - '0') + p[4] - '0')) * 60;
246 }
247
248 return -1;
249}
250
Emeric Brun1d3865b2014-06-20 15:37:32 +0200251static struct eb_root cert_ocsp_tree = EB_ROOT_UNIQUE;
Emeric Brun4147b2e2014-06-16 18:36:30 +0200252
253/* This function starts to check if the OCSP response (in DER format) contained
254 * in chunk 'ocsp_response' is valid (else exits on error).
255 * If 'cid' is not NULL, it will be compared to the OCSP certificate ID
256 * contained in the OCSP Response and exits on error if no match.
257 * If it's a valid OCSP Response:
258 * If 'ocsp' is not NULL, the chunk is copied in the OCSP response's container
259 * pointed by 'ocsp'.
260 * If 'ocsp' is NULL, the function looks up into the OCSP response's
261 * containers tree (using as index the ASN1 form of the OCSP Certificate ID extracted
262 * from the response) and exits on error if not found. Finally, If an OCSP response is
263 * already present in the container, it will be overwritten.
264 *
265 * Note: OCSP response containing more than one OCSP Single response is not
266 * considered valid.
267 *
268 * Returns 0 on success, 1 in error case.
269 */
270static int ssl_sock_load_ocsp_response(struct chunk *ocsp_response, struct certificate_ocsp *ocsp, OCSP_CERTID *cid, char **err)
271{
272 OCSP_RESPONSE *resp;
273 OCSP_BASICRESP *bs = NULL;
274 OCSP_SINGLERESP *sr;
275 unsigned char *p = (unsigned char *)ocsp_response->str;
276 int rc , count_sr;
Emeric Brun13a6b482014-06-20 15:44:34 +0200277 ASN1_GENERALIZEDTIME *revtime, *thisupd, *nextupd = NULL;
Emeric Brun4147b2e2014-06-16 18:36:30 +0200278 int reason;
279 int ret = 1;
280
281 resp = d2i_OCSP_RESPONSE(NULL, (const unsigned char **)&p, ocsp_response->len);
282 if (!resp) {
283 memprintf(err, "Unable to parse OCSP response");
284 goto out;
285 }
286
287 rc = OCSP_response_status(resp);
288 if (rc != OCSP_RESPONSE_STATUS_SUCCESSFUL) {
289 memprintf(err, "OCSP response status not successful");
290 goto out;
291 }
292
293 bs = OCSP_response_get1_basic(resp);
294 if (!bs) {
295 memprintf(err, "Failed to get basic response from OCSP Response");
296 goto out;
297 }
298
299 count_sr = OCSP_resp_count(bs);
300 if (count_sr > 1) {
301 memprintf(err, "OCSP response ignored because contains multiple single responses (%d)", count_sr);
302 goto out;
303 }
304
305 sr = OCSP_resp_get0(bs, 0);
306 if (!sr) {
307 memprintf(err, "Failed to get OCSP single response");
308 goto out;
309 }
310
311 rc = OCSP_single_get0_status(sr, &reason, &revtime, &thisupd, &nextupd);
312 if (rc != V_OCSP_CERTSTATUS_GOOD) {
313 memprintf(err, "OCSP single response: certificate status not good");
314 goto out;
315 }
316
Emeric Brun13a6b482014-06-20 15:44:34 +0200317 if (!nextupd) {
318 memprintf(err, "OCSP single response: missing nextupdate");
319 goto out;
320 }
321
Emeric Brunc8b27b62014-06-19 14:16:17 +0200322 rc = OCSP_check_validity(thisupd, nextupd, OCSP_MAX_RESPONSE_TIME_SKEW, -1);
Emeric Brun4147b2e2014-06-16 18:36:30 +0200323 if (!rc) {
324 memprintf(err, "OCSP single response: no longer valid.");
325 goto out;
326 }
327
328 if (cid) {
329 if (OCSP_id_cmp(sr->certId, cid)) {
330 memprintf(err, "OCSP single response: Certificate ID does not match certificate and issuer");
331 goto out;
332 }
333 }
334
335 if (!ocsp) {
336 unsigned char key[OCSP_MAX_CERTID_ASN1_LENGTH];
337 unsigned char *p;
338
339 rc = i2d_OCSP_CERTID(sr->certId, NULL);
340 if (!rc) {
341 memprintf(err, "OCSP single response: Unable to encode Certificate ID");
342 goto out;
343 }
344
345 if (rc > OCSP_MAX_CERTID_ASN1_LENGTH) {
346 memprintf(err, "OCSP single response: Certificate ID too long");
347 goto out;
348 }
349
350 p = key;
351 memset(key, 0, OCSP_MAX_CERTID_ASN1_LENGTH);
352 i2d_OCSP_CERTID(sr->certId, &p);
353 ocsp = (struct certificate_ocsp *)ebmb_lookup(&cert_ocsp_tree, key, OCSP_MAX_CERTID_ASN1_LENGTH);
354 if (!ocsp) {
355 memprintf(err, "OCSP single response: Certificate ID does not match any certificate or issuer");
356 goto out;
357 }
358 }
359
360 /* According to comments on "chunk_dup", the
361 previous chunk buffer will be freed */
362 if (!chunk_dup(&ocsp->response, ocsp_response)) {
363 memprintf(err, "OCSP response: Memory allocation error");
364 goto out;
365 }
366
Emeric Brun4f3c87a2014-06-20 15:46:13 +0200367 ocsp->expire = asn1_generalizedtime_to_epoch(nextupd) - OCSP_MAX_RESPONSE_TIME_SKEW;
368
Emeric Brun4147b2e2014-06-16 18:36:30 +0200369 ret = 0;
370out:
371 if (bs)
372 OCSP_BASICRESP_free(bs);
373
374 if (resp)
375 OCSP_RESPONSE_free(resp);
376
377 return ret;
378}
379/*
380 * External function use to update the OCSP response in the OCSP response's
381 * containers tree. The chunk 'ocsp_response' must contain the OCSP response
382 * to update in DER format.
383 *
384 * Returns 0 on success, 1 in error case.
385 */
386int ssl_sock_update_ocsp_response(struct chunk *ocsp_response, char **err)
387{
388 return ssl_sock_load_ocsp_response(ocsp_response, NULL, NULL, err);
389}
390
391/*
392 * This function load the OCSP Resonse in DER format contained in file at
393 * path 'ocsp_path' and call 'ssl_sock_load_ocsp_response'
394 *
395 * Returns 0 on success, 1 in error case.
396 */
397static int ssl_sock_load_ocsp_response_from_file(const char *ocsp_path, struct certificate_ocsp *ocsp, OCSP_CERTID *cid, char **err)
398{
399 int fd = -1;
400 int r = 0;
401 int ret = 1;
402
403 fd = open(ocsp_path, O_RDONLY);
404 if (fd == -1) {
405 memprintf(err, "Error opening OCSP response file");
406 goto end;
407 }
408
409 trash.len = 0;
410 while (trash.len < trash.size) {
411 r = read(fd, trash.str + trash.len, trash.size - trash.len);
412 if (r < 0) {
413 if (errno == EINTR)
414 continue;
415
416 memprintf(err, "Error reading OCSP response from file");
417 goto end;
418 }
419 else if (r == 0) {
420 break;
421 }
422 trash.len += r;
423 }
424
425 close(fd);
426 fd = -1;
427
428 ret = ssl_sock_load_ocsp_response(&trash, ocsp, cid, err);
429end:
430 if (fd != -1)
431 close(fd);
432
433 return ret;
434}
435
Nenad Merdanovic05552d42015-02-27 19:56:49 +0100436#if (defined SSL_CTRL_SET_TLSEXT_TICKET_KEY_CB && TLS_TICKETS_NO > 0)
437static 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)
438{
439 struct tls_sess_key *keys;
440 struct connection *conn;
441 int head;
442 int i;
443
444 conn = (struct connection *)SSL_get_app_data(s);
Nenad Merdanovic146defa2015-05-09 08:46:00 +0200445 keys = objt_listener(conn->target)->bind_conf->keys_ref->tlskeys;
446 head = objt_listener(conn->target)->bind_conf->keys_ref->tls_ticket_enc_index;
Nenad Merdanovic05552d42015-02-27 19:56:49 +0100447
448 if (enc) {
449 memcpy(key_name, keys[head].name, 16);
450
451 if(!RAND_pseudo_bytes(iv, EVP_MAX_IV_LENGTH))
452 return -1;
453
454 if(!EVP_EncryptInit_ex(ectx, EVP_aes_128_cbc(), NULL, keys[head].aes_key, iv))
455 return -1;
456
457 HMAC_Init_ex(hctx, keys[head].hmac_key, 16, HASH_FUNCT(), NULL);
458
459 return 1;
460 } else {
461 for (i = 0; i < TLS_TICKETS_NO; i++) {
462 if (!memcmp(key_name, keys[(head + i) % TLS_TICKETS_NO].name, 16))
463 goto found;
464 }
465 return 0;
466
467 found:
468 HMAC_Init_ex(hctx, keys[(head + i) % TLS_TICKETS_NO].hmac_key, 16, HASH_FUNCT(), NULL);
469 if(!EVP_DecryptInit_ex(ectx, EVP_aes_128_cbc(), NULL, keys[(head + i) % TLS_TICKETS_NO].aes_key, iv))
470 return -1;
471 /* 2 for key renewal, 1 if current key is still valid */
472 return i ? 2 : 1;
473 }
Nenad Merdanovic200b0fa2015-05-09 08:46:01 +0200474}
475
476struct tls_keys_ref *tlskeys_ref_lookup(const char *filename)
477{
478 struct tls_keys_ref *ref;
479
480 list_for_each_entry(ref, &tlskeys_reference, list)
481 if (ref->filename && strcmp(filename, ref->filename) == 0)
482 return ref;
483 return NULL;
484}
485
486struct tls_keys_ref *tlskeys_ref_lookupid(int unique_id)
487{
488 struct tls_keys_ref *ref;
489
490 list_for_each_entry(ref, &tlskeys_reference, list)
491 if (ref->unique_id == unique_id)
492 return ref;
493 return NULL;
494}
495
496int ssl_sock_update_tlskey(char *filename, struct chunk *tlskey, char **err) {
497 struct tls_keys_ref *ref = tlskeys_ref_lookup(filename);
498
499 if(!ref) {
500 memprintf(err, "Unable to locate the referenced filename: %s", filename);
501 return 1;
502 }
503
Pradeep Jindalcc79b002015-08-20 18:25:17 +0530504 memcpy((char *) (ref->tlskeys + ((ref->tls_ticket_enc_index + 2) % TLS_TICKETS_NO)), tlskey->str, tlskey->len);
505 ref->tls_ticket_enc_index = (ref->tls_ticket_enc_index + 1) % TLS_TICKETS_NO;
Nenad Merdanovic200b0fa2015-05-09 08:46:01 +0200506
507 return 0;
Nenad Merdanovic05552d42015-02-27 19:56:49 +0100508}
Nenad Merdanovic200b0fa2015-05-09 08:46:01 +0200509
510/* This function finalize the configuration parsing. Its set all the
511 * automatic ids
512 */
513void tlskeys_finalize_config(void)
514{
515 int i = 0;
516 struct tls_keys_ref *ref, *ref2, *ref3;
517 struct list tkr = LIST_HEAD_INIT(tkr);
518
519 list_for_each_entry(ref, &tlskeys_reference, list) {
520 if (ref->unique_id == -1) {
521 /* Look for the first free id. */
522 while (1) {
523 list_for_each_entry(ref2, &tlskeys_reference, list) {
524 if (ref2->unique_id == i) {
525 i++;
526 break;
527 }
528 }
529 if (&ref2->list == &tlskeys_reference)
530 break;
531 }
532
533 /* Uses the unique id and increment it for the next entry. */
534 ref->unique_id = i;
535 i++;
536 }
537 }
538
539 /* This sort the reference list by id. */
540 list_for_each_entry_safe(ref, ref2, &tlskeys_reference, list) {
541 LIST_DEL(&ref->list);
542 list_for_each_entry(ref3, &tkr, list) {
543 if (ref->unique_id < ref3->unique_id) {
544 LIST_ADDQ(&ref3->list, &ref->list);
545 break;
546 }
547 }
548 if (&ref3->list == &tkr)
549 LIST_ADDQ(&tkr, &ref->list);
550 }
551
552 /* swap root */
553 LIST_ADD(&tkr, &tlskeys_reference);
554 LIST_DEL(&tkr);
555}
556
Nenad Merdanovic05552d42015-02-27 19:56:49 +0100557#endif /* SSL_CTRL_SET_TLSEXT_TICKET_KEY_CB */
558
Emeric Brun4147b2e2014-06-16 18:36:30 +0200559/*
560 * Callback used to set OCSP status extension content in server hello.
561 */
562int ssl_sock_ocsp_stapling_cbk(SSL *ssl, void *arg)
563{
564 struct certificate_ocsp *ocsp = (struct certificate_ocsp *)arg;
565 char* ssl_buf;
566
567 if (!ocsp ||
568 !ocsp->response.str ||
Emeric Brun4f3c87a2014-06-20 15:46:13 +0200569 !ocsp->response.len ||
570 (ocsp->expire < now.tv_sec))
Emeric Brun4147b2e2014-06-16 18:36:30 +0200571 return SSL_TLSEXT_ERR_NOACK;
572
573 ssl_buf = OPENSSL_malloc(ocsp->response.len);
574 if (!ssl_buf)
575 return SSL_TLSEXT_ERR_NOACK;
576
577 memcpy(ssl_buf, ocsp->response.str, ocsp->response.len);
578 SSL_set_tlsext_status_ocsp_resp(ssl, ssl_buf, ocsp->response.len);
579
580 return SSL_TLSEXT_ERR_OK;
581}
582
583/*
584 * This function enables the handling of OCSP status extension on 'ctx' if a
585 * file name 'cert_path' suffixed using ".ocsp" is present.
586 * To enable OCSP status extension, the issuer's certificate is mandatory.
587 * It should be present in the certificate's extra chain builded from file
588 * 'cert_path'. If not found, the issuer certificate is loaded from a file
589 * named 'cert_path' suffixed using '.issuer'.
590 *
591 * In addition, ".ocsp" file content is loaded as a DER format of an OCSP
592 * response. If file is empty or content is not a valid OCSP response,
593 * OCSP status extension is enabled but OCSP response is ignored (a warning
594 * is displayed).
595 *
596 * Returns 1 if no ".ocsp" file found, 0 if OCSP status extension is
597 * succesfully enabled, or -1 in other error case.
598 */
599static int ssl_sock_load_ocsp(SSL_CTX *ctx, const char *cert_path)
600{
601
602 BIO *in = NULL;
603 X509 *x, *xi = NULL, *issuer = NULL;
604 STACK_OF(X509) *chain = NULL;
605 OCSP_CERTID *cid = NULL;
606 SSL *ssl;
607 char ocsp_path[MAXPATHLEN+1];
608 int i, ret = -1;
609 struct stat st;
610 struct certificate_ocsp *ocsp = NULL, *iocsp;
611 char *warn = NULL;
612 unsigned char *p;
613
614 snprintf(ocsp_path, MAXPATHLEN+1, "%s.ocsp", cert_path);
615
616 if (stat(ocsp_path, &st))
617 return 1;
618
619 ssl = SSL_new(ctx);
620 if (!ssl)
621 goto out;
622
623 x = SSL_get_certificate(ssl);
624 if (!x)
625 goto out;
626
627 /* Try to lookup for issuer in certificate extra chain */
628#ifdef SSL_CTRL_GET_EXTRA_CHAIN_CERTS
629 SSL_CTX_get_extra_chain_certs(ctx, &chain);
630#else
631 chain = ctx->extra_certs;
632#endif
633 for (i = 0; i < sk_X509_num(chain); i++) {
634 issuer = sk_X509_value(chain, i);
635 if (X509_check_issued(issuer, x) == X509_V_OK)
636 break;
637 else
638 issuer = NULL;
639 }
640
641 /* If not found try to load issuer from a suffixed file */
642 if (!issuer) {
643 char issuer_path[MAXPATHLEN+1];
644
645 in = BIO_new(BIO_s_file());
646 if (!in)
647 goto out;
648
649 snprintf(issuer_path, MAXPATHLEN+1, "%s.issuer", cert_path);
650 if (BIO_read_filename(in, issuer_path) <= 0)
651 goto out;
652
653 xi = PEM_read_bio_X509_AUX(in, NULL, ctx->default_passwd_callback, ctx->default_passwd_callback_userdata);
654 if (!xi)
655 goto out;
656
657 if (X509_check_issued(xi, x) != X509_V_OK)
658 goto out;
659
660 issuer = xi;
661 }
662
663 cid = OCSP_cert_to_id(0, x, issuer);
664 if (!cid)
665 goto out;
666
667 i = i2d_OCSP_CERTID(cid, NULL);
668 if (!i || (i > OCSP_MAX_CERTID_ASN1_LENGTH))
669 goto out;
670
671 ocsp = calloc(1, sizeof(struct certificate_ocsp));
672 if (!ocsp)
673 goto out;
674
675 p = ocsp->key_data;
676 i2d_OCSP_CERTID(cid, &p);
677
678 iocsp = (struct certificate_ocsp *)ebmb_insert(&cert_ocsp_tree, &ocsp->key, OCSP_MAX_CERTID_ASN1_LENGTH);
679 if (iocsp == ocsp)
680 ocsp = NULL;
681
682 SSL_CTX_set_tlsext_status_cb(ctx, ssl_sock_ocsp_stapling_cbk);
683 SSL_CTX_set_tlsext_status_arg(ctx, iocsp);
684
685 ret = 0;
686
687 warn = NULL;
688 if (ssl_sock_load_ocsp_response_from_file(ocsp_path, iocsp, cid, &warn)) {
689 memprintf(&warn, "Loading '%s': %s. Content will be ignored", ocsp_path, warn ? warn : "failure");
690 Warning("%s.\n", warn);
691 }
692
693out:
694 if (ssl)
695 SSL_free(ssl);
696
697 if (in)
698 BIO_free(in);
699
700 if (xi)
701 X509_free(xi);
702
703 if (cid)
704 OCSP_CERTID_free(cid);
705
706 if (ocsp)
707 free(ocsp);
708
709 if (warn)
710 free(warn);
711
712
713 return ret;
714}
715
716#endif
717
Daniel Jakots54ffb912015-11-06 20:02:41 +0100718#if (OPENSSL_VERSION_NUMBER >= 0x1000200fL && !defined OPENSSL_NO_TLSEXT && !defined OPENSSL_IS_BORINGSSL && !defined LIBRESSL_VERSION_NUMBER)
Janusz Dziemidowicz2c701b52015-03-07 23:03:59 +0100719
720#define CT_EXTENSION_TYPE 18
721
722static int sctl_ex_index = -1;
723
724/*
725 * Try to parse Signed Certificate Timestamp List structure. This function
726 * makes only basic test if the data seems like SCTL. No signature validation
727 * is performed.
728 */
729static int ssl_sock_parse_sctl(struct chunk *sctl)
730{
731 int ret = 1;
732 int len, pos, sct_len;
733 unsigned char *data;
734
735 if (sctl->len < 2)
736 goto out;
737
738 data = (unsigned char *)sctl->str;
739 len = (data[0] << 8) | data[1];
740
741 if (len + 2 != sctl->len)
742 goto out;
743
744 data = data + 2;
745 pos = 0;
746 while (pos < len) {
747 if (len - pos < 2)
748 goto out;
749
750 sct_len = (data[pos] << 8) | data[pos + 1];
751 if (pos + sct_len + 2 > len)
752 goto out;
753
754 pos += sct_len + 2;
755 }
756
757 ret = 0;
758
759out:
760 return ret;
761}
762
763static int ssl_sock_load_sctl_from_file(const char *sctl_path, struct chunk **sctl)
764{
765 int fd = -1;
766 int r = 0;
767 int ret = 1;
768
769 *sctl = NULL;
770
771 fd = open(sctl_path, O_RDONLY);
772 if (fd == -1)
773 goto end;
774
775 trash.len = 0;
776 while (trash.len < trash.size) {
777 r = read(fd, trash.str + trash.len, trash.size - trash.len);
778 if (r < 0) {
779 if (errno == EINTR)
780 continue;
781
782 goto end;
783 }
784 else if (r == 0) {
785 break;
786 }
787 trash.len += r;
788 }
789
790 ret = ssl_sock_parse_sctl(&trash);
791 if (ret)
792 goto end;
793
794 *sctl = calloc(1, sizeof(struct chunk));
795 if (!chunk_dup(*sctl, &trash)) {
796 free(*sctl);
797 *sctl = NULL;
798 goto end;
799 }
800
801end:
802 if (fd != -1)
803 close(fd);
804
805 return ret;
806}
807
808int ssl_sock_sctl_add_cbk(SSL *ssl, unsigned ext_type, const unsigned char **out, size_t *outlen, int *al, void *add_arg)
809{
810 struct chunk *sctl = (struct chunk *)add_arg;
811
812 *out = (unsigned char *)sctl->str;
813 *outlen = sctl->len;
814
815 return 1;
816}
817
818int ssl_sock_sctl_parse_cbk(SSL *s, unsigned int ext_type, const unsigned char *in, size_t inlen, int *al, void *parse_arg)
819{
820 return 1;
821}
822
823static int ssl_sock_load_sctl(SSL_CTX *ctx, const char *cert_path)
824{
825 char sctl_path[MAXPATHLEN+1];
826 int ret = -1;
827 struct stat st;
828 struct chunk *sctl = NULL;
829
830 snprintf(sctl_path, MAXPATHLEN+1, "%s.sctl", cert_path);
831
832 if (stat(sctl_path, &st))
833 return 1;
834
835 if (ssl_sock_load_sctl_from_file(sctl_path, &sctl))
836 goto out;
837
838 if (!SSL_CTX_add_server_custom_ext(ctx, CT_EXTENSION_TYPE, ssl_sock_sctl_add_cbk, NULL, sctl, ssl_sock_sctl_parse_cbk, NULL)) {
839 free(sctl);
840 goto out;
841 }
842
843 SSL_CTX_set_ex_data(ctx, sctl_ex_index, sctl);
844
845 ret = 0;
846
847out:
848 return ret;
849}
850
851#endif
852
Emeric Brune1f38db2012-09-03 20:36:47 +0200853void ssl_sock_infocbk(const SSL *ssl, int where, int ret)
854{
855 struct connection *conn = (struct connection *)SSL_get_app_data(ssl);
Emeric Brund8b2bb52014-01-28 15:43:53 +0100856 BIO *write_bio;
Willy Tarreau622317d2015-02-27 16:36:16 +0100857 (void)ret; /* shut gcc stupid warning */
Emeric Brune1f38db2012-09-03 20:36:47 +0200858
859 if (where & SSL_CB_HANDSHAKE_START) {
860 /* Disable renegotiation (CVE-2009-3555) */
Willy Tarreau20879a02012-12-03 16:32:10 +0100861 if (conn->flags & CO_FL_CONNECTED) {
Emeric Brune1f38db2012-09-03 20:36:47 +0200862 conn->flags |= CO_FL_ERROR;
Willy Tarreau20879a02012-12-03 16:32:10 +0100863 conn->err_code = CO_ER_SSL_RENEG;
864 }
Emeric Brune1f38db2012-09-03 20:36:47 +0200865 }
Emeric Brund8b2bb52014-01-28 15:43:53 +0100866
867 if ((where & SSL_CB_ACCEPT_LOOP) == SSL_CB_ACCEPT_LOOP) {
868 if (!(conn->xprt_st & SSL_SOCK_ST_FL_16K_WBFSIZE)) {
869 /* Long certificate chains optimz
870 If write and read bios are differents, we
871 consider that the buffering was activated,
872 so we rise the output buffer size from 4k
873 to 16k */
874 write_bio = SSL_get_wbio(ssl);
875 if (write_bio != SSL_get_rbio(ssl)) {
876 BIO_set_write_buffer_size(write_bio, 16384);
877 conn->xprt_st |= SSL_SOCK_ST_FL_16K_WBFSIZE;
878 }
879 }
880 }
Emeric Brunfc0421f2012-09-07 17:30:07 +0200881}
882
Emeric Brune64aef12012-09-21 13:15:06 +0200883/* Callback is called for each certificate of the chain during a verify
884 ok is set to 1 if preverify detect no error on current certificate.
885 Returns 0 to break the handshake, 1 otherwise. */
Evan Broderbe554312013-06-27 00:05:25 -0700886int ssl_sock_bind_verifycbk(int ok, X509_STORE_CTX *x_store)
Emeric Brune64aef12012-09-21 13:15:06 +0200887{
888 SSL *ssl;
889 struct connection *conn;
Emeric Brun81c00f02012-09-21 14:31:21 +0200890 int err, depth;
Emeric Brune64aef12012-09-21 13:15:06 +0200891
892 ssl = X509_STORE_CTX_get_ex_data(x_store, SSL_get_ex_data_X509_STORE_CTX_idx());
893 conn = (struct connection *)SSL_get_app_data(ssl);
894
Willy Tarreauf7bc57c2012-10-03 00:19:48 +0200895 conn->xprt_st |= SSL_SOCK_ST_FL_VERIFY_DONE;
Emeric Brune64aef12012-09-21 13:15:06 +0200896
Emeric Brun81c00f02012-09-21 14:31:21 +0200897 if (ok) /* no errors */
898 return ok;
899
900 depth = X509_STORE_CTX_get_error_depth(x_store);
901 err = X509_STORE_CTX_get_error(x_store);
902
903 /* check if CA error needs to be ignored */
904 if (depth > 0) {
Willy Tarreauf7bc57c2012-10-03 00:19:48 +0200905 if (!SSL_SOCK_ST_TO_CA_ERROR(conn->xprt_st)) {
906 conn->xprt_st |= SSL_SOCK_CA_ERROR_TO_ST(err);
907 conn->xprt_st |= SSL_SOCK_CAEDEPTH_TO_ST(depth);
Emeric Brunf282a812012-09-21 15:27:54 +0200908 }
909
Emeric Brun1eb20ef2012-12-03 13:24:29 +0100910 if (objt_listener(conn->target)->bind_conf->ca_ignerr & (1ULL << err)) {
911 ERR_clear_error();
Emeric Brun81c00f02012-09-21 14:31:21 +0200912 return 1;
Emeric Brun1eb20ef2012-12-03 13:24:29 +0100913 }
Emeric Brun81c00f02012-09-21 14:31:21 +0200914
Willy Tarreau20879a02012-12-03 16:32:10 +0100915 conn->err_code = CO_ER_SSL_CA_FAIL;
Emeric Brun81c00f02012-09-21 14:31:21 +0200916 return 0;
917 }
918
Willy Tarreauf7bc57c2012-10-03 00:19:48 +0200919 if (!SSL_SOCK_ST_TO_CRTERROR(conn->xprt_st))
920 conn->xprt_st |= SSL_SOCK_CRTERROR_TO_ST(err);
Emeric Brunf282a812012-09-21 15:27:54 +0200921
Emeric Brun81c00f02012-09-21 14:31:21 +0200922 /* check if certificate error needs to be ignored */
Emeric Brun1eb20ef2012-12-03 13:24:29 +0100923 if (objt_listener(conn->target)->bind_conf->crt_ignerr & (1ULL << err)) {
924 ERR_clear_error();
Emeric Brun81c00f02012-09-21 14:31:21 +0200925 return 1;
Emeric Brun1eb20ef2012-12-03 13:24:29 +0100926 }
Emeric Brun81c00f02012-09-21 14:31:21 +0200927
Willy Tarreau20879a02012-12-03 16:32:10 +0100928 conn->err_code = CO_ER_SSL_CRT_FAIL;
Emeric Brun81c00f02012-09-21 14:31:21 +0200929 return 0;
Emeric Brune64aef12012-09-21 13:15:06 +0200930}
931
Emeric Brun29f037d2014-04-25 19:05:36 +0200932/* Callback is called for ssl protocol analyse */
933void ssl_sock_msgcbk(int write_p, int version, int content_type, const void *buf, size_t len, SSL *ssl, void *arg)
934{
Emeric Brun29f037d2014-04-25 19:05:36 +0200935#ifdef TLS1_RT_HEARTBEAT
936 /* test heartbeat received (write_p is set to 0
937 for a received record) */
Willy Tarreauf51c6982014-04-25 20:02:39 +0200938 if ((content_type == TLS1_RT_HEARTBEAT) && (write_p == 0)) {
Willy Tarreau84815002014-04-25 21:40:27 +0200939 struct connection *conn = (struct connection *)SSL_get_app_data(ssl);
Willy Tarreauf51c6982014-04-25 20:02:39 +0200940 const unsigned char *p = buf;
941 unsigned int payload;
942
Emeric Brun29f037d2014-04-25 19:05:36 +0200943 conn->xprt_st |= SSL_SOCK_RECV_HEARTBEAT;
Willy Tarreauf51c6982014-04-25 20:02:39 +0200944
945 /* Check if this is a CVE-2014-0160 exploitation attempt. */
946 if (*p != TLS1_HB_REQUEST)
947 return;
948
Willy Tarreauaeed6722014-04-25 23:59:58 +0200949 if (len < 1 + 2 + 16) /* 1 type + 2 size + 0 payload + 16 padding */
Willy Tarreauf51c6982014-04-25 20:02:39 +0200950 goto kill_it;
951
952 payload = (p[1] * 256) + p[2];
Willy Tarreau3b2fdb62014-04-25 23:44:22 +0200953 if (3 + payload + 16 <= len)
Willy Tarreauf51c6982014-04-25 20:02:39 +0200954 return; /* OK no problem */
Willy Tarreauaeed6722014-04-25 23:59:58 +0200955 kill_it:
Willy Tarreau3b2fdb62014-04-25 23:44:22 +0200956 /* We have a clear heartbleed attack (CVE-2014-0160), the
957 * advertised payload is larger than the advertised packet
958 * length, so we have garbage in the buffer between the
959 * payload and the end of the buffer (p+len). We can't know
960 * if the SSL stack is patched, and we don't know if we can
961 * safely wipe out the area between p+3+len and payload.
962 * So instead, we prevent the response from being sent by
963 * setting the max_send_fragment to 0 and we report an SSL
964 * error, which will kill this connection. It will be reported
965 * above as SSL_ERROR_SSL while an other handshake failure with
Willy Tarreauf51c6982014-04-25 20:02:39 +0200966 * a heartbeat message will be reported as SSL_ERROR_SYSCALL.
967 */
Willy Tarreau3b2fdb62014-04-25 23:44:22 +0200968 ssl->max_send_fragment = 0;
Willy Tarreauf51c6982014-04-25 20:02:39 +0200969 SSLerr(SSL_F_TLS1_HEARTBEAT, SSL_R_SSL_HANDSHAKE_FAILURE);
970 return;
971 }
Emeric Brun29f037d2014-04-25 19:05:36 +0200972#endif
973}
974
Willy Tarreau6c9a3d52012-10-18 18:57:14 +0200975#ifdef OPENSSL_NPN_NEGOTIATED
976/* This callback is used so that the server advertises the list of
977 * negociable protocols for NPN.
978 */
979static int ssl_sock_advertise_npn_protos(SSL *s, const unsigned char **data,
980 unsigned int *len, void *arg)
981{
982 struct bind_conf *conf = arg;
983
984 *data = (const unsigned char *)conf->npn_str;
985 *len = conf->npn_len;
986 return SSL_TLSEXT_ERR_OK;
987}
988#endif
989
Dirkjan Bussink48f1c4e2014-02-13 12:29:42 +0100990#ifdef TLSEXT_TYPE_application_layer_protocol_negotiation
Willy Tarreauab861d32013-04-02 02:30:41 +0200991/* This callback is used so that the server advertises the list of
992 * negociable protocols for ALPN.
993 */
Dirkjan Bussink48f1c4e2014-02-13 12:29:42 +0100994static int ssl_sock_advertise_alpn_protos(SSL *s, const unsigned char **out,
995 unsigned char *outlen,
996 const unsigned char *server,
997 unsigned int server_len, void *arg)
Willy Tarreauab861d32013-04-02 02:30:41 +0200998{
999 struct bind_conf *conf = arg;
1000
Dirkjan Bussink48f1c4e2014-02-13 12:29:42 +01001001 if (SSL_select_next_proto((unsigned char**) out, outlen, (const unsigned char *)conf->alpn_str,
1002 conf->alpn_len, server, server_len) != OPENSSL_NPN_NEGOTIATED) {
1003 return SSL_TLSEXT_ERR_NOACK;
1004 }
Willy Tarreauab861d32013-04-02 02:30:41 +02001005 return SSL_TLSEXT_ERR_OK;
1006}
1007#endif
1008
Willy Tarreauc8ad3be2015-06-17 15:48:26 +02001009#ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME
Christopher Faulet85b5a1a2015-10-09 11:46:32 +02001010static DH *ssl_get_tmp_dh(SSL *ssl, int export, int keylen);
1011
Christopher Faulet30548802015-06-11 13:39:32 +02001012/* Create a X509 certificate with the specified servername and serial. This
1013 * function returns a SSL_CTX object or NULL if an error occurs. */
Christopher Faulet7969a332015-10-09 11:15:03 +02001014static SSL_CTX *
1015ssl_sock_do_create_cert(const char *servername, unsigned int serial,
1016 struct bind_conf *bind_conf, SSL *ssl)
Christopher Faulet31af49d2015-06-09 17:29:50 +02001017{
Christopher Faulet7969a332015-10-09 11:15:03 +02001018 X509 *cacert = bind_conf->ca_sign_cert;
1019 EVP_PKEY *capkey = bind_conf->ca_sign_pkey;
Christopher Faulet31af49d2015-06-09 17:29:50 +02001020 SSL_CTX *ssl_ctx = NULL;
1021 X509 *newcrt = NULL;
1022 EVP_PKEY *pkey = NULL;
Christopher Faulet31af49d2015-06-09 17:29:50 +02001023 X509_NAME *name;
1024 const EVP_MD *digest;
1025 X509V3_CTX ctx;
1026 unsigned int i;
1027
Christopher Faulet7969a332015-10-09 11:15:03 +02001028 /* Get the private key of the defautl certificate and use it */
1029 if (!(pkey = SSL_get_privatekey(ssl)))
Christopher Faulet31af49d2015-06-09 17:29:50 +02001030 goto mkcert_error;
1031
1032 /* Create the certificate */
1033 if (!(newcrt = X509_new()))
1034 goto mkcert_error;
1035
1036 /* Set version number for the certificate (X509v3) and the serial
1037 * number */
1038 if (X509_set_version(newcrt, 2L) != 1)
1039 goto mkcert_error;
1040 ASN1_INTEGER_set(X509_get_serialNumber(newcrt), serial);
1041
1042 /* Set duration for the certificate */
1043 if (!X509_gmtime_adj(X509_get_notBefore(newcrt), (long)-60*60*24) ||
1044 !X509_gmtime_adj(X509_get_notAfter(newcrt),(long)60*60*24*365))
1045 goto mkcert_error;
1046
1047 /* set public key in the certificate */
1048 if (X509_set_pubkey(newcrt, pkey) != 1)
1049 goto mkcert_error;
1050
1051 /* Set issuer name from the CA */
1052 if (!(name = X509_get_subject_name(cacert)))
1053 goto mkcert_error;
1054 if (X509_set_issuer_name(newcrt, name) != 1)
1055 goto mkcert_error;
1056
1057 /* Set the subject name using the same, but the CN */
1058 name = X509_NAME_dup(name);
1059 if (X509_NAME_add_entry_by_txt(name, "CN", MBSTRING_ASC,
1060 (const unsigned char *)servername,
1061 -1, -1, 0) != 1) {
1062 X509_NAME_free(name);
1063 goto mkcert_error;
1064 }
1065 if (X509_set_subject_name(newcrt, name) != 1) {
1066 X509_NAME_free(name);
1067 goto mkcert_error;
1068 }
1069 X509_NAME_free(name);
1070
1071 /* Add x509v3 extensions as specified */
1072 X509V3_set_ctx(&ctx, cacert, newcrt, NULL, NULL, 0);
1073 for (i = 0; i < X509V3_EXT_SIZE; i++) {
1074 X509_EXTENSION *ext;
1075
1076 if (!(ext = X509V3_EXT_conf(NULL, &ctx, x509v3_ext_names[i], x509v3_ext_values[i])))
1077 goto mkcert_error;
1078 if (!X509_add_ext(newcrt, ext, -1)) {
1079 X509_EXTENSION_free(ext);
1080 goto mkcert_error;
1081 }
1082 X509_EXTENSION_free(ext);
1083 }
1084
1085 /* Sign the certificate with the CA private key */
1086 if (EVP_PKEY_type(capkey->type) == EVP_PKEY_DSA)
1087 digest = EVP_dss1();
1088 else if (EVP_PKEY_type (capkey->type) == EVP_PKEY_RSA)
1089 digest = EVP_sha256();
Christopher Faulet7969a332015-10-09 11:15:03 +02001090 else if (EVP_PKEY_type (capkey->type) == EVP_PKEY_EC)
1091 digest = EVP_sha256();
1092 else {
Christopher Faulete7db2162015-10-19 13:59:24 +02001093#if (OPENSSL_VERSION_NUMBER >= 0x1000000fL)
Christopher Faulet7969a332015-10-09 11:15:03 +02001094 int nid;
1095
1096 if (EVP_PKEY_get_default_digest_nid(capkey, &nid) <= 0)
1097 goto mkcert_error;
1098 if (!(digest = EVP_get_digestbynid(nid)))
1099 goto mkcert_error;
Christopher Faulete7db2162015-10-19 13:59:24 +02001100#else
1101 goto mkcert_error;
1102#endif
Christopher Faulet7969a332015-10-09 11:15:03 +02001103 }
1104
Christopher Faulet31af49d2015-06-09 17:29:50 +02001105 if (!(X509_sign(newcrt, capkey, digest)))
1106 goto mkcert_error;
1107
1108 /* Create and set the new SSL_CTX */
1109 if (!(ssl_ctx = SSL_CTX_new(SSLv23_server_method())))
1110 goto mkcert_error;
1111 if (!SSL_CTX_use_PrivateKey(ssl_ctx, pkey))
1112 goto mkcert_error;
1113 if (!SSL_CTX_use_certificate(ssl_ctx, newcrt))
1114 goto mkcert_error;
1115 if (!SSL_CTX_check_private_key(ssl_ctx))
1116 goto mkcert_error;
1117
1118 if (newcrt) X509_free(newcrt);
Christopher Faulet7969a332015-10-09 11:15:03 +02001119
Christopher Faulet85b5a1a2015-10-09 11:46:32 +02001120 SSL_CTX_set_tmp_dh_callback(ssl_ctx, ssl_get_tmp_dh);
1121#if defined(SSL_CTX_set_tmp_ecdh) && !defined(OPENSSL_NO_ECDH)
1122 {
1123 const char *ecdhe = (bind_conf->ecdhe ? bind_conf->ecdhe : ECDHE_DEFAULT_CURVE);
1124 EC_KEY *ecc;
1125 int nid;
1126
1127 if ((nid = OBJ_sn2nid(ecdhe)) == NID_undef)
1128 goto end;
1129 if (!(ecc = EC_KEY_new_by_curve_name(nid)))
1130 goto end;
1131 SSL_CTX_set_tmp_ecdh(ssl_ctx, ecc);
1132 EC_KEY_free(ecc);
1133 }
1134#endif
1135 end:
Christopher Faulet31af49d2015-06-09 17:29:50 +02001136 return ssl_ctx;
1137
1138 mkcert_error:
1139 if (ssl_ctx) SSL_CTX_free(ssl_ctx);
1140 if (newcrt) X509_free(newcrt);
Christopher Faulet31af49d2015-06-09 17:29:50 +02001141 return NULL;
1142}
1143
Christopher Faulet7969a332015-10-09 11:15:03 +02001144SSL_CTX *
1145ssl_sock_create_cert(struct connection *conn, const char *servername, unsigned int serial)
1146{
1147 struct bind_conf *bind_conf = objt_listener(conn->target)->bind_conf;
1148 return ssl_sock_do_create_cert(servername, serial, bind_conf, conn->xprt_ctx);
1149}
1150
Christopher Faulet30548802015-06-11 13:39:32 +02001151/* Do a lookup for a certificate in the LRU cache used to store generated
1152 * certificates. */
1153SSL_CTX *
Christopher Faulet7969a332015-10-09 11:15:03 +02001154ssl_sock_get_generated_cert(unsigned int serial, struct bind_conf *bind_conf)
Christopher Faulet30548802015-06-11 13:39:32 +02001155{
1156 struct lru64 *lru = NULL;
1157
1158 if (ssl_ctx_lru_tree) {
Christopher Faulet7969a332015-10-09 11:15:03 +02001159 lru = lru64_lookup(serial, ssl_ctx_lru_tree, bind_conf->ca_sign_cert, 0);
Christopher Faulet30548802015-06-11 13:39:32 +02001160 if (lru && lru->domain)
1161 return (SSL_CTX *)lru->data;
1162 }
1163 return NULL;
1164}
1165
Christopher Fauletd2cab922015-07-28 16:03:47 +02001166/* Set a certificate int the LRU cache used to store generated
1167 * certificate. Return 0 on success, otherwise -1 */
1168int
Christopher Faulet7969a332015-10-09 11:15:03 +02001169ssl_sock_set_generated_cert(SSL_CTX *ssl_ctx, unsigned int serial, struct bind_conf *bind_conf)
Christopher Faulet30548802015-06-11 13:39:32 +02001170{
1171 struct lru64 *lru = NULL;
1172
1173 if (ssl_ctx_lru_tree) {
Christopher Faulet7969a332015-10-09 11:15:03 +02001174 lru = lru64_get(serial, ssl_ctx_lru_tree, bind_conf->ca_sign_cert, 0);
Christopher Faulet30548802015-06-11 13:39:32 +02001175 if (!lru)
Christopher Fauletd2cab922015-07-28 16:03:47 +02001176 return -1;
Christopher Faulet30548802015-06-11 13:39:32 +02001177 if (lru->domain && lru->data)
1178 lru->free((SSL_CTX *)lru->data);
Christopher Faulet7969a332015-10-09 11:15:03 +02001179 lru64_commit(lru, ssl_ctx, bind_conf->ca_sign_cert, 0, (void (*)(void *))SSL_CTX_free);
Christopher Fauletd2cab922015-07-28 16:03:47 +02001180 return 0;
Christopher Faulet30548802015-06-11 13:39:32 +02001181 }
Christopher Fauletd2cab922015-07-28 16:03:47 +02001182 return -1;
Christopher Faulet30548802015-06-11 13:39:32 +02001183}
1184
1185/* Compute the serial that will be used to create/set/get a certificate. */
1186unsigned int
Willy Tarreau646b8642015-07-07 18:09:15 +02001187ssl_sock_generated_cert_serial(const void *data, size_t len)
Christopher Faulet30548802015-06-11 13:39:32 +02001188{
1189 return XXH32(data, len, ssl_ctx_lru_seed);
1190}
1191
Willy Tarreau2f63ef42015-10-20 15:16:01 +02001192/* Generate a cert and immediately assign it to the SSL session so that the cert's
1193 * refcount is maintained regardless of the cert's presence in the LRU cache.
1194 */
Christopher Faulet31af49d2015-06-09 17:29:50 +02001195static SSL_CTX *
Christopher Faulet7969a332015-10-09 11:15:03 +02001196ssl_sock_generate_certificate(const char *servername, struct bind_conf *bind_conf, SSL *ssl)
Christopher Faulet31af49d2015-06-09 17:29:50 +02001197{
1198 X509 *cacert = bind_conf->ca_sign_cert;
Christopher Faulet31af49d2015-06-09 17:29:50 +02001199 SSL_CTX *ssl_ctx = NULL;
1200 struct lru64 *lru = NULL;
1201 unsigned int serial;
1202
Willy Tarreaufc017fe2015-07-07 18:09:34 +02001203 serial = ssl_sock_generated_cert_serial(servername, strlen(servername));
Christopher Faulet31af49d2015-06-09 17:29:50 +02001204 if (ssl_ctx_lru_tree) {
1205 lru = lru64_get(serial, ssl_ctx_lru_tree, cacert, 0);
1206 if (lru && lru->domain)
1207 ssl_ctx = (SSL_CTX *)lru->data;
Christopher Fauletd2cab922015-07-28 16:03:47 +02001208 if (!ssl_ctx && lru) {
Christopher Faulet7969a332015-10-09 11:15:03 +02001209 ssl_ctx = ssl_sock_do_create_cert(servername, serial, bind_conf, ssl);
Christopher Faulet31af49d2015-06-09 17:29:50 +02001210 lru64_commit(lru, ssl_ctx, cacert, 0, (void (*)(void *))SSL_CTX_free);
Christopher Fauletd2cab922015-07-28 16:03:47 +02001211 }
Willy Tarreau2f63ef42015-10-20 15:16:01 +02001212 SSL_set_SSL_CTX(ssl, ssl_ctx);
Christopher Faulet31af49d2015-06-09 17:29:50 +02001213 }
Willy Tarreau2f63ef42015-10-20 15:16:01 +02001214 else {
Christopher Faulet7969a332015-10-09 11:15:03 +02001215 ssl_ctx = ssl_sock_do_create_cert(servername, serial, bind_conf, ssl);
Willy Tarreau2f63ef42015-10-20 15:16:01 +02001216 SSL_set_SSL_CTX(ssl, ssl_ctx);
1217 /* No LRU cache, this CTX will be released as soon as the session dies */
1218 SSL_CTX_free(ssl_ctx);
1219 }
Christopher Faulet31af49d2015-06-09 17:29:50 +02001220 return ssl_ctx;
1221}
1222
Emeric Brunfc0421f2012-09-07 17:30:07 +02001223/* Sets the SSL ctx of <ssl> to match the advertised server name. Returns a
1224 * warning when no match is found, which implies the default (first) cert
1225 * will keep being used.
1226 */
Willy Tarreau2a65ff02012-09-13 17:54:29 +02001227static int ssl_sock_switchctx_cbk(SSL *ssl, int *al, struct bind_conf *s)
Emeric Brunfc0421f2012-09-07 17:30:07 +02001228{
1229 const char *servername;
1230 const char *wildp = NULL;
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +02001231 struct ebmb_node *node, *n;
Emeric Brunfc0421f2012-09-07 17:30:07 +02001232 int i;
1233 (void)al; /* shut gcc stupid warning */
1234
1235 servername = SSL_get_servername(ssl, TLSEXT_NAMETYPE_host_name);
Emmanuel Hocdet65623372013-01-24 17:17:15 +01001236 if (!servername) {
Willy Tarreauf6721452015-07-07 18:04:38 +02001237 if (s->generate_certs) {
1238 struct connection *conn = (struct connection *)SSL_get_app_data(ssl);
1239 unsigned int serial;
1240 SSL_CTX *ctx;
Christopher Faulet30548802015-06-11 13:39:32 +02001241
Willy Tarreauf6721452015-07-07 18:04:38 +02001242 conn_get_to_addr(conn);
1243 if (conn->flags & CO_FL_ADDR_TO_SET) {
1244 serial = ssl_sock_generated_cert_serial(&conn->addr.to, get_addr_len(&conn->addr.to));
Christopher Faulet7969a332015-10-09 11:15:03 +02001245 ctx = ssl_sock_get_generated_cert(serial, s);
Willy Tarreauf6721452015-07-07 18:04:38 +02001246 if (ctx) {
1247 /* switch ctx */
1248 SSL_set_SSL_CTX(ssl, ctx);
1249 return SSL_TLSEXT_ERR_OK;
1250 }
Christopher Faulet30548802015-06-11 13:39:32 +02001251 }
1252 }
1253
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +02001254 return (s->strict_sni ?
1255 SSL_TLSEXT_ERR_ALERT_FATAL :
Emmanuel Hocdet79274e22013-05-31 12:47:44 +02001256 SSL_TLSEXT_ERR_NOACK);
Emmanuel Hocdet65623372013-01-24 17:17:15 +01001257 }
Emeric Brunfc0421f2012-09-07 17:30:07 +02001258
Willy Tarreau19d14ef2012-10-29 16:51:55 +01001259 for (i = 0; i < trash.size; i++) {
Emeric Brunfc0421f2012-09-07 17:30:07 +02001260 if (!servername[i])
1261 break;
Willy Tarreau19d14ef2012-10-29 16:51:55 +01001262 trash.str[i] = tolower(servername[i]);
1263 if (!wildp && (trash.str[i] == '.'))
1264 wildp = &trash.str[i];
Emeric Brunfc0421f2012-09-07 17:30:07 +02001265 }
Willy Tarreau19d14ef2012-10-29 16:51:55 +01001266 trash.str[i] = 0;
Emeric Brunfc0421f2012-09-07 17:30:07 +02001267
1268 /* lookup in full qualified names */
Willy Tarreau19d14ef2012-10-29 16:51:55 +01001269 node = ebst_lookup(&s->sni_ctx, trash.str);
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +02001270
1271 /* lookup a not neg filter */
1272 for (n = node; n; n = ebmb_next_dup(n)) {
1273 if (!container_of(n, struct sni_ctx, name)->neg) {
1274 node = n;
1275 break;
Emmanuel Hocdet65623372013-01-24 17:17:15 +01001276 }
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +02001277 }
1278 if (!node && wildp) {
1279 /* lookup in wildcards names */
Emeric Brunfc0421f2012-09-07 17:30:07 +02001280 node = ebst_lookup(&s->sni_w_ctx, wildp);
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +02001281 }
1282 if (!node || container_of(node, struct sni_ctx, name)->neg) {
Christopher Faulet31af49d2015-06-09 17:29:50 +02001283 SSL_CTX *ctx;
Christopher Faulet31af49d2015-06-09 17:29:50 +02001284 if (s->generate_certs &&
Christopher Faulet7969a332015-10-09 11:15:03 +02001285 (ctx = ssl_sock_generate_certificate(servername, s, ssl))) {
Christopher Faulet31af49d2015-06-09 17:29:50 +02001286 /* switch ctx */
Christopher Faulet31af49d2015-06-09 17:29:50 +02001287 return SSL_TLSEXT_ERR_OK;
1288 }
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +02001289 return (s->strict_sni ?
1290 SSL_TLSEXT_ERR_ALERT_FATAL :
1291 SSL_TLSEXT_ERR_ALERT_WARNING);
Emeric Brunfc0421f2012-09-07 17:30:07 +02001292 }
1293
1294 /* switch ctx */
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +02001295 SSL_set_SSL_CTX(ssl, container_of(node, struct sni_ctx, name)->ctx);
Emeric Brunfc0421f2012-09-07 17:30:07 +02001296 return SSL_TLSEXT_ERR_OK;
1297}
1298#endif /* SSL_CTRL_SET_TLSEXT_HOSTNAME */
1299
Emeric Bruna4bcd9a2012-09-20 16:19:02 +02001300#ifndef OPENSSL_NO_DH
Remi Gacognef46cd6e2014-06-12 14:58:40 +02001301
1302static DH * ssl_get_dh_1024(void)
1303{
Remi Gacogned3a341a2015-05-29 16:26:17 +02001304 static unsigned char dh1024_p[]={
1305 0xFA,0xF9,0x2A,0x22,0x2A,0xA7,0x7F,0xE1,0x67,0x4E,0x53,0xF7,
1306 0x56,0x13,0xC3,0xB1,0xE3,0x29,0x6B,0x66,0x31,0x6A,0x7F,0xB3,
1307 0xC2,0x68,0x6B,0xCB,0x1D,0x57,0x39,0x1D,0x1F,0xFF,0x1C,0xC9,
1308 0xA6,0xA4,0x98,0x82,0x31,0x5D,0x25,0xFF,0x8A,0xE0,0x73,0x96,
1309 0x81,0xC8,0x83,0x79,0xC1,0x5A,0x04,0xF8,0x37,0x0D,0xA8,0x3D,
1310 0xAE,0x74,0xBC,0xDB,0xB6,0xA4,0x75,0xD9,0x71,0x8A,0xA0,0x17,
1311 0x9E,0x2D,0xC8,0xA8,0xDF,0x2C,0x5F,0x82,0x95,0xF8,0x92,0x9B,
1312 0xA7,0x33,0x5F,0x89,0x71,0xC8,0x2D,0x6B,0x18,0x86,0xC4,0x94,
1313 0x22,0xA5,0x52,0x8D,0xF6,0xF6,0xD2,0x37,0x92,0x0F,0xA5,0xCC,
1314 0xDB,0x7B,0x1D,0x3D,0xA1,0x31,0xB7,0x80,0x8F,0x0B,0x67,0x5E,
1315 0x36,0xA5,0x60,0x0C,0xF1,0x95,0x33,0x8B,
1316 };
1317 static unsigned char dh1024_g[]={
1318 0x02,
1319 };
1320
Remi Gacognef46cd6e2014-06-12 14:58:40 +02001321 DH *dh = DH_new();
1322 if (dh) {
Remi Gacogned3a341a2015-05-29 16:26:17 +02001323 dh->p = BN_bin2bn(dh1024_p, sizeof dh1024_p, NULL);
1324 dh->g = BN_bin2bn(dh1024_g, sizeof dh1024_g, NULL);
1325
Remi Gacognef46cd6e2014-06-12 14:58:40 +02001326 if (!dh->p || !dh->g) {
1327 DH_free(dh);
1328 dh = NULL;
1329 }
1330 }
1331 return dh;
1332}
1333
1334static DH *ssl_get_dh_2048(void)
1335{
Remi Gacogned3a341a2015-05-29 16:26:17 +02001336 static unsigned char dh2048_p[]={
1337 0xEC,0x86,0xF8,0x70,0xA0,0x33,0x16,0xEC,0x05,0x1A,0x73,0x59,
1338 0xCD,0x1F,0x8B,0xF8,0x29,0xE4,0xD2,0xCF,0x52,0xDD,0xC2,0x24,
1339 0x8D,0xB5,0x38,0x9A,0xFB,0x5C,0xA4,0xE4,0xB2,0xDA,0xCE,0x66,
1340 0x50,0x74,0xA6,0x85,0x4D,0x4B,0x1D,0x30,0xB8,0x2B,0xF3,0x10,
1341 0xE9,0xA7,0x2D,0x05,0x71,0xE7,0x81,0xDF,0x8B,0x59,0x52,0x3B,
1342 0x5F,0x43,0x0B,0x68,0xF1,0xDB,0x07,0xBE,0x08,0x6B,0x1B,0x23,
1343 0xEE,0x4D,0xCC,0x9E,0x0E,0x43,0xA0,0x1E,0xDF,0x43,0x8C,0xEC,
1344 0xBE,0xBE,0x90,0xB4,0x51,0x54,0xB9,0x2F,0x7B,0x64,0x76,0x4E,
1345 0x5D,0xD4,0x2E,0xAE,0xC2,0x9E,0xAE,0x51,0x43,0x59,0xC7,0x77,
1346 0x9C,0x50,0x3C,0x0E,0xED,0x73,0x04,0x5F,0xF1,0x4C,0x76,0x2A,
1347 0xD8,0xF8,0xCF,0xFC,0x34,0x40,0xD1,0xB4,0x42,0x61,0x84,0x66,
1348 0x42,0x39,0x04,0xF8,0x68,0xB2,0x62,0xD7,0x55,0xED,0x1B,0x74,
1349 0x75,0x91,0xE0,0xC5,0x69,0xC1,0x31,0x5C,0xDB,0x7B,0x44,0x2E,
1350 0xCE,0x84,0x58,0x0D,0x1E,0x66,0x0C,0xC8,0x44,0x9E,0xFD,0x40,
1351 0x08,0x67,0x5D,0xFB,0xA7,0x76,0x8F,0x00,0x11,0x87,0xE9,0x93,
1352 0xF9,0x7D,0xC4,0xBC,0x74,0x55,0x20,0xD4,0x4A,0x41,0x2F,0x43,
1353 0x42,0x1A,0xC1,0xF2,0x97,0x17,0x49,0x27,0x37,0x6B,0x2F,0x88,
1354 0x7E,0x1C,0xA0,0xA1,0x89,0x92,0x27,0xD9,0x56,0x5A,0x71,0xC1,
1355 0x56,0x37,0x7E,0x3A,0x9D,0x05,0xE7,0xEE,0x5D,0x8F,0x82,0x17,
1356 0xBC,0xE9,0xC2,0x93,0x30,0x82,0xF9,0xF4,0xC9,0xAE,0x49,0xDB,
1357 0xD0,0x54,0xB4,0xD9,0x75,0x4D,0xFA,0x06,0xB8,0xD6,0x38,0x41,
1358 0xB7,0x1F,0x77,0xF3,
1359 };
1360 static unsigned char dh2048_g[]={
1361 0x02,
1362 };
1363
Remi Gacognef46cd6e2014-06-12 14:58:40 +02001364 DH *dh = DH_new();
1365 if (dh) {
Remi Gacogned3a341a2015-05-29 16:26:17 +02001366 dh->p = BN_bin2bn(dh2048_p, sizeof dh2048_p, NULL);
1367 dh->g = BN_bin2bn(dh2048_g, sizeof dh2048_g, NULL);
1368
Remi Gacognef46cd6e2014-06-12 14:58:40 +02001369 if (!dh->p || !dh->g) {
1370 DH_free(dh);
1371 dh = NULL;
1372 }
1373 }
1374 return dh;
1375}
1376
1377static DH *ssl_get_dh_4096(void)
1378{
Remi Gacogned3a341a2015-05-29 16:26:17 +02001379 static unsigned char dh4096_p[]={
1380 0xDE,0x16,0x94,0xCD,0x99,0x58,0x07,0xF1,0xF7,0x32,0x96,0x11,
1381 0x04,0x82,0xD4,0x84,0x72,0x80,0x99,0x06,0xCA,0xF0,0xA3,0x68,
1382 0x07,0xCE,0x64,0x50,0xE7,0x74,0x45,0x20,0x80,0x5E,0x4D,0xAD,
1383 0xA5,0xB6,0xED,0xFA,0x80,0x6C,0x3B,0x35,0xC4,0x9A,0x14,0x6B,
1384 0x32,0xBB,0xFD,0x1F,0x17,0x8E,0xB7,0x1F,0xD6,0xFA,0x3F,0x7B,
1385 0xEE,0x16,0xA5,0x62,0x33,0x0D,0xED,0xBC,0x4E,0x58,0xE5,0x47,
1386 0x4D,0xE9,0xAB,0x8E,0x38,0xD3,0x6E,0x90,0x57,0xE3,0x22,0x15,
1387 0x33,0xBD,0xF6,0x43,0x45,0xB5,0x10,0x0A,0xBE,0x2C,0xB4,0x35,
1388 0xB8,0x53,0x8D,0xAD,0xFB,0xA7,0x1F,0x85,0x58,0x41,0x7A,0x79,
1389 0x20,0x68,0xB3,0xE1,0x3D,0x08,0x76,0xBF,0x86,0x0D,0x49,0xE3,
1390 0x82,0x71,0x8C,0xB4,0x8D,0x81,0x84,0xD4,0xE7,0xBE,0x91,0xDC,
1391 0x26,0x39,0x48,0x0F,0x35,0xC4,0xCA,0x65,0xE3,0x40,0x93,0x52,
1392 0x76,0x58,0x7D,0xDD,0x51,0x75,0xDC,0x69,0x61,0xBF,0x47,0x2C,
1393 0x16,0x68,0x2D,0xC9,0x29,0xD3,0xE6,0xC0,0x99,0x48,0xA0,0x9A,
1394 0xC8,0x78,0xC0,0x6D,0x81,0x67,0x12,0x61,0x3F,0x71,0xBA,0x41,
1395 0x1F,0x6C,0x89,0x44,0x03,0xBA,0x3B,0x39,0x60,0xAA,0x28,0x55,
1396 0x59,0xAE,0xB8,0xFA,0xCB,0x6F,0xA5,0x1A,0xF7,0x2B,0xDD,0x52,
1397 0x8A,0x8B,0xE2,0x71,0xA6,0x5E,0x7E,0xD8,0x2E,0x18,0xE0,0x66,
1398 0xDF,0xDD,0x22,0x21,0x99,0x52,0x73,0xA6,0x33,0x20,0x65,0x0E,
1399 0x53,0xE7,0x6B,0x9B,0xC5,0xA3,0x2F,0x97,0x65,0x76,0xD3,0x47,
1400 0x23,0x77,0x12,0xB6,0x11,0x7B,0x24,0xED,0xF1,0xEF,0xC0,0xE2,
1401 0xA3,0x7E,0x67,0x05,0x3E,0x96,0x4D,0x45,0xC2,0x18,0xD1,0x73,
1402 0x9E,0x07,0xF3,0x81,0x6E,0x52,0x63,0xF6,0x20,0x76,0xB9,0x13,
1403 0xD2,0x65,0x30,0x18,0x16,0x09,0x16,0x9E,0x8F,0xF1,0xD2,0x10,
1404 0x5A,0xD3,0xD4,0xAF,0x16,0x61,0xDA,0x55,0x2E,0x18,0x5E,0x14,
1405 0x08,0x54,0x2E,0x2A,0x25,0xA2,0x1A,0x9B,0x8B,0x32,0xA9,0xFD,
1406 0xC2,0x48,0x96,0xE1,0x80,0xCA,0xE9,0x22,0x17,0xBB,0xCE,0x3E,
1407 0x9E,0xED,0xC7,0xF1,0x1F,0xEC,0x17,0x21,0xDC,0x7B,0x82,0x48,
1408 0x8E,0xBB,0x4B,0x9D,0x5B,0x04,0x04,0xDA,0xDB,0x39,0xDF,0x01,
1409 0x40,0xC3,0xAA,0x26,0x23,0x89,0x75,0xC6,0x0B,0xD0,0xA2,0x60,
1410 0x6A,0xF1,0xCC,0x65,0x18,0x98,0x1B,0x52,0xD2,0x74,0x61,0xCC,
1411 0xBD,0x60,0xAE,0xA3,0xA0,0x66,0x6A,0x16,0x34,0x92,0x3F,0x41,
1412 0x40,0x31,0x29,0xC0,0x2C,0x63,0xB2,0x07,0x8D,0xEB,0x94,0xB8,
1413 0xE8,0x47,0x92,0x52,0x93,0x6A,0x1B,0x7E,0x1A,0x61,0xB3,0x1B,
1414 0xF0,0xD6,0x72,0x9B,0xF1,0xB0,0xAF,0xBF,0x3E,0x65,0xEF,0x23,
1415 0x1D,0x6F,0xFF,0x70,0xCD,0x8A,0x4C,0x8A,0xA0,0x72,0x9D,0xBE,
1416 0xD4,0xBB,0x24,0x47,0x4A,0x68,0xB5,0xF5,0xC6,0xD5,0x7A,0xCD,
1417 0xCA,0x06,0x41,0x07,0xAD,0xC2,0x1E,0xE6,0x54,0xA7,0xAD,0x03,
1418 0xD9,0x12,0xC1,0x9C,0x13,0xB1,0xC9,0x0A,0x43,0x8E,0x1E,0x08,
1419 0xCE,0x50,0x82,0x73,0x5F,0xA7,0x55,0x1D,0xD9,0x59,0xAC,0xB5,
1420 0xEA,0x02,0x7F,0x6C,0x5B,0x74,0x96,0x98,0x67,0x24,0xA3,0x0F,
1421 0x15,0xFC,0xA9,0x7D,0x3E,0x67,0xD1,0x70,0xF8,0x97,0xF3,0x67,
1422 0xC5,0x8C,0x88,0x44,0x08,0x02,0xC7,0x2B,
Remi Gacognef46cd6e2014-06-12 14:58:40 +02001423 };
Remi Gacogned3a341a2015-05-29 16:26:17 +02001424 static unsigned char dh4096_g[]={
1425 0x02,
1426 };
Remi Gacognef46cd6e2014-06-12 14:58:40 +02001427
Remi Gacognef46cd6e2014-06-12 14:58:40 +02001428 DH *dh = DH_new();
1429 if (dh) {
Remi Gacogned3a341a2015-05-29 16:26:17 +02001430 dh->p = BN_bin2bn(dh4096_p, sizeof dh4096_p, NULL);
1431 dh->g = BN_bin2bn(dh4096_g, sizeof dh4096_g, NULL);
1432
Remi Gacognef46cd6e2014-06-12 14:58:40 +02001433 if (!dh->p || !dh->g) {
1434 DH_free(dh);
1435 dh = NULL;
1436 }
1437 }
1438 return dh;
1439}
1440
1441/* Returns Diffie-Hellman parameters matching the private key length
1442 but not exceeding global.tune.ssl_default_dh_param */
1443static DH *ssl_get_tmp_dh(SSL *ssl, int export, int keylen)
1444{
1445 DH *dh = NULL;
1446 EVP_PKEY *pkey = SSL_get_privatekey(ssl);
1447 int type = pkey ? EVP_PKEY_type(pkey->type) : EVP_PKEY_NONE;
1448
1449 /* The keylen supplied by OpenSSL can only be 512 or 1024.
1450 See ssl3_send_server_key_exchange() in ssl/s3_srvr.c
1451 */
1452 if (type == EVP_PKEY_RSA || type == EVP_PKEY_DSA) {
1453 keylen = EVP_PKEY_bits(pkey);
1454 }
1455
1456 if (keylen > global.tune.ssl_default_dh_param) {
1457 keylen = global.tune.ssl_default_dh_param;
1458 }
1459
Remi Gacogned3a341a2015-05-29 16:26:17 +02001460 if (keylen >= 4096) {
Remi Gacogne8de54152014-07-15 11:36:40 +02001461 dh = local_dh_4096;
Remi Gacognef46cd6e2014-06-12 14:58:40 +02001462 }
1463 else if (keylen >= 2048) {
Remi Gacogne8de54152014-07-15 11:36:40 +02001464 dh = local_dh_2048;
Remi Gacognef46cd6e2014-06-12 14:58:40 +02001465 }
1466 else {
Remi Gacogne8de54152014-07-15 11:36:40 +02001467 dh = local_dh_1024;
Remi Gacognef46cd6e2014-06-12 14:58:40 +02001468 }
1469
1470 return dh;
1471}
1472
Remi Gacogne47783ef2015-05-29 15:53:22 +02001473static DH * ssl_sock_get_dh_from_file(const char *filename)
Emeric Bruna4bcd9a2012-09-20 16:19:02 +02001474{
Emeric Bruna4bcd9a2012-09-20 16:19:02 +02001475 DH *dh = NULL;
Remi Gacogne47783ef2015-05-29 15:53:22 +02001476 BIO *in = BIO_new(BIO_s_file());
Emeric Bruna4bcd9a2012-09-20 16:19:02 +02001477
Emeric Bruna4bcd9a2012-09-20 16:19:02 +02001478 if (in == NULL)
1479 goto end;
1480
Remi Gacogne47783ef2015-05-29 15:53:22 +02001481 if (BIO_read_filename(in, filename) <= 0)
Emeric Bruna4bcd9a2012-09-20 16:19:02 +02001482 goto end;
1483
Remi Gacogne47783ef2015-05-29 15:53:22 +02001484 dh = PEM_read_bio_DHparams(in, NULL, NULL, NULL);
1485
1486end:
1487 if (in)
1488 BIO_free(in);
1489
1490 return dh;
1491}
1492
1493int ssl_sock_load_global_dh_param_from_file(const char *filename)
1494{
1495 global_dh = ssl_sock_get_dh_from_file(filename);
1496
1497 if (global_dh) {
1498 return 0;
1499 }
1500
1501 return -1;
1502}
1503
1504/* Loads Diffie-Hellman parameter from a file. Returns 1 if loaded, else -1
1505 if an error occured, and 0 if parameter not found. */
1506int ssl_sock_load_dh_params(SSL_CTX *ctx, const char *file)
1507{
1508 int ret = -1;
1509 DH *dh = ssl_sock_get_dh_from_file(file);
1510
Remi Gacognef46cd6e2014-06-12 14:58:40 +02001511 if (dh) {
1512 ret = 1;
1513 SSL_CTX_set_tmp_dh(ctx, dh);
Remi Gacogne4f902b82015-05-28 16:23:00 +02001514
1515 if (ssl_dh_ptr_index >= 0) {
1516 /* store a pointer to the DH params to avoid complaining about
1517 ssl-default-dh-param not being set for this SSL_CTX */
1518 SSL_CTX_set_ex_data(ctx, ssl_dh_ptr_index, dh);
1519 }
Remi Gacognef46cd6e2014-06-12 14:58:40 +02001520 }
Remi Gacogne47783ef2015-05-29 15:53:22 +02001521 else if (global_dh) {
1522 SSL_CTX_set_tmp_dh(ctx, global_dh);
1523 ret = 0; /* DH params not found */
1524 }
Remi Gacognef46cd6e2014-06-12 14:58:40 +02001525 else {
Emeric Brun41fdb3c2013-04-26 11:05:44 +02001526 /* Clear openssl global errors stack */
1527 ERR_clear_error();
1528
Remi Gacognef46cd6e2014-06-12 14:58:40 +02001529 if (global.tune.ssl_default_dh_param <= 1024) {
1530 /* we are limited to DH parameter of 1024 bits anyway */
Remi Gacogne8de54152014-07-15 11:36:40 +02001531 local_dh_1024 = ssl_get_dh_1024();
1532 if (local_dh_1024 == NULL)
Remi Gacognef46cd6e2014-06-12 14:58:40 +02001533 goto end;
Willy Tarreau6e774b42014-04-25 21:35:23 +02001534
Remi Gacogne8de54152014-07-15 11:36:40 +02001535 SSL_CTX_set_tmp_dh(ctx, local_dh_1024);
Remi Gacognef46cd6e2014-06-12 14:58:40 +02001536 }
1537 else {
1538 SSL_CTX_set_tmp_dh_callback(ctx, ssl_get_tmp_dh);
1539 }
Willy Tarreau6e774b42014-04-25 21:35:23 +02001540
Emeric Brun41fdb3c2013-04-26 11:05:44 +02001541 ret = 0; /* DH params not found */
Emeric Bruna4bcd9a2012-09-20 16:19:02 +02001542 }
Emeric Brun644cde02012-12-14 11:21:13 +01001543
Emeric Bruna4bcd9a2012-09-20 16:19:02 +02001544end:
1545 if (dh)
1546 DH_free(dh);
1547
Emeric Bruna4bcd9a2012-09-20 16:19:02 +02001548 return ret;
1549}
1550#endif
1551
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +02001552static int ssl_sock_add_cert_sni(SSL_CTX *ctx, struct bind_conf *s, char *name, int order)
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01001553{
1554 struct sni_ctx *sc;
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +02001555 int wild = 0, neg = 0;
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01001556
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +02001557 if (*name == '!') {
1558 neg = 1;
1559 name++;
1560 }
1561 if (*name == '*') {
1562 wild = 1;
1563 name++;
1564 }
1565 /* !* filter is a nop */
1566 if (neg && wild)
1567 return order;
1568 if (*name) {
1569 int j, len;
1570 len = strlen(name);
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01001571 sc = malloc(sizeof(struct sni_ctx) + len + 1);
1572 for (j = 0; j < len; j++)
1573 sc->name.key[j] = tolower(name[j]);
1574 sc->name.key[len] = 0;
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01001575 sc->ctx = ctx;
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +02001576 sc->order = order++;
1577 sc->neg = neg;
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01001578 if (wild)
1579 ebst_insert(&s->sni_w_ctx, &sc->name);
1580 else
1581 ebst_insert(&s->sni_ctx, &sc->name);
1582 }
1583 return order;
1584}
1585
yanbzhu488a4d22015-12-01 15:16:07 -05001586
1587/* The following code is used for loading multiple crt files into
1588 * SSL_CTX's based on CN/SAN
1589 */
1590#if OPENSSL_VERSION_NUMBER >= 0x1000200fL
1591/* This is used to preload the certifcate, private key
1592 * and Cert Chain of a file passed in via the crt
1593 * argument
1594 *
1595 * This way, we do not have to read the file multiple times
1596 */
1597struct cert_key_and_chain {
1598 X509 *cert;
1599 EVP_PKEY *key;
1600 unsigned int num_chain_certs;
1601 /* This is an array of X509 pointers */
1602 X509 **chain_certs;
1603};
1604
yanbzhu08ce6ab2015-12-02 13:01:29 -05001605/* The order here matters for picking a default context,
1606 * keep the most common keytype at the bottom of the list
1607 */
1608const char *SSL_SOCK_KEYTYPE_NAMES[] = {
1609 "dsa",
1610 "ecdsa",
1611 "rsa"
1612};
1613#define SSL_SOCK_NUM_KEYTYPES 3
1614#define SSL_SOCK_POSSIBLE_KT_COMBOS (1<<(SSL_SOCK_NUM_KEYTYPES))
1615
1616struct key_combo_ctx {
1617 SSL_CTX *ctx;
1618 int order;
1619};
1620
1621/* Map used for processing multiple keypairs for a single purpose
1622 *
1623 * This maps CN/SNI name to certificate type
1624 */
1625struct sni_keytype {
1626 int keytypes; /* BITMASK for keytypes */
1627 struct ebmb_node name; /* node holding the servername value */
1628};
1629
1630
yanbzhu488a4d22015-12-01 15:16:07 -05001631/* Frees the contents of a cert_key_and_chain
1632 */
1633static void ssl_sock_free_cert_key_and_chain_contents(struct cert_key_and_chain *ckch)
1634{
1635 int i;
1636
1637 if (!ckch)
1638 return;
1639
1640 /* Free the certificate and set pointer to NULL */
1641 if (ckch->cert)
1642 X509_free(ckch->cert);
1643 ckch->cert = NULL;
1644
1645 /* Free the key and set pointer to NULL */
1646 if (ckch->key)
1647 EVP_PKEY_free(ckch->key);
1648 ckch->key = NULL;
1649
1650 /* Free each certificate in the chain */
1651 for (i = 0; i < ckch->num_chain_certs; i++) {
1652 if (ckch->chain_certs[i])
1653 X509_free(ckch->chain_certs[i]);
1654 }
1655
1656 /* Free the chain obj itself and set to NULL */
1657 if (ckch->num_chain_certs > 0) {
1658 free(ckch->chain_certs);
1659 ckch->num_chain_certs = 0;
1660 ckch->chain_certs = NULL;
1661 }
1662
1663}
1664
1665/* checks if a key and cert exists in the ckch
1666 */
1667static int ssl_sock_is_ckch_valid(struct cert_key_and_chain *ckch)
1668{
1669 return (ckch->cert != NULL && ckch->key != NULL);
1670}
1671
1672
1673/* Loads the contents of a crt file (path) into a cert_key_and_chain
1674 * This allows us to carry the contents of the file without having to
1675 * read the file multiple times.
1676 *
1677 * returns:
1678 * 0 on Success
1679 * 1 on SSL Failure
1680 * 2 on file not found
1681 */
1682static int ssl_sock_load_crt_file_into_ckch(const char *path, struct cert_key_and_chain *ckch, char **err)
1683{
1684
1685 BIO *in;
1686 X509 *ca = NULL;
1687 int ret = 1;
1688
1689 ssl_sock_free_cert_key_and_chain_contents(ckch);
1690
1691 in = BIO_new(BIO_s_file());
1692 if (in == NULL)
1693 goto end;
1694
1695 if (BIO_read_filename(in, path) <= 0)
1696 goto end;
1697
1698 /* Read Certificate */
1699 ckch->cert = PEM_read_bio_X509_AUX(in, NULL, NULL, NULL);
1700 if (ckch->cert == NULL) {
1701 memprintf(err, "%sunable to load certificate from file '%s'.\n",
1702 err && *err ? *err : "", path);
1703 goto end;
1704 }
1705
1706 /* Read Private Key */
1707 ckch->key = PEM_read_bio_PrivateKey(in, NULL, NULL, NULL);
1708 if (ckch->key == NULL) {
1709 memprintf(err, "%sunable to load private key from file '%s'.\n",
1710 err && *err ? *err : "", path);
1711 goto end;
1712 }
1713
1714 /* Read Certificate Chain */
1715 while ((ca = PEM_read_bio_X509(in, NULL, NULL, NULL))) {
1716 /* Grow the chain certs */
1717 ckch->num_chain_certs++;
1718 ckch->chain_certs = realloc(ckch->chain_certs, (ckch->num_chain_certs * sizeof(X509 *)));
1719
1720 /* use - 1 here since we just incremented it above */
1721 ckch->chain_certs[ckch->num_chain_certs - 1] = ca;
1722 }
1723 ret = ERR_get_error();
1724 if (ret && (ERR_GET_LIB(ret) != ERR_LIB_PEM && ERR_GET_REASON(ret) != PEM_R_NO_START_LINE)) {
1725 memprintf(err, "%sunable to load certificate chain from file '%s'.\n",
1726 err && *err ? *err : "", path);
1727 ret = 1;
1728 goto end;
1729 }
1730
1731 ret = 0;
1732
1733end:
1734
1735 ERR_clear_error();
1736 if (in)
1737 BIO_free(in);
1738
1739 /* Something went wrong in one of the reads */
1740 if (ret != 0)
1741 ssl_sock_free_cert_key_and_chain_contents(ckch);
1742
1743 return ret;
1744}
1745
1746/* Loads the info in ckch into ctx
1747 * Currently, this does not process any information about ocsp, dhparams or
1748 * sctl
1749 * Returns
1750 * 0 on success
1751 * 1 on failure
1752 */
1753static int ssl_sock_put_ckch_into_ctx(const char *path, const struct cert_key_and_chain *ckch, SSL_CTX *ctx, char **err)
1754{
1755 int i = 0;
1756
1757 if (SSL_CTX_use_PrivateKey(ctx, ckch->key) <= 0) {
1758 memprintf(err, "%sunable to load SSL private key into SSL Context '%s'.\n",
1759 err && *err ? *err : "", path);
1760 return 1;
1761 }
1762
1763 if (!SSL_CTX_use_certificate(ctx, ckch->cert)) {
1764 memprintf(err, "%sunable to load SSL certificate into SSL Context '%s'.\n",
1765 err && *err ? *err : "", path);
1766 return 1;
1767 }
1768
yanbzhu488a4d22015-12-01 15:16:07 -05001769 /* Load all certs in the ckch into the ctx_chain for the ssl_ctx */
1770 for (i = 0; i < ckch->num_chain_certs; i++) {
1771 if (!SSL_CTX_add1_chain_cert(ctx, ckch->chain_certs[i])) {
yanbzhu08ce6ab2015-12-02 13:01:29 -05001772 memprintf(err, "%sunable to load chain certificate #%d into SSL Context '%s'. Make sure you are linking against Openssl >= 1.0.2.\n",
1773 err && *err ? *err : "", (i+1), path);
yanbzhu488a4d22015-12-01 15:16:07 -05001774 return 1;
1775 }
1776 }
1777
1778 if (SSL_CTX_check_private_key(ctx) <= 0) {
1779 memprintf(err, "%sinconsistencies between private key and certificate loaded from PEM file '%s'.\n",
1780 err && *err ? *err : "", path);
1781 return 1;
1782 }
1783
1784 return 0;
1785}
1786
yanbzhu08ce6ab2015-12-02 13:01:29 -05001787
1788static void ssl_sock_populate_sni_keytypes_hplr(const char *str, struct eb_root *sni_keytypes, int key_index)
1789{
1790 struct sni_keytype *s_kt = NULL;
1791 struct ebmb_node *node;
1792 int i;
1793
1794 for (i = 0; i < trash.size; i++) {
1795 if (!str[i])
1796 break;
1797 trash.str[i] = tolower(str[i]);
1798 }
1799 trash.str[i] = 0;
1800 node = ebst_lookup(sni_keytypes, trash.str);
1801 if (!node) {
1802 /* CN not found in tree */
1803 s_kt = malloc(sizeof(struct sni_keytype) + i + 1);
1804 /* Using memcpy here instead of strncpy.
1805 * strncpy will cause sig_abrt errors under certain versions of gcc with -O2
1806 * See: https://gcc.gnu.org/bugzilla/show_bug.cgi?id=60792
1807 */
1808 memcpy(s_kt->name.key, trash.str, i+1);
1809 s_kt->keytypes = 0;
1810 ebst_insert(sni_keytypes, &s_kt->name);
1811 } else {
1812 /* CN found in tree */
1813 s_kt = container_of(node, struct sni_keytype, name);
1814 }
1815
1816 /* Mark that this CN has the keytype of key_index via keytypes mask */
1817 s_kt->keytypes |= 1<<key_index;
1818
1819}
1820
1821
1822/* Given a path that does not exist, try to check for path.rsa, path.dsa and path.ecdsa files.
1823 * If any are found, group these files into a set of SSL_CTX*
1824 * based on shared and unique CN and SAN entries. Add these SSL_CTX* to the SNI tree.
1825 *
1826 * This will allow the user to explictly group multiple cert/keys for a single purpose
1827 *
1828 * Returns
1829 * 0 on success
1830 * 1 on failure
1831 */
1832static int ssl_sock_load_multi_cert(const char *path, struct bind_conf *bind_conf, struct proxy *curproxy, char **sni_filter, char **err)
1833{
1834 char fp[MAXPATHLEN+1] = {0};
1835 int n = 0;
1836 int i = 0;
1837 struct cert_key_and_chain certs_and_keys[SSL_SOCK_NUM_KEYTYPES] = { {0} };
1838 struct eb_root sni_keytypes_map = { {0} };
1839 struct ebmb_node *node;
1840 struct ebmb_node *next;
1841 /* Array of SSL_CTX pointers corresponding to each possible combo
1842 * of keytypes
1843 */
1844 struct key_combo_ctx key_combos[SSL_SOCK_POSSIBLE_KT_COMBOS] = { {0} };
1845 int rv = 0;
1846 X509_NAME *xname = NULL;
1847 char *str = NULL;
1848#ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME
1849 STACK_OF(GENERAL_NAME) *names = NULL;
1850#endif
1851
1852 /* Load all possible certs and keys */
1853 for (n = 0; n < SSL_SOCK_NUM_KEYTYPES; n++) {
1854 struct stat buf;
1855
1856 snprintf(fp, sizeof(fp), "%s.%s", path, SSL_SOCK_KEYTYPE_NAMES[n]);
1857 if (stat(fp, &buf) == 0) {
1858 if (ssl_sock_load_crt_file_into_ckch(fp, &certs_and_keys[n], err) == 1) {
1859 rv = 1;
1860 goto end;
1861 }
1862 }
1863 }
1864
1865 /* Process each ckch and update keytypes for each CN/SAN
1866 * for example, if CN/SAN www.a.com is associated with
1867 * certs with keytype 0 and 2, then at the end of the loop,
1868 * www.a.com will have:
1869 * keyindex = 0 | 1 | 4 = 5
1870 */
1871 for (n = 0; n < SSL_SOCK_NUM_KEYTYPES; n++) {
1872
1873 if (!ssl_sock_is_ckch_valid(&certs_and_keys[n]))
1874 continue;
1875
1876 /* A lot of the following code is OpenSSL boilerplate for processing CN's and SAN's,
1877 * so the line that contains logic is marked via comments
1878 */
1879 xname = X509_get_subject_name(certs_and_keys[n].cert);
1880 i = -1;
1881 while ((i = X509_NAME_get_index_by_NID(xname, NID_commonName, i)) != -1) {
1882 X509_NAME_ENTRY *entry = X509_NAME_get_entry(xname, i);
1883
1884 if (ASN1_STRING_to_UTF8((unsigned char **)&str, entry->value) >= 0) {
1885 /* Important line is here */
1886 ssl_sock_populate_sni_keytypes_hplr(str, &sni_keytypes_map, n);
1887
1888 OPENSSL_free(str);
1889 str = NULL;
1890 }
1891 }
1892
1893 /* Do the above logic for each SAN */
1894#ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME
1895 names = X509_get_ext_d2i(certs_and_keys[n].cert, NID_subject_alt_name, NULL, NULL);
1896 if (names) {
1897 for (i = 0; i < sk_GENERAL_NAME_num(names); i++) {
1898 GENERAL_NAME *name = sk_GENERAL_NAME_value(names, i);
1899
1900 if (name->type == GEN_DNS) {
1901 if (ASN1_STRING_to_UTF8((unsigned char **)&str, name->d.dNSName) >= 0) {
1902 /* Important line is here */
1903 ssl_sock_populate_sni_keytypes_hplr(str, &sni_keytypes_map, n);
1904
1905 OPENSSL_free(str);
1906 str = NULL;
1907 }
1908 }
1909 }
1910 }
1911#endif /* SSL_CTRL_SET_TLSEXT_HOSTNAME */
1912 }
1913
1914 /* If no files found, return error */
1915 if (eb_is_empty(&sni_keytypes_map)) {
1916 memprintf(err, "%sunable to load SSL certificate file '%s' file does not exist.\n",
1917 err && *err ? *err : "", path);
1918 rv = 1;
1919 goto end;
1920 }
1921
1922 /* We now have a map of CN/SAN to keytypes that are loaded in
1923 * Iterate through the map to create the SSL_CTX's (if needed)
1924 * and add each CTX to the SNI tree
1925 *
1926 * Some math here:
1927 * There are 2^n - 1 possibile combinations, each unique
1928 * combination is denoted by the key in the map. Each key
1929 * has a value between 1 and 2^n - 1. Conveniently, the array
1930 * of SSL_CTX* is sized 2^n. So, we can simply use the i'th
1931 * entry in the array to correspond to the unique combo (key)
1932 * associated with i. This unique key combo (i) will be associated
1933 * with combos[i-1]
1934 */
1935
1936 node = ebmb_first(&sni_keytypes_map);
1937 while (node) {
1938 SSL_CTX *cur_ctx;
1939
1940 str = (char *)container_of(node, struct sni_keytype, name)->name.key;
1941 i = container_of(node, struct sni_keytype, name)->keytypes;
1942 cur_ctx = key_combos[i-1].ctx;
1943
1944 if (cur_ctx == NULL) {
1945 /* need to create SSL_CTX */
1946 cur_ctx = SSL_CTX_new(SSLv23_server_method());
1947 if (cur_ctx == NULL) {
1948 memprintf(err, "%sunable to allocate SSL context.\n",
1949 err && *err ? *err : "");
1950 rv = 1;
1951 goto end;
1952 }
1953
1954 /* Load all info into SSL_CTX */
1955 for (n = 0; n < SSL_SOCK_NUM_KEYTYPES; n++) {
1956 if (i & (1<<n)) {
1957 /* Key combo contains ckch[n] */
1958 snprintf(trash.str, trash.size, "%s.%s", path, SSL_SOCK_KEYTYPE_NAMES[n]);
1959 if (ssl_sock_put_ckch_into_ctx(trash.str, &certs_and_keys[n], cur_ctx, err) != 0) {
1960 SSL_CTX_free(cur_ctx);
1961 rv = 1;
1962 goto end;
1963 }
1964 }
1965 }
1966
1967 /* Load DH params into the ctx to support DHE keys */
1968#ifndef OPENSSL_NO_DH
1969 if (ssl_dh_ptr_index >= 0)
1970 SSL_CTX_set_ex_data(cur_ctx, ssl_dh_ptr_index, NULL);
1971
1972 rv = ssl_sock_load_dh_params(cur_ctx, NULL);
1973 if (rv < 0) {
1974 if (err)
1975 memprintf(err, "%sunable to load DH parameters from file '%s'.\n",
1976 *err ? *err : "", path);
1977 rv = 1;
1978 goto end;
1979 }
1980#endif
1981
1982 /* Update key_combos */
1983 key_combos[i-1].ctx = cur_ctx;
1984 }
1985
1986 /* Update SNI Tree */
1987 ssl_sock_add_cert_sni(cur_ctx, bind_conf, str, key_combos[i-1].order++);
1988 node = ebmb_next(node);
1989 }
1990
1991
1992 /* Mark a default context if none exists, using the ctx that has the most shared keys */
1993 if (!bind_conf->default_ctx) {
1994 for (i = SSL_SOCK_POSSIBLE_KT_COMBOS - 1; i >= 0; i--) {
1995 if (key_combos[i].ctx) {
1996 bind_conf->default_ctx = key_combos[i].ctx;
1997 break;
1998 }
1999 }
2000 }
2001
2002end:
2003
2004 if (names)
2005 sk_GENERAL_NAME_pop_free(names, GENERAL_NAME_free);
2006
2007 for (n = 0; n < SSL_SOCK_NUM_KEYTYPES; n++)
2008 ssl_sock_free_cert_key_and_chain_contents(&certs_and_keys[n]);
2009
2010 node = ebmb_first(&sni_keytypes_map);
2011 while (node) {
2012 next = ebmb_next(node);
2013 ebmb_delete(node);
2014 node = next;
2015 }
2016
2017 return rv;
2018}
2019#else
2020/* This is a dummy, that just logs an error and returns error */
2021static int ssl_sock_load_multi_cert(const char *path, struct bind_conf *bind_conf, struct proxy *curproxy, char **sni_filter, char **err)
2022{
2023 memprintf(err, "%sunable to stat SSL certificate from file '%s' : %s.\n",
2024 err && *err ? *err : "", path, strerror(errno));
2025 return 1;
2026}
2027
yanbzhu488a4d22015-12-01 15:16:07 -05002028#endif /* #if OPENSSL_VERSION_NUMBER >= 0x1000200fL: Support for loading multiple certs into a single SSL_CTX */
2029
Emeric Brunfc0421f2012-09-07 17:30:07 +02002030/* Loads a certificate key and CA chain from a file. Returns 0 on error, -1 if
2031 * an early error happens and the caller must call SSL_CTX_free() by itelf.
2032 */
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +02002033static 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 +02002034{
2035 BIO *in;
2036 X509 *x = NULL, *ca;
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +02002037 int i, err;
Emeric Brunfc0421f2012-09-07 17:30:07 +02002038 int ret = -1;
2039 int order = 0;
2040 X509_NAME *xname;
2041 char *str;
Emeric Brunfc0421f2012-09-07 17:30:07 +02002042#ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME
2043 STACK_OF(GENERAL_NAME) *names;
2044#endif
2045
2046 in = BIO_new(BIO_s_file());
2047 if (in == NULL)
2048 goto end;
2049
2050 if (BIO_read_filename(in, file) <= 0)
2051 goto end;
2052
2053 x = PEM_read_bio_X509_AUX(in, NULL, ctx->default_passwd_callback, ctx->default_passwd_callback_userdata);
2054 if (x == NULL)
2055 goto end;
2056
Emeric Brun50bcecc2013-04-22 13:05:23 +02002057 if (fcount) {
2058 while (fcount--)
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +02002059 order = ssl_sock_add_cert_sni(ctx, s, sni_filter[fcount], order);
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01002060 }
2061 else {
Emeric Brunfc0421f2012-09-07 17:30:07 +02002062#ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01002063 names = X509_get_ext_d2i(x, NID_subject_alt_name, NULL, NULL);
2064 if (names) {
2065 for (i = 0; i < sk_GENERAL_NAME_num(names); i++) {
2066 GENERAL_NAME *name = sk_GENERAL_NAME_value(names, i);
2067 if (name->type == GEN_DNS) {
2068 if (ASN1_STRING_to_UTF8((unsigned char **)&str, name->d.dNSName) >= 0) {
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +02002069 order = ssl_sock_add_cert_sni(ctx, s, str, order);
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01002070 OPENSSL_free(str);
Emeric Brunfc0421f2012-09-07 17:30:07 +02002071 }
Emeric Brunfc0421f2012-09-07 17:30:07 +02002072 }
2073 }
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01002074 sk_GENERAL_NAME_pop_free(names, GENERAL_NAME_free);
Emeric Brunfc0421f2012-09-07 17:30:07 +02002075 }
Emeric Brunfc0421f2012-09-07 17:30:07 +02002076#endif /* SSL_CTRL_SET_TLSEXT_HOSTNAME */
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01002077 xname = X509_get_subject_name(x);
2078 i = -1;
2079 while ((i = X509_NAME_get_index_by_NID(xname, NID_commonName, i)) != -1) {
2080 X509_NAME_ENTRY *entry = X509_NAME_get_entry(xname, i);
2081 if (ASN1_STRING_to_UTF8((unsigned char **)&str, entry->value) >= 0) {
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +02002082 order = ssl_sock_add_cert_sni(ctx, s, str, order);
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01002083 OPENSSL_free(str);
Emeric Brunfc0421f2012-09-07 17:30:07 +02002084 }
Emeric Brunfc0421f2012-09-07 17:30:07 +02002085 }
2086 }
2087
2088 ret = 0; /* the caller must not free the SSL_CTX argument anymore */
2089 if (!SSL_CTX_use_certificate(ctx, x))
2090 goto end;
2091
2092 if (ctx->extra_certs != NULL) {
2093 sk_X509_pop_free(ctx->extra_certs, X509_free);
2094 ctx->extra_certs = NULL;
2095 }
2096
2097 while ((ca = PEM_read_bio_X509(in, NULL, ctx->default_passwd_callback, ctx->default_passwd_callback_userdata))) {
2098 if (!SSL_CTX_add_extra_chain_cert(ctx, ca)) {
2099 X509_free(ca);
2100 goto end;
2101 }
2102 }
2103
2104 err = ERR_get_error();
2105 if (!err || (ERR_GET_LIB(err) == ERR_LIB_PEM && ERR_GET_REASON(err) == PEM_R_NO_START_LINE)) {
2106 /* we successfully reached the last cert in the file */
2107 ret = 1;
2108 }
2109 ERR_clear_error();
2110
2111end:
2112 if (x)
2113 X509_free(x);
2114
2115 if (in)
2116 BIO_free(in);
2117
2118 return ret;
2119}
2120
Emeric Brun50bcecc2013-04-22 13:05:23 +02002121static 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 +02002122{
2123 int ret;
2124 SSL_CTX *ctx;
2125
2126 ctx = SSL_CTX_new(SSLv23_server_method());
2127 if (!ctx) {
Willy Tarreaueb6cead2012-09-20 19:43:14 +02002128 memprintf(err, "%sunable to allocate SSL context for cert '%s'.\n",
2129 err && *err ? *err : "", path);
Emeric Brunfc0421f2012-09-07 17:30:07 +02002130 return 1;
2131 }
2132
2133 if (SSL_CTX_use_PrivateKey_file(ctx, path, SSL_FILETYPE_PEM) <= 0) {
Willy Tarreaueb6cead2012-09-20 19:43:14 +02002134 memprintf(err, "%sunable to load SSL private key from PEM file '%s'.\n",
2135 err && *err ? *err : "", path);
Emeric Brunfc0421f2012-09-07 17:30:07 +02002136 SSL_CTX_free(ctx);
2137 return 1;
2138 }
2139
Emeric Brun50bcecc2013-04-22 13:05:23 +02002140 ret = ssl_sock_load_cert_chain_file(ctx, path, bind_conf, sni_filter, fcount);
Emeric Brunfc0421f2012-09-07 17:30:07 +02002141 if (ret <= 0) {
Willy Tarreaueb6cead2012-09-20 19:43:14 +02002142 memprintf(err, "%sunable to load SSL certificate from PEM file '%s'.\n",
2143 err && *err ? *err : "", path);
Emeric Brunfc0421f2012-09-07 17:30:07 +02002144 if (ret < 0) /* serious error, must do that ourselves */
2145 SSL_CTX_free(ctx);
2146 return 1;
2147 }
Emeric Brun61694ab2012-10-26 13:35:33 +02002148
2149 if (SSL_CTX_check_private_key(ctx) <= 0) {
2150 memprintf(err, "%sinconsistencies between private key and certificate loaded from PEM file '%s'.\n",
2151 err && *err ? *err : "", path);
2152 return 1;
2153 }
2154
Emeric Brunfc0421f2012-09-07 17:30:07 +02002155 /* we must not free the SSL_CTX anymore below, since it's already in
2156 * the tree, so it will be discovered and cleaned in time.
2157 */
Emeric Bruna4bcd9a2012-09-20 16:19:02 +02002158#ifndef OPENSSL_NO_DH
Remi Gacogne4f902b82015-05-28 16:23:00 +02002159 /* store a NULL pointer to indicate we have not yet loaded
2160 a custom DH param file */
2161 if (ssl_dh_ptr_index >= 0) {
2162 SSL_CTX_set_ex_data(ctx, ssl_dh_ptr_index, NULL);
2163 }
2164
Emeric Bruna4bcd9a2012-09-20 16:19:02 +02002165 ret = ssl_sock_load_dh_params(ctx, path);
2166 if (ret < 0) {
2167 if (err)
2168 memprintf(err, "%sunable to load DH parameters from file '%s'.\n",
2169 *err ? *err : "", path);
2170 return 1;
2171 }
2172#endif
2173
Lukas Tribuse4e30f72014-12-09 16:32:51 +01002174#if (defined SSL_CTRL_SET_TLSEXT_STATUS_REQ_CB && !defined OPENSSL_NO_OCSP)
Emeric Brun4147b2e2014-06-16 18:36:30 +02002175 ret = ssl_sock_load_ocsp(ctx, path);
2176 if (ret < 0) {
2177 if (err)
2178 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",
2179 *err ? *err : "", path);
2180 return 1;
2181 }
2182#endif
2183
Daniel Jakots54ffb912015-11-06 20:02:41 +01002184#if (OPENSSL_VERSION_NUMBER >= 0x1000200fL && !defined OPENSSL_NO_TLSEXT && !defined OPENSSL_IS_BORINGSSL && !defined LIBRESSL_VERSION_NUMBER)
Janusz Dziemidowicz2c701b52015-03-07 23:03:59 +01002185 if (sctl_ex_index >= 0) {
2186 ret = ssl_sock_load_sctl(ctx, path);
2187 if (ret < 0) {
2188 if (err)
2189 memprintf(err, "%s '%s.sctl' is present but cannot be read or parsed'.\n",
2190 *err ? *err : "", path);
2191 return 1;
2192 }
2193 }
2194#endif
2195
Emeric Brunfc0421f2012-09-07 17:30:07 +02002196#ifndef SSL_CTRL_SET_TLSEXT_HOSTNAME
Willy Tarreau2a65ff02012-09-13 17:54:29 +02002197 if (bind_conf->default_ctx) {
Willy Tarreaueb6cead2012-09-20 19:43:14 +02002198 memprintf(err, "%sthis version of openssl cannot load multiple SSL certificates.\n",
2199 err && *err ? *err : "");
Emeric Brunfc0421f2012-09-07 17:30:07 +02002200 return 1;
2201 }
2202#endif
Willy Tarreau2a65ff02012-09-13 17:54:29 +02002203 if (!bind_conf->default_ctx)
2204 bind_conf->default_ctx = ctx;
Emeric Brunfc0421f2012-09-07 17:30:07 +02002205
2206 return 0;
2207}
2208
Willy Tarreau79eeafa2012-09-14 07:53:05 +02002209int ssl_sock_load_cert(char *path, struct bind_conf *bind_conf, struct proxy *curproxy, char **err)
Emeric Brunfc0421f2012-09-07 17:30:07 +02002210{
Cyril Bonté3180f7b2015-01-25 00:16:08 +01002211 struct dirent **de_list;
2212 int i, n;
Emeric Brunfc0421f2012-09-07 17:30:07 +02002213 DIR *dir;
2214 struct stat buf;
Willy Tarreauee2663b2012-12-06 11:36:59 +01002215 char *end;
2216 char fp[MAXPATHLEN+1];
Emeric Brunfc0421f2012-09-07 17:30:07 +02002217 int cfgerr = 0;
2218
yanbzhu08ce6ab2015-12-02 13:01:29 -05002219 if (stat(path, &buf) == 0) {
2220 dir = opendir(path);
2221 if (!dir)
2222 return ssl_sock_load_cert_file(path, bind_conf, curproxy, NULL, 0, err);
Emeric Brunfc0421f2012-09-07 17:30:07 +02002223
yanbzhu08ce6ab2015-12-02 13:01:29 -05002224 /* strip trailing slashes, including first one */
2225 for (end = path + strlen(path) - 1; end >= path && *end == '/'; end--)
2226 *end = 0;
Emeric Brunfc0421f2012-09-07 17:30:07 +02002227
yanbzhu08ce6ab2015-12-02 13:01:29 -05002228 n = scandir(path, &de_list, 0, alphasort);
2229 if (n < 0) {
2230 memprintf(err, "%sunable to scan directory '%s' : %s.\n",
2231 err && *err ? *err : "", path, strerror(errno));
2232 cfgerr++;
2233 }
2234 else {
2235 for (i = 0; i < n; i++) {
2236 struct dirent *de = de_list[i];
Emeric Brun2aab7222014-06-18 18:15:09 +02002237
yanbzhu08ce6ab2015-12-02 13:01:29 -05002238 end = strrchr(de->d_name, '.');
2239 if (end && (!strcmp(end, ".issuer") || !strcmp(end, ".ocsp") || !strcmp(end, ".sctl")))
2240 goto ignore_entry;
Cyril Bonté3180f7b2015-01-25 00:16:08 +01002241
yanbzhu08ce6ab2015-12-02 13:01:29 -05002242 snprintf(fp, sizeof(fp), "%s/%s", path, de->d_name);
2243 if (stat(fp, &buf) != 0) {
2244 memprintf(err, "%sunable to stat SSL certificate from file '%s' : %s.\n",
2245 err && *err ? *err : "", fp, strerror(errno));
2246 cfgerr++;
2247 goto ignore_entry;
2248 }
2249 if (!S_ISREG(buf.st_mode))
2250 goto ignore_entry;
2251 cfgerr += ssl_sock_load_cert_file(fp, bind_conf, curproxy, NULL, 0, err);
2252ignore_entry:
2253 free(de);
Cyril Bonté3180f7b2015-01-25 00:16:08 +01002254 }
yanbzhu08ce6ab2015-12-02 13:01:29 -05002255 free(de_list);
Emeric Brunfc0421f2012-09-07 17:30:07 +02002256 }
yanbzhu08ce6ab2015-12-02 13:01:29 -05002257 closedir(dir);
2258 return cfgerr;
Emeric Brunfc0421f2012-09-07 17:30:07 +02002259 }
yanbzhu08ce6ab2015-12-02 13:01:29 -05002260
2261 cfgerr = ssl_sock_load_multi_cert(path, bind_conf, curproxy, NULL, err);
2262
Emeric Brunfc0421f2012-09-07 17:30:07 +02002263 return cfgerr;
2264}
2265
Thierry Fournier383085f2013-01-24 14:15:43 +01002266/* Make sure openssl opens /dev/urandom before the chroot. The work is only
2267 * done once. Zero is returned if the operation fails. No error is returned
2268 * if the random is said as not implemented, because we expect that openssl
2269 * will use another method once needed.
2270 */
2271static int ssl_initialize_random()
2272{
2273 unsigned char random;
2274 static int random_initialized = 0;
2275
2276 if (!random_initialized && RAND_bytes(&random, 1) != 0)
2277 random_initialized = 1;
2278
2279 return random_initialized;
2280}
2281
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01002282int ssl_sock_load_cert_list_file(char *file, struct bind_conf *bind_conf, struct proxy *curproxy, char **err)
2283{
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +02002284 char thisline[LINESIZE];
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01002285 FILE *f;
2286 int linenum = 0;
2287 int cfgerr = 0;
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01002288
Willy Tarreauad1731d2013-04-02 17:35:58 +02002289 if ((f = fopen(file, "r")) == NULL) {
2290 memprintf(err, "cannot open file '%s' : %s", file, strerror(errno));
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01002291 return 1;
Willy Tarreauad1731d2013-04-02 17:35:58 +02002292 }
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01002293
2294 while (fgets(thisline, sizeof(thisline), f) != NULL) {
2295 int arg;
Emeric Brun50bcecc2013-04-22 13:05:23 +02002296 int newarg;
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01002297 char *end;
2298 char *args[MAX_LINE_ARGS + 1];
2299 char *line = thisline;
2300
2301 linenum++;
2302 end = line + strlen(line);
2303 if (end-line == sizeof(thisline)-1 && *(end-1) != '\n') {
2304 /* Check if we reached the limit and the last char is not \n.
2305 * Watch out for the last line without the terminating '\n'!
2306 */
Willy Tarreauad1731d2013-04-02 17:35:58 +02002307 memprintf(err, "line %d too long in file '%s', limit is %d characters",
2308 linenum, file, (int)sizeof(thisline)-1);
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01002309 cfgerr = 1;
Willy Tarreauad1731d2013-04-02 17:35:58 +02002310 break;
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01002311 }
2312
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01002313 arg = 0;
Emeric Brun50bcecc2013-04-22 13:05:23 +02002314 newarg = 1;
2315 while (*line) {
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01002316 if (*line == '#' || *line == '\n' || *line == '\r') {
2317 /* end of string, end of loop */
2318 *line = 0;
2319 break;
2320 }
2321 else if (isspace(*line)) {
Emeric Brun50bcecc2013-04-22 13:05:23 +02002322 newarg = 1;
2323 *line = 0;
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01002324 }
Emeric Brun50bcecc2013-04-22 13:05:23 +02002325 else if (newarg) {
2326 if (arg == MAX_LINE_ARGS) {
2327 memprintf(err, "too many args on line %d in file '%s'.",
2328 linenum, file);
2329 cfgerr = 1;
2330 break;
2331 }
2332 newarg = 0;
2333 args[arg++] = line;
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01002334 }
Emeric Brun50bcecc2013-04-22 13:05:23 +02002335 line++;
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01002336 }
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +02002337 if (cfgerr)
2338 break;
Willy Tarreauad1731d2013-04-02 17:35:58 +02002339
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01002340 /* empty line */
Emeric Brun50bcecc2013-04-22 13:05:23 +02002341 if (!arg)
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01002342 continue;
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01002343
Emeric Brun50bcecc2013-04-22 13:05:23 +02002344 cfgerr = ssl_sock_load_cert_file(args[0], bind_conf, curproxy, &args[1], arg-1, err);
Willy Tarreauad1731d2013-04-02 17:35:58 +02002345 if (cfgerr) {
2346 memprintf(err, "error processing line %d in file '%s' : %s", linenum, file, *err);
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01002347 break;
Willy Tarreauad1731d2013-04-02 17:35:58 +02002348 }
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01002349 }
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01002350 fclose(f);
2351 return cfgerr;
2352}
2353
Emeric Brunfc0421f2012-09-07 17:30:07 +02002354#ifndef SSL_OP_CIPHER_SERVER_PREFERENCE /* needs OpenSSL >= 0.9.7 */
2355#define SSL_OP_CIPHER_SERVER_PREFERENCE 0
2356#endif
2357
2358#ifndef SSL_OP_NO_SESSION_RESUMPTION_ON_RENEGOTIATION /* needs OpenSSL >= 0.9.7 */
2359#define SSL_OP_NO_SESSION_RESUMPTION_ON_RENEGOTIATION 0
Willy Tarreau7d588ee2012-11-26 18:47:31 +01002360#define SSL_renegotiate_pending(arg) 0
Emeric Brunfc0421f2012-09-07 17:30:07 +02002361#endif
Emeric Brun2b58d042012-09-20 17:10:03 +02002362#ifndef SSL_OP_SINGLE_ECDH_USE /* needs OpenSSL >= 0.9.8 */
2363#define SSL_OP_SINGLE_ECDH_USE 0
2364#endif
Emeric Brun2d0c4822012-10-02 13:45:20 +02002365#ifndef SSL_OP_NO_TICKET /* needs OpenSSL >= 0.9.8 */
2366#define SSL_OP_NO_TICKET 0
2367#endif
Emeric Brunfc0421f2012-09-07 17:30:07 +02002368#ifndef SSL_OP_NO_COMPRESSION /* needs OpenSSL >= 0.9.9 */
2369#define SSL_OP_NO_COMPRESSION 0
2370#endif
Emeric Brunc0ff4922012-09-28 19:37:02 +02002371#ifndef SSL_OP_NO_TLSv1_1 /* needs OpenSSL >= 1.0.1 */
2372#define SSL_OP_NO_TLSv1_1 0
2373#endif
2374#ifndef SSL_OP_NO_TLSv1_2 /* needs OpenSSL >= 1.0.1 */
2375#define SSL_OP_NO_TLSv1_2 0
2376#endif
Emeric Bruna4bcd9a2012-09-20 16:19:02 +02002377#ifndef SSL_OP_SINGLE_DH_USE /* needs OpenSSL >= 0.9.6 */
2378#define SSL_OP_SINGLE_DH_USE 0
2379#endif
Emeric Brun2b58d042012-09-20 17:10:03 +02002380#ifndef SSL_OP_SINGLE_ECDH_USE /* needs OpenSSL >= 1.0.0 */
2381#define SSL_OP_SINGLE_ECDH_USE 0
2382#endif
Emeric Brunfc0421f2012-09-07 17:30:07 +02002383#ifndef SSL_MODE_RELEASE_BUFFERS /* needs OpenSSL >= 1.0.0 */
2384#define SSL_MODE_RELEASE_BUFFERS 0
2385#endif
Willy Tarreau396a1862014-11-13 14:06:52 +01002386#ifndef SSL_MODE_SMALL_BUFFERS /* needs small_records.patch */
2387#define SSL_MODE_SMALL_BUFFERS 0
2388#endif
Remi Gacognef46cd6e2014-06-12 14:58:40 +02002389
Willy Tarreau2a65ff02012-09-13 17:54:29 +02002390int ssl_sock_prepare_ctx(struct bind_conf *bind_conf, SSL_CTX *ctx, struct proxy *curproxy)
Emeric Brunfc0421f2012-09-07 17:30:07 +02002391{
2392 int cfgerr = 0;
Emeric Brun850efd52014-01-29 12:24:34 +01002393 int verify = SSL_VERIFY_NONE;
Remi Gacogneaf5c3da2014-05-19 10:29:58 +02002394 long ssloptions =
Emeric Brunfc0421f2012-09-07 17:30:07 +02002395 SSL_OP_ALL | /* all known workarounds for bugs */
2396 SSL_OP_NO_SSLv2 |
2397 SSL_OP_NO_COMPRESSION |
Emeric Bruna4bcd9a2012-09-20 16:19:02 +02002398 SSL_OP_SINGLE_DH_USE |
Emeric Brun2b58d042012-09-20 17:10:03 +02002399 SSL_OP_SINGLE_ECDH_USE |
Emeric Brun3c4bc6e2012-10-04 18:44:19 +02002400 SSL_OP_NO_SESSION_RESUMPTION_ON_RENEGOTIATION |
2401 SSL_OP_CIPHER_SERVER_PREFERENCE;
Remi Gacogneaf5c3da2014-05-19 10:29:58 +02002402 long sslmode =
Emeric Brunfc0421f2012-09-07 17:30:07 +02002403 SSL_MODE_ENABLE_PARTIAL_WRITE |
2404 SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER |
Willy Tarreau396a1862014-11-13 14:06:52 +01002405 SSL_MODE_RELEASE_BUFFERS |
2406 SSL_MODE_SMALL_BUFFERS;
Remi Gacognef46cd6e2014-06-12 14:58:40 +02002407 STACK_OF(SSL_CIPHER) * ciphers = NULL;
Willy Tarreaua616ba62014-10-26 06:49:19 +01002408 SSL_CIPHER * cipher = NULL;
Remi Gacognec1eab8c2014-06-12 18:20:11 +02002409 char cipher_description[128];
2410 /* The description of ciphers using an Ephemeral Diffie Hellman key exchange
2411 contains " Kx=DH " or " Kx=DH(". Beware of " Kx=DH/",
2412 which is not ephemeral DH. */
2413 const char dhe_description[] = " Kx=DH ";
2414 const char dhe_export_description[] = " Kx=DH(";
Remi Gacognef46cd6e2014-06-12 14:58:40 +02002415 int idx = 0;
2416 int dhe_found = 0;
Remi Gacogne23d5d372014-10-10 17:04:26 +02002417 SSL *ssl = NULL;
Emeric Brunfc0421f2012-09-07 17:30:07 +02002418
Thierry Fournier383085f2013-01-24 14:15:43 +01002419 /* Make sure openssl opens /dev/urandom before the chroot */
2420 if (!ssl_initialize_random()) {
2421 Alert("OpenSSL random data generator initialization failed.\n");
2422 cfgerr++;
2423 }
2424
Emeric Brun89675492012-10-05 13:48:26 +02002425 if (bind_conf->ssl_options & BC_SSL_O_NO_SSLV3)
Emeric Brunfc0421f2012-09-07 17:30:07 +02002426 ssloptions |= SSL_OP_NO_SSLv3;
Emeric Brun89675492012-10-05 13:48:26 +02002427 if (bind_conf->ssl_options & BC_SSL_O_NO_TLSV10)
Emeric Brunfc0421f2012-09-07 17:30:07 +02002428 ssloptions |= SSL_OP_NO_TLSv1;
Emeric Brun89675492012-10-05 13:48:26 +02002429 if (bind_conf->ssl_options & BC_SSL_O_NO_TLSV11)
Emeric Brunc0ff4922012-09-28 19:37:02 +02002430 ssloptions |= SSL_OP_NO_TLSv1_1;
Emeric Brun89675492012-10-05 13:48:26 +02002431 if (bind_conf->ssl_options & BC_SSL_O_NO_TLSV12)
Emeric Brunc0ff4922012-09-28 19:37:02 +02002432 ssloptions |= SSL_OP_NO_TLSv1_2;
Emeric Brun89675492012-10-05 13:48:26 +02002433 if (bind_conf->ssl_options & BC_SSL_O_NO_TLS_TICKETS)
Emeric Brun2d0c4822012-10-02 13:45:20 +02002434 ssloptions |= SSL_OP_NO_TICKET;
Jérémie Courrèges-Anglas17c3f622015-07-25 16:50:52 -06002435 if (bind_conf->ssl_options & BC_SSL_O_USE_SSLV3) {
2436#ifndef OPENSSL_NO_SSL3
Emeric Brun2cb7ae52012-10-05 14:14:21 +02002437 SSL_CTX_set_ssl_version(ctx, SSLv3_server_method());
Jérémie Courrèges-Anglas17c3f622015-07-25 16:50:52 -06002438#else
2439 Alert("SSLv3 support requested but unavailable.\n");
2440 cfgerr++;
2441#endif
2442 }
Emeric Brun2cb7ae52012-10-05 14:14:21 +02002443 if (bind_conf->ssl_options & BC_SSL_O_USE_TLSV10)
2444 SSL_CTX_set_ssl_version(ctx, TLSv1_server_method());
2445#if SSL_OP_NO_TLSv1_1
2446 if (bind_conf->ssl_options & BC_SSL_O_USE_TLSV11)
2447 SSL_CTX_set_ssl_version(ctx, TLSv1_1_server_method());
2448#endif
2449#if SSL_OP_NO_TLSv1_2
2450 if (bind_conf->ssl_options & BC_SSL_O_USE_TLSV12)
2451 SSL_CTX_set_ssl_version(ctx, TLSv1_2_server_method());
2452#endif
Emeric Brunfc0421f2012-09-07 17:30:07 +02002453
2454 SSL_CTX_set_options(ctx, ssloptions);
2455 SSL_CTX_set_mode(ctx, sslmode);
Emeric Brun850efd52014-01-29 12:24:34 +01002456 switch (bind_conf->verify) {
2457 case SSL_SOCK_VERIFY_NONE:
2458 verify = SSL_VERIFY_NONE;
2459 break;
2460 case SSL_SOCK_VERIFY_OPTIONAL:
2461 verify = SSL_VERIFY_PEER;
2462 break;
2463 case SSL_SOCK_VERIFY_REQUIRED:
2464 verify = SSL_VERIFY_PEER|SSL_VERIFY_FAIL_IF_NO_PEER_CERT;
2465 break;
2466 }
2467 SSL_CTX_set_verify(ctx, verify, ssl_sock_bind_verifycbk);
2468 if (verify & SSL_VERIFY_PEER) {
Emeric Brunfb510ea2012-10-05 12:00:26 +02002469 if (bind_conf->ca_file) {
Emeric Brund94b3fe2012-09-20 18:23:56 +02002470 /* load CAfile to verify */
Emeric Brunfb510ea2012-10-05 12:00:26 +02002471 if (!SSL_CTX_load_verify_locations(ctx, bind_conf->ca_file, NULL)) {
Emeric Brund94b3fe2012-09-20 18:23:56 +02002472 Alert("Proxy '%s': unable to load CA file '%s' for bind '%s' at [%s:%d].\n",
Emeric Brunfb510ea2012-10-05 12:00:26 +02002473 curproxy->id, bind_conf->ca_file, bind_conf->arg, bind_conf->file, bind_conf->line);
Emeric Brund94b3fe2012-09-20 18:23:56 +02002474 cfgerr++;
2475 }
2476 /* set CA names fo client cert request, function returns void */
Emeric Brunfb510ea2012-10-05 12:00:26 +02002477 SSL_CTX_set_client_CA_list(ctx, SSL_load_client_CA_file(bind_conf->ca_file));
Emeric Brund94b3fe2012-09-20 18:23:56 +02002478 }
Emeric Brun850efd52014-01-29 12:24:34 +01002479 else {
2480 Alert("Proxy '%s': verify is enabled but no CA file specified for bind '%s' at [%s:%d].\n",
2481 curproxy->id, bind_conf->arg, bind_conf->file, bind_conf->line);
2482 cfgerr++;
2483 }
Emeric Brun051cdab2012-10-02 19:25:50 +02002484#ifdef X509_V_FLAG_CRL_CHECK
Emeric Brunfb510ea2012-10-05 12:00:26 +02002485 if (bind_conf->crl_file) {
Emeric Brund94b3fe2012-09-20 18:23:56 +02002486 X509_STORE *store = SSL_CTX_get_cert_store(ctx);
2487
Emeric Brunfb510ea2012-10-05 12:00:26 +02002488 if (!store || !X509_STORE_load_locations(store, bind_conf->crl_file, NULL)) {
Emeric Brund94b3fe2012-09-20 18:23:56 +02002489 Alert("Proxy '%s': unable to configure CRL file '%s' for bind '%s' at [%s:%d].\n",
Alexander Rigbofc65af02015-04-07 14:02:16 +02002490 curproxy->id, bind_conf->crl_file, bind_conf->arg, bind_conf->file, bind_conf->line);
Emeric Brund94b3fe2012-09-20 18:23:56 +02002491 cfgerr++;
2492 }
Emeric Brun561e5742012-10-02 15:20:55 +02002493 else {
2494 X509_STORE_set_flags(store, X509_V_FLAG_CRL_CHECK|X509_V_FLAG_CRL_CHECK_ALL);
2495 }
Emeric Brund94b3fe2012-09-20 18:23:56 +02002496 }
Emeric Brun051cdab2012-10-02 19:25:50 +02002497#endif
Emeric Brun644cde02012-12-14 11:21:13 +01002498 ERR_clear_error();
Emeric Brund94b3fe2012-09-20 18:23:56 +02002499 }
Emeric Brunfc0421f2012-09-07 17:30:07 +02002500
Nenad Merdanovic05552d42015-02-27 19:56:49 +01002501#if (defined SSL_CTRL_SET_TLSEXT_TICKET_KEY_CB && TLS_TICKETS_NO > 0)
Nenad Merdanovic146defa2015-05-09 08:46:00 +02002502 if(bind_conf->keys_ref) {
Nenad Merdanovic05552d42015-02-27 19:56:49 +01002503 if (!SSL_CTX_set_tlsext_ticket_key_cb(ctx, ssl_tlsext_ticket_key_cb)) {
2504 Alert("Proxy '%s': unable to set callback for TLS ticket validation for bind '%s' at [%s:%d].\n",
2505 curproxy->id, bind_conf->arg, bind_conf->file, bind_conf->line);
2506 cfgerr++;
2507 }
2508 }
2509#endif
2510
Emeric Brun4f65bff2012-11-16 15:11:00 +01002511 if (global.tune.ssllifetime)
2512 SSL_CTX_set_timeout(ctx, global.tune.ssllifetime);
2513
Emeric Brunfc0421f2012-09-07 17:30:07 +02002514 shared_context_set_cache(ctx);
Willy Tarreau2a65ff02012-09-13 17:54:29 +02002515 if (bind_conf->ciphers &&
2516 !SSL_CTX_set_cipher_list(ctx, bind_conf->ciphers)) {
Emeric Brunfc0421f2012-09-07 17:30:07 +02002517 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 +02002518 curproxy->id, bind_conf->ciphers, bind_conf->arg, bind_conf->file, bind_conf->line);
Emeric Brunfc0421f2012-09-07 17:30:07 +02002519 cfgerr++;
2520 }
2521
Remi Gacogne47783ef2015-05-29 15:53:22 +02002522 /* If tune.ssl.default-dh-param has not been set,
2523 neither has ssl-default-dh-file and no static DH
2524 params were in the certificate file. */
Remi Gacogne4f902b82015-05-28 16:23:00 +02002525 if (global.tune.ssl_default_dh_param == 0 &&
Remi Gacogne47783ef2015-05-29 15:53:22 +02002526 global_dh == NULL &&
Remi Gacogne4f902b82015-05-28 16:23:00 +02002527 (ssl_dh_ptr_index == -1 ||
2528 SSL_CTX_get_ex_data(ctx, ssl_dh_ptr_index) == NULL)) {
Lukas Tribus90132722014-08-18 00:56:33 +02002529
Remi Gacogne23d5d372014-10-10 17:04:26 +02002530 ssl = SSL_new(ctx);
Remi Gacognef46cd6e2014-06-12 14:58:40 +02002531
Remi Gacogne23d5d372014-10-10 17:04:26 +02002532 if (ssl) {
2533 ciphers = SSL_get_ciphers(ssl);
2534
2535 if (ciphers) {
2536 for (idx = 0; idx < sk_SSL_CIPHER_num(ciphers); idx++) {
2537 cipher = sk_SSL_CIPHER_value(ciphers, idx);
2538 if (SSL_CIPHER_description(cipher, cipher_description, sizeof (cipher_description)) == cipher_description) {
2539 if (strstr(cipher_description, dhe_description) != NULL ||
2540 strstr(cipher_description, dhe_export_description) != NULL) {
2541 dhe_found = 1;
2542 break;
2543 }
Remi Gacognec1eab8c2014-06-12 18:20:11 +02002544 }
Remi Gacognef46cd6e2014-06-12 14:58:40 +02002545 }
2546 }
Remi Gacogne23d5d372014-10-10 17:04:26 +02002547 SSL_free(ssl);
2548 ssl = NULL;
Lukas Tribus90132722014-08-18 00:56:33 +02002549 }
Remi Gacognef46cd6e2014-06-12 14:58:40 +02002550
Lukas Tribus90132722014-08-18 00:56:33 +02002551 if (dhe_found) {
2552 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 +02002553 }
2554
2555 global.tune.ssl_default_dh_param = 1024;
2556 }
Remi Gacogne8de54152014-07-15 11:36:40 +02002557
2558#ifndef OPENSSL_NO_DH
2559 if (global.tune.ssl_default_dh_param >= 1024) {
2560 if (local_dh_1024 == NULL) {
2561 local_dh_1024 = ssl_get_dh_1024();
2562 }
2563 if (global.tune.ssl_default_dh_param >= 2048) {
2564 if (local_dh_2048 == NULL) {
2565 local_dh_2048 = ssl_get_dh_2048();
2566 }
2567 if (global.tune.ssl_default_dh_param >= 4096) {
2568 if (local_dh_4096 == NULL) {
2569 local_dh_4096 = ssl_get_dh_4096();
2570 }
Remi Gacogne8de54152014-07-15 11:36:40 +02002571 }
2572 }
2573 }
2574#endif /* OPENSSL_NO_DH */
Remi Gacognef46cd6e2014-06-12 14:58:40 +02002575
Emeric Brunfc0421f2012-09-07 17:30:07 +02002576 SSL_CTX_set_info_callback(ctx, ssl_sock_infocbk);
Willy Tarreau5cbe4ef2014-05-08 22:45:11 +02002577#if OPENSSL_VERSION_NUMBER >= 0x00907000L
Emeric Brun29f037d2014-04-25 19:05:36 +02002578 SSL_CTX_set_msg_callback(ctx, ssl_sock_msgcbk);
Willy Tarreau5cbe4ef2014-05-08 22:45:11 +02002579#endif
Emeric Brun29f037d2014-04-25 19:05:36 +02002580
Willy Tarreau6c9a3d52012-10-18 18:57:14 +02002581#ifdef OPENSSL_NPN_NEGOTIATED
2582 if (bind_conf->npn_str)
2583 SSL_CTX_set_next_protos_advertised_cb(ctx, ssl_sock_advertise_npn_protos, bind_conf);
2584#endif
Dirkjan Bussink48f1c4e2014-02-13 12:29:42 +01002585#ifdef TLSEXT_TYPE_application_layer_protocol_negotiation
Willy Tarreauab861d32013-04-02 02:30:41 +02002586 if (bind_conf->alpn_str)
Dirkjan Bussink48f1c4e2014-02-13 12:29:42 +01002587 SSL_CTX_set_alpn_select_cb(ctx, ssl_sock_advertise_alpn_protos, bind_conf);
Willy Tarreauab861d32013-04-02 02:30:41 +02002588#endif
Willy Tarreau6c9a3d52012-10-18 18:57:14 +02002589
Emeric Brunfc0421f2012-09-07 17:30:07 +02002590#ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME
2591 SSL_CTX_set_tlsext_servername_callback(ctx, ssl_sock_switchctx_cbk);
Willy Tarreau2a65ff02012-09-13 17:54:29 +02002592 SSL_CTX_set_tlsext_servername_arg(ctx, bind_conf);
Emeric Brunfc0421f2012-09-07 17:30:07 +02002593#endif
Emeric Brun2b58d042012-09-20 17:10:03 +02002594#if defined(SSL_CTX_set_tmp_ecdh) && !defined(OPENSSL_NO_ECDH)
Emeric Brun6924ef82013-03-06 14:08:53 +01002595 {
Emeric Brun2b58d042012-09-20 17:10:03 +02002596 int i;
2597 EC_KEY *ecdh;
2598
Emeric Brun6924ef82013-03-06 14:08:53 +01002599 i = OBJ_sn2nid(bind_conf->ecdhe ? bind_conf->ecdhe : ECDHE_DEFAULT_CURVE);
Emeric Brun2b58d042012-09-20 17:10:03 +02002600 if (!i || ((ecdh = EC_KEY_new_by_curve_name(i)) == NULL)) {
2601 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 +01002602 curproxy->id, bind_conf->ecdhe ? bind_conf->ecdhe : ECDHE_DEFAULT_CURVE,
2603 bind_conf->arg, bind_conf->file, bind_conf->line);
Emeric Brun2b58d042012-09-20 17:10:03 +02002604 cfgerr++;
2605 }
2606 else {
2607 SSL_CTX_set_tmp_ecdh(ctx, ecdh);
2608 EC_KEY_free(ecdh);
2609 }
2610 }
2611#endif
2612
Emeric Brunfc0421f2012-09-07 17:30:07 +02002613 return cfgerr;
2614}
2615
Evan Broderbe554312013-06-27 00:05:25 -07002616static int ssl_sock_srv_hostcheck(const char *pattern, const char *hostname)
2617{
2618 const char *pattern_wildcard, *pattern_left_label_end, *hostname_left_label_end;
2619 size_t prefixlen, suffixlen;
2620
2621 /* Trivial case */
2622 if (strcmp(pattern, hostname) == 0)
2623 return 1;
2624
Evan Broderbe554312013-06-27 00:05:25 -07002625 /* The rest of this logic is based on RFC 6125, section 6.4.3
2626 * (http://tools.ietf.org/html/rfc6125#section-6.4.3) */
2627
Emeric Bruna848dae2013-10-08 11:27:28 +02002628 pattern_wildcard = NULL;
2629 pattern_left_label_end = pattern;
2630 while (*pattern_left_label_end != '.') {
2631 switch (*pattern_left_label_end) {
2632 case 0:
2633 /* End of label not found */
2634 return 0;
2635 case '*':
2636 /* If there is more than one wildcards */
2637 if (pattern_wildcard)
2638 return 0;
2639 pattern_wildcard = pattern_left_label_end;
2640 break;
2641 }
2642 pattern_left_label_end++;
2643 }
2644
2645 /* If it's not trivial and there is no wildcard, it can't
2646 * match */
2647 if (!pattern_wildcard)
Evan Broderbe554312013-06-27 00:05:25 -07002648 return 0;
2649
2650 /* Make sure all labels match except the leftmost */
2651 hostname_left_label_end = strchr(hostname, '.');
2652 if (!hostname_left_label_end
2653 || strcmp(pattern_left_label_end, hostname_left_label_end) != 0)
2654 return 0;
2655
2656 /* Make sure the leftmost label of the hostname is long enough
2657 * that the wildcard can match */
Emeric Brun369da852013-10-08 11:39:35 +02002658 if (hostname_left_label_end - hostname < (pattern_left_label_end - pattern) - 1)
Evan Broderbe554312013-06-27 00:05:25 -07002659 return 0;
2660
2661 /* Finally compare the string on either side of the
2662 * wildcard */
2663 prefixlen = pattern_wildcard - pattern;
2664 suffixlen = pattern_left_label_end - (pattern_wildcard + 1);
Emeric Bruna848dae2013-10-08 11:27:28 +02002665 if ((prefixlen && (memcmp(pattern, hostname, prefixlen) != 0))
2666 || (suffixlen && (memcmp(pattern_wildcard + 1, hostname_left_label_end - suffixlen, suffixlen) != 0)))
Evan Broderbe554312013-06-27 00:05:25 -07002667 return 0;
2668
2669 return 1;
2670}
2671
2672static int ssl_sock_srv_verifycbk(int ok, X509_STORE_CTX *ctx)
2673{
2674 SSL *ssl;
2675 struct connection *conn;
2676 char *servername;
2677
2678 int depth;
2679 X509 *cert;
2680 STACK_OF(GENERAL_NAME) *alt_names;
2681 int i;
2682 X509_NAME *cert_subject;
2683 char *str;
2684
2685 if (ok == 0)
2686 return ok;
2687
2688 ssl = X509_STORE_CTX_get_ex_data(ctx, SSL_get_ex_data_X509_STORE_CTX_idx());
2689 conn = (struct connection *)SSL_get_app_data(ssl);
2690
2691 servername = objt_server(conn->target)->ssl_ctx.verify_host;
2692
2693 /* We only need to verify the CN on the actual server cert,
2694 * not the indirect CAs */
2695 depth = X509_STORE_CTX_get_error_depth(ctx);
2696 if (depth != 0)
2697 return ok;
2698
2699 /* At this point, the cert is *not* OK unless we can find a
2700 * hostname match */
2701 ok = 0;
2702
2703 cert = X509_STORE_CTX_get_current_cert(ctx);
2704 /* It seems like this might happen if verify peer isn't set */
2705 if (!cert)
2706 return ok;
2707
2708 alt_names = X509_get_ext_d2i(cert, NID_subject_alt_name, NULL, NULL);
2709 if (alt_names) {
2710 for (i = 0; !ok && i < sk_GENERAL_NAME_num(alt_names); i++) {
2711 GENERAL_NAME *name = sk_GENERAL_NAME_value(alt_names, i);
2712 if (name->type == GEN_DNS) {
Emeric Bruna33410c2013-09-17 15:47:48 +02002713#if OPENSSL_VERSION_NUMBER < 0x00907000L
2714 if (ASN1_STRING_to_UTF8((unsigned char **)&str, name->d.ia5) >= 0) {
2715#else
Evan Broderbe554312013-06-27 00:05:25 -07002716 if (ASN1_STRING_to_UTF8((unsigned char **)&str, name->d.dNSName) >= 0) {
Emeric Bruna33410c2013-09-17 15:47:48 +02002717#endif
Evan Broderbe554312013-06-27 00:05:25 -07002718 ok = ssl_sock_srv_hostcheck(str, servername);
2719 OPENSSL_free(str);
2720 }
2721 }
2722 }
Emeric Brun4ad50a42013-09-17 15:19:54 +02002723 sk_GENERAL_NAME_pop_free(alt_names, GENERAL_NAME_free);
Evan Broderbe554312013-06-27 00:05:25 -07002724 }
2725
2726 cert_subject = X509_get_subject_name(cert);
2727 i = -1;
2728 while (!ok && (i = X509_NAME_get_index_by_NID(cert_subject, NID_commonName, i)) != -1) {
2729 X509_NAME_ENTRY *entry = X509_NAME_get_entry(cert_subject, i);
2730 if (ASN1_STRING_to_UTF8((unsigned char **)&str, entry->value) >= 0) {
2731 ok = ssl_sock_srv_hostcheck(str, servername);
2732 OPENSSL_free(str);
2733 }
2734 }
2735
2736 return ok;
2737}
2738
Emeric Brun94324a42012-10-11 14:00:19 +02002739/* prepare ssl context from servers options. Returns an error count */
2740int ssl_sock_prepare_srv_ctx(struct server *srv, struct proxy *curproxy)
2741{
2742 int cfgerr = 0;
Remi Gacogneaf5c3da2014-05-19 10:29:58 +02002743 long options =
Emeric Brun94324a42012-10-11 14:00:19 +02002744 SSL_OP_ALL | /* all known workarounds for bugs */
2745 SSL_OP_NO_SSLv2 |
2746 SSL_OP_NO_COMPRESSION;
Remi Gacogneaf5c3da2014-05-19 10:29:58 +02002747 long mode =
Emeric Brun94324a42012-10-11 14:00:19 +02002748 SSL_MODE_ENABLE_PARTIAL_WRITE |
2749 SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER |
Willy Tarreau396a1862014-11-13 14:06:52 +01002750 SSL_MODE_RELEASE_BUFFERS |
2751 SSL_MODE_SMALL_BUFFERS;
Emeric Brun850efd52014-01-29 12:24:34 +01002752 int verify = SSL_VERIFY_NONE;
Emeric Brun94324a42012-10-11 14:00:19 +02002753
Thierry Fournier383085f2013-01-24 14:15:43 +01002754 /* Make sure openssl opens /dev/urandom before the chroot */
2755 if (!ssl_initialize_random()) {
2756 Alert("OpenSSL random data generator initialization failed.\n");
2757 cfgerr++;
2758 }
2759
Willy Tarreaufce03112015-01-15 21:32:40 +01002760 /* Automatic memory computations need to know we use SSL there */
2761 global.ssl_used_backend = 1;
2762
2763 /* Initiate SSL context for current server */
Emeric Brun94324a42012-10-11 14:00:19 +02002764 srv->ssl_ctx.reused_sess = NULL;
2765 if (srv->use_ssl)
2766 srv->xprt = &ssl_sock;
2767 if (srv->check.use_ssl)
Cyril Bonté9ce13112014-11-15 22:41:27 +01002768 srv->check.xprt = &ssl_sock;
Emeric Brun94324a42012-10-11 14:00:19 +02002769
2770 srv->ssl_ctx.ctx = SSL_CTX_new(SSLv23_client_method());
2771 if (!srv->ssl_ctx.ctx) {
2772 Alert("config : %s '%s', server '%s': unable to allocate ssl context.\n",
2773 proxy_type_str(curproxy), curproxy->id,
2774 srv->id);
2775 cfgerr++;
2776 return cfgerr;
2777 }
Emeric Bruna7aa3092012-10-26 12:58:00 +02002778 if (srv->ssl_ctx.client_crt) {
2779 if (SSL_CTX_use_PrivateKey_file(srv->ssl_ctx.ctx, srv->ssl_ctx.client_crt, SSL_FILETYPE_PEM) <= 0) {
2780 Alert("config : %s '%s', server '%s': unable to load SSL private key from PEM file '%s'.\n",
2781 proxy_type_str(curproxy), curproxy->id,
2782 srv->id, srv->ssl_ctx.client_crt);
2783 cfgerr++;
2784 }
2785 else if (SSL_CTX_use_certificate_chain_file(srv->ssl_ctx.ctx, srv->ssl_ctx.client_crt) <= 0) {
2786 Alert("config : %s '%s', server '%s': unable to load ssl certificate from PEM file '%s'.\n",
2787 proxy_type_str(curproxy), curproxy->id,
2788 srv->id, srv->ssl_ctx.client_crt);
2789 cfgerr++;
2790 }
2791 else if (SSL_CTX_check_private_key(srv->ssl_ctx.ctx) <= 0) {
2792 Alert("config : %s '%s', server '%s': inconsistencies between private key and certificate loaded from PEM file '%s'.\n",
2793 proxy_type_str(curproxy), curproxy->id,
2794 srv->id, srv->ssl_ctx.client_crt);
2795 cfgerr++;
2796 }
2797 }
Emeric Brun94324a42012-10-11 14:00:19 +02002798
2799 if (srv->ssl_ctx.options & SRV_SSL_O_NO_SSLV3)
2800 options |= SSL_OP_NO_SSLv3;
2801 if (srv->ssl_ctx.options & SRV_SSL_O_NO_TLSV10)
2802 options |= SSL_OP_NO_TLSv1;
2803 if (srv->ssl_ctx.options & SRV_SSL_O_NO_TLSV11)
2804 options |= SSL_OP_NO_TLSv1_1;
2805 if (srv->ssl_ctx.options & SRV_SSL_O_NO_TLSV12)
2806 options |= SSL_OP_NO_TLSv1_2;
Emeric Brunf9c5c472012-10-11 15:28:34 +02002807 if (srv->ssl_ctx.options & SRV_SSL_O_NO_TLS_TICKETS)
2808 options |= SSL_OP_NO_TICKET;
Jérémie Courrèges-Anglas17c3f622015-07-25 16:50:52 -06002809 if (srv->ssl_ctx.options & SRV_SSL_O_USE_SSLV3) {
2810#ifndef OPENSSL_NO_SSL3
Emeric Brun94324a42012-10-11 14:00:19 +02002811 SSL_CTX_set_ssl_version(srv->ssl_ctx.ctx, SSLv3_client_method());
Jérémie Courrèges-Anglas17c3f622015-07-25 16:50:52 -06002812#else
Thierry FOURNIERbc965342015-08-26 08:21:26 +02002813 Alert("SSLv3 support requested but unavailable.\n");
Jérémie Courrèges-Anglas17c3f622015-07-25 16:50:52 -06002814 cfgerr++;
2815#endif
2816 }
Emeric Brun94324a42012-10-11 14:00:19 +02002817 if (srv->ssl_ctx.options & SRV_SSL_O_USE_TLSV10)
2818 SSL_CTX_set_ssl_version(srv->ssl_ctx.ctx, TLSv1_client_method());
2819#if SSL_OP_NO_TLSv1_1
2820 if (srv->ssl_ctx.options & SRV_SSL_O_USE_TLSV11)
2821 SSL_CTX_set_ssl_version(srv->ssl_ctx.ctx, TLSv1_1_client_method());
2822#endif
2823#if SSL_OP_NO_TLSv1_2
2824 if (srv->ssl_ctx.options & SRV_SSL_O_USE_TLSV12)
2825 SSL_CTX_set_ssl_version(srv->ssl_ctx.ctx, TLSv1_2_client_method());
2826#endif
2827
2828 SSL_CTX_set_options(srv->ssl_ctx.ctx, options);
2829 SSL_CTX_set_mode(srv->ssl_ctx.ctx, mode);
Emeric Brun850efd52014-01-29 12:24:34 +01002830
2831 if (global.ssl_server_verify == SSL_SERVER_VERIFY_REQUIRED)
2832 verify = SSL_VERIFY_PEER;
2833
2834 switch (srv->ssl_ctx.verify) {
2835 case SSL_SOCK_VERIFY_NONE:
2836 verify = SSL_VERIFY_NONE;
2837 break;
2838 case SSL_SOCK_VERIFY_REQUIRED:
2839 verify = SSL_VERIFY_PEER;
2840 break;
2841 }
Evan Broderbe554312013-06-27 00:05:25 -07002842 SSL_CTX_set_verify(srv->ssl_ctx.ctx,
Emeric Brun850efd52014-01-29 12:24:34 +01002843 verify,
Evan Broderbe554312013-06-27 00:05:25 -07002844 srv->ssl_ctx.verify_host ? ssl_sock_srv_verifycbk : NULL);
Emeric Brun850efd52014-01-29 12:24:34 +01002845 if (verify & SSL_VERIFY_PEER) {
Emeric Brunef42d922012-10-11 16:11:36 +02002846 if (srv->ssl_ctx.ca_file) {
2847 /* load CAfile to verify */
2848 if (!SSL_CTX_load_verify_locations(srv->ssl_ctx.ctx, srv->ssl_ctx.ca_file, NULL)) {
Willy Tarreau07ba08b2014-02-16 19:22:08 +01002849 Alert("Proxy '%s', server '%s' [%s:%d] unable to load CA file '%s'.\n",
Emeric Brunef42d922012-10-11 16:11:36 +02002850 curproxy->id, srv->id,
2851 srv->conf.file, srv->conf.line, srv->ssl_ctx.ca_file);
2852 cfgerr++;
2853 }
2854 }
Emeric Brun850efd52014-01-29 12:24:34 +01002855 else {
2856 if (global.ssl_server_verify == SSL_SERVER_VERIFY_REQUIRED)
Willy Tarreau07ba08b2014-02-16 19:22:08 +01002857 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 +01002858 curproxy->id, srv->id,
2859 srv->conf.file, srv->conf.line);
2860 else
Willy Tarreau07ba08b2014-02-16 19:22:08 +01002861 Alert("Proxy '%s', server '%s' [%s:%d] verify is enabled but no CA file specified.\n",
Emeric Brun850efd52014-01-29 12:24:34 +01002862 curproxy->id, srv->id,
2863 srv->conf.file, srv->conf.line);
2864 cfgerr++;
2865 }
Emeric Brunef42d922012-10-11 16:11:36 +02002866#ifdef X509_V_FLAG_CRL_CHECK
2867 if (srv->ssl_ctx.crl_file) {
2868 X509_STORE *store = SSL_CTX_get_cert_store(srv->ssl_ctx.ctx);
2869
2870 if (!store || !X509_STORE_load_locations(store, srv->ssl_ctx.crl_file, NULL)) {
Willy Tarreau07ba08b2014-02-16 19:22:08 +01002871 Alert("Proxy '%s', server '%s' [%s:%d] unable to configure CRL file '%s'.\n",
Emeric Brunef42d922012-10-11 16:11:36 +02002872 curproxy->id, srv->id,
2873 srv->conf.file, srv->conf.line, srv->ssl_ctx.crl_file);
2874 cfgerr++;
2875 }
2876 else {
2877 X509_STORE_set_flags(store, X509_V_FLAG_CRL_CHECK|X509_V_FLAG_CRL_CHECK_ALL);
2878 }
2879 }
2880#endif
2881 }
2882
Emeric Brun4f65bff2012-11-16 15:11:00 +01002883 if (global.tune.ssllifetime)
2884 SSL_CTX_set_timeout(srv->ssl_ctx.ctx, global.tune.ssllifetime);
2885
Emeric Brun94324a42012-10-11 14:00:19 +02002886 SSL_CTX_set_session_cache_mode(srv->ssl_ctx.ctx, SSL_SESS_CACHE_OFF);
2887 if (srv->ssl_ctx.ciphers &&
2888 !SSL_CTX_set_cipher_list(srv->ssl_ctx.ctx, srv->ssl_ctx.ciphers)) {
2889 Alert("Proxy '%s', server '%s' [%s:%d] : unable to set SSL cipher list to '%s'.\n",
2890 curproxy->id, srv->id,
2891 srv->conf.file, srv->conf.line, srv->ssl_ctx.ciphers);
2892 cfgerr++;
2893 }
2894
2895 return cfgerr;
2896}
2897
Willy Tarreau2a65ff02012-09-13 17:54:29 +02002898/* Walks down the two trees in bind_conf and prepares all certs. The pointer may
Emeric Brunfc0421f2012-09-07 17:30:07 +02002899 * be NULL, in which case nothing is done. Returns the number of errors
2900 * encountered.
2901 */
Willy Tarreau2a65ff02012-09-13 17:54:29 +02002902int ssl_sock_prepare_all_ctx(struct bind_conf *bind_conf, struct proxy *px)
Emeric Brunfc0421f2012-09-07 17:30:07 +02002903{
2904 struct ebmb_node *node;
2905 struct sni_ctx *sni;
2906 int err = 0;
2907
Willy Tarreau2a65ff02012-09-13 17:54:29 +02002908 if (!bind_conf || !bind_conf->is_ssl)
Emeric Brunfc0421f2012-09-07 17:30:07 +02002909 return 0;
2910
Willy Tarreaufce03112015-01-15 21:32:40 +01002911 /* Automatic memory computations need to know we use SSL there */
2912 global.ssl_used_frontend = 1;
2913
Emeric Brun0bed9942014-10-30 19:25:24 +01002914 if (bind_conf->default_ctx)
2915 err += ssl_sock_prepare_ctx(bind_conf, bind_conf->default_ctx, px);
2916
Willy Tarreau2a65ff02012-09-13 17:54:29 +02002917 node = ebmb_first(&bind_conf->sni_ctx);
Emeric Brunfc0421f2012-09-07 17:30:07 +02002918 while (node) {
2919 sni = ebmb_entry(node, struct sni_ctx, name);
Emeric Brun0bed9942014-10-30 19:25:24 +01002920 if (!sni->order && sni->ctx != bind_conf->default_ctx)
2921 /* only initialize the CTX on its first occurrence and
2922 if it is not the default_ctx */
Willy Tarreau2a65ff02012-09-13 17:54:29 +02002923 err += ssl_sock_prepare_ctx(bind_conf, sni->ctx, px);
Emeric Brunfc0421f2012-09-07 17:30:07 +02002924 node = ebmb_next(node);
2925 }
2926
Willy Tarreau2a65ff02012-09-13 17:54:29 +02002927 node = ebmb_first(&bind_conf->sni_w_ctx);
Emeric Brunfc0421f2012-09-07 17:30:07 +02002928 while (node) {
2929 sni = ebmb_entry(node, struct sni_ctx, name);
Emeric Brun0bed9942014-10-30 19:25:24 +01002930 if (!sni->order && sni->ctx != bind_conf->default_ctx)
2931 /* only initialize the CTX on its first occurrence and
2932 if it is not the default_ctx */
Willy Tarreau2a65ff02012-09-13 17:54:29 +02002933 err += ssl_sock_prepare_ctx(bind_conf, sni->ctx, px);
Emeric Brunfc0421f2012-09-07 17:30:07 +02002934 node = ebmb_next(node);
2935 }
2936 return err;
2937}
2938
Christopher Faulet77fe80c2015-07-29 13:02:40 +02002939
2940/* release ssl context allocated for servers. */
2941void ssl_sock_free_srv_ctx(struct server *srv)
2942{
2943 if (srv->ssl_ctx.ctx)
2944 SSL_CTX_free(srv->ssl_ctx.ctx);
2945}
2946
Willy Tarreau2a65ff02012-09-13 17:54:29 +02002947/* Walks down the two trees in bind_conf and frees all the certs. The pointer may
Emeric Brunfc0421f2012-09-07 17:30:07 +02002948 * be NULL, in which case nothing is done. The default_ctx is nullified too.
2949 */
Willy Tarreau2a65ff02012-09-13 17:54:29 +02002950void ssl_sock_free_all_ctx(struct bind_conf *bind_conf)
Emeric Brunfc0421f2012-09-07 17:30:07 +02002951{
2952 struct ebmb_node *node, *back;
2953 struct sni_ctx *sni;
2954
Willy Tarreau2a65ff02012-09-13 17:54:29 +02002955 if (!bind_conf || !bind_conf->is_ssl)
Emeric Brunfc0421f2012-09-07 17:30:07 +02002956 return;
2957
Willy Tarreau2a65ff02012-09-13 17:54:29 +02002958 node = ebmb_first(&bind_conf->sni_ctx);
Emeric Brunfc0421f2012-09-07 17:30:07 +02002959 while (node) {
2960 sni = ebmb_entry(node, struct sni_ctx, name);
2961 back = ebmb_next(node);
2962 ebmb_delete(node);
2963 if (!sni->order) /* only free the CTX on its first occurrence */
2964 SSL_CTX_free(sni->ctx);
2965 free(sni);
2966 node = back;
2967 }
2968
Willy Tarreau2a65ff02012-09-13 17:54:29 +02002969 node = ebmb_first(&bind_conf->sni_w_ctx);
Emeric Brunfc0421f2012-09-07 17:30:07 +02002970 while (node) {
2971 sni = ebmb_entry(node, struct sni_ctx, name);
2972 back = ebmb_next(node);
2973 ebmb_delete(node);
2974 if (!sni->order) /* only free the CTX on its first occurrence */
2975 SSL_CTX_free(sni->ctx);
2976 free(sni);
2977 node = back;
2978 }
2979
Willy Tarreau2a65ff02012-09-13 17:54:29 +02002980 bind_conf->default_ctx = NULL;
Emeric Brune1f38db2012-09-03 20:36:47 +02002981}
2982
Christopher Faulet31af49d2015-06-09 17:29:50 +02002983/* Load CA cert file and private key used to generate certificates */
2984int
2985ssl_sock_load_ca(struct bind_conf *bind_conf, struct proxy *px)
2986{
2987 FILE *fp;
2988 X509 *cacert = NULL;
2989 EVP_PKEY *capkey = NULL;
2990 int err = 0;
2991
2992 if (!bind_conf || !bind_conf->generate_certs)
2993 return err;
2994
Willy Tarreaua84c2672015-10-09 12:10:13 +02002995#ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME
Christopher Fauletd2cab922015-07-28 16:03:47 +02002996 if (global.tune.ssl_ctx_cache)
2997 ssl_ctx_lru_tree = lru64_new(global.tune.ssl_ctx_cache);
2998 ssl_ctx_lru_seed = (unsigned int)time(NULL);
Willy Tarreaua84c2672015-10-09 12:10:13 +02002999#endif
Christopher Fauletd2cab922015-07-28 16:03:47 +02003000
Christopher Faulet31af49d2015-06-09 17:29:50 +02003001 if (!bind_conf->ca_sign_file) {
3002 Alert("Proxy '%s': cannot enable certificate generation, "
3003 "no CA certificate File configured at [%s:%d].\n",
3004 px->id, bind_conf->file, bind_conf->line);
Christopher Faulet31af49d2015-06-09 17:29:50 +02003005 goto load_error;
Christopher Fauletc6f02fb2015-10-09 10:53:31 +02003006 }
Christopher Faulet31af49d2015-06-09 17:29:50 +02003007
3008 /* read in the CA certificate */
3009 if (!(fp = fopen(bind_conf->ca_sign_file, "r"))) {
3010 Alert("Proxy '%s': Failed to read CA certificate file '%s' at [%s:%d].\n",
3011 px->id, bind_conf->ca_sign_file, bind_conf->file, bind_conf->line);
Christopher Faulet31af49d2015-06-09 17:29:50 +02003012 goto load_error;
3013 }
3014 if (!(cacert = PEM_read_X509(fp, NULL, NULL, NULL))) {
3015 Alert("Proxy '%s': Failed to read CA certificate file '%s' at [%s:%d].\n",
3016 px->id, bind_conf->ca_sign_file, bind_conf->file, bind_conf->line);
Christopher Fauletc6f02fb2015-10-09 10:53:31 +02003017 goto read_error;
Christopher Faulet31af49d2015-06-09 17:29:50 +02003018 }
Christopher Fauletc6f02fb2015-10-09 10:53:31 +02003019 rewind(fp);
Christopher Faulet31af49d2015-06-09 17:29:50 +02003020 if (!(capkey = PEM_read_PrivateKey(fp, NULL, NULL, bind_conf->ca_sign_pass))) {
3021 Alert("Proxy '%s': Failed to read CA private key file '%s' at [%s:%d].\n",
3022 px->id, bind_conf->ca_sign_file, bind_conf->file, bind_conf->line);
Christopher Fauletc6f02fb2015-10-09 10:53:31 +02003023 goto read_error;
Christopher Faulet31af49d2015-06-09 17:29:50 +02003024 }
Christopher Faulet31af49d2015-06-09 17:29:50 +02003025
Christopher Fauletc6f02fb2015-10-09 10:53:31 +02003026 fclose (fp);
Christopher Faulet31af49d2015-06-09 17:29:50 +02003027 bind_conf->ca_sign_cert = cacert;
3028 bind_conf->ca_sign_pkey = capkey;
3029 return err;
3030
Christopher Fauletc6f02fb2015-10-09 10:53:31 +02003031 read_error:
3032 fclose (fp);
Christopher Faulet31af49d2015-06-09 17:29:50 +02003033 if (capkey) EVP_PKEY_free(capkey);
3034 if (cacert) X509_free(cacert);
Christopher Fauletc6f02fb2015-10-09 10:53:31 +02003035 load_error:
3036 bind_conf->generate_certs = 0;
3037 err++;
Christopher Faulet31af49d2015-06-09 17:29:50 +02003038 return err;
3039}
3040
3041/* Release CA cert and private key used to generate certificated */
3042void
3043ssl_sock_free_ca(struct bind_conf *bind_conf)
3044{
3045 if (!bind_conf)
3046 return;
3047
3048 if (bind_conf->ca_sign_pkey)
3049 EVP_PKEY_free(bind_conf->ca_sign_pkey);
3050 if (bind_conf->ca_sign_cert)
3051 X509_free(bind_conf->ca_sign_cert);
3052}
3053
Emeric Brun46591952012-05-18 15:47:34 +02003054/*
3055 * This function is called if SSL * context is not yet allocated. The function
3056 * is designed to be called before any other data-layer operation and sets the
3057 * handshake flag on the connection. It is safe to call it multiple times.
3058 * It returns 0 on success and -1 in error case.
3059 */
3060static int ssl_sock_init(struct connection *conn)
3061{
3062 /* already initialized */
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02003063 if (conn->xprt_ctx)
Emeric Brun46591952012-05-18 15:47:34 +02003064 return 0;
3065
Willy Tarreau3c728722014-01-23 13:50:42 +01003066 if (!conn_ctrl_ready(conn))
Willy Tarreauf79c8172013-10-21 16:30:56 +02003067 return 0;
3068
Willy Tarreau20879a02012-12-03 16:32:10 +01003069 if (global.maxsslconn && sslconns >= global.maxsslconn) {
3070 conn->err_code = CO_ER_SSL_TOO_MANY;
Willy Tarreau403edff2012-09-06 11:58:37 +02003071 return -1;
Willy Tarreau20879a02012-12-03 16:32:10 +01003072 }
Willy Tarreau403edff2012-09-06 11:58:37 +02003073
Emeric Brun46591952012-05-18 15:47:34 +02003074 /* If it is in client mode initiate SSL session
3075 in connect state otherwise accept state */
Willy Tarreau3fdb3662012-11-12 00:42:33 +01003076 if (objt_server(conn->target)) {
Willy Tarreaufba03cd2014-11-13 13:48:58 +01003077 int may_retry = 1;
3078
3079 retry_connect:
Emeric Brun46591952012-05-18 15:47:34 +02003080 /* Alloc a new SSL session ctx */
Willy Tarreau3fdb3662012-11-12 00:42:33 +01003081 conn->xprt_ctx = SSL_new(objt_server(conn->target)->ssl_ctx.ctx);
Willy Tarreau20879a02012-12-03 16:32:10 +01003082 if (!conn->xprt_ctx) {
Willy Tarreaufba03cd2014-11-13 13:48:58 +01003083 if (may_retry--) {
3084 pool_gc2();
3085 goto retry_connect;
3086 }
Willy Tarreau20879a02012-12-03 16:32:10 +01003087 conn->err_code = CO_ER_SSL_NO_MEM;
Emeric Brun46591952012-05-18 15:47:34 +02003088 return -1;
Willy Tarreau20879a02012-12-03 16:32:10 +01003089 }
Emeric Brun46591952012-05-18 15:47:34 +02003090
Emeric Brun46591952012-05-18 15:47:34 +02003091 /* set fd on SSL session context */
Emeric Brun55476152014-11-12 17:35:37 +01003092 if (!SSL_set_fd(conn->xprt_ctx, conn->t.sock.fd)) {
3093 SSL_free(conn->xprt_ctx);
3094 conn->xprt_ctx = NULL;
Willy Tarreaufba03cd2014-11-13 13:48:58 +01003095 if (may_retry--) {
3096 pool_gc2();
3097 goto retry_connect;
3098 }
Emeric Brun55476152014-11-12 17:35:37 +01003099 conn->err_code = CO_ER_SSL_NO_MEM;
3100 return -1;
3101 }
Emeric Brun46591952012-05-18 15:47:34 +02003102
Evan Broderbe554312013-06-27 00:05:25 -07003103 /* set connection pointer */
Emeric Brun55476152014-11-12 17:35:37 +01003104 if (!SSL_set_app_data(conn->xprt_ctx, conn)) {
3105 SSL_free(conn->xprt_ctx);
3106 conn->xprt_ctx = NULL;
Willy Tarreaufba03cd2014-11-13 13:48:58 +01003107 if (may_retry--) {
3108 pool_gc2();
3109 goto retry_connect;
3110 }
Emeric Brun55476152014-11-12 17:35:37 +01003111 conn->err_code = CO_ER_SSL_NO_MEM;
3112 return -1;
3113 }
3114
3115 SSL_set_connect_state(conn->xprt_ctx);
3116 if (objt_server(conn->target)->ssl_ctx.reused_sess) {
3117 if(!SSL_set_session(conn->xprt_ctx, objt_server(conn->target)->ssl_ctx.reused_sess)) {
3118 SSL_SESSION_free(objt_server(conn->target)->ssl_ctx.reused_sess);
3119 objt_server(conn->target)->ssl_ctx.reused_sess = NULL;
3120 }
3121 }
Evan Broderbe554312013-06-27 00:05:25 -07003122
Emeric Brun46591952012-05-18 15:47:34 +02003123 /* leave init state and start handshake */
Willy Tarreau05737472012-09-04 08:03:39 +02003124 conn->flags |= CO_FL_SSL_WAIT_HS | CO_FL_WAIT_L6_CONN;
Willy Tarreau403edff2012-09-06 11:58:37 +02003125
3126 sslconns++;
Willy Tarreau71b734c2014-01-28 15:19:44 +01003127 totalsslconns++;
Emeric Brun46591952012-05-18 15:47:34 +02003128 return 0;
3129 }
Willy Tarreau3fdb3662012-11-12 00:42:33 +01003130 else if (objt_listener(conn->target)) {
Willy Tarreaufba03cd2014-11-13 13:48:58 +01003131 int may_retry = 1;
3132
3133 retry_accept:
Emeric Brun46591952012-05-18 15:47:34 +02003134 /* Alloc a new SSL session ctx */
Willy Tarreau3fdb3662012-11-12 00:42:33 +01003135 conn->xprt_ctx = SSL_new(objt_listener(conn->target)->bind_conf->default_ctx);
Willy Tarreau20879a02012-12-03 16:32:10 +01003136 if (!conn->xprt_ctx) {
Willy Tarreaufba03cd2014-11-13 13:48:58 +01003137 if (may_retry--) {
3138 pool_gc2();
3139 goto retry_accept;
3140 }
Willy Tarreau20879a02012-12-03 16:32:10 +01003141 conn->err_code = CO_ER_SSL_NO_MEM;
Emeric Brun46591952012-05-18 15:47:34 +02003142 return -1;
Willy Tarreau20879a02012-12-03 16:32:10 +01003143 }
Emeric Brun46591952012-05-18 15:47:34 +02003144
Emeric Brun46591952012-05-18 15:47:34 +02003145 /* set fd on SSL session context */
Emeric Brun55476152014-11-12 17:35:37 +01003146 if (!SSL_set_fd(conn->xprt_ctx, conn->t.sock.fd)) {
3147 SSL_free(conn->xprt_ctx);
3148 conn->xprt_ctx = NULL;
Willy Tarreaufba03cd2014-11-13 13:48:58 +01003149 if (may_retry--) {
3150 pool_gc2();
3151 goto retry_accept;
3152 }
Emeric Brun55476152014-11-12 17:35:37 +01003153 conn->err_code = CO_ER_SSL_NO_MEM;
3154 return -1;
3155 }
Emeric Brun46591952012-05-18 15:47:34 +02003156
Emeric Brune1f38db2012-09-03 20:36:47 +02003157 /* set connection pointer */
Emeric Brun55476152014-11-12 17:35:37 +01003158 if (!SSL_set_app_data(conn->xprt_ctx, conn)) {
3159 SSL_free(conn->xprt_ctx);
3160 conn->xprt_ctx = NULL;
Willy Tarreaufba03cd2014-11-13 13:48:58 +01003161 if (may_retry--) {
3162 pool_gc2();
3163 goto retry_accept;
3164 }
Emeric Brun55476152014-11-12 17:35:37 +01003165 conn->err_code = CO_ER_SSL_NO_MEM;
3166 return -1;
3167 }
3168
3169 SSL_set_accept_state(conn->xprt_ctx);
Emeric Brune1f38db2012-09-03 20:36:47 +02003170
Emeric Brun46591952012-05-18 15:47:34 +02003171 /* leave init state and start handshake */
Willy Tarreau05737472012-09-04 08:03:39 +02003172 conn->flags |= CO_FL_SSL_WAIT_HS | CO_FL_WAIT_L6_CONN;
Willy Tarreau403edff2012-09-06 11:58:37 +02003173
3174 sslconns++;
Willy Tarreau71b734c2014-01-28 15:19:44 +01003175 totalsslconns++;
Emeric Brun46591952012-05-18 15:47:34 +02003176 return 0;
3177 }
3178 /* don't know how to handle such a target */
Willy Tarreau20879a02012-12-03 16:32:10 +01003179 conn->err_code = CO_ER_SSL_NO_TARGET;
Emeric Brun46591952012-05-18 15:47:34 +02003180 return -1;
3181}
3182
3183
3184/* This is the callback which is used when an SSL handshake is pending. It
3185 * updates the FD status if it wants some polling before being called again.
3186 * It returns 0 if it fails in a fatal way or needs to poll to go further,
3187 * otherwise it returns non-zero and removes itself from the connection's
3188 * flags (the bit is provided in <flag> by the caller).
3189 */
3190int ssl_sock_handshake(struct connection *conn, unsigned int flag)
3191{
3192 int ret;
3193
Willy Tarreau3c728722014-01-23 13:50:42 +01003194 if (!conn_ctrl_ready(conn))
Willy Tarreauf79c8172013-10-21 16:30:56 +02003195 return 0;
3196
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02003197 if (!conn->xprt_ctx)
Emeric Brun46591952012-05-18 15:47:34 +02003198 goto out_error;
3199
Emeric Brun674b7432012-11-08 19:21:55 +01003200 /* If we use SSL_do_handshake to process a reneg initiated by
3201 * the remote peer, it sometimes returns SSL_ERROR_SSL.
3202 * Usually SSL_write and SSL_read are used and process implicitly
3203 * the reneg handshake.
3204 * Here we use SSL_peek as a workaround for reneg.
3205 */
3206 if ((conn->flags & CO_FL_CONNECTED) && SSL_renegotiate_pending(conn->xprt_ctx)) {
3207 char c;
3208
3209 ret = SSL_peek(conn->xprt_ctx, &c, 1);
3210 if (ret <= 0) {
3211 /* handshake may have not been completed, let's find why */
3212 ret = SSL_get_error(conn->xprt_ctx, ret);
3213 if (ret == SSL_ERROR_WANT_WRITE) {
3214 /* SSL handshake needs to write, L4 connection may not be ready */
3215 __conn_sock_stop_recv(conn);
Willy Tarreaue1f50c42014-01-22 20:02:06 +01003216 __conn_sock_want_send(conn);
3217 fd_cant_send(conn->t.sock.fd);
Emeric Brun674b7432012-11-08 19:21:55 +01003218 return 0;
3219 }
3220 else if (ret == SSL_ERROR_WANT_READ) {
3221 /* handshake may have been completed but we have
3222 * no more data to read.
3223 */
3224 if (!SSL_renegotiate_pending(conn->xprt_ctx)) {
3225 ret = 1;
3226 goto reneg_ok;
3227 }
3228 /* SSL handshake needs to read, L4 connection is ready */
3229 if (conn->flags & CO_FL_WAIT_L4_CONN)
3230 conn->flags &= ~CO_FL_WAIT_L4_CONN;
3231 __conn_sock_stop_send(conn);
Willy Tarreaue1f50c42014-01-22 20:02:06 +01003232 __conn_sock_want_recv(conn);
3233 fd_cant_recv(conn->t.sock.fd);
Emeric Brun674b7432012-11-08 19:21:55 +01003234 return 0;
3235 }
3236 else if (ret == SSL_ERROR_SYSCALL) {
3237 /* if errno is null, then connection was successfully established */
3238 if (!errno && conn->flags & CO_FL_WAIT_L4_CONN)
3239 conn->flags &= ~CO_FL_WAIT_L4_CONN;
Willy Tarreau20879a02012-12-03 16:32:10 +01003240 if (!conn->err_code) {
Emeric Brun29f037d2014-04-25 19:05:36 +02003241 if (!((SSL *)conn->xprt_ctx)->packet_length) {
3242 if (!errno) {
3243 if (conn->xprt_st & SSL_SOCK_RECV_HEARTBEAT)
3244 conn->err_code = CO_ER_SSL_HANDSHAKE_HB;
3245 else
3246 conn->err_code = CO_ER_SSL_EMPTY;
3247 }
3248 else {
3249 if (conn->xprt_st & SSL_SOCK_RECV_HEARTBEAT)
3250 conn->err_code = CO_ER_SSL_HANDSHAKE_HB;
3251 else
3252 conn->err_code = CO_ER_SSL_ABORT;
3253 }
3254 }
3255 else {
3256 if (conn->xprt_st & SSL_SOCK_RECV_HEARTBEAT)
3257 conn->err_code = CO_ER_SSL_HANDSHAKE_HB;
Willy Tarreau20879a02012-12-03 16:32:10 +01003258 else
Emeric Brun29f037d2014-04-25 19:05:36 +02003259 conn->err_code = CO_ER_SSL_HANDSHAKE;
3260 }
Willy Tarreau20879a02012-12-03 16:32:10 +01003261 }
Emeric Brun674b7432012-11-08 19:21:55 +01003262 goto out_error;
3263 }
3264 else {
3265 /* Fail on all other handshake errors */
3266 /* Note: OpenSSL may leave unread bytes in the socket's
3267 * buffer, causing an RST to be emitted upon close() on
3268 * TCP sockets. We first try to drain possibly pending
3269 * data to avoid this as much as possible.
3270 */
Willy Tarreaud85c4852015-03-13 00:40:28 +01003271 conn_sock_drain(conn);
Willy Tarreau20879a02012-12-03 16:32:10 +01003272 if (!conn->err_code)
Willy Tarreauf51c6982014-04-25 20:02:39 +02003273 conn->err_code = (conn->xprt_st & SSL_SOCK_RECV_HEARTBEAT) ?
3274 CO_ER_SSL_KILLED_HB : CO_ER_SSL_HANDSHAKE;
Emeric Brun674b7432012-11-08 19:21:55 +01003275 goto out_error;
3276 }
3277 }
3278 /* read some data: consider handshake completed */
3279 goto reneg_ok;
3280 }
3281
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02003282 ret = SSL_do_handshake(conn->xprt_ctx);
Emeric Brun46591952012-05-18 15:47:34 +02003283 if (ret != 1) {
3284 /* handshake did not complete, let's find why */
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02003285 ret = SSL_get_error(conn->xprt_ctx, ret);
Emeric Brun46591952012-05-18 15:47:34 +02003286
3287 if (ret == SSL_ERROR_WANT_WRITE) {
3288 /* SSL handshake needs to write, L4 connection may not be ready */
3289 __conn_sock_stop_recv(conn);
Willy Tarreaue1f50c42014-01-22 20:02:06 +01003290 __conn_sock_want_send(conn);
3291 fd_cant_send(conn->t.sock.fd);
Emeric Brun46591952012-05-18 15:47:34 +02003292 return 0;
3293 }
3294 else if (ret == SSL_ERROR_WANT_READ) {
3295 /* SSL handshake needs to read, L4 connection is ready */
3296 if (conn->flags & CO_FL_WAIT_L4_CONN)
3297 conn->flags &= ~CO_FL_WAIT_L4_CONN;
3298 __conn_sock_stop_send(conn);
Willy Tarreaue1f50c42014-01-22 20:02:06 +01003299 __conn_sock_want_recv(conn);
3300 fd_cant_recv(conn->t.sock.fd);
Emeric Brun46591952012-05-18 15:47:34 +02003301 return 0;
3302 }
Willy Tarreau89230192012-09-28 20:22:13 +02003303 else if (ret == SSL_ERROR_SYSCALL) {
3304 /* if errno is null, then connection was successfully established */
3305 if (!errno && conn->flags & CO_FL_WAIT_L4_CONN)
3306 conn->flags &= ~CO_FL_WAIT_L4_CONN;
Willy Tarreau20879a02012-12-03 16:32:10 +01003307
Emeric Brun29f037d2014-04-25 19:05:36 +02003308 if (!((SSL *)conn->xprt_ctx)->packet_length) {
3309 if (!errno) {
3310 if (conn->xprt_st & SSL_SOCK_RECV_HEARTBEAT)
3311 conn->err_code = CO_ER_SSL_HANDSHAKE_HB;
3312 else
3313 conn->err_code = CO_ER_SSL_EMPTY;
3314 }
3315 else {
3316 if (conn->xprt_st & SSL_SOCK_RECV_HEARTBEAT)
3317 conn->err_code = CO_ER_SSL_HANDSHAKE_HB;
3318 else
3319 conn->err_code = CO_ER_SSL_ABORT;
3320 }
3321 }
3322 else {
3323 if (conn->xprt_st & SSL_SOCK_RECV_HEARTBEAT)
3324 conn->err_code = CO_ER_SSL_HANDSHAKE_HB;
Willy Tarreau20879a02012-12-03 16:32:10 +01003325 else
Emeric Brun29f037d2014-04-25 19:05:36 +02003326 conn->err_code = CO_ER_SSL_HANDSHAKE;
3327 }
Willy Tarreau89230192012-09-28 20:22:13 +02003328 goto out_error;
3329 }
Emeric Brun46591952012-05-18 15:47:34 +02003330 else {
3331 /* Fail on all other handshake errors */
Willy Tarreau566dc552012-10-19 20:52:18 +02003332 /* Note: OpenSSL may leave unread bytes in the socket's
3333 * buffer, causing an RST to be emitted upon close() on
3334 * TCP sockets. We first try to drain possibly pending
3335 * data to avoid this as much as possible.
3336 */
Willy Tarreaud85c4852015-03-13 00:40:28 +01003337 conn_sock_drain(conn);
Willy Tarreau20879a02012-12-03 16:32:10 +01003338 if (!conn->err_code)
Willy Tarreauf51c6982014-04-25 20:02:39 +02003339 conn->err_code = (conn->xprt_st & SSL_SOCK_RECV_HEARTBEAT) ?
3340 CO_ER_SSL_KILLED_HB : CO_ER_SSL_HANDSHAKE;
Emeric Brun46591952012-05-18 15:47:34 +02003341 goto out_error;
3342 }
3343 }
3344
Emeric Brun674b7432012-11-08 19:21:55 +01003345reneg_ok:
Emeric Brun46591952012-05-18 15:47:34 +02003346 /* Handshake succeeded */
Willy Tarreau0c9c2722014-05-28 12:28:58 +02003347 if (!SSL_session_reused(conn->xprt_ctx)) {
3348 if (objt_server(conn->target)) {
3349 update_freq_ctr(&global.ssl_be_keys_per_sec, 1);
3350 if (global.ssl_be_keys_per_sec.curr_ctr > global.ssl_be_keys_max)
3351 global.ssl_be_keys_max = global.ssl_be_keys_per_sec.curr_ctr;
3352
Emeric Brun46591952012-05-18 15:47:34 +02003353 /* check if session was reused, if not store current session on server for reuse */
Willy Tarreau3fdb3662012-11-12 00:42:33 +01003354 if (objt_server(conn->target)->ssl_ctx.reused_sess)
3355 SSL_SESSION_free(objt_server(conn->target)->ssl_ctx.reused_sess);
Emeric Brun46591952012-05-18 15:47:34 +02003356
Willy Tarreau2a3fb1c2015-02-05 16:47:07 +01003357 if (!(objt_server(conn->target)->ssl_ctx.options & SRV_SSL_O_NO_REUSE))
3358 objt_server(conn->target)->ssl_ctx.reused_sess = SSL_get1_session(conn->xprt_ctx);
Emeric Brun46591952012-05-18 15:47:34 +02003359 }
Willy Tarreau0c9c2722014-05-28 12:28:58 +02003360 else {
3361 update_freq_ctr(&global.ssl_fe_keys_per_sec, 1);
3362 if (global.ssl_fe_keys_per_sec.curr_ctr > global.ssl_fe_keys_max)
3363 global.ssl_fe_keys_max = global.ssl_fe_keys_per_sec.curr_ctr;
3364 }
Emeric Brun46591952012-05-18 15:47:34 +02003365 }
3366
3367 /* The connection is now established at both layers, it's time to leave */
3368 conn->flags &= ~(flag | CO_FL_WAIT_L4_CONN | CO_FL_WAIT_L6_CONN);
3369 return 1;
3370
3371 out_error:
Emeric Brun644cde02012-12-14 11:21:13 +01003372 /* Clear openssl global errors stack */
3373 ERR_clear_error();
3374
Emeric Brun9fa89732012-10-04 17:09:56 +02003375 /* free resumed session if exists */
Willy Tarreau3fdb3662012-11-12 00:42:33 +01003376 if (objt_server(conn->target) && objt_server(conn->target)->ssl_ctx.reused_sess) {
3377 SSL_SESSION_free(objt_server(conn->target)->ssl_ctx.reused_sess);
3378 objt_server(conn->target)->ssl_ctx.reused_sess = NULL;
Emeric Brun9fa89732012-10-04 17:09:56 +02003379 }
3380
Emeric Brun46591952012-05-18 15:47:34 +02003381 /* Fail on all other handshake errors */
3382 conn->flags |= CO_FL_ERROR;
Willy Tarreau20879a02012-12-03 16:32:10 +01003383 if (!conn->err_code)
3384 conn->err_code = CO_ER_SSL_HANDSHAKE;
Emeric Brun46591952012-05-18 15:47:34 +02003385 return 0;
3386}
3387
3388/* Receive up to <count> bytes from connection <conn>'s socket and store them
Willy Tarreauabf08d92014-01-14 11:31:27 +01003389 * into buffer <buf>. Only one call to recv() is performed, unless the
Emeric Brun46591952012-05-18 15:47:34 +02003390 * buffer wraps, in which case a second call may be performed. The connection's
3391 * flags are updated with whatever special event is detected (error, read0,
3392 * empty). The caller is responsible for taking care of those events and
3393 * avoiding the call if inappropriate. The function does not call the
3394 * connection's polling update function, so the caller is responsible for this.
3395 */
3396static int ssl_sock_to_buf(struct connection *conn, struct buffer *buf, int count)
3397{
3398 int ret, done = 0;
Willy Tarreauabf08d92014-01-14 11:31:27 +01003399 int try;
Emeric Brun46591952012-05-18 15:47:34 +02003400
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02003401 if (!conn->xprt_ctx)
Emeric Brun46591952012-05-18 15:47:34 +02003402 goto out_error;
3403
3404 if (conn->flags & CO_FL_HANDSHAKE)
3405 /* a handshake was requested */
3406 return 0;
3407
Willy Tarreauabf08d92014-01-14 11:31:27 +01003408 /* let's realign the buffer to optimize I/O */
3409 if (buffer_empty(buf))
Emeric Brun46591952012-05-18 15:47:34 +02003410 buf->p = buf->data;
Emeric Brun46591952012-05-18 15:47:34 +02003411
3412 /* read the largest possible block. For this, we perform only one call
3413 * to recv() unless the buffer wraps and we exactly fill the first hunk,
3414 * in which case we accept to do it once again. A new attempt is made on
3415 * EINTR too.
3416 */
Willy Tarreau00b0fb92014-01-17 11:09:40 +01003417 while (count > 0) {
Willy Tarreauabf08d92014-01-14 11:31:27 +01003418 /* first check if we have some room after p+i */
3419 try = buf->data + buf->size - (buf->p + buf->i);
3420 /* otherwise continue between data and p-o */
3421 if (try <= 0) {
3422 try = buf->p - (buf->data + buf->o);
3423 if (try <= 0)
3424 break;
3425 }
3426 if (try > count)
3427 try = count;
3428
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02003429 ret = SSL_read(conn->xprt_ctx, bi_end(buf), try);
Emeric Brune1f38db2012-09-03 20:36:47 +02003430 if (conn->flags & CO_FL_ERROR) {
3431 /* CO_FL_ERROR may be set by ssl_sock_infocbk */
Emeric Brun644cde02012-12-14 11:21:13 +01003432 goto out_error;
Emeric Brune1f38db2012-09-03 20:36:47 +02003433 }
Emeric Brun46591952012-05-18 15:47:34 +02003434 if (ret > 0) {
3435 buf->i += ret;
3436 done += ret;
3437 if (ret < try)
3438 break;
3439 count -= ret;
Emeric Brun46591952012-05-18 15:47:34 +02003440 }
3441 else if (ret == 0) {
Emeric Brun644cde02012-12-14 11:21:13 +01003442 ret = SSL_get_error(conn->xprt_ctx, ret);
3443 if (ret != SSL_ERROR_ZERO_RETURN) {
Emeric Brun1c646862012-12-14 12:33:41 +01003444 /* error on protocol or underlying transport */
3445 if ((ret != SSL_ERROR_SYSCALL)
3446 || (errno && (errno != EAGAIN)))
3447 conn->flags |= CO_FL_ERROR;
3448
Emeric Brun644cde02012-12-14 11:21:13 +01003449 /* Clear openssl global errors stack */
3450 ERR_clear_error();
3451 }
Emeric Brun46591952012-05-18 15:47:34 +02003452 goto read0;
3453 }
3454 else {
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02003455 ret = SSL_get_error(conn->xprt_ctx, ret);
Emeric Brun46591952012-05-18 15:47:34 +02003456 if (ret == SSL_ERROR_WANT_WRITE) {
Emeric Brun8af8dd12012-11-08 17:56:20 +01003457 /* handshake is running, and it needs to enable write */
Emeric Brun46591952012-05-18 15:47:34 +02003458 conn->flags |= CO_FL_SSL_WAIT_HS;
Emeric Brun8af8dd12012-11-08 17:56:20 +01003459 __conn_sock_want_send(conn);
Emeric Brun46591952012-05-18 15:47:34 +02003460 break;
3461 }
3462 else if (ret == SSL_ERROR_WANT_READ) {
Emeric Brun282a76a2012-11-08 18:02:56 +01003463 if (SSL_renegotiate_pending(conn->xprt_ctx)) {
3464 /* handshake is running, and it may need to re-enable read */
3465 conn->flags |= CO_FL_SSL_WAIT_HS;
3466 __conn_sock_want_recv(conn);
3467 break;
3468 }
Emeric Brun46591952012-05-18 15:47:34 +02003469 /* we need to poll for retry a read later */
Willy Tarreaue1f50c42014-01-22 20:02:06 +01003470 fd_cant_recv(conn->t.sock.fd);
Emeric Brun46591952012-05-18 15:47:34 +02003471 break;
3472 }
3473 /* otherwise it's a real error */
3474 goto out_error;
3475 }
3476 }
3477 return done;
3478
3479 read0:
3480 conn_sock_read0(conn);
3481 return done;
3482 out_error:
Emeric Brun644cde02012-12-14 11:21:13 +01003483 /* Clear openssl global errors stack */
3484 ERR_clear_error();
3485
Emeric Brun46591952012-05-18 15:47:34 +02003486 conn->flags |= CO_FL_ERROR;
3487 return done;
3488}
3489
3490
3491/* Send all pending bytes from buffer <buf> to connection <conn>'s socket.
Willy Tarreau1049b1f2014-02-02 01:51:17 +01003492 * <flags> may contain some CO_SFL_* flags to hint the system about other
3493 * pending data for example, but this flag is ignored at the moment.
Emeric Brun46591952012-05-18 15:47:34 +02003494 * Only one call to send() is performed, unless the buffer wraps, in which case
3495 * a second call may be performed. The connection's flags are updated with
3496 * whatever special event is detected (error, empty). The caller is responsible
3497 * for taking care of those events and avoiding the call if inappropriate. The
3498 * function does not call the connection's polling update function, so the caller
3499 * is responsible for this.
3500 */
3501static int ssl_sock_from_buf(struct connection *conn, struct buffer *buf, int flags)
3502{
3503 int ret, try, done;
3504
3505 done = 0;
3506
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02003507 if (!conn->xprt_ctx)
Emeric Brun46591952012-05-18 15:47:34 +02003508 goto out_error;
3509
3510 if (conn->flags & CO_FL_HANDSHAKE)
3511 /* a handshake was requested */
3512 return 0;
3513
3514 /* send the largest possible block. For this we perform only one call
3515 * to send() unless the buffer wraps and we exactly fill the first hunk,
3516 * in which case we accept to do it once again.
3517 */
3518 while (buf->o) {
Kevin Hestercad82342013-05-30 15:12:41 -07003519 try = bo_contig_data(buf);
Willy Tarreaubfd59462013-02-21 07:46:09 +01003520
Willy Tarreau7bed9452014-02-02 02:00:24 +01003521 if (!(flags & CO_SFL_STREAMER) &&
Willy Tarreau518cedd2014-02-17 15:43:01 +01003522 !(conn->xprt_st & SSL_SOCK_SEND_UNLIMITED) &&
3523 global.tune.ssl_max_record && try > global.tune.ssl_max_record) {
Willy Tarreaubfd59462013-02-21 07:46:09 +01003524 try = global.tune.ssl_max_record;
Willy Tarreau518cedd2014-02-17 15:43:01 +01003525 }
3526 else {
3527 /* we need to keep the information about the fact that
3528 * we're not limiting the upcoming send(), because if it
3529 * fails, we'll have to retry with at least as many data.
3530 */
3531 conn->xprt_st |= SSL_SOCK_SEND_UNLIMITED;
3532 }
Willy Tarreaubfd59462013-02-21 07:46:09 +01003533
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02003534 ret = SSL_write(conn->xprt_ctx, bo_ptr(buf), try);
Willy Tarreau518cedd2014-02-17 15:43:01 +01003535
Emeric Brune1f38db2012-09-03 20:36:47 +02003536 if (conn->flags & CO_FL_ERROR) {
3537 /* CO_FL_ERROR may be set by ssl_sock_infocbk */
Emeric Brun644cde02012-12-14 11:21:13 +01003538 goto out_error;
Emeric Brune1f38db2012-09-03 20:36:47 +02003539 }
Emeric Brun46591952012-05-18 15:47:34 +02003540 if (ret > 0) {
Willy Tarreau518cedd2014-02-17 15:43:01 +01003541 conn->xprt_st &= ~SSL_SOCK_SEND_UNLIMITED;
3542
Emeric Brun46591952012-05-18 15:47:34 +02003543 buf->o -= ret;
3544 done += ret;
3545
Willy Tarreau5fb38032012-12-16 19:39:09 +01003546 if (likely(buffer_empty(buf)))
Emeric Brun46591952012-05-18 15:47:34 +02003547 /* optimize data alignment in the buffer */
3548 buf->p = buf->data;
3549
3550 /* if the system buffer is full, don't insist */
3551 if (ret < try)
3552 break;
3553 }
3554 else {
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02003555 ret = SSL_get_error(conn->xprt_ctx, ret);
Emeric Brun46591952012-05-18 15:47:34 +02003556 if (ret == SSL_ERROR_WANT_WRITE) {
Emeric Brun282a76a2012-11-08 18:02:56 +01003557 if (SSL_renegotiate_pending(conn->xprt_ctx)) {
3558 /* handshake is running, and it may need to re-enable write */
3559 conn->flags |= CO_FL_SSL_WAIT_HS;
3560 __conn_sock_want_send(conn);
3561 break;
3562 }
Emeric Brun46591952012-05-18 15:47:34 +02003563 /* we need to poll to retry a write later */
Willy Tarreaue1f50c42014-01-22 20:02:06 +01003564 fd_cant_send(conn->t.sock.fd);
Emeric Brun46591952012-05-18 15:47:34 +02003565 break;
3566 }
3567 else if (ret == SSL_ERROR_WANT_READ) {
Emeric Brun8af8dd12012-11-08 17:56:20 +01003568 /* handshake is running, and it needs to enable read */
Emeric Brun46591952012-05-18 15:47:34 +02003569 conn->flags |= CO_FL_SSL_WAIT_HS;
Emeric Brun8af8dd12012-11-08 17:56:20 +01003570 __conn_sock_want_recv(conn);
Emeric Brun46591952012-05-18 15:47:34 +02003571 break;
3572 }
3573 goto out_error;
3574 }
3575 }
3576 return done;
3577
3578 out_error:
Emeric Brun644cde02012-12-14 11:21:13 +01003579 /* Clear openssl global errors stack */
3580 ERR_clear_error();
3581
Emeric Brun46591952012-05-18 15:47:34 +02003582 conn->flags |= CO_FL_ERROR;
3583 return done;
3584}
3585
Emeric Brun46591952012-05-18 15:47:34 +02003586static void ssl_sock_close(struct connection *conn) {
3587
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02003588 if (conn->xprt_ctx) {
3589 SSL_free(conn->xprt_ctx);
3590 conn->xprt_ctx = NULL;
Willy Tarreau403edff2012-09-06 11:58:37 +02003591 sslconns--;
Emeric Brun46591952012-05-18 15:47:34 +02003592 }
Emeric Brun46591952012-05-18 15:47:34 +02003593}
3594
3595/* This function tries to perform a clean shutdown on an SSL connection, and in
3596 * any case, flags the connection as reusable if no handshake was in progress.
3597 */
3598static void ssl_sock_shutw(struct connection *conn, int clean)
3599{
3600 if (conn->flags & CO_FL_HANDSHAKE)
3601 return;
3602 /* no handshake was in progress, try a clean ssl shutdown */
Emeric Brun644cde02012-12-14 11:21:13 +01003603 if (clean && (SSL_shutdown(conn->xprt_ctx) <= 0)) {
3604 /* Clear openssl global errors stack */
3605 ERR_clear_error();
3606 }
Emeric Brun46591952012-05-18 15:47:34 +02003607
3608 /* force flag on ssl to keep session in cache regardless shutdown result */
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02003609 SSL_set_shutdown(conn->xprt_ctx, SSL_SENT_SHUTDOWN);
Emeric Brun46591952012-05-18 15:47:34 +02003610}
3611
Willy Tarreauffc3fcd2012-10-12 20:17:54 +02003612/* used for logging, may be changed for a sample fetch later */
3613const char *ssl_sock_get_cipher_name(struct connection *conn)
3614{
3615 if (!conn->xprt && !conn->xprt_ctx)
3616 return NULL;
3617 return SSL_get_cipher_name(conn->xprt_ctx);
3618}
3619
3620/* used for logging, may be changed for a sample fetch later */
3621const char *ssl_sock_get_proto_version(struct connection *conn)
3622{
3623 if (!conn->xprt && !conn->xprt_ctx)
3624 return NULL;
3625 return SSL_get_version(conn->xprt_ctx);
3626}
3627
Willy Tarreau8d598402012-10-22 17:58:39 +02003628/* Extract a serial from a cert, and copy it to a chunk.
3629 * Returns 1 if serial is found and copied, 0 if no serial found and
3630 * -1 if output is not large enough.
3631 */
3632static int
3633ssl_sock_get_serial(X509 *crt, struct chunk *out)
3634{
3635 ASN1_INTEGER *serial;
3636
3637 serial = X509_get_serialNumber(crt);
3638 if (!serial)
3639 return 0;
3640
3641 if (out->size < serial->length)
3642 return -1;
3643
3644 memcpy(out->str, serial->data, serial->length);
3645 out->len = serial->length;
3646 return 1;
3647}
3648
Emeric Brun43e79582014-10-29 19:03:26 +01003649/* Extract a cert to der, and copy it to a chunk.
3650 * Returns 1 if cert is found and copied, 0 on der convertion failure and
3651 * -1 if output is not large enough.
3652 */
3653static int
3654ssl_sock_crt2der(X509 *crt, struct chunk *out)
3655{
3656 int len;
3657 unsigned char *p = (unsigned char *)out->str;;
3658
3659 len =i2d_X509(crt, NULL);
3660 if (len <= 0)
3661 return 1;
3662
3663 if (out->size < len)
3664 return -1;
3665
3666 i2d_X509(crt,&p);
3667 out->len = len;
3668 return 1;
3669}
3670
Emeric Brunce5ad802012-10-22 14:11:22 +02003671
3672/* Copy Date in ASN1_UTCTIME format in struct chunk out.
3673 * Returns 1 if serial is found and copied, 0 if no valid time found
3674 * and -1 if output is not large enough.
3675 */
3676static int
3677ssl_sock_get_time(ASN1_TIME *tm, struct chunk *out)
3678{
3679 if (tm->type == V_ASN1_GENERALIZEDTIME) {
3680 ASN1_GENERALIZEDTIME *gentm = (ASN1_GENERALIZEDTIME *)tm;
3681
3682 if (gentm->length < 12)
3683 return 0;
3684 if (gentm->data[0] != 0x32 || gentm->data[1] != 0x30)
3685 return 0;
3686 if (out->size < gentm->length-2)
3687 return -1;
3688
3689 memcpy(out->str, gentm->data+2, gentm->length-2);
3690 out->len = gentm->length-2;
3691 return 1;
3692 }
3693 else if (tm->type == V_ASN1_UTCTIME) {
3694 ASN1_UTCTIME *utctm = (ASN1_UTCTIME *)tm;
3695
3696 if (utctm->length < 10)
3697 return 0;
3698 if (utctm->data[0] >= 0x35)
3699 return 0;
3700 if (out->size < utctm->length)
3701 return -1;
3702
3703 memcpy(out->str, utctm->data, utctm->length);
3704 out->len = utctm->length;
3705 return 1;
3706 }
3707
3708 return 0;
3709}
3710
Emeric Brun87855892012-10-17 17:39:35 +02003711/* Extract an entry from a X509_NAME and copy its value to an output chunk.
3712 * Returns 1 if entry found, 0 if entry not found, or -1 if output not large enough.
3713 */
3714static int
3715ssl_sock_get_dn_entry(X509_NAME *a, const struct chunk *entry, int pos, struct chunk *out)
3716{
3717 X509_NAME_ENTRY *ne;
3718 int i, j, n;
3719 int cur = 0;
3720 const char *s;
3721 char tmp[128];
3722
3723 out->len = 0;
3724 for (i = 0; i < sk_X509_NAME_ENTRY_num(a->entries); i++) {
3725 if (pos < 0)
3726 j = (sk_X509_NAME_ENTRY_num(a->entries)-1) - i;
3727 else
3728 j = i;
3729
3730 ne = sk_X509_NAME_ENTRY_value(a->entries, j);
3731 n = OBJ_obj2nid(ne->object);
3732 if ((n == NID_undef) || ((s = OBJ_nid2sn(n)) == NULL)) {
3733 i2t_ASN1_OBJECT(tmp, sizeof(tmp), ne->object);
3734 s = tmp;
3735 }
3736
3737 if (chunk_strcasecmp(entry, s) != 0)
3738 continue;
3739
3740 if (pos < 0)
3741 cur--;
3742 else
3743 cur++;
3744
3745 if (cur != pos)
3746 continue;
3747
3748 if (ne->value->length > out->size)
3749 return -1;
3750
3751 memcpy(out->str, ne->value->data, ne->value->length);
3752 out->len = ne->value->length;
3753 return 1;
3754 }
3755
3756 return 0;
3757
3758}
3759
3760/* Extract and format full DN from a X509_NAME and copy result into a chunk
3761 * Returns 1 if dn entries exits, 0 if no dn entry found or -1 if output is not large enough.
3762 */
3763static int
3764ssl_sock_get_dn_oneline(X509_NAME *a, struct chunk *out)
3765{
3766 X509_NAME_ENTRY *ne;
3767 int i, n, ln;
3768 int l = 0;
3769 const char *s;
3770 char *p;
3771 char tmp[128];
3772
3773 out->len = 0;
3774 p = out->str;
3775 for (i = 0; i < sk_X509_NAME_ENTRY_num(a->entries); i++) {
3776 ne = sk_X509_NAME_ENTRY_value(a->entries, i);
3777 n = OBJ_obj2nid(ne->object);
3778 if ((n == NID_undef) || ((s = OBJ_nid2sn(n)) == NULL)) {
3779 i2t_ASN1_OBJECT(tmp, sizeof(tmp), ne->object);
3780 s = tmp;
3781 }
3782 ln = strlen(s);
3783
3784 l += 1 + ln + 1 + ne->value->length;
3785 if (l > out->size)
3786 return -1;
3787 out->len = l;
3788
3789 *(p++)='/';
3790 memcpy(p, s, ln);
3791 p += ln;
3792 *(p++)='=';
3793 memcpy(p, ne->value->data, ne->value->length);
3794 p += ne->value->length;
3795 }
3796
3797 if (!out->len)
3798 return 0;
3799
3800 return 1;
3801}
3802
David Safb76832014-05-08 23:42:08 -04003803char *ssl_sock_get_version(struct connection *conn)
3804{
3805 if (!ssl_sock_is_ssl(conn))
3806 return NULL;
3807
3808 return (char *)SSL_get_version(conn->xprt_ctx);
3809}
3810
Willy Tarreau63076412015-07-10 11:33:32 +02003811void ssl_sock_set_servername(struct connection *conn, const char *hostname)
3812{
3813#ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME
3814 if (!ssl_sock_is_ssl(conn))
3815 return;
3816
3817 SSL_set_tlsext_host_name(conn->xprt_ctx, hostname);
3818#endif
3819}
3820
Emeric Brun0abf8362014-06-24 18:26:41 +02003821/* Extract peer certificate's common name into the chunk dest
3822 * Returns
3823 * the len of the extracted common name
3824 * or 0 if no CN found in DN
3825 * or -1 on error case (i.e. no peer certificate)
3826 */
3827int ssl_sock_get_remote_common_name(struct connection *conn, struct chunk *dest)
David Safb76832014-05-08 23:42:08 -04003828{
3829 X509 *crt = NULL;
3830 X509_NAME *name;
David Safb76832014-05-08 23:42:08 -04003831 const char find_cn[] = "CN";
3832 const struct chunk find_cn_chunk = {
3833 .str = (char *)&find_cn,
3834 .len = sizeof(find_cn)-1
3835 };
Emeric Brun0abf8362014-06-24 18:26:41 +02003836 int result = -1;
David Safb76832014-05-08 23:42:08 -04003837
3838 if (!ssl_sock_is_ssl(conn))
Emeric Brun0abf8362014-06-24 18:26:41 +02003839 goto out;
David Safb76832014-05-08 23:42:08 -04003840
3841 /* SSL_get_peer_certificate, it increase X509 * ref count */
3842 crt = SSL_get_peer_certificate(conn->xprt_ctx);
3843 if (!crt)
3844 goto out;
3845
3846 name = X509_get_subject_name(crt);
3847 if (!name)
3848 goto out;
David Safb76832014-05-08 23:42:08 -04003849
Emeric Brun0abf8362014-06-24 18:26:41 +02003850 result = ssl_sock_get_dn_entry(name, &find_cn_chunk, 1, dest);
3851out:
David Safb76832014-05-08 23:42:08 -04003852 if (crt)
3853 X509_free(crt);
3854
3855 return result;
3856}
3857
Dave McCowan328fb582014-07-30 10:39:13 -04003858/* returns 1 if client passed a certificate for this session, 0 if not */
3859int ssl_sock_get_cert_used_sess(struct connection *conn)
3860{
3861 X509 *crt = NULL;
3862
3863 if (!ssl_sock_is_ssl(conn))
3864 return 0;
3865
3866 /* SSL_get_peer_certificate, it increase X509 * ref count */
3867 crt = SSL_get_peer_certificate(conn->xprt_ctx);
3868 if (!crt)
3869 return 0;
3870
3871 X509_free(crt);
3872 return 1;
3873}
3874
3875/* returns 1 if client passed a certificate for this connection, 0 if not */
3876int ssl_sock_get_cert_used_conn(struct connection *conn)
David Safb76832014-05-08 23:42:08 -04003877{
3878 if (!ssl_sock_is_ssl(conn))
3879 return 0;
3880
3881 return SSL_SOCK_ST_FL_VERIFY_DONE & conn->xprt_st ? 1 : 0;
3882}
3883
3884/* returns result from SSL verify */
3885unsigned int ssl_sock_get_verify_result(struct connection *conn)
3886{
3887 if (!ssl_sock_is_ssl(conn))
3888 return (unsigned int)X509_V_ERR_APPLICATION_VERIFICATION;
3889
3890 return (unsigned int)SSL_get_verify_result(conn->xprt_ctx);
3891}
3892
Willy Tarreau7875d092012-09-10 08:20:03 +02003893/***** Below are some sample fetching functions for ACL/patterns *****/
3894
Emeric Brune64aef12012-09-21 13:15:06 +02003895/* boolean, returns true if client cert was present */
3896static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02003897smp_fetch_ssl_fc_has_crt(const struct arg *args, struct sample *smp, const char *kw, void *private)
Emeric Brune64aef12012-09-21 13:15:06 +02003898{
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003899 struct connection *conn;
3900
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02003901 conn = objt_conn(smp->sess->origin);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003902 if (!conn || conn->xprt != &ssl_sock)
Emeric Brune64aef12012-09-21 13:15:06 +02003903 return 0;
3904
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003905 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brune64aef12012-09-21 13:15:06 +02003906 smp->flags |= SMP_F_MAY_CHANGE;
3907 return 0;
3908 }
3909
3910 smp->flags = 0;
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02003911 smp->data.type = SMP_T_BOOL;
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02003912 smp->data.u.sint = SSL_SOCK_ST_FL_VERIFY_DONE & conn->xprt_st ? 1 : 0;
Emeric Brune64aef12012-09-21 13:15:06 +02003913
3914 return 1;
3915}
3916
Emeric Brun43e79582014-10-29 19:03:26 +01003917/* binary, returns a certificate in a binary chunk (der/raw).
3918 * The 5th keyword char is used to know if SSL_get_certificate or SSL_get_peer_certificate
3919 * should be use.
3920 */
3921static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02003922smp_fetch_ssl_x_der(const struct arg *args, struct sample *smp, const char *kw, void *private)
Emeric Brun43e79582014-10-29 19:03:26 +01003923{
3924 int cert_peer = (kw[4] == 'c') ? 1 : 0;
3925 X509 *crt = NULL;
3926 int ret = 0;
3927 struct chunk *smp_trash;
3928 struct connection *conn;
3929
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02003930 conn = objt_conn(smp->sess->origin);
Emeric Brun43e79582014-10-29 19:03:26 +01003931 if (!conn || conn->xprt != &ssl_sock)
3932 return 0;
3933
3934 if (!(conn->flags & CO_FL_CONNECTED)) {
3935 smp->flags |= SMP_F_MAY_CHANGE;
3936 return 0;
3937 }
3938
3939 if (cert_peer)
3940 crt = SSL_get_peer_certificate(conn->xprt_ctx);
3941 else
3942 crt = SSL_get_certificate(conn->xprt_ctx);
3943
3944 if (!crt)
3945 goto out;
3946
3947 smp_trash = get_trash_chunk();
3948 if (ssl_sock_crt2der(crt, smp_trash) <= 0)
3949 goto out;
3950
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02003951 smp->data.u.str = *smp_trash;
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02003952 smp->data.type = SMP_T_BIN;
Emeric Brun43e79582014-10-29 19:03:26 +01003953 ret = 1;
3954out:
3955 /* SSL_get_peer_certificate, it increase X509 * ref count */
3956 if (cert_peer && crt)
3957 X509_free(crt);
3958 return ret;
3959}
3960
Emeric Brunba841a12014-04-30 17:05:08 +02003961/* binary, returns serial of certificate in a binary chunk.
3962 * The 5th keyword char is used to know if SSL_get_certificate or SSL_get_peer_certificate
3963 * should be use.
3964 */
Willy Tarreau8d598402012-10-22 17:58:39 +02003965static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02003966smp_fetch_ssl_x_serial(const struct arg *args, struct sample *smp, const char *kw, void *private)
Willy Tarreau8d598402012-10-22 17:58:39 +02003967{
Emeric Brunba841a12014-04-30 17:05:08 +02003968 int cert_peer = (kw[4] == 'c') ? 1 : 0;
Willy Tarreau8d598402012-10-22 17:58:39 +02003969 X509 *crt = NULL;
3970 int ret = 0;
3971 struct chunk *smp_trash;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003972 struct connection *conn;
3973
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02003974 conn = objt_conn(smp->sess->origin);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003975 if (!conn || conn->xprt != &ssl_sock)
Willy Tarreau8d598402012-10-22 17:58:39 +02003976 return 0;
3977
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003978 if (!(conn->flags & CO_FL_CONNECTED)) {
Willy Tarreau8d598402012-10-22 17:58:39 +02003979 smp->flags |= SMP_F_MAY_CHANGE;
3980 return 0;
3981 }
3982
Emeric Brunba841a12014-04-30 17:05:08 +02003983 if (cert_peer)
3984 crt = SSL_get_peer_certificate(conn->xprt_ctx);
3985 else
3986 crt = SSL_get_certificate(conn->xprt_ctx);
3987
Willy Tarreau8d598402012-10-22 17:58:39 +02003988 if (!crt)
3989 goto out;
3990
Willy Tarreau47ca5452012-12-23 20:22:19 +01003991 smp_trash = get_trash_chunk();
Willy Tarreau8d598402012-10-22 17:58:39 +02003992 if (ssl_sock_get_serial(crt, smp_trash) <= 0)
3993 goto out;
3994
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02003995 smp->data.u.str = *smp_trash;
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02003996 smp->data.type = SMP_T_BIN;
Willy Tarreau8d598402012-10-22 17:58:39 +02003997 ret = 1;
3998out:
Emeric Brunba841a12014-04-30 17:05:08 +02003999 /* SSL_get_peer_certificate, it increase X509 * ref count */
4000 if (cert_peer && crt)
Willy Tarreau8d598402012-10-22 17:58:39 +02004001 X509_free(crt);
4002 return ret;
4003}
Emeric Brune64aef12012-09-21 13:15:06 +02004004
Emeric Brunba841a12014-04-30 17:05:08 +02004005/* binary, returns the client certificate's SHA-1 fingerprint (SHA-1 hash of DER-encoded certificate) in a binary chunk.
4006 * The 5th keyword char is used to know if SSL_get_certificate or SSL_get_peer_certificate
4007 * should be use.
4008 */
James Votha051b4a2013-05-14 20:37:59 +02004009static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02004010smp_fetch_ssl_x_sha1(const struct arg *args, struct sample *smp, const char *kw, void *private)
James Votha051b4a2013-05-14 20:37:59 +02004011{
Emeric Brunba841a12014-04-30 17:05:08 +02004012 int cert_peer = (kw[4] == 'c') ? 1 : 0;
James Votha051b4a2013-05-14 20:37:59 +02004013 X509 *crt = NULL;
4014 const EVP_MD *digest;
4015 int ret = 0;
4016 struct chunk *smp_trash;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004017 struct connection *conn;
James Votha051b4a2013-05-14 20:37:59 +02004018
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02004019 conn = objt_conn(smp->sess->origin);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004020 if (!conn || conn->xprt != &ssl_sock)
4021 return 0;
4022
4023 if (!(conn->flags & CO_FL_CONNECTED)) {
James Votha051b4a2013-05-14 20:37:59 +02004024 smp->flags |= SMP_F_MAY_CHANGE;
4025 return 0;
4026 }
4027
Emeric Brunba841a12014-04-30 17:05:08 +02004028 if (cert_peer)
4029 crt = SSL_get_peer_certificate(conn->xprt_ctx);
4030 else
4031 crt = SSL_get_certificate(conn->xprt_ctx);
James Votha051b4a2013-05-14 20:37:59 +02004032 if (!crt)
4033 goto out;
4034
4035 smp_trash = get_trash_chunk();
4036 digest = EVP_sha1();
4037 X509_digest(crt, digest, (unsigned char *)smp_trash->str, (unsigned int *)&smp_trash->len);
4038
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02004039 smp->data.u.str = *smp_trash;
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02004040 smp->data.type = SMP_T_BIN;
James Votha051b4a2013-05-14 20:37:59 +02004041 ret = 1;
4042out:
Emeric Brunba841a12014-04-30 17:05:08 +02004043 /* SSL_get_peer_certificate, it increase X509 * ref count */
4044 if (cert_peer && crt)
James Votha051b4a2013-05-14 20:37:59 +02004045 X509_free(crt);
4046 return ret;
4047}
4048
Emeric Brunba841a12014-04-30 17:05:08 +02004049/* string, returns certificate's notafter date in ASN1_UTCTIME format.
4050 * The 5th keyword char is used to know if SSL_get_certificate or SSL_get_peer_certificate
4051 * should be use.
4052 */
Emeric Brunce5ad802012-10-22 14:11:22 +02004053static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02004054smp_fetch_ssl_x_notafter(const struct arg *args, struct sample *smp, const char *kw, void *private)
Emeric Brunce5ad802012-10-22 14:11:22 +02004055{
Emeric Brunba841a12014-04-30 17:05:08 +02004056 int cert_peer = (kw[4] == 'c') ? 1 : 0;
Emeric Brunce5ad802012-10-22 14:11:22 +02004057 X509 *crt = NULL;
4058 int ret = 0;
4059 struct chunk *smp_trash;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004060 struct connection *conn;
Emeric Brunce5ad802012-10-22 14:11:22 +02004061
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02004062 conn = objt_conn(smp->sess->origin);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004063 if (!conn || conn->xprt != &ssl_sock)
4064 return 0;
4065
4066 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brunce5ad802012-10-22 14:11:22 +02004067 smp->flags |= SMP_F_MAY_CHANGE;
4068 return 0;
4069 }
4070
Emeric Brunba841a12014-04-30 17:05:08 +02004071 if (cert_peer)
4072 crt = SSL_get_peer_certificate(conn->xprt_ctx);
4073 else
4074 crt = SSL_get_certificate(conn->xprt_ctx);
Emeric Brunce5ad802012-10-22 14:11:22 +02004075 if (!crt)
4076 goto out;
4077
Willy Tarreau47ca5452012-12-23 20:22:19 +01004078 smp_trash = get_trash_chunk();
Emeric Brunce5ad802012-10-22 14:11:22 +02004079 if (ssl_sock_get_time(X509_get_notAfter(crt), smp_trash) <= 0)
4080 goto out;
4081
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02004082 smp->data.u.str = *smp_trash;
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02004083 smp->data.type = SMP_T_STR;
Emeric Brunce5ad802012-10-22 14:11:22 +02004084 ret = 1;
4085out:
Emeric Brunba841a12014-04-30 17:05:08 +02004086 /* SSL_get_peer_certificate, it increase X509 * ref count */
4087 if (cert_peer && crt)
Emeric Brunce5ad802012-10-22 14:11:22 +02004088 X509_free(crt);
4089 return ret;
4090}
4091
Emeric Brunba841a12014-04-30 17:05:08 +02004092/* string, returns a string of a formatted full dn \C=..\O=..\OU=.. \CN=.. of certificate's issuer
4093 * The 5th keyword char is used to know if SSL_get_certificate or SSL_get_peer_certificate
4094 * should be use.
4095 */
Emeric Brun87855892012-10-17 17:39:35 +02004096static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02004097smp_fetch_ssl_x_i_dn(const struct arg *args, struct sample *smp, const char *kw, void *private)
Emeric Brun87855892012-10-17 17:39:35 +02004098{
Emeric Brunba841a12014-04-30 17:05:08 +02004099 int cert_peer = (kw[4] == 'c') ? 1 : 0;
Emeric Brun87855892012-10-17 17:39:35 +02004100 X509 *crt = NULL;
4101 X509_NAME *name;
4102 int ret = 0;
4103 struct chunk *smp_trash;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004104 struct connection *conn;
Emeric Brun87855892012-10-17 17:39:35 +02004105
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02004106 conn = objt_conn(smp->sess->origin);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004107 if (!conn || conn->xprt != &ssl_sock)
4108 return 0;
4109
4110 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brun87855892012-10-17 17:39:35 +02004111 smp->flags |= SMP_F_MAY_CHANGE;
4112 return 0;
4113 }
4114
Emeric Brunba841a12014-04-30 17:05:08 +02004115 if (cert_peer)
4116 crt = SSL_get_peer_certificate(conn->xprt_ctx);
4117 else
4118 crt = SSL_get_certificate(conn->xprt_ctx);
Emeric Brun87855892012-10-17 17:39:35 +02004119 if (!crt)
4120 goto out;
4121
4122 name = X509_get_issuer_name(crt);
4123 if (!name)
4124 goto out;
4125
Willy Tarreau47ca5452012-12-23 20:22:19 +01004126 smp_trash = get_trash_chunk();
Emeric Brun87855892012-10-17 17:39:35 +02004127 if (args && args[0].type == ARGT_STR) {
4128 int pos = 1;
4129
4130 if (args[1].type == ARGT_SINT)
4131 pos = args[1].data.sint;
Emeric Brun87855892012-10-17 17:39:35 +02004132
4133 if (ssl_sock_get_dn_entry(name, &args[0].data.str, pos, smp_trash) <= 0)
4134 goto out;
4135 }
4136 else if (ssl_sock_get_dn_oneline(name, smp_trash) <= 0)
4137 goto out;
4138
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02004139 smp->data.type = SMP_T_STR;
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02004140 smp->data.u.str = *smp_trash;
Emeric Brun87855892012-10-17 17:39:35 +02004141 ret = 1;
4142out:
Emeric Brunba841a12014-04-30 17:05:08 +02004143 /* SSL_get_peer_certificate, it increase X509 * ref count */
4144 if (cert_peer && crt)
Emeric Brun87855892012-10-17 17:39:35 +02004145 X509_free(crt);
4146 return ret;
4147}
4148
Emeric Brunba841a12014-04-30 17:05:08 +02004149/* string, returns notbefore date in ASN1_UTCTIME format.
4150 * The 5th keyword char is used to know if SSL_get_certificate or SSL_get_peer_certificate
4151 * should be use.
4152 */
Emeric Brunce5ad802012-10-22 14:11:22 +02004153static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02004154smp_fetch_ssl_x_notbefore(const struct arg *args, struct sample *smp, const char *kw, void *private)
Emeric Brunce5ad802012-10-22 14:11:22 +02004155{
Emeric Brunba841a12014-04-30 17:05:08 +02004156 int cert_peer = (kw[4] == 'c') ? 1 : 0;
Emeric Brunce5ad802012-10-22 14:11:22 +02004157 X509 *crt = NULL;
4158 int ret = 0;
4159 struct chunk *smp_trash;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004160 struct connection *conn;
4161
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02004162 conn = objt_conn(smp->sess->origin);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004163 if (!conn || conn->xprt != &ssl_sock)
Emeric Brunce5ad802012-10-22 14:11:22 +02004164 return 0;
4165
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004166 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brunce5ad802012-10-22 14:11:22 +02004167 smp->flags |= SMP_F_MAY_CHANGE;
4168 return 0;
4169 }
4170
Emeric Brunba841a12014-04-30 17:05:08 +02004171 if (cert_peer)
4172 crt = SSL_get_peer_certificate(conn->xprt_ctx);
4173 else
4174 crt = SSL_get_certificate(conn->xprt_ctx);
Emeric Brunce5ad802012-10-22 14:11:22 +02004175 if (!crt)
4176 goto out;
4177
Willy Tarreau47ca5452012-12-23 20:22:19 +01004178 smp_trash = get_trash_chunk();
Emeric Brunce5ad802012-10-22 14:11:22 +02004179 if (ssl_sock_get_time(X509_get_notBefore(crt), smp_trash) <= 0)
4180 goto out;
4181
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02004182 smp->data.u.str = *smp_trash;
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02004183 smp->data.type = SMP_T_STR;
Emeric Brunce5ad802012-10-22 14:11:22 +02004184 ret = 1;
4185out:
Emeric Brunba841a12014-04-30 17:05:08 +02004186 /* SSL_get_peer_certificate, it increase X509 * ref count */
4187 if (cert_peer && crt)
Emeric Brunce5ad802012-10-22 14:11:22 +02004188 X509_free(crt);
4189 return ret;
4190}
4191
Emeric Brunba841a12014-04-30 17:05:08 +02004192/* string, returns a string of a formatted full dn \C=..\O=..\OU=.. \CN=.. of certificate's subject
4193 * The 5th keyword char is used to know if SSL_get_certificate or SSL_get_peer_certificate
4194 * should be use.
4195 */
Emeric Brun87855892012-10-17 17:39:35 +02004196static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02004197smp_fetch_ssl_x_s_dn(const struct arg *args, struct sample *smp, const char *kw, void *private)
Emeric Brun87855892012-10-17 17:39:35 +02004198{
Emeric Brunba841a12014-04-30 17:05:08 +02004199 int cert_peer = (kw[4] == 'c') ? 1 : 0;
Emeric Brun87855892012-10-17 17:39:35 +02004200 X509 *crt = NULL;
4201 X509_NAME *name;
4202 int ret = 0;
4203 struct chunk *smp_trash;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004204 struct connection *conn;
Emeric Brun87855892012-10-17 17:39:35 +02004205
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02004206 conn = objt_conn(smp->sess->origin);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004207 if (!conn || conn->xprt != &ssl_sock)
4208 return 0;
4209
4210 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brun87855892012-10-17 17:39:35 +02004211 smp->flags |= SMP_F_MAY_CHANGE;
4212 return 0;
4213 }
4214
Emeric Brunba841a12014-04-30 17:05:08 +02004215 if (cert_peer)
4216 crt = SSL_get_peer_certificate(conn->xprt_ctx);
4217 else
4218 crt = SSL_get_certificate(conn->xprt_ctx);
Emeric Brun87855892012-10-17 17:39:35 +02004219 if (!crt)
4220 goto out;
4221
4222 name = X509_get_subject_name(crt);
4223 if (!name)
4224 goto out;
4225
Willy Tarreau47ca5452012-12-23 20:22:19 +01004226 smp_trash = get_trash_chunk();
Emeric Brun87855892012-10-17 17:39:35 +02004227 if (args && args[0].type == ARGT_STR) {
4228 int pos = 1;
4229
4230 if (args[1].type == ARGT_SINT)
4231 pos = args[1].data.sint;
Emeric Brun87855892012-10-17 17:39:35 +02004232
4233 if (ssl_sock_get_dn_entry(name, &args[0].data.str, pos, smp_trash) <= 0)
4234 goto out;
4235 }
4236 else if (ssl_sock_get_dn_oneline(name, smp_trash) <= 0)
4237 goto out;
4238
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02004239 smp->data.type = SMP_T_STR;
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02004240 smp->data.u.str = *smp_trash;
Emeric Brun87855892012-10-17 17:39:35 +02004241 ret = 1;
4242out:
Emeric Brunba841a12014-04-30 17:05:08 +02004243 /* SSL_get_peer_certificate, it increase X509 * ref count */
4244 if (cert_peer && crt)
Emeric Brun87855892012-10-17 17:39:35 +02004245 X509_free(crt);
4246 return ret;
4247}
Emeric Brun9143d372012-12-20 15:44:16 +01004248
4249/* integer, returns true if current session use a client certificate */
4250static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02004251smp_fetch_ssl_c_used(const struct arg *args, struct sample *smp, const char *kw, void *private)
Emeric Brun9143d372012-12-20 15:44:16 +01004252{
4253 X509 *crt;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004254 struct connection *conn;
Emeric Brun9143d372012-12-20 15:44:16 +01004255
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02004256 conn = objt_conn(smp->sess->origin);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004257 if (!conn || conn->xprt != &ssl_sock)
4258 return 0;
4259
4260 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brun9143d372012-12-20 15:44:16 +01004261 smp->flags |= SMP_F_MAY_CHANGE;
4262 return 0;
4263 }
4264
4265 /* SSL_get_peer_certificate returns a ptr on allocated X509 struct */
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004266 crt = SSL_get_peer_certificate(conn->xprt_ctx);
Emeric Brun9143d372012-12-20 15:44:16 +01004267 if (crt) {
4268 X509_free(crt);
4269 }
4270
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02004271 smp->data.type = SMP_T_BOOL;
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02004272 smp->data.u.sint = (crt != NULL);
Emeric Brun9143d372012-12-20 15:44:16 +01004273 return 1;
4274}
4275
Emeric Brunba841a12014-04-30 17:05:08 +02004276/* integer, returns the certificate version
4277 * The 5th keyword char is used to know if SSL_get_certificate or SSL_get_peer_certificate
4278 * should be use.
4279 */
Emeric Bruna7359fd2012-10-17 15:03:11 +02004280static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02004281smp_fetch_ssl_x_version(const struct arg *args, struct sample *smp, const char *kw, void *private)
Emeric Bruna7359fd2012-10-17 15:03:11 +02004282{
Emeric Brunba841a12014-04-30 17:05:08 +02004283 int cert_peer = (kw[4] == 'c') ? 1 : 0;
Emeric Bruna7359fd2012-10-17 15:03:11 +02004284 X509 *crt;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004285 struct connection *conn;
4286
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02004287 conn = objt_conn(smp->sess->origin);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004288 if (!conn || conn->xprt != &ssl_sock)
Emeric Bruna7359fd2012-10-17 15:03:11 +02004289 return 0;
4290
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004291 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Bruna7359fd2012-10-17 15:03:11 +02004292 smp->flags |= SMP_F_MAY_CHANGE;
4293 return 0;
4294 }
4295
Emeric Brunba841a12014-04-30 17:05:08 +02004296 if (cert_peer)
4297 crt = SSL_get_peer_certificate(conn->xprt_ctx);
4298 else
4299 crt = SSL_get_certificate(conn->xprt_ctx);
Emeric Bruna7359fd2012-10-17 15:03:11 +02004300 if (!crt)
4301 return 0;
4302
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02004303 smp->data.u.sint = (unsigned int)(1 + X509_get_version(crt));
Emeric Brunba841a12014-04-30 17:05:08 +02004304 /* SSL_get_peer_certificate increase X509 * ref count */
4305 if (cert_peer)
4306 X509_free(crt);
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02004307 smp->data.type = SMP_T_SINT;
Emeric Bruna7359fd2012-10-17 15:03:11 +02004308
4309 return 1;
4310}
4311
Emeric Brunba841a12014-04-30 17:05:08 +02004312/* string, returns the certificate's signature algorithm.
4313 * The 5th keyword char is used to know if SSL_get_certificate or SSL_get_peer_certificate
4314 * should be use.
4315 */
Emeric Brun7f56e742012-10-19 18:15:40 +02004316static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02004317smp_fetch_ssl_x_sig_alg(const struct arg *args, struct sample *smp, const char *kw, void *private)
Emeric Brun7f56e742012-10-19 18:15:40 +02004318{
Emeric Brunba841a12014-04-30 17:05:08 +02004319 int cert_peer = (kw[4] == 'c') ? 1 : 0;
Emeric Brun7f56e742012-10-19 18:15:40 +02004320 X509 *crt;
4321 int nid;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004322 struct connection *conn;
Emeric Brun7f56e742012-10-19 18:15:40 +02004323
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)
4326 return 0;
4327
4328 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brun7f56e742012-10-19 18:15:40 +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 Brun7f56e742012-10-19 18:15:40 +02004337 if (!crt)
4338 return 0;
4339
4340 nid = OBJ_obj2nid((ASN1_OBJECT *)(crt->cert_info->signature->algorithm));
4341
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02004342 smp->data.u.str.str = (char *)OBJ_nid2sn(nid);
4343 if (!smp->data.u.str.str) {
Emeric Brunba841a12014-04-30 17:05:08 +02004344 /* SSL_get_peer_certificate increase X509 * ref count */
4345 if (cert_peer)
4346 X509_free(crt);
Emeric Brun7f56e742012-10-19 18:15:40 +02004347 return 0;
Emeric Brun9bf3ba22013-10-07 14:31:44 +02004348 }
Emeric Brun7f56e742012-10-19 18:15:40 +02004349
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02004350 smp->data.type = SMP_T_STR;
Thierry FOURNIER7654c9f2013-12-17 00:20:33 +01004351 smp->flags |= SMP_F_CONST;
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02004352 smp->data.u.str.len = strlen(smp->data.u.str.str);
Emeric Brunba841a12014-04-30 17:05:08 +02004353 /* SSL_get_peer_certificate increase X509 * ref count */
4354 if (cert_peer)
4355 X509_free(crt);
Emeric Brun7f56e742012-10-19 18:15:40 +02004356
4357 return 1;
4358}
4359
Emeric Brunba841a12014-04-30 17:05:08 +02004360/* string, returns the certificate's key algorithm.
4361 * The 5th keyword char is used to know if SSL_get_certificate or SSL_get_peer_certificate
4362 * should be use.
4363 */
Emeric Brun521a0112012-10-22 12:22:55 +02004364static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02004365smp_fetch_ssl_x_key_alg(const struct arg *args, struct sample *smp, const char *kw, void *private)
Emeric Brun521a0112012-10-22 12:22:55 +02004366{
Emeric Brunba841a12014-04-30 17:05:08 +02004367 int cert_peer = (kw[4] == 'c') ? 1 : 0;
Emeric Brun521a0112012-10-22 12:22:55 +02004368 X509 *crt;
4369 int nid;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004370 struct connection *conn;
Emeric Brun521a0112012-10-22 12:22:55 +02004371
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02004372 conn = objt_conn(smp->sess->origin);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004373 if (!conn || conn->xprt != &ssl_sock)
4374 return 0;
4375
4376 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brun521a0112012-10-22 12:22:55 +02004377 smp->flags |= SMP_F_MAY_CHANGE;
4378 return 0;
4379 }
4380
Emeric Brunba841a12014-04-30 17:05:08 +02004381 if (cert_peer)
4382 crt = SSL_get_peer_certificate(conn->xprt_ctx);
4383 else
4384 crt = SSL_get_certificate(conn->xprt_ctx);
Emeric Brun521a0112012-10-22 12:22:55 +02004385 if (!crt)
4386 return 0;
4387
4388 nid = OBJ_obj2nid((ASN1_OBJECT *)(crt->cert_info->key->algor->algorithm));
4389
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02004390 smp->data.u.str.str = (char *)OBJ_nid2sn(nid);
4391 if (!smp->data.u.str.str) {
Emeric Brunba841a12014-04-30 17:05:08 +02004392 /* SSL_get_peer_certificate increase X509 * ref count */
4393 if (cert_peer)
4394 X509_free(crt);
Emeric Brun521a0112012-10-22 12:22:55 +02004395 return 0;
Emeric Brun9bf3ba22013-10-07 14:31:44 +02004396 }
Emeric Brun521a0112012-10-22 12:22:55 +02004397
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02004398 smp->data.type = SMP_T_STR;
Thierry FOURNIER7654c9f2013-12-17 00:20:33 +01004399 smp->flags |= SMP_F_CONST;
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02004400 smp->data.u.str.len = strlen(smp->data.u.str.str);
Emeric Brunba841a12014-04-30 17:05:08 +02004401 if (cert_peer)
4402 X509_free(crt);
Emeric Brun521a0112012-10-22 12:22:55 +02004403
4404 return 1;
4405}
4406
Emeric Brun645ae792014-04-30 14:21:06 +02004407/* boolean, returns true if front conn. transport layer is SSL.
4408 * This function is also usable on backend conn if the fetch keyword 5th
4409 * char is 'b'.
4410 */
Willy Tarreau7875d092012-09-10 08:20:03 +02004411static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02004412smp_fetch_ssl_fc(const struct arg *args, struct sample *smp, const char *kw, void *private)
Willy Tarreau7875d092012-09-10 08:20:03 +02004413{
Emeric Brun645ae792014-04-30 14:21:06 +02004414 int back_conn = (kw[4] == 'b') ? 1 : 0;
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02004415 struct connection *conn = objt_conn(smp->strm->si[back_conn].end);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004416
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02004417 smp->data.type = SMP_T_BOOL;
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02004418 smp->data.u.sint = (conn && conn->xprt == &ssl_sock);
Willy Tarreau7875d092012-09-10 08:20:03 +02004419 return 1;
4420}
4421
Emeric Brun2525b6b2012-10-18 15:59:43 +02004422/* boolean, returns true if client present a SNI */
Willy Tarreau7875d092012-09-10 08:20:03 +02004423static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02004424smp_fetch_ssl_fc_has_sni(const struct arg *args, struct sample *smp, const char *kw, void *private)
Willy Tarreau7875d092012-09-10 08:20:03 +02004425{
4426#ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02004427 struct connection *conn = objt_conn(smp->sess->origin);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004428
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02004429 smp->data.type = SMP_T_BOOL;
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02004430 smp->data.u.sint = (conn && conn->xprt == &ssl_sock) &&
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004431 conn->xprt_ctx &&
4432 SSL_get_servername(conn->xprt_ctx, TLSEXT_NAMETYPE_host_name) != NULL;
Willy Tarreau7875d092012-09-10 08:20:03 +02004433 return 1;
4434#else
4435 return 0;
4436#endif
4437}
4438
Nenad Merdanovic26ea8222015-05-18 02:28:57 +02004439/* boolean, returns true if client session has been resumed */
4440static int
4441smp_fetch_ssl_fc_is_resumed(const struct arg *args, struct sample *smp, const char *kw, void *private)
4442{
4443 struct connection *conn = objt_conn(smp->sess->origin);
4444
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02004445 smp->data.type = SMP_T_BOOL;
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02004446 smp->data.u.sint = (conn && conn->xprt == &ssl_sock) &&
Nenad Merdanovic26ea8222015-05-18 02:28:57 +02004447 conn->xprt_ctx &&
4448 SSL_session_reused(conn->xprt_ctx);
4449 return 1;
4450}
4451
Emeric Brun645ae792014-04-30 14:21:06 +02004452/* string, returns the used cipher if front conn. transport layer is SSL.
4453 * This function is also usable on backend conn if the fetch keyword 5th
4454 * char is 'b'.
4455 */
Emeric Brun589fcad2012-10-16 14:13:26 +02004456static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02004457smp_fetch_ssl_fc_cipher(const struct arg *args, struct sample *smp, const char *kw, void *private)
Emeric Brun589fcad2012-10-16 14:13:26 +02004458{
Emeric Brun645ae792014-04-30 14:21:06 +02004459 int back_conn = (kw[4] == 'b') ? 1 : 0;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004460 struct connection *conn;
4461
Emeric Brun589fcad2012-10-16 14:13:26 +02004462 smp->flags = 0;
4463
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02004464 conn = objt_conn(smp->strm->si[back_conn].end);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004465 if (!conn || !conn->xprt_ctx || conn->xprt != &ssl_sock)
Emeric Brun589fcad2012-10-16 14:13:26 +02004466 return 0;
4467
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02004468 smp->data.u.str.str = (char *)SSL_get_cipher_name(conn->xprt_ctx);
4469 if (!smp->data.u.str.str)
Emeric Brun589fcad2012-10-16 14:13:26 +02004470 return 0;
4471
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02004472 smp->data.type = SMP_T_STR;
Thierry FOURNIER7654c9f2013-12-17 00:20:33 +01004473 smp->flags |= SMP_F_CONST;
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02004474 smp->data.u.str.len = strlen(smp->data.u.str.str);
Emeric Brun589fcad2012-10-16 14:13:26 +02004475
4476 return 1;
4477}
4478
Emeric Brun645ae792014-04-30 14:21:06 +02004479/* integer, returns the algoritm's keysize if front conn. transport layer
4480 * is SSL.
4481 * This function is also usable on backend conn if the fetch keyword 5th
4482 * char is 'b'.
4483 */
Emeric Brun589fcad2012-10-16 14:13:26 +02004484static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02004485smp_fetch_ssl_fc_alg_keysize(const struct arg *args, struct sample *smp, const char *kw, void *private)
Emeric Brun589fcad2012-10-16 14:13:26 +02004486{
Emeric Brun645ae792014-04-30 14:21:06 +02004487 int back_conn = (kw[4] == 'b') ? 1 : 0;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004488 struct connection *conn;
Thierry FOURNIER07ee64e2015-07-06 23:43:03 +02004489 int sint;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004490
Emeric Brun589fcad2012-10-16 14:13:26 +02004491 smp->flags = 0;
4492
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02004493 conn = objt_conn(smp->strm->si[back_conn].end);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004494 if (!conn || !conn->xprt_ctx || conn->xprt != &ssl_sock)
Emeric Brun589fcad2012-10-16 14:13:26 +02004495 return 0;
4496
Thierry FOURNIER07ee64e2015-07-06 23:43:03 +02004497 if (!SSL_get_cipher_bits(conn->xprt_ctx, &sint))
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004498 return 0;
4499
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02004500 smp->data.u.sint = sint;
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02004501 smp->data.type = SMP_T_SINT;
Emeric Brun589fcad2012-10-16 14:13:26 +02004502
4503 return 1;
4504}
4505
Emeric Brun645ae792014-04-30 14:21:06 +02004506/* integer, returns the used keysize if front conn. transport layer is SSL.
4507 * This function is also usable on backend conn if the fetch keyword 5th
4508 * char is 'b'.
4509 */
Emeric Brun589fcad2012-10-16 14:13:26 +02004510static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02004511smp_fetch_ssl_fc_use_keysize(const struct arg *args, struct sample *smp, const char *kw, void *private)
Emeric Brun589fcad2012-10-16 14:13:26 +02004512{
Emeric Brun645ae792014-04-30 14:21:06 +02004513 int back_conn = (kw[4] == 'b') ? 1 : 0;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004514 struct connection *conn;
4515
Emeric Brun589fcad2012-10-16 14:13:26 +02004516 smp->flags = 0;
4517
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02004518 conn = objt_conn(smp->strm->si[back_conn].end);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004519 if (!conn || !conn->xprt_ctx || conn->xprt != &ssl_sock)
4520 return 0;
4521
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02004522 smp->data.u.sint = (unsigned int)SSL_get_cipher_bits(conn->xprt_ctx, NULL);
4523 if (!smp->data.u.sint)
Emeric Brun589fcad2012-10-16 14:13:26 +02004524 return 0;
4525
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02004526 smp->data.type = SMP_T_SINT;
Emeric Brun589fcad2012-10-16 14:13:26 +02004527
4528 return 1;
4529}
4530
Willy Tarreau6c9a3d52012-10-18 18:57:14 +02004531#ifdef OPENSSL_NPN_NEGOTIATED
Willy Tarreau7875d092012-09-10 08:20:03 +02004532static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02004533smp_fetch_ssl_fc_npn(const struct arg *args, struct sample *smp, const char *kw, void *private)
Willy Tarreaua33c6542012-10-15 13:19:06 +02004534{
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004535 struct connection *conn;
4536
Thierry FOURNIER7654c9f2013-12-17 00:20:33 +01004537 smp->flags = SMP_F_CONST;
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02004538 smp->data.type = SMP_T_STR;
Willy Tarreaua33c6542012-10-15 13:19:06 +02004539
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02004540 conn = objt_conn(smp->sess->origin);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004541 if (!conn || !conn->xprt_ctx || conn->xprt != &ssl_sock)
4542 return 0;
4543
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02004544 smp->data.u.str.str = NULL;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004545 SSL_get0_next_proto_negotiated(conn->xprt_ctx,
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02004546 (const unsigned char **)&smp->data.u.str.str, (unsigned *)&smp->data.u.str.len);
Willy Tarreaua33c6542012-10-15 13:19:06 +02004547
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02004548 if (!smp->data.u.str.str)
Willy Tarreaua33c6542012-10-15 13:19:06 +02004549 return 0;
4550
4551 return 1;
Willy Tarreaua33c6542012-10-15 13:19:06 +02004552}
Willy Tarreau6c9a3d52012-10-18 18:57:14 +02004553#endif
Willy Tarreaua33c6542012-10-15 13:19:06 +02004554
Dirkjan Bussink48f1c4e2014-02-13 12:29:42 +01004555#ifdef TLSEXT_TYPE_application_layer_protocol_negotiation
Willy Tarreauab861d32013-04-02 02:30:41 +02004556static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02004557smp_fetch_ssl_fc_alpn(const struct arg *args, struct sample *smp, const char *kw, void *private)
Willy Tarreauab861d32013-04-02 02:30:41 +02004558{
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004559 struct connection *conn;
4560
Thierry FOURNIER7654c9f2013-12-17 00:20:33 +01004561 smp->flags = SMP_F_CONST;
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02004562 smp->data.type = SMP_T_STR;
Willy Tarreauab861d32013-04-02 02:30:41 +02004563
Willy Tarreaue26bf052015-05-12 10:30:12 +02004564 conn = objt_conn(smp->sess->origin);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004565 if (!conn || !conn->xprt_ctx || conn->xprt != &ssl_sock)
Willy Tarreauab861d32013-04-02 02:30:41 +02004566 return 0;
4567
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02004568 smp->data.u.str.str = NULL;
Dirkjan Bussink48f1c4e2014-02-13 12:29:42 +01004569 SSL_get0_alpn_selected(conn->xprt_ctx,
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02004570 (const unsigned char **)&smp->data.u.str.str, (unsigned *)&smp->data.u.str.len);
Willy Tarreauab861d32013-04-02 02:30:41 +02004571
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02004572 if (!smp->data.u.str.str)
Willy Tarreauab861d32013-04-02 02:30:41 +02004573 return 0;
4574
4575 return 1;
4576}
4577#endif
4578
Emeric Brun645ae792014-04-30 14:21:06 +02004579/* string, returns the used protocol if front conn. transport layer is SSL.
4580 * This function is also usable on backend conn if the fetch keyword 5th
4581 * char is 'b'.
4582 */
Willy Tarreaua33c6542012-10-15 13:19:06 +02004583static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02004584smp_fetch_ssl_fc_protocol(const struct arg *args, struct sample *smp, const char *kw, void *private)
Emeric Brun589fcad2012-10-16 14:13:26 +02004585{
Emeric Brun645ae792014-04-30 14:21:06 +02004586 int back_conn = (kw[4] == 'b') ? 1 : 0;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004587 struct connection *conn;
4588
Emeric Brun589fcad2012-10-16 14:13:26 +02004589 smp->flags = 0;
4590
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02004591 conn = objt_conn(smp->strm->si[back_conn].end);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004592 if (!conn || !conn->xprt_ctx || conn->xprt != &ssl_sock)
4593 return 0;
4594
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02004595 smp->data.u.str.str = (char *)SSL_get_version(conn->xprt_ctx);
4596 if (!smp->data.u.str.str)
Emeric Brun589fcad2012-10-16 14:13:26 +02004597 return 0;
4598
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02004599 smp->data.type = SMP_T_STR;
Thierry FOURNIER7654c9f2013-12-17 00:20:33 +01004600 smp->flags = SMP_F_CONST;
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02004601 smp->data.u.str.len = strlen(smp->data.u.str.str);
Emeric Brun589fcad2012-10-16 14:13:26 +02004602
4603 return 1;
4604}
4605
Willy Tarreau87b09662015-04-03 00:22:06 +02004606/* binary, returns the SSL stream id if front conn. transport layer is SSL.
Emeric Brun645ae792014-04-30 14:21:06 +02004607 * This function is also usable on backend conn if the fetch keyword 5th
4608 * char is 'b'.
4609 */
Emeric Brun589fcad2012-10-16 14:13:26 +02004610static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02004611smp_fetch_ssl_fc_session_id(const struct arg *args, struct sample *smp, const char *kw, void *private)
Emeric Brunfe68f682012-10-16 14:59:28 +02004612{
4613#if OPENSSL_VERSION_NUMBER > 0x0090800fL
Emeric Brun645ae792014-04-30 14:21:06 +02004614 int back_conn = (kw[4] == 'b') ? 1 : 0;
Willy Tarreau192252e2015-04-04 01:47:55 +02004615 SSL_SESSION *ssl_sess;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004616 struct connection *conn;
Emeric Brunfe68f682012-10-16 14:59:28 +02004617
Thierry FOURNIER7654c9f2013-12-17 00:20:33 +01004618 smp->flags = SMP_F_CONST;
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02004619 smp->data.type = SMP_T_BIN;
Emeric Brunfe68f682012-10-16 14:59:28 +02004620
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02004621 conn = objt_conn(smp->strm->si[back_conn].end);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004622 if (!conn || !conn->xprt_ctx || conn->xprt != &ssl_sock)
4623 return 0;
4624
Willy Tarreau192252e2015-04-04 01:47:55 +02004625 ssl_sess = SSL_get_session(conn->xprt_ctx);
4626 if (!ssl_sess)
Emeric Brunfe68f682012-10-16 14:59:28 +02004627 return 0;
4628
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02004629 smp->data.u.str.str = (char *)SSL_SESSION_get_id(ssl_sess, (unsigned int *)&smp->data.u.str.len);
4630 if (!smp->data.u.str.str || !smp->data.u.str.len)
Emeric Brunfe68f682012-10-16 14:59:28 +02004631 return 0;
4632
4633 return 1;
4634#else
4635 return 0;
4636#endif
4637}
4638
4639static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02004640smp_fetch_ssl_fc_sni(const struct arg *args, struct sample *smp, const char *kw, void *private)
Willy Tarreau7875d092012-09-10 08:20:03 +02004641{
4642#ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004643 struct connection *conn;
4644
Thierry FOURNIER7654c9f2013-12-17 00:20:33 +01004645 smp->flags = SMP_F_CONST;
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02004646 smp->data.type = SMP_T_STR;
Willy Tarreau7875d092012-09-10 08:20:03 +02004647
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02004648 conn = objt_conn(smp->sess->origin);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004649 if (!conn || !conn->xprt_ctx || conn->xprt != &ssl_sock)
4650 return 0;
4651
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02004652 smp->data.u.str.str = (char *)SSL_get_servername(conn->xprt_ctx, TLSEXT_NAMETYPE_host_name);
4653 if (!smp->data.u.str.str)
Willy Tarreau3e394c92012-09-14 23:56:58 +02004654 return 0;
4655
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02004656 smp->data.u.str.len = strlen(smp->data.u.str.str);
Willy Tarreau7875d092012-09-10 08:20:03 +02004657 return 1;
4658#else
4659 return 0;
4660#endif
4661}
4662
David Sc1ad52e2014-04-08 18:48:47 -04004663static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02004664smp_fetch_ssl_fc_unique_id(const struct arg *args, struct sample *smp, const char *kw, void *private)
David Sc1ad52e2014-04-08 18:48:47 -04004665{
4666#if OPENSSL_VERSION_NUMBER > 0x0090800fL
Emeric Brun645ae792014-04-30 14:21:06 +02004667 int back_conn = (kw[4] == 'b') ? 1 : 0;
David Sc1ad52e2014-04-08 18:48:47 -04004668 struct connection *conn;
4669 int finished_len;
David Sc1ad52e2014-04-08 18:48:47 -04004670 struct chunk *finished_trash;
David Sc1ad52e2014-04-08 18:48:47 -04004671
4672 smp->flags = 0;
4673
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02004674 conn = objt_conn(smp->strm->si[back_conn].end);
David Sc1ad52e2014-04-08 18:48:47 -04004675 if (!conn || !conn->xprt_ctx || conn->xprt != &ssl_sock)
4676 return 0;
4677
4678 if (!(conn->flags & CO_FL_CONNECTED)) {
4679 smp->flags |= SMP_F_MAY_CHANGE;
4680 return 0;
4681 }
4682
4683 finished_trash = get_trash_chunk();
4684 if (!SSL_session_reused(conn->xprt_ctx))
4685 finished_len = SSL_get_peer_finished(conn->xprt_ctx, finished_trash->str, finished_trash->size);
4686 else
4687 finished_len = SSL_get_finished(conn->xprt_ctx, finished_trash->str, finished_trash->size);
4688
4689 if (!finished_len)
4690 return 0;
4691
Emeric Brunb73a9b02014-04-30 18:49:19 +02004692 finished_trash->len = finished_len;
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02004693 smp->data.u.str = *finished_trash;
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02004694 smp->data.type = SMP_T_BIN;
David Sc1ad52e2014-04-08 18:48:47 -04004695
4696 return 1;
4697#else
4698 return 0;
4699#endif
4700}
4701
Emeric Brun2525b6b2012-10-18 15:59:43 +02004702/* integer, returns the first verify error in CA chain of client certificate chain. */
Emeric Brunf282a812012-09-21 15:27:54 +02004703static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02004704smp_fetch_ssl_c_ca_err(const struct arg *args, struct sample *smp, const char *kw, void *private)
Emeric Brunf282a812012-09-21 15:27:54 +02004705{
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004706 struct connection *conn;
4707
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02004708 conn = objt_conn(smp->sess->origin);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004709 if (!conn || conn->xprt != &ssl_sock)
4710 return 0;
4711
4712 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brunf282a812012-09-21 15:27:54 +02004713 smp->flags = SMP_F_MAY_CHANGE;
4714 return 0;
4715 }
4716
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02004717 smp->data.type = SMP_T_SINT;
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02004718 smp->data.u.sint = (unsigned long long int)SSL_SOCK_ST_TO_CA_ERROR(conn->xprt_st);
Emeric Brunf282a812012-09-21 15:27:54 +02004719 smp->flags = 0;
4720
4721 return 1;
4722}
4723
Emeric Brun2525b6b2012-10-18 15:59:43 +02004724/* integer, returns the depth of the first verify error in CA chain of client certificate chain. */
Emeric Brunf282a812012-09-21 15:27:54 +02004725static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02004726smp_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 +02004727{
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004728 struct connection *conn;
4729
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02004730 conn = objt_conn(smp->sess->origin);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004731 if (!conn || conn->xprt != &ssl_sock)
Emeric Brunf282a812012-09-21 15:27:54 +02004732 return 0;
4733
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004734 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brunf282a812012-09-21 15:27:54 +02004735 smp->flags = SMP_F_MAY_CHANGE;
4736 return 0;
4737 }
4738
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02004739 smp->data.type = SMP_T_SINT;
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02004740 smp->data.u.sint = (long long int)SSL_SOCK_ST_TO_CAEDEPTH(conn->xprt_st);
Emeric Brunf282a812012-09-21 15:27:54 +02004741 smp->flags = 0;
4742
4743 return 1;
4744}
4745
Emeric Brun2525b6b2012-10-18 15:59:43 +02004746/* integer, returns the first verify error on client certificate */
Emeric Brunf282a812012-09-21 15:27:54 +02004747static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02004748smp_fetch_ssl_c_err(const struct arg *args, struct sample *smp, const char *kw, void *private)
Emeric Brunf282a812012-09-21 15:27:54 +02004749{
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004750 struct connection *conn;
4751
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02004752 conn = objt_conn(smp->sess->origin);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004753 if (!conn || conn->xprt != &ssl_sock)
4754 return 0;
4755
4756 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brunf282a812012-09-21 15:27:54 +02004757 smp->flags = SMP_F_MAY_CHANGE;
4758 return 0;
4759 }
4760
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02004761 smp->data.type = SMP_T_SINT;
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02004762 smp->data.u.sint = (long long int)SSL_SOCK_ST_TO_CRTERROR(conn->xprt_st);
Emeric Brunf282a812012-09-21 15:27:54 +02004763 smp->flags = 0;
4764
4765 return 1;
4766}
4767
Emeric Brun2525b6b2012-10-18 15:59:43 +02004768/* integer, returns the verify result on client cert */
Emeric Brunbaf8ffb2012-09-21 15:27:20 +02004769static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02004770smp_fetch_ssl_c_verify(const struct arg *args, struct sample *smp, const char *kw, void *private)
Emeric Brunbaf8ffb2012-09-21 15:27:20 +02004771{
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004772 struct connection *conn;
4773
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02004774 conn = objt_conn(smp->sess->origin);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004775 if (!conn || conn->xprt != &ssl_sock)
4776 return 0;
4777
4778 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brunbaf8ffb2012-09-21 15:27:20 +02004779 smp->flags = SMP_F_MAY_CHANGE;
4780 return 0;
4781 }
4782
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004783 if (!conn->xprt_ctx)
Emeric Brunbaf8ffb2012-09-21 15:27:20 +02004784 return 0;
4785
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02004786 smp->data.type = SMP_T_SINT;
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02004787 smp->data.u.sint = (long long int)SSL_get_verify_result(conn->xprt_ctx);
Emeric Brunbaf8ffb2012-09-21 15:27:20 +02004788 smp->flags = 0;
4789
4790 return 1;
4791}
4792
Emeric Brunfb510ea2012-10-05 12:00:26 +02004793/* parse the "ca-file" bind keyword */
4794static 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 +02004795{
4796 if (!*args[cur_arg + 1]) {
4797 if (err)
4798 memprintf(err, "'%s' : missing CAfile path", args[cur_arg]);
4799 return ERR_ALERT | ERR_FATAL;
4800 }
4801
Emeric Brunef42d922012-10-11 16:11:36 +02004802 if ((*args[cur_arg + 1] != '/') && global.ca_base)
4803 memprintf(&conf->ca_file, "%s/%s", global.ca_base, args[cur_arg + 1]);
4804 else
4805 memprintf(&conf->ca_file, "%s", args[cur_arg + 1]);
Emeric Brunc8e8d122012-10-02 18:42:10 +02004806
Emeric Brund94b3fe2012-09-20 18:23:56 +02004807 return 0;
4808}
4809
Christopher Faulet31af49d2015-06-09 17:29:50 +02004810/* parse the "ca-sign-file" bind keyword */
4811static int bind_parse_ca_sign_file(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
4812{
4813 if (!*args[cur_arg + 1]) {
4814 if (err)
4815 memprintf(err, "'%s' : missing CAfile path", args[cur_arg]);
4816 return ERR_ALERT | ERR_FATAL;
4817 }
4818
4819 if ((*args[cur_arg + 1] != '/') && global.ca_base)
4820 memprintf(&conf->ca_sign_file, "%s/%s", global.ca_base, args[cur_arg + 1]);
4821 else
4822 memprintf(&conf->ca_sign_file, "%s", args[cur_arg + 1]);
4823
4824 return 0;
4825}
4826
4827/* parse the ca-sign-pass bind keyword */
4828
4829static int bind_parse_ca_sign_pass(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
4830{
4831 if (!*args[cur_arg + 1]) {
4832 if (err)
4833 memprintf(err, "'%s' : missing CAkey password", args[cur_arg]);
4834 return ERR_ALERT | ERR_FATAL;
4835 }
4836 memprintf(&conf->ca_sign_pass, "%s", args[cur_arg + 1]);
4837 return 0;
4838}
4839
Willy Tarreau79eeafa2012-09-14 07:53:05 +02004840/* parse the "ciphers" bind keyword */
Willy Tarreau4348fad2012-09-20 16:48:07 +02004841static 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 +02004842{
4843 if (!*args[cur_arg + 1]) {
Willy Tarreaueb6cead2012-09-20 19:43:14 +02004844 memprintf(err, "'%s' : missing cipher suite", args[cur_arg]);
Willy Tarreau79eeafa2012-09-14 07:53:05 +02004845 return ERR_ALERT | ERR_FATAL;
4846 }
4847
Emeric Brun76d88952012-10-05 15:47:31 +02004848 free(conf->ciphers);
Willy Tarreau4348fad2012-09-20 16:48:07 +02004849 conf->ciphers = strdup(args[cur_arg + 1]);
Willy Tarreau79eeafa2012-09-14 07:53:05 +02004850 return 0;
4851}
4852
4853/* parse the "crt" bind keyword */
Willy Tarreau4348fad2012-09-20 16:48:07 +02004854static 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 +02004855{
Willy Tarreau38011032013-08-13 16:59:39 +02004856 char path[MAXPATHLEN];
Willy Tarreaub75d6922014-04-14 18:05:41 +02004857
Willy Tarreau79eeafa2012-09-14 07:53:05 +02004858 if (!*args[cur_arg + 1]) {
Willy Tarreaueb6cead2012-09-20 19:43:14 +02004859 memprintf(err, "'%s' : missing certificate location", args[cur_arg]);
Willy Tarreau79eeafa2012-09-14 07:53:05 +02004860 return ERR_ALERT | ERR_FATAL;
4861 }
4862
Emeric Brunc8e8d122012-10-02 18:42:10 +02004863 if ((*args[cur_arg + 1] != '/' ) && global.crt_base) {
Willy Tarreau38011032013-08-13 16:59:39 +02004864 if ((strlen(global.crt_base) + 1 + strlen(args[cur_arg + 1]) + 1) > MAXPATHLEN) {
Emeric Brunc8e8d122012-10-02 18:42:10 +02004865 memprintf(err, "'%s' : path too long", args[cur_arg]);
4866 return ERR_ALERT | ERR_FATAL;
4867 }
Willy Tarreaub75d6922014-04-14 18:05:41 +02004868 snprintf(path, sizeof(path), "%s/%s", global.crt_base, args[cur_arg + 1]);
Emeric Brunc8e8d122012-10-02 18:42:10 +02004869 if (ssl_sock_load_cert(path, conf, px, err) > 0)
4870 return ERR_ALERT | ERR_FATAL;
4871
4872 return 0;
4873 }
4874
Willy Tarreau4348fad2012-09-20 16:48:07 +02004875 if (ssl_sock_load_cert(args[cur_arg + 1], conf, px, err) > 0)
Willy Tarreau79eeafa2012-09-14 07:53:05 +02004876 return ERR_ALERT | ERR_FATAL;
Emeric Brund94b3fe2012-09-20 18:23:56 +02004877
4878 return 0;
4879}
4880
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01004881/* parse the "crt-list" bind keyword */
4882static int bind_parse_crt_list(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
4883{
4884 if (!*args[cur_arg + 1]) {
4885 memprintf(err, "'%s' : missing certificate location", args[cur_arg]);
4886 return ERR_ALERT | ERR_FATAL;
4887 }
4888
Willy Tarreauad1731d2013-04-02 17:35:58 +02004889 if (ssl_sock_load_cert_list_file(args[cur_arg + 1], conf, px, err) > 0) {
4890 memprintf(err, "'%s' : %s", args[cur_arg], *err);
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01004891 return ERR_ALERT | ERR_FATAL;
Willy Tarreauad1731d2013-04-02 17:35:58 +02004892 }
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01004893
4894 return 0;
4895}
4896
Emeric Brunfb510ea2012-10-05 12:00:26 +02004897/* parse the "crl-file" bind keyword */
4898static 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 +02004899{
Emeric Brun051cdab2012-10-02 19:25:50 +02004900#ifndef X509_V_FLAG_CRL_CHECK
4901 if (err)
4902 memprintf(err, "'%s' : library does not support CRL verify", args[cur_arg]);
4903 return ERR_ALERT | ERR_FATAL;
4904#else
Emeric Brund94b3fe2012-09-20 18:23:56 +02004905 if (!*args[cur_arg + 1]) {
4906 if (err)
4907 memprintf(err, "'%s' : missing CRLfile path", args[cur_arg]);
4908 return ERR_ALERT | ERR_FATAL;
4909 }
Emeric Brun2b58d042012-09-20 17:10:03 +02004910
Emeric Brunef42d922012-10-11 16:11:36 +02004911 if ((*args[cur_arg + 1] != '/') && global.ca_base)
4912 memprintf(&conf->crl_file, "%s/%s", global.ca_base, args[cur_arg + 1]);
4913 else
4914 memprintf(&conf->crl_file, "%s", args[cur_arg + 1]);
Emeric Brunc8e8d122012-10-02 18:42:10 +02004915
Emeric Brun2b58d042012-09-20 17:10:03 +02004916 return 0;
Emeric Brun051cdab2012-10-02 19:25:50 +02004917#endif
Emeric Brun2b58d042012-09-20 17:10:03 +02004918}
4919
4920/* parse the "ecdhe" bind keyword keywords */
4921static int bind_parse_ecdhe(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
4922{
4923#if OPENSSL_VERSION_NUMBER < 0x0090800fL
4924 if (err)
4925 memprintf(err, "'%s' : library does not support elliptic curve Diffie-Hellman (too old)", args[cur_arg]);
4926 return ERR_ALERT | ERR_FATAL;
4927#elif defined(OPENSSL_NO_ECDH)
4928 if (err)
4929 memprintf(err, "'%s' : library does not support elliptic curve Diffie-Hellman (disabled via OPENSSL_NO_ECDH)", args[cur_arg]);
4930 return ERR_ALERT | ERR_FATAL;
4931#else
4932 if (!*args[cur_arg + 1]) {
4933 if (err)
4934 memprintf(err, "'%s' : missing named curve", args[cur_arg]);
4935 return ERR_ALERT | ERR_FATAL;
4936 }
4937
4938 conf->ecdhe = strdup(args[cur_arg + 1]);
Willy Tarreau79eeafa2012-09-14 07:53:05 +02004939
4940 return 0;
Emeric Brun2b58d042012-09-20 17:10:03 +02004941#endif
Willy Tarreau79eeafa2012-09-14 07:53:05 +02004942}
4943
Emeric Brun81c00f02012-09-21 14:31:21 +02004944/* parse the "crt_ignerr" and "ca_ignerr" bind keywords */
4945static int bind_parse_ignore_err(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
4946{
4947 int code;
4948 char *p = args[cur_arg + 1];
4949 unsigned long long *ignerr = &conf->crt_ignerr;
4950
4951 if (!*p) {
4952 if (err)
4953 memprintf(err, "'%s' : missing error IDs list", args[cur_arg]);
4954 return ERR_ALERT | ERR_FATAL;
4955 }
4956
4957 if (strcmp(args[cur_arg], "ca-ignore-err") == 0)
4958 ignerr = &conf->ca_ignerr;
4959
4960 if (strcmp(p, "all") == 0) {
4961 *ignerr = ~0ULL;
4962 return 0;
4963 }
4964
4965 while (p) {
4966 code = atoi(p);
4967 if ((code <= 0) || (code > 63)) {
4968 if (err)
4969 memprintf(err, "'%s' : ID '%d' out of range (1..63) in error IDs list '%s'",
4970 args[cur_arg], code, args[cur_arg + 1]);
4971 return ERR_ALERT | ERR_FATAL;
4972 }
4973 *ignerr |= 1ULL << code;
4974 p = strchr(p, ',');
4975 if (p)
4976 p++;
4977 }
4978
Emeric Brun2cb7ae52012-10-05 14:14:21 +02004979 return 0;
4980}
4981
4982/* parse the "force-sslv3" bind keyword */
4983static int bind_parse_force_sslv3(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
4984{
4985 conf->ssl_options |= BC_SSL_O_USE_SSLV3;
4986 return 0;
4987}
4988
4989/* parse the "force-tlsv10" bind keyword */
4990static int bind_parse_force_tlsv10(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
4991{
4992 conf->ssl_options |= BC_SSL_O_USE_TLSV10;
Emeric Brun2d0c4822012-10-02 13:45:20 +02004993 return 0;
4994}
4995
Emeric Brun2cb7ae52012-10-05 14:14:21 +02004996/* parse the "force-tlsv11" bind keyword */
4997static int bind_parse_force_tlsv11(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
4998{
4999#if SSL_OP_NO_TLSv1_1
5000 conf->ssl_options |= BC_SSL_O_USE_TLSV11;
5001 return 0;
5002#else
5003 if (err)
5004 memprintf(err, "'%s' : library does not support protocol TLSv1.1", args[cur_arg]);
5005 return ERR_ALERT | ERR_FATAL;
5006#endif
5007}
5008
5009/* parse the "force-tlsv12" bind keyword */
5010static int bind_parse_force_tlsv12(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
5011{
5012#if SSL_OP_NO_TLSv1_2
5013 conf->ssl_options |= BC_SSL_O_USE_TLSV12;
5014 return 0;
5015#else
5016 if (err)
5017 memprintf(err, "'%s' : library does not support protocol TLSv1.2", args[cur_arg]);
5018 return ERR_ALERT | ERR_FATAL;
5019#endif
5020}
5021
5022
Emeric Brun2d0c4822012-10-02 13:45:20 +02005023/* parse the "no-tls-tickets" bind keyword */
5024static int bind_parse_no_tls_tickets(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
5025{
Emeric Brun89675492012-10-05 13:48:26 +02005026 conf->ssl_options |= BC_SSL_O_NO_TLS_TICKETS;
Emeric Brun81c00f02012-09-21 14:31:21 +02005027 return 0;
5028}
5029
Emeric Brun2d0c4822012-10-02 13:45:20 +02005030
Emeric Brun9b3009b2012-10-05 11:55:06 +02005031/* parse the "no-sslv3" bind keyword */
5032static 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 +02005033{
Emeric Brun89675492012-10-05 13:48:26 +02005034 conf->ssl_options |= BC_SSL_O_NO_SSLV3;
Willy Tarreau79eeafa2012-09-14 07:53:05 +02005035 return 0;
5036}
5037
Emeric Brun9b3009b2012-10-05 11:55:06 +02005038/* parse the "no-tlsv10" bind keyword */
5039static 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 +02005040{
Emeric Brun89675492012-10-05 13:48:26 +02005041 conf->ssl_options |= BC_SSL_O_NO_TLSV10;
Emeric Brunc0ff4922012-09-28 19:37:02 +02005042 return 0;
5043}
5044
Emeric Brun9b3009b2012-10-05 11:55:06 +02005045/* parse the "no-tlsv11" bind keyword */
5046static 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 +02005047{
Emeric Brun89675492012-10-05 13:48:26 +02005048 conf->ssl_options |= BC_SSL_O_NO_TLSV11;
Emeric Brunc0ff4922012-09-28 19:37:02 +02005049 return 0;
5050}
5051
Emeric Brun9b3009b2012-10-05 11:55:06 +02005052/* parse the "no-tlsv12" bind keyword */
5053static 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 +02005054{
Emeric Brun89675492012-10-05 13:48:26 +02005055 conf->ssl_options |= BC_SSL_O_NO_TLSV12;
Willy Tarreau79eeafa2012-09-14 07:53:05 +02005056 return 0;
5057}
5058
Willy Tarreau6c9a3d52012-10-18 18:57:14 +02005059/* parse the "npn" bind keyword */
5060static int bind_parse_npn(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
5061{
5062#ifdef OPENSSL_NPN_NEGOTIATED
5063 char *p1, *p2;
5064
5065 if (!*args[cur_arg + 1]) {
5066 memprintf(err, "'%s' : missing the comma-delimited NPN protocol suite", args[cur_arg]);
5067 return ERR_ALERT | ERR_FATAL;
5068 }
5069
5070 free(conf->npn_str);
5071
5072 /* the NPN string is built as a suite of (<len> <name>)* */
5073 conf->npn_len = strlen(args[cur_arg + 1]) + 1;
5074 conf->npn_str = calloc(1, conf->npn_len);
5075 memcpy(conf->npn_str + 1, args[cur_arg + 1], conf->npn_len);
5076
5077 /* replace commas with the name length */
5078 p1 = conf->npn_str;
5079 p2 = p1 + 1;
5080 while (1) {
5081 p2 = memchr(p1 + 1, ',', conf->npn_str + conf->npn_len - (p1 + 1));
5082 if (!p2)
5083 p2 = p1 + 1 + strlen(p1 + 1);
5084
5085 if (p2 - (p1 + 1) > 255) {
5086 *p2 = '\0';
5087 memprintf(err, "'%s' : NPN protocol name too long : '%s'", args[cur_arg], p1 + 1);
5088 return ERR_ALERT | ERR_FATAL;
5089 }
5090
5091 *p1 = p2 - (p1 + 1);
5092 p1 = p2;
5093
5094 if (!*p2)
5095 break;
5096
5097 *(p2++) = '\0';
5098 }
5099 return 0;
5100#else
5101 if (err)
5102 memprintf(err, "'%s' : library does not support TLS NPN extension", args[cur_arg]);
5103 return ERR_ALERT | ERR_FATAL;
5104#endif
5105}
5106
Willy Tarreauab861d32013-04-02 02:30:41 +02005107/* parse the "alpn" bind keyword */
5108static int bind_parse_alpn(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
5109{
Dirkjan Bussink48f1c4e2014-02-13 12:29:42 +01005110#ifdef TLSEXT_TYPE_application_layer_protocol_negotiation
Willy Tarreauab861d32013-04-02 02:30:41 +02005111 char *p1, *p2;
5112
5113 if (!*args[cur_arg + 1]) {
5114 memprintf(err, "'%s' : missing the comma-delimited ALPN protocol suite", args[cur_arg]);
5115 return ERR_ALERT | ERR_FATAL;
5116 }
5117
5118 free(conf->alpn_str);
5119
5120 /* the ALPN string is built as a suite of (<len> <name>)* */
5121 conf->alpn_len = strlen(args[cur_arg + 1]) + 1;
5122 conf->alpn_str = calloc(1, conf->alpn_len);
5123 memcpy(conf->alpn_str + 1, args[cur_arg + 1], conf->alpn_len);
5124
5125 /* replace commas with the name length */
5126 p1 = conf->alpn_str;
5127 p2 = p1 + 1;
5128 while (1) {
5129 p2 = memchr(p1 + 1, ',', conf->alpn_str + conf->alpn_len - (p1 + 1));
5130 if (!p2)
5131 p2 = p1 + 1 + strlen(p1 + 1);
5132
5133 if (p2 - (p1 + 1) > 255) {
5134 *p2 = '\0';
5135 memprintf(err, "'%s' : ALPN protocol name too long : '%s'", args[cur_arg], p1 + 1);
5136 return ERR_ALERT | ERR_FATAL;
5137 }
5138
5139 *p1 = p2 - (p1 + 1);
5140 p1 = p2;
5141
5142 if (!*p2)
5143 break;
5144
5145 *(p2++) = '\0';
5146 }
5147 return 0;
5148#else
5149 if (err)
5150 memprintf(err, "'%s' : library does not support TLS ALPN extension", args[cur_arg]);
5151 return ERR_ALERT | ERR_FATAL;
5152#endif
5153}
5154
Willy Tarreau79eeafa2012-09-14 07:53:05 +02005155/* parse the "ssl" bind keyword */
Willy Tarreau4348fad2012-09-20 16:48:07 +02005156static 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 +02005157{
Willy Tarreau81796be2012-09-22 19:11:47 +02005158 struct listener *l;
5159
Willy Tarreau4348fad2012-09-20 16:48:07 +02005160 conf->is_ssl = 1;
Emeric Brun76d88952012-10-05 15:47:31 +02005161
5162 if (global.listen_default_ciphers && !conf->ciphers)
5163 conf->ciphers = strdup(global.listen_default_ciphers);
Emeric Brun2c86cbf2014-10-30 15:56:50 +01005164 conf->ssl_options |= global.listen_default_ssloptions;
Emeric Brun76d88952012-10-05 15:47:31 +02005165
Willy Tarreau81796be2012-09-22 19:11:47 +02005166 list_for_each_entry(l, &conf->listeners, by_bind)
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02005167 l->xprt = &ssl_sock;
Willy Tarreau81796be2012-09-22 19:11:47 +02005168
Willy Tarreau79eeafa2012-09-14 07:53:05 +02005169 return 0;
5170}
5171
Christopher Faulet31af49d2015-06-09 17:29:50 +02005172/* parse the "generate-certificates" bind keyword */
5173static int bind_parse_generate_certs(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
5174{
5175#ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME
5176 conf->generate_certs = 1;
5177#else
5178 memprintf(err, "%sthis version of openssl cannot generate SSL certificates.\n",
5179 err && *err ? *err : "");
5180#endif
5181 return 0;
5182}
5183
Emmanuel Hocdet65623372013-01-24 17:17:15 +01005184/* parse the "strict-sni" bind keyword */
5185static int bind_parse_strict_sni(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
5186{
5187 conf->strict_sni = 1;
5188 return 0;
Nenad Merdanovic05552d42015-02-27 19:56:49 +01005189}
5190
5191/* parse the "tls-ticket-keys" bind keyword */
5192static int bind_parse_tls_ticket_keys(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
5193{
5194#if (defined SSL_CTRL_SET_TLSEXT_TICKET_KEY_CB && TLS_TICKETS_NO > 0)
5195 FILE *f;
5196 int i = 0;
5197 char thisline[LINESIZE];
Nenad Merdanovic146defa2015-05-09 08:46:00 +02005198 struct tls_keys_ref *keys_ref;
Nenad Merdanovic05552d42015-02-27 19:56:49 +01005199
5200 if (!*args[cur_arg + 1]) {
5201 if (err)
5202 memprintf(err, "'%s' : missing TLS ticket keys file path", args[cur_arg]);
5203 return ERR_ALERT | ERR_FATAL;
5204 }
5205
Nenad Merdanovic200b0fa2015-05-09 08:46:01 +02005206 keys_ref = tlskeys_ref_lookup(args[cur_arg + 1]);
5207 if(keys_ref) {
5208 conf->keys_ref = keys_ref;
5209 return 0;
5210 }
5211
Nenad Merdanovic146defa2015-05-09 08:46:00 +02005212 keys_ref = malloc(sizeof(struct tls_keys_ref));
5213 keys_ref->tlskeys = malloc(TLS_TICKETS_NO * sizeof(struct tls_sess_key));
Nenad Merdanovic05552d42015-02-27 19:56:49 +01005214
5215 if ((f = fopen(args[cur_arg + 1], "r")) == NULL) {
5216 if (err)
5217 memprintf(err, "'%s' : unable to load ssl tickets keys file", args[cur_arg+1]);
5218 return ERR_ALERT | ERR_FATAL;
5219 }
5220
Nenad Merdanovic146defa2015-05-09 08:46:00 +02005221 keys_ref->filename = strdup(args[cur_arg + 1]);
5222
Nenad Merdanovic05552d42015-02-27 19:56:49 +01005223 while (fgets(thisline, sizeof(thisline), f) != NULL) {
5224 int len = strlen(thisline);
5225 /* Strip newline characters from the end */
5226 if(thisline[len - 1] == '\n')
5227 thisline[--len] = 0;
5228
5229 if(thisline[len - 1] == '\r')
5230 thisline[--len] = 0;
5231
Nenad Merdanovic146defa2015-05-09 08:46:00 +02005232 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 +01005233 if (err)
5234 memprintf(err, "'%s' : unable to decode base64 key on line %d", args[cur_arg+1], i + 1);
5235 return ERR_ALERT | ERR_FATAL;
5236 }
5237 i++;
5238 }
5239
5240 if (i < TLS_TICKETS_NO) {
5241 if (err)
5242 memprintf(err, "'%s' : please supply at least %d keys in the tls-tickets-file", args[cur_arg+1], TLS_TICKETS_NO);
5243 return ERR_ALERT | ERR_FATAL;
5244 }
5245
5246 fclose(f);
5247
5248 /* Use penultimate key for encryption, handle when TLS_TICKETS_NO = 1 */
5249 i-=2;
Nenad Merdanovic146defa2015-05-09 08:46:00 +02005250 keys_ref->tls_ticket_enc_index = i < 0 ? 0 : i;
Nenad Merdanovic200b0fa2015-05-09 08:46:01 +02005251 keys_ref->unique_id = -1;
Nenad Merdanovic146defa2015-05-09 08:46:00 +02005252 conf->keys_ref = keys_ref;
Nenad Merdanovic05552d42015-02-27 19:56:49 +01005253
Nenad Merdanovic200b0fa2015-05-09 08:46:01 +02005254 LIST_ADD(&tlskeys_reference, &keys_ref->list);
5255
Nenad Merdanovic05552d42015-02-27 19:56:49 +01005256 return 0;
5257#else
5258 if (err)
5259 memprintf(err, "'%s' : TLS ticket callback extension not supported", args[cur_arg]);
5260 return ERR_ALERT | ERR_FATAL;
5261#endif /* SSL_CTRL_SET_TLSEXT_TICKET_KEY_CB */
Emmanuel Hocdet65623372013-01-24 17:17:15 +01005262}
5263
Emeric Brund94b3fe2012-09-20 18:23:56 +02005264/* parse the "verify" bind keyword */
5265static int bind_parse_verify(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
5266{
5267 if (!*args[cur_arg + 1]) {
5268 if (err)
5269 memprintf(err, "'%s' : missing verify method", args[cur_arg]);
5270 return ERR_ALERT | ERR_FATAL;
5271 }
5272
5273 if (strcmp(args[cur_arg + 1], "none") == 0)
Emeric Brun850efd52014-01-29 12:24:34 +01005274 conf->verify = SSL_SOCK_VERIFY_NONE;
Emeric Brund94b3fe2012-09-20 18:23:56 +02005275 else if (strcmp(args[cur_arg + 1], "optional") == 0)
Emeric Brun850efd52014-01-29 12:24:34 +01005276 conf->verify = SSL_SOCK_VERIFY_OPTIONAL;
Emeric Brund94b3fe2012-09-20 18:23:56 +02005277 else if (strcmp(args[cur_arg + 1], "required") == 0)
Emeric Brun850efd52014-01-29 12:24:34 +01005278 conf->verify = SSL_SOCK_VERIFY_REQUIRED;
Emeric Brund94b3fe2012-09-20 18:23:56 +02005279 else {
5280 if (err)
5281 memprintf(err, "'%s' : unknown verify method '%s', only 'none', 'optional', and 'required' are supported\n",
5282 args[cur_arg], args[cur_arg + 1]);
5283 return ERR_ALERT | ERR_FATAL;
5284 }
5285
5286 return 0;
5287}
5288
Willy Tarreau92faadf2012-10-10 23:04:25 +02005289/************** "server" keywords ****************/
5290
Emeric Brunef42d922012-10-11 16:11:36 +02005291/* parse the "ca-file" server keyword */
5292static int srv_parse_ca_file(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
5293{
5294 if (!*args[*cur_arg + 1]) {
5295 if (err)
5296 memprintf(err, "'%s' : missing CAfile path", args[*cur_arg]);
5297 return ERR_ALERT | ERR_FATAL;
5298 }
5299
5300 if ((*args[*cur_arg + 1] != '/') && global.ca_base)
5301 memprintf(&newsrv->ssl_ctx.ca_file, "%s/%s", global.ca_base, args[*cur_arg + 1]);
5302 else
5303 memprintf(&newsrv->ssl_ctx.ca_file, "%s", args[*cur_arg + 1]);
5304
5305 return 0;
5306}
5307
Willy Tarreau92faadf2012-10-10 23:04:25 +02005308/* parse the "check-ssl" server keyword */
5309static int srv_parse_check_ssl(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
5310{
5311 newsrv->check.use_ssl = 1;
5312 if (global.connect_default_ciphers && !newsrv->ssl_ctx.ciphers)
5313 newsrv->ssl_ctx.ciphers = strdup(global.connect_default_ciphers);
Emeric Brun2c86cbf2014-10-30 15:56:50 +01005314 newsrv->ssl_ctx.options |= global.connect_default_ssloptions;
Willy Tarreau92faadf2012-10-10 23:04:25 +02005315 return 0;
5316}
5317
5318/* parse the "ciphers" server keyword */
5319static int srv_parse_ciphers(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
5320{
5321 if (!*args[*cur_arg + 1]) {
5322 memprintf(err, "'%s' : missing cipher suite", args[*cur_arg]);
5323 return ERR_ALERT | ERR_FATAL;
5324 }
5325
5326 free(newsrv->ssl_ctx.ciphers);
5327 newsrv->ssl_ctx.ciphers = strdup(args[*cur_arg + 1]);
5328 return 0;
5329}
5330
Emeric Brunef42d922012-10-11 16:11:36 +02005331/* parse the "crl-file" server keyword */
5332static int srv_parse_crl_file(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
5333{
5334#ifndef X509_V_FLAG_CRL_CHECK
5335 if (err)
5336 memprintf(err, "'%s' : library does not support CRL verify", args[*cur_arg]);
5337 return ERR_ALERT | ERR_FATAL;
5338#else
5339 if (!*args[*cur_arg + 1]) {
5340 if (err)
5341 memprintf(err, "'%s' : missing CRLfile path", args[*cur_arg]);
5342 return ERR_ALERT | ERR_FATAL;
5343 }
5344
5345 if ((*args[*cur_arg + 1] != '/') && global.ca_base)
5346 memprintf(&newsrv->ssl_ctx.crl_file, "%s/%s", global.ca_base, args[*cur_arg + 1]);
5347 else
5348 memprintf(&newsrv->ssl_ctx.crl_file, "%s", args[*cur_arg + 1]);
5349
5350 return 0;
5351#endif
5352}
5353
Emeric Bruna7aa3092012-10-26 12:58:00 +02005354/* parse the "crt" server keyword */
5355static int srv_parse_crt(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
5356{
5357 if (!*args[*cur_arg + 1]) {
5358 if (err)
5359 memprintf(err, "'%s' : missing certificate file path", args[*cur_arg]);
5360 return ERR_ALERT | ERR_FATAL;
5361 }
5362
5363 if ((*args[*cur_arg + 1] != '/') && global.crt_base)
5364 memprintf(&newsrv->ssl_ctx.client_crt, "%s/%s", global.ca_base, args[*cur_arg + 1]);
5365 else
5366 memprintf(&newsrv->ssl_ctx.client_crt, "%s", args[*cur_arg + 1]);
5367
5368 return 0;
5369}
Emeric Brunef42d922012-10-11 16:11:36 +02005370
Willy Tarreau92faadf2012-10-10 23:04:25 +02005371/* parse the "force-sslv3" server keyword */
5372static int srv_parse_force_sslv3(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
5373{
5374 newsrv->ssl_ctx.options |= SRV_SSL_O_USE_SSLV3;
5375 return 0;
5376}
5377
5378/* parse the "force-tlsv10" server keyword */
5379static int srv_parse_force_tlsv10(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
5380{
5381 newsrv->ssl_ctx.options |= SRV_SSL_O_USE_TLSV10;
5382 return 0;
5383}
5384
5385/* parse the "force-tlsv11" server keyword */
5386static int srv_parse_force_tlsv11(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
5387{
5388#if SSL_OP_NO_TLSv1_1
5389 newsrv->ssl_ctx.options |= SRV_SSL_O_USE_TLSV11;
5390 return 0;
5391#else
5392 if (err)
5393 memprintf(err, "'%s' : library does not support protocol TLSv1.1", args[*cur_arg]);
5394 return ERR_ALERT | ERR_FATAL;
5395#endif
5396}
5397
5398/* parse the "force-tlsv12" server keyword */
5399static int srv_parse_force_tlsv12(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
5400{
5401#if SSL_OP_NO_TLSv1_2
5402 newsrv->ssl_ctx.options |= SRV_SSL_O_USE_TLSV12;
5403 return 0;
5404#else
5405 if (err)
5406 memprintf(err, "'%s' : library does not support protocol TLSv1.2", args[*cur_arg]);
5407 return ERR_ALERT | ERR_FATAL;
5408#endif
5409}
5410
Willy Tarreau2a3fb1c2015-02-05 16:47:07 +01005411/* parse the "no-ssl-reuse" server keyword */
5412static int srv_parse_no_ssl_reuse(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
5413{
5414 newsrv->ssl_ctx.options |= SRV_SSL_O_NO_REUSE;
5415 return 0;
5416}
5417
Willy Tarreau92faadf2012-10-10 23:04:25 +02005418/* parse the "no-sslv3" server keyword */
5419static int srv_parse_no_sslv3(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
5420{
5421 newsrv->ssl_ctx.options |= SRV_SSL_O_NO_SSLV3;
5422 return 0;
5423}
5424
5425/* parse the "no-tlsv10" server keyword */
5426static int srv_parse_no_tlsv10(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
5427{
5428 newsrv->ssl_ctx.options |= SRV_SSL_O_NO_TLSV10;
5429 return 0;
5430}
5431
5432/* parse the "no-tlsv11" server keyword */
5433static int srv_parse_no_tlsv11(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
5434{
5435 newsrv->ssl_ctx.options |= SRV_SSL_O_NO_TLSV11;
5436 return 0;
5437}
5438
5439/* parse the "no-tlsv12" server keyword */
5440static int srv_parse_no_tlsv12(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
5441{
5442 newsrv->ssl_ctx.options |= SRV_SSL_O_NO_TLSV12;
5443 return 0;
5444}
5445
Emeric Brunf9c5c472012-10-11 15:28:34 +02005446/* parse the "no-tls-tickets" server keyword */
5447static int srv_parse_no_tls_tickets(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
5448{
5449 newsrv->ssl_ctx.options |= SRV_SSL_O_NO_TLS_TICKETS;
5450 return 0;
5451}
David Safb76832014-05-08 23:42:08 -04005452/* parse the "send-proxy-v2-ssl" server keyword */
5453static int srv_parse_send_proxy_ssl(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
5454{
5455 newsrv->pp_opts |= SRV_PP_V2;
5456 newsrv->pp_opts |= SRV_PP_V2_SSL;
5457 return 0;
5458}
5459
5460/* parse the "send-proxy-v2-ssl-cn" server keyword */
5461static int srv_parse_send_proxy_cn(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
5462{
5463 newsrv->pp_opts |= SRV_PP_V2;
5464 newsrv->pp_opts |= SRV_PP_V2_SSL;
5465 newsrv->pp_opts |= SRV_PP_V2_SSL_CN;
5466 return 0;
5467}
Emeric Brunf9c5c472012-10-11 15:28:34 +02005468
Willy Tarreau732eac42015-07-09 11:40:25 +02005469/* parse the "sni" server keyword */
5470static int srv_parse_sni(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
5471{
5472#ifndef SSL_CTRL_SET_TLSEXT_HOSTNAME
5473 memprintf(err, "'%s' : the current SSL library doesn't support the SNI TLS extension", args[*cur_arg]);
5474 return ERR_ALERT | ERR_FATAL;
5475#else
5476 struct sample_expr *expr;
5477
5478 if (!*args[*cur_arg + 1]) {
5479 memprintf(err, "'%s' : missing sni expression", args[*cur_arg]);
5480 return ERR_ALERT | ERR_FATAL;
5481 }
5482
5483 (*cur_arg)++;
5484 proxy->conf.args.ctx = ARGC_SRV;
5485
5486 expr = sample_parse_expr((char **)args, cur_arg, px->conf.file, px->conf.line, err, &proxy->conf.args);
5487 if (!expr) {
5488 memprintf(err, "error detected while parsing sni expression : %s", *err);
5489 return ERR_ALERT | ERR_FATAL;
5490 }
5491
5492 if (!(expr->fetch->val & SMP_VAL_BE_SRV_CON)) {
5493 memprintf(err, "error detected while parsing sni expression : "
5494 " fetch method '%s' extracts information from '%s', none of which is available here.\n",
5495 args[*cur_arg-1], sample_src_names(expr->fetch->use));
5496 return ERR_ALERT | ERR_FATAL;
5497 }
5498
5499 px->http_needed |= !!(expr->fetch->use & SMP_USE_HTTP_ANY);
5500 newsrv->ssl_ctx.sni = expr;
5501 return 0;
5502#endif
5503}
5504
Willy Tarreau92faadf2012-10-10 23:04:25 +02005505/* parse the "ssl" server keyword */
5506static int srv_parse_ssl(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
5507{
5508 newsrv->use_ssl = 1;
5509 if (global.connect_default_ciphers && !newsrv->ssl_ctx.ciphers)
5510 newsrv->ssl_ctx.ciphers = strdup(global.connect_default_ciphers);
5511 return 0;
5512}
5513
Emeric Brunef42d922012-10-11 16:11:36 +02005514/* parse the "verify" server keyword */
5515static int srv_parse_verify(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 verify method", args[*cur_arg]);
5520 return ERR_ALERT | ERR_FATAL;
5521 }
5522
5523 if (strcmp(args[*cur_arg + 1], "none") == 0)
Emeric Brun850efd52014-01-29 12:24:34 +01005524 newsrv->ssl_ctx.verify = SSL_SOCK_VERIFY_NONE;
Emeric Brunef42d922012-10-11 16:11:36 +02005525 else if (strcmp(args[*cur_arg + 1], "required") == 0)
Emeric Brun850efd52014-01-29 12:24:34 +01005526 newsrv->ssl_ctx.verify = SSL_SOCK_VERIFY_REQUIRED;
Emeric Brunef42d922012-10-11 16:11:36 +02005527 else {
5528 if (err)
5529 memprintf(err, "'%s' : unknown verify method '%s', only 'none' and 'required' are supported\n",
5530 args[*cur_arg], args[*cur_arg + 1]);
5531 return ERR_ALERT | ERR_FATAL;
5532 }
5533
Evan Broderbe554312013-06-27 00:05:25 -07005534 return 0;
5535}
5536
5537/* parse the "verifyhost" server keyword */
5538static int srv_parse_verifyhost(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
5539{
5540 if (!*args[*cur_arg + 1]) {
5541 if (err)
5542 memprintf(err, "'%s' : missing hostname to verify against", args[*cur_arg]);
5543 return ERR_ALERT | ERR_FATAL;
5544 }
5545
5546 newsrv->ssl_ctx.verify_host = strdup(args[*cur_arg + 1]);
5547
Emeric Brunef42d922012-10-11 16:11:36 +02005548 return 0;
5549}
5550
Emeric Brun2c86cbf2014-10-30 15:56:50 +01005551/* parse the "ssl-default-bind-options" keyword in global section */
5552static int ssl_parse_default_bind_options(char **args, int section_type, struct proxy *curpx,
5553 struct proxy *defpx, const char *file, int line,
5554 char **err) {
5555 int i = 1;
5556
5557 if (*(args[i]) == 0) {
5558 memprintf(err, "global statement '%s' expects an option as an argument.", args[0]);
5559 return -1;
5560 }
5561 while (*(args[i])) {
5562 if (!strcmp(args[i], "no-sslv3"))
5563 global.listen_default_ssloptions |= BC_SSL_O_NO_SSLV3;
5564 else if (!strcmp(args[i], "no-tlsv10"))
5565 global.listen_default_ssloptions |= BC_SSL_O_NO_TLSV10;
5566 else if (!strcmp(args[i], "no-tlsv11"))
5567 global.listen_default_ssloptions |= BC_SSL_O_NO_TLSV11;
5568 else if (!strcmp(args[i], "no-tlsv12"))
5569 global.listen_default_ssloptions |= BC_SSL_O_NO_TLSV12;
5570 else if (!strcmp(args[i], "force-sslv3"))
5571 global.listen_default_ssloptions |= BC_SSL_O_USE_SSLV3;
5572 else if (!strcmp(args[i], "force-tlsv10"))
5573 global.listen_default_ssloptions |= BC_SSL_O_USE_TLSV10;
5574 else if (!strcmp(args[i], "force-tlsv11")) {
5575#if SSL_OP_NO_TLSv1_1
5576 global.listen_default_ssloptions |= BC_SSL_O_USE_TLSV11;
5577#else
5578 memprintf(err, "'%s' '%s': library does not support protocol TLSv1.1", args[0], args[i]);
5579 return -1;
5580#endif
5581 }
5582 else if (!strcmp(args[i], "force-tlsv12")) {
5583#if SSL_OP_NO_TLSv1_2
5584 global.listen_default_ssloptions |= BC_SSL_O_USE_TLSV12;
5585#else
5586 memprintf(err, "'%s' '%s': library does not support protocol TLSv1.2", args[0], args[i]);
5587 return -1;
5588#endif
5589 }
5590 else if (!strcmp(args[i], "no-tls-tickets"))
5591 global.listen_default_ssloptions |= BC_SSL_O_NO_TLS_TICKETS;
5592 else {
5593 memprintf(err, "unknown option '%s' on global statement '%s'.", args[i], args[0]);
5594 return -1;
5595 }
5596 i++;
5597 }
5598 return 0;
5599}
5600
5601/* parse the "ssl-default-server-options" keyword in global section */
5602static int ssl_parse_default_server_options(char **args, int section_type, struct proxy *curpx,
5603 struct proxy *defpx, const char *file, int line,
5604 char **err) {
5605 int i = 1;
5606
5607 if (*(args[i]) == 0) {
5608 memprintf(err, "global statement '%s' expects an option as an argument.", args[0]);
5609 return -1;
5610 }
5611 while (*(args[i])) {
5612 if (!strcmp(args[i], "no-sslv3"))
5613 global.connect_default_ssloptions |= SRV_SSL_O_NO_SSLV3;
5614 else if (!strcmp(args[i], "no-tlsv10"))
5615 global.connect_default_ssloptions |= SRV_SSL_O_NO_TLSV10;
5616 else if (!strcmp(args[i], "no-tlsv11"))
5617 global.connect_default_ssloptions |= SRV_SSL_O_NO_TLSV11;
5618 else if (!strcmp(args[i], "no-tlsv12"))
5619 global.connect_default_ssloptions |= SRV_SSL_O_NO_TLSV12;
5620 else if (!strcmp(args[i], "force-sslv3"))
5621 global.connect_default_ssloptions |= SRV_SSL_O_USE_SSLV3;
5622 else if (!strcmp(args[i], "force-tlsv10"))
5623 global.connect_default_ssloptions |= SRV_SSL_O_USE_TLSV10;
5624 else if (!strcmp(args[i], "force-tlsv11")) {
5625#if SSL_OP_NO_TLSv1_1
5626 global.connect_default_ssloptions |= SRV_SSL_O_USE_TLSV11;
5627#else
5628 memprintf(err, "'%s' '%s': library does not support protocol TLSv1.1", args[0], args[i]);
5629 return -1;
5630#endif
5631 }
5632 else if (!strcmp(args[i], "force-tlsv12")) {
5633#if SSL_OP_NO_TLSv1_2
5634 global.connect_default_ssloptions |= SRV_SSL_O_USE_TLSV12;
5635#else
5636 memprintf(err, "'%s' '%s': library does not support protocol TLSv1.2", args[0], args[i]);
5637 return -1;
5638#endif
5639 }
5640 else if (!strcmp(args[i], "no-tls-tickets"))
5641 global.connect_default_ssloptions |= SRV_SSL_O_NO_TLS_TICKETS;
5642 else {
5643 memprintf(err, "unknown option '%s' on global statement '%s'.", args[i], args[0]);
5644 return -1;
5645 }
5646 i++;
5647 }
5648 return 0;
5649}
5650
Willy Tarreau7875d092012-09-10 08:20:03 +02005651/* Note: must not be declared <const> as its list will be overwritten.
5652 * Please take care of keeping this list alphabetically sorted.
5653 */
Willy Tarreaudc13c112013-06-21 23:16:39 +02005654static struct sample_fetch_kw_list sample_fetch_keywords = {ILH, {
Emeric Brun645ae792014-04-30 14:21:06 +02005655 { "ssl_bc", smp_fetch_ssl_fc, 0, NULL, SMP_T_BOOL, SMP_USE_L5SRV },
Thierry FOURNIER07ee64e2015-07-06 23:43:03 +02005656 { "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 +02005657 { "ssl_bc_cipher", smp_fetch_ssl_fc_cipher, 0, NULL, SMP_T_STR, SMP_USE_L5SRV },
5658 { "ssl_bc_protocol", smp_fetch_ssl_fc_protocol, 0, NULL, SMP_T_STR, SMP_USE_L5SRV },
Emeric Brunb73a9b02014-04-30 18:49:19 +02005659 { "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 +02005660 { "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 +02005661 { "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 +02005662 { "ssl_c_ca_err", smp_fetch_ssl_c_ca_err, 0, NULL, SMP_T_SINT, SMP_USE_L5CLI },
5663 { "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 +01005664 { "ssl_c_der", smp_fetch_ssl_x_der, 0, NULL, SMP_T_BIN, SMP_USE_L5CLI },
Thierry FOURNIER07ee64e2015-07-06 23:43:03 +02005665 { "ssl_c_err", smp_fetch_ssl_c_err, 0, NULL, SMP_T_SINT, SMP_USE_L5CLI },
Emeric Brunba841a12014-04-30 17:05:08 +02005666 { "ssl_c_i_dn", smp_fetch_ssl_x_i_dn, ARG2(0,STR,SINT), NULL, SMP_T_STR, SMP_USE_L5CLI },
5667 { "ssl_c_key_alg", smp_fetch_ssl_x_key_alg, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
5668 { "ssl_c_notafter", smp_fetch_ssl_x_notafter, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
5669 { "ssl_c_notbefore", smp_fetch_ssl_x_notbefore, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
5670 { "ssl_c_sig_alg", smp_fetch_ssl_x_sig_alg, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
5671 { "ssl_c_s_dn", smp_fetch_ssl_x_s_dn, ARG2(0,STR,SINT), NULL, SMP_T_STR, SMP_USE_L5CLI },
5672 { "ssl_c_serial", smp_fetch_ssl_x_serial, 0, NULL, SMP_T_BIN, SMP_USE_L5CLI },
5673 { "ssl_c_sha1", smp_fetch_ssl_x_sha1, 0, NULL, SMP_T_BIN, SMP_USE_L5CLI },
Willy Tarreau80aca902013-01-07 15:42:20 +01005674 { "ssl_c_used", smp_fetch_ssl_c_used, 0, NULL, SMP_T_BOOL, SMP_USE_L5CLI },
Thierry FOURNIER07ee64e2015-07-06 23:43:03 +02005675 { "ssl_c_verify", smp_fetch_ssl_c_verify, 0, NULL, SMP_T_SINT, SMP_USE_L5CLI },
5676 { "ssl_c_version", smp_fetch_ssl_x_version, 0, NULL, SMP_T_SINT, SMP_USE_L5CLI },
Emeric Brun43e79582014-10-29 19:03:26 +01005677 { "ssl_f_der", smp_fetch_ssl_x_der, 0, NULL, SMP_T_BIN, SMP_USE_L5CLI },
Emeric Brunba841a12014-04-30 17:05:08 +02005678 { "ssl_f_i_dn", smp_fetch_ssl_x_i_dn, ARG2(0,STR,SINT), NULL, SMP_T_STR, SMP_USE_L5CLI },
5679 { "ssl_f_key_alg", smp_fetch_ssl_x_key_alg, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
5680 { "ssl_f_notafter", smp_fetch_ssl_x_notafter, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
5681 { "ssl_f_notbefore", smp_fetch_ssl_x_notbefore, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
5682 { "ssl_f_sig_alg", smp_fetch_ssl_x_sig_alg, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
5683 { "ssl_f_s_dn", smp_fetch_ssl_x_s_dn, ARG2(0,STR,SINT), NULL, SMP_T_STR, SMP_USE_L5CLI },
5684 { "ssl_f_serial", smp_fetch_ssl_x_serial, 0, NULL, SMP_T_BIN, SMP_USE_L5CLI },
Emeric Brun55f4fa82014-04-30 17:11:25 +02005685 { "ssl_f_sha1", smp_fetch_ssl_x_sha1, 0, NULL, SMP_T_BIN, SMP_USE_L5CLI },
Thierry FOURNIER07ee64e2015-07-06 23:43:03 +02005686 { "ssl_f_version", smp_fetch_ssl_x_version, 0, NULL, SMP_T_SINT, SMP_USE_L5CLI },
Willy Tarreau80aca902013-01-07 15:42:20 +01005687 { "ssl_fc", smp_fetch_ssl_fc, 0, NULL, SMP_T_BOOL, SMP_USE_L5CLI },
Thierry FOURNIER07ee64e2015-07-06 23:43:03 +02005688 { "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 +01005689 { "ssl_fc_cipher", smp_fetch_ssl_fc_cipher, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
Willy Tarreau80aca902013-01-07 15:42:20 +01005690 { "ssl_fc_has_crt", smp_fetch_ssl_fc_has_crt, 0, NULL, SMP_T_BOOL, SMP_USE_L5CLI },
5691 { "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 +02005692 { "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 +02005693#ifdef OPENSSL_NPN_NEGOTIATED
Thierry FOURNIER7654c9f2013-12-17 00:20:33 +01005694 { "ssl_fc_npn", smp_fetch_ssl_fc_npn, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
Willy Tarreaua33c6542012-10-15 13:19:06 +02005695#endif
Dirkjan Bussink48f1c4e2014-02-13 12:29:42 +01005696#ifdef TLSEXT_TYPE_application_layer_protocol_negotiation
Thierry FOURNIER7654c9f2013-12-17 00:20:33 +01005697 { "ssl_fc_alpn", smp_fetch_ssl_fc_alpn, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
Willy Tarreauab861d32013-04-02 02:30:41 +02005698#endif
Thierry FOURNIER7654c9f2013-12-17 00:20:33 +01005699 { "ssl_fc_protocol", smp_fetch_ssl_fc_protocol, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
Emeric Brunb73a9b02014-04-30 18:49:19 +02005700 { "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 +02005701 { "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 +01005702 { "ssl_fc_session_id", smp_fetch_ssl_fc_session_id, 0, NULL, SMP_T_BIN, SMP_USE_L5CLI },
5703 { "ssl_fc_sni", smp_fetch_ssl_fc_sni, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
Willy Tarreau7875d092012-09-10 08:20:03 +02005704 { NULL, NULL, 0, 0, 0 },
5705}};
5706
5707/* Note: must not be declared <const> as its list will be overwritten.
5708 * Please take care of keeping this list alphabetically sorted.
5709 */
Willy Tarreaudc13c112013-06-21 23:16:39 +02005710static struct acl_kw_list acl_kws = {ILH, {
Thierry FOURNIERc5a4e982014-03-05 16:07:08 +01005711 { "ssl_fc_sni_end", "ssl_fc_sni", PAT_MATCH_END },
5712 { "ssl_fc_sni_reg", "ssl_fc_sni", PAT_MATCH_REG },
Willy Tarreau8ed669b2013-01-11 15:49:37 +01005713 { /* END */ },
Willy Tarreau7875d092012-09-10 08:20:03 +02005714}};
5715
Willy Tarreau79eeafa2012-09-14 07:53:05 +02005716/* Note: must not be declared <const> as its list will be overwritten.
5717 * Please take care of keeping this list alphabetically sorted, doing so helps
5718 * all code contributors.
5719 * Optional keywords are also declared with a NULL ->parse() function so that
5720 * the config parser can report an appropriate error when a known keyword was
5721 * not enabled.
5722 */
Willy Tarreau51fb7652012-09-18 18:24:39 +02005723static struct bind_kw_list bind_kws = { "SSL", { }, {
Nenad Merdanovic05552d42015-02-27 19:56:49 +01005724 { "alpn", bind_parse_alpn, 1 }, /* set ALPN supported protocols */
5725 { "ca-file", bind_parse_ca_file, 1 }, /* set CAfile to process verify on client cert */
5726 { "ca-ignore-err", bind_parse_ignore_err, 1 }, /* set error IDs to ignore on verify depth > 0 */
Christopher Faulet31af49d2015-06-09 17:29:50 +02005727 { "ca-sign-file", bind_parse_ca_sign_file, 1 }, /* set CAFile used to generate and sign server certs */
5728 { "ca-sign-pass", bind_parse_ca_sign_pass, 1 }, /* set CAKey passphrase */
Nenad Merdanovic05552d42015-02-27 19:56:49 +01005729 { "ciphers", bind_parse_ciphers, 1 }, /* set SSL cipher suite */
5730 { "crl-file", bind_parse_crl_file, 1 }, /* set certificat revocation list file use on client cert verify */
5731 { "crt", bind_parse_crt, 1 }, /* load SSL certificates from this location */
5732 { "crt-ignore-err", bind_parse_ignore_err, 1 }, /* set error IDs to ingore on verify depth == 0 */
5733 { "crt-list", bind_parse_crt_list, 1 }, /* load a list of crt from this location */
5734 { "ecdhe", bind_parse_ecdhe, 1 }, /* defines named curve for elliptic curve Diffie-Hellman */
5735 { "force-sslv3", bind_parse_force_sslv3, 0 }, /* force SSLv3 */
5736 { "force-tlsv10", bind_parse_force_tlsv10, 0 }, /* force TLSv10 */
5737 { "force-tlsv11", bind_parse_force_tlsv11, 0 }, /* force TLSv11 */
5738 { "force-tlsv12", bind_parse_force_tlsv12, 0 }, /* force TLSv12 */
Christopher Faulet31af49d2015-06-09 17:29:50 +02005739 { "generate-certificates", bind_parse_generate_certs, 0 }, /* enable the server certificates generation */
Nenad Merdanovic05552d42015-02-27 19:56:49 +01005740 { "no-sslv3", bind_parse_no_sslv3, 0 }, /* disable SSLv3 */
5741 { "no-tlsv10", bind_parse_no_tlsv10, 0 }, /* disable TLSv10 */
5742 { "no-tlsv11", bind_parse_no_tlsv11, 0 }, /* disable TLSv11 */
5743 { "no-tlsv12", bind_parse_no_tlsv12, 0 }, /* disable TLSv12 */
5744 { "no-tls-tickets", bind_parse_no_tls_tickets, 0 }, /* disable session resumption tickets */
5745 { "ssl", bind_parse_ssl, 0 }, /* enable SSL processing */
5746 { "strict-sni", bind_parse_strict_sni, 0 }, /* refuse negotiation if sni doesn't match a certificate */
5747 { "tls-ticket-keys", bind_parse_tls_ticket_keys, 1 }, /* set file to load TLS ticket keys from */
5748 { "verify", bind_parse_verify, 1 }, /* set SSL verify method */
5749 { "npn", bind_parse_npn, 1 }, /* set NPN supported protocols */
Willy Tarreau79eeafa2012-09-14 07:53:05 +02005750 { NULL, NULL, 0 },
5751}};
Emeric Brun46591952012-05-18 15:47:34 +02005752
Willy Tarreau92faadf2012-10-10 23:04:25 +02005753/* Note: must not be declared <const> as its list will be overwritten.
5754 * Please take care of keeping this list alphabetically sorted, doing so helps
5755 * all code contributors.
5756 * Optional keywords are also declared with a NULL ->parse() function so that
5757 * the config parser can report an appropriate error when a known keyword was
5758 * not enabled.
5759 */
5760static struct srv_kw_list srv_kws = { "SSL", { }, {
Emeric Brunef42d922012-10-11 16:11:36 +02005761 { "ca-file", srv_parse_ca_file, 1, 0 }, /* set CAfile to process verify server cert */
Emeric Brunecc91fe2012-10-11 15:05:10 +02005762 { "check-ssl", srv_parse_check_ssl, 0, 0 }, /* enable SSL for health checks */
5763 { "ciphers", srv_parse_ciphers, 1, 0 }, /* select the cipher suite */
Emeric Brunef42d922012-10-11 16:11:36 +02005764 { "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 +02005765 { "crt", srv_parse_crt, 1, 0 }, /* set client certificate */
Emeric Brunecc91fe2012-10-11 15:05:10 +02005766 { "force-sslv3", srv_parse_force_sslv3, 0, 0 }, /* force SSLv3 */
5767 { "force-tlsv10", srv_parse_force_tlsv10, 0, 0 }, /* force TLSv10 */
5768 { "force-tlsv11", srv_parse_force_tlsv11, 0, 0 }, /* force TLSv11 */
5769 { "force-tlsv12", srv_parse_force_tlsv12, 0, 0 }, /* force TLSv12 */
Willy Tarreau2a3fb1c2015-02-05 16:47:07 +01005770 { "no-ssl-reuse", srv_parse_no_ssl_reuse, 0, 0 }, /* disable session reuse */
Emeric Brunecc91fe2012-10-11 15:05:10 +02005771 { "no-sslv3", srv_parse_no_sslv3, 0, 0 }, /* disable SSLv3 */
5772 { "no-tlsv10", srv_parse_no_tlsv10, 0, 0 }, /* disable TLSv10 */
5773 { "no-tlsv11", srv_parse_no_tlsv11, 0, 0 }, /* disable TLSv11 */
5774 { "no-tlsv12", srv_parse_no_tlsv12, 0, 0 }, /* disable TLSv12 */
Emeric Brunf9c5c472012-10-11 15:28:34 +02005775 { "no-tls-tickets", srv_parse_no_tls_tickets, 0, 0 }, /* disable session resumption tickets */
David Safb76832014-05-08 23:42:08 -04005776 { "send-proxy-v2-ssl", srv_parse_send_proxy_ssl, 0, 0 }, /* send PROXY protocol header v2 with SSL info */
5777 { "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 +02005778 { "sni", srv_parse_sni, 1, 0 }, /* send SNI extension */
Emeric Brunecc91fe2012-10-11 15:05:10 +02005779 { "ssl", srv_parse_ssl, 0, 0 }, /* enable SSL processing */
Emeric Brunef42d922012-10-11 16:11:36 +02005780 { "verify", srv_parse_verify, 1, 0 }, /* set SSL verify method */
Evan Broderbe554312013-06-27 00:05:25 -07005781 { "verifyhost", srv_parse_verifyhost, 1, 0 }, /* require that SSL cert verifies for hostname */
Willy Tarreau92faadf2012-10-10 23:04:25 +02005782 { NULL, NULL, 0, 0 },
5783}};
5784
Emeric Brun2c86cbf2014-10-30 15:56:50 +01005785static struct cfg_kw_list cfg_kws = {ILH, {
5786 { CFG_GLOBAL, "ssl-default-bind-options", ssl_parse_default_bind_options },
5787 { CFG_GLOBAL, "ssl-default-server-options", ssl_parse_default_server_options },
5788 { 0, NULL, NULL },
5789}};
5790
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02005791/* transport-layer operations for SSL sockets */
5792struct xprt_ops ssl_sock = {
Emeric Brun46591952012-05-18 15:47:34 +02005793 .snd_buf = ssl_sock_from_buf,
5794 .rcv_buf = ssl_sock_to_buf,
5795 .rcv_pipe = NULL,
5796 .snd_pipe = NULL,
5797 .shutr = NULL,
5798 .shutw = ssl_sock_shutw,
5799 .close = ssl_sock_close,
5800 .init = ssl_sock_init,
5801};
5802
Daniel Jakots54ffb912015-11-06 20:02:41 +01005803#if (OPENSSL_VERSION_NUMBER >= 0x1000200fL && !defined OPENSSL_NO_TLSEXT && !defined OPENSSL_IS_BORINGSSL && !defined LIBRESSL_VERSION_NUMBER)
Janusz Dziemidowicz2c701b52015-03-07 23:03:59 +01005804
5805static void ssl_sock_sctl_free_func(void *parent, void *ptr, CRYPTO_EX_DATA *ad, int idx, long argl, void *argp)
5806{
5807 if (ptr) {
5808 chunk_destroy(ptr);
5809 free(ptr);
5810 }
5811}
5812
5813#endif
5814
Emeric Brun46591952012-05-18 15:47:34 +02005815__attribute__((constructor))
Willy Tarreau92faadf2012-10-10 23:04:25 +02005816static void __ssl_sock_init(void)
5817{
Emeric Brun46591952012-05-18 15:47:34 +02005818 STACK_OF(SSL_COMP)* cm;
5819
Willy Tarreau610f04b2014-02-13 11:36:41 +01005820#ifdef LISTEN_DEFAULT_CIPHERS
5821 global.listen_default_ciphers = LISTEN_DEFAULT_CIPHERS;
5822#endif
5823#ifdef CONNECT_DEFAULT_CIPHERS
5824 global.connect_default_ciphers = CONNECT_DEFAULT_CIPHERS;
5825#endif
5826 if (global.listen_default_ciphers)
5827 global.listen_default_ciphers = strdup(global.listen_default_ciphers);
5828 if (global.connect_default_ciphers)
5829 global.connect_default_ciphers = strdup(global.connect_default_ciphers);
Emeric Brun2c86cbf2014-10-30 15:56:50 +01005830 global.listen_default_ssloptions = BC_SSL_O_NONE;
5831 global.connect_default_ssloptions = SRV_SSL_O_NONE;
Willy Tarreau610f04b2014-02-13 11:36:41 +01005832
Emeric Brun46591952012-05-18 15:47:34 +02005833 SSL_library_init();
5834 cm = SSL_COMP_get_compression_methods();
5835 sk_SSL_COMP_zero(cm);
Daniel Jakots54ffb912015-11-06 20:02:41 +01005836#if (OPENSSL_VERSION_NUMBER >= 0x1000200fL && !defined OPENSSL_NO_TLSEXT && !defined OPENSSL_IS_BORINGSSL && !defined LIBRESSL_VERSION_NUMBER)
Janusz Dziemidowicz2c701b52015-03-07 23:03:59 +01005837 sctl_ex_index = SSL_CTX_get_ex_new_index(0, NULL, NULL, NULL, ssl_sock_sctl_free_func);
5838#endif
Willy Tarreau7875d092012-09-10 08:20:03 +02005839 sample_register_fetches(&sample_fetch_keywords);
5840 acl_register_keywords(&acl_kws);
Willy Tarreau79eeafa2012-09-14 07:53:05 +02005841 bind_register_keywords(&bind_kws);
Willy Tarreau92faadf2012-10-10 23:04:25 +02005842 srv_register_keywords(&srv_kws);
Emeric Brun2c86cbf2014-10-30 15:56:50 +01005843 cfg_register_keywords(&cfg_kws);
Willy Tarreaud92aa5c2015-01-15 21:34:39 +01005844
5845 global.ssl_session_max_cost = SSL_SESSION_MAX_COST;
5846 global.ssl_handshake_max_cost = SSL_HANDSHAKE_MAX_COST;
Remi Gacogne4f902b82015-05-28 16:23:00 +02005847
5848#ifndef OPENSSL_NO_DH
5849 ssl_dh_ptr_index = SSL_CTX_get_ex_new_index(0, NULL, NULL, NULL, NULL);
5850#endif
Emeric Brun46591952012-05-18 15:47:34 +02005851}
5852
Remi Gacogned3a23c32015-05-28 16:39:47 +02005853__attribute__((destructor))
5854static void __ssl_sock_deinit(void)
5855{
Willy Tarreaua84c2672015-10-09 12:10:13 +02005856#ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME
Christopher Faulet31af49d2015-06-09 17:29:50 +02005857 lru64_destroy(ssl_ctx_lru_tree);
Willy Tarreaua84c2672015-10-09 12:10:13 +02005858#endif
Christopher Faulet31af49d2015-06-09 17:29:50 +02005859
Remi Gacogned3a23c32015-05-28 16:39:47 +02005860#ifndef OPENSSL_NO_DH
5861 if (local_dh_1024) {
5862 DH_free(local_dh_1024);
5863 local_dh_1024 = NULL;
5864 }
5865
5866 if (local_dh_2048) {
5867 DH_free(local_dh_2048);
5868 local_dh_2048 = NULL;
5869 }
5870
5871 if (local_dh_4096) {
5872 DH_free(local_dh_4096);
5873 local_dh_4096 = NULL;
5874 }
5875
Remi Gacogne47783ef2015-05-29 15:53:22 +02005876 if (global_dh) {
5877 DH_free(global_dh);
5878 global_dh = NULL;
5879 }
Remi Gacogned3a23c32015-05-28 16:39:47 +02005880#endif
5881
5882 ERR_remove_state(0);
5883 ERR_free_strings();
5884
5885 EVP_cleanup();
5886
5887#if OPENSSL_VERSION_NUMBER >= 0x00907000L
5888 CRYPTO_cleanup_all_ex_data();
5889#endif
5890}
5891
5892
Emeric Brun46591952012-05-18 15:47:34 +02005893/*
5894 * Local variables:
5895 * c-indent-level: 8
5896 * c-basic-offset: 8
5897 * End:
5898 */