blob: 401ff6728846f9f17460fa4dec055e18bde52e8e [file] [log] [blame]
Emeric Brun46591952012-05-18 15:47:34 +02001/*
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02002 * SSL/TLS transport layer over SOCK_STREAM sockets
Emeric Brun46591952012-05-18 15:47:34 +02003 *
4 * Copyright (C) 2012 EXCELIANCE, Emeric Brun <ebrun@exceliance.fr>
5 *
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public License
8 * as published by the Free Software Foundation; either version
9 * 2 of the License, or (at your option) any later version.
10 *
Willy Tarreau69845df2012-09-10 09:43:09 +020011 * Acknowledgement:
12 * We'd like to specially thank the Stud project authors for a very clean
13 * and well documented code which helped us understand how the OpenSSL API
14 * ought to be used in non-blocking mode. This is one difficult part which
15 * is not easy to get from the OpenSSL doc, and reading the Stud code made
16 * it much more obvious than the examples in the OpenSSL package. Keep up
17 * the good works, guys !
18 *
19 * Stud is an extremely efficient and scalable SSL/TLS proxy which combines
20 * particularly well with haproxy. For more info about this project, visit :
21 * https://github.com/bumptech/stud
22 *
Emeric Brun46591952012-05-18 15:47:34 +020023 */
24
25#define _GNU_SOURCE
Emeric Brunfc0421f2012-09-07 17:30:07 +020026#include <ctype.h>
27#include <dirent.h>
Emeric Brun46591952012-05-18 15:47:34 +020028#include <errno.h>
29#include <fcntl.h>
30#include <stdio.h>
31#include <stdlib.h>
Emeric Brunfc0421f2012-09-07 17:30:07 +020032#include <string.h>
33#include <unistd.h>
Emeric Brun46591952012-05-18 15:47:34 +020034
35#include <sys/socket.h>
36#include <sys/stat.h>
37#include <sys/types.h>
Christopher Faulet31af49d2015-06-09 17:29:50 +020038#include <netdb.h>
Emeric Brun46591952012-05-18 15:47:34 +020039#include <netinet/tcp.h>
40
41#include <openssl/ssl.h>
Emeric Brunfc0421f2012-09-07 17:30:07 +020042#include <openssl/x509.h>
43#include <openssl/x509v3.h>
44#include <openssl/x509.h>
45#include <openssl/err.h>
Thierry Fournier383085f2013-01-24 14:15:43 +010046#include <openssl/rand.h>
Lukas Tribuse4e30f72014-12-09 16:32:51 +010047#if (defined SSL_CTRL_SET_TLSEXT_STATUS_REQ_CB && !defined OPENSSL_NO_OCSP)
Emeric Brun4147b2e2014-06-16 18:36:30 +020048#include <openssl/ocsp.h>
49#endif
Remi Gacogne4f902b82015-05-28 16:23:00 +020050#ifndef OPENSSL_NO_DH
51#include <openssl/dh.h>
52#endif
Emeric Brun46591952012-05-18 15:47:34 +020053
Christopher Faulet31af49d2015-06-09 17:29:50 +020054#include <import/lru.h>
55#include <import/xxhash.h>
56
Emeric Brun46591952012-05-18 15:47:34 +020057#include <common/buffer.h>
58#include <common/compat.h>
59#include <common/config.h>
60#include <common/debug.h>
Willy Tarreau79eeafa2012-09-14 07:53:05 +020061#include <common/errors.h>
Emeric Brun46591952012-05-18 15:47:34 +020062#include <common/standard.h>
63#include <common/ticks.h>
64#include <common/time.h>
Emeric Brun2c86cbf2014-10-30 15:56:50 +010065#include <common/cfgparse.h>
Nenad Merdanovic05552d42015-02-27 19:56:49 +010066#include <common/base64.h>
Emeric Brun46591952012-05-18 15:47:34 +020067
Emeric Brunfc0421f2012-09-07 17:30:07 +020068#include <ebsttree.h>
69
70#include <types/global.h>
71#include <types/ssl_sock.h>
72
Willy Tarreau7875d092012-09-10 08:20:03 +020073#include <proto/acl.h>
74#include <proto/arg.h>
Emeric Brun46591952012-05-18 15:47:34 +020075#include <proto/connection.h>
76#include <proto/fd.h>
77#include <proto/freq_ctr.h>
78#include <proto/frontend.h>
Willy Tarreau79eeafa2012-09-14 07:53:05 +020079#include <proto/listener.h>
Thierry FOURNIERed66c292013-11-28 11:05:19 +010080#include <proto/pattern.h>
Christopher Faulet31af49d2015-06-09 17:29:50 +020081#include <proto/proto_tcp.h>
Willy Tarreau92faadf2012-10-10 23:04:25 +020082#include <proto/server.h>
Emeric Brun46591952012-05-18 15:47:34 +020083#include <proto/log.h>
Emeric Brun94324a42012-10-11 14:00:19 +020084#include <proto/proxy.h>
Emeric Brunfc0421f2012-09-07 17:30:07 +020085#include <proto/shctx.h>
Emeric Brun46591952012-05-18 15:47:34 +020086#include <proto/ssl_sock.h>
Willy Tarreau9ad7bd42015-04-03 19:19:59 +020087#include <proto/stream.h>
Emeric Brun46591952012-05-18 15:47:34 +020088#include <proto/task.h>
89
Willy Tarreau518cedd2014-02-17 15:43:01 +010090/* Warning, these are bits, not integers! */
Emeric Brune64aef12012-09-21 13:15:06 +020091#define SSL_SOCK_ST_FL_VERIFY_DONE 0x00000001
Emeric Brund8b2bb52014-01-28 15:43:53 +010092#define SSL_SOCK_ST_FL_16K_WBFSIZE 0x00000002
Willy Tarreau518cedd2014-02-17 15:43:01 +010093#define SSL_SOCK_SEND_UNLIMITED 0x00000004
Emeric Brun29f037d2014-04-25 19:05:36 +020094#define SSL_SOCK_RECV_HEARTBEAT 0x00000008
95
Emeric Brunf282a812012-09-21 15:27:54 +020096/* bits 0xFFFF0000 are reserved to store verify errors */
97
98/* Verify errors macros */
99#define SSL_SOCK_CA_ERROR_TO_ST(e) (((e > 63) ? 63 : e) << (16))
100#define SSL_SOCK_CAEDEPTH_TO_ST(d) (((d > 15) ? 15 : d) << (6+16))
101#define SSL_SOCK_CRTERROR_TO_ST(e) (((e > 63) ? 63 : e) << (4+6+16))
102
103#define SSL_SOCK_ST_TO_CA_ERROR(s) ((s >> (16)) & 63)
104#define SSL_SOCK_ST_TO_CAEDEPTH(s) ((s >> (6+16)) & 15)
105#define SSL_SOCK_ST_TO_CRTERROR(s) ((s >> (4+6+16)) & 63)
Emeric Brune64aef12012-09-21 13:15:06 +0200106
Nenad Merdanovic05552d42015-02-27 19:56:49 +0100107/* Supported hash function for TLS tickets */
108#ifdef OPENSSL_NO_SHA256
109#define HASH_FUNCT EVP_sha1
110#else
111#define HASH_FUNCT EVP_sha256
112#endif /* OPENSSL_NO_SHA256 */
113
Emeric Brun850efd52014-01-29 12:24:34 +0100114/* server and bind verify method, it uses a global value as default */
115enum {
116 SSL_SOCK_VERIFY_DEFAULT = 0,
117 SSL_SOCK_VERIFY_REQUIRED = 1,
118 SSL_SOCK_VERIFY_OPTIONAL = 2,
119 SSL_SOCK_VERIFY_NONE = 3,
120};
121
Willy Tarreau71b734c2014-01-28 15:19:44 +0100122int sslconns = 0;
123int totalsslconns = 0;
Emeric Brune1f38db2012-09-03 20:36:47 +0200124
Nenad Merdanovic200b0fa2015-05-09 08:46:01 +0200125#if (defined SSL_CTRL_SET_TLSEXT_TICKET_KEY_CB && TLS_TICKETS_NO > 0)
126struct list tlskeys_reference = LIST_HEAD_INIT(tlskeys_reference);
127#endif
128
Remi Gacogne8de54152014-07-15 11:36:40 +0200129#ifndef OPENSSL_NO_DH
Remi Gacogne4f902b82015-05-28 16:23:00 +0200130static int ssl_dh_ptr_index = -1;
Remi Gacogne47783ef2015-05-29 15:53:22 +0200131static DH *global_dh = NULL;
Remi Gacogne8de54152014-07-15 11:36:40 +0200132static DH *local_dh_1024 = NULL;
133static DH *local_dh_2048 = NULL;
134static DH *local_dh_4096 = NULL;
Remi Gacogne8de54152014-07-15 11:36:40 +0200135#endif /* OPENSSL_NO_DH */
136
Willy Tarreauc8ad3be2015-06-17 15:48:26 +0200137#ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME
Christopher Faulet31af49d2015-06-09 17:29:50 +0200138/* X509V3 Extensions that will be added on generated certificates */
139#define X509V3_EXT_SIZE 5
140static char *x509v3_ext_names[X509V3_EXT_SIZE] = {
141 "basicConstraints",
142 "nsComment",
143 "subjectKeyIdentifier",
144 "authorityKeyIdentifier",
145 "keyUsage",
146};
147static char *x509v3_ext_values[X509V3_EXT_SIZE] = {
148 "CA:FALSE",
149 "\"OpenSSL Generated Certificate\"",
150 "hash",
151 "keyid,issuer:always",
152 "nonRepudiation,digitalSignature,keyEncipherment"
153};
154
155/* LRU cache to store generated certificate */
156static struct lru64_head *ssl_ctx_lru_tree = NULL;
157static unsigned int ssl_ctx_lru_seed = 0;
Willy Tarreauc8ad3be2015-06-17 15:48:26 +0200158#endif // SSL_CTRL_SET_TLSEXT_HOSTNAME
159
160#if (defined SSL_CTRL_SET_TLSEXT_STATUS_REQ_CB && !defined OPENSSL_NO_OCSP)
161struct certificate_ocsp {
162 struct ebmb_node key;
163 unsigned char key_data[OCSP_MAX_CERTID_ASN1_LENGTH];
164 struct chunk response;
165 long expire;
166};
Christopher Faulet31af49d2015-06-09 17:29:50 +0200167
Emeric Brun4f3c87a2014-06-20 15:46:13 +0200168/*
169 * This function returns the number of seconds elapsed
170 * since the Epoch, 1970-01-01 00:00:00 +0000 (UTC) and the
171 * date presented un ASN1_GENERALIZEDTIME.
172 *
173 * In parsing error case, it returns -1.
174 */
175static long asn1_generalizedtime_to_epoch(ASN1_GENERALIZEDTIME *d)
176{
177 long epoch;
178 char *p, *end;
179 const unsigned short month_offset[12] = {
180 0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334
181 };
182 int year, month;
183
184 if (!d || (d->type != V_ASN1_GENERALIZEDTIME)) return -1;
185
186 p = (char *)d->data;
187 end = p + d->length;
188
189 if (end - p < 4) return -1;
190 year = 1000 * (p[0] - '0') + 100 * (p[1] - '0') + 10 * (p[2] - '0') + p[3] - '0';
191 p += 4;
192 if (end - p < 2) return -1;
193 month = 10 * (p[0] - '0') + p[1] - '0';
194 if (month < 1 || month > 12) return -1;
195 /* Compute the number of seconds since 1 jan 1970 and the beginning of current month
196 We consider leap years and the current month (<marsh or not) */
197 epoch = ( ((year - 1970) * 365)
198 + ((year - (month < 3)) / 4 - (year - (month < 3)) / 100 + (year - (month < 3)) / 400)
199 - ((1970 - 1) / 4 - (1970 - 1) / 100 + (1970 - 1) / 400)
200 + month_offset[month-1]
201 ) * 24 * 60 * 60;
202 p += 2;
203 if (end - p < 2) return -1;
204 /* Add the number of seconds of completed days of current month */
205 epoch += (10 * (p[0] - '0') + p[1] - '0' - 1) * 24 * 60 * 60;
206 p += 2;
207 if (end - p < 2) return -1;
208 /* Add the completed hours of the current day */
209 epoch += (10 * (p[0] - '0') + p[1] - '0') * 60 * 60;
210 p += 2;
211 if (end - p < 2) return -1;
212 /* Add the completed minutes of the current hour */
213 epoch += (10 * (p[0] - '0') + p[1] - '0') * 60;
214 p += 2;
215 if (p == end) return -1;
216 /* Test if there is available seconds */
217 if (p[0] < '0' || p[0] > '9')
218 goto nosec;
219 if (end - p < 2) return -1;
220 /* Add the seconds of the current minute */
221 epoch += 10 * (p[0] - '0') + p[1] - '0';
222 p += 2;
223 if (p == end) return -1;
224 /* Ignore seconds float part if present */
225 if (p[0] == '.') {
226 do {
227 if (++p == end) return -1;
228 } while (p[0] >= '0' && p[0] <= '9');
229 }
230
231nosec:
232 if (p[0] == 'Z') {
233 if (end - p != 1) return -1;
234 return epoch;
235 }
236 else if (p[0] == '+') {
237 if (end - p != 5) return -1;
238 /* Apply timezone offset */
239 return epoch - ((10 * (p[1] - '0') + p[2] - '0') * 60 + (10 * (p[3] - '0') + p[4] - '0')) * 60;
240 }
241 else if (p[0] == '-') {
242 if (end - p != 5) return -1;
243 /* Apply timezone offset */
244 return epoch + ((10 * (p[1] - '0') + p[2] - '0') * 60 + (10 * (p[3] - '0') + p[4] - '0')) * 60;
245 }
246
247 return -1;
248}
249
Emeric Brun1d3865b2014-06-20 15:37:32 +0200250static struct eb_root cert_ocsp_tree = EB_ROOT_UNIQUE;
Emeric Brun4147b2e2014-06-16 18:36:30 +0200251
252/* This function starts to check if the OCSP response (in DER format) contained
253 * in chunk 'ocsp_response' is valid (else exits on error).
254 * If 'cid' is not NULL, it will be compared to the OCSP certificate ID
255 * contained in the OCSP Response and exits on error if no match.
256 * If it's a valid OCSP Response:
257 * If 'ocsp' is not NULL, the chunk is copied in the OCSP response's container
258 * pointed by 'ocsp'.
259 * If 'ocsp' is NULL, the function looks up into the OCSP response's
260 * containers tree (using as index the ASN1 form of the OCSP Certificate ID extracted
261 * from the response) and exits on error if not found. Finally, If an OCSP response is
262 * already present in the container, it will be overwritten.
263 *
264 * Note: OCSP response containing more than one OCSP Single response is not
265 * considered valid.
266 *
267 * Returns 0 on success, 1 in error case.
268 */
269static int ssl_sock_load_ocsp_response(struct chunk *ocsp_response, struct certificate_ocsp *ocsp, OCSP_CERTID *cid, char **err)
270{
271 OCSP_RESPONSE *resp;
272 OCSP_BASICRESP *bs = NULL;
273 OCSP_SINGLERESP *sr;
274 unsigned char *p = (unsigned char *)ocsp_response->str;
275 int rc , count_sr;
Emeric Brun13a6b482014-06-20 15:44:34 +0200276 ASN1_GENERALIZEDTIME *revtime, *thisupd, *nextupd = NULL;
Emeric Brun4147b2e2014-06-16 18:36:30 +0200277 int reason;
278 int ret = 1;
279
280 resp = d2i_OCSP_RESPONSE(NULL, (const unsigned char **)&p, ocsp_response->len);
281 if (!resp) {
282 memprintf(err, "Unable to parse OCSP response");
283 goto out;
284 }
285
286 rc = OCSP_response_status(resp);
287 if (rc != OCSP_RESPONSE_STATUS_SUCCESSFUL) {
288 memprintf(err, "OCSP response status not successful");
289 goto out;
290 }
291
292 bs = OCSP_response_get1_basic(resp);
293 if (!bs) {
294 memprintf(err, "Failed to get basic response from OCSP Response");
295 goto out;
296 }
297
298 count_sr = OCSP_resp_count(bs);
299 if (count_sr > 1) {
300 memprintf(err, "OCSP response ignored because contains multiple single responses (%d)", count_sr);
301 goto out;
302 }
303
304 sr = OCSP_resp_get0(bs, 0);
305 if (!sr) {
306 memprintf(err, "Failed to get OCSP single response");
307 goto out;
308 }
309
310 rc = OCSP_single_get0_status(sr, &reason, &revtime, &thisupd, &nextupd);
311 if (rc != V_OCSP_CERTSTATUS_GOOD) {
312 memprintf(err, "OCSP single response: certificate status not good");
313 goto out;
314 }
315
Emeric Brun13a6b482014-06-20 15:44:34 +0200316 if (!nextupd) {
317 memprintf(err, "OCSP single response: missing nextupdate");
318 goto out;
319 }
320
Emeric Brunc8b27b62014-06-19 14:16:17 +0200321 rc = OCSP_check_validity(thisupd, nextupd, OCSP_MAX_RESPONSE_TIME_SKEW, -1);
Emeric Brun4147b2e2014-06-16 18:36:30 +0200322 if (!rc) {
323 memprintf(err, "OCSP single response: no longer valid.");
324 goto out;
325 }
326
327 if (cid) {
328 if (OCSP_id_cmp(sr->certId, cid)) {
329 memprintf(err, "OCSP single response: Certificate ID does not match certificate and issuer");
330 goto out;
331 }
332 }
333
334 if (!ocsp) {
335 unsigned char key[OCSP_MAX_CERTID_ASN1_LENGTH];
336 unsigned char *p;
337
338 rc = i2d_OCSP_CERTID(sr->certId, NULL);
339 if (!rc) {
340 memprintf(err, "OCSP single response: Unable to encode Certificate ID");
341 goto out;
342 }
343
344 if (rc > OCSP_MAX_CERTID_ASN1_LENGTH) {
345 memprintf(err, "OCSP single response: Certificate ID too long");
346 goto out;
347 }
348
349 p = key;
350 memset(key, 0, OCSP_MAX_CERTID_ASN1_LENGTH);
351 i2d_OCSP_CERTID(sr->certId, &p);
352 ocsp = (struct certificate_ocsp *)ebmb_lookup(&cert_ocsp_tree, key, OCSP_MAX_CERTID_ASN1_LENGTH);
353 if (!ocsp) {
354 memprintf(err, "OCSP single response: Certificate ID does not match any certificate or issuer");
355 goto out;
356 }
357 }
358
359 /* According to comments on "chunk_dup", the
360 previous chunk buffer will be freed */
361 if (!chunk_dup(&ocsp->response, ocsp_response)) {
362 memprintf(err, "OCSP response: Memory allocation error");
363 goto out;
364 }
365
Emeric Brun4f3c87a2014-06-20 15:46:13 +0200366 ocsp->expire = asn1_generalizedtime_to_epoch(nextupd) - OCSP_MAX_RESPONSE_TIME_SKEW;
367
Emeric Brun4147b2e2014-06-16 18:36:30 +0200368 ret = 0;
369out:
370 if (bs)
371 OCSP_BASICRESP_free(bs);
372
373 if (resp)
374 OCSP_RESPONSE_free(resp);
375
376 return ret;
377}
378/*
379 * External function use to update the OCSP response in the OCSP response's
380 * containers tree. The chunk 'ocsp_response' must contain the OCSP response
381 * to update in DER format.
382 *
383 * Returns 0 on success, 1 in error case.
384 */
385int ssl_sock_update_ocsp_response(struct chunk *ocsp_response, char **err)
386{
387 return ssl_sock_load_ocsp_response(ocsp_response, NULL, NULL, err);
388}
389
390/*
391 * This function load the OCSP Resonse in DER format contained in file at
392 * path 'ocsp_path' and call 'ssl_sock_load_ocsp_response'
393 *
394 * Returns 0 on success, 1 in error case.
395 */
396static int ssl_sock_load_ocsp_response_from_file(const char *ocsp_path, struct certificate_ocsp *ocsp, OCSP_CERTID *cid, char **err)
397{
398 int fd = -1;
399 int r = 0;
400 int ret = 1;
401
402 fd = open(ocsp_path, O_RDONLY);
403 if (fd == -1) {
404 memprintf(err, "Error opening OCSP response file");
405 goto end;
406 }
407
408 trash.len = 0;
409 while (trash.len < trash.size) {
410 r = read(fd, trash.str + trash.len, trash.size - trash.len);
411 if (r < 0) {
412 if (errno == EINTR)
413 continue;
414
415 memprintf(err, "Error reading OCSP response from file");
416 goto end;
417 }
418 else if (r == 0) {
419 break;
420 }
421 trash.len += r;
422 }
423
424 close(fd);
425 fd = -1;
426
427 ret = ssl_sock_load_ocsp_response(&trash, ocsp, cid, err);
428end:
429 if (fd != -1)
430 close(fd);
431
432 return ret;
433}
434
Nenad Merdanovic05552d42015-02-27 19:56:49 +0100435#if (defined SSL_CTRL_SET_TLSEXT_TICKET_KEY_CB && TLS_TICKETS_NO > 0)
436static 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)
437{
438 struct tls_sess_key *keys;
439 struct connection *conn;
440 int head;
441 int i;
442
443 conn = (struct connection *)SSL_get_app_data(s);
Nenad Merdanovic146defa2015-05-09 08:46:00 +0200444 keys = objt_listener(conn->target)->bind_conf->keys_ref->tlskeys;
445 head = objt_listener(conn->target)->bind_conf->keys_ref->tls_ticket_enc_index;
Nenad Merdanovic05552d42015-02-27 19:56:49 +0100446
447 if (enc) {
448 memcpy(key_name, keys[head].name, 16);
449
450 if(!RAND_pseudo_bytes(iv, EVP_MAX_IV_LENGTH))
451 return -1;
452
453 if(!EVP_EncryptInit_ex(ectx, EVP_aes_128_cbc(), NULL, keys[head].aes_key, iv))
454 return -1;
455
456 HMAC_Init_ex(hctx, keys[head].hmac_key, 16, HASH_FUNCT(), NULL);
457
458 return 1;
459 } else {
460 for (i = 0; i < TLS_TICKETS_NO; i++) {
461 if (!memcmp(key_name, keys[(head + i) % TLS_TICKETS_NO].name, 16))
462 goto found;
463 }
464 return 0;
465
466 found:
467 HMAC_Init_ex(hctx, keys[(head + i) % TLS_TICKETS_NO].hmac_key, 16, HASH_FUNCT(), NULL);
468 if(!EVP_DecryptInit_ex(ectx, EVP_aes_128_cbc(), NULL, keys[(head + i) % TLS_TICKETS_NO].aes_key, iv))
469 return -1;
470 /* 2 for key renewal, 1 if current key is still valid */
471 return i ? 2 : 1;
472 }
Nenad Merdanovic200b0fa2015-05-09 08:46:01 +0200473}
474
475struct tls_keys_ref *tlskeys_ref_lookup(const char *filename)
476{
477 struct tls_keys_ref *ref;
478
479 list_for_each_entry(ref, &tlskeys_reference, list)
480 if (ref->filename && strcmp(filename, ref->filename) == 0)
481 return ref;
482 return NULL;
483}
484
485struct tls_keys_ref *tlskeys_ref_lookupid(int unique_id)
486{
487 struct tls_keys_ref *ref;
488
489 list_for_each_entry(ref, &tlskeys_reference, list)
490 if (ref->unique_id == unique_id)
491 return ref;
492 return NULL;
493}
494
495int ssl_sock_update_tlskey(char *filename, struct chunk *tlskey, char **err) {
496 struct tls_keys_ref *ref = tlskeys_ref_lookup(filename);
497
498 if(!ref) {
499 memprintf(err, "Unable to locate the referenced filename: %s", filename);
500 return 1;
501 }
502
Pradeep Jindalcc79b002015-08-20 18:25:17 +0530503 memcpy((char *) (ref->tlskeys + ((ref->tls_ticket_enc_index + 2) % TLS_TICKETS_NO)), tlskey->str, tlskey->len);
504 ref->tls_ticket_enc_index = (ref->tls_ticket_enc_index + 1) % TLS_TICKETS_NO;
Nenad Merdanovic200b0fa2015-05-09 08:46:01 +0200505
506 return 0;
Nenad Merdanovic05552d42015-02-27 19:56:49 +0100507}
Nenad Merdanovic200b0fa2015-05-09 08:46:01 +0200508
509/* This function finalize the configuration parsing. Its set all the
510 * automatic ids
511 */
512void tlskeys_finalize_config(void)
513{
514 int i = 0;
515 struct tls_keys_ref *ref, *ref2, *ref3;
516 struct list tkr = LIST_HEAD_INIT(tkr);
517
518 list_for_each_entry(ref, &tlskeys_reference, list) {
519 if (ref->unique_id == -1) {
520 /* Look for the first free id. */
521 while (1) {
522 list_for_each_entry(ref2, &tlskeys_reference, list) {
523 if (ref2->unique_id == i) {
524 i++;
525 break;
526 }
527 }
528 if (&ref2->list == &tlskeys_reference)
529 break;
530 }
531
532 /* Uses the unique id and increment it for the next entry. */
533 ref->unique_id = i;
534 i++;
535 }
536 }
537
538 /* This sort the reference list by id. */
539 list_for_each_entry_safe(ref, ref2, &tlskeys_reference, list) {
540 LIST_DEL(&ref->list);
541 list_for_each_entry(ref3, &tkr, list) {
542 if (ref->unique_id < ref3->unique_id) {
543 LIST_ADDQ(&ref3->list, &ref->list);
544 break;
545 }
546 }
547 if (&ref3->list == &tkr)
548 LIST_ADDQ(&tkr, &ref->list);
549 }
550
551 /* swap root */
552 LIST_ADD(&tkr, &tlskeys_reference);
553 LIST_DEL(&tkr);
554}
555
Nenad Merdanovic05552d42015-02-27 19:56:49 +0100556#endif /* SSL_CTRL_SET_TLSEXT_TICKET_KEY_CB */
557
Emeric Brun4147b2e2014-06-16 18:36:30 +0200558/*
559 * Callback used to set OCSP status extension content in server hello.
560 */
561int ssl_sock_ocsp_stapling_cbk(SSL *ssl, void *arg)
562{
563 struct certificate_ocsp *ocsp = (struct certificate_ocsp *)arg;
564 char* ssl_buf;
565
566 if (!ocsp ||
567 !ocsp->response.str ||
Emeric Brun4f3c87a2014-06-20 15:46:13 +0200568 !ocsp->response.len ||
569 (ocsp->expire < now.tv_sec))
Emeric Brun4147b2e2014-06-16 18:36:30 +0200570 return SSL_TLSEXT_ERR_NOACK;
571
572 ssl_buf = OPENSSL_malloc(ocsp->response.len);
573 if (!ssl_buf)
574 return SSL_TLSEXT_ERR_NOACK;
575
576 memcpy(ssl_buf, ocsp->response.str, ocsp->response.len);
577 SSL_set_tlsext_status_ocsp_resp(ssl, ssl_buf, ocsp->response.len);
578
579 return SSL_TLSEXT_ERR_OK;
580}
581
582/*
583 * This function enables the handling of OCSP status extension on 'ctx' if a
584 * file name 'cert_path' suffixed using ".ocsp" is present.
585 * To enable OCSP status extension, the issuer's certificate is mandatory.
586 * It should be present in the certificate's extra chain builded from file
587 * 'cert_path'. If not found, the issuer certificate is loaded from a file
588 * named 'cert_path' suffixed using '.issuer'.
589 *
590 * In addition, ".ocsp" file content is loaded as a DER format of an OCSP
591 * response. If file is empty or content is not a valid OCSP response,
592 * OCSP status extension is enabled but OCSP response is ignored (a warning
593 * is displayed).
594 *
595 * Returns 1 if no ".ocsp" file found, 0 if OCSP status extension is
596 * succesfully enabled, or -1 in other error case.
597 */
598static int ssl_sock_load_ocsp(SSL_CTX *ctx, const char *cert_path)
599{
600
601 BIO *in = NULL;
602 X509 *x, *xi = NULL, *issuer = NULL;
603 STACK_OF(X509) *chain = NULL;
604 OCSP_CERTID *cid = NULL;
605 SSL *ssl;
606 char ocsp_path[MAXPATHLEN+1];
607 int i, ret = -1;
608 struct stat st;
609 struct certificate_ocsp *ocsp = NULL, *iocsp;
610 char *warn = NULL;
611 unsigned char *p;
612
613 snprintf(ocsp_path, MAXPATHLEN+1, "%s.ocsp", cert_path);
614
615 if (stat(ocsp_path, &st))
616 return 1;
617
618 ssl = SSL_new(ctx);
619 if (!ssl)
620 goto out;
621
622 x = SSL_get_certificate(ssl);
623 if (!x)
624 goto out;
625
626 /* Try to lookup for issuer in certificate extra chain */
627#ifdef SSL_CTRL_GET_EXTRA_CHAIN_CERTS
628 SSL_CTX_get_extra_chain_certs(ctx, &chain);
629#else
630 chain = ctx->extra_certs;
631#endif
632 for (i = 0; i < sk_X509_num(chain); i++) {
633 issuer = sk_X509_value(chain, i);
634 if (X509_check_issued(issuer, x) == X509_V_OK)
635 break;
636 else
637 issuer = NULL;
638 }
639
640 /* If not found try to load issuer from a suffixed file */
641 if (!issuer) {
642 char issuer_path[MAXPATHLEN+1];
643
644 in = BIO_new(BIO_s_file());
645 if (!in)
646 goto out;
647
648 snprintf(issuer_path, MAXPATHLEN+1, "%s.issuer", cert_path);
649 if (BIO_read_filename(in, issuer_path) <= 0)
650 goto out;
651
652 xi = PEM_read_bio_X509_AUX(in, NULL, ctx->default_passwd_callback, ctx->default_passwd_callback_userdata);
653 if (!xi)
654 goto out;
655
656 if (X509_check_issued(xi, x) != X509_V_OK)
657 goto out;
658
659 issuer = xi;
660 }
661
662 cid = OCSP_cert_to_id(0, x, issuer);
663 if (!cid)
664 goto out;
665
666 i = i2d_OCSP_CERTID(cid, NULL);
667 if (!i || (i > OCSP_MAX_CERTID_ASN1_LENGTH))
668 goto out;
669
670 ocsp = calloc(1, sizeof(struct certificate_ocsp));
671 if (!ocsp)
672 goto out;
673
674 p = ocsp->key_data;
675 i2d_OCSP_CERTID(cid, &p);
676
677 iocsp = (struct certificate_ocsp *)ebmb_insert(&cert_ocsp_tree, &ocsp->key, OCSP_MAX_CERTID_ASN1_LENGTH);
678 if (iocsp == ocsp)
679 ocsp = NULL;
680
681 SSL_CTX_set_tlsext_status_cb(ctx, ssl_sock_ocsp_stapling_cbk);
682 SSL_CTX_set_tlsext_status_arg(ctx, iocsp);
683
684 ret = 0;
685
686 warn = NULL;
687 if (ssl_sock_load_ocsp_response_from_file(ocsp_path, iocsp, cid, &warn)) {
688 memprintf(&warn, "Loading '%s': %s. Content will be ignored", ocsp_path, warn ? warn : "failure");
689 Warning("%s.\n", warn);
690 }
691
692out:
693 if (ssl)
694 SSL_free(ssl);
695
696 if (in)
697 BIO_free(in);
698
699 if (xi)
700 X509_free(xi);
701
702 if (cid)
703 OCSP_CERTID_free(cid);
704
705 if (ocsp)
706 free(ocsp);
707
708 if (warn)
709 free(warn);
710
711
712 return ret;
713}
714
715#endif
716
Janusz Dziemidowicz2c701b52015-03-07 23:03:59 +0100717#if (OPENSSL_VERSION_NUMBER >= 0x1000200fL && !defined OPENSSL_NO_TLSEXT && !defined OPENSSL_IS_BORINGSSL)
718
719#define CT_EXTENSION_TYPE 18
720
721static int sctl_ex_index = -1;
722
723/*
724 * Try to parse Signed Certificate Timestamp List structure. This function
725 * makes only basic test if the data seems like SCTL. No signature validation
726 * is performed.
727 */
728static int ssl_sock_parse_sctl(struct chunk *sctl)
729{
730 int ret = 1;
731 int len, pos, sct_len;
732 unsigned char *data;
733
734 if (sctl->len < 2)
735 goto out;
736
737 data = (unsigned char *)sctl->str;
738 len = (data[0] << 8) | data[1];
739
740 if (len + 2 != sctl->len)
741 goto out;
742
743 data = data + 2;
744 pos = 0;
745 while (pos < len) {
746 if (len - pos < 2)
747 goto out;
748
749 sct_len = (data[pos] << 8) | data[pos + 1];
750 if (pos + sct_len + 2 > len)
751 goto out;
752
753 pos += sct_len + 2;
754 }
755
756 ret = 0;
757
758out:
759 return ret;
760}
761
762static int ssl_sock_load_sctl_from_file(const char *sctl_path, struct chunk **sctl)
763{
764 int fd = -1;
765 int r = 0;
766 int ret = 1;
767
768 *sctl = NULL;
769
770 fd = open(sctl_path, O_RDONLY);
771 if (fd == -1)
772 goto end;
773
774 trash.len = 0;
775 while (trash.len < trash.size) {
776 r = read(fd, trash.str + trash.len, trash.size - trash.len);
777 if (r < 0) {
778 if (errno == EINTR)
779 continue;
780
781 goto end;
782 }
783 else if (r == 0) {
784 break;
785 }
786 trash.len += r;
787 }
788
789 ret = ssl_sock_parse_sctl(&trash);
790 if (ret)
791 goto end;
792
793 *sctl = calloc(1, sizeof(struct chunk));
794 if (!chunk_dup(*sctl, &trash)) {
795 free(*sctl);
796 *sctl = NULL;
797 goto end;
798 }
799
800end:
801 if (fd != -1)
802 close(fd);
803
804 return ret;
805}
806
807int ssl_sock_sctl_add_cbk(SSL *ssl, unsigned ext_type, const unsigned char **out, size_t *outlen, int *al, void *add_arg)
808{
809 struct chunk *sctl = (struct chunk *)add_arg;
810
811 *out = (unsigned char *)sctl->str;
812 *outlen = sctl->len;
813
814 return 1;
815}
816
817int ssl_sock_sctl_parse_cbk(SSL *s, unsigned int ext_type, const unsigned char *in, size_t inlen, int *al, void *parse_arg)
818{
819 return 1;
820}
821
822static int ssl_sock_load_sctl(SSL_CTX *ctx, const char *cert_path)
823{
824 char sctl_path[MAXPATHLEN+1];
825 int ret = -1;
826 struct stat st;
827 struct chunk *sctl = NULL;
828
829 snprintf(sctl_path, MAXPATHLEN+1, "%s.sctl", cert_path);
830
831 if (stat(sctl_path, &st))
832 return 1;
833
834 if (ssl_sock_load_sctl_from_file(sctl_path, &sctl))
835 goto out;
836
837 if (!SSL_CTX_add_server_custom_ext(ctx, CT_EXTENSION_TYPE, ssl_sock_sctl_add_cbk, NULL, sctl, ssl_sock_sctl_parse_cbk, NULL)) {
838 free(sctl);
839 goto out;
840 }
841
842 SSL_CTX_set_ex_data(ctx, sctl_ex_index, sctl);
843
844 ret = 0;
845
846out:
847 return ret;
848}
849
850#endif
851
Emeric Brune1f38db2012-09-03 20:36:47 +0200852void ssl_sock_infocbk(const SSL *ssl, int where, int ret)
853{
854 struct connection *conn = (struct connection *)SSL_get_app_data(ssl);
Emeric Brund8b2bb52014-01-28 15:43:53 +0100855 BIO *write_bio;
Willy Tarreau622317d2015-02-27 16:36:16 +0100856 (void)ret; /* shut gcc stupid warning */
Emeric Brune1f38db2012-09-03 20:36:47 +0200857
858 if (where & SSL_CB_HANDSHAKE_START) {
859 /* Disable renegotiation (CVE-2009-3555) */
Willy Tarreau20879a02012-12-03 16:32:10 +0100860 if (conn->flags & CO_FL_CONNECTED) {
Emeric Brune1f38db2012-09-03 20:36:47 +0200861 conn->flags |= CO_FL_ERROR;
Willy Tarreau20879a02012-12-03 16:32:10 +0100862 conn->err_code = CO_ER_SSL_RENEG;
863 }
Emeric Brune1f38db2012-09-03 20:36:47 +0200864 }
Emeric Brund8b2bb52014-01-28 15:43:53 +0100865
866 if ((where & SSL_CB_ACCEPT_LOOP) == SSL_CB_ACCEPT_LOOP) {
867 if (!(conn->xprt_st & SSL_SOCK_ST_FL_16K_WBFSIZE)) {
868 /* Long certificate chains optimz
869 If write and read bios are differents, we
870 consider that the buffering was activated,
871 so we rise the output buffer size from 4k
872 to 16k */
873 write_bio = SSL_get_wbio(ssl);
874 if (write_bio != SSL_get_rbio(ssl)) {
875 BIO_set_write_buffer_size(write_bio, 16384);
876 conn->xprt_st |= SSL_SOCK_ST_FL_16K_WBFSIZE;
877 }
878 }
879 }
Emeric Brunfc0421f2012-09-07 17:30:07 +0200880}
881
Emeric Brune64aef12012-09-21 13:15:06 +0200882/* Callback is called for each certificate of the chain during a verify
883 ok is set to 1 if preverify detect no error on current certificate.
884 Returns 0 to break the handshake, 1 otherwise. */
Evan Broderbe554312013-06-27 00:05:25 -0700885int ssl_sock_bind_verifycbk(int ok, X509_STORE_CTX *x_store)
Emeric Brune64aef12012-09-21 13:15:06 +0200886{
887 SSL *ssl;
888 struct connection *conn;
Emeric Brun81c00f02012-09-21 14:31:21 +0200889 int err, depth;
Emeric Brune64aef12012-09-21 13:15:06 +0200890
891 ssl = X509_STORE_CTX_get_ex_data(x_store, SSL_get_ex_data_X509_STORE_CTX_idx());
892 conn = (struct connection *)SSL_get_app_data(ssl);
893
Willy Tarreauf7bc57c2012-10-03 00:19:48 +0200894 conn->xprt_st |= SSL_SOCK_ST_FL_VERIFY_DONE;
Emeric Brune64aef12012-09-21 13:15:06 +0200895
Emeric Brun81c00f02012-09-21 14:31:21 +0200896 if (ok) /* no errors */
897 return ok;
898
899 depth = X509_STORE_CTX_get_error_depth(x_store);
900 err = X509_STORE_CTX_get_error(x_store);
901
902 /* check if CA error needs to be ignored */
903 if (depth > 0) {
Willy Tarreauf7bc57c2012-10-03 00:19:48 +0200904 if (!SSL_SOCK_ST_TO_CA_ERROR(conn->xprt_st)) {
905 conn->xprt_st |= SSL_SOCK_CA_ERROR_TO_ST(err);
906 conn->xprt_st |= SSL_SOCK_CAEDEPTH_TO_ST(depth);
Emeric Brunf282a812012-09-21 15:27:54 +0200907 }
908
Emeric Brun1eb20ef2012-12-03 13:24:29 +0100909 if (objt_listener(conn->target)->bind_conf->ca_ignerr & (1ULL << err)) {
910 ERR_clear_error();
Emeric Brun81c00f02012-09-21 14:31:21 +0200911 return 1;
Emeric Brun1eb20ef2012-12-03 13:24:29 +0100912 }
Emeric Brun81c00f02012-09-21 14:31:21 +0200913
Willy Tarreau20879a02012-12-03 16:32:10 +0100914 conn->err_code = CO_ER_SSL_CA_FAIL;
Emeric Brun81c00f02012-09-21 14:31:21 +0200915 return 0;
916 }
917
Willy Tarreauf7bc57c2012-10-03 00:19:48 +0200918 if (!SSL_SOCK_ST_TO_CRTERROR(conn->xprt_st))
919 conn->xprt_st |= SSL_SOCK_CRTERROR_TO_ST(err);
Emeric Brunf282a812012-09-21 15:27:54 +0200920
Emeric Brun81c00f02012-09-21 14:31:21 +0200921 /* check if certificate error needs to be ignored */
Emeric Brun1eb20ef2012-12-03 13:24:29 +0100922 if (objt_listener(conn->target)->bind_conf->crt_ignerr & (1ULL << err)) {
923 ERR_clear_error();
Emeric Brun81c00f02012-09-21 14:31:21 +0200924 return 1;
Emeric Brun1eb20ef2012-12-03 13:24:29 +0100925 }
Emeric Brun81c00f02012-09-21 14:31:21 +0200926
Willy Tarreau20879a02012-12-03 16:32:10 +0100927 conn->err_code = CO_ER_SSL_CRT_FAIL;
Emeric Brun81c00f02012-09-21 14:31:21 +0200928 return 0;
Emeric Brune64aef12012-09-21 13:15:06 +0200929}
930
Emeric Brun29f037d2014-04-25 19:05:36 +0200931/* Callback is called for ssl protocol analyse */
932void ssl_sock_msgcbk(int write_p, int version, int content_type, const void *buf, size_t len, SSL *ssl, void *arg)
933{
Emeric Brun29f037d2014-04-25 19:05:36 +0200934#ifdef TLS1_RT_HEARTBEAT
935 /* test heartbeat received (write_p is set to 0
936 for a received record) */
Willy Tarreauf51c6982014-04-25 20:02:39 +0200937 if ((content_type == TLS1_RT_HEARTBEAT) && (write_p == 0)) {
Willy Tarreau84815002014-04-25 21:40:27 +0200938 struct connection *conn = (struct connection *)SSL_get_app_data(ssl);
Willy Tarreauf51c6982014-04-25 20:02:39 +0200939 const unsigned char *p = buf;
940 unsigned int payload;
941
Emeric Brun29f037d2014-04-25 19:05:36 +0200942 conn->xprt_st |= SSL_SOCK_RECV_HEARTBEAT;
Willy Tarreauf51c6982014-04-25 20:02:39 +0200943
944 /* Check if this is a CVE-2014-0160 exploitation attempt. */
945 if (*p != TLS1_HB_REQUEST)
946 return;
947
Willy Tarreauaeed6722014-04-25 23:59:58 +0200948 if (len < 1 + 2 + 16) /* 1 type + 2 size + 0 payload + 16 padding */
Willy Tarreauf51c6982014-04-25 20:02:39 +0200949 goto kill_it;
950
951 payload = (p[1] * 256) + p[2];
Willy Tarreau3b2fdb62014-04-25 23:44:22 +0200952 if (3 + payload + 16 <= len)
Willy Tarreauf51c6982014-04-25 20:02:39 +0200953 return; /* OK no problem */
Willy Tarreauaeed6722014-04-25 23:59:58 +0200954 kill_it:
Willy Tarreau3b2fdb62014-04-25 23:44:22 +0200955 /* We have a clear heartbleed attack (CVE-2014-0160), the
956 * advertised payload is larger than the advertised packet
957 * length, so we have garbage in the buffer between the
958 * payload and the end of the buffer (p+len). We can't know
959 * if the SSL stack is patched, and we don't know if we can
960 * safely wipe out the area between p+3+len and payload.
961 * So instead, we prevent the response from being sent by
962 * setting the max_send_fragment to 0 and we report an SSL
963 * error, which will kill this connection. It will be reported
964 * above as SSL_ERROR_SSL while an other handshake failure with
Willy Tarreauf51c6982014-04-25 20:02:39 +0200965 * a heartbeat message will be reported as SSL_ERROR_SYSCALL.
966 */
Willy Tarreau3b2fdb62014-04-25 23:44:22 +0200967 ssl->max_send_fragment = 0;
Willy Tarreauf51c6982014-04-25 20:02:39 +0200968 SSLerr(SSL_F_TLS1_HEARTBEAT, SSL_R_SSL_HANDSHAKE_FAILURE);
969 return;
970 }
Emeric Brun29f037d2014-04-25 19:05:36 +0200971#endif
972}
973
Willy Tarreau6c9a3d52012-10-18 18:57:14 +0200974#ifdef OPENSSL_NPN_NEGOTIATED
975/* This callback is used so that the server advertises the list of
976 * negociable protocols for NPN.
977 */
978static int ssl_sock_advertise_npn_protos(SSL *s, const unsigned char **data,
979 unsigned int *len, void *arg)
980{
981 struct bind_conf *conf = arg;
982
983 *data = (const unsigned char *)conf->npn_str;
984 *len = conf->npn_len;
985 return SSL_TLSEXT_ERR_OK;
986}
987#endif
988
Dirkjan Bussink48f1c4e2014-02-13 12:29:42 +0100989#ifdef TLSEXT_TYPE_application_layer_protocol_negotiation
Willy Tarreauab861d32013-04-02 02:30:41 +0200990/* This callback is used so that the server advertises the list of
991 * negociable protocols for ALPN.
992 */
Dirkjan Bussink48f1c4e2014-02-13 12:29:42 +0100993static int ssl_sock_advertise_alpn_protos(SSL *s, const unsigned char **out,
994 unsigned char *outlen,
995 const unsigned char *server,
996 unsigned int server_len, void *arg)
Willy Tarreauab861d32013-04-02 02:30:41 +0200997{
998 struct bind_conf *conf = arg;
999
Dirkjan Bussink48f1c4e2014-02-13 12:29:42 +01001000 if (SSL_select_next_proto((unsigned char**) out, outlen, (const unsigned char *)conf->alpn_str,
1001 conf->alpn_len, server, server_len) != OPENSSL_NPN_NEGOTIATED) {
1002 return SSL_TLSEXT_ERR_NOACK;
1003 }
Willy Tarreauab861d32013-04-02 02:30:41 +02001004 return SSL_TLSEXT_ERR_OK;
1005}
1006#endif
1007
Willy Tarreauc8ad3be2015-06-17 15:48:26 +02001008#ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME
Christopher Faulet30548802015-06-11 13:39:32 +02001009/* Create a X509 certificate with the specified servername and serial. This
1010 * function returns a SSL_CTX object or NULL if an error occurs. */
1011SSL_CTX *
Christopher Faulet31af49d2015-06-09 17:29:50 +02001012ssl_sock_create_cert(const char *servername, unsigned int serial, X509 *cacert, EVP_PKEY *capkey)
1013{
1014 SSL_CTX *ssl_ctx = NULL;
1015 X509 *newcrt = NULL;
1016 EVP_PKEY *pkey = NULL;
1017 RSA *rsa;
1018 X509_NAME *name;
1019 const EVP_MD *digest;
1020 X509V3_CTX ctx;
1021 unsigned int i;
1022
1023 /* Generate the public key */
1024 if (!(rsa = RSA_generate_key(2048, 3, NULL, NULL)))
1025 goto mkcert_error;
1026 if (!(pkey = EVP_PKEY_new()))
1027 goto mkcert_error;
1028 if (EVP_PKEY_assign_RSA(pkey, rsa) != 1)
1029 goto mkcert_error;
1030
1031 /* Create the certificate */
1032 if (!(newcrt = X509_new()))
1033 goto mkcert_error;
1034
1035 /* Set version number for the certificate (X509v3) and the serial
1036 * number */
1037 if (X509_set_version(newcrt, 2L) != 1)
1038 goto mkcert_error;
1039 ASN1_INTEGER_set(X509_get_serialNumber(newcrt), serial);
1040
1041 /* Set duration for the certificate */
1042 if (!X509_gmtime_adj(X509_get_notBefore(newcrt), (long)-60*60*24) ||
1043 !X509_gmtime_adj(X509_get_notAfter(newcrt),(long)60*60*24*365))
1044 goto mkcert_error;
1045
1046 /* set public key in the certificate */
1047 if (X509_set_pubkey(newcrt, pkey) != 1)
1048 goto mkcert_error;
1049
1050 /* Set issuer name from the CA */
1051 if (!(name = X509_get_subject_name(cacert)))
1052 goto mkcert_error;
1053 if (X509_set_issuer_name(newcrt, name) != 1)
1054 goto mkcert_error;
1055
1056 /* Set the subject name using the same, but the CN */
1057 name = X509_NAME_dup(name);
1058 if (X509_NAME_add_entry_by_txt(name, "CN", MBSTRING_ASC,
1059 (const unsigned char *)servername,
1060 -1, -1, 0) != 1) {
1061 X509_NAME_free(name);
1062 goto mkcert_error;
1063 }
1064 if (X509_set_subject_name(newcrt, name) != 1) {
1065 X509_NAME_free(name);
1066 goto mkcert_error;
1067 }
1068 X509_NAME_free(name);
1069
1070 /* Add x509v3 extensions as specified */
1071 X509V3_set_ctx(&ctx, cacert, newcrt, NULL, NULL, 0);
1072 for (i = 0; i < X509V3_EXT_SIZE; i++) {
1073 X509_EXTENSION *ext;
1074
1075 if (!(ext = X509V3_EXT_conf(NULL, &ctx, x509v3_ext_names[i], x509v3_ext_values[i])))
1076 goto mkcert_error;
1077 if (!X509_add_ext(newcrt, ext, -1)) {
1078 X509_EXTENSION_free(ext);
1079 goto mkcert_error;
1080 }
1081 X509_EXTENSION_free(ext);
1082 }
1083
1084 /* Sign the certificate with the CA private key */
1085 if (EVP_PKEY_type(capkey->type) == EVP_PKEY_DSA)
1086 digest = EVP_dss1();
1087 else if (EVP_PKEY_type (capkey->type) == EVP_PKEY_RSA)
1088 digest = EVP_sha256();
1089 else
1090 goto mkcert_error;
1091 if (!(X509_sign(newcrt, capkey, digest)))
1092 goto mkcert_error;
1093
1094 /* Create and set the new SSL_CTX */
1095 if (!(ssl_ctx = SSL_CTX_new(SSLv23_server_method())))
1096 goto mkcert_error;
1097 if (!SSL_CTX_use_PrivateKey(ssl_ctx, pkey))
1098 goto mkcert_error;
1099 if (!SSL_CTX_use_certificate(ssl_ctx, newcrt))
1100 goto mkcert_error;
1101 if (!SSL_CTX_check_private_key(ssl_ctx))
1102 goto mkcert_error;
1103
1104 if (newcrt) X509_free(newcrt);
1105 if (pkey) EVP_PKEY_free(pkey);
1106 return ssl_ctx;
1107
1108 mkcert_error:
1109 if (ssl_ctx) SSL_CTX_free(ssl_ctx);
1110 if (newcrt) X509_free(newcrt);
1111 if (pkey) EVP_PKEY_free(pkey);
1112 return NULL;
1113}
1114
Christopher Faulet30548802015-06-11 13:39:32 +02001115/* Do a lookup for a certificate in the LRU cache used to store generated
1116 * certificates. */
1117SSL_CTX *
1118ssl_sock_get_generated_cert(unsigned int serial, X509 *cacert)
1119{
1120 struct lru64 *lru = NULL;
1121
1122 if (ssl_ctx_lru_tree) {
1123 lru = lru64_lookup(serial, ssl_ctx_lru_tree, cacert, 0);
1124 if (lru && lru->domain)
1125 return (SSL_CTX *)lru->data;
1126 }
1127 return NULL;
1128}
1129
1130/* Set a certificate int the LRU cache used to store generated certificate. */
1131void
1132ssl_sock_set_generated_cert(SSL_CTX *ssl_ctx, unsigned int serial, X509 *cacert)
1133{
1134 struct lru64 *lru = NULL;
1135
1136 if (ssl_ctx_lru_tree) {
1137 lru = lru64_get(serial, ssl_ctx_lru_tree, cacert, 0);
1138 if (!lru)
1139 return;
1140 if (lru->domain && lru->data)
1141 lru->free((SSL_CTX *)lru->data);
1142 lru64_commit(lru, ssl_ctx, cacert, 0, (void (*)(void *))SSL_CTX_free);
1143 }
1144}
1145
1146/* Compute the serial that will be used to create/set/get a certificate. */
1147unsigned int
Willy Tarreau646b8642015-07-07 18:09:15 +02001148ssl_sock_generated_cert_serial(const void *data, size_t len)
Christopher Faulet30548802015-06-11 13:39:32 +02001149{
1150 return XXH32(data, len, ssl_ctx_lru_seed);
1151}
1152
Christopher Faulet31af49d2015-06-09 17:29:50 +02001153static SSL_CTX *
1154ssl_sock_generate_certificate(const char *servername, struct bind_conf *bind_conf)
1155{
1156 X509 *cacert = bind_conf->ca_sign_cert;
1157 EVP_PKEY *capkey = bind_conf->ca_sign_pkey;
1158 SSL_CTX *ssl_ctx = NULL;
1159 struct lru64 *lru = NULL;
1160 unsigned int serial;
1161
Willy Tarreaufc017fe2015-07-07 18:09:34 +02001162 serial = ssl_sock_generated_cert_serial(servername, strlen(servername));
Christopher Faulet31af49d2015-06-09 17:29:50 +02001163 if (ssl_ctx_lru_tree) {
1164 lru = lru64_get(serial, ssl_ctx_lru_tree, cacert, 0);
1165 if (lru && lru->domain)
1166 ssl_ctx = (SSL_CTX *)lru->data;
1167 }
1168
1169 if (!ssl_ctx) {
1170 ssl_ctx = ssl_sock_create_cert(servername, serial, cacert, capkey);
1171 if (lru)
1172 lru64_commit(lru, ssl_ctx, cacert, 0, (void (*)(void *))SSL_CTX_free);
1173 }
1174 return ssl_ctx;
1175}
1176
Emeric Brunfc0421f2012-09-07 17:30:07 +02001177/* Sets the SSL ctx of <ssl> to match the advertised server name. Returns a
1178 * warning when no match is found, which implies the default (first) cert
1179 * will keep being used.
1180 */
Willy Tarreau2a65ff02012-09-13 17:54:29 +02001181static int ssl_sock_switchctx_cbk(SSL *ssl, int *al, struct bind_conf *s)
Emeric Brunfc0421f2012-09-07 17:30:07 +02001182{
1183 const char *servername;
1184 const char *wildp = NULL;
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +02001185 struct ebmb_node *node, *n;
Emeric Brunfc0421f2012-09-07 17:30:07 +02001186 int i;
1187 (void)al; /* shut gcc stupid warning */
1188
1189 servername = SSL_get_servername(ssl, TLSEXT_NAMETYPE_host_name);
Emmanuel Hocdet65623372013-01-24 17:17:15 +01001190 if (!servername) {
Willy Tarreauf6721452015-07-07 18:04:38 +02001191 if (s->generate_certs) {
1192 struct connection *conn = (struct connection *)SSL_get_app_data(ssl);
1193 unsigned int serial;
1194 SSL_CTX *ctx;
Christopher Faulet30548802015-06-11 13:39:32 +02001195
Willy Tarreauf6721452015-07-07 18:04:38 +02001196 conn_get_to_addr(conn);
1197 if (conn->flags & CO_FL_ADDR_TO_SET) {
1198 serial = ssl_sock_generated_cert_serial(&conn->addr.to, get_addr_len(&conn->addr.to));
1199 ctx = ssl_sock_get_generated_cert(serial, s->ca_sign_cert);
1200 if (ctx) {
1201 /* switch ctx */
1202 SSL_set_SSL_CTX(ssl, ctx);
1203 return SSL_TLSEXT_ERR_OK;
1204 }
Christopher Faulet30548802015-06-11 13:39:32 +02001205 }
1206 }
1207
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +02001208 return (s->strict_sni ?
1209 SSL_TLSEXT_ERR_ALERT_FATAL :
Emmanuel Hocdet79274e22013-05-31 12:47:44 +02001210 SSL_TLSEXT_ERR_NOACK);
Emmanuel Hocdet65623372013-01-24 17:17:15 +01001211 }
Emeric Brunfc0421f2012-09-07 17:30:07 +02001212
Willy Tarreau19d14ef2012-10-29 16:51:55 +01001213 for (i = 0; i < trash.size; i++) {
Emeric Brunfc0421f2012-09-07 17:30:07 +02001214 if (!servername[i])
1215 break;
Willy Tarreau19d14ef2012-10-29 16:51:55 +01001216 trash.str[i] = tolower(servername[i]);
1217 if (!wildp && (trash.str[i] == '.'))
1218 wildp = &trash.str[i];
Emeric Brunfc0421f2012-09-07 17:30:07 +02001219 }
Willy Tarreau19d14ef2012-10-29 16:51:55 +01001220 trash.str[i] = 0;
Emeric Brunfc0421f2012-09-07 17:30:07 +02001221
1222 /* lookup in full qualified names */
Willy Tarreau19d14ef2012-10-29 16:51:55 +01001223 node = ebst_lookup(&s->sni_ctx, trash.str);
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +02001224
1225 /* lookup a not neg filter */
1226 for (n = node; n; n = ebmb_next_dup(n)) {
1227 if (!container_of(n, struct sni_ctx, name)->neg) {
1228 node = n;
1229 break;
Emmanuel Hocdet65623372013-01-24 17:17:15 +01001230 }
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +02001231 }
1232 if (!node && wildp) {
1233 /* lookup in wildcards names */
Emeric Brunfc0421f2012-09-07 17:30:07 +02001234 node = ebst_lookup(&s->sni_w_ctx, wildp);
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +02001235 }
1236 if (!node || container_of(node, struct sni_ctx, name)->neg) {
Christopher Faulet31af49d2015-06-09 17:29:50 +02001237 SSL_CTX *ctx;
1238
1239 if (s->generate_certs &&
1240 (ctx = ssl_sock_generate_certificate(servername, s))) {
1241 /* switch ctx */
1242 SSL_set_SSL_CTX(ssl, ctx);
1243 return SSL_TLSEXT_ERR_OK;
1244 }
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +02001245 return (s->strict_sni ?
1246 SSL_TLSEXT_ERR_ALERT_FATAL :
1247 SSL_TLSEXT_ERR_ALERT_WARNING);
Emeric Brunfc0421f2012-09-07 17:30:07 +02001248 }
1249
1250 /* switch ctx */
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +02001251 SSL_set_SSL_CTX(ssl, container_of(node, struct sni_ctx, name)->ctx);
Emeric Brunfc0421f2012-09-07 17:30:07 +02001252 return SSL_TLSEXT_ERR_OK;
1253}
1254#endif /* SSL_CTRL_SET_TLSEXT_HOSTNAME */
1255
Emeric Bruna4bcd9a2012-09-20 16:19:02 +02001256#ifndef OPENSSL_NO_DH
Remi Gacognef46cd6e2014-06-12 14:58:40 +02001257
1258static DH * ssl_get_dh_1024(void)
1259{
Remi Gacogned3a341a2015-05-29 16:26:17 +02001260 static unsigned char dh1024_p[]={
1261 0xFA,0xF9,0x2A,0x22,0x2A,0xA7,0x7F,0xE1,0x67,0x4E,0x53,0xF7,
1262 0x56,0x13,0xC3,0xB1,0xE3,0x29,0x6B,0x66,0x31,0x6A,0x7F,0xB3,
1263 0xC2,0x68,0x6B,0xCB,0x1D,0x57,0x39,0x1D,0x1F,0xFF,0x1C,0xC9,
1264 0xA6,0xA4,0x98,0x82,0x31,0x5D,0x25,0xFF,0x8A,0xE0,0x73,0x96,
1265 0x81,0xC8,0x83,0x79,0xC1,0x5A,0x04,0xF8,0x37,0x0D,0xA8,0x3D,
1266 0xAE,0x74,0xBC,0xDB,0xB6,0xA4,0x75,0xD9,0x71,0x8A,0xA0,0x17,
1267 0x9E,0x2D,0xC8,0xA8,0xDF,0x2C,0x5F,0x82,0x95,0xF8,0x92,0x9B,
1268 0xA7,0x33,0x5F,0x89,0x71,0xC8,0x2D,0x6B,0x18,0x86,0xC4,0x94,
1269 0x22,0xA5,0x52,0x8D,0xF6,0xF6,0xD2,0x37,0x92,0x0F,0xA5,0xCC,
1270 0xDB,0x7B,0x1D,0x3D,0xA1,0x31,0xB7,0x80,0x8F,0x0B,0x67,0x5E,
1271 0x36,0xA5,0x60,0x0C,0xF1,0x95,0x33,0x8B,
1272 };
1273 static unsigned char dh1024_g[]={
1274 0x02,
1275 };
1276
Remi Gacognef46cd6e2014-06-12 14:58:40 +02001277 DH *dh = DH_new();
1278 if (dh) {
Remi Gacogned3a341a2015-05-29 16:26:17 +02001279 dh->p = BN_bin2bn(dh1024_p, sizeof dh1024_p, NULL);
1280 dh->g = BN_bin2bn(dh1024_g, sizeof dh1024_g, NULL);
1281
Remi Gacognef46cd6e2014-06-12 14:58:40 +02001282 if (!dh->p || !dh->g) {
1283 DH_free(dh);
1284 dh = NULL;
1285 }
1286 }
1287 return dh;
1288}
1289
1290static DH *ssl_get_dh_2048(void)
1291{
Remi Gacogned3a341a2015-05-29 16:26:17 +02001292 static unsigned char dh2048_p[]={
1293 0xEC,0x86,0xF8,0x70,0xA0,0x33,0x16,0xEC,0x05,0x1A,0x73,0x59,
1294 0xCD,0x1F,0x8B,0xF8,0x29,0xE4,0xD2,0xCF,0x52,0xDD,0xC2,0x24,
1295 0x8D,0xB5,0x38,0x9A,0xFB,0x5C,0xA4,0xE4,0xB2,0xDA,0xCE,0x66,
1296 0x50,0x74,0xA6,0x85,0x4D,0x4B,0x1D,0x30,0xB8,0x2B,0xF3,0x10,
1297 0xE9,0xA7,0x2D,0x05,0x71,0xE7,0x81,0xDF,0x8B,0x59,0x52,0x3B,
1298 0x5F,0x43,0x0B,0x68,0xF1,0xDB,0x07,0xBE,0x08,0x6B,0x1B,0x23,
1299 0xEE,0x4D,0xCC,0x9E,0x0E,0x43,0xA0,0x1E,0xDF,0x43,0x8C,0xEC,
1300 0xBE,0xBE,0x90,0xB4,0x51,0x54,0xB9,0x2F,0x7B,0x64,0x76,0x4E,
1301 0x5D,0xD4,0x2E,0xAE,0xC2,0x9E,0xAE,0x51,0x43,0x59,0xC7,0x77,
1302 0x9C,0x50,0x3C,0x0E,0xED,0x73,0x04,0x5F,0xF1,0x4C,0x76,0x2A,
1303 0xD8,0xF8,0xCF,0xFC,0x34,0x40,0xD1,0xB4,0x42,0x61,0x84,0x66,
1304 0x42,0x39,0x04,0xF8,0x68,0xB2,0x62,0xD7,0x55,0xED,0x1B,0x74,
1305 0x75,0x91,0xE0,0xC5,0x69,0xC1,0x31,0x5C,0xDB,0x7B,0x44,0x2E,
1306 0xCE,0x84,0x58,0x0D,0x1E,0x66,0x0C,0xC8,0x44,0x9E,0xFD,0x40,
1307 0x08,0x67,0x5D,0xFB,0xA7,0x76,0x8F,0x00,0x11,0x87,0xE9,0x93,
1308 0xF9,0x7D,0xC4,0xBC,0x74,0x55,0x20,0xD4,0x4A,0x41,0x2F,0x43,
1309 0x42,0x1A,0xC1,0xF2,0x97,0x17,0x49,0x27,0x37,0x6B,0x2F,0x88,
1310 0x7E,0x1C,0xA0,0xA1,0x89,0x92,0x27,0xD9,0x56,0x5A,0x71,0xC1,
1311 0x56,0x37,0x7E,0x3A,0x9D,0x05,0xE7,0xEE,0x5D,0x8F,0x82,0x17,
1312 0xBC,0xE9,0xC2,0x93,0x30,0x82,0xF9,0xF4,0xC9,0xAE,0x49,0xDB,
1313 0xD0,0x54,0xB4,0xD9,0x75,0x4D,0xFA,0x06,0xB8,0xD6,0x38,0x41,
1314 0xB7,0x1F,0x77,0xF3,
1315 };
1316 static unsigned char dh2048_g[]={
1317 0x02,
1318 };
1319
Remi Gacognef46cd6e2014-06-12 14:58:40 +02001320 DH *dh = DH_new();
1321 if (dh) {
Remi Gacogned3a341a2015-05-29 16:26:17 +02001322 dh->p = BN_bin2bn(dh2048_p, sizeof dh2048_p, NULL);
1323 dh->g = BN_bin2bn(dh2048_g, sizeof dh2048_g, NULL);
1324
Remi Gacognef46cd6e2014-06-12 14:58:40 +02001325 if (!dh->p || !dh->g) {
1326 DH_free(dh);
1327 dh = NULL;
1328 }
1329 }
1330 return dh;
1331}
1332
1333static DH *ssl_get_dh_4096(void)
1334{
Remi Gacogned3a341a2015-05-29 16:26:17 +02001335 static unsigned char dh4096_p[]={
1336 0xDE,0x16,0x94,0xCD,0x99,0x58,0x07,0xF1,0xF7,0x32,0x96,0x11,
1337 0x04,0x82,0xD4,0x84,0x72,0x80,0x99,0x06,0xCA,0xF0,0xA3,0x68,
1338 0x07,0xCE,0x64,0x50,0xE7,0x74,0x45,0x20,0x80,0x5E,0x4D,0xAD,
1339 0xA5,0xB6,0xED,0xFA,0x80,0x6C,0x3B,0x35,0xC4,0x9A,0x14,0x6B,
1340 0x32,0xBB,0xFD,0x1F,0x17,0x8E,0xB7,0x1F,0xD6,0xFA,0x3F,0x7B,
1341 0xEE,0x16,0xA5,0x62,0x33,0x0D,0xED,0xBC,0x4E,0x58,0xE5,0x47,
1342 0x4D,0xE9,0xAB,0x8E,0x38,0xD3,0x6E,0x90,0x57,0xE3,0x22,0x15,
1343 0x33,0xBD,0xF6,0x43,0x45,0xB5,0x10,0x0A,0xBE,0x2C,0xB4,0x35,
1344 0xB8,0x53,0x8D,0xAD,0xFB,0xA7,0x1F,0x85,0x58,0x41,0x7A,0x79,
1345 0x20,0x68,0xB3,0xE1,0x3D,0x08,0x76,0xBF,0x86,0x0D,0x49,0xE3,
1346 0x82,0x71,0x8C,0xB4,0x8D,0x81,0x84,0xD4,0xE7,0xBE,0x91,0xDC,
1347 0x26,0x39,0x48,0x0F,0x35,0xC4,0xCA,0x65,0xE3,0x40,0x93,0x52,
1348 0x76,0x58,0x7D,0xDD,0x51,0x75,0xDC,0x69,0x61,0xBF,0x47,0x2C,
1349 0x16,0x68,0x2D,0xC9,0x29,0xD3,0xE6,0xC0,0x99,0x48,0xA0,0x9A,
1350 0xC8,0x78,0xC0,0x6D,0x81,0x67,0x12,0x61,0x3F,0x71,0xBA,0x41,
1351 0x1F,0x6C,0x89,0x44,0x03,0xBA,0x3B,0x39,0x60,0xAA,0x28,0x55,
1352 0x59,0xAE,0xB8,0xFA,0xCB,0x6F,0xA5,0x1A,0xF7,0x2B,0xDD,0x52,
1353 0x8A,0x8B,0xE2,0x71,0xA6,0x5E,0x7E,0xD8,0x2E,0x18,0xE0,0x66,
1354 0xDF,0xDD,0x22,0x21,0x99,0x52,0x73,0xA6,0x33,0x20,0x65,0x0E,
1355 0x53,0xE7,0x6B,0x9B,0xC5,0xA3,0x2F,0x97,0x65,0x76,0xD3,0x47,
1356 0x23,0x77,0x12,0xB6,0x11,0x7B,0x24,0xED,0xF1,0xEF,0xC0,0xE2,
1357 0xA3,0x7E,0x67,0x05,0x3E,0x96,0x4D,0x45,0xC2,0x18,0xD1,0x73,
1358 0x9E,0x07,0xF3,0x81,0x6E,0x52,0x63,0xF6,0x20,0x76,0xB9,0x13,
1359 0xD2,0x65,0x30,0x18,0x16,0x09,0x16,0x9E,0x8F,0xF1,0xD2,0x10,
1360 0x5A,0xD3,0xD4,0xAF,0x16,0x61,0xDA,0x55,0x2E,0x18,0x5E,0x14,
1361 0x08,0x54,0x2E,0x2A,0x25,0xA2,0x1A,0x9B,0x8B,0x32,0xA9,0xFD,
1362 0xC2,0x48,0x96,0xE1,0x80,0xCA,0xE9,0x22,0x17,0xBB,0xCE,0x3E,
1363 0x9E,0xED,0xC7,0xF1,0x1F,0xEC,0x17,0x21,0xDC,0x7B,0x82,0x48,
1364 0x8E,0xBB,0x4B,0x9D,0x5B,0x04,0x04,0xDA,0xDB,0x39,0xDF,0x01,
1365 0x40,0xC3,0xAA,0x26,0x23,0x89,0x75,0xC6,0x0B,0xD0,0xA2,0x60,
1366 0x6A,0xF1,0xCC,0x65,0x18,0x98,0x1B,0x52,0xD2,0x74,0x61,0xCC,
1367 0xBD,0x60,0xAE,0xA3,0xA0,0x66,0x6A,0x16,0x34,0x92,0x3F,0x41,
1368 0x40,0x31,0x29,0xC0,0x2C,0x63,0xB2,0x07,0x8D,0xEB,0x94,0xB8,
1369 0xE8,0x47,0x92,0x52,0x93,0x6A,0x1B,0x7E,0x1A,0x61,0xB3,0x1B,
1370 0xF0,0xD6,0x72,0x9B,0xF1,0xB0,0xAF,0xBF,0x3E,0x65,0xEF,0x23,
1371 0x1D,0x6F,0xFF,0x70,0xCD,0x8A,0x4C,0x8A,0xA0,0x72,0x9D,0xBE,
1372 0xD4,0xBB,0x24,0x47,0x4A,0x68,0xB5,0xF5,0xC6,0xD5,0x7A,0xCD,
1373 0xCA,0x06,0x41,0x07,0xAD,0xC2,0x1E,0xE6,0x54,0xA7,0xAD,0x03,
1374 0xD9,0x12,0xC1,0x9C,0x13,0xB1,0xC9,0x0A,0x43,0x8E,0x1E,0x08,
1375 0xCE,0x50,0x82,0x73,0x5F,0xA7,0x55,0x1D,0xD9,0x59,0xAC,0xB5,
1376 0xEA,0x02,0x7F,0x6C,0x5B,0x74,0x96,0x98,0x67,0x24,0xA3,0x0F,
1377 0x15,0xFC,0xA9,0x7D,0x3E,0x67,0xD1,0x70,0xF8,0x97,0xF3,0x67,
1378 0xC5,0x8C,0x88,0x44,0x08,0x02,0xC7,0x2B,
Remi Gacognef46cd6e2014-06-12 14:58:40 +02001379 };
Remi Gacogned3a341a2015-05-29 16:26:17 +02001380 static unsigned char dh4096_g[]={
1381 0x02,
1382 };
Remi Gacognef46cd6e2014-06-12 14:58:40 +02001383
Remi Gacognef46cd6e2014-06-12 14:58:40 +02001384 DH *dh = DH_new();
1385 if (dh) {
Remi Gacogned3a341a2015-05-29 16:26:17 +02001386 dh->p = BN_bin2bn(dh4096_p, sizeof dh4096_p, NULL);
1387 dh->g = BN_bin2bn(dh4096_g, sizeof dh4096_g, NULL);
1388
Remi Gacognef46cd6e2014-06-12 14:58:40 +02001389 if (!dh->p || !dh->g) {
1390 DH_free(dh);
1391 dh = NULL;
1392 }
1393 }
1394 return dh;
1395}
1396
1397/* Returns Diffie-Hellman parameters matching the private key length
1398 but not exceeding global.tune.ssl_default_dh_param */
1399static DH *ssl_get_tmp_dh(SSL *ssl, int export, int keylen)
1400{
1401 DH *dh = NULL;
1402 EVP_PKEY *pkey = SSL_get_privatekey(ssl);
1403 int type = pkey ? EVP_PKEY_type(pkey->type) : EVP_PKEY_NONE;
1404
1405 /* The keylen supplied by OpenSSL can only be 512 or 1024.
1406 See ssl3_send_server_key_exchange() in ssl/s3_srvr.c
1407 */
1408 if (type == EVP_PKEY_RSA || type == EVP_PKEY_DSA) {
1409 keylen = EVP_PKEY_bits(pkey);
1410 }
1411
1412 if (keylen > global.tune.ssl_default_dh_param) {
1413 keylen = global.tune.ssl_default_dh_param;
1414 }
1415
Remi Gacogned3a341a2015-05-29 16:26:17 +02001416 if (keylen >= 4096) {
Remi Gacogne8de54152014-07-15 11:36:40 +02001417 dh = local_dh_4096;
Remi Gacognef46cd6e2014-06-12 14:58:40 +02001418 }
1419 else if (keylen >= 2048) {
Remi Gacogne8de54152014-07-15 11:36:40 +02001420 dh = local_dh_2048;
Remi Gacognef46cd6e2014-06-12 14:58:40 +02001421 }
1422 else {
Remi Gacogne8de54152014-07-15 11:36:40 +02001423 dh = local_dh_1024;
Remi Gacognef46cd6e2014-06-12 14:58:40 +02001424 }
1425
1426 return dh;
1427}
1428
Remi Gacogne47783ef2015-05-29 15:53:22 +02001429static DH * ssl_sock_get_dh_from_file(const char *filename)
Emeric Bruna4bcd9a2012-09-20 16:19:02 +02001430{
Emeric Bruna4bcd9a2012-09-20 16:19:02 +02001431 DH *dh = NULL;
Remi Gacogne47783ef2015-05-29 15:53:22 +02001432 BIO *in = BIO_new(BIO_s_file());
Emeric Bruna4bcd9a2012-09-20 16:19:02 +02001433
Emeric Bruna4bcd9a2012-09-20 16:19:02 +02001434 if (in == NULL)
1435 goto end;
1436
Remi Gacogne47783ef2015-05-29 15:53:22 +02001437 if (BIO_read_filename(in, filename) <= 0)
Emeric Bruna4bcd9a2012-09-20 16:19:02 +02001438 goto end;
1439
Remi Gacogne47783ef2015-05-29 15:53:22 +02001440 dh = PEM_read_bio_DHparams(in, NULL, NULL, NULL);
1441
1442end:
1443 if (in)
1444 BIO_free(in);
1445
1446 return dh;
1447}
1448
1449int ssl_sock_load_global_dh_param_from_file(const char *filename)
1450{
1451 global_dh = ssl_sock_get_dh_from_file(filename);
1452
1453 if (global_dh) {
1454 return 0;
1455 }
1456
1457 return -1;
1458}
1459
1460/* Loads Diffie-Hellman parameter from a file. Returns 1 if loaded, else -1
1461 if an error occured, and 0 if parameter not found. */
1462int ssl_sock_load_dh_params(SSL_CTX *ctx, const char *file)
1463{
1464 int ret = -1;
1465 DH *dh = ssl_sock_get_dh_from_file(file);
1466
Remi Gacognef46cd6e2014-06-12 14:58:40 +02001467 if (dh) {
1468 ret = 1;
1469 SSL_CTX_set_tmp_dh(ctx, dh);
Remi Gacogne4f902b82015-05-28 16:23:00 +02001470
1471 if (ssl_dh_ptr_index >= 0) {
1472 /* store a pointer to the DH params to avoid complaining about
1473 ssl-default-dh-param not being set for this SSL_CTX */
1474 SSL_CTX_set_ex_data(ctx, ssl_dh_ptr_index, dh);
1475 }
Remi Gacognef46cd6e2014-06-12 14:58:40 +02001476 }
Remi Gacogne47783ef2015-05-29 15:53:22 +02001477 else if (global_dh) {
1478 SSL_CTX_set_tmp_dh(ctx, global_dh);
1479 ret = 0; /* DH params not found */
1480 }
Remi Gacognef46cd6e2014-06-12 14:58:40 +02001481 else {
Emeric Brun41fdb3c2013-04-26 11:05:44 +02001482 /* Clear openssl global errors stack */
1483 ERR_clear_error();
1484
Remi Gacognef46cd6e2014-06-12 14:58:40 +02001485 if (global.tune.ssl_default_dh_param <= 1024) {
1486 /* we are limited to DH parameter of 1024 bits anyway */
Remi Gacogne8de54152014-07-15 11:36:40 +02001487 local_dh_1024 = ssl_get_dh_1024();
1488 if (local_dh_1024 == NULL)
Remi Gacognef46cd6e2014-06-12 14:58:40 +02001489 goto end;
Willy Tarreau6e774b42014-04-25 21:35:23 +02001490
Remi Gacogne8de54152014-07-15 11:36:40 +02001491 SSL_CTX_set_tmp_dh(ctx, local_dh_1024);
Remi Gacognef46cd6e2014-06-12 14:58:40 +02001492 }
1493 else {
1494 SSL_CTX_set_tmp_dh_callback(ctx, ssl_get_tmp_dh);
1495 }
Willy Tarreau6e774b42014-04-25 21:35:23 +02001496
Emeric Brun41fdb3c2013-04-26 11:05:44 +02001497 ret = 0; /* DH params not found */
Emeric Bruna4bcd9a2012-09-20 16:19:02 +02001498 }
Emeric Brun644cde02012-12-14 11:21:13 +01001499
Emeric Bruna4bcd9a2012-09-20 16:19:02 +02001500end:
1501 if (dh)
1502 DH_free(dh);
1503
Emeric Bruna4bcd9a2012-09-20 16:19:02 +02001504 return ret;
1505}
1506#endif
1507
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +02001508static int ssl_sock_add_cert_sni(SSL_CTX *ctx, struct bind_conf *s, char *name, int order)
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01001509{
1510 struct sni_ctx *sc;
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +02001511 int wild = 0, neg = 0;
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01001512
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +02001513 if (*name == '!') {
1514 neg = 1;
1515 name++;
1516 }
1517 if (*name == '*') {
1518 wild = 1;
1519 name++;
1520 }
1521 /* !* filter is a nop */
1522 if (neg && wild)
1523 return order;
1524 if (*name) {
1525 int j, len;
1526 len = strlen(name);
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01001527 sc = malloc(sizeof(struct sni_ctx) + len + 1);
1528 for (j = 0; j < len; j++)
1529 sc->name.key[j] = tolower(name[j]);
1530 sc->name.key[len] = 0;
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01001531 sc->ctx = ctx;
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +02001532 sc->order = order++;
1533 sc->neg = neg;
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01001534 if (wild)
1535 ebst_insert(&s->sni_w_ctx, &sc->name);
1536 else
1537 ebst_insert(&s->sni_ctx, &sc->name);
1538 }
1539 return order;
1540}
1541
Emeric Brunfc0421f2012-09-07 17:30:07 +02001542/* Loads a certificate key and CA chain from a file. Returns 0 on error, -1 if
1543 * an early error happens and the caller must call SSL_CTX_free() by itelf.
1544 */
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +02001545static 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 +02001546{
1547 BIO *in;
1548 X509 *x = NULL, *ca;
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +02001549 int i, err;
Emeric Brunfc0421f2012-09-07 17:30:07 +02001550 int ret = -1;
1551 int order = 0;
1552 X509_NAME *xname;
1553 char *str;
Emeric Brunfc0421f2012-09-07 17:30:07 +02001554#ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME
1555 STACK_OF(GENERAL_NAME) *names;
1556#endif
1557
1558 in = BIO_new(BIO_s_file());
1559 if (in == NULL)
1560 goto end;
1561
1562 if (BIO_read_filename(in, file) <= 0)
1563 goto end;
1564
1565 x = PEM_read_bio_X509_AUX(in, NULL, ctx->default_passwd_callback, ctx->default_passwd_callback_userdata);
1566 if (x == NULL)
1567 goto end;
1568
Emeric Brun50bcecc2013-04-22 13:05:23 +02001569 if (fcount) {
1570 while (fcount--)
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +02001571 order = ssl_sock_add_cert_sni(ctx, s, sni_filter[fcount], order);
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01001572 }
1573 else {
Emeric Brunfc0421f2012-09-07 17:30:07 +02001574#ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01001575 names = X509_get_ext_d2i(x, NID_subject_alt_name, NULL, NULL);
1576 if (names) {
1577 for (i = 0; i < sk_GENERAL_NAME_num(names); i++) {
1578 GENERAL_NAME *name = sk_GENERAL_NAME_value(names, i);
1579 if (name->type == GEN_DNS) {
1580 if (ASN1_STRING_to_UTF8((unsigned char **)&str, name->d.dNSName) >= 0) {
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +02001581 order = ssl_sock_add_cert_sni(ctx, s, str, order);
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01001582 OPENSSL_free(str);
Emeric Brunfc0421f2012-09-07 17:30:07 +02001583 }
Emeric Brunfc0421f2012-09-07 17:30:07 +02001584 }
1585 }
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01001586 sk_GENERAL_NAME_pop_free(names, GENERAL_NAME_free);
Emeric Brunfc0421f2012-09-07 17:30:07 +02001587 }
Emeric Brunfc0421f2012-09-07 17:30:07 +02001588#endif /* SSL_CTRL_SET_TLSEXT_HOSTNAME */
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01001589 xname = X509_get_subject_name(x);
1590 i = -1;
1591 while ((i = X509_NAME_get_index_by_NID(xname, NID_commonName, i)) != -1) {
1592 X509_NAME_ENTRY *entry = X509_NAME_get_entry(xname, i);
1593 if (ASN1_STRING_to_UTF8((unsigned char **)&str, entry->value) >= 0) {
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +02001594 order = ssl_sock_add_cert_sni(ctx, s, str, order);
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01001595 OPENSSL_free(str);
Emeric Brunfc0421f2012-09-07 17:30:07 +02001596 }
Emeric Brunfc0421f2012-09-07 17:30:07 +02001597 }
1598 }
1599
1600 ret = 0; /* the caller must not free the SSL_CTX argument anymore */
1601 if (!SSL_CTX_use_certificate(ctx, x))
1602 goto end;
1603
1604 if (ctx->extra_certs != NULL) {
1605 sk_X509_pop_free(ctx->extra_certs, X509_free);
1606 ctx->extra_certs = NULL;
1607 }
1608
1609 while ((ca = PEM_read_bio_X509(in, NULL, ctx->default_passwd_callback, ctx->default_passwd_callback_userdata))) {
1610 if (!SSL_CTX_add_extra_chain_cert(ctx, ca)) {
1611 X509_free(ca);
1612 goto end;
1613 }
1614 }
1615
1616 err = ERR_get_error();
1617 if (!err || (ERR_GET_LIB(err) == ERR_LIB_PEM && ERR_GET_REASON(err) == PEM_R_NO_START_LINE)) {
1618 /* we successfully reached the last cert in the file */
1619 ret = 1;
1620 }
1621 ERR_clear_error();
1622
1623end:
1624 if (x)
1625 X509_free(x);
1626
1627 if (in)
1628 BIO_free(in);
1629
1630 return ret;
1631}
1632
Emeric Brun50bcecc2013-04-22 13:05:23 +02001633static 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 +02001634{
1635 int ret;
1636 SSL_CTX *ctx;
1637
1638 ctx = SSL_CTX_new(SSLv23_server_method());
1639 if (!ctx) {
Willy Tarreaueb6cead2012-09-20 19:43:14 +02001640 memprintf(err, "%sunable to allocate SSL context for cert '%s'.\n",
1641 err && *err ? *err : "", path);
Emeric Brunfc0421f2012-09-07 17:30:07 +02001642 return 1;
1643 }
1644
1645 if (SSL_CTX_use_PrivateKey_file(ctx, path, SSL_FILETYPE_PEM) <= 0) {
Willy Tarreaueb6cead2012-09-20 19:43:14 +02001646 memprintf(err, "%sunable to load SSL private key from PEM file '%s'.\n",
1647 err && *err ? *err : "", path);
Emeric Brunfc0421f2012-09-07 17:30:07 +02001648 SSL_CTX_free(ctx);
1649 return 1;
1650 }
1651
Emeric Brun50bcecc2013-04-22 13:05:23 +02001652 ret = ssl_sock_load_cert_chain_file(ctx, path, bind_conf, sni_filter, fcount);
Emeric Brunfc0421f2012-09-07 17:30:07 +02001653 if (ret <= 0) {
Willy Tarreaueb6cead2012-09-20 19:43:14 +02001654 memprintf(err, "%sunable to load SSL certificate from PEM file '%s'.\n",
1655 err && *err ? *err : "", path);
Emeric Brunfc0421f2012-09-07 17:30:07 +02001656 if (ret < 0) /* serious error, must do that ourselves */
1657 SSL_CTX_free(ctx);
1658 return 1;
1659 }
Emeric Brun61694ab2012-10-26 13:35:33 +02001660
1661 if (SSL_CTX_check_private_key(ctx) <= 0) {
1662 memprintf(err, "%sinconsistencies between private key and certificate loaded from PEM file '%s'.\n",
1663 err && *err ? *err : "", path);
1664 return 1;
1665 }
1666
Emeric Brunfc0421f2012-09-07 17:30:07 +02001667 /* we must not free the SSL_CTX anymore below, since it's already in
1668 * the tree, so it will be discovered and cleaned in time.
1669 */
Emeric Bruna4bcd9a2012-09-20 16:19:02 +02001670#ifndef OPENSSL_NO_DH
Remi Gacogne4f902b82015-05-28 16:23:00 +02001671 /* store a NULL pointer to indicate we have not yet loaded
1672 a custom DH param file */
1673 if (ssl_dh_ptr_index >= 0) {
1674 SSL_CTX_set_ex_data(ctx, ssl_dh_ptr_index, NULL);
1675 }
1676
Emeric Bruna4bcd9a2012-09-20 16:19:02 +02001677 ret = ssl_sock_load_dh_params(ctx, path);
1678 if (ret < 0) {
1679 if (err)
1680 memprintf(err, "%sunable to load DH parameters from file '%s'.\n",
1681 *err ? *err : "", path);
1682 return 1;
1683 }
1684#endif
1685
Lukas Tribuse4e30f72014-12-09 16:32:51 +01001686#if (defined SSL_CTRL_SET_TLSEXT_STATUS_REQ_CB && !defined OPENSSL_NO_OCSP)
Emeric Brun4147b2e2014-06-16 18:36:30 +02001687 ret = ssl_sock_load_ocsp(ctx, path);
1688 if (ret < 0) {
1689 if (err)
1690 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",
1691 *err ? *err : "", path);
1692 return 1;
1693 }
1694#endif
1695
Janusz Dziemidowicz2c701b52015-03-07 23:03:59 +01001696#if (OPENSSL_VERSION_NUMBER >= 0x1000200fL && !defined OPENSSL_NO_TLSEXT && !defined OPENSSL_IS_BORINGSSL)
1697 if (sctl_ex_index >= 0) {
1698 ret = ssl_sock_load_sctl(ctx, path);
1699 if (ret < 0) {
1700 if (err)
1701 memprintf(err, "%s '%s.sctl' is present but cannot be read or parsed'.\n",
1702 *err ? *err : "", path);
1703 return 1;
1704 }
1705 }
1706#endif
1707
Emeric Brunfc0421f2012-09-07 17:30:07 +02001708#ifndef SSL_CTRL_SET_TLSEXT_HOSTNAME
Willy Tarreau2a65ff02012-09-13 17:54:29 +02001709 if (bind_conf->default_ctx) {
Willy Tarreaueb6cead2012-09-20 19:43:14 +02001710 memprintf(err, "%sthis version of openssl cannot load multiple SSL certificates.\n",
1711 err && *err ? *err : "");
Emeric Brunfc0421f2012-09-07 17:30:07 +02001712 return 1;
1713 }
1714#endif
Willy Tarreau2a65ff02012-09-13 17:54:29 +02001715 if (!bind_conf->default_ctx)
1716 bind_conf->default_ctx = ctx;
Emeric Brunfc0421f2012-09-07 17:30:07 +02001717
1718 return 0;
1719}
1720
Willy Tarreau79eeafa2012-09-14 07:53:05 +02001721int ssl_sock_load_cert(char *path, struct bind_conf *bind_conf, struct proxy *curproxy, char **err)
Emeric Brunfc0421f2012-09-07 17:30:07 +02001722{
Cyril Bonté3180f7b2015-01-25 00:16:08 +01001723 struct dirent **de_list;
1724 int i, n;
Emeric Brunfc0421f2012-09-07 17:30:07 +02001725 DIR *dir;
1726 struct stat buf;
Willy Tarreauee2663b2012-12-06 11:36:59 +01001727 char *end;
1728 char fp[MAXPATHLEN+1];
Emeric Brunfc0421f2012-09-07 17:30:07 +02001729 int cfgerr = 0;
1730
1731 if (!(dir = opendir(path)))
Emeric Brun50bcecc2013-04-22 13:05:23 +02001732 return ssl_sock_load_cert_file(path, bind_conf, curproxy, NULL, 0, err);
Emeric Brunfc0421f2012-09-07 17:30:07 +02001733
1734 /* strip trailing slashes, including first one */
1735 for (end = path + strlen(path) - 1; end >= path && *end == '/'; end--)
1736 *end = 0;
1737
Cyril Bonté3180f7b2015-01-25 00:16:08 +01001738 n = scandir(path, &de_list, 0, alphasort);
1739 if (n < 0) {
1740 memprintf(err, "%sunable to scan directory '%s' : %s.\n",
1741 err && *err ? *err : "", path, strerror(errno));
1742 cfgerr++;
1743 }
1744 else {
1745 for (i = 0; i < n; i++) {
1746 struct dirent *de = de_list[i];
Emeric Brun2aab7222014-06-18 18:15:09 +02001747
Cyril Bonté3180f7b2015-01-25 00:16:08 +01001748 end = strrchr(de->d_name, '.');
Janusz Dziemidowicz2c701b52015-03-07 23:03:59 +01001749 if (end && (!strcmp(end, ".issuer") || !strcmp(end, ".ocsp") || !strcmp(end, ".sctl")))
Cyril Bonté3180f7b2015-01-25 00:16:08 +01001750 goto ignore_entry;
1751
1752 snprintf(fp, sizeof(fp), "%s/%s", path, de->d_name);
1753 if (stat(fp, &buf) != 0) {
1754 memprintf(err, "%sunable to stat SSL certificate from file '%s' : %s.\n",
1755 err && *err ? *err : "", fp, strerror(errno));
1756 cfgerr++;
1757 goto ignore_entry;
1758 }
1759 if (!S_ISREG(buf.st_mode))
1760 goto ignore_entry;
1761 cfgerr += ssl_sock_load_cert_file(fp, bind_conf, curproxy, NULL, 0, err);
1762 ignore_entry:
1763 free(de);
Emeric Brunfc0421f2012-09-07 17:30:07 +02001764 }
Cyril Bonté3180f7b2015-01-25 00:16:08 +01001765 free(de_list);
Emeric Brunfc0421f2012-09-07 17:30:07 +02001766 }
Emeric Brunfc0421f2012-09-07 17:30:07 +02001767 closedir(dir);
1768 return cfgerr;
1769}
1770
Thierry Fournier383085f2013-01-24 14:15:43 +01001771/* Make sure openssl opens /dev/urandom before the chroot. The work is only
1772 * done once. Zero is returned if the operation fails. No error is returned
1773 * if the random is said as not implemented, because we expect that openssl
1774 * will use another method once needed.
1775 */
1776static int ssl_initialize_random()
1777{
1778 unsigned char random;
1779 static int random_initialized = 0;
1780
1781 if (!random_initialized && RAND_bytes(&random, 1) != 0)
1782 random_initialized = 1;
1783
1784 return random_initialized;
1785}
1786
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01001787int ssl_sock_load_cert_list_file(char *file, struct bind_conf *bind_conf, struct proxy *curproxy, char **err)
1788{
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +02001789 char thisline[LINESIZE];
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01001790 FILE *f;
1791 int linenum = 0;
1792 int cfgerr = 0;
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01001793
Willy Tarreauad1731d2013-04-02 17:35:58 +02001794 if ((f = fopen(file, "r")) == NULL) {
1795 memprintf(err, "cannot open file '%s' : %s", file, strerror(errno));
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01001796 return 1;
Willy Tarreauad1731d2013-04-02 17:35:58 +02001797 }
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01001798
1799 while (fgets(thisline, sizeof(thisline), f) != NULL) {
1800 int arg;
Emeric Brun50bcecc2013-04-22 13:05:23 +02001801 int newarg;
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01001802 char *end;
1803 char *args[MAX_LINE_ARGS + 1];
1804 char *line = thisline;
1805
1806 linenum++;
1807 end = line + strlen(line);
1808 if (end-line == sizeof(thisline)-1 && *(end-1) != '\n') {
1809 /* Check if we reached the limit and the last char is not \n.
1810 * Watch out for the last line without the terminating '\n'!
1811 */
Willy Tarreauad1731d2013-04-02 17:35:58 +02001812 memprintf(err, "line %d too long in file '%s', limit is %d characters",
1813 linenum, file, (int)sizeof(thisline)-1);
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01001814 cfgerr = 1;
Willy Tarreauad1731d2013-04-02 17:35:58 +02001815 break;
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01001816 }
1817
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01001818 arg = 0;
Emeric Brun50bcecc2013-04-22 13:05:23 +02001819 newarg = 1;
1820 while (*line) {
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01001821 if (*line == '#' || *line == '\n' || *line == '\r') {
1822 /* end of string, end of loop */
1823 *line = 0;
1824 break;
1825 }
1826 else if (isspace(*line)) {
Emeric Brun50bcecc2013-04-22 13:05:23 +02001827 newarg = 1;
1828 *line = 0;
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01001829 }
Emeric Brun50bcecc2013-04-22 13:05:23 +02001830 else if (newarg) {
1831 if (arg == MAX_LINE_ARGS) {
1832 memprintf(err, "too many args on line %d in file '%s'.",
1833 linenum, file);
1834 cfgerr = 1;
1835 break;
1836 }
1837 newarg = 0;
1838 args[arg++] = line;
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01001839 }
Emeric Brun50bcecc2013-04-22 13:05:23 +02001840 line++;
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01001841 }
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +02001842 if (cfgerr)
1843 break;
Willy Tarreauad1731d2013-04-02 17:35:58 +02001844
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01001845 /* empty line */
Emeric Brun50bcecc2013-04-22 13:05:23 +02001846 if (!arg)
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01001847 continue;
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01001848
Emeric Brun50bcecc2013-04-22 13:05:23 +02001849 cfgerr = ssl_sock_load_cert_file(args[0], bind_conf, curproxy, &args[1], arg-1, err);
Willy Tarreauad1731d2013-04-02 17:35:58 +02001850 if (cfgerr) {
1851 memprintf(err, "error processing line %d in file '%s' : %s", linenum, file, *err);
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01001852 break;
Willy Tarreauad1731d2013-04-02 17:35:58 +02001853 }
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01001854 }
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01001855 fclose(f);
1856 return cfgerr;
1857}
1858
Emeric Brunfc0421f2012-09-07 17:30:07 +02001859#ifndef SSL_OP_CIPHER_SERVER_PREFERENCE /* needs OpenSSL >= 0.9.7 */
1860#define SSL_OP_CIPHER_SERVER_PREFERENCE 0
1861#endif
1862
1863#ifndef SSL_OP_NO_SESSION_RESUMPTION_ON_RENEGOTIATION /* needs OpenSSL >= 0.9.7 */
1864#define SSL_OP_NO_SESSION_RESUMPTION_ON_RENEGOTIATION 0
Willy Tarreau7d588ee2012-11-26 18:47:31 +01001865#define SSL_renegotiate_pending(arg) 0
Emeric Brunfc0421f2012-09-07 17:30:07 +02001866#endif
Emeric Brun2b58d042012-09-20 17:10:03 +02001867#ifndef SSL_OP_SINGLE_ECDH_USE /* needs OpenSSL >= 0.9.8 */
1868#define SSL_OP_SINGLE_ECDH_USE 0
1869#endif
Emeric Brun2d0c4822012-10-02 13:45:20 +02001870#ifndef SSL_OP_NO_TICKET /* needs OpenSSL >= 0.9.8 */
1871#define SSL_OP_NO_TICKET 0
1872#endif
Emeric Brunfc0421f2012-09-07 17:30:07 +02001873#ifndef SSL_OP_NO_COMPRESSION /* needs OpenSSL >= 0.9.9 */
1874#define SSL_OP_NO_COMPRESSION 0
1875#endif
Emeric Brunc0ff4922012-09-28 19:37:02 +02001876#ifndef SSL_OP_NO_TLSv1_1 /* needs OpenSSL >= 1.0.1 */
1877#define SSL_OP_NO_TLSv1_1 0
1878#endif
1879#ifndef SSL_OP_NO_TLSv1_2 /* needs OpenSSL >= 1.0.1 */
1880#define SSL_OP_NO_TLSv1_2 0
1881#endif
Emeric Bruna4bcd9a2012-09-20 16:19:02 +02001882#ifndef SSL_OP_SINGLE_DH_USE /* needs OpenSSL >= 0.9.6 */
1883#define SSL_OP_SINGLE_DH_USE 0
1884#endif
Emeric Brun2b58d042012-09-20 17:10:03 +02001885#ifndef SSL_OP_SINGLE_ECDH_USE /* needs OpenSSL >= 1.0.0 */
1886#define SSL_OP_SINGLE_ECDH_USE 0
1887#endif
Emeric Brunfc0421f2012-09-07 17:30:07 +02001888#ifndef SSL_MODE_RELEASE_BUFFERS /* needs OpenSSL >= 1.0.0 */
1889#define SSL_MODE_RELEASE_BUFFERS 0
1890#endif
Willy Tarreau396a1862014-11-13 14:06:52 +01001891#ifndef SSL_MODE_SMALL_BUFFERS /* needs small_records.patch */
1892#define SSL_MODE_SMALL_BUFFERS 0
1893#endif
Remi Gacognef46cd6e2014-06-12 14:58:40 +02001894
Willy Tarreau2a65ff02012-09-13 17:54:29 +02001895int ssl_sock_prepare_ctx(struct bind_conf *bind_conf, SSL_CTX *ctx, struct proxy *curproxy)
Emeric Brunfc0421f2012-09-07 17:30:07 +02001896{
1897 int cfgerr = 0;
Emeric Brun850efd52014-01-29 12:24:34 +01001898 int verify = SSL_VERIFY_NONE;
Remi Gacogneaf5c3da2014-05-19 10:29:58 +02001899 long ssloptions =
Emeric Brunfc0421f2012-09-07 17:30:07 +02001900 SSL_OP_ALL | /* all known workarounds for bugs */
1901 SSL_OP_NO_SSLv2 |
1902 SSL_OP_NO_COMPRESSION |
Emeric Bruna4bcd9a2012-09-20 16:19:02 +02001903 SSL_OP_SINGLE_DH_USE |
Emeric Brun2b58d042012-09-20 17:10:03 +02001904 SSL_OP_SINGLE_ECDH_USE |
Emeric Brun3c4bc6e2012-10-04 18:44:19 +02001905 SSL_OP_NO_SESSION_RESUMPTION_ON_RENEGOTIATION |
1906 SSL_OP_CIPHER_SERVER_PREFERENCE;
Remi Gacogneaf5c3da2014-05-19 10:29:58 +02001907 long sslmode =
Emeric Brunfc0421f2012-09-07 17:30:07 +02001908 SSL_MODE_ENABLE_PARTIAL_WRITE |
1909 SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER |
Willy Tarreau396a1862014-11-13 14:06:52 +01001910 SSL_MODE_RELEASE_BUFFERS |
1911 SSL_MODE_SMALL_BUFFERS;
Remi Gacognef46cd6e2014-06-12 14:58:40 +02001912 STACK_OF(SSL_CIPHER) * ciphers = NULL;
Willy Tarreaua616ba62014-10-26 06:49:19 +01001913 SSL_CIPHER * cipher = NULL;
Remi Gacognec1eab8c2014-06-12 18:20:11 +02001914 char cipher_description[128];
1915 /* The description of ciphers using an Ephemeral Diffie Hellman key exchange
1916 contains " Kx=DH " or " Kx=DH(". Beware of " Kx=DH/",
1917 which is not ephemeral DH. */
1918 const char dhe_description[] = " Kx=DH ";
1919 const char dhe_export_description[] = " Kx=DH(";
Remi Gacognef46cd6e2014-06-12 14:58:40 +02001920 int idx = 0;
1921 int dhe_found = 0;
Remi Gacogne23d5d372014-10-10 17:04:26 +02001922 SSL *ssl = NULL;
Emeric Brunfc0421f2012-09-07 17:30:07 +02001923
Thierry Fournier383085f2013-01-24 14:15:43 +01001924 /* Make sure openssl opens /dev/urandom before the chroot */
1925 if (!ssl_initialize_random()) {
1926 Alert("OpenSSL random data generator initialization failed.\n");
1927 cfgerr++;
1928 }
1929
Emeric Brun89675492012-10-05 13:48:26 +02001930 if (bind_conf->ssl_options & BC_SSL_O_NO_SSLV3)
Emeric Brunfc0421f2012-09-07 17:30:07 +02001931 ssloptions |= SSL_OP_NO_SSLv3;
Emeric Brun89675492012-10-05 13:48:26 +02001932 if (bind_conf->ssl_options & BC_SSL_O_NO_TLSV10)
Emeric Brunfc0421f2012-09-07 17:30:07 +02001933 ssloptions |= SSL_OP_NO_TLSv1;
Emeric Brun89675492012-10-05 13:48:26 +02001934 if (bind_conf->ssl_options & BC_SSL_O_NO_TLSV11)
Emeric Brunc0ff4922012-09-28 19:37:02 +02001935 ssloptions |= SSL_OP_NO_TLSv1_1;
Emeric Brun89675492012-10-05 13:48:26 +02001936 if (bind_conf->ssl_options & BC_SSL_O_NO_TLSV12)
Emeric Brunc0ff4922012-09-28 19:37:02 +02001937 ssloptions |= SSL_OP_NO_TLSv1_2;
Emeric Brun89675492012-10-05 13:48:26 +02001938 if (bind_conf->ssl_options & BC_SSL_O_NO_TLS_TICKETS)
Emeric Brun2d0c4822012-10-02 13:45:20 +02001939 ssloptions |= SSL_OP_NO_TICKET;
Jérémie Courrèges-Anglas17c3f622015-07-25 16:50:52 -06001940 if (bind_conf->ssl_options & BC_SSL_O_USE_SSLV3) {
1941#ifndef OPENSSL_NO_SSL3
Emeric Brun2cb7ae52012-10-05 14:14:21 +02001942 SSL_CTX_set_ssl_version(ctx, SSLv3_server_method());
Jérémie Courrèges-Anglas17c3f622015-07-25 16:50:52 -06001943#else
1944 Alert("SSLv3 support requested but unavailable.\n");
1945 cfgerr++;
1946#endif
1947 }
Emeric Brun2cb7ae52012-10-05 14:14:21 +02001948 if (bind_conf->ssl_options & BC_SSL_O_USE_TLSV10)
1949 SSL_CTX_set_ssl_version(ctx, TLSv1_server_method());
1950#if SSL_OP_NO_TLSv1_1
1951 if (bind_conf->ssl_options & BC_SSL_O_USE_TLSV11)
1952 SSL_CTX_set_ssl_version(ctx, TLSv1_1_server_method());
1953#endif
1954#if SSL_OP_NO_TLSv1_2
1955 if (bind_conf->ssl_options & BC_SSL_O_USE_TLSV12)
1956 SSL_CTX_set_ssl_version(ctx, TLSv1_2_server_method());
1957#endif
Emeric Brunfc0421f2012-09-07 17:30:07 +02001958
1959 SSL_CTX_set_options(ctx, ssloptions);
1960 SSL_CTX_set_mode(ctx, sslmode);
Emeric Brun850efd52014-01-29 12:24:34 +01001961 switch (bind_conf->verify) {
1962 case SSL_SOCK_VERIFY_NONE:
1963 verify = SSL_VERIFY_NONE;
1964 break;
1965 case SSL_SOCK_VERIFY_OPTIONAL:
1966 verify = SSL_VERIFY_PEER;
1967 break;
1968 case SSL_SOCK_VERIFY_REQUIRED:
1969 verify = SSL_VERIFY_PEER|SSL_VERIFY_FAIL_IF_NO_PEER_CERT;
1970 break;
1971 }
1972 SSL_CTX_set_verify(ctx, verify, ssl_sock_bind_verifycbk);
1973 if (verify & SSL_VERIFY_PEER) {
Emeric Brunfb510ea2012-10-05 12:00:26 +02001974 if (bind_conf->ca_file) {
Emeric Brund94b3fe2012-09-20 18:23:56 +02001975 /* load CAfile to verify */
Emeric Brunfb510ea2012-10-05 12:00:26 +02001976 if (!SSL_CTX_load_verify_locations(ctx, bind_conf->ca_file, NULL)) {
Emeric Brund94b3fe2012-09-20 18:23:56 +02001977 Alert("Proxy '%s': unable to load CA file '%s' for bind '%s' at [%s:%d].\n",
Emeric Brunfb510ea2012-10-05 12:00:26 +02001978 curproxy->id, bind_conf->ca_file, bind_conf->arg, bind_conf->file, bind_conf->line);
Emeric Brund94b3fe2012-09-20 18:23:56 +02001979 cfgerr++;
1980 }
1981 /* set CA names fo client cert request, function returns void */
Emeric Brunfb510ea2012-10-05 12:00:26 +02001982 SSL_CTX_set_client_CA_list(ctx, SSL_load_client_CA_file(bind_conf->ca_file));
Emeric Brund94b3fe2012-09-20 18:23:56 +02001983 }
Emeric Brun850efd52014-01-29 12:24:34 +01001984 else {
1985 Alert("Proxy '%s': verify is enabled but no CA file specified for bind '%s' at [%s:%d].\n",
1986 curproxy->id, bind_conf->arg, bind_conf->file, bind_conf->line);
1987 cfgerr++;
1988 }
Emeric Brun051cdab2012-10-02 19:25:50 +02001989#ifdef X509_V_FLAG_CRL_CHECK
Emeric Brunfb510ea2012-10-05 12:00:26 +02001990 if (bind_conf->crl_file) {
Emeric Brund94b3fe2012-09-20 18:23:56 +02001991 X509_STORE *store = SSL_CTX_get_cert_store(ctx);
1992
Emeric Brunfb510ea2012-10-05 12:00:26 +02001993 if (!store || !X509_STORE_load_locations(store, bind_conf->crl_file, NULL)) {
Emeric Brund94b3fe2012-09-20 18:23:56 +02001994 Alert("Proxy '%s': unable to configure CRL file '%s' for bind '%s' at [%s:%d].\n",
Alexander Rigbofc65af02015-04-07 14:02:16 +02001995 curproxy->id, bind_conf->crl_file, bind_conf->arg, bind_conf->file, bind_conf->line);
Emeric Brund94b3fe2012-09-20 18:23:56 +02001996 cfgerr++;
1997 }
Emeric Brun561e5742012-10-02 15:20:55 +02001998 else {
1999 X509_STORE_set_flags(store, X509_V_FLAG_CRL_CHECK|X509_V_FLAG_CRL_CHECK_ALL);
2000 }
Emeric Brund94b3fe2012-09-20 18:23:56 +02002001 }
Emeric Brun051cdab2012-10-02 19:25:50 +02002002#endif
Emeric Brun644cde02012-12-14 11:21:13 +01002003 ERR_clear_error();
Emeric Brund94b3fe2012-09-20 18:23:56 +02002004 }
Emeric Brunfc0421f2012-09-07 17:30:07 +02002005
Nenad Merdanovic05552d42015-02-27 19:56:49 +01002006#if (defined SSL_CTRL_SET_TLSEXT_TICKET_KEY_CB && TLS_TICKETS_NO > 0)
Nenad Merdanovic146defa2015-05-09 08:46:00 +02002007 if(bind_conf->keys_ref) {
Nenad Merdanovic05552d42015-02-27 19:56:49 +01002008 if (!SSL_CTX_set_tlsext_ticket_key_cb(ctx, ssl_tlsext_ticket_key_cb)) {
2009 Alert("Proxy '%s': unable to set callback for TLS ticket validation for bind '%s' at [%s:%d].\n",
2010 curproxy->id, bind_conf->arg, bind_conf->file, bind_conf->line);
2011 cfgerr++;
2012 }
2013 }
2014#endif
2015
Emeric Brun4f65bff2012-11-16 15:11:00 +01002016 if (global.tune.ssllifetime)
2017 SSL_CTX_set_timeout(ctx, global.tune.ssllifetime);
2018
Emeric Brunfc0421f2012-09-07 17:30:07 +02002019 shared_context_set_cache(ctx);
Willy Tarreau2a65ff02012-09-13 17:54:29 +02002020 if (bind_conf->ciphers &&
2021 !SSL_CTX_set_cipher_list(ctx, bind_conf->ciphers)) {
Emeric Brunfc0421f2012-09-07 17:30:07 +02002022 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 +02002023 curproxy->id, bind_conf->ciphers, bind_conf->arg, bind_conf->file, bind_conf->line);
Emeric Brunfc0421f2012-09-07 17:30:07 +02002024 cfgerr++;
2025 }
2026
Remi Gacogne47783ef2015-05-29 15:53:22 +02002027 /* If tune.ssl.default-dh-param has not been set,
2028 neither has ssl-default-dh-file and no static DH
2029 params were in the certificate file. */
Remi Gacogne4f902b82015-05-28 16:23:00 +02002030 if (global.tune.ssl_default_dh_param == 0 &&
Remi Gacogne47783ef2015-05-29 15:53:22 +02002031 global_dh == NULL &&
Remi Gacogne4f902b82015-05-28 16:23:00 +02002032 (ssl_dh_ptr_index == -1 ||
2033 SSL_CTX_get_ex_data(ctx, ssl_dh_ptr_index) == NULL)) {
Lukas Tribus90132722014-08-18 00:56:33 +02002034
Remi Gacogne23d5d372014-10-10 17:04:26 +02002035 ssl = SSL_new(ctx);
Remi Gacognef46cd6e2014-06-12 14:58:40 +02002036
Remi Gacogne23d5d372014-10-10 17:04:26 +02002037 if (ssl) {
2038 ciphers = SSL_get_ciphers(ssl);
2039
2040 if (ciphers) {
2041 for (idx = 0; idx < sk_SSL_CIPHER_num(ciphers); idx++) {
2042 cipher = sk_SSL_CIPHER_value(ciphers, idx);
2043 if (SSL_CIPHER_description(cipher, cipher_description, sizeof (cipher_description)) == cipher_description) {
2044 if (strstr(cipher_description, dhe_description) != NULL ||
2045 strstr(cipher_description, dhe_export_description) != NULL) {
2046 dhe_found = 1;
2047 break;
2048 }
Remi Gacognec1eab8c2014-06-12 18:20:11 +02002049 }
Remi Gacognef46cd6e2014-06-12 14:58:40 +02002050 }
2051 }
Remi Gacogne23d5d372014-10-10 17:04:26 +02002052 SSL_free(ssl);
2053 ssl = NULL;
Lukas Tribus90132722014-08-18 00:56:33 +02002054 }
Remi Gacognef46cd6e2014-06-12 14:58:40 +02002055
Lukas Tribus90132722014-08-18 00:56:33 +02002056 if (dhe_found) {
2057 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 +02002058 }
2059
2060 global.tune.ssl_default_dh_param = 1024;
2061 }
Remi Gacogne8de54152014-07-15 11:36:40 +02002062
2063#ifndef OPENSSL_NO_DH
2064 if (global.tune.ssl_default_dh_param >= 1024) {
2065 if (local_dh_1024 == NULL) {
2066 local_dh_1024 = ssl_get_dh_1024();
2067 }
2068 if (global.tune.ssl_default_dh_param >= 2048) {
2069 if (local_dh_2048 == NULL) {
2070 local_dh_2048 = ssl_get_dh_2048();
2071 }
2072 if (global.tune.ssl_default_dh_param >= 4096) {
2073 if (local_dh_4096 == NULL) {
2074 local_dh_4096 = ssl_get_dh_4096();
2075 }
Remi Gacogne8de54152014-07-15 11:36:40 +02002076 }
2077 }
2078 }
2079#endif /* OPENSSL_NO_DH */
Remi Gacognef46cd6e2014-06-12 14:58:40 +02002080
Emeric Brunfc0421f2012-09-07 17:30:07 +02002081 SSL_CTX_set_info_callback(ctx, ssl_sock_infocbk);
Willy Tarreau5cbe4ef2014-05-08 22:45:11 +02002082#if OPENSSL_VERSION_NUMBER >= 0x00907000L
Emeric Brun29f037d2014-04-25 19:05:36 +02002083 SSL_CTX_set_msg_callback(ctx, ssl_sock_msgcbk);
Willy Tarreau5cbe4ef2014-05-08 22:45:11 +02002084#endif
Emeric Brun29f037d2014-04-25 19:05:36 +02002085
Willy Tarreau6c9a3d52012-10-18 18:57:14 +02002086#ifdef OPENSSL_NPN_NEGOTIATED
2087 if (bind_conf->npn_str)
2088 SSL_CTX_set_next_protos_advertised_cb(ctx, ssl_sock_advertise_npn_protos, bind_conf);
2089#endif
Dirkjan Bussink48f1c4e2014-02-13 12:29:42 +01002090#ifdef TLSEXT_TYPE_application_layer_protocol_negotiation
Willy Tarreauab861d32013-04-02 02:30:41 +02002091 if (bind_conf->alpn_str)
Dirkjan Bussink48f1c4e2014-02-13 12:29:42 +01002092 SSL_CTX_set_alpn_select_cb(ctx, ssl_sock_advertise_alpn_protos, bind_conf);
Willy Tarreauab861d32013-04-02 02:30:41 +02002093#endif
Willy Tarreau6c9a3d52012-10-18 18:57:14 +02002094
Emeric Brunfc0421f2012-09-07 17:30:07 +02002095#ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME
2096 SSL_CTX_set_tlsext_servername_callback(ctx, ssl_sock_switchctx_cbk);
Willy Tarreau2a65ff02012-09-13 17:54:29 +02002097 SSL_CTX_set_tlsext_servername_arg(ctx, bind_conf);
Emeric Brunfc0421f2012-09-07 17:30:07 +02002098#endif
Emeric Brun2b58d042012-09-20 17:10:03 +02002099#if defined(SSL_CTX_set_tmp_ecdh) && !defined(OPENSSL_NO_ECDH)
Emeric Brun6924ef82013-03-06 14:08:53 +01002100 {
Emeric Brun2b58d042012-09-20 17:10:03 +02002101 int i;
2102 EC_KEY *ecdh;
2103
Emeric Brun6924ef82013-03-06 14:08:53 +01002104 i = OBJ_sn2nid(bind_conf->ecdhe ? bind_conf->ecdhe : ECDHE_DEFAULT_CURVE);
Emeric Brun2b58d042012-09-20 17:10:03 +02002105 if (!i || ((ecdh = EC_KEY_new_by_curve_name(i)) == NULL)) {
2106 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 +01002107 curproxy->id, bind_conf->ecdhe ? bind_conf->ecdhe : ECDHE_DEFAULT_CURVE,
2108 bind_conf->arg, bind_conf->file, bind_conf->line);
Emeric Brun2b58d042012-09-20 17:10:03 +02002109 cfgerr++;
2110 }
2111 else {
2112 SSL_CTX_set_tmp_ecdh(ctx, ecdh);
2113 EC_KEY_free(ecdh);
2114 }
2115 }
2116#endif
2117
Emeric Brunfc0421f2012-09-07 17:30:07 +02002118 return cfgerr;
2119}
2120
Evan Broderbe554312013-06-27 00:05:25 -07002121static int ssl_sock_srv_hostcheck(const char *pattern, const char *hostname)
2122{
2123 const char *pattern_wildcard, *pattern_left_label_end, *hostname_left_label_end;
2124 size_t prefixlen, suffixlen;
2125
2126 /* Trivial case */
2127 if (strcmp(pattern, hostname) == 0)
2128 return 1;
2129
Evan Broderbe554312013-06-27 00:05:25 -07002130 /* The rest of this logic is based on RFC 6125, section 6.4.3
2131 * (http://tools.ietf.org/html/rfc6125#section-6.4.3) */
2132
Emeric Bruna848dae2013-10-08 11:27:28 +02002133 pattern_wildcard = NULL;
2134 pattern_left_label_end = pattern;
2135 while (*pattern_left_label_end != '.') {
2136 switch (*pattern_left_label_end) {
2137 case 0:
2138 /* End of label not found */
2139 return 0;
2140 case '*':
2141 /* If there is more than one wildcards */
2142 if (pattern_wildcard)
2143 return 0;
2144 pattern_wildcard = pattern_left_label_end;
2145 break;
2146 }
2147 pattern_left_label_end++;
2148 }
2149
2150 /* If it's not trivial and there is no wildcard, it can't
2151 * match */
2152 if (!pattern_wildcard)
Evan Broderbe554312013-06-27 00:05:25 -07002153 return 0;
2154
2155 /* Make sure all labels match except the leftmost */
2156 hostname_left_label_end = strchr(hostname, '.');
2157 if (!hostname_left_label_end
2158 || strcmp(pattern_left_label_end, hostname_left_label_end) != 0)
2159 return 0;
2160
2161 /* Make sure the leftmost label of the hostname is long enough
2162 * that the wildcard can match */
Emeric Brun369da852013-10-08 11:39:35 +02002163 if (hostname_left_label_end - hostname < (pattern_left_label_end - pattern) - 1)
Evan Broderbe554312013-06-27 00:05:25 -07002164 return 0;
2165
2166 /* Finally compare the string on either side of the
2167 * wildcard */
2168 prefixlen = pattern_wildcard - pattern;
2169 suffixlen = pattern_left_label_end - (pattern_wildcard + 1);
Emeric Bruna848dae2013-10-08 11:27:28 +02002170 if ((prefixlen && (memcmp(pattern, hostname, prefixlen) != 0))
2171 || (suffixlen && (memcmp(pattern_wildcard + 1, hostname_left_label_end - suffixlen, suffixlen) != 0)))
Evan Broderbe554312013-06-27 00:05:25 -07002172 return 0;
2173
2174 return 1;
2175}
2176
2177static int ssl_sock_srv_verifycbk(int ok, X509_STORE_CTX *ctx)
2178{
2179 SSL *ssl;
2180 struct connection *conn;
2181 char *servername;
2182
2183 int depth;
2184 X509 *cert;
2185 STACK_OF(GENERAL_NAME) *alt_names;
2186 int i;
2187 X509_NAME *cert_subject;
2188 char *str;
2189
2190 if (ok == 0)
2191 return ok;
2192
2193 ssl = X509_STORE_CTX_get_ex_data(ctx, SSL_get_ex_data_X509_STORE_CTX_idx());
2194 conn = (struct connection *)SSL_get_app_data(ssl);
2195
2196 servername = objt_server(conn->target)->ssl_ctx.verify_host;
2197
2198 /* We only need to verify the CN on the actual server cert,
2199 * not the indirect CAs */
2200 depth = X509_STORE_CTX_get_error_depth(ctx);
2201 if (depth != 0)
2202 return ok;
2203
2204 /* At this point, the cert is *not* OK unless we can find a
2205 * hostname match */
2206 ok = 0;
2207
2208 cert = X509_STORE_CTX_get_current_cert(ctx);
2209 /* It seems like this might happen if verify peer isn't set */
2210 if (!cert)
2211 return ok;
2212
2213 alt_names = X509_get_ext_d2i(cert, NID_subject_alt_name, NULL, NULL);
2214 if (alt_names) {
2215 for (i = 0; !ok && i < sk_GENERAL_NAME_num(alt_names); i++) {
2216 GENERAL_NAME *name = sk_GENERAL_NAME_value(alt_names, i);
2217 if (name->type == GEN_DNS) {
Emeric Bruna33410c2013-09-17 15:47:48 +02002218#if OPENSSL_VERSION_NUMBER < 0x00907000L
2219 if (ASN1_STRING_to_UTF8((unsigned char **)&str, name->d.ia5) >= 0) {
2220#else
Evan Broderbe554312013-06-27 00:05:25 -07002221 if (ASN1_STRING_to_UTF8((unsigned char **)&str, name->d.dNSName) >= 0) {
Emeric Bruna33410c2013-09-17 15:47:48 +02002222#endif
Evan Broderbe554312013-06-27 00:05:25 -07002223 ok = ssl_sock_srv_hostcheck(str, servername);
2224 OPENSSL_free(str);
2225 }
2226 }
2227 }
Emeric Brun4ad50a42013-09-17 15:19:54 +02002228 sk_GENERAL_NAME_pop_free(alt_names, GENERAL_NAME_free);
Evan Broderbe554312013-06-27 00:05:25 -07002229 }
2230
2231 cert_subject = X509_get_subject_name(cert);
2232 i = -1;
2233 while (!ok && (i = X509_NAME_get_index_by_NID(cert_subject, NID_commonName, i)) != -1) {
2234 X509_NAME_ENTRY *entry = X509_NAME_get_entry(cert_subject, i);
2235 if (ASN1_STRING_to_UTF8((unsigned char **)&str, entry->value) >= 0) {
2236 ok = ssl_sock_srv_hostcheck(str, servername);
2237 OPENSSL_free(str);
2238 }
2239 }
2240
2241 return ok;
2242}
2243
Emeric Brun94324a42012-10-11 14:00:19 +02002244/* prepare ssl context from servers options. Returns an error count */
2245int ssl_sock_prepare_srv_ctx(struct server *srv, struct proxy *curproxy)
2246{
2247 int cfgerr = 0;
Remi Gacogneaf5c3da2014-05-19 10:29:58 +02002248 long options =
Emeric Brun94324a42012-10-11 14:00:19 +02002249 SSL_OP_ALL | /* all known workarounds for bugs */
2250 SSL_OP_NO_SSLv2 |
2251 SSL_OP_NO_COMPRESSION;
Remi Gacogneaf5c3da2014-05-19 10:29:58 +02002252 long mode =
Emeric Brun94324a42012-10-11 14:00:19 +02002253 SSL_MODE_ENABLE_PARTIAL_WRITE |
2254 SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER |
Willy Tarreau396a1862014-11-13 14:06:52 +01002255 SSL_MODE_RELEASE_BUFFERS |
2256 SSL_MODE_SMALL_BUFFERS;
Emeric Brun850efd52014-01-29 12:24:34 +01002257 int verify = SSL_VERIFY_NONE;
Emeric Brun94324a42012-10-11 14:00:19 +02002258
Thierry Fournier383085f2013-01-24 14:15:43 +01002259 /* Make sure openssl opens /dev/urandom before the chroot */
2260 if (!ssl_initialize_random()) {
2261 Alert("OpenSSL random data generator initialization failed.\n");
2262 cfgerr++;
2263 }
2264
Willy Tarreaufce03112015-01-15 21:32:40 +01002265 /* Automatic memory computations need to know we use SSL there */
2266 global.ssl_used_backend = 1;
2267
2268 /* Initiate SSL context for current server */
Emeric Brun94324a42012-10-11 14:00:19 +02002269 srv->ssl_ctx.reused_sess = NULL;
2270 if (srv->use_ssl)
2271 srv->xprt = &ssl_sock;
2272 if (srv->check.use_ssl)
Cyril Bonté9ce13112014-11-15 22:41:27 +01002273 srv->check.xprt = &ssl_sock;
Emeric Brun94324a42012-10-11 14:00:19 +02002274
2275 srv->ssl_ctx.ctx = SSL_CTX_new(SSLv23_client_method());
2276 if (!srv->ssl_ctx.ctx) {
2277 Alert("config : %s '%s', server '%s': unable to allocate ssl context.\n",
2278 proxy_type_str(curproxy), curproxy->id,
2279 srv->id);
2280 cfgerr++;
2281 return cfgerr;
2282 }
Emeric Bruna7aa3092012-10-26 12:58:00 +02002283 if (srv->ssl_ctx.client_crt) {
2284 if (SSL_CTX_use_PrivateKey_file(srv->ssl_ctx.ctx, srv->ssl_ctx.client_crt, SSL_FILETYPE_PEM) <= 0) {
2285 Alert("config : %s '%s', server '%s': unable to load SSL private key from PEM file '%s'.\n",
2286 proxy_type_str(curproxy), curproxy->id,
2287 srv->id, srv->ssl_ctx.client_crt);
2288 cfgerr++;
2289 }
2290 else if (SSL_CTX_use_certificate_chain_file(srv->ssl_ctx.ctx, srv->ssl_ctx.client_crt) <= 0) {
2291 Alert("config : %s '%s', server '%s': unable to load ssl certificate from PEM file '%s'.\n",
2292 proxy_type_str(curproxy), curproxy->id,
2293 srv->id, srv->ssl_ctx.client_crt);
2294 cfgerr++;
2295 }
2296 else if (SSL_CTX_check_private_key(srv->ssl_ctx.ctx) <= 0) {
2297 Alert("config : %s '%s', server '%s': inconsistencies between private key and certificate loaded from PEM file '%s'.\n",
2298 proxy_type_str(curproxy), curproxy->id,
2299 srv->id, srv->ssl_ctx.client_crt);
2300 cfgerr++;
2301 }
2302 }
Emeric Brun94324a42012-10-11 14:00:19 +02002303
2304 if (srv->ssl_ctx.options & SRV_SSL_O_NO_SSLV3)
2305 options |= SSL_OP_NO_SSLv3;
2306 if (srv->ssl_ctx.options & SRV_SSL_O_NO_TLSV10)
2307 options |= SSL_OP_NO_TLSv1;
2308 if (srv->ssl_ctx.options & SRV_SSL_O_NO_TLSV11)
2309 options |= SSL_OP_NO_TLSv1_1;
2310 if (srv->ssl_ctx.options & SRV_SSL_O_NO_TLSV12)
2311 options |= SSL_OP_NO_TLSv1_2;
Emeric Brunf9c5c472012-10-11 15:28:34 +02002312 if (srv->ssl_ctx.options & SRV_SSL_O_NO_TLS_TICKETS)
2313 options |= SSL_OP_NO_TICKET;
Jérémie Courrèges-Anglas17c3f622015-07-25 16:50:52 -06002314 if (srv->ssl_ctx.options & SRV_SSL_O_USE_SSLV3) {
2315#ifndef OPENSSL_NO_SSL3
Emeric Brun94324a42012-10-11 14:00:19 +02002316 SSL_CTX_set_ssl_version(srv->ssl_ctx.ctx, SSLv3_client_method());
Jérémie Courrèges-Anglas17c3f622015-07-25 16:50:52 -06002317#else
Thierry FOURNIERbc965342015-08-26 08:21:26 +02002318 Alert("SSLv3 support requested but unavailable.\n");
Jérémie Courrèges-Anglas17c3f622015-07-25 16:50:52 -06002319 cfgerr++;
2320#endif
2321 }
Emeric Brun94324a42012-10-11 14:00:19 +02002322 if (srv->ssl_ctx.options & SRV_SSL_O_USE_TLSV10)
2323 SSL_CTX_set_ssl_version(srv->ssl_ctx.ctx, TLSv1_client_method());
2324#if SSL_OP_NO_TLSv1_1
2325 if (srv->ssl_ctx.options & SRV_SSL_O_USE_TLSV11)
2326 SSL_CTX_set_ssl_version(srv->ssl_ctx.ctx, TLSv1_1_client_method());
2327#endif
2328#if SSL_OP_NO_TLSv1_2
2329 if (srv->ssl_ctx.options & SRV_SSL_O_USE_TLSV12)
2330 SSL_CTX_set_ssl_version(srv->ssl_ctx.ctx, TLSv1_2_client_method());
2331#endif
2332
2333 SSL_CTX_set_options(srv->ssl_ctx.ctx, options);
2334 SSL_CTX_set_mode(srv->ssl_ctx.ctx, mode);
Emeric Brun850efd52014-01-29 12:24:34 +01002335
2336 if (global.ssl_server_verify == SSL_SERVER_VERIFY_REQUIRED)
2337 verify = SSL_VERIFY_PEER;
2338
2339 switch (srv->ssl_ctx.verify) {
2340 case SSL_SOCK_VERIFY_NONE:
2341 verify = SSL_VERIFY_NONE;
2342 break;
2343 case SSL_SOCK_VERIFY_REQUIRED:
2344 verify = SSL_VERIFY_PEER;
2345 break;
2346 }
Evan Broderbe554312013-06-27 00:05:25 -07002347 SSL_CTX_set_verify(srv->ssl_ctx.ctx,
Emeric Brun850efd52014-01-29 12:24:34 +01002348 verify,
Evan Broderbe554312013-06-27 00:05:25 -07002349 srv->ssl_ctx.verify_host ? ssl_sock_srv_verifycbk : NULL);
Emeric Brun850efd52014-01-29 12:24:34 +01002350 if (verify & SSL_VERIFY_PEER) {
Emeric Brunef42d922012-10-11 16:11:36 +02002351 if (srv->ssl_ctx.ca_file) {
2352 /* load CAfile to verify */
2353 if (!SSL_CTX_load_verify_locations(srv->ssl_ctx.ctx, srv->ssl_ctx.ca_file, NULL)) {
Willy Tarreau07ba08b2014-02-16 19:22:08 +01002354 Alert("Proxy '%s', server '%s' [%s:%d] unable to load CA file '%s'.\n",
Emeric Brunef42d922012-10-11 16:11:36 +02002355 curproxy->id, srv->id,
2356 srv->conf.file, srv->conf.line, srv->ssl_ctx.ca_file);
2357 cfgerr++;
2358 }
2359 }
Emeric Brun850efd52014-01-29 12:24:34 +01002360 else {
2361 if (global.ssl_server_verify == SSL_SERVER_VERIFY_REQUIRED)
Willy Tarreau07ba08b2014-02-16 19:22:08 +01002362 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 +01002363 curproxy->id, srv->id,
2364 srv->conf.file, srv->conf.line);
2365 else
Willy Tarreau07ba08b2014-02-16 19:22:08 +01002366 Alert("Proxy '%s', server '%s' [%s:%d] verify is enabled but no CA file specified.\n",
Emeric Brun850efd52014-01-29 12:24:34 +01002367 curproxy->id, srv->id,
2368 srv->conf.file, srv->conf.line);
2369 cfgerr++;
2370 }
Emeric Brunef42d922012-10-11 16:11:36 +02002371#ifdef X509_V_FLAG_CRL_CHECK
2372 if (srv->ssl_ctx.crl_file) {
2373 X509_STORE *store = SSL_CTX_get_cert_store(srv->ssl_ctx.ctx);
2374
2375 if (!store || !X509_STORE_load_locations(store, srv->ssl_ctx.crl_file, NULL)) {
Willy Tarreau07ba08b2014-02-16 19:22:08 +01002376 Alert("Proxy '%s', server '%s' [%s:%d] unable to configure CRL file '%s'.\n",
Emeric Brunef42d922012-10-11 16:11:36 +02002377 curproxy->id, srv->id,
2378 srv->conf.file, srv->conf.line, srv->ssl_ctx.crl_file);
2379 cfgerr++;
2380 }
2381 else {
2382 X509_STORE_set_flags(store, X509_V_FLAG_CRL_CHECK|X509_V_FLAG_CRL_CHECK_ALL);
2383 }
2384 }
2385#endif
2386 }
2387
Emeric Brun4f65bff2012-11-16 15:11:00 +01002388 if (global.tune.ssllifetime)
2389 SSL_CTX_set_timeout(srv->ssl_ctx.ctx, global.tune.ssllifetime);
2390
Emeric Brun94324a42012-10-11 14:00:19 +02002391 SSL_CTX_set_session_cache_mode(srv->ssl_ctx.ctx, SSL_SESS_CACHE_OFF);
2392 if (srv->ssl_ctx.ciphers &&
2393 !SSL_CTX_set_cipher_list(srv->ssl_ctx.ctx, srv->ssl_ctx.ciphers)) {
2394 Alert("Proxy '%s', server '%s' [%s:%d] : unable to set SSL cipher list to '%s'.\n",
2395 curproxy->id, srv->id,
2396 srv->conf.file, srv->conf.line, srv->ssl_ctx.ciphers);
2397 cfgerr++;
2398 }
2399
2400 return cfgerr;
2401}
2402
Willy Tarreau2a65ff02012-09-13 17:54:29 +02002403/* Walks down the two trees in bind_conf and prepares all certs. The pointer may
Emeric Brunfc0421f2012-09-07 17:30:07 +02002404 * be NULL, in which case nothing is done. Returns the number of errors
2405 * encountered.
2406 */
Willy Tarreau2a65ff02012-09-13 17:54:29 +02002407int ssl_sock_prepare_all_ctx(struct bind_conf *bind_conf, struct proxy *px)
Emeric Brunfc0421f2012-09-07 17:30:07 +02002408{
2409 struct ebmb_node *node;
2410 struct sni_ctx *sni;
2411 int err = 0;
2412
Willy Tarreau2a65ff02012-09-13 17:54:29 +02002413 if (!bind_conf || !bind_conf->is_ssl)
Emeric Brunfc0421f2012-09-07 17:30:07 +02002414 return 0;
2415
Willy Tarreaufce03112015-01-15 21:32:40 +01002416 /* Automatic memory computations need to know we use SSL there */
2417 global.ssl_used_frontend = 1;
2418
Emeric Brun0bed9942014-10-30 19:25:24 +01002419 if (bind_conf->default_ctx)
2420 err += ssl_sock_prepare_ctx(bind_conf, bind_conf->default_ctx, px);
2421
Willy Tarreau2a65ff02012-09-13 17:54:29 +02002422 node = ebmb_first(&bind_conf->sni_ctx);
Emeric Brunfc0421f2012-09-07 17:30:07 +02002423 while (node) {
2424 sni = ebmb_entry(node, struct sni_ctx, name);
Emeric Brun0bed9942014-10-30 19:25:24 +01002425 if (!sni->order && sni->ctx != bind_conf->default_ctx)
2426 /* only initialize the CTX on its first occurrence and
2427 if it is not the default_ctx */
Willy Tarreau2a65ff02012-09-13 17:54:29 +02002428 err += ssl_sock_prepare_ctx(bind_conf, sni->ctx, px);
Emeric Brunfc0421f2012-09-07 17:30:07 +02002429 node = ebmb_next(node);
2430 }
2431
Willy Tarreau2a65ff02012-09-13 17:54:29 +02002432 node = ebmb_first(&bind_conf->sni_w_ctx);
Emeric Brunfc0421f2012-09-07 17:30:07 +02002433 while (node) {
2434 sni = ebmb_entry(node, struct sni_ctx, name);
Emeric Brun0bed9942014-10-30 19:25:24 +01002435 if (!sni->order && sni->ctx != bind_conf->default_ctx)
2436 /* only initialize the CTX on its first occurrence and
2437 if it is not the default_ctx */
Willy Tarreau2a65ff02012-09-13 17:54:29 +02002438 err += ssl_sock_prepare_ctx(bind_conf, sni->ctx, px);
Emeric Brunfc0421f2012-09-07 17:30:07 +02002439 node = ebmb_next(node);
2440 }
2441 return err;
2442}
2443
Willy Tarreau2a65ff02012-09-13 17:54:29 +02002444/* Walks down the two trees in bind_conf and frees all the certs. The pointer may
Emeric Brunfc0421f2012-09-07 17:30:07 +02002445 * be NULL, in which case nothing is done. The default_ctx is nullified too.
2446 */
Willy Tarreau2a65ff02012-09-13 17:54:29 +02002447void ssl_sock_free_all_ctx(struct bind_conf *bind_conf)
Emeric Brunfc0421f2012-09-07 17:30:07 +02002448{
2449 struct ebmb_node *node, *back;
2450 struct sni_ctx *sni;
2451
Willy Tarreau2a65ff02012-09-13 17:54:29 +02002452 if (!bind_conf || !bind_conf->is_ssl)
Emeric Brunfc0421f2012-09-07 17:30:07 +02002453 return;
2454
Willy Tarreau2a65ff02012-09-13 17:54:29 +02002455 node = ebmb_first(&bind_conf->sni_ctx);
Emeric Brunfc0421f2012-09-07 17:30:07 +02002456 while (node) {
2457 sni = ebmb_entry(node, struct sni_ctx, name);
2458 back = ebmb_next(node);
2459 ebmb_delete(node);
2460 if (!sni->order) /* only free the CTX on its first occurrence */
2461 SSL_CTX_free(sni->ctx);
2462 free(sni);
2463 node = back;
2464 }
2465
Willy Tarreau2a65ff02012-09-13 17:54:29 +02002466 node = ebmb_first(&bind_conf->sni_w_ctx);
Emeric Brunfc0421f2012-09-07 17:30:07 +02002467 while (node) {
2468 sni = ebmb_entry(node, struct sni_ctx, name);
2469 back = ebmb_next(node);
2470 ebmb_delete(node);
2471 if (!sni->order) /* only free the CTX on its first occurrence */
2472 SSL_CTX_free(sni->ctx);
2473 free(sni);
2474 node = back;
2475 }
2476
Willy Tarreau2a65ff02012-09-13 17:54:29 +02002477 bind_conf->default_ctx = NULL;
Emeric Brune1f38db2012-09-03 20:36:47 +02002478}
2479
Christopher Faulet31af49d2015-06-09 17:29:50 +02002480/* Load CA cert file and private key used to generate certificates */
2481int
2482ssl_sock_load_ca(struct bind_conf *bind_conf, struct proxy *px)
2483{
2484 FILE *fp;
2485 X509 *cacert = NULL;
2486 EVP_PKEY *capkey = NULL;
2487 int err = 0;
2488
2489 if (!bind_conf || !bind_conf->generate_certs)
2490 return err;
2491
2492 if (!bind_conf->ca_sign_file) {
2493 Alert("Proxy '%s': cannot enable certificate generation, "
2494 "no CA certificate File configured at [%s:%d].\n",
2495 px->id, bind_conf->file, bind_conf->line);
2496 err++;
2497 }
2498
2499 if (err)
2500 goto load_error;
2501
2502 /* read in the CA certificate */
2503 if (!(fp = fopen(bind_conf->ca_sign_file, "r"))) {
2504 Alert("Proxy '%s': Failed to read CA certificate file '%s' at [%s:%d].\n",
2505 px->id, bind_conf->ca_sign_file, bind_conf->file, bind_conf->line);
2506 err++;
2507 goto load_error;
2508 }
2509 if (!(cacert = PEM_read_X509(fp, NULL, NULL, NULL))) {
2510 Alert("Proxy '%s': Failed to read CA certificate file '%s' at [%s:%d].\n",
2511 px->id, bind_conf->ca_sign_file, bind_conf->file, bind_conf->line);
2512 fclose (fp);
2513 err++;
2514 goto load_error;
2515 }
2516 if (!(capkey = PEM_read_PrivateKey(fp, NULL, NULL, bind_conf->ca_sign_pass))) {
2517 Alert("Proxy '%s': Failed to read CA private key file '%s' at [%s:%d].\n",
2518 px->id, bind_conf->ca_sign_file, bind_conf->file, bind_conf->line);
2519 fclose (fp);
2520 err++;
2521 goto load_error;
2522 }
2523 fclose (fp);
2524
2525 bind_conf->ca_sign_cert = cacert;
2526 bind_conf->ca_sign_pkey = capkey;
2527 return err;
2528
2529 load_error:
2530 bind_conf->generate_certs = 0;
2531 if (capkey) EVP_PKEY_free(capkey);
2532 if (cacert) X509_free(cacert);
2533 return err;
2534}
2535
2536/* Release CA cert and private key used to generate certificated */
2537void
2538ssl_sock_free_ca(struct bind_conf *bind_conf)
2539{
2540 if (!bind_conf)
2541 return;
2542
2543 if (bind_conf->ca_sign_pkey)
2544 EVP_PKEY_free(bind_conf->ca_sign_pkey);
2545 if (bind_conf->ca_sign_cert)
2546 X509_free(bind_conf->ca_sign_cert);
2547}
2548
Emeric Brun46591952012-05-18 15:47:34 +02002549/*
2550 * This function is called if SSL * context is not yet allocated. The function
2551 * is designed to be called before any other data-layer operation and sets the
2552 * handshake flag on the connection. It is safe to call it multiple times.
2553 * It returns 0 on success and -1 in error case.
2554 */
2555static int ssl_sock_init(struct connection *conn)
2556{
2557 /* already initialized */
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02002558 if (conn->xprt_ctx)
Emeric Brun46591952012-05-18 15:47:34 +02002559 return 0;
2560
Willy Tarreau3c728722014-01-23 13:50:42 +01002561 if (!conn_ctrl_ready(conn))
Willy Tarreauf79c8172013-10-21 16:30:56 +02002562 return 0;
2563
Willy Tarreau20879a02012-12-03 16:32:10 +01002564 if (global.maxsslconn && sslconns >= global.maxsslconn) {
2565 conn->err_code = CO_ER_SSL_TOO_MANY;
Willy Tarreau403edff2012-09-06 11:58:37 +02002566 return -1;
Willy Tarreau20879a02012-12-03 16:32:10 +01002567 }
Willy Tarreau403edff2012-09-06 11:58:37 +02002568
Emeric Brun46591952012-05-18 15:47:34 +02002569 /* If it is in client mode initiate SSL session
2570 in connect state otherwise accept state */
Willy Tarreau3fdb3662012-11-12 00:42:33 +01002571 if (objt_server(conn->target)) {
Willy Tarreaufba03cd2014-11-13 13:48:58 +01002572 int may_retry = 1;
2573
2574 retry_connect:
Emeric Brun46591952012-05-18 15:47:34 +02002575 /* Alloc a new SSL session ctx */
Willy Tarreau3fdb3662012-11-12 00:42:33 +01002576 conn->xprt_ctx = SSL_new(objt_server(conn->target)->ssl_ctx.ctx);
Willy Tarreau20879a02012-12-03 16:32:10 +01002577 if (!conn->xprt_ctx) {
Willy Tarreaufba03cd2014-11-13 13:48:58 +01002578 if (may_retry--) {
2579 pool_gc2();
2580 goto retry_connect;
2581 }
Willy Tarreau20879a02012-12-03 16:32:10 +01002582 conn->err_code = CO_ER_SSL_NO_MEM;
Emeric Brun46591952012-05-18 15:47:34 +02002583 return -1;
Willy Tarreau20879a02012-12-03 16:32:10 +01002584 }
Emeric Brun46591952012-05-18 15:47:34 +02002585
Emeric Brun46591952012-05-18 15:47:34 +02002586 /* set fd on SSL session context */
Emeric Brun55476152014-11-12 17:35:37 +01002587 if (!SSL_set_fd(conn->xprt_ctx, conn->t.sock.fd)) {
2588 SSL_free(conn->xprt_ctx);
2589 conn->xprt_ctx = NULL;
Willy Tarreaufba03cd2014-11-13 13:48:58 +01002590 if (may_retry--) {
2591 pool_gc2();
2592 goto retry_connect;
2593 }
Emeric Brun55476152014-11-12 17:35:37 +01002594 conn->err_code = CO_ER_SSL_NO_MEM;
2595 return -1;
2596 }
Emeric Brun46591952012-05-18 15:47:34 +02002597
Evan Broderbe554312013-06-27 00:05:25 -07002598 /* set connection pointer */
Emeric Brun55476152014-11-12 17:35:37 +01002599 if (!SSL_set_app_data(conn->xprt_ctx, conn)) {
2600 SSL_free(conn->xprt_ctx);
2601 conn->xprt_ctx = NULL;
Willy Tarreaufba03cd2014-11-13 13:48:58 +01002602 if (may_retry--) {
2603 pool_gc2();
2604 goto retry_connect;
2605 }
Emeric Brun55476152014-11-12 17:35:37 +01002606 conn->err_code = CO_ER_SSL_NO_MEM;
2607 return -1;
2608 }
2609
2610 SSL_set_connect_state(conn->xprt_ctx);
2611 if (objt_server(conn->target)->ssl_ctx.reused_sess) {
2612 if(!SSL_set_session(conn->xprt_ctx, objt_server(conn->target)->ssl_ctx.reused_sess)) {
2613 SSL_SESSION_free(objt_server(conn->target)->ssl_ctx.reused_sess);
2614 objt_server(conn->target)->ssl_ctx.reused_sess = NULL;
2615 }
2616 }
Evan Broderbe554312013-06-27 00:05:25 -07002617
Emeric Brun46591952012-05-18 15:47:34 +02002618 /* leave init state and start handshake */
Willy Tarreau05737472012-09-04 08:03:39 +02002619 conn->flags |= CO_FL_SSL_WAIT_HS | CO_FL_WAIT_L6_CONN;
Willy Tarreau403edff2012-09-06 11:58:37 +02002620
2621 sslconns++;
Willy Tarreau71b734c2014-01-28 15:19:44 +01002622 totalsslconns++;
Emeric Brun46591952012-05-18 15:47:34 +02002623 return 0;
2624 }
Willy Tarreau3fdb3662012-11-12 00:42:33 +01002625 else if (objt_listener(conn->target)) {
Willy Tarreaufba03cd2014-11-13 13:48:58 +01002626 int may_retry = 1;
2627
2628 retry_accept:
Emeric Brun46591952012-05-18 15:47:34 +02002629 /* Alloc a new SSL session ctx */
Willy Tarreau3fdb3662012-11-12 00:42:33 +01002630 conn->xprt_ctx = SSL_new(objt_listener(conn->target)->bind_conf->default_ctx);
Willy Tarreau20879a02012-12-03 16:32:10 +01002631 if (!conn->xprt_ctx) {
Willy Tarreaufba03cd2014-11-13 13:48:58 +01002632 if (may_retry--) {
2633 pool_gc2();
2634 goto retry_accept;
2635 }
Willy Tarreau20879a02012-12-03 16:32:10 +01002636 conn->err_code = CO_ER_SSL_NO_MEM;
Emeric Brun46591952012-05-18 15:47:34 +02002637 return -1;
Willy Tarreau20879a02012-12-03 16:32:10 +01002638 }
Emeric Brun46591952012-05-18 15:47:34 +02002639
Emeric Brun46591952012-05-18 15:47:34 +02002640 /* set fd on SSL session context */
Emeric Brun55476152014-11-12 17:35:37 +01002641 if (!SSL_set_fd(conn->xprt_ctx, conn->t.sock.fd)) {
2642 SSL_free(conn->xprt_ctx);
2643 conn->xprt_ctx = NULL;
Willy Tarreaufba03cd2014-11-13 13:48:58 +01002644 if (may_retry--) {
2645 pool_gc2();
2646 goto retry_accept;
2647 }
Emeric Brun55476152014-11-12 17:35:37 +01002648 conn->err_code = CO_ER_SSL_NO_MEM;
2649 return -1;
2650 }
Emeric Brun46591952012-05-18 15:47:34 +02002651
Emeric Brune1f38db2012-09-03 20:36:47 +02002652 /* set connection pointer */
Emeric Brun55476152014-11-12 17:35:37 +01002653 if (!SSL_set_app_data(conn->xprt_ctx, conn)) {
2654 SSL_free(conn->xprt_ctx);
2655 conn->xprt_ctx = NULL;
Willy Tarreaufba03cd2014-11-13 13:48:58 +01002656 if (may_retry--) {
2657 pool_gc2();
2658 goto retry_accept;
2659 }
Emeric Brun55476152014-11-12 17:35:37 +01002660 conn->err_code = CO_ER_SSL_NO_MEM;
2661 return -1;
2662 }
2663
2664 SSL_set_accept_state(conn->xprt_ctx);
Emeric Brune1f38db2012-09-03 20:36:47 +02002665
Emeric Brun46591952012-05-18 15:47:34 +02002666 /* leave init state and start handshake */
Willy Tarreau05737472012-09-04 08:03:39 +02002667 conn->flags |= CO_FL_SSL_WAIT_HS | CO_FL_WAIT_L6_CONN;
Willy Tarreau403edff2012-09-06 11:58:37 +02002668
2669 sslconns++;
Willy Tarreau71b734c2014-01-28 15:19:44 +01002670 totalsslconns++;
Emeric Brun46591952012-05-18 15:47:34 +02002671 return 0;
2672 }
2673 /* don't know how to handle such a target */
Willy Tarreau20879a02012-12-03 16:32:10 +01002674 conn->err_code = CO_ER_SSL_NO_TARGET;
Emeric Brun46591952012-05-18 15:47:34 +02002675 return -1;
2676}
2677
2678
2679/* This is the callback which is used when an SSL handshake is pending. It
2680 * updates the FD status if it wants some polling before being called again.
2681 * It returns 0 if it fails in a fatal way or needs to poll to go further,
2682 * otherwise it returns non-zero and removes itself from the connection's
2683 * flags (the bit is provided in <flag> by the caller).
2684 */
2685int ssl_sock_handshake(struct connection *conn, unsigned int flag)
2686{
2687 int ret;
2688
Willy Tarreau3c728722014-01-23 13:50:42 +01002689 if (!conn_ctrl_ready(conn))
Willy Tarreauf79c8172013-10-21 16:30:56 +02002690 return 0;
2691
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02002692 if (!conn->xprt_ctx)
Emeric Brun46591952012-05-18 15:47:34 +02002693 goto out_error;
2694
Emeric Brun674b7432012-11-08 19:21:55 +01002695 /* If we use SSL_do_handshake to process a reneg initiated by
2696 * the remote peer, it sometimes returns SSL_ERROR_SSL.
2697 * Usually SSL_write and SSL_read are used and process implicitly
2698 * the reneg handshake.
2699 * Here we use SSL_peek as a workaround for reneg.
2700 */
2701 if ((conn->flags & CO_FL_CONNECTED) && SSL_renegotiate_pending(conn->xprt_ctx)) {
2702 char c;
2703
2704 ret = SSL_peek(conn->xprt_ctx, &c, 1);
2705 if (ret <= 0) {
2706 /* handshake may have not been completed, let's find why */
2707 ret = SSL_get_error(conn->xprt_ctx, ret);
2708 if (ret == SSL_ERROR_WANT_WRITE) {
2709 /* SSL handshake needs to write, L4 connection may not be ready */
2710 __conn_sock_stop_recv(conn);
Willy Tarreaue1f50c42014-01-22 20:02:06 +01002711 __conn_sock_want_send(conn);
2712 fd_cant_send(conn->t.sock.fd);
Emeric Brun674b7432012-11-08 19:21:55 +01002713 return 0;
2714 }
2715 else if (ret == SSL_ERROR_WANT_READ) {
2716 /* handshake may have been completed but we have
2717 * no more data to read.
2718 */
2719 if (!SSL_renegotiate_pending(conn->xprt_ctx)) {
2720 ret = 1;
2721 goto reneg_ok;
2722 }
2723 /* SSL handshake needs to read, L4 connection is ready */
2724 if (conn->flags & CO_FL_WAIT_L4_CONN)
2725 conn->flags &= ~CO_FL_WAIT_L4_CONN;
2726 __conn_sock_stop_send(conn);
Willy Tarreaue1f50c42014-01-22 20:02:06 +01002727 __conn_sock_want_recv(conn);
2728 fd_cant_recv(conn->t.sock.fd);
Emeric Brun674b7432012-11-08 19:21:55 +01002729 return 0;
2730 }
2731 else if (ret == SSL_ERROR_SYSCALL) {
2732 /* if errno is null, then connection was successfully established */
2733 if (!errno && conn->flags & CO_FL_WAIT_L4_CONN)
2734 conn->flags &= ~CO_FL_WAIT_L4_CONN;
Willy Tarreau20879a02012-12-03 16:32:10 +01002735 if (!conn->err_code) {
Emeric Brun29f037d2014-04-25 19:05:36 +02002736 if (!((SSL *)conn->xprt_ctx)->packet_length) {
2737 if (!errno) {
2738 if (conn->xprt_st & SSL_SOCK_RECV_HEARTBEAT)
2739 conn->err_code = CO_ER_SSL_HANDSHAKE_HB;
2740 else
2741 conn->err_code = CO_ER_SSL_EMPTY;
2742 }
2743 else {
2744 if (conn->xprt_st & SSL_SOCK_RECV_HEARTBEAT)
2745 conn->err_code = CO_ER_SSL_HANDSHAKE_HB;
2746 else
2747 conn->err_code = CO_ER_SSL_ABORT;
2748 }
2749 }
2750 else {
2751 if (conn->xprt_st & SSL_SOCK_RECV_HEARTBEAT)
2752 conn->err_code = CO_ER_SSL_HANDSHAKE_HB;
Willy Tarreau20879a02012-12-03 16:32:10 +01002753 else
Emeric Brun29f037d2014-04-25 19:05:36 +02002754 conn->err_code = CO_ER_SSL_HANDSHAKE;
2755 }
Willy Tarreau20879a02012-12-03 16:32:10 +01002756 }
Emeric Brun674b7432012-11-08 19:21:55 +01002757 goto out_error;
2758 }
2759 else {
2760 /* Fail on all other handshake errors */
2761 /* Note: OpenSSL may leave unread bytes in the socket's
2762 * buffer, causing an RST to be emitted upon close() on
2763 * TCP sockets. We first try to drain possibly pending
2764 * data to avoid this as much as possible.
2765 */
Willy Tarreaud85c4852015-03-13 00:40:28 +01002766 conn_sock_drain(conn);
Willy Tarreau20879a02012-12-03 16:32:10 +01002767 if (!conn->err_code)
Willy Tarreauf51c6982014-04-25 20:02:39 +02002768 conn->err_code = (conn->xprt_st & SSL_SOCK_RECV_HEARTBEAT) ?
2769 CO_ER_SSL_KILLED_HB : CO_ER_SSL_HANDSHAKE;
Emeric Brun674b7432012-11-08 19:21:55 +01002770 goto out_error;
2771 }
2772 }
2773 /* read some data: consider handshake completed */
2774 goto reneg_ok;
2775 }
2776
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02002777 ret = SSL_do_handshake(conn->xprt_ctx);
Emeric Brun46591952012-05-18 15:47:34 +02002778 if (ret != 1) {
2779 /* handshake did not complete, let's find why */
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02002780 ret = SSL_get_error(conn->xprt_ctx, ret);
Emeric Brun46591952012-05-18 15:47:34 +02002781
2782 if (ret == SSL_ERROR_WANT_WRITE) {
2783 /* SSL handshake needs to write, L4 connection may not be ready */
2784 __conn_sock_stop_recv(conn);
Willy Tarreaue1f50c42014-01-22 20:02:06 +01002785 __conn_sock_want_send(conn);
2786 fd_cant_send(conn->t.sock.fd);
Emeric Brun46591952012-05-18 15:47:34 +02002787 return 0;
2788 }
2789 else if (ret == SSL_ERROR_WANT_READ) {
2790 /* SSL handshake needs to read, L4 connection is ready */
2791 if (conn->flags & CO_FL_WAIT_L4_CONN)
2792 conn->flags &= ~CO_FL_WAIT_L4_CONN;
2793 __conn_sock_stop_send(conn);
Willy Tarreaue1f50c42014-01-22 20:02:06 +01002794 __conn_sock_want_recv(conn);
2795 fd_cant_recv(conn->t.sock.fd);
Emeric Brun46591952012-05-18 15:47:34 +02002796 return 0;
2797 }
Willy Tarreau89230192012-09-28 20:22:13 +02002798 else if (ret == SSL_ERROR_SYSCALL) {
2799 /* if errno is null, then connection was successfully established */
2800 if (!errno && conn->flags & CO_FL_WAIT_L4_CONN)
2801 conn->flags &= ~CO_FL_WAIT_L4_CONN;
Willy Tarreau20879a02012-12-03 16:32:10 +01002802
Emeric Brun29f037d2014-04-25 19:05:36 +02002803 if (!((SSL *)conn->xprt_ctx)->packet_length) {
2804 if (!errno) {
2805 if (conn->xprt_st & SSL_SOCK_RECV_HEARTBEAT)
2806 conn->err_code = CO_ER_SSL_HANDSHAKE_HB;
2807 else
2808 conn->err_code = CO_ER_SSL_EMPTY;
2809 }
2810 else {
2811 if (conn->xprt_st & SSL_SOCK_RECV_HEARTBEAT)
2812 conn->err_code = CO_ER_SSL_HANDSHAKE_HB;
2813 else
2814 conn->err_code = CO_ER_SSL_ABORT;
2815 }
2816 }
2817 else {
2818 if (conn->xprt_st & SSL_SOCK_RECV_HEARTBEAT)
2819 conn->err_code = CO_ER_SSL_HANDSHAKE_HB;
Willy Tarreau20879a02012-12-03 16:32:10 +01002820 else
Emeric Brun29f037d2014-04-25 19:05:36 +02002821 conn->err_code = CO_ER_SSL_HANDSHAKE;
2822 }
Willy Tarreau89230192012-09-28 20:22:13 +02002823 goto out_error;
2824 }
Emeric Brun46591952012-05-18 15:47:34 +02002825 else {
2826 /* Fail on all other handshake errors */
Willy Tarreau566dc552012-10-19 20:52:18 +02002827 /* Note: OpenSSL may leave unread bytes in the socket's
2828 * buffer, causing an RST to be emitted upon close() on
2829 * TCP sockets. We first try to drain possibly pending
2830 * data to avoid this as much as possible.
2831 */
Willy Tarreaud85c4852015-03-13 00:40:28 +01002832 conn_sock_drain(conn);
Willy Tarreau20879a02012-12-03 16:32:10 +01002833 if (!conn->err_code)
Willy Tarreauf51c6982014-04-25 20:02:39 +02002834 conn->err_code = (conn->xprt_st & SSL_SOCK_RECV_HEARTBEAT) ?
2835 CO_ER_SSL_KILLED_HB : CO_ER_SSL_HANDSHAKE;
Emeric Brun46591952012-05-18 15:47:34 +02002836 goto out_error;
2837 }
2838 }
2839
Emeric Brun674b7432012-11-08 19:21:55 +01002840reneg_ok:
2841
Emeric Brun46591952012-05-18 15:47:34 +02002842 /* Handshake succeeded */
Willy Tarreau0c9c2722014-05-28 12:28:58 +02002843 if (!SSL_session_reused(conn->xprt_ctx)) {
2844 if (objt_server(conn->target)) {
2845 update_freq_ctr(&global.ssl_be_keys_per_sec, 1);
2846 if (global.ssl_be_keys_per_sec.curr_ctr > global.ssl_be_keys_max)
2847 global.ssl_be_keys_max = global.ssl_be_keys_per_sec.curr_ctr;
2848
Emeric Brun46591952012-05-18 15:47:34 +02002849 /* check if session was reused, if not store current session on server for reuse */
Willy Tarreau3fdb3662012-11-12 00:42:33 +01002850 if (objt_server(conn->target)->ssl_ctx.reused_sess)
2851 SSL_SESSION_free(objt_server(conn->target)->ssl_ctx.reused_sess);
Emeric Brun46591952012-05-18 15:47:34 +02002852
Willy Tarreau2a3fb1c2015-02-05 16:47:07 +01002853 if (!(objt_server(conn->target)->ssl_ctx.options & SRV_SSL_O_NO_REUSE))
2854 objt_server(conn->target)->ssl_ctx.reused_sess = SSL_get1_session(conn->xprt_ctx);
Emeric Brun46591952012-05-18 15:47:34 +02002855 }
Willy Tarreau0c9c2722014-05-28 12:28:58 +02002856 else {
2857 update_freq_ctr(&global.ssl_fe_keys_per_sec, 1);
2858 if (global.ssl_fe_keys_per_sec.curr_ctr > global.ssl_fe_keys_max)
2859 global.ssl_fe_keys_max = global.ssl_fe_keys_per_sec.curr_ctr;
2860 }
Emeric Brun46591952012-05-18 15:47:34 +02002861 }
2862
2863 /* The connection is now established at both layers, it's time to leave */
2864 conn->flags &= ~(flag | CO_FL_WAIT_L4_CONN | CO_FL_WAIT_L6_CONN);
2865 return 1;
2866
2867 out_error:
Emeric Brun644cde02012-12-14 11:21:13 +01002868 /* Clear openssl global errors stack */
2869 ERR_clear_error();
2870
Emeric Brun9fa89732012-10-04 17:09:56 +02002871 /* free resumed session if exists */
Willy Tarreau3fdb3662012-11-12 00:42:33 +01002872 if (objt_server(conn->target) && objt_server(conn->target)->ssl_ctx.reused_sess) {
2873 SSL_SESSION_free(objt_server(conn->target)->ssl_ctx.reused_sess);
2874 objt_server(conn->target)->ssl_ctx.reused_sess = NULL;
Emeric Brun9fa89732012-10-04 17:09:56 +02002875 }
2876
Emeric Brun46591952012-05-18 15:47:34 +02002877 /* Fail on all other handshake errors */
2878 conn->flags |= CO_FL_ERROR;
Willy Tarreau20879a02012-12-03 16:32:10 +01002879 if (!conn->err_code)
2880 conn->err_code = CO_ER_SSL_HANDSHAKE;
Emeric Brun46591952012-05-18 15:47:34 +02002881 return 0;
2882}
2883
2884/* Receive up to <count> bytes from connection <conn>'s socket and store them
Willy Tarreauabf08d92014-01-14 11:31:27 +01002885 * into buffer <buf>. Only one call to recv() is performed, unless the
Emeric Brun46591952012-05-18 15:47:34 +02002886 * buffer wraps, in which case a second call may be performed. The connection's
2887 * flags are updated with whatever special event is detected (error, read0,
2888 * empty). The caller is responsible for taking care of those events and
2889 * avoiding the call if inappropriate. The function does not call the
2890 * connection's polling update function, so the caller is responsible for this.
2891 */
2892static int ssl_sock_to_buf(struct connection *conn, struct buffer *buf, int count)
2893{
2894 int ret, done = 0;
Willy Tarreauabf08d92014-01-14 11:31:27 +01002895 int try;
Emeric Brun46591952012-05-18 15:47:34 +02002896
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02002897 if (!conn->xprt_ctx)
Emeric Brun46591952012-05-18 15:47:34 +02002898 goto out_error;
2899
2900 if (conn->flags & CO_FL_HANDSHAKE)
2901 /* a handshake was requested */
2902 return 0;
2903
Willy Tarreauabf08d92014-01-14 11:31:27 +01002904 /* let's realign the buffer to optimize I/O */
2905 if (buffer_empty(buf))
Emeric Brun46591952012-05-18 15:47:34 +02002906 buf->p = buf->data;
Emeric Brun46591952012-05-18 15:47:34 +02002907
2908 /* read the largest possible block. For this, we perform only one call
2909 * to recv() unless the buffer wraps and we exactly fill the first hunk,
2910 * in which case we accept to do it once again. A new attempt is made on
2911 * EINTR too.
2912 */
Willy Tarreau00b0fb92014-01-17 11:09:40 +01002913 while (count > 0) {
Willy Tarreauabf08d92014-01-14 11:31:27 +01002914 /* first check if we have some room after p+i */
2915 try = buf->data + buf->size - (buf->p + buf->i);
2916 /* otherwise continue between data and p-o */
2917 if (try <= 0) {
2918 try = buf->p - (buf->data + buf->o);
2919 if (try <= 0)
2920 break;
2921 }
2922 if (try > count)
2923 try = count;
2924
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02002925 ret = SSL_read(conn->xprt_ctx, bi_end(buf), try);
Emeric Brune1f38db2012-09-03 20:36:47 +02002926 if (conn->flags & CO_FL_ERROR) {
2927 /* CO_FL_ERROR may be set by ssl_sock_infocbk */
Emeric Brun644cde02012-12-14 11:21:13 +01002928 goto out_error;
Emeric Brune1f38db2012-09-03 20:36:47 +02002929 }
Emeric Brun46591952012-05-18 15:47:34 +02002930 if (ret > 0) {
2931 buf->i += ret;
2932 done += ret;
2933 if (ret < try)
2934 break;
2935 count -= ret;
Emeric Brun46591952012-05-18 15:47:34 +02002936 }
2937 else if (ret == 0) {
Emeric Brun644cde02012-12-14 11:21:13 +01002938 ret = SSL_get_error(conn->xprt_ctx, ret);
2939 if (ret != SSL_ERROR_ZERO_RETURN) {
Emeric Brun1c646862012-12-14 12:33:41 +01002940 /* error on protocol or underlying transport */
2941 if ((ret != SSL_ERROR_SYSCALL)
2942 || (errno && (errno != EAGAIN)))
2943 conn->flags |= CO_FL_ERROR;
2944
Emeric Brun644cde02012-12-14 11:21:13 +01002945 /* Clear openssl global errors stack */
2946 ERR_clear_error();
2947 }
Emeric Brun46591952012-05-18 15:47:34 +02002948 goto read0;
2949 }
2950 else {
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02002951 ret = SSL_get_error(conn->xprt_ctx, ret);
Emeric Brun46591952012-05-18 15:47:34 +02002952 if (ret == SSL_ERROR_WANT_WRITE) {
Emeric Brun8af8dd12012-11-08 17:56:20 +01002953 /* handshake is running, and it needs to enable write */
Emeric Brun46591952012-05-18 15:47:34 +02002954 conn->flags |= CO_FL_SSL_WAIT_HS;
Emeric Brun8af8dd12012-11-08 17:56:20 +01002955 __conn_sock_want_send(conn);
Emeric Brun46591952012-05-18 15:47:34 +02002956 break;
2957 }
2958 else if (ret == SSL_ERROR_WANT_READ) {
Emeric Brun282a76a2012-11-08 18:02:56 +01002959 if (SSL_renegotiate_pending(conn->xprt_ctx)) {
2960 /* handshake is running, and it may need to re-enable read */
2961 conn->flags |= CO_FL_SSL_WAIT_HS;
2962 __conn_sock_want_recv(conn);
2963 break;
2964 }
Emeric Brun46591952012-05-18 15:47:34 +02002965 /* we need to poll for retry a read later */
Willy Tarreaue1f50c42014-01-22 20:02:06 +01002966 fd_cant_recv(conn->t.sock.fd);
Emeric Brun46591952012-05-18 15:47:34 +02002967 break;
2968 }
2969 /* otherwise it's a real error */
2970 goto out_error;
2971 }
2972 }
2973 return done;
2974
2975 read0:
2976 conn_sock_read0(conn);
2977 return done;
2978 out_error:
Emeric Brun644cde02012-12-14 11:21:13 +01002979 /* Clear openssl global errors stack */
2980 ERR_clear_error();
2981
Emeric Brun46591952012-05-18 15:47:34 +02002982 conn->flags |= CO_FL_ERROR;
2983 return done;
2984}
2985
2986
2987/* Send all pending bytes from buffer <buf> to connection <conn>'s socket.
Willy Tarreau1049b1f2014-02-02 01:51:17 +01002988 * <flags> may contain some CO_SFL_* flags to hint the system about other
2989 * pending data for example, but this flag is ignored at the moment.
Emeric Brun46591952012-05-18 15:47:34 +02002990 * Only one call to send() is performed, unless the buffer wraps, in which case
2991 * a second call may be performed. The connection's flags are updated with
2992 * whatever special event is detected (error, empty). The caller is responsible
2993 * for taking care of those events and avoiding the call if inappropriate. The
2994 * function does not call the connection's polling update function, so the caller
2995 * is responsible for this.
2996 */
2997static int ssl_sock_from_buf(struct connection *conn, struct buffer *buf, int flags)
2998{
2999 int ret, try, done;
3000
3001 done = 0;
3002
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02003003 if (!conn->xprt_ctx)
Emeric Brun46591952012-05-18 15:47:34 +02003004 goto out_error;
3005
3006 if (conn->flags & CO_FL_HANDSHAKE)
3007 /* a handshake was requested */
3008 return 0;
3009
3010 /* send the largest possible block. For this we perform only one call
3011 * to send() unless the buffer wraps and we exactly fill the first hunk,
3012 * in which case we accept to do it once again.
3013 */
3014 while (buf->o) {
Kevin Hestercad82342013-05-30 15:12:41 -07003015 try = bo_contig_data(buf);
Willy Tarreaubfd59462013-02-21 07:46:09 +01003016
Willy Tarreau7bed9452014-02-02 02:00:24 +01003017 if (!(flags & CO_SFL_STREAMER) &&
Willy Tarreau518cedd2014-02-17 15:43:01 +01003018 !(conn->xprt_st & SSL_SOCK_SEND_UNLIMITED) &&
3019 global.tune.ssl_max_record && try > global.tune.ssl_max_record) {
Willy Tarreaubfd59462013-02-21 07:46:09 +01003020 try = global.tune.ssl_max_record;
Willy Tarreau518cedd2014-02-17 15:43:01 +01003021 }
3022 else {
3023 /* we need to keep the information about the fact that
3024 * we're not limiting the upcoming send(), because if it
3025 * fails, we'll have to retry with at least as many data.
3026 */
3027 conn->xprt_st |= SSL_SOCK_SEND_UNLIMITED;
3028 }
Willy Tarreaubfd59462013-02-21 07:46:09 +01003029
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02003030 ret = SSL_write(conn->xprt_ctx, bo_ptr(buf), try);
Willy Tarreau518cedd2014-02-17 15:43:01 +01003031
Emeric Brune1f38db2012-09-03 20:36:47 +02003032 if (conn->flags & CO_FL_ERROR) {
3033 /* CO_FL_ERROR may be set by ssl_sock_infocbk */
Emeric Brun644cde02012-12-14 11:21:13 +01003034 goto out_error;
Emeric Brune1f38db2012-09-03 20:36:47 +02003035 }
Emeric Brun46591952012-05-18 15:47:34 +02003036 if (ret > 0) {
Willy Tarreau518cedd2014-02-17 15:43:01 +01003037 conn->xprt_st &= ~SSL_SOCK_SEND_UNLIMITED;
3038
Emeric Brun46591952012-05-18 15:47:34 +02003039 buf->o -= ret;
3040 done += ret;
3041
Willy Tarreau5fb38032012-12-16 19:39:09 +01003042 if (likely(buffer_empty(buf)))
Emeric Brun46591952012-05-18 15:47:34 +02003043 /* optimize data alignment in the buffer */
3044 buf->p = buf->data;
3045
3046 /* if the system buffer is full, don't insist */
3047 if (ret < try)
3048 break;
3049 }
3050 else {
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02003051 ret = SSL_get_error(conn->xprt_ctx, ret);
Emeric Brun46591952012-05-18 15:47:34 +02003052 if (ret == SSL_ERROR_WANT_WRITE) {
Emeric Brun282a76a2012-11-08 18:02:56 +01003053 if (SSL_renegotiate_pending(conn->xprt_ctx)) {
3054 /* handshake is running, and it may need to re-enable write */
3055 conn->flags |= CO_FL_SSL_WAIT_HS;
3056 __conn_sock_want_send(conn);
3057 break;
3058 }
Emeric Brun46591952012-05-18 15:47:34 +02003059 /* we need to poll to retry a write later */
Willy Tarreaue1f50c42014-01-22 20:02:06 +01003060 fd_cant_send(conn->t.sock.fd);
Emeric Brun46591952012-05-18 15:47:34 +02003061 break;
3062 }
3063 else if (ret == SSL_ERROR_WANT_READ) {
Emeric Brun8af8dd12012-11-08 17:56:20 +01003064 /* handshake is running, and it needs to enable read */
Emeric Brun46591952012-05-18 15:47:34 +02003065 conn->flags |= CO_FL_SSL_WAIT_HS;
Emeric Brun8af8dd12012-11-08 17:56:20 +01003066 __conn_sock_want_recv(conn);
Emeric Brun46591952012-05-18 15:47:34 +02003067 break;
3068 }
3069 goto out_error;
3070 }
3071 }
3072 return done;
3073
3074 out_error:
Emeric Brun644cde02012-12-14 11:21:13 +01003075 /* Clear openssl global errors stack */
3076 ERR_clear_error();
3077
Emeric Brun46591952012-05-18 15:47:34 +02003078 conn->flags |= CO_FL_ERROR;
3079 return done;
3080}
3081
Emeric Brun46591952012-05-18 15:47:34 +02003082static void ssl_sock_close(struct connection *conn) {
3083
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02003084 if (conn->xprt_ctx) {
3085 SSL_free(conn->xprt_ctx);
3086 conn->xprt_ctx = NULL;
Willy Tarreau403edff2012-09-06 11:58:37 +02003087 sslconns--;
Emeric Brun46591952012-05-18 15:47:34 +02003088 }
Emeric Brun46591952012-05-18 15:47:34 +02003089}
3090
3091/* This function tries to perform a clean shutdown on an SSL connection, and in
3092 * any case, flags the connection as reusable if no handshake was in progress.
3093 */
3094static void ssl_sock_shutw(struct connection *conn, int clean)
3095{
3096 if (conn->flags & CO_FL_HANDSHAKE)
3097 return;
3098 /* no handshake was in progress, try a clean ssl shutdown */
Emeric Brun644cde02012-12-14 11:21:13 +01003099 if (clean && (SSL_shutdown(conn->xprt_ctx) <= 0)) {
3100 /* Clear openssl global errors stack */
3101 ERR_clear_error();
3102 }
Emeric Brun46591952012-05-18 15:47:34 +02003103
3104 /* force flag on ssl to keep session in cache regardless shutdown result */
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02003105 SSL_set_shutdown(conn->xprt_ctx, SSL_SENT_SHUTDOWN);
Emeric Brun46591952012-05-18 15:47:34 +02003106}
3107
Willy Tarreauffc3fcd2012-10-12 20:17:54 +02003108/* used for logging, may be changed for a sample fetch later */
3109const char *ssl_sock_get_cipher_name(struct connection *conn)
3110{
3111 if (!conn->xprt && !conn->xprt_ctx)
3112 return NULL;
3113 return SSL_get_cipher_name(conn->xprt_ctx);
3114}
3115
3116/* used for logging, may be changed for a sample fetch later */
3117const char *ssl_sock_get_proto_version(struct connection *conn)
3118{
3119 if (!conn->xprt && !conn->xprt_ctx)
3120 return NULL;
3121 return SSL_get_version(conn->xprt_ctx);
3122}
3123
Willy Tarreau8d598402012-10-22 17:58:39 +02003124/* Extract a serial from a cert, and copy it to a chunk.
3125 * Returns 1 if serial is found and copied, 0 if no serial found and
3126 * -1 if output is not large enough.
3127 */
3128static int
3129ssl_sock_get_serial(X509 *crt, struct chunk *out)
3130{
3131 ASN1_INTEGER *serial;
3132
3133 serial = X509_get_serialNumber(crt);
3134 if (!serial)
3135 return 0;
3136
3137 if (out->size < serial->length)
3138 return -1;
3139
3140 memcpy(out->str, serial->data, serial->length);
3141 out->len = serial->length;
3142 return 1;
3143}
3144
Emeric Brun43e79582014-10-29 19:03:26 +01003145/* Extract a cert to der, and copy it to a chunk.
3146 * Returns 1 if cert is found and copied, 0 on der convertion failure and
3147 * -1 if output is not large enough.
3148 */
3149static int
3150ssl_sock_crt2der(X509 *crt, struct chunk *out)
3151{
3152 int len;
3153 unsigned char *p = (unsigned char *)out->str;;
3154
3155 len =i2d_X509(crt, NULL);
3156 if (len <= 0)
3157 return 1;
3158
3159 if (out->size < len)
3160 return -1;
3161
3162 i2d_X509(crt,&p);
3163 out->len = len;
3164 return 1;
3165}
3166
Emeric Brunce5ad802012-10-22 14:11:22 +02003167
3168/* Copy Date in ASN1_UTCTIME format in struct chunk out.
3169 * Returns 1 if serial is found and copied, 0 if no valid time found
3170 * and -1 if output is not large enough.
3171 */
3172static int
3173ssl_sock_get_time(ASN1_TIME *tm, struct chunk *out)
3174{
3175 if (tm->type == V_ASN1_GENERALIZEDTIME) {
3176 ASN1_GENERALIZEDTIME *gentm = (ASN1_GENERALIZEDTIME *)tm;
3177
3178 if (gentm->length < 12)
3179 return 0;
3180 if (gentm->data[0] != 0x32 || gentm->data[1] != 0x30)
3181 return 0;
3182 if (out->size < gentm->length-2)
3183 return -1;
3184
3185 memcpy(out->str, gentm->data+2, gentm->length-2);
3186 out->len = gentm->length-2;
3187 return 1;
3188 }
3189 else if (tm->type == V_ASN1_UTCTIME) {
3190 ASN1_UTCTIME *utctm = (ASN1_UTCTIME *)tm;
3191
3192 if (utctm->length < 10)
3193 return 0;
3194 if (utctm->data[0] >= 0x35)
3195 return 0;
3196 if (out->size < utctm->length)
3197 return -1;
3198
3199 memcpy(out->str, utctm->data, utctm->length);
3200 out->len = utctm->length;
3201 return 1;
3202 }
3203
3204 return 0;
3205}
3206
Emeric Brun87855892012-10-17 17:39:35 +02003207/* Extract an entry from a X509_NAME and copy its value to an output chunk.
3208 * Returns 1 if entry found, 0 if entry not found, or -1 if output not large enough.
3209 */
3210static int
3211ssl_sock_get_dn_entry(X509_NAME *a, const struct chunk *entry, int pos, struct chunk *out)
3212{
3213 X509_NAME_ENTRY *ne;
3214 int i, j, n;
3215 int cur = 0;
3216 const char *s;
3217 char tmp[128];
3218
3219 out->len = 0;
3220 for (i = 0; i < sk_X509_NAME_ENTRY_num(a->entries); i++) {
3221 if (pos < 0)
3222 j = (sk_X509_NAME_ENTRY_num(a->entries)-1) - i;
3223 else
3224 j = i;
3225
3226 ne = sk_X509_NAME_ENTRY_value(a->entries, j);
3227 n = OBJ_obj2nid(ne->object);
3228 if ((n == NID_undef) || ((s = OBJ_nid2sn(n)) == NULL)) {
3229 i2t_ASN1_OBJECT(tmp, sizeof(tmp), ne->object);
3230 s = tmp;
3231 }
3232
3233 if (chunk_strcasecmp(entry, s) != 0)
3234 continue;
3235
3236 if (pos < 0)
3237 cur--;
3238 else
3239 cur++;
3240
3241 if (cur != pos)
3242 continue;
3243
3244 if (ne->value->length > out->size)
3245 return -1;
3246
3247 memcpy(out->str, ne->value->data, ne->value->length);
3248 out->len = ne->value->length;
3249 return 1;
3250 }
3251
3252 return 0;
3253
3254}
3255
3256/* Extract and format full DN from a X509_NAME and copy result into a chunk
3257 * Returns 1 if dn entries exits, 0 if no dn entry found or -1 if output is not large enough.
3258 */
3259static int
3260ssl_sock_get_dn_oneline(X509_NAME *a, struct chunk *out)
3261{
3262 X509_NAME_ENTRY *ne;
3263 int i, n, ln;
3264 int l = 0;
3265 const char *s;
3266 char *p;
3267 char tmp[128];
3268
3269 out->len = 0;
3270 p = out->str;
3271 for (i = 0; i < sk_X509_NAME_ENTRY_num(a->entries); i++) {
3272 ne = sk_X509_NAME_ENTRY_value(a->entries, i);
3273 n = OBJ_obj2nid(ne->object);
3274 if ((n == NID_undef) || ((s = OBJ_nid2sn(n)) == NULL)) {
3275 i2t_ASN1_OBJECT(tmp, sizeof(tmp), ne->object);
3276 s = tmp;
3277 }
3278 ln = strlen(s);
3279
3280 l += 1 + ln + 1 + ne->value->length;
3281 if (l > out->size)
3282 return -1;
3283 out->len = l;
3284
3285 *(p++)='/';
3286 memcpy(p, s, ln);
3287 p += ln;
3288 *(p++)='=';
3289 memcpy(p, ne->value->data, ne->value->length);
3290 p += ne->value->length;
3291 }
3292
3293 if (!out->len)
3294 return 0;
3295
3296 return 1;
3297}
3298
David Safb76832014-05-08 23:42:08 -04003299char *ssl_sock_get_version(struct connection *conn)
3300{
3301 if (!ssl_sock_is_ssl(conn))
3302 return NULL;
3303
3304 return (char *)SSL_get_version(conn->xprt_ctx);
3305}
3306
Willy Tarreau63076412015-07-10 11:33:32 +02003307void ssl_sock_set_servername(struct connection *conn, const char *hostname)
3308{
3309#ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME
3310 if (!ssl_sock_is_ssl(conn))
3311 return;
3312
3313 SSL_set_tlsext_host_name(conn->xprt_ctx, hostname);
3314#endif
3315}
3316
Emeric Brun0abf8362014-06-24 18:26:41 +02003317/* Extract peer certificate's common name into the chunk dest
3318 * Returns
3319 * the len of the extracted common name
3320 * or 0 if no CN found in DN
3321 * or -1 on error case (i.e. no peer certificate)
3322 */
3323int ssl_sock_get_remote_common_name(struct connection *conn, struct chunk *dest)
David Safb76832014-05-08 23:42:08 -04003324{
3325 X509 *crt = NULL;
3326 X509_NAME *name;
David Safb76832014-05-08 23:42:08 -04003327 const char find_cn[] = "CN";
3328 const struct chunk find_cn_chunk = {
3329 .str = (char *)&find_cn,
3330 .len = sizeof(find_cn)-1
3331 };
Emeric Brun0abf8362014-06-24 18:26:41 +02003332 int result = -1;
David Safb76832014-05-08 23:42:08 -04003333
3334 if (!ssl_sock_is_ssl(conn))
Emeric Brun0abf8362014-06-24 18:26:41 +02003335 goto out;
David Safb76832014-05-08 23:42:08 -04003336
3337 /* SSL_get_peer_certificate, it increase X509 * ref count */
3338 crt = SSL_get_peer_certificate(conn->xprt_ctx);
3339 if (!crt)
3340 goto out;
3341
3342 name = X509_get_subject_name(crt);
3343 if (!name)
3344 goto out;
David Safb76832014-05-08 23:42:08 -04003345
Emeric Brun0abf8362014-06-24 18:26:41 +02003346 result = ssl_sock_get_dn_entry(name, &find_cn_chunk, 1, dest);
3347out:
David Safb76832014-05-08 23:42:08 -04003348 if (crt)
3349 X509_free(crt);
3350
3351 return result;
3352}
3353
Dave McCowan328fb582014-07-30 10:39:13 -04003354/* returns 1 if client passed a certificate for this session, 0 if not */
3355int ssl_sock_get_cert_used_sess(struct connection *conn)
3356{
3357 X509 *crt = NULL;
3358
3359 if (!ssl_sock_is_ssl(conn))
3360 return 0;
3361
3362 /* SSL_get_peer_certificate, it increase X509 * ref count */
3363 crt = SSL_get_peer_certificate(conn->xprt_ctx);
3364 if (!crt)
3365 return 0;
3366
3367 X509_free(crt);
3368 return 1;
3369}
3370
3371/* returns 1 if client passed a certificate for this connection, 0 if not */
3372int ssl_sock_get_cert_used_conn(struct connection *conn)
David Safb76832014-05-08 23:42:08 -04003373{
3374 if (!ssl_sock_is_ssl(conn))
3375 return 0;
3376
3377 return SSL_SOCK_ST_FL_VERIFY_DONE & conn->xprt_st ? 1 : 0;
3378}
3379
3380/* returns result from SSL verify */
3381unsigned int ssl_sock_get_verify_result(struct connection *conn)
3382{
3383 if (!ssl_sock_is_ssl(conn))
3384 return (unsigned int)X509_V_ERR_APPLICATION_VERIFICATION;
3385
3386 return (unsigned int)SSL_get_verify_result(conn->xprt_ctx);
3387}
3388
Willy Tarreau7875d092012-09-10 08:20:03 +02003389/***** Below are some sample fetching functions for ACL/patterns *****/
3390
Emeric Brune64aef12012-09-21 13:15:06 +02003391/* boolean, returns true if client cert was present */
3392static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02003393smp_fetch_ssl_fc_has_crt(const struct arg *args, struct sample *smp, const char *kw, void *private)
Emeric Brune64aef12012-09-21 13:15:06 +02003394{
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003395 struct connection *conn;
3396
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02003397 conn = objt_conn(smp->sess->origin);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003398 if (!conn || conn->xprt != &ssl_sock)
Emeric Brune64aef12012-09-21 13:15:06 +02003399 return 0;
3400
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003401 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brune64aef12012-09-21 13:15:06 +02003402 smp->flags |= SMP_F_MAY_CHANGE;
3403 return 0;
3404 }
3405
3406 smp->flags = 0;
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02003407 smp->data.type = SMP_T_BOOL;
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02003408 smp->data.u.sint = SSL_SOCK_ST_FL_VERIFY_DONE & conn->xprt_st ? 1 : 0;
Emeric Brune64aef12012-09-21 13:15:06 +02003409
3410 return 1;
3411}
3412
Emeric Brun43e79582014-10-29 19:03:26 +01003413/* binary, returns a certificate in a binary chunk (der/raw).
3414 * The 5th keyword char is used to know if SSL_get_certificate or SSL_get_peer_certificate
3415 * should be use.
3416 */
3417static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02003418smp_fetch_ssl_x_der(const struct arg *args, struct sample *smp, const char *kw, void *private)
Emeric Brun43e79582014-10-29 19:03:26 +01003419{
3420 int cert_peer = (kw[4] == 'c') ? 1 : 0;
3421 X509 *crt = NULL;
3422 int ret = 0;
3423 struct chunk *smp_trash;
3424 struct connection *conn;
3425
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02003426 conn = objt_conn(smp->sess->origin);
Emeric Brun43e79582014-10-29 19:03:26 +01003427 if (!conn || conn->xprt != &ssl_sock)
3428 return 0;
3429
3430 if (!(conn->flags & CO_FL_CONNECTED)) {
3431 smp->flags |= SMP_F_MAY_CHANGE;
3432 return 0;
3433 }
3434
3435 if (cert_peer)
3436 crt = SSL_get_peer_certificate(conn->xprt_ctx);
3437 else
3438 crt = SSL_get_certificate(conn->xprt_ctx);
3439
3440 if (!crt)
3441 goto out;
3442
3443 smp_trash = get_trash_chunk();
3444 if (ssl_sock_crt2der(crt, smp_trash) <= 0)
3445 goto out;
3446
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02003447 smp->data.u.str = *smp_trash;
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02003448 smp->data.type = SMP_T_BIN;
Emeric Brun43e79582014-10-29 19:03:26 +01003449 ret = 1;
3450out:
3451 /* SSL_get_peer_certificate, it increase X509 * ref count */
3452 if (cert_peer && crt)
3453 X509_free(crt);
3454 return ret;
3455}
3456
Emeric Brunba841a12014-04-30 17:05:08 +02003457/* binary, returns serial of certificate in a binary chunk.
3458 * The 5th keyword char is used to know if SSL_get_certificate or SSL_get_peer_certificate
3459 * should be use.
3460 */
Willy Tarreau8d598402012-10-22 17:58:39 +02003461static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02003462smp_fetch_ssl_x_serial(const struct arg *args, struct sample *smp, const char *kw, void *private)
Willy Tarreau8d598402012-10-22 17:58:39 +02003463{
Emeric Brunba841a12014-04-30 17:05:08 +02003464 int cert_peer = (kw[4] == 'c') ? 1 : 0;
Willy Tarreau8d598402012-10-22 17:58:39 +02003465 X509 *crt = NULL;
3466 int ret = 0;
3467 struct chunk *smp_trash;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003468 struct connection *conn;
3469
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02003470 conn = objt_conn(smp->sess->origin);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003471 if (!conn || conn->xprt != &ssl_sock)
Willy Tarreau8d598402012-10-22 17:58:39 +02003472 return 0;
3473
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003474 if (!(conn->flags & CO_FL_CONNECTED)) {
Willy Tarreau8d598402012-10-22 17:58:39 +02003475 smp->flags |= SMP_F_MAY_CHANGE;
3476 return 0;
3477 }
3478
Emeric Brunba841a12014-04-30 17:05:08 +02003479 if (cert_peer)
3480 crt = SSL_get_peer_certificate(conn->xprt_ctx);
3481 else
3482 crt = SSL_get_certificate(conn->xprt_ctx);
3483
Willy Tarreau8d598402012-10-22 17:58:39 +02003484 if (!crt)
3485 goto out;
3486
Willy Tarreau47ca5452012-12-23 20:22:19 +01003487 smp_trash = get_trash_chunk();
Willy Tarreau8d598402012-10-22 17:58:39 +02003488 if (ssl_sock_get_serial(crt, smp_trash) <= 0)
3489 goto out;
3490
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02003491 smp->data.u.str = *smp_trash;
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02003492 smp->data.type = SMP_T_BIN;
Willy Tarreau8d598402012-10-22 17:58:39 +02003493 ret = 1;
3494out:
Emeric Brunba841a12014-04-30 17:05:08 +02003495 /* SSL_get_peer_certificate, it increase X509 * ref count */
3496 if (cert_peer && crt)
Willy Tarreau8d598402012-10-22 17:58:39 +02003497 X509_free(crt);
3498 return ret;
3499}
Emeric Brune64aef12012-09-21 13:15:06 +02003500
Emeric Brunba841a12014-04-30 17:05:08 +02003501/* binary, returns the client certificate's SHA-1 fingerprint (SHA-1 hash of DER-encoded certificate) in a binary chunk.
3502 * The 5th keyword char is used to know if SSL_get_certificate or SSL_get_peer_certificate
3503 * should be use.
3504 */
James Votha051b4a2013-05-14 20:37:59 +02003505static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02003506smp_fetch_ssl_x_sha1(const struct arg *args, struct sample *smp, const char *kw, void *private)
James Votha051b4a2013-05-14 20:37:59 +02003507{
Emeric Brunba841a12014-04-30 17:05:08 +02003508 int cert_peer = (kw[4] == 'c') ? 1 : 0;
James Votha051b4a2013-05-14 20:37:59 +02003509 X509 *crt = NULL;
3510 const EVP_MD *digest;
3511 int ret = 0;
3512 struct chunk *smp_trash;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003513 struct connection *conn;
James Votha051b4a2013-05-14 20:37:59 +02003514
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02003515 conn = objt_conn(smp->sess->origin);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003516 if (!conn || conn->xprt != &ssl_sock)
3517 return 0;
3518
3519 if (!(conn->flags & CO_FL_CONNECTED)) {
James Votha051b4a2013-05-14 20:37:59 +02003520 smp->flags |= SMP_F_MAY_CHANGE;
3521 return 0;
3522 }
3523
Emeric Brunba841a12014-04-30 17:05:08 +02003524 if (cert_peer)
3525 crt = SSL_get_peer_certificate(conn->xprt_ctx);
3526 else
3527 crt = SSL_get_certificate(conn->xprt_ctx);
James Votha051b4a2013-05-14 20:37:59 +02003528 if (!crt)
3529 goto out;
3530
3531 smp_trash = get_trash_chunk();
3532 digest = EVP_sha1();
3533 X509_digest(crt, digest, (unsigned char *)smp_trash->str, (unsigned int *)&smp_trash->len);
3534
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02003535 smp->data.u.str = *smp_trash;
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02003536 smp->data.type = SMP_T_BIN;
James Votha051b4a2013-05-14 20:37:59 +02003537 ret = 1;
3538out:
Emeric Brunba841a12014-04-30 17:05:08 +02003539 /* SSL_get_peer_certificate, it increase X509 * ref count */
3540 if (cert_peer && crt)
James Votha051b4a2013-05-14 20:37:59 +02003541 X509_free(crt);
3542 return ret;
3543}
3544
Emeric Brunba841a12014-04-30 17:05:08 +02003545/* string, returns certificate's notafter date in ASN1_UTCTIME format.
3546 * The 5th keyword char is used to know if SSL_get_certificate or SSL_get_peer_certificate
3547 * should be use.
3548 */
Emeric Brunce5ad802012-10-22 14:11:22 +02003549static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02003550smp_fetch_ssl_x_notafter(const struct arg *args, struct sample *smp, const char *kw, void *private)
Emeric Brunce5ad802012-10-22 14:11:22 +02003551{
Emeric Brunba841a12014-04-30 17:05:08 +02003552 int cert_peer = (kw[4] == 'c') ? 1 : 0;
Emeric Brunce5ad802012-10-22 14:11:22 +02003553 X509 *crt = NULL;
3554 int ret = 0;
3555 struct chunk *smp_trash;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003556 struct connection *conn;
Emeric Brunce5ad802012-10-22 14:11:22 +02003557
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02003558 conn = objt_conn(smp->sess->origin);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003559 if (!conn || conn->xprt != &ssl_sock)
3560 return 0;
3561
3562 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brunce5ad802012-10-22 14:11:22 +02003563 smp->flags |= SMP_F_MAY_CHANGE;
3564 return 0;
3565 }
3566
Emeric Brunba841a12014-04-30 17:05:08 +02003567 if (cert_peer)
3568 crt = SSL_get_peer_certificate(conn->xprt_ctx);
3569 else
3570 crt = SSL_get_certificate(conn->xprt_ctx);
Emeric Brunce5ad802012-10-22 14:11:22 +02003571 if (!crt)
3572 goto out;
3573
Willy Tarreau47ca5452012-12-23 20:22:19 +01003574 smp_trash = get_trash_chunk();
Emeric Brunce5ad802012-10-22 14:11:22 +02003575 if (ssl_sock_get_time(X509_get_notAfter(crt), smp_trash) <= 0)
3576 goto out;
3577
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02003578 smp->data.u.str = *smp_trash;
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02003579 smp->data.type = SMP_T_STR;
Emeric Brunce5ad802012-10-22 14:11:22 +02003580 ret = 1;
3581out:
Emeric Brunba841a12014-04-30 17:05:08 +02003582 /* SSL_get_peer_certificate, it increase X509 * ref count */
3583 if (cert_peer && crt)
Emeric Brunce5ad802012-10-22 14:11:22 +02003584 X509_free(crt);
3585 return ret;
3586}
3587
Emeric Brunba841a12014-04-30 17:05:08 +02003588/* string, returns a string of a formatted full dn \C=..\O=..\OU=.. \CN=.. of certificate's issuer
3589 * The 5th keyword char is used to know if SSL_get_certificate or SSL_get_peer_certificate
3590 * should be use.
3591 */
Emeric Brun87855892012-10-17 17:39:35 +02003592static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02003593smp_fetch_ssl_x_i_dn(const struct arg *args, struct sample *smp, const char *kw, void *private)
Emeric Brun87855892012-10-17 17:39:35 +02003594{
Emeric Brunba841a12014-04-30 17:05:08 +02003595 int cert_peer = (kw[4] == 'c') ? 1 : 0;
Emeric Brun87855892012-10-17 17:39:35 +02003596 X509 *crt = NULL;
3597 X509_NAME *name;
3598 int ret = 0;
3599 struct chunk *smp_trash;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003600 struct connection *conn;
Emeric Brun87855892012-10-17 17:39:35 +02003601
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02003602 conn = objt_conn(smp->sess->origin);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003603 if (!conn || conn->xprt != &ssl_sock)
3604 return 0;
3605
3606 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brun87855892012-10-17 17:39:35 +02003607 smp->flags |= SMP_F_MAY_CHANGE;
3608 return 0;
3609 }
3610
Emeric Brunba841a12014-04-30 17:05:08 +02003611 if (cert_peer)
3612 crt = SSL_get_peer_certificate(conn->xprt_ctx);
3613 else
3614 crt = SSL_get_certificate(conn->xprt_ctx);
Emeric Brun87855892012-10-17 17:39:35 +02003615 if (!crt)
3616 goto out;
3617
3618 name = X509_get_issuer_name(crt);
3619 if (!name)
3620 goto out;
3621
Willy Tarreau47ca5452012-12-23 20:22:19 +01003622 smp_trash = get_trash_chunk();
Emeric Brun87855892012-10-17 17:39:35 +02003623 if (args && args[0].type == ARGT_STR) {
3624 int pos = 1;
3625
3626 if (args[1].type == ARGT_SINT)
3627 pos = args[1].data.sint;
Emeric Brun87855892012-10-17 17:39:35 +02003628
3629 if (ssl_sock_get_dn_entry(name, &args[0].data.str, pos, smp_trash) <= 0)
3630 goto out;
3631 }
3632 else if (ssl_sock_get_dn_oneline(name, smp_trash) <= 0)
3633 goto out;
3634
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02003635 smp->data.type = SMP_T_STR;
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02003636 smp->data.u.str = *smp_trash;
Emeric Brun87855892012-10-17 17:39:35 +02003637 ret = 1;
3638out:
Emeric Brunba841a12014-04-30 17:05:08 +02003639 /* SSL_get_peer_certificate, it increase X509 * ref count */
3640 if (cert_peer && crt)
Emeric Brun87855892012-10-17 17:39:35 +02003641 X509_free(crt);
3642 return ret;
3643}
3644
Emeric Brunba841a12014-04-30 17:05:08 +02003645/* string, returns notbefore date in ASN1_UTCTIME format.
3646 * The 5th keyword char is used to know if SSL_get_certificate or SSL_get_peer_certificate
3647 * should be use.
3648 */
Emeric Brunce5ad802012-10-22 14:11:22 +02003649static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02003650smp_fetch_ssl_x_notbefore(const struct arg *args, struct sample *smp, const char *kw, void *private)
Emeric Brunce5ad802012-10-22 14:11:22 +02003651{
Emeric Brunba841a12014-04-30 17:05:08 +02003652 int cert_peer = (kw[4] == 'c') ? 1 : 0;
Emeric Brunce5ad802012-10-22 14:11:22 +02003653 X509 *crt = NULL;
3654 int ret = 0;
3655 struct chunk *smp_trash;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003656 struct connection *conn;
3657
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02003658 conn = objt_conn(smp->sess->origin);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003659 if (!conn || conn->xprt != &ssl_sock)
Emeric Brunce5ad802012-10-22 14:11:22 +02003660 return 0;
3661
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003662 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brunce5ad802012-10-22 14:11:22 +02003663 smp->flags |= SMP_F_MAY_CHANGE;
3664 return 0;
3665 }
3666
Emeric Brunba841a12014-04-30 17:05:08 +02003667 if (cert_peer)
3668 crt = SSL_get_peer_certificate(conn->xprt_ctx);
3669 else
3670 crt = SSL_get_certificate(conn->xprt_ctx);
Emeric Brunce5ad802012-10-22 14:11:22 +02003671 if (!crt)
3672 goto out;
3673
Willy Tarreau47ca5452012-12-23 20:22:19 +01003674 smp_trash = get_trash_chunk();
Emeric Brunce5ad802012-10-22 14:11:22 +02003675 if (ssl_sock_get_time(X509_get_notBefore(crt), smp_trash) <= 0)
3676 goto out;
3677
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02003678 smp->data.u.str = *smp_trash;
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02003679 smp->data.type = SMP_T_STR;
Emeric Brunce5ad802012-10-22 14:11:22 +02003680 ret = 1;
3681out:
Emeric Brunba841a12014-04-30 17:05:08 +02003682 /* SSL_get_peer_certificate, it increase X509 * ref count */
3683 if (cert_peer && crt)
Emeric Brunce5ad802012-10-22 14:11:22 +02003684 X509_free(crt);
3685 return ret;
3686}
3687
Emeric Brunba841a12014-04-30 17:05:08 +02003688/* string, returns a string of a formatted full dn \C=..\O=..\OU=.. \CN=.. of certificate's subject
3689 * The 5th keyword char is used to know if SSL_get_certificate or SSL_get_peer_certificate
3690 * should be use.
3691 */
Emeric Brun87855892012-10-17 17:39:35 +02003692static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02003693smp_fetch_ssl_x_s_dn(const struct arg *args, struct sample *smp, const char *kw, void *private)
Emeric Brun87855892012-10-17 17:39:35 +02003694{
Emeric Brunba841a12014-04-30 17:05:08 +02003695 int cert_peer = (kw[4] == 'c') ? 1 : 0;
Emeric Brun87855892012-10-17 17:39:35 +02003696 X509 *crt = NULL;
3697 X509_NAME *name;
3698 int ret = 0;
3699 struct chunk *smp_trash;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003700 struct connection *conn;
Emeric Brun87855892012-10-17 17:39:35 +02003701
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02003702 conn = objt_conn(smp->sess->origin);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003703 if (!conn || conn->xprt != &ssl_sock)
3704 return 0;
3705
3706 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brun87855892012-10-17 17:39:35 +02003707 smp->flags |= SMP_F_MAY_CHANGE;
3708 return 0;
3709 }
3710
Emeric Brunba841a12014-04-30 17:05:08 +02003711 if (cert_peer)
3712 crt = SSL_get_peer_certificate(conn->xprt_ctx);
3713 else
3714 crt = SSL_get_certificate(conn->xprt_ctx);
Emeric Brun87855892012-10-17 17:39:35 +02003715 if (!crt)
3716 goto out;
3717
3718 name = X509_get_subject_name(crt);
3719 if (!name)
3720 goto out;
3721
Willy Tarreau47ca5452012-12-23 20:22:19 +01003722 smp_trash = get_trash_chunk();
Emeric Brun87855892012-10-17 17:39:35 +02003723 if (args && args[0].type == ARGT_STR) {
3724 int pos = 1;
3725
3726 if (args[1].type == ARGT_SINT)
3727 pos = args[1].data.sint;
Emeric Brun87855892012-10-17 17:39:35 +02003728
3729 if (ssl_sock_get_dn_entry(name, &args[0].data.str, pos, smp_trash) <= 0)
3730 goto out;
3731 }
3732 else if (ssl_sock_get_dn_oneline(name, smp_trash) <= 0)
3733 goto out;
3734
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02003735 smp->data.type = SMP_T_STR;
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02003736 smp->data.u.str = *smp_trash;
Emeric Brun87855892012-10-17 17:39:35 +02003737 ret = 1;
3738out:
Emeric Brunba841a12014-04-30 17:05:08 +02003739 /* SSL_get_peer_certificate, it increase X509 * ref count */
3740 if (cert_peer && crt)
Emeric Brun87855892012-10-17 17:39:35 +02003741 X509_free(crt);
3742 return ret;
3743}
Emeric Brun9143d372012-12-20 15:44:16 +01003744
3745/* integer, returns true if current session use a client certificate */
3746static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02003747smp_fetch_ssl_c_used(const struct arg *args, struct sample *smp, const char *kw, void *private)
Emeric Brun9143d372012-12-20 15:44:16 +01003748{
3749 X509 *crt;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003750 struct connection *conn;
Emeric Brun9143d372012-12-20 15:44:16 +01003751
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02003752 conn = objt_conn(smp->sess->origin);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003753 if (!conn || conn->xprt != &ssl_sock)
3754 return 0;
3755
3756 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brun9143d372012-12-20 15:44:16 +01003757 smp->flags |= SMP_F_MAY_CHANGE;
3758 return 0;
3759 }
3760
3761 /* SSL_get_peer_certificate returns a ptr on allocated X509 struct */
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003762 crt = SSL_get_peer_certificate(conn->xprt_ctx);
Emeric Brun9143d372012-12-20 15:44:16 +01003763 if (crt) {
3764 X509_free(crt);
3765 }
3766
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02003767 smp->data.type = SMP_T_BOOL;
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02003768 smp->data.u.sint = (crt != NULL);
Emeric Brun9143d372012-12-20 15:44:16 +01003769 return 1;
3770}
3771
Emeric Brunba841a12014-04-30 17:05:08 +02003772/* integer, returns the certificate version
3773 * The 5th keyword char is used to know if SSL_get_certificate or SSL_get_peer_certificate
3774 * should be use.
3775 */
Emeric Bruna7359fd2012-10-17 15:03:11 +02003776static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02003777smp_fetch_ssl_x_version(const struct arg *args, struct sample *smp, const char *kw, void *private)
Emeric Bruna7359fd2012-10-17 15:03:11 +02003778{
Emeric Brunba841a12014-04-30 17:05:08 +02003779 int cert_peer = (kw[4] == 'c') ? 1 : 0;
Emeric Bruna7359fd2012-10-17 15:03:11 +02003780 X509 *crt;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003781 struct connection *conn;
3782
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02003783 conn = objt_conn(smp->sess->origin);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003784 if (!conn || conn->xprt != &ssl_sock)
Emeric Bruna7359fd2012-10-17 15:03:11 +02003785 return 0;
3786
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003787 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Bruna7359fd2012-10-17 15:03:11 +02003788 smp->flags |= SMP_F_MAY_CHANGE;
3789 return 0;
3790 }
3791
Emeric Brunba841a12014-04-30 17:05:08 +02003792 if (cert_peer)
3793 crt = SSL_get_peer_certificate(conn->xprt_ctx);
3794 else
3795 crt = SSL_get_certificate(conn->xprt_ctx);
Emeric Bruna7359fd2012-10-17 15:03:11 +02003796 if (!crt)
3797 return 0;
3798
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02003799 smp->data.u.sint = (unsigned int)(1 + X509_get_version(crt));
Emeric Brunba841a12014-04-30 17:05:08 +02003800 /* SSL_get_peer_certificate increase X509 * ref count */
3801 if (cert_peer)
3802 X509_free(crt);
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02003803 smp->data.type = SMP_T_SINT;
Emeric Bruna7359fd2012-10-17 15:03:11 +02003804
3805 return 1;
3806}
3807
Emeric Brunba841a12014-04-30 17:05:08 +02003808/* string, returns the certificate's signature algorithm.
3809 * The 5th keyword char is used to know if SSL_get_certificate or SSL_get_peer_certificate
3810 * should be use.
3811 */
Emeric Brun7f56e742012-10-19 18:15:40 +02003812static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02003813smp_fetch_ssl_x_sig_alg(const struct arg *args, struct sample *smp, const char *kw, void *private)
Emeric Brun7f56e742012-10-19 18:15:40 +02003814{
Emeric Brunba841a12014-04-30 17:05:08 +02003815 int cert_peer = (kw[4] == 'c') ? 1 : 0;
Emeric Brun7f56e742012-10-19 18:15:40 +02003816 X509 *crt;
3817 int nid;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003818 struct connection *conn;
Emeric Brun7f56e742012-10-19 18:15:40 +02003819
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02003820 conn = objt_conn(smp->sess->origin);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003821 if (!conn || conn->xprt != &ssl_sock)
3822 return 0;
3823
3824 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brun7f56e742012-10-19 18:15:40 +02003825 smp->flags |= SMP_F_MAY_CHANGE;
3826 return 0;
3827 }
3828
Emeric Brunba841a12014-04-30 17:05:08 +02003829 if (cert_peer)
3830 crt = SSL_get_peer_certificate(conn->xprt_ctx);
3831 else
3832 crt = SSL_get_certificate(conn->xprt_ctx);
Emeric Brun7f56e742012-10-19 18:15:40 +02003833 if (!crt)
3834 return 0;
3835
3836 nid = OBJ_obj2nid((ASN1_OBJECT *)(crt->cert_info->signature->algorithm));
3837
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02003838 smp->data.u.str.str = (char *)OBJ_nid2sn(nid);
3839 if (!smp->data.u.str.str) {
Emeric Brunba841a12014-04-30 17:05:08 +02003840 /* SSL_get_peer_certificate increase X509 * ref count */
3841 if (cert_peer)
3842 X509_free(crt);
Emeric Brun7f56e742012-10-19 18:15:40 +02003843 return 0;
Emeric Brun9bf3ba22013-10-07 14:31:44 +02003844 }
Emeric Brun7f56e742012-10-19 18:15:40 +02003845
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02003846 smp->data.type = SMP_T_STR;
Thierry FOURNIER7654c9f2013-12-17 00:20:33 +01003847 smp->flags |= SMP_F_CONST;
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02003848 smp->data.u.str.len = strlen(smp->data.u.str.str);
Emeric Brunba841a12014-04-30 17:05:08 +02003849 /* SSL_get_peer_certificate increase X509 * ref count */
3850 if (cert_peer)
3851 X509_free(crt);
Emeric Brun7f56e742012-10-19 18:15:40 +02003852
3853 return 1;
3854}
3855
Emeric Brunba841a12014-04-30 17:05:08 +02003856/* string, returns the certificate's key algorithm.
3857 * The 5th keyword char is used to know if SSL_get_certificate or SSL_get_peer_certificate
3858 * should be use.
3859 */
Emeric Brun521a0112012-10-22 12:22:55 +02003860static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02003861smp_fetch_ssl_x_key_alg(const struct arg *args, struct sample *smp, const char *kw, void *private)
Emeric Brun521a0112012-10-22 12:22:55 +02003862{
Emeric Brunba841a12014-04-30 17:05:08 +02003863 int cert_peer = (kw[4] == 'c') ? 1 : 0;
Emeric Brun521a0112012-10-22 12:22:55 +02003864 X509 *crt;
3865 int nid;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003866 struct connection *conn;
Emeric Brun521a0112012-10-22 12:22:55 +02003867
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02003868 conn = objt_conn(smp->sess->origin);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003869 if (!conn || conn->xprt != &ssl_sock)
3870 return 0;
3871
3872 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brun521a0112012-10-22 12:22:55 +02003873 smp->flags |= SMP_F_MAY_CHANGE;
3874 return 0;
3875 }
3876
Emeric Brunba841a12014-04-30 17:05:08 +02003877 if (cert_peer)
3878 crt = SSL_get_peer_certificate(conn->xprt_ctx);
3879 else
3880 crt = SSL_get_certificate(conn->xprt_ctx);
Emeric Brun521a0112012-10-22 12:22:55 +02003881 if (!crt)
3882 return 0;
3883
3884 nid = OBJ_obj2nid((ASN1_OBJECT *)(crt->cert_info->key->algor->algorithm));
3885
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02003886 smp->data.u.str.str = (char *)OBJ_nid2sn(nid);
3887 if (!smp->data.u.str.str) {
Emeric Brunba841a12014-04-30 17:05:08 +02003888 /* SSL_get_peer_certificate increase X509 * ref count */
3889 if (cert_peer)
3890 X509_free(crt);
Emeric Brun521a0112012-10-22 12:22:55 +02003891 return 0;
Emeric Brun9bf3ba22013-10-07 14:31:44 +02003892 }
Emeric Brun521a0112012-10-22 12:22:55 +02003893
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02003894 smp->data.type = SMP_T_STR;
Thierry FOURNIER7654c9f2013-12-17 00:20:33 +01003895 smp->flags |= SMP_F_CONST;
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02003896 smp->data.u.str.len = strlen(smp->data.u.str.str);
Emeric Brunba841a12014-04-30 17:05:08 +02003897 if (cert_peer)
3898 X509_free(crt);
Emeric Brun521a0112012-10-22 12:22:55 +02003899
3900 return 1;
3901}
3902
Emeric Brun645ae792014-04-30 14:21:06 +02003903/* boolean, returns true if front conn. transport layer is SSL.
3904 * This function is also usable on backend conn if the fetch keyword 5th
3905 * char is 'b'.
3906 */
Willy Tarreau7875d092012-09-10 08:20:03 +02003907static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02003908smp_fetch_ssl_fc(const struct arg *args, struct sample *smp, const char *kw, void *private)
Willy Tarreau7875d092012-09-10 08:20:03 +02003909{
Emeric Brun645ae792014-04-30 14:21:06 +02003910 int back_conn = (kw[4] == 'b') ? 1 : 0;
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02003911 struct connection *conn = objt_conn(smp->strm->si[back_conn].end);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003912
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02003913 smp->data.type = SMP_T_BOOL;
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02003914 smp->data.u.sint = (conn && conn->xprt == &ssl_sock);
Willy Tarreau7875d092012-09-10 08:20:03 +02003915 return 1;
3916}
3917
Emeric Brun2525b6b2012-10-18 15:59:43 +02003918/* boolean, returns true if client present a SNI */
Willy Tarreau7875d092012-09-10 08:20:03 +02003919static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02003920smp_fetch_ssl_fc_has_sni(const struct arg *args, struct sample *smp, const char *kw, void *private)
Willy Tarreau7875d092012-09-10 08:20:03 +02003921{
3922#ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02003923 struct connection *conn = objt_conn(smp->sess->origin);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003924
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02003925 smp->data.type = SMP_T_BOOL;
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02003926 smp->data.u.sint = (conn && conn->xprt == &ssl_sock) &&
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003927 conn->xprt_ctx &&
3928 SSL_get_servername(conn->xprt_ctx, TLSEXT_NAMETYPE_host_name) != NULL;
Willy Tarreau7875d092012-09-10 08:20:03 +02003929 return 1;
3930#else
3931 return 0;
3932#endif
3933}
3934
Nenad Merdanovic26ea8222015-05-18 02:28:57 +02003935/* boolean, returns true if client session has been resumed */
3936static int
3937smp_fetch_ssl_fc_is_resumed(const struct arg *args, struct sample *smp, const char *kw, void *private)
3938{
3939 struct connection *conn = objt_conn(smp->sess->origin);
3940
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02003941 smp->data.type = SMP_T_BOOL;
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02003942 smp->data.u.sint = (conn && conn->xprt == &ssl_sock) &&
Nenad Merdanovic26ea8222015-05-18 02:28:57 +02003943 conn->xprt_ctx &&
3944 SSL_session_reused(conn->xprt_ctx);
3945 return 1;
3946}
3947
Emeric Brun645ae792014-04-30 14:21:06 +02003948/* string, returns the used cipher if front conn. transport layer is SSL.
3949 * This function is also usable on backend conn if the fetch keyword 5th
3950 * char is 'b'.
3951 */
Emeric Brun589fcad2012-10-16 14:13:26 +02003952static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02003953smp_fetch_ssl_fc_cipher(const struct arg *args, struct sample *smp, const char *kw, void *private)
Emeric Brun589fcad2012-10-16 14:13:26 +02003954{
Emeric Brun645ae792014-04-30 14:21:06 +02003955 int back_conn = (kw[4] == 'b') ? 1 : 0;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003956 struct connection *conn;
3957
Emeric Brun589fcad2012-10-16 14:13:26 +02003958 smp->flags = 0;
3959
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02003960 conn = objt_conn(smp->strm->si[back_conn].end);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003961 if (!conn || !conn->xprt_ctx || conn->xprt != &ssl_sock)
Emeric Brun589fcad2012-10-16 14:13:26 +02003962 return 0;
3963
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02003964 smp->data.u.str.str = (char *)SSL_get_cipher_name(conn->xprt_ctx);
3965 if (!smp->data.u.str.str)
Emeric Brun589fcad2012-10-16 14:13:26 +02003966 return 0;
3967
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02003968 smp->data.type = SMP_T_STR;
Thierry FOURNIER7654c9f2013-12-17 00:20:33 +01003969 smp->flags |= SMP_F_CONST;
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02003970 smp->data.u.str.len = strlen(smp->data.u.str.str);
Emeric Brun589fcad2012-10-16 14:13:26 +02003971
3972 return 1;
3973}
3974
Emeric Brun645ae792014-04-30 14:21:06 +02003975/* integer, returns the algoritm's keysize if front conn. transport layer
3976 * is SSL.
3977 * This function is also usable on backend conn if the fetch keyword 5th
3978 * char is 'b'.
3979 */
Emeric Brun589fcad2012-10-16 14:13:26 +02003980static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02003981smp_fetch_ssl_fc_alg_keysize(const struct arg *args, struct sample *smp, const char *kw, void *private)
Emeric Brun589fcad2012-10-16 14:13:26 +02003982{
Emeric Brun645ae792014-04-30 14:21:06 +02003983 int back_conn = (kw[4] == 'b') ? 1 : 0;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003984 struct connection *conn;
Thierry FOURNIER07ee64e2015-07-06 23:43:03 +02003985 int sint;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003986
Emeric Brun589fcad2012-10-16 14:13:26 +02003987 smp->flags = 0;
3988
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02003989 conn = objt_conn(smp->strm->si[back_conn].end);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003990 if (!conn || !conn->xprt_ctx || conn->xprt != &ssl_sock)
Emeric Brun589fcad2012-10-16 14:13:26 +02003991 return 0;
3992
Thierry FOURNIER07ee64e2015-07-06 23:43:03 +02003993 if (!SSL_get_cipher_bits(conn->xprt_ctx, &sint))
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003994 return 0;
3995
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02003996 smp->data.u.sint = sint;
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02003997 smp->data.type = SMP_T_SINT;
Emeric Brun589fcad2012-10-16 14:13:26 +02003998
3999 return 1;
4000}
4001
Emeric Brun645ae792014-04-30 14:21:06 +02004002/* integer, returns the used keysize if front conn. transport layer is SSL.
4003 * This function is also usable on backend conn if the fetch keyword 5th
4004 * char is 'b'.
4005 */
Emeric Brun589fcad2012-10-16 14:13:26 +02004006static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02004007smp_fetch_ssl_fc_use_keysize(const struct arg *args, struct sample *smp, const char *kw, void *private)
Emeric Brun589fcad2012-10-16 14:13:26 +02004008{
Emeric Brun645ae792014-04-30 14:21:06 +02004009 int back_conn = (kw[4] == 'b') ? 1 : 0;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004010 struct connection *conn;
4011
Emeric Brun589fcad2012-10-16 14:13:26 +02004012 smp->flags = 0;
4013
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02004014 conn = objt_conn(smp->strm->si[back_conn].end);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004015 if (!conn || !conn->xprt_ctx || conn->xprt != &ssl_sock)
4016 return 0;
4017
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02004018 smp->data.u.sint = (unsigned int)SSL_get_cipher_bits(conn->xprt_ctx, NULL);
4019 if (!smp->data.u.sint)
Emeric Brun589fcad2012-10-16 14:13:26 +02004020 return 0;
4021
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02004022 smp->data.type = SMP_T_SINT;
Emeric Brun589fcad2012-10-16 14:13:26 +02004023
4024 return 1;
4025}
4026
Willy Tarreau6c9a3d52012-10-18 18:57:14 +02004027#ifdef OPENSSL_NPN_NEGOTIATED
Willy Tarreau7875d092012-09-10 08:20:03 +02004028static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02004029smp_fetch_ssl_fc_npn(const struct arg *args, struct sample *smp, const char *kw, void *private)
Willy Tarreaua33c6542012-10-15 13:19:06 +02004030{
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004031 struct connection *conn;
4032
Thierry FOURNIER7654c9f2013-12-17 00:20:33 +01004033 smp->flags = SMP_F_CONST;
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02004034 smp->data.type = SMP_T_STR;
Willy Tarreaua33c6542012-10-15 13:19:06 +02004035
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02004036 conn = objt_conn(smp->sess->origin);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004037 if (!conn || !conn->xprt_ctx || conn->xprt != &ssl_sock)
4038 return 0;
4039
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02004040 smp->data.u.str.str = NULL;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004041 SSL_get0_next_proto_negotiated(conn->xprt_ctx,
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02004042 (const unsigned char **)&smp->data.u.str.str, (unsigned *)&smp->data.u.str.len);
Willy Tarreaua33c6542012-10-15 13:19:06 +02004043
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02004044 if (!smp->data.u.str.str)
Willy Tarreaua33c6542012-10-15 13:19:06 +02004045 return 0;
4046
4047 return 1;
Willy Tarreaua33c6542012-10-15 13:19:06 +02004048}
Willy Tarreau6c9a3d52012-10-18 18:57:14 +02004049#endif
Willy Tarreaua33c6542012-10-15 13:19:06 +02004050
Dirkjan Bussink48f1c4e2014-02-13 12:29:42 +01004051#ifdef TLSEXT_TYPE_application_layer_protocol_negotiation
Willy Tarreauab861d32013-04-02 02:30:41 +02004052static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02004053smp_fetch_ssl_fc_alpn(const struct arg *args, struct sample *smp, const char *kw, void *private)
Willy Tarreauab861d32013-04-02 02:30:41 +02004054{
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004055 struct connection *conn;
4056
Thierry FOURNIER7654c9f2013-12-17 00:20:33 +01004057 smp->flags = SMP_F_CONST;
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02004058 smp->data.type = SMP_T_STR;
Willy Tarreauab861d32013-04-02 02:30:41 +02004059
Willy Tarreaue26bf052015-05-12 10:30:12 +02004060 conn = objt_conn(smp->sess->origin);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004061 if (!conn || !conn->xprt_ctx || conn->xprt != &ssl_sock)
Willy Tarreauab861d32013-04-02 02:30:41 +02004062 return 0;
4063
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02004064 smp->data.u.str.str = NULL;
Dirkjan Bussink48f1c4e2014-02-13 12:29:42 +01004065 SSL_get0_alpn_selected(conn->xprt_ctx,
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02004066 (const unsigned char **)&smp->data.u.str.str, (unsigned *)&smp->data.u.str.len);
Willy Tarreauab861d32013-04-02 02:30:41 +02004067
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02004068 if (!smp->data.u.str.str)
Willy Tarreauab861d32013-04-02 02:30:41 +02004069 return 0;
4070
4071 return 1;
4072}
4073#endif
4074
Emeric Brun645ae792014-04-30 14:21:06 +02004075/* string, returns the used protocol if front conn. transport layer is SSL.
4076 * This function is also usable on backend conn if the fetch keyword 5th
4077 * char is 'b'.
4078 */
Willy Tarreaua33c6542012-10-15 13:19:06 +02004079static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02004080smp_fetch_ssl_fc_protocol(const struct arg *args, struct sample *smp, const char *kw, void *private)
Emeric Brun589fcad2012-10-16 14:13:26 +02004081{
Emeric Brun645ae792014-04-30 14:21:06 +02004082 int back_conn = (kw[4] == 'b') ? 1 : 0;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004083 struct connection *conn;
4084
Emeric Brun589fcad2012-10-16 14:13:26 +02004085 smp->flags = 0;
4086
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02004087 conn = objt_conn(smp->strm->si[back_conn].end);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004088 if (!conn || !conn->xprt_ctx || conn->xprt != &ssl_sock)
4089 return 0;
4090
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02004091 smp->data.u.str.str = (char *)SSL_get_version(conn->xprt_ctx);
4092 if (!smp->data.u.str.str)
Emeric Brun589fcad2012-10-16 14:13:26 +02004093 return 0;
4094
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02004095 smp->data.type = SMP_T_STR;
Thierry FOURNIER7654c9f2013-12-17 00:20:33 +01004096 smp->flags = SMP_F_CONST;
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02004097 smp->data.u.str.len = strlen(smp->data.u.str.str);
Emeric Brun589fcad2012-10-16 14:13:26 +02004098
4099 return 1;
4100}
4101
Willy Tarreau87b09662015-04-03 00:22:06 +02004102/* binary, returns the SSL stream id if front conn. transport layer is SSL.
Emeric Brun645ae792014-04-30 14:21:06 +02004103 * This function is also usable on backend conn if the fetch keyword 5th
4104 * char is 'b'.
4105 */
Emeric Brun589fcad2012-10-16 14:13:26 +02004106static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02004107smp_fetch_ssl_fc_session_id(const struct arg *args, struct sample *smp, const char *kw, void *private)
Emeric Brunfe68f682012-10-16 14:59:28 +02004108{
4109#if OPENSSL_VERSION_NUMBER > 0x0090800fL
Emeric Brun645ae792014-04-30 14:21:06 +02004110 int back_conn = (kw[4] == 'b') ? 1 : 0;
Willy Tarreau192252e2015-04-04 01:47:55 +02004111 SSL_SESSION *ssl_sess;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004112 struct connection *conn;
Emeric Brunfe68f682012-10-16 14:59:28 +02004113
Thierry FOURNIER7654c9f2013-12-17 00:20:33 +01004114 smp->flags = SMP_F_CONST;
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02004115 smp->data.type = SMP_T_BIN;
Emeric Brunfe68f682012-10-16 14:59:28 +02004116
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02004117 conn = objt_conn(smp->strm->si[back_conn].end);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004118 if (!conn || !conn->xprt_ctx || conn->xprt != &ssl_sock)
4119 return 0;
4120
Willy Tarreau192252e2015-04-04 01:47:55 +02004121 ssl_sess = SSL_get_session(conn->xprt_ctx);
4122 if (!ssl_sess)
Emeric Brunfe68f682012-10-16 14:59:28 +02004123 return 0;
4124
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02004125 smp->data.u.str.str = (char *)SSL_SESSION_get_id(ssl_sess, (unsigned int *)&smp->data.u.str.len);
4126 if (!smp->data.u.str.str || !smp->data.u.str.len)
Emeric Brunfe68f682012-10-16 14:59:28 +02004127 return 0;
4128
4129 return 1;
4130#else
4131 return 0;
4132#endif
4133}
4134
4135static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02004136smp_fetch_ssl_fc_sni(const struct arg *args, struct sample *smp, const char *kw, void *private)
Willy Tarreau7875d092012-09-10 08:20:03 +02004137{
4138#ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004139 struct connection *conn;
4140
Thierry FOURNIER7654c9f2013-12-17 00:20:33 +01004141 smp->flags = SMP_F_CONST;
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02004142 smp->data.type = SMP_T_STR;
Willy Tarreau7875d092012-09-10 08:20:03 +02004143
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02004144 conn = objt_conn(smp->sess->origin);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004145 if (!conn || !conn->xprt_ctx || conn->xprt != &ssl_sock)
4146 return 0;
4147
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02004148 smp->data.u.str.str = (char *)SSL_get_servername(conn->xprt_ctx, TLSEXT_NAMETYPE_host_name);
4149 if (!smp->data.u.str.str)
Willy Tarreau3e394c92012-09-14 23:56:58 +02004150 return 0;
4151
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02004152 smp->data.u.str.len = strlen(smp->data.u.str.str);
Willy Tarreau7875d092012-09-10 08:20:03 +02004153 return 1;
4154#else
4155 return 0;
4156#endif
4157}
4158
David Sc1ad52e2014-04-08 18:48:47 -04004159static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02004160smp_fetch_ssl_fc_unique_id(const struct arg *args, struct sample *smp, const char *kw, void *private)
David Sc1ad52e2014-04-08 18:48:47 -04004161{
4162#if OPENSSL_VERSION_NUMBER > 0x0090800fL
Emeric Brun645ae792014-04-30 14:21:06 +02004163 int back_conn = (kw[4] == 'b') ? 1 : 0;
David Sc1ad52e2014-04-08 18:48:47 -04004164 struct connection *conn;
4165 int finished_len;
David Sc1ad52e2014-04-08 18:48:47 -04004166 struct chunk *finished_trash;
David Sc1ad52e2014-04-08 18:48:47 -04004167
4168 smp->flags = 0;
4169
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02004170 conn = objt_conn(smp->strm->si[back_conn].end);
David Sc1ad52e2014-04-08 18:48:47 -04004171 if (!conn || !conn->xprt_ctx || conn->xprt != &ssl_sock)
4172 return 0;
4173
4174 if (!(conn->flags & CO_FL_CONNECTED)) {
4175 smp->flags |= SMP_F_MAY_CHANGE;
4176 return 0;
4177 }
4178
4179 finished_trash = get_trash_chunk();
4180 if (!SSL_session_reused(conn->xprt_ctx))
4181 finished_len = SSL_get_peer_finished(conn->xprt_ctx, finished_trash->str, finished_trash->size);
4182 else
4183 finished_len = SSL_get_finished(conn->xprt_ctx, finished_trash->str, finished_trash->size);
4184
4185 if (!finished_len)
4186 return 0;
4187
Emeric Brunb73a9b02014-04-30 18:49:19 +02004188 finished_trash->len = finished_len;
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02004189 smp->data.u.str = *finished_trash;
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02004190 smp->data.type = SMP_T_BIN;
David Sc1ad52e2014-04-08 18:48:47 -04004191
4192 return 1;
4193#else
4194 return 0;
4195#endif
4196}
4197
Emeric Brun2525b6b2012-10-18 15:59:43 +02004198/* integer, returns the first verify error in CA chain of client certificate chain. */
Emeric Brunf282a812012-09-21 15:27:54 +02004199static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02004200smp_fetch_ssl_c_ca_err(const struct arg *args, struct sample *smp, const char *kw, void *private)
Emeric Brunf282a812012-09-21 15:27:54 +02004201{
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004202 struct connection *conn;
4203
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02004204 conn = objt_conn(smp->sess->origin);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004205 if (!conn || conn->xprt != &ssl_sock)
4206 return 0;
4207
4208 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brunf282a812012-09-21 15:27:54 +02004209 smp->flags = SMP_F_MAY_CHANGE;
4210 return 0;
4211 }
4212
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02004213 smp->data.type = SMP_T_SINT;
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02004214 smp->data.u.sint = (unsigned long long int)SSL_SOCK_ST_TO_CA_ERROR(conn->xprt_st);
Emeric Brunf282a812012-09-21 15:27:54 +02004215 smp->flags = 0;
4216
4217 return 1;
4218}
4219
Emeric Brun2525b6b2012-10-18 15:59:43 +02004220/* integer, returns the depth of the first verify error in CA chain of client certificate chain. */
Emeric Brunf282a812012-09-21 15:27:54 +02004221static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02004222smp_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 +02004223{
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004224 struct connection *conn;
4225
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02004226 conn = objt_conn(smp->sess->origin);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004227 if (!conn || conn->xprt != &ssl_sock)
Emeric Brunf282a812012-09-21 15:27:54 +02004228 return 0;
4229
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004230 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brunf282a812012-09-21 15:27:54 +02004231 smp->flags = SMP_F_MAY_CHANGE;
4232 return 0;
4233 }
4234
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02004235 smp->data.type = SMP_T_SINT;
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02004236 smp->data.u.sint = (long long int)SSL_SOCK_ST_TO_CAEDEPTH(conn->xprt_st);
Emeric Brunf282a812012-09-21 15:27:54 +02004237 smp->flags = 0;
4238
4239 return 1;
4240}
4241
Emeric Brun2525b6b2012-10-18 15:59:43 +02004242/* integer, returns the first verify error on client certificate */
Emeric Brunf282a812012-09-21 15:27:54 +02004243static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02004244smp_fetch_ssl_c_err(const struct arg *args, struct sample *smp, const char *kw, void *private)
Emeric Brunf282a812012-09-21 15:27:54 +02004245{
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004246 struct connection *conn;
4247
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02004248 conn = objt_conn(smp->sess->origin);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004249 if (!conn || conn->xprt != &ssl_sock)
4250 return 0;
4251
4252 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brunf282a812012-09-21 15:27:54 +02004253 smp->flags = SMP_F_MAY_CHANGE;
4254 return 0;
4255 }
4256
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02004257 smp->data.type = SMP_T_SINT;
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02004258 smp->data.u.sint = (long long int)SSL_SOCK_ST_TO_CRTERROR(conn->xprt_st);
Emeric Brunf282a812012-09-21 15:27:54 +02004259 smp->flags = 0;
4260
4261 return 1;
4262}
4263
Emeric Brun2525b6b2012-10-18 15:59:43 +02004264/* integer, returns the verify result on client cert */
Emeric Brunbaf8ffb2012-09-21 15:27:20 +02004265static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02004266smp_fetch_ssl_c_verify(const struct arg *args, struct sample *smp, const char *kw, void *private)
Emeric Brunbaf8ffb2012-09-21 15:27:20 +02004267{
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004268 struct connection *conn;
4269
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02004270 conn = objt_conn(smp->sess->origin);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004271 if (!conn || conn->xprt != &ssl_sock)
4272 return 0;
4273
4274 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brunbaf8ffb2012-09-21 15:27:20 +02004275 smp->flags = SMP_F_MAY_CHANGE;
4276 return 0;
4277 }
4278
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004279 if (!conn->xprt_ctx)
Emeric Brunbaf8ffb2012-09-21 15:27:20 +02004280 return 0;
4281
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02004282 smp->data.type = SMP_T_SINT;
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02004283 smp->data.u.sint = (long long int)SSL_get_verify_result(conn->xprt_ctx);
Emeric Brunbaf8ffb2012-09-21 15:27:20 +02004284 smp->flags = 0;
4285
4286 return 1;
4287}
4288
Emeric Brunfb510ea2012-10-05 12:00:26 +02004289/* parse the "ca-file" bind keyword */
4290static 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 +02004291{
4292 if (!*args[cur_arg + 1]) {
4293 if (err)
4294 memprintf(err, "'%s' : missing CAfile path", args[cur_arg]);
4295 return ERR_ALERT | ERR_FATAL;
4296 }
4297
Emeric Brunef42d922012-10-11 16:11:36 +02004298 if ((*args[cur_arg + 1] != '/') && global.ca_base)
4299 memprintf(&conf->ca_file, "%s/%s", global.ca_base, args[cur_arg + 1]);
4300 else
4301 memprintf(&conf->ca_file, "%s", args[cur_arg + 1]);
Emeric Brunc8e8d122012-10-02 18:42:10 +02004302
Emeric Brund94b3fe2012-09-20 18:23:56 +02004303 return 0;
4304}
4305
Christopher Faulet31af49d2015-06-09 17:29:50 +02004306/* parse the "ca-sign-file" bind keyword */
4307static int bind_parse_ca_sign_file(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
4308{
4309 if (!*args[cur_arg + 1]) {
4310 if (err)
4311 memprintf(err, "'%s' : missing CAfile path", args[cur_arg]);
4312 return ERR_ALERT | ERR_FATAL;
4313 }
4314
4315 if ((*args[cur_arg + 1] != '/') && global.ca_base)
4316 memprintf(&conf->ca_sign_file, "%s/%s", global.ca_base, args[cur_arg + 1]);
4317 else
4318 memprintf(&conf->ca_sign_file, "%s", args[cur_arg + 1]);
4319
4320 return 0;
4321}
4322
4323/* parse the ca-sign-pass bind keyword */
4324
4325static int bind_parse_ca_sign_pass(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
4326{
4327 if (!*args[cur_arg + 1]) {
4328 if (err)
4329 memprintf(err, "'%s' : missing CAkey password", args[cur_arg]);
4330 return ERR_ALERT | ERR_FATAL;
4331 }
4332 memprintf(&conf->ca_sign_pass, "%s", args[cur_arg + 1]);
4333 return 0;
4334}
4335
Willy Tarreau79eeafa2012-09-14 07:53:05 +02004336/* parse the "ciphers" bind keyword */
Willy Tarreau4348fad2012-09-20 16:48:07 +02004337static 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 +02004338{
4339 if (!*args[cur_arg + 1]) {
Willy Tarreaueb6cead2012-09-20 19:43:14 +02004340 memprintf(err, "'%s' : missing cipher suite", args[cur_arg]);
Willy Tarreau79eeafa2012-09-14 07:53:05 +02004341 return ERR_ALERT | ERR_FATAL;
4342 }
4343
Emeric Brun76d88952012-10-05 15:47:31 +02004344 free(conf->ciphers);
Willy Tarreau4348fad2012-09-20 16:48:07 +02004345 conf->ciphers = strdup(args[cur_arg + 1]);
Willy Tarreau79eeafa2012-09-14 07:53:05 +02004346 return 0;
4347}
4348
4349/* parse the "crt" bind keyword */
Willy Tarreau4348fad2012-09-20 16:48:07 +02004350static 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 +02004351{
Willy Tarreau38011032013-08-13 16:59:39 +02004352 char path[MAXPATHLEN];
Willy Tarreaub75d6922014-04-14 18:05:41 +02004353
Willy Tarreau79eeafa2012-09-14 07:53:05 +02004354 if (!*args[cur_arg + 1]) {
Willy Tarreaueb6cead2012-09-20 19:43:14 +02004355 memprintf(err, "'%s' : missing certificate location", args[cur_arg]);
Willy Tarreau79eeafa2012-09-14 07:53:05 +02004356 return ERR_ALERT | ERR_FATAL;
4357 }
4358
Emeric Brunc8e8d122012-10-02 18:42:10 +02004359 if ((*args[cur_arg + 1] != '/' ) && global.crt_base) {
Willy Tarreau38011032013-08-13 16:59:39 +02004360 if ((strlen(global.crt_base) + 1 + strlen(args[cur_arg + 1]) + 1) > MAXPATHLEN) {
Emeric Brunc8e8d122012-10-02 18:42:10 +02004361 memprintf(err, "'%s' : path too long", args[cur_arg]);
4362 return ERR_ALERT | ERR_FATAL;
4363 }
Willy Tarreaub75d6922014-04-14 18:05:41 +02004364 snprintf(path, sizeof(path), "%s/%s", global.crt_base, args[cur_arg + 1]);
Emeric Brunc8e8d122012-10-02 18:42:10 +02004365 if (ssl_sock_load_cert(path, conf, px, err) > 0)
4366 return ERR_ALERT | ERR_FATAL;
4367
4368 return 0;
4369 }
4370
Willy Tarreau4348fad2012-09-20 16:48:07 +02004371 if (ssl_sock_load_cert(args[cur_arg + 1], conf, px, err) > 0)
Willy Tarreau79eeafa2012-09-14 07:53:05 +02004372 return ERR_ALERT | ERR_FATAL;
Emeric Brund94b3fe2012-09-20 18:23:56 +02004373
4374 return 0;
4375}
4376
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01004377/* parse the "crt-list" bind keyword */
4378static int bind_parse_crt_list(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
4379{
4380 if (!*args[cur_arg + 1]) {
4381 memprintf(err, "'%s' : missing certificate location", args[cur_arg]);
4382 return ERR_ALERT | ERR_FATAL;
4383 }
4384
Willy Tarreauad1731d2013-04-02 17:35:58 +02004385 if (ssl_sock_load_cert_list_file(args[cur_arg + 1], conf, px, err) > 0) {
4386 memprintf(err, "'%s' : %s", args[cur_arg], *err);
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01004387 return ERR_ALERT | ERR_FATAL;
Willy Tarreauad1731d2013-04-02 17:35:58 +02004388 }
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01004389
4390 return 0;
4391}
4392
Emeric Brunfb510ea2012-10-05 12:00:26 +02004393/* parse the "crl-file" bind keyword */
4394static 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 +02004395{
Emeric Brun051cdab2012-10-02 19:25:50 +02004396#ifndef X509_V_FLAG_CRL_CHECK
4397 if (err)
4398 memprintf(err, "'%s' : library does not support CRL verify", args[cur_arg]);
4399 return ERR_ALERT | ERR_FATAL;
4400#else
Emeric Brund94b3fe2012-09-20 18:23:56 +02004401 if (!*args[cur_arg + 1]) {
4402 if (err)
4403 memprintf(err, "'%s' : missing CRLfile path", args[cur_arg]);
4404 return ERR_ALERT | ERR_FATAL;
4405 }
Emeric Brun2b58d042012-09-20 17:10:03 +02004406
Emeric Brunef42d922012-10-11 16:11:36 +02004407 if ((*args[cur_arg + 1] != '/') && global.ca_base)
4408 memprintf(&conf->crl_file, "%s/%s", global.ca_base, args[cur_arg + 1]);
4409 else
4410 memprintf(&conf->crl_file, "%s", args[cur_arg + 1]);
Emeric Brunc8e8d122012-10-02 18:42:10 +02004411
Emeric Brun2b58d042012-09-20 17:10:03 +02004412 return 0;
Emeric Brun051cdab2012-10-02 19:25:50 +02004413#endif
Emeric Brun2b58d042012-09-20 17:10:03 +02004414}
4415
4416/* parse the "ecdhe" bind keyword keywords */
4417static int bind_parse_ecdhe(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
4418{
4419#if OPENSSL_VERSION_NUMBER < 0x0090800fL
4420 if (err)
4421 memprintf(err, "'%s' : library does not support elliptic curve Diffie-Hellman (too old)", args[cur_arg]);
4422 return ERR_ALERT | ERR_FATAL;
4423#elif defined(OPENSSL_NO_ECDH)
4424 if (err)
4425 memprintf(err, "'%s' : library does not support elliptic curve Diffie-Hellman (disabled via OPENSSL_NO_ECDH)", args[cur_arg]);
4426 return ERR_ALERT | ERR_FATAL;
4427#else
4428 if (!*args[cur_arg + 1]) {
4429 if (err)
4430 memprintf(err, "'%s' : missing named curve", args[cur_arg]);
4431 return ERR_ALERT | ERR_FATAL;
4432 }
4433
4434 conf->ecdhe = strdup(args[cur_arg + 1]);
Willy Tarreau79eeafa2012-09-14 07:53:05 +02004435
4436 return 0;
Emeric Brun2b58d042012-09-20 17:10:03 +02004437#endif
Willy Tarreau79eeafa2012-09-14 07:53:05 +02004438}
4439
Emeric Brun81c00f02012-09-21 14:31:21 +02004440/* parse the "crt_ignerr" and "ca_ignerr" bind keywords */
4441static int bind_parse_ignore_err(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
4442{
4443 int code;
4444 char *p = args[cur_arg + 1];
4445 unsigned long long *ignerr = &conf->crt_ignerr;
4446
4447 if (!*p) {
4448 if (err)
4449 memprintf(err, "'%s' : missing error IDs list", args[cur_arg]);
4450 return ERR_ALERT | ERR_FATAL;
4451 }
4452
4453 if (strcmp(args[cur_arg], "ca-ignore-err") == 0)
4454 ignerr = &conf->ca_ignerr;
4455
4456 if (strcmp(p, "all") == 0) {
4457 *ignerr = ~0ULL;
4458 return 0;
4459 }
4460
4461 while (p) {
4462 code = atoi(p);
4463 if ((code <= 0) || (code > 63)) {
4464 if (err)
4465 memprintf(err, "'%s' : ID '%d' out of range (1..63) in error IDs list '%s'",
4466 args[cur_arg], code, args[cur_arg + 1]);
4467 return ERR_ALERT | ERR_FATAL;
4468 }
4469 *ignerr |= 1ULL << code;
4470 p = strchr(p, ',');
4471 if (p)
4472 p++;
4473 }
4474
Emeric Brun2cb7ae52012-10-05 14:14:21 +02004475 return 0;
4476}
4477
4478/* parse the "force-sslv3" bind keyword */
4479static int bind_parse_force_sslv3(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
4480{
4481 conf->ssl_options |= BC_SSL_O_USE_SSLV3;
4482 return 0;
4483}
4484
4485/* parse the "force-tlsv10" bind keyword */
4486static int bind_parse_force_tlsv10(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
4487{
4488 conf->ssl_options |= BC_SSL_O_USE_TLSV10;
Emeric Brun2d0c4822012-10-02 13:45:20 +02004489 return 0;
4490}
4491
Emeric Brun2cb7ae52012-10-05 14:14:21 +02004492/* parse the "force-tlsv11" bind keyword */
4493static int bind_parse_force_tlsv11(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
4494{
4495#if SSL_OP_NO_TLSv1_1
4496 conf->ssl_options |= BC_SSL_O_USE_TLSV11;
4497 return 0;
4498#else
4499 if (err)
4500 memprintf(err, "'%s' : library does not support protocol TLSv1.1", args[cur_arg]);
4501 return ERR_ALERT | ERR_FATAL;
4502#endif
4503}
4504
4505/* parse the "force-tlsv12" bind keyword */
4506static int bind_parse_force_tlsv12(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
4507{
4508#if SSL_OP_NO_TLSv1_2
4509 conf->ssl_options |= BC_SSL_O_USE_TLSV12;
4510 return 0;
4511#else
4512 if (err)
4513 memprintf(err, "'%s' : library does not support protocol TLSv1.2", args[cur_arg]);
4514 return ERR_ALERT | ERR_FATAL;
4515#endif
4516}
4517
4518
Emeric Brun2d0c4822012-10-02 13:45:20 +02004519/* parse the "no-tls-tickets" bind keyword */
4520static int bind_parse_no_tls_tickets(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
4521{
Emeric Brun89675492012-10-05 13:48:26 +02004522 conf->ssl_options |= BC_SSL_O_NO_TLS_TICKETS;
Emeric Brun81c00f02012-09-21 14:31:21 +02004523 return 0;
4524}
4525
Emeric Brun2d0c4822012-10-02 13:45:20 +02004526
Emeric Brun9b3009b2012-10-05 11:55:06 +02004527/* parse the "no-sslv3" bind keyword */
4528static 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 +02004529{
Emeric Brun89675492012-10-05 13:48:26 +02004530 conf->ssl_options |= BC_SSL_O_NO_SSLV3;
Willy Tarreau79eeafa2012-09-14 07:53:05 +02004531 return 0;
4532}
4533
Emeric Brun9b3009b2012-10-05 11:55:06 +02004534/* parse the "no-tlsv10" bind keyword */
4535static 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 +02004536{
Emeric Brun89675492012-10-05 13:48:26 +02004537 conf->ssl_options |= BC_SSL_O_NO_TLSV10;
Emeric Brunc0ff4922012-09-28 19:37:02 +02004538 return 0;
4539}
4540
Emeric Brun9b3009b2012-10-05 11:55:06 +02004541/* parse the "no-tlsv11" bind keyword */
4542static 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 +02004543{
Emeric Brun89675492012-10-05 13:48:26 +02004544 conf->ssl_options |= BC_SSL_O_NO_TLSV11;
Emeric Brunc0ff4922012-09-28 19:37:02 +02004545 return 0;
4546}
4547
Emeric Brun9b3009b2012-10-05 11:55:06 +02004548/* parse the "no-tlsv12" bind keyword */
4549static 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 +02004550{
Emeric Brun89675492012-10-05 13:48:26 +02004551 conf->ssl_options |= BC_SSL_O_NO_TLSV12;
Willy Tarreau79eeafa2012-09-14 07:53:05 +02004552 return 0;
4553}
4554
Willy Tarreau6c9a3d52012-10-18 18:57:14 +02004555/* parse the "npn" bind keyword */
4556static int bind_parse_npn(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
4557{
4558#ifdef OPENSSL_NPN_NEGOTIATED
4559 char *p1, *p2;
4560
4561 if (!*args[cur_arg + 1]) {
4562 memprintf(err, "'%s' : missing the comma-delimited NPN protocol suite", args[cur_arg]);
4563 return ERR_ALERT | ERR_FATAL;
4564 }
4565
4566 free(conf->npn_str);
4567
4568 /* the NPN string is built as a suite of (<len> <name>)* */
4569 conf->npn_len = strlen(args[cur_arg + 1]) + 1;
4570 conf->npn_str = calloc(1, conf->npn_len);
4571 memcpy(conf->npn_str + 1, args[cur_arg + 1], conf->npn_len);
4572
4573 /* replace commas with the name length */
4574 p1 = conf->npn_str;
4575 p2 = p1 + 1;
4576 while (1) {
4577 p2 = memchr(p1 + 1, ',', conf->npn_str + conf->npn_len - (p1 + 1));
4578 if (!p2)
4579 p2 = p1 + 1 + strlen(p1 + 1);
4580
4581 if (p2 - (p1 + 1) > 255) {
4582 *p2 = '\0';
4583 memprintf(err, "'%s' : NPN protocol name too long : '%s'", args[cur_arg], p1 + 1);
4584 return ERR_ALERT | ERR_FATAL;
4585 }
4586
4587 *p1 = p2 - (p1 + 1);
4588 p1 = p2;
4589
4590 if (!*p2)
4591 break;
4592
4593 *(p2++) = '\0';
4594 }
4595 return 0;
4596#else
4597 if (err)
4598 memprintf(err, "'%s' : library does not support TLS NPN extension", args[cur_arg]);
4599 return ERR_ALERT | ERR_FATAL;
4600#endif
4601}
4602
Willy Tarreauab861d32013-04-02 02:30:41 +02004603/* parse the "alpn" bind keyword */
4604static int bind_parse_alpn(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
4605{
Dirkjan Bussink48f1c4e2014-02-13 12:29:42 +01004606#ifdef TLSEXT_TYPE_application_layer_protocol_negotiation
Willy Tarreauab861d32013-04-02 02:30:41 +02004607 char *p1, *p2;
4608
4609 if (!*args[cur_arg + 1]) {
4610 memprintf(err, "'%s' : missing the comma-delimited ALPN protocol suite", args[cur_arg]);
4611 return ERR_ALERT | ERR_FATAL;
4612 }
4613
4614 free(conf->alpn_str);
4615
4616 /* the ALPN string is built as a suite of (<len> <name>)* */
4617 conf->alpn_len = strlen(args[cur_arg + 1]) + 1;
4618 conf->alpn_str = calloc(1, conf->alpn_len);
4619 memcpy(conf->alpn_str + 1, args[cur_arg + 1], conf->alpn_len);
4620
4621 /* replace commas with the name length */
4622 p1 = conf->alpn_str;
4623 p2 = p1 + 1;
4624 while (1) {
4625 p2 = memchr(p1 + 1, ',', conf->alpn_str + conf->alpn_len - (p1 + 1));
4626 if (!p2)
4627 p2 = p1 + 1 + strlen(p1 + 1);
4628
4629 if (p2 - (p1 + 1) > 255) {
4630 *p2 = '\0';
4631 memprintf(err, "'%s' : ALPN protocol name too long : '%s'", args[cur_arg], p1 + 1);
4632 return ERR_ALERT | ERR_FATAL;
4633 }
4634
4635 *p1 = p2 - (p1 + 1);
4636 p1 = p2;
4637
4638 if (!*p2)
4639 break;
4640
4641 *(p2++) = '\0';
4642 }
4643 return 0;
4644#else
4645 if (err)
4646 memprintf(err, "'%s' : library does not support TLS ALPN extension", args[cur_arg]);
4647 return ERR_ALERT | ERR_FATAL;
4648#endif
4649}
4650
Willy Tarreau79eeafa2012-09-14 07:53:05 +02004651/* parse the "ssl" bind keyword */
Willy Tarreau4348fad2012-09-20 16:48:07 +02004652static 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 +02004653{
Willy Tarreau81796be2012-09-22 19:11:47 +02004654 struct listener *l;
4655
Willy Tarreau4348fad2012-09-20 16:48:07 +02004656 conf->is_ssl = 1;
Emeric Brun76d88952012-10-05 15:47:31 +02004657
4658 if (global.listen_default_ciphers && !conf->ciphers)
4659 conf->ciphers = strdup(global.listen_default_ciphers);
Emeric Brun2c86cbf2014-10-30 15:56:50 +01004660 conf->ssl_options |= global.listen_default_ssloptions;
Emeric Brun76d88952012-10-05 15:47:31 +02004661
Willy Tarreau81796be2012-09-22 19:11:47 +02004662 list_for_each_entry(l, &conf->listeners, by_bind)
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02004663 l->xprt = &ssl_sock;
Willy Tarreau81796be2012-09-22 19:11:47 +02004664
Willy Tarreau79eeafa2012-09-14 07:53:05 +02004665 return 0;
4666}
4667
Christopher Faulet31af49d2015-06-09 17:29:50 +02004668/* parse the "generate-certificates" bind keyword */
4669static int bind_parse_generate_certs(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
4670{
4671#ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME
4672 conf->generate_certs = 1;
4673#else
4674 memprintf(err, "%sthis version of openssl cannot generate SSL certificates.\n",
4675 err && *err ? *err : "");
4676#endif
4677 return 0;
4678}
4679
Emmanuel Hocdet65623372013-01-24 17:17:15 +01004680/* parse the "strict-sni" bind keyword */
4681static int bind_parse_strict_sni(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
4682{
4683 conf->strict_sni = 1;
4684 return 0;
Nenad Merdanovic05552d42015-02-27 19:56:49 +01004685}
4686
4687/* parse the "tls-ticket-keys" bind keyword */
4688static int bind_parse_tls_ticket_keys(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
4689{
4690#if (defined SSL_CTRL_SET_TLSEXT_TICKET_KEY_CB && TLS_TICKETS_NO > 0)
4691 FILE *f;
4692 int i = 0;
4693 char thisline[LINESIZE];
Nenad Merdanovic146defa2015-05-09 08:46:00 +02004694 struct tls_keys_ref *keys_ref;
Nenad Merdanovic05552d42015-02-27 19:56:49 +01004695
4696 if (!*args[cur_arg + 1]) {
4697 if (err)
4698 memprintf(err, "'%s' : missing TLS ticket keys file path", args[cur_arg]);
4699 return ERR_ALERT | ERR_FATAL;
4700 }
4701
Nenad Merdanovic200b0fa2015-05-09 08:46:01 +02004702 keys_ref = tlskeys_ref_lookup(args[cur_arg + 1]);
4703 if(keys_ref) {
4704 conf->keys_ref = keys_ref;
4705 return 0;
4706 }
4707
Nenad Merdanovic146defa2015-05-09 08:46:00 +02004708 keys_ref = malloc(sizeof(struct tls_keys_ref));
4709 keys_ref->tlskeys = malloc(TLS_TICKETS_NO * sizeof(struct tls_sess_key));
Nenad Merdanovic05552d42015-02-27 19:56:49 +01004710
4711 if ((f = fopen(args[cur_arg + 1], "r")) == NULL) {
4712 if (err)
4713 memprintf(err, "'%s' : unable to load ssl tickets keys file", args[cur_arg+1]);
4714 return ERR_ALERT | ERR_FATAL;
4715 }
4716
Nenad Merdanovic146defa2015-05-09 08:46:00 +02004717 keys_ref->filename = strdup(args[cur_arg + 1]);
4718
Nenad Merdanovic05552d42015-02-27 19:56:49 +01004719 while (fgets(thisline, sizeof(thisline), f) != NULL) {
4720 int len = strlen(thisline);
4721 /* Strip newline characters from the end */
4722 if(thisline[len - 1] == '\n')
4723 thisline[--len] = 0;
4724
4725 if(thisline[len - 1] == '\r')
4726 thisline[--len] = 0;
4727
Nenad Merdanovic146defa2015-05-09 08:46:00 +02004728 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 +01004729 if (err)
4730 memprintf(err, "'%s' : unable to decode base64 key on line %d", args[cur_arg+1], i + 1);
4731 return ERR_ALERT | ERR_FATAL;
4732 }
4733 i++;
4734 }
4735
4736 if (i < TLS_TICKETS_NO) {
4737 if (err)
4738 memprintf(err, "'%s' : please supply at least %d keys in the tls-tickets-file", args[cur_arg+1], TLS_TICKETS_NO);
4739 return ERR_ALERT | ERR_FATAL;
4740 }
4741
4742 fclose(f);
4743
4744 /* Use penultimate key for encryption, handle when TLS_TICKETS_NO = 1 */
4745 i-=2;
Nenad Merdanovic146defa2015-05-09 08:46:00 +02004746 keys_ref->tls_ticket_enc_index = i < 0 ? 0 : i;
Nenad Merdanovic200b0fa2015-05-09 08:46:01 +02004747 keys_ref->unique_id = -1;
Nenad Merdanovic146defa2015-05-09 08:46:00 +02004748 conf->keys_ref = keys_ref;
Nenad Merdanovic05552d42015-02-27 19:56:49 +01004749
Nenad Merdanovic200b0fa2015-05-09 08:46:01 +02004750 LIST_ADD(&tlskeys_reference, &keys_ref->list);
4751
Nenad Merdanovic05552d42015-02-27 19:56:49 +01004752 return 0;
4753#else
4754 if (err)
4755 memprintf(err, "'%s' : TLS ticket callback extension not supported", args[cur_arg]);
4756 return ERR_ALERT | ERR_FATAL;
4757#endif /* SSL_CTRL_SET_TLSEXT_TICKET_KEY_CB */
Emmanuel Hocdet65623372013-01-24 17:17:15 +01004758}
4759
Emeric Brund94b3fe2012-09-20 18:23:56 +02004760/* parse the "verify" bind keyword */
4761static int bind_parse_verify(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
4762{
4763 if (!*args[cur_arg + 1]) {
4764 if (err)
4765 memprintf(err, "'%s' : missing verify method", args[cur_arg]);
4766 return ERR_ALERT | ERR_FATAL;
4767 }
4768
4769 if (strcmp(args[cur_arg + 1], "none") == 0)
Emeric Brun850efd52014-01-29 12:24:34 +01004770 conf->verify = SSL_SOCK_VERIFY_NONE;
Emeric Brund94b3fe2012-09-20 18:23:56 +02004771 else if (strcmp(args[cur_arg + 1], "optional") == 0)
Emeric Brun850efd52014-01-29 12:24:34 +01004772 conf->verify = SSL_SOCK_VERIFY_OPTIONAL;
Emeric Brund94b3fe2012-09-20 18:23:56 +02004773 else if (strcmp(args[cur_arg + 1], "required") == 0)
Emeric Brun850efd52014-01-29 12:24:34 +01004774 conf->verify = SSL_SOCK_VERIFY_REQUIRED;
Emeric Brund94b3fe2012-09-20 18:23:56 +02004775 else {
4776 if (err)
4777 memprintf(err, "'%s' : unknown verify method '%s', only 'none', 'optional', and 'required' are supported\n",
4778 args[cur_arg], args[cur_arg + 1]);
4779 return ERR_ALERT | ERR_FATAL;
4780 }
4781
4782 return 0;
4783}
4784
Willy Tarreau92faadf2012-10-10 23:04:25 +02004785/************** "server" keywords ****************/
4786
Emeric Brunef42d922012-10-11 16:11:36 +02004787/* parse the "ca-file" server keyword */
4788static int srv_parse_ca_file(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
4789{
4790 if (!*args[*cur_arg + 1]) {
4791 if (err)
4792 memprintf(err, "'%s' : missing CAfile path", args[*cur_arg]);
4793 return ERR_ALERT | ERR_FATAL;
4794 }
4795
4796 if ((*args[*cur_arg + 1] != '/') && global.ca_base)
4797 memprintf(&newsrv->ssl_ctx.ca_file, "%s/%s", global.ca_base, args[*cur_arg + 1]);
4798 else
4799 memprintf(&newsrv->ssl_ctx.ca_file, "%s", args[*cur_arg + 1]);
4800
4801 return 0;
4802}
4803
Willy Tarreau92faadf2012-10-10 23:04:25 +02004804/* parse the "check-ssl" server keyword */
4805static int srv_parse_check_ssl(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
4806{
4807 newsrv->check.use_ssl = 1;
4808 if (global.connect_default_ciphers && !newsrv->ssl_ctx.ciphers)
4809 newsrv->ssl_ctx.ciphers = strdup(global.connect_default_ciphers);
Emeric Brun2c86cbf2014-10-30 15:56:50 +01004810 newsrv->ssl_ctx.options |= global.connect_default_ssloptions;
Willy Tarreau92faadf2012-10-10 23:04:25 +02004811 return 0;
4812}
4813
4814/* parse the "ciphers" server keyword */
4815static int srv_parse_ciphers(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
4816{
4817 if (!*args[*cur_arg + 1]) {
4818 memprintf(err, "'%s' : missing cipher suite", args[*cur_arg]);
4819 return ERR_ALERT | ERR_FATAL;
4820 }
4821
4822 free(newsrv->ssl_ctx.ciphers);
4823 newsrv->ssl_ctx.ciphers = strdup(args[*cur_arg + 1]);
4824 return 0;
4825}
4826
Emeric Brunef42d922012-10-11 16:11:36 +02004827/* parse the "crl-file" server keyword */
4828static int srv_parse_crl_file(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
4829{
4830#ifndef X509_V_FLAG_CRL_CHECK
4831 if (err)
4832 memprintf(err, "'%s' : library does not support CRL verify", args[*cur_arg]);
4833 return ERR_ALERT | ERR_FATAL;
4834#else
4835 if (!*args[*cur_arg + 1]) {
4836 if (err)
4837 memprintf(err, "'%s' : missing CRLfile path", args[*cur_arg]);
4838 return ERR_ALERT | ERR_FATAL;
4839 }
4840
4841 if ((*args[*cur_arg + 1] != '/') && global.ca_base)
4842 memprintf(&newsrv->ssl_ctx.crl_file, "%s/%s", global.ca_base, args[*cur_arg + 1]);
4843 else
4844 memprintf(&newsrv->ssl_ctx.crl_file, "%s", args[*cur_arg + 1]);
4845
4846 return 0;
4847#endif
4848}
4849
Emeric Bruna7aa3092012-10-26 12:58:00 +02004850/* parse the "crt" server keyword */
4851static int srv_parse_crt(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
4852{
4853 if (!*args[*cur_arg + 1]) {
4854 if (err)
4855 memprintf(err, "'%s' : missing certificate file path", args[*cur_arg]);
4856 return ERR_ALERT | ERR_FATAL;
4857 }
4858
4859 if ((*args[*cur_arg + 1] != '/') && global.crt_base)
4860 memprintf(&newsrv->ssl_ctx.client_crt, "%s/%s", global.ca_base, args[*cur_arg + 1]);
4861 else
4862 memprintf(&newsrv->ssl_ctx.client_crt, "%s", args[*cur_arg + 1]);
4863
4864 return 0;
4865}
Emeric Brunef42d922012-10-11 16:11:36 +02004866
Willy Tarreau92faadf2012-10-10 23:04:25 +02004867/* parse the "force-sslv3" server keyword */
4868static int srv_parse_force_sslv3(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
4869{
4870 newsrv->ssl_ctx.options |= SRV_SSL_O_USE_SSLV3;
4871 return 0;
4872}
4873
4874/* parse the "force-tlsv10" server keyword */
4875static int srv_parse_force_tlsv10(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
4876{
4877 newsrv->ssl_ctx.options |= SRV_SSL_O_USE_TLSV10;
4878 return 0;
4879}
4880
4881/* parse the "force-tlsv11" server keyword */
4882static int srv_parse_force_tlsv11(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
4883{
4884#if SSL_OP_NO_TLSv1_1
4885 newsrv->ssl_ctx.options |= SRV_SSL_O_USE_TLSV11;
4886 return 0;
4887#else
4888 if (err)
4889 memprintf(err, "'%s' : library does not support protocol TLSv1.1", args[*cur_arg]);
4890 return ERR_ALERT | ERR_FATAL;
4891#endif
4892}
4893
4894/* parse the "force-tlsv12" server keyword */
4895static int srv_parse_force_tlsv12(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
4896{
4897#if SSL_OP_NO_TLSv1_2
4898 newsrv->ssl_ctx.options |= SRV_SSL_O_USE_TLSV12;
4899 return 0;
4900#else
4901 if (err)
4902 memprintf(err, "'%s' : library does not support protocol TLSv1.2", args[*cur_arg]);
4903 return ERR_ALERT | ERR_FATAL;
4904#endif
4905}
4906
Willy Tarreau2a3fb1c2015-02-05 16:47:07 +01004907/* parse the "no-ssl-reuse" server keyword */
4908static int srv_parse_no_ssl_reuse(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
4909{
4910 newsrv->ssl_ctx.options |= SRV_SSL_O_NO_REUSE;
4911 return 0;
4912}
4913
Willy Tarreau92faadf2012-10-10 23:04:25 +02004914/* parse the "no-sslv3" server keyword */
4915static int srv_parse_no_sslv3(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
4916{
4917 newsrv->ssl_ctx.options |= SRV_SSL_O_NO_SSLV3;
4918 return 0;
4919}
4920
4921/* parse the "no-tlsv10" server keyword */
4922static int srv_parse_no_tlsv10(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
4923{
4924 newsrv->ssl_ctx.options |= SRV_SSL_O_NO_TLSV10;
4925 return 0;
4926}
4927
4928/* parse the "no-tlsv11" server keyword */
4929static int srv_parse_no_tlsv11(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
4930{
4931 newsrv->ssl_ctx.options |= SRV_SSL_O_NO_TLSV11;
4932 return 0;
4933}
4934
4935/* parse the "no-tlsv12" server keyword */
4936static int srv_parse_no_tlsv12(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
4937{
4938 newsrv->ssl_ctx.options |= SRV_SSL_O_NO_TLSV12;
4939 return 0;
4940}
4941
Emeric Brunf9c5c472012-10-11 15:28:34 +02004942/* parse the "no-tls-tickets" server keyword */
4943static int srv_parse_no_tls_tickets(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
4944{
4945 newsrv->ssl_ctx.options |= SRV_SSL_O_NO_TLS_TICKETS;
4946 return 0;
4947}
David Safb76832014-05-08 23:42:08 -04004948/* parse the "send-proxy-v2-ssl" server keyword */
4949static int srv_parse_send_proxy_ssl(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
4950{
4951 newsrv->pp_opts |= SRV_PP_V2;
4952 newsrv->pp_opts |= SRV_PP_V2_SSL;
4953 return 0;
4954}
4955
4956/* parse the "send-proxy-v2-ssl-cn" server keyword */
4957static int srv_parse_send_proxy_cn(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
4958{
4959 newsrv->pp_opts |= SRV_PP_V2;
4960 newsrv->pp_opts |= SRV_PP_V2_SSL;
4961 newsrv->pp_opts |= SRV_PP_V2_SSL_CN;
4962 return 0;
4963}
Emeric Brunf9c5c472012-10-11 15:28:34 +02004964
Willy Tarreau732eac42015-07-09 11:40:25 +02004965/* parse the "sni" server keyword */
4966static int srv_parse_sni(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
4967{
4968#ifndef SSL_CTRL_SET_TLSEXT_HOSTNAME
4969 memprintf(err, "'%s' : the current SSL library doesn't support the SNI TLS extension", args[*cur_arg]);
4970 return ERR_ALERT | ERR_FATAL;
4971#else
4972 struct sample_expr *expr;
4973
4974 if (!*args[*cur_arg + 1]) {
4975 memprintf(err, "'%s' : missing sni expression", args[*cur_arg]);
4976 return ERR_ALERT | ERR_FATAL;
4977 }
4978
4979 (*cur_arg)++;
4980 proxy->conf.args.ctx = ARGC_SRV;
4981
4982 expr = sample_parse_expr((char **)args, cur_arg, px->conf.file, px->conf.line, err, &proxy->conf.args);
4983 if (!expr) {
4984 memprintf(err, "error detected while parsing sni expression : %s", *err);
4985 return ERR_ALERT | ERR_FATAL;
4986 }
4987
4988 if (!(expr->fetch->val & SMP_VAL_BE_SRV_CON)) {
4989 memprintf(err, "error detected while parsing sni expression : "
4990 " fetch method '%s' extracts information from '%s', none of which is available here.\n",
4991 args[*cur_arg-1], sample_src_names(expr->fetch->use));
4992 return ERR_ALERT | ERR_FATAL;
4993 }
4994
4995 px->http_needed |= !!(expr->fetch->use & SMP_USE_HTTP_ANY);
4996 newsrv->ssl_ctx.sni = expr;
4997 return 0;
4998#endif
4999}
5000
Willy Tarreau92faadf2012-10-10 23:04:25 +02005001/* parse the "ssl" server keyword */
5002static int srv_parse_ssl(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
5003{
5004 newsrv->use_ssl = 1;
5005 if (global.connect_default_ciphers && !newsrv->ssl_ctx.ciphers)
5006 newsrv->ssl_ctx.ciphers = strdup(global.connect_default_ciphers);
5007 return 0;
5008}
5009
Emeric Brunef42d922012-10-11 16:11:36 +02005010/* parse the "verify" server keyword */
5011static int srv_parse_verify(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
5012{
5013 if (!*args[*cur_arg + 1]) {
5014 if (err)
5015 memprintf(err, "'%s' : missing verify method", args[*cur_arg]);
5016 return ERR_ALERT | ERR_FATAL;
5017 }
5018
5019 if (strcmp(args[*cur_arg + 1], "none") == 0)
Emeric Brun850efd52014-01-29 12:24:34 +01005020 newsrv->ssl_ctx.verify = SSL_SOCK_VERIFY_NONE;
Emeric Brunef42d922012-10-11 16:11:36 +02005021 else if (strcmp(args[*cur_arg + 1], "required") == 0)
Emeric Brun850efd52014-01-29 12:24:34 +01005022 newsrv->ssl_ctx.verify = SSL_SOCK_VERIFY_REQUIRED;
Emeric Brunef42d922012-10-11 16:11:36 +02005023 else {
5024 if (err)
5025 memprintf(err, "'%s' : unknown verify method '%s', only 'none' and 'required' are supported\n",
5026 args[*cur_arg], args[*cur_arg + 1]);
5027 return ERR_ALERT | ERR_FATAL;
5028 }
5029
Evan Broderbe554312013-06-27 00:05:25 -07005030 return 0;
5031}
5032
5033/* parse the "verifyhost" server keyword */
5034static int srv_parse_verifyhost(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
5035{
5036 if (!*args[*cur_arg + 1]) {
5037 if (err)
5038 memprintf(err, "'%s' : missing hostname to verify against", args[*cur_arg]);
5039 return ERR_ALERT | ERR_FATAL;
5040 }
5041
5042 newsrv->ssl_ctx.verify_host = strdup(args[*cur_arg + 1]);
5043
Emeric Brunef42d922012-10-11 16:11:36 +02005044 return 0;
5045}
5046
Emeric Brun2c86cbf2014-10-30 15:56:50 +01005047/* parse the "ssl-default-bind-options" keyword in global section */
5048static int ssl_parse_default_bind_options(char **args, int section_type, struct proxy *curpx,
5049 struct proxy *defpx, const char *file, int line,
5050 char **err) {
5051 int i = 1;
5052
5053 if (*(args[i]) == 0) {
5054 memprintf(err, "global statement '%s' expects an option as an argument.", args[0]);
5055 return -1;
5056 }
5057 while (*(args[i])) {
5058 if (!strcmp(args[i], "no-sslv3"))
5059 global.listen_default_ssloptions |= BC_SSL_O_NO_SSLV3;
5060 else if (!strcmp(args[i], "no-tlsv10"))
5061 global.listen_default_ssloptions |= BC_SSL_O_NO_TLSV10;
5062 else if (!strcmp(args[i], "no-tlsv11"))
5063 global.listen_default_ssloptions |= BC_SSL_O_NO_TLSV11;
5064 else if (!strcmp(args[i], "no-tlsv12"))
5065 global.listen_default_ssloptions |= BC_SSL_O_NO_TLSV12;
5066 else if (!strcmp(args[i], "force-sslv3"))
5067 global.listen_default_ssloptions |= BC_SSL_O_USE_SSLV3;
5068 else if (!strcmp(args[i], "force-tlsv10"))
5069 global.listen_default_ssloptions |= BC_SSL_O_USE_TLSV10;
5070 else if (!strcmp(args[i], "force-tlsv11")) {
5071#if SSL_OP_NO_TLSv1_1
5072 global.listen_default_ssloptions |= BC_SSL_O_USE_TLSV11;
5073#else
5074 memprintf(err, "'%s' '%s': library does not support protocol TLSv1.1", args[0], args[i]);
5075 return -1;
5076#endif
5077 }
5078 else if (!strcmp(args[i], "force-tlsv12")) {
5079#if SSL_OP_NO_TLSv1_2
5080 global.listen_default_ssloptions |= BC_SSL_O_USE_TLSV12;
5081#else
5082 memprintf(err, "'%s' '%s': library does not support protocol TLSv1.2", args[0], args[i]);
5083 return -1;
5084#endif
5085 }
5086 else if (!strcmp(args[i], "no-tls-tickets"))
5087 global.listen_default_ssloptions |= BC_SSL_O_NO_TLS_TICKETS;
5088 else {
5089 memprintf(err, "unknown option '%s' on global statement '%s'.", args[i], args[0]);
5090 return -1;
5091 }
5092 i++;
5093 }
5094 return 0;
5095}
5096
5097/* parse the "ssl-default-server-options" keyword in global section */
5098static int ssl_parse_default_server_options(char **args, int section_type, struct proxy *curpx,
5099 struct proxy *defpx, const char *file, int line,
5100 char **err) {
5101 int i = 1;
5102
5103 if (*(args[i]) == 0) {
5104 memprintf(err, "global statement '%s' expects an option as an argument.", args[0]);
5105 return -1;
5106 }
5107 while (*(args[i])) {
5108 if (!strcmp(args[i], "no-sslv3"))
5109 global.connect_default_ssloptions |= SRV_SSL_O_NO_SSLV3;
5110 else if (!strcmp(args[i], "no-tlsv10"))
5111 global.connect_default_ssloptions |= SRV_SSL_O_NO_TLSV10;
5112 else if (!strcmp(args[i], "no-tlsv11"))
5113 global.connect_default_ssloptions |= SRV_SSL_O_NO_TLSV11;
5114 else if (!strcmp(args[i], "no-tlsv12"))
5115 global.connect_default_ssloptions |= SRV_SSL_O_NO_TLSV12;
5116 else if (!strcmp(args[i], "force-sslv3"))
5117 global.connect_default_ssloptions |= SRV_SSL_O_USE_SSLV3;
5118 else if (!strcmp(args[i], "force-tlsv10"))
5119 global.connect_default_ssloptions |= SRV_SSL_O_USE_TLSV10;
5120 else if (!strcmp(args[i], "force-tlsv11")) {
5121#if SSL_OP_NO_TLSv1_1
5122 global.connect_default_ssloptions |= SRV_SSL_O_USE_TLSV11;
5123#else
5124 memprintf(err, "'%s' '%s': library does not support protocol TLSv1.1", args[0], args[i]);
5125 return -1;
5126#endif
5127 }
5128 else if (!strcmp(args[i], "force-tlsv12")) {
5129#if SSL_OP_NO_TLSv1_2
5130 global.connect_default_ssloptions |= SRV_SSL_O_USE_TLSV12;
5131#else
5132 memprintf(err, "'%s' '%s': library does not support protocol TLSv1.2", args[0], args[i]);
5133 return -1;
5134#endif
5135 }
5136 else if (!strcmp(args[i], "no-tls-tickets"))
5137 global.connect_default_ssloptions |= SRV_SSL_O_NO_TLS_TICKETS;
5138 else {
5139 memprintf(err, "unknown option '%s' on global statement '%s'.", args[i], args[0]);
5140 return -1;
5141 }
5142 i++;
5143 }
5144 return 0;
5145}
5146
Willy Tarreau7875d092012-09-10 08:20:03 +02005147/* Note: must not be declared <const> as its list will be overwritten.
5148 * Please take care of keeping this list alphabetically sorted.
5149 */
Willy Tarreaudc13c112013-06-21 23:16:39 +02005150static struct sample_fetch_kw_list sample_fetch_keywords = {ILH, {
Emeric Brun645ae792014-04-30 14:21:06 +02005151 { "ssl_bc", smp_fetch_ssl_fc, 0, NULL, SMP_T_BOOL, SMP_USE_L5SRV },
Thierry FOURNIER07ee64e2015-07-06 23:43:03 +02005152 { "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 +02005153 { "ssl_bc_cipher", smp_fetch_ssl_fc_cipher, 0, NULL, SMP_T_STR, SMP_USE_L5SRV },
5154 { "ssl_bc_protocol", smp_fetch_ssl_fc_protocol, 0, NULL, SMP_T_STR, SMP_USE_L5SRV },
Emeric Brunb73a9b02014-04-30 18:49:19 +02005155 { "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 +02005156 { "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 +02005157 { "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 +02005158 { "ssl_c_ca_err", smp_fetch_ssl_c_ca_err, 0, NULL, SMP_T_SINT, SMP_USE_L5CLI },
5159 { "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 +01005160 { "ssl_c_der", smp_fetch_ssl_x_der, 0, NULL, SMP_T_BIN, SMP_USE_L5CLI },
Thierry FOURNIER07ee64e2015-07-06 23:43:03 +02005161 { "ssl_c_err", smp_fetch_ssl_c_err, 0, NULL, SMP_T_SINT, SMP_USE_L5CLI },
Emeric Brunba841a12014-04-30 17:05:08 +02005162 { "ssl_c_i_dn", smp_fetch_ssl_x_i_dn, ARG2(0,STR,SINT), NULL, SMP_T_STR, SMP_USE_L5CLI },
5163 { "ssl_c_key_alg", smp_fetch_ssl_x_key_alg, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
5164 { "ssl_c_notafter", smp_fetch_ssl_x_notafter, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
5165 { "ssl_c_notbefore", smp_fetch_ssl_x_notbefore, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
5166 { "ssl_c_sig_alg", smp_fetch_ssl_x_sig_alg, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
5167 { "ssl_c_s_dn", smp_fetch_ssl_x_s_dn, ARG2(0,STR,SINT), NULL, SMP_T_STR, SMP_USE_L5CLI },
5168 { "ssl_c_serial", smp_fetch_ssl_x_serial, 0, NULL, SMP_T_BIN, SMP_USE_L5CLI },
5169 { "ssl_c_sha1", smp_fetch_ssl_x_sha1, 0, NULL, SMP_T_BIN, SMP_USE_L5CLI },
Willy Tarreau80aca902013-01-07 15:42:20 +01005170 { "ssl_c_used", smp_fetch_ssl_c_used, 0, NULL, SMP_T_BOOL, SMP_USE_L5CLI },
Thierry FOURNIER07ee64e2015-07-06 23:43:03 +02005171 { "ssl_c_verify", smp_fetch_ssl_c_verify, 0, NULL, SMP_T_SINT, SMP_USE_L5CLI },
5172 { "ssl_c_version", smp_fetch_ssl_x_version, 0, NULL, SMP_T_SINT, SMP_USE_L5CLI },
Emeric Brun43e79582014-10-29 19:03:26 +01005173 { "ssl_f_der", smp_fetch_ssl_x_der, 0, NULL, SMP_T_BIN, SMP_USE_L5CLI },
Emeric Brunba841a12014-04-30 17:05:08 +02005174 { "ssl_f_i_dn", smp_fetch_ssl_x_i_dn, ARG2(0,STR,SINT), NULL, SMP_T_STR, SMP_USE_L5CLI },
5175 { "ssl_f_key_alg", smp_fetch_ssl_x_key_alg, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
5176 { "ssl_f_notafter", smp_fetch_ssl_x_notafter, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
5177 { "ssl_f_notbefore", smp_fetch_ssl_x_notbefore, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
5178 { "ssl_f_sig_alg", smp_fetch_ssl_x_sig_alg, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
5179 { "ssl_f_s_dn", smp_fetch_ssl_x_s_dn, ARG2(0,STR,SINT), NULL, SMP_T_STR, SMP_USE_L5CLI },
5180 { "ssl_f_serial", smp_fetch_ssl_x_serial, 0, NULL, SMP_T_BIN, SMP_USE_L5CLI },
Emeric Brun55f4fa82014-04-30 17:11:25 +02005181 { "ssl_f_sha1", smp_fetch_ssl_x_sha1, 0, NULL, SMP_T_BIN, SMP_USE_L5CLI },
Thierry FOURNIER07ee64e2015-07-06 23:43:03 +02005182 { "ssl_f_version", smp_fetch_ssl_x_version, 0, NULL, SMP_T_SINT, SMP_USE_L5CLI },
Willy Tarreau80aca902013-01-07 15:42:20 +01005183 { "ssl_fc", smp_fetch_ssl_fc, 0, NULL, SMP_T_BOOL, SMP_USE_L5CLI },
Thierry FOURNIER07ee64e2015-07-06 23:43:03 +02005184 { "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 +01005185 { "ssl_fc_cipher", smp_fetch_ssl_fc_cipher, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
Willy Tarreau80aca902013-01-07 15:42:20 +01005186 { "ssl_fc_has_crt", smp_fetch_ssl_fc_has_crt, 0, NULL, SMP_T_BOOL, SMP_USE_L5CLI },
5187 { "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 +02005188 { "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 +02005189#ifdef OPENSSL_NPN_NEGOTIATED
Thierry FOURNIER7654c9f2013-12-17 00:20:33 +01005190 { "ssl_fc_npn", smp_fetch_ssl_fc_npn, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
Willy Tarreaua33c6542012-10-15 13:19:06 +02005191#endif
Dirkjan Bussink48f1c4e2014-02-13 12:29:42 +01005192#ifdef TLSEXT_TYPE_application_layer_protocol_negotiation
Thierry FOURNIER7654c9f2013-12-17 00:20:33 +01005193 { "ssl_fc_alpn", smp_fetch_ssl_fc_alpn, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
Willy Tarreauab861d32013-04-02 02:30:41 +02005194#endif
Thierry FOURNIER7654c9f2013-12-17 00:20:33 +01005195 { "ssl_fc_protocol", smp_fetch_ssl_fc_protocol, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
Emeric Brunb73a9b02014-04-30 18:49:19 +02005196 { "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 +02005197 { "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 +01005198 { "ssl_fc_session_id", smp_fetch_ssl_fc_session_id, 0, NULL, SMP_T_BIN, SMP_USE_L5CLI },
5199 { "ssl_fc_sni", smp_fetch_ssl_fc_sni, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
Willy Tarreau7875d092012-09-10 08:20:03 +02005200 { NULL, NULL, 0, 0, 0 },
5201}};
5202
5203/* Note: must not be declared <const> as its list will be overwritten.
5204 * Please take care of keeping this list alphabetically sorted.
5205 */
Willy Tarreaudc13c112013-06-21 23:16:39 +02005206static struct acl_kw_list acl_kws = {ILH, {
Thierry FOURNIERc5a4e982014-03-05 16:07:08 +01005207 { "ssl_fc_sni_end", "ssl_fc_sni", PAT_MATCH_END },
5208 { "ssl_fc_sni_reg", "ssl_fc_sni", PAT_MATCH_REG },
Willy Tarreau8ed669b2013-01-11 15:49:37 +01005209 { /* END */ },
Willy Tarreau7875d092012-09-10 08:20:03 +02005210}};
5211
Willy Tarreau79eeafa2012-09-14 07:53:05 +02005212/* Note: must not be declared <const> as its list will be overwritten.
5213 * Please take care of keeping this list alphabetically sorted, doing so helps
5214 * all code contributors.
5215 * Optional keywords are also declared with a NULL ->parse() function so that
5216 * the config parser can report an appropriate error when a known keyword was
5217 * not enabled.
5218 */
Willy Tarreau51fb7652012-09-18 18:24:39 +02005219static struct bind_kw_list bind_kws = { "SSL", { }, {
Nenad Merdanovic05552d42015-02-27 19:56:49 +01005220 { "alpn", bind_parse_alpn, 1 }, /* set ALPN supported protocols */
5221 { "ca-file", bind_parse_ca_file, 1 }, /* set CAfile to process verify on client cert */
5222 { "ca-ignore-err", bind_parse_ignore_err, 1 }, /* set error IDs to ignore on verify depth > 0 */
Christopher Faulet31af49d2015-06-09 17:29:50 +02005223 { "ca-sign-file", bind_parse_ca_sign_file, 1 }, /* set CAFile used to generate and sign server certs */
5224 { "ca-sign-pass", bind_parse_ca_sign_pass, 1 }, /* set CAKey passphrase */
Nenad Merdanovic05552d42015-02-27 19:56:49 +01005225 { "ciphers", bind_parse_ciphers, 1 }, /* set SSL cipher suite */
5226 { "crl-file", bind_parse_crl_file, 1 }, /* set certificat revocation list file use on client cert verify */
5227 { "crt", bind_parse_crt, 1 }, /* load SSL certificates from this location */
5228 { "crt-ignore-err", bind_parse_ignore_err, 1 }, /* set error IDs to ingore on verify depth == 0 */
5229 { "crt-list", bind_parse_crt_list, 1 }, /* load a list of crt from this location */
5230 { "ecdhe", bind_parse_ecdhe, 1 }, /* defines named curve for elliptic curve Diffie-Hellman */
5231 { "force-sslv3", bind_parse_force_sslv3, 0 }, /* force SSLv3 */
5232 { "force-tlsv10", bind_parse_force_tlsv10, 0 }, /* force TLSv10 */
5233 { "force-tlsv11", bind_parse_force_tlsv11, 0 }, /* force TLSv11 */
5234 { "force-tlsv12", bind_parse_force_tlsv12, 0 }, /* force TLSv12 */
Christopher Faulet31af49d2015-06-09 17:29:50 +02005235 { "generate-certificates", bind_parse_generate_certs, 0 }, /* enable the server certificates generation */
Nenad Merdanovic05552d42015-02-27 19:56:49 +01005236 { "no-sslv3", bind_parse_no_sslv3, 0 }, /* disable SSLv3 */
5237 { "no-tlsv10", bind_parse_no_tlsv10, 0 }, /* disable TLSv10 */
5238 { "no-tlsv11", bind_parse_no_tlsv11, 0 }, /* disable TLSv11 */
5239 { "no-tlsv12", bind_parse_no_tlsv12, 0 }, /* disable TLSv12 */
5240 { "no-tls-tickets", bind_parse_no_tls_tickets, 0 }, /* disable session resumption tickets */
5241 { "ssl", bind_parse_ssl, 0 }, /* enable SSL processing */
5242 { "strict-sni", bind_parse_strict_sni, 0 }, /* refuse negotiation if sni doesn't match a certificate */
5243 { "tls-ticket-keys", bind_parse_tls_ticket_keys, 1 }, /* set file to load TLS ticket keys from */
5244 { "verify", bind_parse_verify, 1 }, /* set SSL verify method */
5245 { "npn", bind_parse_npn, 1 }, /* set NPN supported protocols */
Willy Tarreau79eeafa2012-09-14 07:53:05 +02005246 { NULL, NULL, 0 },
5247}};
Emeric Brun46591952012-05-18 15:47:34 +02005248
Willy Tarreau92faadf2012-10-10 23:04:25 +02005249/* Note: must not be declared <const> as its list will be overwritten.
5250 * Please take care of keeping this list alphabetically sorted, doing so helps
5251 * all code contributors.
5252 * Optional keywords are also declared with a NULL ->parse() function so that
5253 * the config parser can report an appropriate error when a known keyword was
5254 * not enabled.
5255 */
5256static struct srv_kw_list srv_kws = { "SSL", { }, {
Emeric Brunef42d922012-10-11 16:11:36 +02005257 { "ca-file", srv_parse_ca_file, 1, 0 }, /* set CAfile to process verify server cert */
Emeric Brunecc91fe2012-10-11 15:05:10 +02005258 { "check-ssl", srv_parse_check_ssl, 0, 0 }, /* enable SSL for health checks */
5259 { "ciphers", srv_parse_ciphers, 1, 0 }, /* select the cipher suite */
Emeric Brunef42d922012-10-11 16:11:36 +02005260 { "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 +02005261 { "crt", srv_parse_crt, 1, 0 }, /* set client certificate */
Emeric Brunecc91fe2012-10-11 15:05:10 +02005262 { "force-sslv3", srv_parse_force_sslv3, 0, 0 }, /* force SSLv3 */
5263 { "force-tlsv10", srv_parse_force_tlsv10, 0, 0 }, /* force TLSv10 */
5264 { "force-tlsv11", srv_parse_force_tlsv11, 0, 0 }, /* force TLSv11 */
5265 { "force-tlsv12", srv_parse_force_tlsv12, 0, 0 }, /* force TLSv12 */
Willy Tarreau2a3fb1c2015-02-05 16:47:07 +01005266 { "no-ssl-reuse", srv_parse_no_ssl_reuse, 0, 0 }, /* disable session reuse */
Emeric Brunecc91fe2012-10-11 15:05:10 +02005267 { "no-sslv3", srv_parse_no_sslv3, 0, 0 }, /* disable SSLv3 */
5268 { "no-tlsv10", srv_parse_no_tlsv10, 0, 0 }, /* disable TLSv10 */
5269 { "no-tlsv11", srv_parse_no_tlsv11, 0, 0 }, /* disable TLSv11 */
5270 { "no-tlsv12", srv_parse_no_tlsv12, 0, 0 }, /* disable TLSv12 */
Emeric Brunf9c5c472012-10-11 15:28:34 +02005271 { "no-tls-tickets", srv_parse_no_tls_tickets, 0, 0 }, /* disable session resumption tickets */
David Safb76832014-05-08 23:42:08 -04005272 { "send-proxy-v2-ssl", srv_parse_send_proxy_ssl, 0, 0 }, /* send PROXY protocol header v2 with SSL info */
5273 { "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 +02005274 { "sni", srv_parse_sni, 1, 0 }, /* send SNI extension */
Emeric Brunecc91fe2012-10-11 15:05:10 +02005275 { "ssl", srv_parse_ssl, 0, 0 }, /* enable SSL processing */
Emeric Brunef42d922012-10-11 16:11:36 +02005276 { "verify", srv_parse_verify, 1, 0 }, /* set SSL verify method */
Evan Broderbe554312013-06-27 00:05:25 -07005277 { "verifyhost", srv_parse_verifyhost, 1, 0 }, /* require that SSL cert verifies for hostname */
Willy Tarreau92faadf2012-10-10 23:04:25 +02005278 { NULL, NULL, 0, 0 },
5279}};
5280
Emeric Brun2c86cbf2014-10-30 15:56:50 +01005281static struct cfg_kw_list cfg_kws = {ILH, {
5282 { CFG_GLOBAL, "ssl-default-bind-options", ssl_parse_default_bind_options },
5283 { CFG_GLOBAL, "ssl-default-server-options", ssl_parse_default_server_options },
5284 { 0, NULL, NULL },
5285}};
5286
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02005287/* transport-layer operations for SSL sockets */
5288struct xprt_ops ssl_sock = {
Emeric Brun46591952012-05-18 15:47:34 +02005289 .snd_buf = ssl_sock_from_buf,
5290 .rcv_buf = ssl_sock_to_buf,
5291 .rcv_pipe = NULL,
5292 .snd_pipe = NULL,
5293 .shutr = NULL,
5294 .shutw = ssl_sock_shutw,
5295 .close = ssl_sock_close,
5296 .init = ssl_sock_init,
5297};
5298
Janusz Dziemidowicz2c701b52015-03-07 23:03:59 +01005299#if (OPENSSL_VERSION_NUMBER >= 0x1000200fL && !defined OPENSSL_NO_TLSEXT && !defined OPENSSL_IS_BORINGSSL)
5300
5301static void ssl_sock_sctl_free_func(void *parent, void *ptr, CRYPTO_EX_DATA *ad, int idx, long argl, void *argp)
5302{
5303 if (ptr) {
5304 chunk_destroy(ptr);
5305 free(ptr);
5306 }
5307}
5308
5309#endif
5310
Emeric Brun46591952012-05-18 15:47:34 +02005311__attribute__((constructor))
Willy Tarreau92faadf2012-10-10 23:04:25 +02005312static void __ssl_sock_init(void)
5313{
Emeric Brun46591952012-05-18 15:47:34 +02005314 STACK_OF(SSL_COMP)* cm;
5315
Willy Tarreau610f04b2014-02-13 11:36:41 +01005316#ifdef LISTEN_DEFAULT_CIPHERS
5317 global.listen_default_ciphers = LISTEN_DEFAULT_CIPHERS;
5318#endif
5319#ifdef CONNECT_DEFAULT_CIPHERS
5320 global.connect_default_ciphers = CONNECT_DEFAULT_CIPHERS;
5321#endif
5322 if (global.listen_default_ciphers)
5323 global.listen_default_ciphers = strdup(global.listen_default_ciphers);
5324 if (global.connect_default_ciphers)
5325 global.connect_default_ciphers = strdup(global.connect_default_ciphers);
Emeric Brun2c86cbf2014-10-30 15:56:50 +01005326 global.listen_default_ssloptions = BC_SSL_O_NONE;
5327 global.connect_default_ssloptions = SRV_SSL_O_NONE;
Willy Tarreau610f04b2014-02-13 11:36:41 +01005328
Emeric Brun46591952012-05-18 15:47:34 +02005329 SSL_library_init();
5330 cm = SSL_COMP_get_compression_methods();
5331 sk_SSL_COMP_zero(cm);
Janusz Dziemidowicz2c701b52015-03-07 23:03:59 +01005332#if (OPENSSL_VERSION_NUMBER >= 0x1000200fL && !defined OPENSSL_NO_TLSEXT && !defined OPENSSL_IS_BORINGSSL)
5333 sctl_ex_index = SSL_CTX_get_ex_new_index(0, NULL, NULL, NULL, ssl_sock_sctl_free_func);
5334#endif
Willy Tarreau7875d092012-09-10 08:20:03 +02005335 sample_register_fetches(&sample_fetch_keywords);
5336 acl_register_keywords(&acl_kws);
Willy Tarreau79eeafa2012-09-14 07:53:05 +02005337 bind_register_keywords(&bind_kws);
Willy Tarreau92faadf2012-10-10 23:04:25 +02005338 srv_register_keywords(&srv_kws);
Emeric Brun2c86cbf2014-10-30 15:56:50 +01005339 cfg_register_keywords(&cfg_kws);
Willy Tarreaud92aa5c2015-01-15 21:34:39 +01005340
5341 global.ssl_session_max_cost = SSL_SESSION_MAX_COST;
5342 global.ssl_handshake_max_cost = SSL_HANDSHAKE_MAX_COST;
Remi Gacogne4f902b82015-05-28 16:23:00 +02005343
5344#ifndef OPENSSL_NO_DH
5345 ssl_dh_ptr_index = SSL_CTX_get_ex_new_index(0, NULL, NULL, NULL, NULL);
5346#endif
Christopher Faulet31af49d2015-06-09 17:29:50 +02005347
Willy Tarreauc8ad3be2015-06-17 15:48:26 +02005348#ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME
Christopher Faulet31af49d2015-06-09 17:29:50 +02005349 /* Add a global parameter for the LRU cache size */
5350 if (global.tune.ssl_ctx_cache)
5351 ssl_ctx_lru_tree = lru64_new(global.tune.ssl_ctx_cache);
5352 ssl_ctx_lru_seed = (unsigned int)time(NULL);
Willy Tarreauc8ad3be2015-06-17 15:48:26 +02005353#endif
Emeric Brun46591952012-05-18 15:47:34 +02005354}
5355
Remi Gacogned3a23c32015-05-28 16:39:47 +02005356__attribute__((destructor))
5357static void __ssl_sock_deinit(void)
5358{
Willy Tarreauc8ad3be2015-06-17 15:48:26 +02005359#ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME
Christopher Faulet31af49d2015-06-09 17:29:50 +02005360 lru64_destroy(ssl_ctx_lru_tree);
Willy Tarreauc8ad3be2015-06-17 15:48:26 +02005361#endif
Christopher Faulet31af49d2015-06-09 17:29:50 +02005362
Remi Gacogned3a23c32015-05-28 16:39:47 +02005363#ifndef OPENSSL_NO_DH
5364 if (local_dh_1024) {
5365 DH_free(local_dh_1024);
5366 local_dh_1024 = NULL;
5367 }
5368
5369 if (local_dh_2048) {
5370 DH_free(local_dh_2048);
5371 local_dh_2048 = NULL;
5372 }
5373
5374 if (local_dh_4096) {
5375 DH_free(local_dh_4096);
5376 local_dh_4096 = NULL;
5377 }
5378
Remi Gacogne47783ef2015-05-29 15:53:22 +02005379 if (global_dh) {
5380 DH_free(global_dh);
5381 global_dh = NULL;
5382 }
Remi Gacogned3a23c32015-05-28 16:39:47 +02005383#endif
5384
5385 ERR_remove_state(0);
5386 ERR_free_strings();
5387
5388 EVP_cleanup();
5389
5390#if OPENSSL_VERSION_NUMBER >= 0x00907000L
5391 CRYPTO_cleanup_all_ex_data();
5392#endif
5393}
5394
5395
Emeric Brun46591952012-05-18 15:47:34 +02005396/*
5397 * Local variables:
5398 * c-indent-level: 8
5399 * c-basic-offset: 8
5400 * End:
5401 */