blob: c67cd5617e3e9c44f8c4af60d72f110b49eb2f1a [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
Daniel Jakots54ffb912015-11-06 20:02:41 +0100717#if (OPENSSL_VERSION_NUMBER >= 0x1000200fL && !defined OPENSSL_NO_TLSEXT && !defined OPENSSL_IS_BORINGSSL && !defined LIBRESSL_VERSION_NUMBER)
Janusz Dziemidowicz2c701b52015-03-07 23:03:59 +0100718
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 Faulet85b5a1a2015-10-09 11:46:32 +02001009static DH *ssl_get_tmp_dh(SSL *ssl, int export, int keylen);
1010
Christopher Faulet30548802015-06-11 13:39:32 +02001011/* Create a X509 certificate with the specified servername and serial. This
1012 * function returns a SSL_CTX object or NULL if an error occurs. */
Christopher Faulet7969a332015-10-09 11:15:03 +02001013static SSL_CTX *
1014ssl_sock_do_create_cert(const char *servername, unsigned int serial,
1015 struct bind_conf *bind_conf, SSL *ssl)
Christopher Faulet31af49d2015-06-09 17:29:50 +02001016{
Christopher Faulet7969a332015-10-09 11:15:03 +02001017 X509 *cacert = bind_conf->ca_sign_cert;
1018 EVP_PKEY *capkey = bind_conf->ca_sign_pkey;
Christopher Faulet31af49d2015-06-09 17:29:50 +02001019 SSL_CTX *ssl_ctx = NULL;
1020 X509 *newcrt = NULL;
1021 EVP_PKEY *pkey = NULL;
Christopher Faulet31af49d2015-06-09 17:29:50 +02001022 X509_NAME *name;
1023 const EVP_MD *digest;
1024 X509V3_CTX ctx;
1025 unsigned int i;
1026
Christopher Faulet7969a332015-10-09 11:15:03 +02001027 /* Get the private key of the defautl certificate and use it */
1028 if (!(pkey = SSL_get_privatekey(ssl)))
Christopher Faulet31af49d2015-06-09 17:29:50 +02001029 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();
Christopher Faulet7969a332015-10-09 11:15:03 +02001089 else if (EVP_PKEY_type (capkey->type) == EVP_PKEY_EC)
1090 digest = EVP_sha256();
1091 else {
Christopher Faulete7db2162015-10-19 13:59:24 +02001092#if (OPENSSL_VERSION_NUMBER >= 0x1000000fL)
Christopher Faulet7969a332015-10-09 11:15:03 +02001093 int nid;
1094
1095 if (EVP_PKEY_get_default_digest_nid(capkey, &nid) <= 0)
1096 goto mkcert_error;
1097 if (!(digest = EVP_get_digestbynid(nid)))
1098 goto mkcert_error;
Christopher Faulete7db2162015-10-19 13:59:24 +02001099#else
1100 goto mkcert_error;
1101#endif
Christopher Faulet7969a332015-10-09 11:15:03 +02001102 }
1103
Christopher Faulet31af49d2015-06-09 17:29:50 +02001104 if (!(X509_sign(newcrt, capkey, digest)))
1105 goto mkcert_error;
1106
1107 /* Create and set the new SSL_CTX */
1108 if (!(ssl_ctx = SSL_CTX_new(SSLv23_server_method())))
1109 goto mkcert_error;
1110 if (!SSL_CTX_use_PrivateKey(ssl_ctx, pkey))
1111 goto mkcert_error;
1112 if (!SSL_CTX_use_certificate(ssl_ctx, newcrt))
1113 goto mkcert_error;
1114 if (!SSL_CTX_check_private_key(ssl_ctx))
1115 goto mkcert_error;
1116
1117 if (newcrt) X509_free(newcrt);
Christopher Faulet7969a332015-10-09 11:15:03 +02001118
Christopher Faulet85b5a1a2015-10-09 11:46:32 +02001119 SSL_CTX_set_tmp_dh_callback(ssl_ctx, ssl_get_tmp_dh);
1120#if defined(SSL_CTX_set_tmp_ecdh) && !defined(OPENSSL_NO_ECDH)
1121 {
1122 const char *ecdhe = (bind_conf->ecdhe ? bind_conf->ecdhe : ECDHE_DEFAULT_CURVE);
1123 EC_KEY *ecc;
1124 int nid;
1125
1126 if ((nid = OBJ_sn2nid(ecdhe)) == NID_undef)
1127 goto end;
1128 if (!(ecc = EC_KEY_new_by_curve_name(nid)))
1129 goto end;
1130 SSL_CTX_set_tmp_ecdh(ssl_ctx, ecc);
1131 EC_KEY_free(ecc);
1132 }
1133#endif
1134 end:
Christopher Faulet31af49d2015-06-09 17:29:50 +02001135 return ssl_ctx;
1136
1137 mkcert_error:
1138 if (ssl_ctx) SSL_CTX_free(ssl_ctx);
1139 if (newcrt) X509_free(newcrt);
Christopher Faulet31af49d2015-06-09 17:29:50 +02001140 return NULL;
1141}
1142
Christopher Faulet7969a332015-10-09 11:15:03 +02001143SSL_CTX *
1144ssl_sock_create_cert(struct connection *conn, const char *servername, unsigned int serial)
1145{
1146 struct bind_conf *bind_conf = objt_listener(conn->target)->bind_conf;
1147 return ssl_sock_do_create_cert(servername, serial, bind_conf, conn->xprt_ctx);
1148}
1149
Christopher Faulet30548802015-06-11 13:39:32 +02001150/* Do a lookup for a certificate in the LRU cache used to store generated
1151 * certificates. */
1152SSL_CTX *
Christopher Faulet7969a332015-10-09 11:15:03 +02001153ssl_sock_get_generated_cert(unsigned int serial, struct bind_conf *bind_conf)
Christopher Faulet30548802015-06-11 13:39:32 +02001154{
1155 struct lru64 *lru = NULL;
1156
1157 if (ssl_ctx_lru_tree) {
Christopher Faulet7969a332015-10-09 11:15:03 +02001158 lru = lru64_lookup(serial, ssl_ctx_lru_tree, bind_conf->ca_sign_cert, 0);
Christopher Faulet30548802015-06-11 13:39:32 +02001159 if (lru && lru->domain)
1160 return (SSL_CTX *)lru->data;
1161 }
1162 return NULL;
1163}
1164
Christopher Fauletd2cab922015-07-28 16:03:47 +02001165/* Set a certificate int the LRU cache used to store generated
1166 * certificate. Return 0 on success, otherwise -1 */
1167int
Christopher Faulet7969a332015-10-09 11:15:03 +02001168ssl_sock_set_generated_cert(SSL_CTX *ssl_ctx, unsigned int serial, struct bind_conf *bind_conf)
Christopher Faulet30548802015-06-11 13:39:32 +02001169{
1170 struct lru64 *lru = NULL;
1171
1172 if (ssl_ctx_lru_tree) {
Christopher Faulet7969a332015-10-09 11:15:03 +02001173 lru = lru64_get(serial, ssl_ctx_lru_tree, bind_conf->ca_sign_cert, 0);
Christopher Faulet30548802015-06-11 13:39:32 +02001174 if (!lru)
Christopher Fauletd2cab922015-07-28 16:03:47 +02001175 return -1;
Christopher Faulet30548802015-06-11 13:39:32 +02001176 if (lru->domain && lru->data)
1177 lru->free((SSL_CTX *)lru->data);
Christopher Faulet7969a332015-10-09 11:15:03 +02001178 lru64_commit(lru, ssl_ctx, bind_conf->ca_sign_cert, 0, (void (*)(void *))SSL_CTX_free);
Christopher Fauletd2cab922015-07-28 16:03:47 +02001179 return 0;
Christopher Faulet30548802015-06-11 13:39:32 +02001180 }
Christopher Fauletd2cab922015-07-28 16:03:47 +02001181 return -1;
Christopher Faulet30548802015-06-11 13:39:32 +02001182}
1183
1184/* Compute the serial that will be used to create/set/get a certificate. */
1185unsigned int
Willy Tarreau646b8642015-07-07 18:09:15 +02001186ssl_sock_generated_cert_serial(const void *data, size_t len)
Christopher Faulet30548802015-06-11 13:39:32 +02001187{
1188 return XXH32(data, len, ssl_ctx_lru_seed);
1189}
1190
Willy Tarreau2f63ef42015-10-20 15:16:01 +02001191/* Generate a cert and immediately assign it to the SSL session so that the cert's
1192 * refcount is maintained regardless of the cert's presence in the LRU cache.
1193 */
Christopher Faulet31af49d2015-06-09 17:29:50 +02001194static SSL_CTX *
Christopher Faulet7969a332015-10-09 11:15:03 +02001195ssl_sock_generate_certificate(const char *servername, struct bind_conf *bind_conf, SSL *ssl)
Christopher Faulet31af49d2015-06-09 17:29:50 +02001196{
1197 X509 *cacert = bind_conf->ca_sign_cert;
Christopher Faulet31af49d2015-06-09 17:29:50 +02001198 SSL_CTX *ssl_ctx = NULL;
1199 struct lru64 *lru = NULL;
1200 unsigned int serial;
1201
Willy Tarreaufc017fe2015-07-07 18:09:34 +02001202 serial = ssl_sock_generated_cert_serial(servername, strlen(servername));
Christopher Faulet31af49d2015-06-09 17:29:50 +02001203 if (ssl_ctx_lru_tree) {
1204 lru = lru64_get(serial, ssl_ctx_lru_tree, cacert, 0);
1205 if (lru && lru->domain)
1206 ssl_ctx = (SSL_CTX *)lru->data;
Christopher Fauletd2cab922015-07-28 16:03:47 +02001207 if (!ssl_ctx && lru) {
Christopher Faulet7969a332015-10-09 11:15:03 +02001208 ssl_ctx = ssl_sock_do_create_cert(servername, serial, bind_conf, ssl);
Christopher Faulet31af49d2015-06-09 17:29:50 +02001209 lru64_commit(lru, ssl_ctx, cacert, 0, (void (*)(void *))SSL_CTX_free);
Christopher Fauletd2cab922015-07-28 16:03:47 +02001210 }
Willy Tarreau2f63ef42015-10-20 15:16:01 +02001211 SSL_set_SSL_CTX(ssl, ssl_ctx);
Christopher Faulet31af49d2015-06-09 17:29:50 +02001212 }
Willy Tarreau2f63ef42015-10-20 15:16:01 +02001213 else {
Christopher Faulet7969a332015-10-09 11:15:03 +02001214 ssl_ctx = ssl_sock_do_create_cert(servername, serial, bind_conf, ssl);
Willy Tarreau2f63ef42015-10-20 15:16:01 +02001215 SSL_set_SSL_CTX(ssl, ssl_ctx);
1216 /* No LRU cache, this CTX will be released as soon as the session dies */
1217 SSL_CTX_free(ssl_ctx);
1218 }
Christopher Faulet31af49d2015-06-09 17:29:50 +02001219 return ssl_ctx;
1220}
1221
Emeric Brunfc0421f2012-09-07 17:30:07 +02001222/* Sets the SSL ctx of <ssl> to match the advertised server name. Returns a
1223 * warning when no match is found, which implies the default (first) cert
1224 * will keep being used.
1225 */
Willy Tarreau2a65ff02012-09-13 17:54:29 +02001226static int ssl_sock_switchctx_cbk(SSL *ssl, int *al, struct bind_conf *s)
Emeric Brunfc0421f2012-09-07 17:30:07 +02001227{
1228 const char *servername;
1229 const char *wildp = NULL;
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +02001230 struct ebmb_node *node, *n;
Emeric Brunfc0421f2012-09-07 17:30:07 +02001231 int i;
1232 (void)al; /* shut gcc stupid warning */
1233
1234 servername = SSL_get_servername(ssl, TLSEXT_NAMETYPE_host_name);
Emmanuel Hocdet65623372013-01-24 17:17:15 +01001235 if (!servername) {
Willy Tarreauf6721452015-07-07 18:04:38 +02001236 if (s->generate_certs) {
1237 struct connection *conn = (struct connection *)SSL_get_app_data(ssl);
1238 unsigned int serial;
1239 SSL_CTX *ctx;
Christopher Faulet30548802015-06-11 13:39:32 +02001240
Willy Tarreauf6721452015-07-07 18:04:38 +02001241 conn_get_to_addr(conn);
1242 if (conn->flags & CO_FL_ADDR_TO_SET) {
1243 serial = ssl_sock_generated_cert_serial(&conn->addr.to, get_addr_len(&conn->addr.to));
Christopher Faulet7969a332015-10-09 11:15:03 +02001244 ctx = ssl_sock_get_generated_cert(serial, s);
Willy Tarreauf6721452015-07-07 18:04:38 +02001245 if (ctx) {
1246 /* switch ctx */
1247 SSL_set_SSL_CTX(ssl, ctx);
1248 return SSL_TLSEXT_ERR_OK;
1249 }
Christopher Faulet30548802015-06-11 13:39:32 +02001250 }
1251 }
1252
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +02001253 return (s->strict_sni ?
1254 SSL_TLSEXT_ERR_ALERT_FATAL :
Emmanuel Hocdet79274e22013-05-31 12:47:44 +02001255 SSL_TLSEXT_ERR_NOACK);
Emmanuel Hocdet65623372013-01-24 17:17:15 +01001256 }
Emeric Brunfc0421f2012-09-07 17:30:07 +02001257
Willy Tarreau19d14ef2012-10-29 16:51:55 +01001258 for (i = 0; i < trash.size; i++) {
Emeric Brunfc0421f2012-09-07 17:30:07 +02001259 if (!servername[i])
1260 break;
Willy Tarreau19d14ef2012-10-29 16:51:55 +01001261 trash.str[i] = tolower(servername[i]);
1262 if (!wildp && (trash.str[i] == '.'))
1263 wildp = &trash.str[i];
Emeric Brunfc0421f2012-09-07 17:30:07 +02001264 }
Willy Tarreau19d14ef2012-10-29 16:51:55 +01001265 trash.str[i] = 0;
Emeric Brunfc0421f2012-09-07 17:30:07 +02001266
1267 /* lookup in full qualified names */
Willy Tarreau19d14ef2012-10-29 16:51:55 +01001268 node = ebst_lookup(&s->sni_ctx, trash.str);
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +02001269
1270 /* lookup a not neg filter */
1271 for (n = node; n; n = ebmb_next_dup(n)) {
1272 if (!container_of(n, struct sni_ctx, name)->neg) {
1273 node = n;
1274 break;
Emmanuel Hocdet65623372013-01-24 17:17:15 +01001275 }
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +02001276 }
1277 if (!node && wildp) {
1278 /* lookup in wildcards names */
Emeric Brunfc0421f2012-09-07 17:30:07 +02001279 node = ebst_lookup(&s->sni_w_ctx, wildp);
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +02001280 }
1281 if (!node || container_of(node, struct sni_ctx, name)->neg) {
Christopher Faulet31af49d2015-06-09 17:29:50 +02001282 SSL_CTX *ctx;
Christopher Faulet31af49d2015-06-09 17:29:50 +02001283 if (s->generate_certs &&
Christopher Faulet7969a332015-10-09 11:15:03 +02001284 (ctx = ssl_sock_generate_certificate(servername, s, ssl))) {
Christopher Faulet31af49d2015-06-09 17:29:50 +02001285 /* switch ctx */
Christopher Faulet31af49d2015-06-09 17:29:50 +02001286 return SSL_TLSEXT_ERR_OK;
1287 }
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +02001288 return (s->strict_sni ?
1289 SSL_TLSEXT_ERR_ALERT_FATAL :
1290 SSL_TLSEXT_ERR_ALERT_WARNING);
Emeric Brunfc0421f2012-09-07 17:30:07 +02001291 }
1292
1293 /* switch ctx */
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +02001294 SSL_set_SSL_CTX(ssl, container_of(node, struct sni_ctx, name)->ctx);
Emeric Brunfc0421f2012-09-07 17:30:07 +02001295 return SSL_TLSEXT_ERR_OK;
1296}
1297#endif /* SSL_CTRL_SET_TLSEXT_HOSTNAME */
1298
Emeric Bruna4bcd9a2012-09-20 16:19:02 +02001299#ifndef OPENSSL_NO_DH
Remi Gacognef46cd6e2014-06-12 14:58:40 +02001300
1301static DH * ssl_get_dh_1024(void)
1302{
Remi Gacogned3a341a2015-05-29 16:26:17 +02001303 static unsigned char dh1024_p[]={
1304 0xFA,0xF9,0x2A,0x22,0x2A,0xA7,0x7F,0xE1,0x67,0x4E,0x53,0xF7,
1305 0x56,0x13,0xC3,0xB1,0xE3,0x29,0x6B,0x66,0x31,0x6A,0x7F,0xB3,
1306 0xC2,0x68,0x6B,0xCB,0x1D,0x57,0x39,0x1D,0x1F,0xFF,0x1C,0xC9,
1307 0xA6,0xA4,0x98,0x82,0x31,0x5D,0x25,0xFF,0x8A,0xE0,0x73,0x96,
1308 0x81,0xC8,0x83,0x79,0xC1,0x5A,0x04,0xF8,0x37,0x0D,0xA8,0x3D,
1309 0xAE,0x74,0xBC,0xDB,0xB6,0xA4,0x75,0xD9,0x71,0x8A,0xA0,0x17,
1310 0x9E,0x2D,0xC8,0xA8,0xDF,0x2C,0x5F,0x82,0x95,0xF8,0x92,0x9B,
1311 0xA7,0x33,0x5F,0x89,0x71,0xC8,0x2D,0x6B,0x18,0x86,0xC4,0x94,
1312 0x22,0xA5,0x52,0x8D,0xF6,0xF6,0xD2,0x37,0x92,0x0F,0xA5,0xCC,
1313 0xDB,0x7B,0x1D,0x3D,0xA1,0x31,0xB7,0x80,0x8F,0x0B,0x67,0x5E,
1314 0x36,0xA5,0x60,0x0C,0xF1,0x95,0x33,0x8B,
1315 };
1316 static unsigned char dh1024_g[]={
1317 0x02,
1318 };
1319
Remi Gacognef46cd6e2014-06-12 14:58:40 +02001320 DH *dh = DH_new();
1321 if (dh) {
Remi Gacogned3a341a2015-05-29 16:26:17 +02001322 dh->p = BN_bin2bn(dh1024_p, sizeof dh1024_p, NULL);
1323 dh->g = BN_bin2bn(dh1024_g, sizeof dh1024_g, NULL);
1324
Remi Gacognef46cd6e2014-06-12 14:58:40 +02001325 if (!dh->p || !dh->g) {
1326 DH_free(dh);
1327 dh = NULL;
1328 }
1329 }
1330 return dh;
1331}
1332
1333static DH *ssl_get_dh_2048(void)
1334{
Remi Gacogned3a341a2015-05-29 16:26:17 +02001335 static unsigned char dh2048_p[]={
1336 0xEC,0x86,0xF8,0x70,0xA0,0x33,0x16,0xEC,0x05,0x1A,0x73,0x59,
1337 0xCD,0x1F,0x8B,0xF8,0x29,0xE4,0xD2,0xCF,0x52,0xDD,0xC2,0x24,
1338 0x8D,0xB5,0x38,0x9A,0xFB,0x5C,0xA4,0xE4,0xB2,0xDA,0xCE,0x66,
1339 0x50,0x74,0xA6,0x85,0x4D,0x4B,0x1D,0x30,0xB8,0x2B,0xF3,0x10,
1340 0xE9,0xA7,0x2D,0x05,0x71,0xE7,0x81,0xDF,0x8B,0x59,0x52,0x3B,
1341 0x5F,0x43,0x0B,0x68,0xF1,0xDB,0x07,0xBE,0x08,0x6B,0x1B,0x23,
1342 0xEE,0x4D,0xCC,0x9E,0x0E,0x43,0xA0,0x1E,0xDF,0x43,0x8C,0xEC,
1343 0xBE,0xBE,0x90,0xB4,0x51,0x54,0xB9,0x2F,0x7B,0x64,0x76,0x4E,
1344 0x5D,0xD4,0x2E,0xAE,0xC2,0x9E,0xAE,0x51,0x43,0x59,0xC7,0x77,
1345 0x9C,0x50,0x3C,0x0E,0xED,0x73,0x04,0x5F,0xF1,0x4C,0x76,0x2A,
1346 0xD8,0xF8,0xCF,0xFC,0x34,0x40,0xD1,0xB4,0x42,0x61,0x84,0x66,
1347 0x42,0x39,0x04,0xF8,0x68,0xB2,0x62,0xD7,0x55,0xED,0x1B,0x74,
1348 0x75,0x91,0xE0,0xC5,0x69,0xC1,0x31,0x5C,0xDB,0x7B,0x44,0x2E,
1349 0xCE,0x84,0x58,0x0D,0x1E,0x66,0x0C,0xC8,0x44,0x9E,0xFD,0x40,
1350 0x08,0x67,0x5D,0xFB,0xA7,0x76,0x8F,0x00,0x11,0x87,0xE9,0x93,
1351 0xF9,0x7D,0xC4,0xBC,0x74,0x55,0x20,0xD4,0x4A,0x41,0x2F,0x43,
1352 0x42,0x1A,0xC1,0xF2,0x97,0x17,0x49,0x27,0x37,0x6B,0x2F,0x88,
1353 0x7E,0x1C,0xA0,0xA1,0x89,0x92,0x27,0xD9,0x56,0x5A,0x71,0xC1,
1354 0x56,0x37,0x7E,0x3A,0x9D,0x05,0xE7,0xEE,0x5D,0x8F,0x82,0x17,
1355 0xBC,0xE9,0xC2,0x93,0x30,0x82,0xF9,0xF4,0xC9,0xAE,0x49,0xDB,
1356 0xD0,0x54,0xB4,0xD9,0x75,0x4D,0xFA,0x06,0xB8,0xD6,0x38,0x41,
1357 0xB7,0x1F,0x77,0xF3,
1358 };
1359 static unsigned char dh2048_g[]={
1360 0x02,
1361 };
1362
Remi Gacognef46cd6e2014-06-12 14:58:40 +02001363 DH *dh = DH_new();
1364 if (dh) {
Remi Gacogned3a341a2015-05-29 16:26:17 +02001365 dh->p = BN_bin2bn(dh2048_p, sizeof dh2048_p, NULL);
1366 dh->g = BN_bin2bn(dh2048_g, sizeof dh2048_g, NULL);
1367
Remi Gacognef46cd6e2014-06-12 14:58:40 +02001368 if (!dh->p || !dh->g) {
1369 DH_free(dh);
1370 dh = NULL;
1371 }
1372 }
1373 return dh;
1374}
1375
1376static DH *ssl_get_dh_4096(void)
1377{
Remi Gacogned3a341a2015-05-29 16:26:17 +02001378 static unsigned char dh4096_p[]={
1379 0xDE,0x16,0x94,0xCD,0x99,0x58,0x07,0xF1,0xF7,0x32,0x96,0x11,
1380 0x04,0x82,0xD4,0x84,0x72,0x80,0x99,0x06,0xCA,0xF0,0xA3,0x68,
1381 0x07,0xCE,0x64,0x50,0xE7,0x74,0x45,0x20,0x80,0x5E,0x4D,0xAD,
1382 0xA5,0xB6,0xED,0xFA,0x80,0x6C,0x3B,0x35,0xC4,0x9A,0x14,0x6B,
1383 0x32,0xBB,0xFD,0x1F,0x17,0x8E,0xB7,0x1F,0xD6,0xFA,0x3F,0x7B,
1384 0xEE,0x16,0xA5,0x62,0x33,0x0D,0xED,0xBC,0x4E,0x58,0xE5,0x47,
1385 0x4D,0xE9,0xAB,0x8E,0x38,0xD3,0x6E,0x90,0x57,0xE3,0x22,0x15,
1386 0x33,0xBD,0xF6,0x43,0x45,0xB5,0x10,0x0A,0xBE,0x2C,0xB4,0x35,
1387 0xB8,0x53,0x8D,0xAD,0xFB,0xA7,0x1F,0x85,0x58,0x41,0x7A,0x79,
1388 0x20,0x68,0xB3,0xE1,0x3D,0x08,0x76,0xBF,0x86,0x0D,0x49,0xE3,
1389 0x82,0x71,0x8C,0xB4,0x8D,0x81,0x84,0xD4,0xE7,0xBE,0x91,0xDC,
1390 0x26,0x39,0x48,0x0F,0x35,0xC4,0xCA,0x65,0xE3,0x40,0x93,0x52,
1391 0x76,0x58,0x7D,0xDD,0x51,0x75,0xDC,0x69,0x61,0xBF,0x47,0x2C,
1392 0x16,0x68,0x2D,0xC9,0x29,0xD3,0xE6,0xC0,0x99,0x48,0xA0,0x9A,
1393 0xC8,0x78,0xC0,0x6D,0x81,0x67,0x12,0x61,0x3F,0x71,0xBA,0x41,
1394 0x1F,0x6C,0x89,0x44,0x03,0xBA,0x3B,0x39,0x60,0xAA,0x28,0x55,
1395 0x59,0xAE,0xB8,0xFA,0xCB,0x6F,0xA5,0x1A,0xF7,0x2B,0xDD,0x52,
1396 0x8A,0x8B,0xE2,0x71,0xA6,0x5E,0x7E,0xD8,0x2E,0x18,0xE0,0x66,
1397 0xDF,0xDD,0x22,0x21,0x99,0x52,0x73,0xA6,0x33,0x20,0x65,0x0E,
1398 0x53,0xE7,0x6B,0x9B,0xC5,0xA3,0x2F,0x97,0x65,0x76,0xD3,0x47,
1399 0x23,0x77,0x12,0xB6,0x11,0x7B,0x24,0xED,0xF1,0xEF,0xC0,0xE2,
1400 0xA3,0x7E,0x67,0x05,0x3E,0x96,0x4D,0x45,0xC2,0x18,0xD1,0x73,
1401 0x9E,0x07,0xF3,0x81,0x6E,0x52,0x63,0xF6,0x20,0x76,0xB9,0x13,
1402 0xD2,0x65,0x30,0x18,0x16,0x09,0x16,0x9E,0x8F,0xF1,0xD2,0x10,
1403 0x5A,0xD3,0xD4,0xAF,0x16,0x61,0xDA,0x55,0x2E,0x18,0x5E,0x14,
1404 0x08,0x54,0x2E,0x2A,0x25,0xA2,0x1A,0x9B,0x8B,0x32,0xA9,0xFD,
1405 0xC2,0x48,0x96,0xE1,0x80,0xCA,0xE9,0x22,0x17,0xBB,0xCE,0x3E,
1406 0x9E,0xED,0xC7,0xF1,0x1F,0xEC,0x17,0x21,0xDC,0x7B,0x82,0x48,
1407 0x8E,0xBB,0x4B,0x9D,0x5B,0x04,0x04,0xDA,0xDB,0x39,0xDF,0x01,
1408 0x40,0xC3,0xAA,0x26,0x23,0x89,0x75,0xC6,0x0B,0xD0,0xA2,0x60,
1409 0x6A,0xF1,0xCC,0x65,0x18,0x98,0x1B,0x52,0xD2,0x74,0x61,0xCC,
1410 0xBD,0x60,0xAE,0xA3,0xA0,0x66,0x6A,0x16,0x34,0x92,0x3F,0x41,
1411 0x40,0x31,0x29,0xC0,0x2C,0x63,0xB2,0x07,0x8D,0xEB,0x94,0xB8,
1412 0xE8,0x47,0x92,0x52,0x93,0x6A,0x1B,0x7E,0x1A,0x61,0xB3,0x1B,
1413 0xF0,0xD6,0x72,0x9B,0xF1,0xB0,0xAF,0xBF,0x3E,0x65,0xEF,0x23,
1414 0x1D,0x6F,0xFF,0x70,0xCD,0x8A,0x4C,0x8A,0xA0,0x72,0x9D,0xBE,
1415 0xD4,0xBB,0x24,0x47,0x4A,0x68,0xB5,0xF5,0xC6,0xD5,0x7A,0xCD,
1416 0xCA,0x06,0x41,0x07,0xAD,0xC2,0x1E,0xE6,0x54,0xA7,0xAD,0x03,
1417 0xD9,0x12,0xC1,0x9C,0x13,0xB1,0xC9,0x0A,0x43,0x8E,0x1E,0x08,
1418 0xCE,0x50,0x82,0x73,0x5F,0xA7,0x55,0x1D,0xD9,0x59,0xAC,0xB5,
1419 0xEA,0x02,0x7F,0x6C,0x5B,0x74,0x96,0x98,0x67,0x24,0xA3,0x0F,
1420 0x15,0xFC,0xA9,0x7D,0x3E,0x67,0xD1,0x70,0xF8,0x97,0xF3,0x67,
1421 0xC5,0x8C,0x88,0x44,0x08,0x02,0xC7,0x2B,
Remi Gacognef46cd6e2014-06-12 14:58:40 +02001422 };
Remi Gacogned3a341a2015-05-29 16:26:17 +02001423 static unsigned char dh4096_g[]={
1424 0x02,
1425 };
Remi Gacognef46cd6e2014-06-12 14:58:40 +02001426
Remi Gacognef46cd6e2014-06-12 14:58:40 +02001427 DH *dh = DH_new();
1428 if (dh) {
Remi Gacogned3a341a2015-05-29 16:26:17 +02001429 dh->p = BN_bin2bn(dh4096_p, sizeof dh4096_p, NULL);
1430 dh->g = BN_bin2bn(dh4096_g, sizeof dh4096_g, NULL);
1431
Remi Gacognef46cd6e2014-06-12 14:58:40 +02001432 if (!dh->p || !dh->g) {
1433 DH_free(dh);
1434 dh = NULL;
1435 }
1436 }
1437 return dh;
1438}
1439
1440/* Returns Diffie-Hellman parameters matching the private key length
1441 but not exceeding global.tune.ssl_default_dh_param */
1442static DH *ssl_get_tmp_dh(SSL *ssl, int export, int keylen)
1443{
1444 DH *dh = NULL;
1445 EVP_PKEY *pkey = SSL_get_privatekey(ssl);
1446 int type = pkey ? EVP_PKEY_type(pkey->type) : EVP_PKEY_NONE;
1447
1448 /* The keylen supplied by OpenSSL can only be 512 or 1024.
1449 See ssl3_send_server_key_exchange() in ssl/s3_srvr.c
1450 */
1451 if (type == EVP_PKEY_RSA || type == EVP_PKEY_DSA) {
1452 keylen = EVP_PKEY_bits(pkey);
1453 }
1454
1455 if (keylen > global.tune.ssl_default_dh_param) {
1456 keylen = global.tune.ssl_default_dh_param;
1457 }
1458
Remi Gacogned3a341a2015-05-29 16:26:17 +02001459 if (keylen >= 4096) {
Remi Gacogne8de54152014-07-15 11:36:40 +02001460 dh = local_dh_4096;
Remi Gacognef46cd6e2014-06-12 14:58:40 +02001461 }
1462 else if (keylen >= 2048) {
Remi Gacogne8de54152014-07-15 11:36:40 +02001463 dh = local_dh_2048;
Remi Gacognef46cd6e2014-06-12 14:58:40 +02001464 }
1465 else {
Remi Gacogne8de54152014-07-15 11:36:40 +02001466 dh = local_dh_1024;
Remi Gacognef46cd6e2014-06-12 14:58:40 +02001467 }
1468
1469 return dh;
1470}
1471
Remi Gacogne47783ef2015-05-29 15:53:22 +02001472static DH * ssl_sock_get_dh_from_file(const char *filename)
Emeric Bruna4bcd9a2012-09-20 16:19:02 +02001473{
Emeric Bruna4bcd9a2012-09-20 16:19:02 +02001474 DH *dh = NULL;
Remi Gacogne47783ef2015-05-29 15:53:22 +02001475 BIO *in = BIO_new(BIO_s_file());
Emeric Bruna4bcd9a2012-09-20 16:19:02 +02001476
Emeric Bruna4bcd9a2012-09-20 16:19:02 +02001477 if (in == NULL)
1478 goto end;
1479
Remi Gacogne47783ef2015-05-29 15:53:22 +02001480 if (BIO_read_filename(in, filename) <= 0)
Emeric Bruna4bcd9a2012-09-20 16:19:02 +02001481 goto end;
1482
Remi Gacogne47783ef2015-05-29 15:53:22 +02001483 dh = PEM_read_bio_DHparams(in, NULL, NULL, NULL);
1484
1485end:
1486 if (in)
1487 BIO_free(in);
1488
1489 return dh;
1490}
1491
1492int ssl_sock_load_global_dh_param_from_file(const char *filename)
1493{
1494 global_dh = ssl_sock_get_dh_from_file(filename);
1495
1496 if (global_dh) {
1497 return 0;
1498 }
1499
1500 return -1;
1501}
1502
1503/* Loads Diffie-Hellman parameter from a file. Returns 1 if loaded, else -1
1504 if an error occured, and 0 if parameter not found. */
1505int ssl_sock_load_dh_params(SSL_CTX *ctx, const char *file)
1506{
1507 int ret = -1;
1508 DH *dh = ssl_sock_get_dh_from_file(file);
1509
Remi Gacognef46cd6e2014-06-12 14:58:40 +02001510 if (dh) {
1511 ret = 1;
1512 SSL_CTX_set_tmp_dh(ctx, dh);
Remi Gacogne4f902b82015-05-28 16:23:00 +02001513
1514 if (ssl_dh_ptr_index >= 0) {
1515 /* store a pointer to the DH params to avoid complaining about
1516 ssl-default-dh-param not being set for this SSL_CTX */
1517 SSL_CTX_set_ex_data(ctx, ssl_dh_ptr_index, dh);
1518 }
Remi Gacognef46cd6e2014-06-12 14:58:40 +02001519 }
Remi Gacogne47783ef2015-05-29 15:53:22 +02001520 else if (global_dh) {
1521 SSL_CTX_set_tmp_dh(ctx, global_dh);
1522 ret = 0; /* DH params not found */
1523 }
Remi Gacognef46cd6e2014-06-12 14:58:40 +02001524 else {
Emeric Brun41fdb3c2013-04-26 11:05:44 +02001525 /* Clear openssl global errors stack */
1526 ERR_clear_error();
1527
Remi Gacognef46cd6e2014-06-12 14:58:40 +02001528 if (global.tune.ssl_default_dh_param <= 1024) {
1529 /* we are limited to DH parameter of 1024 bits anyway */
Remi Gacogne8de54152014-07-15 11:36:40 +02001530 local_dh_1024 = ssl_get_dh_1024();
1531 if (local_dh_1024 == NULL)
Remi Gacognef46cd6e2014-06-12 14:58:40 +02001532 goto end;
Willy Tarreau6e774b42014-04-25 21:35:23 +02001533
Remi Gacogne8de54152014-07-15 11:36:40 +02001534 SSL_CTX_set_tmp_dh(ctx, local_dh_1024);
Remi Gacognef46cd6e2014-06-12 14:58:40 +02001535 }
1536 else {
1537 SSL_CTX_set_tmp_dh_callback(ctx, ssl_get_tmp_dh);
1538 }
Willy Tarreau6e774b42014-04-25 21:35:23 +02001539
Emeric Brun41fdb3c2013-04-26 11:05:44 +02001540 ret = 0; /* DH params not found */
Emeric Bruna4bcd9a2012-09-20 16:19:02 +02001541 }
Emeric Brun644cde02012-12-14 11:21:13 +01001542
Emeric Bruna4bcd9a2012-09-20 16:19:02 +02001543end:
1544 if (dh)
1545 DH_free(dh);
1546
Emeric Bruna4bcd9a2012-09-20 16:19:02 +02001547 return ret;
1548}
1549#endif
1550
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +02001551static int ssl_sock_add_cert_sni(SSL_CTX *ctx, struct bind_conf *s, char *name, int order)
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01001552{
1553 struct sni_ctx *sc;
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +02001554 int wild = 0, neg = 0;
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01001555
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +02001556 if (*name == '!') {
1557 neg = 1;
1558 name++;
1559 }
1560 if (*name == '*') {
1561 wild = 1;
1562 name++;
1563 }
1564 /* !* filter is a nop */
1565 if (neg && wild)
1566 return order;
1567 if (*name) {
1568 int j, len;
1569 len = strlen(name);
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01001570 sc = malloc(sizeof(struct sni_ctx) + len + 1);
1571 for (j = 0; j < len; j++)
1572 sc->name.key[j] = tolower(name[j]);
1573 sc->name.key[len] = 0;
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01001574 sc->ctx = ctx;
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +02001575 sc->order = order++;
1576 sc->neg = neg;
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01001577 if (wild)
1578 ebst_insert(&s->sni_w_ctx, &sc->name);
1579 else
1580 ebst_insert(&s->sni_ctx, &sc->name);
1581 }
1582 return order;
1583}
1584
Emeric Brunfc0421f2012-09-07 17:30:07 +02001585/* Loads a certificate key and CA chain from a file. Returns 0 on error, -1 if
1586 * an early error happens and the caller must call SSL_CTX_free() by itelf.
1587 */
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +02001588static 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 +02001589{
1590 BIO *in;
1591 X509 *x = NULL, *ca;
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +02001592 int i, err;
Emeric Brunfc0421f2012-09-07 17:30:07 +02001593 int ret = -1;
1594 int order = 0;
1595 X509_NAME *xname;
1596 char *str;
Emeric Brunfc0421f2012-09-07 17:30:07 +02001597#ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME
1598 STACK_OF(GENERAL_NAME) *names;
1599#endif
1600
1601 in = BIO_new(BIO_s_file());
1602 if (in == NULL)
1603 goto end;
1604
1605 if (BIO_read_filename(in, file) <= 0)
1606 goto end;
1607
1608 x = PEM_read_bio_X509_AUX(in, NULL, ctx->default_passwd_callback, ctx->default_passwd_callback_userdata);
1609 if (x == NULL)
1610 goto end;
1611
Emeric Brun50bcecc2013-04-22 13:05:23 +02001612 if (fcount) {
1613 while (fcount--)
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +02001614 order = ssl_sock_add_cert_sni(ctx, s, sni_filter[fcount], order);
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01001615 }
1616 else {
Emeric Brunfc0421f2012-09-07 17:30:07 +02001617#ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01001618 names = X509_get_ext_d2i(x, NID_subject_alt_name, NULL, NULL);
1619 if (names) {
1620 for (i = 0; i < sk_GENERAL_NAME_num(names); i++) {
1621 GENERAL_NAME *name = sk_GENERAL_NAME_value(names, i);
1622 if (name->type == GEN_DNS) {
1623 if (ASN1_STRING_to_UTF8((unsigned char **)&str, name->d.dNSName) >= 0) {
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +02001624 order = ssl_sock_add_cert_sni(ctx, s, str, order);
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01001625 OPENSSL_free(str);
Emeric Brunfc0421f2012-09-07 17:30:07 +02001626 }
Emeric Brunfc0421f2012-09-07 17:30:07 +02001627 }
1628 }
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01001629 sk_GENERAL_NAME_pop_free(names, GENERAL_NAME_free);
Emeric Brunfc0421f2012-09-07 17:30:07 +02001630 }
Emeric Brunfc0421f2012-09-07 17:30:07 +02001631#endif /* SSL_CTRL_SET_TLSEXT_HOSTNAME */
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01001632 xname = X509_get_subject_name(x);
1633 i = -1;
1634 while ((i = X509_NAME_get_index_by_NID(xname, NID_commonName, i)) != -1) {
1635 X509_NAME_ENTRY *entry = X509_NAME_get_entry(xname, i);
1636 if (ASN1_STRING_to_UTF8((unsigned char **)&str, entry->value) >= 0) {
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +02001637 order = ssl_sock_add_cert_sni(ctx, s, str, order);
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01001638 OPENSSL_free(str);
Emeric Brunfc0421f2012-09-07 17:30:07 +02001639 }
Emeric Brunfc0421f2012-09-07 17:30:07 +02001640 }
1641 }
1642
1643 ret = 0; /* the caller must not free the SSL_CTX argument anymore */
1644 if (!SSL_CTX_use_certificate(ctx, x))
1645 goto end;
1646
1647 if (ctx->extra_certs != NULL) {
1648 sk_X509_pop_free(ctx->extra_certs, X509_free);
1649 ctx->extra_certs = NULL;
1650 }
1651
1652 while ((ca = PEM_read_bio_X509(in, NULL, ctx->default_passwd_callback, ctx->default_passwd_callback_userdata))) {
1653 if (!SSL_CTX_add_extra_chain_cert(ctx, ca)) {
1654 X509_free(ca);
1655 goto end;
1656 }
1657 }
1658
1659 err = ERR_get_error();
1660 if (!err || (ERR_GET_LIB(err) == ERR_LIB_PEM && ERR_GET_REASON(err) == PEM_R_NO_START_LINE)) {
1661 /* we successfully reached the last cert in the file */
1662 ret = 1;
1663 }
1664 ERR_clear_error();
1665
1666end:
1667 if (x)
1668 X509_free(x);
1669
1670 if (in)
1671 BIO_free(in);
1672
1673 return ret;
1674}
1675
Emeric Brun50bcecc2013-04-22 13:05:23 +02001676static 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 +02001677{
1678 int ret;
1679 SSL_CTX *ctx;
1680
1681 ctx = SSL_CTX_new(SSLv23_server_method());
1682 if (!ctx) {
Willy Tarreaueb6cead2012-09-20 19:43:14 +02001683 memprintf(err, "%sunable to allocate SSL context for cert '%s'.\n",
1684 err && *err ? *err : "", path);
Emeric Brunfc0421f2012-09-07 17:30:07 +02001685 return 1;
1686 }
1687
1688 if (SSL_CTX_use_PrivateKey_file(ctx, path, SSL_FILETYPE_PEM) <= 0) {
Willy Tarreaueb6cead2012-09-20 19:43:14 +02001689 memprintf(err, "%sunable to load SSL private key from PEM file '%s'.\n",
1690 err && *err ? *err : "", path);
Emeric Brunfc0421f2012-09-07 17:30:07 +02001691 SSL_CTX_free(ctx);
1692 return 1;
1693 }
1694
Emeric Brun50bcecc2013-04-22 13:05:23 +02001695 ret = ssl_sock_load_cert_chain_file(ctx, path, bind_conf, sni_filter, fcount);
Emeric Brunfc0421f2012-09-07 17:30:07 +02001696 if (ret <= 0) {
Willy Tarreaueb6cead2012-09-20 19:43:14 +02001697 memprintf(err, "%sunable to load SSL certificate from PEM file '%s'.\n",
1698 err && *err ? *err : "", path);
Emeric Brunfc0421f2012-09-07 17:30:07 +02001699 if (ret < 0) /* serious error, must do that ourselves */
1700 SSL_CTX_free(ctx);
1701 return 1;
1702 }
Emeric Brun61694ab2012-10-26 13:35:33 +02001703
1704 if (SSL_CTX_check_private_key(ctx) <= 0) {
1705 memprintf(err, "%sinconsistencies between private key and certificate loaded from PEM file '%s'.\n",
1706 err && *err ? *err : "", path);
1707 return 1;
1708 }
1709
Emeric Brunfc0421f2012-09-07 17:30:07 +02001710 /* we must not free the SSL_CTX anymore below, since it's already in
1711 * the tree, so it will be discovered and cleaned in time.
1712 */
Emeric Bruna4bcd9a2012-09-20 16:19:02 +02001713#ifndef OPENSSL_NO_DH
Remi Gacogne4f902b82015-05-28 16:23:00 +02001714 /* store a NULL pointer to indicate we have not yet loaded
1715 a custom DH param file */
1716 if (ssl_dh_ptr_index >= 0) {
1717 SSL_CTX_set_ex_data(ctx, ssl_dh_ptr_index, NULL);
1718 }
1719
Emeric Bruna4bcd9a2012-09-20 16:19:02 +02001720 ret = ssl_sock_load_dh_params(ctx, path);
1721 if (ret < 0) {
1722 if (err)
1723 memprintf(err, "%sunable to load DH parameters from file '%s'.\n",
1724 *err ? *err : "", path);
1725 return 1;
1726 }
1727#endif
1728
Lukas Tribuse4e30f72014-12-09 16:32:51 +01001729#if (defined SSL_CTRL_SET_TLSEXT_STATUS_REQ_CB && !defined OPENSSL_NO_OCSP)
Emeric Brun4147b2e2014-06-16 18:36:30 +02001730 ret = ssl_sock_load_ocsp(ctx, path);
1731 if (ret < 0) {
1732 if (err)
1733 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",
1734 *err ? *err : "", path);
1735 return 1;
1736 }
1737#endif
1738
Daniel Jakots54ffb912015-11-06 20:02:41 +01001739#if (OPENSSL_VERSION_NUMBER >= 0x1000200fL && !defined OPENSSL_NO_TLSEXT && !defined OPENSSL_IS_BORINGSSL && !defined LIBRESSL_VERSION_NUMBER)
Janusz Dziemidowicz2c701b52015-03-07 23:03:59 +01001740 if (sctl_ex_index >= 0) {
1741 ret = ssl_sock_load_sctl(ctx, path);
1742 if (ret < 0) {
1743 if (err)
1744 memprintf(err, "%s '%s.sctl' is present but cannot be read or parsed'.\n",
1745 *err ? *err : "", path);
1746 return 1;
1747 }
1748 }
1749#endif
1750
Emeric Brunfc0421f2012-09-07 17:30:07 +02001751#ifndef SSL_CTRL_SET_TLSEXT_HOSTNAME
Willy Tarreau2a65ff02012-09-13 17:54:29 +02001752 if (bind_conf->default_ctx) {
Willy Tarreaueb6cead2012-09-20 19:43:14 +02001753 memprintf(err, "%sthis version of openssl cannot load multiple SSL certificates.\n",
1754 err && *err ? *err : "");
Emeric Brunfc0421f2012-09-07 17:30:07 +02001755 return 1;
1756 }
1757#endif
Willy Tarreau2a65ff02012-09-13 17:54:29 +02001758 if (!bind_conf->default_ctx)
1759 bind_conf->default_ctx = ctx;
Emeric Brunfc0421f2012-09-07 17:30:07 +02001760
1761 return 0;
1762}
1763
Willy Tarreau79eeafa2012-09-14 07:53:05 +02001764int ssl_sock_load_cert(char *path, struct bind_conf *bind_conf, struct proxy *curproxy, char **err)
Emeric Brunfc0421f2012-09-07 17:30:07 +02001765{
Cyril Bonté3180f7b2015-01-25 00:16:08 +01001766 struct dirent **de_list;
1767 int i, n;
Emeric Brunfc0421f2012-09-07 17:30:07 +02001768 DIR *dir;
1769 struct stat buf;
Willy Tarreauee2663b2012-12-06 11:36:59 +01001770 char *end;
1771 char fp[MAXPATHLEN+1];
Emeric Brunfc0421f2012-09-07 17:30:07 +02001772 int cfgerr = 0;
1773
1774 if (!(dir = opendir(path)))
Emeric Brun50bcecc2013-04-22 13:05:23 +02001775 return ssl_sock_load_cert_file(path, bind_conf, curproxy, NULL, 0, err);
Emeric Brunfc0421f2012-09-07 17:30:07 +02001776
1777 /* strip trailing slashes, including first one */
1778 for (end = path + strlen(path) - 1; end >= path && *end == '/'; end--)
1779 *end = 0;
1780
Cyril Bonté3180f7b2015-01-25 00:16:08 +01001781 n = scandir(path, &de_list, 0, alphasort);
1782 if (n < 0) {
1783 memprintf(err, "%sunable to scan directory '%s' : %s.\n",
1784 err && *err ? *err : "", path, strerror(errno));
1785 cfgerr++;
1786 }
1787 else {
1788 for (i = 0; i < n; i++) {
1789 struct dirent *de = de_list[i];
Emeric Brun2aab7222014-06-18 18:15:09 +02001790
Cyril Bonté3180f7b2015-01-25 00:16:08 +01001791 end = strrchr(de->d_name, '.');
Janusz Dziemidowicz2c701b52015-03-07 23:03:59 +01001792 if (end && (!strcmp(end, ".issuer") || !strcmp(end, ".ocsp") || !strcmp(end, ".sctl")))
Cyril Bonté3180f7b2015-01-25 00:16:08 +01001793 goto ignore_entry;
1794
1795 snprintf(fp, sizeof(fp), "%s/%s", path, de->d_name);
1796 if (stat(fp, &buf) != 0) {
1797 memprintf(err, "%sunable to stat SSL certificate from file '%s' : %s.\n",
1798 err && *err ? *err : "", fp, strerror(errno));
1799 cfgerr++;
1800 goto ignore_entry;
1801 }
1802 if (!S_ISREG(buf.st_mode))
1803 goto ignore_entry;
1804 cfgerr += ssl_sock_load_cert_file(fp, bind_conf, curproxy, NULL, 0, err);
1805 ignore_entry:
1806 free(de);
Emeric Brunfc0421f2012-09-07 17:30:07 +02001807 }
Cyril Bonté3180f7b2015-01-25 00:16:08 +01001808 free(de_list);
Emeric Brunfc0421f2012-09-07 17:30:07 +02001809 }
Emeric Brunfc0421f2012-09-07 17:30:07 +02001810 closedir(dir);
1811 return cfgerr;
1812}
1813
Thierry Fournier383085f2013-01-24 14:15:43 +01001814/* Make sure openssl opens /dev/urandom before the chroot. The work is only
1815 * done once. Zero is returned if the operation fails. No error is returned
1816 * if the random is said as not implemented, because we expect that openssl
1817 * will use another method once needed.
1818 */
1819static int ssl_initialize_random()
1820{
1821 unsigned char random;
1822 static int random_initialized = 0;
1823
1824 if (!random_initialized && RAND_bytes(&random, 1) != 0)
1825 random_initialized = 1;
1826
1827 return random_initialized;
1828}
1829
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01001830int ssl_sock_load_cert_list_file(char *file, struct bind_conf *bind_conf, struct proxy *curproxy, char **err)
1831{
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +02001832 char thisline[LINESIZE];
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01001833 FILE *f;
1834 int linenum = 0;
1835 int cfgerr = 0;
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01001836
Willy Tarreauad1731d2013-04-02 17:35:58 +02001837 if ((f = fopen(file, "r")) == NULL) {
1838 memprintf(err, "cannot open file '%s' : %s", file, strerror(errno));
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01001839 return 1;
Willy Tarreauad1731d2013-04-02 17:35:58 +02001840 }
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01001841
1842 while (fgets(thisline, sizeof(thisline), f) != NULL) {
1843 int arg;
Emeric Brun50bcecc2013-04-22 13:05:23 +02001844 int newarg;
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01001845 char *end;
1846 char *args[MAX_LINE_ARGS + 1];
1847 char *line = thisline;
1848
1849 linenum++;
1850 end = line + strlen(line);
1851 if (end-line == sizeof(thisline)-1 && *(end-1) != '\n') {
1852 /* Check if we reached the limit and the last char is not \n.
1853 * Watch out for the last line without the terminating '\n'!
1854 */
Willy Tarreauad1731d2013-04-02 17:35:58 +02001855 memprintf(err, "line %d too long in file '%s', limit is %d characters",
1856 linenum, file, (int)sizeof(thisline)-1);
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01001857 cfgerr = 1;
Willy Tarreauad1731d2013-04-02 17:35:58 +02001858 break;
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01001859 }
1860
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01001861 arg = 0;
Emeric Brun50bcecc2013-04-22 13:05:23 +02001862 newarg = 1;
1863 while (*line) {
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01001864 if (*line == '#' || *line == '\n' || *line == '\r') {
1865 /* end of string, end of loop */
1866 *line = 0;
1867 break;
1868 }
1869 else if (isspace(*line)) {
Emeric Brun50bcecc2013-04-22 13:05:23 +02001870 newarg = 1;
1871 *line = 0;
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01001872 }
Emeric Brun50bcecc2013-04-22 13:05:23 +02001873 else if (newarg) {
1874 if (arg == MAX_LINE_ARGS) {
1875 memprintf(err, "too many args on line %d in file '%s'.",
1876 linenum, file);
1877 cfgerr = 1;
1878 break;
1879 }
1880 newarg = 0;
1881 args[arg++] = line;
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01001882 }
Emeric Brun50bcecc2013-04-22 13:05:23 +02001883 line++;
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01001884 }
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +02001885 if (cfgerr)
1886 break;
Willy Tarreauad1731d2013-04-02 17:35:58 +02001887
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01001888 /* empty line */
Emeric Brun50bcecc2013-04-22 13:05:23 +02001889 if (!arg)
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01001890 continue;
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01001891
Emeric Brun50bcecc2013-04-22 13:05:23 +02001892 cfgerr = ssl_sock_load_cert_file(args[0], bind_conf, curproxy, &args[1], arg-1, err);
Willy Tarreauad1731d2013-04-02 17:35:58 +02001893 if (cfgerr) {
1894 memprintf(err, "error processing line %d in file '%s' : %s", linenum, file, *err);
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01001895 break;
Willy Tarreauad1731d2013-04-02 17:35:58 +02001896 }
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01001897 }
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01001898 fclose(f);
1899 return cfgerr;
1900}
1901
Emeric Brunfc0421f2012-09-07 17:30:07 +02001902#ifndef SSL_OP_CIPHER_SERVER_PREFERENCE /* needs OpenSSL >= 0.9.7 */
1903#define SSL_OP_CIPHER_SERVER_PREFERENCE 0
1904#endif
1905
1906#ifndef SSL_OP_NO_SESSION_RESUMPTION_ON_RENEGOTIATION /* needs OpenSSL >= 0.9.7 */
1907#define SSL_OP_NO_SESSION_RESUMPTION_ON_RENEGOTIATION 0
Willy Tarreau7d588ee2012-11-26 18:47:31 +01001908#define SSL_renegotiate_pending(arg) 0
Emeric Brunfc0421f2012-09-07 17:30:07 +02001909#endif
Emeric Brun2b58d042012-09-20 17:10:03 +02001910#ifndef SSL_OP_SINGLE_ECDH_USE /* needs OpenSSL >= 0.9.8 */
1911#define SSL_OP_SINGLE_ECDH_USE 0
1912#endif
Emeric Brun2d0c4822012-10-02 13:45:20 +02001913#ifndef SSL_OP_NO_TICKET /* needs OpenSSL >= 0.9.8 */
1914#define SSL_OP_NO_TICKET 0
1915#endif
Emeric Brunfc0421f2012-09-07 17:30:07 +02001916#ifndef SSL_OP_NO_COMPRESSION /* needs OpenSSL >= 0.9.9 */
1917#define SSL_OP_NO_COMPRESSION 0
1918#endif
Emeric Brunc0ff4922012-09-28 19:37:02 +02001919#ifndef SSL_OP_NO_TLSv1_1 /* needs OpenSSL >= 1.0.1 */
1920#define SSL_OP_NO_TLSv1_1 0
1921#endif
1922#ifndef SSL_OP_NO_TLSv1_2 /* needs OpenSSL >= 1.0.1 */
1923#define SSL_OP_NO_TLSv1_2 0
1924#endif
Emeric Bruna4bcd9a2012-09-20 16:19:02 +02001925#ifndef SSL_OP_SINGLE_DH_USE /* needs OpenSSL >= 0.9.6 */
1926#define SSL_OP_SINGLE_DH_USE 0
1927#endif
Emeric Brun2b58d042012-09-20 17:10:03 +02001928#ifndef SSL_OP_SINGLE_ECDH_USE /* needs OpenSSL >= 1.0.0 */
1929#define SSL_OP_SINGLE_ECDH_USE 0
1930#endif
Emeric Brunfc0421f2012-09-07 17:30:07 +02001931#ifndef SSL_MODE_RELEASE_BUFFERS /* needs OpenSSL >= 1.0.0 */
1932#define SSL_MODE_RELEASE_BUFFERS 0
1933#endif
Willy Tarreau396a1862014-11-13 14:06:52 +01001934#ifndef SSL_MODE_SMALL_BUFFERS /* needs small_records.patch */
1935#define SSL_MODE_SMALL_BUFFERS 0
1936#endif
Remi Gacognef46cd6e2014-06-12 14:58:40 +02001937
Willy Tarreau2a65ff02012-09-13 17:54:29 +02001938int ssl_sock_prepare_ctx(struct bind_conf *bind_conf, SSL_CTX *ctx, struct proxy *curproxy)
Emeric Brunfc0421f2012-09-07 17:30:07 +02001939{
1940 int cfgerr = 0;
Emeric Brun850efd52014-01-29 12:24:34 +01001941 int verify = SSL_VERIFY_NONE;
Remi Gacogneaf5c3da2014-05-19 10:29:58 +02001942 long ssloptions =
Emeric Brunfc0421f2012-09-07 17:30:07 +02001943 SSL_OP_ALL | /* all known workarounds for bugs */
1944 SSL_OP_NO_SSLv2 |
1945 SSL_OP_NO_COMPRESSION |
Emeric Bruna4bcd9a2012-09-20 16:19:02 +02001946 SSL_OP_SINGLE_DH_USE |
Emeric Brun2b58d042012-09-20 17:10:03 +02001947 SSL_OP_SINGLE_ECDH_USE |
Emeric Brun3c4bc6e2012-10-04 18:44:19 +02001948 SSL_OP_NO_SESSION_RESUMPTION_ON_RENEGOTIATION |
1949 SSL_OP_CIPHER_SERVER_PREFERENCE;
Remi Gacogneaf5c3da2014-05-19 10:29:58 +02001950 long sslmode =
Emeric Brunfc0421f2012-09-07 17:30:07 +02001951 SSL_MODE_ENABLE_PARTIAL_WRITE |
1952 SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER |
Willy Tarreau396a1862014-11-13 14:06:52 +01001953 SSL_MODE_RELEASE_BUFFERS |
1954 SSL_MODE_SMALL_BUFFERS;
Remi Gacognef46cd6e2014-06-12 14:58:40 +02001955 STACK_OF(SSL_CIPHER) * ciphers = NULL;
Willy Tarreaua616ba62014-10-26 06:49:19 +01001956 SSL_CIPHER * cipher = NULL;
Remi Gacognec1eab8c2014-06-12 18:20:11 +02001957 char cipher_description[128];
1958 /* The description of ciphers using an Ephemeral Diffie Hellman key exchange
1959 contains " Kx=DH " or " Kx=DH(". Beware of " Kx=DH/",
1960 which is not ephemeral DH. */
1961 const char dhe_description[] = " Kx=DH ";
1962 const char dhe_export_description[] = " Kx=DH(";
Remi Gacognef46cd6e2014-06-12 14:58:40 +02001963 int idx = 0;
1964 int dhe_found = 0;
Remi Gacogne23d5d372014-10-10 17:04:26 +02001965 SSL *ssl = NULL;
Emeric Brunfc0421f2012-09-07 17:30:07 +02001966
Thierry Fournier383085f2013-01-24 14:15:43 +01001967 /* Make sure openssl opens /dev/urandom before the chroot */
1968 if (!ssl_initialize_random()) {
1969 Alert("OpenSSL random data generator initialization failed.\n");
1970 cfgerr++;
1971 }
1972
Emeric Brun89675492012-10-05 13:48:26 +02001973 if (bind_conf->ssl_options & BC_SSL_O_NO_SSLV3)
Emeric Brunfc0421f2012-09-07 17:30:07 +02001974 ssloptions |= SSL_OP_NO_SSLv3;
Emeric Brun89675492012-10-05 13:48:26 +02001975 if (bind_conf->ssl_options & BC_SSL_O_NO_TLSV10)
Emeric Brunfc0421f2012-09-07 17:30:07 +02001976 ssloptions |= SSL_OP_NO_TLSv1;
Emeric Brun89675492012-10-05 13:48:26 +02001977 if (bind_conf->ssl_options & BC_SSL_O_NO_TLSV11)
Emeric Brunc0ff4922012-09-28 19:37:02 +02001978 ssloptions |= SSL_OP_NO_TLSv1_1;
Emeric Brun89675492012-10-05 13:48:26 +02001979 if (bind_conf->ssl_options & BC_SSL_O_NO_TLSV12)
Emeric Brunc0ff4922012-09-28 19:37:02 +02001980 ssloptions |= SSL_OP_NO_TLSv1_2;
Emeric Brun89675492012-10-05 13:48:26 +02001981 if (bind_conf->ssl_options & BC_SSL_O_NO_TLS_TICKETS)
Emeric Brun2d0c4822012-10-02 13:45:20 +02001982 ssloptions |= SSL_OP_NO_TICKET;
Jérémie Courrèges-Anglas17c3f622015-07-25 16:50:52 -06001983 if (bind_conf->ssl_options & BC_SSL_O_USE_SSLV3) {
1984#ifndef OPENSSL_NO_SSL3
Emeric Brun2cb7ae52012-10-05 14:14:21 +02001985 SSL_CTX_set_ssl_version(ctx, SSLv3_server_method());
Jérémie Courrèges-Anglas17c3f622015-07-25 16:50:52 -06001986#else
1987 Alert("SSLv3 support requested but unavailable.\n");
1988 cfgerr++;
1989#endif
1990 }
Emeric Brun2cb7ae52012-10-05 14:14:21 +02001991 if (bind_conf->ssl_options & BC_SSL_O_USE_TLSV10)
1992 SSL_CTX_set_ssl_version(ctx, TLSv1_server_method());
1993#if SSL_OP_NO_TLSv1_1
1994 if (bind_conf->ssl_options & BC_SSL_O_USE_TLSV11)
1995 SSL_CTX_set_ssl_version(ctx, TLSv1_1_server_method());
1996#endif
1997#if SSL_OP_NO_TLSv1_2
1998 if (bind_conf->ssl_options & BC_SSL_O_USE_TLSV12)
1999 SSL_CTX_set_ssl_version(ctx, TLSv1_2_server_method());
2000#endif
Emeric Brunfc0421f2012-09-07 17:30:07 +02002001
2002 SSL_CTX_set_options(ctx, ssloptions);
2003 SSL_CTX_set_mode(ctx, sslmode);
Emeric Brun850efd52014-01-29 12:24:34 +01002004 switch (bind_conf->verify) {
2005 case SSL_SOCK_VERIFY_NONE:
2006 verify = SSL_VERIFY_NONE;
2007 break;
2008 case SSL_SOCK_VERIFY_OPTIONAL:
2009 verify = SSL_VERIFY_PEER;
2010 break;
2011 case SSL_SOCK_VERIFY_REQUIRED:
2012 verify = SSL_VERIFY_PEER|SSL_VERIFY_FAIL_IF_NO_PEER_CERT;
2013 break;
2014 }
2015 SSL_CTX_set_verify(ctx, verify, ssl_sock_bind_verifycbk);
2016 if (verify & SSL_VERIFY_PEER) {
Emeric Brunfb510ea2012-10-05 12:00:26 +02002017 if (bind_conf->ca_file) {
Emeric Brund94b3fe2012-09-20 18:23:56 +02002018 /* load CAfile to verify */
Emeric Brunfb510ea2012-10-05 12:00:26 +02002019 if (!SSL_CTX_load_verify_locations(ctx, bind_conf->ca_file, NULL)) {
Emeric Brund94b3fe2012-09-20 18:23:56 +02002020 Alert("Proxy '%s': unable to load CA file '%s' for bind '%s' at [%s:%d].\n",
Emeric Brunfb510ea2012-10-05 12:00:26 +02002021 curproxy->id, bind_conf->ca_file, bind_conf->arg, bind_conf->file, bind_conf->line);
Emeric Brund94b3fe2012-09-20 18:23:56 +02002022 cfgerr++;
2023 }
2024 /* set CA names fo client cert request, function returns void */
Emeric Brunfb510ea2012-10-05 12:00:26 +02002025 SSL_CTX_set_client_CA_list(ctx, SSL_load_client_CA_file(bind_conf->ca_file));
Emeric Brund94b3fe2012-09-20 18:23:56 +02002026 }
Emeric Brun850efd52014-01-29 12:24:34 +01002027 else {
2028 Alert("Proxy '%s': verify is enabled but no CA file specified for bind '%s' at [%s:%d].\n",
2029 curproxy->id, bind_conf->arg, bind_conf->file, bind_conf->line);
2030 cfgerr++;
2031 }
Emeric Brun051cdab2012-10-02 19:25:50 +02002032#ifdef X509_V_FLAG_CRL_CHECK
Emeric Brunfb510ea2012-10-05 12:00:26 +02002033 if (bind_conf->crl_file) {
Emeric Brund94b3fe2012-09-20 18:23:56 +02002034 X509_STORE *store = SSL_CTX_get_cert_store(ctx);
2035
Emeric Brunfb510ea2012-10-05 12:00:26 +02002036 if (!store || !X509_STORE_load_locations(store, bind_conf->crl_file, NULL)) {
Emeric Brund94b3fe2012-09-20 18:23:56 +02002037 Alert("Proxy '%s': unable to configure CRL file '%s' for bind '%s' at [%s:%d].\n",
Alexander Rigbofc65af02015-04-07 14:02:16 +02002038 curproxy->id, bind_conf->crl_file, bind_conf->arg, bind_conf->file, bind_conf->line);
Emeric Brund94b3fe2012-09-20 18:23:56 +02002039 cfgerr++;
2040 }
Emeric Brun561e5742012-10-02 15:20:55 +02002041 else {
2042 X509_STORE_set_flags(store, X509_V_FLAG_CRL_CHECK|X509_V_FLAG_CRL_CHECK_ALL);
2043 }
Emeric Brund94b3fe2012-09-20 18:23:56 +02002044 }
Emeric Brun051cdab2012-10-02 19:25:50 +02002045#endif
Emeric Brun644cde02012-12-14 11:21:13 +01002046 ERR_clear_error();
Emeric Brund94b3fe2012-09-20 18:23:56 +02002047 }
Emeric Brunfc0421f2012-09-07 17:30:07 +02002048
Nenad Merdanovic05552d42015-02-27 19:56:49 +01002049#if (defined SSL_CTRL_SET_TLSEXT_TICKET_KEY_CB && TLS_TICKETS_NO > 0)
Nenad Merdanovic146defa2015-05-09 08:46:00 +02002050 if(bind_conf->keys_ref) {
Nenad Merdanovic05552d42015-02-27 19:56:49 +01002051 if (!SSL_CTX_set_tlsext_ticket_key_cb(ctx, ssl_tlsext_ticket_key_cb)) {
2052 Alert("Proxy '%s': unable to set callback for TLS ticket validation for bind '%s' at [%s:%d].\n",
2053 curproxy->id, bind_conf->arg, bind_conf->file, bind_conf->line);
2054 cfgerr++;
2055 }
2056 }
2057#endif
2058
Emeric Brun4f65bff2012-11-16 15:11:00 +01002059 if (global.tune.ssllifetime)
2060 SSL_CTX_set_timeout(ctx, global.tune.ssllifetime);
2061
Emeric Brunfc0421f2012-09-07 17:30:07 +02002062 shared_context_set_cache(ctx);
Willy Tarreau2a65ff02012-09-13 17:54:29 +02002063 if (bind_conf->ciphers &&
2064 !SSL_CTX_set_cipher_list(ctx, bind_conf->ciphers)) {
Emeric Brunfc0421f2012-09-07 17:30:07 +02002065 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 +02002066 curproxy->id, bind_conf->ciphers, bind_conf->arg, bind_conf->file, bind_conf->line);
Emeric Brunfc0421f2012-09-07 17:30:07 +02002067 cfgerr++;
2068 }
2069
Remi Gacogne47783ef2015-05-29 15:53:22 +02002070 /* If tune.ssl.default-dh-param has not been set,
2071 neither has ssl-default-dh-file and no static DH
2072 params were in the certificate file. */
Remi Gacogne4f902b82015-05-28 16:23:00 +02002073 if (global.tune.ssl_default_dh_param == 0 &&
Remi Gacogne47783ef2015-05-29 15:53:22 +02002074 global_dh == NULL &&
Remi Gacogne4f902b82015-05-28 16:23:00 +02002075 (ssl_dh_ptr_index == -1 ||
2076 SSL_CTX_get_ex_data(ctx, ssl_dh_ptr_index) == NULL)) {
Lukas Tribus90132722014-08-18 00:56:33 +02002077
Remi Gacogne23d5d372014-10-10 17:04:26 +02002078 ssl = SSL_new(ctx);
Remi Gacognef46cd6e2014-06-12 14:58:40 +02002079
Remi Gacogne23d5d372014-10-10 17:04:26 +02002080 if (ssl) {
2081 ciphers = SSL_get_ciphers(ssl);
2082
2083 if (ciphers) {
2084 for (idx = 0; idx < sk_SSL_CIPHER_num(ciphers); idx++) {
2085 cipher = sk_SSL_CIPHER_value(ciphers, idx);
2086 if (SSL_CIPHER_description(cipher, cipher_description, sizeof (cipher_description)) == cipher_description) {
2087 if (strstr(cipher_description, dhe_description) != NULL ||
2088 strstr(cipher_description, dhe_export_description) != NULL) {
2089 dhe_found = 1;
2090 break;
2091 }
Remi Gacognec1eab8c2014-06-12 18:20:11 +02002092 }
Remi Gacognef46cd6e2014-06-12 14:58:40 +02002093 }
2094 }
Remi Gacogne23d5d372014-10-10 17:04:26 +02002095 SSL_free(ssl);
2096 ssl = NULL;
Lukas Tribus90132722014-08-18 00:56:33 +02002097 }
Remi Gacognef46cd6e2014-06-12 14:58:40 +02002098
Lukas Tribus90132722014-08-18 00:56:33 +02002099 if (dhe_found) {
2100 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 +02002101 }
2102
2103 global.tune.ssl_default_dh_param = 1024;
2104 }
Remi Gacogne8de54152014-07-15 11:36:40 +02002105
2106#ifndef OPENSSL_NO_DH
2107 if (global.tune.ssl_default_dh_param >= 1024) {
2108 if (local_dh_1024 == NULL) {
2109 local_dh_1024 = ssl_get_dh_1024();
2110 }
2111 if (global.tune.ssl_default_dh_param >= 2048) {
2112 if (local_dh_2048 == NULL) {
2113 local_dh_2048 = ssl_get_dh_2048();
2114 }
2115 if (global.tune.ssl_default_dh_param >= 4096) {
2116 if (local_dh_4096 == NULL) {
2117 local_dh_4096 = ssl_get_dh_4096();
2118 }
Remi Gacogne8de54152014-07-15 11:36:40 +02002119 }
2120 }
2121 }
2122#endif /* OPENSSL_NO_DH */
Remi Gacognef46cd6e2014-06-12 14:58:40 +02002123
Emeric Brunfc0421f2012-09-07 17:30:07 +02002124 SSL_CTX_set_info_callback(ctx, ssl_sock_infocbk);
Willy Tarreau5cbe4ef2014-05-08 22:45:11 +02002125#if OPENSSL_VERSION_NUMBER >= 0x00907000L
Emeric Brun29f037d2014-04-25 19:05:36 +02002126 SSL_CTX_set_msg_callback(ctx, ssl_sock_msgcbk);
Willy Tarreau5cbe4ef2014-05-08 22:45:11 +02002127#endif
Emeric Brun29f037d2014-04-25 19:05:36 +02002128
Willy Tarreau6c9a3d52012-10-18 18:57:14 +02002129#ifdef OPENSSL_NPN_NEGOTIATED
2130 if (bind_conf->npn_str)
2131 SSL_CTX_set_next_protos_advertised_cb(ctx, ssl_sock_advertise_npn_protos, bind_conf);
2132#endif
Dirkjan Bussink48f1c4e2014-02-13 12:29:42 +01002133#ifdef TLSEXT_TYPE_application_layer_protocol_negotiation
Willy Tarreauab861d32013-04-02 02:30:41 +02002134 if (bind_conf->alpn_str)
Dirkjan Bussink48f1c4e2014-02-13 12:29:42 +01002135 SSL_CTX_set_alpn_select_cb(ctx, ssl_sock_advertise_alpn_protos, bind_conf);
Willy Tarreauab861d32013-04-02 02:30:41 +02002136#endif
Willy Tarreau6c9a3d52012-10-18 18:57:14 +02002137
Emeric Brunfc0421f2012-09-07 17:30:07 +02002138#ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME
2139 SSL_CTX_set_tlsext_servername_callback(ctx, ssl_sock_switchctx_cbk);
Willy Tarreau2a65ff02012-09-13 17:54:29 +02002140 SSL_CTX_set_tlsext_servername_arg(ctx, bind_conf);
Emeric Brunfc0421f2012-09-07 17:30:07 +02002141#endif
Emeric Brun2b58d042012-09-20 17:10:03 +02002142#if defined(SSL_CTX_set_tmp_ecdh) && !defined(OPENSSL_NO_ECDH)
Emeric Brun6924ef82013-03-06 14:08:53 +01002143 {
Emeric Brun2b58d042012-09-20 17:10:03 +02002144 int i;
2145 EC_KEY *ecdh;
2146
Emeric Brun6924ef82013-03-06 14:08:53 +01002147 i = OBJ_sn2nid(bind_conf->ecdhe ? bind_conf->ecdhe : ECDHE_DEFAULT_CURVE);
Emeric Brun2b58d042012-09-20 17:10:03 +02002148 if (!i || ((ecdh = EC_KEY_new_by_curve_name(i)) == NULL)) {
2149 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 +01002150 curproxy->id, bind_conf->ecdhe ? bind_conf->ecdhe : ECDHE_DEFAULT_CURVE,
2151 bind_conf->arg, bind_conf->file, bind_conf->line);
Emeric Brun2b58d042012-09-20 17:10:03 +02002152 cfgerr++;
2153 }
2154 else {
2155 SSL_CTX_set_tmp_ecdh(ctx, ecdh);
2156 EC_KEY_free(ecdh);
2157 }
2158 }
2159#endif
2160
Emeric Brunfc0421f2012-09-07 17:30:07 +02002161 return cfgerr;
2162}
2163
Evan Broderbe554312013-06-27 00:05:25 -07002164static int ssl_sock_srv_hostcheck(const char *pattern, const char *hostname)
2165{
2166 const char *pattern_wildcard, *pattern_left_label_end, *hostname_left_label_end;
2167 size_t prefixlen, suffixlen;
2168
2169 /* Trivial case */
2170 if (strcmp(pattern, hostname) == 0)
2171 return 1;
2172
Evan Broderbe554312013-06-27 00:05:25 -07002173 /* The rest of this logic is based on RFC 6125, section 6.4.3
2174 * (http://tools.ietf.org/html/rfc6125#section-6.4.3) */
2175
Emeric Bruna848dae2013-10-08 11:27:28 +02002176 pattern_wildcard = NULL;
2177 pattern_left_label_end = pattern;
2178 while (*pattern_left_label_end != '.') {
2179 switch (*pattern_left_label_end) {
2180 case 0:
2181 /* End of label not found */
2182 return 0;
2183 case '*':
2184 /* If there is more than one wildcards */
2185 if (pattern_wildcard)
2186 return 0;
2187 pattern_wildcard = pattern_left_label_end;
2188 break;
2189 }
2190 pattern_left_label_end++;
2191 }
2192
2193 /* If it's not trivial and there is no wildcard, it can't
2194 * match */
2195 if (!pattern_wildcard)
Evan Broderbe554312013-06-27 00:05:25 -07002196 return 0;
2197
2198 /* Make sure all labels match except the leftmost */
2199 hostname_left_label_end = strchr(hostname, '.');
2200 if (!hostname_left_label_end
2201 || strcmp(pattern_left_label_end, hostname_left_label_end) != 0)
2202 return 0;
2203
2204 /* Make sure the leftmost label of the hostname is long enough
2205 * that the wildcard can match */
Emeric Brun369da852013-10-08 11:39:35 +02002206 if (hostname_left_label_end - hostname < (pattern_left_label_end - pattern) - 1)
Evan Broderbe554312013-06-27 00:05:25 -07002207 return 0;
2208
2209 /* Finally compare the string on either side of the
2210 * wildcard */
2211 prefixlen = pattern_wildcard - pattern;
2212 suffixlen = pattern_left_label_end - (pattern_wildcard + 1);
Emeric Bruna848dae2013-10-08 11:27:28 +02002213 if ((prefixlen && (memcmp(pattern, hostname, prefixlen) != 0))
2214 || (suffixlen && (memcmp(pattern_wildcard + 1, hostname_left_label_end - suffixlen, suffixlen) != 0)))
Evan Broderbe554312013-06-27 00:05:25 -07002215 return 0;
2216
2217 return 1;
2218}
2219
2220static int ssl_sock_srv_verifycbk(int ok, X509_STORE_CTX *ctx)
2221{
2222 SSL *ssl;
2223 struct connection *conn;
2224 char *servername;
2225
2226 int depth;
2227 X509 *cert;
2228 STACK_OF(GENERAL_NAME) *alt_names;
2229 int i;
2230 X509_NAME *cert_subject;
2231 char *str;
2232
2233 if (ok == 0)
2234 return ok;
2235
2236 ssl = X509_STORE_CTX_get_ex_data(ctx, SSL_get_ex_data_X509_STORE_CTX_idx());
2237 conn = (struct connection *)SSL_get_app_data(ssl);
2238
2239 servername = objt_server(conn->target)->ssl_ctx.verify_host;
2240
2241 /* We only need to verify the CN on the actual server cert,
2242 * not the indirect CAs */
2243 depth = X509_STORE_CTX_get_error_depth(ctx);
2244 if (depth != 0)
2245 return ok;
2246
2247 /* At this point, the cert is *not* OK unless we can find a
2248 * hostname match */
2249 ok = 0;
2250
2251 cert = X509_STORE_CTX_get_current_cert(ctx);
2252 /* It seems like this might happen if verify peer isn't set */
2253 if (!cert)
2254 return ok;
2255
2256 alt_names = X509_get_ext_d2i(cert, NID_subject_alt_name, NULL, NULL);
2257 if (alt_names) {
2258 for (i = 0; !ok && i < sk_GENERAL_NAME_num(alt_names); i++) {
2259 GENERAL_NAME *name = sk_GENERAL_NAME_value(alt_names, i);
2260 if (name->type == GEN_DNS) {
Emeric Bruna33410c2013-09-17 15:47:48 +02002261#if OPENSSL_VERSION_NUMBER < 0x00907000L
2262 if (ASN1_STRING_to_UTF8((unsigned char **)&str, name->d.ia5) >= 0) {
2263#else
Evan Broderbe554312013-06-27 00:05:25 -07002264 if (ASN1_STRING_to_UTF8((unsigned char **)&str, name->d.dNSName) >= 0) {
Emeric Bruna33410c2013-09-17 15:47:48 +02002265#endif
Evan Broderbe554312013-06-27 00:05:25 -07002266 ok = ssl_sock_srv_hostcheck(str, servername);
2267 OPENSSL_free(str);
2268 }
2269 }
2270 }
Emeric Brun4ad50a42013-09-17 15:19:54 +02002271 sk_GENERAL_NAME_pop_free(alt_names, GENERAL_NAME_free);
Evan Broderbe554312013-06-27 00:05:25 -07002272 }
2273
2274 cert_subject = X509_get_subject_name(cert);
2275 i = -1;
2276 while (!ok && (i = X509_NAME_get_index_by_NID(cert_subject, NID_commonName, i)) != -1) {
2277 X509_NAME_ENTRY *entry = X509_NAME_get_entry(cert_subject, i);
2278 if (ASN1_STRING_to_UTF8((unsigned char **)&str, entry->value) >= 0) {
2279 ok = ssl_sock_srv_hostcheck(str, servername);
2280 OPENSSL_free(str);
2281 }
2282 }
2283
2284 return ok;
2285}
2286
Emeric Brun94324a42012-10-11 14:00:19 +02002287/* prepare ssl context from servers options. Returns an error count */
2288int ssl_sock_prepare_srv_ctx(struct server *srv, struct proxy *curproxy)
2289{
2290 int cfgerr = 0;
Remi Gacogneaf5c3da2014-05-19 10:29:58 +02002291 long options =
Emeric Brun94324a42012-10-11 14:00:19 +02002292 SSL_OP_ALL | /* all known workarounds for bugs */
2293 SSL_OP_NO_SSLv2 |
2294 SSL_OP_NO_COMPRESSION;
Remi Gacogneaf5c3da2014-05-19 10:29:58 +02002295 long mode =
Emeric Brun94324a42012-10-11 14:00:19 +02002296 SSL_MODE_ENABLE_PARTIAL_WRITE |
2297 SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER |
Willy Tarreau396a1862014-11-13 14:06:52 +01002298 SSL_MODE_RELEASE_BUFFERS |
2299 SSL_MODE_SMALL_BUFFERS;
Emeric Brun850efd52014-01-29 12:24:34 +01002300 int verify = SSL_VERIFY_NONE;
Emeric Brun94324a42012-10-11 14:00:19 +02002301
Thierry Fournier383085f2013-01-24 14:15:43 +01002302 /* Make sure openssl opens /dev/urandom before the chroot */
2303 if (!ssl_initialize_random()) {
2304 Alert("OpenSSL random data generator initialization failed.\n");
2305 cfgerr++;
2306 }
2307
Willy Tarreaufce03112015-01-15 21:32:40 +01002308 /* Automatic memory computations need to know we use SSL there */
2309 global.ssl_used_backend = 1;
2310
2311 /* Initiate SSL context for current server */
Emeric Brun94324a42012-10-11 14:00:19 +02002312 srv->ssl_ctx.reused_sess = NULL;
2313 if (srv->use_ssl)
2314 srv->xprt = &ssl_sock;
2315 if (srv->check.use_ssl)
Cyril Bonté9ce13112014-11-15 22:41:27 +01002316 srv->check.xprt = &ssl_sock;
Emeric Brun94324a42012-10-11 14:00:19 +02002317
2318 srv->ssl_ctx.ctx = SSL_CTX_new(SSLv23_client_method());
2319 if (!srv->ssl_ctx.ctx) {
2320 Alert("config : %s '%s', server '%s': unable to allocate ssl context.\n",
2321 proxy_type_str(curproxy), curproxy->id,
2322 srv->id);
2323 cfgerr++;
2324 return cfgerr;
2325 }
Emeric Bruna7aa3092012-10-26 12:58:00 +02002326 if (srv->ssl_ctx.client_crt) {
2327 if (SSL_CTX_use_PrivateKey_file(srv->ssl_ctx.ctx, srv->ssl_ctx.client_crt, SSL_FILETYPE_PEM) <= 0) {
2328 Alert("config : %s '%s', server '%s': unable to load SSL private key from PEM file '%s'.\n",
2329 proxy_type_str(curproxy), curproxy->id,
2330 srv->id, srv->ssl_ctx.client_crt);
2331 cfgerr++;
2332 }
2333 else if (SSL_CTX_use_certificate_chain_file(srv->ssl_ctx.ctx, srv->ssl_ctx.client_crt) <= 0) {
2334 Alert("config : %s '%s', server '%s': unable to load ssl certificate from PEM file '%s'.\n",
2335 proxy_type_str(curproxy), curproxy->id,
2336 srv->id, srv->ssl_ctx.client_crt);
2337 cfgerr++;
2338 }
2339 else if (SSL_CTX_check_private_key(srv->ssl_ctx.ctx) <= 0) {
2340 Alert("config : %s '%s', server '%s': inconsistencies between private key and certificate loaded from PEM file '%s'.\n",
2341 proxy_type_str(curproxy), curproxy->id,
2342 srv->id, srv->ssl_ctx.client_crt);
2343 cfgerr++;
2344 }
2345 }
Emeric Brun94324a42012-10-11 14:00:19 +02002346
2347 if (srv->ssl_ctx.options & SRV_SSL_O_NO_SSLV3)
2348 options |= SSL_OP_NO_SSLv3;
2349 if (srv->ssl_ctx.options & SRV_SSL_O_NO_TLSV10)
2350 options |= SSL_OP_NO_TLSv1;
2351 if (srv->ssl_ctx.options & SRV_SSL_O_NO_TLSV11)
2352 options |= SSL_OP_NO_TLSv1_1;
2353 if (srv->ssl_ctx.options & SRV_SSL_O_NO_TLSV12)
2354 options |= SSL_OP_NO_TLSv1_2;
Emeric Brunf9c5c472012-10-11 15:28:34 +02002355 if (srv->ssl_ctx.options & SRV_SSL_O_NO_TLS_TICKETS)
2356 options |= SSL_OP_NO_TICKET;
Jérémie Courrèges-Anglas17c3f622015-07-25 16:50:52 -06002357 if (srv->ssl_ctx.options & SRV_SSL_O_USE_SSLV3) {
2358#ifndef OPENSSL_NO_SSL3
Emeric Brun94324a42012-10-11 14:00:19 +02002359 SSL_CTX_set_ssl_version(srv->ssl_ctx.ctx, SSLv3_client_method());
Jérémie Courrèges-Anglas17c3f622015-07-25 16:50:52 -06002360#else
Thierry FOURNIERbc965342015-08-26 08:21:26 +02002361 Alert("SSLv3 support requested but unavailable.\n");
Jérémie Courrèges-Anglas17c3f622015-07-25 16:50:52 -06002362 cfgerr++;
2363#endif
2364 }
Emeric Brun94324a42012-10-11 14:00:19 +02002365 if (srv->ssl_ctx.options & SRV_SSL_O_USE_TLSV10)
2366 SSL_CTX_set_ssl_version(srv->ssl_ctx.ctx, TLSv1_client_method());
2367#if SSL_OP_NO_TLSv1_1
2368 if (srv->ssl_ctx.options & SRV_SSL_O_USE_TLSV11)
2369 SSL_CTX_set_ssl_version(srv->ssl_ctx.ctx, TLSv1_1_client_method());
2370#endif
2371#if SSL_OP_NO_TLSv1_2
2372 if (srv->ssl_ctx.options & SRV_SSL_O_USE_TLSV12)
2373 SSL_CTX_set_ssl_version(srv->ssl_ctx.ctx, TLSv1_2_client_method());
2374#endif
2375
2376 SSL_CTX_set_options(srv->ssl_ctx.ctx, options);
2377 SSL_CTX_set_mode(srv->ssl_ctx.ctx, mode);
Emeric Brun850efd52014-01-29 12:24:34 +01002378
2379 if (global.ssl_server_verify == SSL_SERVER_VERIFY_REQUIRED)
2380 verify = SSL_VERIFY_PEER;
2381
2382 switch (srv->ssl_ctx.verify) {
2383 case SSL_SOCK_VERIFY_NONE:
2384 verify = SSL_VERIFY_NONE;
2385 break;
2386 case SSL_SOCK_VERIFY_REQUIRED:
2387 verify = SSL_VERIFY_PEER;
2388 break;
2389 }
Evan Broderbe554312013-06-27 00:05:25 -07002390 SSL_CTX_set_verify(srv->ssl_ctx.ctx,
Emeric Brun850efd52014-01-29 12:24:34 +01002391 verify,
Evan Broderbe554312013-06-27 00:05:25 -07002392 srv->ssl_ctx.verify_host ? ssl_sock_srv_verifycbk : NULL);
Emeric Brun850efd52014-01-29 12:24:34 +01002393 if (verify & SSL_VERIFY_PEER) {
Emeric Brunef42d922012-10-11 16:11:36 +02002394 if (srv->ssl_ctx.ca_file) {
2395 /* load CAfile to verify */
2396 if (!SSL_CTX_load_verify_locations(srv->ssl_ctx.ctx, srv->ssl_ctx.ca_file, NULL)) {
Willy Tarreau07ba08b2014-02-16 19:22:08 +01002397 Alert("Proxy '%s', server '%s' [%s:%d] unable to load CA file '%s'.\n",
Emeric Brunef42d922012-10-11 16:11:36 +02002398 curproxy->id, srv->id,
2399 srv->conf.file, srv->conf.line, srv->ssl_ctx.ca_file);
2400 cfgerr++;
2401 }
2402 }
Emeric Brun850efd52014-01-29 12:24:34 +01002403 else {
2404 if (global.ssl_server_verify == SSL_SERVER_VERIFY_REQUIRED)
Willy Tarreau07ba08b2014-02-16 19:22:08 +01002405 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 +01002406 curproxy->id, srv->id,
2407 srv->conf.file, srv->conf.line);
2408 else
Willy Tarreau07ba08b2014-02-16 19:22:08 +01002409 Alert("Proxy '%s', server '%s' [%s:%d] verify is enabled but no CA file specified.\n",
Emeric Brun850efd52014-01-29 12:24:34 +01002410 curproxy->id, srv->id,
2411 srv->conf.file, srv->conf.line);
2412 cfgerr++;
2413 }
Emeric Brunef42d922012-10-11 16:11:36 +02002414#ifdef X509_V_FLAG_CRL_CHECK
2415 if (srv->ssl_ctx.crl_file) {
2416 X509_STORE *store = SSL_CTX_get_cert_store(srv->ssl_ctx.ctx);
2417
2418 if (!store || !X509_STORE_load_locations(store, srv->ssl_ctx.crl_file, NULL)) {
Willy Tarreau07ba08b2014-02-16 19:22:08 +01002419 Alert("Proxy '%s', server '%s' [%s:%d] unable to configure CRL file '%s'.\n",
Emeric Brunef42d922012-10-11 16:11:36 +02002420 curproxy->id, srv->id,
2421 srv->conf.file, srv->conf.line, srv->ssl_ctx.crl_file);
2422 cfgerr++;
2423 }
2424 else {
2425 X509_STORE_set_flags(store, X509_V_FLAG_CRL_CHECK|X509_V_FLAG_CRL_CHECK_ALL);
2426 }
2427 }
2428#endif
2429 }
2430
Emeric Brun4f65bff2012-11-16 15:11:00 +01002431 if (global.tune.ssllifetime)
2432 SSL_CTX_set_timeout(srv->ssl_ctx.ctx, global.tune.ssllifetime);
2433
Emeric Brun94324a42012-10-11 14:00:19 +02002434 SSL_CTX_set_session_cache_mode(srv->ssl_ctx.ctx, SSL_SESS_CACHE_OFF);
2435 if (srv->ssl_ctx.ciphers &&
2436 !SSL_CTX_set_cipher_list(srv->ssl_ctx.ctx, srv->ssl_ctx.ciphers)) {
2437 Alert("Proxy '%s', server '%s' [%s:%d] : unable to set SSL cipher list to '%s'.\n",
2438 curproxy->id, srv->id,
2439 srv->conf.file, srv->conf.line, srv->ssl_ctx.ciphers);
2440 cfgerr++;
2441 }
2442
2443 return cfgerr;
2444}
2445
Willy Tarreau2a65ff02012-09-13 17:54:29 +02002446/* Walks down the two trees in bind_conf and prepares all certs. The pointer may
Emeric Brunfc0421f2012-09-07 17:30:07 +02002447 * be NULL, in which case nothing is done. Returns the number of errors
2448 * encountered.
2449 */
Willy Tarreau2a65ff02012-09-13 17:54:29 +02002450int ssl_sock_prepare_all_ctx(struct bind_conf *bind_conf, struct proxy *px)
Emeric Brunfc0421f2012-09-07 17:30:07 +02002451{
2452 struct ebmb_node *node;
2453 struct sni_ctx *sni;
2454 int err = 0;
2455
Willy Tarreau2a65ff02012-09-13 17:54:29 +02002456 if (!bind_conf || !bind_conf->is_ssl)
Emeric Brunfc0421f2012-09-07 17:30:07 +02002457 return 0;
2458
Willy Tarreaufce03112015-01-15 21:32:40 +01002459 /* Automatic memory computations need to know we use SSL there */
2460 global.ssl_used_frontend = 1;
2461
Emeric Brun0bed9942014-10-30 19:25:24 +01002462 if (bind_conf->default_ctx)
2463 err += ssl_sock_prepare_ctx(bind_conf, bind_conf->default_ctx, px);
2464
Willy Tarreau2a65ff02012-09-13 17:54:29 +02002465 node = ebmb_first(&bind_conf->sni_ctx);
Emeric Brunfc0421f2012-09-07 17:30:07 +02002466 while (node) {
2467 sni = ebmb_entry(node, struct sni_ctx, name);
Emeric Brun0bed9942014-10-30 19:25:24 +01002468 if (!sni->order && sni->ctx != bind_conf->default_ctx)
2469 /* only initialize the CTX on its first occurrence and
2470 if it is not the default_ctx */
Willy Tarreau2a65ff02012-09-13 17:54:29 +02002471 err += ssl_sock_prepare_ctx(bind_conf, sni->ctx, px);
Emeric Brunfc0421f2012-09-07 17:30:07 +02002472 node = ebmb_next(node);
2473 }
2474
Willy Tarreau2a65ff02012-09-13 17:54:29 +02002475 node = ebmb_first(&bind_conf->sni_w_ctx);
Emeric Brunfc0421f2012-09-07 17:30:07 +02002476 while (node) {
2477 sni = ebmb_entry(node, struct sni_ctx, name);
Emeric Brun0bed9942014-10-30 19:25:24 +01002478 if (!sni->order && sni->ctx != bind_conf->default_ctx)
2479 /* only initialize the CTX on its first occurrence and
2480 if it is not the default_ctx */
Willy Tarreau2a65ff02012-09-13 17:54:29 +02002481 err += ssl_sock_prepare_ctx(bind_conf, sni->ctx, px);
Emeric Brunfc0421f2012-09-07 17:30:07 +02002482 node = ebmb_next(node);
2483 }
2484 return err;
2485}
2486
Christopher Faulet77fe80c2015-07-29 13:02:40 +02002487
2488/* release ssl context allocated for servers. */
2489void ssl_sock_free_srv_ctx(struct server *srv)
2490{
2491 if (srv->ssl_ctx.ctx)
2492 SSL_CTX_free(srv->ssl_ctx.ctx);
2493}
2494
Willy Tarreau2a65ff02012-09-13 17:54:29 +02002495/* Walks down the two trees in bind_conf and frees all the certs. The pointer may
Emeric Brunfc0421f2012-09-07 17:30:07 +02002496 * be NULL, in which case nothing is done. The default_ctx is nullified too.
2497 */
Willy Tarreau2a65ff02012-09-13 17:54:29 +02002498void ssl_sock_free_all_ctx(struct bind_conf *bind_conf)
Emeric Brunfc0421f2012-09-07 17:30:07 +02002499{
2500 struct ebmb_node *node, *back;
2501 struct sni_ctx *sni;
2502
Willy Tarreau2a65ff02012-09-13 17:54:29 +02002503 if (!bind_conf || !bind_conf->is_ssl)
Emeric Brunfc0421f2012-09-07 17:30:07 +02002504 return;
2505
Willy Tarreau2a65ff02012-09-13 17:54:29 +02002506 node = ebmb_first(&bind_conf->sni_ctx);
Emeric Brunfc0421f2012-09-07 17:30:07 +02002507 while (node) {
2508 sni = ebmb_entry(node, struct sni_ctx, name);
2509 back = ebmb_next(node);
2510 ebmb_delete(node);
2511 if (!sni->order) /* only free the CTX on its first occurrence */
2512 SSL_CTX_free(sni->ctx);
2513 free(sni);
2514 node = back;
2515 }
2516
Willy Tarreau2a65ff02012-09-13 17:54:29 +02002517 node = ebmb_first(&bind_conf->sni_w_ctx);
Emeric Brunfc0421f2012-09-07 17:30:07 +02002518 while (node) {
2519 sni = ebmb_entry(node, struct sni_ctx, name);
2520 back = ebmb_next(node);
2521 ebmb_delete(node);
2522 if (!sni->order) /* only free the CTX on its first occurrence */
2523 SSL_CTX_free(sni->ctx);
2524 free(sni);
2525 node = back;
2526 }
2527
Willy Tarreau2a65ff02012-09-13 17:54:29 +02002528 bind_conf->default_ctx = NULL;
Emeric Brune1f38db2012-09-03 20:36:47 +02002529}
2530
Christopher Faulet31af49d2015-06-09 17:29:50 +02002531/* Load CA cert file and private key used to generate certificates */
2532int
2533ssl_sock_load_ca(struct bind_conf *bind_conf, struct proxy *px)
2534{
2535 FILE *fp;
2536 X509 *cacert = NULL;
2537 EVP_PKEY *capkey = NULL;
2538 int err = 0;
2539
2540 if (!bind_conf || !bind_conf->generate_certs)
2541 return err;
2542
Willy Tarreaua84c2672015-10-09 12:10:13 +02002543#ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME
Christopher Fauletd2cab922015-07-28 16:03:47 +02002544 if (global.tune.ssl_ctx_cache)
2545 ssl_ctx_lru_tree = lru64_new(global.tune.ssl_ctx_cache);
2546 ssl_ctx_lru_seed = (unsigned int)time(NULL);
Willy Tarreaua84c2672015-10-09 12:10:13 +02002547#endif
Christopher Fauletd2cab922015-07-28 16:03:47 +02002548
Christopher Faulet31af49d2015-06-09 17:29:50 +02002549 if (!bind_conf->ca_sign_file) {
2550 Alert("Proxy '%s': cannot enable certificate generation, "
2551 "no CA certificate File configured at [%s:%d].\n",
2552 px->id, bind_conf->file, bind_conf->line);
Christopher Faulet31af49d2015-06-09 17:29:50 +02002553 goto load_error;
Christopher Fauletc6f02fb2015-10-09 10:53:31 +02002554 }
Christopher Faulet31af49d2015-06-09 17:29:50 +02002555
2556 /* read in the CA certificate */
2557 if (!(fp = fopen(bind_conf->ca_sign_file, "r"))) {
2558 Alert("Proxy '%s': Failed to read CA certificate file '%s' at [%s:%d].\n",
2559 px->id, bind_conf->ca_sign_file, bind_conf->file, bind_conf->line);
Christopher Faulet31af49d2015-06-09 17:29:50 +02002560 goto load_error;
2561 }
2562 if (!(cacert = PEM_read_X509(fp, NULL, NULL, NULL))) {
2563 Alert("Proxy '%s': Failed to read CA certificate file '%s' at [%s:%d].\n",
2564 px->id, bind_conf->ca_sign_file, bind_conf->file, bind_conf->line);
Christopher Fauletc6f02fb2015-10-09 10:53:31 +02002565 goto read_error;
Christopher Faulet31af49d2015-06-09 17:29:50 +02002566 }
Christopher Fauletc6f02fb2015-10-09 10:53:31 +02002567 rewind(fp);
Christopher Faulet31af49d2015-06-09 17:29:50 +02002568 if (!(capkey = PEM_read_PrivateKey(fp, NULL, NULL, bind_conf->ca_sign_pass))) {
2569 Alert("Proxy '%s': Failed to read CA private key file '%s' at [%s:%d].\n",
2570 px->id, bind_conf->ca_sign_file, bind_conf->file, bind_conf->line);
Christopher Fauletc6f02fb2015-10-09 10:53:31 +02002571 goto read_error;
Christopher Faulet31af49d2015-06-09 17:29:50 +02002572 }
Christopher Faulet31af49d2015-06-09 17:29:50 +02002573
Christopher Fauletc6f02fb2015-10-09 10:53:31 +02002574 fclose (fp);
Christopher Faulet31af49d2015-06-09 17:29:50 +02002575 bind_conf->ca_sign_cert = cacert;
2576 bind_conf->ca_sign_pkey = capkey;
2577 return err;
2578
Christopher Fauletc6f02fb2015-10-09 10:53:31 +02002579 read_error:
2580 fclose (fp);
Christopher Faulet31af49d2015-06-09 17:29:50 +02002581 if (capkey) EVP_PKEY_free(capkey);
2582 if (cacert) X509_free(cacert);
Christopher Fauletc6f02fb2015-10-09 10:53:31 +02002583 load_error:
2584 bind_conf->generate_certs = 0;
2585 err++;
Christopher Faulet31af49d2015-06-09 17:29:50 +02002586 return err;
2587}
2588
2589/* Release CA cert and private key used to generate certificated */
2590void
2591ssl_sock_free_ca(struct bind_conf *bind_conf)
2592{
2593 if (!bind_conf)
2594 return;
2595
2596 if (bind_conf->ca_sign_pkey)
2597 EVP_PKEY_free(bind_conf->ca_sign_pkey);
2598 if (bind_conf->ca_sign_cert)
2599 X509_free(bind_conf->ca_sign_cert);
2600}
2601
Emeric Brun46591952012-05-18 15:47:34 +02002602/*
2603 * This function is called if SSL * context is not yet allocated. The function
2604 * is designed to be called before any other data-layer operation and sets the
2605 * handshake flag on the connection. It is safe to call it multiple times.
2606 * It returns 0 on success and -1 in error case.
2607 */
2608static int ssl_sock_init(struct connection *conn)
2609{
2610 /* already initialized */
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02002611 if (conn->xprt_ctx)
Emeric Brun46591952012-05-18 15:47:34 +02002612 return 0;
2613
Willy Tarreau3c728722014-01-23 13:50:42 +01002614 if (!conn_ctrl_ready(conn))
Willy Tarreauf79c8172013-10-21 16:30:56 +02002615 return 0;
2616
Willy Tarreau20879a02012-12-03 16:32:10 +01002617 if (global.maxsslconn && sslconns >= global.maxsslconn) {
2618 conn->err_code = CO_ER_SSL_TOO_MANY;
Willy Tarreau403edff2012-09-06 11:58:37 +02002619 return -1;
Willy Tarreau20879a02012-12-03 16:32:10 +01002620 }
Willy Tarreau403edff2012-09-06 11:58:37 +02002621
Emeric Brun46591952012-05-18 15:47:34 +02002622 /* If it is in client mode initiate SSL session
2623 in connect state otherwise accept state */
Willy Tarreau3fdb3662012-11-12 00:42:33 +01002624 if (objt_server(conn->target)) {
Willy Tarreaufba03cd2014-11-13 13:48:58 +01002625 int may_retry = 1;
2626
2627 retry_connect:
Emeric Brun46591952012-05-18 15:47:34 +02002628 /* Alloc a new SSL session ctx */
Willy Tarreau3fdb3662012-11-12 00:42:33 +01002629 conn->xprt_ctx = SSL_new(objt_server(conn->target)->ssl_ctx.ctx);
Willy Tarreau20879a02012-12-03 16:32:10 +01002630 if (!conn->xprt_ctx) {
Willy Tarreaufba03cd2014-11-13 13:48:58 +01002631 if (may_retry--) {
2632 pool_gc2();
2633 goto retry_connect;
2634 }
Willy Tarreau20879a02012-12-03 16:32:10 +01002635 conn->err_code = CO_ER_SSL_NO_MEM;
Emeric Brun46591952012-05-18 15:47:34 +02002636 return -1;
Willy Tarreau20879a02012-12-03 16:32:10 +01002637 }
Emeric Brun46591952012-05-18 15:47:34 +02002638
Emeric Brun46591952012-05-18 15:47:34 +02002639 /* set fd on SSL session context */
Emeric Brun55476152014-11-12 17:35:37 +01002640 if (!SSL_set_fd(conn->xprt_ctx, conn->t.sock.fd)) {
2641 SSL_free(conn->xprt_ctx);
2642 conn->xprt_ctx = NULL;
Willy Tarreaufba03cd2014-11-13 13:48:58 +01002643 if (may_retry--) {
2644 pool_gc2();
2645 goto retry_connect;
2646 }
Emeric Brun55476152014-11-12 17:35:37 +01002647 conn->err_code = CO_ER_SSL_NO_MEM;
2648 return -1;
2649 }
Emeric Brun46591952012-05-18 15:47:34 +02002650
Evan Broderbe554312013-06-27 00:05:25 -07002651 /* set connection pointer */
Emeric Brun55476152014-11-12 17:35:37 +01002652 if (!SSL_set_app_data(conn->xprt_ctx, conn)) {
2653 SSL_free(conn->xprt_ctx);
2654 conn->xprt_ctx = NULL;
Willy Tarreaufba03cd2014-11-13 13:48:58 +01002655 if (may_retry--) {
2656 pool_gc2();
2657 goto retry_connect;
2658 }
Emeric Brun55476152014-11-12 17:35:37 +01002659 conn->err_code = CO_ER_SSL_NO_MEM;
2660 return -1;
2661 }
2662
2663 SSL_set_connect_state(conn->xprt_ctx);
2664 if (objt_server(conn->target)->ssl_ctx.reused_sess) {
2665 if(!SSL_set_session(conn->xprt_ctx, objt_server(conn->target)->ssl_ctx.reused_sess)) {
2666 SSL_SESSION_free(objt_server(conn->target)->ssl_ctx.reused_sess);
2667 objt_server(conn->target)->ssl_ctx.reused_sess = NULL;
2668 }
2669 }
Evan Broderbe554312013-06-27 00:05:25 -07002670
Emeric Brun46591952012-05-18 15:47:34 +02002671 /* leave init state and start handshake */
Willy Tarreau05737472012-09-04 08:03:39 +02002672 conn->flags |= CO_FL_SSL_WAIT_HS | CO_FL_WAIT_L6_CONN;
Willy Tarreau403edff2012-09-06 11:58:37 +02002673
2674 sslconns++;
Willy Tarreau71b734c2014-01-28 15:19:44 +01002675 totalsslconns++;
Emeric Brun46591952012-05-18 15:47:34 +02002676 return 0;
2677 }
Willy Tarreau3fdb3662012-11-12 00:42:33 +01002678 else if (objt_listener(conn->target)) {
Willy Tarreaufba03cd2014-11-13 13:48:58 +01002679 int may_retry = 1;
2680
2681 retry_accept:
Emeric Brun46591952012-05-18 15:47:34 +02002682 /* Alloc a new SSL session ctx */
Willy Tarreau3fdb3662012-11-12 00:42:33 +01002683 conn->xprt_ctx = SSL_new(objt_listener(conn->target)->bind_conf->default_ctx);
Willy Tarreau20879a02012-12-03 16:32:10 +01002684 if (!conn->xprt_ctx) {
Willy Tarreaufba03cd2014-11-13 13:48:58 +01002685 if (may_retry--) {
2686 pool_gc2();
2687 goto retry_accept;
2688 }
Willy Tarreau20879a02012-12-03 16:32:10 +01002689 conn->err_code = CO_ER_SSL_NO_MEM;
Emeric Brun46591952012-05-18 15:47:34 +02002690 return -1;
Willy Tarreau20879a02012-12-03 16:32:10 +01002691 }
Emeric Brun46591952012-05-18 15:47:34 +02002692
Emeric Brun46591952012-05-18 15:47:34 +02002693 /* set fd on SSL session context */
Emeric Brun55476152014-11-12 17:35:37 +01002694 if (!SSL_set_fd(conn->xprt_ctx, conn->t.sock.fd)) {
2695 SSL_free(conn->xprt_ctx);
2696 conn->xprt_ctx = NULL;
Willy Tarreaufba03cd2014-11-13 13:48:58 +01002697 if (may_retry--) {
2698 pool_gc2();
2699 goto retry_accept;
2700 }
Emeric Brun55476152014-11-12 17:35:37 +01002701 conn->err_code = CO_ER_SSL_NO_MEM;
2702 return -1;
2703 }
Emeric Brun46591952012-05-18 15:47:34 +02002704
Emeric Brune1f38db2012-09-03 20:36:47 +02002705 /* set connection pointer */
Emeric Brun55476152014-11-12 17:35:37 +01002706 if (!SSL_set_app_data(conn->xprt_ctx, conn)) {
2707 SSL_free(conn->xprt_ctx);
2708 conn->xprt_ctx = NULL;
Willy Tarreaufba03cd2014-11-13 13:48:58 +01002709 if (may_retry--) {
2710 pool_gc2();
2711 goto retry_accept;
2712 }
Emeric Brun55476152014-11-12 17:35:37 +01002713 conn->err_code = CO_ER_SSL_NO_MEM;
2714 return -1;
2715 }
2716
2717 SSL_set_accept_state(conn->xprt_ctx);
Emeric Brune1f38db2012-09-03 20:36:47 +02002718
Emeric Brun46591952012-05-18 15:47:34 +02002719 /* leave init state and start handshake */
Willy Tarreau05737472012-09-04 08:03:39 +02002720 conn->flags |= CO_FL_SSL_WAIT_HS | CO_FL_WAIT_L6_CONN;
Willy Tarreau403edff2012-09-06 11:58:37 +02002721
2722 sslconns++;
Willy Tarreau71b734c2014-01-28 15:19:44 +01002723 totalsslconns++;
Emeric Brun46591952012-05-18 15:47:34 +02002724 return 0;
2725 }
2726 /* don't know how to handle such a target */
Willy Tarreau20879a02012-12-03 16:32:10 +01002727 conn->err_code = CO_ER_SSL_NO_TARGET;
Emeric Brun46591952012-05-18 15:47:34 +02002728 return -1;
2729}
2730
2731
2732/* This is the callback which is used when an SSL handshake is pending. It
2733 * updates the FD status if it wants some polling before being called again.
2734 * It returns 0 if it fails in a fatal way or needs to poll to go further,
2735 * otherwise it returns non-zero and removes itself from the connection's
2736 * flags (the bit is provided in <flag> by the caller).
2737 */
2738int ssl_sock_handshake(struct connection *conn, unsigned int flag)
2739{
2740 int ret;
2741
Willy Tarreau3c728722014-01-23 13:50:42 +01002742 if (!conn_ctrl_ready(conn))
Willy Tarreauf79c8172013-10-21 16:30:56 +02002743 return 0;
2744
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02002745 if (!conn->xprt_ctx)
Emeric Brun46591952012-05-18 15:47:34 +02002746 goto out_error;
2747
Emeric Brun674b7432012-11-08 19:21:55 +01002748 /* If we use SSL_do_handshake to process a reneg initiated by
2749 * the remote peer, it sometimes returns SSL_ERROR_SSL.
2750 * Usually SSL_write and SSL_read are used and process implicitly
2751 * the reneg handshake.
2752 * Here we use SSL_peek as a workaround for reneg.
2753 */
2754 if ((conn->flags & CO_FL_CONNECTED) && SSL_renegotiate_pending(conn->xprt_ctx)) {
2755 char c;
2756
2757 ret = SSL_peek(conn->xprt_ctx, &c, 1);
2758 if (ret <= 0) {
2759 /* handshake may have not been completed, let's find why */
2760 ret = SSL_get_error(conn->xprt_ctx, ret);
2761 if (ret == SSL_ERROR_WANT_WRITE) {
2762 /* SSL handshake needs to write, L4 connection may not be ready */
2763 __conn_sock_stop_recv(conn);
Willy Tarreaue1f50c42014-01-22 20:02:06 +01002764 __conn_sock_want_send(conn);
2765 fd_cant_send(conn->t.sock.fd);
Emeric Brun674b7432012-11-08 19:21:55 +01002766 return 0;
2767 }
2768 else if (ret == SSL_ERROR_WANT_READ) {
2769 /* handshake may have been completed but we have
2770 * no more data to read.
2771 */
2772 if (!SSL_renegotiate_pending(conn->xprt_ctx)) {
2773 ret = 1;
2774 goto reneg_ok;
2775 }
2776 /* SSL handshake needs to read, L4 connection is ready */
2777 if (conn->flags & CO_FL_WAIT_L4_CONN)
2778 conn->flags &= ~CO_FL_WAIT_L4_CONN;
2779 __conn_sock_stop_send(conn);
Willy Tarreaue1f50c42014-01-22 20:02:06 +01002780 __conn_sock_want_recv(conn);
2781 fd_cant_recv(conn->t.sock.fd);
Emeric Brun674b7432012-11-08 19:21:55 +01002782 return 0;
2783 }
2784 else if (ret == SSL_ERROR_SYSCALL) {
2785 /* if errno is null, then connection was successfully established */
2786 if (!errno && conn->flags & CO_FL_WAIT_L4_CONN)
2787 conn->flags &= ~CO_FL_WAIT_L4_CONN;
Willy Tarreau20879a02012-12-03 16:32:10 +01002788 if (!conn->err_code) {
Emeric Brun29f037d2014-04-25 19:05:36 +02002789 if (!((SSL *)conn->xprt_ctx)->packet_length) {
2790 if (!errno) {
2791 if (conn->xprt_st & SSL_SOCK_RECV_HEARTBEAT)
2792 conn->err_code = CO_ER_SSL_HANDSHAKE_HB;
2793 else
2794 conn->err_code = CO_ER_SSL_EMPTY;
2795 }
2796 else {
2797 if (conn->xprt_st & SSL_SOCK_RECV_HEARTBEAT)
2798 conn->err_code = CO_ER_SSL_HANDSHAKE_HB;
2799 else
2800 conn->err_code = CO_ER_SSL_ABORT;
2801 }
2802 }
2803 else {
2804 if (conn->xprt_st & SSL_SOCK_RECV_HEARTBEAT)
2805 conn->err_code = CO_ER_SSL_HANDSHAKE_HB;
Willy Tarreau20879a02012-12-03 16:32:10 +01002806 else
Emeric Brun29f037d2014-04-25 19:05:36 +02002807 conn->err_code = CO_ER_SSL_HANDSHAKE;
2808 }
Willy Tarreau20879a02012-12-03 16:32:10 +01002809 }
Emeric Brun674b7432012-11-08 19:21:55 +01002810 goto out_error;
2811 }
2812 else {
2813 /* Fail on all other handshake errors */
2814 /* Note: OpenSSL may leave unread bytes in the socket's
2815 * buffer, causing an RST to be emitted upon close() on
2816 * TCP sockets. We first try to drain possibly pending
2817 * data to avoid this as much as possible.
2818 */
Willy Tarreaud85c4852015-03-13 00:40:28 +01002819 conn_sock_drain(conn);
Willy Tarreau20879a02012-12-03 16:32:10 +01002820 if (!conn->err_code)
Willy Tarreauf51c6982014-04-25 20:02:39 +02002821 conn->err_code = (conn->xprt_st & SSL_SOCK_RECV_HEARTBEAT) ?
2822 CO_ER_SSL_KILLED_HB : CO_ER_SSL_HANDSHAKE;
Emeric Brun674b7432012-11-08 19:21:55 +01002823 goto out_error;
2824 }
2825 }
2826 /* read some data: consider handshake completed */
2827 goto reneg_ok;
2828 }
2829
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02002830 ret = SSL_do_handshake(conn->xprt_ctx);
Emeric Brun46591952012-05-18 15:47:34 +02002831 if (ret != 1) {
2832 /* handshake did not complete, let's find why */
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02002833 ret = SSL_get_error(conn->xprt_ctx, ret);
Emeric Brun46591952012-05-18 15:47:34 +02002834
2835 if (ret == SSL_ERROR_WANT_WRITE) {
2836 /* SSL handshake needs to write, L4 connection may not be ready */
2837 __conn_sock_stop_recv(conn);
Willy Tarreaue1f50c42014-01-22 20:02:06 +01002838 __conn_sock_want_send(conn);
2839 fd_cant_send(conn->t.sock.fd);
Emeric Brun46591952012-05-18 15:47:34 +02002840 return 0;
2841 }
2842 else if (ret == SSL_ERROR_WANT_READ) {
2843 /* SSL handshake needs to read, L4 connection is ready */
2844 if (conn->flags & CO_FL_WAIT_L4_CONN)
2845 conn->flags &= ~CO_FL_WAIT_L4_CONN;
2846 __conn_sock_stop_send(conn);
Willy Tarreaue1f50c42014-01-22 20:02:06 +01002847 __conn_sock_want_recv(conn);
2848 fd_cant_recv(conn->t.sock.fd);
Emeric Brun46591952012-05-18 15:47:34 +02002849 return 0;
2850 }
Willy Tarreau89230192012-09-28 20:22:13 +02002851 else if (ret == SSL_ERROR_SYSCALL) {
2852 /* if errno is null, then connection was successfully established */
2853 if (!errno && conn->flags & CO_FL_WAIT_L4_CONN)
2854 conn->flags &= ~CO_FL_WAIT_L4_CONN;
Willy Tarreau20879a02012-12-03 16:32:10 +01002855
Emeric Brun29f037d2014-04-25 19:05:36 +02002856 if (!((SSL *)conn->xprt_ctx)->packet_length) {
2857 if (!errno) {
2858 if (conn->xprt_st & SSL_SOCK_RECV_HEARTBEAT)
2859 conn->err_code = CO_ER_SSL_HANDSHAKE_HB;
2860 else
2861 conn->err_code = CO_ER_SSL_EMPTY;
2862 }
2863 else {
2864 if (conn->xprt_st & SSL_SOCK_RECV_HEARTBEAT)
2865 conn->err_code = CO_ER_SSL_HANDSHAKE_HB;
2866 else
2867 conn->err_code = CO_ER_SSL_ABORT;
2868 }
2869 }
2870 else {
2871 if (conn->xprt_st & SSL_SOCK_RECV_HEARTBEAT)
2872 conn->err_code = CO_ER_SSL_HANDSHAKE_HB;
Willy Tarreau20879a02012-12-03 16:32:10 +01002873 else
Emeric Brun29f037d2014-04-25 19:05:36 +02002874 conn->err_code = CO_ER_SSL_HANDSHAKE;
2875 }
Willy Tarreau89230192012-09-28 20:22:13 +02002876 goto out_error;
2877 }
Emeric Brun46591952012-05-18 15:47:34 +02002878 else {
2879 /* Fail on all other handshake errors */
Willy Tarreau566dc552012-10-19 20:52:18 +02002880 /* Note: OpenSSL may leave unread bytes in the socket's
2881 * buffer, causing an RST to be emitted upon close() on
2882 * TCP sockets. We first try to drain possibly pending
2883 * data to avoid this as much as possible.
2884 */
Willy Tarreaud85c4852015-03-13 00:40:28 +01002885 conn_sock_drain(conn);
Willy Tarreau20879a02012-12-03 16:32:10 +01002886 if (!conn->err_code)
Willy Tarreauf51c6982014-04-25 20:02:39 +02002887 conn->err_code = (conn->xprt_st & SSL_SOCK_RECV_HEARTBEAT) ?
2888 CO_ER_SSL_KILLED_HB : CO_ER_SSL_HANDSHAKE;
Emeric Brun46591952012-05-18 15:47:34 +02002889 goto out_error;
2890 }
2891 }
2892
Emeric Brun674b7432012-11-08 19:21:55 +01002893reneg_ok:
Emeric Brun46591952012-05-18 15:47:34 +02002894 /* Handshake succeeded */
Willy Tarreau0c9c2722014-05-28 12:28:58 +02002895 if (!SSL_session_reused(conn->xprt_ctx)) {
2896 if (objt_server(conn->target)) {
2897 update_freq_ctr(&global.ssl_be_keys_per_sec, 1);
2898 if (global.ssl_be_keys_per_sec.curr_ctr > global.ssl_be_keys_max)
2899 global.ssl_be_keys_max = global.ssl_be_keys_per_sec.curr_ctr;
2900
Emeric Brun46591952012-05-18 15:47:34 +02002901 /* check if session was reused, if not store current session on server for reuse */
Willy Tarreau3fdb3662012-11-12 00:42:33 +01002902 if (objt_server(conn->target)->ssl_ctx.reused_sess)
2903 SSL_SESSION_free(objt_server(conn->target)->ssl_ctx.reused_sess);
Emeric Brun46591952012-05-18 15:47:34 +02002904
Willy Tarreau2a3fb1c2015-02-05 16:47:07 +01002905 if (!(objt_server(conn->target)->ssl_ctx.options & SRV_SSL_O_NO_REUSE))
2906 objt_server(conn->target)->ssl_ctx.reused_sess = SSL_get1_session(conn->xprt_ctx);
Emeric Brun46591952012-05-18 15:47:34 +02002907 }
Willy Tarreau0c9c2722014-05-28 12:28:58 +02002908 else {
2909 update_freq_ctr(&global.ssl_fe_keys_per_sec, 1);
2910 if (global.ssl_fe_keys_per_sec.curr_ctr > global.ssl_fe_keys_max)
2911 global.ssl_fe_keys_max = global.ssl_fe_keys_per_sec.curr_ctr;
2912 }
Emeric Brun46591952012-05-18 15:47:34 +02002913 }
2914
2915 /* The connection is now established at both layers, it's time to leave */
2916 conn->flags &= ~(flag | CO_FL_WAIT_L4_CONN | CO_FL_WAIT_L6_CONN);
2917 return 1;
2918
2919 out_error:
Emeric Brun644cde02012-12-14 11:21:13 +01002920 /* Clear openssl global errors stack */
2921 ERR_clear_error();
2922
Emeric Brun9fa89732012-10-04 17:09:56 +02002923 /* free resumed session if exists */
Willy Tarreau3fdb3662012-11-12 00:42:33 +01002924 if (objt_server(conn->target) && objt_server(conn->target)->ssl_ctx.reused_sess) {
2925 SSL_SESSION_free(objt_server(conn->target)->ssl_ctx.reused_sess);
2926 objt_server(conn->target)->ssl_ctx.reused_sess = NULL;
Emeric Brun9fa89732012-10-04 17:09:56 +02002927 }
2928
Emeric Brun46591952012-05-18 15:47:34 +02002929 /* Fail on all other handshake errors */
2930 conn->flags |= CO_FL_ERROR;
Willy Tarreau20879a02012-12-03 16:32:10 +01002931 if (!conn->err_code)
2932 conn->err_code = CO_ER_SSL_HANDSHAKE;
Emeric Brun46591952012-05-18 15:47:34 +02002933 return 0;
2934}
2935
2936/* Receive up to <count> bytes from connection <conn>'s socket and store them
Willy Tarreauabf08d92014-01-14 11:31:27 +01002937 * into buffer <buf>. Only one call to recv() is performed, unless the
Emeric Brun46591952012-05-18 15:47:34 +02002938 * buffer wraps, in which case a second call may be performed. The connection's
2939 * flags are updated with whatever special event is detected (error, read0,
2940 * empty). The caller is responsible for taking care of those events and
2941 * avoiding the call if inappropriate. The function does not call the
2942 * connection's polling update function, so the caller is responsible for this.
2943 */
2944static int ssl_sock_to_buf(struct connection *conn, struct buffer *buf, int count)
2945{
2946 int ret, done = 0;
Willy Tarreauabf08d92014-01-14 11:31:27 +01002947 int try;
Emeric Brun46591952012-05-18 15:47:34 +02002948
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02002949 if (!conn->xprt_ctx)
Emeric Brun46591952012-05-18 15:47:34 +02002950 goto out_error;
2951
2952 if (conn->flags & CO_FL_HANDSHAKE)
2953 /* a handshake was requested */
2954 return 0;
2955
Willy Tarreauabf08d92014-01-14 11:31:27 +01002956 /* let's realign the buffer to optimize I/O */
2957 if (buffer_empty(buf))
Emeric Brun46591952012-05-18 15:47:34 +02002958 buf->p = buf->data;
Emeric Brun46591952012-05-18 15:47:34 +02002959
2960 /* read the largest possible block. For this, we perform only one call
2961 * to recv() unless the buffer wraps and we exactly fill the first hunk,
2962 * in which case we accept to do it once again. A new attempt is made on
2963 * EINTR too.
2964 */
Willy Tarreau00b0fb92014-01-17 11:09:40 +01002965 while (count > 0) {
Willy Tarreauabf08d92014-01-14 11:31:27 +01002966 /* first check if we have some room after p+i */
2967 try = buf->data + buf->size - (buf->p + buf->i);
2968 /* otherwise continue between data and p-o */
2969 if (try <= 0) {
2970 try = buf->p - (buf->data + buf->o);
2971 if (try <= 0)
2972 break;
2973 }
2974 if (try > count)
2975 try = count;
2976
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02002977 ret = SSL_read(conn->xprt_ctx, bi_end(buf), try);
Emeric Brune1f38db2012-09-03 20:36:47 +02002978 if (conn->flags & CO_FL_ERROR) {
2979 /* CO_FL_ERROR may be set by ssl_sock_infocbk */
Emeric Brun644cde02012-12-14 11:21:13 +01002980 goto out_error;
Emeric Brune1f38db2012-09-03 20:36:47 +02002981 }
Emeric Brun46591952012-05-18 15:47:34 +02002982 if (ret > 0) {
2983 buf->i += ret;
2984 done += ret;
2985 if (ret < try)
2986 break;
2987 count -= ret;
Emeric Brun46591952012-05-18 15:47:34 +02002988 }
2989 else if (ret == 0) {
Emeric Brun644cde02012-12-14 11:21:13 +01002990 ret = SSL_get_error(conn->xprt_ctx, ret);
2991 if (ret != SSL_ERROR_ZERO_RETURN) {
Emeric Brun1c646862012-12-14 12:33:41 +01002992 /* error on protocol or underlying transport */
2993 if ((ret != SSL_ERROR_SYSCALL)
2994 || (errno && (errno != EAGAIN)))
2995 conn->flags |= CO_FL_ERROR;
2996
Emeric Brun644cde02012-12-14 11:21:13 +01002997 /* Clear openssl global errors stack */
2998 ERR_clear_error();
2999 }
Emeric Brun46591952012-05-18 15:47:34 +02003000 goto read0;
3001 }
3002 else {
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02003003 ret = SSL_get_error(conn->xprt_ctx, ret);
Emeric Brun46591952012-05-18 15:47:34 +02003004 if (ret == SSL_ERROR_WANT_WRITE) {
Emeric Brun8af8dd12012-11-08 17:56:20 +01003005 /* handshake is running, and it needs to enable write */
Emeric Brun46591952012-05-18 15:47:34 +02003006 conn->flags |= CO_FL_SSL_WAIT_HS;
Emeric Brun8af8dd12012-11-08 17:56:20 +01003007 __conn_sock_want_send(conn);
Emeric Brun46591952012-05-18 15:47:34 +02003008 break;
3009 }
3010 else if (ret == SSL_ERROR_WANT_READ) {
Emeric Brun282a76a2012-11-08 18:02:56 +01003011 if (SSL_renegotiate_pending(conn->xprt_ctx)) {
3012 /* handshake is running, and it may need to re-enable read */
3013 conn->flags |= CO_FL_SSL_WAIT_HS;
3014 __conn_sock_want_recv(conn);
3015 break;
3016 }
Emeric Brun46591952012-05-18 15:47:34 +02003017 /* we need to poll for retry a read later */
Willy Tarreaue1f50c42014-01-22 20:02:06 +01003018 fd_cant_recv(conn->t.sock.fd);
Emeric Brun46591952012-05-18 15:47:34 +02003019 break;
3020 }
3021 /* otherwise it's a real error */
3022 goto out_error;
3023 }
3024 }
3025 return done;
3026
3027 read0:
3028 conn_sock_read0(conn);
3029 return done;
3030 out_error:
Emeric Brun644cde02012-12-14 11:21:13 +01003031 /* Clear openssl global errors stack */
3032 ERR_clear_error();
3033
Emeric Brun46591952012-05-18 15:47:34 +02003034 conn->flags |= CO_FL_ERROR;
3035 return done;
3036}
3037
3038
3039/* Send all pending bytes from buffer <buf> to connection <conn>'s socket.
Willy Tarreau1049b1f2014-02-02 01:51:17 +01003040 * <flags> may contain some CO_SFL_* flags to hint the system about other
3041 * pending data for example, but this flag is ignored at the moment.
Emeric Brun46591952012-05-18 15:47:34 +02003042 * Only one call to send() is performed, unless the buffer wraps, in which case
3043 * a second call may be performed. The connection's flags are updated with
3044 * whatever special event is detected (error, empty). The caller is responsible
3045 * for taking care of those events and avoiding the call if inappropriate. The
3046 * function does not call the connection's polling update function, so the caller
3047 * is responsible for this.
3048 */
3049static int ssl_sock_from_buf(struct connection *conn, struct buffer *buf, int flags)
3050{
3051 int ret, try, done;
3052
3053 done = 0;
3054
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02003055 if (!conn->xprt_ctx)
Emeric Brun46591952012-05-18 15:47:34 +02003056 goto out_error;
3057
3058 if (conn->flags & CO_FL_HANDSHAKE)
3059 /* a handshake was requested */
3060 return 0;
3061
3062 /* send the largest possible block. For this we perform only one call
3063 * to send() unless the buffer wraps and we exactly fill the first hunk,
3064 * in which case we accept to do it once again.
3065 */
3066 while (buf->o) {
Kevin Hestercad82342013-05-30 15:12:41 -07003067 try = bo_contig_data(buf);
Willy Tarreaubfd59462013-02-21 07:46:09 +01003068
Willy Tarreau7bed9452014-02-02 02:00:24 +01003069 if (!(flags & CO_SFL_STREAMER) &&
Willy Tarreau518cedd2014-02-17 15:43:01 +01003070 !(conn->xprt_st & SSL_SOCK_SEND_UNLIMITED) &&
3071 global.tune.ssl_max_record && try > global.tune.ssl_max_record) {
Willy Tarreaubfd59462013-02-21 07:46:09 +01003072 try = global.tune.ssl_max_record;
Willy Tarreau518cedd2014-02-17 15:43:01 +01003073 }
3074 else {
3075 /* we need to keep the information about the fact that
3076 * we're not limiting the upcoming send(), because if it
3077 * fails, we'll have to retry with at least as many data.
3078 */
3079 conn->xprt_st |= SSL_SOCK_SEND_UNLIMITED;
3080 }
Willy Tarreaubfd59462013-02-21 07:46:09 +01003081
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02003082 ret = SSL_write(conn->xprt_ctx, bo_ptr(buf), try);
Willy Tarreau518cedd2014-02-17 15:43:01 +01003083
Emeric Brune1f38db2012-09-03 20:36:47 +02003084 if (conn->flags & CO_FL_ERROR) {
3085 /* CO_FL_ERROR may be set by ssl_sock_infocbk */
Emeric Brun644cde02012-12-14 11:21:13 +01003086 goto out_error;
Emeric Brune1f38db2012-09-03 20:36:47 +02003087 }
Emeric Brun46591952012-05-18 15:47:34 +02003088 if (ret > 0) {
Willy Tarreau518cedd2014-02-17 15:43:01 +01003089 conn->xprt_st &= ~SSL_SOCK_SEND_UNLIMITED;
3090
Emeric Brun46591952012-05-18 15:47:34 +02003091 buf->o -= ret;
3092 done += ret;
3093
Willy Tarreau5fb38032012-12-16 19:39:09 +01003094 if (likely(buffer_empty(buf)))
Emeric Brun46591952012-05-18 15:47:34 +02003095 /* optimize data alignment in the buffer */
3096 buf->p = buf->data;
3097
3098 /* if the system buffer is full, don't insist */
3099 if (ret < try)
3100 break;
3101 }
3102 else {
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02003103 ret = SSL_get_error(conn->xprt_ctx, ret);
Emeric Brun46591952012-05-18 15:47:34 +02003104 if (ret == SSL_ERROR_WANT_WRITE) {
Emeric Brun282a76a2012-11-08 18:02:56 +01003105 if (SSL_renegotiate_pending(conn->xprt_ctx)) {
3106 /* handshake is running, and it may need to re-enable write */
3107 conn->flags |= CO_FL_SSL_WAIT_HS;
3108 __conn_sock_want_send(conn);
3109 break;
3110 }
Emeric Brun46591952012-05-18 15:47:34 +02003111 /* we need to poll to retry a write later */
Willy Tarreaue1f50c42014-01-22 20:02:06 +01003112 fd_cant_send(conn->t.sock.fd);
Emeric Brun46591952012-05-18 15:47:34 +02003113 break;
3114 }
3115 else if (ret == SSL_ERROR_WANT_READ) {
Emeric Brun8af8dd12012-11-08 17:56:20 +01003116 /* handshake is running, and it needs to enable read */
Emeric Brun46591952012-05-18 15:47:34 +02003117 conn->flags |= CO_FL_SSL_WAIT_HS;
Emeric Brun8af8dd12012-11-08 17:56:20 +01003118 __conn_sock_want_recv(conn);
Emeric Brun46591952012-05-18 15:47:34 +02003119 break;
3120 }
3121 goto out_error;
3122 }
3123 }
3124 return done;
3125
3126 out_error:
Emeric Brun644cde02012-12-14 11:21:13 +01003127 /* Clear openssl global errors stack */
3128 ERR_clear_error();
3129
Emeric Brun46591952012-05-18 15:47:34 +02003130 conn->flags |= CO_FL_ERROR;
3131 return done;
3132}
3133
Emeric Brun46591952012-05-18 15:47:34 +02003134static void ssl_sock_close(struct connection *conn) {
3135
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02003136 if (conn->xprt_ctx) {
3137 SSL_free(conn->xprt_ctx);
3138 conn->xprt_ctx = NULL;
Willy Tarreau403edff2012-09-06 11:58:37 +02003139 sslconns--;
Emeric Brun46591952012-05-18 15:47:34 +02003140 }
Emeric Brun46591952012-05-18 15:47:34 +02003141}
3142
3143/* This function tries to perform a clean shutdown on an SSL connection, and in
3144 * any case, flags the connection as reusable if no handshake was in progress.
3145 */
3146static void ssl_sock_shutw(struct connection *conn, int clean)
3147{
3148 if (conn->flags & CO_FL_HANDSHAKE)
3149 return;
3150 /* no handshake was in progress, try a clean ssl shutdown */
Emeric Brun644cde02012-12-14 11:21:13 +01003151 if (clean && (SSL_shutdown(conn->xprt_ctx) <= 0)) {
3152 /* Clear openssl global errors stack */
3153 ERR_clear_error();
3154 }
Emeric Brun46591952012-05-18 15:47:34 +02003155
3156 /* force flag on ssl to keep session in cache regardless shutdown result */
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02003157 SSL_set_shutdown(conn->xprt_ctx, SSL_SENT_SHUTDOWN);
Emeric Brun46591952012-05-18 15:47:34 +02003158}
3159
Willy Tarreauffc3fcd2012-10-12 20:17:54 +02003160/* used for logging, may be changed for a sample fetch later */
3161const char *ssl_sock_get_cipher_name(struct connection *conn)
3162{
3163 if (!conn->xprt && !conn->xprt_ctx)
3164 return NULL;
3165 return SSL_get_cipher_name(conn->xprt_ctx);
3166}
3167
3168/* used for logging, may be changed for a sample fetch later */
3169const char *ssl_sock_get_proto_version(struct connection *conn)
3170{
3171 if (!conn->xprt && !conn->xprt_ctx)
3172 return NULL;
3173 return SSL_get_version(conn->xprt_ctx);
3174}
3175
Willy Tarreau8d598402012-10-22 17:58:39 +02003176/* Extract a serial from a cert, and copy it to a chunk.
3177 * Returns 1 if serial is found and copied, 0 if no serial found and
3178 * -1 if output is not large enough.
3179 */
3180static int
3181ssl_sock_get_serial(X509 *crt, struct chunk *out)
3182{
3183 ASN1_INTEGER *serial;
3184
3185 serial = X509_get_serialNumber(crt);
3186 if (!serial)
3187 return 0;
3188
3189 if (out->size < serial->length)
3190 return -1;
3191
3192 memcpy(out->str, serial->data, serial->length);
3193 out->len = serial->length;
3194 return 1;
3195}
3196
Emeric Brun43e79582014-10-29 19:03:26 +01003197/* Extract a cert to der, and copy it to a chunk.
3198 * Returns 1 if cert is found and copied, 0 on der convertion failure and
3199 * -1 if output is not large enough.
3200 */
3201static int
3202ssl_sock_crt2der(X509 *crt, struct chunk *out)
3203{
3204 int len;
3205 unsigned char *p = (unsigned char *)out->str;;
3206
3207 len =i2d_X509(crt, NULL);
3208 if (len <= 0)
3209 return 1;
3210
3211 if (out->size < len)
3212 return -1;
3213
3214 i2d_X509(crt,&p);
3215 out->len = len;
3216 return 1;
3217}
3218
Emeric Brunce5ad802012-10-22 14:11:22 +02003219
3220/* Copy Date in ASN1_UTCTIME format in struct chunk out.
3221 * Returns 1 if serial is found and copied, 0 if no valid time found
3222 * and -1 if output is not large enough.
3223 */
3224static int
3225ssl_sock_get_time(ASN1_TIME *tm, struct chunk *out)
3226{
3227 if (tm->type == V_ASN1_GENERALIZEDTIME) {
3228 ASN1_GENERALIZEDTIME *gentm = (ASN1_GENERALIZEDTIME *)tm;
3229
3230 if (gentm->length < 12)
3231 return 0;
3232 if (gentm->data[0] != 0x32 || gentm->data[1] != 0x30)
3233 return 0;
3234 if (out->size < gentm->length-2)
3235 return -1;
3236
3237 memcpy(out->str, gentm->data+2, gentm->length-2);
3238 out->len = gentm->length-2;
3239 return 1;
3240 }
3241 else if (tm->type == V_ASN1_UTCTIME) {
3242 ASN1_UTCTIME *utctm = (ASN1_UTCTIME *)tm;
3243
3244 if (utctm->length < 10)
3245 return 0;
3246 if (utctm->data[0] >= 0x35)
3247 return 0;
3248 if (out->size < utctm->length)
3249 return -1;
3250
3251 memcpy(out->str, utctm->data, utctm->length);
3252 out->len = utctm->length;
3253 return 1;
3254 }
3255
3256 return 0;
3257}
3258
Emeric Brun87855892012-10-17 17:39:35 +02003259/* Extract an entry from a X509_NAME and copy its value to an output chunk.
3260 * Returns 1 if entry found, 0 if entry not found, or -1 if output not large enough.
3261 */
3262static int
3263ssl_sock_get_dn_entry(X509_NAME *a, const struct chunk *entry, int pos, struct chunk *out)
3264{
3265 X509_NAME_ENTRY *ne;
3266 int i, j, n;
3267 int cur = 0;
3268 const char *s;
3269 char tmp[128];
3270
3271 out->len = 0;
3272 for (i = 0; i < sk_X509_NAME_ENTRY_num(a->entries); i++) {
3273 if (pos < 0)
3274 j = (sk_X509_NAME_ENTRY_num(a->entries)-1) - i;
3275 else
3276 j = i;
3277
3278 ne = sk_X509_NAME_ENTRY_value(a->entries, j);
3279 n = OBJ_obj2nid(ne->object);
3280 if ((n == NID_undef) || ((s = OBJ_nid2sn(n)) == NULL)) {
3281 i2t_ASN1_OBJECT(tmp, sizeof(tmp), ne->object);
3282 s = tmp;
3283 }
3284
3285 if (chunk_strcasecmp(entry, s) != 0)
3286 continue;
3287
3288 if (pos < 0)
3289 cur--;
3290 else
3291 cur++;
3292
3293 if (cur != pos)
3294 continue;
3295
3296 if (ne->value->length > out->size)
3297 return -1;
3298
3299 memcpy(out->str, ne->value->data, ne->value->length);
3300 out->len = ne->value->length;
3301 return 1;
3302 }
3303
3304 return 0;
3305
3306}
3307
3308/* Extract and format full DN from a X509_NAME and copy result into a chunk
3309 * Returns 1 if dn entries exits, 0 if no dn entry found or -1 if output is not large enough.
3310 */
3311static int
3312ssl_sock_get_dn_oneline(X509_NAME *a, struct chunk *out)
3313{
3314 X509_NAME_ENTRY *ne;
3315 int i, n, ln;
3316 int l = 0;
3317 const char *s;
3318 char *p;
3319 char tmp[128];
3320
3321 out->len = 0;
3322 p = out->str;
3323 for (i = 0; i < sk_X509_NAME_ENTRY_num(a->entries); i++) {
3324 ne = sk_X509_NAME_ENTRY_value(a->entries, i);
3325 n = OBJ_obj2nid(ne->object);
3326 if ((n == NID_undef) || ((s = OBJ_nid2sn(n)) == NULL)) {
3327 i2t_ASN1_OBJECT(tmp, sizeof(tmp), ne->object);
3328 s = tmp;
3329 }
3330 ln = strlen(s);
3331
3332 l += 1 + ln + 1 + ne->value->length;
3333 if (l > out->size)
3334 return -1;
3335 out->len = l;
3336
3337 *(p++)='/';
3338 memcpy(p, s, ln);
3339 p += ln;
3340 *(p++)='=';
3341 memcpy(p, ne->value->data, ne->value->length);
3342 p += ne->value->length;
3343 }
3344
3345 if (!out->len)
3346 return 0;
3347
3348 return 1;
3349}
3350
David Safb76832014-05-08 23:42:08 -04003351char *ssl_sock_get_version(struct connection *conn)
3352{
3353 if (!ssl_sock_is_ssl(conn))
3354 return NULL;
3355
3356 return (char *)SSL_get_version(conn->xprt_ctx);
3357}
3358
Willy Tarreau63076412015-07-10 11:33:32 +02003359void ssl_sock_set_servername(struct connection *conn, const char *hostname)
3360{
3361#ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME
3362 if (!ssl_sock_is_ssl(conn))
3363 return;
3364
3365 SSL_set_tlsext_host_name(conn->xprt_ctx, hostname);
3366#endif
3367}
3368
Emeric Brun0abf8362014-06-24 18:26:41 +02003369/* Extract peer certificate's common name into the chunk dest
3370 * Returns
3371 * the len of the extracted common name
3372 * or 0 if no CN found in DN
3373 * or -1 on error case (i.e. no peer certificate)
3374 */
3375int ssl_sock_get_remote_common_name(struct connection *conn, struct chunk *dest)
David Safb76832014-05-08 23:42:08 -04003376{
3377 X509 *crt = NULL;
3378 X509_NAME *name;
David Safb76832014-05-08 23:42:08 -04003379 const char find_cn[] = "CN";
3380 const struct chunk find_cn_chunk = {
3381 .str = (char *)&find_cn,
3382 .len = sizeof(find_cn)-1
3383 };
Emeric Brun0abf8362014-06-24 18:26:41 +02003384 int result = -1;
David Safb76832014-05-08 23:42:08 -04003385
3386 if (!ssl_sock_is_ssl(conn))
Emeric Brun0abf8362014-06-24 18:26:41 +02003387 goto out;
David Safb76832014-05-08 23:42:08 -04003388
3389 /* SSL_get_peer_certificate, it increase X509 * ref count */
3390 crt = SSL_get_peer_certificate(conn->xprt_ctx);
3391 if (!crt)
3392 goto out;
3393
3394 name = X509_get_subject_name(crt);
3395 if (!name)
3396 goto out;
David Safb76832014-05-08 23:42:08 -04003397
Emeric Brun0abf8362014-06-24 18:26:41 +02003398 result = ssl_sock_get_dn_entry(name, &find_cn_chunk, 1, dest);
3399out:
David Safb76832014-05-08 23:42:08 -04003400 if (crt)
3401 X509_free(crt);
3402
3403 return result;
3404}
3405
Dave McCowan328fb582014-07-30 10:39:13 -04003406/* returns 1 if client passed a certificate for this session, 0 if not */
3407int ssl_sock_get_cert_used_sess(struct connection *conn)
3408{
3409 X509 *crt = NULL;
3410
3411 if (!ssl_sock_is_ssl(conn))
3412 return 0;
3413
3414 /* SSL_get_peer_certificate, it increase X509 * ref count */
3415 crt = SSL_get_peer_certificate(conn->xprt_ctx);
3416 if (!crt)
3417 return 0;
3418
3419 X509_free(crt);
3420 return 1;
3421}
3422
3423/* returns 1 if client passed a certificate for this connection, 0 if not */
3424int ssl_sock_get_cert_used_conn(struct connection *conn)
David Safb76832014-05-08 23:42:08 -04003425{
3426 if (!ssl_sock_is_ssl(conn))
3427 return 0;
3428
3429 return SSL_SOCK_ST_FL_VERIFY_DONE & conn->xprt_st ? 1 : 0;
3430}
3431
3432/* returns result from SSL verify */
3433unsigned int ssl_sock_get_verify_result(struct connection *conn)
3434{
3435 if (!ssl_sock_is_ssl(conn))
3436 return (unsigned int)X509_V_ERR_APPLICATION_VERIFICATION;
3437
3438 return (unsigned int)SSL_get_verify_result(conn->xprt_ctx);
3439}
3440
Willy Tarreau7875d092012-09-10 08:20:03 +02003441/***** Below are some sample fetching functions for ACL/patterns *****/
3442
Emeric Brune64aef12012-09-21 13:15:06 +02003443/* boolean, returns true if client cert was present */
3444static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02003445smp_fetch_ssl_fc_has_crt(const struct arg *args, struct sample *smp, const char *kw, void *private)
Emeric Brune64aef12012-09-21 13:15:06 +02003446{
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003447 struct connection *conn;
3448
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02003449 conn = objt_conn(smp->sess->origin);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003450 if (!conn || conn->xprt != &ssl_sock)
Emeric Brune64aef12012-09-21 13:15:06 +02003451 return 0;
3452
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003453 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brune64aef12012-09-21 13:15:06 +02003454 smp->flags |= SMP_F_MAY_CHANGE;
3455 return 0;
3456 }
3457
3458 smp->flags = 0;
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02003459 smp->data.type = SMP_T_BOOL;
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02003460 smp->data.u.sint = SSL_SOCK_ST_FL_VERIFY_DONE & conn->xprt_st ? 1 : 0;
Emeric Brune64aef12012-09-21 13:15:06 +02003461
3462 return 1;
3463}
3464
Emeric Brun43e79582014-10-29 19:03:26 +01003465/* binary, returns a certificate in a binary chunk (der/raw).
3466 * The 5th keyword char is used to know if SSL_get_certificate or SSL_get_peer_certificate
3467 * should be use.
3468 */
3469static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02003470smp_fetch_ssl_x_der(const struct arg *args, struct sample *smp, const char *kw, void *private)
Emeric Brun43e79582014-10-29 19:03:26 +01003471{
3472 int cert_peer = (kw[4] == 'c') ? 1 : 0;
3473 X509 *crt = NULL;
3474 int ret = 0;
3475 struct chunk *smp_trash;
3476 struct connection *conn;
3477
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02003478 conn = objt_conn(smp->sess->origin);
Emeric Brun43e79582014-10-29 19:03:26 +01003479 if (!conn || conn->xprt != &ssl_sock)
3480 return 0;
3481
3482 if (!(conn->flags & CO_FL_CONNECTED)) {
3483 smp->flags |= SMP_F_MAY_CHANGE;
3484 return 0;
3485 }
3486
3487 if (cert_peer)
3488 crt = SSL_get_peer_certificate(conn->xprt_ctx);
3489 else
3490 crt = SSL_get_certificate(conn->xprt_ctx);
3491
3492 if (!crt)
3493 goto out;
3494
3495 smp_trash = get_trash_chunk();
3496 if (ssl_sock_crt2der(crt, smp_trash) <= 0)
3497 goto out;
3498
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02003499 smp->data.u.str = *smp_trash;
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02003500 smp->data.type = SMP_T_BIN;
Emeric Brun43e79582014-10-29 19:03:26 +01003501 ret = 1;
3502out:
3503 /* SSL_get_peer_certificate, it increase X509 * ref count */
3504 if (cert_peer && crt)
3505 X509_free(crt);
3506 return ret;
3507}
3508
Emeric Brunba841a12014-04-30 17:05:08 +02003509/* binary, returns serial of certificate in a binary chunk.
3510 * The 5th keyword char is used to know if SSL_get_certificate or SSL_get_peer_certificate
3511 * should be use.
3512 */
Willy Tarreau8d598402012-10-22 17:58:39 +02003513static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02003514smp_fetch_ssl_x_serial(const struct arg *args, struct sample *smp, const char *kw, void *private)
Willy Tarreau8d598402012-10-22 17:58:39 +02003515{
Emeric Brunba841a12014-04-30 17:05:08 +02003516 int cert_peer = (kw[4] == 'c') ? 1 : 0;
Willy Tarreau8d598402012-10-22 17:58:39 +02003517 X509 *crt = NULL;
3518 int ret = 0;
3519 struct chunk *smp_trash;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003520 struct connection *conn;
3521
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02003522 conn = objt_conn(smp->sess->origin);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003523 if (!conn || conn->xprt != &ssl_sock)
Willy Tarreau8d598402012-10-22 17:58:39 +02003524 return 0;
3525
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003526 if (!(conn->flags & CO_FL_CONNECTED)) {
Willy Tarreau8d598402012-10-22 17:58:39 +02003527 smp->flags |= SMP_F_MAY_CHANGE;
3528 return 0;
3529 }
3530
Emeric Brunba841a12014-04-30 17:05:08 +02003531 if (cert_peer)
3532 crt = SSL_get_peer_certificate(conn->xprt_ctx);
3533 else
3534 crt = SSL_get_certificate(conn->xprt_ctx);
3535
Willy Tarreau8d598402012-10-22 17:58:39 +02003536 if (!crt)
3537 goto out;
3538
Willy Tarreau47ca5452012-12-23 20:22:19 +01003539 smp_trash = get_trash_chunk();
Willy Tarreau8d598402012-10-22 17:58:39 +02003540 if (ssl_sock_get_serial(crt, smp_trash) <= 0)
3541 goto out;
3542
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02003543 smp->data.u.str = *smp_trash;
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02003544 smp->data.type = SMP_T_BIN;
Willy Tarreau8d598402012-10-22 17:58:39 +02003545 ret = 1;
3546out:
Emeric Brunba841a12014-04-30 17:05:08 +02003547 /* SSL_get_peer_certificate, it increase X509 * ref count */
3548 if (cert_peer && crt)
Willy Tarreau8d598402012-10-22 17:58:39 +02003549 X509_free(crt);
3550 return ret;
3551}
Emeric Brune64aef12012-09-21 13:15:06 +02003552
Emeric Brunba841a12014-04-30 17:05:08 +02003553/* binary, returns the client certificate's SHA-1 fingerprint (SHA-1 hash of DER-encoded certificate) in a binary chunk.
3554 * The 5th keyword char is used to know if SSL_get_certificate or SSL_get_peer_certificate
3555 * should be use.
3556 */
James Votha051b4a2013-05-14 20:37:59 +02003557static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02003558smp_fetch_ssl_x_sha1(const struct arg *args, struct sample *smp, const char *kw, void *private)
James Votha051b4a2013-05-14 20:37:59 +02003559{
Emeric Brunba841a12014-04-30 17:05:08 +02003560 int cert_peer = (kw[4] == 'c') ? 1 : 0;
James Votha051b4a2013-05-14 20:37:59 +02003561 X509 *crt = NULL;
3562 const EVP_MD *digest;
3563 int ret = 0;
3564 struct chunk *smp_trash;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003565 struct connection *conn;
James Votha051b4a2013-05-14 20:37:59 +02003566
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02003567 conn = objt_conn(smp->sess->origin);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003568 if (!conn || conn->xprt != &ssl_sock)
3569 return 0;
3570
3571 if (!(conn->flags & CO_FL_CONNECTED)) {
James Votha051b4a2013-05-14 20:37:59 +02003572 smp->flags |= SMP_F_MAY_CHANGE;
3573 return 0;
3574 }
3575
Emeric Brunba841a12014-04-30 17:05:08 +02003576 if (cert_peer)
3577 crt = SSL_get_peer_certificate(conn->xprt_ctx);
3578 else
3579 crt = SSL_get_certificate(conn->xprt_ctx);
James Votha051b4a2013-05-14 20:37:59 +02003580 if (!crt)
3581 goto out;
3582
3583 smp_trash = get_trash_chunk();
3584 digest = EVP_sha1();
3585 X509_digest(crt, digest, (unsigned char *)smp_trash->str, (unsigned int *)&smp_trash->len);
3586
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02003587 smp->data.u.str = *smp_trash;
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02003588 smp->data.type = SMP_T_BIN;
James Votha051b4a2013-05-14 20:37:59 +02003589 ret = 1;
3590out:
Emeric Brunba841a12014-04-30 17:05:08 +02003591 /* SSL_get_peer_certificate, it increase X509 * ref count */
3592 if (cert_peer && crt)
James Votha051b4a2013-05-14 20:37:59 +02003593 X509_free(crt);
3594 return ret;
3595}
3596
Emeric Brunba841a12014-04-30 17:05:08 +02003597/* string, returns certificate's notafter date in ASN1_UTCTIME format.
3598 * The 5th keyword char is used to know if SSL_get_certificate or SSL_get_peer_certificate
3599 * should be use.
3600 */
Emeric Brunce5ad802012-10-22 14:11:22 +02003601static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02003602smp_fetch_ssl_x_notafter(const struct arg *args, struct sample *smp, const char *kw, void *private)
Emeric Brunce5ad802012-10-22 14:11:22 +02003603{
Emeric Brunba841a12014-04-30 17:05:08 +02003604 int cert_peer = (kw[4] == 'c') ? 1 : 0;
Emeric Brunce5ad802012-10-22 14:11:22 +02003605 X509 *crt = NULL;
3606 int ret = 0;
3607 struct chunk *smp_trash;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003608 struct connection *conn;
Emeric Brunce5ad802012-10-22 14:11:22 +02003609
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02003610 conn = objt_conn(smp->sess->origin);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003611 if (!conn || conn->xprt != &ssl_sock)
3612 return 0;
3613
3614 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brunce5ad802012-10-22 14:11:22 +02003615 smp->flags |= SMP_F_MAY_CHANGE;
3616 return 0;
3617 }
3618
Emeric Brunba841a12014-04-30 17:05:08 +02003619 if (cert_peer)
3620 crt = SSL_get_peer_certificate(conn->xprt_ctx);
3621 else
3622 crt = SSL_get_certificate(conn->xprt_ctx);
Emeric Brunce5ad802012-10-22 14:11:22 +02003623 if (!crt)
3624 goto out;
3625
Willy Tarreau47ca5452012-12-23 20:22:19 +01003626 smp_trash = get_trash_chunk();
Emeric Brunce5ad802012-10-22 14:11:22 +02003627 if (ssl_sock_get_time(X509_get_notAfter(crt), smp_trash) <= 0)
3628 goto out;
3629
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02003630 smp->data.u.str = *smp_trash;
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02003631 smp->data.type = SMP_T_STR;
Emeric Brunce5ad802012-10-22 14:11:22 +02003632 ret = 1;
3633out:
Emeric Brunba841a12014-04-30 17:05:08 +02003634 /* SSL_get_peer_certificate, it increase X509 * ref count */
3635 if (cert_peer && crt)
Emeric Brunce5ad802012-10-22 14:11:22 +02003636 X509_free(crt);
3637 return ret;
3638}
3639
Emeric Brunba841a12014-04-30 17:05:08 +02003640/* string, returns a string of a formatted full dn \C=..\O=..\OU=.. \CN=.. of certificate's issuer
3641 * The 5th keyword char is used to know if SSL_get_certificate or SSL_get_peer_certificate
3642 * should be use.
3643 */
Emeric Brun87855892012-10-17 17:39:35 +02003644static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02003645smp_fetch_ssl_x_i_dn(const struct arg *args, struct sample *smp, const char *kw, void *private)
Emeric Brun87855892012-10-17 17:39:35 +02003646{
Emeric Brunba841a12014-04-30 17:05:08 +02003647 int cert_peer = (kw[4] == 'c') ? 1 : 0;
Emeric Brun87855892012-10-17 17:39:35 +02003648 X509 *crt = NULL;
3649 X509_NAME *name;
3650 int ret = 0;
3651 struct chunk *smp_trash;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003652 struct connection *conn;
Emeric Brun87855892012-10-17 17:39:35 +02003653
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02003654 conn = objt_conn(smp->sess->origin);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003655 if (!conn || conn->xprt != &ssl_sock)
3656 return 0;
3657
3658 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brun87855892012-10-17 17:39:35 +02003659 smp->flags |= SMP_F_MAY_CHANGE;
3660 return 0;
3661 }
3662
Emeric Brunba841a12014-04-30 17:05:08 +02003663 if (cert_peer)
3664 crt = SSL_get_peer_certificate(conn->xprt_ctx);
3665 else
3666 crt = SSL_get_certificate(conn->xprt_ctx);
Emeric Brun87855892012-10-17 17:39:35 +02003667 if (!crt)
3668 goto out;
3669
3670 name = X509_get_issuer_name(crt);
3671 if (!name)
3672 goto out;
3673
Willy Tarreau47ca5452012-12-23 20:22:19 +01003674 smp_trash = get_trash_chunk();
Emeric Brun87855892012-10-17 17:39:35 +02003675 if (args && args[0].type == ARGT_STR) {
3676 int pos = 1;
3677
3678 if (args[1].type == ARGT_SINT)
3679 pos = args[1].data.sint;
Emeric Brun87855892012-10-17 17:39:35 +02003680
3681 if (ssl_sock_get_dn_entry(name, &args[0].data.str, pos, smp_trash) <= 0)
3682 goto out;
3683 }
3684 else if (ssl_sock_get_dn_oneline(name, smp_trash) <= 0)
3685 goto out;
3686
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02003687 smp->data.type = SMP_T_STR;
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02003688 smp->data.u.str = *smp_trash;
Emeric Brun87855892012-10-17 17:39:35 +02003689 ret = 1;
3690out:
Emeric Brunba841a12014-04-30 17:05:08 +02003691 /* SSL_get_peer_certificate, it increase X509 * ref count */
3692 if (cert_peer && crt)
Emeric Brun87855892012-10-17 17:39:35 +02003693 X509_free(crt);
3694 return ret;
3695}
3696
Emeric Brunba841a12014-04-30 17:05:08 +02003697/* string, returns notbefore date in ASN1_UTCTIME format.
3698 * The 5th keyword char is used to know if SSL_get_certificate or SSL_get_peer_certificate
3699 * should be use.
3700 */
Emeric Brunce5ad802012-10-22 14:11:22 +02003701static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02003702smp_fetch_ssl_x_notbefore(const struct arg *args, struct sample *smp, const char *kw, void *private)
Emeric Brunce5ad802012-10-22 14:11:22 +02003703{
Emeric Brunba841a12014-04-30 17:05:08 +02003704 int cert_peer = (kw[4] == 'c') ? 1 : 0;
Emeric Brunce5ad802012-10-22 14:11:22 +02003705 X509 *crt = NULL;
3706 int ret = 0;
3707 struct chunk *smp_trash;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003708 struct connection *conn;
3709
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02003710 conn = objt_conn(smp->sess->origin);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003711 if (!conn || conn->xprt != &ssl_sock)
Emeric Brunce5ad802012-10-22 14:11:22 +02003712 return 0;
3713
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003714 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brunce5ad802012-10-22 14:11:22 +02003715 smp->flags |= SMP_F_MAY_CHANGE;
3716 return 0;
3717 }
3718
Emeric Brunba841a12014-04-30 17:05:08 +02003719 if (cert_peer)
3720 crt = SSL_get_peer_certificate(conn->xprt_ctx);
3721 else
3722 crt = SSL_get_certificate(conn->xprt_ctx);
Emeric Brunce5ad802012-10-22 14:11:22 +02003723 if (!crt)
3724 goto out;
3725
Willy Tarreau47ca5452012-12-23 20:22:19 +01003726 smp_trash = get_trash_chunk();
Emeric Brunce5ad802012-10-22 14:11:22 +02003727 if (ssl_sock_get_time(X509_get_notBefore(crt), smp_trash) <= 0)
3728 goto out;
3729
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02003730 smp->data.u.str = *smp_trash;
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02003731 smp->data.type = SMP_T_STR;
Emeric Brunce5ad802012-10-22 14:11:22 +02003732 ret = 1;
3733out:
Emeric Brunba841a12014-04-30 17:05:08 +02003734 /* SSL_get_peer_certificate, it increase X509 * ref count */
3735 if (cert_peer && crt)
Emeric Brunce5ad802012-10-22 14:11:22 +02003736 X509_free(crt);
3737 return ret;
3738}
3739
Emeric Brunba841a12014-04-30 17:05:08 +02003740/* string, returns a string of a formatted full dn \C=..\O=..\OU=.. \CN=.. of certificate's subject
3741 * The 5th keyword char is used to know if SSL_get_certificate or SSL_get_peer_certificate
3742 * should be use.
3743 */
Emeric Brun87855892012-10-17 17:39:35 +02003744static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02003745smp_fetch_ssl_x_s_dn(const struct arg *args, struct sample *smp, const char *kw, void *private)
Emeric Brun87855892012-10-17 17:39:35 +02003746{
Emeric Brunba841a12014-04-30 17:05:08 +02003747 int cert_peer = (kw[4] == 'c') ? 1 : 0;
Emeric Brun87855892012-10-17 17:39:35 +02003748 X509 *crt = NULL;
3749 X509_NAME *name;
3750 int ret = 0;
3751 struct chunk *smp_trash;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003752 struct connection *conn;
Emeric Brun87855892012-10-17 17:39:35 +02003753
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02003754 conn = objt_conn(smp->sess->origin);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003755 if (!conn || conn->xprt != &ssl_sock)
3756 return 0;
3757
3758 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brun87855892012-10-17 17:39:35 +02003759 smp->flags |= SMP_F_MAY_CHANGE;
3760 return 0;
3761 }
3762
Emeric Brunba841a12014-04-30 17:05:08 +02003763 if (cert_peer)
3764 crt = SSL_get_peer_certificate(conn->xprt_ctx);
3765 else
3766 crt = SSL_get_certificate(conn->xprt_ctx);
Emeric Brun87855892012-10-17 17:39:35 +02003767 if (!crt)
3768 goto out;
3769
3770 name = X509_get_subject_name(crt);
3771 if (!name)
3772 goto out;
3773
Willy Tarreau47ca5452012-12-23 20:22:19 +01003774 smp_trash = get_trash_chunk();
Emeric Brun87855892012-10-17 17:39:35 +02003775 if (args && args[0].type == ARGT_STR) {
3776 int pos = 1;
3777
3778 if (args[1].type == ARGT_SINT)
3779 pos = args[1].data.sint;
Emeric Brun87855892012-10-17 17:39:35 +02003780
3781 if (ssl_sock_get_dn_entry(name, &args[0].data.str, pos, smp_trash) <= 0)
3782 goto out;
3783 }
3784 else if (ssl_sock_get_dn_oneline(name, smp_trash) <= 0)
3785 goto out;
3786
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02003787 smp->data.type = SMP_T_STR;
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02003788 smp->data.u.str = *smp_trash;
Emeric Brun87855892012-10-17 17:39:35 +02003789 ret = 1;
3790out:
Emeric Brunba841a12014-04-30 17:05:08 +02003791 /* SSL_get_peer_certificate, it increase X509 * ref count */
3792 if (cert_peer && crt)
Emeric Brun87855892012-10-17 17:39:35 +02003793 X509_free(crt);
3794 return ret;
3795}
Emeric Brun9143d372012-12-20 15:44:16 +01003796
3797/* integer, returns true if current session use a client certificate */
3798static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02003799smp_fetch_ssl_c_used(const struct arg *args, struct sample *smp, const char *kw, void *private)
Emeric Brun9143d372012-12-20 15:44:16 +01003800{
3801 X509 *crt;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003802 struct connection *conn;
Emeric Brun9143d372012-12-20 15:44:16 +01003803
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02003804 conn = objt_conn(smp->sess->origin);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003805 if (!conn || conn->xprt != &ssl_sock)
3806 return 0;
3807
3808 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brun9143d372012-12-20 15:44:16 +01003809 smp->flags |= SMP_F_MAY_CHANGE;
3810 return 0;
3811 }
3812
3813 /* SSL_get_peer_certificate returns a ptr on allocated X509 struct */
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003814 crt = SSL_get_peer_certificate(conn->xprt_ctx);
Emeric Brun9143d372012-12-20 15:44:16 +01003815 if (crt) {
3816 X509_free(crt);
3817 }
3818
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02003819 smp->data.type = SMP_T_BOOL;
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02003820 smp->data.u.sint = (crt != NULL);
Emeric Brun9143d372012-12-20 15:44:16 +01003821 return 1;
3822}
3823
Emeric Brunba841a12014-04-30 17:05:08 +02003824/* integer, returns the certificate version
3825 * The 5th keyword char is used to know if SSL_get_certificate or SSL_get_peer_certificate
3826 * should be use.
3827 */
Emeric Bruna7359fd2012-10-17 15:03:11 +02003828static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02003829smp_fetch_ssl_x_version(const struct arg *args, struct sample *smp, const char *kw, void *private)
Emeric Bruna7359fd2012-10-17 15:03:11 +02003830{
Emeric Brunba841a12014-04-30 17:05:08 +02003831 int cert_peer = (kw[4] == 'c') ? 1 : 0;
Emeric Bruna7359fd2012-10-17 15:03:11 +02003832 X509 *crt;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003833 struct connection *conn;
3834
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02003835 conn = objt_conn(smp->sess->origin);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003836 if (!conn || conn->xprt != &ssl_sock)
Emeric Bruna7359fd2012-10-17 15:03:11 +02003837 return 0;
3838
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003839 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Bruna7359fd2012-10-17 15:03:11 +02003840 smp->flags |= SMP_F_MAY_CHANGE;
3841 return 0;
3842 }
3843
Emeric Brunba841a12014-04-30 17:05:08 +02003844 if (cert_peer)
3845 crt = SSL_get_peer_certificate(conn->xprt_ctx);
3846 else
3847 crt = SSL_get_certificate(conn->xprt_ctx);
Emeric Bruna7359fd2012-10-17 15:03:11 +02003848 if (!crt)
3849 return 0;
3850
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02003851 smp->data.u.sint = (unsigned int)(1 + X509_get_version(crt));
Emeric Brunba841a12014-04-30 17:05:08 +02003852 /* SSL_get_peer_certificate increase X509 * ref count */
3853 if (cert_peer)
3854 X509_free(crt);
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02003855 smp->data.type = SMP_T_SINT;
Emeric Bruna7359fd2012-10-17 15:03:11 +02003856
3857 return 1;
3858}
3859
Emeric Brunba841a12014-04-30 17:05:08 +02003860/* string, returns the certificate's signature algorithm.
3861 * The 5th keyword char is used to know if SSL_get_certificate or SSL_get_peer_certificate
3862 * should be use.
3863 */
Emeric Brun7f56e742012-10-19 18:15:40 +02003864static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02003865smp_fetch_ssl_x_sig_alg(const struct arg *args, struct sample *smp, const char *kw, void *private)
Emeric Brun7f56e742012-10-19 18:15:40 +02003866{
Emeric Brunba841a12014-04-30 17:05:08 +02003867 int cert_peer = (kw[4] == 'c') ? 1 : 0;
Emeric Brun7f56e742012-10-19 18:15:40 +02003868 X509 *crt;
3869 int nid;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003870 struct connection *conn;
Emeric Brun7f56e742012-10-19 18:15:40 +02003871
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02003872 conn = objt_conn(smp->sess->origin);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003873 if (!conn || conn->xprt != &ssl_sock)
3874 return 0;
3875
3876 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brun7f56e742012-10-19 18:15:40 +02003877 smp->flags |= SMP_F_MAY_CHANGE;
3878 return 0;
3879 }
3880
Emeric Brunba841a12014-04-30 17:05:08 +02003881 if (cert_peer)
3882 crt = SSL_get_peer_certificate(conn->xprt_ctx);
3883 else
3884 crt = SSL_get_certificate(conn->xprt_ctx);
Emeric Brun7f56e742012-10-19 18:15:40 +02003885 if (!crt)
3886 return 0;
3887
3888 nid = OBJ_obj2nid((ASN1_OBJECT *)(crt->cert_info->signature->algorithm));
3889
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02003890 smp->data.u.str.str = (char *)OBJ_nid2sn(nid);
3891 if (!smp->data.u.str.str) {
Emeric Brunba841a12014-04-30 17:05:08 +02003892 /* SSL_get_peer_certificate increase X509 * ref count */
3893 if (cert_peer)
3894 X509_free(crt);
Emeric Brun7f56e742012-10-19 18:15:40 +02003895 return 0;
Emeric Brun9bf3ba22013-10-07 14:31:44 +02003896 }
Emeric Brun7f56e742012-10-19 18:15:40 +02003897
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02003898 smp->data.type = SMP_T_STR;
Thierry FOURNIER7654c9f2013-12-17 00:20:33 +01003899 smp->flags |= SMP_F_CONST;
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02003900 smp->data.u.str.len = strlen(smp->data.u.str.str);
Emeric Brunba841a12014-04-30 17:05:08 +02003901 /* SSL_get_peer_certificate increase X509 * ref count */
3902 if (cert_peer)
3903 X509_free(crt);
Emeric Brun7f56e742012-10-19 18:15:40 +02003904
3905 return 1;
3906}
3907
Emeric Brunba841a12014-04-30 17:05:08 +02003908/* string, returns the certificate's key algorithm.
3909 * The 5th keyword char is used to know if SSL_get_certificate or SSL_get_peer_certificate
3910 * should be use.
3911 */
Emeric Brun521a0112012-10-22 12:22:55 +02003912static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02003913smp_fetch_ssl_x_key_alg(const struct arg *args, struct sample *smp, const char *kw, void *private)
Emeric Brun521a0112012-10-22 12:22:55 +02003914{
Emeric Brunba841a12014-04-30 17:05:08 +02003915 int cert_peer = (kw[4] == 'c') ? 1 : 0;
Emeric Brun521a0112012-10-22 12:22:55 +02003916 X509 *crt;
3917 int nid;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003918 struct connection *conn;
Emeric Brun521a0112012-10-22 12:22:55 +02003919
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02003920 conn = objt_conn(smp->sess->origin);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003921 if (!conn || conn->xprt != &ssl_sock)
3922 return 0;
3923
3924 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brun521a0112012-10-22 12:22:55 +02003925 smp->flags |= SMP_F_MAY_CHANGE;
3926 return 0;
3927 }
3928
Emeric Brunba841a12014-04-30 17:05:08 +02003929 if (cert_peer)
3930 crt = SSL_get_peer_certificate(conn->xprt_ctx);
3931 else
3932 crt = SSL_get_certificate(conn->xprt_ctx);
Emeric Brun521a0112012-10-22 12:22:55 +02003933 if (!crt)
3934 return 0;
3935
3936 nid = OBJ_obj2nid((ASN1_OBJECT *)(crt->cert_info->key->algor->algorithm));
3937
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02003938 smp->data.u.str.str = (char *)OBJ_nid2sn(nid);
3939 if (!smp->data.u.str.str) {
Emeric Brunba841a12014-04-30 17:05:08 +02003940 /* SSL_get_peer_certificate increase X509 * ref count */
3941 if (cert_peer)
3942 X509_free(crt);
Emeric Brun521a0112012-10-22 12:22:55 +02003943 return 0;
Emeric Brun9bf3ba22013-10-07 14:31:44 +02003944 }
Emeric Brun521a0112012-10-22 12:22:55 +02003945
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02003946 smp->data.type = SMP_T_STR;
Thierry FOURNIER7654c9f2013-12-17 00:20:33 +01003947 smp->flags |= SMP_F_CONST;
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02003948 smp->data.u.str.len = strlen(smp->data.u.str.str);
Emeric Brunba841a12014-04-30 17:05:08 +02003949 if (cert_peer)
3950 X509_free(crt);
Emeric Brun521a0112012-10-22 12:22:55 +02003951
3952 return 1;
3953}
3954
Emeric Brun645ae792014-04-30 14:21:06 +02003955/* boolean, returns true if front conn. transport layer is SSL.
3956 * This function is also usable on backend conn if the fetch keyword 5th
3957 * char is 'b'.
3958 */
Willy Tarreau7875d092012-09-10 08:20:03 +02003959static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02003960smp_fetch_ssl_fc(const struct arg *args, struct sample *smp, const char *kw, void *private)
Willy Tarreau7875d092012-09-10 08:20:03 +02003961{
Emeric Brun645ae792014-04-30 14:21:06 +02003962 int back_conn = (kw[4] == 'b') ? 1 : 0;
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02003963 struct connection *conn = objt_conn(smp->strm->si[back_conn].end);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003964
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02003965 smp->data.type = SMP_T_BOOL;
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02003966 smp->data.u.sint = (conn && conn->xprt == &ssl_sock);
Willy Tarreau7875d092012-09-10 08:20:03 +02003967 return 1;
3968}
3969
Emeric Brun2525b6b2012-10-18 15:59:43 +02003970/* boolean, returns true if client present a SNI */
Willy Tarreau7875d092012-09-10 08:20:03 +02003971static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02003972smp_fetch_ssl_fc_has_sni(const struct arg *args, struct sample *smp, const char *kw, void *private)
Willy Tarreau7875d092012-09-10 08:20:03 +02003973{
3974#ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02003975 struct connection *conn = objt_conn(smp->sess->origin);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003976
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02003977 smp->data.type = SMP_T_BOOL;
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02003978 smp->data.u.sint = (conn && conn->xprt == &ssl_sock) &&
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003979 conn->xprt_ctx &&
3980 SSL_get_servername(conn->xprt_ctx, TLSEXT_NAMETYPE_host_name) != NULL;
Willy Tarreau7875d092012-09-10 08:20:03 +02003981 return 1;
3982#else
3983 return 0;
3984#endif
3985}
3986
Nenad Merdanovic26ea8222015-05-18 02:28:57 +02003987/* boolean, returns true if client session has been resumed */
3988static int
3989smp_fetch_ssl_fc_is_resumed(const struct arg *args, struct sample *smp, const char *kw, void *private)
3990{
3991 struct connection *conn = objt_conn(smp->sess->origin);
3992
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02003993 smp->data.type = SMP_T_BOOL;
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02003994 smp->data.u.sint = (conn && conn->xprt == &ssl_sock) &&
Nenad Merdanovic26ea8222015-05-18 02:28:57 +02003995 conn->xprt_ctx &&
3996 SSL_session_reused(conn->xprt_ctx);
3997 return 1;
3998}
3999
Emeric Brun645ae792014-04-30 14:21:06 +02004000/* string, returns the used cipher if front conn. transport layer is SSL.
4001 * This function is also usable on backend conn if the fetch keyword 5th
4002 * char is 'b'.
4003 */
Emeric Brun589fcad2012-10-16 14:13:26 +02004004static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02004005smp_fetch_ssl_fc_cipher(const struct arg *args, struct sample *smp, const char *kw, void *private)
Emeric Brun589fcad2012-10-16 14:13:26 +02004006{
Emeric Brun645ae792014-04-30 14:21:06 +02004007 int back_conn = (kw[4] == 'b') ? 1 : 0;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004008 struct connection *conn;
4009
Emeric Brun589fcad2012-10-16 14:13:26 +02004010 smp->flags = 0;
4011
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02004012 conn = objt_conn(smp->strm->si[back_conn].end);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004013 if (!conn || !conn->xprt_ctx || conn->xprt != &ssl_sock)
Emeric Brun589fcad2012-10-16 14:13:26 +02004014 return 0;
4015
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02004016 smp->data.u.str.str = (char *)SSL_get_cipher_name(conn->xprt_ctx);
4017 if (!smp->data.u.str.str)
Emeric Brun589fcad2012-10-16 14:13:26 +02004018 return 0;
4019
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02004020 smp->data.type = SMP_T_STR;
Thierry FOURNIER7654c9f2013-12-17 00:20:33 +01004021 smp->flags |= SMP_F_CONST;
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02004022 smp->data.u.str.len = strlen(smp->data.u.str.str);
Emeric Brun589fcad2012-10-16 14:13:26 +02004023
4024 return 1;
4025}
4026
Emeric Brun645ae792014-04-30 14:21:06 +02004027/* integer, returns the algoritm's keysize if front conn. transport layer
4028 * is SSL.
4029 * This function is also usable on backend conn if the fetch keyword 5th
4030 * char is 'b'.
4031 */
Emeric Brun589fcad2012-10-16 14:13:26 +02004032static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02004033smp_fetch_ssl_fc_alg_keysize(const struct arg *args, struct sample *smp, const char *kw, void *private)
Emeric Brun589fcad2012-10-16 14:13:26 +02004034{
Emeric Brun645ae792014-04-30 14:21:06 +02004035 int back_conn = (kw[4] == 'b') ? 1 : 0;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004036 struct connection *conn;
Thierry FOURNIER07ee64e2015-07-06 23:43:03 +02004037 int sint;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004038
Emeric Brun589fcad2012-10-16 14:13:26 +02004039 smp->flags = 0;
4040
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02004041 conn = objt_conn(smp->strm->si[back_conn].end);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004042 if (!conn || !conn->xprt_ctx || conn->xprt != &ssl_sock)
Emeric Brun589fcad2012-10-16 14:13:26 +02004043 return 0;
4044
Thierry FOURNIER07ee64e2015-07-06 23:43:03 +02004045 if (!SSL_get_cipher_bits(conn->xprt_ctx, &sint))
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004046 return 0;
4047
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02004048 smp->data.u.sint = sint;
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02004049 smp->data.type = SMP_T_SINT;
Emeric Brun589fcad2012-10-16 14:13:26 +02004050
4051 return 1;
4052}
4053
Emeric Brun645ae792014-04-30 14:21:06 +02004054/* integer, returns the used keysize if front conn. transport layer is SSL.
4055 * This function is also usable on backend conn if the fetch keyword 5th
4056 * char is 'b'.
4057 */
Emeric Brun589fcad2012-10-16 14:13:26 +02004058static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02004059smp_fetch_ssl_fc_use_keysize(const struct arg *args, struct sample *smp, const char *kw, void *private)
Emeric Brun589fcad2012-10-16 14:13:26 +02004060{
Emeric Brun645ae792014-04-30 14:21:06 +02004061 int back_conn = (kw[4] == 'b') ? 1 : 0;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004062 struct connection *conn;
4063
Emeric Brun589fcad2012-10-16 14:13:26 +02004064 smp->flags = 0;
4065
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02004066 conn = objt_conn(smp->strm->si[back_conn].end);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004067 if (!conn || !conn->xprt_ctx || conn->xprt != &ssl_sock)
4068 return 0;
4069
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02004070 smp->data.u.sint = (unsigned int)SSL_get_cipher_bits(conn->xprt_ctx, NULL);
4071 if (!smp->data.u.sint)
Emeric Brun589fcad2012-10-16 14:13:26 +02004072 return 0;
4073
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02004074 smp->data.type = SMP_T_SINT;
Emeric Brun589fcad2012-10-16 14:13:26 +02004075
4076 return 1;
4077}
4078
Willy Tarreau6c9a3d52012-10-18 18:57:14 +02004079#ifdef OPENSSL_NPN_NEGOTIATED
Willy Tarreau7875d092012-09-10 08:20:03 +02004080static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02004081smp_fetch_ssl_fc_npn(const struct arg *args, struct sample *smp, const char *kw, void *private)
Willy Tarreaua33c6542012-10-15 13:19:06 +02004082{
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004083 struct connection *conn;
4084
Thierry FOURNIER7654c9f2013-12-17 00:20:33 +01004085 smp->flags = SMP_F_CONST;
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02004086 smp->data.type = SMP_T_STR;
Willy Tarreaua33c6542012-10-15 13:19:06 +02004087
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02004088 conn = objt_conn(smp->sess->origin);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004089 if (!conn || !conn->xprt_ctx || conn->xprt != &ssl_sock)
4090 return 0;
4091
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02004092 smp->data.u.str.str = NULL;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004093 SSL_get0_next_proto_negotiated(conn->xprt_ctx,
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02004094 (const unsigned char **)&smp->data.u.str.str, (unsigned *)&smp->data.u.str.len);
Willy Tarreaua33c6542012-10-15 13:19:06 +02004095
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02004096 if (!smp->data.u.str.str)
Willy Tarreaua33c6542012-10-15 13:19:06 +02004097 return 0;
4098
4099 return 1;
Willy Tarreaua33c6542012-10-15 13:19:06 +02004100}
Willy Tarreau6c9a3d52012-10-18 18:57:14 +02004101#endif
Willy Tarreaua33c6542012-10-15 13:19:06 +02004102
Dirkjan Bussink48f1c4e2014-02-13 12:29:42 +01004103#ifdef TLSEXT_TYPE_application_layer_protocol_negotiation
Willy Tarreauab861d32013-04-02 02:30:41 +02004104static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02004105smp_fetch_ssl_fc_alpn(const struct arg *args, struct sample *smp, const char *kw, void *private)
Willy Tarreauab861d32013-04-02 02:30:41 +02004106{
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004107 struct connection *conn;
4108
Thierry FOURNIER7654c9f2013-12-17 00:20:33 +01004109 smp->flags = SMP_F_CONST;
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02004110 smp->data.type = SMP_T_STR;
Willy Tarreauab861d32013-04-02 02:30:41 +02004111
Willy Tarreaue26bf052015-05-12 10:30:12 +02004112 conn = objt_conn(smp->sess->origin);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004113 if (!conn || !conn->xprt_ctx || conn->xprt != &ssl_sock)
Willy Tarreauab861d32013-04-02 02:30:41 +02004114 return 0;
4115
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02004116 smp->data.u.str.str = NULL;
Dirkjan Bussink48f1c4e2014-02-13 12:29:42 +01004117 SSL_get0_alpn_selected(conn->xprt_ctx,
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02004118 (const unsigned char **)&smp->data.u.str.str, (unsigned *)&smp->data.u.str.len);
Willy Tarreauab861d32013-04-02 02:30:41 +02004119
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02004120 if (!smp->data.u.str.str)
Willy Tarreauab861d32013-04-02 02:30:41 +02004121 return 0;
4122
4123 return 1;
4124}
4125#endif
4126
Emeric Brun645ae792014-04-30 14:21:06 +02004127/* string, returns the used protocol if front conn. transport layer is SSL.
4128 * This function is also usable on backend conn if the fetch keyword 5th
4129 * char is 'b'.
4130 */
Willy Tarreaua33c6542012-10-15 13:19:06 +02004131static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02004132smp_fetch_ssl_fc_protocol(const struct arg *args, struct sample *smp, const char *kw, void *private)
Emeric Brun589fcad2012-10-16 14:13:26 +02004133{
Emeric Brun645ae792014-04-30 14:21:06 +02004134 int back_conn = (kw[4] == 'b') ? 1 : 0;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004135 struct connection *conn;
4136
Emeric Brun589fcad2012-10-16 14:13:26 +02004137 smp->flags = 0;
4138
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02004139 conn = objt_conn(smp->strm->si[back_conn].end);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004140 if (!conn || !conn->xprt_ctx || conn->xprt != &ssl_sock)
4141 return 0;
4142
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02004143 smp->data.u.str.str = (char *)SSL_get_version(conn->xprt_ctx);
4144 if (!smp->data.u.str.str)
Emeric Brun589fcad2012-10-16 14:13:26 +02004145 return 0;
4146
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02004147 smp->data.type = SMP_T_STR;
Thierry FOURNIER7654c9f2013-12-17 00:20:33 +01004148 smp->flags = SMP_F_CONST;
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02004149 smp->data.u.str.len = strlen(smp->data.u.str.str);
Emeric Brun589fcad2012-10-16 14:13:26 +02004150
4151 return 1;
4152}
4153
Willy Tarreau87b09662015-04-03 00:22:06 +02004154/* binary, returns the SSL stream id if front conn. transport layer is SSL.
Emeric Brun645ae792014-04-30 14:21:06 +02004155 * This function is also usable on backend conn if the fetch keyword 5th
4156 * char is 'b'.
4157 */
Emeric Brun589fcad2012-10-16 14:13:26 +02004158static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02004159smp_fetch_ssl_fc_session_id(const struct arg *args, struct sample *smp, const char *kw, void *private)
Emeric Brunfe68f682012-10-16 14:59:28 +02004160{
4161#if OPENSSL_VERSION_NUMBER > 0x0090800fL
Emeric Brun645ae792014-04-30 14:21:06 +02004162 int back_conn = (kw[4] == 'b') ? 1 : 0;
Willy Tarreau192252e2015-04-04 01:47:55 +02004163 SSL_SESSION *ssl_sess;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004164 struct connection *conn;
Emeric Brunfe68f682012-10-16 14:59:28 +02004165
Thierry FOURNIER7654c9f2013-12-17 00:20:33 +01004166 smp->flags = SMP_F_CONST;
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02004167 smp->data.type = SMP_T_BIN;
Emeric Brunfe68f682012-10-16 14:59:28 +02004168
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02004169 conn = objt_conn(smp->strm->si[back_conn].end);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004170 if (!conn || !conn->xprt_ctx || conn->xprt != &ssl_sock)
4171 return 0;
4172
Willy Tarreau192252e2015-04-04 01:47:55 +02004173 ssl_sess = SSL_get_session(conn->xprt_ctx);
4174 if (!ssl_sess)
Emeric Brunfe68f682012-10-16 14:59:28 +02004175 return 0;
4176
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02004177 smp->data.u.str.str = (char *)SSL_SESSION_get_id(ssl_sess, (unsigned int *)&smp->data.u.str.len);
4178 if (!smp->data.u.str.str || !smp->data.u.str.len)
Emeric Brunfe68f682012-10-16 14:59:28 +02004179 return 0;
4180
4181 return 1;
4182#else
4183 return 0;
4184#endif
4185}
4186
4187static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02004188smp_fetch_ssl_fc_sni(const struct arg *args, struct sample *smp, const char *kw, void *private)
Willy Tarreau7875d092012-09-10 08:20:03 +02004189{
4190#ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004191 struct connection *conn;
4192
Thierry FOURNIER7654c9f2013-12-17 00:20:33 +01004193 smp->flags = SMP_F_CONST;
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02004194 smp->data.type = SMP_T_STR;
Willy Tarreau7875d092012-09-10 08:20:03 +02004195
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02004196 conn = objt_conn(smp->sess->origin);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004197 if (!conn || !conn->xprt_ctx || conn->xprt != &ssl_sock)
4198 return 0;
4199
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02004200 smp->data.u.str.str = (char *)SSL_get_servername(conn->xprt_ctx, TLSEXT_NAMETYPE_host_name);
4201 if (!smp->data.u.str.str)
Willy Tarreau3e394c92012-09-14 23:56:58 +02004202 return 0;
4203
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02004204 smp->data.u.str.len = strlen(smp->data.u.str.str);
Willy Tarreau7875d092012-09-10 08:20:03 +02004205 return 1;
4206#else
4207 return 0;
4208#endif
4209}
4210
David Sc1ad52e2014-04-08 18:48:47 -04004211static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02004212smp_fetch_ssl_fc_unique_id(const struct arg *args, struct sample *smp, const char *kw, void *private)
David Sc1ad52e2014-04-08 18:48:47 -04004213{
4214#if OPENSSL_VERSION_NUMBER > 0x0090800fL
Emeric Brun645ae792014-04-30 14:21:06 +02004215 int back_conn = (kw[4] == 'b') ? 1 : 0;
David Sc1ad52e2014-04-08 18:48:47 -04004216 struct connection *conn;
4217 int finished_len;
David Sc1ad52e2014-04-08 18:48:47 -04004218 struct chunk *finished_trash;
David Sc1ad52e2014-04-08 18:48:47 -04004219
4220 smp->flags = 0;
4221
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02004222 conn = objt_conn(smp->strm->si[back_conn].end);
David Sc1ad52e2014-04-08 18:48:47 -04004223 if (!conn || !conn->xprt_ctx || conn->xprt != &ssl_sock)
4224 return 0;
4225
4226 if (!(conn->flags & CO_FL_CONNECTED)) {
4227 smp->flags |= SMP_F_MAY_CHANGE;
4228 return 0;
4229 }
4230
4231 finished_trash = get_trash_chunk();
4232 if (!SSL_session_reused(conn->xprt_ctx))
4233 finished_len = SSL_get_peer_finished(conn->xprt_ctx, finished_trash->str, finished_trash->size);
4234 else
4235 finished_len = SSL_get_finished(conn->xprt_ctx, finished_trash->str, finished_trash->size);
4236
4237 if (!finished_len)
4238 return 0;
4239
Emeric Brunb73a9b02014-04-30 18:49:19 +02004240 finished_trash->len = finished_len;
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02004241 smp->data.u.str = *finished_trash;
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02004242 smp->data.type = SMP_T_BIN;
David Sc1ad52e2014-04-08 18:48:47 -04004243
4244 return 1;
4245#else
4246 return 0;
4247#endif
4248}
4249
Emeric Brun2525b6b2012-10-18 15:59:43 +02004250/* integer, returns the first verify error in CA chain of client certificate chain. */
Emeric Brunf282a812012-09-21 15:27:54 +02004251static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02004252smp_fetch_ssl_c_ca_err(const struct arg *args, struct sample *smp, const char *kw, void *private)
Emeric Brunf282a812012-09-21 15:27:54 +02004253{
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004254 struct connection *conn;
4255
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02004256 conn = objt_conn(smp->sess->origin);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004257 if (!conn || conn->xprt != &ssl_sock)
4258 return 0;
4259
4260 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brunf282a812012-09-21 15:27:54 +02004261 smp->flags = SMP_F_MAY_CHANGE;
4262 return 0;
4263 }
4264
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02004265 smp->data.type = SMP_T_SINT;
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02004266 smp->data.u.sint = (unsigned long long int)SSL_SOCK_ST_TO_CA_ERROR(conn->xprt_st);
Emeric Brunf282a812012-09-21 15:27:54 +02004267 smp->flags = 0;
4268
4269 return 1;
4270}
4271
Emeric Brun2525b6b2012-10-18 15:59:43 +02004272/* integer, returns the depth of the first verify error in CA chain of client certificate chain. */
Emeric Brunf282a812012-09-21 15:27:54 +02004273static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02004274smp_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 +02004275{
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004276 struct connection *conn;
4277
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02004278 conn = objt_conn(smp->sess->origin);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004279 if (!conn || conn->xprt != &ssl_sock)
Emeric Brunf282a812012-09-21 15:27:54 +02004280 return 0;
4281
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004282 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brunf282a812012-09-21 15:27:54 +02004283 smp->flags = SMP_F_MAY_CHANGE;
4284 return 0;
4285 }
4286
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02004287 smp->data.type = SMP_T_SINT;
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02004288 smp->data.u.sint = (long long int)SSL_SOCK_ST_TO_CAEDEPTH(conn->xprt_st);
Emeric Brunf282a812012-09-21 15:27:54 +02004289 smp->flags = 0;
4290
4291 return 1;
4292}
4293
Emeric Brun2525b6b2012-10-18 15:59:43 +02004294/* integer, returns the first verify error on client certificate */
Emeric Brunf282a812012-09-21 15:27:54 +02004295static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02004296smp_fetch_ssl_c_err(const struct arg *args, struct sample *smp, const char *kw, void *private)
Emeric Brunf282a812012-09-21 15:27:54 +02004297{
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004298 struct connection *conn;
4299
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02004300 conn = objt_conn(smp->sess->origin);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004301 if (!conn || conn->xprt != &ssl_sock)
4302 return 0;
4303
4304 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brunf282a812012-09-21 15:27:54 +02004305 smp->flags = SMP_F_MAY_CHANGE;
4306 return 0;
4307 }
4308
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02004309 smp->data.type = SMP_T_SINT;
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02004310 smp->data.u.sint = (long long int)SSL_SOCK_ST_TO_CRTERROR(conn->xprt_st);
Emeric Brunf282a812012-09-21 15:27:54 +02004311 smp->flags = 0;
4312
4313 return 1;
4314}
4315
Emeric Brun2525b6b2012-10-18 15:59:43 +02004316/* integer, returns the verify result on client cert */
Emeric Brunbaf8ffb2012-09-21 15:27:20 +02004317static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02004318smp_fetch_ssl_c_verify(const struct arg *args, struct sample *smp, const char *kw, void *private)
Emeric Brunbaf8ffb2012-09-21 15:27:20 +02004319{
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004320 struct connection *conn;
4321
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02004322 conn = objt_conn(smp->sess->origin);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004323 if (!conn || conn->xprt != &ssl_sock)
4324 return 0;
4325
4326 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brunbaf8ffb2012-09-21 15:27:20 +02004327 smp->flags = SMP_F_MAY_CHANGE;
4328 return 0;
4329 }
4330
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004331 if (!conn->xprt_ctx)
Emeric Brunbaf8ffb2012-09-21 15:27:20 +02004332 return 0;
4333
Thierry FOURNIER8c542ca2015-08-19 09:00:18 +02004334 smp->data.type = SMP_T_SINT;
Thierry FOURNIER136f9d32015-08-19 09:07:19 +02004335 smp->data.u.sint = (long long int)SSL_get_verify_result(conn->xprt_ctx);
Emeric Brunbaf8ffb2012-09-21 15:27:20 +02004336 smp->flags = 0;
4337
4338 return 1;
4339}
4340
Emeric Brunfb510ea2012-10-05 12:00:26 +02004341/* parse the "ca-file" bind keyword */
4342static 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 +02004343{
4344 if (!*args[cur_arg + 1]) {
4345 if (err)
4346 memprintf(err, "'%s' : missing CAfile path", args[cur_arg]);
4347 return ERR_ALERT | ERR_FATAL;
4348 }
4349
Emeric Brunef42d922012-10-11 16:11:36 +02004350 if ((*args[cur_arg + 1] != '/') && global.ca_base)
4351 memprintf(&conf->ca_file, "%s/%s", global.ca_base, args[cur_arg + 1]);
4352 else
4353 memprintf(&conf->ca_file, "%s", args[cur_arg + 1]);
Emeric Brunc8e8d122012-10-02 18:42:10 +02004354
Emeric Brund94b3fe2012-09-20 18:23:56 +02004355 return 0;
4356}
4357
Christopher Faulet31af49d2015-06-09 17:29:50 +02004358/* parse the "ca-sign-file" bind keyword */
4359static int bind_parse_ca_sign_file(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
4360{
4361 if (!*args[cur_arg + 1]) {
4362 if (err)
4363 memprintf(err, "'%s' : missing CAfile path", args[cur_arg]);
4364 return ERR_ALERT | ERR_FATAL;
4365 }
4366
4367 if ((*args[cur_arg + 1] != '/') && global.ca_base)
4368 memprintf(&conf->ca_sign_file, "%s/%s", global.ca_base, args[cur_arg + 1]);
4369 else
4370 memprintf(&conf->ca_sign_file, "%s", args[cur_arg + 1]);
4371
4372 return 0;
4373}
4374
4375/* parse the ca-sign-pass bind keyword */
4376
4377static int bind_parse_ca_sign_pass(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
4378{
4379 if (!*args[cur_arg + 1]) {
4380 if (err)
4381 memprintf(err, "'%s' : missing CAkey password", args[cur_arg]);
4382 return ERR_ALERT | ERR_FATAL;
4383 }
4384 memprintf(&conf->ca_sign_pass, "%s", args[cur_arg + 1]);
4385 return 0;
4386}
4387
Willy Tarreau79eeafa2012-09-14 07:53:05 +02004388/* parse the "ciphers" bind keyword */
Willy Tarreau4348fad2012-09-20 16:48:07 +02004389static 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 +02004390{
4391 if (!*args[cur_arg + 1]) {
Willy Tarreaueb6cead2012-09-20 19:43:14 +02004392 memprintf(err, "'%s' : missing cipher suite", args[cur_arg]);
Willy Tarreau79eeafa2012-09-14 07:53:05 +02004393 return ERR_ALERT | ERR_FATAL;
4394 }
4395
Emeric Brun76d88952012-10-05 15:47:31 +02004396 free(conf->ciphers);
Willy Tarreau4348fad2012-09-20 16:48:07 +02004397 conf->ciphers = strdup(args[cur_arg + 1]);
Willy Tarreau79eeafa2012-09-14 07:53:05 +02004398 return 0;
4399}
4400
4401/* parse the "crt" bind keyword */
Willy Tarreau4348fad2012-09-20 16:48:07 +02004402static 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 +02004403{
Willy Tarreau38011032013-08-13 16:59:39 +02004404 char path[MAXPATHLEN];
Willy Tarreaub75d6922014-04-14 18:05:41 +02004405
Willy Tarreau79eeafa2012-09-14 07:53:05 +02004406 if (!*args[cur_arg + 1]) {
Willy Tarreaueb6cead2012-09-20 19:43:14 +02004407 memprintf(err, "'%s' : missing certificate location", args[cur_arg]);
Willy Tarreau79eeafa2012-09-14 07:53:05 +02004408 return ERR_ALERT | ERR_FATAL;
4409 }
4410
Emeric Brunc8e8d122012-10-02 18:42:10 +02004411 if ((*args[cur_arg + 1] != '/' ) && global.crt_base) {
Willy Tarreau38011032013-08-13 16:59:39 +02004412 if ((strlen(global.crt_base) + 1 + strlen(args[cur_arg + 1]) + 1) > MAXPATHLEN) {
Emeric Brunc8e8d122012-10-02 18:42:10 +02004413 memprintf(err, "'%s' : path too long", args[cur_arg]);
4414 return ERR_ALERT | ERR_FATAL;
4415 }
Willy Tarreaub75d6922014-04-14 18:05:41 +02004416 snprintf(path, sizeof(path), "%s/%s", global.crt_base, args[cur_arg + 1]);
Emeric Brunc8e8d122012-10-02 18:42:10 +02004417 if (ssl_sock_load_cert(path, conf, px, err) > 0)
4418 return ERR_ALERT | ERR_FATAL;
4419
4420 return 0;
4421 }
4422
Willy Tarreau4348fad2012-09-20 16:48:07 +02004423 if (ssl_sock_load_cert(args[cur_arg + 1], conf, px, err) > 0)
Willy Tarreau79eeafa2012-09-14 07:53:05 +02004424 return ERR_ALERT | ERR_FATAL;
Emeric Brund94b3fe2012-09-20 18:23:56 +02004425
4426 return 0;
4427}
4428
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01004429/* parse the "crt-list" bind keyword */
4430static int bind_parse_crt_list(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
4431{
4432 if (!*args[cur_arg + 1]) {
4433 memprintf(err, "'%s' : missing certificate location", args[cur_arg]);
4434 return ERR_ALERT | ERR_FATAL;
4435 }
4436
Willy Tarreauad1731d2013-04-02 17:35:58 +02004437 if (ssl_sock_load_cert_list_file(args[cur_arg + 1], conf, px, err) > 0) {
4438 memprintf(err, "'%s' : %s", args[cur_arg], *err);
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01004439 return ERR_ALERT | ERR_FATAL;
Willy Tarreauad1731d2013-04-02 17:35:58 +02004440 }
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01004441
4442 return 0;
4443}
4444
Emeric Brunfb510ea2012-10-05 12:00:26 +02004445/* parse the "crl-file" bind keyword */
4446static 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 +02004447{
Emeric Brun051cdab2012-10-02 19:25:50 +02004448#ifndef X509_V_FLAG_CRL_CHECK
4449 if (err)
4450 memprintf(err, "'%s' : library does not support CRL verify", args[cur_arg]);
4451 return ERR_ALERT | ERR_FATAL;
4452#else
Emeric Brund94b3fe2012-09-20 18:23:56 +02004453 if (!*args[cur_arg + 1]) {
4454 if (err)
4455 memprintf(err, "'%s' : missing CRLfile path", args[cur_arg]);
4456 return ERR_ALERT | ERR_FATAL;
4457 }
Emeric Brun2b58d042012-09-20 17:10:03 +02004458
Emeric Brunef42d922012-10-11 16:11:36 +02004459 if ((*args[cur_arg + 1] != '/') && global.ca_base)
4460 memprintf(&conf->crl_file, "%s/%s", global.ca_base, args[cur_arg + 1]);
4461 else
4462 memprintf(&conf->crl_file, "%s", args[cur_arg + 1]);
Emeric Brunc8e8d122012-10-02 18:42:10 +02004463
Emeric Brun2b58d042012-09-20 17:10:03 +02004464 return 0;
Emeric Brun051cdab2012-10-02 19:25:50 +02004465#endif
Emeric Brun2b58d042012-09-20 17:10:03 +02004466}
4467
4468/* parse the "ecdhe" bind keyword keywords */
4469static int bind_parse_ecdhe(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
4470{
4471#if OPENSSL_VERSION_NUMBER < 0x0090800fL
4472 if (err)
4473 memprintf(err, "'%s' : library does not support elliptic curve Diffie-Hellman (too old)", args[cur_arg]);
4474 return ERR_ALERT | ERR_FATAL;
4475#elif defined(OPENSSL_NO_ECDH)
4476 if (err)
4477 memprintf(err, "'%s' : library does not support elliptic curve Diffie-Hellman (disabled via OPENSSL_NO_ECDH)", args[cur_arg]);
4478 return ERR_ALERT | ERR_FATAL;
4479#else
4480 if (!*args[cur_arg + 1]) {
4481 if (err)
4482 memprintf(err, "'%s' : missing named curve", args[cur_arg]);
4483 return ERR_ALERT | ERR_FATAL;
4484 }
4485
4486 conf->ecdhe = strdup(args[cur_arg + 1]);
Willy Tarreau79eeafa2012-09-14 07:53:05 +02004487
4488 return 0;
Emeric Brun2b58d042012-09-20 17:10:03 +02004489#endif
Willy Tarreau79eeafa2012-09-14 07:53:05 +02004490}
4491
Emeric Brun81c00f02012-09-21 14:31:21 +02004492/* parse the "crt_ignerr" and "ca_ignerr" bind keywords */
4493static int bind_parse_ignore_err(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
4494{
4495 int code;
4496 char *p = args[cur_arg + 1];
4497 unsigned long long *ignerr = &conf->crt_ignerr;
4498
4499 if (!*p) {
4500 if (err)
4501 memprintf(err, "'%s' : missing error IDs list", args[cur_arg]);
4502 return ERR_ALERT | ERR_FATAL;
4503 }
4504
4505 if (strcmp(args[cur_arg], "ca-ignore-err") == 0)
4506 ignerr = &conf->ca_ignerr;
4507
4508 if (strcmp(p, "all") == 0) {
4509 *ignerr = ~0ULL;
4510 return 0;
4511 }
4512
4513 while (p) {
4514 code = atoi(p);
4515 if ((code <= 0) || (code > 63)) {
4516 if (err)
4517 memprintf(err, "'%s' : ID '%d' out of range (1..63) in error IDs list '%s'",
4518 args[cur_arg], code, args[cur_arg + 1]);
4519 return ERR_ALERT | ERR_FATAL;
4520 }
4521 *ignerr |= 1ULL << code;
4522 p = strchr(p, ',');
4523 if (p)
4524 p++;
4525 }
4526
Emeric Brun2cb7ae52012-10-05 14:14:21 +02004527 return 0;
4528}
4529
4530/* parse the "force-sslv3" bind keyword */
4531static int bind_parse_force_sslv3(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
4532{
4533 conf->ssl_options |= BC_SSL_O_USE_SSLV3;
4534 return 0;
4535}
4536
4537/* parse the "force-tlsv10" bind keyword */
4538static int bind_parse_force_tlsv10(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
4539{
4540 conf->ssl_options |= BC_SSL_O_USE_TLSV10;
Emeric Brun2d0c4822012-10-02 13:45:20 +02004541 return 0;
4542}
4543
Emeric Brun2cb7ae52012-10-05 14:14:21 +02004544/* parse the "force-tlsv11" bind keyword */
4545static int bind_parse_force_tlsv11(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
4546{
4547#if SSL_OP_NO_TLSv1_1
4548 conf->ssl_options |= BC_SSL_O_USE_TLSV11;
4549 return 0;
4550#else
4551 if (err)
4552 memprintf(err, "'%s' : library does not support protocol TLSv1.1", args[cur_arg]);
4553 return ERR_ALERT | ERR_FATAL;
4554#endif
4555}
4556
4557/* parse the "force-tlsv12" bind keyword */
4558static int bind_parse_force_tlsv12(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
4559{
4560#if SSL_OP_NO_TLSv1_2
4561 conf->ssl_options |= BC_SSL_O_USE_TLSV12;
4562 return 0;
4563#else
4564 if (err)
4565 memprintf(err, "'%s' : library does not support protocol TLSv1.2", args[cur_arg]);
4566 return ERR_ALERT | ERR_FATAL;
4567#endif
4568}
4569
4570
Emeric Brun2d0c4822012-10-02 13:45:20 +02004571/* parse the "no-tls-tickets" bind keyword */
4572static int bind_parse_no_tls_tickets(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
4573{
Emeric Brun89675492012-10-05 13:48:26 +02004574 conf->ssl_options |= BC_SSL_O_NO_TLS_TICKETS;
Emeric Brun81c00f02012-09-21 14:31:21 +02004575 return 0;
4576}
4577
Emeric Brun2d0c4822012-10-02 13:45:20 +02004578
Emeric Brun9b3009b2012-10-05 11:55:06 +02004579/* parse the "no-sslv3" bind keyword */
4580static 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 +02004581{
Emeric Brun89675492012-10-05 13:48:26 +02004582 conf->ssl_options |= BC_SSL_O_NO_SSLV3;
Willy Tarreau79eeafa2012-09-14 07:53:05 +02004583 return 0;
4584}
4585
Emeric Brun9b3009b2012-10-05 11:55:06 +02004586/* parse the "no-tlsv10" bind keyword */
4587static 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 +02004588{
Emeric Brun89675492012-10-05 13:48:26 +02004589 conf->ssl_options |= BC_SSL_O_NO_TLSV10;
Emeric Brunc0ff4922012-09-28 19:37:02 +02004590 return 0;
4591}
4592
Emeric Brun9b3009b2012-10-05 11:55:06 +02004593/* parse the "no-tlsv11" bind keyword */
4594static 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 +02004595{
Emeric Brun89675492012-10-05 13:48:26 +02004596 conf->ssl_options |= BC_SSL_O_NO_TLSV11;
Emeric Brunc0ff4922012-09-28 19:37:02 +02004597 return 0;
4598}
4599
Emeric Brun9b3009b2012-10-05 11:55:06 +02004600/* parse the "no-tlsv12" bind keyword */
4601static 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 +02004602{
Emeric Brun89675492012-10-05 13:48:26 +02004603 conf->ssl_options |= BC_SSL_O_NO_TLSV12;
Willy Tarreau79eeafa2012-09-14 07:53:05 +02004604 return 0;
4605}
4606
Willy Tarreau6c9a3d52012-10-18 18:57:14 +02004607/* parse the "npn" bind keyword */
4608static int bind_parse_npn(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
4609{
4610#ifdef OPENSSL_NPN_NEGOTIATED
4611 char *p1, *p2;
4612
4613 if (!*args[cur_arg + 1]) {
4614 memprintf(err, "'%s' : missing the comma-delimited NPN protocol suite", args[cur_arg]);
4615 return ERR_ALERT | ERR_FATAL;
4616 }
4617
4618 free(conf->npn_str);
4619
4620 /* the NPN string is built as a suite of (<len> <name>)* */
4621 conf->npn_len = strlen(args[cur_arg + 1]) + 1;
4622 conf->npn_str = calloc(1, conf->npn_len);
4623 memcpy(conf->npn_str + 1, args[cur_arg + 1], conf->npn_len);
4624
4625 /* replace commas with the name length */
4626 p1 = conf->npn_str;
4627 p2 = p1 + 1;
4628 while (1) {
4629 p2 = memchr(p1 + 1, ',', conf->npn_str + conf->npn_len - (p1 + 1));
4630 if (!p2)
4631 p2 = p1 + 1 + strlen(p1 + 1);
4632
4633 if (p2 - (p1 + 1) > 255) {
4634 *p2 = '\0';
4635 memprintf(err, "'%s' : NPN protocol name too long : '%s'", args[cur_arg], p1 + 1);
4636 return ERR_ALERT | ERR_FATAL;
4637 }
4638
4639 *p1 = p2 - (p1 + 1);
4640 p1 = p2;
4641
4642 if (!*p2)
4643 break;
4644
4645 *(p2++) = '\0';
4646 }
4647 return 0;
4648#else
4649 if (err)
4650 memprintf(err, "'%s' : library does not support TLS NPN extension", args[cur_arg]);
4651 return ERR_ALERT | ERR_FATAL;
4652#endif
4653}
4654
Willy Tarreauab861d32013-04-02 02:30:41 +02004655/* parse the "alpn" bind keyword */
4656static int bind_parse_alpn(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
4657{
Dirkjan Bussink48f1c4e2014-02-13 12:29:42 +01004658#ifdef TLSEXT_TYPE_application_layer_protocol_negotiation
Willy Tarreauab861d32013-04-02 02:30:41 +02004659 char *p1, *p2;
4660
4661 if (!*args[cur_arg + 1]) {
4662 memprintf(err, "'%s' : missing the comma-delimited ALPN protocol suite", args[cur_arg]);
4663 return ERR_ALERT | ERR_FATAL;
4664 }
4665
4666 free(conf->alpn_str);
4667
4668 /* the ALPN string is built as a suite of (<len> <name>)* */
4669 conf->alpn_len = strlen(args[cur_arg + 1]) + 1;
4670 conf->alpn_str = calloc(1, conf->alpn_len);
4671 memcpy(conf->alpn_str + 1, args[cur_arg + 1], conf->alpn_len);
4672
4673 /* replace commas with the name length */
4674 p1 = conf->alpn_str;
4675 p2 = p1 + 1;
4676 while (1) {
4677 p2 = memchr(p1 + 1, ',', conf->alpn_str + conf->alpn_len - (p1 + 1));
4678 if (!p2)
4679 p2 = p1 + 1 + strlen(p1 + 1);
4680
4681 if (p2 - (p1 + 1) > 255) {
4682 *p2 = '\0';
4683 memprintf(err, "'%s' : ALPN protocol name too long : '%s'", args[cur_arg], p1 + 1);
4684 return ERR_ALERT | ERR_FATAL;
4685 }
4686
4687 *p1 = p2 - (p1 + 1);
4688 p1 = p2;
4689
4690 if (!*p2)
4691 break;
4692
4693 *(p2++) = '\0';
4694 }
4695 return 0;
4696#else
4697 if (err)
4698 memprintf(err, "'%s' : library does not support TLS ALPN extension", args[cur_arg]);
4699 return ERR_ALERT | ERR_FATAL;
4700#endif
4701}
4702
Willy Tarreau79eeafa2012-09-14 07:53:05 +02004703/* parse the "ssl" bind keyword */
Willy Tarreau4348fad2012-09-20 16:48:07 +02004704static 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 +02004705{
Willy Tarreau81796be2012-09-22 19:11:47 +02004706 struct listener *l;
4707
Willy Tarreau4348fad2012-09-20 16:48:07 +02004708 conf->is_ssl = 1;
Emeric Brun76d88952012-10-05 15:47:31 +02004709
4710 if (global.listen_default_ciphers && !conf->ciphers)
4711 conf->ciphers = strdup(global.listen_default_ciphers);
Emeric Brun2c86cbf2014-10-30 15:56:50 +01004712 conf->ssl_options |= global.listen_default_ssloptions;
Emeric Brun76d88952012-10-05 15:47:31 +02004713
Willy Tarreau81796be2012-09-22 19:11:47 +02004714 list_for_each_entry(l, &conf->listeners, by_bind)
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02004715 l->xprt = &ssl_sock;
Willy Tarreau81796be2012-09-22 19:11:47 +02004716
Willy Tarreau79eeafa2012-09-14 07:53:05 +02004717 return 0;
4718}
4719
Christopher Faulet31af49d2015-06-09 17:29:50 +02004720/* parse the "generate-certificates" bind keyword */
4721static int bind_parse_generate_certs(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
4722{
4723#ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME
4724 conf->generate_certs = 1;
4725#else
4726 memprintf(err, "%sthis version of openssl cannot generate SSL certificates.\n",
4727 err && *err ? *err : "");
4728#endif
4729 return 0;
4730}
4731
Emmanuel Hocdet65623372013-01-24 17:17:15 +01004732/* parse the "strict-sni" bind keyword */
4733static int bind_parse_strict_sni(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
4734{
4735 conf->strict_sni = 1;
4736 return 0;
Nenad Merdanovic05552d42015-02-27 19:56:49 +01004737}
4738
4739/* parse the "tls-ticket-keys" bind keyword */
4740static int bind_parse_tls_ticket_keys(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
4741{
4742#if (defined SSL_CTRL_SET_TLSEXT_TICKET_KEY_CB && TLS_TICKETS_NO > 0)
4743 FILE *f;
4744 int i = 0;
4745 char thisline[LINESIZE];
Nenad Merdanovic146defa2015-05-09 08:46:00 +02004746 struct tls_keys_ref *keys_ref;
Nenad Merdanovic05552d42015-02-27 19:56:49 +01004747
4748 if (!*args[cur_arg + 1]) {
4749 if (err)
4750 memprintf(err, "'%s' : missing TLS ticket keys file path", args[cur_arg]);
4751 return ERR_ALERT | ERR_FATAL;
4752 }
4753
Nenad Merdanovic200b0fa2015-05-09 08:46:01 +02004754 keys_ref = tlskeys_ref_lookup(args[cur_arg + 1]);
4755 if(keys_ref) {
4756 conf->keys_ref = keys_ref;
4757 return 0;
4758 }
4759
Nenad Merdanovic146defa2015-05-09 08:46:00 +02004760 keys_ref = malloc(sizeof(struct tls_keys_ref));
4761 keys_ref->tlskeys = malloc(TLS_TICKETS_NO * sizeof(struct tls_sess_key));
Nenad Merdanovic05552d42015-02-27 19:56:49 +01004762
4763 if ((f = fopen(args[cur_arg + 1], "r")) == NULL) {
4764 if (err)
4765 memprintf(err, "'%s' : unable to load ssl tickets keys file", args[cur_arg+1]);
4766 return ERR_ALERT | ERR_FATAL;
4767 }
4768
Nenad Merdanovic146defa2015-05-09 08:46:00 +02004769 keys_ref->filename = strdup(args[cur_arg + 1]);
4770
Nenad Merdanovic05552d42015-02-27 19:56:49 +01004771 while (fgets(thisline, sizeof(thisline), f) != NULL) {
4772 int len = strlen(thisline);
4773 /* Strip newline characters from the end */
4774 if(thisline[len - 1] == '\n')
4775 thisline[--len] = 0;
4776
4777 if(thisline[len - 1] == '\r')
4778 thisline[--len] = 0;
4779
Nenad Merdanovic146defa2015-05-09 08:46:00 +02004780 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 +01004781 if (err)
4782 memprintf(err, "'%s' : unable to decode base64 key on line %d", args[cur_arg+1], i + 1);
4783 return ERR_ALERT | ERR_FATAL;
4784 }
4785 i++;
4786 }
4787
4788 if (i < TLS_TICKETS_NO) {
4789 if (err)
4790 memprintf(err, "'%s' : please supply at least %d keys in the tls-tickets-file", args[cur_arg+1], TLS_TICKETS_NO);
4791 return ERR_ALERT | ERR_FATAL;
4792 }
4793
4794 fclose(f);
4795
4796 /* Use penultimate key for encryption, handle when TLS_TICKETS_NO = 1 */
4797 i-=2;
Nenad Merdanovic146defa2015-05-09 08:46:00 +02004798 keys_ref->tls_ticket_enc_index = i < 0 ? 0 : i;
Nenad Merdanovic200b0fa2015-05-09 08:46:01 +02004799 keys_ref->unique_id = -1;
Nenad Merdanovic146defa2015-05-09 08:46:00 +02004800 conf->keys_ref = keys_ref;
Nenad Merdanovic05552d42015-02-27 19:56:49 +01004801
Nenad Merdanovic200b0fa2015-05-09 08:46:01 +02004802 LIST_ADD(&tlskeys_reference, &keys_ref->list);
4803
Nenad Merdanovic05552d42015-02-27 19:56:49 +01004804 return 0;
4805#else
4806 if (err)
4807 memprintf(err, "'%s' : TLS ticket callback extension not supported", args[cur_arg]);
4808 return ERR_ALERT | ERR_FATAL;
4809#endif /* SSL_CTRL_SET_TLSEXT_TICKET_KEY_CB */
Emmanuel Hocdet65623372013-01-24 17:17:15 +01004810}
4811
Emeric Brund94b3fe2012-09-20 18:23:56 +02004812/* parse the "verify" bind keyword */
4813static int bind_parse_verify(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
4814{
4815 if (!*args[cur_arg + 1]) {
4816 if (err)
4817 memprintf(err, "'%s' : missing verify method", args[cur_arg]);
4818 return ERR_ALERT | ERR_FATAL;
4819 }
4820
4821 if (strcmp(args[cur_arg + 1], "none") == 0)
Emeric Brun850efd52014-01-29 12:24:34 +01004822 conf->verify = SSL_SOCK_VERIFY_NONE;
Emeric Brund94b3fe2012-09-20 18:23:56 +02004823 else if (strcmp(args[cur_arg + 1], "optional") == 0)
Emeric Brun850efd52014-01-29 12:24:34 +01004824 conf->verify = SSL_SOCK_VERIFY_OPTIONAL;
Emeric Brund94b3fe2012-09-20 18:23:56 +02004825 else if (strcmp(args[cur_arg + 1], "required") == 0)
Emeric Brun850efd52014-01-29 12:24:34 +01004826 conf->verify = SSL_SOCK_VERIFY_REQUIRED;
Emeric Brund94b3fe2012-09-20 18:23:56 +02004827 else {
4828 if (err)
4829 memprintf(err, "'%s' : unknown verify method '%s', only 'none', 'optional', and 'required' are supported\n",
4830 args[cur_arg], args[cur_arg + 1]);
4831 return ERR_ALERT | ERR_FATAL;
4832 }
4833
4834 return 0;
4835}
4836
Willy Tarreau92faadf2012-10-10 23:04:25 +02004837/************** "server" keywords ****************/
4838
Emeric Brunef42d922012-10-11 16:11:36 +02004839/* parse the "ca-file" server keyword */
4840static int srv_parse_ca_file(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
4841{
4842 if (!*args[*cur_arg + 1]) {
4843 if (err)
4844 memprintf(err, "'%s' : missing CAfile path", args[*cur_arg]);
4845 return ERR_ALERT | ERR_FATAL;
4846 }
4847
4848 if ((*args[*cur_arg + 1] != '/') && global.ca_base)
4849 memprintf(&newsrv->ssl_ctx.ca_file, "%s/%s", global.ca_base, args[*cur_arg + 1]);
4850 else
4851 memprintf(&newsrv->ssl_ctx.ca_file, "%s", args[*cur_arg + 1]);
4852
4853 return 0;
4854}
4855
Willy Tarreau92faadf2012-10-10 23:04:25 +02004856/* parse the "check-ssl" server keyword */
4857static int srv_parse_check_ssl(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
4858{
4859 newsrv->check.use_ssl = 1;
4860 if (global.connect_default_ciphers && !newsrv->ssl_ctx.ciphers)
4861 newsrv->ssl_ctx.ciphers = strdup(global.connect_default_ciphers);
Emeric Brun2c86cbf2014-10-30 15:56:50 +01004862 newsrv->ssl_ctx.options |= global.connect_default_ssloptions;
Willy Tarreau92faadf2012-10-10 23:04:25 +02004863 return 0;
4864}
4865
4866/* parse the "ciphers" server keyword */
4867static int srv_parse_ciphers(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
4868{
4869 if (!*args[*cur_arg + 1]) {
4870 memprintf(err, "'%s' : missing cipher suite", args[*cur_arg]);
4871 return ERR_ALERT | ERR_FATAL;
4872 }
4873
4874 free(newsrv->ssl_ctx.ciphers);
4875 newsrv->ssl_ctx.ciphers = strdup(args[*cur_arg + 1]);
4876 return 0;
4877}
4878
Emeric Brunef42d922012-10-11 16:11:36 +02004879/* parse the "crl-file" server keyword */
4880static int srv_parse_crl_file(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
4881{
4882#ifndef X509_V_FLAG_CRL_CHECK
4883 if (err)
4884 memprintf(err, "'%s' : library does not support CRL verify", args[*cur_arg]);
4885 return ERR_ALERT | ERR_FATAL;
4886#else
4887 if (!*args[*cur_arg + 1]) {
4888 if (err)
4889 memprintf(err, "'%s' : missing CRLfile path", args[*cur_arg]);
4890 return ERR_ALERT | ERR_FATAL;
4891 }
4892
4893 if ((*args[*cur_arg + 1] != '/') && global.ca_base)
4894 memprintf(&newsrv->ssl_ctx.crl_file, "%s/%s", global.ca_base, args[*cur_arg + 1]);
4895 else
4896 memprintf(&newsrv->ssl_ctx.crl_file, "%s", args[*cur_arg + 1]);
4897
4898 return 0;
4899#endif
4900}
4901
Emeric Bruna7aa3092012-10-26 12:58:00 +02004902/* parse the "crt" server keyword */
4903static int srv_parse_crt(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
4904{
4905 if (!*args[*cur_arg + 1]) {
4906 if (err)
4907 memprintf(err, "'%s' : missing certificate file path", args[*cur_arg]);
4908 return ERR_ALERT | ERR_FATAL;
4909 }
4910
4911 if ((*args[*cur_arg + 1] != '/') && global.crt_base)
4912 memprintf(&newsrv->ssl_ctx.client_crt, "%s/%s", global.ca_base, args[*cur_arg + 1]);
4913 else
4914 memprintf(&newsrv->ssl_ctx.client_crt, "%s", args[*cur_arg + 1]);
4915
4916 return 0;
4917}
Emeric Brunef42d922012-10-11 16:11:36 +02004918
Willy Tarreau92faadf2012-10-10 23:04:25 +02004919/* parse the "force-sslv3" server keyword */
4920static int srv_parse_force_sslv3(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
4921{
4922 newsrv->ssl_ctx.options |= SRV_SSL_O_USE_SSLV3;
4923 return 0;
4924}
4925
4926/* parse the "force-tlsv10" server keyword */
4927static int srv_parse_force_tlsv10(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
4928{
4929 newsrv->ssl_ctx.options |= SRV_SSL_O_USE_TLSV10;
4930 return 0;
4931}
4932
4933/* parse the "force-tlsv11" server keyword */
4934static int srv_parse_force_tlsv11(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
4935{
4936#if SSL_OP_NO_TLSv1_1
4937 newsrv->ssl_ctx.options |= SRV_SSL_O_USE_TLSV11;
4938 return 0;
4939#else
4940 if (err)
4941 memprintf(err, "'%s' : library does not support protocol TLSv1.1", args[*cur_arg]);
4942 return ERR_ALERT | ERR_FATAL;
4943#endif
4944}
4945
4946/* parse the "force-tlsv12" server keyword */
4947static int srv_parse_force_tlsv12(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
4948{
4949#if SSL_OP_NO_TLSv1_2
4950 newsrv->ssl_ctx.options |= SRV_SSL_O_USE_TLSV12;
4951 return 0;
4952#else
4953 if (err)
4954 memprintf(err, "'%s' : library does not support protocol TLSv1.2", args[*cur_arg]);
4955 return ERR_ALERT | ERR_FATAL;
4956#endif
4957}
4958
Willy Tarreau2a3fb1c2015-02-05 16:47:07 +01004959/* parse the "no-ssl-reuse" server keyword */
4960static int srv_parse_no_ssl_reuse(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
4961{
4962 newsrv->ssl_ctx.options |= SRV_SSL_O_NO_REUSE;
4963 return 0;
4964}
4965
Willy Tarreau92faadf2012-10-10 23:04:25 +02004966/* parse the "no-sslv3" server keyword */
4967static int srv_parse_no_sslv3(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
4968{
4969 newsrv->ssl_ctx.options |= SRV_SSL_O_NO_SSLV3;
4970 return 0;
4971}
4972
4973/* parse the "no-tlsv10" server keyword */
4974static int srv_parse_no_tlsv10(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
4975{
4976 newsrv->ssl_ctx.options |= SRV_SSL_O_NO_TLSV10;
4977 return 0;
4978}
4979
4980/* parse the "no-tlsv11" server keyword */
4981static int srv_parse_no_tlsv11(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
4982{
4983 newsrv->ssl_ctx.options |= SRV_SSL_O_NO_TLSV11;
4984 return 0;
4985}
4986
4987/* parse the "no-tlsv12" server keyword */
4988static int srv_parse_no_tlsv12(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
4989{
4990 newsrv->ssl_ctx.options |= SRV_SSL_O_NO_TLSV12;
4991 return 0;
4992}
4993
Emeric Brunf9c5c472012-10-11 15:28:34 +02004994/* parse the "no-tls-tickets" server keyword */
4995static int srv_parse_no_tls_tickets(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
4996{
4997 newsrv->ssl_ctx.options |= SRV_SSL_O_NO_TLS_TICKETS;
4998 return 0;
4999}
David Safb76832014-05-08 23:42:08 -04005000/* parse the "send-proxy-v2-ssl" server keyword */
5001static int srv_parse_send_proxy_ssl(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
5002{
5003 newsrv->pp_opts |= SRV_PP_V2;
5004 newsrv->pp_opts |= SRV_PP_V2_SSL;
5005 return 0;
5006}
5007
5008/* parse the "send-proxy-v2-ssl-cn" server keyword */
5009static int srv_parse_send_proxy_cn(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
5010{
5011 newsrv->pp_opts |= SRV_PP_V2;
5012 newsrv->pp_opts |= SRV_PP_V2_SSL;
5013 newsrv->pp_opts |= SRV_PP_V2_SSL_CN;
5014 return 0;
5015}
Emeric Brunf9c5c472012-10-11 15:28:34 +02005016
Willy Tarreau732eac42015-07-09 11:40:25 +02005017/* parse the "sni" server keyword */
5018static int srv_parse_sni(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
5019{
5020#ifndef SSL_CTRL_SET_TLSEXT_HOSTNAME
5021 memprintf(err, "'%s' : the current SSL library doesn't support the SNI TLS extension", args[*cur_arg]);
5022 return ERR_ALERT | ERR_FATAL;
5023#else
5024 struct sample_expr *expr;
5025
5026 if (!*args[*cur_arg + 1]) {
5027 memprintf(err, "'%s' : missing sni expression", args[*cur_arg]);
5028 return ERR_ALERT | ERR_FATAL;
5029 }
5030
5031 (*cur_arg)++;
5032 proxy->conf.args.ctx = ARGC_SRV;
5033
5034 expr = sample_parse_expr((char **)args, cur_arg, px->conf.file, px->conf.line, err, &proxy->conf.args);
5035 if (!expr) {
5036 memprintf(err, "error detected while parsing sni expression : %s", *err);
5037 return ERR_ALERT | ERR_FATAL;
5038 }
5039
5040 if (!(expr->fetch->val & SMP_VAL_BE_SRV_CON)) {
5041 memprintf(err, "error detected while parsing sni expression : "
5042 " fetch method '%s' extracts information from '%s', none of which is available here.\n",
5043 args[*cur_arg-1], sample_src_names(expr->fetch->use));
5044 return ERR_ALERT | ERR_FATAL;
5045 }
5046
5047 px->http_needed |= !!(expr->fetch->use & SMP_USE_HTTP_ANY);
5048 newsrv->ssl_ctx.sni = expr;
5049 return 0;
5050#endif
5051}
5052
Willy Tarreau92faadf2012-10-10 23:04:25 +02005053/* parse the "ssl" server keyword */
5054static int srv_parse_ssl(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
5055{
5056 newsrv->use_ssl = 1;
5057 if (global.connect_default_ciphers && !newsrv->ssl_ctx.ciphers)
5058 newsrv->ssl_ctx.ciphers = strdup(global.connect_default_ciphers);
5059 return 0;
5060}
5061
Emeric Brunef42d922012-10-11 16:11:36 +02005062/* parse the "verify" server keyword */
5063static int srv_parse_verify(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
5064{
5065 if (!*args[*cur_arg + 1]) {
5066 if (err)
5067 memprintf(err, "'%s' : missing verify method", args[*cur_arg]);
5068 return ERR_ALERT | ERR_FATAL;
5069 }
5070
5071 if (strcmp(args[*cur_arg + 1], "none") == 0)
Emeric Brun850efd52014-01-29 12:24:34 +01005072 newsrv->ssl_ctx.verify = SSL_SOCK_VERIFY_NONE;
Emeric Brunef42d922012-10-11 16:11:36 +02005073 else if (strcmp(args[*cur_arg + 1], "required") == 0)
Emeric Brun850efd52014-01-29 12:24:34 +01005074 newsrv->ssl_ctx.verify = SSL_SOCK_VERIFY_REQUIRED;
Emeric Brunef42d922012-10-11 16:11:36 +02005075 else {
5076 if (err)
5077 memprintf(err, "'%s' : unknown verify method '%s', only 'none' and 'required' are supported\n",
5078 args[*cur_arg], args[*cur_arg + 1]);
5079 return ERR_ALERT | ERR_FATAL;
5080 }
5081
Evan Broderbe554312013-06-27 00:05:25 -07005082 return 0;
5083}
5084
5085/* parse the "verifyhost" server keyword */
5086static int srv_parse_verifyhost(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
5087{
5088 if (!*args[*cur_arg + 1]) {
5089 if (err)
5090 memprintf(err, "'%s' : missing hostname to verify against", args[*cur_arg]);
5091 return ERR_ALERT | ERR_FATAL;
5092 }
5093
5094 newsrv->ssl_ctx.verify_host = strdup(args[*cur_arg + 1]);
5095
Emeric Brunef42d922012-10-11 16:11:36 +02005096 return 0;
5097}
5098
Emeric Brun2c86cbf2014-10-30 15:56:50 +01005099/* parse the "ssl-default-bind-options" keyword in global section */
5100static int ssl_parse_default_bind_options(char **args, int section_type, struct proxy *curpx,
5101 struct proxy *defpx, const char *file, int line,
5102 char **err) {
5103 int i = 1;
5104
5105 if (*(args[i]) == 0) {
5106 memprintf(err, "global statement '%s' expects an option as an argument.", args[0]);
5107 return -1;
5108 }
5109 while (*(args[i])) {
5110 if (!strcmp(args[i], "no-sslv3"))
5111 global.listen_default_ssloptions |= BC_SSL_O_NO_SSLV3;
5112 else if (!strcmp(args[i], "no-tlsv10"))
5113 global.listen_default_ssloptions |= BC_SSL_O_NO_TLSV10;
5114 else if (!strcmp(args[i], "no-tlsv11"))
5115 global.listen_default_ssloptions |= BC_SSL_O_NO_TLSV11;
5116 else if (!strcmp(args[i], "no-tlsv12"))
5117 global.listen_default_ssloptions |= BC_SSL_O_NO_TLSV12;
5118 else if (!strcmp(args[i], "force-sslv3"))
5119 global.listen_default_ssloptions |= BC_SSL_O_USE_SSLV3;
5120 else if (!strcmp(args[i], "force-tlsv10"))
5121 global.listen_default_ssloptions |= BC_SSL_O_USE_TLSV10;
5122 else if (!strcmp(args[i], "force-tlsv11")) {
5123#if SSL_OP_NO_TLSv1_1
5124 global.listen_default_ssloptions |= BC_SSL_O_USE_TLSV11;
5125#else
5126 memprintf(err, "'%s' '%s': library does not support protocol TLSv1.1", args[0], args[i]);
5127 return -1;
5128#endif
5129 }
5130 else if (!strcmp(args[i], "force-tlsv12")) {
5131#if SSL_OP_NO_TLSv1_2
5132 global.listen_default_ssloptions |= BC_SSL_O_USE_TLSV12;
5133#else
5134 memprintf(err, "'%s' '%s': library does not support protocol TLSv1.2", args[0], args[i]);
5135 return -1;
5136#endif
5137 }
5138 else if (!strcmp(args[i], "no-tls-tickets"))
5139 global.listen_default_ssloptions |= BC_SSL_O_NO_TLS_TICKETS;
5140 else {
5141 memprintf(err, "unknown option '%s' on global statement '%s'.", args[i], args[0]);
5142 return -1;
5143 }
5144 i++;
5145 }
5146 return 0;
5147}
5148
5149/* parse the "ssl-default-server-options" keyword in global section */
5150static int ssl_parse_default_server_options(char **args, int section_type, struct proxy *curpx,
5151 struct proxy *defpx, const char *file, int line,
5152 char **err) {
5153 int i = 1;
5154
5155 if (*(args[i]) == 0) {
5156 memprintf(err, "global statement '%s' expects an option as an argument.", args[0]);
5157 return -1;
5158 }
5159 while (*(args[i])) {
5160 if (!strcmp(args[i], "no-sslv3"))
5161 global.connect_default_ssloptions |= SRV_SSL_O_NO_SSLV3;
5162 else if (!strcmp(args[i], "no-tlsv10"))
5163 global.connect_default_ssloptions |= SRV_SSL_O_NO_TLSV10;
5164 else if (!strcmp(args[i], "no-tlsv11"))
5165 global.connect_default_ssloptions |= SRV_SSL_O_NO_TLSV11;
5166 else if (!strcmp(args[i], "no-tlsv12"))
5167 global.connect_default_ssloptions |= SRV_SSL_O_NO_TLSV12;
5168 else if (!strcmp(args[i], "force-sslv3"))
5169 global.connect_default_ssloptions |= SRV_SSL_O_USE_SSLV3;
5170 else if (!strcmp(args[i], "force-tlsv10"))
5171 global.connect_default_ssloptions |= SRV_SSL_O_USE_TLSV10;
5172 else if (!strcmp(args[i], "force-tlsv11")) {
5173#if SSL_OP_NO_TLSv1_1
5174 global.connect_default_ssloptions |= SRV_SSL_O_USE_TLSV11;
5175#else
5176 memprintf(err, "'%s' '%s': library does not support protocol TLSv1.1", args[0], args[i]);
5177 return -1;
5178#endif
5179 }
5180 else if (!strcmp(args[i], "force-tlsv12")) {
5181#if SSL_OP_NO_TLSv1_2
5182 global.connect_default_ssloptions |= SRV_SSL_O_USE_TLSV12;
5183#else
5184 memprintf(err, "'%s' '%s': library does not support protocol TLSv1.2", args[0], args[i]);
5185 return -1;
5186#endif
5187 }
5188 else if (!strcmp(args[i], "no-tls-tickets"))
5189 global.connect_default_ssloptions |= SRV_SSL_O_NO_TLS_TICKETS;
5190 else {
5191 memprintf(err, "unknown option '%s' on global statement '%s'.", args[i], args[0]);
5192 return -1;
5193 }
5194 i++;
5195 }
5196 return 0;
5197}
5198
Willy Tarreau7875d092012-09-10 08:20:03 +02005199/* Note: must not be declared <const> as its list will be overwritten.
5200 * Please take care of keeping this list alphabetically sorted.
5201 */
Willy Tarreaudc13c112013-06-21 23:16:39 +02005202static struct sample_fetch_kw_list sample_fetch_keywords = {ILH, {
Emeric Brun645ae792014-04-30 14:21:06 +02005203 { "ssl_bc", smp_fetch_ssl_fc, 0, NULL, SMP_T_BOOL, SMP_USE_L5SRV },
Thierry FOURNIER07ee64e2015-07-06 23:43:03 +02005204 { "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 +02005205 { "ssl_bc_cipher", smp_fetch_ssl_fc_cipher, 0, NULL, SMP_T_STR, SMP_USE_L5SRV },
5206 { "ssl_bc_protocol", smp_fetch_ssl_fc_protocol, 0, NULL, SMP_T_STR, SMP_USE_L5SRV },
Emeric Brunb73a9b02014-04-30 18:49:19 +02005207 { "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 +02005208 { "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 +02005209 { "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 +02005210 { "ssl_c_ca_err", smp_fetch_ssl_c_ca_err, 0, NULL, SMP_T_SINT, SMP_USE_L5CLI },
5211 { "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 +01005212 { "ssl_c_der", smp_fetch_ssl_x_der, 0, NULL, SMP_T_BIN, SMP_USE_L5CLI },
Thierry FOURNIER07ee64e2015-07-06 23:43:03 +02005213 { "ssl_c_err", smp_fetch_ssl_c_err, 0, NULL, SMP_T_SINT, SMP_USE_L5CLI },
Emeric Brunba841a12014-04-30 17:05:08 +02005214 { "ssl_c_i_dn", smp_fetch_ssl_x_i_dn, ARG2(0,STR,SINT), NULL, SMP_T_STR, SMP_USE_L5CLI },
5215 { "ssl_c_key_alg", smp_fetch_ssl_x_key_alg, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
5216 { "ssl_c_notafter", smp_fetch_ssl_x_notafter, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
5217 { "ssl_c_notbefore", smp_fetch_ssl_x_notbefore, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
5218 { "ssl_c_sig_alg", smp_fetch_ssl_x_sig_alg, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
5219 { "ssl_c_s_dn", smp_fetch_ssl_x_s_dn, ARG2(0,STR,SINT), NULL, SMP_T_STR, SMP_USE_L5CLI },
5220 { "ssl_c_serial", smp_fetch_ssl_x_serial, 0, NULL, SMP_T_BIN, SMP_USE_L5CLI },
5221 { "ssl_c_sha1", smp_fetch_ssl_x_sha1, 0, NULL, SMP_T_BIN, SMP_USE_L5CLI },
Willy Tarreau80aca902013-01-07 15:42:20 +01005222 { "ssl_c_used", smp_fetch_ssl_c_used, 0, NULL, SMP_T_BOOL, SMP_USE_L5CLI },
Thierry FOURNIER07ee64e2015-07-06 23:43:03 +02005223 { "ssl_c_verify", smp_fetch_ssl_c_verify, 0, NULL, SMP_T_SINT, SMP_USE_L5CLI },
5224 { "ssl_c_version", smp_fetch_ssl_x_version, 0, NULL, SMP_T_SINT, SMP_USE_L5CLI },
Emeric Brun43e79582014-10-29 19:03:26 +01005225 { "ssl_f_der", smp_fetch_ssl_x_der, 0, NULL, SMP_T_BIN, SMP_USE_L5CLI },
Emeric Brunba841a12014-04-30 17:05:08 +02005226 { "ssl_f_i_dn", smp_fetch_ssl_x_i_dn, ARG2(0,STR,SINT), NULL, SMP_T_STR, SMP_USE_L5CLI },
5227 { "ssl_f_key_alg", smp_fetch_ssl_x_key_alg, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
5228 { "ssl_f_notafter", smp_fetch_ssl_x_notafter, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
5229 { "ssl_f_notbefore", smp_fetch_ssl_x_notbefore, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
5230 { "ssl_f_sig_alg", smp_fetch_ssl_x_sig_alg, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
5231 { "ssl_f_s_dn", smp_fetch_ssl_x_s_dn, ARG2(0,STR,SINT), NULL, SMP_T_STR, SMP_USE_L5CLI },
5232 { "ssl_f_serial", smp_fetch_ssl_x_serial, 0, NULL, SMP_T_BIN, SMP_USE_L5CLI },
Emeric Brun55f4fa82014-04-30 17:11:25 +02005233 { "ssl_f_sha1", smp_fetch_ssl_x_sha1, 0, NULL, SMP_T_BIN, SMP_USE_L5CLI },
Thierry FOURNIER07ee64e2015-07-06 23:43:03 +02005234 { "ssl_f_version", smp_fetch_ssl_x_version, 0, NULL, SMP_T_SINT, SMP_USE_L5CLI },
Willy Tarreau80aca902013-01-07 15:42:20 +01005235 { "ssl_fc", smp_fetch_ssl_fc, 0, NULL, SMP_T_BOOL, SMP_USE_L5CLI },
Thierry FOURNIER07ee64e2015-07-06 23:43:03 +02005236 { "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 +01005237 { "ssl_fc_cipher", smp_fetch_ssl_fc_cipher, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
Willy Tarreau80aca902013-01-07 15:42:20 +01005238 { "ssl_fc_has_crt", smp_fetch_ssl_fc_has_crt, 0, NULL, SMP_T_BOOL, SMP_USE_L5CLI },
5239 { "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 +02005240 { "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 +02005241#ifdef OPENSSL_NPN_NEGOTIATED
Thierry FOURNIER7654c9f2013-12-17 00:20:33 +01005242 { "ssl_fc_npn", smp_fetch_ssl_fc_npn, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
Willy Tarreaua33c6542012-10-15 13:19:06 +02005243#endif
Dirkjan Bussink48f1c4e2014-02-13 12:29:42 +01005244#ifdef TLSEXT_TYPE_application_layer_protocol_negotiation
Thierry FOURNIER7654c9f2013-12-17 00:20:33 +01005245 { "ssl_fc_alpn", smp_fetch_ssl_fc_alpn, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
Willy Tarreauab861d32013-04-02 02:30:41 +02005246#endif
Thierry FOURNIER7654c9f2013-12-17 00:20:33 +01005247 { "ssl_fc_protocol", smp_fetch_ssl_fc_protocol, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
Emeric Brunb73a9b02014-04-30 18:49:19 +02005248 { "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 +02005249 { "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 +01005250 { "ssl_fc_session_id", smp_fetch_ssl_fc_session_id, 0, NULL, SMP_T_BIN, SMP_USE_L5CLI },
5251 { "ssl_fc_sni", smp_fetch_ssl_fc_sni, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
Willy Tarreau7875d092012-09-10 08:20:03 +02005252 { NULL, NULL, 0, 0, 0 },
5253}};
5254
5255/* Note: must not be declared <const> as its list will be overwritten.
5256 * Please take care of keeping this list alphabetically sorted.
5257 */
Willy Tarreaudc13c112013-06-21 23:16:39 +02005258static struct acl_kw_list acl_kws = {ILH, {
Thierry FOURNIERc5a4e982014-03-05 16:07:08 +01005259 { "ssl_fc_sni_end", "ssl_fc_sni", PAT_MATCH_END },
5260 { "ssl_fc_sni_reg", "ssl_fc_sni", PAT_MATCH_REG },
Willy Tarreau8ed669b2013-01-11 15:49:37 +01005261 { /* END */ },
Willy Tarreau7875d092012-09-10 08:20:03 +02005262}};
5263
Willy Tarreau79eeafa2012-09-14 07:53:05 +02005264/* Note: must not be declared <const> as its list will be overwritten.
5265 * Please take care of keeping this list alphabetically sorted, doing so helps
5266 * all code contributors.
5267 * Optional keywords are also declared with a NULL ->parse() function so that
5268 * the config parser can report an appropriate error when a known keyword was
5269 * not enabled.
5270 */
Willy Tarreau51fb7652012-09-18 18:24:39 +02005271static struct bind_kw_list bind_kws = { "SSL", { }, {
Nenad Merdanovic05552d42015-02-27 19:56:49 +01005272 { "alpn", bind_parse_alpn, 1 }, /* set ALPN supported protocols */
5273 { "ca-file", bind_parse_ca_file, 1 }, /* set CAfile to process verify on client cert */
5274 { "ca-ignore-err", bind_parse_ignore_err, 1 }, /* set error IDs to ignore on verify depth > 0 */
Christopher Faulet31af49d2015-06-09 17:29:50 +02005275 { "ca-sign-file", bind_parse_ca_sign_file, 1 }, /* set CAFile used to generate and sign server certs */
5276 { "ca-sign-pass", bind_parse_ca_sign_pass, 1 }, /* set CAKey passphrase */
Nenad Merdanovic05552d42015-02-27 19:56:49 +01005277 { "ciphers", bind_parse_ciphers, 1 }, /* set SSL cipher suite */
5278 { "crl-file", bind_parse_crl_file, 1 }, /* set certificat revocation list file use on client cert verify */
5279 { "crt", bind_parse_crt, 1 }, /* load SSL certificates from this location */
5280 { "crt-ignore-err", bind_parse_ignore_err, 1 }, /* set error IDs to ingore on verify depth == 0 */
5281 { "crt-list", bind_parse_crt_list, 1 }, /* load a list of crt from this location */
5282 { "ecdhe", bind_parse_ecdhe, 1 }, /* defines named curve for elliptic curve Diffie-Hellman */
5283 { "force-sslv3", bind_parse_force_sslv3, 0 }, /* force SSLv3 */
5284 { "force-tlsv10", bind_parse_force_tlsv10, 0 }, /* force TLSv10 */
5285 { "force-tlsv11", bind_parse_force_tlsv11, 0 }, /* force TLSv11 */
5286 { "force-tlsv12", bind_parse_force_tlsv12, 0 }, /* force TLSv12 */
Christopher Faulet31af49d2015-06-09 17:29:50 +02005287 { "generate-certificates", bind_parse_generate_certs, 0 }, /* enable the server certificates generation */
Nenad Merdanovic05552d42015-02-27 19:56:49 +01005288 { "no-sslv3", bind_parse_no_sslv3, 0 }, /* disable SSLv3 */
5289 { "no-tlsv10", bind_parse_no_tlsv10, 0 }, /* disable TLSv10 */
5290 { "no-tlsv11", bind_parse_no_tlsv11, 0 }, /* disable TLSv11 */
5291 { "no-tlsv12", bind_parse_no_tlsv12, 0 }, /* disable TLSv12 */
5292 { "no-tls-tickets", bind_parse_no_tls_tickets, 0 }, /* disable session resumption tickets */
5293 { "ssl", bind_parse_ssl, 0 }, /* enable SSL processing */
5294 { "strict-sni", bind_parse_strict_sni, 0 }, /* refuse negotiation if sni doesn't match a certificate */
5295 { "tls-ticket-keys", bind_parse_tls_ticket_keys, 1 }, /* set file to load TLS ticket keys from */
5296 { "verify", bind_parse_verify, 1 }, /* set SSL verify method */
5297 { "npn", bind_parse_npn, 1 }, /* set NPN supported protocols */
Willy Tarreau79eeafa2012-09-14 07:53:05 +02005298 { NULL, NULL, 0 },
5299}};
Emeric Brun46591952012-05-18 15:47:34 +02005300
Willy Tarreau92faadf2012-10-10 23:04:25 +02005301/* Note: must not be declared <const> as its list will be overwritten.
5302 * Please take care of keeping this list alphabetically sorted, doing so helps
5303 * all code contributors.
5304 * Optional keywords are also declared with a NULL ->parse() function so that
5305 * the config parser can report an appropriate error when a known keyword was
5306 * not enabled.
5307 */
5308static struct srv_kw_list srv_kws = { "SSL", { }, {
Emeric Brunef42d922012-10-11 16:11:36 +02005309 { "ca-file", srv_parse_ca_file, 1, 0 }, /* set CAfile to process verify server cert */
Emeric Brunecc91fe2012-10-11 15:05:10 +02005310 { "check-ssl", srv_parse_check_ssl, 0, 0 }, /* enable SSL for health checks */
5311 { "ciphers", srv_parse_ciphers, 1, 0 }, /* select the cipher suite */
Emeric Brunef42d922012-10-11 16:11:36 +02005312 { "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 +02005313 { "crt", srv_parse_crt, 1, 0 }, /* set client certificate */
Emeric Brunecc91fe2012-10-11 15:05:10 +02005314 { "force-sslv3", srv_parse_force_sslv3, 0, 0 }, /* force SSLv3 */
5315 { "force-tlsv10", srv_parse_force_tlsv10, 0, 0 }, /* force TLSv10 */
5316 { "force-tlsv11", srv_parse_force_tlsv11, 0, 0 }, /* force TLSv11 */
5317 { "force-tlsv12", srv_parse_force_tlsv12, 0, 0 }, /* force TLSv12 */
Willy Tarreau2a3fb1c2015-02-05 16:47:07 +01005318 { "no-ssl-reuse", srv_parse_no_ssl_reuse, 0, 0 }, /* disable session reuse */
Emeric Brunecc91fe2012-10-11 15:05:10 +02005319 { "no-sslv3", srv_parse_no_sslv3, 0, 0 }, /* disable SSLv3 */
5320 { "no-tlsv10", srv_parse_no_tlsv10, 0, 0 }, /* disable TLSv10 */
5321 { "no-tlsv11", srv_parse_no_tlsv11, 0, 0 }, /* disable TLSv11 */
5322 { "no-tlsv12", srv_parse_no_tlsv12, 0, 0 }, /* disable TLSv12 */
Emeric Brunf9c5c472012-10-11 15:28:34 +02005323 { "no-tls-tickets", srv_parse_no_tls_tickets, 0, 0 }, /* disable session resumption tickets */
David Safb76832014-05-08 23:42:08 -04005324 { "send-proxy-v2-ssl", srv_parse_send_proxy_ssl, 0, 0 }, /* send PROXY protocol header v2 with SSL info */
5325 { "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 +02005326 { "sni", srv_parse_sni, 1, 0 }, /* send SNI extension */
Emeric Brunecc91fe2012-10-11 15:05:10 +02005327 { "ssl", srv_parse_ssl, 0, 0 }, /* enable SSL processing */
Emeric Brunef42d922012-10-11 16:11:36 +02005328 { "verify", srv_parse_verify, 1, 0 }, /* set SSL verify method */
Evan Broderbe554312013-06-27 00:05:25 -07005329 { "verifyhost", srv_parse_verifyhost, 1, 0 }, /* require that SSL cert verifies for hostname */
Willy Tarreau92faadf2012-10-10 23:04:25 +02005330 { NULL, NULL, 0, 0 },
5331}};
5332
Emeric Brun2c86cbf2014-10-30 15:56:50 +01005333static struct cfg_kw_list cfg_kws = {ILH, {
5334 { CFG_GLOBAL, "ssl-default-bind-options", ssl_parse_default_bind_options },
5335 { CFG_GLOBAL, "ssl-default-server-options", ssl_parse_default_server_options },
5336 { 0, NULL, NULL },
5337}};
5338
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02005339/* transport-layer operations for SSL sockets */
5340struct xprt_ops ssl_sock = {
Emeric Brun46591952012-05-18 15:47:34 +02005341 .snd_buf = ssl_sock_from_buf,
5342 .rcv_buf = ssl_sock_to_buf,
5343 .rcv_pipe = NULL,
5344 .snd_pipe = NULL,
5345 .shutr = NULL,
5346 .shutw = ssl_sock_shutw,
5347 .close = ssl_sock_close,
5348 .init = ssl_sock_init,
5349};
5350
Daniel Jakots54ffb912015-11-06 20:02:41 +01005351#if (OPENSSL_VERSION_NUMBER >= 0x1000200fL && !defined OPENSSL_NO_TLSEXT && !defined OPENSSL_IS_BORINGSSL && !defined LIBRESSL_VERSION_NUMBER)
Janusz Dziemidowicz2c701b52015-03-07 23:03:59 +01005352
5353static void ssl_sock_sctl_free_func(void *parent, void *ptr, CRYPTO_EX_DATA *ad, int idx, long argl, void *argp)
5354{
5355 if (ptr) {
5356 chunk_destroy(ptr);
5357 free(ptr);
5358 }
5359}
5360
5361#endif
5362
Emeric Brun46591952012-05-18 15:47:34 +02005363__attribute__((constructor))
Willy Tarreau92faadf2012-10-10 23:04:25 +02005364static void __ssl_sock_init(void)
5365{
Emeric Brun46591952012-05-18 15:47:34 +02005366 STACK_OF(SSL_COMP)* cm;
5367
Willy Tarreau610f04b2014-02-13 11:36:41 +01005368#ifdef LISTEN_DEFAULT_CIPHERS
5369 global.listen_default_ciphers = LISTEN_DEFAULT_CIPHERS;
5370#endif
5371#ifdef CONNECT_DEFAULT_CIPHERS
5372 global.connect_default_ciphers = CONNECT_DEFAULT_CIPHERS;
5373#endif
5374 if (global.listen_default_ciphers)
5375 global.listen_default_ciphers = strdup(global.listen_default_ciphers);
5376 if (global.connect_default_ciphers)
5377 global.connect_default_ciphers = strdup(global.connect_default_ciphers);
Emeric Brun2c86cbf2014-10-30 15:56:50 +01005378 global.listen_default_ssloptions = BC_SSL_O_NONE;
5379 global.connect_default_ssloptions = SRV_SSL_O_NONE;
Willy Tarreau610f04b2014-02-13 11:36:41 +01005380
Emeric Brun46591952012-05-18 15:47:34 +02005381 SSL_library_init();
5382 cm = SSL_COMP_get_compression_methods();
5383 sk_SSL_COMP_zero(cm);
Daniel Jakots54ffb912015-11-06 20:02:41 +01005384#if (OPENSSL_VERSION_NUMBER >= 0x1000200fL && !defined OPENSSL_NO_TLSEXT && !defined OPENSSL_IS_BORINGSSL && !defined LIBRESSL_VERSION_NUMBER)
Janusz Dziemidowicz2c701b52015-03-07 23:03:59 +01005385 sctl_ex_index = SSL_CTX_get_ex_new_index(0, NULL, NULL, NULL, ssl_sock_sctl_free_func);
5386#endif
Willy Tarreau7875d092012-09-10 08:20:03 +02005387 sample_register_fetches(&sample_fetch_keywords);
5388 acl_register_keywords(&acl_kws);
Willy Tarreau79eeafa2012-09-14 07:53:05 +02005389 bind_register_keywords(&bind_kws);
Willy Tarreau92faadf2012-10-10 23:04:25 +02005390 srv_register_keywords(&srv_kws);
Emeric Brun2c86cbf2014-10-30 15:56:50 +01005391 cfg_register_keywords(&cfg_kws);
Willy Tarreaud92aa5c2015-01-15 21:34:39 +01005392
5393 global.ssl_session_max_cost = SSL_SESSION_MAX_COST;
5394 global.ssl_handshake_max_cost = SSL_HANDSHAKE_MAX_COST;
Remi Gacogne4f902b82015-05-28 16:23:00 +02005395
5396#ifndef OPENSSL_NO_DH
5397 ssl_dh_ptr_index = SSL_CTX_get_ex_new_index(0, NULL, NULL, NULL, NULL);
5398#endif
Emeric Brun46591952012-05-18 15:47:34 +02005399}
5400
Remi Gacogned3a23c32015-05-28 16:39:47 +02005401__attribute__((destructor))
5402static void __ssl_sock_deinit(void)
5403{
Willy Tarreaua84c2672015-10-09 12:10:13 +02005404#ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME
Christopher Faulet31af49d2015-06-09 17:29:50 +02005405 lru64_destroy(ssl_ctx_lru_tree);
Willy Tarreaua84c2672015-10-09 12:10:13 +02005406#endif
Christopher Faulet31af49d2015-06-09 17:29:50 +02005407
Remi Gacogned3a23c32015-05-28 16:39:47 +02005408#ifndef OPENSSL_NO_DH
5409 if (local_dh_1024) {
5410 DH_free(local_dh_1024);
5411 local_dh_1024 = NULL;
5412 }
5413
5414 if (local_dh_2048) {
5415 DH_free(local_dh_2048);
5416 local_dh_2048 = NULL;
5417 }
5418
5419 if (local_dh_4096) {
5420 DH_free(local_dh_4096);
5421 local_dh_4096 = NULL;
5422 }
5423
Remi Gacogne47783ef2015-05-29 15:53:22 +02005424 if (global_dh) {
5425 DH_free(global_dh);
5426 global_dh = NULL;
5427 }
Remi Gacogned3a23c32015-05-28 16:39:47 +02005428#endif
5429
5430 ERR_remove_state(0);
5431 ERR_free_strings();
5432
5433 EVP_cleanup();
5434
5435#if OPENSSL_VERSION_NUMBER >= 0x00907000L
5436 CRYPTO_cleanup_all_ex_data();
5437#endif
5438}
5439
5440
Emeric Brun46591952012-05-18 15:47:34 +02005441/*
5442 * Local variables:
5443 * c-indent-level: 8
5444 * c-basic-offset: 8
5445 * End:
5446 */