blob: deb658e98aec9d1d5fdc6e261cec88256b471c25 [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
Christopher Fauletd2cab922015-07-28 16:03:47 +02001130/* Set a certificate int the LRU cache used to store generated
1131 * certificate. Return 0 on success, otherwise -1 */
1132int
Christopher Faulet30548802015-06-11 13:39:32 +02001133ssl_sock_set_generated_cert(SSL_CTX *ssl_ctx, unsigned int serial, X509 *cacert)
1134{
1135 struct lru64 *lru = NULL;
1136
1137 if (ssl_ctx_lru_tree) {
1138 lru = lru64_get(serial, ssl_ctx_lru_tree, cacert, 0);
1139 if (!lru)
Christopher Fauletd2cab922015-07-28 16:03:47 +02001140 return -1;
Christopher Faulet30548802015-06-11 13:39:32 +02001141 if (lru->domain && lru->data)
1142 lru->free((SSL_CTX *)lru->data);
1143 lru64_commit(lru, ssl_ctx, cacert, 0, (void (*)(void *))SSL_CTX_free);
Christopher Fauletd2cab922015-07-28 16:03:47 +02001144 return 0;
Christopher Faulet30548802015-06-11 13:39:32 +02001145 }
Christopher Fauletd2cab922015-07-28 16:03:47 +02001146 return -1;
Christopher Faulet30548802015-06-11 13:39:32 +02001147}
1148
1149/* Compute the serial that will be used to create/set/get a certificate. */
1150unsigned int
Willy Tarreau646b8642015-07-07 18:09:15 +02001151ssl_sock_generated_cert_serial(const void *data, size_t len)
Christopher Faulet30548802015-06-11 13:39:32 +02001152{
1153 return XXH32(data, len, ssl_ctx_lru_seed);
1154}
1155
Christopher Faulet31af49d2015-06-09 17:29:50 +02001156static SSL_CTX *
1157ssl_sock_generate_certificate(const char *servername, struct bind_conf *bind_conf)
1158{
1159 X509 *cacert = bind_conf->ca_sign_cert;
1160 EVP_PKEY *capkey = bind_conf->ca_sign_pkey;
1161 SSL_CTX *ssl_ctx = NULL;
1162 struct lru64 *lru = NULL;
1163 unsigned int serial;
1164
Willy Tarreaufc017fe2015-07-07 18:09:34 +02001165 serial = ssl_sock_generated_cert_serial(servername, strlen(servername));
Christopher Faulet31af49d2015-06-09 17:29:50 +02001166 if (ssl_ctx_lru_tree) {
1167 lru = lru64_get(serial, ssl_ctx_lru_tree, cacert, 0);
1168 if (lru && lru->domain)
1169 ssl_ctx = (SSL_CTX *)lru->data;
Christopher Fauletd2cab922015-07-28 16:03:47 +02001170 if (!ssl_ctx && lru) {
1171 ssl_ctx = ssl_sock_create_cert(servername, serial, cacert, capkey);
Christopher Faulet31af49d2015-06-09 17:29:50 +02001172 lru64_commit(lru, ssl_ctx, cacert, 0, (void (*)(void *))SSL_CTX_free);
Christopher Fauletd2cab922015-07-28 16:03:47 +02001173 }
Christopher Faulet31af49d2015-06-09 17:29:50 +02001174 }
Christopher Fauletd2cab922015-07-28 16:03:47 +02001175 else
1176 ssl_ctx = ssl_sock_create_cert(servername, serial, cacert, capkey);
Christopher Faulet31af49d2015-06-09 17:29:50 +02001177 return ssl_ctx;
1178}
1179
Emeric Brunfc0421f2012-09-07 17:30:07 +02001180/* Sets the SSL ctx of <ssl> to match the advertised server name. Returns a
1181 * warning when no match is found, which implies the default (first) cert
1182 * will keep being used.
1183 */
Willy Tarreau2a65ff02012-09-13 17:54:29 +02001184static int ssl_sock_switchctx_cbk(SSL *ssl, int *al, struct bind_conf *s)
Emeric Brunfc0421f2012-09-07 17:30:07 +02001185{
1186 const char *servername;
1187 const char *wildp = NULL;
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +02001188 struct ebmb_node *node, *n;
Emeric Brunfc0421f2012-09-07 17:30:07 +02001189 int i;
1190 (void)al; /* shut gcc stupid warning */
1191
1192 servername = SSL_get_servername(ssl, TLSEXT_NAMETYPE_host_name);
Emmanuel Hocdet65623372013-01-24 17:17:15 +01001193 if (!servername) {
Willy Tarreauf6721452015-07-07 18:04:38 +02001194 if (s->generate_certs) {
1195 struct connection *conn = (struct connection *)SSL_get_app_data(ssl);
1196 unsigned int serial;
1197 SSL_CTX *ctx;
Christopher Faulet30548802015-06-11 13:39:32 +02001198
Willy Tarreauf6721452015-07-07 18:04:38 +02001199 conn_get_to_addr(conn);
1200 if (conn->flags & CO_FL_ADDR_TO_SET) {
1201 serial = ssl_sock_generated_cert_serial(&conn->addr.to, get_addr_len(&conn->addr.to));
1202 ctx = ssl_sock_get_generated_cert(serial, s->ca_sign_cert);
1203 if (ctx) {
1204 /* switch ctx */
1205 SSL_set_SSL_CTX(ssl, ctx);
1206 return SSL_TLSEXT_ERR_OK;
1207 }
Christopher Faulet30548802015-06-11 13:39:32 +02001208 }
1209 }
1210
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +02001211 return (s->strict_sni ?
1212 SSL_TLSEXT_ERR_ALERT_FATAL :
Emmanuel Hocdet79274e22013-05-31 12:47:44 +02001213 SSL_TLSEXT_ERR_NOACK);
Emmanuel Hocdet65623372013-01-24 17:17:15 +01001214 }
Emeric Brunfc0421f2012-09-07 17:30:07 +02001215
Willy Tarreau19d14ef2012-10-29 16:51:55 +01001216 for (i = 0; i < trash.size; i++) {
Emeric Brunfc0421f2012-09-07 17:30:07 +02001217 if (!servername[i])
1218 break;
Willy Tarreau19d14ef2012-10-29 16:51:55 +01001219 trash.str[i] = tolower(servername[i]);
1220 if (!wildp && (trash.str[i] == '.'))
1221 wildp = &trash.str[i];
Emeric Brunfc0421f2012-09-07 17:30:07 +02001222 }
Willy Tarreau19d14ef2012-10-29 16:51:55 +01001223 trash.str[i] = 0;
Emeric Brunfc0421f2012-09-07 17:30:07 +02001224
1225 /* lookup in full qualified names */
Willy Tarreau19d14ef2012-10-29 16:51:55 +01001226 node = ebst_lookup(&s->sni_ctx, trash.str);
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +02001227
1228 /* lookup a not neg filter */
1229 for (n = node; n; n = ebmb_next_dup(n)) {
1230 if (!container_of(n, struct sni_ctx, name)->neg) {
1231 node = n;
1232 break;
Emmanuel Hocdet65623372013-01-24 17:17:15 +01001233 }
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +02001234 }
1235 if (!node && wildp) {
1236 /* lookup in wildcards names */
Emeric Brunfc0421f2012-09-07 17:30:07 +02001237 node = ebst_lookup(&s->sni_w_ctx, wildp);
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +02001238 }
1239 if (!node || container_of(node, struct sni_ctx, name)->neg) {
Christopher Faulet31af49d2015-06-09 17:29:50 +02001240 SSL_CTX *ctx;
1241
1242 if (s->generate_certs &&
1243 (ctx = ssl_sock_generate_certificate(servername, s))) {
1244 /* switch ctx */
1245 SSL_set_SSL_CTX(ssl, ctx);
1246 return SSL_TLSEXT_ERR_OK;
1247 }
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +02001248 return (s->strict_sni ?
1249 SSL_TLSEXT_ERR_ALERT_FATAL :
1250 SSL_TLSEXT_ERR_ALERT_WARNING);
Emeric Brunfc0421f2012-09-07 17:30:07 +02001251 }
1252
1253 /* switch ctx */
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +02001254 SSL_set_SSL_CTX(ssl, container_of(node, struct sni_ctx, name)->ctx);
Emeric Brunfc0421f2012-09-07 17:30:07 +02001255 return SSL_TLSEXT_ERR_OK;
1256}
1257#endif /* SSL_CTRL_SET_TLSEXT_HOSTNAME */
1258
Emeric Bruna4bcd9a2012-09-20 16:19:02 +02001259#ifndef OPENSSL_NO_DH
Remi Gacognef46cd6e2014-06-12 14:58:40 +02001260
1261static DH * ssl_get_dh_1024(void)
1262{
Remi Gacogned3a341a2015-05-29 16:26:17 +02001263 static unsigned char dh1024_p[]={
1264 0xFA,0xF9,0x2A,0x22,0x2A,0xA7,0x7F,0xE1,0x67,0x4E,0x53,0xF7,
1265 0x56,0x13,0xC3,0xB1,0xE3,0x29,0x6B,0x66,0x31,0x6A,0x7F,0xB3,
1266 0xC2,0x68,0x6B,0xCB,0x1D,0x57,0x39,0x1D,0x1F,0xFF,0x1C,0xC9,
1267 0xA6,0xA4,0x98,0x82,0x31,0x5D,0x25,0xFF,0x8A,0xE0,0x73,0x96,
1268 0x81,0xC8,0x83,0x79,0xC1,0x5A,0x04,0xF8,0x37,0x0D,0xA8,0x3D,
1269 0xAE,0x74,0xBC,0xDB,0xB6,0xA4,0x75,0xD9,0x71,0x8A,0xA0,0x17,
1270 0x9E,0x2D,0xC8,0xA8,0xDF,0x2C,0x5F,0x82,0x95,0xF8,0x92,0x9B,
1271 0xA7,0x33,0x5F,0x89,0x71,0xC8,0x2D,0x6B,0x18,0x86,0xC4,0x94,
1272 0x22,0xA5,0x52,0x8D,0xF6,0xF6,0xD2,0x37,0x92,0x0F,0xA5,0xCC,
1273 0xDB,0x7B,0x1D,0x3D,0xA1,0x31,0xB7,0x80,0x8F,0x0B,0x67,0x5E,
1274 0x36,0xA5,0x60,0x0C,0xF1,0x95,0x33,0x8B,
1275 };
1276 static unsigned char dh1024_g[]={
1277 0x02,
1278 };
1279
Remi Gacognef46cd6e2014-06-12 14:58:40 +02001280 DH *dh = DH_new();
1281 if (dh) {
Remi Gacogned3a341a2015-05-29 16:26:17 +02001282 dh->p = BN_bin2bn(dh1024_p, sizeof dh1024_p, NULL);
1283 dh->g = BN_bin2bn(dh1024_g, sizeof dh1024_g, NULL);
1284
Remi Gacognef46cd6e2014-06-12 14:58:40 +02001285 if (!dh->p || !dh->g) {
1286 DH_free(dh);
1287 dh = NULL;
1288 }
1289 }
1290 return dh;
1291}
1292
1293static DH *ssl_get_dh_2048(void)
1294{
Remi Gacogned3a341a2015-05-29 16:26:17 +02001295 static unsigned char dh2048_p[]={
1296 0xEC,0x86,0xF8,0x70,0xA0,0x33,0x16,0xEC,0x05,0x1A,0x73,0x59,
1297 0xCD,0x1F,0x8B,0xF8,0x29,0xE4,0xD2,0xCF,0x52,0xDD,0xC2,0x24,
1298 0x8D,0xB5,0x38,0x9A,0xFB,0x5C,0xA4,0xE4,0xB2,0xDA,0xCE,0x66,
1299 0x50,0x74,0xA6,0x85,0x4D,0x4B,0x1D,0x30,0xB8,0x2B,0xF3,0x10,
1300 0xE9,0xA7,0x2D,0x05,0x71,0xE7,0x81,0xDF,0x8B,0x59,0x52,0x3B,
1301 0x5F,0x43,0x0B,0x68,0xF1,0xDB,0x07,0xBE,0x08,0x6B,0x1B,0x23,
1302 0xEE,0x4D,0xCC,0x9E,0x0E,0x43,0xA0,0x1E,0xDF,0x43,0x8C,0xEC,
1303 0xBE,0xBE,0x90,0xB4,0x51,0x54,0xB9,0x2F,0x7B,0x64,0x76,0x4E,
1304 0x5D,0xD4,0x2E,0xAE,0xC2,0x9E,0xAE,0x51,0x43,0x59,0xC7,0x77,
1305 0x9C,0x50,0x3C,0x0E,0xED,0x73,0x04,0x5F,0xF1,0x4C,0x76,0x2A,
1306 0xD8,0xF8,0xCF,0xFC,0x34,0x40,0xD1,0xB4,0x42,0x61,0x84,0x66,
1307 0x42,0x39,0x04,0xF8,0x68,0xB2,0x62,0xD7,0x55,0xED,0x1B,0x74,
1308 0x75,0x91,0xE0,0xC5,0x69,0xC1,0x31,0x5C,0xDB,0x7B,0x44,0x2E,
1309 0xCE,0x84,0x58,0x0D,0x1E,0x66,0x0C,0xC8,0x44,0x9E,0xFD,0x40,
1310 0x08,0x67,0x5D,0xFB,0xA7,0x76,0x8F,0x00,0x11,0x87,0xE9,0x93,
1311 0xF9,0x7D,0xC4,0xBC,0x74,0x55,0x20,0xD4,0x4A,0x41,0x2F,0x43,
1312 0x42,0x1A,0xC1,0xF2,0x97,0x17,0x49,0x27,0x37,0x6B,0x2F,0x88,
1313 0x7E,0x1C,0xA0,0xA1,0x89,0x92,0x27,0xD9,0x56,0x5A,0x71,0xC1,
1314 0x56,0x37,0x7E,0x3A,0x9D,0x05,0xE7,0xEE,0x5D,0x8F,0x82,0x17,
1315 0xBC,0xE9,0xC2,0x93,0x30,0x82,0xF9,0xF4,0xC9,0xAE,0x49,0xDB,
1316 0xD0,0x54,0xB4,0xD9,0x75,0x4D,0xFA,0x06,0xB8,0xD6,0x38,0x41,
1317 0xB7,0x1F,0x77,0xF3,
1318 };
1319 static unsigned char dh2048_g[]={
1320 0x02,
1321 };
1322
Remi Gacognef46cd6e2014-06-12 14:58:40 +02001323 DH *dh = DH_new();
1324 if (dh) {
Remi Gacogned3a341a2015-05-29 16:26:17 +02001325 dh->p = BN_bin2bn(dh2048_p, sizeof dh2048_p, NULL);
1326 dh->g = BN_bin2bn(dh2048_g, sizeof dh2048_g, NULL);
1327
Remi Gacognef46cd6e2014-06-12 14:58:40 +02001328 if (!dh->p || !dh->g) {
1329 DH_free(dh);
1330 dh = NULL;
1331 }
1332 }
1333 return dh;
1334}
1335
1336static DH *ssl_get_dh_4096(void)
1337{
Remi Gacogned3a341a2015-05-29 16:26:17 +02001338 static unsigned char dh4096_p[]={
1339 0xDE,0x16,0x94,0xCD,0x99,0x58,0x07,0xF1,0xF7,0x32,0x96,0x11,
1340 0x04,0x82,0xD4,0x84,0x72,0x80,0x99,0x06,0xCA,0xF0,0xA3,0x68,
1341 0x07,0xCE,0x64,0x50,0xE7,0x74,0x45,0x20,0x80,0x5E,0x4D,0xAD,
1342 0xA5,0xB6,0xED,0xFA,0x80,0x6C,0x3B,0x35,0xC4,0x9A,0x14,0x6B,
1343 0x32,0xBB,0xFD,0x1F,0x17,0x8E,0xB7,0x1F,0xD6,0xFA,0x3F,0x7B,
1344 0xEE,0x16,0xA5,0x62,0x33,0x0D,0xED,0xBC,0x4E,0x58,0xE5,0x47,
1345 0x4D,0xE9,0xAB,0x8E,0x38,0xD3,0x6E,0x90,0x57,0xE3,0x22,0x15,
1346 0x33,0xBD,0xF6,0x43,0x45,0xB5,0x10,0x0A,0xBE,0x2C,0xB4,0x35,
1347 0xB8,0x53,0x8D,0xAD,0xFB,0xA7,0x1F,0x85,0x58,0x41,0x7A,0x79,
1348 0x20,0x68,0xB3,0xE1,0x3D,0x08,0x76,0xBF,0x86,0x0D,0x49,0xE3,
1349 0x82,0x71,0x8C,0xB4,0x8D,0x81,0x84,0xD4,0xE7,0xBE,0x91,0xDC,
1350 0x26,0x39,0x48,0x0F,0x35,0xC4,0xCA,0x65,0xE3,0x40,0x93,0x52,
1351 0x76,0x58,0x7D,0xDD,0x51,0x75,0xDC,0x69,0x61,0xBF,0x47,0x2C,
1352 0x16,0x68,0x2D,0xC9,0x29,0xD3,0xE6,0xC0,0x99,0x48,0xA0,0x9A,
1353 0xC8,0x78,0xC0,0x6D,0x81,0x67,0x12,0x61,0x3F,0x71,0xBA,0x41,
1354 0x1F,0x6C,0x89,0x44,0x03,0xBA,0x3B,0x39,0x60,0xAA,0x28,0x55,
1355 0x59,0xAE,0xB8,0xFA,0xCB,0x6F,0xA5,0x1A,0xF7,0x2B,0xDD,0x52,
1356 0x8A,0x8B,0xE2,0x71,0xA6,0x5E,0x7E,0xD8,0x2E,0x18,0xE0,0x66,
1357 0xDF,0xDD,0x22,0x21,0x99,0x52,0x73,0xA6,0x33,0x20,0x65,0x0E,
1358 0x53,0xE7,0x6B,0x9B,0xC5,0xA3,0x2F,0x97,0x65,0x76,0xD3,0x47,
1359 0x23,0x77,0x12,0xB6,0x11,0x7B,0x24,0xED,0xF1,0xEF,0xC0,0xE2,
1360 0xA3,0x7E,0x67,0x05,0x3E,0x96,0x4D,0x45,0xC2,0x18,0xD1,0x73,
1361 0x9E,0x07,0xF3,0x81,0x6E,0x52,0x63,0xF6,0x20,0x76,0xB9,0x13,
1362 0xD2,0x65,0x30,0x18,0x16,0x09,0x16,0x9E,0x8F,0xF1,0xD2,0x10,
1363 0x5A,0xD3,0xD4,0xAF,0x16,0x61,0xDA,0x55,0x2E,0x18,0x5E,0x14,
1364 0x08,0x54,0x2E,0x2A,0x25,0xA2,0x1A,0x9B,0x8B,0x32,0xA9,0xFD,
1365 0xC2,0x48,0x96,0xE1,0x80,0xCA,0xE9,0x22,0x17,0xBB,0xCE,0x3E,
1366 0x9E,0xED,0xC7,0xF1,0x1F,0xEC,0x17,0x21,0xDC,0x7B,0x82,0x48,
1367 0x8E,0xBB,0x4B,0x9D,0x5B,0x04,0x04,0xDA,0xDB,0x39,0xDF,0x01,
1368 0x40,0xC3,0xAA,0x26,0x23,0x89,0x75,0xC6,0x0B,0xD0,0xA2,0x60,
1369 0x6A,0xF1,0xCC,0x65,0x18,0x98,0x1B,0x52,0xD2,0x74,0x61,0xCC,
1370 0xBD,0x60,0xAE,0xA3,0xA0,0x66,0x6A,0x16,0x34,0x92,0x3F,0x41,
1371 0x40,0x31,0x29,0xC0,0x2C,0x63,0xB2,0x07,0x8D,0xEB,0x94,0xB8,
1372 0xE8,0x47,0x92,0x52,0x93,0x6A,0x1B,0x7E,0x1A,0x61,0xB3,0x1B,
1373 0xF0,0xD6,0x72,0x9B,0xF1,0xB0,0xAF,0xBF,0x3E,0x65,0xEF,0x23,
1374 0x1D,0x6F,0xFF,0x70,0xCD,0x8A,0x4C,0x8A,0xA0,0x72,0x9D,0xBE,
1375 0xD4,0xBB,0x24,0x47,0x4A,0x68,0xB5,0xF5,0xC6,0xD5,0x7A,0xCD,
1376 0xCA,0x06,0x41,0x07,0xAD,0xC2,0x1E,0xE6,0x54,0xA7,0xAD,0x03,
1377 0xD9,0x12,0xC1,0x9C,0x13,0xB1,0xC9,0x0A,0x43,0x8E,0x1E,0x08,
1378 0xCE,0x50,0x82,0x73,0x5F,0xA7,0x55,0x1D,0xD9,0x59,0xAC,0xB5,
1379 0xEA,0x02,0x7F,0x6C,0x5B,0x74,0x96,0x98,0x67,0x24,0xA3,0x0F,
1380 0x15,0xFC,0xA9,0x7D,0x3E,0x67,0xD1,0x70,0xF8,0x97,0xF3,0x67,
1381 0xC5,0x8C,0x88,0x44,0x08,0x02,0xC7,0x2B,
Remi Gacognef46cd6e2014-06-12 14:58:40 +02001382 };
Remi Gacogned3a341a2015-05-29 16:26:17 +02001383 static unsigned char dh4096_g[]={
1384 0x02,
1385 };
Remi Gacognef46cd6e2014-06-12 14:58:40 +02001386
Remi Gacognef46cd6e2014-06-12 14:58:40 +02001387 DH *dh = DH_new();
1388 if (dh) {
Remi Gacogned3a341a2015-05-29 16:26:17 +02001389 dh->p = BN_bin2bn(dh4096_p, sizeof dh4096_p, NULL);
1390 dh->g = BN_bin2bn(dh4096_g, sizeof dh4096_g, NULL);
1391
Remi Gacognef46cd6e2014-06-12 14:58:40 +02001392 if (!dh->p || !dh->g) {
1393 DH_free(dh);
1394 dh = NULL;
1395 }
1396 }
1397 return dh;
1398}
1399
1400/* Returns Diffie-Hellman parameters matching the private key length
1401 but not exceeding global.tune.ssl_default_dh_param */
1402static DH *ssl_get_tmp_dh(SSL *ssl, int export, int keylen)
1403{
1404 DH *dh = NULL;
1405 EVP_PKEY *pkey = SSL_get_privatekey(ssl);
1406 int type = pkey ? EVP_PKEY_type(pkey->type) : EVP_PKEY_NONE;
1407
1408 /* The keylen supplied by OpenSSL can only be 512 or 1024.
1409 See ssl3_send_server_key_exchange() in ssl/s3_srvr.c
1410 */
1411 if (type == EVP_PKEY_RSA || type == EVP_PKEY_DSA) {
1412 keylen = EVP_PKEY_bits(pkey);
1413 }
1414
1415 if (keylen > global.tune.ssl_default_dh_param) {
1416 keylen = global.tune.ssl_default_dh_param;
1417 }
1418
Remi Gacogned3a341a2015-05-29 16:26:17 +02001419 if (keylen >= 4096) {
Remi Gacogne8de54152014-07-15 11:36:40 +02001420 dh = local_dh_4096;
Remi Gacognef46cd6e2014-06-12 14:58:40 +02001421 }
1422 else if (keylen >= 2048) {
Remi Gacogne8de54152014-07-15 11:36:40 +02001423 dh = local_dh_2048;
Remi Gacognef46cd6e2014-06-12 14:58:40 +02001424 }
1425 else {
Remi Gacogne8de54152014-07-15 11:36:40 +02001426 dh = local_dh_1024;
Remi Gacognef46cd6e2014-06-12 14:58:40 +02001427 }
1428
1429 return dh;
1430}
1431
Remi Gacogne47783ef2015-05-29 15:53:22 +02001432static DH * ssl_sock_get_dh_from_file(const char *filename)
Emeric Bruna4bcd9a2012-09-20 16:19:02 +02001433{
Emeric Bruna4bcd9a2012-09-20 16:19:02 +02001434 DH *dh = NULL;
Remi Gacogne47783ef2015-05-29 15:53:22 +02001435 BIO *in = BIO_new(BIO_s_file());
Emeric Bruna4bcd9a2012-09-20 16:19:02 +02001436
Emeric Bruna4bcd9a2012-09-20 16:19:02 +02001437 if (in == NULL)
1438 goto end;
1439
Remi Gacogne47783ef2015-05-29 15:53:22 +02001440 if (BIO_read_filename(in, filename) <= 0)
Emeric Bruna4bcd9a2012-09-20 16:19:02 +02001441 goto end;
1442
Remi Gacogne47783ef2015-05-29 15:53:22 +02001443 dh = PEM_read_bio_DHparams(in, NULL, NULL, NULL);
1444
1445end:
1446 if (in)
1447 BIO_free(in);
1448
1449 return dh;
1450}
1451
1452int ssl_sock_load_global_dh_param_from_file(const char *filename)
1453{
1454 global_dh = ssl_sock_get_dh_from_file(filename);
1455
1456 if (global_dh) {
1457 return 0;
1458 }
1459
1460 return -1;
1461}
1462
1463/* Loads Diffie-Hellman parameter from a file. Returns 1 if loaded, else -1
1464 if an error occured, and 0 if parameter not found. */
1465int ssl_sock_load_dh_params(SSL_CTX *ctx, const char *file)
1466{
1467 int ret = -1;
1468 DH *dh = ssl_sock_get_dh_from_file(file);
1469
Remi Gacognef46cd6e2014-06-12 14:58:40 +02001470 if (dh) {
1471 ret = 1;
1472 SSL_CTX_set_tmp_dh(ctx, dh);
Remi Gacogne4f902b82015-05-28 16:23:00 +02001473
1474 if (ssl_dh_ptr_index >= 0) {
1475 /* store a pointer to the DH params to avoid complaining about
1476 ssl-default-dh-param not being set for this SSL_CTX */
1477 SSL_CTX_set_ex_data(ctx, ssl_dh_ptr_index, dh);
1478 }
Remi Gacognef46cd6e2014-06-12 14:58:40 +02001479 }
Remi Gacogne47783ef2015-05-29 15:53:22 +02001480 else if (global_dh) {
1481 SSL_CTX_set_tmp_dh(ctx, global_dh);
1482 ret = 0; /* DH params not found */
1483 }
Remi Gacognef46cd6e2014-06-12 14:58:40 +02001484 else {
Emeric Brun41fdb3c2013-04-26 11:05:44 +02001485 /* Clear openssl global errors stack */
1486 ERR_clear_error();
1487
Remi Gacognef46cd6e2014-06-12 14:58:40 +02001488 if (global.tune.ssl_default_dh_param <= 1024) {
1489 /* we are limited to DH parameter of 1024 bits anyway */
Remi Gacogne8de54152014-07-15 11:36:40 +02001490 local_dh_1024 = ssl_get_dh_1024();
1491 if (local_dh_1024 == NULL)
Remi Gacognef46cd6e2014-06-12 14:58:40 +02001492 goto end;
Willy Tarreau6e774b42014-04-25 21:35:23 +02001493
Remi Gacogne8de54152014-07-15 11:36:40 +02001494 SSL_CTX_set_tmp_dh(ctx, local_dh_1024);
Remi Gacognef46cd6e2014-06-12 14:58:40 +02001495 }
1496 else {
1497 SSL_CTX_set_tmp_dh_callback(ctx, ssl_get_tmp_dh);
1498 }
Willy Tarreau6e774b42014-04-25 21:35:23 +02001499
Emeric Brun41fdb3c2013-04-26 11:05:44 +02001500 ret = 0; /* DH params not found */
Emeric Bruna4bcd9a2012-09-20 16:19:02 +02001501 }
Emeric Brun644cde02012-12-14 11:21:13 +01001502
Emeric Bruna4bcd9a2012-09-20 16:19:02 +02001503end:
1504 if (dh)
1505 DH_free(dh);
1506
Emeric Bruna4bcd9a2012-09-20 16:19:02 +02001507 return ret;
1508}
1509#endif
1510
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +02001511static int ssl_sock_add_cert_sni(SSL_CTX *ctx, struct bind_conf *s, char *name, int order)
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01001512{
1513 struct sni_ctx *sc;
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +02001514 int wild = 0, neg = 0;
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01001515
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +02001516 if (*name == '!') {
1517 neg = 1;
1518 name++;
1519 }
1520 if (*name == '*') {
1521 wild = 1;
1522 name++;
1523 }
1524 /* !* filter is a nop */
1525 if (neg && wild)
1526 return order;
1527 if (*name) {
1528 int j, len;
1529 len = strlen(name);
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01001530 sc = malloc(sizeof(struct sni_ctx) + len + 1);
1531 for (j = 0; j < len; j++)
1532 sc->name.key[j] = tolower(name[j]);
1533 sc->name.key[len] = 0;
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01001534 sc->ctx = ctx;
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +02001535 sc->order = order++;
1536 sc->neg = neg;
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01001537 if (wild)
1538 ebst_insert(&s->sni_w_ctx, &sc->name);
1539 else
1540 ebst_insert(&s->sni_ctx, &sc->name);
1541 }
1542 return order;
1543}
1544
Emeric Brunfc0421f2012-09-07 17:30:07 +02001545/* Loads a certificate key and CA chain from a file. Returns 0 on error, -1 if
1546 * an early error happens and the caller must call SSL_CTX_free() by itelf.
1547 */
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +02001548static 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 +02001549{
1550 BIO *in;
1551 X509 *x = NULL, *ca;
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +02001552 int i, err;
Emeric Brunfc0421f2012-09-07 17:30:07 +02001553 int ret = -1;
1554 int order = 0;
1555 X509_NAME *xname;
1556 char *str;
Emeric Brunfc0421f2012-09-07 17:30:07 +02001557#ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME
1558 STACK_OF(GENERAL_NAME) *names;
1559#endif
1560
1561 in = BIO_new(BIO_s_file());
1562 if (in == NULL)
1563 goto end;
1564
1565 if (BIO_read_filename(in, file) <= 0)
1566 goto end;
1567
1568 x = PEM_read_bio_X509_AUX(in, NULL, ctx->default_passwd_callback, ctx->default_passwd_callback_userdata);
1569 if (x == NULL)
1570 goto end;
1571
Emeric Brun50bcecc2013-04-22 13:05:23 +02001572 if (fcount) {
1573 while (fcount--)
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +02001574 order = ssl_sock_add_cert_sni(ctx, s, sni_filter[fcount], order);
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01001575 }
1576 else {
Emeric Brunfc0421f2012-09-07 17:30:07 +02001577#ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01001578 names = X509_get_ext_d2i(x, NID_subject_alt_name, NULL, NULL);
1579 if (names) {
1580 for (i = 0; i < sk_GENERAL_NAME_num(names); i++) {
1581 GENERAL_NAME *name = sk_GENERAL_NAME_value(names, i);
1582 if (name->type == GEN_DNS) {
1583 if (ASN1_STRING_to_UTF8((unsigned char **)&str, name->d.dNSName) >= 0) {
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +02001584 order = ssl_sock_add_cert_sni(ctx, s, str, order);
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01001585 OPENSSL_free(str);
Emeric Brunfc0421f2012-09-07 17:30:07 +02001586 }
Emeric Brunfc0421f2012-09-07 17:30:07 +02001587 }
1588 }
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01001589 sk_GENERAL_NAME_pop_free(names, GENERAL_NAME_free);
Emeric Brunfc0421f2012-09-07 17:30:07 +02001590 }
Emeric Brunfc0421f2012-09-07 17:30:07 +02001591#endif /* SSL_CTRL_SET_TLSEXT_HOSTNAME */
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01001592 xname = X509_get_subject_name(x);
1593 i = -1;
1594 while ((i = X509_NAME_get_index_by_NID(xname, NID_commonName, i)) != -1) {
1595 X509_NAME_ENTRY *entry = X509_NAME_get_entry(xname, i);
1596 if (ASN1_STRING_to_UTF8((unsigned char **)&str, entry->value) >= 0) {
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +02001597 order = ssl_sock_add_cert_sni(ctx, s, str, order);
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01001598 OPENSSL_free(str);
Emeric Brunfc0421f2012-09-07 17:30:07 +02001599 }
Emeric Brunfc0421f2012-09-07 17:30:07 +02001600 }
1601 }
1602
1603 ret = 0; /* the caller must not free the SSL_CTX argument anymore */
1604 if (!SSL_CTX_use_certificate(ctx, x))
1605 goto end;
1606
1607 if (ctx->extra_certs != NULL) {
1608 sk_X509_pop_free(ctx->extra_certs, X509_free);
1609 ctx->extra_certs = NULL;
1610 }
1611
1612 while ((ca = PEM_read_bio_X509(in, NULL, ctx->default_passwd_callback, ctx->default_passwd_callback_userdata))) {
1613 if (!SSL_CTX_add_extra_chain_cert(ctx, ca)) {
1614 X509_free(ca);
1615 goto end;
1616 }
1617 }
1618
1619 err = ERR_get_error();
1620 if (!err || (ERR_GET_LIB(err) == ERR_LIB_PEM && ERR_GET_REASON(err) == PEM_R_NO_START_LINE)) {
1621 /* we successfully reached the last cert in the file */
1622 ret = 1;
1623 }
1624 ERR_clear_error();
1625
1626end:
1627 if (x)
1628 X509_free(x);
1629
1630 if (in)
1631 BIO_free(in);
1632
1633 return ret;
1634}
1635
Emeric Brun50bcecc2013-04-22 13:05:23 +02001636static 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 +02001637{
1638 int ret;
1639 SSL_CTX *ctx;
1640
1641 ctx = SSL_CTX_new(SSLv23_server_method());
1642 if (!ctx) {
Willy Tarreaueb6cead2012-09-20 19:43:14 +02001643 memprintf(err, "%sunable to allocate SSL context for cert '%s'.\n",
1644 err && *err ? *err : "", path);
Emeric Brunfc0421f2012-09-07 17:30:07 +02001645 return 1;
1646 }
1647
1648 if (SSL_CTX_use_PrivateKey_file(ctx, path, SSL_FILETYPE_PEM) <= 0) {
Willy Tarreaueb6cead2012-09-20 19:43:14 +02001649 memprintf(err, "%sunable to load SSL private key from PEM file '%s'.\n",
1650 err && *err ? *err : "", path);
Emeric Brunfc0421f2012-09-07 17:30:07 +02001651 SSL_CTX_free(ctx);
1652 return 1;
1653 }
1654
Emeric Brun50bcecc2013-04-22 13:05:23 +02001655 ret = ssl_sock_load_cert_chain_file(ctx, path, bind_conf, sni_filter, fcount);
Emeric Brunfc0421f2012-09-07 17:30:07 +02001656 if (ret <= 0) {
Willy Tarreaueb6cead2012-09-20 19:43:14 +02001657 memprintf(err, "%sunable to load SSL certificate from PEM file '%s'.\n",
1658 err && *err ? *err : "", path);
Emeric Brunfc0421f2012-09-07 17:30:07 +02001659 if (ret < 0) /* serious error, must do that ourselves */
1660 SSL_CTX_free(ctx);
1661 return 1;
1662 }
Emeric Brun61694ab2012-10-26 13:35:33 +02001663
1664 if (SSL_CTX_check_private_key(ctx) <= 0) {
1665 memprintf(err, "%sinconsistencies between private key and certificate loaded from PEM file '%s'.\n",
1666 err && *err ? *err : "", path);
1667 return 1;
1668 }
1669
Emeric Brunfc0421f2012-09-07 17:30:07 +02001670 /* we must not free the SSL_CTX anymore below, since it's already in
1671 * the tree, so it will be discovered and cleaned in time.
1672 */
Emeric Bruna4bcd9a2012-09-20 16:19:02 +02001673#ifndef OPENSSL_NO_DH
Remi Gacogne4f902b82015-05-28 16:23:00 +02001674 /* store a NULL pointer to indicate we have not yet loaded
1675 a custom DH param file */
1676 if (ssl_dh_ptr_index >= 0) {
1677 SSL_CTX_set_ex_data(ctx, ssl_dh_ptr_index, NULL);
1678 }
1679
Emeric Bruna4bcd9a2012-09-20 16:19:02 +02001680 ret = ssl_sock_load_dh_params(ctx, path);
1681 if (ret < 0) {
1682 if (err)
1683 memprintf(err, "%sunable to load DH parameters from file '%s'.\n",
1684 *err ? *err : "", path);
1685 return 1;
1686 }
1687#endif
1688
Lukas Tribuse4e30f72014-12-09 16:32:51 +01001689#if (defined SSL_CTRL_SET_TLSEXT_STATUS_REQ_CB && !defined OPENSSL_NO_OCSP)
Emeric Brun4147b2e2014-06-16 18:36:30 +02001690 ret = ssl_sock_load_ocsp(ctx, path);
1691 if (ret < 0) {
1692 if (err)
1693 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",
1694 *err ? *err : "", path);
1695 return 1;
1696 }
1697#endif
1698
Janusz Dziemidowicz2c701b52015-03-07 23:03:59 +01001699#if (OPENSSL_VERSION_NUMBER >= 0x1000200fL && !defined OPENSSL_NO_TLSEXT && !defined OPENSSL_IS_BORINGSSL)
1700 if (sctl_ex_index >= 0) {
1701 ret = ssl_sock_load_sctl(ctx, path);
1702 if (ret < 0) {
1703 if (err)
1704 memprintf(err, "%s '%s.sctl' is present but cannot be read or parsed'.\n",
1705 *err ? *err : "", path);
1706 return 1;
1707 }
1708 }
1709#endif
1710
Emeric Brunfc0421f2012-09-07 17:30:07 +02001711#ifndef SSL_CTRL_SET_TLSEXT_HOSTNAME
Willy Tarreau2a65ff02012-09-13 17:54:29 +02001712 if (bind_conf->default_ctx) {
Willy Tarreaueb6cead2012-09-20 19:43:14 +02001713 memprintf(err, "%sthis version of openssl cannot load multiple SSL certificates.\n",
1714 err && *err ? *err : "");
Emeric Brunfc0421f2012-09-07 17:30:07 +02001715 return 1;
1716 }
1717#endif
Willy Tarreau2a65ff02012-09-13 17:54:29 +02001718 if (!bind_conf->default_ctx)
1719 bind_conf->default_ctx = ctx;
Emeric Brunfc0421f2012-09-07 17:30:07 +02001720
1721 return 0;
1722}
1723
Willy Tarreau79eeafa2012-09-14 07:53:05 +02001724int ssl_sock_load_cert(char *path, struct bind_conf *bind_conf, struct proxy *curproxy, char **err)
Emeric Brunfc0421f2012-09-07 17:30:07 +02001725{
Cyril Bonté3180f7b2015-01-25 00:16:08 +01001726 struct dirent **de_list;
1727 int i, n;
Emeric Brunfc0421f2012-09-07 17:30:07 +02001728 DIR *dir;
1729 struct stat buf;
Willy Tarreauee2663b2012-12-06 11:36:59 +01001730 char *end;
1731 char fp[MAXPATHLEN+1];
Emeric Brunfc0421f2012-09-07 17:30:07 +02001732 int cfgerr = 0;
1733
1734 if (!(dir = opendir(path)))
Emeric Brun50bcecc2013-04-22 13:05:23 +02001735 return ssl_sock_load_cert_file(path, bind_conf, curproxy, NULL, 0, err);
Emeric Brunfc0421f2012-09-07 17:30:07 +02001736
1737 /* strip trailing slashes, including first one */
1738 for (end = path + strlen(path) - 1; end >= path && *end == '/'; end--)
1739 *end = 0;
1740
Cyril Bonté3180f7b2015-01-25 00:16:08 +01001741 n = scandir(path, &de_list, 0, alphasort);
1742 if (n < 0) {
1743 memprintf(err, "%sunable to scan directory '%s' : %s.\n",
1744 err && *err ? *err : "", path, strerror(errno));
1745 cfgerr++;
1746 }
1747 else {
1748 for (i = 0; i < n; i++) {
1749 struct dirent *de = de_list[i];
Emeric Brun2aab7222014-06-18 18:15:09 +02001750
Cyril Bonté3180f7b2015-01-25 00:16:08 +01001751 end = strrchr(de->d_name, '.');
Janusz Dziemidowicz2c701b52015-03-07 23:03:59 +01001752 if (end && (!strcmp(end, ".issuer") || !strcmp(end, ".ocsp") || !strcmp(end, ".sctl")))
Cyril Bonté3180f7b2015-01-25 00:16:08 +01001753 goto ignore_entry;
1754
1755 snprintf(fp, sizeof(fp), "%s/%s", path, de->d_name);
1756 if (stat(fp, &buf) != 0) {
1757 memprintf(err, "%sunable to stat SSL certificate from file '%s' : %s.\n",
1758 err && *err ? *err : "", fp, strerror(errno));
1759 cfgerr++;
1760 goto ignore_entry;
1761 }
1762 if (!S_ISREG(buf.st_mode))
1763 goto ignore_entry;
1764 cfgerr += ssl_sock_load_cert_file(fp, bind_conf, curproxy, NULL, 0, err);
1765 ignore_entry:
1766 free(de);
Emeric Brunfc0421f2012-09-07 17:30:07 +02001767 }
Cyril Bonté3180f7b2015-01-25 00:16:08 +01001768 free(de_list);
Emeric Brunfc0421f2012-09-07 17:30:07 +02001769 }
Emeric Brunfc0421f2012-09-07 17:30:07 +02001770 closedir(dir);
1771 return cfgerr;
1772}
1773
Thierry Fournier383085f2013-01-24 14:15:43 +01001774/* Make sure openssl opens /dev/urandom before the chroot. The work is only
1775 * done once. Zero is returned if the operation fails. No error is returned
1776 * if the random is said as not implemented, because we expect that openssl
1777 * will use another method once needed.
1778 */
1779static int ssl_initialize_random()
1780{
1781 unsigned char random;
1782 static int random_initialized = 0;
1783
1784 if (!random_initialized && RAND_bytes(&random, 1) != 0)
1785 random_initialized = 1;
1786
1787 return random_initialized;
1788}
1789
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01001790int ssl_sock_load_cert_list_file(char *file, struct bind_conf *bind_conf, struct proxy *curproxy, char **err)
1791{
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +02001792 char thisline[LINESIZE];
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01001793 FILE *f;
1794 int linenum = 0;
1795 int cfgerr = 0;
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01001796
Willy Tarreauad1731d2013-04-02 17:35:58 +02001797 if ((f = fopen(file, "r")) == NULL) {
1798 memprintf(err, "cannot open file '%s' : %s", file, strerror(errno));
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01001799 return 1;
Willy Tarreauad1731d2013-04-02 17:35:58 +02001800 }
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01001801
1802 while (fgets(thisline, sizeof(thisline), f) != NULL) {
1803 int arg;
Emeric Brun50bcecc2013-04-22 13:05:23 +02001804 int newarg;
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01001805 char *end;
1806 char *args[MAX_LINE_ARGS + 1];
1807 char *line = thisline;
1808
1809 linenum++;
1810 end = line + strlen(line);
1811 if (end-line == sizeof(thisline)-1 && *(end-1) != '\n') {
1812 /* Check if we reached the limit and the last char is not \n.
1813 * Watch out for the last line without the terminating '\n'!
1814 */
Willy Tarreauad1731d2013-04-02 17:35:58 +02001815 memprintf(err, "line %d too long in file '%s', limit is %d characters",
1816 linenum, file, (int)sizeof(thisline)-1);
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01001817 cfgerr = 1;
Willy Tarreauad1731d2013-04-02 17:35:58 +02001818 break;
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01001819 }
1820
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01001821 arg = 0;
Emeric Brun50bcecc2013-04-22 13:05:23 +02001822 newarg = 1;
1823 while (*line) {
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01001824 if (*line == '#' || *line == '\n' || *line == '\r') {
1825 /* end of string, end of loop */
1826 *line = 0;
1827 break;
1828 }
1829 else if (isspace(*line)) {
Emeric Brun50bcecc2013-04-22 13:05:23 +02001830 newarg = 1;
1831 *line = 0;
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01001832 }
Emeric Brun50bcecc2013-04-22 13:05:23 +02001833 else if (newarg) {
1834 if (arg == MAX_LINE_ARGS) {
1835 memprintf(err, "too many args on line %d in file '%s'.",
1836 linenum, file);
1837 cfgerr = 1;
1838 break;
1839 }
1840 newarg = 0;
1841 args[arg++] = line;
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01001842 }
Emeric Brun50bcecc2013-04-22 13:05:23 +02001843 line++;
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01001844 }
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +02001845 if (cfgerr)
1846 break;
Willy Tarreauad1731d2013-04-02 17:35:58 +02001847
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01001848 /* empty line */
Emeric Brun50bcecc2013-04-22 13:05:23 +02001849 if (!arg)
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01001850 continue;
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01001851
Emeric Brun50bcecc2013-04-22 13:05:23 +02001852 cfgerr = ssl_sock_load_cert_file(args[0], bind_conf, curproxy, &args[1], arg-1, err);
Willy Tarreauad1731d2013-04-02 17:35:58 +02001853 if (cfgerr) {
1854 memprintf(err, "error processing line %d in file '%s' : %s", linenum, file, *err);
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01001855 break;
Willy Tarreauad1731d2013-04-02 17:35:58 +02001856 }
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01001857 }
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01001858 fclose(f);
1859 return cfgerr;
1860}
1861
Emeric Brunfc0421f2012-09-07 17:30:07 +02001862#ifndef SSL_OP_CIPHER_SERVER_PREFERENCE /* needs OpenSSL >= 0.9.7 */
1863#define SSL_OP_CIPHER_SERVER_PREFERENCE 0
1864#endif
1865
1866#ifndef SSL_OP_NO_SESSION_RESUMPTION_ON_RENEGOTIATION /* needs OpenSSL >= 0.9.7 */
1867#define SSL_OP_NO_SESSION_RESUMPTION_ON_RENEGOTIATION 0
Willy Tarreau7d588ee2012-11-26 18:47:31 +01001868#define SSL_renegotiate_pending(arg) 0
Emeric Brunfc0421f2012-09-07 17:30:07 +02001869#endif
Emeric Brun2b58d042012-09-20 17:10:03 +02001870#ifndef SSL_OP_SINGLE_ECDH_USE /* needs OpenSSL >= 0.9.8 */
1871#define SSL_OP_SINGLE_ECDH_USE 0
1872#endif
Emeric Brun2d0c4822012-10-02 13:45:20 +02001873#ifndef SSL_OP_NO_TICKET /* needs OpenSSL >= 0.9.8 */
1874#define SSL_OP_NO_TICKET 0
1875#endif
Emeric Brunfc0421f2012-09-07 17:30:07 +02001876#ifndef SSL_OP_NO_COMPRESSION /* needs OpenSSL >= 0.9.9 */
1877#define SSL_OP_NO_COMPRESSION 0
1878#endif
Emeric Brunc0ff4922012-09-28 19:37:02 +02001879#ifndef SSL_OP_NO_TLSv1_1 /* needs OpenSSL >= 1.0.1 */
1880#define SSL_OP_NO_TLSv1_1 0
1881#endif
1882#ifndef SSL_OP_NO_TLSv1_2 /* needs OpenSSL >= 1.0.1 */
1883#define SSL_OP_NO_TLSv1_2 0
1884#endif
Emeric Bruna4bcd9a2012-09-20 16:19:02 +02001885#ifndef SSL_OP_SINGLE_DH_USE /* needs OpenSSL >= 0.9.6 */
1886#define SSL_OP_SINGLE_DH_USE 0
1887#endif
Emeric Brun2b58d042012-09-20 17:10:03 +02001888#ifndef SSL_OP_SINGLE_ECDH_USE /* needs OpenSSL >= 1.0.0 */
1889#define SSL_OP_SINGLE_ECDH_USE 0
1890#endif
Emeric Brunfc0421f2012-09-07 17:30:07 +02001891#ifndef SSL_MODE_RELEASE_BUFFERS /* needs OpenSSL >= 1.0.0 */
1892#define SSL_MODE_RELEASE_BUFFERS 0
1893#endif
Willy Tarreau396a1862014-11-13 14:06:52 +01001894#ifndef SSL_MODE_SMALL_BUFFERS /* needs small_records.patch */
1895#define SSL_MODE_SMALL_BUFFERS 0
1896#endif
Remi Gacognef46cd6e2014-06-12 14:58:40 +02001897
Willy Tarreau2a65ff02012-09-13 17:54:29 +02001898int ssl_sock_prepare_ctx(struct bind_conf *bind_conf, SSL_CTX *ctx, struct proxy *curproxy)
Emeric Brunfc0421f2012-09-07 17:30:07 +02001899{
1900 int cfgerr = 0;
Emeric Brun850efd52014-01-29 12:24:34 +01001901 int verify = SSL_VERIFY_NONE;
Remi Gacogneaf5c3da2014-05-19 10:29:58 +02001902 long ssloptions =
Emeric Brunfc0421f2012-09-07 17:30:07 +02001903 SSL_OP_ALL | /* all known workarounds for bugs */
1904 SSL_OP_NO_SSLv2 |
1905 SSL_OP_NO_COMPRESSION |
Emeric Bruna4bcd9a2012-09-20 16:19:02 +02001906 SSL_OP_SINGLE_DH_USE |
Emeric Brun2b58d042012-09-20 17:10:03 +02001907 SSL_OP_SINGLE_ECDH_USE |
Emeric Brun3c4bc6e2012-10-04 18:44:19 +02001908 SSL_OP_NO_SESSION_RESUMPTION_ON_RENEGOTIATION |
1909 SSL_OP_CIPHER_SERVER_PREFERENCE;
Remi Gacogneaf5c3da2014-05-19 10:29:58 +02001910 long sslmode =
Emeric Brunfc0421f2012-09-07 17:30:07 +02001911 SSL_MODE_ENABLE_PARTIAL_WRITE |
1912 SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER |
Willy Tarreau396a1862014-11-13 14:06:52 +01001913 SSL_MODE_RELEASE_BUFFERS |
1914 SSL_MODE_SMALL_BUFFERS;
Remi Gacognef46cd6e2014-06-12 14:58:40 +02001915 STACK_OF(SSL_CIPHER) * ciphers = NULL;
Willy Tarreaua616ba62014-10-26 06:49:19 +01001916 SSL_CIPHER * cipher = NULL;
Remi Gacognec1eab8c2014-06-12 18:20:11 +02001917 char cipher_description[128];
1918 /* The description of ciphers using an Ephemeral Diffie Hellman key exchange
1919 contains " Kx=DH " or " Kx=DH(". Beware of " Kx=DH/",
1920 which is not ephemeral DH. */
1921 const char dhe_description[] = " Kx=DH ";
1922 const char dhe_export_description[] = " Kx=DH(";
Remi Gacognef46cd6e2014-06-12 14:58:40 +02001923 int idx = 0;
1924 int dhe_found = 0;
Remi Gacogne23d5d372014-10-10 17:04:26 +02001925 SSL *ssl = NULL;
Emeric Brunfc0421f2012-09-07 17:30:07 +02001926
Thierry Fournier383085f2013-01-24 14:15:43 +01001927 /* Make sure openssl opens /dev/urandom before the chroot */
1928 if (!ssl_initialize_random()) {
1929 Alert("OpenSSL random data generator initialization failed.\n");
1930 cfgerr++;
1931 }
1932
Emeric Brun89675492012-10-05 13:48:26 +02001933 if (bind_conf->ssl_options & BC_SSL_O_NO_SSLV3)
Emeric Brunfc0421f2012-09-07 17:30:07 +02001934 ssloptions |= SSL_OP_NO_SSLv3;
Emeric Brun89675492012-10-05 13:48:26 +02001935 if (bind_conf->ssl_options & BC_SSL_O_NO_TLSV10)
Emeric Brunfc0421f2012-09-07 17:30:07 +02001936 ssloptions |= SSL_OP_NO_TLSv1;
Emeric Brun89675492012-10-05 13:48:26 +02001937 if (bind_conf->ssl_options & BC_SSL_O_NO_TLSV11)
Emeric Brunc0ff4922012-09-28 19:37:02 +02001938 ssloptions |= SSL_OP_NO_TLSv1_1;
Emeric Brun89675492012-10-05 13:48:26 +02001939 if (bind_conf->ssl_options & BC_SSL_O_NO_TLSV12)
Emeric Brunc0ff4922012-09-28 19:37:02 +02001940 ssloptions |= SSL_OP_NO_TLSv1_2;
Emeric Brun89675492012-10-05 13:48:26 +02001941 if (bind_conf->ssl_options & BC_SSL_O_NO_TLS_TICKETS)
Emeric Brun2d0c4822012-10-02 13:45:20 +02001942 ssloptions |= SSL_OP_NO_TICKET;
Jérémie Courrèges-Anglas17c3f622015-07-25 16:50:52 -06001943 if (bind_conf->ssl_options & BC_SSL_O_USE_SSLV3) {
1944#ifndef OPENSSL_NO_SSL3
Emeric Brun2cb7ae52012-10-05 14:14:21 +02001945 SSL_CTX_set_ssl_version(ctx, SSLv3_server_method());
Jérémie Courrèges-Anglas17c3f622015-07-25 16:50:52 -06001946#else
1947 Alert("SSLv3 support requested but unavailable.\n");
1948 cfgerr++;
1949#endif
1950 }
Emeric Brun2cb7ae52012-10-05 14:14:21 +02001951 if (bind_conf->ssl_options & BC_SSL_O_USE_TLSV10)
1952 SSL_CTX_set_ssl_version(ctx, TLSv1_server_method());
1953#if SSL_OP_NO_TLSv1_1
1954 if (bind_conf->ssl_options & BC_SSL_O_USE_TLSV11)
1955 SSL_CTX_set_ssl_version(ctx, TLSv1_1_server_method());
1956#endif
1957#if SSL_OP_NO_TLSv1_2
1958 if (bind_conf->ssl_options & BC_SSL_O_USE_TLSV12)
1959 SSL_CTX_set_ssl_version(ctx, TLSv1_2_server_method());
1960#endif
Emeric Brunfc0421f2012-09-07 17:30:07 +02001961
1962 SSL_CTX_set_options(ctx, ssloptions);
1963 SSL_CTX_set_mode(ctx, sslmode);
Emeric Brun850efd52014-01-29 12:24:34 +01001964 switch (bind_conf->verify) {
1965 case SSL_SOCK_VERIFY_NONE:
1966 verify = SSL_VERIFY_NONE;
1967 break;
1968 case SSL_SOCK_VERIFY_OPTIONAL:
1969 verify = SSL_VERIFY_PEER;
1970 break;
1971 case SSL_SOCK_VERIFY_REQUIRED:
1972 verify = SSL_VERIFY_PEER|SSL_VERIFY_FAIL_IF_NO_PEER_CERT;
1973 break;
1974 }
1975 SSL_CTX_set_verify(ctx, verify, ssl_sock_bind_verifycbk);
1976 if (verify & SSL_VERIFY_PEER) {
Emeric Brunfb510ea2012-10-05 12:00:26 +02001977 if (bind_conf->ca_file) {
Emeric Brund94b3fe2012-09-20 18:23:56 +02001978 /* load CAfile to verify */
Emeric Brunfb510ea2012-10-05 12:00:26 +02001979 if (!SSL_CTX_load_verify_locations(ctx, bind_conf->ca_file, NULL)) {
Emeric Brund94b3fe2012-09-20 18:23:56 +02001980 Alert("Proxy '%s': unable to load CA file '%s' for bind '%s' at [%s:%d].\n",
Emeric Brunfb510ea2012-10-05 12:00:26 +02001981 curproxy->id, bind_conf->ca_file, bind_conf->arg, bind_conf->file, bind_conf->line);
Emeric Brund94b3fe2012-09-20 18:23:56 +02001982 cfgerr++;
1983 }
1984 /* set CA names fo client cert request, function returns void */
Emeric Brunfb510ea2012-10-05 12:00:26 +02001985 SSL_CTX_set_client_CA_list(ctx, SSL_load_client_CA_file(bind_conf->ca_file));
Emeric Brund94b3fe2012-09-20 18:23:56 +02001986 }
Emeric Brun850efd52014-01-29 12:24:34 +01001987 else {
1988 Alert("Proxy '%s': verify is enabled but no CA file specified for bind '%s' at [%s:%d].\n",
1989 curproxy->id, bind_conf->arg, bind_conf->file, bind_conf->line);
1990 cfgerr++;
1991 }
Emeric Brun051cdab2012-10-02 19:25:50 +02001992#ifdef X509_V_FLAG_CRL_CHECK
Emeric Brunfb510ea2012-10-05 12:00:26 +02001993 if (bind_conf->crl_file) {
Emeric Brund94b3fe2012-09-20 18:23:56 +02001994 X509_STORE *store = SSL_CTX_get_cert_store(ctx);
1995
Emeric Brunfb510ea2012-10-05 12:00:26 +02001996 if (!store || !X509_STORE_load_locations(store, bind_conf->crl_file, NULL)) {
Emeric Brund94b3fe2012-09-20 18:23:56 +02001997 Alert("Proxy '%s': unable to configure CRL file '%s' for bind '%s' at [%s:%d].\n",
Alexander Rigbofc65af02015-04-07 14:02:16 +02001998 curproxy->id, bind_conf->crl_file, bind_conf->arg, bind_conf->file, bind_conf->line);
Emeric Brund94b3fe2012-09-20 18:23:56 +02001999 cfgerr++;
2000 }
Emeric Brun561e5742012-10-02 15:20:55 +02002001 else {
2002 X509_STORE_set_flags(store, X509_V_FLAG_CRL_CHECK|X509_V_FLAG_CRL_CHECK_ALL);
2003 }
Emeric Brund94b3fe2012-09-20 18:23:56 +02002004 }
Emeric Brun051cdab2012-10-02 19:25:50 +02002005#endif
Emeric Brun644cde02012-12-14 11:21:13 +01002006 ERR_clear_error();
Emeric Brund94b3fe2012-09-20 18:23:56 +02002007 }
Emeric Brunfc0421f2012-09-07 17:30:07 +02002008
Nenad Merdanovic05552d42015-02-27 19:56:49 +01002009#if (defined SSL_CTRL_SET_TLSEXT_TICKET_KEY_CB && TLS_TICKETS_NO > 0)
Nenad Merdanovic146defa2015-05-09 08:46:00 +02002010 if(bind_conf->keys_ref) {
Nenad Merdanovic05552d42015-02-27 19:56:49 +01002011 if (!SSL_CTX_set_tlsext_ticket_key_cb(ctx, ssl_tlsext_ticket_key_cb)) {
2012 Alert("Proxy '%s': unable to set callback for TLS ticket validation for bind '%s' at [%s:%d].\n",
2013 curproxy->id, bind_conf->arg, bind_conf->file, bind_conf->line);
2014 cfgerr++;
2015 }
2016 }
2017#endif
2018
Emeric Brun4f65bff2012-11-16 15:11:00 +01002019 if (global.tune.ssllifetime)
2020 SSL_CTX_set_timeout(ctx, global.tune.ssllifetime);
2021
Emeric Brunfc0421f2012-09-07 17:30:07 +02002022 shared_context_set_cache(ctx);
Willy Tarreau2a65ff02012-09-13 17:54:29 +02002023 if (bind_conf->ciphers &&
2024 !SSL_CTX_set_cipher_list(ctx, bind_conf->ciphers)) {
Emeric Brunfc0421f2012-09-07 17:30:07 +02002025 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 +02002026 curproxy->id, bind_conf->ciphers, bind_conf->arg, bind_conf->file, bind_conf->line);
Emeric Brunfc0421f2012-09-07 17:30:07 +02002027 cfgerr++;
2028 }
2029
Remi Gacogne47783ef2015-05-29 15:53:22 +02002030 /* If tune.ssl.default-dh-param has not been set,
2031 neither has ssl-default-dh-file and no static DH
2032 params were in the certificate file. */
Remi Gacogne4f902b82015-05-28 16:23:00 +02002033 if (global.tune.ssl_default_dh_param == 0 &&
Remi Gacogne47783ef2015-05-29 15:53:22 +02002034 global_dh == NULL &&
Remi Gacogne4f902b82015-05-28 16:23:00 +02002035 (ssl_dh_ptr_index == -1 ||
2036 SSL_CTX_get_ex_data(ctx, ssl_dh_ptr_index) == NULL)) {
Lukas Tribus90132722014-08-18 00:56:33 +02002037
Remi Gacogne23d5d372014-10-10 17:04:26 +02002038 ssl = SSL_new(ctx);
Remi Gacognef46cd6e2014-06-12 14:58:40 +02002039
Remi Gacogne23d5d372014-10-10 17:04:26 +02002040 if (ssl) {
2041 ciphers = SSL_get_ciphers(ssl);
2042
2043 if (ciphers) {
2044 for (idx = 0; idx < sk_SSL_CIPHER_num(ciphers); idx++) {
2045 cipher = sk_SSL_CIPHER_value(ciphers, idx);
2046 if (SSL_CIPHER_description(cipher, cipher_description, sizeof (cipher_description)) == cipher_description) {
2047 if (strstr(cipher_description, dhe_description) != NULL ||
2048 strstr(cipher_description, dhe_export_description) != NULL) {
2049 dhe_found = 1;
2050 break;
2051 }
Remi Gacognec1eab8c2014-06-12 18:20:11 +02002052 }
Remi Gacognef46cd6e2014-06-12 14:58:40 +02002053 }
2054 }
Remi Gacogne23d5d372014-10-10 17:04:26 +02002055 SSL_free(ssl);
2056 ssl = NULL;
Lukas Tribus90132722014-08-18 00:56:33 +02002057 }
Remi Gacognef46cd6e2014-06-12 14:58:40 +02002058
Lukas Tribus90132722014-08-18 00:56:33 +02002059 if (dhe_found) {
2060 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 +02002061 }
2062
2063 global.tune.ssl_default_dh_param = 1024;
2064 }
Remi Gacogne8de54152014-07-15 11:36:40 +02002065
2066#ifndef OPENSSL_NO_DH
2067 if (global.tune.ssl_default_dh_param >= 1024) {
2068 if (local_dh_1024 == NULL) {
2069 local_dh_1024 = ssl_get_dh_1024();
2070 }
2071 if (global.tune.ssl_default_dh_param >= 2048) {
2072 if (local_dh_2048 == NULL) {
2073 local_dh_2048 = ssl_get_dh_2048();
2074 }
2075 if (global.tune.ssl_default_dh_param >= 4096) {
2076 if (local_dh_4096 == NULL) {
2077 local_dh_4096 = ssl_get_dh_4096();
2078 }
Remi Gacogne8de54152014-07-15 11:36:40 +02002079 }
2080 }
2081 }
2082#endif /* OPENSSL_NO_DH */
Remi Gacognef46cd6e2014-06-12 14:58:40 +02002083
Emeric Brunfc0421f2012-09-07 17:30:07 +02002084 SSL_CTX_set_info_callback(ctx, ssl_sock_infocbk);
Willy Tarreau5cbe4ef2014-05-08 22:45:11 +02002085#if OPENSSL_VERSION_NUMBER >= 0x00907000L
Emeric Brun29f037d2014-04-25 19:05:36 +02002086 SSL_CTX_set_msg_callback(ctx, ssl_sock_msgcbk);
Willy Tarreau5cbe4ef2014-05-08 22:45:11 +02002087#endif
Emeric Brun29f037d2014-04-25 19:05:36 +02002088
Willy Tarreau6c9a3d52012-10-18 18:57:14 +02002089#ifdef OPENSSL_NPN_NEGOTIATED
2090 if (bind_conf->npn_str)
2091 SSL_CTX_set_next_protos_advertised_cb(ctx, ssl_sock_advertise_npn_protos, bind_conf);
2092#endif
Dirkjan Bussink48f1c4e2014-02-13 12:29:42 +01002093#ifdef TLSEXT_TYPE_application_layer_protocol_negotiation
Willy Tarreauab861d32013-04-02 02:30:41 +02002094 if (bind_conf->alpn_str)
Dirkjan Bussink48f1c4e2014-02-13 12:29:42 +01002095 SSL_CTX_set_alpn_select_cb(ctx, ssl_sock_advertise_alpn_protos, bind_conf);
Willy Tarreauab861d32013-04-02 02:30:41 +02002096#endif
Willy Tarreau6c9a3d52012-10-18 18:57:14 +02002097
Emeric Brunfc0421f2012-09-07 17:30:07 +02002098#ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME
2099 SSL_CTX_set_tlsext_servername_callback(ctx, ssl_sock_switchctx_cbk);
Willy Tarreau2a65ff02012-09-13 17:54:29 +02002100 SSL_CTX_set_tlsext_servername_arg(ctx, bind_conf);
Emeric Brunfc0421f2012-09-07 17:30:07 +02002101#endif
Emeric Brun2b58d042012-09-20 17:10:03 +02002102#if defined(SSL_CTX_set_tmp_ecdh) && !defined(OPENSSL_NO_ECDH)
Emeric Brun6924ef82013-03-06 14:08:53 +01002103 {
Emeric Brun2b58d042012-09-20 17:10:03 +02002104 int i;
2105 EC_KEY *ecdh;
2106
Emeric Brun6924ef82013-03-06 14:08:53 +01002107 i = OBJ_sn2nid(bind_conf->ecdhe ? bind_conf->ecdhe : ECDHE_DEFAULT_CURVE);
Emeric Brun2b58d042012-09-20 17:10:03 +02002108 if (!i || ((ecdh = EC_KEY_new_by_curve_name(i)) == NULL)) {
2109 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 +01002110 curproxy->id, bind_conf->ecdhe ? bind_conf->ecdhe : ECDHE_DEFAULT_CURVE,
2111 bind_conf->arg, bind_conf->file, bind_conf->line);
Emeric Brun2b58d042012-09-20 17:10:03 +02002112 cfgerr++;
2113 }
2114 else {
2115 SSL_CTX_set_tmp_ecdh(ctx, ecdh);
2116 EC_KEY_free(ecdh);
2117 }
2118 }
2119#endif
2120
Emeric Brunfc0421f2012-09-07 17:30:07 +02002121 return cfgerr;
2122}
2123
Evan Broderbe554312013-06-27 00:05:25 -07002124static int ssl_sock_srv_hostcheck(const char *pattern, const char *hostname)
2125{
2126 const char *pattern_wildcard, *pattern_left_label_end, *hostname_left_label_end;
2127 size_t prefixlen, suffixlen;
2128
2129 /* Trivial case */
2130 if (strcmp(pattern, hostname) == 0)
2131 return 1;
2132
Evan Broderbe554312013-06-27 00:05:25 -07002133 /* The rest of this logic is based on RFC 6125, section 6.4.3
2134 * (http://tools.ietf.org/html/rfc6125#section-6.4.3) */
2135
Emeric Bruna848dae2013-10-08 11:27:28 +02002136 pattern_wildcard = NULL;
2137 pattern_left_label_end = pattern;
2138 while (*pattern_left_label_end != '.') {
2139 switch (*pattern_left_label_end) {
2140 case 0:
2141 /* End of label not found */
2142 return 0;
2143 case '*':
2144 /* If there is more than one wildcards */
2145 if (pattern_wildcard)
2146 return 0;
2147 pattern_wildcard = pattern_left_label_end;
2148 break;
2149 }
2150 pattern_left_label_end++;
2151 }
2152
2153 /* If it's not trivial and there is no wildcard, it can't
2154 * match */
2155 if (!pattern_wildcard)
Evan Broderbe554312013-06-27 00:05:25 -07002156 return 0;
2157
2158 /* Make sure all labels match except the leftmost */
2159 hostname_left_label_end = strchr(hostname, '.');
2160 if (!hostname_left_label_end
2161 || strcmp(pattern_left_label_end, hostname_left_label_end) != 0)
2162 return 0;
2163
2164 /* Make sure the leftmost label of the hostname is long enough
2165 * that the wildcard can match */
Emeric Brun369da852013-10-08 11:39:35 +02002166 if (hostname_left_label_end - hostname < (pattern_left_label_end - pattern) - 1)
Evan Broderbe554312013-06-27 00:05:25 -07002167 return 0;
2168
2169 /* Finally compare the string on either side of the
2170 * wildcard */
2171 prefixlen = pattern_wildcard - pattern;
2172 suffixlen = pattern_left_label_end - (pattern_wildcard + 1);
Emeric Bruna848dae2013-10-08 11:27:28 +02002173 if ((prefixlen && (memcmp(pattern, hostname, prefixlen) != 0))
2174 || (suffixlen && (memcmp(pattern_wildcard + 1, hostname_left_label_end - suffixlen, suffixlen) != 0)))
Evan Broderbe554312013-06-27 00:05:25 -07002175 return 0;
2176
2177 return 1;
2178}
2179
2180static int ssl_sock_srv_verifycbk(int ok, X509_STORE_CTX *ctx)
2181{
2182 SSL *ssl;
2183 struct connection *conn;
2184 char *servername;
2185
2186 int depth;
2187 X509 *cert;
2188 STACK_OF(GENERAL_NAME) *alt_names;
2189 int i;
2190 X509_NAME *cert_subject;
2191 char *str;
2192
2193 if (ok == 0)
2194 return ok;
2195
2196 ssl = X509_STORE_CTX_get_ex_data(ctx, SSL_get_ex_data_X509_STORE_CTX_idx());
2197 conn = (struct connection *)SSL_get_app_data(ssl);
2198
2199 servername = objt_server(conn->target)->ssl_ctx.verify_host;
2200
2201 /* We only need to verify the CN on the actual server cert,
2202 * not the indirect CAs */
2203 depth = X509_STORE_CTX_get_error_depth(ctx);
2204 if (depth != 0)
2205 return ok;
2206
2207 /* At this point, the cert is *not* OK unless we can find a
2208 * hostname match */
2209 ok = 0;
2210
2211 cert = X509_STORE_CTX_get_current_cert(ctx);
2212 /* It seems like this might happen if verify peer isn't set */
2213 if (!cert)
2214 return ok;
2215
2216 alt_names = X509_get_ext_d2i(cert, NID_subject_alt_name, NULL, NULL);
2217 if (alt_names) {
2218 for (i = 0; !ok && i < sk_GENERAL_NAME_num(alt_names); i++) {
2219 GENERAL_NAME *name = sk_GENERAL_NAME_value(alt_names, i);
2220 if (name->type == GEN_DNS) {
Emeric Bruna33410c2013-09-17 15:47:48 +02002221#if OPENSSL_VERSION_NUMBER < 0x00907000L
2222 if (ASN1_STRING_to_UTF8((unsigned char **)&str, name->d.ia5) >= 0) {
2223#else
Evan Broderbe554312013-06-27 00:05:25 -07002224 if (ASN1_STRING_to_UTF8((unsigned char **)&str, name->d.dNSName) >= 0) {
Emeric Bruna33410c2013-09-17 15:47:48 +02002225#endif
Evan Broderbe554312013-06-27 00:05:25 -07002226 ok = ssl_sock_srv_hostcheck(str, servername);
2227 OPENSSL_free(str);
2228 }
2229 }
2230 }
Emeric Brun4ad50a42013-09-17 15:19:54 +02002231 sk_GENERAL_NAME_pop_free(alt_names, GENERAL_NAME_free);
Evan Broderbe554312013-06-27 00:05:25 -07002232 }
2233
2234 cert_subject = X509_get_subject_name(cert);
2235 i = -1;
2236 while (!ok && (i = X509_NAME_get_index_by_NID(cert_subject, NID_commonName, i)) != -1) {
2237 X509_NAME_ENTRY *entry = X509_NAME_get_entry(cert_subject, i);
2238 if (ASN1_STRING_to_UTF8((unsigned char **)&str, entry->value) >= 0) {
2239 ok = ssl_sock_srv_hostcheck(str, servername);
2240 OPENSSL_free(str);
2241 }
2242 }
2243
2244 return ok;
2245}
2246
Emeric Brun94324a42012-10-11 14:00:19 +02002247/* prepare ssl context from servers options. Returns an error count */
2248int ssl_sock_prepare_srv_ctx(struct server *srv, struct proxy *curproxy)
2249{
2250 int cfgerr = 0;
Remi Gacogneaf5c3da2014-05-19 10:29:58 +02002251 long options =
Emeric Brun94324a42012-10-11 14:00:19 +02002252 SSL_OP_ALL | /* all known workarounds for bugs */
2253 SSL_OP_NO_SSLv2 |
2254 SSL_OP_NO_COMPRESSION;
Remi Gacogneaf5c3da2014-05-19 10:29:58 +02002255 long mode =
Emeric Brun94324a42012-10-11 14:00:19 +02002256 SSL_MODE_ENABLE_PARTIAL_WRITE |
2257 SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER |
Willy Tarreau396a1862014-11-13 14:06:52 +01002258 SSL_MODE_RELEASE_BUFFERS |
2259 SSL_MODE_SMALL_BUFFERS;
Emeric Brun850efd52014-01-29 12:24:34 +01002260 int verify = SSL_VERIFY_NONE;
Emeric Brun94324a42012-10-11 14:00:19 +02002261
Thierry Fournier383085f2013-01-24 14:15:43 +01002262 /* Make sure openssl opens /dev/urandom before the chroot */
2263 if (!ssl_initialize_random()) {
2264 Alert("OpenSSL random data generator initialization failed.\n");
2265 cfgerr++;
2266 }
2267
Willy Tarreaufce03112015-01-15 21:32:40 +01002268 /* Automatic memory computations need to know we use SSL there */
2269 global.ssl_used_backend = 1;
2270
2271 /* Initiate SSL context for current server */
Emeric Brun94324a42012-10-11 14:00:19 +02002272 srv->ssl_ctx.reused_sess = NULL;
2273 if (srv->use_ssl)
2274 srv->xprt = &ssl_sock;
2275 if (srv->check.use_ssl)
Cyril Bonté9ce13112014-11-15 22:41:27 +01002276 srv->check.xprt = &ssl_sock;
Emeric Brun94324a42012-10-11 14:00:19 +02002277
2278 srv->ssl_ctx.ctx = SSL_CTX_new(SSLv23_client_method());
2279 if (!srv->ssl_ctx.ctx) {
2280 Alert("config : %s '%s', server '%s': unable to allocate ssl context.\n",
2281 proxy_type_str(curproxy), curproxy->id,
2282 srv->id);
2283 cfgerr++;
2284 return cfgerr;
2285 }
Emeric Bruna7aa3092012-10-26 12:58:00 +02002286 if (srv->ssl_ctx.client_crt) {
2287 if (SSL_CTX_use_PrivateKey_file(srv->ssl_ctx.ctx, srv->ssl_ctx.client_crt, SSL_FILETYPE_PEM) <= 0) {
2288 Alert("config : %s '%s', server '%s': unable to load SSL private key from PEM file '%s'.\n",
2289 proxy_type_str(curproxy), curproxy->id,
2290 srv->id, srv->ssl_ctx.client_crt);
2291 cfgerr++;
2292 }
2293 else if (SSL_CTX_use_certificate_chain_file(srv->ssl_ctx.ctx, srv->ssl_ctx.client_crt) <= 0) {
2294 Alert("config : %s '%s', server '%s': unable to load ssl certificate from PEM file '%s'.\n",
2295 proxy_type_str(curproxy), curproxy->id,
2296 srv->id, srv->ssl_ctx.client_crt);
2297 cfgerr++;
2298 }
2299 else if (SSL_CTX_check_private_key(srv->ssl_ctx.ctx) <= 0) {
2300 Alert("config : %s '%s', server '%s': inconsistencies between private key and certificate loaded from PEM file '%s'.\n",
2301 proxy_type_str(curproxy), curproxy->id,
2302 srv->id, srv->ssl_ctx.client_crt);
2303 cfgerr++;
2304 }
2305 }
Emeric Brun94324a42012-10-11 14:00:19 +02002306
2307 if (srv->ssl_ctx.options & SRV_SSL_O_NO_SSLV3)
2308 options |= SSL_OP_NO_SSLv3;
2309 if (srv->ssl_ctx.options & SRV_SSL_O_NO_TLSV10)
2310 options |= SSL_OP_NO_TLSv1;
2311 if (srv->ssl_ctx.options & SRV_SSL_O_NO_TLSV11)
2312 options |= SSL_OP_NO_TLSv1_1;
2313 if (srv->ssl_ctx.options & SRV_SSL_O_NO_TLSV12)
2314 options |= SSL_OP_NO_TLSv1_2;
Emeric Brunf9c5c472012-10-11 15:28:34 +02002315 if (srv->ssl_ctx.options & SRV_SSL_O_NO_TLS_TICKETS)
2316 options |= SSL_OP_NO_TICKET;
Jérémie Courrèges-Anglas17c3f622015-07-25 16:50:52 -06002317 if (srv->ssl_ctx.options & SRV_SSL_O_USE_SSLV3) {
2318#ifndef OPENSSL_NO_SSL3
Emeric Brun94324a42012-10-11 14:00:19 +02002319 SSL_CTX_set_ssl_version(srv->ssl_ctx.ctx, SSLv3_client_method());
Jérémie Courrèges-Anglas17c3f622015-07-25 16:50:52 -06002320#else
Thierry FOURNIERbc965342015-08-26 08:21:26 +02002321 Alert("SSLv3 support requested but unavailable.\n");
Jérémie Courrèges-Anglas17c3f622015-07-25 16:50:52 -06002322 cfgerr++;
2323#endif
2324 }
Emeric Brun94324a42012-10-11 14:00:19 +02002325 if (srv->ssl_ctx.options & SRV_SSL_O_USE_TLSV10)
2326 SSL_CTX_set_ssl_version(srv->ssl_ctx.ctx, TLSv1_client_method());
2327#if SSL_OP_NO_TLSv1_1
2328 if (srv->ssl_ctx.options & SRV_SSL_O_USE_TLSV11)
2329 SSL_CTX_set_ssl_version(srv->ssl_ctx.ctx, TLSv1_1_client_method());
2330#endif
2331#if SSL_OP_NO_TLSv1_2
2332 if (srv->ssl_ctx.options & SRV_SSL_O_USE_TLSV12)
2333 SSL_CTX_set_ssl_version(srv->ssl_ctx.ctx, TLSv1_2_client_method());
2334#endif
2335
2336 SSL_CTX_set_options(srv->ssl_ctx.ctx, options);
2337 SSL_CTX_set_mode(srv->ssl_ctx.ctx, mode);
Emeric Brun850efd52014-01-29 12:24:34 +01002338
2339 if (global.ssl_server_verify == SSL_SERVER_VERIFY_REQUIRED)
2340 verify = SSL_VERIFY_PEER;
2341
2342 switch (srv->ssl_ctx.verify) {
2343 case SSL_SOCK_VERIFY_NONE:
2344 verify = SSL_VERIFY_NONE;
2345 break;
2346 case SSL_SOCK_VERIFY_REQUIRED:
2347 verify = SSL_VERIFY_PEER;
2348 break;
2349 }
Evan Broderbe554312013-06-27 00:05:25 -07002350 SSL_CTX_set_verify(srv->ssl_ctx.ctx,
Emeric Brun850efd52014-01-29 12:24:34 +01002351 verify,
Evan Broderbe554312013-06-27 00:05:25 -07002352 srv->ssl_ctx.verify_host ? ssl_sock_srv_verifycbk : NULL);
Emeric Brun850efd52014-01-29 12:24:34 +01002353 if (verify & SSL_VERIFY_PEER) {
Emeric Brunef42d922012-10-11 16:11:36 +02002354 if (srv->ssl_ctx.ca_file) {
2355 /* load CAfile to verify */
2356 if (!SSL_CTX_load_verify_locations(srv->ssl_ctx.ctx, srv->ssl_ctx.ca_file, NULL)) {
Willy Tarreau07ba08b2014-02-16 19:22:08 +01002357 Alert("Proxy '%s', server '%s' [%s:%d] unable to load CA file '%s'.\n",
Emeric Brunef42d922012-10-11 16:11:36 +02002358 curproxy->id, srv->id,
2359 srv->conf.file, srv->conf.line, srv->ssl_ctx.ca_file);
2360 cfgerr++;
2361 }
2362 }
Emeric Brun850efd52014-01-29 12:24:34 +01002363 else {
2364 if (global.ssl_server_verify == SSL_SERVER_VERIFY_REQUIRED)
Willy Tarreau07ba08b2014-02-16 19:22:08 +01002365 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 +01002366 curproxy->id, srv->id,
2367 srv->conf.file, srv->conf.line);
2368 else
Willy Tarreau07ba08b2014-02-16 19:22:08 +01002369 Alert("Proxy '%s', server '%s' [%s:%d] verify is enabled but no CA file specified.\n",
Emeric Brun850efd52014-01-29 12:24:34 +01002370 curproxy->id, srv->id,
2371 srv->conf.file, srv->conf.line);
2372 cfgerr++;
2373 }
Emeric Brunef42d922012-10-11 16:11:36 +02002374#ifdef X509_V_FLAG_CRL_CHECK
2375 if (srv->ssl_ctx.crl_file) {
2376 X509_STORE *store = SSL_CTX_get_cert_store(srv->ssl_ctx.ctx);
2377
2378 if (!store || !X509_STORE_load_locations(store, srv->ssl_ctx.crl_file, NULL)) {
Willy Tarreau07ba08b2014-02-16 19:22:08 +01002379 Alert("Proxy '%s', server '%s' [%s:%d] unable to configure CRL file '%s'.\n",
Emeric Brunef42d922012-10-11 16:11:36 +02002380 curproxy->id, srv->id,
2381 srv->conf.file, srv->conf.line, srv->ssl_ctx.crl_file);
2382 cfgerr++;
2383 }
2384 else {
2385 X509_STORE_set_flags(store, X509_V_FLAG_CRL_CHECK|X509_V_FLAG_CRL_CHECK_ALL);
2386 }
2387 }
2388#endif
2389 }
2390
Emeric Brun4f65bff2012-11-16 15:11:00 +01002391 if (global.tune.ssllifetime)
2392 SSL_CTX_set_timeout(srv->ssl_ctx.ctx, global.tune.ssllifetime);
2393
Emeric Brun94324a42012-10-11 14:00:19 +02002394 SSL_CTX_set_session_cache_mode(srv->ssl_ctx.ctx, SSL_SESS_CACHE_OFF);
2395 if (srv->ssl_ctx.ciphers &&
2396 !SSL_CTX_set_cipher_list(srv->ssl_ctx.ctx, srv->ssl_ctx.ciphers)) {
2397 Alert("Proxy '%s', server '%s' [%s:%d] : unable to set SSL cipher list to '%s'.\n",
2398 curproxy->id, srv->id,
2399 srv->conf.file, srv->conf.line, srv->ssl_ctx.ciphers);
2400 cfgerr++;
2401 }
2402
2403 return cfgerr;
2404}
2405
Willy Tarreau2a65ff02012-09-13 17:54:29 +02002406/* Walks down the two trees in bind_conf and prepares all certs. The pointer may
Emeric Brunfc0421f2012-09-07 17:30:07 +02002407 * be NULL, in which case nothing is done. Returns the number of errors
2408 * encountered.
2409 */
Willy Tarreau2a65ff02012-09-13 17:54:29 +02002410int ssl_sock_prepare_all_ctx(struct bind_conf *bind_conf, struct proxy *px)
Emeric Brunfc0421f2012-09-07 17:30:07 +02002411{
2412 struct ebmb_node *node;
2413 struct sni_ctx *sni;
2414 int err = 0;
2415
Willy Tarreau2a65ff02012-09-13 17:54:29 +02002416 if (!bind_conf || !bind_conf->is_ssl)
Emeric Brunfc0421f2012-09-07 17:30:07 +02002417 return 0;
2418
Willy Tarreaufce03112015-01-15 21:32:40 +01002419 /* Automatic memory computations need to know we use SSL there */
2420 global.ssl_used_frontend = 1;
2421
Emeric Brun0bed9942014-10-30 19:25:24 +01002422 if (bind_conf->default_ctx)
2423 err += ssl_sock_prepare_ctx(bind_conf, bind_conf->default_ctx, px);
2424
Willy Tarreau2a65ff02012-09-13 17:54:29 +02002425 node = ebmb_first(&bind_conf->sni_ctx);
Emeric Brunfc0421f2012-09-07 17:30:07 +02002426 while (node) {
2427 sni = ebmb_entry(node, struct sni_ctx, name);
Emeric Brun0bed9942014-10-30 19:25:24 +01002428 if (!sni->order && sni->ctx != bind_conf->default_ctx)
2429 /* only initialize the CTX on its first occurrence and
2430 if it is not the default_ctx */
Willy Tarreau2a65ff02012-09-13 17:54:29 +02002431 err += ssl_sock_prepare_ctx(bind_conf, sni->ctx, px);
Emeric Brunfc0421f2012-09-07 17:30:07 +02002432 node = ebmb_next(node);
2433 }
2434
Willy Tarreau2a65ff02012-09-13 17:54:29 +02002435 node = ebmb_first(&bind_conf->sni_w_ctx);
Emeric Brunfc0421f2012-09-07 17:30:07 +02002436 while (node) {
2437 sni = ebmb_entry(node, struct sni_ctx, name);
Emeric Brun0bed9942014-10-30 19:25:24 +01002438 if (!sni->order && sni->ctx != bind_conf->default_ctx)
2439 /* only initialize the CTX on its first occurrence and
2440 if it is not the default_ctx */
Willy Tarreau2a65ff02012-09-13 17:54:29 +02002441 err += ssl_sock_prepare_ctx(bind_conf, sni->ctx, px);
Emeric Brunfc0421f2012-09-07 17:30:07 +02002442 node = ebmb_next(node);
2443 }
2444 return err;
2445}
2446
Willy Tarreau2a65ff02012-09-13 17:54:29 +02002447/* Walks down the two trees in bind_conf and frees all the certs. The pointer may
Emeric Brunfc0421f2012-09-07 17:30:07 +02002448 * be NULL, in which case nothing is done. The default_ctx is nullified too.
2449 */
Willy Tarreau2a65ff02012-09-13 17:54:29 +02002450void ssl_sock_free_all_ctx(struct bind_conf *bind_conf)
Emeric Brunfc0421f2012-09-07 17:30:07 +02002451{
2452 struct ebmb_node *node, *back;
2453 struct sni_ctx *sni;
2454
Willy Tarreau2a65ff02012-09-13 17:54:29 +02002455 if (!bind_conf || !bind_conf->is_ssl)
Emeric Brunfc0421f2012-09-07 17:30:07 +02002456 return;
2457
Willy Tarreau2a65ff02012-09-13 17:54:29 +02002458 node = ebmb_first(&bind_conf->sni_ctx);
Emeric Brunfc0421f2012-09-07 17:30:07 +02002459 while (node) {
2460 sni = ebmb_entry(node, struct sni_ctx, name);
2461 back = ebmb_next(node);
2462 ebmb_delete(node);
2463 if (!sni->order) /* only free the CTX on its first occurrence */
2464 SSL_CTX_free(sni->ctx);
2465 free(sni);
2466 node = back;
2467 }
2468
Willy Tarreau2a65ff02012-09-13 17:54:29 +02002469 node = ebmb_first(&bind_conf->sni_w_ctx);
Emeric Brunfc0421f2012-09-07 17:30:07 +02002470 while (node) {
2471 sni = ebmb_entry(node, struct sni_ctx, name);
2472 back = ebmb_next(node);
2473 ebmb_delete(node);
2474 if (!sni->order) /* only free the CTX on its first occurrence */
2475 SSL_CTX_free(sni->ctx);
2476 free(sni);
2477 node = back;
2478 }
2479
Willy Tarreau2a65ff02012-09-13 17:54:29 +02002480 bind_conf->default_ctx = NULL;
Emeric Brune1f38db2012-09-03 20:36:47 +02002481}
2482
Christopher Faulet31af49d2015-06-09 17:29:50 +02002483/* Load CA cert file and private key used to generate certificates */
2484int
2485ssl_sock_load_ca(struct bind_conf *bind_conf, struct proxy *px)
2486{
2487 FILE *fp;
2488 X509 *cacert = NULL;
2489 EVP_PKEY *capkey = NULL;
2490 int err = 0;
2491
2492 if (!bind_conf || !bind_conf->generate_certs)
2493 return err;
2494
Christopher Fauletd2cab922015-07-28 16:03:47 +02002495 if (global.tune.ssl_ctx_cache)
2496 ssl_ctx_lru_tree = lru64_new(global.tune.ssl_ctx_cache);
2497 ssl_ctx_lru_seed = (unsigned int)time(NULL);
2498
Christopher Faulet31af49d2015-06-09 17:29:50 +02002499 if (!bind_conf->ca_sign_file) {
2500 Alert("Proxy '%s': cannot enable certificate generation, "
2501 "no CA certificate File configured at [%s:%d].\n",
2502 px->id, bind_conf->file, bind_conf->line);
2503 err++;
2504 }
2505
2506 if (err)
2507 goto load_error;
2508
2509 /* read in the CA certificate */
2510 if (!(fp = fopen(bind_conf->ca_sign_file, "r"))) {
2511 Alert("Proxy '%s': Failed to read CA certificate file '%s' at [%s:%d].\n",
2512 px->id, bind_conf->ca_sign_file, bind_conf->file, bind_conf->line);
2513 err++;
2514 goto load_error;
2515 }
2516 if (!(cacert = PEM_read_X509(fp, NULL, NULL, NULL))) {
2517 Alert("Proxy '%s': Failed to read CA certificate 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 if (!(capkey = PEM_read_PrivateKey(fp, NULL, NULL, bind_conf->ca_sign_pass))) {
2524 Alert("Proxy '%s': Failed to read CA private key file '%s' at [%s:%d].\n",
2525 px->id, bind_conf->ca_sign_file, bind_conf->file, bind_conf->line);
2526 fclose (fp);
2527 err++;
2528 goto load_error;
2529 }
2530 fclose (fp);
2531
2532 bind_conf->ca_sign_cert = cacert;
2533 bind_conf->ca_sign_pkey = capkey;
2534 return err;
2535
2536 load_error:
2537 bind_conf->generate_certs = 0;
2538 if (capkey) EVP_PKEY_free(capkey);
2539 if (cacert) X509_free(cacert);
2540 return err;
2541}
2542
2543/* Release CA cert and private key used to generate certificated */
2544void
2545ssl_sock_free_ca(struct bind_conf *bind_conf)
2546{
2547 if (!bind_conf)
2548 return;
2549
2550 if (bind_conf->ca_sign_pkey)
2551 EVP_PKEY_free(bind_conf->ca_sign_pkey);
2552 if (bind_conf->ca_sign_cert)
2553 X509_free(bind_conf->ca_sign_cert);
2554}
2555
Emeric Brun46591952012-05-18 15:47:34 +02002556/*
2557 * This function is called if SSL * context is not yet allocated. The function
2558 * is designed to be called before any other data-layer operation and sets the
2559 * handshake flag on the connection. It is safe to call it multiple times.
2560 * It returns 0 on success and -1 in error case.
2561 */
2562static int ssl_sock_init(struct connection *conn)
2563{
2564 /* already initialized */
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02002565 if (conn->xprt_ctx)
Emeric Brun46591952012-05-18 15:47:34 +02002566 return 0;
2567
Willy Tarreau3c728722014-01-23 13:50:42 +01002568 if (!conn_ctrl_ready(conn))
Willy Tarreauf79c8172013-10-21 16:30:56 +02002569 return 0;
2570
Willy Tarreau20879a02012-12-03 16:32:10 +01002571 if (global.maxsslconn && sslconns >= global.maxsslconn) {
2572 conn->err_code = CO_ER_SSL_TOO_MANY;
Willy Tarreau403edff2012-09-06 11:58:37 +02002573 return -1;
Willy Tarreau20879a02012-12-03 16:32:10 +01002574 }
Willy Tarreau403edff2012-09-06 11:58:37 +02002575
Emeric Brun46591952012-05-18 15:47:34 +02002576 /* If it is in client mode initiate SSL session
2577 in connect state otherwise accept state */
Willy Tarreau3fdb3662012-11-12 00:42:33 +01002578 if (objt_server(conn->target)) {
Willy Tarreaufba03cd2014-11-13 13:48:58 +01002579 int may_retry = 1;
2580
2581 retry_connect:
Emeric Brun46591952012-05-18 15:47:34 +02002582 /* Alloc a new SSL session ctx */
Willy Tarreau3fdb3662012-11-12 00:42:33 +01002583 conn->xprt_ctx = SSL_new(objt_server(conn->target)->ssl_ctx.ctx);
Willy Tarreau20879a02012-12-03 16:32:10 +01002584 if (!conn->xprt_ctx) {
Willy Tarreaufba03cd2014-11-13 13:48:58 +01002585 if (may_retry--) {
2586 pool_gc2();
2587 goto retry_connect;
2588 }
Willy Tarreau20879a02012-12-03 16:32:10 +01002589 conn->err_code = CO_ER_SSL_NO_MEM;
Emeric Brun46591952012-05-18 15:47:34 +02002590 return -1;
Willy Tarreau20879a02012-12-03 16:32:10 +01002591 }
Emeric Brun46591952012-05-18 15:47:34 +02002592
Emeric Brun46591952012-05-18 15:47:34 +02002593 /* set fd on SSL session context */
Emeric Brun55476152014-11-12 17:35:37 +01002594 if (!SSL_set_fd(conn->xprt_ctx, conn->t.sock.fd)) {
2595 SSL_free(conn->xprt_ctx);
2596 conn->xprt_ctx = NULL;
Willy Tarreaufba03cd2014-11-13 13:48:58 +01002597 if (may_retry--) {
2598 pool_gc2();
2599 goto retry_connect;
2600 }
Emeric Brun55476152014-11-12 17:35:37 +01002601 conn->err_code = CO_ER_SSL_NO_MEM;
2602 return -1;
2603 }
Emeric Brun46591952012-05-18 15:47:34 +02002604
Evan Broderbe554312013-06-27 00:05:25 -07002605 /* set connection pointer */
Emeric Brun55476152014-11-12 17:35:37 +01002606 if (!SSL_set_app_data(conn->xprt_ctx, conn)) {
2607 SSL_free(conn->xprt_ctx);
2608 conn->xprt_ctx = NULL;
Willy Tarreaufba03cd2014-11-13 13:48:58 +01002609 if (may_retry--) {
2610 pool_gc2();
2611 goto retry_connect;
2612 }
Emeric Brun55476152014-11-12 17:35:37 +01002613 conn->err_code = CO_ER_SSL_NO_MEM;
2614 return -1;
2615 }
2616
2617 SSL_set_connect_state(conn->xprt_ctx);
2618 if (objt_server(conn->target)->ssl_ctx.reused_sess) {
2619 if(!SSL_set_session(conn->xprt_ctx, objt_server(conn->target)->ssl_ctx.reused_sess)) {
2620 SSL_SESSION_free(objt_server(conn->target)->ssl_ctx.reused_sess);
2621 objt_server(conn->target)->ssl_ctx.reused_sess = NULL;
2622 }
2623 }
Evan Broderbe554312013-06-27 00:05:25 -07002624
Emeric Brun46591952012-05-18 15:47:34 +02002625 /* leave init state and start handshake */
Willy Tarreau05737472012-09-04 08:03:39 +02002626 conn->flags |= CO_FL_SSL_WAIT_HS | CO_FL_WAIT_L6_CONN;
Willy Tarreau403edff2012-09-06 11:58:37 +02002627
2628 sslconns++;
Willy Tarreau71b734c2014-01-28 15:19:44 +01002629 totalsslconns++;
Emeric Brun46591952012-05-18 15:47:34 +02002630 return 0;
2631 }
Willy Tarreau3fdb3662012-11-12 00:42:33 +01002632 else if (objt_listener(conn->target)) {
Willy Tarreaufba03cd2014-11-13 13:48:58 +01002633 int may_retry = 1;
2634
2635 retry_accept:
Emeric Brun46591952012-05-18 15:47:34 +02002636 /* Alloc a new SSL session ctx */
Willy Tarreau3fdb3662012-11-12 00:42:33 +01002637 conn->xprt_ctx = SSL_new(objt_listener(conn->target)->bind_conf->default_ctx);
Willy Tarreau20879a02012-12-03 16:32:10 +01002638 if (!conn->xprt_ctx) {
Willy Tarreaufba03cd2014-11-13 13:48:58 +01002639 if (may_retry--) {
2640 pool_gc2();
2641 goto retry_accept;
2642 }
Willy Tarreau20879a02012-12-03 16:32:10 +01002643 conn->err_code = CO_ER_SSL_NO_MEM;
Emeric Brun46591952012-05-18 15:47:34 +02002644 return -1;
Willy Tarreau20879a02012-12-03 16:32:10 +01002645 }
Emeric Brun46591952012-05-18 15:47:34 +02002646
Emeric Brun46591952012-05-18 15:47:34 +02002647 /* set fd on SSL session context */
Emeric Brun55476152014-11-12 17:35:37 +01002648 if (!SSL_set_fd(conn->xprt_ctx, conn->t.sock.fd)) {
2649 SSL_free(conn->xprt_ctx);
2650 conn->xprt_ctx = NULL;
Willy Tarreaufba03cd2014-11-13 13:48:58 +01002651 if (may_retry--) {
2652 pool_gc2();
2653 goto retry_accept;
2654 }
Emeric Brun55476152014-11-12 17:35:37 +01002655 conn->err_code = CO_ER_SSL_NO_MEM;
2656 return -1;
2657 }
Emeric Brun46591952012-05-18 15:47:34 +02002658
Emeric Brune1f38db2012-09-03 20:36:47 +02002659 /* set connection pointer */
Emeric Brun55476152014-11-12 17:35:37 +01002660 if (!SSL_set_app_data(conn->xprt_ctx, conn)) {
2661 SSL_free(conn->xprt_ctx);
2662 conn->xprt_ctx = NULL;
Willy Tarreaufba03cd2014-11-13 13:48:58 +01002663 if (may_retry--) {
2664 pool_gc2();
2665 goto retry_accept;
2666 }
Emeric Brun55476152014-11-12 17:35:37 +01002667 conn->err_code = CO_ER_SSL_NO_MEM;
2668 return -1;
2669 }
2670
2671 SSL_set_accept_state(conn->xprt_ctx);
Emeric Brune1f38db2012-09-03 20:36:47 +02002672
Emeric Brun46591952012-05-18 15:47:34 +02002673 /* leave init state and start handshake */
Willy Tarreau05737472012-09-04 08:03:39 +02002674 conn->flags |= CO_FL_SSL_WAIT_HS | CO_FL_WAIT_L6_CONN;
Willy Tarreau403edff2012-09-06 11:58:37 +02002675
2676 sslconns++;
Willy Tarreau71b734c2014-01-28 15:19:44 +01002677 totalsslconns++;
Emeric Brun46591952012-05-18 15:47:34 +02002678 return 0;
2679 }
2680 /* don't know how to handle such a target */
Willy Tarreau20879a02012-12-03 16:32:10 +01002681 conn->err_code = CO_ER_SSL_NO_TARGET;
Emeric Brun46591952012-05-18 15:47:34 +02002682 return -1;
2683}
2684
2685
2686/* This is the callback which is used when an SSL handshake is pending. It
2687 * updates the FD status if it wants some polling before being called again.
2688 * It returns 0 if it fails in a fatal way or needs to poll to go further,
2689 * otherwise it returns non-zero and removes itself from the connection's
2690 * flags (the bit is provided in <flag> by the caller).
2691 */
2692int ssl_sock_handshake(struct connection *conn, unsigned int flag)
2693{
2694 int ret;
2695
Willy Tarreau3c728722014-01-23 13:50:42 +01002696 if (!conn_ctrl_ready(conn))
Willy Tarreauf79c8172013-10-21 16:30:56 +02002697 return 0;
2698
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02002699 if (!conn->xprt_ctx)
Emeric Brun46591952012-05-18 15:47:34 +02002700 goto out_error;
2701
Emeric Brun674b7432012-11-08 19:21:55 +01002702 /* If we use SSL_do_handshake to process a reneg initiated by
2703 * the remote peer, it sometimes returns SSL_ERROR_SSL.
2704 * Usually SSL_write and SSL_read are used and process implicitly
2705 * the reneg handshake.
2706 * Here we use SSL_peek as a workaround for reneg.
2707 */
2708 if ((conn->flags & CO_FL_CONNECTED) && SSL_renegotiate_pending(conn->xprt_ctx)) {
2709 char c;
2710
2711 ret = SSL_peek(conn->xprt_ctx, &c, 1);
2712 if (ret <= 0) {
2713 /* handshake may have not been completed, let's find why */
2714 ret = SSL_get_error(conn->xprt_ctx, ret);
2715 if (ret == SSL_ERROR_WANT_WRITE) {
2716 /* SSL handshake needs to write, L4 connection may not be ready */
2717 __conn_sock_stop_recv(conn);
Willy Tarreaue1f50c42014-01-22 20:02:06 +01002718 __conn_sock_want_send(conn);
2719 fd_cant_send(conn->t.sock.fd);
Emeric Brun674b7432012-11-08 19:21:55 +01002720 return 0;
2721 }
2722 else if (ret == SSL_ERROR_WANT_READ) {
2723 /* handshake may have been completed but we have
2724 * no more data to read.
2725 */
2726 if (!SSL_renegotiate_pending(conn->xprt_ctx)) {
2727 ret = 1;
2728 goto reneg_ok;
2729 }
2730 /* SSL handshake needs to read, L4 connection is ready */
2731 if (conn->flags & CO_FL_WAIT_L4_CONN)
2732 conn->flags &= ~CO_FL_WAIT_L4_CONN;
2733 __conn_sock_stop_send(conn);
Willy Tarreaue1f50c42014-01-22 20:02:06 +01002734 __conn_sock_want_recv(conn);
2735 fd_cant_recv(conn->t.sock.fd);
Emeric Brun674b7432012-11-08 19:21:55 +01002736 return 0;
2737 }
2738 else if (ret == SSL_ERROR_SYSCALL) {
2739 /* if errno is null, then connection was successfully established */
2740 if (!errno && conn->flags & CO_FL_WAIT_L4_CONN)
2741 conn->flags &= ~CO_FL_WAIT_L4_CONN;
Willy Tarreau20879a02012-12-03 16:32:10 +01002742 if (!conn->err_code) {
Emeric Brun29f037d2014-04-25 19:05:36 +02002743 if (!((SSL *)conn->xprt_ctx)->packet_length) {
2744 if (!errno) {
2745 if (conn->xprt_st & SSL_SOCK_RECV_HEARTBEAT)
2746 conn->err_code = CO_ER_SSL_HANDSHAKE_HB;
2747 else
2748 conn->err_code = CO_ER_SSL_EMPTY;
2749 }
2750 else {
2751 if (conn->xprt_st & SSL_SOCK_RECV_HEARTBEAT)
2752 conn->err_code = CO_ER_SSL_HANDSHAKE_HB;
2753 else
2754 conn->err_code = CO_ER_SSL_ABORT;
2755 }
2756 }
2757 else {
2758 if (conn->xprt_st & SSL_SOCK_RECV_HEARTBEAT)
2759 conn->err_code = CO_ER_SSL_HANDSHAKE_HB;
Willy Tarreau20879a02012-12-03 16:32:10 +01002760 else
Emeric Brun29f037d2014-04-25 19:05:36 +02002761 conn->err_code = CO_ER_SSL_HANDSHAKE;
2762 }
Willy Tarreau20879a02012-12-03 16:32:10 +01002763 }
Emeric Brun674b7432012-11-08 19:21:55 +01002764 goto out_error;
2765 }
2766 else {
2767 /* Fail on all other handshake errors */
2768 /* Note: OpenSSL may leave unread bytes in the socket's
2769 * buffer, causing an RST to be emitted upon close() on
2770 * TCP sockets. We first try to drain possibly pending
2771 * data to avoid this as much as possible.
2772 */
Willy Tarreaud85c4852015-03-13 00:40:28 +01002773 conn_sock_drain(conn);
Willy Tarreau20879a02012-12-03 16:32:10 +01002774 if (!conn->err_code)
Willy Tarreauf51c6982014-04-25 20:02:39 +02002775 conn->err_code = (conn->xprt_st & SSL_SOCK_RECV_HEARTBEAT) ?
2776 CO_ER_SSL_KILLED_HB : CO_ER_SSL_HANDSHAKE;
Emeric Brun674b7432012-11-08 19:21:55 +01002777 goto out_error;
2778 }
2779 }
2780 /* read some data: consider handshake completed */
2781 goto reneg_ok;
2782 }
2783
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02002784 ret = SSL_do_handshake(conn->xprt_ctx);
Emeric Brun46591952012-05-18 15:47:34 +02002785 if (ret != 1) {
2786 /* handshake did not complete, let's find why */
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02002787 ret = SSL_get_error(conn->xprt_ctx, ret);
Emeric Brun46591952012-05-18 15:47:34 +02002788
2789 if (ret == SSL_ERROR_WANT_WRITE) {
2790 /* SSL handshake needs to write, L4 connection may not be ready */
2791 __conn_sock_stop_recv(conn);
Willy Tarreaue1f50c42014-01-22 20:02:06 +01002792 __conn_sock_want_send(conn);
2793 fd_cant_send(conn->t.sock.fd);
Emeric Brun46591952012-05-18 15:47:34 +02002794 return 0;
2795 }
2796 else if (ret == SSL_ERROR_WANT_READ) {
2797 /* SSL handshake needs to read, L4 connection is ready */
2798 if (conn->flags & CO_FL_WAIT_L4_CONN)
2799 conn->flags &= ~CO_FL_WAIT_L4_CONN;
2800 __conn_sock_stop_send(conn);
Willy Tarreaue1f50c42014-01-22 20:02:06 +01002801 __conn_sock_want_recv(conn);
2802 fd_cant_recv(conn->t.sock.fd);
Emeric Brun46591952012-05-18 15:47:34 +02002803 return 0;
2804 }
Willy Tarreau89230192012-09-28 20:22:13 +02002805 else if (ret == SSL_ERROR_SYSCALL) {
2806 /* if errno is null, then connection was successfully established */
2807 if (!errno && conn->flags & CO_FL_WAIT_L4_CONN)
2808 conn->flags &= ~CO_FL_WAIT_L4_CONN;
Willy Tarreau20879a02012-12-03 16:32:10 +01002809
Emeric Brun29f037d2014-04-25 19:05:36 +02002810 if (!((SSL *)conn->xprt_ctx)->packet_length) {
2811 if (!errno) {
2812 if (conn->xprt_st & SSL_SOCK_RECV_HEARTBEAT)
2813 conn->err_code = CO_ER_SSL_HANDSHAKE_HB;
2814 else
2815 conn->err_code = CO_ER_SSL_EMPTY;
2816 }
2817 else {
2818 if (conn->xprt_st & SSL_SOCK_RECV_HEARTBEAT)
2819 conn->err_code = CO_ER_SSL_HANDSHAKE_HB;
2820 else
2821 conn->err_code = CO_ER_SSL_ABORT;
2822 }
2823 }
2824 else {
2825 if (conn->xprt_st & SSL_SOCK_RECV_HEARTBEAT)
2826 conn->err_code = CO_ER_SSL_HANDSHAKE_HB;
Willy Tarreau20879a02012-12-03 16:32:10 +01002827 else
Emeric Brun29f037d2014-04-25 19:05:36 +02002828 conn->err_code = CO_ER_SSL_HANDSHAKE;
2829 }
Willy Tarreau89230192012-09-28 20:22:13 +02002830 goto out_error;
2831 }
Emeric Brun46591952012-05-18 15:47:34 +02002832 else {
2833 /* Fail on all other handshake errors */
Willy Tarreau566dc552012-10-19 20:52:18 +02002834 /* Note: OpenSSL may leave unread bytes in the socket's
2835 * buffer, causing an RST to be emitted upon close() on
2836 * TCP sockets. We first try to drain possibly pending
2837 * data to avoid this as much as possible.
2838 */
Willy Tarreaud85c4852015-03-13 00:40:28 +01002839 conn_sock_drain(conn);
Willy Tarreau20879a02012-12-03 16:32:10 +01002840 if (!conn->err_code)
Willy Tarreauf51c6982014-04-25 20:02:39 +02002841 conn->err_code = (conn->xprt_st & SSL_SOCK_RECV_HEARTBEAT) ?
2842 CO_ER_SSL_KILLED_HB : CO_ER_SSL_HANDSHAKE;
Emeric Brun46591952012-05-18 15:47:34 +02002843 goto out_error;
2844 }
2845 }
2846
Emeric Brun674b7432012-11-08 19:21:55 +01002847reneg_ok:
Emeric Brun46591952012-05-18 15:47:34 +02002848 /* Handshake succeeded */
Willy Tarreau0c9c2722014-05-28 12:28:58 +02002849 if (!SSL_session_reused(conn->xprt_ctx)) {
2850 if (objt_server(conn->target)) {
2851 update_freq_ctr(&global.ssl_be_keys_per_sec, 1);
2852 if (global.ssl_be_keys_per_sec.curr_ctr > global.ssl_be_keys_max)
2853 global.ssl_be_keys_max = global.ssl_be_keys_per_sec.curr_ctr;
2854
Emeric Brun46591952012-05-18 15:47:34 +02002855 /* check if session was reused, if not store current session on server for reuse */
Willy Tarreau3fdb3662012-11-12 00:42:33 +01002856 if (objt_server(conn->target)->ssl_ctx.reused_sess)
2857 SSL_SESSION_free(objt_server(conn->target)->ssl_ctx.reused_sess);
Emeric Brun46591952012-05-18 15:47:34 +02002858
Willy Tarreau2a3fb1c2015-02-05 16:47:07 +01002859 if (!(objt_server(conn->target)->ssl_ctx.options & SRV_SSL_O_NO_REUSE))
2860 objt_server(conn->target)->ssl_ctx.reused_sess = SSL_get1_session(conn->xprt_ctx);
Emeric Brun46591952012-05-18 15:47:34 +02002861 }
Willy Tarreau0c9c2722014-05-28 12:28:58 +02002862 else {
2863 update_freq_ctr(&global.ssl_fe_keys_per_sec, 1);
2864 if (global.ssl_fe_keys_per_sec.curr_ctr > global.ssl_fe_keys_max)
2865 global.ssl_fe_keys_max = global.ssl_fe_keys_per_sec.curr_ctr;
2866 }
Emeric Brun46591952012-05-18 15:47:34 +02002867 }
2868
2869 /* The connection is now established at both layers, it's time to leave */
2870 conn->flags &= ~(flag | CO_FL_WAIT_L4_CONN | CO_FL_WAIT_L6_CONN);
2871 return 1;
2872
2873 out_error:
Emeric Brun644cde02012-12-14 11:21:13 +01002874 /* Clear openssl global errors stack */
2875 ERR_clear_error();
2876
Emeric Brun9fa89732012-10-04 17:09:56 +02002877 /* free resumed session if exists */
Willy Tarreau3fdb3662012-11-12 00:42:33 +01002878 if (objt_server(conn->target) && objt_server(conn->target)->ssl_ctx.reused_sess) {
2879 SSL_SESSION_free(objt_server(conn->target)->ssl_ctx.reused_sess);
2880 objt_server(conn->target)->ssl_ctx.reused_sess = NULL;
Emeric Brun9fa89732012-10-04 17:09:56 +02002881 }
2882
Emeric Brun46591952012-05-18 15:47:34 +02002883 /* Fail on all other handshake errors */
2884 conn->flags |= CO_FL_ERROR;
Willy Tarreau20879a02012-12-03 16:32:10 +01002885 if (!conn->err_code)
2886 conn->err_code = CO_ER_SSL_HANDSHAKE;
Emeric Brun46591952012-05-18 15:47:34 +02002887 return 0;
2888}
2889
2890/* Receive up to <count> bytes from connection <conn>'s socket and store them
Willy Tarreauabf08d92014-01-14 11:31:27 +01002891 * into buffer <buf>. Only one call to recv() is performed, unless the
Emeric Brun46591952012-05-18 15:47:34 +02002892 * buffer wraps, in which case a second call may be performed. The connection's
2893 * flags are updated with whatever special event is detected (error, read0,
2894 * empty). The caller is responsible for taking care of those events and
2895 * avoiding the call if inappropriate. The function does not call the
2896 * connection's polling update function, so the caller is responsible for this.
2897 */
2898static int ssl_sock_to_buf(struct connection *conn, struct buffer *buf, int count)
2899{
2900 int ret, done = 0;
Willy Tarreauabf08d92014-01-14 11:31:27 +01002901 int try;
Emeric Brun46591952012-05-18 15:47:34 +02002902
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02002903 if (!conn->xprt_ctx)
Emeric Brun46591952012-05-18 15:47:34 +02002904 goto out_error;
2905
2906 if (conn->flags & CO_FL_HANDSHAKE)
2907 /* a handshake was requested */
2908 return 0;
2909
Willy Tarreauabf08d92014-01-14 11:31:27 +01002910 /* let's realign the buffer to optimize I/O */
2911 if (buffer_empty(buf))
Emeric Brun46591952012-05-18 15:47:34 +02002912 buf->p = buf->data;
Emeric Brun46591952012-05-18 15:47:34 +02002913
2914 /* read the largest possible block. For this, we perform only one call
2915 * to recv() unless the buffer wraps and we exactly fill the first hunk,
2916 * in which case we accept to do it once again. A new attempt is made on
2917 * EINTR too.
2918 */
Willy Tarreau00b0fb92014-01-17 11:09:40 +01002919 while (count > 0) {
Willy Tarreauabf08d92014-01-14 11:31:27 +01002920 /* first check if we have some room after p+i */
2921 try = buf->data + buf->size - (buf->p + buf->i);
2922 /* otherwise continue between data and p-o */
2923 if (try <= 0) {
2924 try = buf->p - (buf->data + buf->o);
2925 if (try <= 0)
2926 break;
2927 }
2928 if (try > count)
2929 try = count;
2930
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02002931 ret = SSL_read(conn->xprt_ctx, bi_end(buf), try);
Emeric Brune1f38db2012-09-03 20:36:47 +02002932 if (conn->flags & CO_FL_ERROR) {
2933 /* CO_FL_ERROR may be set by ssl_sock_infocbk */
Emeric Brun644cde02012-12-14 11:21:13 +01002934 goto out_error;
Emeric Brune1f38db2012-09-03 20:36:47 +02002935 }
Emeric Brun46591952012-05-18 15:47:34 +02002936 if (ret > 0) {
2937 buf->i += ret;
2938 done += ret;
2939 if (ret < try)
2940 break;
2941 count -= ret;
Emeric Brun46591952012-05-18 15:47:34 +02002942 }
2943 else if (ret == 0) {
Emeric Brun644cde02012-12-14 11:21:13 +01002944 ret = SSL_get_error(conn->xprt_ctx, ret);
2945 if (ret != SSL_ERROR_ZERO_RETURN) {
Emeric Brun1c646862012-12-14 12:33:41 +01002946 /* error on protocol or underlying transport */
2947 if ((ret != SSL_ERROR_SYSCALL)
2948 || (errno && (errno != EAGAIN)))
2949 conn->flags |= CO_FL_ERROR;
2950
Emeric Brun644cde02012-12-14 11:21:13 +01002951 /* Clear openssl global errors stack */
2952 ERR_clear_error();
2953 }
Emeric Brun46591952012-05-18 15:47:34 +02002954 goto read0;
2955 }
2956 else {
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02002957 ret = SSL_get_error(conn->xprt_ctx, ret);
Emeric Brun46591952012-05-18 15:47:34 +02002958 if (ret == SSL_ERROR_WANT_WRITE) {
Emeric Brun8af8dd12012-11-08 17:56:20 +01002959 /* handshake is running, and it needs to enable write */
Emeric Brun46591952012-05-18 15:47:34 +02002960 conn->flags |= CO_FL_SSL_WAIT_HS;
Emeric Brun8af8dd12012-11-08 17:56:20 +01002961 __conn_sock_want_send(conn);
Emeric Brun46591952012-05-18 15:47:34 +02002962 break;
2963 }
2964 else if (ret == SSL_ERROR_WANT_READ) {
Emeric Brun282a76a2012-11-08 18:02:56 +01002965 if (SSL_renegotiate_pending(conn->xprt_ctx)) {
2966 /* handshake is running, and it may need to re-enable read */
2967 conn->flags |= CO_FL_SSL_WAIT_HS;
2968 __conn_sock_want_recv(conn);
2969 break;
2970 }
Emeric Brun46591952012-05-18 15:47:34 +02002971 /* we need to poll for retry a read later */
Willy Tarreaue1f50c42014-01-22 20:02:06 +01002972 fd_cant_recv(conn->t.sock.fd);
Emeric Brun46591952012-05-18 15:47:34 +02002973 break;
2974 }
2975 /* otherwise it's a real error */
2976 goto out_error;
2977 }
2978 }
2979 return done;
2980
2981 read0:
2982 conn_sock_read0(conn);
2983 return done;
2984 out_error:
Emeric Brun644cde02012-12-14 11:21:13 +01002985 /* Clear openssl global errors stack */
2986 ERR_clear_error();
2987
Emeric Brun46591952012-05-18 15:47:34 +02002988 conn->flags |= CO_FL_ERROR;
2989 return done;
2990}
2991
2992
2993/* Send all pending bytes from buffer <buf> to connection <conn>'s socket.
Willy Tarreau1049b1f2014-02-02 01:51:17 +01002994 * <flags> may contain some CO_SFL_* flags to hint the system about other
2995 * pending data for example, but this flag is ignored at the moment.
Emeric Brun46591952012-05-18 15:47:34 +02002996 * Only one call to send() is performed, unless the buffer wraps, in which case
2997 * a second call may be performed. The connection's flags are updated with
2998 * whatever special event is detected (error, empty). The caller is responsible
2999 * for taking care of those events and avoiding the call if inappropriate. The
3000 * function does not call the connection's polling update function, so the caller
3001 * is responsible for this.
3002 */
3003static int ssl_sock_from_buf(struct connection *conn, struct buffer *buf, int flags)
3004{
3005 int ret, try, done;
3006
3007 done = 0;
3008
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02003009 if (!conn->xprt_ctx)
Emeric Brun46591952012-05-18 15:47:34 +02003010 goto out_error;
3011
3012 if (conn->flags & CO_FL_HANDSHAKE)
3013 /* a handshake was requested */
3014 return 0;
3015
3016 /* send the largest possible block. For this we perform only one call
3017 * to send() unless the buffer wraps and we exactly fill the first hunk,
3018 * in which case we accept to do it once again.
3019 */
3020 while (buf->o) {
Kevin Hestercad82342013-05-30 15:12:41 -07003021 try = bo_contig_data(buf);
Willy Tarreaubfd59462013-02-21 07:46:09 +01003022
Willy Tarreau7bed9452014-02-02 02:00:24 +01003023 if (!(flags & CO_SFL_STREAMER) &&
Willy Tarreau518cedd2014-02-17 15:43:01 +01003024 !(conn->xprt_st & SSL_SOCK_SEND_UNLIMITED) &&
3025 global.tune.ssl_max_record && try > global.tune.ssl_max_record) {
Willy Tarreaubfd59462013-02-21 07:46:09 +01003026 try = global.tune.ssl_max_record;
Willy Tarreau518cedd2014-02-17 15:43:01 +01003027 }
3028 else {
3029 /* we need to keep the information about the fact that
3030 * we're not limiting the upcoming send(), because if it
3031 * fails, we'll have to retry with at least as many data.
3032 */
3033 conn->xprt_st |= SSL_SOCK_SEND_UNLIMITED;
3034 }
Willy Tarreaubfd59462013-02-21 07:46:09 +01003035
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02003036 ret = SSL_write(conn->xprt_ctx, bo_ptr(buf), try);
Willy Tarreau518cedd2014-02-17 15:43:01 +01003037
Emeric Brune1f38db2012-09-03 20:36:47 +02003038 if (conn->flags & CO_FL_ERROR) {
3039 /* CO_FL_ERROR may be set by ssl_sock_infocbk */
Emeric Brun644cde02012-12-14 11:21:13 +01003040 goto out_error;
Emeric Brune1f38db2012-09-03 20:36:47 +02003041 }
Emeric Brun46591952012-05-18 15:47:34 +02003042 if (ret > 0) {
Willy Tarreau518cedd2014-02-17 15:43:01 +01003043 conn->xprt_st &= ~SSL_SOCK_SEND_UNLIMITED;
3044
Emeric Brun46591952012-05-18 15:47:34 +02003045 buf->o -= ret;
3046 done += ret;
3047
Willy Tarreau5fb38032012-12-16 19:39:09 +01003048 if (likely(buffer_empty(buf)))
Emeric Brun46591952012-05-18 15:47:34 +02003049 /* optimize data alignment in the buffer */
3050 buf->p = buf->data;
3051
3052 /* if the system buffer is full, don't insist */
3053 if (ret < try)
3054 break;
3055 }
3056 else {
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02003057 ret = SSL_get_error(conn->xprt_ctx, ret);
Emeric Brun46591952012-05-18 15:47:34 +02003058 if (ret == SSL_ERROR_WANT_WRITE) {
Emeric Brun282a76a2012-11-08 18:02:56 +01003059 if (SSL_renegotiate_pending(conn->xprt_ctx)) {
3060 /* handshake is running, and it may need to re-enable write */
3061 conn->flags |= CO_FL_SSL_WAIT_HS;
3062 __conn_sock_want_send(conn);
3063 break;
3064 }
Emeric Brun46591952012-05-18 15:47:34 +02003065 /* we need to poll to retry a write later */
Willy Tarreaue1f50c42014-01-22 20:02:06 +01003066 fd_cant_send(conn->t.sock.fd);
Emeric Brun46591952012-05-18 15:47:34 +02003067 break;
3068 }
3069 else if (ret == SSL_ERROR_WANT_READ) {
Emeric Brun8af8dd12012-11-08 17:56:20 +01003070 /* handshake is running, and it needs to enable read */
Emeric Brun46591952012-05-18 15:47:34 +02003071 conn->flags |= CO_FL_SSL_WAIT_HS;
Emeric Brun8af8dd12012-11-08 17:56:20 +01003072 __conn_sock_want_recv(conn);
Emeric Brun46591952012-05-18 15:47:34 +02003073 break;
3074 }
3075 goto out_error;
3076 }
3077 }
3078 return done;
3079
3080 out_error:
Emeric Brun644cde02012-12-14 11:21:13 +01003081 /* Clear openssl global errors stack */
3082 ERR_clear_error();
3083
Emeric Brun46591952012-05-18 15:47:34 +02003084 conn->flags |= CO_FL_ERROR;
3085 return done;
3086}
3087
Emeric Brun46591952012-05-18 15:47:34 +02003088static void ssl_sock_close(struct connection *conn) {
3089
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02003090 if (conn->xprt_ctx) {
Christopher Fauletd2cab922015-07-28 16:03:47 +02003091 if (!ssl_ctx_lru_tree && objt_listener(conn->target)) {
3092 SSL_CTX *ctx = SSL_get_SSL_CTX(conn->xprt_ctx);
3093 if (ctx != objt_listener(conn->target)->bind_conf->default_ctx)
3094 SSL_CTX_free(ctx);
3095 }
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02003096 SSL_free(conn->xprt_ctx);
3097 conn->xprt_ctx = NULL;
Willy Tarreau403edff2012-09-06 11:58:37 +02003098 sslconns--;
Emeric Brun46591952012-05-18 15:47:34 +02003099 }
Emeric Brun46591952012-05-18 15:47:34 +02003100}
3101
3102/* This function tries to perform a clean shutdown on an SSL connection, and in
3103 * any case, flags the connection as reusable if no handshake was in progress.
3104 */
3105static void ssl_sock_shutw(struct connection *conn, int clean)
3106{
3107 if (conn->flags & CO_FL_HANDSHAKE)
3108 return;
3109 /* no handshake was in progress, try a clean ssl shutdown */
Emeric Brun644cde02012-12-14 11:21:13 +01003110 if (clean && (SSL_shutdown(conn->xprt_ctx) <= 0)) {
3111 /* Clear openssl global errors stack */
3112 ERR_clear_error();
3113 }
Emeric Brun46591952012-05-18 15:47:34 +02003114
3115 /* force flag on ssl to keep session in cache regardless shutdown result */
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02003116 SSL_set_shutdown(conn->xprt_ctx, SSL_SENT_SHUTDOWN);
Emeric Brun46591952012-05-18 15:47:34 +02003117}
3118
Willy Tarreauffc3fcd2012-10-12 20:17:54 +02003119/* used for logging, may be changed for a sample fetch later */
3120const char *ssl_sock_get_cipher_name(struct connection *conn)
3121{
3122 if (!conn->xprt && !conn->xprt_ctx)
3123 return NULL;
3124 return SSL_get_cipher_name(conn->xprt_ctx);
3125}
3126
3127/* used for logging, may be changed for a sample fetch later */
3128const char *ssl_sock_get_proto_version(struct connection *conn)
3129{
3130 if (!conn->xprt && !conn->xprt_ctx)
3131 return NULL;
3132 return SSL_get_version(conn->xprt_ctx);
3133}
3134
Willy Tarreau8d598402012-10-22 17:58:39 +02003135/* Extract a serial from a cert, and copy it to a chunk.
3136 * Returns 1 if serial is found and copied, 0 if no serial found and
3137 * -1 if output is not large enough.
3138 */
3139static int
3140ssl_sock_get_serial(X509 *crt, struct chunk *out)
3141{
3142 ASN1_INTEGER *serial;
3143
3144 serial = X509_get_serialNumber(crt);
3145 if (!serial)
3146 return 0;
3147
3148 if (out->size < serial->length)
3149 return -1;
3150
3151 memcpy(out->str, serial->data, serial->length);
3152 out->len = serial->length;
3153 return 1;
3154}
3155
Emeric Brun43e79582014-10-29 19:03:26 +01003156/* Extract a cert to der, and copy it to a chunk.
3157 * Returns 1 if cert is found and copied, 0 on der convertion failure and
3158 * -1 if output is not large enough.
3159 */
3160static int
3161ssl_sock_crt2der(X509 *crt, struct chunk *out)
3162{
3163 int len;
3164 unsigned char *p = (unsigned char *)out->str;;
3165
3166 len =i2d_X509(crt, NULL);
3167 if (len <= 0)
3168 return 1;
3169
3170 if (out->size < len)
3171 return -1;
3172
3173 i2d_X509(crt,&p);
3174 out->len = len;
3175 return 1;
3176}
3177
Emeric Brunce5ad802012-10-22 14:11:22 +02003178
3179/* Copy Date in ASN1_UTCTIME format in struct chunk out.
3180 * Returns 1 if serial is found and copied, 0 if no valid time found
3181 * and -1 if output is not large enough.
3182 */
3183static int
3184ssl_sock_get_time(ASN1_TIME *tm, struct chunk *out)
3185{
3186 if (tm->type == V_ASN1_GENERALIZEDTIME) {
3187 ASN1_GENERALIZEDTIME *gentm = (ASN1_GENERALIZEDTIME *)tm;
3188
3189 if (gentm->length < 12)
3190 return 0;
3191 if (gentm->data[0] != 0x32 || gentm->data[1] != 0x30)
3192 return 0;
3193 if (out->size < gentm->length-2)
3194 return -1;
3195
3196 memcpy(out->str, gentm->data+2, gentm->length-2);
3197 out->len = gentm->length-2;
3198 return 1;
3199 }
3200 else if (tm->type == V_ASN1_UTCTIME) {
3201 ASN1_UTCTIME *utctm = (ASN1_UTCTIME *)tm;
3202
3203 if (utctm->length < 10)
3204 return 0;
3205 if (utctm->data[0] >= 0x35)
3206 return 0;
3207 if (out->size < utctm->length)
3208 return -1;
3209
3210 memcpy(out->str, utctm->data, utctm->length);
3211 out->len = utctm->length;
3212 return 1;
3213 }
3214
3215 return 0;
3216}
3217
Emeric Brun87855892012-10-17 17:39:35 +02003218/* Extract an entry from a X509_NAME and copy its value to an output chunk.
3219 * Returns 1 if entry found, 0 if entry not found, or -1 if output not large enough.
3220 */
3221static int
3222ssl_sock_get_dn_entry(X509_NAME *a, const struct chunk *entry, int pos, struct chunk *out)
3223{
3224 X509_NAME_ENTRY *ne;
3225 int i, j, n;
3226 int cur = 0;
3227 const char *s;
3228 char tmp[128];
3229
3230 out->len = 0;
3231 for (i = 0; i < sk_X509_NAME_ENTRY_num(a->entries); i++) {
3232 if (pos < 0)
3233 j = (sk_X509_NAME_ENTRY_num(a->entries)-1) - i;
3234 else
3235 j = i;
3236
3237 ne = sk_X509_NAME_ENTRY_value(a->entries, j);
3238 n = OBJ_obj2nid(ne->object);
3239 if ((n == NID_undef) || ((s = OBJ_nid2sn(n)) == NULL)) {
3240 i2t_ASN1_OBJECT(tmp, sizeof(tmp), ne->object);
3241 s = tmp;
3242 }
3243
3244 if (chunk_strcasecmp(entry, s) != 0)
3245 continue;
3246
3247 if (pos < 0)
3248 cur--;
3249 else
3250 cur++;
3251
3252 if (cur != pos)
3253 continue;
3254
3255 if (ne->value->length > out->size)
3256 return -1;
3257
3258 memcpy(out->str, ne->value->data, ne->value->length);
3259 out->len = ne->value->length;
3260 return 1;
3261 }
3262
3263 return 0;
3264
3265}
3266
3267/* Extract and format full DN from a X509_NAME and copy result into a chunk
3268 * Returns 1 if dn entries exits, 0 if no dn entry found or -1 if output is not large enough.
3269 */
3270static int
3271ssl_sock_get_dn_oneline(X509_NAME *a, struct chunk *out)
3272{
3273 X509_NAME_ENTRY *ne;
3274 int i, n, ln;
3275 int l = 0;
3276 const char *s;
3277 char *p;
3278 char tmp[128];
3279
3280 out->len = 0;
3281 p = out->str;
3282 for (i = 0; i < sk_X509_NAME_ENTRY_num(a->entries); i++) {
3283 ne = sk_X509_NAME_ENTRY_value(a->entries, i);
3284 n = OBJ_obj2nid(ne->object);
3285 if ((n == NID_undef) || ((s = OBJ_nid2sn(n)) == NULL)) {
3286 i2t_ASN1_OBJECT(tmp, sizeof(tmp), ne->object);
3287 s = tmp;
3288 }
3289 ln = strlen(s);
3290
3291 l += 1 + ln + 1 + ne->value->length;
3292 if (l > out->size)
3293 return -1;
3294 out->len = l;
3295
3296 *(p++)='/';
3297 memcpy(p, s, ln);
3298 p += ln;
3299 *(p++)='=';
3300 memcpy(p, ne->value->data, ne->value->length);
3301 p += ne->value->length;
3302 }
3303
3304 if (!out->len)
3305 return 0;
3306
3307 return 1;
3308}
3309
David Safb76832014-05-08 23:42:08 -04003310char *ssl_sock_get_version(struct connection *conn)
3311{
3312 if (!ssl_sock_is_ssl(conn))
3313 return NULL;
3314
3315 return (char *)SSL_get_version(conn->xprt_ctx);
3316}
3317
Willy Tarreau63076412015-07-10 11:33:32 +02003318void ssl_sock_set_servername(struct connection *conn, const char *hostname)
3319{
3320#ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME
3321 if (!ssl_sock_is_ssl(conn))
3322 return;
3323
3324 SSL_set_tlsext_host_name(conn->xprt_ctx, hostname);
3325#endif
3326}
3327
Emeric Brun0abf8362014-06-24 18:26:41 +02003328/* Extract peer certificate's common name into the chunk dest
3329 * Returns
3330 * the len of the extracted common name
3331 * or 0 if no CN found in DN
3332 * or -1 on error case (i.e. no peer certificate)
3333 */
3334int ssl_sock_get_remote_common_name(struct connection *conn, struct chunk *dest)
David Safb76832014-05-08 23:42:08 -04003335{
3336 X509 *crt = NULL;
3337 X509_NAME *name;
David Safb76832014-05-08 23:42:08 -04003338 const char find_cn[] = "CN";
3339 const struct chunk find_cn_chunk = {
3340 .str = (char *)&find_cn,
3341 .len = sizeof(find_cn)-1
3342 };
Emeric Brun0abf8362014-06-24 18:26:41 +02003343 int result = -1;
David Safb76832014-05-08 23:42:08 -04003344
3345 if (!ssl_sock_is_ssl(conn))
Emeric Brun0abf8362014-06-24 18:26:41 +02003346 goto out;
David Safb76832014-05-08 23:42:08 -04003347
3348 /* SSL_get_peer_certificate, it increase X509 * ref count */
3349 crt = SSL_get_peer_certificate(conn->xprt_ctx);
3350 if (!crt)
3351 goto out;
3352
3353 name = X509_get_subject_name(crt);
3354 if (!name)
3355 goto out;
David Safb76832014-05-08 23:42:08 -04003356
Emeric Brun0abf8362014-06-24 18:26:41 +02003357 result = ssl_sock_get_dn_entry(name, &find_cn_chunk, 1, dest);
3358out:
David Safb76832014-05-08 23:42:08 -04003359 if (crt)
3360 X509_free(crt);
3361
3362 return result;
3363}
3364
Dave McCowan328fb582014-07-30 10:39:13 -04003365/* returns 1 if client passed a certificate for this session, 0 if not */
3366int ssl_sock_get_cert_used_sess(struct connection *conn)
3367{
3368 X509 *crt = NULL;
3369
3370 if (!ssl_sock_is_ssl(conn))
3371 return 0;
3372
3373 /* SSL_get_peer_certificate, it increase X509 * ref count */
3374 crt = SSL_get_peer_certificate(conn->xprt_ctx);
3375 if (!crt)
3376 return 0;
3377
3378 X509_free(crt);
3379 return 1;
3380}
3381
3382/* returns 1 if client passed a certificate for this connection, 0 if not */
3383int ssl_sock_get_cert_used_conn(struct connection *conn)
David Safb76832014-05-08 23:42:08 -04003384{
3385 if (!ssl_sock_is_ssl(conn))
3386 return 0;
3387
3388 return SSL_SOCK_ST_FL_VERIFY_DONE & conn->xprt_st ? 1 : 0;
3389}
3390
3391/* returns result from SSL verify */
3392unsigned int ssl_sock_get_verify_result(struct connection *conn)
3393{
3394 if (!ssl_sock_is_ssl(conn))
3395 return (unsigned int)X509_V_ERR_APPLICATION_VERIFICATION;
3396
3397 return (unsigned int)SSL_get_verify_result(conn->xprt_ctx);
3398}
3399
Willy Tarreau7875d092012-09-10 08:20:03 +02003400/***** Below are some sample fetching functions for ACL/patterns *****/
3401
Emeric Brune64aef12012-09-21 13:15:06 +02003402/* boolean, returns true if client cert was present */
3403static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02003404smp_fetch_ssl_fc_has_crt(const struct arg *args, struct sample *smp, const char *kw, void *private)
Emeric Brune64aef12012-09-21 13:15:06 +02003405{
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003406 struct connection *conn;
3407
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02003408 conn = objt_conn(smp->sess->origin);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003409 if (!conn || conn->xprt != &ssl_sock)
Emeric Brune64aef12012-09-21 13:15:06 +02003410 return 0;
3411
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003412 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brune64aef12012-09-21 13:15:06 +02003413 smp->flags |= SMP_F_MAY_CHANGE;
3414 return 0;
3415 }
3416
3417 smp->flags = 0;
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02003418 smp->data.type = SMP_T_BOOL;
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02003419 smp->data.u.sint = SSL_SOCK_ST_FL_VERIFY_DONE & conn->xprt_st ? 1 : 0;
Emeric Brune64aef12012-09-21 13:15:06 +02003420
3421 return 1;
3422}
3423
Emeric Brun43e79582014-10-29 19:03:26 +01003424/* binary, returns a certificate in a binary chunk (der/raw).
3425 * The 5th keyword char is used to know if SSL_get_certificate or SSL_get_peer_certificate
3426 * should be use.
3427 */
3428static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02003429smp_fetch_ssl_x_der(const struct arg *args, struct sample *smp, const char *kw, void *private)
Emeric Brun43e79582014-10-29 19:03:26 +01003430{
3431 int cert_peer = (kw[4] == 'c') ? 1 : 0;
3432 X509 *crt = NULL;
3433 int ret = 0;
3434 struct chunk *smp_trash;
3435 struct connection *conn;
3436
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02003437 conn = objt_conn(smp->sess->origin);
Emeric Brun43e79582014-10-29 19:03:26 +01003438 if (!conn || conn->xprt != &ssl_sock)
3439 return 0;
3440
3441 if (!(conn->flags & CO_FL_CONNECTED)) {
3442 smp->flags |= SMP_F_MAY_CHANGE;
3443 return 0;
3444 }
3445
3446 if (cert_peer)
3447 crt = SSL_get_peer_certificate(conn->xprt_ctx);
3448 else
3449 crt = SSL_get_certificate(conn->xprt_ctx);
3450
3451 if (!crt)
3452 goto out;
3453
3454 smp_trash = get_trash_chunk();
3455 if (ssl_sock_crt2der(crt, smp_trash) <= 0)
3456 goto out;
3457
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02003458 smp->data.u.str = *smp_trash;
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02003459 smp->data.type = SMP_T_BIN;
Emeric Brun43e79582014-10-29 19:03:26 +01003460 ret = 1;
3461out:
3462 /* SSL_get_peer_certificate, it increase X509 * ref count */
3463 if (cert_peer && crt)
3464 X509_free(crt);
3465 return ret;
3466}
3467
Emeric Brunba841a12014-04-30 17:05:08 +02003468/* binary, returns serial of certificate in a binary chunk.
3469 * The 5th keyword char is used to know if SSL_get_certificate or SSL_get_peer_certificate
3470 * should be use.
3471 */
Willy Tarreau8d598402012-10-22 17:58:39 +02003472static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02003473smp_fetch_ssl_x_serial(const struct arg *args, struct sample *smp, const char *kw, void *private)
Willy Tarreau8d598402012-10-22 17:58:39 +02003474{
Emeric Brunba841a12014-04-30 17:05:08 +02003475 int cert_peer = (kw[4] == 'c') ? 1 : 0;
Willy Tarreau8d598402012-10-22 17:58:39 +02003476 X509 *crt = NULL;
3477 int ret = 0;
3478 struct chunk *smp_trash;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003479 struct connection *conn;
3480
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02003481 conn = objt_conn(smp->sess->origin);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003482 if (!conn || conn->xprt != &ssl_sock)
Willy Tarreau8d598402012-10-22 17:58:39 +02003483 return 0;
3484
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003485 if (!(conn->flags & CO_FL_CONNECTED)) {
Willy Tarreau8d598402012-10-22 17:58:39 +02003486 smp->flags |= SMP_F_MAY_CHANGE;
3487 return 0;
3488 }
3489
Emeric Brunba841a12014-04-30 17:05:08 +02003490 if (cert_peer)
3491 crt = SSL_get_peer_certificate(conn->xprt_ctx);
3492 else
3493 crt = SSL_get_certificate(conn->xprt_ctx);
3494
Willy Tarreau8d598402012-10-22 17:58:39 +02003495 if (!crt)
3496 goto out;
3497
Willy Tarreau47ca5452012-12-23 20:22:19 +01003498 smp_trash = get_trash_chunk();
Willy Tarreau8d598402012-10-22 17:58:39 +02003499 if (ssl_sock_get_serial(crt, smp_trash) <= 0)
3500 goto out;
3501
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02003502 smp->data.u.str = *smp_trash;
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02003503 smp->data.type = SMP_T_BIN;
Willy Tarreau8d598402012-10-22 17:58:39 +02003504 ret = 1;
3505out:
Emeric Brunba841a12014-04-30 17:05:08 +02003506 /* SSL_get_peer_certificate, it increase X509 * ref count */
3507 if (cert_peer && crt)
Willy Tarreau8d598402012-10-22 17:58:39 +02003508 X509_free(crt);
3509 return ret;
3510}
Emeric Brune64aef12012-09-21 13:15:06 +02003511
Emeric Brunba841a12014-04-30 17:05:08 +02003512/* binary, returns the client certificate's SHA-1 fingerprint (SHA-1 hash of DER-encoded certificate) in a binary chunk.
3513 * The 5th keyword char is used to know if SSL_get_certificate or SSL_get_peer_certificate
3514 * should be use.
3515 */
James Votha051b4a2013-05-14 20:37:59 +02003516static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02003517smp_fetch_ssl_x_sha1(const struct arg *args, struct sample *smp, const char *kw, void *private)
James Votha051b4a2013-05-14 20:37:59 +02003518{
Emeric Brunba841a12014-04-30 17:05:08 +02003519 int cert_peer = (kw[4] == 'c') ? 1 : 0;
James Votha051b4a2013-05-14 20:37:59 +02003520 X509 *crt = NULL;
3521 const EVP_MD *digest;
3522 int ret = 0;
3523 struct chunk *smp_trash;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003524 struct connection *conn;
James Votha051b4a2013-05-14 20:37:59 +02003525
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02003526 conn = objt_conn(smp->sess->origin);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003527 if (!conn || conn->xprt != &ssl_sock)
3528 return 0;
3529
3530 if (!(conn->flags & CO_FL_CONNECTED)) {
James Votha051b4a2013-05-14 20:37:59 +02003531 smp->flags |= SMP_F_MAY_CHANGE;
3532 return 0;
3533 }
3534
Emeric Brunba841a12014-04-30 17:05:08 +02003535 if (cert_peer)
3536 crt = SSL_get_peer_certificate(conn->xprt_ctx);
3537 else
3538 crt = SSL_get_certificate(conn->xprt_ctx);
James Votha051b4a2013-05-14 20:37:59 +02003539 if (!crt)
3540 goto out;
3541
3542 smp_trash = get_trash_chunk();
3543 digest = EVP_sha1();
3544 X509_digest(crt, digest, (unsigned char *)smp_trash->str, (unsigned int *)&smp_trash->len);
3545
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02003546 smp->data.u.str = *smp_trash;
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02003547 smp->data.type = SMP_T_BIN;
James Votha051b4a2013-05-14 20:37:59 +02003548 ret = 1;
3549out:
Emeric Brunba841a12014-04-30 17:05:08 +02003550 /* SSL_get_peer_certificate, it increase X509 * ref count */
3551 if (cert_peer && crt)
James Votha051b4a2013-05-14 20:37:59 +02003552 X509_free(crt);
3553 return ret;
3554}
3555
Emeric Brunba841a12014-04-30 17:05:08 +02003556/* string, returns certificate's notafter date in ASN1_UTCTIME format.
3557 * The 5th keyword char is used to know if SSL_get_certificate or SSL_get_peer_certificate
3558 * should be use.
3559 */
Emeric Brunce5ad802012-10-22 14:11:22 +02003560static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02003561smp_fetch_ssl_x_notafter(const struct arg *args, struct sample *smp, const char *kw, void *private)
Emeric Brunce5ad802012-10-22 14:11:22 +02003562{
Emeric Brunba841a12014-04-30 17:05:08 +02003563 int cert_peer = (kw[4] == 'c') ? 1 : 0;
Emeric Brunce5ad802012-10-22 14:11:22 +02003564 X509 *crt = NULL;
3565 int ret = 0;
3566 struct chunk *smp_trash;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003567 struct connection *conn;
Emeric Brunce5ad802012-10-22 14:11:22 +02003568
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02003569 conn = objt_conn(smp->sess->origin);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003570 if (!conn || conn->xprt != &ssl_sock)
3571 return 0;
3572
3573 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brunce5ad802012-10-22 14:11:22 +02003574 smp->flags |= SMP_F_MAY_CHANGE;
3575 return 0;
3576 }
3577
Emeric Brunba841a12014-04-30 17:05:08 +02003578 if (cert_peer)
3579 crt = SSL_get_peer_certificate(conn->xprt_ctx);
3580 else
3581 crt = SSL_get_certificate(conn->xprt_ctx);
Emeric Brunce5ad802012-10-22 14:11:22 +02003582 if (!crt)
3583 goto out;
3584
Willy Tarreau47ca5452012-12-23 20:22:19 +01003585 smp_trash = get_trash_chunk();
Emeric Brunce5ad802012-10-22 14:11:22 +02003586 if (ssl_sock_get_time(X509_get_notAfter(crt), smp_trash) <= 0)
3587 goto out;
3588
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02003589 smp->data.u.str = *smp_trash;
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02003590 smp->data.type = SMP_T_STR;
Emeric Brunce5ad802012-10-22 14:11:22 +02003591 ret = 1;
3592out:
Emeric Brunba841a12014-04-30 17:05:08 +02003593 /* SSL_get_peer_certificate, it increase X509 * ref count */
3594 if (cert_peer && crt)
Emeric Brunce5ad802012-10-22 14:11:22 +02003595 X509_free(crt);
3596 return ret;
3597}
3598
Emeric Brunba841a12014-04-30 17:05:08 +02003599/* string, returns a string of a formatted full dn \C=..\O=..\OU=.. \CN=.. of certificate's issuer
3600 * The 5th keyword char is used to know if SSL_get_certificate or SSL_get_peer_certificate
3601 * should be use.
3602 */
Emeric Brun87855892012-10-17 17:39:35 +02003603static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02003604smp_fetch_ssl_x_i_dn(const struct arg *args, struct sample *smp, const char *kw, void *private)
Emeric Brun87855892012-10-17 17:39:35 +02003605{
Emeric Brunba841a12014-04-30 17:05:08 +02003606 int cert_peer = (kw[4] == 'c') ? 1 : 0;
Emeric Brun87855892012-10-17 17:39:35 +02003607 X509 *crt = NULL;
3608 X509_NAME *name;
3609 int ret = 0;
3610 struct chunk *smp_trash;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003611 struct connection *conn;
Emeric Brun87855892012-10-17 17:39:35 +02003612
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02003613 conn = objt_conn(smp->sess->origin);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003614 if (!conn || conn->xprt != &ssl_sock)
3615 return 0;
3616
3617 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brun87855892012-10-17 17:39:35 +02003618 smp->flags |= SMP_F_MAY_CHANGE;
3619 return 0;
3620 }
3621
Emeric Brunba841a12014-04-30 17:05:08 +02003622 if (cert_peer)
3623 crt = SSL_get_peer_certificate(conn->xprt_ctx);
3624 else
3625 crt = SSL_get_certificate(conn->xprt_ctx);
Emeric Brun87855892012-10-17 17:39:35 +02003626 if (!crt)
3627 goto out;
3628
3629 name = X509_get_issuer_name(crt);
3630 if (!name)
3631 goto out;
3632
Willy Tarreau47ca5452012-12-23 20:22:19 +01003633 smp_trash = get_trash_chunk();
Emeric Brun87855892012-10-17 17:39:35 +02003634 if (args && args[0].type == ARGT_STR) {
3635 int pos = 1;
3636
3637 if (args[1].type == ARGT_SINT)
3638 pos = args[1].data.sint;
Emeric Brun87855892012-10-17 17:39:35 +02003639
3640 if (ssl_sock_get_dn_entry(name, &args[0].data.str, pos, smp_trash) <= 0)
3641 goto out;
3642 }
3643 else if (ssl_sock_get_dn_oneline(name, smp_trash) <= 0)
3644 goto out;
3645
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02003646 smp->data.type = SMP_T_STR;
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02003647 smp->data.u.str = *smp_trash;
Emeric Brun87855892012-10-17 17:39:35 +02003648 ret = 1;
3649out:
Emeric Brunba841a12014-04-30 17:05:08 +02003650 /* SSL_get_peer_certificate, it increase X509 * ref count */
3651 if (cert_peer && crt)
Emeric Brun87855892012-10-17 17:39:35 +02003652 X509_free(crt);
3653 return ret;
3654}
3655
Emeric Brunba841a12014-04-30 17:05:08 +02003656/* string, returns notbefore date in ASN1_UTCTIME format.
3657 * The 5th keyword char is used to know if SSL_get_certificate or SSL_get_peer_certificate
3658 * should be use.
3659 */
Emeric Brunce5ad802012-10-22 14:11:22 +02003660static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02003661smp_fetch_ssl_x_notbefore(const struct arg *args, struct sample *smp, const char *kw, void *private)
Emeric Brunce5ad802012-10-22 14:11:22 +02003662{
Emeric Brunba841a12014-04-30 17:05:08 +02003663 int cert_peer = (kw[4] == 'c') ? 1 : 0;
Emeric Brunce5ad802012-10-22 14:11:22 +02003664 X509 *crt = NULL;
3665 int ret = 0;
3666 struct chunk *smp_trash;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003667 struct connection *conn;
3668
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02003669 conn = objt_conn(smp->sess->origin);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003670 if (!conn || conn->xprt != &ssl_sock)
Emeric Brunce5ad802012-10-22 14:11:22 +02003671 return 0;
3672
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003673 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brunce5ad802012-10-22 14:11:22 +02003674 smp->flags |= SMP_F_MAY_CHANGE;
3675 return 0;
3676 }
3677
Emeric Brunba841a12014-04-30 17:05:08 +02003678 if (cert_peer)
3679 crt = SSL_get_peer_certificate(conn->xprt_ctx);
3680 else
3681 crt = SSL_get_certificate(conn->xprt_ctx);
Emeric Brunce5ad802012-10-22 14:11:22 +02003682 if (!crt)
3683 goto out;
3684
Willy Tarreau47ca5452012-12-23 20:22:19 +01003685 smp_trash = get_trash_chunk();
Emeric Brunce5ad802012-10-22 14:11:22 +02003686 if (ssl_sock_get_time(X509_get_notBefore(crt), smp_trash) <= 0)
3687 goto out;
3688
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02003689 smp->data.u.str = *smp_trash;
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02003690 smp->data.type = SMP_T_STR;
Emeric Brunce5ad802012-10-22 14:11:22 +02003691 ret = 1;
3692out:
Emeric Brunba841a12014-04-30 17:05:08 +02003693 /* SSL_get_peer_certificate, it increase X509 * ref count */
3694 if (cert_peer && crt)
Emeric Brunce5ad802012-10-22 14:11:22 +02003695 X509_free(crt);
3696 return ret;
3697}
3698
Emeric Brunba841a12014-04-30 17:05:08 +02003699/* string, returns a string of a formatted full dn \C=..\O=..\OU=.. \CN=.. of certificate's subject
3700 * The 5th keyword char is used to know if SSL_get_certificate or SSL_get_peer_certificate
3701 * should be use.
3702 */
Emeric Brun87855892012-10-17 17:39:35 +02003703static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02003704smp_fetch_ssl_x_s_dn(const struct arg *args, struct sample *smp, const char *kw, void *private)
Emeric Brun87855892012-10-17 17:39:35 +02003705{
Emeric Brunba841a12014-04-30 17:05:08 +02003706 int cert_peer = (kw[4] == 'c') ? 1 : 0;
Emeric Brun87855892012-10-17 17:39:35 +02003707 X509 *crt = NULL;
3708 X509_NAME *name;
3709 int ret = 0;
3710 struct chunk *smp_trash;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003711 struct connection *conn;
Emeric Brun87855892012-10-17 17:39:35 +02003712
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02003713 conn = objt_conn(smp->sess->origin);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003714 if (!conn || conn->xprt != &ssl_sock)
3715 return 0;
3716
3717 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brun87855892012-10-17 17:39:35 +02003718 smp->flags |= SMP_F_MAY_CHANGE;
3719 return 0;
3720 }
3721
Emeric Brunba841a12014-04-30 17:05:08 +02003722 if (cert_peer)
3723 crt = SSL_get_peer_certificate(conn->xprt_ctx);
3724 else
3725 crt = SSL_get_certificate(conn->xprt_ctx);
Emeric Brun87855892012-10-17 17:39:35 +02003726 if (!crt)
3727 goto out;
3728
3729 name = X509_get_subject_name(crt);
3730 if (!name)
3731 goto out;
3732
Willy Tarreau47ca5452012-12-23 20:22:19 +01003733 smp_trash = get_trash_chunk();
Emeric Brun87855892012-10-17 17:39:35 +02003734 if (args && args[0].type == ARGT_STR) {
3735 int pos = 1;
3736
3737 if (args[1].type == ARGT_SINT)
3738 pos = args[1].data.sint;
Emeric Brun87855892012-10-17 17:39:35 +02003739
3740 if (ssl_sock_get_dn_entry(name, &args[0].data.str, pos, smp_trash) <= 0)
3741 goto out;
3742 }
3743 else if (ssl_sock_get_dn_oneline(name, smp_trash) <= 0)
3744 goto out;
3745
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02003746 smp->data.type = SMP_T_STR;
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02003747 smp->data.u.str = *smp_trash;
Emeric Brun87855892012-10-17 17:39:35 +02003748 ret = 1;
3749out:
Emeric Brunba841a12014-04-30 17:05:08 +02003750 /* SSL_get_peer_certificate, it increase X509 * ref count */
3751 if (cert_peer && crt)
Emeric Brun87855892012-10-17 17:39:35 +02003752 X509_free(crt);
3753 return ret;
3754}
Emeric Brun9143d372012-12-20 15:44:16 +01003755
3756/* integer, returns true if current session use a client certificate */
3757static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02003758smp_fetch_ssl_c_used(const struct arg *args, struct sample *smp, const char *kw, void *private)
Emeric Brun9143d372012-12-20 15:44:16 +01003759{
3760 X509 *crt;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003761 struct connection *conn;
Emeric Brun9143d372012-12-20 15:44:16 +01003762
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02003763 conn = objt_conn(smp->sess->origin);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003764 if (!conn || conn->xprt != &ssl_sock)
3765 return 0;
3766
3767 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brun9143d372012-12-20 15:44:16 +01003768 smp->flags |= SMP_F_MAY_CHANGE;
3769 return 0;
3770 }
3771
3772 /* SSL_get_peer_certificate returns a ptr on allocated X509 struct */
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003773 crt = SSL_get_peer_certificate(conn->xprt_ctx);
Emeric Brun9143d372012-12-20 15:44:16 +01003774 if (crt) {
3775 X509_free(crt);
3776 }
3777
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02003778 smp->data.type = SMP_T_BOOL;
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02003779 smp->data.u.sint = (crt != NULL);
Emeric Brun9143d372012-12-20 15:44:16 +01003780 return 1;
3781}
3782
Emeric Brunba841a12014-04-30 17:05:08 +02003783/* integer, returns the certificate version
3784 * The 5th keyword char is used to know if SSL_get_certificate or SSL_get_peer_certificate
3785 * should be use.
3786 */
Emeric Bruna7359fd2012-10-17 15:03:11 +02003787static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02003788smp_fetch_ssl_x_version(const struct arg *args, struct sample *smp, const char *kw, void *private)
Emeric Bruna7359fd2012-10-17 15:03:11 +02003789{
Emeric Brunba841a12014-04-30 17:05:08 +02003790 int cert_peer = (kw[4] == 'c') ? 1 : 0;
Emeric Bruna7359fd2012-10-17 15:03:11 +02003791 X509 *crt;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003792 struct connection *conn;
3793
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02003794 conn = objt_conn(smp->sess->origin);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003795 if (!conn || conn->xprt != &ssl_sock)
Emeric Bruna7359fd2012-10-17 15:03:11 +02003796 return 0;
3797
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003798 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Bruna7359fd2012-10-17 15:03:11 +02003799 smp->flags |= SMP_F_MAY_CHANGE;
3800 return 0;
3801 }
3802
Emeric Brunba841a12014-04-30 17:05:08 +02003803 if (cert_peer)
3804 crt = SSL_get_peer_certificate(conn->xprt_ctx);
3805 else
3806 crt = SSL_get_certificate(conn->xprt_ctx);
Emeric Bruna7359fd2012-10-17 15:03:11 +02003807 if (!crt)
3808 return 0;
3809
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02003810 smp->data.u.sint = (unsigned int)(1 + X509_get_version(crt));
Emeric Brunba841a12014-04-30 17:05:08 +02003811 /* SSL_get_peer_certificate increase X509 * ref count */
3812 if (cert_peer)
3813 X509_free(crt);
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02003814 smp->data.type = SMP_T_SINT;
Emeric Bruna7359fd2012-10-17 15:03:11 +02003815
3816 return 1;
3817}
3818
Emeric Brunba841a12014-04-30 17:05:08 +02003819/* string, returns the certificate's signature algorithm.
3820 * The 5th keyword char is used to know if SSL_get_certificate or SSL_get_peer_certificate
3821 * should be use.
3822 */
Emeric Brun7f56e742012-10-19 18:15:40 +02003823static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02003824smp_fetch_ssl_x_sig_alg(const struct arg *args, struct sample *smp, const char *kw, void *private)
Emeric Brun7f56e742012-10-19 18:15:40 +02003825{
Emeric Brunba841a12014-04-30 17:05:08 +02003826 int cert_peer = (kw[4] == 'c') ? 1 : 0;
Emeric Brun7f56e742012-10-19 18:15:40 +02003827 X509 *crt;
3828 int nid;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003829 struct connection *conn;
Emeric Brun7f56e742012-10-19 18:15:40 +02003830
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02003831 conn = objt_conn(smp->sess->origin);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003832 if (!conn || conn->xprt != &ssl_sock)
3833 return 0;
3834
3835 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brun7f56e742012-10-19 18:15:40 +02003836 smp->flags |= SMP_F_MAY_CHANGE;
3837 return 0;
3838 }
3839
Emeric Brunba841a12014-04-30 17:05:08 +02003840 if (cert_peer)
3841 crt = SSL_get_peer_certificate(conn->xprt_ctx);
3842 else
3843 crt = SSL_get_certificate(conn->xprt_ctx);
Emeric Brun7f56e742012-10-19 18:15:40 +02003844 if (!crt)
3845 return 0;
3846
3847 nid = OBJ_obj2nid((ASN1_OBJECT *)(crt->cert_info->signature->algorithm));
3848
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02003849 smp->data.u.str.str = (char *)OBJ_nid2sn(nid);
3850 if (!smp->data.u.str.str) {
Emeric Brunba841a12014-04-30 17:05:08 +02003851 /* SSL_get_peer_certificate increase X509 * ref count */
3852 if (cert_peer)
3853 X509_free(crt);
Emeric Brun7f56e742012-10-19 18:15:40 +02003854 return 0;
Emeric Brun9bf3ba22013-10-07 14:31:44 +02003855 }
Emeric Brun7f56e742012-10-19 18:15:40 +02003856
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02003857 smp->data.type = SMP_T_STR;
Thierry FOURNIER7654c9f2013-12-17 00:20:33 +01003858 smp->flags |= SMP_F_CONST;
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02003859 smp->data.u.str.len = strlen(smp->data.u.str.str);
Emeric Brunba841a12014-04-30 17:05:08 +02003860 /* SSL_get_peer_certificate increase X509 * ref count */
3861 if (cert_peer)
3862 X509_free(crt);
Emeric Brun7f56e742012-10-19 18:15:40 +02003863
3864 return 1;
3865}
3866
Emeric Brunba841a12014-04-30 17:05:08 +02003867/* string, returns the certificate's key algorithm.
3868 * The 5th keyword char is used to know if SSL_get_certificate or SSL_get_peer_certificate
3869 * should be use.
3870 */
Emeric Brun521a0112012-10-22 12:22:55 +02003871static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02003872smp_fetch_ssl_x_key_alg(const struct arg *args, struct sample *smp, const char *kw, void *private)
Emeric Brun521a0112012-10-22 12:22:55 +02003873{
Emeric Brunba841a12014-04-30 17:05:08 +02003874 int cert_peer = (kw[4] == 'c') ? 1 : 0;
Emeric Brun521a0112012-10-22 12:22:55 +02003875 X509 *crt;
3876 int nid;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003877 struct connection *conn;
Emeric Brun521a0112012-10-22 12:22:55 +02003878
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02003879 conn = objt_conn(smp->sess->origin);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003880 if (!conn || conn->xprt != &ssl_sock)
3881 return 0;
3882
3883 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brun521a0112012-10-22 12:22:55 +02003884 smp->flags |= SMP_F_MAY_CHANGE;
3885 return 0;
3886 }
3887
Emeric Brunba841a12014-04-30 17:05:08 +02003888 if (cert_peer)
3889 crt = SSL_get_peer_certificate(conn->xprt_ctx);
3890 else
3891 crt = SSL_get_certificate(conn->xprt_ctx);
Emeric Brun521a0112012-10-22 12:22:55 +02003892 if (!crt)
3893 return 0;
3894
3895 nid = OBJ_obj2nid((ASN1_OBJECT *)(crt->cert_info->key->algor->algorithm));
3896
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02003897 smp->data.u.str.str = (char *)OBJ_nid2sn(nid);
3898 if (!smp->data.u.str.str) {
Emeric Brunba841a12014-04-30 17:05:08 +02003899 /* SSL_get_peer_certificate increase X509 * ref count */
3900 if (cert_peer)
3901 X509_free(crt);
Emeric Brun521a0112012-10-22 12:22:55 +02003902 return 0;
Emeric Brun9bf3ba22013-10-07 14:31:44 +02003903 }
Emeric Brun521a0112012-10-22 12:22:55 +02003904
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02003905 smp->data.type = SMP_T_STR;
Thierry FOURNIER7654c9f2013-12-17 00:20:33 +01003906 smp->flags |= SMP_F_CONST;
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02003907 smp->data.u.str.len = strlen(smp->data.u.str.str);
Emeric Brunba841a12014-04-30 17:05:08 +02003908 if (cert_peer)
3909 X509_free(crt);
Emeric Brun521a0112012-10-22 12:22:55 +02003910
3911 return 1;
3912}
3913
Emeric Brun645ae792014-04-30 14:21:06 +02003914/* boolean, returns true if front conn. transport layer is SSL.
3915 * This function is also usable on backend conn if the fetch keyword 5th
3916 * char is 'b'.
3917 */
Willy Tarreau7875d092012-09-10 08:20:03 +02003918static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02003919smp_fetch_ssl_fc(const struct arg *args, struct sample *smp, const char *kw, void *private)
Willy Tarreau7875d092012-09-10 08:20:03 +02003920{
Emeric Brun645ae792014-04-30 14:21:06 +02003921 int back_conn = (kw[4] == 'b') ? 1 : 0;
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02003922 struct connection *conn = objt_conn(smp->strm->si[back_conn].end);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003923
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02003924 smp->data.type = SMP_T_BOOL;
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02003925 smp->data.u.sint = (conn && conn->xprt == &ssl_sock);
Willy Tarreau7875d092012-09-10 08:20:03 +02003926 return 1;
3927}
3928
Emeric Brun2525b6b2012-10-18 15:59:43 +02003929/* boolean, returns true if client present a SNI */
Willy Tarreau7875d092012-09-10 08:20:03 +02003930static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02003931smp_fetch_ssl_fc_has_sni(const struct arg *args, struct sample *smp, const char *kw, void *private)
Willy Tarreau7875d092012-09-10 08:20:03 +02003932{
3933#ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02003934 struct connection *conn = objt_conn(smp->sess->origin);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003935
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02003936 smp->data.type = SMP_T_BOOL;
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02003937 smp->data.u.sint = (conn && conn->xprt == &ssl_sock) &&
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003938 conn->xprt_ctx &&
3939 SSL_get_servername(conn->xprt_ctx, TLSEXT_NAMETYPE_host_name) != NULL;
Willy Tarreau7875d092012-09-10 08:20:03 +02003940 return 1;
3941#else
3942 return 0;
3943#endif
3944}
3945
Nenad Merdanovic26ea8222015-05-18 02:28:57 +02003946/* boolean, returns true if client session has been resumed */
3947static int
3948smp_fetch_ssl_fc_is_resumed(const struct arg *args, struct sample *smp, const char *kw, void *private)
3949{
3950 struct connection *conn = objt_conn(smp->sess->origin);
3951
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02003952 smp->data.type = SMP_T_BOOL;
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02003953 smp->data.u.sint = (conn && conn->xprt == &ssl_sock) &&
Nenad Merdanovic26ea8222015-05-18 02:28:57 +02003954 conn->xprt_ctx &&
3955 SSL_session_reused(conn->xprt_ctx);
3956 return 1;
3957}
3958
Emeric Brun645ae792014-04-30 14:21:06 +02003959/* string, returns the used cipher if front conn. transport layer is SSL.
3960 * This function is also usable on backend conn if the fetch keyword 5th
3961 * char is 'b'.
3962 */
Emeric Brun589fcad2012-10-16 14:13:26 +02003963static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02003964smp_fetch_ssl_fc_cipher(const struct arg *args, struct sample *smp, const char *kw, void *private)
Emeric Brun589fcad2012-10-16 14:13:26 +02003965{
Emeric Brun645ae792014-04-30 14:21:06 +02003966 int back_conn = (kw[4] == 'b') ? 1 : 0;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003967 struct connection *conn;
3968
Emeric Brun589fcad2012-10-16 14:13:26 +02003969 smp->flags = 0;
3970
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02003971 conn = objt_conn(smp->strm->si[back_conn].end);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003972 if (!conn || !conn->xprt_ctx || conn->xprt != &ssl_sock)
Emeric Brun589fcad2012-10-16 14:13:26 +02003973 return 0;
3974
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02003975 smp->data.u.str.str = (char *)SSL_get_cipher_name(conn->xprt_ctx);
3976 if (!smp->data.u.str.str)
Emeric Brun589fcad2012-10-16 14:13:26 +02003977 return 0;
3978
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02003979 smp->data.type = SMP_T_STR;
Thierry FOURNIER7654c9f2013-12-17 00:20:33 +01003980 smp->flags |= SMP_F_CONST;
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02003981 smp->data.u.str.len = strlen(smp->data.u.str.str);
Emeric Brun589fcad2012-10-16 14:13:26 +02003982
3983 return 1;
3984}
3985
Emeric Brun645ae792014-04-30 14:21:06 +02003986/* integer, returns the algoritm's keysize if front conn. transport layer
3987 * is SSL.
3988 * This function is also usable on backend conn if the fetch keyword 5th
3989 * char is 'b'.
3990 */
Emeric Brun589fcad2012-10-16 14:13:26 +02003991static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02003992smp_fetch_ssl_fc_alg_keysize(const struct arg *args, struct sample *smp, const char *kw, void *private)
Emeric Brun589fcad2012-10-16 14:13:26 +02003993{
Emeric Brun645ae792014-04-30 14:21:06 +02003994 int back_conn = (kw[4] == 'b') ? 1 : 0;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003995 struct connection *conn;
Thierry FOURNIER07ee64e2015-07-06 23:43:03 +02003996 int sint;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003997
Emeric Brun589fcad2012-10-16 14:13:26 +02003998 smp->flags = 0;
3999
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02004000 conn = objt_conn(smp->strm->si[back_conn].end);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004001 if (!conn || !conn->xprt_ctx || conn->xprt != &ssl_sock)
Emeric Brun589fcad2012-10-16 14:13:26 +02004002 return 0;
4003
Thierry FOURNIER07ee64e2015-07-06 23:43:03 +02004004 if (!SSL_get_cipher_bits(conn->xprt_ctx, &sint))
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004005 return 0;
4006
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02004007 smp->data.u.sint = sint;
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02004008 smp->data.type = SMP_T_SINT;
Emeric Brun589fcad2012-10-16 14:13:26 +02004009
4010 return 1;
4011}
4012
Emeric Brun645ae792014-04-30 14:21:06 +02004013/* integer, returns the used keysize if front conn. transport layer is SSL.
4014 * This function is also usable on backend conn if the fetch keyword 5th
4015 * char is 'b'.
4016 */
Emeric Brun589fcad2012-10-16 14:13:26 +02004017static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02004018smp_fetch_ssl_fc_use_keysize(const struct arg *args, struct sample *smp, const char *kw, void *private)
Emeric Brun589fcad2012-10-16 14:13:26 +02004019{
Emeric Brun645ae792014-04-30 14:21:06 +02004020 int back_conn = (kw[4] == 'b') ? 1 : 0;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004021 struct connection *conn;
4022
Emeric Brun589fcad2012-10-16 14:13:26 +02004023 smp->flags = 0;
4024
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02004025 conn = objt_conn(smp->strm->si[back_conn].end);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004026 if (!conn || !conn->xprt_ctx || conn->xprt != &ssl_sock)
4027 return 0;
4028
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02004029 smp->data.u.sint = (unsigned int)SSL_get_cipher_bits(conn->xprt_ctx, NULL);
4030 if (!smp->data.u.sint)
Emeric Brun589fcad2012-10-16 14:13:26 +02004031 return 0;
4032
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02004033 smp->data.type = SMP_T_SINT;
Emeric Brun589fcad2012-10-16 14:13:26 +02004034
4035 return 1;
4036}
4037
Willy Tarreau6c9a3d52012-10-18 18:57:14 +02004038#ifdef OPENSSL_NPN_NEGOTIATED
Willy Tarreau7875d092012-09-10 08:20:03 +02004039static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02004040smp_fetch_ssl_fc_npn(const struct arg *args, struct sample *smp, const char *kw, void *private)
Willy Tarreaua33c6542012-10-15 13:19:06 +02004041{
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004042 struct connection *conn;
4043
Thierry FOURNIER7654c9f2013-12-17 00:20:33 +01004044 smp->flags = SMP_F_CONST;
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02004045 smp->data.type = SMP_T_STR;
Willy Tarreaua33c6542012-10-15 13:19:06 +02004046
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02004047 conn = objt_conn(smp->sess->origin);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004048 if (!conn || !conn->xprt_ctx || conn->xprt != &ssl_sock)
4049 return 0;
4050
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02004051 smp->data.u.str.str = NULL;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004052 SSL_get0_next_proto_negotiated(conn->xprt_ctx,
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02004053 (const unsigned char **)&smp->data.u.str.str, (unsigned *)&smp->data.u.str.len);
Willy Tarreaua33c6542012-10-15 13:19:06 +02004054
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02004055 if (!smp->data.u.str.str)
Willy Tarreaua33c6542012-10-15 13:19:06 +02004056 return 0;
4057
4058 return 1;
Willy Tarreaua33c6542012-10-15 13:19:06 +02004059}
Willy Tarreau6c9a3d52012-10-18 18:57:14 +02004060#endif
Willy Tarreaua33c6542012-10-15 13:19:06 +02004061
Dirkjan Bussink48f1c4e2014-02-13 12:29:42 +01004062#ifdef TLSEXT_TYPE_application_layer_protocol_negotiation
Willy Tarreauab861d32013-04-02 02:30:41 +02004063static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02004064smp_fetch_ssl_fc_alpn(const struct arg *args, struct sample *smp, const char *kw, void *private)
Willy Tarreauab861d32013-04-02 02:30:41 +02004065{
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004066 struct connection *conn;
4067
Thierry FOURNIER7654c9f2013-12-17 00:20:33 +01004068 smp->flags = SMP_F_CONST;
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02004069 smp->data.type = SMP_T_STR;
Willy Tarreauab861d32013-04-02 02:30:41 +02004070
Willy Tarreaue26bf052015-05-12 10:30:12 +02004071 conn = objt_conn(smp->sess->origin);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004072 if (!conn || !conn->xprt_ctx || conn->xprt != &ssl_sock)
Willy Tarreauab861d32013-04-02 02:30:41 +02004073 return 0;
4074
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02004075 smp->data.u.str.str = NULL;
Dirkjan Bussink48f1c4e2014-02-13 12:29:42 +01004076 SSL_get0_alpn_selected(conn->xprt_ctx,
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02004077 (const unsigned char **)&smp->data.u.str.str, (unsigned *)&smp->data.u.str.len);
Willy Tarreauab861d32013-04-02 02:30:41 +02004078
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02004079 if (!smp->data.u.str.str)
Willy Tarreauab861d32013-04-02 02:30:41 +02004080 return 0;
4081
4082 return 1;
4083}
4084#endif
4085
Emeric Brun645ae792014-04-30 14:21:06 +02004086/* string, returns the used protocol if front conn. transport layer is SSL.
4087 * This function is also usable on backend conn if the fetch keyword 5th
4088 * char is 'b'.
4089 */
Willy Tarreaua33c6542012-10-15 13:19:06 +02004090static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02004091smp_fetch_ssl_fc_protocol(const struct arg *args, struct sample *smp, const char *kw, void *private)
Emeric Brun589fcad2012-10-16 14:13:26 +02004092{
Emeric Brun645ae792014-04-30 14:21:06 +02004093 int back_conn = (kw[4] == 'b') ? 1 : 0;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004094 struct connection *conn;
4095
Emeric Brun589fcad2012-10-16 14:13:26 +02004096 smp->flags = 0;
4097
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02004098 conn = objt_conn(smp->strm->si[back_conn].end);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004099 if (!conn || !conn->xprt_ctx || conn->xprt != &ssl_sock)
4100 return 0;
4101
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02004102 smp->data.u.str.str = (char *)SSL_get_version(conn->xprt_ctx);
4103 if (!smp->data.u.str.str)
Emeric Brun589fcad2012-10-16 14:13:26 +02004104 return 0;
4105
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02004106 smp->data.type = SMP_T_STR;
Thierry FOURNIER7654c9f2013-12-17 00:20:33 +01004107 smp->flags = SMP_F_CONST;
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02004108 smp->data.u.str.len = strlen(smp->data.u.str.str);
Emeric Brun589fcad2012-10-16 14:13:26 +02004109
4110 return 1;
4111}
4112
Willy Tarreau87b09662015-04-03 00:22:06 +02004113/* binary, returns the SSL stream id if front conn. transport layer is SSL.
Emeric Brun645ae792014-04-30 14:21:06 +02004114 * This function is also usable on backend conn if the fetch keyword 5th
4115 * char is 'b'.
4116 */
Emeric Brun589fcad2012-10-16 14:13:26 +02004117static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02004118smp_fetch_ssl_fc_session_id(const struct arg *args, struct sample *smp, const char *kw, void *private)
Emeric Brunfe68f682012-10-16 14:59:28 +02004119{
4120#if OPENSSL_VERSION_NUMBER > 0x0090800fL
Emeric Brun645ae792014-04-30 14:21:06 +02004121 int back_conn = (kw[4] == 'b') ? 1 : 0;
Willy Tarreau192252e2015-04-04 01:47:55 +02004122 SSL_SESSION *ssl_sess;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004123 struct connection *conn;
Emeric Brunfe68f682012-10-16 14:59:28 +02004124
Thierry FOURNIER7654c9f2013-12-17 00:20:33 +01004125 smp->flags = SMP_F_CONST;
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02004126 smp->data.type = SMP_T_BIN;
Emeric Brunfe68f682012-10-16 14:59:28 +02004127
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02004128 conn = objt_conn(smp->strm->si[back_conn].end);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004129 if (!conn || !conn->xprt_ctx || conn->xprt != &ssl_sock)
4130 return 0;
4131
Willy Tarreau192252e2015-04-04 01:47:55 +02004132 ssl_sess = SSL_get_session(conn->xprt_ctx);
4133 if (!ssl_sess)
Emeric Brunfe68f682012-10-16 14:59:28 +02004134 return 0;
4135
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02004136 smp->data.u.str.str = (char *)SSL_SESSION_get_id(ssl_sess, (unsigned int *)&smp->data.u.str.len);
4137 if (!smp->data.u.str.str || !smp->data.u.str.len)
Emeric Brunfe68f682012-10-16 14:59:28 +02004138 return 0;
4139
4140 return 1;
4141#else
4142 return 0;
4143#endif
4144}
4145
4146static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02004147smp_fetch_ssl_fc_sni(const struct arg *args, struct sample *smp, const char *kw, void *private)
Willy Tarreau7875d092012-09-10 08:20:03 +02004148{
4149#ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004150 struct connection *conn;
4151
Thierry FOURNIER7654c9f2013-12-17 00:20:33 +01004152 smp->flags = SMP_F_CONST;
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02004153 smp->data.type = SMP_T_STR;
Willy Tarreau7875d092012-09-10 08:20:03 +02004154
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02004155 conn = objt_conn(smp->sess->origin);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004156 if (!conn || !conn->xprt_ctx || conn->xprt != &ssl_sock)
4157 return 0;
4158
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02004159 smp->data.u.str.str = (char *)SSL_get_servername(conn->xprt_ctx, TLSEXT_NAMETYPE_host_name);
4160 if (!smp->data.u.str.str)
Willy Tarreau3e394c92012-09-14 23:56:58 +02004161 return 0;
4162
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02004163 smp->data.u.str.len = strlen(smp->data.u.str.str);
Willy Tarreau7875d092012-09-10 08:20:03 +02004164 return 1;
4165#else
4166 return 0;
4167#endif
4168}
4169
David Sc1ad52e2014-04-08 18:48:47 -04004170static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02004171smp_fetch_ssl_fc_unique_id(const struct arg *args, struct sample *smp, const char *kw, void *private)
David Sc1ad52e2014-04-08 18:48:47 -04004172{
4173#if OPENSSL_VERSION_NUMBER > 0x0090800fL
Emeric Brun645ae792014-04-30 14:21:06 +02004174 int back_conn = (kw[4] == 'b') ? 1 : 0;
David Sc1ad52e2014-04-08 18:48:47 -04004175 struct connection *conn;
4176 int finished_len;
David Sc1ad52e2014-04-08 18:48:47 -04004177 struct chunk *finished_trash;
David Sc1ad52e2014-04-08 18:48:47 -04004178
4179 smp->flags = 0;
4180
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02004181 conn = objt_conn(smp->strm->si[back_conn].end);
David Sc1ad52e2014-04-08 18:48:47 -04004182 if (!conn || !conn->xprt_ctx || conn->xprt != &ssl_sock)
4183 return 0;
4184
4185 if (!(conn->flags & CO_FL_CONNECTED)) {
4186 smp->flags |= SMP_F_MAY_CHANGE;
4187 return 0;
4188 }
4189
4190 finished_trash = get_trash_chunk();
4191 if (!SSL_session_reused(conn->xprt_ctx))
4192 finished_len = SSL_get_peer_finished(conn->xprt_ctx, finished_trash->str, finished_trash->size);
4193 else
4194 finished_len = SSL_get_finished(conn->xprt_ctx, finished_trash->str, finished_trash->size);
4195
4196 if (!finished_len)
4197 return 0;
4198
Emeric Brunb73a9b02014-04-30 18:49:19 +02004199 finished_trash->len = finished_len;
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02004200 smp->data.u.str = *finished_trash;
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02004201 smp->data.type = SMP_T_BIN;
David Sc1ad52e2014-04-08 18:48:47 -04004202
4203 return 1;
4204#else
4205 return 0;
4206#endif
4207}
4208
Emeric Brun2525b6b2012-10-18 15:59:43 +02004209/* integer, returns the first verify error in CA chain of client certificate chain. */
Emeric Brunf282a812012-09-21 15:27:54 +02004210static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02004211smp_fetch_ssl_c_ca_err(const struct arg *args, struct sample *smp, const char *kw, void *private)
Emeric Brunf282a812012-09-21 15:27:54 +02004212{
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004213 struct connection *conn;
4214
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02004215 conn = objt_conn(smp->sess->origin);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004216 if (!conn || conn->xprt != &ssl_sock)
4217 return 0;
4218
4219 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brunf282a812012-09-21 15:27:54 +02004220 smp->flags = SMP_F_MAY_CHANGE;
4221 return 0;
4222 }
4223
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02004224 smp->data.type = SMP_T_SINT;
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02004225 smp->data.u.sint = (unsigned long long int)SSL_SOCK_ST_TO_CA_ERROR(conn->xprt_st);
Emeric Brunf282a812012-09-21 15:27:54 +02004226 smp->flags = 0;
4227
4228 return 1;
4229}
4230
Emeric Brun2525b6b2012-10-18 15:59:43 +02004231/* integer, returns the depth of the first verify error in CA chain of client certificate chain. */
Emeric Brunf282a812012-09-21 15:27:54 +02004232static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02004233smp_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 +02004234{
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004235 struct connection *conn;
4236
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02004237 conn = objt_conn(smp->sess->origin);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004238 if (!conn || conn->xprt != &ssl_sock)
Emeric Brunf282a812012-09-21 15:27:54 +02004239 return 0;
4240
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004241 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brunf282a812012-09-21 15:27:54 +02004242 smp->flags = SMP_F_MAY_CHANGE;
4243 return 0;
4244 }
4245
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02004246 smp->data.type = SMP_T_SINT;
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02004247 smp->data.u.sint = (long long int)SSL_SOCK_ST_TO_CAEDEPTH(conn->xprt_st);
Emeric Brunf282a812012-09-21 15:27:54 +02004248 smp->flags = 0;
4249
4250 return 1;
4251}
4252
Emeric Brun2525b6b2012-10-18 15:59:43 +02004253/* integer, returns the first verify error on client certificate */
Emeric Brunf282a812012-09-21 15:27:54 +02004254static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02004255smp_fetch_ssl_c_err(const struct arg *args, struct sample *smp, const char *kw, void *private)
Emeric Brunf282a812012-09-21 15:27:54 +02004256{
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004257 struct connection *conn;
4258
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02004259 conn = objt_conn(smp->sess->origin);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004260 if (!conn || conn->xprt != &ssl_sock)
4261 return 0;
4262
4263 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brunf282a812012-09-21 15:27:54 +02004264 smp->flags = SMP_F_MAY_CHANGE;
4265 return 0;
4266 }
4267
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02004268 smp->data.type = SMP_T_SINT;
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02004269 smp->data.u.sint = (long long int)SSL_SOCK_ST_TO_CRTERROR(conn->xprt_st);
Emeric Brunf282a812012-09-21 15:27:54 +02004270 smp->flags = 0;
4271
4272 return 1;
4273}
4274
Emeric Brun2525b6b2012-10-18 15:59:43 +02004275/* integer, returns the verify result on client cert */
Emeric Brunbaf8ffb2012-09-21 15:27:20 +02004276static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02004277smp_fetch_ssl_c_verify(const struct arg *args, struct sample *smp, const char *kw, void *private)
Emeric Brunbaf8ffb2012-09-21 15:27:20 +02004278{
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004279 struct connection *conn;
4280
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02004281 conn = objt_conn(smp->sess->origin);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004282 if (!conn || conn->xprt != &ssl_sock)
4283 return 0;
4284
4285 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brunbaf8ffb2012-09-21 15:27:20 +02004286 smp->flags = SMP_F_MAY_CHANGE;
4287 return 0;
4288 }
4289
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004290 if (!conn->xprt_ctx)
Emeric Brunbaf8ffb2012-09-21 15:27:20 +02004291 return 0;
4292
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02004293 smp->data.type = SMP_T_SINT;
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02004294 smp->data.u.sint = (long long int)SSL_get_verify_result(conn->xprt_ctx);
Emeric Brunbaf8ffb2012-09-21 15:27:20 +02004295 smp->flags = 0;
4296
4297 return 1;
4298}
4299
Emeric Brunfb510ea2012-10-05 12:00:26 +02004300/* parse the "ca-file" bind keyword */
4301static 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 +02004302{
4303 if (!*args[cur_arg + 1]) {
4304 if (err)
4305 memprintf(err, "'%s' : missing CAfile path", args[cur_arg]);
4306 return ERR_ALERT | ERR_FATAL;
4307 }
4308
Emeric Brunef42d922012-10-11 16:11:36 +02004309 if ((*args[cur_arg + 1] != '/') && global.ca_base)
4310 memprintf(&conf->ca_file, "%s/%s", global.ca_base, args[cur_arg + 1]);
4311 else
4312 memprintf(&conf->ca_file, "%s", args[cur_arg + 1]);
Emeric Brunc8e8d122012-10-02 18:42:10 +02004313
Emeric Brund94b3fe2012-09-20 18:23:56 +02004314 return 0;
4315}
4316
Christopher Faulet31af49d2015-06-09 17:29:50 +02004317/* parse the "ca-sign-file" bind keyword */
4318static int bind_parse_ca_sign_file(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
4319{
4320 if (!*args[cur_arg + 1]) {
4321 if (err)
4322 memprintf(err, "'%s' : missing CAfile path", args[cur_arg]);
4323 return ERR_ALERT | ERR_FATAL;
4324 }
4325
4326 if ((*args[cur_arg + 1] != '/') && global.ca_base)
4327 memprintf(&conf->ca_sign_file, "%s/%s", global.ca_base, args[cur_arg + 1]);
4328 else
4329 memprintf(&conf->ca_sign_file, "%s", args[cur_arg + 1]);
4330
4331 return 0;
4332}
4333
4334/* parse the ca-sign-pass bind keyword */
4335
4336static int bind_parse_ca_sign_pass(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
4337{
4338 if (!*args[cur_arg + 1]) {
4339 if (err)
4340 memprintf(err, "'%s' : missing CAkey password", args[cur_arg]);
4341 return ERR_ALERT | ERR_FATAL;
4342 }
4343 memprintf(&conf->ca_sign_pass, "%s", args[cur_arg + 1]);
4344 return 0;
4345}
4346
Willy Tarreau79eeafa2012-09-14 07:53:05 +02004347/* parse the "ciphers" bind keyword */
Willy Tarreau4348fad2012-09-20 16:48:07 +02004348static 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 +02004349{
4350 if (!*args[cur_arg + 1]) {
Willy Tarreaueb6cead2012-09-20 19:43:14 +02004351 memprintf(err, "'%s' : missing cipher suite", args[cur_arg]);
Willy Tarreau79eeafa2012-09-14 07:53:05 +02004352 return ERR_ALERT | ERR_FATAL;
4353 }
4354
Emeric Brun76d88952012-10-05 15:47:31 +02004355 free(conf->ciphers);
Willy Tarreau4348fad2012-09-20 16:48:07 +02004356 conf->ciphers = strdup(args[cur_arg + 1]);
Willy Tarreau79eeafa2012-09-14 07:53:05 +02004357 return 0;
4358}
4359
4360/* parse the "crt" bind keyword */
Willy Tarreau4348fad2012-09-20 16:48:07 +02004361static 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 +02004362{
Willy Tarreau38011032013-08-13 16:59:39 +02004363 char path[MAXPATHLEN];
Willy Tarreaub75d6922014-04-14 18:05:41 +02004364
Willy Tarreau79eeafa2012-09-14 07:53:05 +02004365 if (!*args[cur_arg + 1]) {
Willy Tarreaueb6cead2012-09-20 19:43:14 +02004366 memprintf(err, "'%s' : missing certificate location", args[cur_arg]);
Willy Tarreau79eeafa2012-09-14 07:53:05 +02004367 return ERR_ALERT | ERR_FATAL;
4368 }
4369
Emeric Brunc8e8d122012-10-02 18:42:10 +02004370 if ((*args[cur_arg + 1] != '/' ) && global.crt_base) {
Willy Tarreau38011032013-08-13 16:59:39 +02004371 if ((strlen(global.crt_base) + 1 + strlen(args[cur_arg + 1]) + 1) > MAXPATHLEN) {
Emeric Brunc8e8d122012-10-02 18:42:10 +02004372 memprintf(err, "'%s' : path too long", args[cur_arg]);
4373 return ERR_ALERT | ERR_FATAL;
4374 }
Willy Tarreaub75d6922014-04-14 18:05:41 +02004375 snprintf(path, sizeof(path), "%s/%s", global.crt_base, args[cur_arg + 1]);
Emeric Brunc8e8d122012-10-02 18:42:10 +02004376 if (ssl_sock_load_cert(path, conf, px, err) > 0)
4377 return ERR_ALERT | ERR_FATAL;
4378
4379 return 0;
4380 }
4381
Willy Tarreau4348fad2012-09-20 16:48:07 +02004382 if (ssl_sock_load_cert(args[cur_arg + 1], conf, px, err) > 0)
Willy Tarreau79eeafa2012-09-14 07:53:05 +02004383 return ERR_ALERT | ERR_FATAL;
Emeric Brund94b3fe2012-09-20 18:23:56 +02004384
4385 return 0;
4386}
4387
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01004388/* parse the "crt-list" bind keyword */
4389static int bind_parse_crt_list(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
4390{
4391 if (!*args[cur_arg + 1]) {
4392 memprintf(err, "'%s' : missing certificate location", args[cur_arg]);
4393 return ERR_ALERT | ERR_FATAL;
4394 }
4395
Willy Tarreauad1731d2013-04-02 17:35:58 +02004396 if (ssl_sock_load_cert_list_file(args[cur_arg + 1], conf, px, err) > 0) {
4397 memprintf(err, "'%s' : %s", args[cur_arg], *err);
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01004398 return ERR_ALERT | ERR_FATAL;
Willy Tarreauad1731d2013-04-02 17:35:58 +02004399 }
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01004400
4401 return 0;
4402}
4403
Emeric Brunfb510ea2012-10-05 12:00:26 +02004404/* parse the "crl-file" bind keyword */
4405static 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 +02004406{
Emeric Brun051cdab2012-10-02 19:25:50 +02004407#ifndef X509_V_FLAG_CRL_CHECK
4408 if (err)
4409 memprintf(err, "'%s' : library does not support CRL verify", args[cur_arg]);
4410 return ERR_ALERT | ERR_FATAL;
4411#else
Emeric Brund94b3fe2012-09-20 18:23:56 +02004412 if (!*args[cur_arg + 1]) {
4413 if (err)
4414 memprintf(err, "'%s' : missing CRLfile path", args[cur_arg]);
4415 return ERR_ALERT | ERR_FATAL;
4416 }
Emeric Brun2b58d042012-09-20 17:10:03 +02004417
Emeric Brunef42d922012-10-11 16:11:36 +02004418 if ((*args[cur_arg + 1] != '/') && global.ca_base)
4419 memprintf(&conf->crl_file, "%s/%s", global.ca_base, args[cur_arg + 1]);
4420 else
4421 memprintf(&conf->crl_file, "%s", args[cur_arg + 1]);
Emeric Brunc8e8d122012-10-02 18:42:10 +02004422
Emeric Brun2b58d042012-09-20 17:10:03 +02004423 return 0;
Emeric Brun051cdab2012-10-02 19:25:50 +02004424#endif
Emeric Brun2b58d042012-09-20 17:10:03 +02004425}
4426
4427/* parse the "ecdhe" bind keyword keywords */
4428static int bind_parse_ecdhe(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
4429{
4430#if OPENSSL_VERSION_NUMBER < 0x0090800fL
4431 if (err)
4432 memprintf(err, "'%s' : library does not support elliptic curve Diffie-Hellman (too old)", args[cur_arg]);
4433 return ERR_ALERT | ERR_FATAL;
4434#elif defined(OPENSSL_NO_ECDH)
4435 if (err)
4436 memprintf(err, "'%s' : library does not support elliptic curve Diffie-Hellman (disabled via OPENSSL_NO_ECDH)", args[cur_arg]);
4437 return ERR_ALERT | ERR_FATAL;
4438#else
4439 if (!*args[cur_arg + 1]) {
4440 if (err)
4441 memprintf(err, "'%s' : missing named curve", args[cur_arg]);
4442 return ERR_ALERT | ERR_FATAL;
4443 }
4444
4445 conf->ecdhe = strdup(args[cur_arg + 1]);
Willy Tarreau79eeafa2012-09-14 07:53:05 +02004446
4447 return 0;
Emeric Brun2b58d042012-09-20 17:10:03 +02004448#endif
Willy Tarreau79eeafa2012-09-14 07:53:05 +02004449}
4450
Emeric Brun81c00f02012-09-21 14:31:21 +02004451/* parse the "crt_ignerr" and "ca_ignerr" bind keywords */
4452static int bind_parse_ignore_err(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
4453{
4454 int code;
4455 char *p = args[cur_arg + 1];
4456 unsigned long long *ignerr = &conf->crt_ignerr;
4457
4458 if (!*p) {
4459 if (err)
4460 memprintf(err, "'%s' : missing error IDs list", args[cur_arg]);
4461 return ERR_ALERT | ERR_FATAL;
4462 }
4463
4464 if (strcmp(args[cur_arg], "ca-ignore-err") == 0)
4465 ignerr = &conf->ca_ignerr;
4466
4467 if (strcmp(p, "all") == 0) {
4468 *ignerr = ~0ULL;
4469 return 0;
4470 }
4471
4472 while (p) {
4473 code = atoi(p);
4474 if ((code <= 0) || (code > 63)) {
4475 if (err)
4476 memprintf(err, "'%s' : ID '%d' out of range (1..63) in error IDs list '%s'",
4477 args[cur_arg], code, args[cur_arg + 1]);
4478 return ERR_ALERT | ERR_FATAL;
4479 }
4480 *ignerr |= 1ULL << code;
4481 p = strchr(p, ',');
4482 if (p)
4483 p++;
4484 }
4485
Emeric Brun2cb7ae52012-10-05 14:14:21 +02004486 return 0;
4487}
4488
4489/* parse the "force-sslv3" bind keyword */
4490static int bind_parse_force_sslv3(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
4491{
4492 conf->ssl_options |= BC_SSL_O_USE_SSLV3;
4493 return 0;
4494}
4495
4496/* parse the "force-tlsv10" bind keyword */
4497static int bind_parse_force_tlsv10(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
4498{
4499 conf->ssl_options |= BC_SSL_O_USE_TLSV10;
Emeric Brun2d0c4822012-10-02 13:45:20 +02004500 return 0;
4501}
4502
Emeric Brun2cb7ae52012-10-05 14:14:21 +02004503/* parse the "force-tlsv11" bind keyword */
4504static int bind_parse_force_tlsv11(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
4505{
4506#if SSL_OP_NO_TLSv1_1
4507 conf->ssl_options |= BC_SSL_O_USE_TLSV11;
4508 return 0;
4509#else
4510 if (err)
4511 memprintf(err, "'%s' : library does not support protocol TLSv1.1", args[cur_arg]);
4512 return ERR_ALERT | ERR_FATAL;
4513#endif
4514}
4515
4516/* parse the "force-tlsv12" bind keyword */
4517static int bind_parse_force_tlsv12(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
4518{
4519#if SSL_OP_NO_TLSv1_2
4520 conf->ssl_options |= BC_SSL_O_USE_TLSV12;
4521 return 0;
4522#else
4523 if (err)
4524 memprintf(err, "'%s' : library does not support protocol TLSv1.2", args[cur_arg]);
4525 return ERR_ALERT | ERR_FATAL;
4526#endif
4527}
4528
4529
Emeric Brun2d0c4822012-10-02 13:45:20 +02004530/* parse the "no-tls-tickets" bind keyword */
4531static int bind_parse_no_tls_tickets(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
4532{
Emeric Brun89675492012-10-05 13:48:26 +02004533 conf->ssl_options |= BC_SSL_O_NO_TLS_TICKETS;
Emeric Brun81c00f02012-09-21 14:31:21 +02004534 return 0;
4535}
4536
Emeric Brun2d0c4822012-10-02 13:45:20 +02004537
Emeric Brun9b3009b2012-10-05 11:55:06 +02004538/* parse the "no-sslv3" bind keyword */
4539static 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 +02004540{
Emeric Brun89675492012-10-05 13:48:26 +02004541 conf->ssl_options |= BC_SSL_O_NO_SSLV3;
Willy Tarreau79eeafa2012-09-14 07:53:05 +02004542 return 0;
4543}
4544
Emeric Brun9b3009b2012-10-05 11:55:06 +02004545/* parse the "no-tlsv10" bind keyword */
4546static 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 +02004547{
Emeric Brun89675492012-10-05 13:48:26 +02004548 conf->ssl_options |= BC_SSL_O_NO_TLSV10;
Emeric Brunc0ff4922012-09-28 19:37:02 +02004549 return 0;
4550}
4551
Emeric Brun9b3009b2012-10-05 11:55:06 +02004552/* parse the "no-tlsv11" bind keyword */
4553static 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 +02004554{
Emeric Brun89675492012-10-05 13:48:26 +02004555 conf->ssl_options |= BC_SSL_O_NO_TLSV11;
Emeric Brunc0ff4922012-09-28 19:37:02 +02004556 return 0;
4557}
4558
Emeric Brun9b3009b2012-10-05 11:55:06 +02004559/* parse the "no-tlsv12" bind keyword */
4560static 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 +02004561{
Emeric Brun89675492012-10-05 13:48:26 +02004562 conf->ssl_options |= BC_SSL_O_NO_TLSV12;
Willy Tarreau79eeafa2012-09-14 07:53:05 +02004563 return 0;
4564}
4565
Willy Tarreau6c9a3d52012-10-18 18:57:14 +02004566/* parse the "npn" bind keyword */
4567static int bind_parse_npn(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
4568{
4569#ifdef OPENSSL_NPN_NEGOTIATED
4570 char *p1, *p2;
4571
4572 if (!*args[cur_arg + 1]) {
4573 memprintf(err, "'%s' : missing the comma-delimited NPN protocol suite", args[cur_arg]);
4574 return ERR_ALERT | ERR_FATAL;
4575 }
4576
4577 free(conf->npn_str);
4578
4579 /* the NPN string is built as a suite of (<len> <name>)* */
4580 conf->npn_len = strlen(args[cur_arg + 1]) + 1;
4581 conf->npn_str = calloc(1, conf->npn_len);
4582 memcpy(conf->npn_str + 1, args[cur_arg + 1], conf->npn_len);
4583
4584 /* replace commas with the name length */
4585 p1 = conf->npn_str;
4586 p2 = p1 + 1;
4587 while (1) {
4588 p2 = memchr(p1 + 1, ',', conf->npn_str + conf->npn_len - (p1 + 1));
4589 if (!p2)
4590 p2 = p1 + 1 + strlen(p1 + 1);
4591
4592 if (p2 - (p1 + 1) > 255) {
4593 *p2 = '\0';
4594 memprintf(err, "'%s' : NPN protocol name too long : '%s'", args[cur_arg], p1 + 1);
4595 return ERR_ALERT | ERR_FATAL;
4596 }
4597
4598 *p1 = p2 - (p1 + 1);
4599 p1 = p2;
4600
4601 if (!*p2)
4602 break;
4603
4604 *(p2++) = '\0';
4605 }
4606 return 0;
4607#else
4608 if (err)
4609 memprintf(err, "'%s' : library does not support TLS NPN extension", args[cur_arg]);
4610 return ERR_ALERT | ERR_FATAL;
4611#endif
4612}
4613
Willy Tarreauab861d32013-04-02 02:30:41 +02004614/* parse the "alpn" bind keyword */
4615static int bind_parse_alpn(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
4616{
Dirkjan Bussink48f1c4e2014-02-13 12:29:42 +01004617#ifdef TLSEXT_TYPE_application_layer_protocol_negotiation
Willy Tarreauab861d32013-04-02 02:30:41 +02004618 char *p1, *p2;
4619
4620 if (!*args[cur_arg + 1]) {
4621 memprintf(err, "'%s' : missing the comma-delimited ALPN protocol suite", args[cur_arg]);
4622 return ERR_ALERT | ERR_FATAL;
4623 }
4624
4625 free(conf->alpn_str);
4626
4627 /* the ALPN string is built as a suite of (<len> <name>)* */
4628 conf->alpn_len = strlen(args[cur_arg + 1]) + 1;
4629 conf->alpn_str = calloc(1, conf->alpn_len);
4630 memcpy(conf->alpn_str + 1, args[cur_arg + 1], conf->alpn_len);
4631
4632 /* replace commas with the name length */
4633 p1 = conf->alpn_str;
4634 p2 = p1 + 1;
4635 while (1) {
4636 p2 = memchr(p1 + 1, ',', conf->alpn_str + conf->alpn_len - (p1 + 1));
4637 if (!p2)
4638 p2 = p1 + 1 + strlen(p1 + 1);
4639
4640 if (p2 - (p1 + 1) > 255) {
4641 *p2 = '\0';
4642 memprintf(err, "'%s' : ALPN protocol name too long : '%s'", args[cur_arg], p1 + 1);
4643 return ERR_ALERT | ERR_FATAL;
4644 }
4645
4646 *p1 = p2 - (p1 + 1);
4647 p1 = p2;
4648
4649 if (!*p2)
4650 break;
4651
4652 *(p2++) = '\0';
4653 }
4654 return 0;
4655#else
4656 if (err)
4657 memprintf(err, "'%s' : library does not support TLS ALPN extension", args[cur_arg]);
4658 return ERR_ALERT | ERR_FATAL;
4659#endif
4660}
4661
Willy Tarreau79eeafa2012-09-14 07:53:05 +02004662/* parse the "ssl" bind keyword */
Willy Tarreau4348fad2012-09-20 16:48:07 +02004663static 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 +02004664{
Willy Tarreau81796be2012-09-22 19:11:47 +02004665 struct listener *l;
4666
Willy Tarreau4348fad2012-09-20 16:48:07 +02004667 conf->is_ssl = 1;
Emeric Brun76d88952012-10-05 15:47:31 +02004668
4669 if (global.listen_default_ciphers && !conf->ciphers)
4670 conf->ciphers = strdup(global.listen_default_ciphers);
Emeric Brun2c86cbf2014-10-30 15:56:50 +01004671 conf->ssl_options |= global.listen_default_ssloptions;
Emeric Brun76d88952012-10-05 15:47:31 +02004672
Willy Tarreau81796be2012-09-22 19:11:47 +02004673 list_for_each_entry(l, &conf->listeners, by_bind)
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02004674 l->xprt = &ssl_sock;
Willy Tarreau81796be2012-09-22 19:11:47 +02004675
Willy Tarreau79eeafa2012-09-14 07:53:05 +02004676 return 0;
4677}
4678
Christopher Faulet31af49d2015-06-09 17:29:50 +02004679/* parse the "generate-certificates" bind keyword */
4680static int bind_parse_generate_certs(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
4681{
4682#ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME
4683 conf->generate_certs = 1;
4684#else
4685 memprintf(err, "%sthis version of openssl cannot generate SSL certificates.\n",
4686 err && *err ? *err : "");
4687#endif
4688 return 0;
4689}
4690
Emmanuel Hocdet65623372013-01-24 17:17:15 +01004691/* parse the "strict-sni" bind keyword */
4692static int bind_parse_strict_sni(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
4693{
4694 conf->strict_sni = 1;
4695 return 0;
Nenad Merdanovic05552d42015-02-27 19:56:49 +01004696}
4697
4698/* parse the "tls-ticket-keys" bind keyword */
4699static int bind_parse_tls_ticket_keys(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
4700{
4701#if (defined SSL_CTRL_SET_TLSEXT_TICKET_KEY_CB && TLS_TICKETS_NO > 0)
4702 FILE *f;
4703 int i = 0;
4704 char thisline[LINESIZE];
Nenad Merdanovic146defa2015-05-09 08:46:00 +02004705 struct tls_keys_ref *keys_ref;
Nenad Merdanovic05552d42015-02-27 19:56:49 +01004706
4707 if (!*args[cur_arg + 1]) {
4708 if (err)
4709 memprintf(err, "'%s' : missing TLS ticket keys file path", args[cur_arg]);
4710 return ERR_ALERT | ERR_FATAL;
4711 }
4712
Nenad Merdanovic200b0fa2015-05-09 08:46:01 +02004713 keys_ref = tlskeys_ref_lookup(args[cur_arg + 1]);
4714 if(keys_ref) {
4715 conf->keys_ref = keys_ref;
4716 return 0;
4717 }
4718
Nenad Merdanovic146defa2015-05-09 08:46:00 +02004719 keys_ref = malloc(sizeof(struct tls_keys_ref));
4720 keys_ref->tlskeys = malloc(TLS_TICKETS_NO * sizeof(struct tls_sess_key));
Nenad Merdanovic05552d42015-02-27 19:56:49 +01004721
4722 if ((f = fopen(args[cur_arg + 1], "r")) == NULL) {
4723 if (err)
4724 memprintf(err, "'%s' : unable to load ssl tickets keys file", args[cur_arg+1]);
4725 return ERR_ALERT | ERR_FATAL;
4726 }
4727
Nenad Merdanovic146defa2015-05-09 08:46:00 +02004728 keys_ref->filename = strdup(args[cur_arg + 1]);
4729
Nenad Merdanovic05552d42015-02-27 19:56:49 +01004730 while (fgets(thisline, sizeof(thisline), f) != NULL) {
4731 int len = strlen(thisline);
4732 /* Strip newline characters from the end */
4733 if(thisline[len - 1] == '\n')
4734 thisline[--len] = 0;
4735
4736 if(thisline[len - 1] == '\r')
4737 thisline[--len] = 0;
4738
Nenad Merdanovic146defa2015-05-09 08:46:00 +02004739 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 +01004740 if (err)
4741 memprintf(err, "'%s' : unable to decode base64 key on line %d", args[cur_arg+1], i + 1);
4742 return ERR_ALERT | ERR_FATAL;
4743 }
4744 i++;
4745 }
4746
4747 if (i < TLS_TICKETS_NO) {
4748 if (err)
4749 memprintf(err, "'%s' : please supply at least %d keys in the tls-tickets-file", args[cur_arg+1], TLS_TICKETS_NO);
4750 return ERR_ALERT | ERR_FATAL;
4751 }
4752
4753 fclose(f);
4754
4755 /* Use penultimate key for encryption, handle when TLS_TICKETS_NO = 1 */
4756 i-=2;
Nenad Merdanovic146defa2015-05-09 08:46:00 +02004757 keys_ref->tls_ticket_enc_index = i < 0 ? 0 : i;
Nenad Merdanovic200b0fa2015-05-09 08:46:01 +02004758 keys_ref->unique_id = -1;
Nenad Merdanovic146defa2015-05-09 08:46:00 +02004759 conf->keys_ref = keys_ref;
Nenad Merdanovic05552d42015-02-27 19:56:49 +01004760
Nenad Merdanovic200b0fa2015-05-09 08:46:01 +02004761 LIST_ADD(&tlskeys_reference, &keys_ref->list);
4762
Nenad Merdanovic05552d42015-02-27 19:56:49 +01004763 return 0;
4764#else
4765 if (err)
4766 memprintf(err, "'%s' : TLS ticket callback extension not supported", args[cur_arg]);
4767 return ERR_ALERT | ERR_FATAL;
4768#endif /* SSL_CTRL_SET_TLSEXT_TICKET_KEY_CB */
Emmanuel Hocdet65623372013-01-24 17:17:15 +01004769}
4770
Emeric Brund94b3fe2012-09-20 18:23:56 +02004771/* parse the "verify" bind keyword */
4772static int bind_parse_verify(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
4773{
4774 if (!*args[cur_arg + 1]) {
4775 if (err)
4776 memprintf(err, "'%s' : missing verify method", args[cur_arg]);
4777 return ERR_ALERT | ERR_FATAL;
4778 }
4779
4780 if (strcmp(args[cur_arg + 1], "none") == 0)
Emeric Brun850efd52014-01-29 12:24:34 +01004781 conf->verify = SSL_SOCK_VERIFY_NONE;
Emeric Brund94b3fe2012-09-20 18:23:56 +02004782 else if (strcmp(args[cur_arg + 1], "optional") == 0)
Emeric Brun850efd52014-01-29 12:24:34 +01004783 conf->verify = SSL_SOCK_VERIFY_OPTIONAL;
Emeric Brund94b3fe2012-09-20 18:23:56 +02004784 else if (strcmp(args[cur_arg + 1], "required") == 0)
Emeric Brun850efd52014-01-29 12:24:34 +01004785 conf->verify = SSL_SOCK_VERIFY_REQUIRED;
Emeric Brund94b3fe2012-09-20 18:23:56 +02004786 else {
4787 if (err)
4788 memprintf(err, "'%s' : unknown verify method '%s', only 'none', 'optional', and 'required' are supported\n",
4789 args[cur_arg], args[cur_arg + 1]);
4790 return ERR_ALERT | ERR_FATAL;
4791 }
4792
4793 return 0;
4794}
4795
Willy Tarreau92faadf2012-10-10 23:04:25 +02004796/************** "server" keywords ****************/
4797
Emeric Brunef42d922012-10-11 16:11:36 +02004798/* parse the "ca-file" server keyword */
4799static int srv_parse_ca_file(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
4800{
4801 if (!*args[*cur_arg + 1]) {
4802 if (err)
4803 memprintf(err, "'%s' : missing CAfile path", args[*cur_arg]);
4804 return ERR_ALERT | ERR_FATAL;
4805 }
4806
4807 if ((*args[*cur_arg + 1] != '/') && global.ca_base)
4808 memprintf(&newsrv->ssl_ctx.ca_file, "%s/%s", global.ca_base, args[*cur_arg + 1]);
4809 else
4810 memprintf(&newsrv->ssl_ctx.ca_file, "%s", args[*cur_arg + 1]);
4811
4812 return 0;
4813}
4814
Willy Tarreau92faadf2012-10-10 23:04:25 +02004815/* parse the "check-ssl" server keyword */
4816static int srv_parse_check_ssl(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
4817{
4818 newsrv->check.use_ssl = 1;
4819 if (global.connect_default_ciphers && !newsrv->ssl_ctx.ciphers)
4820 newsrv->ssl_ctx.ciphers = strdup(global.connect_default_ciphers);
Emeric Brun2c86cbf2014-10-30 15:56:50 +01004821 newsrv->ssl_ctx.options |= global.connect_default_ssloptions;
Willy Tarreau92faadf2012-10-10 23:04:25 +02004822 return 0;
4823}
4824
4825/* parse the "ciphers" server keyword */
4826static int srv_parse_ciphers(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
4827{
4828 if (!*args[*cur_arg + 1]) {
4829 memprintf(err, "'%s' : missing cipher suite", args[*cur_arg]);
4830 return ERR_ALERT | ERR_FATAL;
4831 }
4832
4833 free(newsrv->ssl_ctx.ciphers);
4834 newsrv->ssl_ctx.ciphers = strdup(args[*cur_arg + 1]);
4835 return 0;
4836}
4837
Emeric Brunef42d922012-10-11 16:11:36 +02004838/* parse the "crl-file" server keyword */
4839static int srv_parse_crl_file(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
4840{
4841#ifndef X509_V_FLAG_CRL_CHECK
4842 if (err)
4843 memprintf(err, "'%s' : library does not support CRL verify", args[*cur_arg]);
4844 return ERR_ALERT | ERR_FATAL;
4845#else
4846 if (!*args[*cur_arg + 1]) {
4847 if (err)
4848 memprintf(err, "'%s' : missing CRLfile path", args[*cur_arg]);
4849 return ERR_ALERT | ERR_FATAL;
4850 }
4851
4852 if ((*args[*cur_arg + 1] != '/') && global.ca_base)
4853 memprintf(&newsrv->ssl_ctx.crl_file, "%s/%s", global.ca_base, args[*cur_arg + 1]);
4854 else
4855 memprintf(&newsrv->ssl_ctx.crl_file, "%s", args[*cur_arg + 1]);
4856
4857 return 0;
4858#endif
4859}
4860
Emeric Bruna7aa3092012-10-26 12:58:00 +02004861/* parse the "crt" server keyword */
4862static int srv_parse_crt(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
4863{
4864 if (!*args[*cur_arg + 1]) {
4865 if (err)
4866 memprintf(err, "'%s' : missing certificate file path", args[*cur_arg]);
4867 return ERR_ALERT | ERR_FATAL;
4868 }
4869
4870 if ((*args[*cur_arg + 1] != '/') && global.crt_base)
4871 memprintf(&newsrv->ssl_ctx.client_crt, "%s/%s", global.ca_base, args[*cur_arg + 1]);
4872 else
4873 memprintf(&newsrv->ssl_ctx.client_crt, "%s", args[*cur_arg + 1]);
4874
4875 return 0;
4876}
Emeric Brunef42d922012-10-11 16:11:36 +02004877
Willy Tarreau92faadf2012-10-10 23:04:25 +02004878/* parse the "force-sslv3" server keyword */
4879static int srv_parse_force_sslv3(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
4880{
4881 newsrv->ssl_ctx.options |= SRV_SSL_O_USE_SSLV3;
4882 return 0;
4883}
4884
4885/* parse the "force-tlsv10" server keyword */
4886static int srv_parse_force_tlsv10(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
4887{
4888 newsrv->ssl_ctx.options |= SRV_SSL_O_USE_TLSV10;
4889 return 0;
4890}
4891
4892/* parse the "force-tlsv11" server keyword */
4893static int srv_parse_force_tlsv11(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
4894{
4895#if SSL_OP_NO_TLSv1_1
4896 newsrv->ssl_ctx.options |= SRV_SSL_O_USE_TLSV11;
4897 return 0;
4898#else
4899 if (err)
4900 memprintf(err, "'%s' : library does not support protocol TLSv1.1", args[*cur_arg]);
4901 return ERR_ALERT | ERR_FATAL;
4902#endif
4903}
4904
4905/* parse the "force-tlsv12" server keyword */
4906static int srv_parse_force_tlsv12(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
4907{
4908#if SSL_OP_NO_TLSv1_2
4909 newsrv->ssl_ctx.options |= SRV_SSL_O_USE_TLSV12;
4910 return 0;
4911#else
4912 if (err)
4913 memprintf(err, "'%s' : library does not support protocol TLSv1.2", args[*cur_arg]);
4914 return ERR_ALERT | ERR_FATAL;
4915#endif
4916}
4917
Willy Tarreau2a3fb1c2015-02-05 16:47:07 +01004918/* parse the "no-ssl-reuse" server keyword */
4919static int srv_parse_no_ssl_reuse(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
4920{
4921 newsrv->ssl_ctx.options |= SRV_SSL_O_NO_REUSE;
4922 return 0;
4923}
4924
Willy Tarreau92faadf2012-10-10 23:04:25 +02004925/* parse the "no-sslv3" server keyword */
4926static int srv_parse_no_sslv3(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
4927{
4928 newsrv->ssl_ctx.options |= SRV_SSL_O_NO_SSLV3;
4929 return 0;
4930}
4931
4932/* parse the "no-tlsv10" server keyword */
4933static int srv_parse_no_tlsv10(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
4934{
4935 newsrv->ssl_ctx.options |= SRV_SSL_O_NO_TLSV10;
4936 return 0;
4937}
4938
4939/* parse the "no-tlsv11" server keyword */
4940static int srv_parse_no_tlsv11(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
4941{
4942 newsrv->ssl_ctx.options |= SRV_SSL_O_NO_TLSV11;
4943 return 0;
4944}
4945
4946/* parse the "no-tlsv12" server keyword */
4947static int srv_parse_no_tlsv12(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
4948{
4949 newsrv->ssl_ctx.options |= SRV_SSL_O_NO_TLSV12;
4950 return 0;
4951}
4952
Emeric Brunf9c5c472012-10-11 15:28:34 +02004953/* parse the "no-tls-tickets" server keyword */
4954static int srv_parse_no_tls_tickets(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
4955{
4956 newsrv->ssl_ctx.options |= SRV_SSL_O_NO_TLS_TICKETS;
4957 return 0;
4958}
David Safb76832014-05-08 23:42:08 -04004959/* parse the "send-proxy-v2-ssl" server keyword */
4960static int srv_parse_send_proxy_ssl(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
4961{
4962 newsrv->pp_opts |= SRV_PP_V2;
4963 newsrv->pp_opts |= SRV_PP_V2_SSL;
4964 return 0;
4965}
4966
4967/* parse the "send-proxy-v2-ssl-cn" server keyword */
4968static int srv_parse_send_proxy_cn(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
4969{
4970 newsrv->pp_opts |= SRV_PP_V2;
4971 newsrv->pp_opts |= SRV_PP_V2_SSL;
4972 newsrv->pp_opts |= SRV_PP_V2_SSL_CN;
4973 return 0;
4974}
Emeric Brunf9c5c472012-10-11 15:28:34 +02004975
Willy Tarreau732eac42015-07-09 11:40:25 +02004976/* parse the "sni" server keyword */
4977static int srv_parse_sni(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
4978{
4979#ifndef SSL_CTRL_SET_TLSEXT_HOSTNAME
4980 memprintf(err, "'%s' : the current SSL library doesn't support the SNI TLS extension", args[*cur_arg]);
4981 return ERR_ALERT | ERR_FATAL;
4982#else
4983 struct sample_expr *expr;
4984
4985 if (!*args[*cur_arg + 1]) {
4986 memprintf(err, "'%s' : missing sni expression", args[*cur_arg]);
4987 return ERR_ALERT | ERR_FATAL;
4988 }
4989
4990 (*cur_arg)++;
4991 proxy->conf.args.ctx = ARGC_SRV;
4992
4993 expr = sample_parse_expr((char **)args, cur_arg, px->conf.file, px->conf.line, err, &proxy->conf.args);
4994 if (!expr) {
4995 memprintf(err, "error detected while parsing sni expression : %s", *err);
4996 return ERR_ALERT | ERR_FATAL;
4997 }
4998
4999 if (!(expr->fetch->val & SMP_VAL_BE_SRV_CON)) {
5000 memprintf(err, "error detected while parsing sni expression : "
5001 " fetch method '%s' extracts information from '%s', none of which is available here.\n",
5002 args[*cur_arg-1], sample_src_names(expr->fetch->use));
5003 return ERR_ALERT | ERR_FATAL;
5004 }
5005
5006 px->http_needed |= !!(expr->fetch->use & SMP_USE_HTTP_ANY);
5007 newsrv->ssl_ctx.sni = expr;
5008 return 0;
5009#endif
5010}
5011
Willy Tarreau92faadf2012-10-10 23:04:25 +02005012/* parse the "ssl" server keyword */
5013static int srv_parse_ssl(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
5014{
5015 newsrv->use_ssl = 1;
5016 if (global.connect_default_ciphers && !newsrv->ssl_ctx.ciphers)
5017 newsrv->ssl_ctx.ciphers = strdup(global.connect_default_ciphers);
5018 return 0;
5019}
5020
Emeric Brunef42d922012-10-11 16:11:36 +02005021/* parse the "verify" server keyword */
5022static int srv_parse_verify(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
5023{
5024 if (!*args[*cur_arg + 1]) {
5025 if (err)
5026 memprintf(err, "'%s' : missing verify method", args[*cur_arg]);
5027 return ERR_ALERT | ERR_FATAL;
5028 }
5029
5030 if (strcmp(args[*cur_arg + 1], "none") == 0)
Emeric Brun850efd52014-01-29 12:24:34 +01005031 newsrv->ssl_ctx.verify = SSL_SOCK_VERIFY_NONE;
Emeric Brunef42d922012-10-11 16:11:36 +02005032 else if (strcmp(args[*cur_arg + 1], "required") == 0)
Emeric Brun850efd52014-01-29 12:24:34 +01005033 newsrv->ssl_ctx.verify = SSL_SOCK_VERIFY_REQUIRED;
Emeric Brunef42d922012-10-11 16:11:36 +02005034 else {
5035 if (err)
5036 memprintf(err, "'%s' : unknown verify method '%s', only 'none' and 'required' are supported\n",
5037 args[*cur_arg], args[*cur_arg + 1]);
5038 return ERR_ALERT | ERR_FATAL;
5039 }
5040
Evan Broderbe554312013-06-27 00:05:25 -07005041 return 0;
5042}
5043
5044/* parse the "verifyhost" server keyword */
5045static int srv_parse_verifyhost(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
5046{
5047 if (!*args[*cur_arg + 1]) {
5048 if (err)
5049 memprintf(err, "'%s' : missing hostname to verify against", args[*cur_arg]);
5050 return ERR_ALERT | ERR_FATAL;
5051 }
5052
5053 newsrv->ssl_ctx.verify_host = strdup(args[*cur_arg + 1]);
5054
Emeric Brunef42d922012-10-11 16:11:36 +02005055 return 0;
5056}
5057
Emeric Brun2c86cbf2014-10-30 15:56:50 +01005058/* parse the "ssl-default-bind-options" keyword in global section */
5059static int ssl_parse_default_bind_options(char **args, int section_type, struct proxy *curpx,
5060 struct proxy *defpx, const char *file, int line,
5061 char **err) {
5062 int i = 1;
5063
5064 if (*(args[i]) == 0) {
5065 memprintf(err, "global statement '%s' expects an option as an argument.", args[0]);
5066 return -1;
5067 }
5068 while (*(args[i])) {
5069 if (!strcmp(args[i], "no-sslv3"))
5070 global.listen_default_ssloptions |= BC_SSL_O_NO_SSLV3;
5071 else if (!strcmp(args[i], "no-tlsv10"))
5072 global.listen_default_ssloptions |= BC_SSL_O_NO_TLSV10;
5073 else if (!strcmp(args[i], "no-tlsv11"))
5074 global.listen_default_ssloptions |= BC_SSL_O_NO_TLSV11;
5075 else if (!strcmp(args[i], "no-tlsv12"))
5076 global.listen_default_ssloptions |= BC_SSL_O_NO_TLSV12;
5077 else if (!strcmp(args[i], "force-sslv3"))
5078 global.listen_default_ssloptions |= BC_SSL_O_USE_SSLV3;
5079 else if (!strcmp(args[i], "force-tlsv10"))
5080 global.listen_default_ssloptions |= BC_SSL_O_USE_TLSV10;
5081 else if (!strcmp(args[i], "force-tlsv11")) {
5082#if SSL_OP_NO_TLSv1_1
5083 global.listen_default_ssloptions |= BC_SSL_O_USE_TLSV11;
5084#else
5085 memprintf(err, "'%s' '%s': library does not support protocol TLSv1.1", args[0], args[i]);
5086 return -1;
5087#endif
5088 }
5089 else if (!strcmp(args[i], "force-tlsv12")) {
5090#if SSL_OP_NO_TLSv1_2
5091 global.listen_default_ssloptions |= BC_SSL_O_USE_TLSV12;
5092#else
5093 memprintf(err, "'%s' '%s': library does not support protocol TLSv1.2", args[0], args[i]);
5094 return -1;
5095#endif
5096 }
5097 else if (!strcmp(args[i], "no-tls-tickets"))
5098 global.listen_default_ssloptions |= BC_SSL_O_NO_TLS_TICKETS;
5099 else {
5100 memprintf(err, "unknown option '%s' on global statement '%s'.", args[i], args[0]);
5101 return -1;
5102 }
5103 i++;
5104 }
5105 return 0;
5106}
5107
5108/* parse the "ssl-default-server-options" keyword in global section */
5109static int ssl_parse_default_server_options(char **args, int section_type, struct proxy *curpx,
5110 struct proxy *defpx, const char *file, int line,
5111 char **err) {
5112 int i = 1;
5113
5114 if (*(args[i]) == 0) {
5115 memprintf(err, "global statement '%s' expects an option as an argument.", args[0]);
5116 return -1;
5117 }
5118 while (*(args[i])) {
5119 if (!strcmp(args[i], "no-sslv3"))
5120 global.connect_default_ssloptions |= SRV_SSL_O_NO_SSLV3;
5121 else if (!strcmp(args[i], "no-tlsv10"))
5122 global.connect_default_ssloptions |= SRV_SSL_O_NO_TLSV10;
5123 else if (!strcmp(args[i], "no-tlsv11"))
5124 global.connect_default_ssloptions |= SRV_SSL_O_NO_TLSV11;
5125 else if (!strcmp(args[i], "no-tlsv12"))
5126 global.connect_default_ssloptions |= SRV_SSL_O_NO_TLSV12;
5127 else if (!strcmp(args[i], "force-sslv3"))
5128 global.connect_default_ssloptions |= SRV_SSL_O_USE_SSLV3;
5129 else if (!strcmp(args[i], "force-tlsv10"))
5130 global.connect_default_ssloptions |= SRV_SSL_O_USE_TLSV10;
5131 else if (!strcmp(args[i], "force-tlsv11")) {
5132#if SSL_OP_NO_TLSv1_1
5133 global.connect_default_ssloptions |= SRV_SSL_O_USE_TLSV11;
5134#else
5135 memprintf(err, "'%s' '%s': library does not support protocol TLSv1.1", args[0], args[i]);
5136 return -1;
5137#endif
5138 }
5139 else if (!strcmp(args[i], "force-tlsv12")) {
5140#if SSL_OP_NO_TLSv1_2
5141 global.connect_default_ssloptions |= SRV_SSL_O_USE_TLSV12;
5142#else
5143 memprintf(err, "'%s' '%s': library does not support protocol TLSv1.2", args[0], args[i]);
5144 return -1;
5145#endif
5146 }
5147 else if (!strcmp(args[i], "no-tls-tickets"))
5148 global.connect_default_ssloptions |= SRV_SSL_O_NO_TLS_TICKETS;
5149 else {
5150 memprintf(err, "unknown option '%s' on global statement '%s'.", args[i], args[0]);
5151 return -1;
5152 }
5153 i++;
5154 }
5155 return 0;
5156}
5157
Willy Tarreau7875d092012-09-10 08:20:03 +02005158/* Note: must not be declared <const> as its list will be overwritten.
5159 * Please take care of keeping this list alphabetically sorted.
5160 */
Willy Tarreaudc13c112013-06-21 23:16:39 +02005161static struct sample_fetch_kw_list sample_fetch_keywords = {ILH, {
Emeric Brun645ae792014-04-30 14:21:06 +02005162 { "ssl_bc", smp_fetch_ssl_fc, 0, NULL, SMP_T_BOOL, SMP_USE_L5SRV },
Thierry FOURNIER07ee64e2015-07-06 23:43:03 +02005163 { "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 +02005164 { "ssl_bc_cipher", smp_fetch_ssl_fc_cipher, 0, NULL, SMP_T_STR, SMP_USE_L5SRV },
5165 { "ssl_bc_protocol", smp_fetch_ssl_fc_protocol, 0, NULL, SMP_T_STR, SMP_USE_L5SRV },
Emeric Brunb73a9b02014-04-30 18:49:19 +02005166 { "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 +02005167 { "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 +02005168 { "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 +02005169 { "ssl_c_ca_err", smp_fetch_ssl_c_ca_err, 0, NULL, SMP_T_SINT, SMP_USE_L5CLI },
5170 { "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 +01005171 { "ssl_c_der", smp_fetch_ssl_x_der, 0, NULL, SMP_T_BIN, SMP_USE_L5CLI },
Thierry FOURNIER07ee64e2015-07-06 23:43:03 +02005172 { "ssl_c_err", smp_fetch_ssl_c_err, 0, NULL, SMP_T_SINT, SMP_USE_L5CLI },
Emeric Brunba841a12014-04-30 17:05:08 +02005173 { "ssl_c_i_dn", smp_fetch_ssl_x_i_dn, ARG2(0,STR,SINT), NULL, SMP_T_STR, SMP_USE_L5CLI },
5174 { "ssl_c_key_alg", smp_fetch_ssl_x_key_alg, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
5175 { "ssl_c_notafter", smp_fetch_ssl_x_notafter, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
5176 { "ssl_c_notbefore", smp_fetch_ssl_x_notbefore, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
5177 { "ssl_c_sig_alg", smp_fetch_ssl_x_sig_alg, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
5178 { "ssl_c_s_dn", smp_fetch_ssl_x_s_dn, ARG2(0,STR,SINT), NULL, SMP_T_STR, SMP_USE_L5CLI },
5179 { "ssl_c_serial", smp_fetch_ssl_x_serial, 0, NULL, SMP_T_BIN, SMP_USE_L5CLI },
5180 { "ssl_c_sha1", smp_fetch_ssl_x_sha1, 0, NULL, SMP_T_BIN, SMP_USE_L5CLI },
Willy Tarreau80aca902013-01-07 15:42:20 +01005181 { "ssl_c_used", smp_fetch_ssl_c_used, 0, NULL, SMP_T_BOOL, SMP_USE_L5CLI },
Thierry FOURNIER07ee64e2015-07-06 23:43:03 +02005182 { "ssl_c_verify", smp_fetch_ssl_c_verify, 0, NULL, SMP_T_SINT, SMP_USE_L5CLI },
5183 { "ssl_c_version", smp_fetch_ssl_x_version, 0, NULL, SMP_T_SINT, SMP_USE_L5CLI },
Emeric Brun43e79582014-10-29 19:03:26 +01005184 { "ssl_f_der", smp_fetch_ssl_x_der, 0, NULL, SMP_T_BIN, SMP_USE_L5CLI },
Emeric Brunba841a12014-04-30 17:05:08 +02005185 { "ssl_f_i_dn", smp_fetch_ssl_x_i_dn, ARG2(0,STR,SINT), NULL, SMP_T_STR, SMP_USE_L5CLI },
5186 { "ssl_f_key_alg", smp_fetch_ssl_x_key_alg, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
5187 { "ssl_f_notafter", smp_fetch_ssl_x_notafter, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
5188 { "ssl_f_notbefore", smp_fetch_ssl_x_notbefore, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
5189 { "ssl_f_sig_alg", smp_fetch_ssl_x_sig_alg, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
5190 { "ssl_f_s_dn", smp_fetch_ssl_x_s_dn, ARG2(0,STR,SINT), NULL, SMP_T_STR, SMP_USE_L5CLI },
5191 { "ssl_f_serial", smp_fetch_ssl_x_serial, 0, NULL, SMP_T_BIN, SMP_USE_L5CLI },
Emeric Brun55f4fa82014-04-30 17:11:25 +02005192 { "ssl_f_sha1", smp_fetch_ssl_x_sha1, 0, NULL, SMP_T_BIN, SMP_USE_L5CLI },
Thierry FOURNIER07ee64e2015-07-06 23:43:03 +02005193 { "ssl_f_version", smp_fetch_ssl_x_version, 0, NULL, SMP_T_SINT, SMP_USE_L5CLI },
Willy Tarreau80aca902013-01-07 15:42:20 +01005194 { "ssl_fc", smp_fetch_ssl_fc, 0, NULL, SMP_T_BOOL, SMP_USE_L5CLI },
Thierry FOURNIER07ee64e2015-07-06 23:43:03 +02005195 { "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 +01005196 { "ssl_fc_cipher", smp_fetch_ssl_fc_cipher, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
Willy Tarreau80aca902013-01-07 15:42:20 +01005197 { "ssl_fc_has_crt", smp_fetch_ssl_fc_has_crt, 0, NULL, SMP_T_BOOL, SMP_USE_L5CLI },
5198 { "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 +02005199 { "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 +02005200#ifdef OPENSSL_NPN_NEGOTIATED
Thierry FOURNIER7654c9f2013-12-17 00:20:33 +01005201 { "ssl_fc_npn", smp_fetch_ssl_fc_npn, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
Willy Tarreaua33c6542012-10-15 13:19:06 +02005202#endif
Dirkjan Bussink48f1c4e2014-02-13 12:29:42 +01005203#ifdef TLSEXT_TYPE_application_layer_protocol_negotiation
Thierry FOURNIER7654c9f2013-12-17 00:20:33 +01005204 { "ssl_fc_alpn", smp_fetch_ssl_fc_alpn, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
Willy Tarreauab861d32013-04-02 02:30:41 +02005205#endif
Thierry FOURNIER7654c9f2013-12-17 00:20:33 +01005206 { "ssl_fc_protocol", smp_fetch_ssl_fc_protocol, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
Emeric Brunb73a9b02014-04-30 18:49:19 +02005207 { "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 +02005208 { "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 +01005209 { "ssl_fc_session_id", smp_fetch_ssl_fc_session_id, 0, NULL, SMP_T_BIN, SMP_USE_L5CLI },
5210 { "ssl_fc_sni", smp_fetch_ssl_fc_sni, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
Willy Tarreau7875d092012-09-10 08:20:03 +02005211 { NULL, NULL, 0, 0, 0 },
5212}};
5213
5214/* Note: must not be declared <const> as its list will be overwritten.
5215 * Please take care of keeping this list alphabetically sorted.
5216 */
Willy Tarreaudc13c112013-06-21 23:16:39 +02005217static struct acl_kw_list acl_kws = {ILH, {
Thierry FOURNIERc5a4e982014-03-05 16:07:08 +01005218 { "ssl_fc_sni_end", "ssl_fc_sni", PAT_MATCH_END },
5219 { "ssl_fc_sni_reg", "ssl_fc_sni", PAT_MATCH_REG },
Willy Tarreau8ed669b2013-01-11 15:49:37 +01005220 { /* END */ },
Willy Tarreau7875d092012-09-10 08:20:03 +02005221}};
5222
Willy Tarreau79eeafa2012-09-14 07:53:05 +02005223/* Note: must not be declared <const> as its list will be overwritten.
5224 * Please take care of keeping this list alphabetically sorted, doing so helps
5225 * all code contributors.
5226 * Optional keywords are also declared with a NULL ->parse() function so that
5227 * the config parser can report an appropriate error when a known keyword was
5228 * not enabled.
5229 */
Willy Tarreau51fb7652012-09-18 18:24:39 +02005230static struct bind_kw_list bind_kws = { "SSL", { }, {
Nenad Merdanovic05552d42015-02-27 19:56:49 +01005231 { "alpn", bind_parse_alpn, 1 }, /* set ALPN supported protocols */
5232 { "ca-file", bind_parse_ca_file, 1 }, /* set CAfile to process verify on client cert */
5233 { "ca-ignore-err", bind_parse_ignore_err, 1 }, /* set error IDs to ignore on verify depth > 0 */
Christopher Faulet31af49d2015-06-09 17:29:50 +02005234 { "ca-sign-file", bind_parse_ca_sign_file, 1 }, /* set CAFile used to generate and sign server certs */
5235 { "ca-sign-pass", bind_parse_ca_sign_pass, 1 }, /* set CAKey passphrase */
Nenad Merdanovic05552d42015-02-27 19:56:49 +01005236 { "ciphers", bind_parse_ciphers, 1 }, /* set SSL cipher suite */
5237 { "crl-file", bind_parse_crl_file, 1 }, /* set certificat revocation list file use on client cert verify */
5238 { "crt", bind_parse_crt, 1 }, /* load SSL certificates from this location */
5239 { "crt-ignore-err", bind_parse_ignore_err, 1 }, /* set error IDs to ingore on verify depth == 0 */
5240 { "crt-list", bind_parse_crt_list, 1 }, /* load a list of crt from this location */
5241 { "ecdhe", bind_parse_ecdhe, 1 }, /* defines named curve for elliptic curve Diffie-Hellman */
5242 { "force-sslv3", bind_parse_force_sslv3, 0 }, /* force SSLv3 */
5243 { "force-tlsv10", bind_parse_force_tlsv10, 0 }, /* force TLSv10 */
5244 { "force-tlsv11", bind_parse_force_tlsv11, 0 }, /* force TLSv11 */
5245 { "force-tlsv12", bind_parse_force_tlsv12, 0 }, /* force TLSv12 */
Christopher Faulet31af49d2015-06-09 17:29:50 +02005246 { "generate-certificates", bind_parse_generate_certs, 0 }, /* enable the server certificates generation */
Nenad Merdanovic05552d42015-02-27 19:56:49 +01005247 { "no-sslv3", bind_parse_no_sslv3, 0 }, /* disable SSLv3 */
5248 { "no-tlsv10", bind_parse_no_tlsv10, 0 }, /* disable TLSv10 */
5249 { "no-tlsv11", bind_parse_no_tlsv11, 0 }, /* disable TLSv11 */
5250 { "no-tlsv12", bind_parse_no_tlsv12, 0 }, /* disable TLSv12 */
5251 { "no-tls-tickets", bind_parse_no_tls_tickets, 0 }, /* disable session resumption tickets */
5252 { "ssl", bind_parse_ssl, 0 }, /* enable SSL processing */
5253 { "strict-sni", bind_parse_strict_sni, 0 }, /* refuse negotiation if sni doesn't match a certificate */
5254 { "tls-ticket-keys", bind_parse_tls_ticket_keys, 1 }, /* set file to load TLS ticket keys from */
5255 { "verify", bind_parse_verify, 1 }, /* set SSL verify method */
5256 { "npn", bind_parse_npn, 1 }, /* set NPN supported protocols */
Willy Tarreau79eeafa2012-09-14 07:53:05 +02005257 { NULL, NULL, 0 },
5258}};
Emeric Brun46591952012-05-18 15:47:34 +02005259
Willy Tarreau92faadf2012-10-10 23:04:25 +02005260/* Note: must not be declared <const> as its list will be overwritten.
5261 * Please take care of keeping this list alphabetically sorted, doing so helps
5262 * all code contributors.
5263 * Optional keywords are also declared with a NULL ->parse() function so that
5264 * the config parser can report an appropriate error when a known keyword was
5265 * not enabled.
5266 */
5267static struct srv_kw_list srv_kws = { "SSL", { }, {
Emeric Brunef42d922012-10-11 16:11:36 +02005268 { "ca-file", srv_parse_ca_file, 1, 0 }, /* set CAfile to process verify server cert */
Emeric Brunecc91fe2012-10-11 15:05:10 +02005269 { "check-ssl", srv_parse_check_ssl, 0, 0 }, /* enable SSL for health checks */
5270 { "ciphers", srv_parse_ciphers, 1, 0 }, /* select the cipher suite */
Emeric Brunef42d922012-10-11 16:11:36 +02005271 { "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 +02005272 { "crt", srv_parse_crt, 1, 0 }, /* set client certificate */
Emeric Brunecc91fe2012-10-11 15:05:10 +02005273 { "force-sslv3", srv_parse_force_sslv3, 0, 0 }, /* force SSLv3 */
5274 { "force-tlsv10", srv_parse_force_tlsv10, 0, 0 }, /* force TLSv10 */
5275 { "force-tlsv11", srv_parse_force_tlsv11, 0, 0 }, /* force TLSv11 */
5276 { "force-tlsv12", srv_parse_force_tlsv12, 0, 0 }, /* force TLSv12 */
Willy Tarreau2a3fb1c2015-02-05 16:47:07 +01005277 { "no-ssl-reuse", srv_parse_no_ssl_reuse, 0, 0 }, /* disable session reuse */
Emeric Brunecc91fe2012-10-11 15:05:10 +02005278 { "no-sslv3", srv_parse_no_sslv3, 0, 0 }, /* disable SSLv3 */
5279 { "no-tlsv10", srv_parse_no_tlsv10, 0, 0 }, /* disable TLSv10 */
5280 { "no-tlsv11", srv_parse_no_tlsv11, 0, 0 }, /* disable TLSv11 */
5281 { "no-tlsv12", srv_parse_no_tlsv12, 0, 0 }, /* disable TLSv12 */
Emeric Brunf9c5c472012-10-11 15:28:34 +02005282 { "no-tls-tickets", srv_parse_no_tls_tickets, 0, 0 }, /* disable session resumption tickets */
David Safb76832014-05-08 23:42:08 -04005283 { "send-proxy-v2-ssl", srv_parse_send_proxy_ssl, 0, 0 }, /* send PROXY protocol header v2 with SSL info */
5284 { "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 +02005285 { "sni", srv_parse_sni, 1, 0 }, /* send SNI extension */
Emeric Brunecc91fe2012-10-11 15:05:10 +02005286 { "ssl", srv_parse_ssl, 0, 0 }, /* enable SSL processing */
Emeric Brunef42d922012-10-11 16:11:36 +02005287 { "verify", srv_parse_verify, 1, 0 }, /* set SSL verify method */
Evan Broderbe554312013-06-27 00:05:25 -07005288 { "verifyhost", srv_parse_verifyhost, 1, 0 }, /* require that SSL cert verifies for hostname */
Willy Tarreau92faadf2012-10-10 23:04:25 +02005289 { NULL, NULL, 0, 0 },
5290}};
5291
Emeric Brun2c86cbf2014-10-30 15:56:50 +01005292static struct cfg_kw_list cfg_kws = {ILH, {
5293 { CFG_GLOBAL, "ssl-default-bind-options", ssl_parse_default_bind_options },
5294 { CFG_GLOBAL, "ssl-default-server-options", ssl_parse_default_server_options },
5295 { 0, NULL, NULL },
5296}};
5297
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02005298/* transport-layer operations for SSL sockets */
5299struct xprt_ops ssl_sock = {
Emeric Brun46591952012-05-18 15:47:34 +02005300 .snd_buf = ssl_sock_from_buf,
5301 .rcv_buf = ssl_sock_to_buf,
5302 .rcv_pipe = NULL,
5303 .snd_pipe = NULL,
5304 .shutr = NULL,
5305 .shutw = ssl_sock_shutw,
5306 .close = ssl_sock_close,
5307 .init = ssl_sock_init,
5308};
5309
Janusz Dziemidowicz2c701b52015-03-07 23:03:59 +01005310#if (OPENSSL_VERSION_NUMBER >= 0x1000200fL && !defined OPENSSL_NO_TLSEXT && !defined OPENSSL_IS_BORINGSSL)
5311
5312static void ssl_sock_sctl_free_func(void *parent, void *ptr, CRYPTO_EX_DATA *ad, int idx, long argl, void *argp)
5313{
5314 if (ptr) {
5315 chunk_destroy(ptr);
5316 free(ptr);
5317 }
5318}
5319
5320#endif
5321
Emeric Brun46591952012-05-18 15:47:34 +02005322__attribute__((constructor))
Willy Tarreau92faadf2012-10-10 23:04:25 +02005323static void __ssl_sock_init(void)
5324{
Emeric Brun46591952012-05-18 15:47:34 +02005325 STACK_OF(SSL_COMP)* cm;
5326
Willy Tarreau610f04b2014-02-13 11:36:41 +01005327#ifdef LISTEN_DEFAULT_CIPHERS
5328 global.listen_default_ciphers = LISTEN_DEFAULT_CIPHERS;
5329#endif
5330#ifdef CONNECT_DEFAULT_CIPHERS
5331 global.connect_default_ciphers = CONNECT_DEFAULT_CIPHERS;
5332#endif
5333 if (global.listen_default_ciphers)
5334 global.listen_default_ciphers = strdup(global.listen_default_ciphers);
5335 if (global.connect_default_ciphers)
5336 global.connect_default_ciphers = strdup(global.connect_default_ciphers);
Emeric Brun2c86cbf2014-10-30 15:56:50 +01005337 global.listen_default_ssloptions = BC_SSL_O_NONE;
5338 global.connect_default_ssloptions = SRV_SSL_O_NONE;
Willy Tarreau610f04b2014-02-13 11:36:41 +01005339
Emeric Brun46591952012-05-18 15:47:34 +02005340 SSL_library_init();
5341 cm = SSL_COMP_get_compression_methods();
5342 sk_SSL_COMP_zero(cm);
Janusz Dziemidowicz2c701b52015-03-07 23:03:59 +01005343#if (OPENSSL_VERSION_NUMBER >= 0x1000200fL && !defined OPENSSL_NO_TLSEXT && !defined OPENSSL_IS_BORINGSSL)
5344 sctl_ex_index = SSL_CTX_get_ex_new_index(0, NULL, NULL, NULL, ssl_sock_sctl_free_func);
5345#endif
Willy Tarreau7875d092012-09-10 08:20:03 +02005346 sample_register_fetches(&sample_fetch_keywords);
5347 acl_register_keywords(&acl_kws);
Willy Tarreau79eeafa2012-09-14 07:53:05 +02005348 bind_register_keywords(&bind_kws);
Willy Tarreau92faadf2012-10-10 23:04:25 +02005349 srv_register_keywords(&srv_kws);
Emeric Brun2c86cbf2014-10-30 15:56:50 +01005350 cfg_register_keywords(&cfg_kws);
Willy Tarreaud92aa5c2015-01-15 21:34:39 +01005351
5352 global.ssl_session_max_cost = SSL_SESSION_MAX_COST;
5353 global.ssl_handshake_max_cost = SSL_HANDSHAKE_MAX_COST;
Remi Gacogne4f902b82015-05-28 16:23:00 +02005354
5355#ifndef OPENSSL_NO_DH
5356 ssl_dh_ptr_index = SSL_CTX_get_ex_new_index(0, NULL, NULL, NULL, NULL);
5357#endif
Emeric Brun46591952012-05-18 15:47:34 +02005358}
5359
Remi Gacogned3a23c32015-05-28 16:39:47 +02005360__attribute__((destructor))
5361static void __ssl_sock_deinit(void)
5362{
Christopher Faulet31af49d2015-06-09 17:29:50 +02005363 lru64_destroy(ssl_ctx_lru_tree);
5364
Remi Gacogned3a23c32015-05-28 16:39:47 +02005365#ifndef OPENSSL_NO_DH
5366 if (local_dh_1024) {
5367 DH_free(local_dh_1024);
5368 local_dh_1024 = NULL;
5369 }
5370
5371 if (local_dh_2048) {
5372 DH_free(local_dh_2048);
5373 local_dh_2048 = NULL;
5374 }
5375
5376 if (local_dh_4096) {
5377 DH_free(local_dh_4096);
5378 local_dh_4096 = NULL;
5379 }
5380
Remi Gacogne47783ef2015-05-29 15:53:22 +02005381 if (global_dh) {
5382 DH_free(global_dh);
5383 global_dh = NULL;
5384 }
Remi Gacogned3a23c32015-05-28 16:39:47 +02005385#endif
5386
5387 ERR_remove_state(0);
5388 ERR_free_strings();
5389
5390 EVP_cleanup();
5391
5392#if OPENSSL_VERSION_NUMBER >= 0x00907000L
5393 CRYPTO_cleanup_all_ex_data();
5394#endif
5395}
5396
5397
Emeric Brun46591952012-05-18 15:47:34 +02005398/*
5399 * Local variables:
5400 * c-indent-level: 8
5401 * c-basic-offset: 8
5402 * End:
5403 */