blob: 8739e8bac58a5aaeec7053ba760a1e5f2a9b9af5 [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 Tribuse4e30f72014-12-09 16:32:51 +010047#if (defined SSL_CTRL_SET_TLSEXT_STATUS_REQ_CB && !defined OPENSSL_NO_OCSP)
Emeric Brun4147b2e2014-06-16 18:36:30 +020048#include <openssl/ocsp.h>
49#endif
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 Tribuse4e30f72014-12-09 16:32:51 +0100116#if (defined SSL_CTRL_SET_TLSEXT_STATUS_REQ_CB && !defined OPENSSL_NO_OCSP)
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 Tribuse4e30f72014-12-09 16:32:51 +01001286#if (defined SSL_CTRL_SET_TLSEXT_STATUS_REQ_CB && !defined OPENSSL_NO_OCSP)
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{
Cyril Bonté3180f7b2015-01-25 00:16:08 +01001311 struct dirent **de_list;
1312 int i, n;
Emeric Brunfc0421f2012-09-07 17:30:07 +02001313 DIR *dir;
1314 struct stat buf;
Willy Tarreauee2663b2012-12-06 11:36:59 +01001315 char *end;
1316 char fp[MAXPATHLEN+1];
Emeric Brunfc0421f2012-09-07 17:30:07 +02001317 int cfgerr = 0;
1318
1319 if (!(dir = opendir(path)))
Emeric Brun50bcecc2013-04-22 13:05:23 +02001320 return ssl_sock_load_cert_file(path, bind_conf, curproxy, NULL, 0, err);
Emeric Brunfc0421f2012-09-07 17:30:07 +02001321
1322 /* strip trailing slashes, including first one */
1323 for (end = path + strlen(path) - 1; end >= path && *end == '/'; end--)
1324 *end = 0;
1325
Cyril Bonté3180f7b2015-01-25 00:16:08 +01001326 n = scandir(path, &de_list, 0, alphasort);
1327 if (n < 0) {
1328 memprintf(err, "%sunable to scan directory '%s' : %s.\n",
1329 err && *err ? *err : "", path, strerror(errno));
1330 cfgerr++;
1331 }
1332 else {
1333 for (i = 0; i < n; i++) {
1334 struct dirent *de = de_list[i];
Emeric Brun2aab7222014-06-18 18:15:09 +02001335
Cyril Bonté3180f7b2015-01-25 00:16:08 +01001336 end = strrchr(de->d_name, '.');
1337 if (end && (!strcmp(end, ".issuer") || !strcmp(end, ".ocsp")))
1338 goto ignore_entry;
1339
1340 snprintf(fp, sizeof(fp), "%s/%s", path, de->d_name);
1341 if (stat(fp, &buf) != 0) {
1342 memprintf(err, "%sunable to stat SSL certificate from file '%s' : %s.\n",
1343 err && *err ? *err : "", fp, strerror(errno));
1344 cfgerr++;
1345 goto ignore_entry;
1346 }
1347 if (!S_ISREG(buf.st_mode))
1348 goto ignore_entry;
1349 cfgerr += ssl_sock_load_cert_file(fp, bind_conf, curproxy, NULL, 0, err);
1350 ignore_entry:
1351 free(de);
Emeric Brunfc0421f2012-09-07 17:30:07 +02001352 }
Cyril Bonté3180f7b2015-01-25 00:16:08 +01001353 free(de_list);
Emeric Brunfc0421f2012-09-07 17:30:07 +02001354 }
Emeric Brunfc0421f2012-09-07 17:30:07 +02001355 closedir(dir);
1356 return cfgerr;
1357}
1358
Thierry Fournier383085f2013-01-24 14:15:43 +01001359/* Make sure openssl opens /dev/urandom before the chroot. The work is only
1360 * done once. Zero is returned if the operation fails. No error is returned
1361 * if the random is said as not implemented, because we expect that openssl
1362 * will use another method once needed.
1363 */
1364static int ssl_initialize_random()
1365{
1366 unsigned char random;
1367 static int random_initialized = 0;
1368
1369 if (!random_initialized && RAND_bytes(&random, 1) != 0)
1370 random_initialized = 1;
1371
1372 return random_initialized;
1373}
1374
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01001375int ssl_sock_load_cert_list_file(char *file, struct bind_conf *bind_conf, struct proxy *curproxy, char **err)
1376{
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +02001377 char thisline[LINESIZE];
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01001378 FILE *f;
1379 int linenum = 0;
1380 int cfgerr = 0;
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01001381
Willy Tarreauad1731d2013-04-02 17:35:58 +02001382 if ((f = fopen(file, "r")) == NULL) {
1383 memprintf(err, "cannot open file '%s' : %s", file, strerror(errno));
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01001384 return 1;
Willy Tarreauad1731d2013-04-02 17:35:58 +02001385 }
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01001386
1387 while (fgets(thisline, sizeof(thisline), f) != NULL) {
1388 int arg;
Emeric Brun50bcecc2013-04-22 13:05:23 +02001389 int newarg;
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01001390 char *end;
1391 char *args[MAX_LINE_ARGS + 1];
1392 char *line = thisline;
1393
1394 linenum++;
1395 end = line + strlen(line);
1396 if (end-line == sizeof(thisline)-1 && *(end-1) != '\n') {
1397 /* Check if we reached the limit and the last char is not \n.
1398 * Watch out for the last line without the terminating '\n'!
1399 */
Willy Tarreauad1731d2013-04-02 17:35:58 +02001400 memprintf(err, "line %d too long in file '%s', limit is %d characters",
1401 linenum, file, (int)sizeof(thisline)-1);
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01001402 cfgerr = 1;
Willy Tarreauad1731d2013-04-02 17:35:58 +02001403 break;
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01001404 }
1405
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01001406 arg = 0;
Emeric Brun50bcecc2013-04-22 13:05:23 +02001407 newarg = 1;
1408 while (*line) {
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01001409 if (*line == '#' || *line == '\n' || *line == '\r') {
1410 /* end of string, end of loop */
1411 *line = 0;
1412 break;
1413 }
1414 else if (isspace(*line)) {
Emeric Brun50bcecc2013-04-22 13:05:23 +02001415 newarg = 1;
1416 *line = 0;
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01001417 }
Emeric Brun50bcecc2013-04-22 13:05:23 +02001418 else if (newarg) {
1419 if (arg == MAX_LINE_ARGS) {
1420 memprintf(err, "too many args on line %d in file '%s'.",
1421 linenum, file);
1422 cfgerr = 1;
1423 break;
1424 }
1425 newarg = 0;
1426 args[arg++] = line;
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01001427 }
Emeric Brun50bcecc2013-04-22 13:05:23 +02001428 line++;
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01001429 }
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +02001430 if (cfgerr)
1431 break;
Willy Tarreauad1731d2013-04-02 17:35:58 +02001432
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01001433 /* empty line */
Emeric Brun50bcecc2013-04-22 13:05:23 +02001434 if (!arg)
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01001435 continue;
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01001436
Emeric Brun50bcecc2013-04-22 13:05:23 +02001437 cfgerr = ssl_sock_load_cert_file(args[0], bind_conf, curproxy, &args[1], arg-1, err);
Willy Tarreauad1731d2013-04-02 17:35:58 +02001438 if (cfgerr) {
1439 memprintf(err, "error processing line %d in file '%s' : %s", linenum, file, *err);
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01001440 break;
Willy Tarreauad1731d2013-04-02 17:35:58 +02001441 }
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01001442 }
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01001443 fclose(f);
1444 return cfgerr;
1445}
1446
Emeric Brunfc0421f2012-09-07 17:30:07 +02001447#ifndef SSL_OP_CIPHER_SERVER_PREFERENCE /* needs OpenSSL >= 0.9.7 */
1448#define SSL_OP_CIPHER_SERVER_PREFERENCE 0
1449#endif
1450
1451#ifndef SSL_OP_NO_SESSION_RESUMPTION_ON_RENEGOTIATION /* needs OpenSSL >= 0.9.7 */
1452#define SSL_OP_NO_SESSION_RESUMPTION_ON_RENEGOTIATION 0
Willy Tarreau7d588ee2012-11-26 18:47:31 +01001453#define SSL_renegotiate_pending(arg) 0
Emeric Brunfc0421f2012-09-07 17:30:07 +02001454#endif
Emeric Brun2b58d042012-09-20 17:10:03 +02001455#ifndef SSL_OP_SINGLE_ECDH_USE /* needs OpenSSL >= 0.9.8 */
1456#define SSL_OP_SINGLE_ECDH_USE 0
1457#endif
Emeric Brun2d0c4822012-10-02 13:45:20 +02001458#ifndef SSL_OP_NO_TICKET /* needs OpenSSL >= 0.9.8 */
1459#define SSL_OP_NO_TICKET 0
1460#endif
Emeric Brunfc0421f2012-09-07 17:30:07 +02001461#ifndef SSL_OP_NO_COMPRESSION /* needs OpenSSL >= 0.9.9 */
1462#define SSL_OP_NO_COMPRESSION 0
1463#endif
Emeric Brunc0ff4922012-09-28 19:37:02 +02001464#ifndef SSL_OP_NO_TLSv1_1 /* needs OpenSSL >= 1.0.1 */
1465#define SSL_OP_NO_TLSv1_1 0
1466#endif
1467#ifndef SSL_OP_NO_TLSv1_2 /* needs OpenSSL >= 1.0.1 */
1468#define SSL_OP_NO_TLSv1_2 0
1469#endif
Emeric Bruna4bcd9a2012-09-20 16:19:02 +02001470#ifndef SSL_OP_SINGLE_DH_USE /* needs OpenSSL >= 0.9.6 */
1471#define SSL_OP_SINGLE_DH_USE 0
1472#endif
Emeric Brun2b58d042012-09-20 17:10:03 +02001473#ifndef SSL_OP_SINGLE_ECDH_USE /* needs OpenSSL >= 1.0.0 */
1474#define SSL_OP_SINGLE_ECDH_USE 0
1475#endif
Emeric Brunfc0421f2012-09-07 17:30:07 +02001476#ifndef SSL_MODE_RELEASE_BUFFERS /* needs OpenSSL >= 1.0.0 */
1477#define SSL_MODE_RELEASE_BUFFERS 0
1478#endif
Willy Tarreau396a1862014-11-13 14:06:52 +01001479#ifndef SSL_MODE_SMALL_BUFFERS /* needs small_records.patch */
1480#define SSL_MODE_SMALL_BUFFERS 0
1481#endif
Remi Gacognef46cd6e2014-06-12 14:58:40 +02001482
Willy Tarreau2a65ff02012-09-13 17:54:29 +02001483int ssl_sock_prepare_ctx(struct bind_conf *bind_conf, SSL_CTX *ctx, struct proxy *curproxy)
Emeric Brunfc0421f2012-09-07 17:30:07 +02001484{
1485 int cfgerr = 0;
Emeric Brun850efd52014-01-29 12:24:34 +01001486 int verify = SSL_VERIFY_NONE;
Remi Gacogneaf5c3da2014-05-19 10:29:58 +02001487 long ssloptions =
Emeric Brunfc0421f2012-09-07 17:30:07 +02001488 SSL_OP_ALL | /* all known workarounds for bugs */
1489 SSL_OP_NO_SSLv2 |
1490 SSL_OP_NO_COMPRESSION |
Emeric Bruna4bcd9a2012-09-20 16:19:02 +02001491 SSL_OP_SINGLE_DH_USE |
Emeric Brun2b58d042012-09-20 17:10:03 +02001492 SSL_OP_SINGLE_ECDH_USE |
Emeric Brun3c4bc6e2012-10-04 18:44:19 +02001493 SSL_OP_NO_SESSION_RESUMPTION_ON_RENEGOTIATION |
1494 SSL_OP_CIPHER_SERVER_PREFERENCE;
Remi Gacogneaf5c3da2014-05-19 10:29:58 +02001495 long sslmode =
Emeric Brunfc0421f2012-09-07 17:30:07 +02001496 SSL_MODE_ENABLE_PARTIAL_WRITE |
1497 SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER |
Willy Tarreau396a1862014-11-13 14:06:52 +01001498 SSL_MODE_RELEASE_BUFFERS |
1499 SSL_MODE_SMALL_BUFFERS;
Remi Gacognef46cd6e2014-06-12 14:58:40 +02001500 STACK_OF(SSL_CIPHER) * ciphers = NULL;
Willy Tarreaua616ba62014-10-26 06:49:19 +01001501 SSL_CIPHER * cipher = NULL;
Remi Gacognec1eab8c2014-06-12 18:20:11 +02001502 char cipher_description[128];
1503 /* The description of ciphers using an Ephemeral Diffie Hellman key exchange
1504 contains " Kx=DH " or " Kx=DH(". Beware of " Kx=DH/",
1505 which is not ephemeral DH. */
1506 const char dhe_description[] = " Kx=DH ";
1507 const char dhe_export_description[] = " Kx=DH(";
Remi Gacognef46cd6e2014-06-12 14:58:40 +02001508 int idx = 0;
1509 int dhe_found = 0;
Remi Gacogne23d5d372014-10-10 17:04:26 +02001510 SSL *ssl = NULL;
Emeric Brunfc0421f2012-09-07 17:30:07 +02001511
Thierry Fournier383085f2013-01-24 14:15:43 +01001512 /* Make sure openssl opens /dev/urandom before the chroot */
1513 if (!ssl_initialize_random()) {
1514 Alert("OpenSSL random data generator initialization failed.\n");
1515 cfgerr++;
1516 }
1517
Emeric Brun89675492012-10-05 13:48:26 +02001518 if (bind_conf->ssl_options & BC_SSL_O_NO_SSLV3)
Emeric Brunfc0421f2012-09-07 17:30:07 +02001519 ssloptions |= SSL_OP_NO_SSLv3;
Emeric Brun89675492012-10-05 13:48:26 +02001520 if (bind_conf->ssl_options & BC_SSL_O_NO_TLSV10)
Emeric Brunfc0421f2012-09-07 17:30:07 +02001521 ssloptions |= SSL_OP_NO_TLSv1;
Emeric Brun89675492012-10-05 13:48:26 +02001522 if (bind_conf->ssl_options & BC_SSL_O_NO_TLSV11)
Emeric Brunc0ff4922012-09-28 19:37:02 +02001523 ssloptions |= SSL_OP_NO_TLSv1_1;
Emeric Brun89675492012-10-05 13:48:26 +02001524 if (bind_conf->ssl_options & BC_SSL_O_NO_TLSV12)
Emeric Brunc0ff4922012-09-28 19:37:02 +02001525 ssloptions |= SSL_OP_NO_TLSv1_2;
Emeric Brun89675492012-10-05 13:48:26 +02001526 if (bind_conf->ssl_options & BC_SSL_O_NO_TLS_TICKETS)
Emeric Brun2d0c4822012-10-02 13:45:20 +02001527 ssloptions |= SSL_OP_NO_TICKET;
Emeric Brun2cb7ae52012-10-05 14:14:21 +02001528 if (bind_conf->ssl_options & BC_SSL_O_USE_SSLV3)
1529 SSL_CTX_set_ssl_version(ctx, SSLv3_server_method());
1530 if (bind_conf->ssl_options & BC_SSL_O_USE_TLSV10)
1531 SSL_CTX_set_ssl_version(ctx, TLSv1_server_method());
1532#if SSL_OP_NO_TLSv1_1
1533 if (bind_conf->ssl_options & BC_SSL_O_USE_TLSV11)
1534 SSL_CTX_set_ssl_version(ctx, TLSv1_1_server_method());
1535#endif
1536#if SSL_OP_NO_TLSv1_2
1537 if (bind_conf->ssl_options & BC_SSL_O_USE_TLSV12)
1538 SSL_CTX_set_ssl_version(ctx, TLSv1_2_server_method());
1539#endif
Emeric Brunfc0421f2012-09-07 17:30:07 +02001540
1541 SSL_CTX_set_options(ctx, ssloptions);
1542 SSL_CTX_set_mode(ctx, sslmode);
Emeric Brun850efd52014-01-29 12:24:34 +01001543 switch (bind_conf->verify) {
1544 case SSL_SOCK_VERIFY_NONE:
1545 verify = SSL_VERIFY_NONE;
1546 break;
1547 case SSL_SOCK_VERIFY_OPTIONAL:
1548 verify = SSL_VERIFY_PEER;
1549 break;
1550 case SSL_SOCK_VERIFY_REQUIRED:
1551 verify = SSL_VERIFY_PEER|SSL_VERIFY_FAIL_IF_NO_PEER_CERT;
1552 break;
1553 }
1554 SSL_CTX_set_verify(ctx, verify, ssl_sock_bind_verifycbk);
1555 if (verify & SSL_VERIFY_PEER) {
Emeric Brunfb510ea2012-10-05 12:00:26 +02001556 if (bind_conf->ca_file) {
Emeric Brund94b3fe2012-09-20 18:23:56 +02001557 /* load CAfile to verify */
Emeric Brunfb510ea2012-10-05 12:00:26 +02001558 if (!SSL_CTX_load_verify_locations(ctx, bind_conf->ca_file, NULL)) {
Emeric Brund94b3fe2012-09-20 18:23:56 +02001559 Alert("Proxy '%s': unable to load CA file '%s' for bind '%s' at [%s:%d].\n",
Emeric Brunfb510ea2012-10-05 12:00:26 +02001560 curproxy->id, bind_conf->ca_file, bind_conf->arg, bind_conf->file, bind_conf->line);
Emeric Brund94b3fe2012-09-20 18:23:56 +02001561 cfgerr++;
1562 }
1563 /* set CA names fo client cert request, function returns void */
Emeric Brunfb510ea2012-10-05 12:00:26 +02001564 SSL_CTX_set_client_CA_list(ctx, SSL_load_client_CA_file(bind_conf->ca_file));
Emeric Brund94b3fe2012-09-20 18:23:56 +02001565 }
Emeric Brun850efd52014-01-29 12:24:34 +01001566 else {
1567 Alert("Proxy '%s': verify is enabled but no CA file specified for bind '%s' at [%s:%d].\n",
1568 curproxy->id, bind_conf->arg, bind_conf->file, bind_conf->line);
1569 cfgerr++;
1570 }
Emeric Brun051cdab2012-10-02 19:25:50 +02001571#ifdef X509_V_FLAG_CRL_CHECK
Emeric Brunfb510ea2012-10-05 12:00:26 +02001572 if (bind_conf->crl_file) {
Emeric Brund94b3fe2012-09-20 18:23:56 +02001573 X509_STORE *store = SSL_CTX_get_cert_store(ctx);
1574
Emeric Brunfb510ea2012-10-05 12:00:26 +02001575 if (!store || !X509_STORE_load_locations(store, bind_conf->crl_file, NULL)) {
Emeric Brund94b3fe2012-09-20 18:23:56 +02001576 Alert("Proxy '%s': unable to configure CRL file '%s' for bind '%s' at [%s:%d].\n",
Emeric Brunfb510ea2012-10-05 12:00:26 +02001577 curproxy->id, bind_conf->ca_file, bind_conf->arg, bind_conf->file, bind_conf->line);
Emeric Brund94b3fe2012-09-20 18:23:56 +02001578 cfgerr++;
1579 }
Emeric Brun561e5742012-10-02 15:20:55 +02001580 else {
1581 X509_STORE_set_flags(store, X509_V_FLAG_CRL_CHECK|X509_V_FLAG_CRL_CHECK_ALL);
1582 }
Emeric Brund94b3fe2012-09-20 18:23:56 +02001583 }
Emeric Brun051cdab2012-10-02 19:25:50 +02001584#endif
Emeric Brun644cde02012-12-14 11:21:13 +01001585 ERR_clear_error();
Emeric Brund94b3fe2012-09-20 18:23:56 +02001586 }
Emeric Brunfc0421f2012-09-07 17:30:07 +02001587
Emeric Brun4f65bff2012-11-16 15:11:00 +01001588 if (global.tune.ssllifetime)
1589 SSL_CTX_set_timeout(ctx, global.tune.ssllifetime);
1590
Emeric Brunfc0421f2012-09-07 17:30:07 +02001591 shared_context_set_cache(ctx);
Willy Tarreau2a65ff02012-09-13 17:54:29 +02001592 if (bind_conf->ciphers &&
1593 !SSL_CTX_set_cipher_list(ctx, bind_conf->ciphers)) {
Emeric Brunfc0421f2012-09-07 17:30:07 +02001594 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 +02001595 curproxy->id, bind_conf->ciphers, bind_conf->arg, bind_conf->file, bind_conf->line);
Emeric Brunfc0421f2012-09-07 17:30:07 +02001596 cfgerr++;
1597 }
1598
Remi Gacognef46cd6e2014-06-12 14:58:40 +02001599 /* If tune.ssl.default-dh-param has not been set and
1600 no static DH params were in the certificate file. */
1601 if (global.tune.ssl_default_dh_param == 0) {
Lukas Tribus90132722014-08-18 00:56:33 +02001602
Remi Gacogne23d5d372014-10-10 17:04:26 +02001603 ssl = SSL_new(ctx);
Remi Gacognef46cd6e2014-06-12 14:58:40 +02001604
Remi Gacogne23d5d372014-10-10 17:04:26 +02001605 if (ssl) {
1606 ciphers = SSL_get_ciphers(ssl);
1607
1608 if (ciphers) {
1609 for (idx = 0; idx < sk_SSL_CIPHER_num(ciphers); idx++) {
1610 cipher = sk_SSL_CIPHER_value(ciphers, idx);
1611 if (SSL_CIPHER_description(cipher, cipher_description, sizeof (cipher_description)) == cipher_description) {
1612 if (strstr(cipher_description, dhe_description) != NULL ||
1613 strstr(cipher_description, dhe_export_description) != NULL) {
1614 dhe_found = 1;
1615 break;
1616 }
Remi Gacognec1eab8c2014-06-12 18:20:11 +02001617 }
Remi Gacognef46cd6e2014-06-12 14:58:40 +02001618 }
1619 }
Remi Gacogne23d5d372014-10-10 17:04:26 +02001620 SSL_free(ssl);
1621 ssl = NULL;
Lukas Tribus90132722014-08-18 00:56:33 +02001622 }
Remi Gacognef46cd6e2014-06-12 14:58:40 +02001623
Lukas Tribus90132722014-08-18 00:56:33 +02001624 if (dhe_found) {
1625 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 +02001626 }
1627
1628 global.tune.ssl_default_dh_param = 1024;
1629 }
Remi Gacogne8de54152014-07-15 11:36:40 +02001630
1631#ifndef OPENSSL_NO_DH
1632 if (global.tune.ssl_default_dh_param >= 1024) {
1633 if (local_dh_1024 == NULL) {
1634 local_dh_1024 = ssl_get_dh_1024();
1635 }
1636 if (global.tune.ssl_default_dh_param >= 2048) {
1637 if (local_dh_2048 == NULL) {
1638 local_dh_2048 = ssl_get_dh_2048();
1639 }
1640 if (global.tune.ssl_default_dh_param >= 4096) {
1641 if (local_dh_4096 == NULL) {
1642 local_dh_4096 = ssl_get_dh_4096();
1643 }
1644 if (global.tune.ssl_default_dh_param >= 8192 &&
1645 local_dh_8192 == NULL) {
1646 local_dh_8192 = ssl_get_dh_8192();
1647 }
1648 }
1649 }
1650 }
1651#endif /* OPENSSL_NO_DH */
Remi Gacognef46cd6e2014-06-12 14:58:40 +02001652
Emeric Brunfc0421f2012-09-07 17:30:07 +02001653 SSL_CTX_set_info_callback(ctx, ssl_sock_infocbk);
Willy Tarreau5cbe4ef2014-05-08 22:45:11 +02001654#if OPENSSL_VERSION_NUMBER >= 0x00907000L
Emeric Brun29f037d2014-04-25 19:05:36 +02001655 SSL_CTX_set_msg_callback(ctx, ssl_sock_msgcbk);
Willy Tarreau5cbe4ef2014-05-08 22:45:11 +02001656#endif
Emeric Brun29f037d2014-04-25 19:05:36 +02001657
Willy Tarreau6c9a3d52012-10-18 18:57:14 +02001658#ifdef OPENSSL_NPN_NEGOTIATED
1659 if (bind_conf->npn_str)
1660 SSL_CTX_set_next_protos_advertised_cb(ctx, ssl_sock_advertise_npn_protos, bind_conf);
1661#endif
Dirkjan Bussink48f1c4e2014-02-13 12:29:42 +01001662#ifdef TLSEXT_TYPE_application_layer_protocol_negotiation
Willy Tarreauab861d32013-04-02 02:30:41 +02001663 if (bind_conf->alpn_str)
Dirkjan Bussink48f1c4e2014-02-13 12:29:42 +01001664 SSL_CTX_set_alpn_select_cb(ctx, ssl_sock_advertise_alpn_protos, bind_conf);
Willy Tarreauab861d32013-04-02 02:30:41 +02001665#endif
Willy Tarreau6c9a3d52012-10-18 18:57:14 +02001666
Emeric Brunfc0421f2012-09-07 17:30:07 +02001667#ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME
1668 SSL_CTX_set_tlsext_servername_callback(ctx, ssl_sock_switchctx_cbk);
Willy Tarreau2a65ff02012-09-13 17:54:29 +02001669 SSL_CTX_set_tlsext_servername_arg(ctx, bind_conf);
Emeric Brunfc0421f2012-09-07 17:30:07 +02001670#endif
Emeric Brun2b58d042012-09-20 17:10:03 +02001671#if defined(SSL_CTX_set_tmp_ecdh) && !defined(OPENSSL_NO_ECDH)
Emeric Brun6924ef82013-03-06 14:08:53 +01001672 {
Emeric Brun2b58d042012-09-20 17:10:03 +02001673 int i;
1674 EC_KEY *ecdh;
1675
Emeric Brun6924ef82013-03-06 14:08:53 +01001676 i = OBJ_sn2nid(bind_conf->ecdhe ? bind_conf->ecdhe : ECDHE_DEFAULT_CURVE);
Emeric Brun2b58d042012-09-20 17:10:03 +02001677 if (!i || ((ecdh = EC_KEY_new_by_curve_name(i)) == NULL)) {
1678 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 +01001679 curproxy->id, bind_conf->ecdhe ? bind_conf->ecdhe : ECDHE_DEFAULT_CURVE,
1680 bind_conf->arg, bind_conf->file, bind_conf->line);
Emeric Brun2b58d042012-09-20 17:10:03 +02001681 cfgerr++;
1682 }
1683 else {
1684 SSL_CTX_set_tmp_ecdh(ctx, ecdh);
1685 EC_KEY_free(ecdh);
1686 }
1687 }
1688#endif
1689
Emeric Brunfc0421f2012-09-07 17:30:07 +02001690 return cfgerr;
1691}
1692
Evan Broderbe554312013-06-27 00:05:25 -07001693static int ssl_sock_srv_hostcheck(const char *pattern, const char *hostname)
1694{
1695 const char *pattern_wildcard, *pattern_left_label_end, *hostname_left_label_end;
1696 size_t prefixlen, suffixlen;
1697
1698 /* Trivial case */
1699 if (strcmp(pattern, hostname) == 0)
1700 return 1;
1701
Evan Broderbe554312013-06-27 00:05:25 -07001702 /* The rest of this logic is based on RFC 6125, section 6.4.3
1703 * (http://tools.ietf.org/html/rfc6125#section-6.4.3) */
1704
Emeric Bruna848dae2013-10-08 11:27:28 +02001705 pattern_wildcard = NULL;
1706 pattern_left_label_end = pattern;
1707 while (*pattern_left_label_end != '.') {
1708 switch (*pattern_left_label_end) {
1709 case 0:
1710 /* End of label not found */
1711 return 0;
1712 case '*':
1713 /* If there is more than one wildcards */
1714 if (pattern_wildcard)
1715 return 0;
1716 pattern_wildcard = pattern_left_label_end;
1717 break;
1718 }
1719 pattern_left_label_end++;
1720 }
1721
1722 /* If it's not trivial and there is no wildcard, it can't
1723 * match */
1724 if (!pattern_wildcard)
Evan Broderbe554312013-06-27 00:05:25 -07001725 return 0;
1726
1727 /* Make sure all labels match except the leftmost */
1728 hostname_left_label_end = strchr(hostname, '.');
1729 if (!hostname_left_label_end
1730 || strcmp(pattern_left_label_end, hostname_left_label_end) != 0)
1731 return 0;
1732
1733 /* Make sure the leftmost label of the hostname is long enough
1734 * that the wildcard can match */
Emeric Brun369da852013-10-08 11:39:35 +02001735 if (hostname_left_label_end - hostname < (pattern_left_label_end - pattern) - 1)
Evan Broderbe554312013-06-27 00:05:25 -07001736 return 0;
1737
1738 /* Finally compare the string on either side of the
1739 * wildcard */
1740 prefixlen = pattern_wildcard - pattern;
1741 suffixlen = pattern_left_label_end - (pattern_wildcard + 1);
Emeric Bruna848dae2013-10-08 11:27:28 +02001742 if ((prefixlen && (memcmp(pattern, hostname, prefixlen) != 0))
1743 || (suffixlen && (memcmp(pattern_wildcard + 1, hostname_left_label_end - suffixlen, suffixlen) != 0)))
Evan Broderbe554312013-06-27 00:05:25 -07001744 return 0;
1745
1746 return 1;
1747}
1748
1749static int ssl_sock_srv_verifycbk(int ok, X509_STORE_CTX *ctx)
1750{
1751 SSL *ssl;
1752 struct connection *conn;
1753 char *servername;
1754
1755 int depth;
1756 X509 *cert;
1757 STACK_OF(GENERAL_NAME) *alt_names;
1758 int i;
1759 X509_NAME *cert_subject;
1760 char *str;
1761
1762 if (ok == 0)
1763 return ok;
1764
1765 ssl = X509_STORE_CTX_get_ex_data(ctx, SSL_get_ex_data_X509_STORE_CTX_idx());
1766 conn = (struct connection *)SSL_get_app_data(ssl);
1767
1768 servername = objt_server(conn->target)->ssl_ctx.verify_host;
1769
1770 /* We only need to verify the CN on the actual server cert,
1771 * not the indirect CAs */
1772 depth = X509_STORE_CTX_get_error_depth(ctx);
1773 if (depth != 0)
1774 return ok;
1775
1776 /* At this point, the cert is *not* OK unless we can find a
1777 * hostname match */
1778 ok = 0;
1779
1780 cert = X509_STORE_CTX_get_current_cert(ctx);
1781 /* It seems like this might happen if verify peer isn't set */
1782 if (!cert)
1783 return ok;
1784
1785 alt_names = X509_get_ext_d2i(cert, NID_subject_alt_name, NULL, NULL);
1786 if (alt_names) {
1787 for (i = 0; !ok && i < sk_GENERAL_NAME_num(alt_names); i++) {
1788 GENERAL_NAME *name = sk_GENERAL_NAME_value(alt_names, i);
1789 if (name->type == GEN_DNS) {
Emeric Bruna33410c2013-09-17 15:47:48 +02001790#if OPENSSL_VERSION_NUMBER < 0x00907000L
1791 if (ASN1_STRING_to_UTF8((unsigned char **)&str, name->d.ia5) >= 0) {
1792#else
Evan Broderbe554312013-06-27 00:05:25 -07001793 if (ASN1_STRING_to_UTF8((unsigned char **)&str, name->d.dNSName) >= 0) {
Emeric Bruna33410c2013-09-17 15:47:48 +02001794#endif
Evan Broderbe554312013-06-27 00:05:25 -07001795 ok = ssl_sock_srv_hostcheck(str, servername);
1796 OPENSSL_free(str);
1797 }
1798 }
1799 }
Emeric Brun4ad50a42013-09-17 15:19:54 +02001800 sk_GENERAL_NAME_pop_free(alt_names, GENERAL_NAME_free);
Evan Broderbe554312013-06-27 00:05:25 -07001801 }
1802
1803 cert_subject = X509_get_subject_name(cert);
1804 i = -1;
1805 while (!ok && (i = X509_NAME_get_index_by_NID(cert_subject, NID_commonName, i)) != -1) {
1806 X509_NAME_ENTRY *entry = X509_NAME_get_entry(cert_subject, i);
1807 if (ASN1_STRING_to_UTF8((unsigned char **)&str, entry->value) >= 0) {
1808 ok = ssl_sock_srv_hostcheck(str, servername);
1809 OPENSSL_free(str);
1810 }
1811 }
1812
1813 return ok;
1814}
1815
Emeric Brun94324a42012-10-11 14:00:19 +02001816/* prepare ssl context from servers options. Returns an error count */
1817int ssl_sock_prepare_srv_ctx(struct server *srv, struct proxy *curproxy)
1818{
1819 int cfgerr = 0;
Remi Gacogneaf5c3da2014-05-19 10:29:58 +02001820 long options =
Emeric Brun94324a42012-10-11 14:00:19 +02001821 SSL_OP_ALL | /* all known workarounds for bugs */
1822 SSL_OP_NO_SSLv2 |
1823 SSL_OP_NO_COMPRESSION;
Remi Gacogneaf5c3da2014-05-19 10:29:58 +02001824 long mode =
Emeric Brun94324a42012-10-11 14:00:19 +02001825 SSL_MODE_ENABLE_PARTIAL_WRITE |
1826 SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER |
Willy Tarreau396a1862014-11-13 14:06:52 +01001827 SSL_MODE_RELEASE_BUFFERS |
1828 SSL_MODE_SMALL_BUFFERS;
Emeric Brun850efd52014-01-29 12:24:34 +01001829 int verify = SSL_VERIFY_NONE;
Emeric Brun94324a42012-10-11 14:00:19 +02001830
Thierry Fournier383085f2013-01-24 14:15:43 +01001831 /* Make sure openssl opens /dev/urandom before the chroot */
1832 if (!ssl_initialize_random()) {
1833 Alert("OpenSSL random data generator initialization failed.\n");
1834 cfgerr++;
1835 }
1836
Willy Tarreaufce03112015-01-15 21:32:40 +01001837 /* Automatic memory computations need to know we use SSL there */
1838 global.ssl_used_backend = 1;
1839
1840 /* Initiate SSL context for current server */
Emeric Brun94324a42012-10-11 14:00:19 +02001841 srv->ssl_ctx.reused_sess = NULL;
1842 if (srv->use_ssl)
1843 srv->xprt = &ssl_sock;
1844 if (srv->check.use_ssl)
Cyril Bonté9ce13112014-11-15 22:41:27 +01001845 srv->check.xprt = &ssl_sock;
Emeric Brun94324a42012-10-11 14:00:19 +02001846
1847 srv->ssl_ctx.ctx = SSL_CTX_new(SSLv23_client_method());
1848 if (!srv->ssl_ctx.ctx) {
1849 Alert("config : %s '%s', server '%s': unable to allocate ssl context.\n",
1850 proxy_type_str(curproxy), curproxy->id,
1851 srv->id);
1852 cfgerr++;
1853 return cfgerr;
1854 }
Emeric Bruna7aa3092012-10-26 12:58:00 +02001855 if (srv->ssl_ctx.client_crt) {
1856 if (SSL_CTX_use_PrivateKey_file(srv->ssl_ctx.ctx, srv->ssl_ctx.client_crt, SSL_FILETYPE_PEM) <= 0) {
1857 Alert("config : %s '%s', server '%s': unable to load SSL private key from PEM file '%s'.\n",
1858 proxy_type_str(curproxy), curproxy->id,
1859 srv->id, srv->ssl_ctx.client_crt);
1860 cfgerr++;
1861 }
1862 else if (SSL_CTX_use_certificate_chain_file(srv->ssl_ctx.ctx, srv->ssl_ctx.client_crt) <= 0) {
1863 Alert("config : %s '%s', server '%s': unable to load ssl certificate from PEM file '%s'.\n",
1864 proxy_type_str(curproxy), curproxy->id,
1865 srv->id, srv->ssl_ctx.client_crt);
1866 cfgerr++;
1867 }
1868 else if (SSL_CTX_check_private_key(srv->ssl_ctx.ctx) <= 0) {
1869 Alert("config : %s '%s', server '%s': inconsistencies between private key and certificate loaded from PEM file '%s'.\n",
1870 proxy_type_str(curproxy), curproxy->id,
1871 srv->id, srv->ssl_ctx.client_crt);
1872 cfgerr++;
1873 }
1874 }
Emeric Brun94324a42012-10-11 14:00:19 +02001875
1876 if (srv->ssl_ctx.options & SRV_SSL_O_NO_SSLV3)
1877 options |= SSL_OP_NO_SSLv3;
1878 if (srv->ssl_ctx.options & SRV_SSL_O_NO_TLSV10)
1879 options |= SSL_OP_NO_TLSv1;
1880 if (srv->ssl_ctx.options & SRV_SSL_O_NO_TLSV11)
1881 options |= SSL_OP_NO_TLSv1_1;
1882 if (srv->ssl_ctx.options & SRV_SSL_O_NO_TLSV12)
1883 options |= SSL_OP_NO_TLSv1_2;
Emeric Brunf9c5c472012-10-11 15:28:34 +02001884 if (srv->ssl_ctx.options & SRV_SSL_O_NO_TLS_TICKETS)
1885 options |= SSL_OP_NO_TICKET;
Emeric Brun94324a42012-10-11 14:00:19 +02001886 if (srv->ssl_ctx.options & SRV_SSL_O_USE_SSLV3)
1887 SSL_CTX_set_ssl_version(srv->ssl_ctx.ctx, SSLv3_client_method());
1888 if (srv->ssl_ctx.options & SRV_SSL_O_USE_TLSV10)
1889 SSL_CTX_set_ssl_version(srv->ssl_ctx.ctx, TLSv1_client_method());
1890#if SSL_OP_NO_TLSv1_1
1891 if (srv->ssl_ctx.options & SRV_SSL_O_USE_TLSV11)
1892 SSL_CTX_set_ssl_version(srv->ssl_ctx.ctx, TLSv1_1_client_method());
1893#endif
1894#if SSL_OP_NO_TLSv1_2
1895 if (srv->ssl_ctx.options & SRV_SSL_O_USE_TLSV12)
1896 SSL_CTX_set_ssl_version(srv->ssl_ctx.ctx, TLSv1_2_client_method());
1897#endif
1898
1899 SSL_CTX_set_options(srv->ssl_ctx.ctx, options);
1900 SSL_CTX_set_mode(srv->ssl_ctx.ctx, mode);
Emeric Brun850efd52014-01-29 12:24:34 +01001901
1902 if (global.ssl_server_verify == SSL_SERVER_VERIFY_REQUIRED)
1903 verify = SSL_VERIFY_PEER;
1904
1905 switch (srv->ssl_ctx.verify) {
1906 case SSL_SOCK_VERIFY_NONE:
1907 verify = SSL_VERIFY_NONE;
1908 break;
1909 case SSL_SOCK_VERIFY_REQUIRED:
1910 verify = SSL_VERIFY_PEER;
1911 break;
1912 }
Evan Broderbe554312013-06-27 00:05:25 -07001913 SSL_CTX_set_verify(srv->ssl_ctx.ctx,
Emeric Brun850efd52014-01-29 12:24:34 +01001914 verify,
Evan Broderbe554312013-06-27 00:05:25 -07001915 srv->ssl_ctx.verify_host ? ssl_sock_srv_verifycbk : NULL);
Emeric Brun850efd52014-01-29 12:24:34 +01001916 if (verify & SSL_VERIFY_PEER) {
Emeric Brunef42d922012-10-11 16:11:36 +02001917 if (srv->ssl_ctx.ca_file) {
1918 /* load CAfile to verify */
1919 if (!SSL_CTX_load_verify_locations(srv->ssl_ctx.ctx, srv->ssl_ctx.ca_file, NULL)) {
Willy Tarreau07ba08b2014-02-16 19:22:08 +01001920 Alert("Proxy '%s', server '%s' [%s:%d] unable to load CA 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.ca_file);
1923 cfgerr++;
1924 }
1925 }
Emeric Brun850efd52014-01-29 12:24:34 +01001926 else {
1927 if (global.ssl_server_verify == SSL_SERVER_VERIFY_REQUIRED)
Willy Tarreau07ba08b2014-02-16 19:22:08 +01001928 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 +01001929 curproxy->id, srv->id,
1930 srv->conf.file, srv->conf.line);
1931 else
Willy Tarreau07ba08b2014-02-16 19:22:08 +01001932 Alert("Proxy '%s', server '%s' [%s:%d] verify is enabled but no CA file specified.\n",
Emeric Brun850efd52014-01-29 12:24:34 +01001933 curproxy->id, srv->id,
1934 srv->conf.file, srv->conf.line);
1935 cfgerr++;
1936 }
Emeric Brunef42d922012-10-11 16:11:36 +02001937#ifdef X509_V_FLAG_CRL_CHECK
1938 if (srv->ssl_ctx.crl_file) {
1939 X509_STORE *store = SSL_CTX_get_cert_store(srv->ssl_ctx.ctx);
1940
1941 if (!store || !X509_STORE_load_locations(store, srv->ssl_ctx.crl_file, NULL)) {
Willy Tarreau07ba08b2014-02-16 19:22:08 +01001942 Alert("Proxy '%s', server '%s' [%s:%d] unable to configure CRL file '%s'.\n",
Emeric Brunef42d922012-10-11 16:11:36 +02001943 curproxy->id, srv->id,
1944 srv->conf.file, srv->conf.line, srv->ssl_ctx.crl_file);
1945 cfgerr++;
1946 }
1947 else {
1948 X509_STORE_set_flags(store, X509_V_FLAG_CRL_CHECK|X509_V_FLAG_CRL_CHECK_ALL);
1949 }
1950 }
1951#endif
1952 }
1953
Emeric Brun4f65bff2012-11-16 15:11:00 +01001954 if (global.tune.ssllifetime)
1955 SSL_CTX_set_timeout(srv->ssl_ctx.ctx, global.tune.ssllifetime);
1956
Emeric Brun94324a42012-10-11 14:00:19 +02001957 SSL_CTX_set_session_cache_mode(srv->ssl_ctx.ctx, SSL_SESS_CACHE_OFF);
1958 if (srv->ssl_ctx.ciphers &&
1959 !SSL_CTX_set_cipher_list(srv->ssl_ctx.ctx, srv->ssl_ctx.ciphers)) {
1960 Alert("Proxy '%s', server '%s' [%s:%d] : unable to set SSL cipher list to '%s'.\n",
1961 curproxy->id, srv->id,
1962 srv->conf.file, srv->conf.line, srv->ssl_ctx.ciphers);
1963 cfgerr++;
1964 }
1965
1966 return cfgerr;
1967}
1968
Willy Tarreau2a65ff02012-09-13 17:54:29 +02001969/* Walks down the two trees in bind_conf and prepares all certs. The pointer may
Emeric Brunfc0421f2012-09-07 17:30:07 +02001970 * be NULL, in which case nothing is done. Returns the number of errors
1971 * encountered.
1972 */
Willy Tarreau2a65ff02012-09-13 17:54:29 +02001973int ssl_sock_prepare_all_ctx(struct bind_conf *bind_conf, struct proxy *px)
Emeric Brunfc0421f2012-09-07 17:30:07 +02001974{
1975 struct ebmb_node *node;
1976 struct sni_ctx *sni;
1977 int err = 0;
1978
Willy Tarreau2a65ff02012-09-13 17:54:29 +02001979 if (!bind_conf || !bind_conf->is_ssl)
Emeric Brunfc0421f2012-09-07 17:30:07 +02001980 return 0;
1981
Willy Tarreaufce03112015-01-15 21:32:40 +01001982 /* Automatic memory computations need to know we use SSL there */
1983 global.ssl_used_frontend = 1;
1984
Emeric Brun0bed9942014-10-30 19:25:24 +01001985 if (bind_conf->default_ctx)
1986 err += ssl_sock_prepare_ctx(bind_conf, bind_conf->default_ctx, px);
1987
Willy Tarreau2a65ff02012-09-13 17:54:29 +02001988 node = ebmb_first(&bind_conf->sni_ctx);
Emeric Brunfc0421f2012-09-07 17:30:07 +02001989 while (node) {
1990 sni = ebmb_entry(node, struct sni_ctx, name);
Emeric Brun0bed9942014-10-30 19:25:24 +01001991 if (!sni->order && sni->ctx != bind_conf->default_ctx)
1992 /* only initialize the CTX on its first occurrence and
1993 if it is not the default_ctx */
Willy Tarreau2a65ff02012-09-13 17:54:29 +02001994 err += ssl_sock_prepare_ctx(bind_conf, sni->ctx, px);
Emeric Brunfc0421f2012-09-07 17:30:07 +02001995 node = ebmb_next(node);
1996 }
1997
Willy Tarreau2a65ff02012-09-13 17:54:29 +02001998 node = ebmb_first(&bind_conf->sni_w_ctx);
Emeric Brunfc0421f2012-09-07 17:30:07 +02001999 while (node) {
2000 sni = ebmb_entry(node, struct sni_ctx, name);
Emeric Brun0bed9942014-10-30 19:25:24 +01002001 if (!sni->order && sni->ctx != bind_conf->default_ctx)
2002 /* only initialize the CTX on its first occurrence and
2003 if it is not the default_ctx */
Willy Tarreau2a65ff02012-09-13 17:54:29 +02002004 err += ssl_sock_prepare_ctx(bind_conf, sni->ctx, px);
Emeric Brunfc0421f2012-09-07 17:30:07 +02002005 node = ebmb_next(node);
2006 }
2007 return err;
2008}
2009
Willy Tarreau2a65ff02012-09-13 17:54:29 +02002010/* Walks down the two trees in bind_conf and frees all the certs. The pointer may
Emeric Brunfc0421f2012-09-07 17:30:07 +02002011 * be NULL, in which case nothing is done. The default_ctx is nullified too.
2012 */
Willy Tarreau2a65ff02012-09-13 17:54:29 +02002013void ssl_sock_free_all_ctx(struct bind_conf *bind_conf)
Emeric Brunfc0421f2012-09-07 17:30:07 +02002014{
2015 struct ebmb_node *node, *back;
2016 struct sni_ctx *sni;
2017
Willy Tarreau2a65ff02012-09-13 17:54:29 +02002018 if (!bind_conf || !bind_conf->is_ssl)
Emeric Brunfc0421f2012-09-07 17:30:07 +02002019 return;
2020
Willy Tarreau2a65ff02012-09-13 17:54:29 +02002021 node = ebmb_first(&bind_conf->sni_ctx);
Emeric Brunfc0421f2012-09-07 17:30:07 +02002022 while (node) {
2023 sni = ebmb_entry(node, struct sni_ctx, name);
2024 back = ebmb_next(node);
2025 ebmb_delete(node);
2026 if (!sni->order) /* only free the CTX on its first occurrence */
2027 SSL_CTX_free(sni->ctx);
2028 free(sni);
2029 node = back;
2030 }
2031
Willy Tarreau2a65ff02012-09-13 17:54:29 +02002032 node = ebmb_first(&bind_conf->sni_w_ctx);
Emeric Brunfc0421f2012-09-07 17:30:07 +02002033 while (node) {
2034 sni = ebmb_entry(node, struct sni_ctx, name);
2035 back = ebmb_next(node);
2036 ebmb_delete(node);
2037 if (!sni->order) /* only free the CTX on its first occurrence */
2038 SSL_CTX_free(sni->ctx);
2039 free(sni);
2040 node = back;
2041 }
2042
Willy Tarreau2a65ff02012-09-13 17:54:29 +02002043 bind_conf->default_ctx = NULL;
Emeric Brune1f38db2012-09-03 20:36:47 +02002044}
2045
Emeric Brun46591952012-05-18 15:47:34 +02002046/*
2047 * This function is called if SSL * context is not yet allocated. The function
2048 * is designed to be called before any other data-layer operation and sets the
2049 * handshake flag on the connection. It is safe to call it multiple times.
2050 * It returns 0 on success and -1 in error case.
2051 */
2052static int ssl_sock_init(struct connection *conn)
2053{
2054 /* already initialized */
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02002055 if (conn->xprt_ctx)
Emeric Brun46591952012-05-18 15:47:34 +02002056 return 0;
2057
Willy Tarreau3c728722014-01-23 13:50:42 +01002058 if (!conn_ctrl_ready(conn))
Willy Tarreauf79c8172013-10-21 16:30:56 +02002059 return 0;
2060
Willy Tarreau20879a02012-12-03 16:32:10 +01002061 if (global.maxsslconn && sslconns >= global.maxsslconn) {
2062 conn->err_code = CO_ER_SSL_TOO_MANY;
Willy Tarreau403edff2012-09-06 11:58:37 +02002063 return -1;
Willy Tarreau20879a02012-12-03 16:32:10 +01002064 }
Willy Tarreau403edff2012-09-06 11:58:37 +02002065
Emeric Brun46591952012-05-18 15:47:34 +02002066 /* If it is in client mode initiate SSL session
2067 in connect state otherwise accept state */
Willy Tarreau3fdb3662012-11-12 00:42:33 +01002068 if (objt_server(conn->target)) {
Willy Tarreaufba03cd2014-11-13 13:48:58 +01002069 int may_retry = 1;
2070
2071 retry_connect:
Emeric Brun46591952012-05-18 15:47:34 +02002072 /* Alloc a new SSL session ctx */
Willy Tarreau3fdb3662012-11-12 00:42:33 +01002073 conn->xprt_ctx = SSL_new(objt_server(conn->target)->ssl_ctx.ctx);
Willy Tarreau20879a02012-12-03 16:32:10 +01002074 if (!conn->xprt_ctx) {
Willy Tarreaufba03cd2014-11-13 13:48:58 +01002075 if (may_retry--) {
2076 pool_gc2();
2077 goto retry_connect;
2078 }
Willy Tarreau20879a02012-12-03 16:32:10 +01002079 conn->err_code = CO_ER_SSL_NO_MEM;
Emeric Brun46591952012-05-18 15:47:34 +02002080 return -1;
Willy Tarreau20879a02012-12-03 16:32:10 +01002081 }
Emeric Brun46591952012-05-18 15:47:34 +02002082
Emeric Brun46591952012-05-18 15:47:34 +02002083 /* set fd on SSL session context */
Emeric Brun55476152014-11-12 17:35:37 +01002084 if (!SSL_set_fd(conn->xprt_ctx, conn->t.sock.fd)) {
2085 SSL_free(conn->xprt_ctx);
2086 conn->xprt_ctx = NULL;
Willy Tarreaufba03cd2014-11-13 13:48:58 +01002087 if (may_retry--) {
2088 pool_gc2();
2089 goto retry_connect;
2090 }
Emeric Brun55476152014-11-12 17:35:37 +01002091 conn->err_code = CO_ER_SSL_NO_MEM;
2092 return -1;
2093 }
Emeric Brun46591952012-05-18 15:47:34 +02002094
Evan Broderbe554312013-06-27 00:05:25 -07002095 /* set connection pointer */
Emeric Brun55476152014-11-12 17:35:37 +01002096 if (!SSL_set_app_data(conn->xprt_ctx, conn)) {
2097 SSL_free(conn->xprt_ctx);
2098 conn->xprt_ctx = NULL;
Willy Tarreaufba03cd2014-11-13 13:48:58 +01002099 if (may_retry--) {
2100 pool_gc2();
2101 goto retry_connect;
2102 }
Emeric Brun55476152014-11-12 17:35:37 +01002103 conn->err_code = CO_ER_SSL_NO_MEM;
2104 return -1;
2105 }
2106
2107 SSL_set_connect_state(conn->xprt_ctx);
2108 if (objt_server(conn->target)->ssl_ctx.reused_sess) {
2109 if(!SSL_set_session(conn->xprt_ctx, objt_server(conn->target)->ssl_ctx.reused_sess)) {
2110 SSL_SESSION_free(objt_server(conn->target)->ssl_ctx.reused_sess);
2111 objt_server(conn->target)->ssl_ctx.reused_sess = NULL;
2112 }
2113 }
Evan Broderbe554312013-06-27 00:05:25 -07002114
Emeric Brun46591952012-05-18 15:47:34 +02002115 /* leave init state and start handshake */
Willy Tarreau05737472012-09-04 08:03:39 +02002116 conn->flags |= CO_FL_SSL_WAIT_HS | CO_FL_WAIT_L6_CONN;
Willy Tarreau403edff2012-09-06 11:58:37 +02002117
2118 sslconns++;
Willy Tarreau71b734c2014-01-28 15:19:44 +01002119 totalsslconns++;
Emeric Brun46591952012-05-18 15:47:34 +02002120 return 0;
2121 }
Willy Tarreau3fdb3662012-11-12 00:42:33 +01002122 else if (objt_listener(conn->target)) {
Willy Tarreaufba03cd2014-11-13 13:48:58 +01002123 int may_retry = 1;
2124
2125 retry_accept:
Emeric Brun46591952012-05-18 15:47:34 +02002126 /* Alloc a new SSL session ctx */
Willy Tarreau3fdb3662012-11-12 00:42:33 +01002127 conn->xprt_ctx = SSL_new(objt_listener(conn->target)->bind_conf->default_ctx);
Willy Tarreau20879a02012-12-03 16:32:10 +01002128 if (!conn->xprt_ctx) {
Willy Tarreaufba03cd2014-11-13 13:48:58 +01002129 if (may_retry--) {
2130 pool_gc2();
2131 goto retry_accept;
2132 }
Willy Tarreau20879a02012-12-03 16:32:10 +01002133 conn->err_code = CO_ER_SSL_NO_MEM;
Emeric Brun46591952012-05-18 15:47:34 +02002134 return -1;
Willy Tarreau20879a02012-12-03 16:32:10 +01002135 }
Emeric Brun46591952012-05-18 15:47:34 +02002136
Emeric Brun46591952012-05-18 15:47:34 +02002137 /* set fd on SSL session context */
Emeric Brun55476152014-11-12 17:35:37 +01002138 if (!SSL_set_fd(conn->xprt_ctx, conn->t.sock.fd)) {
2139 SSL_free(conn->xprt_ctx);
2140 conn->xprt_ctx = NULL;
Willy Tarreaufba03cd2014-11-13 13:48:58 +01002141 if (may_retry--) {
2142 pool_gc2();
2143 goto retry_accept;
2144 }
Emeric Brun55476152014-11-12 17:35:37 +01002145 conn->err_code = CO_ER_SSL_NO_MEM;
2146 return -1;
2147 }
Emeric Brun46591952012-05-18 15:47:34 +02002148
Emeric Brune1f38db2012-09-03 20:36:47 +02002149 /* set connection pointer */
Emeric Brun55476152014-11-12 17:35:37 +01002150 if (!SSL_set_app_data(conn->xprt_ctx, conn)) {
2151 SSL_free(conn->xprt_ctx);
2152 conn->xprt_ctx = NULL;
Willy Tarreaufba03cd2014-11-13 13:48:58 +01002153 if (may_retry--) {
2154 pool_gc2();
2155 goto retry_accept;
2156 }
Emeric Brun55476152014-11-12 17:35:37 +01002157 conn->err_code = CO_ER_SSL_NO_MEM;
2158 return -1;
2159 }
2160
2161 SSL_set_accept_state(conn->xprt_ctx);
Emeric Brune1f38db2012-09-03 20:36:47 +02002162
Emeric Brun46591952012-05-18 15:47:34 +02002163 /* leave init state and start handshake */
Willy Tarreau05737472012-09-04 08:03:39 +02002164 conn->flags |= CO_FL_SSL_WAIT_HS | CO_FL_WAIT_L6_CONN;
Willy Tarreau403edff2012-09-06 11:58:37 +02002165
2166 sslconns++;
Willy Tarreau71b734c2014-01-28 15:19:44 +01002167 totalsslconns++;
Emeric Brun46591952012-05-18 15:47:34 +02002168 return 0;
2169 }
2170 /* don't know how to handle such a target */
Willy Tarreau20879a02012-12-03 16:32:10 +01002171 conn->err_code = CO_ER_SSL_NO_TARGET;
Emeric Brun46591952012-05-18 15:47:34 +02002172 return -1;
2173}
2174
2175
2176/* This is the callback which is used when an SSL handshake is pending. It
2177 * updates the FD status if it wants some polling before being called again.
2178 * It returns 0 if it fails in a fatal way or needs to poll to go further,
2179 * otherwise it returns non-zero and removes itself from the connection's
2180 * flags (the bit is provided in <flag> by the caller).
2181 */
2182int ssl_sock_handshake(struct connection *conn, unsigned int flag)
2183{
2184 int ret;
2185
Willy Tarreau3c728722014-01-23 13:50:42 +01002186 if (!conn_ctrl_ready(conn))
Willy Tarreauf79c8172013-10-21 16:30:56 +02002187 return 0;
2188
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02002189 if (!conn->xprt_ctx)
Emeric Brun46591952012-05-18 15:47:34 +02002190 goto out_error;
2191
Emeric Brun674b7432012-11-08 19:21:55 +01002192 /* If we use SSL_do_handshake to process a reneg initiated by
2193 * the remote peer, it sometimes returns SSL_ERROR_SSL.
2194 * Usually SSL_write and SSL_read are used and process implicitly
2195 * the reneg handshake.
2196 * Here we use SSL_peek as a workaround for reneg.
2197 */
2198 if ((conn->flags & CO_FL_CONNECTED) && SSL_renegotiate_pending(conn->xprt_ctx)) {
2199 char c;
2200
2201 ret = SSL_peek(conn->xprt_ctx, &c, 1);
2202 if (ret <= 0) {
2203 /* handshake may have not been completed, let's find why */
2204 ret = SSL_get_error(conn->xprt_ctx, ret);
2205 if (ret == SSL_ERROR_WANT_WRITE) {
2206 /* SSL handshake needs to write, L4 connection may not be ready */
2207 __conn_sock_stop_recv(conn);
Willy Tarreaue1f50c42014-01-22 20:02:06 +01002208 __conn_sock_want_send(conn);
2209 fd_cant_send(conn->t.sock.fd);
Emeric Brun674b7432012-11-08 19:21:55 +01002210 return 0;
2211 }
2212 else if (ret == SSL_ERROR_WANT_READ) {
2213 /* handshake may have been completed but we have
2214 * no more data to read.
2215 */
2216 if (!SSL_renegotiate_pending(conn->xprt_ctx)) {
2217 ret = 1;
2218 goto reneg_ok;
2219 }
2220 /* SSL handshake needs to read, L4 connection is ready */
2221 if (conn->flags & CO_FL_WAIT_L4_CONN)
2222 conn->flags &= ~CO_FL_WAIT_L4_CONN;
2223 __conn_sock_stop_send(conn);
Willy Tarreaue1f50c42014-01-22 20:02:06 +01002224 __conn_sock_want_recv(conn);
2225 fd_cant_recv(conn->t.sock.fd);
Emeric Brun674b7432012-11-08 19:21:55 +01002226 return 0;
2227 }
2228 else if (ret == SSL_ERROR_SYSCALL) {
2229 /* if errno is null, then connection was successfully established */
2230 if (!errno && conn->flags & CO_FL_WAIT_L4_CONN)
2231 conn->flags &= ~CO_FL_WAIT_L4_CONN;
Willy Tarreau20879a02012-12-03 16:32:10 +01002232 if (!conn->err_code) {
Emeric Brun29f037d2014-04-25 19:05:36 +02002233 if (!((SSL *)conn->xprt_ctx)->packet_length) {
2234 if (!errno) {
2235 if (conn->xprt_st & SSL_SOCK_RECV_HEARTBEAT)
2236 conn->err_code = CO_ER_SSL_HANDSHAKE_HB;
2237 else
2238 conn->err_code = CO_ER_SSL_EMPTY;
2239 }
2240 else {
2241 if (conn->xprt_st & SSL_SOCK_RECV_HEARTBEAT)
2242 conn->err_code = CO_ER_SSL_HANDSHAKE_HB;
2243 else
2244 conn->err_code = CO_ER_SSL_ABORT;
2245 }
2246 }
2247 else {
2248 if (conn->xprt_st & SSL_SOCK_RECV_HEARTBEAT)
2249 conn->err_code = CO_ER_SSL_HANDSHAKE_HB;
Willy Tarreau20879a02012-12-03 16:32:10 +01002250 else
Emeric Brun29f037d2014-04-25 19:05:36 +02002251 conn->err_code = CO_ER_SSL_HANDSHAKE;
2252 }
Willy Tarreau20879a02012-12-03 16:32:10 +01002253 }
Emeric Brun674b7432012-11-08 19:21:55 +01002254 goto out_error;
2255 }
2256 else {
2257 /* Fail on all other handshake errors */
2258 /* Note: OpenSSL may leave unread bytes in the socket's
2259 * buffer, causing an RST to be emitted upon close() on
2260 * TCP sockets. We first try to drain possibly pending
2261 * data to avoid this as much as possible.
2262 */
Willy Tarreau46be2e52014-01-20 12:10:52 +01002263 conn_drain(conn);
Willy Tarreau20879a02012-12-03 16:32:10 +01002264 if (!conn->err_code)
Willy Tarreauf51c6982014-04-25 20:02:39 +02002265 conn->err_code = (conn->xprt_st & SSL_SOCK_RECV_HEARTBEAT) ?
2266 CO_ER_SSL_KILLED_HB : CO_ER_SSL_HANDSHAKE;
Emeric Brun674b7432012-11-08 19:21:55 +01002267 goto out_error;
2268 }
2269 }
2270 /* read some data: consider handshake completed */
2271 goto reneg_ok;
2272 }
2273
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02002274 ret = SSL_do_handshake(conn->xprt_ctx);
Emeric Brun46591952012-05-18 15:47:34 +02002275 if (ret != 1) {
2276 /* handshake did not complete, let's find why */
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02002277 ret = SSL_get_error(conn->xprt_ctx, ret);
Emeric Brun46591952012-05-18 15:47:34 +02002278
2279 if (ret == SSL_ERROR_WANT_WRITE) {
2280 /* SSL handshake needs to write, L4 connection may not be ready */
2281 __conn_sock_stop_recv(conn);
Willy Tarreaue1f50c42014-01-22 20:02:06 +01002282 __conn_sock_want_send(conn);
2283 fd_cant_send(conn->t.sock.fd);
Emeric Brun46591952012-05-18 15:47:34 +02002284 return 0;
2285 }
2286 else if (ret == SSL_ERROR_WANT_READ) {
2287 /* SSL handshake needs to read, L4 connection is ready */
2288 if (conn->flags & CO_FL_WAIT_L4_CONN)
2289 conn->flags &= ~CO_FL_WAIT_L4_CONN;
2290 __conn_sock_stop_send(conn);
Willy Tarreaue1f50c42014-01-22 20:02:06 +01002291 __conn_sock_want_recv(conn);
2292 fd_cant_recv(conn->t.sock.fd);
Emeric Brun46591952012-05-18 15:47:34 +02002293 return 0;
2294 }
Willy Tarreau89230192012-09-28 20:22:13 +02002295 else if (ret == SSL_ERROR_SYSCALL) {
2296 /* if errno is null, then connection was successfully established */
2297 if (!errno && conn->flags & CO_FL_WAIT_L4_CONN)
2298 conn->flags &= ~CO_FL_WAIT_L4_CONN;
Willy Tarreau20879a02012-12-03 16:32:10 +01002299
Emeric Brun29f037d2014-04-25 19:05:36 +02002300 if (!((SSL *)conn->xprt_ctx)->packet_length) {
2301 if (!errno) {
2302 if (conn->xprt_st & SSL_SOCK_RECV_HEARTBEAT)
2303 conn->err_code = CO_ER_SSL_HANDSHAKE_HB;
2304 else
2305 conn->err_code = CO_ER_SSL_EMPTY;
2306 }
2307 else {
2308 if (conn->xprt_st & SSL_SOCK_RECV_HEARTBEAT)
2309 conn->err_code = CO_ER_SSL_HANDSHAKE_HB;
2310 else
2311 conn->err_code = CO_ER_SSL_ABORT;
2312 }
2313 }
2314 else {
2315 if (conn->xprt_st & SSL_SOCK_RECV_HEARTBEAT)
2316 conn->err_code = CO_ER_SSL_HANDSHAKE_HB;
Willy Tarreau20879a02012-12-03 16:32:10 +01002317 else
Emeric Brun29f037d2014-04-25 19:05:36 +02002318 conn->err_code = CO_ER_SSL_HANDSHAKE;
2319 }
Willy Tarreau89230192012-09-28 20:22:13 +02002320 goto out_error;
2321 }
Emeric Brun46591952012-05-18 15:47:34 +02002322 else {
2323 /* Fail on all other handshake errors */
Willy Tarreau566dc552012-10-19 20:52:18 +02002324 /* Note: OpenSSL may leave unread bytes in the socket's
2325 * buffer, causing an RST to be emitted upon close() on
2326 * TCP sockets. We first try to drain possibly pending
2327 * data to avoid this as much as possible.
2328 */
Willy Tarreau46be2e52014-01-20 12:10:52 +01002329 conn_drain(conn);
Willy Tarreau20879a02012-12-03 16:32:10 +01002330 if (!conn->err_code)
Willy Tarreauf51c6982014-04-25 20:02:39 +02002331 conn->err_code = (conn->xprt_st & SSL_SOCK_RECV_HEARTBEAT) ?
2332 CO_ER_SSL_KILLED_HB : CO_ER_SSL_HANDSHAKE;
Emeric Brun46591952012-05-18 15:47:34 +02002333 goto out_error;
2334 }
2335 }
2336
Emeric Brun674b7432012-11-08 19:21:55 +01002337reneg_ok:
2338
Emeric Brun46591952012-05-18 15:47:34 +02002339 /* Handshake succeeded */
Willy Tarreau0c9c2722014-05-28 12:28:58 +02002340 if (!SSL_session_reused(conn->xprt_ctx)) {
2341 if (objt_server(conn->target)) {
2342 update_freq_ctr(&global.ssl_be_keys_per_sec, 1);
2343 if (global.ssl_be_keys_per_sec.curr_ctr > global.ssl_be_keys_max)
2344 global.ssl_be_keys_max = global.ssl_be_keys_per_sec.curr_ctr;
2345
Emeric Brun46591952012-05-18 15:47:34 +02002346 /* check if session was reused, if not store current session on server for reuse */
Willy Tarreau3fdb3662012-11-12 00:42:33 +01002347 if (objt_server(conn->target)->ssl_ctx.reused_sess)
2348 SSL_SESSION_free(objt_server(conn->target)->ssl_ctx.reused_sess);
Emeric Brun46591952012-05-18 15:47:34 +02002349
Willy Tarreau2a3fb1c2015-02-05 16:47:07 +01002350 if (!(objt_server(conn->target)->ssl_ctx.options & SRV_SSL_O_NO_REUSE))
2351 objt_server(conn->target)->ssl_ctx.reused_sess = SSL_get1_session(conn->xprt_ctx);
Emeric Brun46591952012-05-18 15:47:34 +02002352 }
Willy Tarreau0c9c2722014-05-28 12:28:58 +02002353 else {
2354 update_freq_ctr(&global.ssl_fe_keys_per_sec, 1);
2355 if (global.ssl_fe_keys_per_sec.curr_ctr > global.ssl_fe_keys_max)
2356 global.ssl_fe_keys_max = global.ssl_fe_keys_per_sec.curr_ctr;
2357 }
Emeric Brun46591952012-05-18 15:47:34 +02002358 }
2359
2360 /* The connection is now established at both layers, it's time to leave */
2361 conn->flags &= ~(flag | CO_FL_WAIT_L4_CONN | CO_FL_WAIT_L6_CONN);
2362 return 1;
2363
2364 out_error:
Emeric Brun644cde02012-12-14 11:21:13 +01002365 /* Clear openssl global errors stack */
2366 ERR_clear_error();
2367
Emeric Brun9fa89732012-10-04 17:09:56 +02002368 /* free resumed session if exists */
Willy Tarreau3fdb3662012-11-12 00:42:33 +01002369 if (objt_server(conn->target) && objt_server(conn->target)->ssl_ctx.reused_sess) {
2370 SSL_SESSION_free(objt_server(conn->target)->ssl_ctx.reused_sess);
2371 objt_server(conn->target)->ssl_ctx.reused_sess = NULL;
Emeric Brun9fa89732012-10-04 17:09:56 +02002372 }
2373
Emeric Brun46591952012-05-18 15:47:34 +02002374 /* Fail on all other handshake errors */
2375 conn->flags |= CO_FL_ERROR;
Willy Tarreau20879a02012-12-03 16:32:10 +01002376 if (!conn->err_code)
2377 conn->err_code = CO_ER_SSL_HANDSHAKE;
Emeric Brun46591952012-05-18 15:47:34 +02002378 return 0;
2379}
2380
2381/* Receive up to <count> bytes from connection <conn>'s socket and store them
Willy Tarreauabf08d92014-01-14 11:31:27 +01002382 * into buffer <buf>. Only one call to recv() is performed, unless the
Emeric Brun46591952012-05-18 15:47:34 +02002383 * buffer wraps, in which case a second call may be performed. The connection's
2384 * flags are updated with whatever special event is detected (error, read0,
2385 * empty). The caller is responsible for taking care of those events and
2386 * avoiding the call if inappropriate. The function does not call the
2387 * connection's polling update function, so the caller is responsible for this.
2388 */
2389static int ssl_sock_to_buf(struct connection *conn, struct buffer *buf, int count)
2390{
2391 int ret, done = 0;
Willy Tarreauabf08d92014-01-14 11:31:27 +01002392 int try;
Emeric Brun46591952012-05-18 15:47:34 +02002393
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02002394 if (!conn->xprt_ctx)
Emeric Brun46591952012-05-18 15:47:34 +02002395 goto out_error;
2396
2397 if (conn->flags & CO_FL_HANDSHAKE)
2398 /* a handshake was requested */
2399 return 0;
2400
Willy Tarreauabf08d92014-01-14 11:31:27 +01002401 /* let's realign the buffer to optimize I/O */
2402 if (buffer_empty(buf))
Emeric Brun46591952012-05-18 15:47:34 +02002403 buf->p = buf->data;
Emeric Brun46591952012-05-18 15:47:34 +02002404
2405 /* read the largest possible block. For this, we perform only one call
2406 * to recv() unless the buffer wraps and we exactly fill the first hunk,
2407 * in which case we accept to do it once again. A new attempt is made on
2408 * EINTR too.
2409 */
Willy Tarreau00b0fb92014-01-17 11:09:40 +01002410 while (count > 0) {
Willy Tarreauabf08d92014-01-14 11:31:27 +01002411 /* first check if we have some room after p+i */
2412 try = buf->data + buf->size - (buf->p + buf->i);
2413 /* otherwise continue between data and p-o */
2414 if (try <= 0) {
2415 try = buf->p - (buf->data + buf->o);
2416 if (try <= 0)
2417 break;
2418 }
2419 if (try > count)
2420 try = count;
2421
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02002422 ret = SSL_read(conn->xprt_ctx, bi_end(buf), try);
Emeric Brune1f38db2012-09-03 20:36:47 +02002423 if (conn->flags & CO_FL_ERROR) {
2424 /* CO_FL_ERROR may be set by ssl_sock_infocbk */
Emeric Brun644cde02012-12-14 11:21:13 +01002425 goto out_error;
Emeric Brune1f38db2012-09-03 20:36:47 +02002426 }
Emeric Brun46591952012-05-18 15:47:34 +02002427 if (ret > 0) {
2428 buf->i += ret;
2429 done += ret;
2430 if (ret < try)
2431 break;
2432 count -= ret;
Emeric Brun46591952012-05-18 15:47:34 +02002433 }
2434 else if (ret == 0) {
Emeric Brun644cde02012-12-14 11:21:13 +01002435 ret = SSL_get_error(conn->xprt_ctx, ret);
2436 if (ret != SSL_ERROR_ZERO_RETURN) {
Emeric Brun1c646862012-12-14 12:33:41 +01002437 /* error on protocol or underlying transport */
2438 if ((ret != SSL_ERROR_SYSCALL)
2439 || (errno && (errno != EAGAIN)))
2440 conn->flags |= CO_FL_ERROR;
2441
Emeric Brun644cde02012-12-14 11:21:13 +01002442 /* Clear openssl global errors stack */
2443 ERR_clear_error();
2444 }
Emeric Brun46591952012-05-18 15:47:34 +02002445 goto read0;
2446 }
2447 else {
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02002448 ret = SSL_get_error(conn->xprt_ctx, ret);
Emeric Brun46591952012-05-18 15:47:34 +02002449 if (ret == SSL_ERROR_WANT_WRITE) {
Emeric Brun8af8dd12012-11-08 17:56:20 +01002450 /* handshake is running, and it needs to enable write */
Emeric Brun46591952012-05-18 15:47:34 +02002451 conn->flags |= CO_FL_SSL_WAIT_HS;
Emeric Brun8af8dd12012-11-08 17:56:20 +01002452 __conn_sock_want_send(conn);
Emeric Brun46591952012-05-18 15:47:34 +02002453 break;
2454 }
2455 else if (ret == SSL_ERROR_WANT_READ) {
Emeric Brun282a76a2012-11-08 18:02:56 +01002456 if (SSL_renegotiate_pending(conn->xprt_ctx)) {
2457 /* handshake is running, and it may need to re-enable read */
2458 conn->flags |= CO_FL_SSL_WAIT_HS;
2459 __conn_sock_want_recv(conn);
2460 break;
2461 }
Emeric Brun46591952012-05-18 15:47:34 +02002462 /* we need to poll for retry a read later */
Willy Tarreaue1f50c42014-01-22 20:02:06 +01002463 fd_cant_recv(conn->t.sock.fd);
Emeric Brun46591952012-05-18 15:47:34 +02002464 break;
2465 }
2466 /* otherwise it's a real error */
2467 goto out_error;
2468 }
2469 }
2470 return done;
2471
2472 read0:
2473 conn_sock_read0(conn);
2474 return done;
2475 out_error:
Emeric Brun644cde02012-12-14 11:21:13 +01002476 /* Clear openssl global errors stack */
2477 ERR_clear_error();
2478
Emeric Brun46591952012-05-18 15:47:34 +02002479 conn->flags |= CO_FL_ERROR;
2480 return done;
2481}
2482
2483
2484/* Send all pending bytes from buffer <buf> to connection <conn>'s socket.
Willy Tarreau1049b1f2014-02-02 01:51:17 +01002485 * <flags> may contain some CO_SFL_* flags to hint the system about other
2486 * pending data for example, but this flag is ignored at the moment.
Emeric Brun46591952012-05-18 15:47:34 +02002487 * Only one call to send() is performed, unless the buffer wraps, in which case
2488 * a second call may be performed. The connection's flags are updated with
2489 * whatever special event is detected (error, empty). The caller is responsible
2490 * for taking care of those events and avoiding the call if inappropriate. The
2491 * function does not call the connection's polling update function, so the caller
2492 * is responsible for this.
2493 */
2494static int ssl_sock_from_buf(struct connection *conn, struct buffer *buf, int flags)
2495{
2496 int ret, try, done;
2497
2498 done = 0;
2499
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02002500 if (!conn->xprt_ctx)
Emeric Brun46591952012-05-18 15:47:34 +02002501 goto out_error;
2502
2503 if (conn->flags & CO_FL_HANDSHAKE)
2504 /* a handshake was requested */
2505 return 0;
2506
2507 /* send the largest possible block. For this we perform only one call
2508 * to send() unless the buffer wraps and we exactly fill the first hunk,
2509 * in which case we accept to do it once again.
2510 */
2511 while (buf->o) {
Kevin Hestercad82342013-05-30 15:12:41 -07002512 try = bo_contig_data(buf);
Willy Tarreaubfd59462013-02-21 07:46:09 +01002513
Willy Tarreau7bed9452014-02-02 02:00:24 +01002514 if (!(flags & CO_SFL_STREAMER) &&
Willy Tarreau518cedd2014-02-17 15:43:01 +01002515 !(conn->xprt_st & SSL_SOCK_SEND_UNLIMITED) &&
2516 global.tune.ssl_max_record && try > global.tune.ssl_max_record) {
Willy Tarreaubfd59462013-02-21 07:46:09 +01002517 try = global.tune.ssl_max_record;
Willy Tarreau518cedd2014-02-17 15:43:01 +01002518 }
2519 else {
2520 /* we need to keep the information about the fact that
2521 * we're not limiting the upcoming send(), because if it
2522 * fails, we'll have to retry with at least as many data.
2523 */
2524 conn->xprt_st |= SSL_SOCK_SEND_UNLIMITED;
2525 }
Willy Tarreaubfd59462013-02-21 07:46:09 +01002526
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02002527 ret = SSL_write(conn->xprt_ctx, bo_ptr(buf), try);
Willy Tarreau518cedd2014-02-17 15:43:01 +01002528
Emeric Brune1f38db2012-09-03 20:36:47 +02002529 if (conn->flags & CO_FL_ERROR) {
2530 /* CO_FL_ERROR may be set by ssl_sock_infocbk */
Emeric Brun644cde02012-12-14 11:21:13 +01002531 goto out_error;
Emeric Brune1f38db2012-09-03 20:36:47 +02002532 }
Emeric Brun46591952012-05-18 15:47:34 +02002533 if (ret > 0) {
Willy Tarreau518cedd2014-02-17 15:43:01 +01002534 conn->xprt_st &= ~SSL_SOCK_SEND_UNLIMITED;
2535
Emeric Brun46591952012-05-18 15:47:34 +02002536 buf->o -= ret;
2537 done += ret;
2538
Willy Tarreau5fb38032012-12-16 19:39:09 +01002539 if (likely(buffer_empty(buf)))
Emeric Brun46591952012-05-18 15:47:34 +02002540 /* optimize data alignment in the buffer */
2541 buf->p = buf->data;
2542
2543 /* if the system buffer is full, don't insist */
2544 if (ret < try)
2545 break;
2546 }
2547 else {
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02002548 ret = SSL_get_error(conn->xprt_ctx, ret);
Emeric Brun46591952012-05-18 15:47:34 +02002549 if (ret == SSL_ERROR_WANT_WRITE) {
Emeric Brun282a76a2012-11-08 18:02:56 +01002550 if (SSL_renegotiate_pending(conn->xprt_ctx)) {
2551 /* handshake is running, and it may need to re-enable write */
2552 conn->flags |= CO_FL_SSL_WAIT_HS;
2553 __conn_sock_want_send(conn);
2554 break;
2555 }
Emeric Brun46591952012-05-18 15:47:34 +02002556 /* we need to poll to retry a write later */
Willy Tarreaue1f50c42014-01-22 20:02:06 +01002557 fd_cant_send(conn->t.sock.fd);
Emeric Brun46591952012-05-18 15:47:34 +02002558 break;
2559 }
2560 else if (ret == SSL_ERROR_WANT_READ) {
Emeric Brun8af8dd12012-11-08 17:56:20 +01002561 /* handshake is running, and it needs to enable read */
Emeric Brun46591952012-05-18 15:47:34 +02002562 conn->flags |= CO_FL_SSL_WAIT_HS;
Emeric Brun8af8dd12012-11-08 17:56:20 +01002563 __conn_sock_want_recv(conn);
Emeric Brun46591952012-05-18 15:47:34 +02002564 break;
2565 }
2566 goto out_error;
2567 }
2568 }
2569 return done;
2570
2571 out_error:
Emeric Brun644cde02012-12-14 11:21:13 +01002572 /* Clear openssl global errors stack */
2573 ERR_clear_error();
2574
Emeric Brun46591952012-05-18 15:47:34 +02002575 conn->flags |= CO_FL_ERROR;
2576 return done;
2577}
2578
Emeric Brun46591952012-05-18 15:47:34 +02002579static void ssl_sock_close(struct connection *conn) {
2580
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02002581 if (conn->xprt_ctx) {
2582 SSL_free(conn->xprt_ctx);
2583 conn->xprt_ctx = NULL;
Willy Tarreau403edff2012-09-06 11:58:37 +02002584 sslconns--;
Emeric Brun46591952012-05-18 15:47:34 +02002585 }
Emeric Brun46591952012-05-18 15:47:34 +02002586}
2587
2588/* This function tries to perform a clean shutdown on an SSL connection, and in
2589 * any case, flags the connection as reusable if no handshake was in progress.
2590 */
2591static void ssl_sock_shutw(struct connection *conn, int clean)
2592{
2593 if (conn->flags & CO_FL_HANDSHAKE)
2594 return;
2595 /* no handshake was in progress, try a clean ssl shutdown */
Emeric Brun644cde02012-12-14 11:21:13 +01002596 if (clean && (SSL_shutdown(conn->xprt_ctx) <= 0)) {
2597 /* Clear openssl global errors stack */
2598 ERR_clear_error();
2599 }
Emeric Brun46591952012-05-18 15:47:34 +02002600
2601 /* force flag on ssl to keep session in cache regardless shutdown result */
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02002602 SSL_set_shutdown(conn->xprt_ctx, SSL_SENT_SHUTDOWN);
Emeric Brun46591952012-05-18 15:47:34 +02002603}
2604
Willy Tarreauffc3fcd2012-10-12 20:17:54 +02002605/* used for logging, may be changed for a sample fetch later */
2606const char *ssl_sock_get_cipher_name(struct connection *conn)
2607{
2608 if (!conn->xprt && !conn->xprt_ctx)
2609 return NULL;
2610 return SSL_get_cipher_name(conn->xprt_ctx);
2611}
2612
2613/* used for logging, may be changed for a sample fetch later */
2614const char *ssl_sock_get_proto_version(struct connection *conn)
2615{
2616 if (!conn->xprt && !conn->xprt_ctx)
2617 return NULL;
2618 return SSL_get_version(conn->xprt_ctx);
2619}
2620
Willy Tarreau8d598402012-10-22 17:58:39 +02002621/* Extract a serial from a cert, and copy it to a chunk.
2622 * Returns 1 if serial is found and copied, 0 if no serial found and
2623 * -1 if output is not large enough.
2624 */
2625static int
2626ssl_sock_get_serial(X509 *crt, struct chunk *out)
2627{
2628 ASN1_INTEGER *serial;
2629
2630 serial = X509_get_serialNumber(crt);
2631 if (!serial)
2632 return 0;
2633
2634 if (out->size < serial->length)
2635 return -1;
2636
2637 memcpy(out->str, serial->data, serial->length);
2638 out->len = serial->length;
2639 return 1;
2640}
2641
Emeric Brun43e79582014-10-29 19:03:26 +01002642/* Extract a cert to der, and copy it to a chunk.
2643 * Returns 1 if cert is found and copied, 0 on der convertion failure and
2644 * -1 if output is not large enough.
2645 */
2646static int
2647ssl_sock_crt2der(X509 *crt, struct chunk *out)
2648{
2649 int len;
2650 unsigned char *p = (unsigned char *)out->str;;
2651
2652 len =i2d_X509(crt, NULL);
2653 if (len <= 0)
2654 return 1;
2655
2656 if (out->size < len)
2657 return -1;
2658
2659 i2d_X509(crt,&p);
2660 out->len = len;
2661 return 1;
2662}
2663
Emeric Brunce5ad802012-10-22 14:11:22 +02002664
2665/* Copy Date in ASN1_UTCTIME format in struct chunk out.
2666 * Returns 1 if serial is found and copied, 0 if no valid time found
2667 * and -1 if output is not large enough.
2668 */
2669static int
2670ssl_sock_get_time(ASN1_TIME *tm, struct chunk *out)
2671{
2672 if (tm->type == V_ASN1_GENERALIZEDTIME) {
2673 ASN1_GENERALIZEDTIME *gentm = (ASN1_GENERALIZEDTIME *)tm;
2674
2675 if (gentm->length < 12)
2676 return 0;
2677 if (gentm->data[0] != 0x32 || gentm->data[1] != 0x30)
2678 return 0;
2679 if (out->size < gentm->length-2)
2680 return -1;
2681
2682 memcpy(out->str, gentm->data+2, gentm->length-2);
2683 out->len = gentm->length-2;
2684 return 1;
2685 }
2686 else if (tm->type == V_ASN1_UTCTIME) {
2687 ASN1_UTCTIME *utctm = (ASN1_UTCTIME *)tm;
2688
2689 if (utctm->length < 10)
2690 return 0;
2691 if (utctm->data[0] >= 0x35)
2692 return 0;
2693 if (out->size < utctm->length)
2694 return -1;
2695
2696 memcpy(out->str, utctm->data, utctm->length);
2697 out->len = utctm->length;
2698 return 1;
2699 }
2700
2701 return 0;
2702}
2703
Emeric Brun87855892012-10-17 17:39:35 +02002704/* Extract an entry from a X509_NAME and copy its value to an output chunk.
2705 * Returns 1 if entry found, 0 if entry not found, or -1 if output not large enough.
2706 */
2707static int
2708ssl_sock_get_dn_entry(X509_NAME *a, const struct chunk *entry, int pos, struct chunk *out)
2709{
2710 X509_NAME_ENTRY *ne;
2711 int i, j, n;
2712 int cur = 0;
2713 const char *s;
2714 char tmp[128];
2715
2716 out->len = 0;
2717 for (i = 0; i < sk_X509_NAME_ENTRY_num(a->entries); i++) {
2718 if (pos < 0)
2719 j = (sk_X509_NAME_ENTRY_num(a->entries)-1) - i;
2720 else
2721 j = i;
2722
2723 ne = sk_X509_NAME_ENTRY_value(a->entries, j);
2724 n = OBJ_obj2nid(ne->object);
2725 if ((n == NID_undef) || ((s = OBJ_nid2sn(n)) == NULL)) {
2726 i2t_ASN1_OBJECT(tmp, sizeof(tmp), ne->object);
2727 s = tmp;
2728 }
2729
2730 if (chunk_strcasecmp(entry, s) != 0)
2731 continue;
2732
2733 if (pos < 0)
2734 cur--;
2735 else
2736 cur++;
2737
2738 if (cur != pos)
2739 continue;
2740
2741 if (ne->value->length > out->size)
2742 return -1;
2743
2744 memcpy(out->str, ne->value->data, ne->value->length);
2745 out->len = ne->value->length;
2746 return 1;
2747 }
2748
2749 return 0;
2750
2751}
2752
2753/* Extract and format full DN from a X509_NAME and copy result into a chunk
2754 * Returns 1 if dn entries exits, 0 if no dn entry found or -1 if output is not large enough.
2755 */
2756static int
2757ssl_sock_get_dn_oneline(X509_NAME *a, struct chunk *out)
2758{
2759 X509_NAME_ENTRY *ne;
2760 int i, n, ln;
2761 int l = 0;
2762 const char *s;
2763 char *p;
2764 char tmp[128];
2765
2766 out->len = 0;
2767 p = out->str;
2768 for (i = 0; i < sk_X509_NAME_ENTRY_num(a->entries); i++) {
2769 ne = sk_X509_NAME_ENTRY_value(a->entries, i);
2770 n = OBJ_obj2nid(ne->object);
2771 if ((n == NID_undef) || ((s = OBJ_nid2sn(n)) == NULL)) {
2772 i2t_ASN1_OBJECT(tmp, sizeof(tmp), ne->object);
2773 s = tmp;
2774 }
2775 ln = strlen(s);
2776
2777 l += 1 + ln + 1 + ne->value->length;
2778 if (l > out->size)
2779 return -1;
2780 out->len = l;
2781
2782 *(p++)='/';
2783 memcpy(p, s, ln);
2784 p += ln;
2785 *(p++)='=';
2786 memcpy(p, ne->value->data, ne->value->length);
2787 p += ne->value->length;
2788 }
2789
2790 if (!out->len)
2791 return 0;
2792
2793 return 1;
2794}
2795
David Safb76832014-05-08 23:42:08 -04002796char *ssl_sock_get_version(struct connection *conn)
2797{
2798 if (!ssl_sock_is_ssl(conn))
2799 return NULL;
2800
2801 return (char *)SSL_get_version(conn->xprt_ctx);
2802}
2803
Emeric Brun0abf8362014-06-24 18:26:41 +02002804/* Extract peer certificate's common name into the chunk dest
2805 * Returns
2806 * the len of the extracted common name
2807 * or 0 if no CN found in DN
2808 * or -1 on error case (i.e. no peer certificate)
2809 */
2810int ssl_sock_get_remote_common_name(struct connection *conn, struct chunk *dest)
David Safb76832014-05-08 23:42:08 -04002811{
2812 X509 *crt = NULL;
2813 X509_NAME *name;
David Safb76832014-05-08 23:42:08 -04002814 const char find_cn[] = "CN";
2815 const struct chunk find_cn_chunk = {
2816 .str = (char *)&find_cn,
2817 .len = sizeof(find_cn)-1
2818 };
Emeric Brun0abf8362014-06-24 18:26:41 +02002819 int result = -1;
David Safb76832014-05-08 23:42:08 -04002820
2821 if (!ssl_sock_is_ssl(conn))
Emeric Brun0abf8362014-06-24 18:26:41 +02002822 goto out;
David Safb76832014-05-08 23:42:08 -04002823
2824 /* SSL_get_peer_certificate, it increase X509 * ref count */
2825 crt = SSL_get_peer_certificate(conn->xprt_ctx);
2826 if (!crt)
2827 goto out;
2828
2829 name = X509_get_subject_name(crt);
2830 if (!name)
2831 goto out;
David Safb76832014-05-08 23:42:08 -04002832
Emeric Brun0abf8362014-06-24 18:26:41 +02002833 result = ssl_sock_get_dn_entry(name, &find_cn_chunk, 1, dest);
2834out:
David Safb76832014-05-08 23:42:08 -04002835 if (crt)
2836 X509_free(crt);
2837
2838 return result;
2839}
2840
Dave McCowan328fb582014-07-30 10:39:13 -04002841/* returns 1 if client passed a certificate for this session, 0 if not */
2842int ssl_sock_get_cert_used_sess(struct connection *conn)
2843{
2844 X509 *crt = NULL;
2845
2846 if (!ssl_sock_is_ssl(conn))
2847 return 0;
2848
2849 /* SSL_get_peer_certificate, it increase X509 * ref count */
2850 crt = SSL_get_peer_certificate(conn->xprt_ctx);
2851 if (!crt)
2852 return 0;
2853
2854 X509_free(crt);
2855 return 1;
2856}
2857
2858/* returns 1 if client passed a certificate for this connection, 0 if not */
2859int ssl_sock_get_cert_used_conn(struct connection *conn)
David Safb76832014-05-08 23:42:08 -04002860{
2861 if (!ssl_sock_is_ssl(conn))
2862 return 0;
2863
2864 return SSL_SOCK_ST_FL_VERIFY_DONE & conn->xprt_st ? 1 : 0;
2865}
2866
2867/* returns result from SSL verify */
2868unsigned int ssl_sock_get_verify_result(struct connection *conn)
2869{
2870 if (!ssl_sock_is_ssl(conn))
2871 return (unsigned int)X509_V_ERR_APPLICATION_VERIFICATION;
2872
2873 return (unsigned int)SSL_get_verify_result(conn->xprt_ctx);
2874}
2875
Willy Tarreau7875d092012-09-10 08:20:03 +02002876/***** Below are some sample fetching functions for ACL/patterns *****/
2877
Emeric Brune64aef12012-09-21 13:15:06 +02002878/* boolean, returns true if client cert was present */
2879static int
Emeric Brun2525b6b2012-10-18 15:59:43 +02002880smp_fetch_ssl_fc_has_crt(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
Willy Tarreauef38c392013-07-22 16:29:32 +02002881 const struct arg *args, struct sample *smp, const char *kw)
Emeric Brune64aef12012-09-21 13:15:06 +02002882{
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002883 struct connection *conn;
2884
2885 if (!l4)
2886 return 0;
2887
2888 conn = objt_conn(l4->si[0].end);
2889 if (!conn || conn->xprt != &ssl_sock)
Emeric Brune64aef12012-09-21 13:15:06 +02002890 return 0;
2891
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002892 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brune64aef12012-09-21 13:15:06 +02002893 smp->flags |= SMP_F_MAY_CHANGE;
2894 return 0;
2895 }
2896
2897 smp->flags = 0;
2898 smp->type = SMP_T_BOOL;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002899 smp->data.uint = SSL_SOCK_ST_FL_VERIFY_DONE & conn->xprt_st ? 1 : 0;
Emeric Brune64aef12012-09-21 13:15:06 +02002900
2901 return 1;
2902}
2903
Emeric Brun43e79582014-10-29 19:03:26 +01002904/* binary, returns a certificate in a binary chunk (der/raw).
2905 * The 5th keyword char is used to know if SSL_get_certificate or SSL_get_peer_certificate
2906 * should be use.
2907 */
2908static int
2909smp_fetch_ssl_x_der(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
2910 const struct arg *args, struct sample *smp, const char *kw)
2911{
2912 int cert_peer = (kw[4] == 'c') ? 1 : 0;
2913 X509 *crt = NULL;
2914 int ret = 0;
2915 struct chunk *smp_trash;
2916 struct connection *conn;
2917
2918 if (!l4)
2919 return 0;
2920
2921 conn = objt_conn(l4->si[0].end);
2922 if (!conn || conn->xprt != &ssl_sock)
2923 return 0;
2924
2925 if (!(conn->flags & CO_FL_CONNECTED)) {
2926 smp->flags |= SMP_F_MAY_CHANGE;
2927 return 0;
2928 }
2929
2930 if (cert_peer)
2931 crt = SSL_get_peer_certificate(conn->xprt_ctx);
2932 else
2933 crt = SSL_get_certificate(conn->xprt_ctx);
2934
2935 if (!crt)
2936 goto out;
2937
2938 smp_trash = get_trash_chunk();
2939 if (ssl_sock_crt2der(crt, smp_trash) <= 0)
2940 goto out;
2941
2942 smp->data.str = *smp_trash;
2943 smp->type = SMP_T_BIN;
2944 ret = 1;
2945out:
2946 /* SSL_get_peer_certificate, it increase X509 * ref count */
2947 if (cert_peer && crt)
2948 X509_free(crt);
2949 return ret;
2950}
2951
Emeric Brunba841a12014-04-30 17:05:08 +02002952/* binary, returns serial of certificate in a binary chunk.
2953 * The 5th keyword char is used to know if SSL_get_certificate or SSL_get_peer_certificate
2954 * should be use.
2955 */
Willy Tarreau8d598402012-10-22 17:58:39 +02002956static int
Emeric Brunba841a12014-04-30 17:05:08 +02002957smp_fetch_ssl_x_serial(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
Willy Tarreauef38c392013-07-22 16:29:32 +02002958 const struct arg *args, struct sample *smp, const char *kw)
Willy Tarreau8d598402012-10-22 17:58:39 +02002959{
Emeric Brunba841a12014-04-30 17:05:08 +02002960 int cert_peer = (kw[4] == 'c') ? 1 : 0;
Willy Tarreau8d598402012-10-22 17:58:39 +02002961 X509 *crt = NULL;
2962 int ret = 0;
2963 struct chunk *smp_trash;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002964 struct connection *conn;
2965
2966 if (!l4)
2967 return 0;
Willy Tarreau8d598402012-10-22 17:58:39 +02002968
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002969 conn = objt_conn(l4->si[0].end);
2970 if (!conn || conn->xprt != &ssl_sock)
Willy Tarreau8d598402012-10-22 17:58:39 +02002971 return 0;
2972
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002973 if (!(conn->flags & CO_FL_CONNECTED)) {
Willy Tarreau8d598402012-10-22 17:58:39 +02002974 smp->flags |= SMP_F_MAY_CHANGE;
2975 return 0;
2976 }
2977
Emeric Brunba841a12014-04-30 17:05:08 +02002978 if (cert_peer)
2979 crt = SSL_get_peer_certificate(conn->xprt_ctx);
2980 else
2981 crt = SSL_get_certificate(conn->xprt_ctx);
2982
Willy Tarreau8d598402012-10-22 17:58:39 +02002983 if (!crt)
2984 goto out;
2985
Willy Tarreau47ca5452012-12-23 20:22:19 +01002986 smp_trash = get_trash_chunk();
Willy Tarreau8d598402012-10-22 17:58:39 +02002987 if (ssl_sock_get_serial(crt, smp_trash) <= 0)
2988 goto out;
2989
2990 smp->data.str = *smp_trash;
2991 smp->type = SMP_T_BIN;
2992 ret = 1;
2993out:
Emeric Brunba841a12014-04-30 17:05:08 +02002994 /* SSL_get_peer_certificate, it increase X509 * ref count */
2995 if (cert_peer && crt)
Willy Tarreau8d598402012-10-22 17:58:39 +02002996 X509_free(crt);
2997 return ret;
2998}
Emeric Brune64aef12012-09-21 13:15:06 +02002999
Emeric Brunba841a12014-04-30 17:05:08 +02003000/* binary, returns the client certificate's SHA-1 fingerprint (SHA-1 hash of DER-encoded certificate) in a binary chunk.
3001 * The 5th keyword char is used to know if SSL_get_certificate or SSL_get_peer_certificate
3002 * should be use.
3003 */
James Votha051b4a2013-05-14 20:37:59 +02003004static int
Emeric Brunba841a12014-04-30 17:05:08 +02003005smp_fetch_ssl_x_sha1(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
Willy Tarreauef38c392013-07-22 16:29:32 +02003006 const struct arg *args, struct sample *smp, const char *kw)
James Votha051b4a2013-05-14 20:37:59 +02003007{
Emeric Brunba841a12014-04-30 17:05:08 +02003008 int cert_peer = (kw[4] == 'c') ? 1 : 0;
James Votha051b4a2013-05-14 20:37:59 +02003009 X509 *crt = NULL;
3010 const EVP_MD *digest;
3011 int ret = 0;
3012 struct chunk *smp_trash;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003013 struct connection *conn;
James Votha051b4a2013-05-14 20:37:59 +02003014
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003015 if (!l4)
James Votha051b4a2013-05-14 20:37:59 +02003016 return 0;
3017
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003018 conn = objt_conn(l4->si[0].end);
3019 if (!conn || conn->xprt != &ssl_sock)
3020 return 0;
3021
3022 if (!(conn->flags & CO_FL_CONNECTED)) {
James Votha051b4a2013-05-14 20:37:59 +02003023 smp->flags |= SMP_F_MAY_CHANGE;
3024 return 0;
3025 }
3026
Emeric Brunba841a12014-04-30 17:05:08 +02003027 if (cert_peer)
3028 crt = SSL_get_peer_certificate(conn->xprt_ctx);
3029 else
3030 crt = SSL_get_certificate(conn->xprt_ctx);
James Votha051b4a2013-05-14 20:37:59 +02003031 if (!crt)
3032 goto out;
3033
3034 smp_trash = get_trash_chunk();
3035 digest = EVP_sha1();
3036 X509_digest(crt, digest, (unsigned char *)smp_trash->str, (unsigned int *)&smp_trash->len);
3037
3038 smp->data.str = *smp_trash;
3039 smp->type = SMP_T_BIN;
3040 ret = 1;
3041out:
Emeric Brunba841a12014-04-30 17:05:08 +02003042 /* SSL_get_peer_certificate, it increase X509 * ref count */
3043 if (cert_peer && crt)
James Votha051b4a2013-05-14 20:37:59 +02003044 X509_free(crt);
3045 return ret;
3046}
3047
Emeric Brunba841a12014-04-30 17:05:08 +02003048/* string, returns certificate's notafter date in ASN1_UTCTIME format.
3049 * The 5th keyword char is used to know if SSL_get_certificate or SSL_get_peer_certificate
3050 * should be use.
3051 */
Emeric Brunce5ad802012-10-22 14:11:22 +02003052static int
Emeric Brunba841a12014-04-30 17:05:08 +02003053smp_fetch_ssl_x_notafter(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
Willy Tarreauef38c392013-07-22 16:29:32 +02003054 const struct arg *args, struct sample *smp, const char *kw)
Emeric Brunce5ad802012-10-22 14:11:22 +02003055{
Emeric Brunba841a12014-04-30 17:05:08 +02003056 int cert_peer = (kw[4] == 'c') ? 1 : 0;
Emeric Brunce5ad802012-10-22 14:11:22 +02003057 X509 *crt = NULL;
3058 int ret = 0;
3059 struct chunk *smp_trash;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003060 struct connection *conn;
Emeric Brunce5ad802012-10-22 14:11:22 +02003061
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003062 if (!l4)
Emeric Brunce5ad802012-10-22 14:11:22 +02003063 return 0;
3064
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003065 conn = objt_conn(l4->si[0].end);
3066 if (!conn || conn->xprt != &ssl_sock)
3067 return 0;
3068
3069 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brunce5ad802012-10-22 14:11:22 +02003070 smp->flags |= SMP_F_MAY_CHANGE;
3071 return 0;
3072 }
3073
Emeric Brunba841a12014-04-30 17:05:08 +02003074 if (cert_peer)
3075 crt = SSL_get_peer_certificate(conn->xprt_ctx);
3076 else
3077 crt = SSL_get_certificate(conn->xprt_ctx);
Emeric Brunce5ad802012-10-22 14:11:22 +02003078 if (!crt)
3079 goto out;
3080
Willy Tarreau47ca5452012-12-23 20:22:19 +01003081 smp_trash = get_trash_chunk();
Emeric Brunce5ad802012-10-22 14:11:22 +02003082 if (ssl_sock_get_time(X509_get_notAfter(crt), smp_trash) <= 0)
3083 goto out;
3084
3085 smp->data.str = *smp_trash;
3086 smp->type = SMP_T_STR;
3087 ret = 1;
3088out:
Emeric Brunba841a12014-04-30 17:05:08 +02003089 /* SSL_get_peer_certificate, it increase X509 * ref count */
3090 if (cert_peer && crt)
Emeric Brunce5ad802012-10-22 14:11:22 +02003091 X509_free(crt);
3092 return ret;
3093}
3094
Emeric Brunba841a12014-04-30 17:05:08 +02003095/* string, returns a string of a formatted full dn \C=..\O=..\OU=.. \CN=.. of certificate's issuer
3096 * The 5th keyword char is used to know if SSL_get_certificate or SSL_get_peer_certificate
3097 * should be use.
3098 */
Emeric Brun87855892012-10-17 17:39:35 +02003099static int
Emeric Brunba841a12014-04-30 17:05:08 +02003100smp_fetch_ssl_x_i_dn(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
Willy Tarreauef38c392013-07-22 16:29:32 +02003101 const struct arg *args, struct sample *smp, const char *kw)
Emeric Brun87855892012-10-17 17:39:35 +02003102{
Emeric Brunba841a12014-04-30 17:05:08 +02003103 int cert_peer = (kw[4] == 'c') ? 1 : 0;
Emeric Brun87855892012-10-17 17:39:35 +02003104 X509 *crt = NULL;
3105 X509_NAME *name;
3106 int ret = 0;
3107 struct chunk *smp_trash;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003108 struct connection *conn;
Emeric Brun87855892012-10-17 17:39:35 +02003109
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003110 if (!l4)
Emeric Brun87855892012-10-17 17:39:35 +02003111 return 0;
3112
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003113 conn = objt_conn(l4->si[0].end);
3114 if (!conn || conn->xprt != &ssl_sock)
3115 return 0;
3116
3117 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brun87855892012-10-17 17:39:35 +02003118 smp->flags |= SMP_F_MAY_CHANGE;
3119 return 0;
3120 }
3121
Emeric Brunba841a12014-04-30 17:05:08 +02003122 if (cert_peer)
3123 crt = SSL_get_peer_certificate(conn->xprt_ctx);
3124 else
3125 crt = SSL_get_certificate(conn->xprt_ctx);
Emeric Brun87855892012-10-17 17:39:35 +02003126 if (!crt)
3127 goto out;
3128
3129 name = X509_get_issuer_name(crt);
3130 if (!name)
3131 goto out;
3132
Willy Tarreau47ca5452012-12-23 20:22:19 +01003133 smp_trash = get_trash_chunk();
Emeric Brun87855892012-10-17 17:39:35 +02003134 if (args && args[0].type == ARGT_STR) {
3135 int pos = 1;
3136
3137 if (args[1].type == ARGT_SINT)
3138 pos = args[1].data.sint;
3139 else if (args[1].type == ARGT_UINT)
3140 pos =(int)args[1].data.uint;
3141
3142 if (ssl_sock_get_dn_entry(name, &args[0].data.str, pos, smp_trash) <= 0)
3143 goto out;
3144 }
3145 else if (ssl_sock_get_dn_oneline(name, smp_trash) <= 0)
3146 goto out;
3147
3148 smp->type = SMP_T_STR;
3149 smp->data.str = *smp_trash;
3150 ret = 1;
3151out:
Emeric Brunba841a12014-04-30 17:05:08 +02003152 /* SSL_get_peer_certificate, it increase X509 * ref count */
3153 if (cert_peer && crt)
Emeric Brun87855892012-10-17 17:39:35 +02003154 X509_free(crt);
3155 return ret;
3156}
3157
Emeric Brunba841a12014-04-30 17:05:08 +02003158/* string, returns notbefore date in ASN1_UTCTIME format.
3159 * The 5th keyword char is used to know if SSL_get_certificate or SSL_get_peer_certificate
3160 * should be use.
3161 */
Emeric Brunce5ad802012-10-22 14:11:22 +02003162static int
Emeric Brunba841a12014-04-30 17:05:08 +02003163smp_fetch_ssl_x_notbefore(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
Willy Tarreauef38c392013-07-22 16:29:32 +02003164 const struct arg *args, struct sample *smp, const char *kw)
Emeric Brunce5ad802012-10-22 14:11:22 +02003165{
Emeric Brunba841a12014-04-30 17:05:08 +02003166 int cert_peer = (kw[4] == 'c') ? 1 : 0;
Emeric Brunce5ad802012-10-22 14:11:22 +02003167 X509 *crt = NULL;
3168 int ret = 0;
3169 struct chunk *smp_trash;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003170 struct connection *conn;
3171
3172 if (!l4)
3173 return 0;
Emeric Brunce5ad802012-10-22 14:11:22 +02003174
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003175 conn = objt_conn(l4->si[0].end);
3176 if (!conn || conn->xprt != &ssl_sock)
Emeric Brunce5ad802012-10-22 14:11:22 +02003177 return 0;
3178
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003179 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brunce5ad802012-10-22 14:11:22 +02003180 smp->flags |= SMP_F_MAY_CHANGE;
3181 return 0;
3182 }
3183
Emeric Brunba841a12014-04-30 17:05:08 +02003184 if (cert_peer)
3185 crt = SSL_get_peer_certificate(conn->xprt_ctx);
3186 else
3187 crt = SSL_get_certificate(conn->xprt_ctx);
Emeric Brunce5ad802012-10-22 14:11:22 +02003188 if (!crt)
3189 goto out;
3190
Willy Tarreau47ca5452012-12-23 20:22:19 +01003191 smp_trash = get_trash_chunk();
Emeric Brunce5ad802012-10-22 14:11:22 +02003192 if (ssl_sock_get_time(X509_get_notBefore(crt), smp_trash) <= 0)
3193 goto out;
3194
3195 smp->data.str = *smp_trash;
3196 smp->type = SMP_T_STR;
3197 ret = 1;
3198out:
Emeric Brunba841a12014-04-30 17:05:08 +02003199 /* SSL_get_peer_certificate, it increase X509 * ref count */
3200 if (cert_peer && crt)
Emeric Brunce5ad802012-10-22 14:11:22 +02003201 X509_free(crt);
3202 return ret;
3203}
3204
Emeric Brunba841a12014-04-30 17:05:08 +02003205/* string, returns a string of a formatted full dn \C=..\O=..\OU=.. \CN=.. of certificate's subject
3206 * The 5th keyword char is used to know if SSL_get_certificate or SSL_get_peer_certificate
3207 * should be use.
3208 */
Emeric Brun87855892012-10-17 17:39:35 +02003209static int
Emeric Brunba841a12014-04-30 17:05:08 +02003210smp_fetch_ssl_x_s_dn(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
Willy Tarreauef38c392013-07-22 16:29:32 +02003211 const struct arg *args, struct sample *smp, const char *kw)
Emeric Brun87855892012-10-17 17:39:35 +02003212{
Emeric Brunba841a12014-04-30 17:05:08 +02003213 int cert_peer = (kw[4] == 'c') ? 1 : 0;
Emeric Brun87855892012-10-17 17:39:35 +02003214 X509 *crt = NULL;
3215 X509_NAME *name;
3216 int ret = 0;
3217 struct chunk *smp_trash;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003218 struct connection *conn;
Emeric Brun87855892012-10-17 17:39:35 +02003219
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003220 if (!l4)
Emeric Brun87855892012-10-17 17:39:35 +02003221 return 0;
3222
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003223 conn = objt_conn(l4->si[0].end);
3224 if (!conn || conn->xprt != &ssl_sock)
3225 return 0;
3226
3227 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brun87855892012-10-17 17:39:35 +02003228 smp->flags |= SMP_F_MAY_CHANGE;
3229 return 0;
3230 }
3231
Emeric Brunba841a12014-04-30 17:05:08 +02003232 if (cert_peer)
3233 crt = SSL_get_peer_certificate(conn->xprt_ctx);
3234 else
3235 crt = SSL_get_certificate(conn->xprt_ctx);
Emeric Brun87855892012-10-17 17:39:35 +02003236 if (!crt)
3237 goto out;
3238
3239 name = X509_get_subject_name(crt);
3240 if (!name)
3241 goto out;
3242
Willy Tarreau47ca5452012-12-23 20:22:19 +01003243 smp_trash = get_trash_chunk();
Emeric Brun87855892012-10-17 17:39:35 +02003244 if (args && args[0].type == ARGT_STR) {
3245 int pos = 1;
3246
3247 if (args[1].type == ARGT_SINT)
3248 pos = args[1].data.sint;
3249 else if (args[1].type == ARGT_UINT)
3250 pos =(int)args[1].data.uint;
3251
3252 if (ssl_sock_get_dn_entry(name, &args[0].data.str, pos, smp_trash) <= 0)
3253 goto out;
3254 }
3255 else if (ssl_sock_get_dn_oneline(name, smp_trash) <= 0)
3256 goto out;
3257
3258 smp->type = SMP_T_STR;
3259 smp->data.str = *smp_trash;
3260 ret = 1;
3261out:
Emeric Brunba841a12014-04-30 17:05:08 +02003262 /* SSL_get_peer_certificate, it increase X509 * ref count */
3263 if (cert_peer && crt)
Emeric Brun87855892012-10-17 17:39:35 +02003264 X509_free(crt);
3265 return ret;
3266}
Emeric Brun9143d372012-12-20 15:44:16 +01003267
3268/* integer, returns true if current session use a client certificate */
3269static int
3270smp_fetch_ssl_c_used(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
Willy Tarreauef38c392013-07-22 16:29:32 +02003271 const struct arg *args, struct sample *smp, const char *kw)
Emeric Brun9143d372012-12-20 15:44:16 +01003272{
3273 X509 *crt;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003274 struct connection *conn;
Emeric Brun9143d372012-12-20 15:44:16 +01003275
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003276 if (!l4)
Emeric Brun9143d372012-12-20 15:44:16 +01003277 return 0;
3278
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003279 conn = objt_conn(l4->si[0].end);
3280 if (!conn || conn->xprt != &ssl_sock)
3281 return 0;
3282
3283 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brun9143d372012-12-20 15:44:16 +01003284 smp->flags |= SMP_F_MAY_CHANGE;
3285 return 0;
3286 }
3287
3288 /* SSL_get_peer_certificate returns a ptr on allocated X509 struct */
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003289 crt = SSL_get_peer_certificate(conn->xprt_ctx);
Emeric Brun9143d372012-12-20 15:44:16 +01003290 if (crt) {
3291 X509_free(crt);
3292 }
3293
3294 smp->type = SMP_T_BOOL;
3295 smp->data.uint = (crt != NULL);
3296 return 1;
3297}
3298
Emeric Brunba841a12014-04-30 17:05:08 +02003299/* integer, returns the certificate version
3300 * The 5th keyword char is used to know if SSL_get_certificate or SSL_get_peer_certificate
3301 * should be use.
3302 */
Emeric Bruna7359fd2012-10-17 15:03:11 +02003303static int
Emeric Brunba841a12014-04-30 17:05:08 +02003304smp_fetch_ssl_x_version(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
Willy Tarreauef38c392013-07-22 16:29:32 +02003305 const struct arg *args, struct sample *smp, const char *kw)
Emeric Bruna7359fd2012-10-17 15:03:11 +02003306{
Emeric Brunba841a12014-04-30 17:05:08 +02003307 int cert_peer = (kw[4] == 'c') ? 1 : 0;
Emeric Bruna7359fd2012-10-17 15:03:11 +02003308 X509 *crt;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003309 struct connection *conn;
3310
3311 if (!l4)
3312 return 0;
Emeric Bruna7359fd2012-10-17 15:03:11 +02003313
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003314 conn = objt_conn(l4->si[0].end);
3315 if (!conn || conn->xprt != &ssl_sock)
Emeric Bruna7359fd2012-10-17 15:03:11 +02003316 return 0;
3317
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003318 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Bruna7359fd2012-10-17 15:03:11 +02003319 smp->flags |= SMP_F_MAY_CHANGE;
3320 return 0;
3321 }
3322
Emeric Brunba841a12014-04-30 17:05:08 +02003323 if (cert_peer)
3324 crt = SSL_get_peer_certificate(conn->xprt_ctx);
3325 else
3326 crt = SSL_get_certificate(conn->xprt_ctx);
Emeric Bruna7359fd2012-10-17 15:03:11 +02003327 if (!crt)
3328 return 0;
3329
3330 smp->data.uint = (unsigned int)(1 + X509_get_version(crt));
Emeric Brunba841a12014-04-30 17:05:08 +02003331 /* SSL_get_peer_certificate increase X509 * ref count */
3332 if (cert_peer)
3333 X509_free(crt);
Emeric Bruna7359fd2012-10-17 15:03:11 +02003334 smp->type = SMP_T_UINT;
3335
3336 return 1;
3337}
3338
Emeric Brunba841a12014-04-30 17:05:08 +02003339/* string, returns the certificate's signature algorithm.
3340 * The 5th keyword char is used to know if SSL_get_certificate or SSL_get_peer_certificate
3341 * should be use.
3342 */
Emeric Brun7f56e742012-10-19 18:15:40 +02003343static int
Emeric Brunba841a12014-04-30 17:05:08 +02003344smp_fetch_ssl_x_sig_alg(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
Willy Tarreauef38c392013-07-22 16:29:32 +02003345 const struct arg *args, struct sample *smp, const char *kw)
Emeric Brun7f56e742012-10-19 18:15:40 +02003346{
Emeric Brunba841a12014-04-30 17:05:08 +02003347 int cert_peer = (kw[4] == 'c') ? 1 : 0;
Emeric Brun7f56e742012-10-19 18:15:40 +02003348 X509 *crt;
3349 int nid;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003350 struct connection *conn;
Emeric Brun7f56e742012-10-19 18:15:40 +02003351
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003352 if (!l4)
Emeric Brun7f56e742012-10-19 18:15:40 +02003353 return 0;
3354
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003355 conn = objt_conn(l4->si[0].end);
3356 if (!conn || conn->xprt != &ssl_sock)
3357 return 0;
3358
3359 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brun7f56e742012-10-19 18:15:40 +02003360 smp->flags |= SMP_F_MAY_CHANGE;
3361 return 0;
3362 }
3363
Emeric Brunba841a12014-04-30 17:05:08 +02003364 if (cert_peer)
3365 crt = SSL_get_peer_certificate(conn->xprt_ctx);
3366 else
3367 crt = SSL_get_certificate(conn->xprt_ctx);
Emeric Brun7f56e742012-10-19 18:15:40 +02003368 if (!crt)
3369 return 0;
3370
3371 nid = OBJ_obj2nid((ASN1_OBJECT *)(crt->cert_info->signature->algorithm));
3372
3373 smp->data.str.str = (char *)OBJ_nid2sn(nid);
Emeric Brun9bf3ba22013-10-07 14:31:44 +02003374 if (!smp->data.str.str) {
Emeric Brunba841a12014-04-30 17:05:08 +02003375 /* SSL_get_peer_certificate increase X509 * ref count */
3376 if (cert_peer)
3377 X509_free(crt);
Emeric Brun7f56e742012-10-19 18:15:40 +02003378 return 0;
Emeric Brun9bf3ba22013-10-07 14:31:44 +02003379 }
Emeric Brun7f56e742012-10-19 18:15:40 +02003380
Thierry FOURNIER7654c9f2013-12-17 00:20:33 +01003381 smp->type = SMP_T_STR;
3382 smp->flags |= SMP_F_CONST;
Emeric Brun7f56e742012-10-19 18:15:40 +02003383 smp->data.str.len = strlen(smp->data.str.str);
Emeric Brunba841a12014-04-30 17:05:08 +02003384 /* SSL_get_peer_certificate increase X509 * ref count */
3385 if (cert_peer)
3386 X509_free(crt);
Emeric Brun7f56e742012-10-19 18:15:40 +02003387
3388 return 1;
3389}
3390
Emeric Brunba841a12014-04-30 17:05:08 +02003391/* string, returns the certificate's key algorithm.
3392 * The 5th keyword char is used to know if SSL_get_certificate or SSL_get_peer_certificate
3393 * should be use.
3394 */
Emeric Brun521a0112012-10-22 12:22:55 +02003395static int
Emeric Brunba841a12014-04-30 17:05:08 +02003396smp_fetch_ssl_x_key_alg(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
Willy Tarreauef38c392013-07-22 16:29:32 +02003397 const struct arg *args, struct sample *smp, const char *kw)
Emeric Brun521a0112012-10-22 12:22:55 +02003398{
Emeric Brunba841a12014-04-30 17:05:08 +02003399 int cert_peer = (kw[4] == 'c') ? 1 : 0;
Emeric Brun521a0112012-10-22 12:22:55 +02003400 X509 *crt;
3401 int nid;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003402 struct connection *conn;
Emeric Brun521a0112012-10-22 12:22:55 +02003403
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003404 if (!l4)
Emeric Brun521a0112012-10-22 12:22:55 +02003405 return 0;
3406
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003407 conn = objt_conn(l4->si[0].end);
3408 if (!conn || conn->xprt != &ssl_sock)
3409 return 0;
3410
3411 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brun521a0112012-10-22 12:22:55 +02003412 smp->flags |= SMP_F_MAY_CHANGE;
3413 return 0;
3414 }
3415
Emeric Brunba841a12014-04-30 17:05:08 +02003416 if (cert_peer)
3417 crt = SSL_get_peer_certificate(conn->xprt_ctx);
3418 else
3419 crt = SSL_get_certificate(conn->xprt_ctx);
Emeric Brun521a0112012-10-22 12:22:55 +02003420 if (!crt)
3421 return 0;
3422
3423 nid = OBJ_obj2nid((ASN1_OBJECT *)(crt->cert_info->key->algor->algorithm));
3424
3425 smp->data.str.str = (char *)OBJ_nid2sn(nid);
Emeric Brun9bf3ba22013-10-07 14:31:44 +02003426 if (!smp->data.str.str) {
Emeric Brunba841a12014-04-30 17:05:08 +02003427 /* SSL_get_peer_certificate increase X509 * ref count */
3428 if (cert_peer)
3429 X509_free(crt);
Emeric Brun521a0112012-10-22 12:22:55 +02003430 return 0;
Emeric Brun9bf3ba22013-10-07 14:31:44 +02003431 }
Emeric Brun521a0112012-10-22 12:22:55 +02003432
Thierry FOURNIER7654c9f2013-12-17 00:20:33 +01003433 smp->type = SMP_T_STR;
3434 smp->flags |= SMP_F_CONST;
Emeric Brun521a0112012-10-22 12:22:55 +02003435 smp->data.str.len = strlen(smp->data.str.str);
Emeric Brunba841a12014-04-30 17:05:08 +02003436 if (cert_peer)
3437 X509_free(crt);
Emeric Brun521a0112012-10-22 12:22:55 +02003438
3439 return 1;
3440}
3441
Emeric Brun645ae792014-04-30 14:21:06 +02003442/* boolean, returns true if front conn. transport layer is SSL.
3443 * This function is also usable on backend conn if the fetch keyword 5th
3444 * char is 'b'.
3445 */
Willy Tarreau7875d092012-09-10 08:20:03 +02003446static int
Emeric Brun2525b6b2012-10-18 15:59:43 +02003447smp_fetch_ssl_fc(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
Willy Tarreauef38c392013-07-22 16:29:32 +02003448 const struct arg *args, struct sample *smp, const char *kw)
Willy Tarreau7875d092012-09-10 08:20:03 +02003449{
Emeric Brun645ae792014-04-30 14:21:06 +02003450 int back_conn = (kw[4] == 'b') ? 1 : 0;
3451 struct connection *conn = objt_conn(l4->si[back_conn].end);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003452
Willy Tarreau7875d092012-09-10 08:20:03 +02003453 smp->type = SMP_T_BOOL;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003454 smp->data.uint = (conn && conn->xprt == &ssl_sock);
Willy Tarreau7875d092012-09-10 08:20:03 +02003455 return 1;
3456}
3457
Emeric Brun2525b6b2012-10-18 15:59:43 +02003458/* boolean, returns true if client present a SNI */
Willy Tarreau7875d092012-09-10 08:20:03 +02003459static int
Emeric Brun2525b6b2012-10-18 15:59:43 +02003460smp_fetch_ssl_fc_has_sni(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
Willy Tarreauef38c392013-07-22 16:29:32 +02003461 const struct arg *args, struct sample *smp, const char *kw)
Willy Tarreau7875d092012-09-10 08:20:03 +02003462{
3463#ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003464 struct connection *conn = objt_conn(l4->si[0].end);
3465
Willy Tarreau7875d092012-09-10 08:20:03 +02003466 smp->type = SMP_T_BOOL;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003467 smp->data.uint = (conn && conn->xprt == &ssl_sock) &&
3468 conn->xprt_ctx &&
3469 SSL_get_servername(conn->xprt_ctx, TLSEXT_NAMETYPE_host_name) != NULL;
Willy Tarreau7875d092012-09-10 08:20:03 +02003470 return 1;
3471#else
3472 return 0;
3473#endif
3474}
3475
Emeric Brun645ae792014-04-30 14:21:06 +02003476/* string, returns the used cipher if front conn. transport layer is SSL.
3477 * This function is also usable on backend conn if the fetch keyword 5th
3478 * char is 'b'.
3479 */
Emeric Brun589fcad2012-10-16 14:13:26 +02003480static int
3481smp_fetch_ssl_fc_cipher(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
Willy Tarreauef38c392013-07-22 16:29:32 +02003482 const struct arg *args, struct sample *smp, const char *kw)
Emeric Brun589fcad2012-10-16 14:13:26 +02003483{
Emeric Brun645ae792014-04-30 14:21:06 +02003484 int back_conn = (kw[4] == 'b') ? 1 : 0;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003485 struct connection *conn;
3486
Emeric Brun589fcad2012-10-16 14:13:26 +02003487 smp->flags = 0;
3488
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003489 if (!l4)
3490 return 0;
3491
Emeric Brun645ae792014-04-30 14:21:06 +02003492 conn = objt_conn(l4->si[back_conn].end);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003493 if (!conn || !conn->xprt_ctx || conn->xprt != &ssl_sock)
Emeric Brun589fcad2012-10-16 14:13:26 +02003494 return 0;
3495
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003496 smp->data.str.str = (char *)SSL_get_cipher_name(conn->xprt_ctx);
Emeric Brun589fcad2012-10-16 14:13:26 +02003497 if (!smp->data.str.str)
3498 return 0;
3499
Thierry FOURNIER7654c9f2013-12-17 00:20:33 +01003500 smp->type = SMP_T_STR;
3501 smp->flags |= SMP_F_CONST;
Emeric Brun589fcad2012-10-16 14:13:26 +02003502 smp->data.str.len = strlen(smp->data.str.str);
3503
3504 return 1;
3505}
3506
Emeric Brun645ae792014-04-30 14:21:06 +02003507/* integer, returns the algoritm's keysize if front conn. transport layer
3508 * is SSL.
3509 * This function is also usable on backend conn if the fetch keyword 5th
3510 * char is 'b'.
3511 */
Emeric Brun589fcad2012-10-16 14:13:26 +02003512static int
3513smp_fetch_ssl_fc_alg_keysize(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
Willy Tarreauef38c392013-07-22 16:29:32 +02003514 const struct arg *args, struct sample *smp, const char *kw)
Emeric Brun589fcad2012-10-16 14:13:26 +02003515{
Emeric Brun645ae792014-04-30 14:21:06 +02003516 int back_conn = (kw[4] == 'b') ? 1 : 0;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003517 struct connection *conn;
3518
Emeric Brun589fcad2012-10-16 14:13:26 +02003519 smp->flags = 0;
3520
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003521 if (!l4)
Emeric Brun589fcad2012-10-16 14:13:26 +02003522 return 0;
3523
Emeric Brun645ae792014-04-30 14:21:06 +02003524 conn = objt_conn(l4->si[back_conn].end);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003525 if (!conn || !conn->xprt_ctx || conn->xprt != &ssl_sock)
Emeric Brun589fcad2012-10-16 14:13:26 +02003526 return 0;
3527
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003528 if (!SSL_get_cipher_bits(conn->xprt_ctx, (int *)&smp->data.uint))
3529 return 0;
3530
Emeric Brun589fcad2012-10-16 14:13:26 +02003531 smp->type = SMP_T_UINT;
3532
3533 return 1;
3534}
3535
Emeric Brun645ae792014-04-30 14:21:06 +02003536/* integer, returns the used keysize if front conn. transport layer is SSL.
3537 * This function is also usable on backend conn if the fetch keyword 5th
3538 * char is 'b'.
3539 */
Emeric Brun589fcad2012-10-16 14:13:26 +02003540static int
3541smp_fetch_ssl_fc_use_keysize(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
Willy Tarreauef38c392013-07-22 16:29:32 +02003542 const struct arg *args, struct sample *smp, const char *kw)
Emeric Brun589fcad2012-10-16 14:13:26 +02003543{
Emeric Brun645ae792014-04-30 14:21:06 +02003544 int back_conn = (kw[4] == 'b') ? 1 : 0;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003545 struct connection *conn;
3546
Emeric Brun589fcad2012-10-16 14:13:26 +02003547 smp->flags = 0;
3548
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003549 if (!l4)
Emeric Brun589fcad2012-10-16 14:13:26 +02003550 return 0;
3551
Emeric Brun645ae792014-04-30 14:21:06 +02003552 conn = objt_conn(l4->si[back_conn].end);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003553 if (!conn || !conn->xprt_ctx || conn->xprt != &ssl_sock)
3554 return 0;
3555
3556 smp->data.uint = (unsigned int)SSL_get_cipher_bits(conn->xprt_ctx, NULL);
Emeric Brun589fcad2012-10-16 14:13:26 +02003557 if (!smp->data.uint)
3558 return 0;
3559
3560 smp->type = SMP_T_UINT;
3561
3562 return 1;
3563}
3564
Willy Tarreau6c9a3d52012-10-18 18:57:14 +02003565#ifdef OPENSSL_NPN_NEGOTIATED
Willy Tarreau7875d092012-09-10 08:20:03 +02003566static int
Emeric Brun2525b6b2012-10-18 15:59:43 +02003567smp_fetch_ssl_fc_npn(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
Willy Tarreauef38c392013-07-22 16:29:32 +02003568 const struct arg *args, struct sample *smp, const char *kw)
Willy Tarreaua33c6542012-10-15 13:19:06 +02003569{
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003570 struct connection *conn;
3571
Thierry FOURNIER7654c9f2013-12-17 00:20:33 +01003572 smp->flags = SMP_F_CONST;
3573 smp->type = SMP_T_STR;
Willy Tarreaua33c6542012-10-15 13:19:06 +02003574
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003575 if (!l4)
Willy Tarreaua33c6542012-10-15 13:19:06 +02003576 return 0;
3577
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003578 conn = objt_conn(l4->si[0].end);
3579 if (!conn || !conn->xprt_ctx || conn->xprt != &ssl_sock)
3580 return 0;
3581
Willy Tarreaua33c6542012-10-15 13:19:06 +02003582 smp->data.str.str = NULL;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003583 SSL_get0_next_proto_negotiated(conn->xprt_ctx,
Willy Tarreaua33c6542012-10-15 13:19:06 +02003584 (const unsigned char **)&smp->data.str.str, (unsigned *)&smp->data.str.len);
3585
3586 if (!smp->data.str.str)
3587 return 0;
3588
3589 return 1;
Willy Tarreaua33c6542012-10-15 13:19:06 +02003590}
Willy Tarreau6c9a3d52012-10-18 18:57:14 +02003591#endif
Willy Tarreaua33c6542012-10-15 13:19:06 +02003592
Dirkjan Bussink48f1c4e2014-02-13 12:29:42 +01003593#ifdef TLSEXT_TYPE_application_layer_protocol_negotiation
Willy Tarreauab861d32013-04-02 02:30:41 +02003594static int
3595smp_fetch_ssl_fc_alpn(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
Willy Tarreauef38c392013-07-22 16:29:32 +02003596 const struct arg *args, struct sample *smp, const char *kw)
Willy Tarreauab861d32013-04-02 02:30:41 +02003597{
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003598 struct connection *conn;
3599
Thierry FOURNIER7654c9f2013-12-17 00:20:33 +01003600 smp->flags = SMP_F_CONST;
3601 smp->type = SMP_T_STR;
Willy Tarreauab861d32013-04-02 02:30:41 +02003602
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003603 if (!l4)
3604 return 0;
3605
3606 conn = objt_conn(l4->si[0].end);
3607 if (!conn || !conn->xprt_ctx || conn->xprt != &ssl_sock)
Willy Tarreauab861d32013-04-02 02:30:41 +02003608 return 0;
3609
3610 smp->data.str.str = NULL;
Dirkjan Bussink48f1c4e2014-02-13 12:29:42 +01003611 SSL_get0_alpn_selected(conn->xprt_ctx,
Willy Tarreauab861d32013-04-02 02:30:41 +02003612 (const unsigned char **)&smp->data.str.str, (unsigned *)&smp->data.str.len);
3613
3614 if (!smp->data.str.str)
3615 return 0;
3616
3617 return 1;
3618}
3619#endif
3620
Emeric Brun645ae792014-04-30 14:21:06 +02003621/* string, returns the used protocol if front conn. transport layer is SSL.
3622 * This function is also usable on backend conn if the fetch keyword 5th
3623 * char is 'b'.
3624 */
Willy Tarreaua33c6542012-10-15 13:19:06 +02003625static int
Emeric Brun589fcad2012-10-16 14:13:26 +02003626smp_fetch_ssl_fc_protocol(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
Willy Tarreauef38c392013-07-22 16:29:32 +02003627 const struct arg *args, struct sample *smp, const char *kw)
Emeric Brun589fcad2012-10-16 14:13:26 +02003628{
Emeric Brun645ae792014-04-30 14:21:06 +02003629 int back_conn = (kw[4] == 'b') ? 1 : 0;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003630 struct connection *conn;
3631
Emeric Brun589fcad2012-10-16 14:13:26 +02003632 smp->flags = 0;
3633
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003634 if (!l4)
Emeric Brun589fcad2012-10-16 14:13:26 +02003635 return 0;
3636
Emeric Brun645ae792014-04-30 14:21:06 +02003637 conn = objt_conn(l4->si[back_conn].end);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003638 if (!conn || !conn->xprt_ctx || conn->xprt != &ssl_sock)
3639 return 0;
3640
3641 smp->data.str.str = (char *)SSL_get_version(conn->xprt_ctx);
Emeric Brun589fcad2012-10-16 14:13:26 +02003642 if (!smp->data.str.str)
3643 return 0;
3644
Thierry FOURNIER7654c9f2013-12-17 00:20:33 +01003645 smp->type = SMP_T_STR;
3646 smp->flags = SMP_F_CONST;
Emeric Brun589fcad2012-10-16 14:13:26 +02003647 smp->data.str.len = strlen(smp->data.str.str);
3648
3649 return 1;
3650}
3651
Emeric Brun645ae792014-04-30 14:21:06 +02003652/* binary, returns the SSL session id if front conn. transport layer is SSL.
3653 * This function is also usable on backend conn if the fetch keyword 5th
3654 * char is 'b'.
3655 */
Emeric Brun589fcad2012-10-16 14:13:26 +02003656static int
Emeric Brunfe68f682012-10-16 14:59:28 +02003657smp_fetch_ssl_fc_session_id(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
Willy Tarreauef38c392013-07-22 16:29:32 +02003658 const struct arg *args, struct sample *smp, const char *kw)
Emeric Brunfe68f682012-10-16 14:59:28 +02003659{
3660#if OPENSSL_VERSION_NUMBER > 0x0090800fL
Emeric Brun645ae792014-04-30 14:21:06 +02003661 int back_conn = (kw[4] == 'b') ? 1 : 0;
Emeric Brunfe68f682012-10-16 14:59:28 +02003662 SSL_SESSION *sess;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003663 struct connection *conn;
Emeric Brunfe68f682012-10-16 14:59:28 +02003664
Thierry FOURNIER7654c9f2013-12-17 00:20:33 +01003665 smp->flags = SMP_F_CONST;
3666 smp->type = SMP_T_BIN;
Emeric Brunfe68f682012-10-16 14:59:28 +02003667
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003668 if (!l4)
Emeric Brunfe68f682012-10-16 14:59:28 +02003669 return 0;
3670
Emeric Brun645ae792014-04-30 14:21:06 +02003671 conn = objt_conn(l4->si[back_conn].end);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003672 if (!conn || !conn->xprt_ctx || conn->xprt != &ssl_sock)
3673 return 0;
3674
3675 sess = SSL_get_session(conn->xprt_ctx);
Emeric Brunfe68f682012-10-16 14:59:28 +02003676 if (!sess)
3677 return 0;
3678
3679 smp->data.str.str = (char *)SSL_SESSION_get_id(sess, (unsigned int *)&smp->data.str.len);
3680 if (!smp->data.str.str || !&smp->data.str.len)
3681 return 0;
3682
3683 return 1;
3684#else
3685 return 0;
3686#endif
3687}
3688
3689static int
Emeric Brun2525b6b2012-10-18 15:59:43 +02003690smp_fetch_ssl_fc_sni(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
Willy Tarreauef38c392013-07-22 16:29:32 +02003691 const struct arg *args, struct sample *smp, const char *kw)
Willy Tarreau7875d092012-09-10 08:20:03 +02003692{
3693#ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003694 struct connection *conn;
3695
Thierry FOURNIER7654c9f2013-12-17 00:20:33 +01003696 smp->flags = SMP_F_CONST;
3697 smp->type = SMP_T_STR;
Willy Tarreau7875d092012-09-10 08:20:03 +02003698
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003699 if (!l4)
Willy Tarreau7875d092012-09-10 08:20:03 +02003700 return 0;
3701
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003702 conn = objt_conn(l4->si[0].end);
3703 if (!conn || !conn->xprt_ctx || conn->xprt != &ssl_sock)
3704 return 0;
3705
3706 smp->data.str.str = (char *)SSL_get_servername(conn->xprt_ctx, TLSEXT_NAMETYPE_host_name);
Willy Tarreau3e394c92012-09-14 23:56:58 +02003707 if (!smp->data.str.str)
3708 return 0;
3709
Willy Tarreau7875d092012-09-10 08:20:03 +02003710 smp->data.str.len = strlen(smp->data.str.str);
3711 return 1;
3712#else
3713 return 0;
3714#endif
3715}
3716
David Sc1ad52e2014-04-08 18:48:47 -04003717static int
3718smp_fetch_ssl_fc_unique_id(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
3719 const struct arg *args, struct sample *smp, const char *kw)
3720{
3721#if OPENSSL_VERSION_NUMBER > 0x0090800fL
Emeric Brun645ae792014-04-30 14:21:06 +02003722 int back_conn = (kw[4] == 'b') ? 1 : 0;
David Sc1ad52e2014-04-08 18:48:47 -04003723 struct connection *conn;
3724 int finished_len;
David Sc1ad52e2014-04-08 18:48:47 -04003725 struct chunk *finished_trash;
David Sc1ad52e2014-04-08 18:48:47 -04003726
3727 smp->flags = 0;
3728
3729 if (!l4)
3730 return 0;
3731
Emeric Brun645ae792014-04-30 14:21:06 +02003732 conn = objt_conn(l4->si[back_conn].end);
David Sc1ad52e2014-04-08 18:48:47 -04003733 if (!conn || !conn->xprt_ctx || conn->xprt != &ssl_sock)
3734 return 0;
3735
3736 if (!(conn->flags & CO_FL_CONNECTED)) {
3737 smp->flags |= SMP_F_MAY_CHANGE;
3738 return 0;
3739 }
3740
3741 finished_trash = get_trash_chunk();
3742 if (!SSL_session_reused(conn->xprt_ctx))
3743 finished_len = SSL_get_peer_finished(conn->xprt_ctx, finished_trash->str, finished_trash->size);
3744 else
3745 finished_len = SSL_get_finished(conn->xprt_ctx, finished_trash->str, finished_trash->size);
3746
3747 if (!finished_len)
3748 return 0;
3749
Emeric Brunb73a9b02014-04-30 18:49:19 +02003750 finished_trash->len = finished_len;
3751 smp->data.str = *finished_trash;
3752 smp->type = SMP_T_BIN;
David Sc1ad52e2014-04-08 18:48:47 -04003753
3754 return 1;
3755#else
3756 return 0;
3757#endif
3758}
3759
Emeric Brun2525b6b2012-10-18 15:59:43 +02003760/* integer, returns the first verify error in CA chain of client certificate chain. */
Emeric Brunf282a812012-09-21 15:27:54 +02003761static int
Emeric Brun2525b6b2012-10-18 15:59:43 +02003762smp_fetch_ssl_c_ca_err(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
Willy Tarreauef38c392013-07-22 16:29:32 +02003763 const struct arg *args, struct sample *smp, const char *kw)
Emeric Brunf282a812012-09-21 15:27:54 +02003764{
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003765 struct connection *conn;
3766
3767 if (!l4)
Emeric Brunf282a812012-09-21 15:27:54 +02003768 return 0;
3769
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003770 conn = objt_conn(l4->si[0].end);
3771 if (!conn || conn->xprt != &ssl_sock)
3772 return 0;
3773
3774 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brunf282a812012-09-21 15:27:54 +02003775 smp->flags = SMP_F_MAY_CHANGE;
3776 return 0;
3777 }
3778
3779 smp->type = SMP_T_UINT;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003780 smp->data.uint = (unsigned int)SSL_SOCK_ST_TO_CA_ERROR(conn->xprt_st);
Emeric Brunf282a812012-09-21 15:27:54 +02003781 smp->flags = 0;
3782
3783 return 1;
3784}
3785
Emeric Brun2525b6b2012-10-18 15:59:43 +02003786/* integer, returns the depth of the first verify error in CA chain of client certificate chain. */
Emeric Brunf282a812012-09-21 15:27:54 +02003787static int
Emeric Brun2525b6b2012-10-18 15:59:43 +02003788smp_fetch_ssl_c_ca_err_depth(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
Willy Tarreauef38c392013-07-22 16:29:32 +02003789 const struct arg *args, struct sample *smp, const char *kw)
Emeric Brunf282a812012-09-21 15:27:54 +02003790{
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003791 struct connection *conn;
3792
3793 if (!l4)
3794 return 0;
3795
3796 conn = objt_conn(l4->si[0].end);
3797 if (!conn || conn->xprt != &ssl_sock)
Emeric Brunf282a812012-09-21 15:27:54 +02003798 return 0;
3799
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003800 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brunf282a812012-09-21 15:27:54 +02003801 smp->flags = SMP_F_MAY_CHANGE;
3802 return 0;
3803 }
3804
3805 smp->type = SMP_T_UINT;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003806 smp->data.uint = (unsigned int)SSL_SOCK_ST_TO_CAEDEPTH(conn->xprt_st);
Emeric Brunf282a812012-09-21 15:27:54 +02003807 smp->flags = 0;
3808
3809 return 1;
3810}
3811
Emeric Brun2525b6b2012-10-18 15:59:43 +02003812/* integer, returns the first verify error on client certificate */
Emeric Brunf282a812012-09-21 15:27:54 +02003813static int
Emeric Brun2525b6b2012-10-18 15:59:43 +02003814smp_fetch_ssl_c_err(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
Willy Tarreauef38c392013-07-22 16:29:32 +02003815 const struct arg *args, struct sample *smp, const char *kw)
Emeric Brunf282a812012-09-21 15:27:54 +02003816{
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003817 struct connection *conn;
3818
3819 if (!l4)
Emeric Brunf282a812012-09-21 15:27:54 +02003820 return 0;
3821
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003822 conn = objt_conn(l4->si[0].end);
3823 if (!conn || conn->xprt != &ssl_sock)
3824 return 0;
3825
3826 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brunf282a812012-09-21 15:27:54 +02003827 smp->flags = SMP_F_MAY_CHANGE;
3828 return 0;
3829 }
3830
3831 smp->type = SMP_T_UINT;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003832 smp->data.uint = (unsigned int)SSL_SOCK_ST_TO_CRTERROR(conn->xprt_st);
Emeric Brunf282a812012-09-21 15:27:54 +02003833 smp->flags = 0;
3834
3835 return 1;
3836}
3837
Emeric Brun2525b6b2012-10-18 15:59:43 +02003838/* integer, returns the verify result on client cert */
Emeric Brunbaf8ffb2012-09-21 15:27:20 +02003839static int
Emeric Brun2525b6b2012-10-18 15:59:43 +02003840smp_fetch_ssl_c_verify(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
Willy Tarreauef38c392013-07-22 16:29:32 +02003841 const struct arg *args, struct sample *smp, const char *kw)
Emeric Brunbaf8ffb2012-09-21 15:27:20 +02003842{
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003843 struct connection *conn;
3844
3845 if (!l4)
Emeric Brunbaf8ffb2012-09-21 15:27:20 +02003846 return 0;
3847
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003848 conn = objt_conn(l4->si[0].end);
3849 if (!conn || conn->xprt != &ssl_sock)
3850 return 0;
3851
3852 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brunbaf8ffb2012-09-21 15:27:20 +02003853 smp->flags = SMP_F_MAY_CHANGE;
3854 return 0;
3855 }
3856
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003857 if (!conn->xprt_ctx)
Emeric Brunbaf8ffb2012-09-21 15:27:20 +02003858 return 0;
3859
3860 smp->type = SMP_T_UINT;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003861 smp->data.uint = (unsigned int)SSL_get_verify_result(conn->xprt_ctx);
Emeric Brunbaf8ffb2012-09-21 15:27:20 +02003862 smp->flags = 0;
3863
3864 return 1;
3865}
3866
Emeric Brunfb510ea2012-10-05 12:00:26 +02003867/* parse the "ca-file" bind keyword */
3868static 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 +02003869{
3870 if (!*args[cur_arg + 1]) {
3871 if (err)
3872 memprintf(err, "'%s' : missing CAfile path", args[cur_arg]);
3873 return ERR_ALERT | ERR_FATAL;
3874 }
3875
Emeric Brunef42d922012-10-11 16:11:36 +02003876 if ((*args[cur_arg + 1] != '/') && global.ca_base)
3877 memprintf(&conf->ca_file, "%s/%s", global.ca_base, args[cur_arg + 1]);
3878 else
3879 memprintf(&conf->ca_file, "%s", args[cur_arg + 1]);
Emeric Brunc8e8d122012-10-02 18:42:10 +02003880
Emeric Brund94b3fe2012-09-20 18:23:56 +02003881 return 0;
3882}
3883
Willy Tarreau79eeafa2012-09-14 07:53:05 +02003884/* parse the "ciphers" bind keyword */
Willy Tarreau4348fad2012-09-20 16:48:07 +02003885static 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 +02003886{
3887 if (!*args[cur_arg + 1]) {
Willy Tarreaueb6cead2012-09-20 19:43:14 +02003888 memprintf(err, "'%s' : missing cipher suite", args[cur_arg]);
Willy Tarreau79eeafa2012-09-14 07:53:05 +02003889 return ERR_ALERT | ERR_FATAL;
3890 }
3891
Emeric Brun76d88952012-10-05 15:47:31 +02003892 free(conf->ciphers);
Willy Tarreau4348fad2012-09-20 16:48:07 +02003893 conf->ciphers = strdup(args[cur_arg + 1]);
Willy Tarreau79eeafa2012-09-14 07:53:05 +02003894 return 0;
3895}
3896
3897/* parse the "crt" bind keyword */
Willy Tarreau4348fad2012-09-20 16:48:07 +02003898static 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 +02003899{
Willy Tarreau38011032013-08-13 16:59:39 +02003900 char path[MAXPATHLEN];
Willy Tarreaub75d6922014-04-14 18:05:41 +02003901
Willy Tarreau79eeafa2012-09-14 07:53:05 +02003902 if (!*args[cur_arg + 1]) {
Willy Tarreaueb6cead2012-09-20 19:43:14 +02003903 memprintf(err, "'%s' : missing certificate location", args[cur_arg]);
Willy Tarreau79eeafa2012-09-14 07:53:05 +02003904 return ERR_ALERT | ERR_FATAL;
3905 }
3906
Emeric Brunc8e8d122012-10-02 18:42:10 +02003907 if ((*args[cur_arg + 1] != '/' ) && global.crt_base) {
Willy Tarreau38011032013-08-13 16:59:39 +02003908 if ((strlen(global.crt_base) + 1 + strlen(args[cur_arg + 1]) + 1) > MAXPATHLEN) {
Emeric Brunc8e8d122012-10-02 18:42:10 +02003909 memprintf(err, "'%s' : path too long", args[cur_arg]);
3910 return ERR_ALERT | ERR_FATAL;
3911 }
Willy Tarreaub75d6922014-04-14 18:05:41 +02003912 snprintf(path, sizeof(path), "%s/%s", global.crt_base, args[cur_arg + 1]);
Emeric Brunc8e8d122012-10-02 18:42:10 +02003913 if (ssl_sock_load_cert(path, conf, px, err) > 0)
3914 return ERR_ALERT | ERR_FATAL;
3915
3916 return 0;
3917 }
3918
Willy Tarreau4348fad2012-09-20 16:48:07 +02003919 if (ssl_sock_load_cert(args[cur_arg + 1], conf, px, err) > 0)
Willy Tarreau79eeafa2012-09-14 07:53:05 +02003920 return ERR_ALERT | ERR_FATAL;
Emeric Brund94b3fe2012-09-20 18:23:56 +02003921
3922 return 0;
3923}
3924
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01003925/* parse the "crt-list" bind keyword */
3926static int bind_parse_crt_list(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
3927{
3928 if (!*args[cur_arg + 1]) {
3929 memprintf(err, "'%s' : missing certificate location", args[cur_arg]);
3930 return ERR_ALERT | ERR_FATAL;
3931 }
3932
Willy Tarreauad1731d2013-04-02 17:35:58 +02003933 if (ssl_sock_load_cert_list_file(args[cur_arg + 1], conf, px, err) > 0) {
3934 memprintf(err, "'%s' : %s", args[cur_arg], *err);
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01003935 return ERR_ALERT | ERR_FATAL;
Willy Tarreauad1731d2013-04-02 17:35:58 +02003936 }
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01003937
3938 return 0;
3939}
3940
Emeric Brunfb510ea2012-10-05 12:00:26 +02003941/* parse the "crl-file" bind keyword */
3942static 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 +02003943{
Emeric Brun051cdab2012-10-02 19:25:50 +02003944#ifndef X509_V_FLAG_CRL_CHECK
3945 if (err)
3946 memprintf(err, "'%s' : library does not support CRL verify", args[cur_arg]);
3947 return ERR_ALERT | ERR_FATAL;
3948#else
Emeric Brund94b3fe2012-09-20 18:23:56 +02003949 if (!*args[cur_arg + 1]) {
3950 if (err)
3951 memprintf(err, "'%s' : missing CRLfile path", args[cur_arg]);
3952 return ERR_ALERT | ERR_FATAL;
3953 }
Emeric Brun2b58d042012-09-20 17:10:03 +02003954
Emeric Brunef42d922012-10-11 16:11:36 +02003955 if ((*args[cur_arg + 1] != '/') && global.ca_base)
3956 memprintf(&conf->crl_file, "%s/%s", global.ca_base, args[cur_arg + 1]);
3957 else
3958 memprintf(&conf->crl_file, "%s", args[cur_arg + 1]);
Emeric Brunc8e8d122012-10-02 18:42:10 +02003959
Emeric Brun2b58d042012-09-20 17:10:03 +02003960 return 0;
Emeric Brun051cdab2012-10-02 19:25:50 +02003961#endif
Emeric Brun2b58d042012-09-20 17:10:03 +02003962}
3963
3964/* parse the "ecdhe" bind keyword keywords */
3965static int bind_parse_ecdhe(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
3966{
3967#if OPENSSL_VERSION_NUMBER < 0x0090800fL
3968 if (err)
3969 memprintf(err, "'%s' : library does not support elliptic curve Diffie-Hellman (too old)", args[cur_arg]);
3970 return ERR_ALERT | ERR_FATAL;
3971#elif defined(OPENSSL_NO_ECDH)
3972 if (err)
3973 memprintf(err, "'%s' : library does not support elliptic curve Diffie-Hellman (disabled via OPENSSL_NO_ECDH)", args[cur_arg]);
3974 return ERR_ALERT | ERR_FATAL;
3975#else
3976 if (!*args[cur_arg + 1]) {
3977 if (err)
3978 memprintf(err, "'%s' : missing named curve", args[cur_arg]);
3979 return ERR_ALERT | ERR_FATAL;
3980 }
3981
3982 conf->ecdhe = strdup(args[cur_arg + 1]);
Willy Tarreau79eeafa2012-09-14 07:53:05 +02003983
3984 return 0;
Emeric Brun2b58d042012-09-20 17:10:03 +02003985#endif
Willy Tarreau79eeafa2012-09-14 07:53:05 +02003986}
3987
Emeric Brun81c00f02012-09-21 14:31:21 +02003988/* parse the "crt_ignerr" and "ca_ignerr" bind keywords */
3989static int bind_parse_ignore_err(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
3990{
3991 int code;
3992 char *p = args[cur_arg + 1];
3993 unsigned long long *ignerr = &conf->crt_ignerr;
3994
3995 if (!*p) {
3996 if (err)
3997 memprintf(err, "'%s' : missing error IDs list", args[cur_arg]);
3998 return ERR_ALERT | ERR_FATAL;
3999 }
4000
4001 if (strcmp(args[cur_arg], "ca-ignore-err") == 0)
4002 ignerr = &conf->ca_ignerr;
4003
4004 if (strcmp(p, "all") == 0) {
4005 *ignerr = ~0ULL;
4006 return 0;
4007 }
4008
4009 while (p) {
4010 code = atoi(p);
4011 if ((code <= 0) || (code > 63)) {
4012 if (err)
4013 memprintf(err, "'%s' : ID '%d' out of range (1..63) in error IDs list '%s'",
4014 args[cur_arg], code, args[cur_arg + 1]);
4015 return ERR_ALERT | ERR_FATAL;
4016 }
4017 *ignerr |= 1ULL << code;
4018 p = strchr(p, ',');
4019 if (p)
4020 p++;
4021 }
4022
Emeric Brun2cb7ae52012-10-05 14:14:21 +02004023 return 0;
4024}
4025
4026/* parse the "force-sslv3" bind keyword */
4027static int bind_parse_force_sslv3(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
4028{
4029 conf->ssl_options |= BC_SSL_O_USE_SSLV3;
4030 return 0;
4031}
4032
4033/* parse the "force-tlsv10" bind keyword */
4034static int bind_parse_force_tlsv10(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
4035{
4036 conf->ssl_options |= BC_SSL_O_USE_TLSV10;
Emeric Brun2d0c4822012-10-02 13:45:20 +02004037 return 0;
4038}
4039
Emeric Brun2cb7ae52012-10-05 14:14:21 +02004040/* parse the "force-tlsv11" bind keyword */
4041static int bind_parse_force_tlsv11(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
4042{
4043#if SSL_OP_NO_TLSv1_1
4044 conf->ssl_options |= BC_SSL_O_USE_TLSV11;
4045 return 0;
4046#else
4047 if (err)
4048 memprintf(err, "'%s' : library does not support protocol TLSv1.1", args[cur_arg]);
4049 return ERR_ALERT | ERR_FATAL;
4050#endif
4051}
4052
4053/* parse the "force-tlsv12" bind keyword */
4054static int bind_parse_force_tlsv12(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
4055{
4056#if SSL_OP_NO_TLSv1_2
4057 conf->ssl_options |= BC_SSL_O_USE_TLSV12;
4058 return 0;
4059#else
4060 if (err)
4061 memprintf(err, "'%s' : library does not support protocol TLSv1.2", args[cur_arg]);
4062 return ERR_ALERT | ERR_FATAL;
4063#endif
4064}
4065
4066
Emeric Brun2d0c4822012-10-02 13:45:20 +02004067/* parse the "no-tls-tickets" bind keyword */
4068static int bind_parse_no_tls_tickets(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
4069{
Emeric Brun89675492012-10-05 13:48:26 +02004070 conf->ssl_options |= BC_SSL_O_NO_TLS_TICKETS;
Emeric Brun81c00f02012-09-21 14:31:21 +02004071 return 0;
4072}
4073
Emeric Brun2d0c4822012-10-02 13:45:20 +02004074
Emeric Brun9b3009b2012-10-05 11:55:06 +02004075/* parse the "no-sslv3" bind keyword */
4076static 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 +02004077{
Emeric Brun89675492012-10-05 13:48:26 +02004078 conf->ssl_options |= BC_SSL_O_NO_SSLV3;
Willy Tarreau79eeafa2012-09-14 07:53:05 +02004079 return 0;
4080}
4081
Emeric Brun9b3009b2012-10-05 11:55:06 +02004082/* parse the "no-tlsv10" bind keyword */
4083static 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 +02004084{
Emeric Brun89675492012-10-05 13:48:26 +02004085 conf->ssl_options |= BC_SSL_O_NO_TLSV10;
Emeric Brunc0ff4922012-09-28 19:37:02 +02004086 return 0;
4087}
4088
Emeric Brun9b3009b2012-10-05 11:55:06 +02004089/* parse the "no-tlsv11" bind keyword */
4090static 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 +02004091{
Emeric Brun89675492012-10-05 13:48:26 +02004092 conf->ssl_options |= BC_SSL_O_NO_TLSV11;
Emeric Brunc0ff4922012-09-28 19:37:02 +02004093 return 0;
4094}
4095
Emeric Brun9b3009b2012-10-05 11:55:06 +02004096/* parse the "no-tlsv12" bind keyword */
4097static 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 +02004098{
Emeric Brun89675492012-10-05 13:48:26 +02004099 conf->ssl_options |= BC_SSL_O_NO_TLSV12;
Willy Tarreau79eeafa2012-09-14 07:53:05 +02004100 return 0;
4101}
4102
Willy Tarreau6c9a3d52012-10-18 18:57:14 +02004103/* parse the "npn" bind keyword */
4104static int bind_parse_npn(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
4105{
4106#ifdef OPENSSL_NPN_NEGOTIATED
4107 char *p1, *p2;
4108
4109 if (!*args[cur_arg + 1]) {
4110 memprintf(err, "'%s' : missing the comma-delimited NPN protocol suite", args[cur_arg]);
4111 return ERR_ALERT | ERR_FATAL;
4112 }
4113
4114 free(conf->npn_str);
4115
4116 /* the NPN string is built as a suite of (<len> <name>)* */
4117 conf->npn_len = strlen(args[cur_arg + 1]) + 1;
4118 conf->npn_str = calloc(1, conf->npn_len);
4119 memcpy(conf->npn_str + 1, args[cur_arg + 1], conf->npn_len);
4120
4121 /* replace commas with the name length */
4122 p1 = conf->npn_str;
4123 p2 = p1 + 1;
4124 while (1) {
4125 p2 = memchr(p1 + 1, ',', conf->npn_str + conf->npn_len - (p1 + 1));
4126 if (!p2)
4127 p2 = p1 + 1 + strlen(p1 + 1);
4128
4129 if (p2 - (p1 + 1) > 255) {
4130 *p2 = '\0';
4131 memprintf(err, "'%s' : NPN protocol name too long : '%s'", args[cur_arg], p1 + 1);
4132 return ERR_ALERT | ERR_FATAL;
4133 }
4134
4135 *p1 = p2 - (p1 + 1);
4136 p1 = p2;
4137
4138 if (!*p2)
4139 break;
4140
4141 *(p2++) = '\0';
4142 }
4143 return 0;
4144#else
4145 if (err)
4146 memprintf(err, "'%s' : library does not support TLS NPN extension", args[cur_arg]);
4147 return ERR_ALERT | ERR_FATAL;
4148#endif
4149}
4150
Willy Tarreauab861d32013-04-02 02:30:41 +02004151/* parse the "alpn" bind keyword */
4152static int bind_parse_alpn(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
4153{
Dirkjan Bussink48f1c4e2014-02-13 12:29:42 +01004154#ifdef TLSEXT_TYPE_application_layer_protocol_negotiation
Willy Tarreauab861d32013-04-02 02:30:41 +02004155 char *p1, *p2;
4156
4157 if (!*args[cur_arg + 1]) {
4158 memprintf(err, "'%s' : missing the comma-delimited ALPN protocol suite", args[cur_arg]);
4159 return ERR_ALERT | ERR_FATAL;
4160 }
4161
4162 free(conf->alpn_str);
4163
4164 /* the ALPN string is built as a suite of (<len> <name>)* */
4165 conf->alpn_len = strlen(args[cur_arg + 1]) + 1;
4166 conf->alpn_str = calloc(1, conf->alpn_len);
4167 memcpy(conf->alpn_str + 1, args[cur_arg + 1], conf->alpn_len);
4168
4169 /* replace commas with the name length */
4170 p1 = conf->alpn_str;
4171 p2 = p1 + 1;
4172 while (1) {
4173 p2 = memchr(p1 + 1, ',', conf->alpn_str + conf->alpn_len - (p1 + 1));
4174 if (!p2)
4175 p2 = p1 + 1 + strlen(p1 + 1);
4176
4177 if (p2 - (p1 + 1) > 255) {
4178 *p2 = '\0';
4179 memprintf(err, "'%s' : ALPN protocol name too long : '%s'", args[cur_arg], p1 + 1);
4180 return ERR_ALERT | ERR_FATAL;
4181 }
4182
4183 *p1 = p2 - (p1 + 1);
4184 p1 = p2;
4185
4186 if (!*p2)
4187 break;
4188
4189 *(p2++) = '\0';
4190 }
4191 return 0;
4192#else
4193 if (err)
4194 memprintf(err, "'%s' : library does not support TLS ALPN extension", args[cur_arg]);
4195 return ERR_ALERT | ERR_FATAL;
4196#endif
4197}
4198
Willy Tarreau79eeafa2012-09-14 07:53:05 +02004199/* parse the "ssl" bind keyword */
Willy Tarreau4348fad2012-09-20 16:48:07 +02004200static 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 +02004201{
Willy Tarreau81796be2012-09-22 19:11:47 +02004202 struct listener *l;
4203
Willy Tarreau4348fad2012-09-20 16:48:07 +02004204 conf->is_ssl = 1;
Emeric Brun76d88952012-10-05 15:47:31 +02004205
4206 if (global.listen_default_ciphers && !conf->ciphers)
4207 conf->ciphers = strdup(global.listen_default_ciphers);
Emeric Brun2c86cbf2014-10-30 15:56:50 +01004208 conf->ssl_options |= global.listen_default_ssloptions;
Emeric Brun76d88952012-10-05 15:47:31 +02004209
Willy Tarreau81796be2012-09-22 19:11:47 +02004210 list_for_each_entry(l, &conf->listeners, by_bind)
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02004211 l->xprt = &ssl_sock;
Willy Tarreau81796be2012-09-22 19:11:47 +02004212
Willy Tarreau79eeafa2012-09-14 07:53:05 +02004213 return 0;
4214}
4215
Emmanuel Hocdet65623372013-01-24 17:17:15 +01004216/* parse the "strict-sni" bind keyword */
4217static int bind_parse_strict_sni(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
4218{
4219 conf->strict_sni = 1;
4220 return 0;
4221}
4222
Emeric Brund94b3fe2012-09-20 18:23:56 +02004223/* parse the "verify" bind keyword */
4224static int bind_parse_verify(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
4225{
4226 if (!*args[cur_arg + 1]) {
4227 if (err)
4228 memprintf(err, "'%s' : missing verify method", args[cur_arg]);
4229 return ERR_ALERT | ERR_FATAL;
4230 }
4231
4232 if (strcmp(args[cur_arg + 1], "none") == 0)
Emeric Brun850efd52014-01-29 12:24:34 +01004233 conf->verify = SSL_SOCK_VERIFY_NONE;
Emeric Brund94b3fe2012-09-20 18:23:56 +02004234 else if (strcmp(args[cur_arg + 1], "optional") == 0)
Emeric Brun850efd52014-01-29 12:24:34 +01004235 conf->verify = SSL_SOCK_VERIFY_OPTIONAL;
Emeric Brund94b3fe2012-09-20 18:23:56 +02004236 else if (strcmp(args[cur_arg + 1], "required") == 0)
Emeric Brun850efd52014-01-29 12:24:34 +01004237 conf->verify = SSL_SOCK_VERIFY_REQUIRED;
Emeric Brund94b3fe2012-09-20 18:23:56 +02004238 else {
4239 if (err)
4240 memprintf(err, "'%s' : unknown verify method '%s', only 'none', 'optional', and 'required' are supported\n",
4241 args[cur_arg], args[cur_arg + 1]);
4242 return ERR_ALERT | ERR_FATAL;
4243 }
4244
4245 return 0;
4246}
4247
Willy Tarreau92faadf2012-10-10 23:04:25 +02004248/************** "server" keywords ****************/
4249
Emeric Brunef42d922012-10-11 16:11:36 +02004250/* parse the "ca-file" server keyword */
4251static int srv_parse_ca_file(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
4252{
4253 if (!*args[*cur_arg + 1]) {
4254 if (err)
4255 memprintf(err, "'%s' : missing CAfile path", args[*cur_arg]);
4256 return ERR_ALERT | ERR_FATAL;
4257 }
4258
4259 if ((*args[*cur_arg + 1] != '/') && global.ca_base)
4260 memprintf(&newsrv->ssl_ctx.ca_file, "%s/%s", global.ca_base, args[*cur_arg + 1]);
4261 else
4262 memprintf(&newsrv->ssl_ctx.ca_file, "%s", args[*cur_arg + 1]);
4263
4264 return 0;
4265}
4266
Willy Tarreau92faadf2012-10-10 23:04:25 +02004267/* parse the "check-ssl" server keyword */
4268static int srv_parse_check_ssl(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
4269{
4270 newsrv->check.use_ssl = 1;
4271 if (global.connect_default_ciphers && !newsrv->ssl_ctx.ciphers)
4272 newsrv->ssl_ctx.ciphers = strdup(global.connect_default_ciphers);
Emeric Brun2c86cbf2014-10-30 15:56:50 +01004273 newsrv->ssl_ctx.options |= global.connect_default_ssloptions;
Willy Tarreau92faadf2012-10-10 23:04:25 +02004274 return 0;
4275}
4276
4277/* parse the "ciphers" server keyword */
4278static int srv_parse_ciphers(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
4279{
4280 if (!*args[*cur_arg + 1]) {
4281 memprintf(err, "'%s' : missing cipher suite", args[*cur_arg]);
4282 return ERR_ALERT | ERR_FATAL;
4283 }
4284
4285 free(newsrv->ssl_ctx.ciphers);
4286 newsrv->ssl_ctx.ciphers = strdup(args[*cur_arg + 1]);
4287 return 0;
4288}
4289
Emeric Brunef42d922012-10-11 16:11:36 +02004290/* parse the "crl-file" server keyword */
4291static int srv_parse_crl_file(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
4292{
4293#ifndef X509_V_FLAG_CRL_CHECK
4294 if (err)
4295 memprintf(err, "'%s' : library does not support CRL verify", args[*cur_arg]);
4296 return ERR_ALERT | ERR_FATAL;
4297#else
4298 if (!*args[*cur_arg + 1]) {
4299 if (err)
4300 memprintf(err, "'%s' : missing CRLfile path", args[*cur_arg]);
4301 return ERR_ALERT | ERR_FATAL;
4302 }
4303
4304 if ((*args[*cur_arg + 1] != '/') && global.ca_base)
4305 memprintf(&newsrv->ssl_ctx.crl_file, "%s/%s", global.ca_base, args[*cur_arg + 1]);
4306 else
4307 memprintf(&newsrv->ssl_ctx.crl_file, "%s", args[*cur_arg + 1]);
4308
4309 return 0;
4310#endif
4311}
4312
Emeric Bruna7aa3092012-10-26 12:58:00 +02004313/* parse the "crt" server keyword */
4314static int srv_parse_crt(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
4315{
4316 if (!*args[*cur_arg + 1]) {
4317 if (err)
4318 memprintf(err, "'%s' : missing certificate file path", args[*cur_arg]);
4319 return ERR_ALERT | ERR_FATAL;
4320 }
4321
4322 if ((*args[*cur_arg + 1] != '/') && global.crt_base)
4323 memprintf(&newsrv->ssl_ctx.client_crt, "%s/%s", global.ca_base, args[*cur_arg + 1]);
4324 else
4325 memprintf(&newsrv->ssl_ctx.client_crt, "%s", args[*cur_arg + 1]);
4326
4327 return 0;
4328}
Emeric Brunef42d922012-10-11 16:11:36 +02004329
Willy Tarreau92faadf2012-10-10 23:04:25 +02004330/* parse the "force-sslv3" server keyword */
4331static int srv_parse_force_sslv3(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
4332{
4333 newsrv->ssl_ctx.options |= SRV_SSL_O_USE_SSLV3;
4334 return 0;
4335}
4336
4337/* parse the "force-tlsv10" server keyword */
4338static int srv_parse_force_tlsv10(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
4339{
4340 newsrv->ssl_ctx.options |= SRV_SSL_O_USE_TLSV10;
4341 return 0;
4342}
4343
4344/* parse the "force-tlsv11" server keyword */
4345static int srv_parse_force_tlsv11(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
4346{
4347#if SSL_OP_NO_TLSv1_1
4348 newsrv->ssl_ctx.options |= SRV_SSL_O_USE_TLSV11;
4349 return 0;
4350#else
4351 if (err)
4352 memprintf(err, "'%s' : library does not support protocol TLSv1.1", args[*cur_arg]);
4353 return ERR_ALERT | ERR_FATAL;
4354#endif
4355}
4356
4357/* parse the "force-tlsv12" server keyword */
4358static int srv_parse_force_tlsv12(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
4359{
4360#if SSL_OP_NO_TLSv1_2
4361 newsrv->ssl_ctx.options |= SRV_SSL_O_USE_TLSV12;
4362 return 0;
4363#else
4364 if (err)
4365 memprintf(err, "'%s' : library does not support protocol TLSv1.2", args[*cur_arg]);
4366 return ERR_ALERT | ERR_FATAL;
4367#endif
4368}
4369
Willy Tarreau2a3fb1c2015-02-05 16:47:07 +01004370/* parse the "no-ssl-reuse" server keyword */
4371static int srv_parse_no_ssl_reuse(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
4372{
4373 newsrv->ssl_ctx.options |= SRV_SSL_O_NO_REUSE;
4374 return 0;
4375}
4376
Willy Tarreau92faadf2012-10-10 23:04:25 +02004377/* parse the "no-sslv3" server keyword */
4378static int srv_parse_no_sslv3(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
4379{
4380 newsrv->ssl_ctx.options |= SRV_SSL_O_NO_SSLV3;
4381 return 0;
4382}
4383
4384/* parse the "no-tlsv10" server keyword */
4385static int srv_parse_no_tlsv10(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
4386{
4387 newsrv->ssl_ctx.options |= SRV_SSL_O_NO_TLSV10;
4388 return 0;
4389}
4390
4391/* parse the "no-tlsv11" server keyword */
4392static int srv_parse_no_tlsv11(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
4393{
4394 newsrv->ssl_ctx.options |= SRV_SSL_O_NO_TLSV11;
4395 return 0;
4396}
4397
4398/* parse the "no-tlsv12" server keyword */
4399static int srv_parse_no_tlsv12(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
4400{
4401 newsrv->ssl_ctx.options |= SRV_SSL_O_NO_TLSV12;
4402 return 0;
4403}
4404
Emeric Brunf9c5c472012-10-11 15:28:34 +02004405/* parse the "no-tls-tickets" server keyword */
4406static int srv_parse_no_tls_tickets(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
4407{
4408 newsrv->ssl_ctx.options |= SRV_SSL_O_NO_TLS_TICKETS;
4409 return 0;
4410}
David Safb76832014-05-08 23:42:08 -04004411/* parse the "send-proxy-v2-ssl" server keyword */
4412static int srv_parse_send_proxy_ssl(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
4413{
4414 newsrv->pp_opts |= SRV_PP_V2;
4415 newsrv->pp_opts |= SRV_PP_V2_SSL;
4416 return 0;
4417}
4418
4419/* parse the "send-proxy-v2-ssl-cn" server keyword */
4420static int srv_parse_send_proxy_cn(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
4421{
4422 newsrv->pp_opts |= SRV_PP_V2;
4423 newsrv->pp_opts |= SRV_PP_V2_SSL;
4424 newsrv->pp_opts |= SRV_PP_V2_SSL_CN;
4425 return 0;
4426}
Emeric Brunf9c5c472012-10-11 15:28:34 +02004427
Willy Tarreau92faadf2012-10-10 23:04:25 +02004428/* parse the "ssl" server keyword */
4429static int srv_parse_ssl(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
4430{
4431 newsrv->use_ssl = 1;
4432 if (global.connect_default_ciphers && !newsrv->ssl_ctx.ciphers)
4433 newsrv->ssl_ctx.ciphers = strdup(global.connect_default_ciphers);
4434 return 0;
4435}
4436
Emeric Brunef42d922012-10-11 16:11:36 +02004437/* parse the "verify" server keyword */
4438static int srv_parse_verify(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
4439{
4440 if (!*args[*cur_arg + 1]) {
4441 if (err)
4442 memprintf(err, "'%s' : missing verify method", args[*cur_arg]);
4443 return ERR_ALERT | ERR_FATAL;
4444 }
4445
4446 if (strcmp(args[*cur_arg + 1], "none") == 0)
Emeric Brun850efd52014-01-29 12:24:34 +01004447 newsrv->ssl_ctx.verify = SSL_SOCK_VERIFY_NONE;
Emeric Brunef42d922012-10-11 16:11:36 +02004448 else if (strcmp(args[*cur_arg + 1], "required") == 0)
Emeric Brun850efd52014-01-29 12:24:34 +01004449 newsrv->ssl_ctx.verify = SSL_SOCK_VERIFY_REQUIRED;
Emeric Brunef42d922012-10-11 16:11:36 +02004450 else {
4451 if (err)
4452 memprintf(err, "'%s' : unknown verify method '%s', only 'none' and 'required' are supported\n",
4453 args[*cur_arg], args[*cur_arg + 1]);
4454 return ERR_ALERT | ERR_FATAL;
4455 }
4456
Evan Broderbe554312013-06-27 00:05:25 -07004457 return 0;
4458}
4459
4460/* parse the "verifyhost" server keyword */
4461static int srv_parse_verifyhost(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
4462{
4463 if (!*args[*cur_arg + 1]) {
4464 if (err)
4465 memprintf(err, "'%s' : missing hostname to verify against", args[*cur_arg]);
4466 return ERR_ALERT | ERR_FATAL;
4467 }
4468
4469 newsrv->ssl_ctx.verify_host = strdup(args[*cur_arg + 1]);
4470
Emeric Brunef42d922012-10-11 16:11:36 +02004471 return 0;
4472}
4473
Emeric Brun2c86cbf2014-10-30 15:56:50 +01004474/* parse the "ssl-default-bind-options" keyword in global section */
4475static int ssl_parse_default_bind_options(char **args, int section_type, struct proxy *curpx,
4476 struct proxy *defpx, const char *file, int line,
4477 char **err) {
4478 int i = 1;
4479
4480 if (*(args[i]) == 0) {
4481 memprintf(err, "global statement '%s' expects an option as an argument.", args[0]);
4482 return -1;
4483 }
4484 while (*(args[i])) {
4485 if (!strcmp(args[i], "no-sslv3"))
4486 global.listen_default_ssloptions |= BC_SSL_O_NO_SSLV3;
4487 else if (!strcmp(args[i], "no-tlsv10"))
4488 global.listen_default_ssloptions |= BC_SSL_O_NO_TLSV10;
4489 else if (!strcmp(args[i], "no-tlsv11"))
4490 global.listen_default_ssloptions |= BC_SSL_O_NO_TLSV11;
4491 else if (!strcmp(args[i], "no-tlsv12"))
4492 global.listen_default_ssloptions |= BC_SSL_O_NO_TLSV12;
4493 else if (!strcmp(args[i], "force-sslv3"))
4494 global.listen_default_ssloptions |= BC_SSL_O_USE_SSLV3;
4495 else if (!strcmp(args[i], "force-tlsv10"))
4496 global.listen_default_ssloptions |= BC_SSL_O_USE_TLSV10;
4497 else if (!strcmp(args[i], "force-tlsv11")) {
4498#if SSL_OP_NO_TLSv1_1
4499 global.listen_default_ssloptions |= BC_SSL_O_USE_TLSV11;
4500#else
4501 memprintf(err, "'%s' '%s': library does not support protocol TLSv1.1", args[0], args[i]);
4502 return -1;
4503#endif
4504 }
4505 else if (!strcmp(args[i], "force-tlsv12")) {
4506#if SSL_OP_NO_TLSv1_2
4507 global.listen_default_ssloptions |= BC_SSL_O_USE_TLSV12;
4508#else
4509 memprintf(err, "'%s' '%s': library does not support protocol TLSv1.2", args[0], args[i]);
4510 return -1;
4511#endif
4512 }
4513 else if (!strcmp(args[i], "no-tls-tickets"))
4514 global.listen_default_ssloptions |= BC_SSL_O_NO_TLS_TICKETS;
4515 else {
4516 memprintf(err, "unknown option '%s' on global statement '%s'.", args[i], args[0]);
4517 return -1;
4518 }
4519 i++;
4520 }
4521 return 0;
4522}
4523
4524/* parse the "ssl-default-server-options" keyword in global section */
4525static int ssl_parse_default_server_options(char **args, int section_type, struct proxy *curpx,
4526 struct proxy *defpx, const char *file, int line,
4527 char **err) {
4528 int i = 1;
4529
4530 if (*(args[i]) == 0) {
4531 memprintf(err, "global statement '%s' expects an option as an argument.", args[0]);
4532 return -1;
4533 }
4534 while (*(args[i])) {
4535 if (!strcmp(args[i], "no-sslv3"))
4536 global.connect_default_ssloptions |= SRV_SSL_O_NO_SSLV3;
4537 else if (!strcmp(args[i], "no-tlsv10"))
4538 global.connect_default_ssloptions |= SRV_SSL_O_NO_TLSV10;
4539 else if (!strcmp(args[i], "no-tlsv11"))
4540 global.connect_default_ssloptions |= SRV_SSL_O_NO_TLSV11;
4541 else if (!strcmp(args[i], "no-tlsv12"))
4542 global.connect_default_ssloptions |= SRV_SSL_O_NO_TLSV12;
4543 else if (!strcmp(args[i], "force-sslv3"))
4544 global.connect_default_ssloptions |= SRV_SSL_O_USE_SSLV3;
4545 else if (!strcmp(args[i], "force-tlsv10"))
4546 global.connect_default_ssloptions |= SRV_SSL_O_USE_TLSV10;
4547 else if (!strcmp(args[i], "force-tlsv11")) {
4548#if SSL_OP_NO_TLSv1_1
4549 global.connect_default_ssloptions |= SRV_SSL_O_USE_TLSV11;
4550#else
4551 memprintf(err, "'%s' '%s': library does not support protocol TLSv1.1", args[0], args[i]);
4552 return -1;
4553#endif
4554 }
4555 else if (!strcmp(args[i], "force-tlsv12")) {
4556#if SSL_OP_NO_TLSv1_2
4557 global.connect_default_ssloptions |= SRV_SSL_O_USE_TLSV12;
4558#else
4559 memprintf(err, "'%s' '%s': library does not support protocol TLSv1.2", args[0], args[i]);
4560 return -1;
4561#endif
4562 }
4563 else if (!strcmp(args[i], "no-tls-tickets"))
4564 global.connect_default_ssloptions |= SRV_SSL_O_NO_TLS_TICKETS;
4565 else {
4566 memprintf(err, "unknown option '%s' on global statement '%s'.", args[i], args[0]);
4567 return -1;
4568 }
4569 i++;
4570 }
4571 return 0;
4572}
4573
Willy Tarreau7875d092012-09-10 08:20:03 +02004574/* Note: must not be declared <const> as its list will be overwritten.
4575 * Please take care of keeping this list alphabetically sorted.
4576 */
Willy Tarreaudc13c112013-06-21 23:16:39 +02004577static struct sample_fetch_kw_list sample_fetch_keywords = {ILH, {
Emeric Brun645ae792014-04-30 14:21:06 +02004578 { "ssl_bc", smp_fetch_ssl_fc, 0, NULL, SMP_T_BOOL, SMP_USE_L5SRV },
4579 { "ssl_bc_alg_keysize", smp_fetch_ssl_fc_alg_keysize, 0, NULL, SMP_T_UINT, SMP_USE_L5SRV },
4580 { "ssl_bc_cipher", smp_fetch_ssl_fc_cipher, 0, NULL, SMP_T_STR, SMP_USE_L5SRV },
4581 { "ssl_bc_protocol", smp_fetch_ssl_fc_protocol, 0, NULL, SMP_T_STR, SMP_USE_L5SRV },
Emeric Brunb73a9b02014-04-30 18:49:19 +02004582 { "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 +02004583 { "ssl_bc_use_keysize", smp_fetch_ssl_fc_use_keysize, 0, NULL, SMP_T_UINT, SMP_USE_L5SRV },
4584 { "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 +01004585 { "ssl_c_ca_err", smp_fetch_ssl_c_ca_err, 0, NULL, SMP_T_UINT, SMP_USE_L5CLI },
4586 { "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 +01004587 { "ssl_c_der", smp_fetch_ssl_x_der, 0, NULL, SMP_T_BIN, SMP_USE_L5CLI },
Willy Tarreau80aca902013-01-07 15:42:20 +01004588 { "ssl_c_err", smp_fetch_ssl_c_err, 0, NULL, SMP_T_UINT, SMP_USE_L5CLI },
Emeric Brunba841a12014-04-30 17:05:08 +02004589 { "ssl_c_i_dn", smp_fetch_ssl_x_i_dn, ARG2(0,STR,SINT), NULL, SMP_T_STR, SMP_USE_L5CLI },
4590 { "ssl_c_key_alg", smp_fetch_ssl_x_key_alg, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
4591 { "ssl_c_notafter", smp_fetch_ssl_x_notafter, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
4592 { "ssl_c_notbefore", smp_fetch_ssl_x_notbefore, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
4593 { "ssl_c_sig_alg", smp_fetch_ssl_x_sig_alg, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
4594 { "ssl_c_s_dn", smp_fetch_ssl_x_s_dn, ARG2(0,STR,SINT), NULL, SMP_T_STR, SMP_USE_L5CLI },
4595 { "ssl_c_serial", smp_fetch_ssl_x_serial, 0, NULL, SMP_T_BIN, SMP_USE_L5CLI },
4596 { "ssl_c_sha1", smp_fetch_ssl_x_sha1, 0, NULL, SMP_T_BIN, SMP_USE_L5CLI },
Willy Tarreau80aca902013-01-07 15:42:20 +01004597 { "ssl_c_used", smp_fetch_ssl_c_used, 0, NULL, SMP_T_BOOL, SMP_USE_L5CLI },
4598 { "ssl_c_verify", smp_fetch_ssl_c_verify, 0, NULL, SMP_T_UINT, SMP_USE_L5CLI },
Emeric Brunba841a12014-04-30 17:05:08 +02004599 { "ssl_c_version", smp_fetch_ssl_x_version, 0, NULL, SMP_T_UINT, SMP_USE_L5CLI },
Emeric Brun43e79582014-10-29 19:03:26 +01004600 { "ssl_f_der", smp_fetch_ssl_x_der, 0, NULL, SMP_T_BIN, SMP_USE_L5CLI },
Emeric Brunba841a12014-04-30 17:05:08 +02004601 { "ssl_f_i_dn", smp_fetch_ssl_x_i_dn, ARG2(0,STR,SINT), NULL, SMP_T_STR, SMP_USE_L5CLI },
4602 { "ssl_f_key_alg", smp_fetch_ssl_x_key_alg, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
4603 { "ssl_f_notafter", smp_fetch_ssl_x_notafter, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
4604 { "ssl_f_notbefore", smp_fetch_ssl_x_notbefore, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
4605 { "ssl_f_sig_alg", smp_fetch_ssl_x_sig_alg, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
4606 { "ssl_f_s_dn", smp_fetch_ssl_x_s_dn, ARG2(0,STR,SINT), NULL, SMP_T_STR, SMP_USE_L5CLI },
4607 { "ssl_f_serial", smp_fetch_ssl_x_serial, 0, NULL, SMP_T_BIN, SMP_USE_L5CLI },
Emeric Brun55f4fa82014-04-30 17:11:25 +02004608 { "ssl_f_sha1", smp_fetch_ssl_x_sha1, 0, NULL, SMP_T_BIN, SMP_USE_L5CLI },
Emeric Brunba841a12014-04-30 17:05:08 +02004609 { "ssl_f_version", smp_fetch_ssl_x_version, 0, NULL, SMP_T_UINT, SMP_USE_L5CLI },
Willy Tarreau80aca902013-01-07 15:42:20 +01004610 { "ssl_fc", smp_fetch_ssl_fc, 0, NULL, SMP_T_BOOL, SMP_USE_L5CLI },
4611 { "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 +01004612 { "ssl_fc_cipher", smp_fetch_ssl_fc_cipher, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
Willy Tarreau80aca902013-01-07 15:42:20 +01004613 { "ssl_fc_has_crt", smp_fetch_ssl_fc_has_crt, 0, NULL, SMP_T_BOOL, SMP_USE_L5CLI },
4614 { "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 +02004615#ifdef OPENSSL_NPN_NEGOTIATED
Thierry FOURNIER7654c9f2013-12-17 00:20:33 +01004616 { "ssl_fc_npn", smp_fetch_ssl_fc_npn, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
Willy Tarreaua33c6542012-10-15 13:19:06 +02004617#endif
Dirkjan Bussink48f1c4e2014-02-13 12:29:42 +01004618#ifdef TLSEXT_TYPE_application_layer_protocol_negotiation
Thierry FOURNIER7654c9f2013-12-17 00:20:33 +01004619 { "ssl_fc_alpn", smp_fetch_ssl_fc_alpn, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
Willy Tarreauab861d32013-04-02 02:30:41 +02004620#endif
Thierry FOURNIER7654c9f2013-12-17 00:20:33 +01004621 { "ssl_fc_protocol", smp_fetch_ssl_fc_protocol, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
Emeric Brunb73a9b02014-04-30 18:49:19 +02004622 { "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 +01004623 { "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 +01004624 { "ssl_fc_session_id", smp_fetch_ssl_fc_session_id, 0, NULL, SMP_T_BIN, SMP_USE_L5CLI },
4625 { "ssl_fc_sni", smp_fetch_ssl_fc_sni, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
Willy Tarreau7875d092012-09-10 08:20:03 +02004626 { NULL, NULL, 0, 0, 0 },
4627}};
4628
4629/* Note: must not be declared <const> as its list will be overwritten.
4630 * Please take care of keeping this list alphabetically sorted.
4631 */
Willy Tarreaudc13c112013-06-21 23:16:39 +02004632static struct acl_kw_list acl_kws = {ILH, {
Thierry FOURNIERc5a4e982014-03-05 16:07:08 +01004633 { "ssl_fc_sni_end", "ssl_fc_sni", PAT_MATCH_END },
4634 { "ssl_fc_sni_reg", "ssl_fc_sni", PAT_MATCH_REG },
Willy Tarreau8ed669b2013-01-11 15:49:37 +01004635 { /* END */ },
Willy Tarreau7875d092012-09-10 08:20:03 +02004636}};
4637
Willy Tarreau79eeafa2012-09-14 07:53:05 +02004638/* Note: must not be declared <const> as its list will be overwritten.
4639 * Please take care of keeping this list alphabetically sorted, doing so helps
4640 * all code contributors.
4641 * Optional keywords are also declared with a NULL ->parse() function so that
4642 * the config parser can report an appropriate error when a known keyword was
4643 * not enabled.
4644 */
Willy Tarreau51fb7652012-09-18 18:24:39 +02004645static struct bind_kw_list bind_kws = { "SSL", { }, {
Willy Tarreauab861d32013-04-02 02:30:41 +02004646 { "alpn", bind_parse_alpn, 1 }, /* set ALPN supported protocols */
Emeric Brunfb510ea2012-10-05 12:00:26 +02004647 { "ca-file", bind_parse_ca_file, 1 }, /* set CAfile to process verify on client cert */
Emeric Brun2d0c4822012-10-02 13:45:20 +02004648 { "ca-ignore-err", bind_parse_ignore_err, 1 }, /* set error IDs to ignore on verify depth > 0 */
4649 { "ciphers", bind_parse_ciphers, 1 }, /* set SSL cipher suite */
Emeric Brunfb510ea2012-10-05 12:00:26 +02004650 { "crl-file", bind_parse_crl_file, 1 }, /* set certificat revocation list file use on client cert verify */
Emeric Brun2d0c4822012-10-02 13:45:20 +02004651 { "crt", bind_parse_crt, 1 }, /* load SSL certificates from this location */
4652 { "crt-ignore-err", bind_parse_ignore_err, 1 }, /* set error IDs to ingore on verify depth == 0 */
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01004653 { "crt-list", bind_parse_crt_list, 1 }, /* load a list of crt from this location */
Emeric Brun2d0c4822012-10-02 13:45:20 +02004654 { "ecdhe", bind_parse_ecdhe, 1 }, /* defines named curve for elliptic curve Diffie-Hellman */
Emeric Brun2cb7ae52012-10-05 14:14:21 +02004655 { "force-sslv3", bind_parse_force_sslv3, 0 }, /* force SSLv3 */
4656 { "force-tlsv10", bind_parse_force_tlsv10, 0 }, /* force TLSv10 */
4657 { "force-tlsv11", bind_parse_force_tlsv11, 0 }, /* force TLSv11 */
4658 { "force-tlsv12", bind_parse_force_tlsv12, 0 }, /* force TLSv12 */
Emeric Brun9b3009b2012-10-05 11:55:06 +02004659 { "no-sslv3", bind_parse_no_sslv3, 0 }, /* disable SSLv3 */
4660 { "no-tlsv10", bind_parse_no_tlsv10, 0 }, /* disable TLSv10 */
4661 { "no-tlsv11", bind_parse_no_tlsv11, 0 }, /* disable TLSv11 */
4662 { "no-tlsv12", bind_parse_no_tlsv12, 0 }, /* disable TLSv12 */
Emeric Brun2d0c4822012-10-02 13:45:20 +02004663 { "no-tls-tickets", bind_parse_no_tls_tickets, 0 }, /* disable session resumption tickets */
Emeric Brun2d0c4822012-10-02 13:45:20 +02004664 { "ssl", bind_parse_ssl, 0 }, /* enable SSL processing */
Emmanuel Hocdet65623372013-01-24 17:17:15 +01004665 { "strict-sni", bind_parse_strict_sni, 0 }, /* refuse negotiation if sni doesn't match a certificate */
Emeric Brun2d0c4822012-10-02 13:45:20 +02004666 { "verify", bind_parse_verify, 1 }, /* set SSL verify method */
Willy Tarreau6c9a3d52012-10-18 18:57:14 +02004667 { "npn", bind_parse_npn, 1 }, /* set NPN supported protocols */
Willy Tarreau79eeafa2012-09-14 07:53:05 +02004668 { NULL, NULL, 0 },
4669}};
Emeric Brun46591952012-05-18 15:47:34 +02004670
Willy Tarreau92faadf2012-10-10 23:04:25 +02004671/* Note: must not be declared <const> as its list will be overwritten.
4672 * Please take care of keeping this list alphabetically sorted, doing so helps
4673 * all code contributors.
4674 * Optional keywords are also declared with a NULL ->parse() function so that
4675 * the config parser can report an appropriate error when a known keyword was
4676 * not enabled.
4677 */
4678static struct srv_kw_list srv_kws = { "SSL", { }, {
Emeric Brunef42d922012-10-11 16:11:36 +02004679 { "ca-file", srv_parse_ca_file, 1, 0 }, /* set CAfile to process verify server cert */
Emeric Brunecc91fe2012-10-11 15:05:10 +02004680 { "check-ssl", srv_parse_check_ssl, 0, 0 }, /* enable SSL for health checks */
4681 { "ciphers", srv_parse_ciphers, 1, 0 }, /* select the cipher suite */
Emeric Brunef42d922012-10-11 16:11:36 +02004682 { "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 +02004683 { "crt", srv_parse_crt, 1, 0 }, /* set client certificate */
Emeric Brunecc91fe2012-10-11 15:05:10 +02004684 { "force-sslv3", srv_parse_force_sslv3, 0, 0 }, /* force SSLv3 */
4685 { "force-tlsv10", srv_parse_force_tlsv10, 0, 0 }, /* force TLSv10 */
4686 { "force-tlsv11", srv_parse_force_tlsv11, 0, 0 }, /* force TLSv11 */
4687 { "force-tlsv12", srv_parse_force_tlsv12, 0, 0 }, /* force TLSv12 */
Willy Tarreau2a3fb1c2015-02-05 16:47:07 +01004688 { "no-ssl-reuse", srv_parse_no_ssl_reuse, 0, 0 }, /* disable session reuse */
Emeric Brunecc91fe2012-10-11 15:05:10 +02004689 { "no-sslv3", srv_parse_no_sslv3, 0, 0 }, /* disable SSLv3 */
4690 { "no-tlsv10", srv_parse_no_tlsv10, 0, 0 }, /* disable TLSv10 */
4691 { "no-tlsv11", srv_parse_no_tlsv11, 0, 0 }, /* disable TLSv11 */
4692 { "no-tlsv12", srv_parse_no_tlsv12, 0, 0 }, /* disable TLSv12 */
Emeric Brunf9c5c472012-10-11 15:28:34 +02004693 { "no-tls-tickets", srv_parse_no_tls_tickets, 0, 0 }, /* disable session resumption tickets */
David Safb76832014-05-08 23:42:08 -04004694 { "send-proxy-v2-ssl", srv_parse_send_proxy_ssl, 0, 0 }, /* send PROXY protocol header v2 with SSL info */
4695 { "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 +02004696 { "ssl", srv_parse_ssl, 0, 0 }, /* enable SSL processing */
Emeric Brunef42d922012-10-11 16:11:36 +02004697 { "verify", srv_parse_verify, 1, 0 }, /* set SSL verify method */
Evan Broderbe554312013-06-27 00:05:25 -07004698 { "verifyhost", srv_parse_verifyhost, 1, 0 }, /* require that SSL cert verifies for hostname */
Willy Tarreau92faadf2012-10-10 23:04:25 +02004699 { NULL, NULL, 0, 0 },
4700}};
4701
Emeric Brun2c86cbf2014-10-30 15:56:50 +01004702static struct cfg_kw_list cfg_kws = {ILH, {
4703 { CFG_GLOBAL, "ssl-default-bind-options", ssl_parse_default_bind_options },
4704 { CFG_GLOBAL, "ssl-default-server-options", ssl_parse_default_server_options },
4705 { 0, NULL, NULL },
4706}};
4707
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02004708/* transport-layer operations for SSL sockets */
4709struct xprt_ops ssl_sock = {
Emeric Brun46591952012-05-18 15:47:34 +02004710 .snd_buf = ssl_sock_from_buf,
4711 .rcv_buf = ssl_sock_to_buf,
4712 .rcv_pipe = NULL,
4713 .snd_pipe = NULL,
4714 .shutr = NULL,
4715 .shutw = ssl_sock_shutw,
4716 .close = ssl_sock_close,
4717 .init = ssl_sock_init,
4718};
4719
4720__attribute__((constructor))
Willy Tarreau92faadf2012-10-10 23:04:25 +02004721static void __ssl_sock_init(void)
4722{
Emeric Brun46591952012-05-18 15:47:34 +02004723 STACK_OF(SSL_COMP)* cm;
4724
Willy Tarreau610f04b2014-02-13 11:36:41 +01004725#ifdef LISTEN_DEFAULT_CIPHERS
4726 global.listen_default_ciphers = LISTEN_DEFAULT_CIPHERS;
4727#endif
4728#ifdef CONNECT_DEFAULT_CIPHERS
4729 global.connect_default_ciphers = CONNECT_DEFAULT_CIPHERS;
4730#endif
4731 if (global.listen_default_ciphers)
4732 global.listen_default_ciphers = strdup(global.listen_default_ciphers);
4733 if (global.connect_default_ciphers)
4734 global.connect_default_ciphers = strdup(global.connect_default_ciphers);
Emeric Brun2c86cbf2014-10-30 15:56:50 +01004735 global.listen_default_ssloptions = BC_SSL_O_NONE;
4736 global.connect_default_ssloptions = SRV_SSL_O_NONE;
Willy Tarreau610f04b2014-02-13 11:36:41 +01004737
Emeric Brun46591952012-05-18 15:47:34 +02004738 SSL_library_init();
4739 cm = SSL_COMP_get_compression_methods();
4740 sk_SSL_COMP_zero(cm);
Willy Tarreau7875d092012-09-10 08:20:03 +02004741 sample_register_fetches(&sample_fetch_keywords);
4742 acl_register_keywords(&acl_kws);
Willy Tarreau79eeafa2012-09-14 07:53:05 +02004743 bind_register_keywords(&bind_kws);
Willy Tarreau92faadf2012-10-10 23:04:25 +02004744 srv_register_keywords(&srv_kws);
Emeric Brun2c86cbf2014-10-30 15:56:50 +01004745 cfg_register_keywords(&cfg_kws);
Willy Tarreaud92aa5c2015-01-15 21:34:39 +01004746
4747 global.ssl_session_max_cost = SSL_SESSION_MAX_COST;
4748 global.ssl_handshake_max_cost = SSL_HANDSHAKE_MAX_COST;
Emeric Brun46591952012-05-18 15:47:34 +02004749}
4750
4751/*
4752 * Local variables:
4753 * c-indent-level: 8
4754 * c-basic-offset: 8
4755 * End:
4756 */