blob: d0f4d0180dcc1c717eaf70baa930c4956747c3a3 [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>
Emeric Brun4147b2e2014-06-16 18:36:30 +020047#ifdef SSL_CTRL_SET_TLSEXT_STATUS_REQ_CB
48#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 Brun42a3e202014-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 Gacogne60d7aeb2014-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
Emeric Brun4147b2e2014-06-16 18:36:30 +0200116#ifdef SSL_CTRL_SET_TLSEXT_STATUS_REQ_CB
117struct certificate_ocsp {
118 struct ebmb_node key;
119 unsigned char key_data[OCSP_MAX_CERTID_ASN1_LENGTH];
120 struct chunk response;
Emeric Brun58484372014-06-20 15:46:13 +0200121 long expire;
Emeric Brun4147b2e2014-06-16 18:36:30 +0200122};
123
Emeric Brun58484372014-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 Brun8d914d12014-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 Brun1135ea42014-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 Brun1135ea42014-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 Brun58484372014-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 Brun58484372014-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{
765#if OPENSSL_VERSION_NUMBER < 0x0090801fL
766 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) {
782#if OPENSSL_VERSION_NUMBER >= 0x0090801fL
783 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{
801#if OPENSSL_VERSION_NUMBER < 0x0090801fL
802 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) {
829#if OPENSSL_VERSION_NUMBER >= 0x0090801fL
830 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{
848#if OPENSSL_VERSION_NUMBER < 0x0090801fL
849 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) {
897#if OPENSSL_VERSION_NUMBER >= 0x0090801fL
898 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{
916#if OPENSSL_VERSION_NUMBER < 0x0090801fL
917 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) {
1008#if OPENSSL_VERSION_NUMBER >= 0x0090801fL
1009 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 Gacogne60d7aeb2014-07-15 11:36:40 +02001045 dh = local_dh_8192;
Remi Gacognef46cd6e2014-06-12 14:58:40 +02001046 }
1047 else if (keylen >= 4096) {
Remi Gacogne60d7aeb2014-07-15 11:36:40 +02001048 dh = local_dh_4096;
Remi Gacognef46cd6e2014-06-12 14:58:40 +02001049 }
1050 else if (keylen >= 2048) {
Remi Gacogne60d7aeb2014-07-15 11:36:40 +02001051 dh = local_dh_2048;
Remi Gacognef46cd6e2014-06-12 14:58:40 +02001052 }
1053 else {
Remi Gacogne60d7aeb2014-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 Gacogne60d7aeb2014-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 Gacogne60d7aeb2014-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
Emeric Brun4147b2e2014-06-16 18:36:30 +02001286#ifdef SSL_CTRL_SET_TLSEXT_STATUS_REQ_CB
1287 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é62043c92015-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é62043c92015-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é62043c92015-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é62043c92015-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
Remi Gacognef46cd6e2014-06-12 14:58:40 +02001479
Willy Tarreau2a65ff02012-09-13 17:54:29 +02001480int ssl_sock_prepare_ctx(struct bind_conf *bind_conf, SSL_CTX *ctx, struct proxy *curproxy)
Emeric Brunfc0421f2012-09-07 17:30:07 +02001481{
1482 int cfgerr = 0;
Emeric Brun850efd52014-01-29 12:24:34 +01001483 int verify = SSL_VERIFY_NONE;
Remi Gacogneaf5c3da2014-05-19 10:29:58 +02001484 long ssloptions =
Emeric Brunfc0421f2012-09-07 17:30:07 +02001485 SSL_OP_ALL | /* all known workarounds for bugs */
1486 SSL_OP_NO_SSLv2 |
1487 SSL_OP_NO_COMPRESSION |
Emeric Bruna4bcd9a2012-09-20 16:19:02 +02001488 SSL_OP_SINGLE_DH_USE |
Emeric Brun2b58d042012-09-20 17:10:03 +02001489 SSL_OP_SINGLE_ECDH_USE |
Emeric Brun3c4bc6e2012-10-04 18:44:19 +02001490 SSL_OP_NO_SESSION_RESUMPTION_ON_RENEGOTIATION |
1491 SSL_OP_CIPHER_SERVER_PREFERENCE;
Remi Gacogneaf5c3da2014-05-19 10:29:58 +02001492 long sslmode =
Emeric Brunfc0421f2012-09-07 17:30:07 +02001493 SSL_MODE_ENABLE_PARTIAL_WRITE |
1494 SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER |
1495 SSL_MODE_RELEASE_BUFFERS;
Remi Gacognef46cd6e2014-06-12 14:58:40 +02001496 STACK_OF(SSL_CIPHER) * ciphers = NULL;
1497 SSL_CIPHER * cipher = NULL;
Remi Gacognec1eab8c2014-06-12 18:20:11 +02001498 char cipher_description[128];
1499 /* The description of ciphers using an Ephemeral Diffie Hellman key exchange
1500 contains " Kx=DH " or " Kx=DH(". Beware of " Kx=DH/",
1501 which is not ephemeral DH. */
1502 const char dhe_description[] = " Kx=DH ";
1503 const char dhe_export_description[] = " Kx=DH(";
Remi Gacognef46cd6e2014-06-12 14:58:40 +02001504 int idx = 0;
1505 int dhe_found = 0;
Emeric Brunfc0421f2012-09-07 17:30:07 +02001506
Thierry Fournier383085f2013-01-24 14:15:43 +01001507 /* Make sure openssl opens /dev/urandom before the chroot */
1508 if (!ssl_initialize_random()) {
1509 Alert("OpenSSL random data generator initialization failed.\n");
1510 cfgerr++;
1511 }
1512
Emeric Brun89675492012-10-05 13:48:26 +02001513 if (bind_conf->ssl_options & BC_SSL_O_NO_SSLV3)
Emeric Brunfc0421f2012-09-07 17:30:07 +02001514 ssloptions |= SSL_OP_NO_SSLv3;
Emeric Brun89675492012-10-05 13:48:26 +02001515 if (bind_conf->ssl_options & BC_SSL_O_NO_TLSV10)
Emeric Brunfc0421f2012-09-07 17:30:07 +02001516 ssloptions |= SSL_OP_NO_TLSv1;
Emeric Brun89675492012-10-05 13:48:26 +02001517 if (bind_conf->ssl_options & BC_SSL_O_NO_TLSV11)
Emeric Brunc0ff4922012-09-28 19:37:02 +02001518 ssloptions |= SSL_OP_NO_TLSv1_1;
Emeric Brun89675492012-10-05 13:48:26 +02001519 if (bind_conf->ssl_options & BC_SSL_O_NO_TLSV12)
Emeric Brunc0ff4922012-09-28 19:37:02 +02001520 ssloptions |= SSL_OP_NO_TLSv1_2;
Emeric Brun89675492012-10-05 13:48:26 +02001521 if (bind_conf->ssl_options & BC_SSL_O_NO_TLS_TICKETS)
Emeric Brun2d0c4822012-10-02 13:45:20 +02001522 ssloptions |= SSL_OP_NO_TICKET;
Emeric Brun2cb7ae52012-10-05 14:14:21 +02001523 if (bind_conf->ssl_options & BC_SSL_O_USE_SSLV3)
1524 SSL_CTX_set_ssl_version(ctx, SSLv3_server_method());
1525 if (bind_conf->ssl_options & BC_SSL_O_USE_TLSV10)
1526 SSL_CTX_set_ssl_version(ctx, TLSv1_server_method());
1527#if SSL_OP_NO_TLSv1_1
1528 if (bind_conf->ssl_options & BC_SSL_O_USE_TLSV11)
1529 SSL_CTX_set_ssl_version(ctx, TLSv1_1_server_method());
1530#endif
1531#if SSL_OP_NO_TLSv1_2
1532 if (bind_conf->ssl_options & BC_SSL_O_USE_TLSV12)
1533 SSL_CTX_set_ssl_version(ctx, TLSv1_2_server_method());
1534#endif
Emeric Brunfc0421f2012-09-07 17:30:07 +02001535
1536 SSL_CTX_set_options(ctx, ssloptions);
1537 SSL_CTX_set_mode(ctx, sslmode);
Emeric Brun850efd52014-01-29 12:24:34 +01001538 switch (bind_conf->verify) {
1539 case SSL_SOCK_VERIFY_NONE:
1540 verify = SSL_VERIFY_NONE;
1541 break;
1542 case SSL_SOCK_VERIFY_OPTIONAL:
1543 verify = SSL_VERIFY_PEER;
1544 break;
1545 case SSL_SOCK_VERIFY_REQUIRED:
1546 verify = SSL_VERIFY_PEER|SSL_VERIFY_FAIL_IF_NO_PEER_CERT;
1547 break;
1548 }
1549 SSL_CTX_set_verify(ctx, verify, ssl_sock_bind_verifycbk);
1550 if (verify & SSL_VERIFY_PEER) {
Emeric Brunfb510ea2012-10-05 12:00:26 +02001551 if (bind_conf->ca_file) {
Emeric Brund94b3fe2012-09-20 18:23:56 +02001552 /* load CAfile to verify */
Emeric Brunfb510ea2012-10-05 12:00:26 +02001553 if (!SSL_CTX_load_verify_locations(ctx, bind_conf->ca_file, NULL)) {
Emeric Brund94b3fe2012-09-20 18:23:56 +02001554 Alert("Proxy '%s': unable to load CA file '%s' for bind '%s' at [%s:%d].\n",
Emeric Brunfb510ea2012-10-05 12:00:26 +02001555 curproxy->id, bind_conf->ca_file, bind_conf->arg, bind_conf->file, bind_conf->line);
Emeric Brund94b3fe2012-09-20 18:23:56 +02001556 cfgerr++;
1557 }
1558 /* set CA names fo client cert request, function returns void */
Emeric Brunfb510ea2012-10-05 12:00:26 +02001559 SSL_CTX_set_client_CA_list(ctx, SSL_load_client_CA_file(bind_conf->ca_file));
Emeric Brund94b3fe2012-09-20 18:23:56 +02001560 }
Emeric Brun850efd52014-01-29 12:24:34 +01001561 else {
1562 Alert("Proxy '%s': verify is enabled but no CA file specified for bind '%s' at [%s:%d].\n",
1563 curproxy->id, bind_conf->arg, bind_conf->file, bind_conf->line);
1564 cfgerr++;
1565 }
Emeric Brun051cdab2012-10-02 19:25:50 +02001566#ifdef X509_V_FLAG_CRL_CHECK
Emeric Brunfb510ea2012-10-05 12:00:26 +02001567 if (bind_conf->crl_file) {
Emeric Brund94b3fe2012-09-20 18:23:56 +02001568 X509_STORE *store = SSL_CTX_get_cert_store(ctx);
1569
Emeric Brunfb510ea2012-10-05 12:00:26 +02001570 if (!store || !X509_STORE_load_locations(store, bind_conf->crl_file, NULL)) {
Emeric Brund94b3fe2012-09-20 18:23:56 +02001571 Alert("Proxy '%s': unable to configure CRL file '%s' for bind '%s' at [%s:%d].\n",
Alexander Rigbo37dc94c2015-04-07 14:02:16 +02001572 curproxy->id, bind_conf->crl_file, bind_conf->arg, bind_conf->file, bind_conf->line);
Emeric Brund94b3fe2012-09-20 18:23:56 +02001573 cfgerr++;
1574 }
Emeric Brun561e5742012-10-02 15:20:55 +02001575 else {
1576 X509_STORE_set_flags(store, X509_V_FLAG_CRL_CHECK|X509_V_FLAG_CRL_CHECK_ALL);
1577 }
Emeric Brund94b3fe2012-09-20 18:23:56 +02001578 }
Emeric Brun051cdab2012-10-02 19:25:50 +02001579#endif
Emeric Brun644cde02012-12-14 11:21:13 +01001580 ERR_clear_error();
Emeric Brund94b3fe2012-09-20 18:23:56 +02001581 }
Emeric Brunfc0421f2012-09-07 17:30:07 +02001582
Emeric Brun4f65bff2012-11-16 15:11:00 +01001583 if (global.tune.ssllifetime)
1584 SSL_CTX_set_timeout(ctx, global.tune.ssllifetime);
1585
Emeric Brunfc0421f2012-09-07 17:30:07 +02001586 shared_context_set_cache(ctx);
Willy Tarreau2a65ff02012-09-13 17:54:29 +02001587 if (bind_conf->ciphers &&
1588 !SSL_CTX_set_cipher_list(ctx, bind_conf->ciphers)) {
Emeric Brunfc0421f2012-09-07 17:30:07 +02001589 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 +02001590 curproxy->id, bind_conf->ciphers, bind_conf->arg, bind_conf->file, bind_conf->line);
Emeric Brunfc0421f2012-09-07 17:30:07 +02001591 cfgerr++;
1592 }
1593
Remi Gacognef46cd6e2014-06-12 14:58:40 +02001594 /* If tune.ssl.default-dh-param has not been set and
1595 no static DH params were in the certificate file. */
1596 if (global.tune.ssl_default_dh_param == 0) {
1597 ciphers = ctx->cipher_list;
1598
1599 if (ciphers) {
1600 for (idx = 0; idx < sk_SSL_CIPHER_num(ciphers); idx++) {
1601 cipher = sk_SSL_CIPHER_value(ciphers, idx);
Remi Gacognec1eab8c2014-06-12 18:20:11 +02001602 if (SSL_CIPHER_description(cipher, cipher_description, sizeof (cipher_description)) == cipher_description) {
1603 if (strstr(cipher_description, dhe_description) != NULL ||
1604 strstr(cipher_description, dhe_export_description) != NULL) {
1605 dhe_found = 1;
1606 break;
1607 }
Remi Gacognef46cd6e2014-06-12 14:58:40 +02001608 }
1609 }
1610
1611 if (dhe_found) {
1612 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");
1613 }
1614 }
1615
1616 global.tune.ssl_default_dh_param = 1024;
1617 }
Remi Gacogne60d7aeb2014-07-15 11:36:40 +02001618
1619#ifndef OPENSSL_NO_DH
1620 if (global.tune.ssl_default_dh_param >= 1024) {
1621 if (local_dh_1024 == NULL) {
1622 local_dh_1024 = ssl_get_dh_1024();
1623 }
1624 if (global.tune.ssl_default_dh_param >= 2048) {
1625 if (local_dh_2048 == NULL) {
1626 local_dh_2048 = ssl_get_dh_2048();
1627 }
1628 if (global.tune.ssl_default_dh_param >= 4096) {
1629 if (local_dh_4096 == NULL) {
1630 local_dh_4096 = ssl_get_dh_4096();
1631 }
1632 if (global.tune.ssl_default_dh_param >= 8192 &&
1633 local_dh_8192 == NULL) {
1634 local_dh_8192 = ssl_get_dh_8192();
1635 }
1636 }
1637 }
1638 }
1639#endif /* OPENSSL_NO_DH */
Remi Gacognef46cd6e2014-06-12 14:58:40 +02001640
Emeric Brunfc0421f2012-09-07 17:30:07 +02001641 SSL_CTX_set_info_callback(ctx, ssl_sock_infocbk);
Willy Tarreau5cbe4ef2014-05-08 22:45:11 +02001642#if OPENSSL_VERSION_NUMBER >= 0x00907000L
Emeric Brun29f037d2014-04-25 19:05:36 +02001643 SSL_CTX_set_msg_callback(ctx, ssl_sock_msgcbk);
Willy Tarreau5cbe4ef2014-05-08 22:45:11 +02001644#endif
Emeric Brun29f037d2014-04-25 19:05:36 +02001645
Willy Tarreau6c9a3d52012-10-18 18:57:14 +02001646#ifdef OPENSSL_NPN_NEGOTIATED
1647 if (bind_conf->npn_str)
1648 SSL_CTX_set_next_protos_advertised_cb(ctx, ssl_sock_advertise_npn_protos, bind_conf);
1649#endif
Dirkjan Bussink48f1c4e2014-02-13 12:29:42 +01001650#ifdef TLSEXT_TYPE_application_layer_protocol_negotiation
Willy Tarreauab861d32013-04-02 02:30:41 +02001651 if (bind_conf->alpn_str)
Dirkjan Bussink48f1c4e2014-02-13 12:29:42 +01001652 SSL_CTX_set_alpn_select_cb(ctx, ssl_sock_advertise_alpn_protos, bind_conf);
Willy Tarreauab861d32013-04-02 02:30:41 +02001653#endif
Willy Tarreau6c9a3d52012-10-18 18:57:14 +02001654
Emeric Brunfc0421f2012-09-07 17:30:07 +02001655#ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME
1656 SSL_CTX_set_tlsext_servername_callback(ctx, ssl_sock_switchctx_cbk);
Willy Tarreau2a65ff02012-09-13 17:54:29 +02001657 SSL_CTX_set_tlsext_servername_arg(ctx, bind_conf);
Emeric Brunfc0421f2012-09-07 17:30:07 +02001658#endif
Emeric Brun2b58d042012-09-20 17:10:03 +02001659#if defined(SSL_CTX_set_tmp_ecdh) && !defined(OPENSSL_NO_ECDH)
Emeric Brun6924ef82013-03-06 14:08:53 +01001660 {
Emeric Brun2b58d042012-09-20 17:10:03 +02001661 int i;
1662 EC_KEY *ecdh;
1663
Emeric Brun6924ef82013-03-06 14:08:53 +01001664 i = OBJ_sn2nid(bind_conf->ecdhe ? bind_conf->ecdhe : ECDHE_DEFAULT_CURVE);
Emeric Brun2b58d042012-09-20 17:10:03 +02001665 if (!i || ((ecdh = EC_KEY_new_by_curve_name(i)) == NULL)) {
1666 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 +01001667 curproxy->id, bind_conf->ecdhe ? bind_conf->ecdhe : ECDHE_DEFAULT_CURVE,
1668 bind_conf->arg, bind_conf->file, bind_conf->line);
Emeric Brun2b58d042012-09-20 17:10:03 +02001669 cfgerr++;
1670 }
1671 else {
1672 SSL_CTX_set_tmp_ecdh(ctx, ecdh);
1673 EC_KEY_free(ecdh);
1674 }
1675 }
1676#endif
1677
Emeric Brunfc0421f2012-09-07 17:30:07 +02001678 return cfgerr;
1679}
1680
Evan Broderbe554312013-06-27 00:05:25 -07001681static int ssl_sock_srv_hostcheck(const char *pattern, const char *hostname)
1682{
1683 const char *pattern_wildcard, *pattern_left_label_end, *hostname_left_label_end;
1684 size_t prefixlen, suffixlen;
1685
1686 /* Trivial case */
1687 if (strcmp(pattern, hostname) == 0)
1688 return 1;
1689
Evan Broderbe554312013-06-27 00:05:25 -07001690 /* The rest of this logic is based on RFC 6125, section 6.4.3
1691 * (http://tools.ietf.org/html/rfc6125#section-6.4.3) */
1692
Emeric Bruna848dae2013-10-08 11:27:28 +02001693 pattern_wildcard = NULL;
1694 pattern_left_label_end = pattern;
1695 while (*pattern_left_label_end != '.') {
1696 switch (*pattern_left_label_end) {
1697 case 0:
1698 /* End of label not found */
1699 return 0;
1700 case '*':
1701 /* If there is more than one wildcards */
1702 if (pattern_wildcard)
1703 return 0;
1704 pattern_wildcard = pattern_left_label_end;
1705 break;
1706 }
1707 pattern_left_label_end++;
1708 }
1709
1710 /* If it's not trivial and there is no wildcard, it can't
1711 * match */
1712 if (!pattern_wildcard)
Evan Broderbe554312013-06-27 00:05:25 -07001713 return 0;
1714
1715 /* Make sure all labels match except the leftmost */
1716 hostname_left_label_end = strchr(hostname, '.');
1717 if (!hostname_left_label_end
1718 || strcmp(pattern_left_label_end, hostname_left_label_end) != 0)
1719 return 0;
1720
1721 /* Make sure the leftmost label of the hostname is long enough
1722 * that the wildcard can match */
Emeric Brun369da852013-10-08 11:39:35 +02001723 if (hostname_left_label_end - hostname < (pattern_left_label_end - pattern) - 1)
Evan Broderbe554312013-06-27 00:05:25 -07001724 return 0;
1725
1726 /* Finally compare the string on either side of the
1727 * wildcard */
1728 prefixlen = pattern_wildcard - pattern;
1729 suffixlen = pattern_left_label_end - (pattern_wildcard + 1);
Emeric Bruna848dae2013-10-08 11:27:28 +02001730 if ((prefixlen && (memcmp(pattern, hostname, prefixlen) != 0))
1731 || (suffixlen && (memcmp(pattern_wildcard + 1, hostname_left_label_end - suffixlen, suffixlen) != 0)))
Evan Broderbe554312013-06-27 00:05:25 -07001732 return 0;
1733
1734 return 1;
1735}
1736
1737static int ssl_sock_srv_verifycbk(int ok, X509_STORE_CTX *ctx)
1738{
1739 SSL *ssl;
1740 struct connection *conn;
1741 char *servername;
1742
1743 int depth;
1744 X509 *cert;
1745 STACK_OF(GENERAL_NAME) *alt_names;
1746 int i;
1747 X509_NAME *cert_subject;
1748 char *str;
1749
1750 if (ok == 0)
1751 return ok;
1752
1753 ssl = X509_STORE_CTX_get_ex_data(ctx, SSL_get_ex_data_X509_STORE_CTX_idx());
1754 conn = (struct connection *)SSL_get_app_data(ssl);
1755
1756 servername = objt_server(conn->target)->ssl_ctx.verify_host;
1757
1758 /* We only need to verify the CN on the actual server cert,
1759 * not the indirect CAs */
1760 depth = X509_STORE_CTX_get_error_depth(ctx);
1761 if (depth != 0)
1762 return ok;
1763
1764 /* At this point, the cert is *not* OK unless we can find a
1765 * hostname match */
1766 ok = 0;
1767
1768 cert = X509_STORE_CTX_get_current_cert(ctx);
1769 /* It seems like this might happen if verify peer isn't set */
1770 if (!cert)
1771 return ok;
1772
1773 alt_names = X509_get_ext_d2i(cert, NID_subject_alt_name, NULL, NULL);
1774 if (alt_names) {
1775 for (i = 0; !ok && i < sk_GENERAL_NAME_num(alt_names); i++) {
1776 GENERAL_NAME *name = sk_GENERAL_NAME_value(alt_names, i);
1777 if (name->type == GEN_DNS) {
Emeric Bruna33410c2013-09-17 15:47:48 +02001778#if OPENSSL_VERSION_NUMBER < 0x00907000L
1779 if (ASN1_STRING_to_UTF8((unsigned char **)&str, name->d.ia5) >= 0) {
1780#else
Evan Broderbe554312013-06-27 00:05:25 -07001781 if (ASN1_STRING_to_UTF8((unsigned char **)&str, name->d.dNSName) >= 0) {
Emeric Bruna33410c2013-09-17 15:47:48 +02001782#endif
Evan Broderbe554312013-06-27 00:05:25 -07001783 ok = ssl_sock_srv_hostcheck(str, servername);
1784 OPENSSL_free(str);
1785 }
1786 }
1787 }
Emeric Brun4ad50a42013-09-17 15:19:54 +02001788 sk_GENERAL_NAME_pop_free(alt_names, GENERAL_NAME_free);
Evan Broderbe554312013-06-27 00:05:25 -07001789 }
1790
1791 cert_subject = X509_get_subject_name(cert);
1792 i = -1;
1793 while (!ok && (i = X509_NAME_get_index_by_NID(cert_subject, NID_commonName, i)) != -1) {
1794 X509_NAME_ENTRY *entry = X509_NAME_get_entry(cert_subject, i);
1795 if (ASN1_STRING_to_UTF8((unsigned char **)&str, entry->value) >= 0) {
1796 ok = ssl_sock_srv_hostcheck(str, servername);
1797 OPENSSL_free(str);
1798 }
1799 }
1800
1801 return ok;
1802}
1803
Emeric Brun94324a42012-10-11 14:00:19 +02001804/* prepare ssl context from servers options. Returns an error count */
1805int ssl_sock_prepare_srv_ctx(struct server *srv, struct proxy *curproxy)
1806{
1807 int cfgerr = 0;
Remi Gacogneaf5c3da2014-05-19 10:29:58 +02001808 long options =
Emeric Brun94324a42012-10-11 14:00:19 +02001809 SSL_OP_ALL | /* all known workarounds for bugs */
1810 SSL_OP_NO_SSLv2 |
1811 SSL_OP_NO_COMPRESSION;
Remi Gacogneaf5c3da2014-05-19 10:29:58 +02001812 long mode =
Emeric Brun94324a42012-10-11 14:00:19 +02001813 SSL_MODE_ENABLE_PARTIAL_WRITE |
1814 SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER |
1815 SSL_MODE_RELEASE_BUFFERS;
Emeric Brun850efd52014-01-29 12:24:34 +01001816 int verify = SSL_VERIFY_NONE;
Emeric Brun94324a42012-10-11 14:00:19 +02001817
Thierry Fournier383085f2013-01-24 14:15:43 +01001818 /* Make sure openssl opens /dev/urandom before the chroot */
1819 if (!ssl_initialize_random()) {
1820 Alert("OpenSSL random data generator initialization failed.\n");
1821 cfgerr++;
1822 }
1823
Emeric Brun94324a42012-10-11 14:00:19 +02001824 /* Initiate SSL context for current server */
1825 srv->ssl_ctx.reused_sess = NULL;
1826 if (srv->use_ssl)
1827 srv->xprt = &ssl_sock;
1828 if (srv->check.use_ssl)
Cyril Bonté1f96a872014-11-15 22:41:27 +01001829 srv->check.xprt = &ssl_sock;
Emeric Brun94324a42012-10-11 14:00:19 +02001830
1831 srv->ssl_ctx.ctx = SSL_CTX_new(SSLv23_client_method());
1832 if (!srv->ssl_ctx.ctx) {
1833 Alert("config : %s '%s', server '%s': unable to allocate ssl context.\n",
1834 proxy_type_str(curproxy), curproxy->id,
1835 srv->id);
1836 cfgerr++;
1837 return cfgerr;
1838 }
Emeric Bruna7aa3092012-10-26 12:58:00 +02001839 if (srv->ssl_ctx.client_crt) {
1840 if (SSL_CTX_use_PrivateKey_file(srv->ssl_ctx.ctx, srv->ssl_ctx.client_crt, SSL_FILETYPE_PEM) <= 0) {
1841 Alert("config : %s '%s', server '%s': unable to load SSL private key from PEM file '%s'.\n",
1842 proxy_type_str(curproxy), curproxy->id,
1843 srv->id, srv->ssl_ctx.client_crt);
1844 cfgerr++;
1845 }
1846 else if (SSL_CTX_use_certificate_chain_file(srv->ssl_ctx.ctx, srv->ssl_ctx.client_crt) <= 0) {
1847 Alert("config : %s '%s', server '%s': unable to load ssl certificate from PEM file '%s'.\n",
1848 proxy_type_str(curproxy), curproxy->id,
1849 srv->id, srv->ssl_ctx.client_crt);
1850 cfgerr++;
1851 }
1852 else if (SSL_CTX_check_private_key(srv->ssl_ctx.ctx) <= 0) {
1853 Alert("config : %s '%s', server '%s': inconsistencies between private key and certificate loaded from PEM file '%s'.\n",
1854 proxy_type_str(curproxy), curproxy->id,
1855 srv->id, srv->ssl_ctx.client_crt);
1856 cfgerr++;
1857 }
1858 }
Emeric Brun94324a42012-10-11 14:00:19 +02001859
1860 if (srv->ssl_ctx.options & SRV_SSL_O_NO_SSLV3)
1861 options |= SSL_OP_NO_SSLv3;
1862 if (srv->ssl_ctx.options & SRV_SSL_O_NO_TLSV10)
1863 options |= SSL_OP_NO_TLSv1;
1864 if (srv->ssl_ctx.options & SRV_SSL_O_NO_TLSV11)
1865 options |= SSL_OP_NO_TLSv1_1;
1866 if (srv->ssl_ctx.options & SRV_SSL_O_NO_TLSV12)
1867 options |= SSL_OP_NO_TLSv1_2;
Emeric Brunf9c5c472012-10-11 15:28:34 +02001868 if (srv->ssl_ctx.options & SRV_SSL_O_NO_TLS_TICKETS)
1869 options |= SSL_OP_NO_TICKET;
Emeric Brun94324a42012-10-11 14:00:19 +02001870 if (srv->ssl_ctx.options & SRV_SSL_O_USE_SSLV3)
1871 SSL_CTX_set_ssl_version(srv->ssl_ctx.ctx, SSLv3_client_method());
1872 if (srv->ssl_ctx.options & SRV_SSL_O_USE_TLSV10)
1873 SSL_CTX_set_ssl_version(srv->ssl_ctx.ctx, TLSv1_client_method());
1874#if SSL_OP_NO_TLSv1_1
1875 if (srv->ssl_ctx.options & SRV_SSL_O_USE_TLSV11)
1876 SSL_CTX_set_ssl_version(srv->ssl_ctx.ctx, TLSv1_1_client_method());
1877#endif
1878#if SSL_OP_NO_TLSv1_2
1879 if (srv->ssl_ctx.options & SRV_SSL_O_USE_TLSV12)
1880 SSL_CTX_set_ssl_version(srv->ssl_ctx.ctx, TLSv1_2_client_method());
1881#endif
1882
1883 SSL_CTX_set_options(srv->ssl_ctx.ctx, options);
1884 SSL_CTX_set_mode(srv->ssl_ctx.ctx, mode);
Emeric Brun850efd52014-01-29 12:24:34 +01001885
1886 if (global.ssl_server_verify == SSL_SERVER_VERIFY_REQUIRED)
1887 verify = SSL_VERIFY_PEER;
1888
1889 switch (srv->ssl_ctx.verify) {
1890 case SSL_SOCK_VERIFY_NONE:
1891 verify = SSL_VERIFY_NONE;
1892 break;
1893 case SSL_SOCK_VERIFY_REQUIRED:
1894 verify = SSL_VERIFY_PEER;
1895 break;
1896 }
Evan Broderbe554312013-06-27 00:05:25 -07001897 SSL_CTX_set_verify(srv->ssl_ctx.ctx,
Emeric Brun850efd52014-01-29 12:24:34 +01001898 verify,
Evan Broderbe554312013-06-27 00:05:25 -07001899 srv->ssl_ctx.verify_host ? ssl_sock_srv_verifycbk : NULL);
Emeric Brun850efd52014-01-29 12:24:34 +01001900 if (verify & SSL_VERIFY_PEER) {
Emeric Brunef42d922012-10-11 16:11:36 +02001901 if (srv->ssl_ctx.ca_file) {
1902 /* load CAfile to verify */
1903 if (!SSL_CTX_load_verify_locations(srv->ssl_ctx.ctx, srv->ssl_ctx.ca_file, NULL)) {
Willy Tarreau07ba08b2014-02-16 19:22:08 +01001904 Alert("Proxy '%s', server '%s' [%s:%d] unable to load CA file '%s'.\n",
Emeric Brunef42d922012-10-11 16:11:36 +02001905 curproxy->id, srv->id,
1906 srv->conf.file, srv->conf.line, srv->ssl_ctx.ca_file);
1907 cfgerr++;
1908 }
1909 }
Emeric Brun850efd52014-01-29 12:24:34 +01001910 else {
1911 if (global.ssl_server_verify == SSL_SERVER_VERIFY_REQUIRED)
Willy Tarreau07ba08b2014-02-16 19:22:08 +01001912 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 +01001913 curproxy->id, srv->id,
1914 srv->conf.file, srv->conf.line);
1915 else
Willy Tarreau07ba08b2014-02-16 19:22:08 +01001916 Alert("Proxy '%s', server '%s' [%s:%d] verify is enabled but no CA file specified.\n",
Emeric Brun850efd52014-01-29 12:24:34 +01001917 curproxy->id, srv->id,
1918 srv->conf.file, srv->conf.line);
1919 cfgerr++;
1920 }
Emeric Brunef42d922012-10-11 16:11:36 +02001921#ifdef X509_V_FLAG_CRL_CHECK
1922 if (srv->ssl_ctx.crl_file) {
1923 X509_STORE *store = SSL_CTX_get_cert_store(srv->ssl_ctx.ctx);
1924
1925 if (!store || !X509_STORE_load_locations(store, srv->ssl_ctx.crl_file, NULL)) {
Willy Tarreau07ba08b2014-02-16 19:22:08 +01001926 Alert("Proxy '%s', server '%s' [%s:%d] unable to configure CRL file '%s'.\n",
Emeric Brunef42d922012-10-11 16:11:36 +02001927 curproxy->id, srv->id,
1928 srv->conf.file, srv->conf.line, srv->ssl_ctx.crl_file);
1929 cfgerr++;
1930 }
1931 else {
1932 X509_STORE_set_flags(store, X509_V_FLAG_CRL_CHECK|X509_V_FLAG_CRL_CHECK_ALL);
1933 }
1934 }
1935#endif
1936 }
1937
Emeric Brun4f65bff2012-11-16 15:11:00 +01001938 if (global.tune.ssllifetime)
1939 SSL_CTX_set_timeout(srv->ssl_ctx.ctx, global.tune.ssllifetime);
1940
Emeric Brun94324a42012-10-11 14:00:19 +02001941 SSL_CTX_set_session_cache_mode(srv->ssl_ctx.ctx, SSL_SESS_CACHE_OFF);
1942 if (srv->ssl_ctx.ciphers &&
1943 !SSL_CTX_set_cipher_list(srv->ssl_ctx.ctx, srv->ssl_ctx.ciphers)) {
1944 Alert("Proxy '%s', server '%s' [%s:%d] : unable to set SSL cipher list to '%s'.\n",
1945 curproxy->id, srv->id,
1946 srv->conf.file, srv->conf.line, srv->ssl_ctx.ciphers);
1947 cfgerr++;
1948 }
1949
1950 return cfgerr;
1951}
1952
Willy Tarreau2a65ff02012-09-13 17:54:29 +02001953/* Walks down the two trees in bind_conf and prepares all certs. The pointer may
Emeric Brunfc0421f2012-09-07 17:30:07 +02001954 * be NULL, in which case nothing is done. Returns the number of errors
1955 * encountered.
1956 */
Willy Tarreau2a65ff02012-09-13 17:54:29 +02001957int ssl_sock_prepare_all_ctx(struct bind_conf *bind_conf, struct proxy *px)
Emeric Brunfc0421f2012-09-07 17:30:07 +02001958{
1959 struct ebmb_node *node;
1960 struct sni_ctx *sni;
1961 int err = 0;
1962
Willy Tarreau2a65ff02012-09-13 17:54:29 +02001963 if (!bind_conf || !bind_conf->is_ssl)
Emeric Brunfc0421f2012-09-07 17:30:07 +02001964 return 0;
1965
Emeric Brun8068b032014-10-30 19:25:24 +01001966 if (bind_conf->default_ctx)
1967 err += ssl_sock_prepare_ctx(bind_conf, bind_conf->default_ctx, px);
1968
Willy Tarreau2a65ff02012-09-13 17:54:29 +02001969 node = ebmb_first(&bind_conf->sni_ctx);
Emeric Brunfc0421f2012-09-07 17:30:07 +02001970 while (node) {
1971 sni = ebmb_entry(node, struct sni_ctx, name);
Emeric Brun8068b032014-10-30 19:25:24 +01001972 if (!sni->order && sni->ctx != bind_conf->default_ctx)
1973 /* only initialize the CTX on its first occurrence and
1974 if it is not the default_ctx */
Willy Tarreau2a65ff02012-09-13 17:54:29 +02001975 err += ssl_sock_prepare_ctx(bind_conf, sni->ctx, px);
Emeric Brunfc0421f2012-09-07 17:30:07 +02001976 node = ebmb_next(node);
1977 }
1978
Willy Tarreau2a65ff02012-09-13 17:54:29 +02001979 node = ebmb_first(&bind_conf->sni_w_ctx);
Emeric Brunfc0421f2012-09-07 17:30:07 +02001980 while (node) {
1981 sni = ebmb_entry(node, struct sni_ctx, name);
Emeric Brun8068b032014-10-30 19:25:24 +01001982 if (!sni->order && sni->ctx != bind_conf->default_ctx)
1983 /* only initialize the CTX on its first occurrence and
1984 if it is not the default_ctx */
Willy Tarreau2a65ff02012-09-13 17:54:29 +02001985 err += ssl_sock_prepare_ctx(bind_conf, sni->ctx, px);
Emeric Brunfc0421f2012-09-07 17:30:07 +02001986 node = ebmb_next(node);
1987 }
1988 return err;
1989}
1990
Willy Tarreau2a65ff02012-09-13 17:54:29 +02001991/* Walks down the two trees in bind_conf and frees all the certs. The pointer may
Emeric Brunfc0421f2012-09-07 17:30:07 +02001992 * be NULL, in which case nothing is done. The default_ctx is nullified too.
1993 */
Willy Tarreau2a65ff02012-09-13 17:54:29 +02001994void ssl_sock_free_all_ctx(struct bind_conf *bind_conf)
Emeric Brunfc0421f2012-09-07 17:30:07 +02001995{
1996 struct ebmb_node *node, *back;
1997 struct sni_ctx *sni;
1998
Willy Tarreau2a65ff02012-09-13 17:54:29 +02001999 if (!bind_conf || !bind_conf->is_ssl)
Emeric Brunfc0421f2012-09-07 17:30:07 +02002000 return;
2001
Willy Tarreau2a65ff02012-09-13 17:54:29 +02002002 node = ebmb_first(&bind_conf->sni_ctx);
Emeric Brunfc0421f2012-09-07 17:30:07 +02002003 while (node) {
2004 sni = ebmb_entry(node, struct sni_ctx, name);
2005 back = ebmb_next(node);
2006 ebmb_delete(node);
2007 if (!sni->order) /* only free the CTX on its first occurrence */
2008 SSL_CTX_free(sni->ctx);
2009 free(sni);
2010 node = back;
2011 }
2012
Willy Tarreau2a65ff02012-09-13 17:54:29 +02002013 node = ebmb_first(&bind_conf->sni_w_ctx);
Emeric Brunfc0421f2012-09-07 17:30:07 +02002014 while (node) {
2015 sni = ebmb_entry(node, struct sni_ctx, name);
2016 back = ebmb_next(node);
2017 ebmb_delete(node);
2018 if (!sni->order) /* only free the CTX on its first occurrence */
2019 SSL_CTX_free(sni->ctx);
2020 free(sni);
2021 node = back;
2022 }
2023
Willy Tarreau2a65ff02012-09-13 17:54:29 +02002024 bind_conf->default_ctx = NULL;
Emeric Brune1f38db2012-09-03 20:36:47 +02002025}
2026
Emeric Brun46591952012-05-18 15:47:34 +02002027/*
2028 * This function is called if SSL * context is not yet allocated. The function
2029 * is designed to be called before any other data-layer operation and sets the
2030 * handshake flag on the connection. It is safe to call it multiple times.
2031 * It returns 0 on success and -1 in error case.
2032 */
2033static int ssl_sock_init(struct connection *conn)
2034{
2035 /* already initialized */
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02002036 if (conn->xprt_ctx)
Emeric Brun46591952012-05-18 15:47:34 +02002037 return 0;
2038
Willy Tarreau3c728722014-01-23 13:50:42 +01002039 if (!conn_ctrl_ready(conn))
Willy Tarreauf79c8172013-10-21 16:30:56 +02002040 return 0;
2041
Willy Tarreau20879a02012-12-03 16:32:10 +01002042 if (global.maxsslconn && sslconns >= global.maxsslconn) {
2043 conn->err_code = CO_ER_SSL_TOO_MANY;
Willy Tarreau403edff2012-09-06 11:58:37 +02002044 return -1;
Willy Tarreau20879a02012-12-03 16:32:10 +01002045 }
Willy Tarreau403edff2012-09-06 11:58:37 +02002046
Emeric Brun46591952012-05-18 15:47:34 +02002047 /* If it is in client mode initiate SSL session
2048 in connect state otherwise accept state */
Willy Tarreau3fdb3662012-11-12 00:42:33 +01002049 if (objt_server(conn->target)) {
Willy Tarreau9bcc01a2014-11-13 13:48:58 +01002050 int may_retry = 1;
2051
2052 retry_connect:
Emeric Brun46591952012-05-18 15:47:34 +02002053 /* Alloc a new SSL session ctx */
Willy Tarreau3fdb3662012-11-12 00:42:33 +01002054 conn->xprt_ctx = SSL_new(objt_server(conn->target)->ssl_ctx.ctx);
Willy Tarreau20879a02012-12-03 16:32:10 +01002055 if (!conn->xprt_ctx) {
Willy Tarreau9bcc01a2014-11-13 13:48:58 +01002056 if (may_retry--) {
2057 pool_gc2();
2058 goto retry_connect;
2059 }
Willy Tarreau20879a02012-12-03 16:32:10 +01002060 conn->err_code = CO_ER_SSL_NO_MEM;
Emeric Brun46591952012-05-18 15:47:34 +02002061 return -1;
Willy Tarreau20879a02012-12-03 16:32:10 +01002062 }
Emeric Brun46591952012-05-18 15:47:34 +02002063
Emeric Brun46591952012-05-18 15:47:34 +02002064 /* set fd on SSL session context */
Emeric Brun90951492014-11-12 17:35:37 +01002065 if (!SSL_set_fd(conn->xprt_ctx, conn->t.sock.fd)) {
2066 SSL_free(conn->xprt_ctx);
2067 conn->xprt_ctx = NULL;
Willy Tarreau9bcc01a2014-11-13 13:48:58 +01002068 if (may_retry--) {
2069 pool_gc2();
2070 goto retry_connect;
2071 }
Emeric Brun90951492014-11-12 17:35:37 +01002072 conn->err_code = CO_ER_SSL_NO_MEM;
2073 return -1;
2074 }
Emeric Brun46591952012-05-18 15:47:34 +02002075
Evan Broderbe554312013-06-27 00:05:25 -07002076 /* set connection pointer */
Emeric Brun90951492014-11-12 17:35:37 +01002077 if (!SSL_set_app_data(conn->xprt_ctx, conn)) {
2078 SSL_free(conn->xprt_ctx);
2079 conn->xprt_ctx = NULL;
Willy Tarreau9bcc01a2014-11-13 13:48:58 +01002080 if (may_retry--) {
2081 pool_gc2();
2082 goto retry_connect;
2083 }
Emeric Brun90951492014-11-12 17:35:37 +01002084 conn->err_code = CO_ER_SSL_NO_MEM;
2085 return -1;
2086 }
2087
2088 SSL_set_connect_state(conn->xprt_ctx);
2089 if (objt_server(conn->target)->ssl_ctx.reused_sess) {
2090 if(!SSL_set_session(conn->xprt_ctx, objt_server(conn->target)->ssl_ctx.reused_sess)) {
2091 SSL_SESSION_free(objt_server(conn->target)->ssl_ctx.reused_sess);
2092 objt_server(conn->target)->ssl_ctx.reused_sess = NULL;
2093 }
2094 }
Evan Broderbe554312013-06-27 00:05:25 -07002095
Emeric Brun46591952012-05-18 15:47:34 +02002096 /* leave init state and start handshake */
Willy Tarreau05737472012-09-04 08:03:39 +02002097 conn->flags |= CO_FL_SSL_WAIT_HS | CO_FL_WAIT_L6_CONN;
Willy Tarreau403edff2012-09-06 11:58:37 +02002098
2099 sslconns++;
Willy Tarreau71b734c2014-01-28 15:19:44 +01002100 totalsslconns++;
Emeric Brun46591952012-05-18 15:47:34 +02002101 return 0;
2102 }
Willy Tarreau3fdb3662012-11-12 00:42:33 +01002103 else if (objt_listener(conn->target)) {
Willy Tarreau9bcc01a2014-11-13 13:48:58 +01002104 int may_retry = 1;
2105
2106 retry_accept:
Emeric Brun46591952012-05-18 15:47:34 +02002107 /* Alloc a new SSL session ctx */
Willy Tarreau3fdb3662012-11-12 00:42:33 +01002108 conn->xprt_ctx = SSL_new(objt_listener(conn->target)->bind_conf->default_ctx);
Willy Tarreau20879a02012-12-03 16:32:10 +01002109 if (!conn->xprt_ctx) {
Willy Tarreau9bcc01a2014-11-13 13:48:58 +01002110 if (may_retry--) {
2111 pool_gc2();
2112 goto retry_accept;
2113 }
Willy Tarreau20879a02012-12-03 16:32:10 +01002114 conn->err_code = CO_ER_SSL_NO_MEM;
Emeric Brun46591952012-05-18 15:47:34 +02002115 return -1;
Willy Tarreau20879a02012-12-03 16:32:10 +01002116 }
Emeric Brun46591952012-05-18 15:47:34 +02002117
Emeric Brun46591952012-05-18 15:47:34 +02002118 /* set fd on SSL session context */
Emeric Brun90951492014-11-12 17:35:37 +01002119 if (!SSL_set_fd(conn->xprt_ctx, conn->t.sock.fd)) {
2120 SSL_free(conn->xprt_ctx);
2121 conn->xprt_ctx = NULL;
Willy Tarreau9bcc01a2014-11-13 13:48:58 +01002122 if (may_retry--) {
2123 pool_gc2();
2124 goto retry_accept;
2125 }
Emeric Brun90951492014-11-12 17:35:37 +01002126 conn->err_code = CO_ER_SSL_NO_MEM;
2127 return -1;
2128 }
Emeric Brun46591952012-05-18 15:47:34 +02002129
Emeric Brune1f38db2012-09-03 20:36:47 +02002130 /* set connection pointer */
Emeric Brun90951492014-11-12 17:35:37 +01002131 if (!SSL_set_app_data(conn->xprt_ctx, conn)) {
2132 SSL_free(conn->xprt_ctx);
2133 conn->xprt_ctx = NULL;
Willy Tarreau9bcc01a2014-11-13 13:48:58 +01002134 if (may_retry--) {
2135 pool_gc2();
2136 goto retry_accept;
2137 }
Emeric Brun90951492014-11-12 17:35:37 +01002138 conn->err_code = CO_ER_SSL_NO_MEM;
2139 return -1;
2140 }
2141
2142 SSL_set_accept_state(conn->xprt_ctx);
Emeric Brune1f38db2012-09-03 20:36:47 +02002143
Emeric Brun46591952012-05-18 15:47:34 +02002144 /* leave init state and start handshake */
Willy Tarreau05737472012-09-04 08:03:39 +02002145 conn->flags |= CO_FL_SSL_WAIT_HS | CO_FL_WAIT_L6_CONN;
Willy Tarreau403edff2012-09-06 11:58:37 +02002146
2147 sslconns++;
Willy Tarreau71b734c2014-01-28 15:19:44 +01002148 totalsslconns++;
Emeric Brun46591952012-05-18 15:47:34 +02002149 return 0;
2150 }
2151 /* don't know how to handle such a target */
Willy Tarreau20879a02012-12-03 16:32:10 +01002152 conn->err_code = CO_ER_SSL_NO_TARGET;
Emeric Brun46591952012-05-18 15:47:34 +02002153 return -1;
2154}
2155
2156
2157/* This is the callback which is used when an SSL handshake is pending. It
2158 * updates the FD status if it wants some polling before being called again.
2159 * It returns 0 if it fails in a fatal way or needs to poll to go further,
2160 * otherwise it returns non-zero and removes itself from the connection's
2161 * flags (the bit is provided in <flag> by the caller).
2162 */
2163int ssl_sock_handshake(struct connection *conn, unsigned int flag)
2164{
2165 int ret;
2166
Willy Tarreau3c728722014-01-23 13:50:42 +01002167 if (!conn_ctrl_ready(conn))
Willy Tarreauf79c8172013-10-21 16:30:56 +02002168 return 0;
2169
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02002170 if (!conn->xprt_ctx)
Emeric Brun46591952012-05-18 15:47:34 +02002171 goto out_error;
2172
Emeric Brun674b7432012-11-08 19:21:55 +01002173 /* If we use SSL_do_handshake to process a reneg initiated by
2174 * the remote peer, it sometimes returns SSL_ERROR_SSL.
2175 * Usually SSL_write and SSL_read are used and process implicitly
2176 * the reneg handshake.
2177 * Here we use SSL_peek as a workaround for reneg.
2178 */
2179 if ((conn->flags & CO_FL_CONNECTED) && SSL_renegotiate_pending(conn->xprt_ctx)) {
2180 char c;
2181
2182 ret = SSL_peek(conn->xprt_ctx, &c, 1);
2183 if (ret <= 0) {
2184 /* handshake may have not been completed, let's find why */
2185 ret = SSL_get_error(conn->xprt_ctx, ret);
2186 if (ret == SSL_ERROR_WANT_WRITE) {
2187 /* SSL handshake needs to write, L4 connection may not be ready */
2188 __conn_sock_stop_recv(conn);
Willy Tarreaue1f50c42014-01-22 20:02:06 +01002189 __conn_sock_want_send(conn);
2190 fd_cant_send(conn->t.sock.fd);
Emeric Brun674b7432012-11-08 19:21:55 +01002191 return 0;
2192 }
2193 else if (ret == SSL_ERROR_WANT_READ) {
2194 /* handshake may have been completed but we have
2195 * no more data to read.
2196 */
2197 if (!SSL_renegotiate_pending(conn->xprt_ctx)) {
2198 ret = 1;
2199 goto reneg_ok;
2200 }
2201 /* SSL handshake needs to read, L4 connection is ready */
2202 if (conn->flags & CO_FL_WAIT_L4_CONN)
2203 conn->flags &= ~CO_FL_WAIT_L4_CONN;
2204 __conn_sock_stop_send(conn);
Willy Tarreaue1f50c42014-01-22 20:02:06 +01002205 __conn_sock_want_recv(conn);
2206 fd_cant_recv(conn->t.sock.fd);
Emeric Brun674b7432012-11-08 19:21:55 +01002207 return 0;
2208 }
2209 else if (ret == SSL_ERROR_SYSCALL) {
2210 /* if errno is null, then connection was successfully established */
2211 if (!errno && conn->flags & CO_FL_WAIT_L4_CONN)
2212 conn->flags &= ~CO_FL_WAIT_L4_CONN;
Willy Tarreau20879a02012-12-03 16:32:10 +01002213 if (!conn->err_code) {
Emeric Brun29f037d2014-04-25 19:05:36 +02002214 if (!((SSL *)conn->xprt_ctx)->packet_length) {
2215 if (!errno) {
2216 if (conn->xprt_st & SSL_SOCK_RECV_HEARTBEAT)
2217 conn->err_code = CO_ER_SSL_HANDSHAKE_HB;
2218 else
2219 conn->err_code = CO_ER_SSL_EMPTY;
2220 }
2221 else {
2222 if (conn->xprt_st & SSL_SOCK_RECV_HEARTBEAT)
2223 conn->err_code = CO_ER_SSL_HANDSHAKE_HB;
2224 else
2225 conn->err_code = CO_ER_SSL_ABORT;
2226 }
2227 }
2228 else {
2229 if (conn->xprt_st & SSL_SOCK_RECV_HEARTBEAT)
2230 conn->err_code = CO_ER_SSL_HANDSHAKE_HB;
Willy Tarreau20879a02012-12-03 16:32:10 +01002231 else
Emeric Brun29f037d2014-04-25 19:05:36 +02002232 conn->err_code = CO_ER_SSL_HANDSHAKE;
2233 }
Willy Tarreau20879a02012-12-03 16:32:10 +01002234 }
Emeric Brun674b7432012-11-08 19:21:55 +01002235 goto out_error;
2236 }
2237 else {
2238 /* Fail on all other handshake errors */
2239 /* Note: OpenSSL may leave unread bytes in the socket's
2240 * buffer, causing an RST to be emitted upon close() on
2241 * TCP sockets. We first try to drain possibly pending
2242 * data to avoid this as much as possible.
2243 */
Willy Tarreau46be2e52014-01-20 12:10:52 +01002244 conn_drain(conn);
Willy Tarreau20879a02012-12-03 16:32:10 +01002245 if (!conn->err_code)
Willy Tarreauf51c6982014-04-25 20:02:39 +02002246 conn->err_code = (conn->xprt_st & SSL_SOCK_RECV_HEARTBEAT) ?
2247 CO_ER_SSL_KILLED_HB : CO_ER_SSL_HANDSHAKE;
Emeric Brun674b7432012-11-08 19:21:55 +01002248 goto out_error;
2249 }
2250 }
2251 /* read some data: consider handshake completed */
2252 goto reneg_ok;
2253 }
2254
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02002255 ret = SSL_do_handshake(conn->xprt_ctx);
Emeric Brun46591952012-05-18 15:47:34 +02002256 if (ret != 1) {
2257 /* handshake did not complete, let's find why */
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02002258 ret = SSL_get_error(conn->xprt_ctx, ret);
Emeric Brun46591952012-05-18 15:47:34 +02002259
2260 if (ret == SSL_ERROR_WANT_WRITE) {
2261 /* SSL handshake needs to write, L4 connection may not be ready */
2262 __conn_sock_stop_recv(conn);
Willy Tarreaue1f50c42014-01-22 20:02:06 +01002263 __conn_sock_want_send(conn);
2264 fd_cant_send(conn->t.sock.fd);
Emeric Brun46591952012-05-18 15:47:34 +02002265 return 0;
2266 }
2267 else if (ret == SSL_ERROR_WANT_READ) {
2268 /* SSL handshake needs to read, L4 connection is ready */
2269 if (conn->flags & CO_FL_WAIT_L4_CONN)
2270 conn->flags &= ~CO_FL_WAIT_L4_CONN;
2271 __conn_sock_stop_send(conn);
Willy Tarreaue1f50c42014-01-22 20:02:06 +01002272 __conn_sock_want_recv(conn);
2273 fd_cant_recv(conn->t.sock.fd);
Emeric Brun46591952012-05-18 15:47:34 +02002274 return 0;
2275 }
Willy Tarreau89230192012-09-28 20:22:13 +02002276 else if (ret == SSL_ERROR_SYSCALL) {
2277 /* if errno is null, then connection was successfully established */
2278 if (!errno && conn->flags & CO_FL_WAIT_L4_CONN)
2279 conn->flags &= ~CO_FL_WAIT_L4_CONN;
Willy Tarreau20879a02012-12-03 16:32:10 +01002280
Emeric Brun29f037d2014-04-25 19:05:36 +02002281 if (!((SSL *)conn->xprt_ctx)->packet_length) {
2282 if (!errno) {
2283 if (conn->xprt_st & SSL_SOCK_RECV_HEARTBEAT)
2284 conn->err_code = CO_ER_SSL_HANDSHAKE_HB;
2285 else
2286 conn->err_code = CO_ER_SSL_EMPTY;
2287 }
2288 else {
2289 if (conn->xprt_st & SSL_SOCK_RECV_HEARTBEAT)
2290 conn->err_code = CO_ER_SSL_HANDSHAKE_HB;
2291 else
2292 conn->err_code = CO_ER_SSL_ABORT;
2293 }
2294 }
2295 else {
2296 if (conn->xprt_st & SSL_SOCK_RECV_HEARTBEAT)
2297 conn->err_code = CO_ER_SSL_HANDSHAKE_HB;
Willy Tarreau20879a02012-12-03 16:32:10 +01002298 else
Emeric Brun29f037d2014-04-25 19:05:36 +02002299 conn->err_code = CO_ER_SSL_HANDSHAKE;
2300 }
Willy Tarreau89230192012-09-28 20:22:13 +02002301 goto out_error;
2302 }
Emeric Brun46591952012-05-18 15:47:34 +02002303 else {
2304 /* Fail on all other handshake errors */
Willy Tarreau566dc552012-10-19 20:52:18 +02002305 /* Note: OpenSSL may leave unread bytes in the socket's
2306 * buffer, causing an RST to be emitted upon close() on
2307 * TCP sockets. We first try to drain possibly pending
2308 * data to avoid this as much as possible.
2309 */
Willy Tarreau46be2e52014-01-20 12:10:52 +01002310 conn_drain(conn);
Willy Tarreau20879a02012-12-03 16:32:10 +01002311 if (!conn->err_code)
Willy Tarreauf51c6982014-04-25 20:02:39 +02002312 conn->err_code = (conn->xprt_st & SSL_SOCK_RECV_HEARTBEAT) ?
2313 CO_ER_SSL_KILLED_HB : CO_ER_SSL_HANDSHAKE;
Emeric Brun46591952012-05-18 15:47:34 +02002314 goto out_error;
2315 }
2316 }
2317
Emeric Brun674b7432012-11-08 19:21:55 +01002318reneg_ok:
2319
Emeric Brun46591952012-05-18 15:47:34 +02002320 /* Handshake succeeded */
Willy Tarreau0c9c2722014-05-28 12:28:58 +02002321 if (!SSL_session_reused(conn->xprt_ctx)) {
2322 if (objt_server(conn->target)) {
2323 update_freq_ctr(&global.ssl_be_keys_per_sec, 1);
2324 if (global.ssl_be_keys_per_sec.curr_ctr > global.ssl_be_keys_max)
2325 global.ssl_be_keys_max = global.ssl_be_keys_per_sec.curr_ctr;
2326
Emeric Brun46591952012-05-18 15:47:34 +02002327 /* check if session was reused, if not store current session on server for reuse */
Willy Tarreau3fdb3662012-11-12 00:42:33 +01002328 if (objt_server(conn->target)->ssl_ctx.reused_sess)
2329 SSL_SESSION_free(objt_server(conn->target)->ssl_ctx.reused_sess);
Emeric Brun46591952012-05-18 15:47:34 +02002330
Willy Tarreau3fdb3662012-11-12 00:42:33 +01002331 objt_server(conn->target)->ssl_ctx.reused_sess = SSL_get1_session(conn->xprt_ctx);
Emeric Brun46591952012-05-18 15:47:34 +02002332 }
Willy Tarreau0c9c2722014-05-28 12:28:58 +02002333 else {
2334 update_freq_ctr(&global.ssl_fe_keys_per_sec, 1);
2335 if (global.ssl_fe_keys_per_sec.curr_ctr > global.ssl_fe_keys_max)
2336 global.ssl_fe_keys_max = global.ssl_fe_keys_per_sec.curr_ctr;
2337 }
Emeric Brun46591952012-05-18 15:47:34 +02002338 }
2339
2340 /* The connection is now established at both layers, it's time to leave */
2341 conn->flags &= ~(flag | CO_FL_WAIT_L4_CONN | CO_FL_WAIT_L6_CONN);
2342 return 1;
2343
2344 out_error:
Emeric Brun644cde02012-12-14 11:21:13 +01002345 /* Clear openssl global errors stack */
2346 ERR_clear_error();
2347
Emeric Brun9fa89732012-10-04 17:09:56 +02002348 /* free resumed session if exists */
Willy Tarreau3fdb3662012-11-12 00:42:33 +01002349 if (objt_server(conn->target) && objt_server(conn->target)->ssl_ctx.reused_sess) {
2350 SSL_SESSION_free(objt_server(conn->target)->ssl_ctx.reused_sess);
2351 objt_server(conn->target)->ssl_ctx.reused_sess = NULL;
Emeric Brun9fa89732012-10-04 17:09:56 +02002352 }
2353
Emeric Brun46591952012-05-18 15:47:34 +02002354 /* Fail on all other handshake errors */
2355 conn->flags |= CO_FL_ERROR;
Willy Tarreau20879a02012-12-03 16:32:10 +01002356 if (!conn->err_code)
2357 conn->err_code = CO_ER_SSL_HANDSHAKE;
Emeric Brun46591952012-05-18 15:47:34 +02002358 return 0;
2359}
2360
2361/* Receive up to <count> bytes from connection <conn>'s socket and store them
Willy Tarreauabf08d92014-01-14 11:31:27 +01002362 * into buffer <buf>. Only one call to recv() is performed, unless the
Emeric Brun46591952012-05-18 15:47:34 +02002363 * buffer wraps, in which case a second call may be performed. The connection's
2364 * flags are updated with whatever special event is detected (error, read0,
2365 * empty). The caller is responsible for taking care of those events and
2366 * avoiding the call if inappropriate. The function does not call the
2367 * connection's polling update function, so the caller is responsible for this.
2368 */
2369static int ssl_sock_to_buf(struct connection *conn, struct buffer *buf, int count)
2370{
2371 int ret, done = 0;
Willy Tarreauabf08d92014-01-14 11:31:27 +01002372 int try;
Emeric Brun46591952012-05-18 15:47:34 +02002373
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02002374 if (!conn->xprt_ctx)
Emeric Brun46591952012-05-18 15:47:34 +02002375 goto out_error;
2376
2377 if (conn->flags & CO_FL_HANDSHAKE)
2378 /* a handshake was requested */
2379 return 0;
2380
Willy Tarreauabf08d92014-01-14 11:31:27 +01002381 /* let's realign the buffer to optimize I/O */
2382 if (buffer_empty(buf))
Emeric Brun46591952012-05-18 15:47:34 +02002383 buf->p = buf->data;
Emeric Brun46591952012-05-18 15:47:34 +02002384
2385 /* read the largest possible block. For this, we perform only one call
2386 * to recv() unless the buffer wraps and we exactly fill the first hunk,
2387 * in which case we accept to do it once again. A new attempt is made on
2388 * EINTR too.
2389 */
Willy Tarreau00b0fb92014-01-17 11:09:40 +01002390 while (count > 0) {
Willy Tarreauabf08d92014-01-14 11:31:27 +01002391 /* first check if we have some room after p+i */
2392 try = buf->data + buf->size - (buf->p + buf->i);
2393 /* otherwise continue between data and p-o */
2394 if (try <= 0) {
2395 try = buf->p - (buf->data + buf->o);
2396 if (try <= 0)
2397 break;
2398 }
2399 if (try > count)
2400 try = count;
2401
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02002402 ret = SSL_read(conn->xprt_ctx, bi_end(buf), try);
Emeric Brune1f38db2012-09-03 20:36:47 +02002403 if (conn->flags & CO_FL_ERROR) {
2404 /* CO_FL_ERROR may be set by ssl_sock_infocbk */
Emeric Brun644cde02012-12-14 11:21:13 +01002405 goto out_error;
Emeric Brune1f38db2012-09-03 20:36:47 +02002406 }
Emeric Brun46591952012-05-18 15:47:34 +02002407 if (ret > 0) {
2408 buf->i += ret;
2409 done += ret;
2410 if (ret < try)
2411 break;
2412 count -= ret;
Emeric Brun46591952012-05-18 15:47:34 +02002413 }
2414 else if (ret == 0) {
Emeric Brun644cde02012-12-14 11:21:13 +01002415 ret = SSL_get_error(conn->xprt_ctx, ret);
2416 if (ret != SSL_ERROR_ZERO_RETURN) {
Emeric Brun1c646862012-12-14 12:33:41 +01002417 /* error on protocol or underlying transport */
2418 if ((ret != SSL_ERROR_SYSCALL)
2419 || (errno && (errno != EAGAIN)))
2420 conn->flags |= CO_FL_ERROR;
2421
Emeric Brun644cde02012-12-14 11:21:13 +01002422 /* Clear openssl global errors stack */
2423 ERR_clear_error();
2424 }
Emeric Brun46591952012-05-18 15:47:34 +02002425 goto read0;
2426 }
2427 else {
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02002428 ret = SSL_get_error(conn->xprt_ctx, ret);
Emeric Brun46591952012-05-18 15:47:34 +02002429 if (ret == SSL_ERROR_WANT_WRITE) {
Emeric Brun8af8dd12012-11-08 17:56:20 +01002430 /* handshake is running, and it needs to enable write */
Emeric Brun46591952012-05-18 15:47:34 +02002431 conn->flags |= CO_FL_SSL_WAIT_HS;
Emeric Brun8af8dd12012-11-08 17:56:20 +01002432 __conn_sock_want_send(conn);
Emeric Brun46591952012-05-18 15:47:34 +02002433 break;
2434 }
2435 else if (ret == SSL_ERROR_WANT_READ) {
Emeric Brun282a76a2012-11-08 18:02:56 +01002436 if (SSL_renegotiate_pending(conn->xprt_ctx)) {
2437 /* handshake is running, and it may need to re-enable read */
2438 conn->flags |= CO_FL_SSL_WAIT_HS;
2439 __conn_sock_want_recv(conn);
2440 break;
2441 }
Emeric Brun46591952012-05-18 15:47:34 +02002442 /* we need to poll for retry a read later */
Willy Tarreaue1f50c42014-01-22 20:02:06 +01002443 fd_cant_recv(conn->t.sock.fd);
Emeric Brun46591952012-05-18 15:47:34 +02002444 break;
2445 }
2446 /* otherwise it's a real error */
2447 goto out_error;
2448 }
2449 }
2450 return done;
2451
2452 read0:
2453 conn_sock_read0(conn);
2454 return done;
2455 out_error:
Emeric Brun644cde02012-12-14 11:21:13 +01002456 /* Clear openssl global errors stack */
2457 ERR_clear_error();
2458
Emeric Brun46591952012-05-18 15:47:34 +02002459 conn->flags |= CO_FL_ERROR;
2460 return done;
2461}
2462
2463
2464/* Send all pending bytes from buffer <buf> to connection <conn>'s socket.
Willy Tarreau1049b1f2014-02-02 01:51:17 +01002465 * <flags> may contain some CO_SFL_* flags to hint the system about other
2466 * pending data for example, but this flag is ignored at the moment.
Emeric Brun46591952012-05-18 15:47:34 +02002467 * Only one call to send() is performed, unless the buffer wraps, in which case
2468 * a second call may be performed. The connection's flags are updated with
2469 * whatever special event is detected (error, empty). The caller is responsible
2470 * for taking care of those events and avoiding the call if inappropriate. The
2471 * function does not call the connection's polling update function, so the caller
2472 * is responsible for this.
2473 */
2474static int ssl_sock_from_buf(struct connection *conn, struct buffer *buf, int flags)
2475{
2476 int ret, try, done;
2477
2478 done = 0;
2479
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02002480 if (!conn->xprt_ctx)
Emeric Brun46591952012-05-18 15:47:34 +02002481 goto out_error;
2482
2483 if (conn->flags & CO_FL_HANDSHAKE)
2484 /* a handshake was requested */
2485 return 0;
2486
2487 /* send the largest possible block. For this we perform only one call
2488 * to send() unless the buffer wraps and we exactly fill the first hunk,
2489 * in which case we accept to do it once again.
2490 */
2491 while (buf->o) {
Kevin Hestercad82342013-05-30 15:12:41 -07002492 try = bo_contig_data(buf);
Willy Tarreaubfd59462013-02-21 07:46:09 +01002493
Willy Tarreau7bed9452014-02-02 02:00:24 +01002494 if (!(flags & CO_SFL_STREAMER) &&
Willy Tarreau518cedd2014-02-17 15:43:01 +01002495 !(conn->xprt_st & SSL_SOCK_SEND_UNLIMITED) &&
2496 global.tune.ssl_max_record && try > global.tune.ssl_max_record) {
Willy Tarreaubfd59462013-02-21 07:46:09 +01002497 try = global.tune.ssl_max_record;
Willy Tarreau518cedd2014-02-17 15:43:01 +01002498 }
2499 else {
2500 /* we need to keep the information about the fact that
2501 * we're not limiting the upcoming send(), because if it
2502 * fails, we'll have to retry with at least as many data.
2503 */
2504 conn->xprt_st |= SSL_SOCK_SEND_UNLIMITED;
2505 }
Willy Tarreaubfd59462013-02-21 07:46:09 +01002506
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02002507 ret = SSL_write(conn->xprt_ctx, bo_ptr(buf), try);
Willy Tarreau518cedd2014-02-17 15:43:01 +01002508
Emeric Brune1f38db2012-09-03 20:36:47 +02002509 if (conn->flags & CO_FL_ERROR) {
2510 /* CO_FL_ERROR may be set by ssl_sock_infocbk */
Emeric Brun644cde02012-12-14 11:21:13 +01002511 goto out_error;
Emeric Brune1f38db2012-09-03 20:36:47 +02002512 }
Emeric Brun46591952012-05-18 15:47:34 +02002513 if (ret > 0) {
Willy Tarreau518cedd2014-02-17 15:43:01 +01002514 conn->xprt_st &= ~SSL_SOCK_SEND_UNLIMITED;
2515
Emeric Brun46591952012-05-18 15:47:34 +02002516 buf->o -= ret;
2517 done += ret;
2518
Willy Tarreau5fb38032012-12-16 19:39:09 +01002519 if (likely(buffer_empty(buf)))
Emeric Brun46591952012-05-18 15:47:34 +02002520 /* optimize data alignment in the buffer */
2521 buf->p = buf->data;
2522
2523 /* if the system buffer is full, don't insist */
2524 if (ret < try)
2525 break;
2526 }
2527 else {
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02002528 ret = SSL_get_error(conn->xprt_ctx, ret);
Emeric Brun46591952012-05-18 15:47:34 +02002529 if (ret == SSL_ERROR_WANT_WRITE) {
Emeric Brun282a76a2012-11-08 18:02:56 +01002530 if (SSL_renegotiate_pending(conn->xprt_ctx)) {
2531 /* handshake is running, and it may need to re-enable write */
2532 conn->flags |= CO_FL_SSL_WAIT_HS;
2533 __conn_sock_want_send(conn);
2534 break;
2535 }
Emeric Brun46591952012-05-18 15:47:34 +02002536 /* we need to poll to retry a write later */
Willy Tarreaue1f50c42014-01-22 20:02:06 +01002537 fd_cant_send(conn->t.sock.fd);
Emeric Brun46591952012-05-18 15:47:34 +02002538 break;
2539 }
2540 else if (ret == SSL_ERROR_WANT_READ) {
Emeric Brun8af8dd12012-11-08 17:56:20 +01002541 /* handshake is running, and it needs to enable read */
Emeric Brun46591952012-05-18 15:47:34 +02002542 conn->flags |= CO_FL_SSL_WAIT_HS;
Emeric Brun8af8dd12012-11-08 17:56:20 +01002543 __conn_sock_want_recv(conn);
Emeric Brun46591952012-05-18 15:47:34 +02002544 break;
2545 }
2546 goto out_error;
2547 }
2548 }
2549 return done;
2550
2551 out_error:
Emeric Brun644cde02012-12-14 11:21:13 +01002552 /* Clear openssl global errors stack */
2553 ERR_clear_error();
2554
Emeric Brun46591952012-05-18 15:47:34 +02002555 conn->flags |= CO_FL_ERROR;
2556 return done;
2557}
2558
Emeric Brun46591952012-05-18 15:47:34 +02002559static void ssl_sock_close(struct connection *conn) {
2560
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02002561 if (conn->xprt_ctx) {
2562 SSL_free(conn->xprt_ctx);
2563 conn->xprt_ctx = NULL;
Willy Tarreau403edff2012-09-06 11:58:37 +02002564 sslconns--;
Emeric Brun46591952012-05-18 15:47:34 +02002565 }
Emeric Brun46591952012-05-18 15:47:34 +02002566}
2567
2568/* This function tries to perform a clean shutdown on an SSL connection, and in
2569 * any case, flags the connection as reusable if no handshake was in progress.
2570 */
2571static void ssl_sock_shutw(struct connection *conn, int clean)
2572{
2573 if (conn->flags & CO_FL_HANDSHAKE)
2574 return;
2575 /* no handshake was in progress, try a clean ssl shutdown */
Emeric Brun644cde02012-12-14 11:21:13 +01002576 if (clean && (SSL_shutdown(conn->xprt_ctx) <= 0)) {
2577 /* Clear openssl global errors stack */
2578 ERR_clear_error();
2579 }
Emeric Brun46591952012-05-18 15:47:34 +02002580
2581 /* force flag on ssl to keep session in cache regardless shutdown result */
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02002582 SSL_set_shutdown(conn->xprt_ctx, SSL_SENT_SHUTDOWN);
Emeric Brun46591952012-05-18 15:47:34 +02002583}
2584
Willy Tarreauffc3fcd2012-10-12 20:17:54 +02002585/* used for logging, may be changed for a sample fetch later */
2586const char *ssl_sock_get_cipher_name(struct connection *conn)
2587{
2588 if (!conn->xprt && !conn->xprt_ctx)
2589 return NULL;
2590 return SSL_get_cipher_name(conn->xprt_ctx);
2591}
2592
2593/* used for logging, may be changed for a sample fetch later */
2594const char *ssl_sock_get_proto_version(struct connection *conn)
2595{
2596 if (!conn->xprt && !conn->xprt_ctx)
2597 return NULL;
2598 return SSL_get_version(conn->xprt_ctx);
2599}
2600
Willy Tarreau8d598402012-10-22 17:58:39 +02002601/* Extract a serial from a cert, and copy it to a chunk.
2602 * Returns 1 if serial is found and copied, 0 if no serial found and
2603 * -1 if output is not large enough.
2604 */
2605static int
2606ssl_sock_get_serial(X509 *crt, struct chunk *out)
2607{
2608 ASN1_INTEGER *serial;
2609
2610 serial = X509_get_serialNumber(crt);
2611 if (!serial)
2612 return 0;
2613
2614 if (out->size < serial->length)
2615 return -1;
2616
2617 memcpy(out->str, serial->data, serial->length);
2618 out->len = serial->length;
2619 return 1;
2620}
2621
Emeric Brunb3cc4252014-10-29 19:03:26 +01002622/* Extract a cert to der, and copy it to a chunk.
2623 * Returns 1 if cert is found and copied, 0 on der convertion failure and
2624 * -1 if output is not large enough.
2625 */
2626static int
2627ssl_sock_crt2der(X509 *crt, struct chunk *out)
2628{
2629 int len;
2630 unsigned char *p = (unsigned char *)out->str;;
2631
2632 len =i2d_X509(crt, NULL);
2633 if (len <= 0)
2634 return 1;
2635
2636 if (out->size < len)
2637 return -1;
2638
2639 i2d_X509(crt,&p);
2640 out->len = len;
2641 return 1;
2642}
2643
Emeric Brunce5ad802012-10-22 14:11:22 +02002644
2645/* Copy Date in ASN1_UTCTIME format in struct chunk out.
2646 * Returns 1 if serial is found and copied, 0 if no valid time found
2647 * and -1 if output is not large enough.
2648 */
2649static int
2650ssl_sock_get_time(ASN1_TIME *tm, struct chunk *out)
2651{
2652 if (tm->type == V_ASN1_GENERALIZEDTIME) {
2653 ASN1_GENERALIZEDTIME *gentm = (ASN1_GENERALIZEDTIME *)tm;
2654
2655 if (gentm->length < 12)
2656 return 0;
2657 if (gentm->data[0] != 0x32 || gentm->data[1] != 0x30)
2658 return 0;
2659 if (out->size < gentm->length-2)
2660 return -1;
2661
2662 memcpy(out->str, gentm->data+2, gentm->length-2);
2663 out->len = gentm->length-2;
2664 return 1;
2665 }
2666 else if (tm->type == V_ASN1_UTCTIME) {
2667 ASN1_UTCTIME *utctm = (ASN1_UTCTIME *)tm;
2668
2669 if (utctm->length < 10)
2670 return 0;
2671 if (utctm->data[0] >= 0x35)
2672 return 0;
2673 if (out->size < utctm->length)
2674 return -1;
2675
2676 memcpy(out->str, utctm->data, utctm->length);
2677 out->len = utctm->length;
2678 return 1;
2679 }
2680
2681 return 0;
2682}
2683
Emeric Brun87855892012-10-17 17:39:35 +02002684/* Extract an entry from a X509_NAME and copy its value to an output chunk.
2685 * Returns 1 if entry found, 0 if entry not found, or -1 if output not large enough.
2686 */
2687static int
2688ssl_sock_get_dn_entry(X509_NAME *a, const struct chunk *entry, int pos, struct chunk *out)
2689{
2690 X509_NAME_ENTRY *ne;
2691 int i, j, n;
2692 int cur = 0;
2693 const char *s;
2694 char tmp[128];
2695
2696 out->len = 0;
2697 for (i = 0; i < sk_X509_NAME_ENTRY_num(a->entries); i++) {
2698 if (pos < 0)
2699 j = (sk_X509_NAME_ENTRY_num(a->entries)-1) - i;
2700 else
2701 j = i;
2702
2703 ne = sk_X509_NAME_ENTRY_value(a->entries, j);
2704 n = OBJ_obj2nid(ne->object);
2705 if ((n == NID_undef) || ((s = OBJ_nid2sn(n)) == NULL)) {
2706 i2t_ASN1_OBJECT(tmp, sizeof(tmp), ne->object);
2707 s = tmp;
2708 }
2709
2710 if (chunk_strcasecmp(entry, s) != 0)
2711 continue;
2712
2713 if (pos < 0)
2714 cur--;
2715 else
2716 cur++;
2717
2718 if (cur != pos)
2719 continue;
2720
2721 if (ne->value->length > out->size)
2722 return -1;
2723
2724 memcpy(out->str, ne->value->data, ne->value->length);
2725 out->len = ne->value->length;
2726 return 1;
2727 }
2728
2729 return 0;
2730
2731}
2732
2733/* Extract and format full DN from a X509_NAME and copy result into a chunk
2734 * Returns 1 if dn entries exits, 0 if no dn entry found or -1 if output is not large enough.
2735 */
2736static int
2737ssl_sock_get_dn_oneline(X509_NAME *a, struct chunk *out)
2738{
2739 X509_NAME_ENTRY *ne;
2740 int i, n, ln;
2741 int l = 0;
2742 const char *s;
2743 char *p;
2744 char tmp[128];
2745
2746 out->len = 0;
2747 p = out->str;
2748 for (i = 0; i < sk_X509_NAME_ENTRY_num(a->entries); i++) {
2749 ne = sk_X509_NAME_ENTRY_value(a->entries, i);
2750 n = OBJ_obj2nid(ne->object);
2751 if ((n == NID_undef) || ((s = OBJ_nid2sn(n)) == NULL)) {
2752 i2t_ASN1_OBJECT(tmp, sizeof(tmp), ne->object);
2753 s = tmp;
2754 }
2755 ln = strlen(s);
2756
2757 l += 1 + ln + 1 + ne->value->length;
2758 if (l > out->size)
2759 return -1;
2760 out->len = l;
2761
2762 *(p++)='/';
2763 memcpy(p, s, ln);
2764 p += ln;
2765 *(p++)='=';
2766 memcpy(p, ne->value->data, ne->value->length);
2767 p += ne->value->length;
2768 }
2769
2770 if (!out->len)
2771 return 0;
2772
2773 return 1;
2774}
2775
David Safb76832014-05-08 23:42:08 -04002776char *ssl_sock_get_version(struct connection *conn)
2777{
2778 if (!ssl_sock_is_ssl(conn))
2779 return NULL;
2780
2781 return (char *)SSL_get_version(conn->xprt_ctx);
2782}
2783
Emeric Brun49100982014-06-24 18:26:41 +02002784/* Extract peer certificate's common name into the chunk dest
2785 * Returns
2786 * the len of the extracted common name
2787 * or 0 if no CN found in DN
2788 * or -1 on error case (i.e. no peer certificate)
2789 */
2790int ssl_sock_get_remote_common_name(struct connection *conn, struct chunk *dest)
David Safb76832014-05-08 23:42:08 -04002791{
2792 X509 *crt = NULL;
2793 X509_NAME *name;
David Safb76832014-05-08 23:42:08 -04002794 const char find_cn[] = "CN";
2795 const struct chunk find_cn_chunk = {
2796 .str = (char *)&find_cn,
2797 .len = sizeof(find_cn)-1
2798 };
Emeric Brun49100982014-06-24 18:26:41 +02002799 int result = -1;
David Safb76832014-05-08 23:42:08 -04002800
2801 if (!ssl_sock_is_ssl(conn))
Emeric Brun49100982014-06-24 18:26:41 +02002802 goto out;
David Safb76832014-05-08 23:42:08 -04002803
2804 /* SSL_get_peer_certificate, it increase X509 * ref count */
2805 crt = SSL_get_peer_certificate(conn->xprt_ctx);
2806 if (!crt)
2807 goto out;
2808
2809 name = X509_get_subject_name(crt);
2810 if (!name)
2811 goto out;
David Safb76832014-05-08 23:42:08 -04002812
Emeric Brun49100982014-06-24 18:26:41 +02002813 result = ssl_sock_get_dn_entry(name, &find_cn_chunk, 1, dest);
2814out:
David Safb76832014-05-08 23:42:08 -04002815 if (crt)
2816 X509_free(crt);
2817
2818 return result;
2819}
2820
Dave McCowand6ec6052014-07-30 10:39:13 -04002821/* returns 1 if client passed a certificate for this session, 0 if not */
2822int ssl_sock_get_cert_used_sess(struct connection *conn)
2823{
2824 X509 *crt = NULL;
2825
2826 if (!ssl_sock_is_ssl(conn))
2827 return 0;
2828
2829 /* SSL_get_peer_certificate, it increase X509 * ref count */
2830 crt = SSL_get_peer_certificate(conn->xprt_ctx);
2831 if (!crt)
2832 return 0;
2833
2834 X509_free(crt);
2835 return 1;
2836}
2837
2838/* returns 1 if client passed a certificate for this connection, 0 if not */
2839int ssl_sock_get_cert_used_conn(struct connection *conn)
David Safb76832014-05-08 23:42:08 -04002840{
2841 if (!ssl_sock_is_ssl(conn))
2842 return 0;
2843
2844 return SSL_SOCK_ST_FL_VERIFY_DONE & conn->xprt_st ? 1 : 0;
2845}
2846
2847/* returns result from SSL verify */
2848unsigned int ssl_sock_get_verify_result(struct connection *conn)
2849{
2850 if (!ssl_sock_is_ssl(conn))
2851 return (unsigned int)X509_V_ERR_APPLICATION_VERIFICATION;
2852
2853 return (unsigned int)SSL_get_verify_result(conn->xprt_ctx);
2854}
2855
Willy Tarreau7875d092012-09-10 08:20:03 +02002856/***** Below are some sample fetching functions for ACL/patterns *****/
2857
Emeric Brune64aef12012-09-21 13:15:06 +02002858/* boolean, returns true if client cert was present */
2859static int
Emeric Brun2525b6b2012-10-18 15:59:43 +02002860smp_fetch_ssl_fc_has_crt(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
Willy Tarreauef38c392013-07-22 16:29:32 +02002861 const struct arg *args, struct sample *smp, const char *kw)
Emeric Brune64aef12012-09-21 13:15:06 +02002862{
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002863 struct connection *conn;
2864
2865 if (!l4)
2866 return 0;
2867
2868 conn = objt_conn(l4->si[0].end);
2869 if (!conn || conn->xprt != &ssl_sock)
Emeric Brune64aef12012-09-21 13:15:06 +02002870 return 0;
2871
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002872 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brune64aef12012-09-21 13:15:06 +02002873 smp->flags |= SMP_F_MAY_CHANGE;
2874 return 0;
2875 }
2876
2877 smp->flags = 0;
2878 smp->type = SMP_T_BOOL;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002879 smp->data.uint = SSL_SOCK_ST_FL_VERIFY_DONE & conn->xprt_st ? 1 : 0;
Emeric Brune64aef12012-09-21 13:15:06 +02002880
2881 return 1;
2882}
2883
Emeric Brunb3cc4252014-10-29 19:03:26 +01002884/* binary, returns a certificate in a binary chunk (der/raw).
2885 * The 5th keyword char is used to know if SSL_get_certificate or SSL_get_peer_certificate
2886 * should be use.
2887 */
2888static int
2889smp_fetch_ssl_x_der(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
2890 const struct arg *args, struct sample *smp, const char *kw)
2891{
2892 int cert_peer = (kw[4] == 'c') ? 1 : 0;
2893 X509 *crt = NULL;
2894 int ret = 0;
2895 struct chunk *smp_trash;
2896 struct connection *conn;
2897
2898 if (!l4)
2899 return 0;
2900
2901 conn = objt_conn(l4->si[0].end);
2902 if (!conn || conn->xprt != &ssl_sock)
2903 return 0;
2904
2905 if (!(conn->flags & CO_FL_CONNECTED)) {
2906 smp->flags |= SMP_F_MAY_CHANGE;
2907 return 0;
2908 }
2909
2910 if (cert_peer)
2911 crt = SSL_get_peer_certificate(conn->xprt_ctx);
2912 else
2913 crt = SSL_get_certificate(conn->xprt_ctx);
2914
2915 if (!crt)
2916 goto out;
2917
2918 smp_trash = get_trash_chunk();
2919 if (ssl_sock_crt2der(crt, smp_trash) <= 0)
2920 goto out;
2921
2922 smp->data.str = *smp_trash;
2923 smp->type = SMP_T_BIN;
2924 ret = 1;
2925out:
2926 /* SSL_get_peer_certificate, it increase X509 * ref count */
2927 if (cert_peer && crt)
2928 X509_free(crt);
2929 return ret;
2930}
2931
Emeric Brunba841a12014-04-30 17:05:08 +02002932/* binary, returns serial of certificate in a binary chunk.
2933 * The 5th keyword char is used to know if SSL_get_certificate or SSL_get_peer_certificate
2934 * should be use.
2935 */
Willy Tarreau8d598402012-10-22 17:58:39 +02002936static int
Emeric Brunba841a12014-04-30 17:05:08 +02002937smp_fetch_ssl_x_serial(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
Willy Tarreauef38c392013-07-22 16:29:32 +02002938 const struct arg *args, struct sample *smp, const char *kw)
Willy Tarreau8d598402012-10-22 17:58:39 +02002939{
Emeric Brunba841a12014-04-30 17:05:08 +02002940 int cert_peer = (kw[4] == 'c') ? 1 : 0;
Willy Tarreau8d598402012-10-22 17:58:39 +02002941 X509 *crt = NULL;
2942 int ret = 0;
2943 struct chunk *smp_trash;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002944 struct connection *conn;
2945
2946 if (!l4)
2947 return 0;
Willy Tarreau8d598402012-10-22 17:58:39 +02002948
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002949 conn = objt_conn(l4->si[0].end);
2950 if (!conn || conn->xprt != &ssl_sock)
Willy Tarreau8d598402012-10-22 17:58:39 +02002951 return 0;
2952
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002953 if (!(conn->flags & CO_FL_CONNECTED)) {
Willy Tarreau8d598402012-10-22 17:58:39 +02002954 smp->flags |= SMP_F_MAY_CHANGE;
2955 return 0;
2956 }
2957
Emeric Brunba841a12014-04-30 17:05:08 +02002958 if (cert_peer)
2959 crt = SSL_get_peer_certificate(conn->xprt_ctx);
2960 else
2961 crt = SSL_get_certificate(conn->xprt_ctx);
2962
Willy Tarreau8d598402012-10-22 17:58:39 +02002963 if (!crt)
2964 goto out;
2965
Willy Tarreau47ca5452012-12-23 20:22:19 +01002966 smp_trash = get_trash_chunk();
Willy Tarreau8d598402012-10-22 17:58:39 +02002967 if (ssl_sock_get_serial(crt, smp_trash) <= 0)
2968 goto out;
2969
2970 smp->data.str = *smp_trash;
2971 smp->type = SMP_T_BIN;
2972 ret = 1;
2973out:
Emeric Brunba841a12014-04-30 17:05:08 +02002974 /* SSL_get_peer_certificate, it increase X509 * ref count */
2975 if (cert_peer && crt)
Willy Tarreau8d598402012-10-22 17:58:39 +02002976 X509_free(crt);
2977 return ret;
2978}
Emeric Brune64aef12012-09-21 13:15:06 +02002979
Emeric Brunba841a12014-04-30 17:05:08 +02002980/* binary, returns the client certificate's SHA-1 fingerprint (SHA-1 hash of DER-encoded certificate) in a binary chunk.
2981 * The 5th keyword char is used to know if SSL_get_certificate or SSL_get_peer_certificate
2982 * should be use.
2983 */
James Votha051b4a2013-05-14 20:37:59 +02002984static int
Emeric Brunba841a12014-04-30 17:05:08 +02002985smp_fetch_ssl_x_sha1(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
Willy Tarreauef38c392013-07-22 16:29:32 +02002986 const struct arg *args, struct sample *smp, const char *kw)
James Votha051b4a2013-05-14 20:37:59 +02002987{
Emeric Brunba841a12014-04-30 17:05:08 +02002988 int cert_peer = (kw[4] == 'c') ? 1 : 0;
James Votha051b4a2013-05-14 20:37:59 +02002989 X509 *crt = NULL;
2990 const EVP_MD *digest;
2991 int ret = 0;
2992 struct chunk *smp_trash;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002993 struct connection *conn;
James Votha051b4a2013-05-14 20:37:59 +02002994
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002995 if (!l4)
James Votha051b4a2013-05-14 20:37:59 +02002996 return 0;
2997
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002998 conn = objt_conn(l4->si[0].end);
2999 if (!conn || conn->xprt != &ssl_sock)
3000 return 0;
3001
3002 if (!(conn->flags & CO_FL_CONNECTED)) {
James Votha051b4a2013-05-14 20:37:59 +02003003 smp->flags |= SMP_F_MAY_CHANGE;
3004 return 0;
3005 }
3006
Emeric Brunba841a12014-04-30 17:05:08 +02003007 if (cert_peer)
3008 crt = SSL_get_peer_certificate(conn->xprt_ctx);
3009 else
3010 crt = SSL_get_certificate(conn->xprt_ctx);
James Votha051b4a2013-05-14 20:37:59 +02003011 if (!crt)
3012 goto out;
3013
3014 smp_trash = get_trash_chunk();
3015 digest = EVP_sha1();
3016 X509_digest(crt, digest, (unsigned char *)smp_trash->str, (unsigned int *)&smp_trash->len);
3017
3018 smp->data.str = *smp_trash;
3019 smp->type = SMP_T_BIN;
3020 ret = 1;
3021out:
Emeric Brunba841a12014-04-30 17:05:08 +02003022 /* SSL_get_peer_certificate, it increase X509 * ref count */
3023 if (cert_peer && crt)
James Votha051b4a2013-05-14 20:37:59 +02003024 X509_free(crt);
3025 return ret;
3026}
3027
Emeric Brunba841a12014-04-30 17:05:08 +02003028/* string, returns certificate's notafter date in ASN1_UTCTIME format.
3029 * The 5th keyword char is used to know if SSL_get_certificate or SSL_get_peer_certificate
3030 * should be use.
3031 */
Emeric Brunce5ad802012-10-22 14:11:22 +02003032static int
Emeric Brunba841a12014-04-30 17:05:08 +02003033smp_fetch_ssl_x_notafter(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
Willy Tarreauef38c392013-07-22 16:29:32 +02003034 const struct arg *args, struct sample *smp, const char *kw)
Emeric Brunce5ad802012-10-22 14:11:22 +02003035{
Emeric Brunba841a12014-04-30 17:05:08 +02003036 int cert_peer = (kw[4] == 'c') ? 1 : 0;
Emeric Brunce5ad802012-10-22 14:11:22 +02003037 X509 *crt = NULL;
3038 int ret = 0;
3039 struct chunk *smp_trash;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003040 struct connection *conn;
Emeric Brunce5ad802012-10-22 14:11:22 +02003041
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003042 if (!l4)
Emeric Brunce5ad802012-10-22 14:11:22 +02003043 return 0;
3044
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003045 conn = objt_conn(l4->si[0].end);
3046 if (!conn || conn->xprt != &ssl_sock)
3047 return 0;
3048
3049 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brunce5ad802012-10-22 14:11:22 +02003050 smp->flags |= SMP_F_MAY_CHANGE;
3051 return 0;
3052 }
3053
Emeric Brunba841a12014-04-30 17:05:08 +02003054 if (cert_peer)
3055 crt = SSL_get_peer_certificate(conn->xprt_ctx);
3056 else
3057 crt = SSL_get_certificate(conn->xprt_ctx);
Emeric Brunce5ad802012-10-22 14:11:22 +02003058 if (!crt)
3059 goto out;
3060
Willy Tarreau47ca5452012-12-23 20:22:19 +01003061 smp_trash = get_trash_chunk();
Emeric Brunce5ad802012-10-22 14:11:22 +02003062 if (ssl_sock_get_time(X509_get_notAfter(crt), smp_trash) <= 0)
3063 goto out;
3064
3065 smp->data.str = *smp_trash;
3066 smp->type = SMP_T_STR;
3067 ret = 1;
3068out:
Emeric Brunba841a12014-04-30 17:05:08 +02003069 /* SSL_get_peer_certificate, it increase X509 * ref count */
3070 if (cert_peer && crt)
Emeric Brunce5ad802012-10-22 14:11:22 +02003071 X509_free(crt);
3072 return ret;
3073}
3074
Emeric Brunba841a12014-04-30 17:05:08 +02003075/* string, returns a string of a formatted full dn \C=..\O=..\OU=.. \CN=.. of certificate's issuer
3076 * The 5th keyword char is used to know if SSL_get_certificate or SSL_get_peer_certificate
3077 * should be use.
3078 */
Emeric Brun87855892012-10-17 17:39:35 +02003079static int
Emeric Brunba841a12014-04-30 17:05:08 +02003080smp_fetch_ssl_x_i_dn(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
Willy Tarreauef38c392013-07-22 16:29:32 +02003081 const struct arg *args, struct sample *smp, const char *kw)
Emeric Brun87855892012-10-17 17:39:35 +02003082{
Emeric Brunba841a12014-04-30 17:05:08 +02003083 int cert_peer = (kw[4] == 'c') ? 1 : 0;
Emeric Brun87855892012-10-17 17:39:35 +02003084 X509 *crt = NULL;
3085 X509_NAME *name;
3086 int ret = 0;
3087 struct chunk *smp_trash;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003088 struct connection *conn;
Emeric Brun87855892012-10-17 17:39:35 +02003089
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003090 if (!l4)
Emeric Brun87855892012-10-17 17:39:35 +02003091 return 0;
3092
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003093 conn = objt_conn(l4->si[0].end);
3094 if (!conn || conn->xprt != &ssl_sock)
3095 return 0;
3096
3097 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brun87855892012-10-17 17:39:35 +02003098 smp->flags |= SMP_F_MAY_CHANGE;
3099 return 0;
3100 }
3101
Emeric Brunba841a12014-04-30 17:05:08 +02003102 if (cert_peer)
3103 crt = SSL_get_peer_certificate(conn->xprt_ctx);
3104 else
3105 crt = SSL_get_certificate(conn->xprt_ctx);
Emeric Brun87855892012-10-17 17:39:35 +02003106 if (!crt)
3107 goto out;
3108
3109 name = X509_get_issuer_name(crt);
3110 if (!name)
3111 goto out;
3112
Willy Tarreau47ca5452012-12-23 20:22:19 +01003113 smp_trash = get_trash_chunk();
Emeric Brun87855892012-10-17 17:39:35 +02003114 if (args && args[0].type == ARGT_STR) {
3115 int pos = 1;
3116
3117 if (args[1].type == ARGT_SINT)
3118 pos = args[1].data.sint;
3119 else if (args[1].type == ARGT_UINT)
3120 pos =(int)args[1].data.uint;
3121
3122 if (ssl_sock_get_dn_entry(name, &args[0].data.str, pos, smp_trash) <= 0)
3123 goto out;
3124 }
3125 else if (ssl_sock_get_dn_oneline(name, smp_trash) <= 0)
3126 goto out;
3127
3128 smp->type = SMP_T_STR;
3129 smp->data.str = *smp_trash;
3130 ret = 1;
3131out:
Emeric Brunba841a12014-04-30 17:05:08 +02003132 /* SSL_get_peer_certificate, it increase X509 * ref count */
3133 if (cert_peer && crt)
Emeric Brun87855892012-10-17 17:39:35 +02003134 X509_free(crt);
3135 return ret;
3136}
3137
Emeric Brunba841a12014-04-30 17:05:08 +02003138/* string, returns notbefore date in ASN1_UTCTIME format.
3139 * The 5th keyword char is used to know if SSL_get_certificate or SSL_get_peer_certificate
3140 * should be use.
3141 */
Emeric Brunce5ad802012-10-22 14:11:22 +02003142static int
Emeric Brunba841a12014-04-30 17:05:08 +02003143smp_fetch_ssl_x_notbefore(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
Willy Tarreauef38c392013-07-22 16:29:32 +02003144 const struct arg *args, struct sample *smp, const char *kw)
Emeric Brunce5ad802012-10-22 14:11:22 +02003145{
Emeric Brunba841a12014-04-30 17:05:08 +02003146 int cert_peer = (kw[4] == 'c') ? 1 : 0;
Emeric Brunce5ad802012-10-22 14:11:22 +02003147 X509 *crt = NULL;
3148 int ret = 0;
3149 struct chunk *smp_trash;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003150 struct connection *conn;
3151
3152 if (!l4)
3153 return 0;
Emeric Brunce5ad802012-10-22 14:11:22 +02003154
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003155 conn = objt_conn(l4->si[0].end);
3156 if (!conn || conn->xprt != &ssl_sock)
Emeric Brunce5ad802012-10-22 14:11:22 +02003157 return 0;
3158
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003159 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brunce5ad802012-10-22 14:11:22 +02003160 smp->flags |= SMP_F_MAY_CHANGE;
3161 return 0;
3162 }
3163
Emeric Brunba841a12014-04-30 17:05:08 +02003164 if (cert_peer)
3165 crt = SSL_get_peer_certificate(conn->xprt_ctx);
3166 else
3167 crt = SSL_get_certificate(conn->xprt_ctx);
Emeric Brunce5ad802012-10-22 14:11:22 +02003168 if (!crt)
3169 goto out;
3170
Willy Tarreau47ca5452012-12-23 20:22:19 +01003171 smp_trash = get_trash_chunk();
Emeric Brunce5ad802012-10-22 14:11:22 +02003172 if (ssl_sock_get_time(X509_get_notBefore(crt), smp_trash) <= 0)
3173 goto out;
3174
3175 smp->data.str = *smp_trash;
3176 smp->type = SMP_T_STR;
3177 ret = 1;
3178out:
Emeric Brunba841a12014-04-30 17:05:08 +02003179 /* SSL_get_peer_certificate, it increase X509 * ref count */
3180 if (cert_peer && crt)
Emeric Brunce5ad802012-10-22 14:11:22 +02003181 X509_free(crt);
3182 return ret;
3183}
3184
Emeric Brunba841a12014-04-30 17:05:08 +02003185/* string, returns a string of a formatted full dn \C=..\O=..\OU=.. \CN=.. of certificate's subject
3186 * The 5th keyword char is used to know if SSL_get_certificate or SSL_get_peer_certificate
3187 * should be use.
3188 */
Emeric Brun87855892012-10-17 17:39:35 +02003189static int
Emeric Brunba841a12014-04-30 17:05:08 +02003190smp_fetch_ssl_x_s_dn(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
Willy Tarreauef38c392013-07-22 16:29:32 +02003191 const struct arg *args, struct sample *smp, const char *kw)
Emeric Brun87855892012-10-17 17:39:35 +02003192{
Emeric Brunba841a12014-04-30 17:05:08 +02003193 int cert_peer = (kw[4] == 'c') ? 1 : 0;
Emeric Brun87855892012-10-17 17:39:35 +02003194 X509 *crt = NULL;
3195 X509_NAME *name;
3196 int ret = 0;
3197 struct chunk *smp_trash;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003198 struct connection *conn;
Emeric Brun87855892012-10-17 17:39:35 +02003199
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003200 if (!l4)
Emeric Brun87855892012-10-17 17:39:35 +02003201 return 0;
3202
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003203 conn = objt_conn(l4->si[0].end);
3204 if (!conn || conn->xprt != &ssl_sock)
3205 return 0;
3206
3207 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brun87855892012-10-17 17:39:35 +02003208 smp->flags |= SMP_F_MAY_CHANGE;
3209 return 0;
3210 }
3211
Emeric Brunba841a12014-04-30 17:05:08 +02003212 if (cert_peer)
3213 crt = SSL_get_peer_certificate(conn->xprt_ctx);
3214 else
3215 crt = SSL_get_certificate(conn->xprt_ctx);
Emeric Brun87855892012-10-17 17:39:35 +02003216 if (!crt)
3217 goto out;
3218
3219 name = X509_get_subject_name(crt);
3220 if (!name)
3221 goto out;
3222
Willy Tarreau47ca5452012-12-23 20:22:19 +01003223 smp_trash = get_trash_chunk();
Emeric Brun87855892012-10-17 17:39:35 +02003224 if (args && args[0].type == ARGT_STR) {
3225 int pos = 1;
3226
3227 if (args[1].type == ARGT_SINT)
3228 pos = args[1].data.sint;
3229 else if (args[1].type == ARGT_UINT)
3230 pos =(int)args[1].data.uint;
3231
3232 if (ssl_sock_get_dn_entry(name, &args[0].data.str, pos, smp_trash) <= 0)
3233 goto out;
3234 }
3235 else if (ssl_sock_get_dn_oneline(name, smp_trash) <= 0)
3236 goto out;
3237
3238 smp->type = SMP_T_STR;
3239 smp->data.str = *smp_trash;
3240 ret = 1;
3241out:
Emeric Brunba841a12014-04-30 17:05:08 +02003242 /* SSL_get_peer_certificate, it increase X509 * ref count */
3243 if (cert_peer && crt)
Emeric Brun87855892012-10-17 17:39:35 +02003244 X509_free(crt);
3245 return ret;
3246}
Emeric Brun9143d372012-12-20 15:44:16 +01003247
3248/* integer, returns true if current session use a client certificate */
3249static int
3250smp_fetch_ssl_c_used(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
Willy Tarreauef38c392013-07-22 16:29:32 +02003251 const struct arg *args, struct sample *smp, const char *kw)
Emeric Brun9143d372012-12-20 15:44:16 +01003252{
3253 X509 *crt;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003254 struct connection *conn;
Emeric Brun9143d372012-12-20 15:44:16 +01003255
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003256 if (!l4)
Emeric Brun9143d372012-12-20 15:44:16 +01003257 return 0;
3258
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003259 conn = objt_conn(l4->si[0].end);
3260 if (!conn || conn->xprt != &ssl_sock)
3261 return 0;
3262
3263 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brun9143d372012-12-20 15:44:16 +01003264 smp->flags |= SMP_F_MAY_CHANGE;
3265 return 0;
3266 }
3267
3268 /* SSL_get_peer_certificate returns a ptr on allocated X509 struct */
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003269 crt = SSL_get_peer_certificate(conn->xprt_ctx);
Emeric Brun9143d372012-12-20 15:44:16 +01003270 if (crt) {
3271 X509_free(crt);
3272 }
3273
3274 smp->type = SMP_T_BOOL;
3275 smp->data.uint = (crt != NULL);
3276 return 1;
3277}
3278
Emeric Brunba841a12014-04-30 17:05:08 +02003279/* integer, returns the certificate version
3280 * The 5th keyword char is used to know if SSL_get_certificate or SSL_get_peer_certificate
3281 * should be use.
3282 */
Emeric Bruna7359fd2012-10-17 15:03:11 +02003283static int
Emeric Brunba841a12014-04-30 17:05:08 +02003284smp_fetch_ssl_x_version(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
Willy Tarreauef38c392013-07-22 16:29:32 +02003285 const struct arg *args, struct sample *smp, const char *kw)
Emeric Bruna7359fd2012-10-17 15:03:11 +02003286{
Emeric Brunba841a12014-04-30 17:05:08 +02003287 int cert_peer = (kw[4] == 'c') ? 1 : 0;
Emeric Bruna7359fd2012-10-17 15:03:11 +02003288 X509 *crt;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003289 struct connection *conn;
3290
3291 if (!l4)
3292 return 0;
Emeric Bruna7359fd2012-10-17 15:03:11 +02003293
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003294 conn = objt_conn(l4->si[0].end);
3295 if (!conn || conn->xprt != &ssl_sock)
Emeric Bruna7359fd2012-10-17 15:03:11 +02003296 return 0;
3297
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003298 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Bruna7359fd2012-10-17 15:03:11 +02003299 smp->flags |= SMP_F_MAY_CHANGE;
3300 return 0;
3301 }
3302
Emeric Brunba841a12014-04-30 17:05:08 +02003303 if (cert_peer)
3304 crt = SSL_get_peer_certificate(conn->xprt_ctx);
3305 else
3306 crt = SSL_get_certificate(conn->xprt_ctx);
Emeric Bruna7359fd2012-10-17 15:03:11 +02003307 if (!crt)
3308 return 0;
3309
3310 smp->data.uint = (unsigned int)(1 + X509_get_version(crt));
Emeric Brunba841a12014-04-30 17:05:08 +02003311 /* SSL_get_peer_certificate increase X509 * ref count */
3312 if (cert_peer)
3313 X509_free(crt);
Emeric Bruna7359fd2012-10-17 15:03:11 +02003314 smp->type = SMP_T_UINT;
3315
3316 return 1;
3317}
3318
Emeric Brunba841a12014-04-30 17:05:08 +02003319/* string, returns the certificate's signature algorithm.
3320 * The 5th keyword char is used to know if SSL_get_certificate or SSL_get_peer_certificate
3321 * should be use.
3322 */
Emeric Brun7f56e742012-10-19 18:15:40 +02003323static int
Emeric Brunba841a12014-04-30 17:05:08 +02003324smp_fetch_ssl_x_sig_alg(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
Willy Tarreauef38c392013-07-22 16:29:32 +02003325 const struct arg *args, struct sample *smp, const char *kw)
Emeric Brun7f56e742012-10-19 18:15:40 +02003326{
Emeric Brunba841a12014-04-30 17:05:08 +02003327 int cert_peer = (kw[4] == 'c') ? 1 : 0;
Emeric Brun7f56e742012-10-19 18:15:40 +02003328 X509 *crt;
3329 int nid;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003330 struct connection *conn;
Emeric Brun7f56e742012-10-19 18:15:40 +02003331
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003332 if (!l4)
Emeric Brun7f56e742012-10-19 18:15:40 +02003333 return 0;
3334
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003335 conn = objt_conn(l4->si[0].end);
3336 if (!conn || conn->xprt != &ssl_sock)
3337 return 0;
3338
3339 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brun7f56e742012-10-19 18:15:40 +02003340 smp->flags |= SMP_F_MAY_CHANGE;
3341 return 0;
3342 }
3343
Emeric Brunba841a12014-04-30 17:05:08 +02003344 if (cert_peer)
3345 crt = SSL_get_peer_certificate(conn->xprt_ctx);
3346 else
3347 crt = SSL_get_certificate(conn->xprt_ctx);
Emeric Brun7f56e742012-10-19 18:15:40 +02003348 if (!crt)
3349 return 0;
3350
3351 nid = OBJ_obj2nid((ASN1_OBJECT *)(crt->cert_info->signature->algorithm));
3352
3353 smp->data.str.str = (char *)OBJ_nid2sn(nid);
Emeric Brun9bf3ba22013-10-07 14:31:44 +02003354 if (!smp->data.str.str) {
Emeric Brunba841a12014-04-30 17:05:08 +02003355 /* SSL_get_peer_certificate increase X509 * ref count */
3356 if (cert_peer)
3357 X509_free(crt);
Emeric Brun7f56e742012-10-19 18:15:40 +02003358 return 0;
Emeric Brun9bf3ba22013-10-07 14:31:44 +02003359 }
Emeric Brun7f56e742012-10-19 18:15:40 +02003360
Thierry FOURNIER7654c9f2013-12-17 00:20:33 +01003361 smp->type = SMP_T_STR;
3362 smp->flags |= SMP_F_CONST;
Emeric Brun7f56e742012-10-19 18:15:40 +02003363 smp->data.str.len = strlen(smp->data.str.str);
Emeric Brunba841a12014-04-30 17:05:08 +02003364 /* SSL_get_peer_certificate increase X509 * ref count */
3365 if (cert_peer)
3366 X509_free(crt);
Emeric Brun7f56e742012-10-19 18:15:40 +02003367
3368 return 1;
3369}
3370
Emeric Brunba841a12014-04-30 17:05:08 +02003371/* string, returns the certificate's key algorithm.
3372 * The 5th keyword char is used to know if SSL_get_certificate or SSL_get_peer_certificate
3373 * should be use.
3374 */
Emeric Brun521a0112012-10-22 12:22:55 +02003375static int
Emeric Brunba841a12014-04-30 17:05:08 +02003376smp_fetch_ssl_x_key_alg(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
Willy Tarreauef38c392013-07-22 16:29:32 +02003377 const struct arg *args, struct sample *smp, const char *kw)
Emeric Brun521a0112012-10-22 12:22:55 +02003378{
Emeric Brunba841a12014-04-30 17:05:08 +02003379 int cert_peer = (kw[4] == 'c') ? 1 : 0;
Emeric Brun521a0112012-10-22 12:22:55 +02003380 X509 *crt;
3381 int nid;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003382 struct connection *conn;
Emeric Brun521a0112012-10-22 12:22:55 +02003383
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003384 if (!l4)
Emeric Brun521a0112012-10-22 12:22:55 +02003385 return 0;
3386
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003387 conn = objt_conn(l4->si[0].end);
3388 if (!conn || conn->xprt != &ssl_sock)
3389 return 0;
3390
3391 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brun521a0112012-10-22 12:22:55 +02003392 smp->flags |= SMP_F_MAY_CHANGE;
3393 return 0;
3394 }
3395
Emeric Brunba841a12014-04-30 17:05:08 +02003396 if (cert_peer)
3397 crt = SSL_get_peer_certificate(conn->xprt_ctx);
3398 else
3399 crt = SSL_get_certificate(conn->xprt_ctx);
Emeric Brun521a0112012-10-22 12:22:55 +02003400 if (!crt)
3401 return 0;
3402
3403 nid = OBJ_obj2nid((ASN1_OBJECT *)(crt->cert_info->key->algor->algorithm));
3404
3405 smp->data.str.str = (char *)OBJ_nid2sn(nid);
Emeric Brun9bf3ba22013-10-07 14:31:44 +02003406 if (!smp->data.str.str) {
Emeric Brunba841a12014-04-30 17:05:08 +02003407 /* SSL_get_peer_certificate increase X509 * ref count */
3408 if (cert_peer)
3409 X509_free(crt);
Emeric Brun521a0112012-10-22 12:22:55 +02003410 return 0;
Emeric Brun9bf3ba22013-10-07 14:31:44 +02003411 }
Emeric Brun521a0112012-10-22 12:22:55 +02003412
Thierry FOURNIER7654c9f2013-12-17 00:20:33 +01003413 smp->type = SMP_T_STR;
3414 smp->flags |= SMP_F_CONST;
Emeric Brun521a0112012-10-22 12:22:55 +02003415 smp->data.str.len = strlen(smp->data.str.str);
Emeric Brunba841a12014-04-30 17:05:08 +02003416 if (cert_peer)
3417 X509_free(crt);
Emeric Brun521a0112012-10-22 12:22:55 +02003418
3419 return 1;
3420}
3421
Emeric Brun645ae792014-04-30 14:21:06 +02003422/* boolean, returns true if front conn. transport layer is SSL.
3423 * This function is also usable on backend conn if the fetch keyword 5th
3424 * char is 'b'.
3425 */
Willy Tarreau7875d092012-09-10 08:20:03 +02003426static int
Emeric Brun2525b6b2012-10-18 15:59:43 +02003427smp_fetch_ssl_fc(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
Willy Tarreauef38c392013-07-22 16:29:32 +02003428 const struct arg *args, struct sample *smp, const char *kw)
Willy Tarreau7875d092012-09-10 08:20:03 +02003429{
Emeric Brun645ae792014-04-30 14:21:06 +02003430 int back_conn = (kw[4] == 'b') ? 1 : 0;
3431 struct connection *conn = objt_conn(l4->si[back_conn].end);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003432
Willy Tarreau7875d092012-09-10 08:20:03 +02003433 smp->type = SMP_T_BOOL;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003434 smp->data.uint = (conn && conn->xprt == &ssl_sock);
Willy Tarreau7875d092012-09-10 08:20:03 +02003435 return 1;
3436}
3437
Emeric Brun2525b6b2012-10-18 15:59:43 +02003438/* boolean, returns true if client present a SNI */
Willy Tarreau7875d092012-09-10 08:20:03 +02003439static int
Emeric Brun2525b6b2012-10-18 15:59:43 +02003440smp_fetch_ssl_fc_has_sni(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
Willy Tarreauef38c392013-07-22 16:29:32 +02003441 const struct arg *args, struct sample *smp, const char *kw)
Willy Tarreau7875d092012-09-10 08:20:03 +02003442{
3443#ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003444 struct connection *conn = objt_conn(l4->si[0].end);
3445
Willy Tarreau7875d092012-09-10 08:20:03 +02003446 smp->type = SMP_T_BOOL;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003447 smp->data.uint = (conn && conn->xprt == &ssl_sock) &&
3448 conn->xprt_ctx &&
3449 SSL_get_servername(conn->xprt_ctx, TLSEXT_NAMETYPE_host_name) != NULL;
Willy Tarreau7875d092012-09-10 08:20:03 +02003450 return 1;
3451#else
3452 return 0;
3453#endif
3454}
3455
Emeric Brun645ae792014-04-30 14:21:06 +02003456/* string, returns the used cipher if front conn. transport layer is SSL.
3457 * This function is also usable on backend conn if the fetch keyword 5th
3458 * char is 'b'.
3459 */
Emeric Brun589fcad2012-10-16 14:13:26 +02003460static int
3461smp_fetch_ssl_fc_cipher(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
Willy Tarreauef38c392013-07-22 16:29:32 +02003462 const struct arg *args, struct sample *smp, const char *kw)
Emeric Brun589fcad2012-10-16 14:13:26 +02003463{
Emeric Brun645ae792014-04-30 14:21:06 +02003464 int back_conn = (kw[4] == 'b') ? 1 : 0;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003465 struct connection *conn;
3466
Emeric Brun589fcad2012-10-16 14:13:26 +02003467 smp->flags = 0;
3468
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003469 if (!l4)
3470 return 0;
3471
Emeric Brun645ae792014-04-30 14:21:06 +02003472 conn = objt_conn(l4->si[back_conn].end);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003473 if (!conn || !conn->xprt_ctx || conn->xprt != &ssl_sock)
Emeric Brun589fcad2012-10-16 14:13:26 +02003474 return 0;
3475
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003476 smp->data.str.str = (char *)SSL_get_cipher_name(conn->xprt_ctx);
Emeric Brun589fcad2012-10-16 14:13:26 +02003477 if (!smp->data.str.str)
3478 return 0;
3479
Thierry FOURNIER7654c9f2013-12-17 00:20:33 +01003480 smp->type = SMP_T_STR;
3481 smp->flags |= SMP_F_CONST;
Emeric Brun589fcad2012-10-16 14:13:26 +02003482 smp->data.str.len = strlen(smp->data.str.str);
3483
3484 return 1;
3485}
3486
Emeric Brun645ae792014-04-30 14:21:06 +02003487/* integer, returns the algoritm's keysize if front conn. transport layer
3488 * is SSL.
3489 * This function is also usable on backend conn if the fetch keyword 5th
3490 * char is 'b'.
3491 */
Emeric Brun589fcad2012-10-16 14:13:26 +02003492static int
3493smp_fetch_ssl_fc_alg_keysize(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
Willy Tarreauef38c392013-07-22 16:29:32 +02003494 const struct arg *args, struct sample *smp, const char *kw)
Emeric Brun589fcad2012-10-16 14:13:26 +02003495{
Emeric Brun645ae792014-04-30 14:21:06 +02003496 int back_conn = (kw[4] == 'b') ? 1 : 0;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003497 struct connection *conn;
3498
Emeric Brun589fcad2012-10-16 14:13:26 +02003499 smp->flags = 0;
3500
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003501 if (!l4)
Emeric Brun589fcad2012-10-16 14:13:26 +02003502 return 0;
3503
Emeric Brun645ae792014-04-30 14:21:06 +02003504 conn = objt_conn(l4->si[back_conn].end);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003505 if (!conn || !conn->xprt_ctx || conn->xprt != &ssl_sock)
Emeric Brun589fcad2012-10-16 14:13:26 +02003506 return 0;
3507
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003508 if (!SSL_get_cipher_bits(conn->xprt_ctx, (int *)&smp->data.uint))
3509 return 0;
3510
Emeric Brun589fcad2012-10-16 14:13:26 +02003511 smp->type = SMP_T_UINT;
3512
3513 return 1;
3514}
3515
Emeric Brun645ae792014-04-30 14:21:06 +02003516/* integer, returns the used keysize if front conn. transport layer is SSL.
3517 * This function is also usable on backend conn if the fetch keyword 5th
3518 * char is 'b'.
3519 */
Emeric Brun589fcad2012-10-16 14:13:26 +02003520static int
3521smp_fetch_ssl_fc_use_keysize(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
Willy Tarreauef38c392013-07-22 16:29:32 +02003522 const struct arg *args, struct sample *smp, const char *kw)
Emeric Brun589fcad2012-10-16 14:13:26 +02003523{
Emeric Brun645ae792014-04-30 14:21:06 +02003524 int back_conn = (kw[4] == 'b') ? 1 : 0;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003525 struct connection *conn;
3526
Emeric Brun589fcad2012-10-16 14:13:26 +02003527 smp->flags = 0;
3528
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003529 if (!l4)
Emeric Brun589fcad2012-10-16 14:13:26 +02003530 return 0;
3531
Emeric Brun645ae792014-04-30 14:21:06 +02003532 conn = objt_conn(l4->si[back_conn].end);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003533 if (!conn || !conn->xprt_ctx || conn->xprt != &ssl_sock)
3534 return 0;
3535
3536 smp->data.uint = (unsigned int)SSL_get_cipher_bits(conn->xprt_ctx, NULL);
Emeric Brun589fcad2012-10-16 14:13:26 +02003537 if (!smp->data.uint)
3538 return 0;
3539
3540 smp->type = SMP_T_UINT;
3541
3542 return 1;
3543}
3544
Willy Tarreau6c9a3d52012-10-18 18:57:14 +02003545#ifdef OPENSSL_NPN_NEGOTIATED
Willy Tarreau7875d092012-09-10 08:20:03 +02003546static int
Emeric Brun2525b6b2012-10-18 15:59:43 +02003547smp_fetch_ssl_fc_npn(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
Willy Tarreauef38c392013-07-22 16:29:32 +02003548 const struct arg *args, struct sample *smp, const char *kw)
Willy Tarreaua33c6542012-10-15 13:19:06 +02003549{
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003550 struct connection *conn;
3551
Thierry FOURNIER7654c9f2013-12-17 00:20:33 +01003552 smp->flags = SMP_F_CONST;
3553 smp->type = SMP_T_STR;
Willy Tarreaua33c6542012-10-15 13:19:06 +02003554
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003555 if (!l4)
Willy Tarreaua33c6542012-10-15 13:19:06 +02003556 return 0;
3557
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003558 conn = objt_conn(l4->si[0].end);
3559 if (!conn || !conn->xprt_ctx || conn->xprt != &ssl_sock)
3560 return 0;
3561
Willy Tarreaua33c6542012-10-15 13:19:06 +02003562 smp->data.str.str = NULL;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003563 SSL_get0_next_proto_negotiated(conn->xprt_ctx,
Willy Tarreaua33c6542012-10-15 13:19:06 +02003564 (const unsigned char **)&smp->data.str.str, (unsigned *)&smp->data.str.len);
3565
3566 if (!smp->data.str.str)
3567 return 0;
3568
3569 return 1;
Willy Tarreaua33c6542012-10-15 13:19:06 +02003570}
Willy Tarreau6c9a3d52012-10-18 18:57:14 +02003571#endif
Willy Tarreaua33c6542012-10-15 13:19:06 +02003572
Dirkjan Bussink48f1c4e2014-02-13 12:29:42 +01003573#ifdef TLSEXT_TYPE_application_layer_protocol_negotiation
Willy Tarreauab861d32013-04-02 02:30:41 +02003574static int
3575smp_fetch_ssl_fc_alpn(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
Willy Tarreauef38c392013-07-22 16:29:32 +02003576 const struct arg *args, struct sample *smp, const char *kw)
Willy Tarreauab861d32013-04-02 02:30:41 +02003577{
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003578 struct connection *conn;
3579
Thierry FOURNIER7654c9f2013-12-17 00:20:33 +01003580 smp->flags = SMP_F_CONST;
3581 smp->type = SMP_T_STR;
Willy Tarreauab861d32013-04-02 02:30:41 +02003582
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003583 if (!l4)
3584 return 0;
3585
3586 conn = objt_conn(l4->si[0].end);
3587 if (!conn || !conn->xprt_ctx || conn->xprt != &ssl_sock)
Willy Tarreauab861d32013-04-02 02:30:41 +02003588 return 0;
3589
3590 smp->data.str.str = NULL;
Dirkjan Bussink48f1c4e2014-02-13 12:29:42 +01003591 SSL_get0_alpn_selected(conn->xprt_ctx,
Willy Tarreauab861d32013-04-02 02:30:41 +02003592 (const unsigned char **)&smp->data.str.str, (unsigned *)&smp->data.str.len);
3593
3594 if (!smp->data.str.str)
3595 return 0;
3596
3597 return 1;
3598}
3599#endif
3600
Emeric Brun645ae792014-04-30 14:21:06 +02003601/* string, returns the used protocol if front conn. transport layer is SSL.
3602 * This function is also usable on backend conn if the fetch keyword 5th
3603 * char is 'b'.
3604 */
Willy Tarreaua33c6542012-10-15 13:19:06 +02003605static int
Emeric Brun589fcad2012-10-16 14:13:26 +02003606smp_fetch_ssl_fc_protocol(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
Willy Tarreauef38c392013-07-22 16:29:32 +02003607 const struct arg *args, struct sample *smp, const char *kw)
Emeric Brun589fcad2012-10-16 14:13:26 +02003608{
Emeric Brun645ae792014-04-30 14:21:06 +02003609 int back_conn = (kw[4] == 'b') ? 1 : 0;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003610 struct connection *conn;
3611
Emeric Brun589fcad2012-10-16 14:13:26 +02003612 smp->flags = 0;
3613
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003614 if (!l4)
Emeric Brun589fcad2012-10-16 14:13:26 +02003615 return 0;
3616
Emeric Brun645ae792014-04-30 14:21:06 +02003617 conn = objt_conn(l4->si[back_conn].end);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003618 if (!conn || !conn->xprt_ctx || conn->xprt != &ssl_sock)
3619 return 0;
3620
3621 smp->data.str.str = (char *)SSL_get_version(conn->xprt_ctx);
Emeric Brun589fcad2012-10-16 14:13:26 +02003622 if (!smp->data.str.str)
3623 return 0;
3624
Thierry FOURNIER7654c9f2013-12-17 00:20:33 +01003625 smp->type = SMP_T_STR;
3626 smp->flags = SMP_F_CONST;
Emeric Brun589fcad2012-10-16 14:13:26 +02003627 smp->data.str.len = strlen(smp->data.str.str);
3628
3629 return 1;
3630}
3631
Emeric Brun645ae792014-04-30 14:21:06 +02003632/* binary, returns the SSL session id if front conn. transport layer is SSL.
3633 * This function is also usable on backend conn if the fetch keyword 5th
3634 * char is 'b'.
3635 */
Emeric Brun589fcad2012-10-16 14:13:26 +02003636static int
Emeric Brunfe68f682012-10-16 14:59:28 +02003637smp_fetch_ssl_fc_session_id(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
Willy Tarreauef38c392013-07-22 16:29:32 +02003638 const struct arg *args, struct sample *smp, const char *kw)
Emeric Brunfe68f682012-10-16 14:59:28 +02003639{
3640#if OPENSSL_VERSION_NUMBER > 0x0090800fL
Emeric Brun645ae792014-04-30 14:21:06 +02003641 int back_conn = (kw[4] == 'b') ? 1 : 0;
Emeric Brunfe68f682012-10-16 14:59:28 +02003642 SSL_SESSION *sess;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003643 struct connection *conn;
Emeric Brunfe68f682012-10-16 14:59:28 +02003644
Thierry FOURNIER7654c9f2013-12-17 00:20:33 +01003645 smp->flags = SMP_F_CONST;
3646 smp->type = SMP_T_BIN;
Emeric Brunfe68f682012-10-16 14:59:28 +02003647
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003648 if (!l4)
Emeric Brunfe68f682012-10-16 14:59:28 +02003649 return 0;
3650
Emeric Brun645ae792014-04-30 14:21:06 +02003651 conn = objt_conn(l4->si[back_conn].end);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003652 if (!conn || !conn->xprt_ctx || conn->xprt != &ssl_sock)
3653 return 0;
3654
3655 sess = SSL_get_session(conn->xprt_ctx);
Emeric Brunfe68f682012-10-16 14:59:28 +02003656 if (!sess)
3657 return 0;
3658
3659 smp->data.str.str = (char *)SSL_SESSION_get_id(sess, (unsigned int *)&smp->data.str.len);
3660 if (!smp->data.str.str || !&smp->data.str.len)
3661 return 0;
3662
3663 return 1;
3664#else
3665 return 0;
3666#endif
3667}
3668
3669static int
Emeric Brun2525b6b2012-10-18 15:59:43 +02003670smp_fetch_ssl_fc_sni(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
Willy Tarreauef38c392013-07-22 16:29:32 +02003671 const struct arg *args, struct sample *smp, const char *kw)
Willy Tarreau7875d092012-09-10 08:20:03 +02003672{
3673#ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003674 struct connection *conn;
3675
Thierry FOURNIER7654c9f2013-12-17 00:20:33 +01003676 smp->flags = SMP_F_CONST;
3677 smp->type = SMP_T_STR;
Willy Tarreau7875d092012-09-10 08:20:03 +02003678
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003679 if (!l4)
Willy Tarreau7875d092012-09-10 08:20:03 +02003680 return 0;
3681
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003682 conn = objt_conn(l4->si[0].end);
3683 if (!conn || !conn->xprt_ctx || conn->xprt != &ssl_sock)
3684 return 0;
3685
3686 smp->data.str.str = (char *)SSL_get_servername(conn->xprt_ctx, TLSEXT_NAMETYPE_host_name);
Willy Tarreau3e394c92012-09-14 23:56:58 +02003687 if (!smp->data.str.str)
3688 return 0;
3689
Willy Tarreau7875d092012-09-10 08:20:03 +02003690 smp->data.str.len = strlen(smp->data.str.str);
3691 return 1;
3692#else
3693 return 0;
3694#endif
3695}
3696
David Sc1ad52e2014-04-08 18:48:47 -04003697static int
3698smp_fetch_ssl_fc_unique_id(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
3699 const struct arg *args, struct sample *smp, const char *kw)
3700{
3701#if OPENSSL_VERSION_NUMBER > 0x0090800fL
Emeric Brun645ae792014-04-30 14:21:06 +02003702 int back_conn = (kw[4] == 'b') ? 1 : 0;
David Sc1ad52e2014-04-08 18:48:47 -04003703 struct connection *conn;
3704 int finished_len;
David Sc1ad52e2014-04-08 18:48:47 -04003705 struct chunk *finished_trash;
David Sc1ad52e2014-04-08 18:48:47 -04003706
3707 smp->flags = 0;
3708
3709 if (!l4)
3710 return 0;
3711
Emeric Brun645ae792014-04-30 14:21:06 +02003712 conn = objt_conn(l4->si[back_conn].end);
David Sc1ad52e2014-04-08 18:48:47 -04003713 if (!conn || !conn->xprt_ctx || conn->xprt != &ssl_sock)
3714 return 0;
3715
3716 if (!(conn->flags & CO_FL_CONNECTED)) {
3717 smp->flags |= SMP_F_MAY_CHANGE;
3718 return 0;
3719 }
3720
3721 finished_trash = get_trash_chunk();
3722 if (!SSL_session_reused(conn->xprt_ctx))
3723 finished_len = SSL_get_peer_finished(conn->xprt_ctx, finished_trash->str, finished_trash->size);
3724 else
3725 finished_len = SSL_get_finished(conn->xprt_ctx, finished_trash->str, finished_trash->size);
3726
3727 if (!finished_len)
3728 return 0;
3729
Emeric Brunb73a9b02014-04-30 18:49:19 +02003730 finished_trash->len = finished_len;
3731 smp->data.str = *finished_trash;
3732 smp->type = SMP_T_BIN;
David Sc1ad52e2014-04-08 18:48:47 -04003733
3734 return 1;
3735#else
3736 return 0;
3737#endif
3738}
3739
Emeric Brun2525b6b2012-10-18 15:59:43 +02003740/* integer, returns the first verify error in CA chain of client certificate chain. */
Emeric Brunf282a812012-09-21 15:27:54 +02003741static int
Emeric Brun2525b6b2012-10-18 15:59:43 +02003742smp_fetch_ssl_c_ca_err(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
Willy Tarreauef38c392013-07-22 16:29:32 +02003743 const struct arg *args, struct sample *smp, const char *kw)
Emeric Brunf282a812012-09-21 15:27:54 +02003744{
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003745 struct connection *conn;
3746
3747 if (!l4)
Emeric Brunf282a812012-09-21 15:27:54 +02003748 return 0;
3749
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003750 conn = objt_conn(l4->si[0].end);
3751 if (!conn || conn->xprt != &ssl_sock)
3752 return 0;
3753
3754 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brunf282a812012-09-21 15:27:54 +02003755 smp->flags = SMP_F_MAY_CHANGE;
3756 return 0;
3757 }
3758
3759 smp->type = SMP_T_UINT;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003760 smp->data.uint = (unsigned int)SSL_SOCK_ST_TO_CA_ERROR(conn->xprt_st);
Emeric Brunf282a812012-09-21 15:27:54 +02003761 smp->flags = 0;
3762
3763 return 1;
3764}
3765
Emeric Brun2525b6b2012-10-18 15:59:43 +02003766/* integer, returns the depth of the first verify error in CA chain of client certificate chain. */
Emeric Brunf282a812012-09-21 15:27:54 +02003767static int
Emeric Brun2525b6b2012-10-18 15:59:43 +02003768smp_fetch_ssl_c_ca_err_depth(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
Willy Tarreauef38c392013-07-22 16:29:32 +02003769 const struct arg *args, struct sample *smp, const char *kw)
Emeric Brunf282a812012-09-21 15:27:54 +02003770{
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003771 struct connection *conn;
3772
3773 if (!l4)
3774 return 0;
3775
3776 conn = objt_conn(l4->si[0].end);
3777 if (!conn || conn->xprt != &ssl_sock)
Emeric Brunf282a812012-09-21 15:27:54 +02003778 return 0;
3779
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003780 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brunf282a812012-09-21 15:27:54 +02003781 smp->flags = SMP_F_MAY_CHANGE;
3782 return 0;
3783 }
3784
3785 smp->type = SMP_T_UINT;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003786 smp->data.uint = (unsigned int)SSL_SOCK_ST_TO_CAEDEPTH(conn->xprt_st);
Emeric Brunf282a812012-09-21 15:27:54 +02003787 smp->flags = 0;
3788
3789 return 1;
3790}
3791
Emeric Brun2525b6b2012-10-18 15:59:43 +02003792/* integer, returns the first verify error on client certificate */
Emeric Brunf282a812012-09-21 15:27:54 +02003793static int
Emeric Brun2525b6b2012-10-18 15:59:43 +02003794smp_fetch_ssl_c_err(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
Willy Tarreauef38c392013-07-22 16:29:32 +02003795 const struct arg *args, struct sample *smp, const char *kw)
Emeric Brunf282a812012-09-21 15:27:54 +02003796{
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003797 struct connection *conn;
3798
3799 if (!l4)
Emeric Brunf282a812012-09-21 15:27:54 +02003800 return 0;
3801
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003802 conn = objt_conn(l4->si[0].end);
3803 if (!conn || conn->xprt != &ssl_sock)
3804 return 0;
3805
3806 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brunf282a812012-09-21 15:27:54 +02003807 smp->flags = SMP_F_MAY_CHANGE;
3808 return 0;
3809 }
3810
3811 smp->type = SMP_T_UINT;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003812 smp->data.uint = (unsigned int)SSL_SOCK_ST_TO_CRTERROR(conn->xprt_st);
Emeric Brunf282a812012-09-21 15:27:54 +02003813 smp->flags = 0;
3814
3815 return 1;
3816}
3817
Emeric Brun2525b6b2012-10-18 15:59:43 +02003818/* integer, returns the verify result on client cert */
Emeric Brunbaf8ffb2012-09-21 15:27:20 +02003819static int
Emeric Brun2525b6b2012-10-18 15:59:43 +02003820smp_fetch_ssl_c_verify(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
Willy Tarreauef38c392013-07-22 16:29:32 +02003821 const struct arg *args, struct sample *smp, const char *kw)
Emeric Brunbaf8ffb2012-09-21 15:27:20 +02003822{
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003823 struct connection *conn;
3824
3825 if (!l4)
Emeric Brunbaf8ffb2012-09-21 15:27:20 +02003826 return 0;
3827
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003828 conn = objt_conn(l4->si[0].end);
3829 if (!conn || conn->xprt != &ssl_sock)
3830 return 0;
3831
3832 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brunbaf8ffb2012-09-21 15:27:20 +02003833 smp->flags = SMP_F_MAY_CHANGE;
3834 return 0;
3835 }
3836
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003837 if (!conn->xprt_ctx)
Emeric Brunbaf8ffb2012-09-21 15:27:20 +02003838 return 0;
3839
3840 smp->type = SMP_T_UINT;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003841 smp->data.uint = (unsigned int)SSL_get_verify_result(conn->xprt_ctx);
Emeric Brunbaf8ffb2012-09-21 15:27:20 +02003842 smp->flags = 0;
3843
3844 return 1;
3845}
3846
Emeric Brunfb510ea2012-10-05 12:00:26 +02003847/* parse the "ca-file" bind keyword */
3848static 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 +02003849{
3850 if (!*args[cur_arg + 1]) {
3851 if (err)
3852 memprintf(err, "'%s' : missing CAfile path", args[cur_arg]);
3853 return ERR_ALERT | ERR_FATAL;
3854 }
3855
Emeric Brunef42d922012-10-11 16:11:36 +02003856 if ((*args[cur_arg + 1] != '/') && global.ca_base)
3857 memprintf(&conf->ca_file, "%s/%s", global.ca_base, args[cur_arg + 1]);
3858 else
3859 memprintf(&conf->ca_file, "%s", args[cur_arg + 1]);
Emeric Brunc8e8d122012-10-02 18:42:10 +02003860
Emeric Brund94b3fe2012-09-20 18:23:56 +02003861 return 0;
3862}
3863
Willy Tarreau79eeafa2012-09-14 07:53:05 +02003864/* parse the "ciphers" bind keyword */
Willy Tarreau4348fad2012-09-20 16:48:07 +02003865static 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 +02003866{
3867 if (!*args[cur_arg + 1]) {
Willy Tarreaueb6cead2012-09-20 19:43:14 +02003868 memprintf(err, "'%s' : missing cipher suite", args[cur_arg]);
Willy Tarreau79eeafa2012-09-14 07:53:05 +02003869 return ERR_ALERT | ERR_FATAL;
3870 }
3871
Emeric Brun76d88952012-10-05 15:47:31 +02003872 free(conf->ciphers);
Willy Tarreau4348fad2012-09-20 16:48:07 +02003873 conf->ciphers = strdup(args[cur_arg + 1]);
Willy Tarreau79eeafa2012-09-14 07:53:05 +02003874 return 0;
3875}
3876
3877/* parse the "crt" bind keyword */
Willy Tarreau4348fad2012-09-20 16:48:07 +02003878static 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 +02003879{
Willy Tarreau38011032013-08-13 16:59:39 +02003880 char path[MAXPATHLEN];
Willy Tarreaub75d6922014-04-14 18:05:41 +02003881
Willy Tarreau79eeafa2012-09-14 07:53:05 +02003882 if (!*args[cur_arg + 1]) {
Willy Tarreaueb6cead2012-09-20 19:43:14 +02003883 memprintf(err, "'%s' : missing certificate location", args[cur_arg]);
Willy Tarreau79eeafa2012-09-14 07:53:05 +02003884 return ERR_ALERT | ERR_FATAL;
3885 }
3886
Emeric Brunc8e8d122012-10-02 18:42:10 +02003887 if ((*args[cur_arg + 1] != '/' ) && global.crt_base) {
Willy Tarreau38011032013-08-13 16:59:39 +02003888 if ((strlen(global.crt_base) + 1 + strlen(args[cur_arg + 1]) + 1) > MAXPATHLEN) {
Emeric Brunc8e8d122012-10-02 18:42:10 +02003889 memprintf(err, "'%s' : path too long", args[cur_arg]);
3890 return ERR_ALERT | ERR_FATAL;
3891 }
Willy Tarreaub75d6922014-04-14 18:05:41 +02003892 snprintf(path, sizeof(path), "%s/%s", global.crt_base, args[cur_arg + 1]);
Emeric Brunc8e8d122012-10-02 18:42:10 +02003893 if (ssl_sock_load_cert(path, conf, px, err) > 0)
3894 return ERR_ALERT | ERR_FATAL;
3895
3896 return 0;
3897 }
3898
Willy Tarreau4348fad2012-09-20 16:48:07 +02003899 if (ssl_sock_load_cert(args[cur_arg + 1], conf, px, err) > 0)
Willy Tarreau79eeafa2012-09-14 07:53:05 +02003900 return ERR_ALERT | ERR_FATAL;
Emeric Brund94b3fe2012-09-20 18:23:56 +02003901
3902 return 0;
3903}
3904
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01003905/* parse the "crt-list" bind keyword */
3906static int bind_parse_crt_list(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
3907{
3908 if (!*args[cur_arg + 1]) {
3909 memprintf(err, "'%s' : missing certificate location", args[cur_arg]);
3910 return ERR_ALERT | ERR_FATAL;
3911 }
3912
Willy Tarreauad1731d2013-04-02 17:35:58 +02003913 if (ssl_sock_load_cert_list_file(args[cur_arg + 1], conf, px, err) > 0) {
3914 memprintf(err, "'%s' : %s", args[cur_arg], *err);
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01003915 return ERR_ALERT | ERR_FATAL;
Willy Tarreauad1731d2013-04-02 17:35:58 +02003916 }
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01003917
3918 return 0;
3919}
3920
Emeric Brunfb510ea2012-10-05 12:00:26 +02003921/* parse the "crl-file" bind keyword */
3922static 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 +02003923{
Emeric Brun051cdab2012-10-02 19:25:50 +02003924#ifndef X509_V_FLAG_CRL_CHECK
3925 if (err)
3926 memprintf(err, "'%s' : library does not support CRL verify", args[cur_arg]);
3927 return ERR_ALERT | ERR_FATAL;
3928#else
Emeric Brund94b3fe2012-09-20 18:23:56 +02003929 if (!*args[cur_arg + 1]) {
3930 if (err)
3931 memprintf(err, "'%s' : missing CRLfile path", args[cur_arg]);
3932 return ERR_ALERT | ERR_FATAL;
3933 }
Emeric Brun2b58d042012-09-20 17:10:03 +02003934
Emeric Brunef42d922012-10-11 16:11:36 +02003935 if ((*args[cur_arg + 1] != '/') && global.ca_base)
3936 memprintf(&conf->crl_file, "%s/%s", global.ca_base, args[cur_arg + 1]);
3937 else
3938 memprintf(&conf->crl_file, "%s", args[cur_arg + 1]);
Emeric Brunc8e8d122012-10-02 18:42:10 +02003939
Emeric Brun2b58d042012-09-20 17:10:03 +02003940 return 0;
Emeric Brun051cdab2012-10-02 19:25:50 +02003941#endif
Emeric Brun2b58d042012-09-20 17:10:03 +02003942}
3943
3944/* parse the "ecdhe" bind keyword keywords */
3945static int bind_parse_ecdhe(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
3946{
3947#if OPENSSL_VERSION_NUMBER < 0x0090800fL
3948 if (err)
3949 memprintf(err, "'%s' : library does not support elliptic curve Diffie-Hellman (too old)", args[cur_arg]);
3950 return ERR_ALERT | ERR_FATAL;
3951#elif defined(OPENSSL_NO_ECDH)
3952 if (err)
3953 memprintf(err, "'%s' : library does not support elliptic curve Diffie-Hellman (disabled via OPENSSL_NO_ECDH)", args[cur_arg]);
3954 return ERR_ALERT | ERR_FATAL;
3955#else
3956 if (!*args[cur_arg + 1]) {
3957 if (err)
3958 memprintf(err, "'%s' : missing named curve", args[cur_arg]);
3959 return ERR_ALERT | ERR_FATAL;
3960 }
3961
3962 conf->ecdhe = strdup(args[cur_arg + 1]);
Willy Tarreau79eeafa2012-09-14 07:53:05 +02003963
3964 return 0;
Emeric Brun2b58d042012-09-20 17:10:03 +02003965#endif
Willy Tarreau79eeafa2012-09-14 07:53:05 +02003966}
3967
Emeric Brun81c00f02012-09-21 14:31:21 +02003968/* parse the "crt_ignerr" and "ca_ignerr" bind keywords */
3969static int bind_parse_ignore_err(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
3970{
3971 int code;
3972 char *p = args[cur_arg + 1];
3973 unsigned long long *ignerr = &conf->crt_ignerr;
3974
3975 if (!*p) {
3976 if (err)
3977 memprintf(err, "'%s' : missing error IDs list", args[cur_arg]);
3978 return ERR_ALERT | ERR_FATAL;
3979 }
3980
3981 if (strcmp(args[cur_arg], "ca-ignore-err") == 0)
3982 ignerr = &conf->ca_ignerr;
3983
3984 if (strcmp(p, "all") == 0) {
3985 *ignerr = ~0ULL;
3986 return 0;
3987 }
3988
3989 while (p) {
3990 code = atoi(p);
3991 if ((code <= 0) || (code > 63)) {
3992 if (err)
3993 memprintf(err, "'%s' : ID '%d' out of range (1..63) in error IDs list '%s'",
3994 args[cur_arg], code, args[cur_arg + 1]);
3995 return ERR_ALERT | ERR_FATAL;
3996 }
3997 *ignerr |= 1ULL << code;
3998 p = strchr(p, ',');
3999 if (p)
4000 p++;
4001 }
4002
Emeric Brun2cb7ae52012-10-05 14:14:21 +02004003 return 0;
4004}
4005
4006/* parse the "force-sslv3" bind keyword */
4007static int bind_parse_force_sslv3(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
4008{
4009 conf->ssl_options |= BC_SSL_O_USE_SSLV3;
4010 return 0;
4011}
4012
4013/* parse the "force-tlsv10" bind keyword */
4014static int bind_parse_force_tlsv10(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
4015{
4016 conf->ssl_options |= BC_SSL_O_USE_TLSV10;
Emeric Brun2d0c4822012-10-02 13:45:20 +02004017 return 0;
4018}
4019
Emeric Brun2cb7ae52012-10-05 14:14:21 +02004020/* parse the "force-tlsv11" bind keyword */
4021static int bind_parse_force_tlsv11(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
4022{
4023#if SSL_OP_NO_TLSv1_1
4024 conf->ssl_options |= BC_SSL_O_USE_TLSV11;
4025 return 0;
4026#else
4027 if (err)
4028 memprintf(err, "'%s' : library does not support protocol TLSv1.1", args[cur_arg]);
4029 return ERR_ALERT | ERR_FATAL;
4030#endif
4031}
4032
4033/* parse the "force-tlsv12" bind keyword */
4034static int bind_parse_force_tlsv12(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
4035{
4036#if SSL_OP_NO_TLSv1_2
4037 conf->ssl_options |= BC_SSL_O_USE_TLSV12;
4038 return 0;
4039#else
4040 if (err)
4041 memprintf(err, "'%s' : library does not support protocol TLSv1.2", args[cur_arg]);
4042 return ERR_ALERT | ERR_FATAL;
4043#endif
4044}
4045
4046
Emeric Brun2d0c4822012-10-02 13:45:20 +02004047/* parse the "no-tls-tickets" bind keyword */
4048static int bind_parse_no_tls_tickets(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
4049{
Emeric Brun89675492012-10-05 13:48:26 +02004050 conf->ssl_options |= BC_SSL_O_NO_TLS_TICKETS;
Emeric Brun81c00f02012-09-21 14:31:21 +02004051 return 0;
4052}
4053
Emeric Brun2d0c4822012-10-02 13:45:20 +02004054
Emeric Brun9b3009b2012-10-05 11:55:06 +02004055/* parse the "no-sslv3" bind keyword */
4056static 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 +02004057{
Emeric Brun89675492012-10-05 13:48:26 +02004058 conf->ssl_options |= BC_SSL_O_NO_SSLV3;
Willy Tarreau79eeafa2012-09-14 07:53:05 +02004059 return 0;
4060}
4061
Emeric Brun9b3009b2012-10-05 11:55:06 +02004062/* parse the "no-tlsv10" bind keyword */
4063static 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 +02004064{
Emeric Brun89675492012-10-05 13:48:26 +02004065 conf->ssl_options |= BC_SSL_O_NO_TLSV10;
Emeric Brunc0ff4922012-09-28 19:37:02 +02004066 return 0;
4067}
4068
Emeric Brun9b3009b2012-10-05 11:55:06 +02004069/* parse the "no-tlsv11" bind keyword */
4070static 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 +02004071{
Emeric Brun89675492012-10-05 13:48:26 +02004072 conf->ssl_options |= BC_SSL_O_NO_TLSV11;
Emeric Brunc0ff4922012-09-28 19:37:02 +02004073 return 0;
4074}
4075
Emeric Brun9b3009b2012-10-05 11:55:06 +02004076/* parse the "no-tlsv12" bind keyword */
4077static 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 +02004078{
Emeric Brun89675492012-10-05 13:48:26 +02004079 conf->ssl_options |= BC_SSL_O_NO_TLSV12;
Willy Tarreau79eeafa2012-09-14 07:53:05 +02004080 return 0;
4081}
4082
Willy Tarreau6c9a3d52012-10-18 18:57:14 +02004083/* parse the "npn" bind keyword */
4084static int bind_parse_npn(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
4085{
4086#ifdef OPENSSL_NPN_NEGOTIATED
4087 char *p1, *p2;
4088
4089 if (!*args[cur_arg + 1]) {
4090 memprintf(err, "'%s' : missing the comma-delimited NPN protocol suite", args[cur_arg]);
4091 return ERR_ALERT | ERR_FATAL;
4092 }
4093
4094 free(conf->npn_str);
4095
4096 /* the NPN string is built as a suite of (<len> <name>)* */
4097 conf->npn_len = strlen(args[cur_arg + 1]) + 1;
4098 conf->npn_str = calloc(1, conf->npn_len);
4099 memcpy(conf->npn_str + 1, args[cur_arg + 1], conf->npn_len);
4100
4101 /* replace commas with the name length */
4102 p1 = conf->npn_str;
4103 p2 = p1 + 1;
4104 while (1) {
4105 p2 = memchr(p1 + 1, ',', conf->npn_str + conf->npn_len - (p1 + 1));
4106 if (!p2)
4107 p2 = p1 + 1 + strlen(p1 + 1);
4108
4109 if (p2 - (p1 + 1) > 255) {
4110 *p2 = '\0';
4111 memprintf(err, "'%s' : NPN protocol name too long : '%s'", args[cur_arg], p1 + 1);
4112 return ERR_ALERT | ERR_FATAL;
4113 }
4114
4115 *p1 = p2 - (p1 + 1);
4116 p1 = p2;
4117
4118 if (!*p2)
4119 break;
4120
4121 *(p2++) = '\0';
4122 }
4123 return 0;
4124#else
4125 if (err)
4126 memprintf(err, "'%s' : library does not support TLS NPN extension", args[cur_arg]);
4127 return ERR_ALERT | ERR_FATAL;
4128#endif
4129}
4130
Willy Tarreauab861d32013-04-02 02:30:41 +02004131/* parse the "alpn" bind keyword */
4132static int bind_parse_alpn(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
4133{
Dirkjan Bussink48f1c4e2014-02-13 12:29:42 +01004134#ifdef TLSEXT_TYPE_application_layer_protocol_negotiation
Willy Tarreauab861d32013-04-02 02:30:41 +02004135 char *p1, *p2;
4136
4137 if (!*args[cur_arg + 1]) {
4138 memprintf(err, "'%s' : missing the comma-delimited ALPN protocol suite", args[cur_arg]);
4139 return ERR_ALERT | ERR_FATAL;
4140 }
4141
4142 free(conf->alpn_str);
4143
4144 /* the ALPN string is built as a suite of (<len> <name>)* */
4145 conf->alpn_len = strlen(args[cur_arg + 1]) + 1;
4146 conf->alpn_str = calloc(1, conf->alpn_len);
4147 memcpy(conf->alpn_str + 1, args[cur_arg + 1], conf->alpn_len);
4148
4149 /* replace commas with the name length */
4150 p1 = conf->alpn_str;
4151 p2 = p1 + 1;
4152 while (1) {
4153 p2 = memchr(p1 + 1, ',', conf->alpn_str + conf->alpn_len - (p1 + 1));
4154 if (!p2)
4155 p2 = p1 + 1 + strlen(p1 + 1);
4156
4157 if (p2 - (p1 + 1) > 255) {
4158 *p2 = '\0';
4159 memprintf(err, "'%s' : ALPN protocol name too long : '%s'", args[cur_arg], p1 + 1);
4160 return ERR_ALERT | ERR_FATAL;
4161 }
4162
4163 *p1 = p2 - (p1 + 1);
4164 p1 = p2;
4165
4166 if (!*p2)
4167 break;
4168
4169 *(p2++) = '\0';
4170 }
4171 return 0;
4172#else
4173 if (err)
4174 memprintf(err, "'%s' : library does not support TLS ALPN extension", args[cur_arg]);
4175 return ERR_ALERT | ERR_FATAL;
4176#endif
4177}
4178
Willy Tarreau79eeafa2012-09-14 07:53:05 +02004179/* parse the "ssl" bind keyword */
Willy Tarreau4348fad2012-09-20 16:48:07 +02004180static 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 +02004181{
Willy Tarreau81796be2012-09-22 19:11:47 +02004182 struct listener *l;
4183
Willy Tarreau4348fad2012-09-20 16:48:07 +02004184 conf->is_ssl = 1;
Emeric Brun76d88952012-10-05 15:47:31 +02004185
4186 if (global.listen_default_ciphers && !conf->ciphers)
4187 conf->ciphers = strdup(global.listen_default_ciphers);
Emeric Brun42a3e202014-10-30 15:56:50 +01004188 conf->ssl_options |= global.listen_default_ssloptions;
Emeric Brun76d88952012-10-05 15:47:31 +02004189
Willy Tarreau81796be2012-09-22 19:11:47 +02004190 list_for_each_entry(l, &conf->listeners, by_bind)
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02004191 l->xprt = &ssl_sock;
Willy Tarreau81796be2012-09-22 19:11:47 +02004192
Willy Tarreau79eeafa2012-09-14 07:53:05 +02004193 return 0;
4194}
4195
Emmanuel Hocdet65623372013-01-24 17:17:15 +01004196/* parse the "strict-sni" bind keyword */
4197static int bind_parse_strict_sni(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
4198{
4199 conf->strict_sni = 1;
4200 return 0;
4201}
4202
Emeric Brund94b3fe2012-09-20 18:23:56 +02004203/* parse the "verify" bind keyword */
4204static int bind_parse_verify(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
4205{
4206 if (!*args[cur_arg + 1]) {
4207 if (err)
4208 memprintf(err, "'%s' : missing verify method", args[cur_arg]);
4209 return ERR_ALERT | ERR_FATAL;
4210 }
4211
4212 if (strcmp(args[cur_arg + 1], "none") == 0)
Emeric Brun850efd52014-01-29 12:24:34 +01004213 conf->verify = SSL_SOCK_VERIFY_NONE;
Emeric Brund94b3fe2012-09-20 18:23:56 +02004214 else if (strcmp(args[cur_arg + 1], "optional") == 0)
Emeric Brun850efd52014-01-29 12:24:34 +01004215 conf->verify = SSL_SOCK_VERIFY_OPTIONAL;
Emeric Brund94b3fe2012-09-20 18:23:56 +02004216 else if (strcmp(args[cur_arg + 1], "required") == 0)
Emeric Brun850efd52014-01-29 12:24:34 +01004217 conf->verify = SSL_SOCK_VERIFY_REQUIRED;
Emeric Brund94b3fe2012-09-20 18:23:56 +02004218 else {
4219 if (err)
4220 memprintf(err, "'%s' : unknown verify method '%s', only 'none', 'optional', and 'required' are supported\n",
4221 args[cur_arg], args[cur_arg + 1]);
4222 return ERR_ALERT | ERR_FATAL;
4223 }
4224
4225 return 0;
4226}
4227
Willy Tarreau92faadf2012-10-10 23:04:25 +02004228/************** "server" keywords ****************/
4229
Emeric Brunef42d922012-10-11 16:11:36 +02004230/* parse the "ca-file" server keyword */
4231static int srv_parse_ca_file(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
4232{
4233 if (!*args[*cur_arg + 1]) {
4234 if (err)
4235 memprintf(err, "'%s' : missing CAfile path", args[*cur_arg]);
4236 return ERR_ALERT | ERR_FATAL;
4237 }
4238
4239 if ((*args[*cur_arg + 1] != '/') && global.ca_base)
4240 memprintf(&newsrv->ssl_ctx.ca_file, "%s/%s", global.ca_base, args[*cur_arg + 1]);
4241 else
4242 memprintf(&newsrv->ssl_ctx.ca_file, "%s", args[*cur_arg + 1]);
4243
4244 return 0;
4245}
4246
Willy Tarreau92faadf2012-10-10 23:04:25 +02004247/* parse the "check-ssl" server keyword */
4248static int srv_parse_check_ssl(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
4249{
4250 newsrv->check.use_ssl = 1;
4251 if (global.connect_default_ciphers && !newsrv->ssl_ctx.ciphers)
4252 newsrv->ssl_ctx.ciphers = strdup(global.connect_default_ciphers);
Emeric Brun42a3e202014-10-30 15:56:50 +01004253 newsrv->ssl_ctx.options |= global.connect_default_ssloptions;
Willy Tarreau92faadf2012-10-10 23:04:25 +02004254 return 0;
4255}
4256
4257/* parse the "ciphers" server keyword */
4258static int srv_parse_ciphers(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
4259{
4260 if (!*args[*cur_arg + 1]) {
4261 memprintf(err, "'%s' : missing cipher suite", args[*cur_arg]);
4262 return ERR_ALERT | ERR_FATAL;
4263 }
4264
4265 free(newsrv->ssl_ctx.ciphers);
4266 newsrv->ssl_ctx.ciphers = strdup(args[*cur_arg + 1]);
4267 return 0;
4268}
4269
Emeric Brunef42d922012-10-11 16:11:36 +02004270/* parse the "crl-file" server keyword */
4271static int srv_parse_crl_file(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
4272{
4273#ifndef X509_V_FLAG_CRL_CHECK
4274 if (err)
4275 memprintf(err, "'%s' : library does not support CRL verify", args[*cur_arg]);
4276 return ERR_ALERT | ERR_FATAL;
4277#else
4278 if (!*args[*cur_arg + 1]) {
4279 if (err)
4280 memprintf(err, "'%s' : missing CRLfile path", args[*cur_arg]);
4281 return ERR_ALERT | ERR_FATAL;
4282 }
4283
4284 if ((*args[*cur_arg + 1] != '/') && global.ca_base)
4285 memprintf(&newsrv->ssl_ctx.crl_file, "%s/%s", global.ca_base, args[*cur_arg + 1]);
4286 else
4287 memprintf(&newsrv->ssl_ctx.crl_file, "%s", args[*cur_arg + 1]);
4288
4289 return 0;
4290#endif
4291}
4292
Emeric Bruna7aa3092012-10-26 12:58:00 +02004293/* parse the "crt" server keyword */
4294static int srv_parse_crt(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
4295{
4296 if (!*args[*cur_arg + 1]) {
4297 if (err)
4298 memprintf(err, "'%s' : missing certificate file path", args[*cur_arg]);
4299 return ERR_ALERT | ERR_FATAL;
4300 }
4301
4302 if ((*args[*cur_arg + 1] != '/') && global.crt_base)
4303 memprintf(&newsrv->ssl_ctx.client_crt, "%s/%s", global.ca_base, args[*cur_arg + 1]);
4304 else
4305 memprintf(&newsrv->ssl_ctx.client_crt, "%s", args[*cur_arg + 1]);
4306
4307 return 0;
4308}
Emeric Brunef42d922012-10-11 16:11:36 +02004309
Willy Tarreau92faadf2012-10-10 23:04:25 +02004310/* parse the "force-sslv3" server keyword */
4311static int srv_parse_force_sslv3(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
4312{
4313 newsrv->ssl_ctx.options |= SRV_SSL_O_USE_SSLV3;
4314 return 0;
4315}
4316
4317/* parse the "force-tlsv10" server keyword */
4318static int srv_parse_force_tlsv10(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
4319{
4320 newsrv->ssl_ctx.options |= SRV_SSL_O_USE_TLSV10;
4321 return 0;
4322}
4323
4324/* parse the "force-tlsv11" server keyword */
4325static int srv_parse_force_tlsv11(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
4326{
4327#if SSL_OP_NO_TLSv1_1
4328 newsrv->ssl_ctx.options |= SRV_SSL_O_USE_TLSV11;
4329 return 0;
4330#else
4331 if (err)
4332 memprintf(err, "'%s' : library does not support protocol TLSv1.1", args[*cur_arg]);
4333 return ERR_ALERT | ERR_FATAL;
4334#endif
4335}
4336
4337/* parse the "force-tlsv12" server keyword */
4338static int srv_parse_force_tlsv12(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
4339{
4340#if SSL_OP_NO_TLSv1_2
4341 newsrv->ssl_ctx.options |= SRV_SSL_O_USE_TLSV12;
4342 return 0;
4343#else
4344 if (err)
4345 memprintf(err, "'%s' : library does not support protocol TLSv1.2", args[*cur_arg]);
4346 return ERR_ALERT | ERR_FATAL;
4347#endif
4348}
4349
4350/* parse the "no-sslv3" server keyword */
4351static int srv_parse_no_sslv3(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
4352{
4353 newsrv->ssl_ctx.options |= SRV_SSL_O_NO_SSLV3;
4354 return 0;
4355}
4356
4357/* parse the "no-tlsv10" server keyword */
4358static int srv_parse_no_tlsv10(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
4359{
4360 newsrv->ssl_ctx.options |= SRV_SSL_O_NO_TLSV10;
4361 return 0;
4362}
4363
4364/* parse the "no-tlsv11" server keyword */
4365static int srv_parse_no_tlsv11(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
4366{
4367 newsrv->ssl_ctx.options |= SRV_SSL_O_NO_TLSV11;
4368 return 0;
4369}
4370
4371/* parse the "no-tlsv12" server keyword */
4372static int srv_parse_no_tlsv12(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
4373{
4374 newsrv->ssl_ctx.options |= SRV_SSL_O_NO_TLSV12;
4375 return 0;
4376}
4377
Emeric Brunf9c5c472012-10-11 15:28:34 +02004378/* parse the "no-tls-tickets" server keyword */
4379static int srv_parse_no_tls_tickets(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
4380{
4381 newsrv->ssl_ctx.options |= SRV_SSL_O_NO_TLS_TICKETS;
4382 return 0;
4383}
David Safb76832014-05-08 23:42:08 -04004384/* parse the "send-proxy-v2-ssl" server keyword */
4385static int srv_parse_send_proxy_ssl(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
4386{
4387 newsrv->pp_opts |= SRV_PP_V2;
4388 newsrv->pp_opts |= SRV_PP_V2_SSL;
4389 return 0;
4390}
4391
4392/* parse the "send-proxy-v2-ssl-cn" server keyword */
4393static int srv_parse_send_proxy_cn(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
4394{
4395 newsrv->pp_opts |= SRV_PP_V2;
4396 newsrv->pp_opts |= SRV_PP_V2_SSL;
4397 newsrv->pp_opts |= SRV_PP_V2_SSL_CN;
4398 return 0;
4399}
Emeric Brunf9c5c472012-10-11 15:28:34 +02004400
Willy Tarreau92faadf2012-10-10 23:04:25 +02004401/* parse the "ssl" server keyword */
4402static int srv_parse_ssl(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
4403{
4404 newsrv->use_ssl = 1;
4405 if (global.connect_default_ciphers && !newsrv->ssl_ctx.ciphers)
4406 newsrv->ssl_ctx.ciphers = strdup(global.connect_default_ciphers);
4407 return 0;
4408}
4409
Emeric Brunef42d922012-10-11 16:11:36 +02004410/* parse the "verify" server keyword */
4411static int srv_parse_verify(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
4412{
4413 if (!*args[*cur_arg + 1]) {
4414 if (err)
4415 memprintf(err, "'%s' : missing verify method", args[*cur_arg]);
4416 return ERR_ALERT | ERR_FATAL;
4417 }
4418
4419 if (strcmp(args[*cur_arg + 1], "none") == 0)
Emeric Brun850efd52014-01-29 12:24:34 +01004420 newsrv->ssl_ctx.verify = SSL_SOCK_VERIFY_NONE;
Emeric Brunef42d922012-10-11 16:11:36 +02004421 else if (strcmp(args[*cur_arg + 1], "required") == 0)
Emeric Brun850efd52014-01-29 12:24:34 +01004422 newsrv->ssl_ctx.verify = SSL_SOCK_VERIFY_REQUIRED;
Emeric Brunef42d922012-10-11 16:11:36 +02004423 else {
4424 if (err)
4425 memprintf(err, "'%s' : unknown verify method '%s', only 'none' and 'required' are supported\n",
4426 args[*cur_arg], args[*cur_arg + 1]);
4427 return ERR_ALERT | ERR_FATAL;
4428 }
4429
Evan Broderbe554312013-06-27 00:05:25 -07004430 return 0;
4431}
4432
4433/* parse the "verifyhost" server keyword */
4434static int srv_parse_verifyhost(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
4435{
4436 if (!*args[*cur_arg + 1]) {
4437 if (err)
4438 memprintf(err, "'%s' : missing hostname to verify against", args[*cur_arg]);
4439 return ERR_ALERT | ERR_FATAL;
4440 }
4441
4442 newsrv->ssl_ctx.verify_host = strdup(args[*cur_arg + 1]);
4443
Emeric Brunef42d922012-10-11 16:11:36 +02004444 return 0;
4445}
4446
Emeric Brun42a3e202014-10-30 15:56:50 +01004447/* parse the "ssl-default-bind-options" keyword in global section */
4448static int ssl_parse_default_bind_options(char **args, int section_type, struct proxy *curpx,
4449 struct proxy *defpx, const char *file, int line,
4450 char **err) {
4451 int i = 1;
4452
4453 if (*(args[i]) == 0) {
4454 memprintf(err, "global statement '%s' expects an option as an argument.", args[0]);
4455 return -1;
4456 }
4457 while (*(args[i])) {
4458 if (!strcmp(args[i], "no-sslv3"))
4459 global.listen_default_ssloptions |= BC_SSL_O_NO_SSLV3;
4460 else if (!strcmp(args[i], "no-tlsv10"))
4461 global.listen_default_ssloptions |= BC_SSL_O_NO_TLSV10;
4462 else if (!strcmp(args[i], "no-tlsv11"))
4463 global.listen_default_ssloptions |= BC_SSL_O_NO_TLSV11;
4464 else if (!strcmp(args[i], "no-tlsv12"))
4465 global.listen_default_ssloptions |= BC_SSL_O_NO_TLSV12;
4466 else if (!strcmp(args[i], "force-sslv3"))
4467 global.listen_default_ssloptions |= BC_SSL_O_USE_SSLV3;
4468 else if (!strcmp(args[i], "force-tlsv10"))
4469 global.listen_default_ssloptions |= BC_SSL_O_USE_TLSV10;
4470 else if (!strcmp(args[i], "force-tlsv11")) {
4471#if SSL_OP_NO_TLSv1_1
4472 global.listen_default_ssloptions |= BC_SSL_O_USE_TLSV11;
4473#else
4474 memprintf(err, "'%s' '%s': library does not support protocol TLSv1.1", args[0], args[i]);
4475 return -1;
4476#endif
4477 }
4478 else if (!strcmp(args[i], "force-tlsv12")) {
4479#if SSL_OP_NO_TLSv1_2
4480 global.listen_default_ssloptions |= BC_SSL_O_USE_TLSV12;
4481#else
4482 memprintf(err, "'%s' '%s': library does not support protocol TLSv1.2", args[0], args[i]);
4483 return -1;
4484#endif
4485 }
4486 else if (!strcmp(args[i], "no-tls-tickets"))
4487 global.listen_default_ssloptions |= BC_SSL_O_NO_TLS_TICKETS;
4488 else {
4489 memprintf(err, "unknown option '%s' on global statement '%s'.", args[i], args[0]);
4490 return -1;
4491 }
4492 i++;
4493 }
4494 return 0;
4495}
4496
4497/* parse the "ssl-default-server-options" keyword in global section */
4498static int ssl_parse_default_server_options(char **args, int section_type, struct proxy *curpx,
4499 struct proxy *defpx, const char *file, int line,
4500 char **err) {
4501 int i = 1;
4502
4503 if (*(args[i]) == 0) {
4504 memprintf(err, "global statement '%s' expects an option as an argument.", args[0]);
4505 return -1;
4506 }
4507 while (*(args[i])) {
4508 if (!strcmp(args[i], "no-sslv3"))
4509 global.connect_default_ssloptions |= SRV_SSL_O_NO_SSLV3;
4510 else if (!strcmp(args[i], "no-tlsv10"))
4511 global.connect_default_ssloptions |= SRV_SSL_O_NO_TLSV10;
4512 else if (!strcmp(args[i], "no-tlsv11"))
4513 global.connect_default_ssloptions |= SRV_SSL_O_NO_TLSV11;
4514 else if (!strcmp(args[i], "no-tlsv12"))
4515 global.connect_default_ssloptions |= SRV_SSL_O_NO_TLSV12;
4516 else if (!strcmp(args[i], "force-sslv3"))
4517 global.connect_default_ssloptions |= SRV_SSL_O_USE_SSLV3;
4518 else if (!strcmp(args[i], "force-tlsv10"))
4519 global.connect_default_ssloptions |= SRV_SSL_O_USE_TLSV10;
4520 else if (!strcmp(args[i], "force-tlsv11")) {
4521#if SSL_OP_NO_TLSv1_1
4522 global.connect_default_ssloptions |= SRV_SSL_O_USE_TLSV11;
4523#else
4524 memprintf(err, "'%s' '%s': library does not support protocol TLSv1.1", args[0], args[i]);
4525 return -1;
4526#endif
4527 }
4528 else if (!strcmp(args[i], "force-tlsv12")) {
4529#if SSL_OP_NO_TLSv1_2
4530 global.connect_default_ssloptions |= SRV_SSL_O_USE_TLSV12;
4531#else
4532 memprintf(err, "'%s' '%s': library does not support protocol TLSv1.2", args[0], args[i]);
4533 return -1;
4534#endif
4535 }
4536 else if (!strcmp(args[i], "no-tls-tickets"))
4537 global.connect_default_ssloptions |= SRV_SSL_O_NO_TLS_TICKETS;
4538 else {
4539 memprintf(err, "unknown option '%s' on global statement '%s'.", args[i], args[0]);
4540 return -1;
4541 }
4542 i++;
4543 }
4544 return 0;
4545}
4546
Willy Tarreau7875d092012-09-10 08:20:03 +02004547/* Note: must not be declared <const> as its list will be overwritten.
4548 * Please take care of keeping this list alphabetically sorted.
4549 */
Willy Tarreaudc13c112013-06-21 23:16:39 +02004550static struct sample_fetch_kw_list sample_fetch_keywords = {ILH, {
Emeric Brun645ae792014-04-30 14:21:06 +02004551 { "ssl_bc", smp_fetch_ssl_fc, 0, NULL, SMP_T_BOOL, SMP_USE_L5SRV },
4552 { "ssl_bc_alg_keysize", smp_fetch_ssl_fc_alg_keysize, 0, NULL, SMP_T_UINT, SMP_USE_L5SRV },
4553 { "ssl_bc_cipher", smp_fetch_ssl_fc_cipher, 0, NULL, SMP_T_STR, SMP_USE_L5SRV },
4554 { "ssl_bc_protocol", smp_fetch_ssl_fc_protocol, 0, NULL, SMP_T_STR, SMP_USE_L5SRV },
Emeric Brunb73a9b02014-04-30 18:49:19 +02004555 { "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 +02004556 { "ssl_bc_use_keysize", smp_fetch_ssl_fc_use_keysize, 0, NULL, SMP_T_UINT, SMP_USE_L5SRV },
4557 { "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 +01004558 { "ssl_c_ca_err", smp_fetch_ssl_c_ca_err, 0, NULL, SMP_T_UINT, SMP_USE_L5CLI },
4559 { "ssl_c_ca_err_depth", smp_fetch_ssl_c_ca_err_depth, 0, NULL, SMP_T_UINT, SMP_USE_L5CLI },
Emeric Brunb3cc4252014-10-29 19:03:26 +01004560 { "ssl_c_der", smp_fetch_ssl_x_der, 0, NULL, SMP_T_BIN, SMP_USE_L5CLI },
Willy Tarreau80aca902013-01-07 15:42:20 +01004561 { "ssl_c_err", smp_fetch_ssl_c_err, 0, NULL, SMP_T_UINT, SMP_USE_L5CLI },
Emeric Brunba841a12014-04-30 17:05:08 +02004562 { "ssl_c_i_dn", smp_fetch_ssl_x_i_dn, ARG2(0,STR,SINT), NULL, SMP_T_STR, SMP_USE_L5CLI },
4563 { "ssl_c_key_alg", smp_fetch_ssl_x_key_alg, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
4564 { "ssl_c_notafter", smp_fetch_ssl_x_notafter, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
4565 { "ssl_c_notbefore", smp_fetch_ssl_x_notbefore, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
4566 { "ssl_c_sig_alg", smp_fetch_ssl_x_sig_alg, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
4567 { "ssl_c_s_dn", smp_fetch_ssl_x_s_dn, ARG2(0,STR,SINT), NULL, SMP_T_STR, SMP_USE_L5CLI },
4568 { "ssl_c_serial", smp_fetch_ssl_x_serial, 0, NULL, SMP_T_BIN, SMP_USE_L5CLI },
4569 { "ssl_c_sha1", smp_fetch_ssl_x_sha1, 0, NULL, SMP_T_BIN, SMP_USE_L5CLI },
Willy Tarreau80aca902013-01-07 15:42:20 +01004570 { "ssl_c_used", smp_fetch_ssl_c_used, 0, NULL, SMP_T_BOOL, SMP_USE_L5CLI },
4571 { "ssl_c_verify", smp_fetch_ssl_c_verify, 0, NULL, SMP_T_UINT, SMP_USE_L5CLI },
Emeric Brunba841a12014-04-30 17:05:08 +02004572 { "ssl_c_version", smp_fetch_ssl_x_version, 0, NULL, SMP_T_UINT, SMP_USE_L5CLI },
Emeric Brunb3cc4252014-10-29 19:03:26 +01004573 { "ssl_f_der", smp_fetch_ssl_x_der, 0, NULL, SMP_T_BIN, SMP_USE_L5CLI },
Emeric Brunba841a12014-04-30 17:05:08 +02004574 { "ssl_f_i_dn", smp_fetch_ssl_x_i_dn, ARG2(0,STR,SINT), NULL, SMP_T_STR, SMP_USE_L5CLI },
4575 { "ssl_f_key_alg", smp_fetch_ssl_x_key_alg, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
4576 { "ssl_f_notafter", smp_fetch_ssl_x_notafter, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
4577 { "ssl_f_notbefore", smp_fetch_ssl_x_notbefore, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
4578 { "ssl_f_sig_alg", smp_fetch_ssl_x_sig_alg, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
4579 { "ssl_f_s_dn", smp_fetch_ssl_x_s_dn, ARG2(0,STR,SINT), NULL, SMP_T_STR, SMP_USE_L5CLI },
4580 { "ssl_f_serial", smp_fetch_ssl_x_serial, 0, NULL, SMP_T_BIN, SMP_USE_L5CLI },
Emeric Brun55f4fa82014-04-30 17:11:25 +02004581 { "ssl_f_sha1", smp_fetch_ssl_x_sha1, 0, NULL, SMP_T_BIN, SMP_USE_L5CLI },
Emeric Brunba841a12014-04-30 17:05:08 +02004582 { "ssl_f_version", smp_fetch_ssl_x_version, 0, NULL, SMP_T_UINT, SMP_USE_L5CLI },
Willy Tarreau80aca902013-01-07 15:42:20 +01004583 { "ssl_fc", smp_fetch_ssl_fc, 0, NULL, SMP_T_BOOL, SMP_USE_L5CLI },
4584 { "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 +01004585 { "ssl_fc_cipher", smp_fetch_ssl_fc_cipher, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
Willy Tarreau80aca902013-01-07 15:42:20 +01004586 { "ssl_fc_has_crt", smp_fetch_ssl_fc_has_crt, 0, NULL, SMP_T_BOOL, SMP_USE_L5CLI },
4587 { "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 +02004588#ifdef OPENSSL_NPN_NEGOTIATED
Thierry FOURNIER7654c9f2013-12-17 00:20:33 +01004589 { "ssl_fc_npn", smp_fetch_ssl_fc_npn, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
Willy Tarreaua33c6542012-10-15 13:19:06 +02004590#endif
Dirkjan Bussink48f1c4e2014-02-13 12:29:42 +01004591#ifdef TLSEXT_TYPE_application_layer_protocol_negotiation
Thierry FOURNIER7654c9f2013-12-17 00:20:33 +01004592 { "ssl_fc_alpn", smp_fetch_ssl_fc_alpn, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
Willy Tarreauab861d32013-04-02 02:30:41 +02004593#endif
Thierry FOURNIER7654c9f2013-12-17 00:20:33 +01004594 { "ssl_fc_protocol", smp_fetch_ssl_fc_protocol, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
Emeric Brunb73a9b02014-04-30 18:49:19 +02004595 { "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 +01004596 { "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 +01004597 { "ssl_fc_session_id", smp_fetch_ssl_fc_session_id, 0, NULL, SMP_T_BIN, SMP_USE_L5CLI },
4598 { "ssl_fc_sni", smp_fetch_ssl_fc_sni, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
Willy Tarreau7875d092012-09-10 08:20:03 +02004599 { NULL, NULL, 0, 0, 0 },
4600}};
4601
4602/* Note: must not be declared <const> as its list will be overwritten.
4603 * Please take care of keeping this list alphabetically sorted.
4604 */
Willy Tarreaudc13c112013-06-21 23:16:39 +02004605static struct acl_kw_list acl_kws = {ILH, {
Thierry FOURNIERc5a4e982014-03-05 16:07:08 +01004606 { "ssl_fc_sni_end", "ssl_fc_sni", PAT_MATCH_END },
4607 { "ssl_fc_sni_reg", "ssl_fc_sni", PAT_MATCH_REG },
Willy Tarreau8ed669b2013-01-11 15:49:37 +01004608 { /* END */ },
Willy Tarreau7875d092012-09-10 08:20:03 +02004609}};
4610
Willy Tarreau79eeafa2012-09-14 07:53:05 +02004611/* Note: must not be declared <const> as its list will be overwritten.
4612 * Please take care of keeping this list alphabetically sorted, doing so helps
4613 * all code contributors.
4614 * Optional keywords are also declared with a NULL ->parse() function so that
4615 * the config parser can report an appropriate error when a known keyword was
4616 * not enabled.
4617 */
Willy Tarreau51fb7652012-09-18 18:24:39 +02004618static struct bind_kw_list bind_kws = { "SSL", { }, {
Willy Tarreauab861d32013-04-02 02:30:41 +02004619 { "alpn", bind_parse_alpn, 1 }, /* set ALPN supported protocols */
Emeric Brunfb510ea2012-10-05 12:00:26 +02004620 { "ca-file", bind_parse_ca_file, 1 }, /* set CAfile to process verify on client cert */
Emeric Brun2d0c4822012-10-02 13:45:20 +02004621 { "ca-ignore-err", bind_parse_ignore_err, 1 }, /* set error IDs to ignore on verify depth > 0 */
4622 { "ciphers", bind_parse_ciphers, 1 }, /* set SSL cipher suite */
Emeric Brunfb510ea2012-10-05 12:00:26 +02004623 { "crl-file", bind_parse_crl_file, 1 }, /* set certificat revocation list file use on client cert verify */
Emeric Brun2d0c4822012-10-02 13:45:20 +02004624 { "crt", bind_parse_crt, 1 }, /* load SSL certificates from this location */
4625 { "crt-ignore-err", bind_parse_ignore_err, 1 }, /* set error IDs to ingore on verify depth == 0 */
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01004626 { "crt-list", bind_parse_crt_list, 1 }, /* load a list of crt from this location */
Emeric Brun2d0c4822012-10-02 13:45:20 +02004627 { "ecdhe", bind_parse_ecdhe, 1 }, /* defines named curve for elliptic curve Diffie-Hellman */
Emeric Brun2cb7ae52012-10-05 14:14:21 +02004628 { "force-sslv3", bind_parse_force_sslv3, 0 }, /* force SSLv3 */
4629 { "force-tlsv10", bind_parse_force_tlsv10, 0 }, /* force TLSv10 */
4630 { "force-tlsv11", bind_parse_force_tlsv11, 0 }, /* force TLSv11 */
4631 { "force-tlsv12", bind_parse_force_tlsv12, 0 }, /* force TLSv12 */
Emeric Brun9b3009b2012-10-05 11:55:06 +02004632 { "no-sslv3", bind_parse_no_sslv3, 0 }, /* disable SSLv3 */
4633 { "no-tlsv10", bind_parse_no_tlsv10, 0 }, /* disable TLSv10 */
4634 { "no-tlsv11", bind_parse_no_tlsv11, 0 }, /* disable TLSv11 */
4635 { "no-tlsv12", bind_parse_no_tlsv12, 0 }, /* disable TLSv12 */
Emeric Brun2d0c4822012-10-02 13:45:20 +02004636 { "no-tls-tickets", bind_parse_no_tls_tickets, 0 }, /* disable session resumption tickets */
Emeric Brun2d0c4822012-10-02 13:45:20 +02004637 { "ssl", bind_parse_ssl, 0 }, /* enable SSL processing */
Emmanuel Hocdet65623372013-01-24 17:17:15 +01004638 { "strict-sni", bind_parse_strict_sni, 0 }, /* refuse negotiation if sni doesn't match a certificate */
Emeric Brun2d0c4822012-10-02 13:45:20 +02004639 { "verify", bind_parse_verify, 1 }, /* set SSL verify method */
Willy Tarreau6c9a3d52012-10-18 18:57:14 +02004640 { "npn", bind_parse_npn, 1 }, /* set NPN supported protocols */
Willy Tarreau79eeafa2012-09-14 07:53:05 +02004641 { NULL, NULL, 0 },
4642}};
Emeric Brun46591952012-05-18 15:47:34 +02004643
Willy Tarreau92faadf2012-10-10 23:04:25 +02004644/* Note: must not be declared <const> as its list will be overwritten.
4645 * Please take care of keeping this list alphabetically sorted, doing so helps
4646 * all code contributors.
4647 * Optional keywords are also declared with a NULL ->parse() function so that
4648 * the config parser can report an appropriate error when a known keyword was
4649 * not enabled.
4650 */
4651static struct srv_kw_list srv_kws = { "SSL", { }, {
Emeric Brunef42d922012-10-11 16:11:36 +02004652 { "ca-file", srv_parse_ca_file, 1, 0 }, /* set CAfile to process verify server cert */
Emeric Brunecc91fe2012-10-11 15:05:10 +02004653 { "check-ssl", srv_parse_check_ssl, 0, 0 }, /* enable SSL for health checks */
4654 { "ciphers", srv_parse_ciphers, 1, 0 }, /* select the cipher suite */
Emeric Brunef42d922012-10-11 16:11:36 +02004655 { "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 +02004656 { "crt", srv_parse_crt, 1, 0 }, /* set client certificate */
Emeric Brunecc91fe2012-10-11 15:05:10 +02004657 { "force-sslv3", srv_parse_force_sslv3, 0, 0 }, /* force SSLv3 */
4658 { "force-tlsv10", srv_parse_force_tlsv10, 0, 0 }, /* force TLSv10 */
4659 { "force-tlsv11", srv_parse_force_tlsv11, 0, 0 }, /* force TLSv11 */
4660 { "force-tlsv12", srv_parse_force_tlsv12, 0, 0 }, /* force TLSv12 */
4661 { "no-sslv3", srv_parse_no_sslv3, 0, 0 }, /* disable SSLv3 */
4662 { "no-tlsv10", srv_parse_no_tlsv10, 0, 0 }, /* disable TLSv10 */
4663 { "no-tlsv11", srv_parse_no_tlsv11, 0, 0 }, /* disable TLSv11 */
4664 { "no-tlsv12", srv_parse_no_tlsv12, 0, 0 }, /* disable TLSv12 */
Emeric Brunf9c5c472012-10-11 15:28:34 +02004665 { "no-tls-tickets", srv_parse_no_tls_tickets, 0, 0 }, /* disable session resumption tickets */
David Safb76832014-05-08 23:42:08 -04004666 { "send-proxy-v2-ssl", srv_parse_send_proxy_ssl, 0, 0 }, /* send PROXY protocol header v2 with SSL info */
4667 { "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 +02004668 { "ssl", srv_parse_ssl, 0, 0 }, /* enable SSL processing */
Emeric Brunef42d922012-10-11 16:11:36 +02004669 { "verify", srv_parse_verify, 1, 0 }, /* set SSL verify method */
Evan Broderbe554312013-06-27 00:05:25 -07004670 { "verifyhost", srv_parse_verifyhost, 1, 0 }, /* require that SSL cert verifies for hostname */
Willy Tarreau92faadf2012-10-10 23:04:25 +02004671 { NULL, NULL, 0, 0 },
4672}};
4673
Emeric Brun42a3e202014-10-30 15:56:50 +01004674static struct cfg_kw_list cfg_kws = {ILH, {
4675 { CFG_GLOBAL, "ssl-default-bind-options", ssl_parse_default_bind_options },
4676 { CFG_GLOBAL, "ssl-default-server-options", ssl_parse_default_server_options },
4677 { 0, NULL, NULL },
4678}};
4679
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02004680/* transport-layer operations for SSL sockets */
4681struct xprt_ops ssl_sock = {
Emeric Brun46591952012-05-18 15:47:34 +02004682 .snd_buf = ssl_sock_from_buf,
4683 .rcv_buf = ssl_sock_to_buf,
4684 .rcv_pipe = NULL,
4685 .snd_pipe = NULL,
4686 .shutr = NULL,
4687 .shutw = ssl_sock_shutw,
4688 .close = ssl_sock_close,
4689 .init = ssl_sock_init,
4690};
4691
4692__attribute__((constructor))
Willy Tarreau92faadf2012-10-10 23:04:25 +02004693static void __ssl_sock_init(void)
4694{
Emeric Brun46591952012-05-18 15:47:34 +02004695 STACK_OF(SSL_COMP)* cm;
4696
Willy Tarreau610f04b2014-02-13 11:36:41 +01004697#ifdef LISTEN_DEFAULT_CIPHERS
4698 global.listen_default_ciphers = LISTEN_DEFAULT_CIPHERS;
4699#endif
4700#ifdef CONNECT_DEFAULT_CIPHERS
4701 global.connect_default_ciphers = CONNECT_DEFAULT_CIPHERS;
4702#endif
4703 if (global.listen_default_ciphers)
4704 global.listen_default_ciphers = strdup(global.listen_default_ciphers);
4705 if (global.connect_default_ciphers)
4706 global.connect_default_ciphers = strdup(global.connect_default_ciphers);
Emeric Brun42a3e202014-10-30 15:56:50 +01004707 global.listen_default_ssloptions = BC_SSL_O_NONE;
4708 global.connect_default_ssloptions = SRV_SSL_O_NONE;
Willy Tarreau610f04b2014-02-13 11:36:41 +01004709
Emeric Brun46591952012-05-18 15:47:34 +02004710 SSL_library_init();
4711 cm = SSL_COMP_get_compression_methods();
4712 sk_SSL_COMP_zero(cm);
Willy Tarreau7875d092012-09-10 08:20:03 +02004713 sample_register_fetches(&sample_fetch_keywords);
4714 acl_register_keywords(&acl_kws);
Willy Tarreau79eeafa2012-09-14 07:53:05 +02004715 bind_register_keywords(&bind_kws);
Willy Tarreau92faadf2012-10-10 23:04:25 +02004716 srv_register_keywords(&srv_kws);
Emeric Brun42a3e202014-10-30 15:56:50 +01004717 cfg_register_keywords(&cfg_kws);
Emeric Brun46591952012-05-18 15:47:34 +02004718}
4719
4720/*
4721 * Local variables:
4722 * c-indent-level: 8
4723 * c-basic-offset: 8
4724 * End:
4725 */