blob: fbf8f9a624fcfc3526b771e52c317a0e5bd4e041 [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>
38
39#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 Tribus656c5fa2014-08-18 00:56:31 +020047#if (defined SSL_CTRL_SET_TLSEXT_STATUS_REQ_CB && !defined OPENSSL_IS_BORINGSSL)
Emeric Brun4147b2e2014-06-16 18:36:30 +020048#include <openssl/ocsp.h>
49#endif
Emeric Brun46591952012-05-18 15:47:34 +020050
51#include <common/buffer.h>
52#include <common/compat.h>
53#include <common/config.h>
54#include <common/debug.h>
Willy Tarreau79eeafa2012-09-14 07:53:05 +020055#include <common/errors.h>
Emeric Brun46591952012-05-18 15:47:34 +020056#include <common/standard.h>
57#include <common/ticks.h>
58#include <common/time.h>
Emeric Brun2c86cbf2014-10-30 15:56:50 +010059#include <common/cfgparse.h>
Emeric Brun46591952012-05-18 15:47:34 +020060
Emeric Brunfc0421f2012-09-07 17:30:07 +020061#include <ebsttree.h>
62
63#include <types/global.h>
64#include <types/ssl_sock.h>
65
Willy Tarreau7875d092012-09-10 08:20:03 +020066#include <proto/acl.h>
67#include <proto/arg.h>
Emeric Brun46591952012-05-18 15:47:34 +020068#include <proto/connection.h>
69#include <proto/fd.h>
70#include <proto/freq_ctr.h>
71#include <proto/frontend.h>
Willy Tarreau79eeafa2012-09-14 07:53:05 +020072#include <proto/listener.h>
Thierry FOURNIERed66c292013-11-28 11:05:19 +010073#include <proto/pattern.h>
Willy Tarreau92faadf2012-10-10 23:04:25 +020074#include <proto/server.h>
Emeric Brun46591952012-05-18 15:47:34 +020075#include <proto/log.h>
Emeric Brun94324a42012-10-11 14:00:19 +020076#include <proto/proxy.h>
Emeric Brunfc0421f2012-09-07 17:30:07 +020077#include <proto/shctx.h>
Emeric Brun46591952012-05-18 15:47:34 +020078#include <proto/ssl_sock.h>
79#include <proto/task.h>
80
Willy Tarreau518cedd2014-02-17 15:43:01 +010081/* Warning, these are bits, not integers! */
Emeric Brune64aef12012-09-21 13:15:06 +020082#define SSL_SOCK_ST_FL_VERIFY_DONE 0x00000001
Emeric Brund8b2bb52014-01-28 15:43:53 +010083#define SSL_SOCK_ST_FL_16K_WBFSIZE 0x00000002
Willy Tarreau518cedd2014-02-17 15:43:01 +010084#define SSL_SOCK_SEND_UNLIMITED 0x00000004
Emeric Brun29f037d2014-04-25 19:05:36 +020085#define SSL_SOCK_RECV_HEARTBEAT 0x00000008
86
Emeric Brunf282a812012-09-21 15:27:54 +020087/* bits 0xFFFF0000 are reserved to store verify errors */
88
89/* Verify errors macros */
90#define SSL_SOCK_CA_ERROR_TO_ST(e) (((e > 63) ? 63 : e) << (16))
91#define SSL_SOCK_CAEDEPTH_TO_ST(d) (((d > 15) ? 15 : d) << (6+16))
92#define SSL_SOCK_CRTERROR_TO_ST(e) (((e > 63) ? 63 : e) << (4+6+16))
93
94#define SSL_SOCK_ST_TO_CA_ERROR(s) ((s >> (16)) & 63)
95#define SSL_SOCK_ST_TO_CAEDEPTH(s) ((s >> (6+16)) & 15)
96#define SSL_SOCK_ST_TO_CRTERROR(s) ((s >> (4+6+16)) & 63)
Emeric Brune64aef12012-09-21 13:15:06 +020097
Emeric Brun850efd52014-01-29 12:24:34 +010098/* server and bind verify method, it uses a global value as default */
99enum {
100 SSL_SOCK_VERIFY_DEFAULT = 0,
101 SSL_SOCK_VERIFY_REQUIRED = 1,
102 SSL_SOCK_VERIFY_OPTIONAL = 2,
103 SSL_SOCK_VERIFY_NONE = 3,
104};
105
Willy Tarreau71b734c2014-01-28 15:19:44 +0100106int sslconns = 0;
107int totalsslconns = 0;
Emeric Brune1f38db2012-09-03 20:36:47 +0200108
Remi Gacogne8de54152014-07-15 11:36:40 +0200109#ifndef OPENSSL_NO_DH
110static DH *local_dh_1024 = NULL;
111static DH *local_dh_2048 = NULL;
112static DH *local_dh_4096 = NULL;
113static DH *local_dh_8192 = NULL;
114#endif /* OPENSSL_NO_DH */
115
Lukas Tribus656c5fa2014-08-18 00:56:31 +0200116#if (defined SSL_CTRL_SET_TLSEXT_STATUS_REQ_CB && !defined OPENSSL_IS_BORINGSSL)
Emeric Brun4147b2e2014-06-16 18:36:30 +0200117struct certificate_ocsp {
118 struct ebmb_node key;
119 unsigned char key_data[OCSP_MAX_CERTID_ASN1_LENGTH];
120 struct chunk response;
Emeric Brun4f3c87a2014-06-20 15:46:13 +0200121 long expire;
Emeric Brun4147b2e2014-06-16 18:36:30 +0200122};
123
Emeric Brun4f3c87a2014-06-20 15:46:13 +0200124/*
125 * This function returns the number of seconds elapsed
126 * since the Epoch, 1970-01-01 00:00:00 +0000 (UTC) and the
127 * date presented un ASN1_GENERALIZEDTIME.
128 *
129 * In parsing error case, it returns -1.
130 */
131static long asn1_generalizedtime_to_epoch(ASN1_GENERALIZEDTIME *d)
132{
133 long epoch;
134 char *p, *end;
135 const unsigned short month_offset[12] = {
136 0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334
137 };
138 int year, month;
139
140 if (!d || (d->type != V_ASN1_GENERALIZEDTIME)) return -1;
141
142 p = (char *)d->data;
143 end = p + d->length;
144
145 if (end - p < 4) return -1;
146 year = 1000 * (p[0] - '0') + 100 * (p[1] - '0') + 10 * (p[2] - '0') + p[3] - '0';
147 p += 4;
148 if (end - p < 2) return -1;
149 month = 10 * (p[0] - '0') + p[1] - '0';
150 if (month < 1 || month > 12) return -1;
151 /* Compute the number of seconds since 1 jan 1970 and the beginning of current month
152 We consider leap years and the current month (<marsh or not) */
153 epoch = ( ((year - 1970) * 365)
154 + ((year - (month < 3)) / 4 - (year - (month < 3)) / 100 + (year - (month < 3)) / 400)
155 - ((1970 - 1) / 4 - (1970 - 1) / 100 + (1970 - 1) / 400)
156 + month_offset[month-1]
157 ) * 24 * 60 * 60;
158 p += 2;
159 if (end - p < 2) return -1;
160 /* Add the number of seconds of completed days of current month */
161 epoch += (10 * (p[0] - '0') + p[1] - '0' - 1) * 24 * 60 * 60;
162 p += 2;
163 if (end - p < 2) return -1;
164 /* Add the completed hours of the current day */
165 epoch += (10 * (p[0] - '0') + p[1] - '0') * 60 * 60;
166 p += 2;
167 if (end - p < 2) return -1;
168 /* Add the completed minutes of the current hour */
169 epoch += (10 * (p[0] - '0') + p[1] - '0') * 60;
170 p += 2;
171 if (p == end) return -1;
172 /* Test if there is available seconds */
173 if (p[0] < '0' || p[0] > '9')
174 goto nosec;
175 if (end - p < 2) return -1;
176 /* Add the seconds of the current minute */
177 epoch += 10 * (p[0] - '0') + p[1] - '0';
178 p += 2;
179 if (p == end) return -1;
180 /* Ignore seconds float part if present */
181 if (p[0] == '.') {
182 do {
183 if (++p == end) return -1;
184 } while (p[0] >= '0' && p[0] <= '9');
185 }
186
187nosec:
188 if (p[0] == 'Z') {
189 if (end - p != 1) return -1;
190 return epoch;
191 }
192 else if (p[0] == '+') {
193 if (end - p != 5) return -1;
194 /* Apply timezone offset */
195 return epoch - ((10 * (p[1] - '0') + p[2] - '0') * 60 + (10 * (p[3] - '0') + p[4] - '0')) * 60;
196 }
197 else if (p[0] == '-') {
198 if (end - p != 5) return -1;
199 /* Apply timezone offset */
200 return epoch + ((10 * (p[1] - '0') + p[2] - '0') * 60 + (10 * (p[3] - '0') + p[4] - '0')) * 60;
201 }
202
203 return -1;
204}
205
Emeric Brun1d3865b2014-06-20 15:37:32 +0200206static struct eb_root cert_ocsp_tree = EB_ROOT_UNIQUE;
Emeric Brun4147b2e2014-06-16 18:36:30 +0200207
208/* This function starts to check if the OCSP response (in DER format) contained
209 * in chunk 'ocsp_response' is valid (else exits on error).
210 * If 'cid' is not NULL, it will be compared to the OCSP certificate ID
211 * contained in the OCSP Response and exits on error if no match.
212 * If it's a valid OCSP Response:
213 * If 'ocsp' is not NULL, the chunk is copied in the OCSP response's container
214 * pointed by 'ocsp'.
215 * If 'ocsp' is NULL, the function looks up into the OCSP response's
216 * containers tree (using as index the ASN1 form of the OCSP Certificate ID extracted
217 * from the response) and exits on error if not found. Finally, If an OCSP response is
218 * already present in the container, it will be overwritten.
219 *
220 * Note: OCSP response containing more than one OCSP Single response is not
221 * considered valid.
222 *
223 * Returns 0 on success, 1 in error case.
224 */
225static int ssl_sock_load_ocsp_response(struct chunk *ocsp_response, struct certificate_ocsp *ocsp, OCSP_CERTID *cid, char **err)
226{
227 OCSP_RESPONSE *resp;
228 OCSP_BASICRESP *bs = NULL;
229 OCSP_SINGLERESP *sr;
230 unsigned char *p = (unsigned char *)ocsp_response->str;
231 int rc , count_sr;
Emeric Brun13a6b482014-06-20 15:44:34 +0200232 ASN1_GENERALIZEDTIME *revtime, *thisupd, *nextupd = NULL;
Emeric Brun4147b2e2014-06-16 18:36:30 +0200233 int reason;
234 int ret = 1;
235
236 resp = d2i_OCSP_RESPONSE(NULL, (const unsigned char **)&p, ocsp_response->len);
237 if (!resp) {
238 memprintf(err, "Unable to parse OCSP response");
239 goto out;
240 }
241
242 rc = OCSP_response_status(resp);
243 if (rc != OCSP_RESPONSE_STATUS_SUCCESSFUL) {
244 memprintf(err, "OCSP response status not successful");
245 goto out;
246 }
247
248 bs = OCSP_response_get1_basic(resp);
249 if (!bs) {
250 memprintf(err, "Failed to get basic response from OCSP Response");
251 goto out;
252 }
253
254 count_sr = OCSP_resp_count(bs);
255 if (count_sr > 1) {
256 memprintf(err, "OCSP response ignored because contains multiple single responses (%d)", count_sr);
257 goto out;
258 }
259
260 sr = OCSP_resp_get0(bs, 0);
261 if (!sr) {
262 memprintf(err, "Failed to get OCSP single response");
263 goto out;
264 }
265
266 rc = OCSP_single_get0_status(sr, &reason, &revtime, &thisupd, &nextupd);
267 if (rc != V_OCSP_CERTSTATUS_GOOD) {
268 memprintf(err, "OCSP single response: certificate status not good");
269 goto out;
270 }
271
Emeric Brun13a6b482014-06-20 15:44:34 +0200272 if (!nextupd) {
273 memprintf(err, "OCSP single response: missing nextupdate");
274 goto out;
275 }
276
Emeric Brunc8b27b62014-06-19 14:16:17 +0200277 rc = OCSP_check_validity(thisupd, nextupd, OCSP_MAX_RESPONSE_TIME_SKEW, -1);
Emeric Brun4147b2e2014-06-16 18:36:30 +0200278 if (!rc) {
279 memprintf(err, "OCSP single response: no longer valid.");
280 goto out;
281 }
282
283 if (cid) {
284 if (OCSP_id_cmp(sr->certId, cid)) {
285 memprintf(err, "OCSP single response: Certificate ID does not match certificate and issuer");
286 goto out;
287 }
288 }
289
290 if (!ocsp) {
291 unsigned char key[OCSP_MAX_CERTID_ASN1_LENGTH];
292 unsigned char *p;
293
294 rc = i2d_OCSP_CERTID(sr->certId, NULL);
295 if (!rc) {
296 memprintf(err, "OCSP single response: Unable to encode Certificate ID");
297 goto out;
298 }
299
300 if (rc > OCSP_MAX_CERTID_ASN1_LENGTH) {
301 memprintf(err, "OCSP single response: Certificate ID too long");
302 goto out;
303 }
304
305 p = key;
306 memset(key, 0, OCSP_MAX_CERTID_ASN1_LENGTH);
307 i2d_OCSP_CERTID(sr->certId, &p);
308 ocsp = (struct certificate_ocsp *)ebmb_lookup(&cert_ocsp_tree, key, OCSP_MAX_CERTID_ASN1_LENGTH);
309 if (!ocsp) {
310 memprintf(err, "OCSP single response: Certificate ID does not match any certificate or issuer");
311 goto out;
312 }
313 }
314
315 /* According to comments on "chunk_dup", the
316 previous chunk buffer will be freed */
317 if (!chunk_dup(&ocsp->response, ocsp_response)) {
318 memprintf(err, "OCSP response: Memory allocation error");
319 goto out;
320 }
321
Emeric Brun4f3c87a2014-06-20 15:46:13 +0200322 ocsp->expire = asn1_generalizedtime_to_epoch(nextupd) - OCSP_MAX_RESPONSE_TIME_SKEW;
323
Emeric Brun4147b2e2014-06-16 18:36:30 +0200324 ret = 0;
325out:
326 if (bs)
327 OCSP_BASICRESP_free(bs);
328
329 if (resp)
330 OCSP_RESPONSE_free(resp);
331
332 return ret;
333}
334/*
335 * External function use to update the OCSP response in the OCSP response's
336 * containers tree. The chunk 'ocsp_response' must contain the OCSP response
337 * to update in DER format.
338 *
339 * Returns 0 on success, 1 in error case.
340 */
341int ssl_sock_update_ocsp_response(struct chunk *ocsp_response, char **err)
342{
343 return ssl_sock_load_ocsp_response(ocsp_response, NULL, NULL, err);
344}
345
346/*
347 * This function load the OCSP Resonse in DER format contained in file at
348 * path 'ocsp_path' and call 'ssl_sock_load_ocsp_response'
349 *
350 * Returns 0 on success, 1 in error case.
351 */
352static int ssl_sock_load_ocsp_response_from_file(const char *ocsp_path, struct certificate_ocsp *ocsp, OCSP_CERTID *cid, char **err)
353{
354 int fd = -1;
355 int r = 0;
356 int ret = 1;
357
358 fd = open(ocsp_path, O_RDONLY);
359 if (fd == -1) {
360 memprintf(err, "Error opening OCSP response file");
361 goto end;
362 }
363
364 trash.len = 0;
365 while (trash.len < trash.size) {
366 r = read(fd, trash.str + trash.len, trash.size - trash.len);
367 if (r < 0) {
368 if (errno == EINTR)
369 continue;
370
371 memprintf(err, "Error reading OCSP response from file");
372 goto end;
373 }
374 else if (r == 0) {
375 break;
376 }
377 trash.len += r;
378 }
379
380 close(fd);
381 fd = -1;
382
383 ret = ssl_sock_load_ocsp_response(&trash, ocsp, cid, err);
384end:
385 if (fd != -1)
386 close(fd);
387
388 return ret;
389}
390
391/*
392 * Callback used to set OCSP status extension content in server hello.
393 */
394int ssl_sock_ocsp_stapling_cbk(SSL *ssl, void *arg)
395{
396 struct certificate_ocsp *ocsp = (struct certificate_ocsp *)arg;
397 char* ssl_buf;
398
399 if (!ocsp ||
400 !ocsp->response.str ||
Emeric Brun4f3c87a2014-06-20 15:46:13 +0200401 !ocsp->response.len ||
402 (ocsp->expire < now.tv_sec))
Emeric Brun4147b2e2014-06-16 18:36:30 +0200403 return SSL_TLSEXT_ERR_NOACK;
404
405 ssl_buf = OPENSSL_malloc(ocsp->response.len);
406 if (!ssl_buf)
407 return SSL_TLSEXT_ERR_NOACK;
408
409 memcpy(ssl_buf, ocsp->response.str, ocsp->response.len);
410 SSL_set_tlsext_status_ocsp_resp(ssl, ssl_buf, ocsp->response.len);
411
412 return SSL_TLSEXT_ERR_OK;
413}
414
415/*
416 * This function enables the handling of OCSP status extension on 'ctx' if a
417 * file name 'cert_path' suffixed using ".ocsp" is present.
418 * To enable OCSP status extension, the issuer's certificate is mandatory.
419 * It should be present in the certificate's extra chain builded from file
420 * 'cert_path'. If not found, the issuer certificate is loaded from a file
421 * named 'cert_path' suffixed using '.issuer'.
422 *
423 * In addition, ".ocsp" file content is loaded as a DER format of an OCSP
424 * response. If file is empty or content is not a valid OCSP response,
425 * OCSP status extension is enabled but OCSP response is ignored (a warning
426 * is displayed).
427 *
428 * Returns 1 if no ".ocsp" file found, 0 if OCSP status extension is
429 * succesfully enabled, or -1 in other error case.
430 */
431static int ssl_sock_load_ocsp(SSL_CTX *ctx, const char *cert_path)
432{
433
434 BIO *in = NULL;
435 X509 *x, *xi = NULL, *issuer = NULL;
436 STACK_OF(X509) *chain = NULL;
437 OCSP_CERTID *cid = NULL;
438 SSL *ssl;
439 char ocsp_path[MAXPATHLEN+1];
440 int i, ret = -1;
441 struct stat st;
442 struct certificate_ocsp *ocsp = NULL, *iocsp;
443 char *warn = NULL;
444 unsigned char *p;
445
446 snprintf(ocsp_path, MAXPATHLEN+1, "%s.ocsp", cert_path);
447
448 if (stat(ocsp_path, &st))
449 return 1;
450
451 ssl = SSL_new(ctx);
452 if (!ssl)
453 goto out;
454
455 x = SSL_get_certificate(ssl);
456 if (!x)
457 goto out;
458
459 /* Try to lookup for issuer in certificate extra chain */
460#ifdef SSL_CTRL_GET_EXTRA_CHAIN_CERTS
461 SSL_CTX_get_extra_chain_certs(ctx, &chain);
462#else
463 chain = ctx->extra_certs;
464#endif
465 for (i = 0; i < sk_X509_num(chain); i++) {
466 issuer = sk_X509_value(chain, i);
467 if (X509_check_issued(issuer, x) == X509_V_OK)
468 break;
469 else
470 issuer = NULL;
471 }
472
473 /* If not found try to load issuer from a suffixed file */
474 if (!issuer) {
475 char issuer_path[MAXPATHLEN+1];
476
477 in = BIO_new(BIO_s_file());
478 if (!in)
479 goto out;
480
481 snprintf(issuer_path, MAXPATHLEN+1, "%s.issuer", cert_path);
482 if (BIO_read_filename(in, issuer_path) <= 0)
483 goto out;
484
485 xi = PEM_read_bio_X509_AUX(in, NULL, ctx->default_passwd_callback, ctx->default_passwd_callback_userdata);
486 if (!xi)
487 goto out;
488
489 if (X509_check_issued(xi, x) != X509_V_OK)
490 goto out;
491
492 issuer = xi;
493 }
494
495 cid = OCSP_cert_to_id(0, x, issuer);
496 if (!cid)
497 goto out;
498
499 i = i2d_OCSP_CERTID(cid, NULL);
500 if (!i || (i > OCSP_MAX_CERTID_ASN1_LENGTH))
501 goto out;
502
503 ocsp = calloc(1, sizeof(struct certificate_ocsp));
504 if (!ocsp)
505 goto out;
506
507 p = ocsp->key_data;
508 i2d_OCSP_CERTID(cid, &p);
509
510 iocsp = (struct certificate_ocsp *)ebmb_insert(&cert_ocsp_tree, &ocsp->key, OCSP_MAX_CERTID_ASN1_LENGTH);
511 if (iocsp == ocsp)
512 ocsp = NULL;
513
514 SSL_CTX_set_tlsext_status_cb(ctx, ssl_sock_ocsp_stapling_cbk);
515 SSL_CTX_set_tlsext_status_arg(ctx, iocsp);
516
517 ret = 0;
518
519 warn = NULL;
520 if (ssl_sock_load_ocsp_response_from_file(ocsp_path, iocsp, cid, &warn)) {
521 memprintf(&warn, "Loading '%s': %s. Content will be ignored", ocsp_path, warn ? warn : "failure");
522 Warning("%s.\n", warn);
523 }
524
525out:
526 if (ssl)
527 SSL_free(ssl);
528
529 if (in)
530 BIO_free(in);
531
532 if (xi)
533 X509_free(xi);
534
535 if (cid)
536 OCSP_CERTID_free(cid);
537
538 if (ocsp)
539 free(ocsp);
540
541 if (warn)
542 free(warn);
543
544
545 return ret;
546}
547
548#endif
549
Emeric Brune1f38db2012-09-03 20:36:47 +0200550void ssl_sock_infocbk(const SSL *ssl, int where, int ret)
551{
552 struct connection *conn = (struct connection *)SSL_get_app_data(ssl);
553 (void)ret; /* shut gcc stupid warning */
Emeric Brund8b2bb52014-01-28 15:43:53 +0100554 BIO *write_bio;
Emeric Brune1f38db2012-09-03 20:36:47 +0200555
556 if (where & SSL_CB_HANDSHAKE_START) {
557 /* Disable renegotiation (CVE-2009-3555) */
Willy Tarreau20879a02012-12-03 16:32:10 +0100558 if (conn->flags & CO_FL_CONNECTED) {
Emeric Brune1f38db2012-09-03 20:36:47 +0200559 conn->flags |= CO_FL_ERROR;
Willy Tarreau20879a02012-12-03 16:32:10 +0100560 conn->err_code = CO_ER_SSL_RENEG;
561 }
Emeric Brune1f38db2012-09-03 20:36:47 +0200562 }
Emeric Brund8b2bb52014-01-28 15:43:53 +0100563
564 if ((where & SSL_CB_ACCEPT_LOOP) == SSL_CB_ACCEPT_LOOP) {
565 if (!(conn->xprt_st & SSL_SOCK_ST_FL_16K_WBFSIZE)) {
566 /* Long certificate chains optimz
567 If write and read bios are differents, we
568 consider that the buffering was activated,
569 so we rise the output buffer size from 4k
570 to 16k */
571 write_bio = SSL_get_wbio(ssl);
572 if (write_bio != SSL_get_rbio(ssl)) {
573 BIO_set_write_buffer_size(write_bio, 16384);
574 conn->xprt_st |= SSL_SOCK_ST_FL_16K_WBFSIZE;
575 }
576 }
577 }
Emeric Brunfc0421f2012-09-07 17:30:07 +0200578}
579
Emeric Brune64aef12012-09-21 13:15:06 +0200580/* Callback is called for each certificate of the chain during a verify
581 ok is set to 1 if preverify detect no error on current certificate.
582 Returns 0 to break the handshake, 1 otherwise. */
Evan Broderbe554312013-06-27 00:05:25 -0700583int ssl_sock_bind_verifycbk(int ok, X509_STORE_CTX *x_store)
Emeric Brune64aef12012-09-21 13:15:06 +0200584{
585 SSL *ssl;
586 struct connection *conn;
Emeric Brun81c00f02012-09-21 14:31:21 +0200587 int err, depth;
Emeric Brune64aef12012-09-21 13:15:06 +0200588
589 ssl = X509_STORE_CTX_get_ex_data(x_store, SSL_get_ex_data_X509_STORE_CTX_idx());
590 conn = (struct connection *)SSL_get_app_data(ssl);
591
Willy Tarreauf7bc57c2012-10-03 00:19:48 +0200592 conn->xprt_st |= SSL_SOCK_ST_FL_VERIFY_DONE;
Emeric Brune64aef12012-09-21 13:15:06 +0200593
Emeric Brun81c00f02012-09-21 14:31:21 +0200594 if (ok) /* no errors */
595 return ok;
596
597 depth = X509_STORE_CTX_get_error_depth(x_store);
598 err = X509_STORE_CTX_get_error(x_store);
599
600 /* check if CA error needs to be ignored */
601 if (depth > 0) {
Willy Tarreauf7bc57c2012-10-03 00:19:48 +0200602 if (!SSL_SOCK_ST_TO_CA_ERROR(conn->xprt_st)) {
603 conn->xprt_st |= SSL_SOCK_CA_ERROR_TO_ST(err);
604 conn->xprt_st |= SSL_SOCK_CAEDEPTH_TO_ST(depth);
Emeric Brunf282a812012-09-21 15:27:54 +0200605 }
606
Emeric Brun1eb20ef2012-12-03 13:24:29 +0100607 if (objt_listener(conn->target)->bind_conf->ca_ignerr & (1ULL << err)) {
608 ERR_clear_error();
Emeric Brun81c00f02012-09-21 14:31:21 +0200609 return 1;
Emeric Brun1eb20ef2012-12-03 13:24:29 +0100610 }
Emeric Brun81c00f02012-09-21 14:31:21 +0200611
Willy Tarreau20879a02012-12-03 16:32:10 +0100612 conn->err_code = CO_ER_SSL_CA_FAIL;
Emeric Brun81c00f02012-09-21 14:31:21 +0200613 return 0;
614 }
615
Willy Tarreauf7bc57c2012-10-03 00:19:48 +0200616 if (!SSL_SOCK_ST_TO_CRTERROR(conn->xprt_st))
617 conn->xprt_st |= SSL_SOCK_CRTERROR_TO_ST(err);
Emeric Brunf282a812012-09-21 15:27:54 +0200618
Emeric Brun81c00f02012-09-21 14:31:21 +0200619 /* check if certificate error needs to be ignored */
Emeric Brun1eb20ef2012-12-03 13:24:29 +0100620 if (objt_listener(conn->target)->bind_conf->crt_ignerr & (1ULL << err)) {
621 ERR_clear_error();
Emeric Brun81c00f02012-09-21 14:31:21 +0200622 return 1;
Emeric Brun1eb20ef2012-12-03 13:24:29 +0100623 }
Emeric Brun81c00f02012-09-21 14:31:21 +0200624
Willy Tarreau20879a02012-12-03 16:32:10 +0100625 conn->err_code = CO_ER_SSL_CRT_FAIL;
Emeric Brun81c00f02012-09-21 14:31:21 +0200626 return 0;
Emeric Brune64aef12012-09-21 13:15:06 +0200627}
628
Emeric Brun29f037d2014-04-25 19:05:36 +0200629/* Callback is called for ssl protocol analyse */
630void ssl_sock_msgcbk(int write_p, int version, int content_type, const void *buf, size_t len, SSL *ssl, void *arg)
631{
Emeric Brun29f037d2014-04-25 19:05:36 +0200632#ifdef TLS1_RT_HEARTBEAT
633 /* test heartbeat received (write_p is set to 0
634 for a received record) */
Willy Tarreauf51c6982014-04-25 20:02:39 +0200635 if ((content_type == TLS1_RT_HEARTBEAT) && (write_p == 0)) {
Willy Tarreau84815002014-04-25 21:40:27 +0200636 struct connection *conn = (struct connection *)SSL_get_app_data(ssl);
Willy Tarreauf51c6982014-04-25 20:02:39 +0200637 const unsigned char *p = buf;
638 unsigned int payload;
639
Emeric Brun29f037d2014-04-25 19:05:36 +0200640 conn->xprt_st |= SSL_SOCK_RECV_HEARTBEAT;
Willy Tarreauf51c6982014-04-25 20:02:39 +0200641
642 /* Check if this is a CVE-2014-0160 exploitation attempt. */
643 if (*p != TLS1_HB_REQUEST)
644 return;
645
Willy Tarreauaeed6722014-04-25 23:59:58 +0200646 if (len < 1 + 2 + 16) /* 1 type + 2 size + 0 payload + 16 padding */
Willy Tarreauf51c6982014-04-25 20:02:39 +0200647 goto kill_it;
648
649 payload = (p[1] * 256) + p[2];
Willy Tarreau3b2fdb62014-04-25 23:44:22 +0200650 if (3 + payload + 16 <= len)
Willy Tarreauf51c6982014-04-25 20:02:39 +0200651 return; /* OK no problem */
Willy Tarreauaeed6722014-04-25 23:59:58 +0200652 kill_it:
Willy Tarreau3b2fdb62014-04-25 23:44:22 +0200653 /* We have a clear heartbleed attack (CVE-2014-0160), the
654 * advertised payload is larger than the advertised packet
655 * length, so we have garbage in the buffer between the
656 * payload and the end of the buffer (p+len). We can't know
657 * if the SSL stack is patched, and we don't know if we can
658 * safely wipe out the area between p+3+len and payload.
659 * So instead, we prevent the response from being sent by
660 * setting the max_send_fragment to 0 and we report an SSL
661 * error, which will kill this connection. It will be reported
662 * above as SSL_ERROR_SSL while an other handshake failure with
Willy Tarreauf51c6982014-04-25 20:02:39 +0200663 * a heartbeat message will be reported as SSL_ERROR_SYSCALL.
664 */
Willy Tarreau3b2fdb62014-04-25 23:44:22 +0200665 ssl->max_send_fragment = 0;
Willy Tarreauf51c6982014-04-25 20:02:39 +0200666 SSLerr(SSL_F_TLS1_HEARTBEAT, SSL_R_SSL_HANDSHAKE_FAILURE);
667 return;
668 }
Emeric Brun29f037d2014-04-25 19:05:36 +0200669#endif
670}
671
Willy Tarreau6c9a3d52012-10-18 18:57:14 +0200672#ifdef OPENSSL_NPN_NEGOTIATED
673/* This callback is used so that the server advertises the list of
674 * negociable protocols for NPN.
675 */
676static int ssl_sock_advertise_npn_protos(SSL *s, const unsigned char **data,
677 unsigned int *len, void *arg)
678{
679 struct bind_conf *conf = arg;
680
681 *data = (const unsigned char *)conf->npn_str;
682 *len = conf->npn_len;
683 return SSL_TLSEXT_ERR_OK;
684}
685#endif
686
Dirkjan Bussink48f1c4e2014-02-13 12:29:42 +0100687#ifdef TLSEXT_TYPE_application_layer_protocol_negotiation
Willy Tarreauab861d32013-04-02 02:30:41 +0200688/* This callback is used so that the server advertises the list of
689 * negociable protocols for ALPN.
690 */
Dirkjan Bussink48f1c4e2014-02-13 12:29:42 +0100691static int ssl_sock_advertise_alpn_protos(SSL *s, const unsigned char **out,
692 unsigned char *outlen,
693 const unsigned char *server,
694 unsigned int server_len, void *arg)
Willy Tarreauab861d32013-04-02 02:30:41 +0200695{
696 struct bind_conf *conf = arg;
697
Dirkjan Bussink48f1c4e2014-02-13 12:29:42 +0100698 if (SSL_select_next_proto((unsigned char**) out, outlen, (const unsigned char *)conf->alpn_str,
699 conf->alpn_len, server, server_len) != OPENSSL_NPN_NEGOTIATED) {
700 return SSL_TLSEXT_ERR_NOACK;
701 }
Willy Tarreauab861d32013-04-02 02:30:41 +0200702 return SSL_TLSEXT_ERR_OK;
703}
704#endif
705
Emeric Brunfc0421f2012-09-07 17:30:07 +0200706#ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME
707/* Sets the SSL ctx of <ssl> to match the advertised server name. Returns a
708 * warning when no match is found, which implies the default (first) cert
709 * will keep being used.
710 */
Willy Tarreau2a65ff02012-09-13 17:54:29 +0200711static int ssl_sock_switchctx_cbk(SSL *ssl, int *al, struct bind_conf *s)
Emeric Brunfc0421f2012-09-07 17:30:07 +0200712{
713 const char *servername;
714 const char *wildp = NULL;
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +0200715 struct ebmb_node *node, *n;
Emeric Brunfc0421f2012-09-07 17:30:07 +0200716 int i;
717 (void)al; /* shut gcc stupid warning */
718
719 servername = SSL_get_servername(ssl, TLSEXT_NAMETYPE_host_name);
Emmanuel Hocdet65623372013-01-24 17:17:15 +0100720 if (!servername) {
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +0200721 return (s->strict_sni ?
722 SSL_TLSEXT_ERR_ALERT_FATAL :
Emmanuel Hocdet79274e22013-05-31 12:47:44 +0200723 SSL_TLSEXT_ERR_NOACK);
Emmanuel Hocdet65623372013-01-24 17:17:15 +0100724 }
Emeric Brunfc0421f2012-09-07 17:30:07 +0200725
Willy Tarreau19d14ef2012-10-29 16:51:55 +0100726 for (i = 0; i < trash.size; i++) {
Emeric Brunfc0421f2012-09-07 17:30:07 +0200727 if (!servername[i])
728 break;
Willy Tarreau19d14ef2012-10-29 16:51:55 +0100729 trash.str[i] = tolower(servername[i]);
730 if (!wildp && (trash.str[i] == '.'))
731 wildp = &trash.str[i];
Emeric Brunfc0421f2012-09-07 17:30:07 +0200732 }
Willy Tarreau19d14ef2012-10-29 16:51:55 +0100733 trash.str[i] = 0;
Emeric Brunfc0421f2012-09-07 17:30:07 +0200734
735 /* lookup in full qualified names */
Willy Tarreau19d14ef2012-10-29 16:51:55 +0100736 node = ebst_lookup(&s->sni_ctx, trash.str);
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +0200737
738 /* lookup a not neg filter */
739 for (n = node; n; n = ebmb_next_dup(n)) {
740 if (!container_of(n, struct sni_ctx, name)->neg) {
741 node = n;
742 break;
Emmanuel Hocdet65623372013-01-24 17:17:15 +0100743 }
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +0200744 }
745 if (!node && wildp) {
746 /* lookup in wildcards names */
Emeric Brunfc0421f2012-09-07 17:30:07 +0200747 node = ebst_lookup(&s->sni_w_ctx, wildp);
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +0200748 }
749 if (!node || container_of(node, struct sni_ctx, name)->neg) {
750 return (s->strict_sni ?
751 SSL_TLSEXT_ERR_ALERT_FATAL :
752 SSL_TLSEXT_ERR_ALERT_WARNING);
Emeric Brunfc0421f2012-09-07 17:30:07 +0200753 }
754
755 /* switch ctx */
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +0200756 SSL_set_SSL_CTX(ssl, container_of(node, struct sni_ctx, name)->ctx);
Emeric Brunfc0421f2012-09-07 17:30:07 +0200757 return SSL_TLSEXT_ERR_OK;
758}
759#endif /* SSL_CTRL_SET_TLSEXT_HOSTNAME */
760
Emeric Bruna4bcd9a2012-09-20 16:19:02 +0200761#ifndef OPENSSL_NO_DH
Remi Gacognef46cd6e2014-06-12 14:58:40 +0200762
763static DH * ssl_get_dh_1024(void)
764{
Lukas Tribus4c0d45a2014-08-18 00:56:32 +0200765#if (OPENSSL_VERSION_NUMBER < 0x0090801fL || defined OPENSSL_IS_BORINGSSL)
Remi Gacognef46cd6e2014-06-12 14:58:40 +0200766 static const unsigned char rfc_2409_prime_1024[] = {
767 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xC9,0x0F,0xDA,0xA2,
768 0x21,0x68,0xC2,0x34,0xC4,0xC6,0x62,0x8B,0x80,0xDC,0x1C,0xD1,
769 0x29,0x02,0x4E,0x08,0x8A,0x67,0xCC,0x74,0x02,0x0B,0xBE,0xA6,
770 0x3B,0x13,0x9B,0x22,0x51,0x4A,0x08,0x79,0x8E,0x34,0x04,0xDD,
771 0xEF,0x95,0x19,0xB3,0xCD,0x3A,0x43,0x1B,0x30,0x2B,0x0A,0x6D,
772 0xF2,0x5F,0x14,0x37,0x4F,0xE1,0x35,0x6D,0x6D,0x51,0xC2,0x45,
773 0xE4,0x85,0xB5,0x76,0x62,0x5E,0x7E,0xC6,0xF4,0x4C,0x42,0xE9,
774 0xA6,0x37,0xED,0x6B,0x0B,0xFF,0x5C,0xB6,0xF4,0x06,0xB7,0xED,
775 0xEE,0x38,0x6B,0xFB,0x5A,0x89,0x9F,0xA5,0xAE,0x9F,0x24,0x11,
776 0x7C,0x4B,0x1F,0xE6,0x49,0x28,0x66,0x51,0xEC,0xE6,0x53,0x81,
777 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
778 };
779#endif
780 DH *dh = DH_new();
781 if (dh) {
Lukas Tribus4c0d45a2014-08-18 00:56:32 +0200782#if (OPENSSL_VERSION_NUMBER >= 0x0090801fL && !defined OPENSSL_IS_BORINGSSL)
Remi Gacognef46cd6e2014-06-12 14:58:40 +0200783 dh->p = get_rfc2409_prime_1024(NULL);
784#else
785 dh->p = BN_bin2bn(rfc_2409_prime_1024, sizeof rfc_2409_prime_1024, NULL);
786#endif
787 /* See RFC 2409, Section 6 "Oakley Groups"
788 for the reason why 2 is used as generator.
789 */
790 BN_dec2bn(&dh->g, "2");
791 if (!dh->p || !dh->g) {
792 DH_free(dh);
793 dh = NULL;
794 }
795 }
796 return dh;
797}
798
799static DH *ssl_get_dh_2048(void)
800{
Lukas Tribus4c0d45a2014-08-18 00:56:32 +0200801#if (OPENSSL_VERSION_NUMBER < 0x0090801fL || defined OPENSSL_IS_BORINGSSL)
Remi Gacognef46cd6e2014-06-12 14:58:40 +0200802 static const unsigned char rfc_3526_prime_2048[] = {
803 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xC9,0x0F,0xDA,0xA2,
804 0x21,0x68,0xC2,0x34,0xC4,0xC6,0x62,0x8B,0x80,0xDC,0x1C,0xD1,
805 0x29,0x02,0x4E,0x08,0x8A,0x67,0xCC,0x74,0x02,0x0B,0xBE,0xA6,
806 0x3B,0x13,0x9B,0x22,0x51,0x4A,0x08,0x79,0x8E,0x34,0x04,0xDD,
807 0xEF,0x95,0x19,0xB3,0xCD,0x3A,0x43,0x1B,0x30,0x2B,0x0A,0x6D,
808 0xF2,0x5F,0x14,0x37,0x4F,0xE1,0x35,0x6D,0x6D,0x51,0xC2,0x45,
809 0xE4,0x85,0xB5,0x76,0x62,0x5E,0x7E,0xC6,0xF4,0x4C,0x42,0xE9,
810 0xA6,0x37,0xED,0x6B,0x0B,0xFF,0x5C,0xB6,0xF4,0x06,0xB7,0xED,
811 0xEE,0x38,0x6B,0xFB,0x5A,0x89,0x9F,0xA5,0xAE,0x9F,0x24,0x11,
812 0x7C,0x4B,0x1F,0xE6,0x49,0x28,0x66,0x51,0xEC,0xE4,0x5B,0x3D,
813 0xC2,0x00,0x7C,0xB8,0xA1,0x63,0xBF,0x05,0x98,0xDA,0x48,0x36,
814 0x1C,0x55,0xD3,0x9A,0x69,0x16,0x3F,0xA8,0xFD,0x24,0xCF,0x5F,
815 0x83,0x65,0x5D,0x23,0xDC,0xA3,0xAD,0x96,0x1C,0x62,0xF3,0x56,
816 0x20,0x85,0x52,0xBB,0x9E,0xD5,0x29,0x07,0x70,0x96,0x96,0x6D,
817 0x67,0x0C,0x35,0x4E,0x4A,0xBC,0x98,0x04,0xF1,0x74,0x6C,0x08,
818 0xCA,0x18,0x21,0x7C,0x32,0x90,0x5E,0x46,0x2E,0x36,0xCE,0x3B,
819 0xE3,0x9E,0x77,0x2C,0x18,0x0E,0x86,0x03,0x9B,0x27,0x83,0xA2,
820 0xEC,0x07,0xA2,0x8F,0xB5,0xC5,0x5D,0xF0,0x6F,0x4C,0x52,0xC9,
821 0xDE,0x2B,0xCB,0xF6,0x95,0x58,0x17,0x18,0x39,0x95,0x49,0x7C,
822 0xEA,0x95,0x6A,0xE5,0x15,0xD2,0x26,0x18,0x98,0xFA,0x05,0x10,
823 0x15,0x72,0x8E,0x5A,0x8A,0xAC,0xAA,0x68,0xFF,0xFF,0xFF,0xFF,
824 0xFF,0xFF,0xFF,0xFF,
825 };
826#endif
827 DH *dh = DH_new();
828 if (dh) {
Lukas Tribus4c0d45a2014-08-18 00:56:32 +0200829#if (OPENSSL_VERSION_NUMBER >= 0x0090801fL && !defined OPENSSL_IS_BORINGSSL)
Remi Gacognef46cd6e2014-06-12 14:58:40 +0200830 dh->p = get_rfc3526_prime_2048(NULL);
831#else
832 dh->p = BN_bin2bn(rfc_3526_prime_2048, sizeof rfc_3526_prime_2048, NULL);
833#endif
834 /* See RFC 3526, Section 3 "2048-bit MODP Group"
835 for the reason why 2 is used as generator.
836 */
837 BN_dec2bn(&dh->g, "2");
838 if (!dh->p || !dh->g) {
839 DH_free(dh);
840 dh = NULL;
841 }
842 }
843 return dh;
844}
845
846static DH *ssl_get_dh_4096(void)
847{
Lukas Tribus4c0d45a2014-08-18 00:56:32 +0200848#if (OPENSSL_VERSION_NUMBER < 0x0090801fL || defined OPENSSL_IS_BORINGSSL)
Remi Gacognef46cd6e2014-06-12 14:58:40 +0200849 static const unsigned char rfc_3526_prime_4096[] = {
850 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xC9,0x0F,0xDA,0xA2,
851 0x21,0x68,0xC2,0x34,0xC4,0xC6,0x62,0x8B,0x80,0xDC,0x1C,0xD1,
852 0x29,0x02,0x4E,0x08,0x8A,0x67,0xCC,0x74,0x02,0x0B,0xBE,0xA6,
853 0x3B,0x13,0x9B,0x22,0x51,0x4A,0x08,0x79,0x8E,0x34,0x04,0xDD,
854 0xEF,0x95,0x19,0xB3,0xCD,0x3A,0x43,0x1B,0x30,0x2B,0x0A,0x6D,
855 0xF2,0x5F,0x14,0x37,0x4F,0xE1,0x35,0x6D,0x6D,0x51,0xC2,0x45,
856 0xE4,0x85,0xB5,0x76,0x62,0x5E,0x7E,0xC6,0xF4,0x4C,0x42,0xE9,
857 0xA6,0x37,0xED,0x6B,0x0B,0xFF,0x5C,0xB6,0xF4,0x06,0xB7,0xED,
858 0xEE,0x38,0x6B,0xFB,0x5A,0x89,0x9F,0xA5,0xAE,0x9F,0x24,0x11,
859 0x7C,0x4B,0x1F,0xE6,0x49,0x28,0x66,0x51,0xEC,0xE4,0x5B,0x3D,
860 0xC2,0x00,0x7C,0xB8,0xA1,0x63,0xBF,0x05,0x98,0xDA,0x48,0x36,
861 0x1C,0x55,0xD3,0x9A,0x69,0x16,0x3F,0xA8,0xFD,0x24,0xCF,0x5F,
862 0x83,0x65,0x5D,0x23,0xDC,0xA3,0xAD,0x96,0x1C,0x62,0xF3,0x56,
863 0x20,0x85,0x52,0xBB,0x9E,0xD5,0x29,0x07,0x70,0x96,0x96,0x6D,
864 0x67,0x0C,0x35,0x4E,0x4A,0xBC,0x98,0x04,0xF1,0x74,0x6C,0x08,
865 0xCA,0x18,0x21,0x7C,0x32,0x90,0x5E,0x46,0x2E,0x36,0xCE,0x3B,
866 0xE3,0x9E,0x77,0x2C,0x18,0x0E,0x86,0x03,0x9B,0x27,0x83,0xA2,
867 0xEC,0x07,0xA2,0x8F,0xB5,0xC5,0x5D,0xF0,0x6F,0x4C,0x52,0xC9,
868 0xDE,0x2B,0xCB,0xF6,0x95,0x58,0x17,0x18,0x39,0x95,0x49,0x7C,
869 0xEA,0x95,0x6A,0xE5,0x15,0xD2,0x26,0x18,0x98,0xFA,0x05,0x10,
870 0x15,0x72,0x8E,0x5A,0x8A,0xAA,0xC4,0x2D,0xAD,0x33,0x17,0x0D,
871 0x04,0x50,0x7A,0x33,0xA8,0x55,0x21,0xAB,0xDF,0x1C,0xBA,0x64,
872 0xEC,0xFB,0x85,0x04,0x58,0xDB,0xEF,0x0A,0x8A,0xEA,0x71,0x57,
873 0x5D,0x06,0x0C,0x7D,0xB3,0x97,0x0F,0x85,0xA6,0xE1,0xE4,0xC7,
874 0xAB,0xF5,0xAE,0x8C,0xDB,0x09,0x33,0xD7,0x1E,0x8C,0x94,0xE0,
875 0x4A,0x25,0x61,0x9D,0xCE,0xE3,0xD2,0x26,0x1A,0xD2,0xEE,0x6B,
876 0xF1,0x2F,0xFA,0x06,0xD9,0x8A,0x08,0x64,0xD8,0x76,0x02,0x73,
877 0x3E,0xC8,0x6A,0x64,0x52,0x1F,0x2B,0x18,0x17,0x7B,0x20,0x0C,
878 0xBB,0xE1,0x17,0x57,0x7A,0x61,0x5D,0x6C,0x77,0x09,0x88,0xC0,
879 0xBA,0xD9,0x46,0xE2,0x08,0xE2,0x4F,0xA0,0x74,0xE5,0xAB,0x31,
880 0x43,0xDB,0x5B,0xFC,0xE0,0xFD,0x10,0x8E,0x4B,0x82,0xD1,0x20,
881 0xA9,0x21,0x08,0x01,0x1A,0x72,0x3C,0x12,0xA7,0x87,0xE6,0xD7,
882 0x88,0x71,0x9A,0x10,0xBD,0xBA,0x5B,0x26,0x99,0xC3,0x27,0x18,
883 0x6A,0xF4,0xE2,0x3C,0x1A,0x94,0x68,0x34,0xB6,0x15,0x0B,0xDA,
884 0x25,0x83,0xE9,0xCA,0x2A,0xD4,0x4C,0xE8,0xDB,0xBB,0xC2,0xDB,
885 0x04,0xDE,0x8E,0xF9,0x2E,0x8E,0xFC,0x14,0x1F,0xBE,0xCA,0xA6,
886 0x28,0x7C,0x59,0x47,0x4E,0x6B,0xC0,0x5D,0x99,0xB2,0x96,0x4F,
887 0xA0,0x90,0xC3,0xA2,0x23,0x3B,0xA1,0x86,0x51,0x5B,0xE7,0xED,
888 0x1F,0x61,0x29,0x70,0xCE,0xE2,0xD7,0xAF,0xB8,0x1B,0xDD,0x76,
889 0x21,0x70,0x48,0x1C,0xD0,0x06,0x91,0x27,0xD5,0xB0,0x5A,0xA9,
890 0x93,0xB4,0xEA,0x98,0x8D,0x8F,0xDD,0xC1,0x86,0xFF,0xB7,0xDC,
891 0x90,0xA6,0xC0,0x8F,0x4D,0xF4,0x35,0xC9,0x34,0x06,0x31,0x99,
892 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
893 };
894#endif
895 DH *dh = DH_new();
896 if (dh) {
Lukas Tribus4c0d45a2014-08-18 00:56:32 +0200897#if (OPENSSL_VERSION_NUMBER >= 0x0090801fL && !defined OPENSSL_IS_BORINGSSL)
Remi Gacognef46cd6e2014-06-12 14:58:40 +0200898 dh->p = get_rfc3526_prime_4096(NULL);
899#else
900 dh->p = BN_bin2bn(rfc_3526_prime_4096, sizeof rfc_3526_prime_4096, NULL);
901#endif
902 /* See RFC 3526, Section 5 "4096-bit MODP Group"
903 for the reason why 2 is used as generator.
904 */
905 BN_dec2bn(&dh->g, "2");
906 if (!dh->p || !dh->g) {
907 DH_free(dh);
908 dh = NULL;
909 }
910 }
911 return dh;
912}
913
914static DH *ssl_get_dh_8192(void)
915{
Lukas Tribus4c0d45a2014-08-18 00:56:32 +0200916#if (OPENSSL_VERSION_NUMBER < 0x0090801fL || defined OPENSSL_IS_BORINGSSL)
Remi Gacognef46cd6e2014-06-12 14:58:40 +0200917 static const unsigned char rfc_3526_prime_8192[] = {
918 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xC9,0x0F,0xDA,0xA2,
919 0x21,0x68,0xC2,0x34,0xC4,0xC6,0x62,0x8B,0x80,0xDC,0x1C,0xD1,
920 0x29,0x02,0x4E,0x08,0x8A,0x67,0xCC,0x74,0x02,0x0B,0xBE,0xA6,
921 0x3B,0x13,0x9B,0x22,0x51,0x4A,0x08,0x79,0x8E,0x34,0x04,0xDD,
922 0xEF,0x95,0x19,0xB3,0xCD,0x3A,0x43,0x1B,0x30,0x2B,0x0A,0x6D,
923 0xF2,0x5F,0x14,0x37,0x4F,0xE1,0x35,0x6D,0x6D,0x51,0xC2,0x45,
924 0xE4,0x85,0xB5,0x76,0x62,0x5E,0x7E,0xC6,0xF4,0x4C,0x42,0xE9,
925 0xA6,0x37,0xED,0x6B,0x0B,0xFF,0x5C,0xB6,0xF4,0x06,0xB7,0xED,
926 0xEE,0x38,0x6B,0xFB,0x5A,0x89,0x9F,0xA5,0xAE,0x9F,0x24,0x11,
927 0x7C,0x4B,0x1F,0xE6,0x49,0x28,0x66,0x51,0xEC,0xE4,0x5B,0x3D,
928 0xC2,0x00,0x7C,0xB8,0xA1,0x63,0xBF,0x05,0x98,0xDA,0x48,0x36,
929 0x1C,0x55,0xD3,0x9A,0x69,0x16,0x3F,0xA8,0xFD,0x24,0xCF,0x5F,
930 0x83,0x65,0x5D,0x23,0xDC,0xA3,0xAD,0x96,0x1C,0x62,0xF3,0x56,
931 0x20,0x85,0x52,0xBB,0x9E,0xD5,0x29,0x07,0x70,0x96,0x96,0x6D,
932 0x67,0x0C,0x35,0x4E,0x4A,0xBC,0x98,0x04,0xF1,0x74,0x6C,0x08,
933 0xCA,0x18,0x21,0x7C,0x32,0x90,0x5E,0x46,0x2E,0x36,0xCE,0x3B,
934 0xE3,0x9E,0x77,0x2C,0x18,0x0E,0x86,0x03,0x9B,0x27,0x83,0xA2,
935 0xEC,0x07,0xA2,0x8F,0xB5,0xC5,0x5D,0xF0,0x6F,0x4C,0x52,0xC9,
936 0xDE,0x2B,0xCB,0xF6,0x95,0x58,0x17,0x18,0x39,0x95,0x49,0x7C,
937 0xEA,0x95,0x6A,0xE5,0x15,0xD2,0x26,0x18,0x98,0xFA,0x05,0x10,
938 0x15,0x72,0x8E,0x5A,0x8A,0xAA,0xC4,0x2D,0xAD,0x33,0x17,0x0D,
939 0x04,0x50,0x7A,0x33,0xA8,0x55,0x21,0xAB,0xDF,0x1C,0xBA,0x64,
940 0xEC,0xFB,0x85,0x04,0x58,0xDB,0xEF,0x0A,0x8A,0xEA,0x71,0x57,
941 0x5D,0x06,0x0C,0x7D,0xB3,0x97,0x0F,0x85,0xA6,0xE1,0xE4,0xC7,
942 0xAB,0xF5,0xAE,0x8C,0xDB,0x09,0x33,0xD7,0x1E,0x8C,0x94,0xE0,
943 0x4A,0x25,0x61,0x9D,0xCE,0xE3,0xD2,0x26,0x1A,0xD2,0xEE,0x6B,
944 0xF1,0x2F,0xFA,0x06,0xD9,0x8A,0x08,0x64,0xD8,0x76,0x02,0x73,
945 0x3E,0xC8,0x6A,0x64,0x52,0x1F,0x2B,0x18,0x17,0x7B,0x20,0x0C,
946 0xBB,0xE1,0x17,0x57,0x7A,0x61,0x5D,0x6C,0x77,0x09,0x88,0xC0,
947 0xBA,0xD9,0x46,0xE2,0x08,0xE2,0x4F,0xA0,0x74,0xE5,0xAB,0x31,
948 0x43,0xDB,0x5B,0xFC,0xE0,0xFD,0x10,0x8E,0x4B,0x82,0xD1,0x20,
949 0xA9,0x21,0x08,0x01,0x1A,0x72,0x3C,0x12,0xA7,0x87,0xE6,0xD7,
950 0x88,0x71,0x9A,0x10,0xBD,0xBA,0x5B,0x26,0x99,0xC3,0x27,0x18,
951 0x6A,0xF4,0xE2,0x3C,0x1A,0x94,0x68,0x34,0xB6,0x15,0x0B,0xDA,
952 0x25,0x83,0xE9,0xCA,0x2A,0xD4,0x4C,0xE8,0xDB,0xBB,0xC2,0xDB,
953 0x04,0xDE,0x8E,0xF9,0x2E,0x8E,0xFC,0x14,0x1F,0xBE,0xCA,0xA6,
954 0x28,0x7C,0x59,0x47,0x4E,0x6B,0xC0,0x5D,0x99,0xB2,0x96,0x4F,
955 0xA0,0x90,0xC3,0xA2,0x23,0x3B,0xA1,0x86,0x51,0x5B,0xE7,0xED,
956 0x1F,0x61,0x29,0x70,0xCE,0xE2,0xD7,0xAF,0xB8,0x1B,0xDD,0x76,
957 0x21,0x70,0x48,0x1C,0xD0,0x06,0x91,0x27,0xD5,0xB0,0x5A,0xA9,
958 0x93,0xB4,0xEA,0x98,0x8D,0x8F,0xDD,0xC1,0x86,0xFF,0xB7,0xDC,
959 0x90,0xA6,0xC0,0x8F,0x4D,0xF4,0x35,0xC9,0x34,0x02,0x84,0x92,
960 0x36,0xC3,0xFA,0xB4,0xD2,0x7C,0x70,0x26,0xC1,0xD4,0xDC,0xB2,
961 0x60,0x26,0x46,0xDE,0xC9,0x75,0x1E,0x76,0x3D,0xBA,0x37,0xBD,
962 0xF8,0xFF,0x94,0x06,0xAD,0x9E,0x53,0x0E,0xE5,0xDB,0x38,0x2F,
963 0x41,0x30,0x01,0xAE,0xB0,0x6A,0x53,0xED,0x90,0x27,0xD8,0x31,
964 0x17,0x97,0x27,0xB0,0x86,0x5A,0x89,0x18,0xDA,0x3E,0xDB,0xEB,
965 0xCF,0x9B,0x14,0xED,0x44,0xCE,0x6C,0xBA,0xCE,0xD4,0xBB,0x1B,
966 0xDB,0x7F,0x14,0x47,0xE6,0xCC,0x25,0x4B,0x33,0x20,0x51,0x51,
967 0x2B,0xD7,0xAF,0x42,0x6F,0xB8,0xF4,0x01,0x37,0x8C,0xD2,0xBF,
968 0x59,0x83,0xCA,0x01,0xC6,0x4B,0x92,0xEC,0xF0,0x32,0xEA,0x15,
969 0xD1,0x72,0x1D,0x03,0xF4,0x82,0xD7,0xCE,0x6E,0x74,0xFE,0xF6,
970 0xD5,0x5E,0x70,0x2F,0x46,0x98,0x0C,0x82,0xB5,0xA8,0x40,0x31,
971 0x90,0x0B,0x1C,0x9E,0x59,0xE7,0xC9,0x7F,0xBE,0xC7,0xE8,0xF3,
972 0x23,0xA9,0x7A,0x7E,0x36,0xCC,0x88,0xBE,0x0F,0x1D,0x45,0xB7,
973 0xFF,0x58,0x5A,0xC5,0x4B,0xD4,0x07,0xB2,0x2B,0x41,0x54,0xAA,
974 0xCC,0x8F,0x6D,0x7E,0xBF,0x48,0xE1,0xD8,0x14,0xCC,0x5E,0xD2,
975 0x0F,0x80,0x37,0xE0,0xA7,0x97,0x15,0xEE,0xF2,0x9B,0xE3,0x28,
976 0x06,0xA1,0xD5,0x8B,0xB7,0xC5,0xDA,0x76,0xF5,0x50,0xAA,0x3D,
977 0x8A,0x1F,0xBF,0xF0,0xEB,0x19,0xCC,0xB1,0xA3,0x13,0xD5,0x5C,
978 0xDA,0x56,0xC9,0xEC,0x2E,0xF2,0x96,0x32,0x38,0x7F,0xE8,0xD7,
979 0x6E,0x3C,0x04,0x68,0x04,0x3E,0x8F,0x66,0x3F,0x48,0x60,0xEE,
980 0x12,0xBF,0x2D,0x5B,0x0B,0x74,0x74,0xD6,0xE6,0x94,0xF9,0x1E,
981 0x6D,0xBE,0x11,0x59,0x74,0xA3,0x92,0x6F,0x12,0xFE,0xE5,0xE4,
982 0x38,0x77,0x7C,0xB6,0xA9,0x32,0xDF,0x8C,0xD8,0xBE,0xC4,0xD0,
983 0x73,0xB9,0x31,0xBA,0x3B,0xC8,0x32,0xB6,0x8D,0x9D,0xD3,0x00,
984 0x74,0x1F,0xA7,0xBF,0x8A,0xFC,0x47,0xED,0x25,0x76,0xF6,0x93,
985 0x6B,0xA4,0x24,0x66,0x3A,0xAB,0x63,0x9C,0x5A,0xE4,0xF5,0x68,
986 0x34,0x23,0xB4,0x74,0x2B,0xF1,0xC9,0x78,0x23,0x8F,0x16,0xCB,
987 0xE3,0x9D,0x65,0x2D,0xE3,0xFD,0xB8,0xBE,0xFC,0x84,0x8A,0xD9,
988 0x22,0x22,0x2E,0x04,0xA4,0x03,0x7C,0x07,0x13,0xEB,0x57,0xA8,
989 0x1A,0x23,0xF0,0xC7,0x34,0x73,0xFC,0x64,0x6C,0xEA,0x30,0x6B,
990 0x4B,0xCB,0xC8,0x86,0x2F,0x83,0x85,0xDD,0xFA,0x9D,0x4B,0x7F,
991 0xA2,0xC0,0x87,0xE8,0x79,0x68,0x33,0x03,0xED,0x5B,0xDD,0x3A,
992 0x06,0x2B,0x3C,0xF5,0xB3,0xA2,0x78,0xA6,0x6D,0x2A,0x13,0xF8,
993 0x3F,0x44,0xF8,0x2D,0xDF,0x31,0x0E,0xE0,0x74,0xAB,0x6A,0x36,
994 0x45,0x97,0xE8,0x99,0xA0,0x25,0x5D,0xC1,0x64,0xF3,0x1C,0xC5,
995 0x08,0x46,0x85,0x1D,0xF9,0xAB,0x48,0x19,0x5D,0xED,0x7E,0xA1,
996 0xB1,0xD5,0x10,0xBD,0x7E,0xE7,0x4D,0x73,0xFA,0xF3,0x6B,0xC3,
997 0x1E,0xCF,0xA2,0x68,0x35,0x90,0x46,0xF4,0xEB,0x87,0x9F,0x92,
998 0x40,0x09,0x43,0x8B,0x48,0x1C,0x6C,0xD7,0x88,0x9A,0x00,0x2E,
999 0xD5,0xEE,0x38,0x2B,0xC9,0x19,0x0D,0xA6,0xFC,0x02,0x6E,0x47,
1000 0x95,0x58,0xE4,0x47,0x56,0x77,0xE9,0xAA,0x9E,0x30,0x50,0xE2,
1001 0x76,0x56,0x94,0xDF,0xC8,0x1F,0x56,0xE8,0x80,0xB9,0x6E,0x71,
1002 0x60,0xC9,0x80,0xDD,0x98,0xED,0xD3,0xDF,0xFF,0xFF,0xFF,0xFF,
1003 0xFF,0xFF,0xFF,0xFF,
1004 };
1005#endif
1006 DH *dh = DH_new();
1007 if (dh) {
Lukas Tribus4c0d45a2014-08-18 00:56:32 +02001008#if (OPENSSL_VERSION_NUMBER >= 0x0090801fL && !defined OPENSSL_IS_BORINGSSL)
Remi Gacognef46cd6e2014-06-12 14:58:40 +02001009 dh->p = get_rfc3526_prime_8192(NULL);
1010#else
1011 dh->p = BN_bin2bn(rfc_3526_prime_8192, sizeof rfc_3526_prime_8192, NULL);
1012#endif
1013 /* See RFC 3526, Section 7 "8192-bit MODP Group"
1014 for the reason why 2 is used as generator.
1015 */
1016 BN_dec2bn(&dh->g, "2");
1017 if (!dh->p || !dh->g) {
1018 DH_free(dh);
1019 dh = NULL;
1020 }
1021 }
1022 return dh;
1023}
1024
1025/* Returns Diffie-Hellman parameters matching the private key length
1026 but not exceeding global.tune.ssl_default_dh_param */
1027static DH *ssl_get_tmp_dh(SSL *ssl, int export, int keylen)
1028{
1029 DH *dh = NULL;
1030 EVP_PKEY *pkey = SSL_get_privatekey(ssl);
1031 int type = pkey ? EVP_PKEY_type(pkey->type) : EVP_PKEY_NONE;
1032
1033 /* The keylen supplied by OpenSSL can only be 512 or 1024.
1034 See ssl3_send_server_key_exchange() in ssl/s3_srvr.c
1035 */
1036 if (type == EVP_PKEY_RSA || type == EVP_PKEY_DSA) {
1037 keylen = EVP_PKEY_bits(pkey);
1038 }
1039
1040 if (keylen > global.tune.ssl_default_dh_param) {
1041 keylen = global.tune.ssl_default_dh_param;
1042 }
1043
1044 if (keylen >= 8192) {
Remi Gacogne8de54152014-07-15 11:36:40 +02001045 dh = local_dh_8192;
Remi Gacognef46cd6e2014-06-12 14:58:40 +02001046 }
1047 else if (keylen >= 4096) {
Remi Gacogne8de54152014-07-15 11:36:40 +02001048 dh = local_dh_4096;
Remi Gacognef46cd6e2014-06-12 14:58:40 +02001049 }
1050 else if (keylen >= 2048) {
Remi Gacogne8de54152014-07-15 11:36:40 +02001051 dh = local_dh_2048;
Remi Gacognef46cd6e2014-06-12 14:58:40 +02001052 }
1053 else {
Remi Gacogne8de54152014-07-15 11:36:40 +02001054 dh = local_dh_1024;
Remi Gacognef46cd6e2014-06-12 14:58:40 +02001055 }
1056
1057 return dh;
1058}
1059
Emeric Bruna4bcd9a2012-09-20 16:19:02 +02001060/* Loads Diffie-Hellman parameter from a file. Returns 1 if loaded, else -1
1061 if an error occured, and 0 if parameter not found. */
Willy Tarreau6e774b42014-04-25 21:35:23 +02001062int ssl_sock_load_dh_params(SSL_CTX *ctx, const char *file)
Emeric Bruna4bcd9a2012-09-20 16:19:02 +02001063{
1064 int ret = -1;
1065 BIO *in;
1066 DH *dh = NULL;
1067
1068 in = BIO_new(BIO_s_file());
1069 if (in == NULL)
1070 goto end;
1071
1072 if (BIO_read_filename(in, file) <= 0)
1073 goto end;
1074
1075 dh = PEM_read_bio_DHparams(in, NULL, ctx->default_passwd_callback, ctx->default_passwd_callback_userdata);
Remi Gacognef46cd6e2014-06-12 14:58:40 +02001076 if (dh) {
1077 ret = 1;
1078 SSL_CTX_set_tmp_dh(ctx, dh);
1079 /* Setting ssl default dh param to the size of the static DH params
1080 found in the file. This way we know that there is no use
1081 complaining later about ssl-default-dh-param not being set. */
1082 global.tune.ssl_default_dh_param = DH_size(dh) * 8;
1083 }
1084 else {
Emeric Brun41fdb3c2013-04-26 11:05:44 +02001085 /* Clear openssl global errors stack */
1086 ERR_clear_error();
1087
Remi Gacognef46cd6e2014-06-12 14:58:40 +02001088 if (global.tune.ssl_default_dh_param <= 1024) {
1089 /* we are limited to DH parameter of 1024 bits anyway */
Remi Gacogne8de54152014-07-15 11:36:40 +02001090 local_dh_1024 = ssl_get_dh_1024();
1091 if (local_dh_1024 == NULL)
Remi Gacognef46cd6e2014-06-12 14:58:40 +02001092 goto end;
Willy Tarreau6e774b42014-04-25 21:35:23 +02001093
Remi Gacogne8de54152014-07-15 11:36:40 +02001094 SSL_CTX_set_tmp_dh(ctx, local_dh_1024);
Remi Gacognef46cd6e2014-06-12 14:58:40 +02001095 }
1096 else {
1097 SSL_CTX_set_tmp_dh_callback(ctx, ssl_get_tmp_dh);
1098 }
Willy Tarreau6e774b42014-04-25 21:35:23 +02001099
Emeric Brun41fdb3c2013-04-26 11:05:44 +02001100 ret = 0; /* DH params not found */
Emeric Bruna4bcd9a2012-09-20 16:19:02 +02001101 }
Emeric Brun644cde02012-12-14 11:21:13 +01001102
Emeric Bruna4bcd9a2012-09-20 16:19:02 +02001103end:
1104 if (dh)
1105 DH_free(dh);
1106
1107 if (in)
Emeric Brun41fdb3c2013-04-26 11:05:44 +02001108 BIO_free(in);
Emeric Bruna4bcd9a2012-09-20 16:19:02 +02001109
1110 return ret;
1111}
1112#endif
1113
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +02001114static int ssl_sock_add_cert_sni(SSL_CTX *ctx, struct bind_conf *s, char *name, int order)
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01001115{
1116 struct sni_ctx *sc;
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +02001117 int wild = 0, neg = 0;
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01001118
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +02001119 if (*name == '!') {
1120 neg = 1;
1121 name++;
1122 }
1123 if (*name == '*') {
1124 wild = 1;
1125 name++;
1126 }
1127 /* !* filter is a nop */
1128 if (neg && wild)
1129 return order;
1130 if (*name) {
1131 int j, len;
1132 len = strlen(name);
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01001133 sc = malloc(sizeof(struct sni_ctx) + len + 1);
1134 for (j = 0; j < len; j++)
1135 sc->name.key[j] = tolower(name[j]);
1136 sc->name.key[len] = 0;
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01001137 sc->ctx = ctx;
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +02001138 sc->order = order++;
1139 sc->neg = neg;
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01001140 if (wild)
1141 ebst_insert(&s->sni_w_ctx, &sc->name);
1142 else
1143 ebst_insert(&s->sni_ctx, &sc->name);
1144 }
1145 return order;
1146}
1147
Emeric Brunfc0421f2012-09-07 17:30:07 +02001148/* Loads a certificate key and CA chain from a file. Returns 0 on error, -1 if
1149 * an early error happens and the caller must call SSL_CTX_free() by itelf.
1150 */
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +02001151static 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 +02001152{
1153 BIO *in;
1154 X509 *x = NULL, *ca;
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +02001155 int i, err;
Emeric Brunfc0421f2012-09-07 17:30:07 +02001156 int ret = -1;
1157 int order = 0;
1158 X509_NAME *xname;
1159 char *str;
Emeric Brunfc0421f2012-09-07 17:30:07 +02001160#ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME
1161 STACK_OF(GENERAL_NAME) *names;
1162#endif
1163
1164 in = BIO_new(BIO_s_file());
1165 if (in == NULL)
1166 goto end;
1167
1168 if (BIO_read_filename(in, file) <= 0)
1169 goto end;
1170
1171 x = PEM_read_bio_X509_AUX(in, NULL, ctx->default_passwd_callback, ctx->default_passwd_callback_userdata);
1172 if (x == NULL)
1173 goto end;
1174
Emeric Brun50bcecc2013-04-22 13:05:23 +02001175 if (fcount) {
1176 while (fcount--)
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +02001177 order = ssl_sock_add_cert_sni(ctx, s, sni_filter[fcount], order);
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01001178 }
1179 else {
Emeric Brunfc0421f2012-09-07 17:30:07 +02001180#ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01001181 names = X509_get_ext_d2i(x, NID_subject_alt_name, NULL, NULL);
1182 if (names) {
1183 for (i = 0; i < sk_GENERAL_NAME_num(names); i++) {
1184 GENERAL_NAME *name = sk_GENERAL_NAME_value(names, i);
1185 if (name->type == GEN_DNS) {
1186 if (ASN1_STRING_to_UTF8((unsigned char **)&str, name->d.dNSName) >= 0) {
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +02001187 order = ssl_sock_add_cert_sni(ctx, s, str, order);
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01001188 OPENSSL_free(str);
Emeric Brunfc0421f2012-09-07 17:30:07 +02001189 }
Emeric Brunfc0421f2012-09-07 17:30:07 +02001190 }
1191 }
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01001192 sk_GENERAL_NAME_pop_free(names, GENERAL_NAME_free);
Emeric Brunfc0421f2012-09-07 17:30:07 +02001193 }
Emeric Brunfc0421f2012-09-07 17:30:07 +02001194#endif /* SSL_CTRL_SET_TLSEXT_HOSTNAME */
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01001195 xname = X509_get_subject_name(x);
1196 i = -1;
1197 while ((i = X509_NAME_get_index_by_NID(xname, NID_commonName, i)) != -1) {
1198 X509_NAME_ENTRY *entry = X509_NAME_get_entry(xname, i);
1199 if (ASN1_STRING_to_UTF8((unsigned char **)&str, entry->value) >= 0) {
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +02001200 order = ssl_sock_add_cert_sni(ctx, s, str, order);
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01001201 OPENSSL_free(str);
Emeric Brunfc0421f2012-09-07 17:30:07 +02001202 }
Emeric Brunfc0421f2012-09-07 17:30:07 +02001203 }
1204 }
1205
1206 ret = 0; /* the caller must not free the SSL_CTX argument anymore */
1207 if (!SSL_CTX_use_certificate(ctx, x))
1208 goto end;
1209
1210 if (ctx->extra_certs != NULL) {
1211 sk_X509_pop_free(ctx->extra_certs, X509_free);
1212 ctx->extra_certs = NULL;
1213 }
1214
1215 while ((ca = PEM_read_bio_X509(in, NULL, ctx->default_passwd_callback, ctx->default_passwd_callback_userdata))) {
1216 if (!SSL_CTX_add_extra_chain_cert(ctx, ca)) {
1217 X509_free(ca);
1218 goto end;
1219 }
1220 }
1221
1222 err = ERR_get_error();
1223 if (!err || (ERR_GET_LIB(err) == ERR_LIB_PEM && ERR_GET_REASON(err) == PEM_R_NO_START_LINE)) {
1224 /* we successfully reached the last cert in the file */
1225 ret = 1;
1226 }
1227 ERR_clear_error();
1228
1229end:
1230 if (x)
1231 X509_free(x);
1232
1233 if (in)
1234 BIO_free(in);
1235
1236 return ret;
1237}
1238
Emeric Brun50bcecc2013-04-22 13:05:23 +02001239static 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 +02001240{
1241 int ret;
1242 SSL_CTX *ctx;
1243
1244 ctx = SSL_CTX_new(SSLv23_server_method());
1245 if (!ctx) {
Willy Tarreaueb6cead2012-09-20 19:43:14 +02001246 memprintf(err, "%sunable to allocate SSL context for cert '%s'.\n",
1247 err && *err ? *err : "", path);
Emeric Brunfc0421f2012-09-07 17:30:07 +02001248 return 1;
1249 }
1250
1251 if (SSL_CTX_use_PrivateKey_file(ctx, path, SSL_FILETYPE_PEM) <= 0) {
Willy Tarreaueb6cead2012-09-20 19:43:14 +02001252 memprintf(err, "%sunable to load SSL private key from PEM file '%s'.\n",
1253 err && *err ? *err : "", path);
Emeric Brunfc0421f2012-09-07 17:30:07 +02001254 SSL_CTX_free(ctx);
1255 return 1;
1256 }
1257
Emeric Brun50bcecc2013-04-22 13:05:23 +02001258 ret = ssl_sock_load_cert_chain_file(ctx, path, bind_conf, sni_filter, fcount);
Emeric Brunfc0421f2012-09-07 17:30:07 +02001259 if (ret <= 0) {
Willy Tarreaueb6cead2012-09-20 19:43:14 +02001260 memprintf(err, "%sunable to load SSL certificate from PEM file '%s'.\n",
1261 err && *err ? *err : "", path);
Emeric Brunfc0421f2012-09-07 17:30:07 +02001262 if (ret < 0) /* serious error, must do that ourselves */
1263 SSL_CTX_free(ctx);
1264 return 1;
1265 }
Emeric Brun61694ab2012-10-26 13:35:33 +02001266
1267 if (SSL_CTX_check_private_key(ctx) <= 0) {
1268 memprintf(err, "%sinconsistencies between private key and certificate loaded from PEM file '%s'.\n",
1269 err && *err ? *err : "", path);
1270 return 1;
1271 }
1272
Emeric Brunfc0421f2012-09-07 17:30:07 +02001273 /* we must not free the SSL_CTX anymore below, since it's already in
1274 * the tree, so it will be discovered and cleaned in time.
1275 */
Emeric Bruna4bcd9a2012-09-20 16:19:02 +02001276#ifndef OPENSSL_NO_DH
1277 ret = ssl_sock_load_dh_params(ctx, path);
1278 if (ret < 0) {
1279 if (err)
1280 memprintf(err, "%sunable to load DH parameters from file '%s'.\n",
1281 *err ? *err : "", path);
1282 return 1;
1283 }
1284#endif
1285
Lukas Tribus656c5fa2014-08-18 00:56:31 +02001286#if (defined SSL_CTRL_SET_TLSEXT_STATUS_REQ_CB && !defined OPENSSL_IS_BORINGSSL)
Emeric Brun4147b2e2014-06-16 18:36:30 +02001287 ret = ssl_sock_load_ocsp(ctx, path);
1288 if (ret < 0) {
1289 if (err)
1290 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",
1291 *err ? *err : "", path);
1292 return 1;
1293 }
1294#endif
1295
Emeric Brunfc0421f2012-09-07 17:30:07 +02001296#ifndef SSL_CTRL_SET_TLSEXT_HOSTNAME
Willy Tarreau2a65ff02012-09-13 17:54:29 +02001297 if (bind_conf->default_ctx) {
Willy Tarreaueb6cead2012-09-20 19:43:14 +02001298 memprintf(err, "%sthis version of openssl cannot load multiple SSL certificates.\n",
1299 err && *err ? *err : "");
Emeric Brunfc0421f2012-09-07 17:30:07 +02001300 return 1;
1301 }
1302#endif
Willy Tarreau2a65ff02012-09-13 17:54:29 +02001303 if (!bind_conf->default_ctx)
1304 bind_conf->default_ctx = ctx;
Emeric Brunfc0421f2012-09-07 17:30:07 +02001305
1306 return 0;
1307}
1308
Willy Tarreau79eeafa2012-09-14 07:53:05 +02001309int ssl_sock_load_cert(char *path, struct bind_conf *bind_conf, struct proxy *curproxy, char **err)
Emeric Brunfc0421f2012-09-07 17:30:07 +02001310{
1311 struct dirent *de;
1312 DIR *dir;
1313 struct stat buf;
Willy Tarreauee2663b2012-12-06 11:36:59 +01001314 char *end;
1315 char fp[MAXPATHLEN+1];
Emeric Brunfc0421f2012-09-07 17:30:07 +02001316 int cfgerr = 0;
1317
1318 if (!(dir = opendir(path)))
Emeric Brun50bcecc2013-04-22 13:05:23 +02001319 return ssl_sock_load_cert_file(path, bind_conf, curproxy, NULL, 0, err);
Emeric Brunfc0421f2012-09-07 17:30:07 +02001320
1321 /* strip trailing slashes, including first one */
1322 for (end = path + strlen(path) - 1; end >= path && *end == '/'; end--)
1323 *end = 0;
1324
Emeric Brunfc0421f2012-09-07 17:30:07 +02001325 while ((de = readdir(dir))) {
Emeric Brun2aab7222014-06-18 18:15:09 +02001326 end = strrchr(de->d_name, '.');
1327 if (end && (!strcmp(end, ".issuer") || !strcmp(end, ".ocsp")))
1328 continue;
1329
Willy Tarreauee2663b2012-12-06 11:36:59 +01001330 snprintf(fp, sizeof(fp), "%s/%s", path, de->d_name);
Emeric Brunfc0421f2012-09-07 17:30:07 +02001331 if (stat(fp, &buf) != 0) {
Willy Tarreaueb6cead2012-09-20 19:43:14 +02001332 memprintf(err, "%sunable to stat SSL certificate from file '%s' : %s.\n",
1333 err && *err ? *err : "", fp, strerror(errno));
Emeric Brunfc0421f2012-09-07 17:30:07 +02001334 cfgerr++;
1335 continue;
1336 }
1337 if (!S_ISREG(buf.st_mode))
1338 continue;
Emeric Brun50bcecc2013-04-22 13:05:23 +02001339 cfgerr += ssl_sock_load_cert_file(fp, bind_conf, curproxy, NULL, 0, err);
Emeric Brunfc0421f2012-09-07 17:30:07 +02001340 }
Emeric Brunfc0421f2012-09-07 17:30:07 +02001341 closedir(dir);
1342 return cfgerr;
1343}
1344
Thierry Fournier383085f2013-01-24 14:15:43 +01001345/* Make sure openssl opens /dev/urandom before the chroot. The work is only
1346 * done once. Zero is returned if the operation fails. No error is returned
1347 * if the random is said as not implemented, because we expect that openssl
1348 * will use another method once needed.
1349 */
1350static int ssl_initialize_random()
1351{
1352 unsigned char random;
1353 static int random_initialized = 0;
1354
1355 if (!random_initialized && RAND_bytes(&random, 1) != 0)
1356 random_initialized = 1;
1357
1358 return random_initialized;
1359}
1360
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01001361int ssl_sock_load_cert_list_file(char *file, struct bind_conf *bind_conf, struct proxy *curproxy, char **err)
1362{
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +02001363 char thisline[LINESIZE];
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01001364 FILE *f;
1365 int linenum = 0;
1366 int cfgerr = 0;
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01001367
Willy Tarreauad1731d2013-04-02 17:35:58 +02001368 if ((f = fopen(file, "r")) == NULL) {
1369 memprintf(err, "cannot open file '%s' : %s", file, strerror(errno));
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01001370 return 1;
Willy Tarreauad1731d2013-04-02 17:35:58 +02001371 }
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01001372
1373 while (fgets(thisline, sizeof(thisline), f) != NULL) {
1374 int arg;
Emeric Brun50bcecc2013-04-22 13:05:23 +02001375 int newarg;
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01001376 char *end;
1377 char *args[MAX_LINE_ARGS + 1];
1378 char *line = thisline;
1379
1380 linenum++;
1381 end = line + strlen(line);
1382 if (end-line == sizeof(thisline)-1 && *(end-1) != '\n') {
1383 /* Check if we reached the limit and the last char is not \n.
1384 * Watch out for the last line without the terminating '\n'!
1385 */
Willy Tarreauad1731d2013-04-02 17:35:58 +02001386 memprintf(err, "line %d too long in file '%s', limit is %d characters",
1387 linenum, file, (int)sizeof(thisline)-1);
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01001388 cfgerr = 1;
Willy Tarreauad1731d2013-04-02 17:35:58 +02001389 break;
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01001390 }
1391
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01001392 arg = 0;
Emeric Brun50bcecc2013-04-22 13:05:23 +02001393 newarg = 1;
1394 while (*line) {
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01001395 if (*line == '#' || *line == '\n' || *line == '\r') {
1396 /* end of string, end of loop */
1397 *line = 0;
1398 break;
1399 }
1400 else if (isspace(*line)) {
Emeric Brun50bcecc2013-04-22 13:05:23 +02001401 newarg = 1;
1402 *line = 0;
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01001403 }
Emeric Brun50bcecc2013-04-22 13:05:23 +02001404 else if (newarg) {
1405 if (arg == MAX_LINE_ARGS) {
1406 memprintf(err, "too many args on line %d in file '%s'.",
1407 linenum, file);
1408 cfgerr = 1;
1409 break;
1410 }
1411 newarg = 0;
1412 args[arg++] = line;
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01001413 }
Emeric Brun50bcecc2013-04-22 13:05:23 +02001414 line++;
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01001415 }
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +02001416 if (cfgerr)
1417 break;
Willy Tarreauad1731d2013-04-02 17:35:58 +02001418
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01001419 /* empty line */
Emeric Brun50bcecc2013-04-22 13:05:23 +02001420 if (!arg)
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01001421 continue;
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01001422
Emeric Brun50bcecc2013-04-22 13:05:23 +02001423 cfgerr = ssl_sock_load_cert_file(args[0], bind_conf, curproxy, &args[1], arg-1, err);
Willy Tarreauad1731d2013-04-02 17:35:58 +02001424 if (cfgerr) {
1425 memprintf(err, "error processing line %d in file '%s' : %s", linenum, file, *err);
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01001426 break;
Willy Tarreauad1731d2013-04-02 17:35:58 +02001427 }
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01001428 }
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01001429 fclose(f);
1430 return cfgerr;
1431}
1432
Emeric Brunfc0421f2012-09-07 17:30:07 +02001433#ifndef SSL_OP_CIPHER_SERVER_PREFERENCE /* needs OpenSSL >= 0.9.7 */
1434#define SSL_OP_CIPHER_SERVER_PREFERENCE 0
1435#endif
1436
1437#ifndef SSL_OP_NO_SESSION_RESUMPTION_ON_RENEGOTIATION /* needs OpenSSL >= 0.9.7 */
1438#define SSL_OP_NO_SESSION_RESUMPTION_ON_RENEGOTIATION 0
Willy Tarreau7d588ee2012-11-26 18:47:31 +01001439#define SSL_renegotiate_pending(arg) 0
Emeric Brunfc0421f2012-09-07 17:30:07 +02001440#endif
Emeric Brun2b58d042012-09-20 17:10:03 +02001441#ifndef SSL_OP_SINGLE_ECDH_USE /* needs OpenSSL >= 0.9.8 */
1442#define SSL_OP_SINGLE_ECDH_USE 0
1443#endif
Emeric Brun2d0c4822012-10-02 13:45:20 +02001444#ifndef SSL_OP_NO_TICKET /* needs OpenSSL >= 0.9.8 */
1445#define SSL_OP_NO_TICKET 0
1446#endif
Emeric Brunfc0421f2012-09-07 17:30:07 +02001447#ifndef SSL_OP_NO_COMPRESSION /* needs OpenSSL >= 0.9.9 */
1448#define SSL_OP_NO_COMPRESSION 0
1449#endif
Emeric Brunc0ff4922012-09-28 19:37:02 +02001450#ifndef SSL_OP_NO_TLSv1_1 /* needs OpenSSL >= 1.0.1 */
1451#define SSL_OP_NO_TLSv1_1 0
1452#endif
1453#ifndef SSL_OP_NO_TLSv1_2 /* needs OpenSSL >= 1.0.1 */
1454#define SSL_OP_NO_TLSv1_2 0
1455#endif
Emeric Bruna4bcd9a2012-09-20 16:19:02 +02001456#ifndef SSL_OP_SINGLE_DH_USE /* needs OpenSSL >= 0.9.6 */
1457#define SSL_OP_SINGLE_DH_USE 0
1458#endif
Emeric Brun2b58d042012-09-20 17:10:03 +02001459#ifndef SSL_OP_SINGLE_ECDH_USE /* needs OpenSSL >= 1.0.0 */
1460#define SSL_OP_SINGLE_ECDH_USE 0
1461#endif
Emeric Brunfc0421f2012-09-07 17:30:07 +02001462#ifndef SSL_MODE_RELEASE_BUFFERS /* needs OpenSSL >= 1.0.0 */
1463#define SSL_MODE_RELEASE_BUFFERS 0
1464#endif
Remi Gacognef46cd6e2014-06-12 14:58:40 +02001465
Willy Tarreau2a65ff02012-09-13 17:54:29 +02001466int ssl_sock_prepare_ctx(struct bind_conf *bind_conf, SSL_CTX *ctx, struct proxy *curproxy)
Emeric Brunfc0421f2012-09-07 17:30:07 +02001467{
1468 int cfgerr = 0;
Emeric Brun850efd52014-01-29 12:24:34 +01001469 int verify = SSL_VERIFY_NONE;
Remi Gacogneaf5c3da2014-05-19 10:29:58 +02001470 long ssloptions =
Emeric Brunfc0421f2012-09-07 17:30:07 +02001471 SSL_OP_ALL | /* all known workarounds for bugs */
1472 SSL_OP_NO_SSLv2 |
1473 SSL_OP_NO_COMPRESSION |
Emeric Bruna4bcd9a2012-09-20 16:19:02 +02001474 SSL_OP_SINGLE_DH_USE |
Emeric Brun2b58d042012-09-20 17:10:03 +02001475 SSL_OP_SINGLE_ECDH_USE |
Emeric Brun3c4bc6e2012-10-04 18:44:19 +02001476 SSL_OP_NO_SESSION_RESUMPTION_ON_RENEGOTIATION |
1477 SSL_OP_CIPHER_SERVER_PREFERENCE;
Remi Gacogneaf5c3da2014-05-19 10:29:58 +02001478 long sslmode =
Emeric Brunfc0421f2012-09-07 17:30:07 +02001479 SSL_MODE_ENABLE_PARTIAL_WRITE |
1480 SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER |
1481 SSL_MODE_RELEASE_BUFFERS;
Remi Gacognef46cd6e2014-06-12 14:58:40 +02001482 STACK_OF(SSL_CIPHER) * ciphers = NULL;
Willy Tarreaua616ba62014-10-26 06:49:19 +01001483 SSL_CIPHER * cipher = NULL;
Remi Gacognec1eab8c2014-06-12 18:20:11 +02001484 char cipher_description[128];
1485 /* The description of ciphers using an Ephemeral Diffie Hellman key exchange
1486 contains " Kx=DH " or " Kx=DH(". Beware of " Kx=DH/",
1487 which is not ephemeral DH. */
1488 const char dhe_description[] = " Kx=DH ";
1489 const char dhe_export_description[] = " Kx=DH(";
Remi Gacognef46cd6e2014-06-12 14:58:40 +02001490 int idx = 0;
1491 int dhe_found = 0;
Remi Gacogne23d5d372014-10-10 17:04:26 +02001492 SSL *ssl = NULL;
Emeric Brunfc0421f2012-09-07 17:30:07 +02001493
Thierry Fournier383085f2013-01-24 14:15:43 +01001494 /* Make sure openssl opens /dev/urandom before the chroot */
1495 if (!ssl_initialize_random()) {
1496 Alert("OpenSSL random data generator initialization failed.\n");
1497 cfgerr++;
1498 }
1499
Emeric Brun89675492012-10-05 13:48:26 +02001500 if (bind_conf->ssl_options & BC_SSL_O_NO_SSLV3)
Emeric Brunfc0421f2012-09-07 17:30:07 +02001501 ssloptions |= SSL_OP_NO_SSLv3;
Emeric Brun89675492012-10-05 13:48:26 +02001502 if (bind_conf->ssl_options & BC_SSL_O_NO_TLSV10)
Emeric Brunfc0421f2012-09-07 17:30:07 +02001503 ssloptions |= SSL_OP_NO_TLSv1;
Emeric Brun89675492012-10-05 13:48:26 +02001504 if (bind_conf->ssl_options & BC_SSL_O_NO_TLSV11)
Emeric Brunc0ff4922012-09-28 19:37:02 +02001505 ssloptions |= SSL_OP_NO_TLSv1_1;
Emeric Brun89675492012-10-05 13:48:26 +02001506 if (bind_conf->ssl_options & BC_SSL_O_NO_TLSV12)
Emeric Brunc0ff4922012-09-28 19:37:02 +02001507 ssloptions |= SSL_OP_NO_TLSv1_2;
Emeric Brun89675492012-10-05 13:48:26 +02001508 if (bind_conf->ssl_options & BC_SSL_O_NO_TLS_TICKETS)
Emeric Brun2d0c4822012-10-02 13:45:20 +02001509 ssloptions |= SSL_OP_NO_TICKET;
Emeric Brun2cb7ae52012-10-05 14:14:21 +02001510 if (bind_conf->ssl_options & BC_SSL_O_USE_SSLV3)
1511 SSL_CTX_set_ssl_version(ctx, SSLv3_server_method());
1512 if (bind_conf->ssl_options & BC_SSL_O_USE_TLSV10)
1513 SSL_CTX_set_ssl_version(ctx, TLSv1_server_method());
1514#if SSL_OP_NO_TLSv1_1
1515 if (bind_conf->ssl_options & BC_SSL_O_USE_TLSV11)
1516 SSL_CTX_set_ssl_version(ctx, TLSv1_1_server_method());
1517#endif
1518#if SSL_OP_NO_TLSv1_2
1519 if (bind_conf->ssl_options & BC_SSL_O_USE_TLSV12)
1520 SSL_CTX_set_ssl_version(ctx, TLSv1_2_server_method());
1521#endif
Emeric Brunfc0421f2012-09-07 17:30:07 +02001522
1523 SSL_CTX_set_options(ctx, ssloptions);
1524 SSL_CTX_set_mode(ctx, sslmode);
Emeric Brun850efd52014-01-29 12:24:34 +01001525 switch (bind_conf->verify) {
1526 case SSL_SOCK_VERIFY_NONE:
1527 verify = SSL_VERIFY_NONE;
1528 break;
1529 case SSL_SOCK_VERIFY_OPTIONAL:
1530 verify = SSL_VERIFY_PEER;
1531 break;
1532 case SSL_SOCK_VERIFY_REQUIRED:
1533 verify = SSL_VERIFY_PEER|SSL_VERIFY_FAIL_IF_NO_PEER_CERT;
1534 break;
1535 }
1536 SSL_CTX_set_verify(ctx, verify, ssl_sock_bind_verifycbk);
1537 if (verify & SSL_VERIFY_PEER) {
Emeric Brunfb510ea2012-10-05 12:00:26 +02001538 if (bind_conf->ca_file) {
Emeric Brund94b3fe2012-09-20 18:23:56 +02001539 /* load CAfile to verify */
Emeric Brunfb510ea2012-10-05 12:00:26 +02001540 if (!SSL_CTX_load_verify_locations(ctx, bind_conf->ca_file, NULL)) {
Emeric Brund94b3fe2012-09-20 18:23:56 +02001541 Alert("Proxy '%s': unable to load CA file '%s' for bind '%s' at [%s:%d].\n",
Emeric Brunfb510ea2012-10-05 12:00:26 +02001542 curproxy->id, bind_conf->ca_file, bind_conf->arg, bind_conf->file, bind_conf->line);
Emeric Brund94b3fe2012-09-20 18:23:56 +02001543 cfgerr++;
1544 }
1545 /* set CA names fo client cert request, function returns void */
Emeric Brunfb510ea2012-10-05 12:00:26 +02001546 SSL_CTX_set_client_CA_list(ctx, SSL_load_client_CA_file(bind_conf->ca_file));
Emeric Brund94b3fe2012-09-20 18:23:56 +02001547 }
Emeric Brun850efd52014-01-29 12:24:34 +01001548 else {
1549 Alert("Proxy '%s': verify is enabled but no CA file specified for bind '%s' at [%s:%d].\n",
1550 curproxy->id, bind_conf->arg, bind_conf->file, bind_conf->line);
1551 cfgerr++;
1552 }
Emeric Brun051cdab2012-10-02 19:25:50 +02001553#ifdef X509_V_FLAG_CRL_CHECK
Emeric Brunfb510ea2012-10-05 12:00:26 +02001554 if (bind_conf->crl_file) {
Emeric Brund94b3fe2012-09-20 18:23:56 +02001555 X509_STORE *store = SSL_CTX_get_cert_store(ctx);
1556
Emeric Brunfb510ea2012-10-05 12:00:26 +02001557 if (!store || !X509_STORE_load_locations(store, bind_conf->crl_file, NULL)) {
Emeric Brund94b3fe2012-09-20 18:23:56 +02001558 Alert("Proxy '%s': unable to configure CRL file '%s' for bind '%s' at [%s:%d].\n",
Emeric Brunfb510ea2012-10-05 12:00:26 +02001559 curproxy->id, bind_conf->ca_file, bind_conf->arg, bind_conf->file, bind_conf->line);
Emeric Brund94b3fe2012-09-20 18:23:56 +02001560 cfgerr++;
1561 }
Emeric Brun561e5742012-10-02 15:20:55 +02001562 else {
1563 X509_STORE_set_flags(store, X509_V_FLAG_CRL_CHECK|X509_V_FLAG_CRL_CHECK_ALL);
1564 }
Emeric Brund94b3fe2012-09-20 18:23:56 +02001565 }
Emeric Brun051cdab2012-10-02 19:25:50 +02001566#endif
Emeric Brun644cde02012-12-14 11:21:13 +01001567 ERR_clear_error();
Emeric Brund94b3fe2012-09-20 18:23:56 +02001568 }
Emeric Brunfc0421f2012-09-07 17:30:07 +02001569
Emeric Brun4f65bff2012-11-16 15:11:00 +01001570 if (global.tune.ssllifetime)
1571 SSL_CTX_set_timeout(ctx, global.tune.ssllifetime);
1572
Emeric Brunfc0421f2012-09-07 17:30:07 +02001573 shared_context_set_cache(ctx);
Willy Tarreau2a65ff02012-09-13 17:54:29 +02001574 if (bind_conf->ciphers &&
1575 !SSL_CTX_set_cipher_list(ctx, bind_conf->ciphers)) {
Emeric Brunfc0421f2012-09-07 17:30:07 +02001576 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 +02001577 curproxy->id, bind_conf->ciphers, bind_conf->arg, bind_conf->file, bind_conf->line);
Emeric Brunfc0421f2012-09-07 17:30:07 +02001578 cfgerr++;
1579 }
1580
Remi Gacognef46cd6e2014-06-12 14:58:40 +02001581 /* If tune.ssl.default-dh-param has not been set and
1582 no static DH params were in the certificate file. */
1583 if (global.tune.ssl_default_dh_param == 0) {
Lukas Tribus90132722014-08-18 00:56:33 +02001584
Remi Gacogne23d5d372014-10-10 17:04:26 +02001585 ssl = SSL_new(ctx);
Remi Gacognef46cd6e2014-06-12 14:58:40 +02001586
Remi Gacogne23d5d372014-10-10 17:04:26 +02001587 if (ssl) {
1588 ciphers = SSL_get_ciphers(ssl);
1589
1590 if (ciphers) {
1591 for (idx = 0; idx < sk_SSL_CIPHER_num(ciphers); idx++) {
1592 cipher = sk_SSL_CIPHER_value(ciphers, idx);
1593 if (SSL_CIPHER_description(cipher, cipher_description, sizeof (cipher_description)) == cipher_description) {
1594 if (strstr(cipher_description, dhe_description) != NULL ||
1595 strstr(cipher_description, dhe_export_description) != NULL) {
1596 dhe_found = 1;
1597 break;
1598 }
Remi Gacognec1eab8c2014-06-12 18:20:11 +02001599 }
Remi Gacognef46cd6e2014-06-12 14:58:40 +02001600 }
1601 }
Remi Gacogne23d5d372014-10-10 17:04:26 +02001602 SSL_free(ssl);
1603 ssl = NULL;
Lukas Tribus90132722014-08-18 00:56:33 +02001604 }
Remi Gacognef46cd6e2014-06-12 14:58:40 +02001605
Lukas Tribus90132722014-08-18 00:56:33 +02001606 if (dhe_found) {
1607 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 +02001608 }
1609
1610 global.tune.ssl_default_dh_param = 1024;
1611 }
Remi Gacogne8de54152014-07-15 11:36:40 +02001612
1613#ifndef OPENSSL_NO_DH
1614 if (global.tune.ssl_default_dh_param >= 1024) {
1615 if (local_dh_1024 == NULL) {
1616 local_dh_1024 = ssl_get_dh_1024();
1617 }
1618 if (global.tune.ssl_default_dh_param >= 2048) {
1619 if (local_dh_2048 == NULL) {
1620 local_dh_2048 = ssl_get_dh_2048();
1621 }
1622 if (global.tune.ssl_default_dh_param >= 4096) {
1623 if (local_dh_4096 == NULL) {
1624 local_dh_4096 = ssl_get_dh_4096();
1625 }
1626 if (global.tune.ssl_default_dh_param >= 8192 &&
1627 local_dh_8192 == NULL) {
1628 local_dh_8192 = ssl_get_dh_8192();
1629 }
1630 }
1631 }
1632 }
1633#endif /* OPENSSL_NO_DH */
Remi Gacognef46cd6e2014-06-12 14:58:40 +02001634
Emeric Brunfc0421f2012-09-07 17:30:07 +02001635 SSL_CTX_set_info_callback(ctx, ssl_sock_infocbk);
Willy Tarreau5cbe4ef2014-05-08 22:45:11 +02001636#if OPENSSL_VERSION_NUMBER >= 0x00907000L
Emeric Brun29f037d2014-04-25 19:05:36 +02001637 SSL_CTX_set_msg_callback(ctx, ssl_sock_msgcbk);
Willy Tarreau5cbe4ef2014-05-08 22:45:11 +02001638#endif
Emeric Brun29f037d2014-04-25 19:05:36 +02001639
Willy Tarreau6c9a3d52012-10-18 18:57:14 +02001640#ifdef OPENSSL_NPN_NEGOTIATED
1641 if (bind_conf->npn_str)
1642 SSL_CTX_set_next_protos_advertised_cb(ctx, ssl_sock_advertise_npn_protos, bind_conf);
1643#endif
Dirkjan Bussink48f1c4e2014-02-13 12:29:42 +01001644#ifdef TLSEXT_TYPE_application_layer_protocol_negotiation
Willy Tarreauab861d32013-04-02 02:30:41 +02001645 if (bind_conf->alpn_str)
Dirkjan Bussink48f1c4e2014-02-13 12:29:42 +01001646 SSL_CTX_set_alpn_select_cb(ctx, ssl_sock_advertise_alpn_protos, bind_conf);
Willy Tarreauab861d32013-04-02 02:30:41 +02001647#endif
Willy Tarreau6c9a3d52012-10-18 18:57:14 +02001648
Emeric Brunfc0421f2012-09-07 17:30:07 +02001649#ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME
1650 SSL_CTX_set_tlsext_servername_callback(ctx, ssl_sock_switchctx_cbk);
Willy Tarreau2a65ff02012-09-13 17:54:29 +02001651 SSL_CTX_set_tlsext_servername_arg(ctx, bind_conf);
Emeric Brunfc0421f2012-09-07 17:30:07 +02001652#endif
Emeric Brun2b58d042012-09-20 17:10:03 +02001653#if defined(SSL_CTX_set_tmp_ecdh) && !defined(OPENSSL_NO_ECDH)
Emeric Brun6924ef82013-03-06 14:08:53 +01001654 {
Emeric Brun2b58d042012-09-20 17:10:03 +02001655 int i;
1656 EC_KEY *ecdh;
1657
Emeric Brun6924ef82013-03-06 14:08:53 +01001658 i = OBJ_sn2nid(bind_conf->ecdhe ? bind_conf->ecdhe : ECDHE_DEFAULT_CURVE);
Emeric Brun2b58d042012-09-20 17:10:03 +02001659 if (!i || ((ecdh = EC_KEY_new_by_curve_name(i)) == NULL)) {
1660 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 +01001661 curproxy->id, bind_conf->ecdhe ? bind_conf->ecdhe : ECDHE_DEFAULT_CURVE,
1662 bind_conf->arg, bind_conf->file, bind_conf->line);
Emeric Brun2b58d042012-09-20 17:10:03 +02001663 cfgerr++;
1664 }
1665 else {
1666 SSL_CTX_set_tmp_ecdh(ctx, ecdh);
1667 EC_KEY_free(ecdh);
1668 }
1669 }
1670#endif
1671
Emeric Brunfc0421f2012-09-07 17:30:07 +02001672 return cfgerr;
1673}
1674
Evan Broderbe554312013-06-27 00:05:25 -07001675static int ssl_sock_srv_hostcheck(const char *pattern, const char *hostname)
1676{
1677 const char *pattern_wildcard, *pattern_left_label_end, *hostname_left_label_end;
1678 size_t prefixlen, suffixlen;
1679
1680 /* Trivial case */
1681 if (strcmp(pattern, hostname) == 0)
1682 return 1;
1683
Evan Broderbe554312013-06-27 00:05:25 -07001684 /* The rest of this logic is based on RFC 6125, section 6.4.3
1685 * (http://tools.ietf.org/html/rfc6125#section-6.4.3) */
1686
Emeric Bruna848dae2013-10-08 11:27:28 +02001687 pattern_wildcard = NULL;
1688 pattern_left_label_end = pattern;
1689 while (*pattern_left_label_end != '.') {
1690 switch (*pattern_left_label_end) {
1691 case 0:
1692 /* End of label not found */
1693 return 0;
1694 case '*':
1695 /* If there is more than one wildcards */
1696 if (pattern_wildcard)
1697 return 0;
1698 pattern_wildcard = pattern_left_label_end;
1699 break;
1700 }
1701 pattern_left_label_end++;
1702 }
1703
1704 /* If it's not trivial and there is no wildcard, it can't
1705 * match */
1706 if (!pattern_wildcard)
Evan Broderbe554312013-06-27 00:05:25 -07001707 return 0;
1708
1709 /* Make sure all labels match except the leftmost */
1710 hostname_left_label_end = strchr(hostname, '.');
1711 if (!hostname_left_label_end
1712 || strcmp(pattern_left_label_end, hostname_left_label_end) != 0)
1713 return 0;
1714
1715 /* Make sure the leftmost label of the hostname is long enough
1716 * that the wildcard can match */
Emeric Brun369da852013-10-08 11:39:35 +02001717 if (hostname_left_label_end - hostname < (pattern_left_label_end - pattern) - 1)
Evan Broderbe554312013-06-27 00:05:25 -07001718 return 0;
1719
1720 /* Finally compare the string on either side of the
1721 * wildcard */
1722 prefixlen = pattern_wildcard - pattern;
1723 suffixlen = pattern_left_label_end - (pattern_wildcard + 1);
Emeric Bruna848dae2013-10-08 11:27:28 +02001724 if ((prefixlen && (memcmp(pattern, hostname, prefixlen) != 0))
1725 || (suffixlen && (memcmp(pattern_wildcard + 1, hostname_left_label_end - suffixlen, suffixlen) != 0)))
Evan Broderbe554312013-06-27 00:05:25 -07001726 return 0;
1727
1728 return 1;
1729}
1730
1731static int ssl_sock_srv_verifycbk(int ok, X509_STORE_CTX *ctx)
1732{
1733 SSL *ssl;
1734 struct connection *conn;
1735 char *servername;
1736
1737 int depth;
1738 X509 *cert;
1739 STACK_OF(GENERAL_NAME) *alt_names;
1740 int i;
1741 X509_NAME *cert_subject;
1742 char *str;
1743
1744 if (ok == 0)
1745 return ok;
1746
1747 ssl = X509_STORE_CTX_get_ex_data(ctx, SSL_get_ex_data_X509_STORE_CTX_idx());
1748 conn = (struct connection *)SSL_get_app_data(ssl);
1749
1750 servername = objt_server(conn->target)->ssl_ctx.verify_host;
1751
1752 /* We only need to verify the CN on the actual server cert,
1753 * not the indirect CAs */
1754 depth = X509_STORE_CTX_get_error_depth(ctx);
1755 if (depth != 0)
1756 return ok;
1757
1758 /* At this point, the cert is *not* OK unless we can find a
1759 * hostname match */
1760 ok = 0;
1761
1762 cert = X509_STORE_CTX_get_current_cert(ctx);
1763 /* It seems like this might happen if verify peer isn't set */
1764 if (!cert)
1765 return ok;
1766
1767 alt_names = X509_get_ext_d2i(cert, NID_subject_alt_name, NULL, NULL);
1768 if (alt_names) {
1769 for (i = 0; !ok && i < sk_GENERAL_NAME_num(alt_names); i++) {
1770 GENERAL_NAME *name = sk_GENERAL_NAME_value(alt_names, i);
1771 if (name->type == GEN_DNS) {
Emeric Bruna33410c2013-09-17 15:47:48 +02001772#if OPENSSL_VERSION_NUMBER < 0x00907000L
1773 if (ASN1_STRING_to_UTF8((unsigned char **)&str, name->d.ia5) >= 0) {
1774#else
Evan Broderbe554312013-06-27 00:05:25 -07001775 if (ASN1_STRING_to_UTF8((unsigned char **)&str, name->d.dNSName) >= 0) {
Emeric Bruna33410c2013-09-17 15:47:48 +02001776#endif
Evan Broderbe554312013-06-27 00:05:25 -07001777 ok = ssl_sock_srv_hostcheck(str, servername);
1778 OPENSSL_free(str);
1779 }
1780 }
1781 }
Emeric Brun4ad50a42013-09-17 15:19:54 +02001782 sk_GENERAL_NAME_pop_free(alt_names, GENERAL_NAME_free);
Evan Broderbe554312013-06-27 00:05:25 -07001783 }
1784
1785 cert_subject = X509_get_subject_name(cert);
1786 i = -1;
1787 while (!ok && (i = X509_NAME_get_index_by_NID(cert_subject, NID_commonName, i)) != -1) {
1788 X509_NAME_ENTRY *entry = X509_NAME_get_entry(cert_subject, i);
1789 if (ASN1_STRING_to_UTF8((unsigned char **)&str, entry->value) >= 0) {
1790 ok = ssl_sock_srv_hostcheck(str, servername);
1791 OPENSSL_free(str);
1792 }
1793 }
1794
1795 return ok;
1796}
1797
Emeric Brun94324a42012-10-11 14:00:19 +02001798/* prepare ssl context from servers options. Returns an error count */
1799int ssl_sock_prepare_srv_ctx(struct server *srv, struct proxy *curproxy)
1800{
1801 int cfgerr = 0;
Remi Gacogneaf5c3da2014-05-19 10:29:58 +02001802 long options =
Emeric Brun94324a42012-10-11 14:00:19 +02001803 SSL_OP_ALL | /* all known workarounds for bugs */
1804 SSL_OP_NO_SSLv2 |
1805 SSL_OP_NO_COMPRESSION;
Remi Gacogneaf5c3da2014-05-19 10:29:58 +02001806 long mode =
Emeric Brun94324a42012-10-11 14:00:19 +02001807 SSL_MODE_ENABLE_PARTIAL_WRITE |
1808 SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER |
1809 SSL_MODE_RELEASE_BUFFERS;
Emeric Brun850efd52014-01-29 12:24:34 +01001810 int verify = SSL_VERIFY_NONE;
Emeric Brun94324a42012-10-11 14:00:19 +02001811
Thierry Fournier383085f2013-01-24 14:15:43 +01001812 /* Make sure openssl opens /dev/urandom before the chroot */
1813 if (!ssl_initialize_random()) {
1814 Alert("OpenSSL random data generator initialization failed.\n");
1815 cfgerr++;
1816 }
1817
Emeric Brun94324a42012-10-11 14:00:19 +02001818 /* Initiate SSL context for current server */
1819 srv->ssl_ctx.reused_sess = NULL;
1820 if (srv->use_ssl)
1821 srv->xprt = &ssl_sock;
1822 if (srv->check.use_ssl)
Simon Horman66183002013-02-23 10:16:43 +09001823 srv->check_common.xprt = &ssl_sock;
Emeric Brun94324a42012-10-11 14:00:19 +02001824
1825 srv->ssl_ctx.ctx = SSL_CTX_new(SSLv23_client_method());
1826 if (!srv->ssl_ctx.ctx) {
1827 Alert("config : %s '%s', server '%s': unable to allocate ssl context.\n",
1828 proxy_type_str(curproxy), curproxy->id,
1829 srv->id);
1830 cfgerr++;
1831 return cfgerr;
1832 }
Emeric Bruna7aa3092012-10-26 12:58:00 +02001833 if (srv->ssl_ctx.client_crt) {
1834 if (SSL_CTX_use_PrivateKey_file(srv->ssl_ctx.ctx, srv->ssl_ctx.client_crt, SSL_FILETYPE_PEM) <= 0) {
1835 Alert("config : %s '%s', server '%s': unable to load SSL private key from PEM file '%s'.\n",
1836 proxy_type_str(curproxy), curproxy->id,
1837 srv->id, srv->ssl_ctx.client_crt);
1838 cfgerr++;
1839 }
1840 else if (SSL_CTX_use_certificate_chain_file(srv->ssl_ctx.ctx, srv->ssl_ctx.client_crt) <= 0) {
1841 Alert("config : %s '%s', server '%s': unable to load ssl certificate from PEM file '%s'.\n",
1842 proxy_type_str(curproxy), curproxy->id,
1843 srv->id, srv->ssl_ctx.client_crt);
1844 cfgerr++;
1845 }
1846 else if (SSL_CTX_check_private_key(srv->ssl_ctx.ctx) <= 0) {
1847 Alert("config : %s '%s', server '%s': inconsistencies between private key and certificate loaded from PEM file '%s'.\n",
1848 proxy_type_str(curproxy), curproxy->id,
1849 srv->id, srv->ssl_ctx.client_crt);
1850 cfgerr++;
1851 }
1852 }
Emeric Brun94324a42012-10-11 14:00:19 +02001853
1854 if (srv->ssl_ctx.options & SRV_SSL_O_NO_SSLV3)
1855 options |= SSL_OP_NO_SSLv3;
1856 if (srv->ssl_ctx.options & SRV_SSL_O_NO_TLSV10)
1857 options |= SSL_OP_NO_TLSv1;
1858 if (srv->ssl_ctx.options & SRV_SSL_O_NO_TLSV11)
1859 options |= SSL_OP_NO_TLSv1_1;
1860 if (srv->ssl_ctx.options & SRV_SSL_O_NO_TLSV12)
1861 options |= SSL_OP_NO_TLSv1_2;
Emeric Brunf9c5c472012-10-11 15:28:34 +02001862 if (srv->ssl_ctx.options & SRV_SSL_O_NO_TLS_TICKETS)
1863 options |= SSL_OP_NO_TICKET;
Emeric Brun94324a42012-10-11 14:00:19 +02001864 if (srv->ssl_ctx.options & SRV_SSL_O_USE_SSLV3)
1865 SSL_CTX_set_ssl_version(srv->ssl_ctx.ctx, SSLv3_client_method());
1866 if (srv->ssl_ctx.options & SRV_SSL_O_USE_TLSV10)
1867 SSL_CTX_set_ssl_version(srv->ssl_ctx.ctx, TLSv1_client_method());
1868#if SSL_OP_NO_TLSv1_1
1869 if (srv->ssl_ctx.options & SRV_SSL_O_USE_TLSV11)
1870 SSL_CTX_set_ssl_version(srv->ssl_ctx.ctx, TLSv1_1_client_method());
1871#endif
1872#if SSL_OP_NO_TLSv1_2
1873 if (srv->ssl_ctx.options & SRV_SSL_O_USE_TLSV12)
1874 SSL_CTX_set_ssl_version(srv->ssl_ctx.ctx, TLSv1_2_client_method());
1875#endif
1876
1877 SSL_CTX_set_options(srv->ssl_ctx.ctx, options);
1878 SSL_CTX_set_mode(srv->ssl_ctx.ctx, mode);
Emeric Brun850efd52014-01-29 12:24:34 +01001879
1880 if (global.ssl_server_verify == SSL_SERVER_VERIFY_REQUIRED)
1881 verify = SSL_VERIFY_PEER;
1882
1883 switch (srv->ssl_ctx.verify) {
1884 case SSL_SOCK_VERIFY_NONE:
1885 verify = SSL_VERIFY_NONE;
1886 break;
1887 case SSL_SOCK_VERIFY_REQUIRED:
1888 verify = SSL_VERIFY_PEER;
1889 break;
1890 }
Evan Broderbe554312013-06-27 00:05:25 -07001891 SSL_CTX_set_verify(srv->ssl_ctx.ctx,
Emeric Brun850efd52014-01-29 12:24:34 +01001892 verify,
Evan Broderbe554312013-06-27 00:05:25 -07001893 srv->ssl_ctx.verify_host ? ssl_sock_srv_verifycbk : NULL);
Emeric Brun850efd52014-01-29 12:24:34 +01001894 if (verify & SSL_VERIFY_PEER) {
Emeric Brunef42d922012-10-11 16:11:36 +02001895 if (srv->ssl_ctx.ca_file) {
1896 /* load CAfile to verify */
1897 if (!SSL_CTX_load_verify_locations(srv->ssl_ctx.ctx, srv->ssl_ctx.ca_file, NULL)) {
Willy Tarreau07ba08b2014-02-16 19:22:08 +01001898 Alert("Proxy '%s', server '%s' [%s:%d] unable to load CA file '%s'.\n",
Emeric Brunef42d922012-10-11 16:11:36 +02001899 curproxy->id, srv->id,
1900 srv->conf.file, srv->conf.line, srv->ssl_ctx.ca_file);
1901 cfgerr++;
1902 }
1903 }
Emeric Brun850efd52014-01-29 12:24:34 +01001904 else {
1905 if (global.ssl_server_verify == SSL_SERVER_VERIFY_REQUIRED)
Willy Tarreau07ba08b2014-02-16 19:22:08 +01001906 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 +01001907 curproxy->id, srv->id,
1908 srv->conf.file, srv->conf.line);
1909 else
Willy Tarreau07ba08b2014-02-16 19:22:08 +01001910 Alert("Proxy '%s', server '%s' [%s:%d] verify is enabled but no CA file specified.\n",
Emeric Brun850efd52014-01-29 12:24:34 +01001911 curproxy->id, srv->id,
1912 srv->conf.file, srv->conf.line);
1913 cfgerr++;
1914 }
Emeric Brunef42d922012-10-11 16:11:36 +02001915#ifdef X509_V_FLAG_CRL_CHECK
1916 if (srv->ssl_ctx.crl_file) {
1917 X509_STORE *store = SSL_CTX_get_cert_store(srv->ssl_ctx.ctx);
1918
1919 if (!store || !X509_STORE_load_locations(store, srv->ssl_ctx.crl_file, NULL)) {
Willy Tarreau07ba08b2014-02-16 19:22:08 +01001920 Alert("Proxy '%s', server '%s' [%s:%d] unable to configure CRL file '%s'.\n",
Emeric Brunef42d922012-10-11 16:11:36 +02001921 curproxy->id, srv->id,
1922 srv->conf.file, srv->conf.line, srv->ssl_ctx.crl_file);
1923 cfgerr++;
1924 }
1925 else {
1926 X509_STORE_set_flags(store, X509_V_FLAG_CRL_CHECK|X509_V_FLAG_CRL_CHECK_ALL);
1927 }
1928 }
1929#endif
1930 }
1931
Emeric Brun4f65bff2012-11-16 15:11:00 +01001932 if (global.tune.ssllifetime)
1933 SSL_CTX_set_timeout(srv->ssl_ctx.ctx, global.tune.ssllifetime);
1934
Emeric Brun94324a42012-10-11 14:00:19 +02001935 SSL_CTX_set_session_cache_mode(srv->ssl_ctx.ctx, SSL_SESS_CACHE_OFF);
1936 if (srv->ssl_ctx.ciphers &&
1937 !SSL_CTX_set_cipher_list(srv->ssl_ctx.ctx, srv->ssl_ctx.ciphers)) {
1938 Alert("Proxy '%s', server '%s' [%s:%d] : unable to set SSL cipher list to '%s'.\n",
1939 curproxy->id, srv->id,
1940 srv->conf.file, srv->conf.line, srv->ssl_ctx.ciphers);
1941 cfgerr++;
1942 }
1943
1944 return cfgerr;
1945}
1946
Willy Tarreau2a65ff02012-09-13 17:54:29 +02001947/* Walks down the two trees in bind_conf and prepares all certs. The pointer may
Emeric Brunfc0421f2012-09-07 17:30:07 +02001948 * be NULL, in which case nothing is done. Returns the number of errors
1949 * encountered.
1950 */
Willy Tarreau2a65ff02012-09-13 17:54:29 +02001951int ssl_sock_prepare_all_ctx(struct bind_conf *bind_conf, struct proxy *px)
Emeric Brunfc0421f2012-09-07 17:30:07 +02001952{
1953 struct ebmb_node *node;
1954 struct sni_ctx *sni;
1955 int err = 0;
1956
Willy Tarreau2a65ff02012-09-13 17:54:29 +02001957 if (!bind_conf || !bind_conf->is_ssl)
Emeric Brunfc0421f2012-09-07 17:30:07 +02001958 return 0;
1959
Emeric Brun0bed9942014-10-30 19:25:24 +01001960 if (bind_conf->default_ctx)
1961 err += ssl_sock_prepare_ctx(bind_conf, bind_conf->default_ctx, px);
1962
Willy Tarreau2a65ff02012-09-13 17:54:29 +02001963 node = ebmb_first(&bind_conf->sni_ctx);
Emeric Brunfc0421f2012-09-07 17:30:07 +02001964 while (node) {
1965 sni = ebmb_entry(node, struct sni_ctx, name);
Emeric Brun0bed9942014-10-30 19:25:24 +01001966 if (!sni->order && sni->ctx != bind_conf->default_ctx)
1967 /* only initialize the CTX on its first occurrence and
1968 if it is not the default_ctx */
Willy Tarreau2a65ff02012-09-13 17:54:29 +02001969 err += ssl_sock_prepare_ctx(bind_conf, sni->ctx, px);
Emeric Brunfc0421f2012-09-07 17:30:07 +02001970 node = ebmb_next(node);
1971 }
1972
Willy Tarreau2a65ff02012-09-13 17:54:29 +02001973 node = ebmb_first(&bind_conf->sni_w_ctx);
Emeric Brunfc0421f2012-09-07 17:30:07 +02001974 while (node) {
1975 sni = ebmb_entry(node, struct sni_ctx, name);
Emeric Brun0bed9942014-10-30 19:25:24 +01001976 if (!sni->order && sni->ctx != bind_conf->default_ctx)
1977 /* only initialize the CTX on its first occurrence and
1978 if it is not the default_ctx */
Willy Tarreau2a65ff02012-09-13 17:54:29 +02001979 err += ssl_sock_prepare_ctx(bind_conf, sni->ctx, px);
Emeric Brunfc0421f2012-09-07 17:30:07 +02001980 node = ebmb_next(node);
1981 }
1982 return err;
1983}
1984
Willy Tarreau2a65ff02012-09-13 17:54:29 +02001985/* Walks down the two trees in bind_conf and frees all the certs. The pointer may
Emeric Brunfc0421f2012-09-07 17:30:07 +02001986 * be NULL, in which case nothing is done. The default_ctx is nullified too.
1987 */
Willy Tarreau2a65ff02012-09-13 17:54:29 +02001988void ssl_sock_free_all_ctx(struct bind_conf *bind_conf)
Emeric Brunfc0421f2012-09-07 17:30:07 +02001989{
1990 struct ebmb_node *node, *back;
1991 struct sni_ctx *sni;
1992
Willy Tarreau2a65ff02012-09-13 17:54:29 +02001993 if (!bind_conf || !bind_conf->is_ssl)
Emeric Brunfc0421f2012-09-07 17:30:07 +02001994 return;
1995
Willy Tarreau2a65ff02012-09-13 17:54:29 +02001996 node = ebmb_first(&bind_conf->sni_ctx);
Emeric Brunfc0421f2012-09-07 17:30:07 +02001997 while (node) {
1998 sni = ebmb_entry(node, struct sni_ctx, name);
1999 back = ebmb_next(node);
2000 ebmb_delete(node);
2001 if (!sni->order) /* only free the CTX on its first occurrence */
2002 SSL_CTX_free(sni->ctx);
2003 free(sni);
2004 node = back;
2005 }
2006
Willy Tarreau2a65ff02012-09-13 17:54:29 +02002007 node = ebmb_first(&bind_conf->sni_w_ctx);
Emeric Brunfc0421f2012-09-07 17:30:07 +02002008 while (node) {
2009 sni = ebmb_entry(node, struct sni_ctx, name);
2010 back = ebmb_next(node);
2011 ebmb_delete(node);
2012 if (!sni->order) /* only free the CTX on its first occurrence */
2013 SSL_CTX_free(sni->ctx);
2014 free(sni);
2015 node = back;
2016 }
2017
Willy Tarreau2a65ff02012-09-13 17:54:29 +02002018 bind_conf->default_ctx = NULL;
Emeric Brune1f38db2012-09-03 20:36:47 +02002019}
2020
Emeric Brun46591952012-05-18 15:47:34 +02002021/*
2022 * This function is called if SSL * context is not yet allocated. The function
2023 * is designed to be called before any other data-layer operation and sets the
2024 * handshake flag on the connection. It is safe to call it multiple times.
2025 * It returns 0 on success and -1 in error case.
2026 */
2027static int ssl_sock_init(struct connection *conn)
2028{
2029 /* already initialized */
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02002030 if (conn->xprt_ctx)
Emeric Brun46591952012-05-18 15:47:34 +02002031 return 0;
2032
Willy Tarreau3c728722014-01-23 13:50:42 +01002033 if (!conn_ctrl_ready(conn))
Willy Tarreauf79c8172013-10-21 16:30:56 +02002034 return 0;
2035
Willy Tarreau20879a02012-12-03 16:32:10 +01002036 if (global.maxsslconn && sslconns >= global.maxsslconn) {
2037 conn->err_code = CO_ER_SSL_TOO_MANY;
Willy Tarreau403edff2012-09-06 11:58:37 +02002038 return -1;
Willy Tarreau20879a02012-12-03 16:32:10 +01002039 }
Willy Tarreau403edff2012-09-06 11:58:37 +02002040
Emeric Brun46591952012-05-18 15:47:34 +02002041 /* If it is in client mode initiate SSL session
2042 in connect state otherwise accept state */
Willy Tarreau3fdb3662012-11-12 00:42:33 +01002043 if (objt_server(conn->target)) {
Emeric Brun46591952012-05-18 15:47:34 +02002044 /* Alloc a new SSL session ctx */
Willy Tarreau3fdb3662012-11-12 00:42:33 +01002045 conn->xprt_ctx = SSL_new(objt_server(conn->target)->ssl_ctx.ctx);
Willy Tarreau20879a02012-12-03 16:32:10 +01002046 if (!conn->xprt_ctx) {
2047 conn->err_code = CO_ER_SSL_NO_MEM;
Emeric Brun46591952012-05-18 15:47:34 +02002048 return -1;
Willy Tarreau20879a02012-12-03 16:32:10 +01002049 }
Emeric Brun46591952012-05-18 15:47:34 +02002050
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02002051 SSL_set_connect_state(conn->xprt_ctx);
Willy Tarreau3fdb3662012-11-12 00:42:33 +01002052 if (objt_server(conn->target)->ssl_ctx.reused_sess)
2053 SSL_set_session(conn->xprt_ctx, objt_server(conn->target)->ssl_ctx.reused_sess);
Emeric Brun46591952012-05-18 15:47:34 +02002054
2055 /* set fd on SSL session context */
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02002056 SSL_set_fd(conn->xprt_ctx, conn->t.sock.fd);
Emeric Brun46591952012-05-18 15:47:34 +02002057
Evan Broderbe554312013-06-27 00:05:25 -07002058 /* set connection pointer */
2059 SSL_set_app_data(conn->xprt_ctx, conn);
2060
Emeric Brun46591952012-05-18 15:47:34 +02002061 /* leave init state and start handshake */
Willy Tarreau05737472012-09-04 08:03:39 +02002062 conn->flags |= CO_FL_SSL_WAIT_HS | CO_FL_WAIT_L6_CONN;
Willy Tarreau403edff2012-09-06 11:58:37 +02002063
2064 sslconns++;
Willy Tarreau71b734c2014-01-28 15:19:44 +01002065 totalsslconns++;
Emeric Brun46591952012-05-18 15:47:34 +02002066 return 0;
2067 }
Willy Tarreau3fdb3662012-11-12 00:42:33 +01002068 else if (objt_listener(conn->target)) {
Emeric Brun46591952012-05-18 15:47:34 +02002069 /* Alloc a new SSL session ctx */
Willy Tarreau3fdb3662012-11-12 00:42:33 +01002070 conn->xprt_ctx = SSL_new(objt_listener(conn->target)->bind_conf->default_ctx);
Willy Tarreau20879a02012-12-03 16:32:10 +01002071 if (!conn->xprt_ctx) {
2072 conn->err_code = CO_ER_SSL_NO_MEM;
Emeric Brun46591952012-05-18 15:47:34 +02002073 return -1;
Willy Tarreau20879a02012-12-03 16:32:10 +01002074 }
Emeric Brun46591952012-05-18 15:47:34 +02002075
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02002076 SSL_set_accept_state(conn->xprt_ctx);
Emeric Brun46591952012-05-18 15:47:34 +02002077
2078 /* set fd on SSL session context */
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02002079 SSL_set_fd(conn->xprt_ctx, conn->t.sock.fd);
Emeric Brun46591952012-05-18 15:47:34 +02002080
Emeric Brune1f38db2012-09-03 20:36:47 +02002081 /* set connection pointer */
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02002082 SSL_set_app_data(conn->xprt_ctx, conn);
Emeric Brune1f38db2012-09-03 20:36:47 +02002083
Emeric Brun46591952012-05-18 15:47:34 +02002084 /* leave init state and start handshake */
Willy Tarreau05737472012-09-04 08:03:39 +02002085 conn->flags |= CO_FL_SSL_WAIT_HS | CO_FL_WAIT_L6_CONN;
Willy Tarreau403edff2012-09-06 11:58:37 +02002086
2087 sslconns++;
Willy Tarreau71b734c2014-01-28 15:19:44 +01002088 totalsslconns++;
Emeric Brun46591952012-05-18 15:47:34 +02002089 return 0;
2090 }
2091 /* don't know how to handle such a target */
Willy Tarreau20879a02012-12-03 16:32:10 +01002092 conn->err_code = CO_ER_SSL_NO_TARGET;
Emeric Brun46591952012-05-18 15:47:34 +02002093 return -1;
2094}
2095
2096
2097/* This is the callback which is used when an SSL handshake is pending. It
2098 * updates the FD status if it wants some polling before being called again.
2099 * It returns 0 if it fails in a fatal way or needs to poll to go further,
2100 * otherwise it returns non-zero and removes itself from the connection's
2101 * flags (the bit is provided in <flag> by the caller).
2102 */
2103int ssl_sock_handshake(struct connection *conn, unsigned int flag)
2104{
2105 int ret;
2106
Willy Tarreau3c728722014-01-23 13:50:42 +01002107 if (!conn_ctrl_ready(conn))
Willy Tarreauf79c8172013-10-21 16:30:56 +02002108 return 0;
2109
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02002110 if (!conn->xprt_ctx)
Emeric Brun46591952012-05-18 15:47:34 +02002111 goto out_error;
2112
Emeric Brun674b7432012-11-08 19:21:55 +01002113 /* If we use SSL_do_handshake to process a reneg initiated by
2114 * the remote peer, it sometimes returns SSL_ERROR_SSL.
2115 * Usually SSL_write and SSL_read are used and process implicitly
2116 * the reneg handshake.
2117 * Here we use SSL_peek as a workaround for reneg.
2118 */
2119 if ((conn->flags & CO_FL_CONNECTED) && SSL_renegotiate_pending(conn->xprt_ctx)) {
2120 char c;
2121
2122 ret = SSL_peek(conn->xprt_ctx, &c, 1);
2123 if (ret <= 0) {
2124 /* handshake may have not been completed, let's find why */
2125 ret = SSL_get_error(conn->xprt_ctx, ret);
2126 if (ret == SSL_ERROR_WANT_WRITE) {
2127 /* SSL handshake needs to write, L4 connection may not be ready */
2128 __conn_sock_stop_recv(conn);
Willy Tarreaue1f50c42014-01-22 20:02:06 +01002129 __conn_sock_want_send(conn);
2130 fd_cant_send(conn->t.sock.fd);
Emeric Brun674b7432012-11-08 19:21:55 +01002131 return 0;
2132 }
2133 else if (ret == SSL_ERROR_WANT_READ) {
2134 /* handshake may have been completed but we have
2135 * no more data to read.
2136 */
2137 if (!SSL_renegotiate_pending(conn->xprt_ctx)) {
2138 ret = 1;
2139 goto reneg_ok;
2140 }
2141 /* SSL handshake needs to read, L4 connection is ready */
2142 if (conn->flags & CO_FL_WAIT_L4_CONN)
2143 conn->flags &= ~CO_FL_WAIT_L4_CONN;
2144 __conn_sock_stop_send(conn);
Willy Tarreaue1f50c42014-01-22 20:02:06 +01002145 __conn_sock_want_recv(conn);
2146 fd_cant_recv(conn->t.sock.fd);
Emeric Brun674b7432012-11-08 19:21:55 +01002147 return 0;
2148 }
2149 else if (ret == SSL_ERROR_SYSCALL) {
2150 /* if errno is null, then connection was successfully established */
2151 if (!errno && conn->flags & CO_FL_WAIT_L4_CONN)
2152 conn->flags &= ~CO_FL_WAIT_L4_CONN;
Willy Tarreau20879a02012-12-03 16:32:10 +01002153 if (!conn->err_code) {
Emeric Brun29f037d2014-04-25 19:05:36 +02002154 if (!((SSL *)conn->xprt_ctx)->packet_length) {
2155 if (!errno) {
2156 if (conn->xprt_st & SSL_SOCK_RECV_HEARTBEAT)
2157 conn->err_code = CO_ER_SSL_HANDSHAKE_HB;
2158 else
2159 conn->err_code = CO_ER_SSL_EMPTY;
2160 }
2161 else {
2162 if (conn->xprt_st & SSL_SOCK_RECV_HEARTBEAT)
2163 conn->err_code = CO_ER_SSL_HANDSHAKE_HB;
2164 else
2165 conn->err_code = CO_ER_SSL_ABORT;
2166 }
2167 }
2168 else {
2169 if (conn->xprt_st & SSL_SOCK_RECV_HEARTBEAT)
2170 conn->err_code = CO_ER_SSL_HANDSHAKE_HB;
Willy Tarreau20879a02012-12-03 16:32:10 +01002171 else
Emeric Brun29f037d2014-04-25 19:05:36 +02002172 conn->err_code = CO_ER_SSL_HANDSHAKE;
2173 }
Willy Tarreau20879a02012-12-03 16:32:10 +01002174 }
Emeric Brun674b7432012-11-08 19:21:55 +01002175 goto out_error;
2176 }
2177 else {
2178 /* Fail on all other handshake errors */
2179 /* Note: OpenSSL may leave unread bytes in the socket's
2180 * buffer, causing an RST to be emitted upon close() on
2181 * TCP sockets. We first try to drain possibly pending
2182 * data to avoid this as much as possible.
2183 */
Willy Tarreau46be2e52014-01-20 12:10:52 +01002184 conn_drain(conn);
Willy Tarreau20879a02012-12-03 16:32:10 +01002185 if (!conn->err_code)
Willy Tarreauf51c6982014-04-25 20:02:39 +02002186 conn->err_code = (conn->xprt_st & SSL_SOCK_RECV_HEARTBEAT) ?
2187 CO_ER_SSL_KILLED_HB : CO_ER_SSL_HANDSHAKE;
Emeric Brun674b7432012-11-08 19:21:55 +01002188 goto out_error;
2189 }
2190 }
2191 /* read some data: consider handshake completed */
2192 goto reneg_ok;
2193 }
2194
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02002195 ret = SSL_do_handshake(conn->xprt_ctx);
Emeric Brun46591952012-05-18 15:47:34 +02002196 if (ret != 1) {
2197 /* handshake did not complete, let's find why */
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02002198 ret = SSL_get_error(conn->xprt_ctx, ret);
Emeric Brun46591952012-05-18 15:47:34 +02002199
2200 if (ret == SSL_ERROR_WANT_WRITE) {
2201 /* SSL handshake needs to write, L4 connection may not be ready */
2202 __conn_sock_stop_recv(conn);
Willy Tarreaue1f50c42014-01-22 20:02:06 +01002203 __conn_sock_want_send(conn);
2204 fd_cant_send(conn->t.sock.fd);
Emeric Brun46591952012-05-18 15:47:34 +02002205 return 0;
2206 }
2207 else if (ret == SSL_ERROR_WANT_READ) {
2208 /* SSL handshake needs to read, L4 connection is ready */
2209 if (conn->flags & CO_FL_WAIT_L4_CONN)
2210 conn->flags &= ~CO_FL_WAIT_L4_CONN;
2211 __conn_sock_stop_send(conn);
Willy Tarreaue1f50c42014-01-22 20:02:06 +01002212 __conn_sock_want_recv(conn);
2213 fd_cant_recv(conn->t.sock.fd);
Emeric Brun46591952012-05-18 15:47:34 +02002214 return 0;
2215 }
Willy Tarreau89230192012-09-28 20:22:13 +02002216 else if (ret == SSL_ERROR_SYSCALL) {
2217 /* if errno is null, then connection was successfully established */
2218 if (!errno && conn->flags & CO_FL_WAIT_L4_CONN)
2219 conn->flags &= ~CO_FL_WAIT_L4_CONN;
Willy Tarreau20879a02012-12-03 16:32:10 +01002220
Emeric Brun29f037d2014-04-25 19:05:36 +02002221 if (!((SSL *)conn->xprt_ctx)->packet_length) {
2222 if (!errno) {
2223 if (conn->xprt_st & SSL_SOCK_RECV_HEARTBEAT)
2224 conn->err_code = CO_ER_SSL_HANDSHAKE_HB;
2225 else
2226 conn->err_code = CO_ER_SSL_EMPTY;
2227 }
2228 else {
2229 if (conn->xprt_st & SSL_SOCK_RECV_HEARTBEAT)
2230 conn->err_code = CO_ER_SSL_HANDSHAKE_HB;
2231 else
2232 conn->err_code = CO_ER_SSL_ABORT;
2233 }
2234 }
2235 else {
2236 if (conn->xprt_st & SSL_SOCK_RECV_HEARTBEAT)
2237 conn->err_code = CO_ER_SSL_HANDSHAKE_HB;
Willy Tarreau20879a02012-12-03 16:32:10 +01002238 else
Emeric Brun29f037d2014-04-25 19:05:36 +02002239 conn->err_code = CO_ER_SSL_HANDSHAKE;
2240 }
Willy Tarreau89230192012-09-28 20:22:13 +02002241 goto out_error;
2242 }
Emeric Brun46591952012-05-18 15:47:34 +02002243 else {
2244 /* Fail on all other handshake errors */
Willy Tarreau566dc552012-10-19 20:52:18 +02002245 /* Note: OpenSSL may leave unread bytes in the socket's
2246 * buffer, causing an RST to be emitted upon close() on
2247 * TCP sockets. We first try to drain possibly pending
2248 * data to avoid this as much as possible.
2249 */
Willy Tarreau46be2e52014-01-20 12:10:52 +01002250 conn_drain(conn);
Willy Tarreau20879a02012-12-03 16:32:10 +01002251 if (!conn->err_code)
Willy Tarreauf51c6982014-04-25 20:02:39 +02002252 conn->err_code = (conn->xprt_st & SSL_SOCK_RECV_HEARTBEAT) ?
2253 CO_ER_SSL_KILLED_HB : CO_ER_SSL_HANDSHAKE;
Emeric Brun46591952012-05-18 15:47:34 +02002254 goto out_error;
2255 }
2256 }
2257
Emeric Brun674b7432012-11-08 19:21:55 +01002258reneg_ok:
2259
Emeric Brun46591952012-05-18 15:47:34 +02002260 /* Handshake succeeded */
Willy Tarreau0c9c2722014-05-28 12:28:58 +02002261 if (!SSL_session_reused(conn->xprt_ctx)) {
2262 if (objt_server(conn->target)) {
2263 update_freq_ctr(&global.ssl_be_keys_per_sec, 1);
2264 if (global.ssl_be_keys_per_sec.curr_ctr > global.ssl_be_keys_max)
2265 global.ssl_be_keys_max = global.ssl_be_keys_per_sec.curr_ctr;
2266
Emeric Brun46591952012-05-18 15:47:34 +02002267 /* check if session was reused, if not store current session on server for reuse */
Willy Tarreau3fdb3662012-11-12 00:42:33 +01002268 if (objt_server(conn->target)->ssl_ctx.reused_sess)
2269 SSL_SESSION_free(objt_server(conn->target)->ssl_ctx.reused_sess);
Emeric Brun46591952012-05-18 15:47:34 +02002270
Willy Tarreau3fdb3662012-11-12 00:42:33 +01002271 objt_server(conn->target)->ssl_ctx.reused_sess = SSL_get1_session(conn->xprt_ctx);
Emeric Brun46591952012-05-18 15:47:34 +02002272 }
Willy Tarreau0c9c2722014-05-28 12:28:58 +02002273 else {
2274 update_freq_ctr(&global.ssl_fe_keys_per_sec, 1);
2275 if (global.ssl_fe_keys_per_sec.curr_ctr > global.ssl_fe_keys_max)
2276 global.ssl_fe_keys_max = global.ssl_fe_keys_per_sec.curr_ctr;
2277 }
Emeric Brun46591952012-05-18 15:47:34 +02002278 }
2279
2280 /* The connection is now established at both layers, it's time to leave */
2281 conn->flags &= ~(flag | CO_FL_WAIT_L4_CONN | CO_FL_WAIT_L6_CONN);
2282 return 1;
2283
2284 out_error:
Emeric Brun644cde02012-12-14 11:21:13 +01002285 /* Clear openssl global errors stack */
2286 ERR_clear_error();
2287
Emeric Brun9fa89732012-10-04 17:09:56 +02002288 /* free resumed session if exists */
Willy Tarreau3fdb3662012-11-12 00:42:33 +01002289 if (objt_server(conn->target) && objt_server(conn->target)->ssl_ctx.reused_sess) {
2290 SSL_SESSION_free(objt_server(conn->target)->ssl_ctx.reused_sess);
2291 objt_server(conn->target)->ssl_ctx.reused_sess = NULL;
Emeric Brun9fa89732012-10-04 17:09:56 +02002292 }
2293
Emeric Brun46591952012-05-18 15:47:34 +02002294 /* Fail on all other handshake errors */
2295 conn->flags |= CO_FL_ERROR;
Willy Tarreau20879a02012-12-03 16:32:10 +01002296 if (!conn->err_code)
2297 conn->err_code = CO_ER_SSL_HANDSHAKE;
Emeric Brun46591952012-05-18 15:47:34 +02002298 return 0;
2299}
2300
2301/* Receive up to <count> bytes from connection <conn>'s socket and store them
Willy Tarreauabf08d92014-01-14 11:31:27 +01002302 * into buffer <buf>. Only one call to recv() is performed, unless the
Emeric Brun46591952012-05-18 15:47:34 +02002303 * buffer wraps, in which case a second call may be performed. The connection's
2304 * flags are updated with whatever special event is detected (error, read0,
2305 * empty). The caller is responsible for taking care of those events and
2306 * avoiding the call if inappropriate. The function does not call the
2307 * connection's polling update function, so the caller is responsible for this.
2308 */
2309static int ssl_sock_to_buf(struct connection *conn, struct buffer *buf, int count)
2310{
2311 int ret, done = 0;
Willy Tarreauabf08d92014-01-14 11:31:27 +01002312 int try;
Emeric Brun46591952012-05-18 15:47:34 +02002313
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02002314 if (!conn->xprt_ctx)
Emeric Brun46591952012-05-18 15:47:34 +02002315 goto out_error;
2316
2317 if (conn->flags & CO_FL_HANDSHAKE)
2318 /* a handshake was requested */
2319 return 0;
2320
Willy Tarreauabf08d92014-01-14 11:31:27 +01002321 /* let's realign the buffer to optimize I/O */
2322 if (buffer_empty(buf))
Emeric Brun46591952012-05-18 15:47:34 +02002323 buf->p = buf->data;
Emeric Brun46591952012-05-18 15:47:34 +02002324
2325 /* read the largest possible block. For this, we perform only one call
2326 * to recv() unless the buffer wraps and we exactly fill the first hunk,
2327 * in which case we accept to do it once again. A new attempt is made on
2328 * EINTR too.
2329 */
Willy Tarreau00b0fb92014-01-17 11:09:40 +01002330 while (count > 0) {
Willy Tarreauabf08d92014-01-14 11:31:27 +01002331 /* first check if we have some room after p+i */
2332 try = buf->data + buf->size - (buf->p + buf->i);
2333 /* otherwise continue between data and p-o */
2334 if (try <= 0) {
2335 try = buf->p - (buf->data + buf->o);
2336 if (try <= 0)
2337 break;
2338 }
2339 if (try > count)
2340 try = count;
2341
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02002342 ret = SSL_read(conn->xprt_ctx, bi_end(buf), try);
Emeric Brune1f38db2012-09-03 20:36:47 +02002343 if (conn->flags & CO_FL_ERROR) {
2344 /* CO_FL_ERROR may be set by ssl_sock_infocbk */
Emeric Brun644cde02012-12-14 11:21:13 +01002345 goto out_error;
Emeric Brune1f38db2012-09-03 20:36:47 +02002346 }
Emeric Brun46591952012-05-18 15:47:34 +02002347 if (ret > 0) {
2348 buf->i += ret;
2349 done += ret;
2350 if (ret < try)
2351 break;
2352 count -= ret;
Emeric Brun46591952012-05-18 15:47:34 +02002353 }
2354 else if (ret == 0) {
Emeric Brun644cde02012-12-14 11:21:13 +01002355 ret = SSL_get_error(conn->xprt_ctx, ret);
2356 if (ret != SSL_ERROR_ZERO_RETURN) {
Emeric Brun1c646862012-12-14 12:33:41 +01002357 /* error on protocol or underlying transport */
2358 if ((ret != SSL_ERROR_SYSCALL)
2359 || (errno && (errno != EAGAIN)))
2360 conn->flags |= CO_FL_ERROR;
2361
Emeric Brun644cde02012-12-14 11:21:13 +01002362 /* Clear openssl global errors stack */
2363 ERR_clear_error();
2364 }
Emeric Brun46591952012-05-18 15:47:34 +02002365 goto read0;
2366 }
2367 else {
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02002368 ret = SSL_get_error(conn->xprt_ctx, ret);
Emeric Brun46591952012-05-18 15:47:34 +02002369 if (ret == SSL_ERROR_WANT_WRITE) {
Emeric Brun8af8dd12012-11-08 17:56:20 +01002370 /* handshake is running, and it needs to enable write */
Emeric Brun46591952012-05-18 15:47:34 +02002371 conn->flags |= CO_FL_SSL_WAIT_HS;
Emeric Brun8af8dd12012-11-08 17:56:20 +01002372 __conn_sock_want_send(conn);
Emeric Brun46591952012-05-18 15:47:34 +02002373 break;
2374 }
2375 else if (ret == SSL_ERROR_WANT_READ) {
Emeric Brun282a76a2012-11-08 18:02:56 +01002376 if (SSL_renegotiate_pending(conn->xprt_ctx)) {
2377 /* handshake is running, and it may need to re-enable read */
2378 conn->flags |= CO_FL_SSL_WAIT_HS;
2379 __conn_sock_want_recv(conn);
2380 break;
2381 }
Emeric Brun46591952012-05-18 15:47:34 +02002382 /* we need to poll for retry a read later */
Willy Tarreaue1f50c42014-01-22 20:02:06 +01002383 fd_cant_recv(conn->t.sock.fd);
Emeric Brun46591952012-05-18 15:47:34 +02002384 break;
2385 }
2386 /* otherwise it's a real error */
2387 goto out_error;
2388 }
2389 }
2390 return done;
2391
2392 read0:
2393 conn_sock_read0(conn);
2394 return done;
2395 out_error:
Emeric Brun644cde02012-12-14 11:21:13 +01002396 /* Clear openssl global errors stack */
2397 ERR_clear_error();
2398
Emeric Brun46591952012-05-18 15:47:34 +02002399 conn->flags |= CO_FL_ERROR;
2400 return done;
2401}
2402
2403
2404/* Send all pending bytes from buffer <buf> to connection <conn>'s socket.
Willy Tarreau1049b1f2014-02-02 01:51:17 +01002405 * <flags> may contain some CO_SFL_* flags to hint the system about other
2406 * pending data for example, but this flag is ignored at the moment.
Emeric Brun46591952012-05-18 15:47:34 +02002407 * Only one call to send() is performed, unless the buffer wraps, in which case
2408 * a second call may be performed. The connection's flags are updated with
2409 * whatever special event is detected (error, empty). The caller is responsible
2410 * for taking care of those events and avoiding the call if inappropriate. The
2411 * function does not call the connection's polling update function, so the caller
2412 * is responsible for this.
2413 */
2414static int ssl_sock_from_buf(struct connection *conn, struct buffer *buf, int flags)
2415{
2416 int ret, try, done;
2417
2418 done = 0;
2419
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02002420 if (!conn->xprt_ctx)
Emeric Brun46591952012-05-18 15:47:34 +02002421 goto out_error;
2422
2423 if (conn->flags & CO_FL_HANDSHAKE)
2424 /* a handshake was requested */
2425 return 0;
2426
2427 /* send the largest possible block. For this we perform only one call
2428 * to send() unless the buffer wraps and we exactly fill the first hunk,
2429 * in which case we accept to do it once again.
2430 */
2431 while (buf->o) {
Kevin Hestercad82342013-05-30 15:12:41 -07002432 try = bo_contig_data(buf);
Willy Tarreaubfd59462013-02-21 07:46:09 +01002433
Willy Tarreau7bed9452014-02-02 02:00:24 +01002434 if (!(flags & CO_SFL_STREAMER) &&
Willy Tarreau518cedd2014-02-17 15:43:01 +01002435 !(conn->xprt_st & SSL_SOCK_SEND_UNLIMITED) &&
2436 global.tune.ssl_max_record && try > global.tune.ssl_max_record) {
Willy Tarreaubfd59462013-02-21 07:46:09 +01002437 try = global.tune.ssl_max_record;
Willy Tarreau518cedd2014-02-17 15:43:01 +01002438 }
2439 else {
2440 /* we need to keep the information about the fact that
2441 * we're not limiting the upcoming send(), because if it
2442 * fails, we'll have to retry with at least as many data.
2443 */
2444 conn->xprt_st |= SSL_SOCK_SEND_UNLIMITED;
2445 }
Willy Tarreaubfd59462013-02-21 07:46:09 +01002446
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02002447 ret = SSL_write(conn->xprt_ctx, bo_ptr(buf), try);
Willy Tarreau518cedd2014-02-17 15:43:01 +01002448
Emeric Brune1f38db2012-09-03 20:36:47 +02002449 if (conn->flags & CO_FL_ERROR) {
2450 /* CO_FL_ERROR may be set by ssl_sock_infocbk */
Emeric Brun644cde02012-12-14 11:21:13 +01002451 goto out_error;
Emeric Brune1f38db2012-09-03 20:36:47 +02002452 }
Emeric Brun46591952012-05-18 15:47:34 +02002453 if (ret > 0) {
Willy Tarreau518cedd2014-02-17 15:43:01 +01002454 conn->xprt_st &= ~SSL_SOCK_SEND_UNLIMITED;
2455
Emeric Brun46591952012-05-18 15:47:34 +02002456 buf->o -= ret;
2457 done += ret;
2458
Willy Tarreau5fb38032012-12-16 19:39:09 +01002459 if (likely(buffer_empty(buf)))
Emeric Brun46591952012-05-18 15:47:34 +02002460 /* optimize data alignment in the buffer */
2461 buf->p = buf->data;
2462
2463 /* if the system buffer is full, don't insist */
2464 if (ret < try)
2465 break;
2466 }
2467 else {
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02002468 ret = SSL_get_error(conn->xprt_ctx, ret);
Emeric Brun46591952012-05-18 15:47:34 +02002469 if (ret == SSL_ERROR_WANT_WRITE) {
Emeric Brun282a76a2012-11-08 18:02:56 +01002470 if (SSL_renegotiate_pending(conn->xprt_ctx)) {
2471 /* handshake is running, and it may need to re-enable write */
2472 conn->flags |= CO_FL_SSL_WAIT_HS;
2473 __conn_sock_want_send(conn);
2474 break;
2475 }
Emeric Brun46591952012-05-18 15:47:34 +02002476 /* we need to poll to retry a write later */
Willy Tarreaue1f50c42014-01-22 20:02:06 +01002477 fd_cant_send(conn->t.sock.fd);
Emeric Brun46591952012-05-18 15:47:34 +02002478 break;
2479 }
2480 else if (ret == SSL_ERROR_WANT_READ) {
Emeric Brun8af8dd12012-11-08 17:56:20 +01002481 /* handshake is running, and it needs to enable read */
Emeric Brun46591952012-05-18 15:47:34 +02002482 conn->flags |= CO_FL_SSL_WAIT_HS;
Emeric Brun8af8dd12012-11-08 17:56:20 +01002483 __conn_sock_want_recv(conn);
Emeric Brun46591952012-05-18 15:47:34 +02002484 break;
2485 }
2486 goto out_error;
2487 }
2488 }
2489 return done;
2490
2491 out_error:
Emeric Brun644cde02012-12-14 11:21:13 +01002492 /* Clear openssl global errors stack */
2493 ERR_clear_error();
2494
Emeric Brun46591952012-05-18 15:47:34 +02002495 conn->flags |= CO_FL_ERROR;
2496 return done;
2497}
2498
Emeric Brun46591952012-05-18 15:47:34 +02002499static void ssl_sock_close(struct connection *conn) {
2500
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02002501 if (conn->xprt_ctx) {
2502 SSL_free(conn->xprt_ctx);
2503 conn->xprt_ctx = NULL;
Willy Tarreau403edff2012-09-06 11:58:37 +02002504 sslconns--;
Emeric Brun46591952012-05-18 15:47:34 +02002505 }
Emeric Brun46591952012-05-18 15:47:34 +02002506}
2507
2508/* This function tries to perform a clean shutdown on an SSL connection, and in
2509 * any case, flags the connection as reusable if no handshake was in progress.
2510 */
2511static void ssl_sock_shutw(struct connection *conn, int clean)
2512{
2513 if (conn->flags & CO_FL_HANDSHAKE)
2514 return;
2515 /* no handshake was in progress, try a clean ssl shutdown */
Emeric Brun644cde02012-12-14 11:21:13 +01002516 if (clean && (SSL_shutdown(conn->xprt_ctx) <= 0)) {
2517 /* Clear openssl global errors stack */
2518 ERR_clear_error();
2519 }
Emeric Brun46591952012-05-18 15:47:34 +02002520
2521 /* force flag on ssl to keep session in cache regardless shutdown result */
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02002522 SSL_set_shutdown(conn->xprt_ctx, SSL_SENT_SHUTDOWN);
Emeric Brun46591952012-05-18 15:47:34 +02002523}
2524
Willy Tarreauffc3fcd2012-10-12 20:17:54 +02002525/* used for logging, may be changed for a sample fetch later */
2526const char *ssl_sock_get_cipher_name(struct connection *conn)
2527{
2528 if (!conn->xprt && !conn->xprt_ctx)
2529 return NULL;
2530 return SSL_get_cipher_name(conn->xprt_ctx);
2531}
2532
2533/* used for logging, may be changed for a sample fetch later */
2534const char *ssl_sock_get_proto_version(struct connection *conn)
2535{
2536 if (!conn->xprt && !conn->xprt_ctx)
2537 return NULL;
2538 return SSL_get_version(conn->xprt_ctx);
2539}
2540
Willy Tarreau8d598402012-10-22 17:58:39 +02002541/* Extract a serial from a cert, and copy it to a chunk.
2542 * Returns 1 if serial is found and copied, 0 if no serial found and
2543 * -1 if output is not large enough.
2544 */
2545static int
2546ssl_sock_get_serial(X509 *crt, struct chunk *out)
2547{
2548 ASN1_INTEGER *serial;
2549
2550 serial = X509_get_serialNumber(crt);
2551 if (!serial)
2552 return 0;
2553
2554 if (out->size < serial->length)
2555 return -1;
2556
2557 memcpy(out->str, serial->data, serial->length);
2558 out->len = serial->length;
2559 return 1;
2560}
2561
Emeric Brun43e79582014-10-29 19:03:26 +01002562/* Extract a cert to der, and copy it to a chunk.
2563 * Returns 1 if cert is found and copied, 0 on der convertion failure and
2564 * -1 if output is not large enough.
2565 */
2566static int
2567ssl_sock_crt2der(X509 *crt, struct chunk *out)
2568{
2569 int len;
2570 unsigned char *p = (unsigned char *)out->str;;
2571
2572 len =i2d_X509(crt, NULL);
2573 if (len <= 0)
2574 return 1;
2575
2576 if (out->size < len)
2577 return -1;
2578
2579 i2d_X509(crt,&p);
2580 out->len = len;
2581 return 1;
2582}
2583
Emeric Brunce5ad802012-10-22 14:11:22 +02002584
2585/* Copy Date in ASN1_UTCTIME format in struct chunk out.
2586 * Returns 1 if serial is found and copied, 0 if no valid time found
2587 * and -1 if output is not large enough.
2588 */
2589static int
2590ssl_sock_get_time(ASN1_TIME *tm, struct chunk *out)
2591{
2592 if (tm->type == V_ASN1_GENERALIZEDTIME) {
2593 ASN1_GENERALIZEDTIME *gentm = (ASN1_GENERALIZEDTIME *)tm;
2594
2595 if (gentm->length < 12)
2596 return 0;
2597 if (gentm->data[0] != 0x32 || gentm->data[1] != 0x30)
2598 return 0;
2599 if (out->size < gentm->length-2)
2600 return -1;
2601
2602 memcpy(out->str, gentm->data+2, gentm->length-2);
2603 out->len = gentm->length-2;
2604 return 1;
2605 }
2606 else if (tm->type == V_ASN1_UTCTIME) {
2607 ASN1_UTCTIME *utctm = (ASN1_UTCTIME *)tm;
2608
2609 if (utctm->length < 10)
2610 return 0;
2611 if (utctm->data[0] >= 0x35)
2612 return 0;
2613 if (out->size < utctm->length)
2614 return -1;
2615
2616 memcpy(out->str, utctm->data, utctm->length);
2617 out->len = utctm->length;
2618 return 1;
2619 }
2620
2621 return 0;
2622}
2623
Emeric Brun87855892012-10-17 17:39:35 +02002624/* Extract an entry from a X509_NAME and copy its value to an output chunk.
2625 * Returns 1 if entry found, 0 if entry not found, or -1 if output not large enough.
2626 */
2627static int
2628ssl_sock_get_dn_entry(X509_NAME *a, const struct chunk *entry, int pos, struct chunk *out)
2629{
2630 X509_NAME_ENTRY *ne;
2631 int i, j, n;
2632 int cur = 0;
2633 const char *s;
2634 char tmp[128];
2635
2636 out->len = 0;
2637 for (i = 0; i < sk_X509_NAME_ENTRY_num(a->entries); i++) {
2638 if (pos < 0)
2639 j = (sk_X509_NAME_ENTRY_num(a->entries)-1) - i;
2640 else
2641 j = i;
2642
2643 ne = sk_X509_NAME_ENTRY_value(a->entries, j);
2644 n = OBJ_obj2nid(ne->object);
2645 if ((n == NID_undef) || ((s = OBJ_nid2sn(n)) == NULL)) {
2646 i2t_ASN1_OBJECT(tmp, sizeof(tmp), ne->object);
2647 s = tmp;
2648 }
2649
2650 if (chunk_strcasecmp(entry, s) != 0)
2651 continue;
2652
2653 if (pos < 0)
2654 cur--;
2655 else
2656 cur++;
2657
2658 if (cur != pos)
2659 continue;
2660
2661 if (ne->value->length > out->size)
2662 return -1;
2663
2664 memcpy(out->str, ne->value->data, ne->value->length);
2665 out->len = ne->value->length;
2666 return 1;
2667 }
2668
2669 return 0;
2670
2671}
2672
2673/* Extract and format full DN from a X509_NAME and copy result into a chunk
2674 * Returns 1 if dn entries exits, 0 if no dn entry found or -1 if output is not large enough.
2675 */
2676static int
2677ssl_sock_get_dn_oneline(X509_NAME *a, struct chunk *out)
2678{
2679 X509_NAME_ENTRY *ne;
2680 int i, n, ln;
2681 int l = 0;
2682 const char *s;
2683 char *p;
2684 char tmp[128];
2685
2686 out->len = 0;
2687 p = out->str;
2688 for (i = 0; i < sk_X509_NAME_ENTRY_num(a->entries); i++) {
2689 ne = sk_X509_NAME_ENTRY_value(a->entries, i);
2690 n = OBJ_obj2nid(ne->object);
2691 if ((n == NID_undef) || ((s = OBJ_nid2sn(n)) == NULL)) {
2692 i2t_ASN1_OBJECT(tmp, sizeof(tmp), ne->object);
2693 s = tmp;
2694 }
2695 ln = strlen(s);
2696
2697 l += 1 + ln + 1 + ne->value->length;
2698 if (l > out->size)
2699 return -1;
2700 out->len = l;
2701
2702 *(p++)='/';
2703 memcpy(p, s, ln);
2704 p += ln;
2705 *(p++)='=';
2706 memcpy(p, ne->value->data, ne->value->length);
2707 p += ne->value->length;
2708 }
2709
2710 if (!out->len)
2711 return 0;
2712
2713 return 1;
2714}
2715
David Safb76832014-05-08 23:42:08 -04002716char *ssl_sock_get_version(struct connection *conn)
2717{
2718 if (!ssl_sock_is_ssl(conn))
2719 return NULL;
2720
2721 return (char *)SSL_get_version(conn->xprt_ctx);
2722}
2723
Emeric Brun0abf8362014-06-24 18:26:41 +02002724/* Extract peer certificate's common name into the chunk dest
2725 * Returns
2726 * the len of the extracted common name
2727 * or 0 if no CN found in DN
2728 * or -1 on error case (i.e. no peer certificate)
2729 */
2730int ssl_sock_get_remote_common_name(struct connection *conn, struct chunk *dest)
David Safb76832014-05-08 23:42:08 -04002731{
2732 X509 *crt = NULL;
2733 X509_NAME *name;
David Safb76832014-05-08 23:42:08 -04002734 const char find_cn[] = "CN";
2735 const struct chunk find_cn_chunk = {
2736 .str = (char *)&find_cn,
2737 .len = sizeof(find_cn)-1
2738 };
Emeric Brun0abf8362014-06-24 18:26:41 +02002739 int result = -1;
David Safb76832014-05-08 23:42:08 -04002740
2741 if (!ssl_sock_is_ssl(conn))
Emeric Brun0abf8362014-06-24 18:26:41 +02002742 goto out;
David Safb76832014-05-08 23:42:08 -04002743
2744 /* SSL_get_peer_certificate, it increase X509 * ref count */
2745 crt = SSL_get_peer_certificate(conn->xprt_ctx);
2746 if (!crt)
2747 goto out;
2748
2749 name = X509_get_subject_name(crt);
2750 if (!name)
2751 goto out;
David Safb76832014-05-08 23:42:08 -04002752
Emeric Brun0abf8362014-06-24 18:26:41 +02002753 result = ssl_sock_get_dn_entry(name, &find_cn_chunk, 1, dest);
2754out:
David Safb76832014-05-08 23:42:08 -04002755 if (crt)
2756 X509_free(crt);
2757
2758 return result;
2759}
2760
Dave McCowan328fb582014-07-30 10:39:13 -04002761/* returns 1 if client passed a certificate for this session, 0 if not */
2762int ssl_sock_get_cert_used_sess(struct connection *conn)
2763{
2764 X509 *crt = NULL;
2765
2766 if (!ssl_sock_is_ssl(conn))
2767 return 0;
2768
2769 /* SSL_get_peer_certificate, it increase X509 * ref count */
2770 crt = SSL_get_peer_certificate(conn->xprt_ctx);
2771 if (!crt)
2772 return 0;
2773
2774 X509_free(crt);
2775 return 1;
2776}
2777
2778/* returns 1 if client passed a certificate for this connection, 0 if not */
2779int ssl_sock_get_cert_used_conn(struct connection *conn)
David Safb76832014-05-08 23:42:08 -04002780{
2781 if (!ssl_sock_is_ssl(conn))
2782 return 0;
2783
2784 return SSL_SOCK_ST_FL_VERIFY_DONE & conn->xprt_st ? 1 : 0;
2785}
2786
2787/* returns result from SSL verify */
2788unsigned int ssl_sock_get_verify_result(struct connection *conn)
2789{
2790 if (!ssl_sock_is_ssl(conn))
2791 return (unsigned int)X509_V_ERR_APPLICATION_VERIFICATION;
2792
2793 return (unsigned int)SSL_get_verify_result(conn->xprt_ctx);
2794}
2795
Willy Tarreau7875d092012-09-10 08:20:03 +02002796/***** Below are some sample fetching functions for ACL/patterns *****/
2797
Emeric Brune64aef12012-09-21 13:15:06 +02002798/* boolean, returns true if client cert was present */
2799static int
Emeric Brun2525b6b2012-10-18 15:59:43 +02002800smp_fetch_ssl_fc_has_crt(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
Willy Tarreauef38c392013-07-22 16:29:32 +02002801 const struct arg *args, struct sample *smp, const char *kw)
Emeric Brune64aef12012-09-21 13:15:06 +02002802{
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002803 struct connection *conn;
2804
2805 if (!l4)
2806 return 0;
2807
2808 conn = objt_conn(l4->si[0].end);
2809 if (!conn || conn->xprt != &ssl_sock)
Emeric Brune64aef12012-09-21 13:15:06 +02002810 return 0;
2811
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002812 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brune64aef12012-09-21 13:15:06 +02002813 smp->flags |= SMP_F_MAY_CHANGE;
2814 return 0;
2815 }
2816
2817 smp->flags = 0;
2818 smp->type = SMP_T_BOOL;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002819 smp->data.uint = SSL_SOCK_ST_FL_VERIFY_DONE & conn->xprt_st ? 1 : 0;
Emeric Brune64aef12012-09-21 13:15:06 +02002820
2821 return 1;
2822}
2823
Emeric Brun43e79582014-10-29 19:03:26 +01002824/* binary, returns a certificate in a binary chunk (der/raw).
2825 * The 5th keyword char is used to know if SSL_get_certificate or SSL_get_peer_certificate
2826 * should be use.
2827 */
2828static int
2829smp_fetch_ssl_x_der(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
2830 const struct arg *args, struct sample *smp, const char *kw)
2831{
2832 int cert_peer = (kw[4] == 'c') ? 1 : 0;
2833 X509 *crt = NULL;
2834 int ret = 0;
2835 struct chunk *smp_trash;
2836 struct connection *conn;
2837
2838 if (!l4)
2839 return 0;
2840
2841 conn = objt_conn(l4->si[0].end);
2842 if (!conn || conn->xprt != &ssl_sock)
2843 return 0;
2844
2845 if (!(conn->flags & CO_FL_CONNECTED)) {
2846 smp->flags |= SMP_F_MAY_CHANGE;
2847 return 0;
2848 }
2849
2850 if (cert_peer)
2851 crt = SSL_get_peer_certificate(conn->xprt_ctx);
2852 else
2853 crt = SSL_get_certificate(conn->xprt_ctx);
2854
2855 if (!crt)
2856 goto out;
2857
2858 smp_trash = get_trash_chunk();
2859 if (ssl_sock_crt2der(crt, smp_trash) <= 0)
2860 goto out;
2861
2862 smp->data.str = *smp_trash;
2863 smp->type = SMP_T_BIN;
2864 ret = 1;
2865out:
2866 /* SSL_get_peer_certificate, it increase X509 * ref count */
2867 if (cert_peer && crt)
2868 X509_free(crt);
2869 return ret;
2870}
2871
Emeric Brunba841a12014-04-30 17:05:08 +02002872/* binary, returns serial of certificate in a binary chunk.
2873 * The 5th keyword char is used to know if SSL_get_certificate or SSL_get_peer_certificate
2874 * should be use.
2875 */
Willy Tarreau8d598402012-10-22 17:58:39 +02002876static int
Emeric Brunba841a12014-04-30 17:05:08 +02002877smp_fetch_ssl_x_serial(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
Willy Tarreauef38c392013-07-22 16:29:32 +02002878 const struct arg *args, struct sample *smp, const char *kw)
Willy Tarreau8d598402012-10-22 17:58:39 +02002879{
Emeric Brunba841a12014-04-30 17:05:08 +02002880 int cert_peer = (kw[4] == 'c') ? 1 : 0;
Willy Tarreau8d598402012-10-22 17:58:39 +02002881 X509 *crt = NULL;
2882 int ret = 0;
2883 struct chunk *smp_trash;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002884 struct connection *conn;
2885
2886 if (!l4)
2887 return 0;
Willy Tarreau8d598402012-10-22 17:58:39 +02002888
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002889 conn = objt_conn(l4->si[0].end);
2890 if (!conn || conn->xprt != &ssl_sock)
Willy Tarreau8d598402012-10-22 17:58:39 +02002891 return 0;
2892
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002893 if (!(conn->flags & CO_FL_CONNECTED)) {
Willy Tarreau8d598402012-10-22 17:58:39 +02002894 smp->flags |= SMP_F_MAY_CHANGE;
2895 return 0;
2896 }
2897
Emeric Brunba841a12014-04-30 17:05:08 +02002898 if (cert_peer)
2899 crt = SSL_get_peer_certificate(conn->xprt_ctx);
2900 else
2901 crt = SSL_get_certificate(conn->xprt_ctx);
2902
Willy Tarreau8d598402012-10-22 17:58:39 +02002903 if (!crt)
2904 goto out;
2905
Willy Tarreau47ca5452012-12-23 20:22:19 +01002906 smp_trash = get_trash_chunk();
Willy Tarreau8d598402012-10-22 17:58:39 +02002907 if (ssl_sock_get_serial(crt, smp_trash) <= 0)
2908 goto out;
2909
2910 smp->data.str = *smp_trash;
2911 smp->type = SMP_T_BIN;
2912 ret = 1;
2913out:
Emeric Brunba841a12014-04-30 17:05:08 +02002914 /* SSL_get_peer_certificate, it increase X509 * ref count */
2915 if (cert_peer && crt)
Willy Tarreau8d598402012-10-22 17:58:39 +02002916 X509_free(crt);
2917 return ret;
2918}
Emeric Brune64aef12012-09-21 13:15:06 +02002919
Emeric Brunba841a12014-04-30 17:05:08 +02002920/* binary, returns the client certificate's SHA-1 fingerprint (SHA-1 hash of DER-encoded certificate) in a binary chunk.
2921 * The 5th keyword char is used to know if SSL_get_certificate or SSL_get_peer_certificate
2922 * should be use.
2923 */
James Votha051b4a2013-05-14 20:37:59 +02002924static int
Emeric Brunba841a12014-04-30 17:05:08 +02002925smp_fetch_ssl_x_sha1(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
Willy Tarreauef38c392013-07-22 16:29:32 +02002926 const struct arg *args, struct sample *smp, const char *kw)
James Votha051b4a2013-05-14 20:37:59 +02002927{
Emeric Brunba841a12014-04-30 17:05:08 +02002928 int cert_peer = (kw[4] == 'c') ? 1 : 0;
James Votha051b4a2013-05-14 20:37:59 +02002929 X509 *crt = NULL;
2930 const EVP_MD *digest;
2931 int ret = 0;
2932 struct chunk *smp_trash;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002933 struct connection *conn;
James Votha051b4a2013-05-14 20:37:59 +02002934
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002935 if (!l4)
James Votha051b4a2013-05-14 20:37:59 +02002936 return 0;
2937
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002938 conn = objt_conn(l4->si[0].end);
2939 if (!conn || conn->xprt != &ssl_sock)
2940 return 0;
2941
2942 if (!(conn->flags & CO_FL_CONNECTED)) {
James Votha051b4a2013-05-14 20:37:59 +02002943 smp->flags |= SMP_F_MAY_CHANGE;
2944 return 0;
2945 }
2946
Emeric Brunba841a12014-04-30 17:05:08 +02002947 if (cert_peer)
2948 crt = SSL_get_peer_certificate(conn->xprt_ctx);
2949 else
2950 crt = SSL_get_certificate(conn->xprt_ctx);
James Votha051b4a2013-05-14 20:37:59 +02002951 if (!crt)
2952 goto out;
2953
2954 smp_trash = get_trash_chunk();
2955 digest = EVP_sha1();
2956 X509_digest(crt, digest, (unsigned char *)smp_trash->str, (unsigned int *)&smp_trash->len);
2957
2958 smp->data.str = *smp_trash;
2959 smp->type = SMP_T_BIN;
2960 ret = 1;
2961out:
Emeric Brunba841a12014-04-30 17:05:08 +02002962 /* SSL_get_peer_certificate, it increase X509 * ref count */
2963 if (cert_peer && crt)
James Votha051b4a2013-05-14 20:37:59 +02002964 X509_free(crt);
2965 return ret;
2966}
2967
Emeric Brunba841a12014-04-30 17:05:08 +02002968/* string, returns certificate's notafter date in ASN1_UTCTIME format.
2969 * The 5th keyword char is used to know if SSL_get_certificate or SSL_get_peer_certificate
2970 * should be use.
2971 */
Emeric Brunce5ad802012-10-22 14:11:22 +02002972static int
Emeric Brunba841a12014-04-30 17:05:08 +02002973smp_fetch_ssl_x_notafter(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
Willy Tarreauef38c392013-07-22 16:29:32 +02002974 const struct arg *args, struct sample *smp, const char *kw)
Emeric Brunce5ad802012-10-22 14:11:22 +02002975{
Emeric Brunba841a12014-04-30 17:05:08 +02002976 int cert_peer = (kw[4] == 'c') ? 1 : 0;
Emeric Brunce5ad802012-10-22 14:11:22 +02002977 X509 *crt = NULL;
2978 int ret = 0;
2979 struct chunk *smp_trash;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002980 struct connection *conn;
Emeric Brunce5ad802012-10-22 14:11:22 +02002981
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002982 if (!l4)
Emeric Brunce5ad802012-10-22 14:11:22 +02002983 return 0;
2984
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002985 conn = objt_conn(l4->si[0].end);
2986 if (!conn || conn->xprt != &ssl_sock)
2987 return 0;
2988
2989 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brunce5ad802012-10-22 14:11:22 +02002990 smp->flags |= SMP_F_MAY_CHANGE;
2991 return 0;
2992 }
2993
Emeric Brunba841a12014-04-30 17:05:08 +02002994 if (cert_peer)
2995 crt = SSL_get_peer_certificate(conn->xprt_ctx);
2996 else
2997 crt = SSL_get_certificate(conn->xprt_ctx);
Emeric Brunce5ad802012-10-22 14:11:22 +02002998 if (!crt)
2999 goto out;
3000
Willy Tarreau47ca5452012-12-23 20:22:19 +01003001 smp_trash = get_trash_chunk();
Emeric Brunce5ad802012-10-22 14:11:22 +02003002 if (ssl_sock_get_time(X509_get_notAfter(crt), smp_trash) <= 0)
3003 goto out;
3004
3005 smp->data.str = *smp_trash;
3006 smp->type = SMP_T_STR;
3007 ret = 1;
3008out:
Emeric Brunba841a12014-04-30 17:05:08 +02003009 /* SSL_get_peer_certificate, it increase X509 * ref count */
3010 if (cert_peer && crt)
Emeric Brunce5ad802012-10-22 14:11:22 +02003011 X509_free(crt);
3012 return ret;
3013}
3014
Emeric Brunba841a12014-04-30 17:05:08 +02003015/* string, returns a string of a formatted full dn \C=..\O=..\OU=.. \CN=.. of certificate's issuer
3016 * The 5th keyword char is used to know if SSL_get_certificate or SSL_get_peer_certificate
3017 * should be use.
3018 */
Emeric Brun87855892012-10-17 17:39:35 +02003019static int
Emeric Brunba841a12014-04-30 17:05:08 +02003020smp_fetch_ssl_x_i_dn(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
Willy Tarreauef38c392013-07-22 16:29:32 +02003021 const struct arg *args, struct sample *smp, const char *kw)
Emeric Brun87855892012-10-17 17:39:35 +02003022{
Emeric Brunba841a12014-04-30 17:05:08 +02003023 int cert_peer = (kw[4] == 'c') ? 1 : 0;
Emeric Brun87855892012-10-17 17:39:35 +02003024 X509 *crt = NULL;
3025 X509_NAME *name;
3026 int ret = 0;
3027 struct chunk *smp_trash;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003028 struct connection *conn;
Emeric Brun87855892012-10-17 17:39:35 +02003029
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003030 if (!l4)
Emeric Brun87855892012-10-17 17:39:35 +02003031 return 0;
3032
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003033 conn = objt_conn(l4->si[0].end);
3034 if (!conn || conn->xprt != &ssl_sock)
3035 return 0;
3036
3037 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brun87855892012-10-17 17:39:35 +02003038 smp->flags |= SMP_F_MAY_CHANGE;
3039 return 0;
3040 }
3041
Emeric Brunba841a12014-04-30 17:05:08 +02003042 if (cert_peer)
3043 crt = SSL_get_peer_certificate(conn->xprt_ctx);
3044 else
3045 crt = SSL_get_certificate(conn->xprt_ctx);
Emeric Brun87855892012-10-17 17:39:35 +02003046 if (!crt)
3047 goto out;
3048
3049 name = X509_get_issuer_name(crt);
3050 if (!name)
3051 goto out;
3052
Willy Tarreau47ca5452012-12-23 20:22:19 +01003053 smp_trash = get_trash_chunk();
Emeric Brun87855892012-10-17 17:39:35 +02003054 if (args && args[0].type == ARGT_STR) {
3055 int pos = 1;
3056
3057 if (args[1].type == ARGT_SINT)
3058 pos = args[1].data.sint;
3059 else if (args[1].type == ARGT_UINT)
3060 pos =(int)args[1].data.uint;
3061
3062 if (ssl_sock_get_dn_entry(name, &args[0].data.str, pos, smp_trash) <= 0)
3063 goto out;
3064 }
3065 else if (ssl_sock_get_dn_oneline(name, smp_trash) <= 0)
3066 goto out;
3067
3068 smp->type = SMP_T_STR;
3069 smp->data.str = *smp_trash;
3070 ret = 1;
3071out:
Emeric Brunba841a12014-04-30 17:05:08 +02003072 /* SSL_get_peer_certificate, it increase X509 * ref count */
3073 if (cert_peer && crt)
Emeric Brun87855892012-10-17 17:39:35 +02003074 X509_free(crt);
3075 return ret;
3076}
3077
Emeric Brunba841a12014-04-30 17:05:08 +02003078/* string, returns notbefore date in ASN1_UTCTIME format.
3079 * The 5th keyword char is used to know if SSL_get_certificate or SSL_get_peer_certificate
3080 * should be use.
3081 */
Emeric Brunce5ad802012-10-22 14:11:22 +02003082static int
Emeric Brunba841a12014-04-30 17:05:08 +02003083smp_fetch_ssl_x_notbefore(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
Willy Tarreauef38c392013-07-22 16:29:32 +02003084 const struct arg *args, struct sample *smp, const char *kw)
Emeric Brunce5ad802012-10-22 14:11:22 +02003085{
Emeric Brunba841a12014-04-30 17:05:08 +02003086 int cert_peer = (kw[4] == 'c') ? 1 : 0;
Emeric Brunce5ad802012-10-22 14:11:22 +02003087 X509 *crt = NULL;
3088 int ret = 0;
3089 struct chunk *smp_trash;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003090 struct connection *conn;
3091
3092 if (!l4)
3093 return 0;
Emeric Brunce5ad802012-10-22 14:11:22 +02003094
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003095 conn = objt_conn(l4->si[0].end);
3096 if (!conn || conn->xprt != &ssl_sock)
Emeric Brunce5ad802012-10-22 14:11:22 +02003097 return 0;
3098
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003099 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brunce5ad802012-10-22 14:11:22 +02003100 smp->flags |= SMP_F_MAY_CHANGE;
3101 return 0;
3102 }
3103
Emeric Brunba841a12014-04-30 17:05:08 +02003104 if (cert_peer)
3105 crt = SSL_get_peer_certificate(conn->xprt_ctx);
3106 else
3107 crt = SSL_get_certificate(conn->xprt_ctx);
Emeric Brunce5ad802012-10-22 14:11:22 +02003108 if (!crt)
3109 goto out;
3110
Willy Tarreau47ca5452012-12-23 20:22:19 +01003111 smp_trash = get_trash_chunk();
Emeric Brunce5ad802012-10-22 14:11:22 +02003112 if (ssl_sock_get_time(X509_get_notBefore(crt), smp_trash) <= 0)
3113 goto out;
3114
3115 smp->data.str = *smp_trash;
3116 smp->type = SMP_T_STR;
3117 ret = 1;
3118out:
Emeric Brunba841a12014-04-30 17:05:08 +02003119 /* SSL_get_peer_certificate, it increase X509 * ref count */
3120 if (cert_peer && crt)
Emeric Brunce5ad802012-10-22 14:11:22 +02003121 X509_free(crt);
3122 return ret;
3123}
3124
Emeric Brunba841a12014-04-30 17:05:08 +02003125/* string, returns a string of a formatted full dn \C=..\O=..\OU=.. \CN=.. of certificate's subject
3126 * The 5th keyword char is used to know if SSL_get_certificate or SSL_get_peer_certificate
3127 * should be use.
3128 */
Emeric Brun87855892012-10-17 17:39:35 +02003129static int
Emeric Brunba841a12014-04-30 17:05:08 +02003130smp_fetch_ssl_x_s_dn(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
Willy Tarreauef38c392013-07-22 16:29:32 +02003131 const struct arg *args, struct sample *smp, const char *kw)
Emeric Brun87855892012-10-17 17:39:35 +02003132{
Emeric Brunba841a12014-04-30 17:05:08 +02003133 int cert_peer = (kw[4] == 'c') ? 1 : 0;
Emeric Brun87855892012-10-17 17:39:35 +02003134 X509 *crt = NULL;
3135 X509_NAME *name;
3136 int ret = 0;
3137 struct chunk *smp_trash;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003138 struct connection *conn;
Emeric Brun87855892012-10-17 17:39:35 +02003139
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003140 if (!l4)
Emeric Brun87855892012-10-17 17:39:35 +02003141 return 0;
3142
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003143 conn = objt_conn(l4->si[0].end);
3144 if (!conn || conn->xprt != &ssl_sock)
3145 return 0;
3146
3147 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brun87855892012-10-17 17:39:35 +02003148 smp->flags |= SMP_F_MAY_CHANGE;
3149 return 0;
3150 }
3151
Emeric Brunba841a12014-04-30 17:05:08 +02003152 if (cert_peer)
3153 crt = SSL_get_peer_certificate(conn->xprt_ctx);
3154 else
3155 crt = SSL_get_certificate(conn->xprt_ctx);
Emeric Brun87855892012-10-17 17:39:35 +02003156 if (!crt)
3157 goto out;
3158
3159 name = X509_get_subject_name(crt);
3160 if (!name)
3161 goto out;
3162
Willy Tarreau47ca5452012-12-23 20:22:19 +01003163 smp_trash = get_trash_chunk();
Emeric Brun87855892012-10-17 17:39:35 +02003164 if (args && args[0].type == ARGT_STR) {
3165 int pos = 1;
3166
3167 if (args[1].type == ARGT_SINT)
3168 pos = args[1].data.sint;
3169 else if (args[1].type == ARGT_UINT)
3170 pos =(int)args[1].data.uint;
3171
3172 if (ssl_sock_get_dn_entry(name, &args[0].data.str, pos, smp_trash) <= 0)
3173 goto out;
3174 }
3175 else if (ssl_sock_get_dn_oneline(name, smp_trash) <= 0)
3176 goto out;
3177
3178 smp->type = SMP_T_STR;
3179 smp->data.str = *smp_trash;
3180 ret = 1;
3181out:
Emeric Brunba841a12014-04-30 17:05:08 +02003182 /* SSL_get_peer_certificate, it increase X509 * ref count */
3183 if (cert_peer && crt)
Emeric Brun87855892012-10-17 17:39:35 +02003184 X509_free(crt);
3185 return ret;
3186}
Emeric Brun9143d372012-12-20 15:44:16 +01003187
3188/* integer, returns true if current session use a client certificate */
3189static int
3190smp_fetch_ssl_c_used(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
Willy Tarreauef38c392013-07-22 16:29:32 +02003191 const struct arg *args, struct sample *smp, const char *kw)
Emeric Brun9143d372012-12-20 15:44:16 +01003192{
3193 X509 *crt;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003194 struct connection *conn;
Emeric Brun9143d372012-12-20 15:44:16 +01003195
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003196 if (!l4)
Emeric Brun9143d372012-12-20 15:44:16 +01003197 return 0;
3198
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003199 conn = objt_conn(l4->si[0].end);
3200 if (!conn || conn->xprt != &ssl_sock)
3201 return 0;
3202
3203 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brun9143d372012-12-20 15:44:16 +01003204 smp->flags |= SMP_F_MAY_CHANGE;
3205 return 0;
3206 }
3207
3208 /* SSL_get_peer_certificate returns a ptr on allocated X509 struct */
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003209 crt = SSL_get_peer_certificate(conn->xprt_ctx);
Emeric Brun9143d372012-12-20 15:44:16 +01003210 if (crt) {
3211 X509_free(crt);
3212 }
3213
3214 smp->type = SMP_T_BOOL;
3215 smp->data.uint = (crt != NULL);
3216 return 1;
3217}
3218
Emeric Brunba841a12014-04-30 17:05:08 +02003219/* integer, returns the certificate version
3220 * The 5th keyword char is used to know if SSL_get_certificate or SSL_get_peer_certificate
3221 * should be use.
3222 */
Emeric Bruna7359fd2012-10-17 15:03:11 +02003223static int
Emeric Brunba841a12014-04-30 17:05:08 +02003224smp_fetch_ssl_x_version(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
Willy Tarreauef38c392013-07-22 16:29:32 +02003225 const struct arg *args, struct sample *smp, const char *kw)
Emeric Bruna7359fd2012-10-17 15:03:11 +02003226{
Emeric Brunba841a12014-04-30 17:05:08 +02003227 int cert_peer = (kw[4] == 'c') ? 1 : 0;
Emeric Bruna7359fd2012-10-17 15:03:11 +02003228 X509 *crt;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003229 struct connection *conn;
3230
3231 if (!l4)
3232 return 0;
Emeric Bruna7359fd2012-10-17 15:03:11 +02003233
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003234 conn = objt_conn(l4->si[0].end);
3235 if (!conn || conn->xprt != &ssl_sock)
Emeric Bruna7359fd2012-10-17 15:03:11 +02003236 return 0;
3237
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003238 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Bruna7359fd2012-10-17 15:03:11 +02003239 smp->flags |= SMP_F_MAY_CHANGE;
3240 return 0;
3241 }
3242
Emeric Brunba841a12014-04-30 17:05:08 +02003243 if (cert_peer)
3244 crt = SSL_get_peer_certificate(conn->xprt_ctx);
3245 else
3246 crt = SSL_get_certificate(conn->xprt_ctx);
Emeric Bruna7359fd2012-10-17 15:03:11 +02003247 if (!crt)
3248 return 0;
3249
3250 smp->data.uint = (unsigned int)(1 + X509_get_version(crt));
Emeric Brunba841a12014-04-30 17:05:08 +02003251 /* SSL_get_peer_certificate increase X509 * ref count */
3252 if (cert_peer)
3253 X509_free(crt);
Emeric Bruna7359fd2012-10-17 15:03:11 +02003254 smp->type = SMP_T_UINT;
3255
3256 return 1;
3257}
3258
Emeric Brunba841a12014-04-30 17:05:08 +02003259/* string, returns the certificate's signature algorithm.
3260 * The 5th keyword char is used to know if SSL_get_certificate or SSL_get_peer_certificate
3261 * should be use.
3262 */
Emeric Brun7f56e742012-10-19 18:15:40 +02003263static int
Emeric Brunba841a12014-04-30 17:05:08 +02003264smp_fetch_ssl_x_sig_alg(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
Willy Tarreauef38c392013-07-22 16:29:32 +02003265 const struct arg *args, struct sample *smp, const char *kw)
Emeric Brun7f56e742012-10-19 18:15:40 +02003266{
Emeric Brunba841a12014-04-30 17:05:08 +02003267 int cert_peer = (kw[4] == 'c') ? 1 : 0;
Emeric Brun7f56e742012-10-19 18:15:40 +02003268 X509 *crt;
3269 int nid;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003270 struct connection *conn;
Emeric Brun7f56e742012-10-19 18:15:40 +02003271
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003272 if (!l4)
Emeric Brun7f56e742012-10-19 18:15:40 +02003273 return 0;
3274
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003275 conn = objt_conn(l4->si[0].end);
3276 if (!conn || conn->xprt != &ssl_sock)
3277 return 0;
3278
3279 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brun7f56e742012-10-19 18:15:40 +02003280 smp->flags |= SMP_F_MAY_CHANGE;
3281 return 0;
3282 }
3283
Emeric Brunba841a12014-04-30 17:05:08 +02003284 if (cert_peer)
3285 crt = SSL_get_peer_certificate(conn->xprt_ctx);
3286 else
3287 crt = SSL_get_certificate(conn->xprt_ctx);
Emeric Brun7f56e742012-10-19 18:15:40 +02003288 if (!crt)
3289 return 0;
3290
3291 nid = OBJ_obj2nid((ASN1_OBJECT *)(crt->cert_info->signature->algorithm));
3292
3293 smp->data.str.str = (char *)OBJ_nid2sn(nid);
Emeric Brun9bf3ba22013-10-07 14:31:44 +02003294 if (!smp->data.str.str) {
Emeric Brunba841a12014-04-30 17:05:08 +02003295 /* SSL_get_peer_certificate increase X509 * ref count */
3296 if (cert_peer)
3297 X509_free(crt);
Emeric Brun7f56e742012-10-19 18:15:40 +02003298 return 0;
Emeric Brun9bf3ba22013-10-07 14:31:44 +02003299 }
Emeric Brun7f56e742012-10-19 18:15:40 +02003300
Thierry FOURNIER7654c9f2013-12-17 00:20:33 +01003301 smp->type = SMP_T_STR;
3302 smp->flags |= SMP_F_CONST;
Emeric Brun7f56e742012-10-19 18:15:40 +02003303 smp->data.str.len = strlen(smp->data.str.str);
Emeric Brunba841a12014-04-30 17:05:08 +02003304 /* SSL_get_peer_certificate increase X509 * ref count */
3305 if (cert_peer)
3306 X509_free(crt);
Emeric Brun7f56e742012-10-19 18:15:40 +02003307
3308 return 1;
3309}
3310
Emeric Brunba841a12014-04-30 17:05:08 +02003311/* string, returns the certificate's key algorithm.
3312 * The 5th keyword char is used to know if SSL_get_certificate or SSL_get_peer_certificate
3313 * should be use.
3314 */
Emeric Brun521a0112012-10-22 12:22:55 +02003315static int
Emeric Brunba841a12014-04-30 17:05:08 +02003316smp_fetch_ssl_x_key_alg(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
Willy Tarreauef38c392013-07-22 16:29:32 +02003317 const struct arg *args, struct sample *smp, const char *kw)
Emeric Brun521a0112012-10-22 12:22:55 +02003318{
Emeric Brunba841a12014-04-30 17:05:08 +02003319 int cert_peer = (kw[4] == 'c') ? 1 : 0;
Emeric Brun521a0112012-10-22 12:22:55 +02003320 X509 *crt;
3321 int nid;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003322 struct connection *conn;
Emeric Brun521a0112012-10-22 12:22:55 +02003323
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003324 if (!l4)
Emeric Brun521a0112012-10-22 12:22:55 +02003325 return 0;
3326
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003327 conn = objt_conn(l4->si[0].end);
3328 if (!conn || conn->xprt != &ssl_sock)
3329 return 0;
3330
3331 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brun521a0112012-10-22 12:22:55 +02003332 smp->flags |= SMP_F_MAY_CHANGE;
3333 return 0;
3334 }
3335
Emeric Brunba841a12014-04-30 17:05:08 +02003336 if (cert_peer)
3337 crt = SSL_get_peer_certificate(conn->xprt_ctx);
3338 else
3339 crt = SSL_get_certificate(conn->xprt_ctx);
Emeric Brun521a0112012-10-22 12:22:55 +02003340 if (!crt)
3341 return 0;
3342
3343 nid = OBJ_obj2nid((ASN1_OBJECT *)(crt->cert_info->key->algor->algorithm));
3344
3345 smp->data.str.str = (char *)OBJ_nid2sn(nid);
Emeric Brun9bf3ba22013-10-07 14:31:44 +02003346 if (!smp->data.str.str) {
Emeric Brunba841a12014-04-30 17:05:08 +02003347 /* SSL_get_peer_certificate increase X509 * ref count */
3348 if (cert_peer)
3349 X509_free(crt);
Emeric Brun521a0112012-10-22 12:22:55 +02003350 return 0;
Emeric Brun9bf3ba22013-10-07 14:31:44 +02003351 }
Emeric Brun521a0112012-10-22 12:22:55 +02003352
Thierry FOURNIER7654c9f2013-12-17 00:20:33 +01003353 smp->type = SMP_T_STR;
3354 smp->flags |= SMP_F_CONST;
Emeric Brun521a0112012-10-22 12:22:55 +02003355 smp->data.str.len = strlen(smp->data.str.str);
Emeric Brunba841a12014-04-30 17:05:08 +02003356 if (cert_peer)
3357 X509_free(crt);
Emeric Brun521a0112012-10-22 12:22:55 +02003358
3359 return 1;
3360}
3361
Emeric Brun645ae792014-04-30 14:21:06 +02003362/* boolean, returns true if front conn. transport layer is SSL.
3363 * This function is also usable on backend conn if the fetch keyword 5th
3364 * char is 'b'.
3365 */
Willy Tarreau7875d092012-09-10 08:20:03 +02003366static int
Emeric Brun2525b6b2012-10-18 15:59:43 +02003367smp_fetch_ssl_fc(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
Willy Tarreauef38c392013-07-22 16:29:32 +02003368 const struct arg *args, struct sample *smp, const char *kw)
Willy Tarreau7875d092012-09-10 08:20:03 +02003369{
Emeric Brun645ae792014-04-30 14:21:06 +02003370 int back_conn = (kw[4] == 'b') ? 1 : 0;
3371 struct connection *conn = objt_conn(l4->si[back_conn].end);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003372
Willy Tarreau7875d092012-09-10 08:20:03 +02003373 smp->type = SMP_T_BOOL;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003374 smp->data.uint = (conn && conn->xprt == &ssl_sock);
Willy Tarreau7875d092012-09-10 08:20:03 +02003375 return 1;
3376}
3377
Emeric Brun2525b6b2012-10-18 15:59:43 +02003378/* boolean, returns true if client present a SNI */
Willy Tarreau7875d092012-09-10 08:20:03 +02003379static int
Emeric Brun2525b6b2012-10-18 15:59:43 +02003380smp_fetch_ssl_fc_has_sni(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
Willy Tarreauef38c392013-07-22 16:29:32 +02003381 const struct arg *args, struct sample *smp, const char *kw)
Willy Tarreau7875d092012-09-10 08:20:03 +02003382{
3383#ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003384 struct connection *conn = objt_conn(l4->si[0].end);
3385
Willy Tarreau7875d092012-09-10 08:20:03 +02003386 smp->type = SMP_T_BOOL;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003387 smp->data.uint = (conn && conn->xprt == &ssl_sock) &&
3388 conn->xprt_ctx &&
3389 SSL_get_servername(conn->xprt_ctx, TLSEXT_NAMETYPE_host_name) != NULL;
Willy Tarreau7875d092012-09-10 08:20:03 +02003390 return 1;
3391#else
3392 return 0;
3393#endif
3394}
3395
Emeric Brun645ae792014-04-30 14:21:06 +02003396/* string, returns the used cipher if front conn. transport layer is SSL.
3397 * This function is also usable on backend conn if the fetch keyword 5th
3398 * char is 'b'.
3399 */
Emeric Brun589fcad2012-10-16 14:13:26 +02003400static int
3401smp_fetch_ssl_fc_cipher(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
Willy Tarreauef38c392013-07-22 16:29:32 +02003402 const struct arg *args, struct sample *smp, const char *kw)
Emeric Brun589fcad2012-10-16 14:13:26 +02003403{
Emeric Brun645ae792014-04-30 14:21:06 +02003404 int back_conn = (kw[4] == 'b') ? 1 : 0;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003405 struct connection *conn;
3406
Emeric Brun589fcad2012-10-16 14:13:26 +02003407 smp->flags = 0;
3408
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003409 if (!l4)
3410 return 0;
3411
Emeric Brun645ae792014-04-30 14:21:06 +02003412 conn = objt_conn(l4->si[back_conn].end);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003413 if (!conn || !conn->xprt_ctx || conn->xprt != &ssl_sock)
Emeric Brun589fcad2012-10-16 14:13:26 +02003414 return 0;
3415
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003416 smp->data.str.str = (char *)SSL_get_cipher_name(conn->xprt_ctx);
Emeric Brun589fcad2012-10-16 14:13:26 +02003417 if (!smp->data.str.str)
3418 return 0;
3419
Thierry FOURNIER7654c9f2013-12-17 00:20:33 +01003420 smp->type = SMP_T_STR;
3421 smp->flags |= SMP_F_CONST;
Emeric Brun589fcad2012-10-16 14:13:26 +02003422 smp->data.str.len = strlen(smp->data.str.str);
3423
3424 return 1;
3425}
3426
Emeric Brun645ae792014-04-30 14:21:06 +02003427/* integer, returns the algoritm's keysize if front conn. transport layer
3428 * is SSL.
3429 * This function is also usable on backend conn if the fetch keyword 5th
3430 * char is 'b'.
3431 */
Emeric Brun589fcad2012-10-16 14:13:26 +02003432static int
3433smp_fetch_ssl_fc_alg_keysize(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
Willy Tarreauef38c392013-07-22 16:29:32 +02003434 const struct arg *args, struct sample *smp, const char *kw)
Emeric Brun589fcad2012-10-16 14:13:26 +02003435{
Emeric Brun645ae792014-04-30 14:21:06 +02003436 int back_conn = (kw[4] == 'b') ? 1 : 0;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003437 struct connection *conn;
3438
Emeric Brun589fcad2012-10-16 14:13:26 +02003439 smp->flags = 0;
3440
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003441 if (!l4)
Emeric Brun589fcad2012-10-16 14:13:26 +02003442 return 0;
3443
Emeric Brun645ae792014-04-30 14:21:06 +02003444 conn = objt_conn(l4->si[back_conn].end);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003445 if (!conn || !conn->xprt_ctx || conn->xprt != &ssl_sock)
Emeric Brun589fcad2012-10-16 14:13:26 +02003446 return 0;
3447
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003448 if (!SSL_get_cipher_bits(conn->xprt_ctx, (int *)&smp->data.uint))
3449 return 0;
3450
Emeric Brun589fcad2012-10-16 14:13:26 +02003451 smp->type = SMP_T_UINT;
3452
3453 return 1;
3454}
3455
Emeric Brun645ae792014-04-30 14:21:06 +02003456/* integer, returns the used keysize if front conn. transport layer is SSL.
3457 * This function is also usable on backend conn if the fetch keyword 5th
3458 * char is 'b'.
3459 */
Emeric Brun589fcad2012-10-16 14:13:26 +02003460static int
3461smp_fetch_ssl_fc_use_keysize(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
Willy Tarreauef38c392013-07-22 16:29:32 +02003462 const struct arg *args, struct sample *smp, const char *kw)
Emeric Brun589fcad2012-10-16 14:13:26 +02003463{
Emeric Brun645ae792014-04-30 14:21:06 +02003464 int back_conn = (kw[4] == 'b') ? 1 : 0;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003465 struct connection *conn;
3466
Emeric Brun589fcad2012-10-16 14:13:26 +02003467 smp->flags = 0;
3468
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003469 if (!l4)
Emeric Brun589fcad2012-10-16 14:13:26 +02003470 return 0;
3471
Emeric Brun645ae792014-04-30 14:21:06 +02003472 conn = objt_conn(l4->si[back_conn].end);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003473 if (!conn || !conn->xprt_ctx || conn->xprt != &ssl_sock)
3474 return 0;
3475
3476 smp->data.uint = (unsigned int)SSL_get_cipher_bits(conn->xprt_ctx, NULL);
Emeric Brun589fcad2012-10-16 14:13:26 +02003477 if (!smp->data.uint)
3478 return 0;
3479
3480 smp->type = SMP_T_UINT;
3481
3482 return 1;
3483}
3484
Willy Tarreau6c9a3d52012-10-18 18:57:14 +02003485#ifdef OPENSSL_NPN_NEGOTIATED
Willy Tarreau7875d092012-09-10 08:20:03 +02003486static int
Emeric Brun2525b6b2012-10-18 15:59:43 +02003487smp_fetch_ssl_fc_npn(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
Willy Tarreauef38c392013-07-22 16:29:32 +02003488 const struct arg *args, struct sample *smp, const char *kw)
Willy Tarreaua33c6542012-10-15 13:19:06 +02003489{
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003490 struct connection *conn;
3491
Thierry FOURNIER7654c9f2013-12-17 00:20:33 +01003492 smp->flags = SMP_F_CONST;
3493 smp->type = SMP_T_STR;
Willy Tarreaua33c6542012-10-15 13:19:06 +02003494
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003495 if (!l4)
Willy Tarreaua33c6542012-10-15 13:19:06 +02003496 return 0;
3497
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003498 conn = objt_conn(l4->si[0].end);
3499 if (!conn || !conn->xprt_ctx || conn->xprt != &ssl_sock)
3500 return 0;
3501
Willy Tarreaua33c6542012-10-15 13:19:06 +02003502 smp->data.str.str = NULL;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003503 SSL_get0_next_proto_negotiated(conn->xprt_ctx,
Willy Tarreaua33c6542012-10-15 13:19:06 +02003504 (const unsigned char **)&smp->data.str.str, (unsigned *)&smp->data.str.len);
3505
3506 if (!smp->data.str.str)
3507 return 0;
3508
3509 return 1;
Willy Tarreaua33c6542012-10-15 13:19:06 +02003510}
Willy Tarreau6c9a3d52012-10-18 18:57:14 +02003511#endif
Willy Tarreaua33c6542012-10-15 13:19:06 +02003512
Dirkjan Bussink48f1c4e2014-02-13 12:29:42 +01003513#ifdef TLSEXT_TYPE_application_layer_protocol_negotiation
Willy Tarreauab861d32013-04-02 02:30:41 +02003514static int
3515smp_fetch_ssl_fc_alpn(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
Willy Tarreauef38c392013-07-22 16:29:32 +02003516 const struct arg *args, struct sample *smp, const char *kw)
Willy Tarreauab861d32013-04-02 02:30:41 +02003517{
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003518 struct connection *conn;
3519
Thierry FOURNIER7654c9f2013-12-17 00:20:33 +01003520 smp->flags = SMP_F_CONST;
3521 smp->type = SMP_T_STR;
Willy Tarreauab861d32013-04-02 02:30:41 +02003522
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003523 if (!l4)
3524 return 0;
3525
3526 conn = objt_conn(l4->si[0].end);
3527 if (!conn || !conn->xprt_ctx || conn->xprt != &ssl_sock)
Willy Tarreauab861d32013-04-02 02:30:41 +02003528 return 0;
3529
3530 smp->data.str.str = NULL;
Dirkjan Bussink48f1c4e2014-02-13 12:29:42 +01003531 SSL_get0_alpn_selected(conn->xprt_ctx,
Willy Tarreauab861d32013-04-02 02:30:41 +02003532 (const unsigned char **)&smp->data.str.str, (unsigned *)&smp->data.str.len);
3533
3534 if (!smp->data.str.str)
3535 return 0;
3536
3537 return 1;
3538}
3539#endif
3540
Emeric Brun645ae792014-04-30 14:21:06 +02003541/* string, returns the used protocol if front conn. transport layer is SSL.
3542 * This function is also usable on backend conn if the fetch keyword 5th
3543 * char is 'b'.
3544 */
Willy Tarreaua33c6542012-10-15 13:19:06 +02003545static int
Emeric Brun589fcad2012-10-16 14:13:26 +02003546smp_fetch_ssl_fc_protocol(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
Willy Tarreauef38c392013-07-22 16:29:32 +02003547 const struct arg *args, struct sample *smp, const char *kw)
Emeric Brun589fcad2012-10-16 14:13:26 +02003548{
Emeric Brun645ae792014-04-30 14:21:06 +02003549 int back_conn = (kw[4] == 'b') ? 1 : 0;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003550 struct connection *conn;
3551
Emeric Brun589fcad2012-10-16 14:13:26 +02003552 smp->flags = 0;
3553
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003554 if (!l4)
Emeric Brun589fcad2012-10-16 14:13:26 +02003555 return 0;
3556
Emeric Brun645ae792014-04-30 14:21:06 +02003557 conn = objt_conn(l4->si[back_conn].end);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003558 if (!conn || !conn->xprt_ctx || conn->xprt != &ssl_sock)
3559 return 0;
3560
3561 smp->data.str.str = (char *)SSL_get_version(conn->xprt_ctx);
Emeric Brun589fcad2012-10-16 14:13:26 +02003562 if (!smp->data.str.str)
3563 return 0;
3564
Thierry FOURNIER7654c9f2013-12-17 00:20:33 +01003565 smp->type = SMP_T_STR;
3566 smp->flags = SMP_F_CONST;
Emeric Brun589fcad2012-10-16 14:13:26 +02003567 smp->data.str.len = strlen(smp->data.str.str);
3568
3569 return 1;
3570}
3571
Emeric Brun645ae792014-04-30 14:21:06 +02003572/* binary, returns the SSL session id if front conn. transport layer is SSL.
3573 * This function is also usable on backend conn if the fetch keyword 5th
3574 * char is 'b'.
3575 */
Emeric Brun589fcad2012-10-16 14:13:26 +02003576static int
Emeric Brunfe68f682012-10-16 14:59:28 +02003577smp_fetch_ssl_fc_session_id(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
Willy Tarreauef38c392013-07-22 16:29:32 +02003578 const struct arg *args, struct sample *smp, const char *kw)
Emeric Brunfe68f682012-10-16 14:59:28 +02003579{
3580#if OPENSSL_VERSION_NUMBER > 0x0090800fL
Emeric Brun645ae792014-04-30 14:21:06 +02003581 int back_conn = (kw[4] == 'b') ? 1 : 0;
Emeric Brunfe68f682012-10-16 14:59:28 +02003582 SSL_SESSION *sess;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003583 struct connection *conn;
Emeric Brunfe68f682012-10-16 14:59:28 +02003584
Thierry FOURNIER7654c9f2013-12-17 00:20:33 +01003585 smp->flags = SMP_F_CONST;
3586 smp->type = SMP_T_BIN;
Emeric Brunfe68f682012-10-16 14:59:28 +02003587
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003588 if (!l4)
Emeric Brunfe68f682012-10-16 14:59:28 +02003589 return 0;
3590
Emeric Brun645ae792014-04-30 14:21:06 +02003591 conn = objt_conn(l4->si[back_conn].end);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003592 if (!conn || !conn->xprt_ctx || conn->xprt != &ssl_sock)
3593 return 0;
3594
3595 sess = SSL_get_session(conn->xprt_ctx);
Emeric Brunfe68f682012-10-16 14:59:28 +02003596 if (!sess)
3597 return 0;
3598
3599 smp->data.str.str = (char *)SSL_SESSION_get_id(sess, (unsigned int *)&smp->data.str.len);
3600 if (!smp->data.str.str || !&smp->data.str.len)
3601 return 0;
3602
3603 return 1;
3604#else
3605 return 0;
3606#endif
3607}
3608
3609static int
Emeric Brun2525b6b2012-10-18 15:59:43 +02003610smp_fetch_ssl_fc_sni(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
Willy Tarreauef38c392013-07-22 16:29:32 +02003611 const struct arg *args, struct sample *smp, const char *kw)
Willy Tarreau7875d092012-09-10 08:20:03 +02003612{
3613#ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003614 struct connection *conn;
3615
Thierry FOURNIER7654c9f2013-12-17 00:20:33 +01003616 smp->flags = SMP_F_CONST;
3617 smp->type = SMP_T_STR;
Willy Tarreau7875d092012-09-10 08:20:03 +02003618
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003619 if (!l4)
Willy Tarreau7875d092012-09-10 08:20:03 +02003620 return 0;
3621
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003622 conn = objt_conn(l4->si[0].end);
3623 if (!conn || !conn->xprt_ctx || conn->xprt != &ssl_sock)
3624 return 0;
3625
3626 smp->data.str.str = (char *)SSL_get_servername(conn->xprt_ctx, TLSEXT_NAMETYPE_host_name);
Willy Tarreau3e394c92012-09-14 23:56:58 +02003627 if (!smp->data.str.str)
3628 return 0;
3629
Willy Tarreau7875d092012-09-10 08:20:03 +02003630 smp->data.str.len = strlen(smp->data.str.str);
3631 return 1;
3632#else
3633 return 0;
3634#endif
3635}
3636
David Sc1ad52e2014-04-08 18:48:47 -04003637static int
3638smp_fetch_ssl_fc_unique_id(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
3639 const struct arg *args, struct sample *smp, const char *kw)
3640{
3641#if OPENSSL_VERSION_NUMBER > 0x0090800fL
Emeric Brun645ae792014-04-30 14:21:06 +02003642 int back_conn = (kw[4] == 'b') ? 1 : 0;
David Sc1ad52e2014-04-08 18:48:47 -04003643 struct connection *conn;
3644 int finished_len;
David Sc1ad52e2014-04-08 18:48:47 -04003645 struct chunk *finished_trash;
David Sc1ad52e2014-04-08 18:48:47 -04003646
3647 smp->flags = 0;
3648
3649 if (!l4)
3650 return 0;
3651
Emeric Brun645ae792014-04-30 14:21:06 +02003652 conn = objt_conn(l4->si[back_conn].end);
David Sc1ad52e2014-04-08 18:48:47 -04003653 if (!conn || !conn->xprt_ctx || conn->xprt != &ssl_sock)
3654 return 0;
3655
3656 if (!(conn->flags & CO_FL_CONNECTED)) {
3657 smp->flags |= SMP_F_MAY_CHANGE;
3658 return 0;
3659 }
3660
3661 finished_trash = get_trash_chunk();
3662 if (!SSL_session_reused(conn->xprt_ctx))
3663 finished_len = SSL_get_peer_finished(conn->xprt_ctx, finished_trash->str, finished_trash->size);
3664 else
3665 finished_len = SSL_get_finished(conn->xprt_ctx, finished_trash->str, finished_trash->size);
3666
3667 if (!finished_len)
3668 return 0;
3669
Emeric Brunb73a9b02014-04-30 18:49:19 +02003670 finished_trash->len = finished_len;
3671 smp->data.str = *finished_trash;
3672 smp->type = SMP_T_BIN;
David Sc1ad52e2014-04-08 18:48:47 -04003673
3674 return 1;
3675#else
3676 return 0;
3677#endif
3678}
3679
Emeric Brun2525b6b2012-10-18 15:59:43 +02003680/* integer, returns the first verify error in CA chain of client certificate chain. */
Emeric Brunf282a812012-09-21 15:27:54 +02003681static int
Emeric Brun2525b6b2012-10-18 15:59:43 +02003682smp_fetch_ssl_c_ca_err(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
Willy Tarreauef38c392013-07-22 16:29:32 +02003683 const struct arg *args, struct sample *smp, const char *kw)
Emeric Brunf282a812012-09-21 15:27:54 +02003684{
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003685 struct connection *conn;
3686
3687 if (!l4)
Emeric Brunf282a812012-09-21 15:27:54 +02003688 return 0;
3689
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003690 conn = objt_conn(l4->si[0].end);
3691 if (!conn || conn->xprt != &ssl_sock)
3692 return 0;
3693
3694 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brunf282a812012-09-21 15:27:54 +02003695 smp->flags = SMP_F_MAY_CHANGE;
3696 return 0;
3697 }
3698
3699 smp->type = SMP_T_UINT;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003700 smp->data.uint = (unsigned int)SSL_SOCK_ST_TO_CA_ERROR(conn->xprt_st);
Emeric Brunf282a812012-09-21 15:27:54 +02003701 smp->flags = 0;
3702
3703 return 1;
3704}
3705
Emeric Brun2525b6b2012-10-18 15:59:43 +02003706/* integer, returns the depth of the first verify error in CA chain of client certificate chain. */
Emeric Brunf282a812012-09-21 15:27:54 +02003707static int
Emeric Brun2525b6b2012-10-18 15:59:43 +02003708smp_fetch_ssl_c_ca_err_depth(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
Willy Tarreauef38c392013-07-22 16:29:32 +02003709 const struct arg *args, struct sample *smp, const char *kw)
Emeric Brunf282a812012-09-21 15:27:54 +02003710{
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003711 struct connection *conn;
3712
3713 if (!l4)
3714 return 0;
3715
3716 conn = objt_conn(l4->si[0].end);
3717 if (!conn || conn->xprt != &ssl_sock)
Emeric Brunf282a812012-09-21 15:27:54 +02003718 return 0;
3719
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003720 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brunf282a812012-09-21 15:27:54 +02003721 smp->flags = SMP_F_MAY_CHANGE;
3722 return 0;
3723 }
3724
3725 smp->type = SMP_T_UINT;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003726 smp->data.uint = (unsigned int)SSL_SOCK_ST_TO_CAEDEPTH(conn->xprt_st);
Emeric Brunf282a812012-09-21 15:27:54 +02003727 smp->flags = 0;
3728
3729 return 1;
3730}
3731
Emeric Brun2525b6b2012-10-18 15:59:43 +02003732/* integer, returns the first verify error on client certificate */
Emeric Brunf282a812012-09-21 15:27:54 +02003733static int
Emeric Brun2525b6b2012-10-18 15:59:43 +02003734smp_fetch_ssl_c_err(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
Willy Tarreauef38c392013-07-22 16:29:32 +02003735 const struct arg *args, struct sample *smp, const char *kw)
Emeric Brunf282a812012-09-21 15:27:54 +02003736{
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003737 struct connection *conn;
3738
3739 if (!l4)
Emeric Brunf282a812012-09-21 15:27:54 +02003740 return 0;
3741
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003742 conn = objt_conn(l4->si[0].end);
3743 if (!conn || conn->xprt != &ssl_sock)
3744 return 0;
3745
3746 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brunf282a812012-09-21 15:27:54 +02003747 smp->flags = SMP_F_MAY_CHANGE;
3748 return 0;
3749 }
3750
3751 smp->type = SMP_T_UINT;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003752 smp->data.uint = (unsigned int)SSL_SOCK_ST_TO_CRTERROR(conn->xprt_st);
Emeric Brunf282a812012-09-21 15:27:54 +02003753 smp->flags = 0;
3754
3755 return 1;
3756}
3757
Emeric Brun2525b6b2012-10-18 15:59:43 +02003758/* integer, returns the verify result on client cert */
Emeric Brunbaf8ffb2012-09-21 15:27:20 +02003759static int
Emeric Brun2525b6b2012-10-18 15:59:43 +02003760smp_fetch_ssl_c_verify(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
Willy Tarreauef38c392013-07-22 16:29:32 +02003761 const struct arg *args, struct sample *smp, const char *kw)
Emeric Brunbaf8ffb2012-09-21 15:27:20 +02003762{
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003763 struct connection *conn;
3764
3765 if (!l4)
Emeric Brunbaf8ffb2012-09-21 15:27:20 +02003766 return 0;
3767
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003768 conn = objt_conn(l4->si[0].end);
3769 if (!conn || conn->xprt != &ssl_sock)
3770 return 0;
3771
3772 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brunbaf8ffb2012-09-21 15:27:20 +02003773 smp->flags = SMP_F_MAY_CHANGE;
3774 return 0;
3775 }
3776
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003777 if (!conn->xprt_ctx)
Emeric Brunbaf8ffb2012-09-21 15:27:20 +02003778 return 0;
3779
3780 smp->type = SMP_T_UINT;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003781 smp->data.uint = (unsigned int)SSL_get_verify_result(conn->xprt_ctx);
Emeric Brunbaf8ffb2012-09-21 15:27:20 +02003782 smp->flags = 0;
3783
3784 return 1;
3785}
3786
Emeric Brunfb510ea2012-10-05 12:00:26 +02003787/* parse the "ca-file" bind keyword */
3788static 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 +02003789{
3790 if (!*args[cur_arg + 1]) {
3791 if (err)
3792 memprintf(err, "'%s' : missing CAfile path", args[cur_arg]);
3793 return ERR_ALERT | ERR_FATAL;
3794 }
3795
Emeric Brunef42d922012-10-11 16:11:36 +02003796 if ((*args[cur_arg + 1] != '/') && global.ca_base)
3797 memprintf(&conf->ca_file, "%s/%s", global.ca_base, args[cur_arg + 1]);
3798 else
3799 memprintf(&conf->ca_file, "%s", args[cur_arg + 1]);
Emeric Brunc8e8d122012-10-02 18:42:10 +02003800
Emeric Brund94b3fe2012-09-20 18:23:56 +02003801 return 0;
3802}
3803
Willy Tarreau79eeafa2012-09-14 07:53:05 +02003804/* parse the "ciphers" bind keyword */
Willy Tarreau4348fad2012-09-20 16:48:07 +02003805static 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 +02003806{
3807 if (!*args[cur_arg + 1]) {
Willy Tarreaueb6cead2012-09-20 19:43:14 +02003808 memprintf(err, "'%s' : missing cipher suite", args[cur_arg]);
Willy Tarreau79eeafa2012-09-14 07:53:05 +02003809 return ERR_ALERT | ERR_FATAL;
3810 }
3811
Emeric Brun76d88952012-10-05 15:47:31 +02003812 free(conf->ciphers);
Willy Tarreau4348fad2012-09-20 16:48:07 +02003813 conf->ciphers = strdup(args[cur_arg + 1]);
Willy Tarreau79eeafa2012-09-14 07:53:05 +02003814 return 0;
3815}
3816
3817/* parse the "crt" bind keyword */
Willy Tarreau4348fad2012-09-20 16:48:07 +02003818static 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 +02003819{
Willy Tarreau38011032013-08-13 16:59:39 +02003820 char path[MAXPATHLEN];
Willy Tarreaub75d6922014-04-14 18:05:41 +02003821
Willy Tarreau79eeafa2012-09-14 07:53:05 +02003822 if (!*args[cur_arg + 1]) {
Willy Tarreaueb6cead2012-09-20 19:43:14 +02003823 memprintf(err, "'%s' : missing certificate location", args[cur_arg]);
Willy Tarreau79eeafa2012-09-14 07:53:05 +02003824 return ERR_ALERT | ERR_FATAL;
3825 }
3826
Emeric Brunc8e8d122012-10-02 18:42:10 +02003827 if ((*args[cur_arg + 1] != '/' ) && global.crt_base) {
Willy Tarreau38011032013-08-13 16:59:39 +02003828 if ((strlen(global.crt_base) + 1 + strlen(args[cur_arg + 1]) + 1) > MAXPATHLEN) {
Emeric Brunc8e8d122012-10-02 18:42:10 +02003829 memprintf(err, "'%s' : path too long", args[cur_arg]);
3830 return ERR_ALERT | ERR_FATAL;
3831 }
Willy Tarreaub75d6922014-04-14 18:05:41 +02003832 snprintf(path, sizeof(path), "%s/%s", global.crt_base, args[cur_arg + 1]);
Emeric Brunc8e8d122012-10-02 18:42:10 +02003833 if (ssl_sock_load_cert(path, conf, px, err) > 0)
3834 return ERR_ALERT | ERR_FATAL;
3835
3836 return 0;
3837 }
3838
Willy Tarreau4348fad2012-09-20 16:48:07 +02003839 if (ssl_sock_load_cert(args[cur_arg + 1], conf, px, err) > 0)
Willy Tarreau79eeafa2012-09-14 07:53:05 +02003840 return ERR_ALERT | ERR_FATAL;
Emeric Brund94b3fe2012-09-20 18:23:56 +02003841
3842 return 0;
3843}
3844
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01003845/* parse the "crt-list" bind keyword */
3846static int bind_parse_crt_list(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
3847{
3848 if (!*args[cur_arg + 1]) {
3849 memprintf(err, "'%s' : missing certificate location", args[cur_arg]);
3850 return ERR_ALERT | ERR_FATAL;
3851 }
3852
Willy Tarreauad1731d2013-04-02 17:35:58 +02003853 if (ssl_sock_load_cert_list_file(args[cur_arg + 1], conf, px, err) > 0) {
3854 memprintf(err, "'%s' : %s", args[cur_arg], *err);
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01003855 return ERR_ALERT | ERR_FATAL;
Willy Tarreauad1731d2013-04-02 17:35:58 +02003856 }
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01003857
3858 return 0;
3859}
3860
Emeric Brunfb510ea2012-10-05 12:00:26 +02003861/* parse the "crl-file" bind keyword */
3862static 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 +02003863{
Emeric Brun051cdab2012-10-02 19:25:50 +02003864#ifndef X509_V_FLAG_CRL_CHECK
3865 if (err)
3866 memprintf(err, "'%s' : library does not support CRL verify", args[cur_arg]);
3867 return ERR_ALERT | ERR_FATAL;
3868#else
Emeric Brund94b3fe2012-09-20 18:23:56 +02003869 if (!*args[cur_arg + 1]) {
3870 if (err)
3871 memprintf(err, "'%s' : missing CRLfile path", args[cur_arg]);
3872 return ERR_ALERT | ERR_FATAL;
3873 }
Emeric Brun2b58d042012-09-20 17:10:03 +02003874
Emeric Brunef42d922012-10-11 16:11:36 +02003875 if ((*args[cur_arg + 1] != '/') && global.ca_base)
3876 memprintf(&conf->crl_file, "%s/%s", global.ca_base, args[cur_arg + 1]);
3877 else
3878 memprintf(&conf->crl_file, "%s", args[cur_arg + 1]);
Emeric Brunc8e8d122012-10-02 18:42:10 +02003879
Emeric Brun2b58d042012-09-20 17:10:03 +02003880 return 0;
Emeric Brun051cdab2012-10-02 19:25:50 +02003881#endif
Emeric Brun2b58d042012-09-20 17:10:03 +02003882}
3883
3884/* parse the "ecdhe" bind keyword keywords */
3885static int bind_parse_ecdhe(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
3886{
3887#if OPENSSL_VERSION_NUMBER < 0x0090800fL
3888 if (err)
3889 memprintf(err, "'%s' : library does not support elliptic curve Diffie-Hellman (too old)", args[cur_arg]);
3890 return ERR_ALERT | ERR_FATAL;
3891#elif defined(OPENSSL_NO_ECDH)
3892 if (err)
3893 memprintf(err, "'%s' : library does not support elliptic curve Diffie-Hellman (disabled via OPENSSL_NO_ECDH)", args[cur_arg]);
3894 return ERR_ALERT | ERR_FATAL;
3895#else
3896 if (!*args[cur_arg + 1]) {
3897 if (err)
3898 memprintf(err, "'%s' : missing named curve", args[cur_arg]);
3899 return ERR_ALERT | ERR_FATAL;
3900 }
3901
3902 conf->ecdhe = strdup(args[cur_arg + 1]);
Willy Tarreau79eeafa2012-09-14 07:53:05 +02003903
3904 return 0;
Emeric Brun2b58d042012-09-20 17:10:03 +02003905#endif
Willy Tarreau79eeafa2012-09-14 07:53:05 +02003906}
3907
Emeric Brun81c00f02012-09-21 14:31:21 +02003908/* parse the "crt_ignerr" and "ca_ignerr" bind keywords */
3909static int bind_parse_ignore_err(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
3910{
3911 int code;
3912 char *p = args[cur_arg + 1];
3913 unsigned long long *ignerr = &conf->crt_ignerr;
3914
3915 if (!*p) {
3916 if (err)
3917 memprintf(err, "'%s' : missing error IDs list", args[cur_arg]);
3918 return ERR_ALERT | ERR_FATAL;
3919 }
3920
3921 if (strcmp(args[cur_arg], "ca-ignore-err") == 0)
3922 ignerr = &conf->ca_ignerr;
3923
3924 if (strcmp(p, "all") == 0) {
3925 *ignerr = ~0ULL;
3926 return 0;
3927 }
3928
3929 while (p) {
3930 code = atoi(p);
3931 if ((code <= 0) || (code > 63)) {
3932 if (err)
3933 memprintf(err, "'%s' : ID '%d' out of range (1..63) in error IDs list '%s'",
3934 args[cur_arg], code, args[cur_arg + 1]);
3935 return ERR_ALERT | ERR_FATAL;
3936 }
3937 *ignerr |= 1ULL << code;
3938 p = strchr(p, ',');
3939 if (p)
3940 p++;
3941 }
3942
Emeric Brun2cb7ae52012-10-05 14:14:21 +02003943 return 0;
3944}
3945
3946/* parse the "force-sslv3" bind keyword */
3947static int bind_parse_force_sslv3(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
3948{
3949 conf->ssl_options |= BC_SSL_O_USE_SSLV3;
3950 return 0;
3951}
3952
3953/* parse the "force-tlsv10" bind keyword */
3954static int bind_parse_force_tlsv10(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
3955{
3956 conf->ssl_options |= BC_SSL_O_USE_TLSV10;
Emeric Brun2d0c4822012-10-02 13:45:20 +02003957 return 0;
3958}
3959
Emeric Brun2cb7ae52012-10-05 14:14:21 +02003960/* parse the "force-tlsv11" bind keyword */
3961static int bind_parse_force_tlsv11(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
3962{
3963#if SSL_OP_NO_TLSv1_1
3964 conf->ssl_options |= BC_SSL_O_USE_TLSV11;
3965 return 0;
3966#else
3967 if (err)
3968 memprintf(err, "'%s' : library does not support protocol TLSv1.1", args[cur_arg]);
3969 return ERR_ALERT | ERR_FATAL;
3970#endif
3971}
3972
3973/* parse the "force-tlsv12" bind keyword */
3974static int bind_parse_force_tlsv12(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
3975{
3976#if SSL_OP_NO_TLSv1_2
3977 conf->ssl_options |= BC_SSL_O_USE_TLSV12;
3978 return 0;
3979#else
3980 if (err)
3981 memprintf(err, "'%s' : library does not support protocol TLSv1.2", args[cur_arg]);
3982 return ERR_ALERT | ERR_FATAL;
3983#endif
3984}
3985
3986
Emeric Brun2d0c4822012-10-02 13:45:20 +02003987/* parse the "no-tls-tickets" bind keyword */
3988static int bind_parse_no_tls_tickets(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
3989{
Emeric Brun89675492012-10-05 13:48:26 +02003990 conf->ssl_options |= BC_SSL_O_NO_TLS_TICKETS;
Emeric Brun81c00f02012-09-21 14:31:21 +02003991 return 0;
3992}
3993
Emeric Brun2d0c4822012-10-02 13:45:20 +02003994
Emeric Brun9b3009b2012-10-05 11:55:06 +02003995/* parse the "no-sslv3" bind keyword */
3996static 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 +02003997{
Emeric Brun89675492012-10-05 13:48:26 +02003998 conf->ssl_options |= BC_SSL_O_NO_SSLV3;
Willy Tarreau79eeafa2012-09-14 07:53:05 +02003999 return 0;
4000}
4001
Emeric Brun9b3009b2012-10-05 11:55:06 +02004002/* parse the "no-tlsv10" bind keyword */
4003static 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 +02004004{
Emeric Brun89675492012-10-05 13:48:26 +02004005 conf->ssl_options |= BC_SSL_O_NO_TLSV10;
Emeric Brunc0ff4922012-09-28 19:37:02 +02004006 return 0;
4007}
4008
Emeric Brun9b3009b2012-10-05 11:55:06 +02004009/* parse the "no-tlsv11" bind keyword */
4010static 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 +02004011{
Emeric Brun89675492012-10-05 13:48:26 +02004012 conf->ssl_options |= BC_SSL_O_NO_TLSV11;
Emeric Brunc0ff4922012-09-28 19:37:02 +02004013 return 0;
4014}
4015
Emeric Brun9b3009b2012-10-05 11:55:06 +02004016/* parse the "no-tlsv12" bind keyword */
4017static 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 +02004018{
Emeric Brun89675492012-10-05 13:48:26 +02004019 conf->ssl_options |= BC_SSL_O_NO_TLSV12;
Willy Tarreau79eeafa2012-09-14 07:53:05 +02004020 return 0;
4021}
4022
Willy Tarreau6c9a3d52012-10-18 18:57:14 +02004023/* parse the "npn" bind keyword */
4024static int bind_parse_npn(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
4025{
4026#ifdef OPENSSL_NPN_NEGOTIATED
4027 char *p1, *p2;
4028
4029 if (!*args[cur_arg + 1]) {
4030 memprintf(err, "'%s' : missing the comma-delimited NPN protocol suite", args[cur_arg]);
4031 return ERR_ALERT | ERR_FATAL;
4032 }
4033
4034 free(conf->npn_str);
4035
4036 /* the NPN string is built as a suite of (<len> <name>)* */
4037 conf->npn_len = strlen(args[cur_arg + 1]) + 1;
4038 conf->npn_str = calloc(1, conf->npn_len);
4039 memcpy(conf->npn_str + 1, args[cur_arg + 1], conf->npn_len);
4040
4041 /* replace commas with the name length */
4042 p1 = conf->npn_str;
4043 p2 = p1 + 1;
4044 while (1) {
4045 p2 = memchr(p1 + 1, ',', conf->npn_str + conf->npn_len - (p1 + 1));
4046 if (!p2)
4047 p2 = p1 + 1 + strlen(p1 + 1);
4048
4049 if (p2 - (p1 + 1) > 255) {
4050 *p2 = '\0';
4051 memprintf(err, "'%s' : NPN protocol name too long : '%s'", args[cur_arg], p1 + 1);
4052 return ERR_ALERT | ERR_FATAL;
4053 }
4054
4055 *p1 = p2 - (p1 + 1);
4056 p1 = p2;
4057
4058 if (!*p2)
4059 break;
4060
4061 *(p2++) = '\0';
4062 }
4063 return 0;
4064#else
4065 if (err)
4066 memprintf(err, "'%s' : library does not support TLS NPN extension", args[cur_arg]);
4067 return ERR_ALERT | ERR_FATAL;
4068#endif
4069}
4070
Willy Tarreauab861d32013-04-02 02:30:41 +02004071/* parse the "alpn" bind keyword */
4072static int bind_parse_alpn(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
4073{
Dirkjan Bussink48f1c4e2014-02-13 12:29:42 +01004074#ifdef TLSEXT_TYPE_application_layer_protocol_negotiation
Willy Tarreauab861d32013-04-02 02:30:41 +02004075 char *p1, *p2;
4076
4077 if (!*args[cur_arg + 1]) {
4078 memprintf(err, "'%s' : missing the comma-delimited ALPN protocol suite", args[cur_arg]);
4079 return ERR_ALERT | ERR_FATAL;
4080 }
4081
4082 free(conf->alpn_str);
4083
4084 /* the ALPN string is built as a suite of (<len> <name>)* */
4085 conf->alpn_len = strlen(args[cur_arg + 1]) + 1;
4086 conf->alpn_str = calloc(1, conf->alpn_len);
4087 memcpy(conf->alpn_str + 1, args[cur_arg + 1], conf->alpn_len);
4088
4089 /* replace commas with the name length */
4090 p1 = conf->alpn_str;
4091 p2 = p1 + 1;
4092 while (1) {
4093 p2 = memchr(p1 + 1, ',', conf->alpn_str + conf->alpn_len - (p1 + 1));
4094 if (!p2)
4095 p2 = p1 + 1 + strlen(p1 + 1);
4096
4097 if (p2 - (p1 + 1) > 255) {
4098 *p2 = '\0';
4099 memprintf(err, "'%s' : ALPN protocol name too long : '%s'", args[cur_arg], p1 + 1);
4100 return ERR_ALERT | ERR_FATAL;
4101 }
4102
4103 *p1 = p2 - (p1 + 1);
4104 p1 = p2;
4105
4106 if (!*p2)
4107 break;
4108
4109 *(p2++) = '\0';
4110 }
4111 return 0;
4112#else
4113 if (err)
4114 memprintf(err, "'%s' : library does not support TLS ALPN extension", args[cur_arg]);
4115 return ERR_ALERT | ERR_FATAL;
4116#endif
4117}
4118
Willy Tarreau79eeafa2012-09-14 07:53:05 +02004119/* parse the "ssl" bind keyword */
Willy Tarreau4348fad2012-09-20 16:48:07 +02004120static 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 +02004121{
Willy Tarreau81796be2012-09-22 19:11:47 +02004122 struct listener *l;
4123
Willy Tarreau4348fad2012-09-20 16:48:07 +02004124 conf->is_ssl = 1;
Emeric Brun76d88952012-10-05 15:47:31 +02004125
4126 if (global.listen_default_ciphers && !conf->ciphers)
4127 conf->ciphers = strdup(global.listen_default_ciphers);
Emeric Brun2c86cbf2014-10-30 15:56:50 +01004128 conf->ssl_options |= global.listen_default_ssloptions;
Emeric Brun76d88952012-10-05 15:47:31 +02004129
Willy Tarreau81796be2012-09-22 19:11:47 +02004130 list_for_each_entry(l, &conf->listeners, by_bind)
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02004131 l->xprt = &ssl_sock;
Willy Tarreau81796be2012-09-22 19:11:47 +02004132
Willy Tarreau79eeafa2012-09-14 07:53:05 +02004133 return 0;
4134}
4135
Emmanuel Hocdet65623372013-01-24 17:17:15 +01004136/* parse the "strict-sni" bind keyword */
4137static int bind_parse_strict_sni(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
4138{
4139 conf->strict_sni = 1;
4140 return 0;
4141}
4142
Emeric Brund94b3fe2012-09-20 18:23:56 +02004143/* parse the "verify" bind keyword */
4144static int bind_parse_verify(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
4145{
4146 if (!*args[cur_arg + 1]) {
4147 if (err)
4148 memprintf(err, "'%s' : missing verify method", args[cur_arg]);
4149 return ERR_ALERT | ERR_FATAL;
4150 }
4151
4152 if (strcmp(args[cur_arg + 1], "none") == 0)
Emeric Brun850efd52014-01-29 12:24:34 +01004153 conf->verify = SSL_SOCK_VERIFY_NONE;
Emeric Brund94b3fe2012-09-20 18:23:56 +02004154 else if (strcmp(args[cur_arg + 1], "optional") == 0)
Emeric Brun850efd52014-01-29 12:24:34 +01004155 conf->verify = SSL_SOCK_VERIFY_OPTIONAL;
Emeric Brund94b3fe2012-09-20 18:23:56 +02004156 else if (strcmp(args[cur_arg + 1], "required") == 0)
Emeric Brun850efd52014-01-29 12:24:34 +01004157 conf->verify = SSL_SOCK_VERIFY_REQUIRED;
Emeric Brund94b3fe2012-09-20 18:23:56 +02004158 else {
4159 if (err)
4160 memprintf(err, "'%s' : unknown verify method '%s', only 'none', 'optional', and 'required' are supported\n",
4161 args[cur_arg], args[cur_arg + 1]);
4162 return ERR_ALERT | ERR_FATAL;
4163 }
4164
4165 return 0;
4166}
4167
Willy Tarreau92faadf2012-10-10 23:04:25 +02004168/************** "server" keywords ****************/
4169
Emeric Brunef42d922012-10-11 16:11:36 +02004170/* parse the "ca-file" server keyword */
4171static int srv_parse_ca_file(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
4172{
4173 if (!*args[*cur_arg + 1]) {
4174 if (err)
4175 memprintf(err, "'%s' : missing CAfile path", args[*cur_arg]);
4176 return ERR_ALERT | ERR_FATAL;
4177 }
4178
4179 if ((*args[*cur_arg + 1] != '/') && global.ca_base)
4180 memprintf(&newsrv->ssl_ctx.ca_file, "%s/%s", global.ca_base, args[*cur_arg + 1]);
4181 else
4182 memprintf(&newsrv->ssl_ctx.ca_file, "%s", args[*cur_arg + 1]);
4183
4184 return 0;
4185}
4186
Willy Tarreau92faadf2012-10-10 23:04:25 +02004187/* parse the "check-ssl" server keyword */
4188static int srv_parse_check_ssl(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
4189{
4190 newsrv->check.use_ssl = 1;
4191 if (global.connect_default_ciphers && !newsrv->ssl_ctx.ciphers)
4192 newsrv->ssl_ctx.ciphers = strdup(global.connect_default_ciphers);
Emeric Brun2c86cbf2014-10-30 15:56:50 +01004193 newsrv->ssl_ctx.options |= global.connect_default_ssloptions;
Willy Tarreau92faadf2012-10-10 23:04:25 +02004194 return 0;
4195}
4196
4197/* parse the "ciphers" server keyword */
4198static int srv_parse_ciphers(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
4199{
4200 if (!*args[*cur_arg + 1]) {
4201 memprintf(err, "'%s' : missing cipher suite", args[*cur_arg]);
4202 return ERR_ALERT | ERR_FATAL;
4203 }
4204
4205 free(newsrv->ssl_ctx.ciphers);
4206 newsrv->ssl_ctx.ciphers = strdup(args[*cur_arg + 1]);
4207 return 0;
4208}
4209
Emeric Brunef42d922012-10-11 16:11:36 +02004210/* parse the "crl-file" server keyword */
4211static int srv_parse_crl_file(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
4212{
4213#ifndef X509_V_FLAG_CRL_CHECK
4214 if (err)
4215 memprintf(err, "'%s' : library does not support CRL verify", args[*cur_arg]);
4216 return ERR_ALERT | ERR_FATAL;
4217#else
4218 if (!*args[*cur_arg + 1]) {
4219 if (err)
4220 memprintf(err, "'%s' : missing CRLfile path", args[*cur_arg]);
4221 return ERR_ALERT | ERR_FATAL;
4222 }
4223
4224 if ((*args[*cur_arg + 1] != '/') && global.ca_base)
4225 memprintf(&newsrv->ssl_ctx.crl_file, "%s/%s", global.ca_base, args[*cur_arg + 1]);
4226 else
4227 memprintf(&newsrv->ssl_ctx.crl_file, "%s", args[*cur_arg + 1]);
4228
4229 return 0;
4230#endif
4231}
4232
Emeric Bruna7aa3092012-10-26 12:58:00 +02004233/* parse the "crt" server keyword */
4234static int srv_parse_crt(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
4235{
4236 if (!*args[*cur_arg + 1]) {
4237 if (err)
4238 memprintf(err, "'%s' : missing certificate file path", args[*cur_arg]);
4239 return ERR_ALERT | ERR_FATAL;
4240 }
4241
4242 if ((*args[*cur_arg + 1] != '/') && global.crt_base)
4243 memprintf(&newsrv->ssl_ctx.client_crt, "%s/%s", global.ca_base, args[*cur_arg + 1]);
4244 else
4245 memprintf(&newsrv->ssl_ctx.client_crt, "%s", args[*cur_arg + 1]);
4246
4247 return 0;
4248}
Emeric Brunef42d922012-10-11 16:11:36 +02004249
Willy Tarreau92faadf2012-10-10 23:04:25 +02004250/* parse the "force-sslv3" server keyword */
4251static int srv_parse_force_sslv3(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
4252{
4253 newsrv->ssl_ctx.options |= SRV_SSL_O_USE_SSLV3;
4254 return 0;
4255}
4256
4257/* parse the "force-tlsv10" server keyword */
4258static int srv_parse_force_tlsv10(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
4259{
4260 newsrv->ssl_ctx.options |= SRV_SSL_O_USE_TLSV10;
4261 return 0;
4262}
4263
4264/* parse the "force-tlsv11" server keyword */
4265static int srv_parse_force_tlsv11(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
4266{
4267#if SSL_OP_NO_TLSv1_1
4268 newsrv->ssl_ctx.options |= SRV_SSL_O_USE_TLSV11;
4269 return 0;
4270#else
4271 if (err)
4272 memprintf(err, "'%s' : library does not support protocol TLSv1.1", args[*cur_arg]);
4273 return ERR_ALERT | ERR_FATAL;
4274#endif
4275}
4276
4277/* parse the "force-tlsv12" server keyword */
4278static int srv_parse_force_tlsv12(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
4279{
4280#if SSL_OP_NO_TLSv1_2
4281 newsrv->ssl_ctx.options |= SRV_SSL_O_USE_TLSV12;
4282 return 0;
4283#else
4284 if (err)
4285 memprintf(err, "'%s' : library does not support protocol TLSv1.2", args[*cur_arg]);
4286 return ERR_ALERT | ERR_FATAL;
4287#endif
4288}
4289
4290/* parse the "no-sslv3" server keyword */
4291static int srv_parse_no_sslv3(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
4292{
4293 newsrv->ssl_ctx.options |= SRV_SSL_O_NO_SSLV3;
4294 return 0;
4295}
4296
4297/* parse the "no-tlsv10" server keyword */
4298static int srv_parse_no_tlsv10(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
4299{
4300 newsrv->ssl_ctx.options |= SRV_SSL_O_NO_TLSV10;
4301 return 0;
4302}
4303
4304/* parse the "no-tlsv11" server keyword */
4305static int srv_parse_no_tlsv11(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
4306{
4307 newsrv->ssl_ctx.options |= SRV_SSL_O_NO_TLSV11;
4308 return 0;
4309}
4310
4311/* parse the "no-tlsv12" server keyword */
4312static int srv_parse_no_tlsv12(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
4313{
4314 newsrv->ssl_ctx.options |= SRV_SSL_O_NO_TLSV12;
4315 return 0;
4316}
4317
Emeric Brunf9c5c472012-10-11 15:28:34 +02004318/* parse the "no-tls-tickets" server keyword */
4319static int srv_parse_no_tls_tickets(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
4320{
4321 newsrv->ssl_ctx.options |= SRV_SSL_O_NO_TLS_TICKETS;
4322 return 0;
4323}
David Safb76832014-05-08 23:42:08 -04004324/* parse the "send-proxy-v2-ssl" server keyword */
4325static int srv_parse_send_proxy_ssl(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
4326{
4327 newsrv->pp_opts |= SRV_PP_V2;
4328 newsrv->pp_opts |= SRV_PP_V2_SSL;
4329 return 0;
4330}
4331
4332/* parse the "send-proxy-v2-ssl-cn" server keyword */
4333static int srv_parse_send_proxy_cn(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
4334{
4335 newsrv->pp_opts |= SRV_PP_V2;
4336 newsrv->pp_opts |= SRV_PP_V2_SSL;
4337 newsrv->pp_opts |= SRV_PP_V2_SSL_CN;
4338 return 0;
4339}
Emeric Brunf9c5c472012-10-11 15:28:34 +02004340
Willy Tarreau92faadf2012-10-10 23:04:25 +02004341/* parse the "ssl" server keyword */
4342static int srv_parse_ssl(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
4343{
4344 newsrv->use_ssl = 1;
4345 if (global.connect_default_ciphers && !newsrv->ssl_ctx.ciphers)
4346 newsrv->ssl_ctx.ciphers = strdup(global.connect_default_ciphers);
4347 return 0;
4348}
4349
Emeric Brunef42d922012-10-11 16:11:36 +02004350/* parse the "verify" server keyword */
4351static int srv_parse_verify(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
4352{
4353 if (!*args[*cur_arg + 1]) {
4354 if (err)
4355 memprintf(err, "'%s' : missing verify method", args[*cur_arg]);
4356 return ERR_ALERT | ERR_FATAL;
4357 }
4358
4359 if (strcmp(args[*cur_arg + 1], "none") == 0)
Emeric Brun850efd52014-01-29 12:24:34 +01004360 newsrv->ssl_ctx.verify = SSL_SOCK_VERIFY_NONE;
Emeric Brunef42d922012-10-11 16:11:36 +02004361 else if (strcmp(args[*cur_arg + 1], "required") == 0)
Emeric Brun850efd52014-01-29 12:24:34 +01004362 newsrv->ssl_ctx.verify = SSL_SOCK_VERIFY_REQUIRED;
Emeric Brunef42d922012-10-11 16:11:36 +02004363 else {
4364 if (err)
4365 memprintf(err, "'%s' : unknown verify method '%s', only 'none' and 'required' are supported\n",
4366 args[*cur_arg], args[*cur_arg + 1]);
4367 return ERR_ALERT | ERR_FATAL;
4368 }
4369
Evan Broderbe554312013-06-27 00:05:25 -07004370 return 0;
4371}
4372
4373/* parse the "verifyhost" server keyword */
4374static int srv_parse_verifyhost(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
4375{
4376 if (!*args[*cur_arg + 1]) {
4377 if (err)
4378 memprintf(err, "'%s' : missing hostname to verify against", args[*cur_arg]);
4379 return ERR_ALERT | ERR_FATAL;
4380 }
4381
4382 newsrv->ssl_ctx.verify_host = strdup(args[*cur_arg + 1]);
4383
Emeric Brunef42d922012-10-11 16:11:36 +02004384 return 0;
4385}
4386
Emeric Brun2c86cbf2014-10-30 15:56:50 +01004387/* parse the "ssl-default-bind-options" keyword in global section */
4388static int ssl_parse_default_bind_options(char **args, int section_type, struct proxy *curpx,
4389 struct proxy *defpx, const char *file, int line,
4390 char **err) {
4391 int i = 1;
4392
4393 if (*(args[i]) == 0) {
4394 memprintf(err, "global statement '%s' expects an option as an argument.", args[0]);
4395 return -1;
4396 }
4397 while (*(args[i])) {
4398 if (!strcmp(args[i], "no-sslv3"))
4399 global.listen_default_ssloptions |= BC_SSL_O_NO_SSLV3;
4400 else if (!strcmp(args[i], "no-tlsv10"))
4401 global.listen_default_ssloptions |= BC_SSL_O_NO_TLSV10;
4402 else if (!strcmp(args[i], "no-tlsv11"))
4403 global.listen_default_ssloptions |= BC_SSL_O_NO_TLSV11;
4404 else if (!strcmp(args[i], "no-tlsv12"))
4405 global.listen_default_ssloptions |= BC_SSL_O_NO_TLSV12;
4406 else if (!strcmp(args[i], "force-sslv3"))
4407 global.listen_default_ssloptions |= BC_SSL_O_USE_SSLV3;
4408 else if (!strcmp(args[i], "force-tlsv10"))
4409 global.listen_default_ssloptions |= BC_SSL_O_USE_TLSV10;
4410 else if (!strcmp(args[i], "force-tlsv11")) {
4411#if SSL_OP_NO_TLSv1_1
4412 global.listen_default_ssloptions |= BC_SSL_O_USE_TLSV11;
4413#else
4414 memprintf(err, "'%s' '%s': library does not support protocol TLSv1.1", args[0], args[i]);
4415 return -1;
4416#endif
4417 }
4418 else if (!strcmp(args[i], "force-tlsv12")) {
4419#if SSL_OP_NO_TLSv1_2
4420 global.listen_default_ssloptions |= BC_SSL_O_USE_TLSV12;
4421#else
4422 memprintf(err, "'%s' '%s': library does not support protocol TLSv1.2", args[0], args[i]);
4423 return -1;
4424#endif
4425 }
4426 else if (!strcmp(args[i], "no-tls-tickets"))
4427 global.listen_default_ssloptions |= BC_SSL_O_NO_TLS_TICKETS;
4428 else {
4429 memprintf(err, "unknown option '%s' on global statement '%s'.", args[i], args[0]);
4430 return -1;
4431 }
4432 i++;
4433 }
4434 return 0;
4435}
4436
4437/* parse the "ssl-default-server-options" keyword in global section */
4438static int ssl_parse_default_server_options(char **args, int section_type, struct proxy *curpx,
4439 struct proxy *defpx, const char *file, int line,
4440 char **err) {
4441 int i = 1;
4442
4443 if (*(args[i]) == 0) {
4444 memprintf(err, "global statement '%s' expects an option as an argument.", args[0]);
4445 return -1;
4446 }
4447 while (*(args[i])) {
4448 if (!strcmp(args[i], "no-sslv3"))
4449 global.connect_default_ssloptions |= SRV_SSL_O_NO_SSLV3;
4450 else if (!strcmp(args[i], "no-tlsv10"))
4451 global.connect_default_ssloptions |= SRV_SSL_O_NO_TLSV10;
4452 else if (!strcmp(args[i], "no-tlsv11"))
4453 global.connect_default_ssloptions |= SRV_SSL_O_NO_TLSV11;
4454 else if (!strcmp(args[i], "no-tlsv12"))
4455 global.connect_default_ssloptions |= SRV_SSL_O_NO_TLSV12;
4456 else if (!strcmp(args[i], "force-sslv3"))
4457 global.connect_default_ssloptions |= SRV_SSL_O_USE_SSLV3;
4458 else if (!strcmp(args[i], "force-tlsv10"))
4459 global.connect_default_ssloptions |= SRV_SSL_O_USE_TLSV10;
4460 else if (!strcmp(args[i], "force-tlsv11")) {
4461#if SSL_OP_NO_TLSv1_1
4462 global.connect_default_ssloptions |= SRV_SSL_O_USE_TLSV11;
4463#else
4464 memprintf(err, "'%s' '%s': library does not support protocol TLSv1.1", args[0], args[i]);
4465 return -1;
4466#endif
4467 }
4468 else if (!strcmp(args[i], "force-tlsv12")) {
4469#if SSL_OP_NO_TLSv1_2
4470 global.connect_default_ssloptions |= SRV_SSL_O_USE_TLSV12;
4471#else
4472 memprintf(err, "'%s' '%s': library does not support protocol TLSv1.2", args[0], args[i]);
4473 return -1;
4474#endif
4475 }
4476 else if (!strcmp(args[i], "no-tls-tickets"))
4477 global.connect_default_ssloptions |= SRV_SSL_O_NO_TLS_TICKETS;
4478 else {
4479 memprintf(err, "unknown option '%s' on global statement '%s'.", args[i], args[0]);
4480 return -1;
4481 }
4482 i++;
4483 }
4484 return 0;
4485}
4486
Willy Tarreau7875d092012-09-10 08:20:03 +02004487/* Note: must not be declared <const> as its list will be overwritten.
4488 * Please take care of keeping this list alphabetically sorted.
4489 */
Willy Tarreaudc13c112013-06-21 23:16:39 +02004490static struct sample_fetch_kw_list sample_fetch_keywords = {ILH, {
Emeric Brun645ae792014-04-30 14:21:06 +02004491 { "ssl_bc", smp_fetch_ssl_fc, 0, NULL, SMP_T_BOOL, SMP_USE_L5SRV },
4492 { "ssl_bc_alg_keysize", smp_fetch_ssl_fc_alg_keysize, 0, NULL, SMP_T_UINT, SMP_USE_L5SRV },
4493 { "ssl_bc_cipher", smp_fetch_ssl_fc_cipher, 0, NULL, SMP_T_STR, SMP_USE_L5SRV },
4494 { "ssl_bc_protocol", smp_fetch_ssl_fc_protocol, 0, NULL, SMP_T_STR, SMP_USE_L5SRV },
Emeric Brunb73a9b02014-04-30 18:49:19 +02004495 { "ssl_bc_unique_id", smp_fetch_ssl_fc_unique_id, 0, NULL, SMP_T_BIN, SMP_USE_L5SRV },
Emeric Brun645ae792014-04-30 14:21:06 +02004496 { "ssl_bc_use_keysize", smp_fetch_ssl_fc_use_keysize, 0, NULL, SMP_T_UINT, SMP_USE_L5SRV },
4497 { "ssl_bc_session_id", smp_fetch_ssl_fc_session_id, 0, NULL, SMP_T_BIN, SMP_USE_L5SRV },
Willy Tarreau80aca902013-01-07 15:42:20 +01004498 { "ssl_c_ca_err", smp_fetch_ssl_c_ca_err, 0, NULL, SMP_T_UINT, SMP_USE_L5CLI },
4499 { "ssl_c_ca_err_depth", smp_fetch_ssl_c_ca_err_depth, 0, NULL, SMP_T_UINT, SMP_USE_L5CLI },
Emeric Brun43e79582014-10-29 19:03:26 +01004500 { "ssl_c_der", smp_fetch_ssl_x_der, 0, NULL, SMP_T_BIN, SMP_USE_L5CLI },
Willy Tarreau80aca902013-01-07 15:42:20 +01004501 { "ssl_c_err", smp_fetch_ssl_c_err, 0, NULL, SMP_T_UINT, SMP_USE_L5CLI },
Emeric Brunba841a12014-04-30 17:05:08 +02004502 { "ssl_c_i_dn", smp_fetch_ssl_x_i_dn, ARG2(0,STR,SINT), NULL, SMP_T_STR, SMP_USE_L5CLI },
4503 { "ssl_c_key_alg", smp_fetch_ssl_x_key_alg, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
4504 { "ssl_c_notafter", smp_fetch_ssl_x_notafter, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
4505 { "ssl_c_notbefore", smp_fetch_ssl_x_notbefore, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
4506 { "ssl_c_sig_alg", smp_fetch_ssl_x_sig_alg, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
4507 { "ssl_c_s_dn", smp_fetch_ssl_x_s_dn, ARG2(0,STR,SINT), NULL, SMP_T_STR, SMP_USE_L5CLI },
4508 { "ssl_c_serial", smp_fetch_ssl_x_serial, 0, NULL, SMP_T_BIN, SMP_USE_L5CLI },
4509 { "ssl_c_sha1", smp_fetch_ssl_x_sha1, 0, NULL, SMP_T_BIN, SMP_USE_L5CLI },
Willy Tarreau80aca902013-01-07 15:42:20 +01004510 { "ssl_c_used", smp_fetch_ssl_c_used, 0, NULL, SMP_T_BOOL, SMP_USE_L5CLI },
4511 { "ssl_c_verify", smp_fetch_ssl_c_verify, 0, NULL, SMP_T_UINT, SMP_USE_L5CLI },
Emeric Brunba841a12014-04-30 17:05:08 +02004512 { "ssl_c_version", smp_fetch_ssl_x_version, 0, NULL, SMP_T_UINT, SMP_USE_L5CLI },
Emeric Brun43e79582014-10-29 19:03:26 +01004513 { "ssl_f_der", smp_fetch_ssl_x_der, 0, NULL, SMP_T_BIN, SMP_USE_L5CLI },
Emeric Brunba841a12014-04-30 17:05:08 +02004514 { "ssl_f_i_dn", smp_fetch_ssl_x_i_dn, ARG2(0,STR,SINT), NULL, SMP_T_STR, SMP_USE_L5CLI },
4515 { "ssl_f_key_alg", smp_fetch_ssl_x_key_alg, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
4516 { "ssl_f_notafter", smp_fetch_ssl_x_notafter, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
4517 { "ssl_f_notbefore", smp_fetch_ssl_x_notbefore, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
4518 { "ssl_f_sig_alg", smp_fetch_ssl_x_sig_alg, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
4519 { "ssl_f_s_dn", smp_fetch_ssl_x_s_dn, ARG2(0,STR,SINT), NULL, SMP_T_STR, SMP_USE_L5CLI },
4520 { "ssl_f_serial", smp_fetch_ssl_x_serial, 0, NULL, SMP_T_BIN, SMP_USE_L5CLI },
Emeric Brun55f4fa82014-04-30 17:11:25 +02004521 { "ssl_f_sha1", smp_fetch_ssl_x_sha1, 0, NULL, SMP_T_BIN, SMP_USE_L5CLI },
Emeric Brunba841a12014-04-30 17:05:08 +02004522 { "ssl_f_version", smp_fetch_ssl_x_version, 0, NULL, SMP_T_UINT, SMP_USE_L5CLI },
Willy Tarreau80aca902013-01-07 15:42:20 +01004523 { "ssl_fc", smp_fetch_ssl_fc, 0, NULL, SMP_T_BOOL, SMP_USE_L5CLI },
4524 { "ssl_fc_alg_keysize", smp_fetch_ssl_fc_alg_keysize, 0, NULL, SMP_T_UINT, SMP_USE_L5CLI },
Thierry FOURNIER7654c9f2013-12-17 00:20:33 +01004525 { "ssl_fc_cipher", smp_fetch_ssl_fc_cipher, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
Willy Tarreau80aca902013-01-07 15:42:20 +01004526 { "ssl_fc_has_crt", smp_fetch_ssl_fc_has_crt, 0, NULL, SMP_T_BOOL, SMP_USE_L5CLI },
4527 { "ssl_fc_has_sni", smp_fetch_ssl_fc_has_sni, 0, NULL, SMP_T_BOOL, SMP_USE_L5CLI },
Willy Tarreaua33c6542012-10-15 13:19:06 +02004528#ifdef OPENSSL_NPN_NEGOTIATED
Thierry FOURNIER7654c9f2013-12-17 00:20:33 +01004529 { "ssl_fc_npn", smp_fetch_ssl_fc_npn, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
Willy Tarreaua33c6542012-10-15 13:19:06 +02004530#endif
Dirkjan Bussink48f1c4e2014-02-13 12:29:42 +01004531#ifdef TLSEXT_TYPE_application_layer_protocol_negotiation
Thierry FOURNIER7654c9f2013-12-17 00:20:33 +01004532 { "ssl_fc_alpn", smp_fetch_ssl_fc_alpn, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
Willy Tarreauab861d32013-04-02 02:30:41 +02004533#endif
Thierry FOURNIER7654c9f2013-12-17 00:20:33 +01004534 { "ssl_fc_protocol", smp_fetch_ssl_fc_protocol, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
Emeric Brunb73a9b02014-04-30 18:49:19 +02004535 { "ssl_fc_unique_id", smp_fetch_ssl_fc_unique_id, 0, NULL, SMP_T_BIN, SMP_USE_L5CLI },
Willy Tarreau80aca902013-01-07 15:42:20 +01004536 { "ssl_fc_use_keysize", smp_fetch_ssl_fc_use_keysize, 0, NULL, SMP_T_UINT, SMP_USE_L5CLI },
Thierry FOURNIER7654c9f2013-12-17 00:20:33 +01004537 { "ssl_fc_session_id", smp_fetch_ssl_fc_session_id, 0, NULL, SMP_T_BIN, SMP_USE_L5CLI },
4538 { "ssl_fc_sni", smp_fetch_ssl_fc_sni, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
Willy Tarreau7875d092012-09-10 08:20:03 +02004539 { NULL, NULL, 0, 0, 0 },
4540}};
4541
4542/* Note: must not be declared <const> as its list will be overwritten.
4543 * Please take care of keeping this list alphabetically sorted.
4544 */
Willy Tarreaudc13c112013-06-21 23:16:39 +02004545static struct acl_kw_list acl_kws = {ILH, {
Thierry FOURNIERc5a4e982014-03-05 16:07:08 +01004546 { "ssl_fc_sni_end", "ssl_fc_sni", PAT_MATCH_END },
4547 { "ssl_fc_sni_reg", "ssl_fc_sni", PAT_MATCH_REG },
Willy Tarreau8ed669b2013-01-11 15:49:37 +01004548 { /* END */ },
Willy Tarreau7875d092012-09-10 08:20:03 +02004549}};
4550
Willy Tarreau79eeafa2012-09-14 07:53:05 +02004551/* Note: must not be declared <const> as its list will be overwritten.
4552 * Please take care of keeping this list alphabetically sorted, doing so helps
4553 * all code contributors.
4554 * Optional keywords are also declared with a NULL ->parse() function so that
4555 * the config parser can report an appropriate error when a known keyword was
4556 * not enabled.
4557 */
Willy Tarreau51fb7652012-09-18 18:24:39 +02004558static struct bind_kw_list bind_kws = { "SSL", { }, {
Willy Tarreauab861d32013-04-02 02:30:41 +02004559 { "alpn", bind_parse_alpn, 1 }, /* set ALPN supported protocols */
Emeric Brunfb510ea2012-10-05 12:00:26 +02004560 { "ca-file", bind_parse_ca_file, 1 }, /* set CAfile to process verify on client cert */
Emeric Brun2d0c4822012-10-02 13:45:20 +02004561 { "ca-ignore-err", bind_parse_ignore_err, 1 }, /* set error IDs to ignore on verify depth > 0 */
4562 { "ciphers", bind_parse_ciphers, 1 }, /* set SSL cipher suite */
Emeric Brunfb510ea2012-10-05 12:00:26 +02004563 { "crl-file", bind_parse_crl_file, 1 }, /* set certificat revocation list file use on client cert verify */
Emeric Brun2d0c4822012-10-02 13:45:20 +02004564 { "crt", bind_parse_crt, 1 }, /* load SSL certificates from this location */
4565 { "crt-ignore-err", bind_parse_ignore_err, 1 }, /* set error IDs to ingore on verify depth == 0 */
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01004566 { "crt-list", bind_parse_crt_list, 1 }, /* load a list of crt from this location */
Emeric Brun2d0c4822012-10-02 13:45:20 +02004567 { "ecdhe", bind_parse_ecdhe, 1 }, /* defines named curve for elliptic curve Diffie-Hellman */
Emeric Brun2cb7ae52012-10-05 14:14:21 +02004568 { "force-sslv3", bind_parse_force_sslv3, 0 }, /* force SSLv3 */
4569 { "force-tlsv10", bind_parse_force_tlsv10, 0 }, /* force TLSv10 */
4570 { "force-tlsv11", bind_parse_force_tlsv11, 0 }, /* force TLSv11 */
4571 { "force-tlsv12", bind_parse_force_tlsv12, 0 }, /* force TLSv12 */
Emeric Brun9b3009b2012-10-05 11:55:06 +02004572 { "no-sslv3", bind_parse_no_sslv3, 0 }, /* disable SSLv3 */
4573 { "no-tlsv10", bind_parse_no_tlsv10, 0 }, /* disable TLSv10 */
4574 { "no-tlsv11", bind_parse_no_tlsv11, 0 }, /* disable TLSv11 */
4575 { "no-tlsv12", bind_parse_no_tlsv12, 0 }, /* disable TLSv12 */
Emeric Brun2d0c4822012-10-02 13:45:20 +02004576 { "no-tls-tickets", bind_parse_no_tls_tickets, 0 }, /* disable session resumption tickets */
Emeric Brun2d0c4822012-10-02 13:45:20 +02004577 { "ssl", bind_parse_ssl, 0 }, /* enable SSL processing */
Emmanuel Hocdet65623372013-01-24 17:17:15 +01004578 { "strict-sni", bind_parse_strict_sni, 0 }, /* refuse negotiation if sni doesn't match a certificate */
Emeric Brun2d0c4822012-10-02 13:45:20 +02004579 { "verify", bind_parse_verify, 1 }, /* set SSL verify method */
Willy Tarreau6c9a3d52012-10-18 18:57:14 +02004580 { "npn", bind_parse_npn, 1 }, /* set NPN supported protocols */
Willy Tarreau79eeafa2012-09-14 07:53:05 +02004581 { NULL, NULL, 0 },
4582}};
Emeric Brun46591952012-05-18 15:47:34 +02004583
Willy Tarreau92faadf2012-10-10 23:04:25 +02004584/* Note: must not be declared <const> as its list will be overwritten.
4585 * Please take care of keeping this list alphabetically sorted, doing so helps
4586 * all code contributors.
4587 * Optional keywords are also declared with a NULL ->parse() function so that
4588 * the config parser can report an appropriate error when a known keyword was
4589 * not enabled.
4590 */
4591static struct srv_kw_list srv_kws = { "SSL", { }, {
Emeric Brunef42d922012-10-11 16:11:36 +02004592 { "ca-file", srv_parse_ca_file, 1, 0 }, /* set CAfile to process verify server cert */
Emeric Brunecc91fe2012-10-11 15:05:10 +02004593 { "check-ssl", srv_parse_check_ssl, 0, 0 }, /* enable SSL for health checks */
4594 { "ciphers", srv_parse_ciphers, 1, 0 }, /* select the cipher suite */
Emeric Brunef42d922012-10-11 16:11:36 +02004595 { "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 +02004596 { "crt", srv_parse_crt, 1, 0 }, /* set client certificate */
Emeric Brunecc91fe2012-10-11 15:05:10 +02004597 { "force-sslv3", srv_parse_force_sslv3, 0, 0 }, /* force SSLv3 */
4598 { "force-tlsv10", srv_parse_force_tlsv10, 0, 0 }, /* force TLSv10 */
4599 { "force-tlsv11", srv_parse_force_tlsv11, 0, 0 }, /* force TLSv11 */
4600 { "force-tlsv12", srv_parse_force_tlsv12, 0, 0 }, /* force TLSv12 */
4601 { "no-sslv3", srv_parse_no_sslv3, 0, 0 }, /* disable SSLv3 */
4602 { "no-tlsv10", srv_parse_no_tlsv10, 0, 0 }, /* disable TLSv10 */
4603 { "no-tlsv11", srv_parse_no_tlsv11, 0, 0 }, /* disable TLSv11 */
4604 { "no-tlsv12", srv_parse_no_tlsv12, 0, 0 }, /* disable TLSv12 */
Emeric Brunf9c5c472012-10-11 15:28:34 +02004605 { "no-tls-tickets", srv_parse_no_tls_tickets, 0, 0 }, /* disable session resumption tickets */
David Safb76832014-05-08 23:42:08 -04004606 { "send-proxy-v2-ssl", srv_parse_send_proxy_ssl, 0, 0 }, /* send PROXY protocol header v2 with SSL info */
4607 { "send-proxy-v2-ssl-cn", srv_parse_send_proxy_cn, 0, 0 }, /* send PROXY protocol header v2 with CN */
Emeric Brunecc91fe2012-10-11 15:05:10 +02004608 { "ssl", srv_parse_ssl, 0, 0 }, /* enable SSL processing */
Emeric Brunef42d922012-10-11 16:11:36 +02004609 { "verify", srv_parse_verify, 1, 0 }, /* set SSL verify method */
Evan Broderbe554312013-06-27 00:05:25 -07004610 { "verifyhost", srv_parse_verifyhost, 1, 0 }, /* require that SSL cert verifies for hostname */
Willy Tarreau92faadf2012-10-10 23:04:25 +02004611 { NULL, NULL, 0, 0 },
4612}};
4613
Emeric Brun2c86cbf2014-10-30 15:56:50 +01004614static struct cfg_kw_list cfg_kws = {ILH, {
4615 { CFG_GLOBAL, "ssl-default-bind-options", ssl_parse_default_bind_options },
4616 { CFG_GLOBAL, "ssl-default-server-options", ssl_parse_default_server_options },
4617 { 0, NULL, NULL },
4618}};
4619
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02004620/* transport-layer operations for SSL sockets */
4621struct xprt_ops ssl_sock = {
Emeric Brun46591952012-05-18 15:47:34 +02004622 .snd_buf = ssl_sock_from_buf,
4623 .rcv_buf = ssl_sock_to_buf,
4624 .rcv_pipe = NULL,
4625 .snd_pipe = NULL,
4626 .shutr = NULL,
4627 .shutw = ssl_sock_shutw,
4628 .close = ssl_sock_close,
4629 .init = ssl_sock_init,
4630};
4631
4632__attribute__((constructor))
Willy Tarreau92faadf2012-10-10 23:04:25 +02004633static void __ssl_sock_init(void)
4634{
Emeric Brun46591952012-05-18 15:47:34 +02004635 STACK_OF(SSL_COMP)* cm;
4636
Willy Tarreau610f04b2014-02-13 11:36:41 +01004637#ifdef LISTEN_DEFAULT_CIPHERS
4638 global.listen_default_ciphers = LISTEN_DEFAULT_CIPHERS;
4639#endif
4640#ifdef CONNECT_DEFAULT_CIPHERS
4641 global.connect_default_ciphers = CONNECT_DEFAULT_CIPHERS;
4642#endif
4643 if (global.listen_default_ciphers)
4644 global.listen_default_ciphers = strdup(global.listen_default_ciphers);
4645 if (global.connect_default_ciphers)
4646 global.connect_default_ciphers = strdup(global.connect_default_ciphers);
Emeric Brun2c86cbf2014-10-30 15:56:50 +01004647 global.listen_default_ssloptions = BC_SSL_O_NONE;
4648 global.connect_default_ssloptions = SRV_SSL_O_NONE;
Willy Tarreau610f04b2014-02-13 11:36:41 +01004649
Emeric Brun46591952012-05-18 15:47:34 +02004650 SSL_library_init();
4651 cm = SSL_COMP_get_compression_methods();
4652 sk_SSL_COMP_zero(cm);
Willy Tarreau7875d092012-09-10 08:20:03 +02004653 sample_register_fetches(&sample_fetch_keywords);
4654 acl_register_keywords(&acl_kws);
Willy Tarreau79eeafa2012-09-14 07:53:05 +02004655 bind_register_keywords(&bind_kws);
Willy Tarreau92faadf2012-10-10 23:04:25 +02004656 srv_register_keywords(&srv_kws);
Emeric Brun2c86cbf2014-10-30 15:56:50 +01004657 cfg_register_keywords(&cfg_kws);
Emeric Brun46591952012-05-18 15:47:34 +02004658}
4659
4660/*
4661 * Local variables:
4662 * c-indent-level: 8
4663 * c-basic-offset: 8
4664 * End:
4665 */