blob: b73d6f9a9d471e1b0d1eb2b816c2a9d0f83e2b6b [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{
1311 struct dirent *de;
1312 DIR *dir;
1313 struct stat buf;
Willy Tarreauee2663b2012-12-06 11:36:59 +01001314 char *end;
1315 char fp[MAXPATHLEN+1];
Emeric Brunfc0421f2012-09-07 17:30:07 +02001316 int cfgerr = 0;
1317
1318 if (!(dir = opendir(path)))
Emeric Brun50bcecc2013-04-22 13:05:23 +02001319 return ssl_sock_load_cert_file(path, bind_conf, curproxy, NULL, 0, err);
Emeric Brunfc0421f2012-09-07 17:30:07 +02001320
1321 /* strip trailing slashes, including first one */
1322 for (end = path + strlen(path) - 1; end >= path && *end == '/'; end--)
1323 *end = 0;
1324
Emeric Brunfc0421f2012-09-07 17:30:07 +02001325 while ((de = readdir(dir))) {
Emeric Brun2aab7222014-06-18 18:15:09 +02001326 end = strrchr(de->d_name, '.');
1327 if (end && (!strcmp(end, ".issuer") || !strcmp(end, ".ocsp")))
1328 continue;
1329
Willy Tarreauee2663b2012-12-06 11:36:59 +01001330 snprintf(fp, sizeof(fp), "%s/%s", path, de->d_name);
Emeric Brunfc0421f2012-09-07 17:30:07 +02001331 if (stat(fp, &buf) != 0) {
Willy Tarreaueb6cead2012-09-20 19:43:14 +02001332 memprintf(err, "%sunable to stat SSL certificate from file '%s' : %s.\n",
1333 err && *err ? *err : "", fp, strerror(errno));
Emeric Brunfc0421f2012-09-07 17:30:07 +02001334 cfgerr++;
1335 continue;
1336 }
1337 if (!S_ISREG(buf.st_mode))
1338 continue;
Emeric Brun50bcecc2013-04-22 13:05:23 +02001339 cfgerr += ssl_sock_load_cert_file(fp, bind_conf, curproxy, NULL, 0, err);
Emeric Brunfc0421f2012-09-07 17:30:07 +02001340 }
Emeric Brunfc0421f2012-09-07 17:30:07 +02001341 closedir(dir);
1342 return cfgerr;
1343}
1344
Thierry Fournier383085f2013-01-24 14:15:43 +01001345/* Make sure openssl opens /dev/urandom before the chroot. The work is only
1346 * done once. Zero is returned if the operation fails. No error is returned
1347 * if the random is said as not implemented, because we expect that openssl
1348 * will use another method once needed.
1349 */
1350static int ssl_initialize_random()
1351{
1352 unsigned char random;
1353 static int random_initialized = 0;
1354
1355 if (!random_initialized && RAND_bytes(&random, 1) != 0)
1356 random_initialized = 1;
1357
1358 return random_initialized;
1359}
1360
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01001361int ssl_sock_load_cert_list_file(char *file, struct bind_conf *bind_conf, struct proxy *curproxy, char **err)
1362{
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +02001363 char thisline[LINESIZE];
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01001364 FILE *f;
1365 int linenum = 0;
1366 int cfgerr = 0;
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01001367
Willy Tarreauad1731d2013-04-02 17:35:58 +02001368 if ((f = fopen(file, "r")) == NULL) {
1369 memprintf(err, "cannot open file '%s' : %s", file, strerror(errno));
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01001370 return 1;
Willy Tarreauad1731d2013-04-02 17:35:58 +02001371 }
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01001372
1373 while (fgets(thisline, sizeof(thisline), f) != NULL) {
1374 int arg;
Emeric Brun50bcecc2013-04-22 13:05:23 +02001375 int newarg;
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01001376 char *end;
1377 char *args[MAX_LINE_ARGS + 1];
1378 char *line = thisline;
1379
1380 linenum++;
1381 end = line + strlen(line);
1382 if (end-line == sizeof(thisline)-1 && *(end-1) != '\n') {
1383 /* Check if we reached the limit and the last char is not \n.
1384 * Watch out for the last line without the terminating '\n'!
1385 */
Willy Tarreauad1731d2013-04-02 17:35:58 +02001386 memprintf(err, "line %d too long in file '%s', limit is %d characters",
1387 linenum, file, (int)sizeof(thisline)-1);
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01001388 cfgerr = 1;
Willy Tarreauad1731d2013-04-02 17:35:58 +02001389 break;
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01001390 }
1391
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01001392 arg = 0;
Emeric Brun50bcecc2013-04-22 13:05:23 +02001393 newarg = 1;
1394 while (*line) {
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01001395 if (*line == '#' || *line == '\n' || *line == '\r') {
1396 /* end of string, end of loop */
1397 *line = 0;
1398 break;
1399 }
1400 else if (isspace(*line)) {
Emeric Brun50bcecc2013-04-22 13:05:23 +02001401 newarg = 1;
1402 *line = 0;
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01001403 }
Emeric Brun50bcecc2013-04-22 13:05:23 +02001404 else if (newarg) {
1405 if (arg == MAX_LINE_ARGS) {
1406 memprintf(err, "too many args on line %d in file '%s'.",
1407 linenum, file);
1408 cfgerr = 1;
1409 break;
1410 }
1411 newarg = 0;
1412 args[arg++] = line;
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01001413 }
Emeric Brun50bcecc2013-04-22 13:05:23 +02001414 line++;
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01001415 }
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +02001416 if (cfgerr)
1417 break;
Willy Tarreauad1731d2013-04-02 17:35:58 +02001418
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01001419 /* empty line */
Emeric Brun50bcecc2013-04-22 13:05:23 +02001420 if (!arg)
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01001421 continue;
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01001422
Emeric Brun50bcecc2013-04-22 13:05:23 +02001423 cfgerr = ssl_sock_load_cert_file(args[0], bind_conf, curproxy, &args[1], arg-1, err);
Willy Tarreauad1731d2013-04-02 17:35:58 +02001424 if (cfgerr) {
1425 memprintf(err, "error processing line %d in file '%s' : %s", linenum, file, *err);
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01001426 break;
Willy Tarreauad1731d2013-04-02 17:35:58 +02001427 }
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01001428 }
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01001429 fclose(f);
1430 return cfgerr;
1431}
1432
Emeric Brunfc0421f2012-09-07 17:30:07 +02001433#ifndef SSL_OP_CIPHER_SERVER_PREFERENCE /* needs OpenSSL >= 0.9.7 */
1434#define SSL_OP_CIPHER_SERVER_PREFERENCE 0
1435#endif
1436
1437#ifndef SSL_OP_NO_SESSION_RESUMPTION_ON_RENEGOTIATION /* needs OpenSSL >= 0.9.7 */
1438#define SSL_OP_NO_SESSION_RESUMPTION_ON_RENEGOTIATION 0
Willy Tarreau7d588ee2012-11-26 18:47:31 +01001439#define SSL_renegotiate_pending(arg) 0
Emeric Brunfc0421f2012-09-07 17:30:07 +02001440#endif
Emeric Brun2b58d042012-09-20 17:10:03 +02001441#ifndef SSL_OP_SINGLE_ECDH_USE /* needs OpenSSL >= 0.9.8 */
1442#define SSL_OP_SINGLE_ECDH_USE 0
1443#endif
Emeric Brun2d0c4822012-10-02 13:45:20 +02001444#ifndef SSL_OP_NO_TICKET /* needs OpenSSL >= 0.9.8 */
1445#define SSL_OP_NO_TICKET 0
1446#endif
Emeric Brunfc0421f2012-09-07 17:30:07 +02001447#ifndef SSL_OP_NO_COMPRESSION /* needs OpenSSL >= 0.9.9 */
1448#define SSL_OP_NO_COMPRESSION 0
1449#endif
Emeric Brunc0ff4922012-09-28 19:37:02 +02001450#ifndef SSL_OP_NO_TLSv1_1 /* needs OpenSSL >= 1.0.1 */
1451#define SSL_OP_NO_TLSv1_1 0
1452#endif
1453#ifndef SSL_OP_NO_TLSv1_2 /* needs OpenSSL >= 1.0.1 */
1454#define SSL_OP_NO_TLSv1_2 0
1455#endif
Emeric Bruna4bcd9a2012-09-20 16:19:02 +02001456#ifndef SSL_OP_SINGLE_DH_USE /* needs OpenSSL >= 0.9.6 */
1457#define SSL_OP_SINGLE_DH_USE 0
1458#endif
Emeric Brun2b58d042012-09-20 17:10:03 +02001459#ifndef SSL_OP_SINGLE_ECDH_USE /* needs OpenSSL >= 1.0.0 */
1460#define SSL_OP_SINGLE_ECDH_USE 0
1461#endif
Emeric Brunfc0421f2012-09-07 17:30:07 +02001462#ifndef SSL_MODE_RELEASE_BUFFERS /* needs OpenSSL >= 1.0.0 */
1463#define SSL_MODE_RELEASE_BUFFERS 0
1464#endif
Remi Gacognef46cd6e2014-06-12 14:58:40 +02001465
Willy Tarreau2a65ff02012-09-13 17:54:29 +02001466int ssl_sock_prepare_ctx(struct bind_conf *bind_conf, SSL_CTX *ctx, struct proxy *curproxy)
Emeric Brunfc0421f2012-09-07 17:30:07 +02001467{
1468 int cfgerr = 0;
Emeric Brun850efd52014-01-29 12:24:34 +01001469 int verify = SSL_VERIFY_NONE;
Remi Gacogneaf5c3da2014-05-19 10:29:58 +02001470 long ssloptions =
Emeric Brunfc0421f2012-09-07 17:30:07 +02001471 SSL_OP_ALL | /* all known workarounds for bugs */
1472 SSL_OP_NO_SSLv2 |
1473 SSL_OP_NO_COMPRESSION |
Emeric Bruna4bcd9a2012-09-20 16:19:02 +02001474 SSL_OP_SINGLE_DH_USE |
Emeric Brun2b58d042012-09-20 17:10:03 +02001475 SSL_OP_SINGLE_ECDH_USE |
Emeric Brun3c4bc6e2012-10-04 18:44:19 +02001476 SSL_OP_NO_SESSION_RESUMPTION_ON_RENEGOTIATION |
1477 SSL_OP_CIPHER_SERVER_PREFERENCE;
Remi Gacogneaf5c3da2014-05-19 10:29:58 +02001478 long sslmode =
Emeric Brunfc0421f2012-09-07 17:30:07 +02001479 SSL_MODE_ENABLE_PARTIAL_WRITE |
1480 SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER |
1481 SSL_MODE_RELEASE_BUFFERS;
Remi Gacognef46cd6e2014-06-12 14:58:40 +02001482 STACK_OF(SSL_CIPHER) * ciphers = NULL;
1483 SSL_CIPHER * cipher = NULL;
Remi Gacognec1eab8c2014-06-12 18:20:11 +02001484 char cipher_description[128];
1485 /* The description of ciphers using an Ephemeral Diffie Hellman key exchange
1486 contains " Kx=DH " or " Kx=DH(". Beware of " Kx=DH/",
1487 which is not ephemeral DH. */
1488 const char dhe_description[] = " Kx=DH ";
1489 const char dhe_export_description[] = " Kx=DH(";
Remi Gacognef46cd6e2014-06-12 14:58:40 +02001490 int idx = 0;
1491 int dhe_found = 0;
Emeric Brunfc0421f2012-09-07 17:30:07 +02001492
Thierry Fournier383085f2013-01-24 14:15:43 +01001493 /* Make sure openssl opens /dev/urandom before the chroot */
1494 if (!ssl_initialize_random()) {
1495 Alert("OpenSSL random data generator initialization failed.\n");
1496 cfgerr++;
1497 }
1498
Emeric Brun89675492012-10-05 13:48:26 +02001499 if (bind_conf->ssl_options & BC_SSL_O_NO_SSLV3)
Emeric Brunfc0421f2012-09-07 17:30:07 +02001500 ssloptions |= SSL_OP_NO_SSLv3;
Emeric Brun89675492012-10-05 13:48:26 +02001501 if (bind_conf->ssl_options & BC_SSL_O_NO_TLSV10)
Emeric Brunfc0421f2012-09-07 17:30:07 +02001502 ssloptions |= SSL_OP_NO_TLSv1;
Emeric Brun89675492012-10-05 13:48:26 +02001503 if (bind_conf->ssl_options & BC_SSL_O_NO_TLSV11)
Emeric Brunc0ff4922012-09-28 19:37:02 +02001504 ssloptions |= SSL_OP_NO_TLSv1_1;
Emeric Brun89675492012-10-05 13:48:26 +02001505 if (bind_conf->ssl_options & BC_SSL_O_NO_TLSV12)
Emeric Brunc0ff4922012-09-28 19:37:02 +02001506 ssloptions |= SSL_OP_NO_TLSv1_2;
Emeric Brun89675492012-10-05 13:48:26 +02001507 if (bind_conf->ssl_options & BC_SSL_O_NO_TLS_TICKETS)
Emeric Brun2d0c4822012-10-02 13:45:20 +02001508 ssloptions |= SSL_OP_NO_TICKET;
Emeric Brun2cb7ae52012-10-05 14:14:21 +02001509 if (bind_conf->ssl_options & BC_SSL_O_USE_SSLV3)
1510 SSL_CTX_set_ssl_version(ctx, SSLv3_server_method());
1511 if (bind_conf->ssl_options & BC_SSL_O_USE_TLSV10)
1512 SSL_CTX_set_ssl_version(ctx, TLSv1_server_method());
1513#if SSL_OP_NO_TLSv1_1
1514 if (bind_conf->ssl_options & BC_SSL_O_USE_TLSV11)
1515 SSL_CTX_set_ssl_version(ctx, TLSv1_1_server_method());
1516#endif
1517#if SSL_OP_NO_TLSv1_2
1518 if (bind_conf->ssl_options & BC_SSL_O_USE_TLSV12)
1519 SSL_CTX_set_ssl_version(ctx, TLSv1_2_server_method());
1520#endif
Emeric Brunfc0421f2012-09-07 17:30:07 +02001521
1522 SSL_CTX_set_options(ctx, ssloptions);
1523 SSL_CTX_set_mode(ctx, sslmode);
Emeric Brun850efd52014-01-29 12:24:34 +01001524 switch (bind_conf->verify) {
1525 case SSL_SOCK_VERIFY_NONE:
1526 verify = SSL_VERIFY_NONE;
1527 break;
1528 case SSL_SOCK_VERIFY_OPTIONAL:
1529 verify = SSL_VERIFY_PEER;
1530 break;
1531 case SSL_SOCK_VERIFY_REQUIRED:
1532 verify = SSL_VERIFY_PEER|SSL_VERIFY_FAIL_IF_NO_PEER_CERT;
1533 break;
1534 }
1535 SSL_CTX_set_verify(ctx, verify, ssl_sock_bind_verifycbk);
1536 if (verify & SSL_VERIFY_PEER) {
Emeric Brunfb510ea2012-10-05 12:00:26 +02001537 if (bind_conf->ca_file) {
Emeric Brund94b3fe2012-09-20 18:23:56 +02001538 /* load CAfile to verify */
Emeric Brunfb510ea2012-10-05 12:00:26 +02001539 if (!SSL_CTX_load_verify_locations(ctx, bind_conf->ca_file, NULL)) {
Emeric Brund94b3fe2012-09-20 18:23:56 +02001540 Alert("Proxy '%s': unable to load CA file '%s' for bind '%s' at [%s:%d].\n",
Emeric Brunfb510ea2012-10-05 12:00:26 +02001541 curproxy->id, bind_conf->ca_file, bind_conf->arg, bind_conf->file, bind_conf->line);
Emeric Brund94b3fe2012-09-20 18:23:56 +02001542 cfgerr++;
1543 }
1544 /* set CA names fo client cert request, function returns void */
Emeric Brunfb510ea2012-10-05 12:00:26 +02001545 SSL_CTX_set_client_CA_list(ctx, SSL_load_client_CA_file(bind_conf->ca_file));
Emeric Brund94b3fe2012-09-20 18:23:56 +02001546 }
Emeric Brun850efd52014-01-29 12:24:34 +01001547 else {
1548 Alert("Proxy '%s': verify is enabled but no CA file specified for bind '%s' at [%s:%d].\n",
1549 curproxy->id, bind_conf->arg, bind_conf->file, bind_conf->line);
1550 cfgerr++;
1551 }
Emeric Brun051cdab2012-10-02 19:25:50 +02001552#ifdef X509_V_FLAG_CRL_CHECK
Emeric Brunfb510ea2012-10-05 12:00:26 +02001553 if (bind_conf->crl_file) {
Emeric Brund94b3fe2012-09-20 18:23:56 +02001554 X509_STORE *store = SSL_CTX_get_cert_store(ctx);
1555
Emeric Brunfb510ea2012-10-05 12:00:26 +02001556 if (!store || !X509_STORE_load_locations(store, bind_conf->crl_file, NULL)) {
Emeric Brund94b3fe2012-09-20 18:23:56 +02001557 Alert("Proxy '%s': unable to configure CRL file '%s' for bind '%s' at [%s:%d].\n",
Emeric Brunfb510ea2012-10-05 12:00:26 +02001558 curproxy->id, bind_conf->ca_file, bind_conf->arg, bind_conf->file, bind_conf->line);
Emeric Brund94b3fe2012-09-20 18:23:56 +02001559 cfgerr++;
1560 }
Emeric Brun561e5742012-10-02 15:20:55 +02001561 else {
1562 X509_STORE_set_flags(store, X509_V_FLAG_CRL_CHECK|X509_V_FLAG_CRL_CHECK_ALL);
1563 }
Emeric Brund94b3fe2012-09-20 18:23:56 +02001564 }
Emeric Brun051cdab2012-10-02 19:25:50 +02001565#endif
Emeric Brun644cde02012-12-14 11:21:13 +01001566 ERR_clear_error();
Emeric Brund94b3fe2012-09-20 18:23:56 +02001567 }
Emeric Brunfc0421f2012-09-07 17:30:07 +02001568
Emeric Brun4f65bff2012-11-16 15:11:00 +01001569 if (global.tune.ssllifetime)
1570 SSL_CTX_set_timeout(ctx, global.tune.ssllifetime);
1571
Emeric Brunfc0421f2012-09-07 17:30:07 +02001572 shared_context_set_cache(ctx);
Willy Tarreau2a65ff02012-09-13 17:54:29 +02001573 if (bind_conf->ciphers &&
1574 !SSL_CTX_set_cipher_list(ctx, bind_conf->ciphers)) {
Emeric Brunfc0421f2012-09-07 17:30:07 +02001575 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 +02001576 curproxy->id, bind_conf->ciphers, bind_conf->arg, bind_conf->file, bind_conf->line);
Emeric Brunfc0421f2012-09-07 17:30:07 +02001577 cfgerr++;
1578 }
1579
Remi Gacognef46cd6e2014-06-12 14:58:40 +02001580 /* If tune.ssl.default-dh-param has not been set and
1581 no static DH params were in the certificate file. */
1582 if (global.tune.ssl_default_dh_param == 0) {
1583 ciphers = ctx->cipher_list;
1584
1585 if (ciphers) {
1586 for (idx = 0; idx < sk_SSL_CIPHER_num(ciphers); idx++) {
1587 cipher = sk_SSL_CIPHER_value(ciphers, idx);
Remi Gacognec1eab8c2014-06-12 18:20:11 +02001588 if (SSL_CIPHER_description(cipher, cipher_description, sizeof (cipher_description)) == cipher_description) {
1589 if (strstr(cipher_description, dhe_description) != NULL ||
1590 strstr(cipher_description, dhe_export_description) != NULL) {
1591 dhe_found = 1;
1592 break;
1593 }
Remi Gacognef46cd6e2014-06-12 14:58:40 +02001594 }
1595 }
1596
1597 if (dhe_found) {
1598 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");
1599 }
1600 }
1601
1602 global.tune.ssl_default_dh_param = 1024;
1603 }
Remi Gacogne60d7aeb2014-07-15 11:36:40 +02001604
1605#ifndef OPENSSL_NO_DH
1606 if (global.tune.ssl_default_dh_param >= 1024) {
1607 if (local_dh_1024 == NULL) {
1608 local_dh_1024 = ssl_get_dh_1024();
1609 }
1610 if (global.tune.ssl_default_dh_param >= 2048) {
1611 if (local_dh_2048 == NULL) {
1612 local_dh_2048 = ssl_get_dh_2048();
1613 }
1614 if (global.tune.ssl_default_dh_param >= 4096) {
1615 if (local_dh_4096 == NULL) {
1616 local_dh_4096 = ssl_get_dh_4096();
1617 }
1618 if (global.tune.ssl_default_dh_param >= 8192 &&
1619 local_dh_8192 == NULL) {
1620 local_dh_8192 = ssl_get_dh_8192();
1621 }
1622 }
1623 }
1624 }
1625#endif /* OPENSSL_NO_DH */
Remi Gacognef46cd6e2014-06-12 14:58:40 +02001626
Emeric Brunfc0421f2012-09-07 17:30:07 +02001627 SSL_CTX_set_info_callback(ctx, ssl_sock_infocbk);
Willy Tarreau5cbe4ef2014-05-08 22:45:11 +02001628#if OPENSSL_VERSION_NUMBER >= 0x00907000L
Emeric Brun29f037d2014-04-25 19:05:36 +02001629 SSL_CTX_set_msg_callback(ctx, ssl_sock_msgcbk);
Willy Tarreau5cbe4ef2014-05-08 22:45:11 +02001630#endif
Emeric Brun29f037d2014-04-25 19:05:36 +02001631
Willy Tarreau6c9a3d52012-10-18 18:57:14 +02001632#ifdef OPENSSL_NPN_NEGOTIATED
1633 if (bind_conf->npn_str)
1634 SSL_CTX_set_next_protos_advertised_cb(ctx, ssl_sock_advertise_npn_protos, bind_conf);
1635#endif
Dirkjan Bussink48f1c4e2014-02-13 12:29:42 +01001636#ifdef TLSEXT_TYPE_application_layer_protocol_negotiation
Willy Tarreauab861d32013-04-02 02:30:41 +02001637 if (bind_conf->alpn_str)
Dirkjan Bussink48f1c4e2014-02-13 12:29:42 +01001638 SSL_CTX_set_alpn_select_cb(ctx, ssl_sock_advertise_alpn_protos, bind_conf);
Willy Tarreauab861d32013-04-02 02:30:41 +02001639#endif
Willy Tarreau6c9a3d52012-10-18 18:57:14 +02001640
Emeric Brunfc0421f2012-09-07 17:30:07 +02001641#ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME
1642 SSL_CTX_set_tlsext_servername_callback(ctx, ssl_sock_switchctx_cbk);
Willy Tarreau2a65ff02012-09-13 17:54:29 +02001643 SSL_CTX_set_tlsext_servername_arg(ctx, bind_conf);
Emeric Brunfc0421f2012-09-07 17:30:07 +02001644#endif
Emeric Brun2b58d042012-09-20 17:10:03 +02001645#if defined(SSL_CTX_set_tmp_ecdh) && !defined(OPENSSL_NO_ECDH)
Emeric Brun6924ef82013-03-06 14:08:53 +01001646 {
Emeric Brun2b58d042012-09-20 17:10:03 +02001647 int i;
1648 EC_KEY *ecdh;
1649
Emeric Brun6924ef82013-03-06 14:08:53 +01001650 i = OBJ_sn2nid(bind_conf->ecdhe ? bind_conf->ecdhe : ECDHE_DEFAULT_CURVE);
Emeric Brun2b58d042012-09-20 17:10:03 +02001651 if (!i || ((ecdh = EC_KEY_new_by_curve_name(i)) == NULL)) {
1652 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 +01001653 curproxy->id, bind_conf->ecdhe ? bind_conf->ecdhe : ECDHE_DEFAULT_CURVE,
1654 bind_conf->arg, bind_conf->file, bind_conf->line);
Emeric Brun2b58d042012-09-20 17:10:03 +02001655 cfgerr++;
1656 }
1657 else {
1658 SSL_CTX_set_tmp_ecdh(ctx, ecdh);
1659 EC_KEY_free(ecdh);
1660 }
1661 }
1662#endif
1663
Emeric Brunfc0421f2012-09-07 17:30:07 +02001664 return cfgerr;
1665}
1666
Evan Broderbe554312013-06-27 00:05:25 -07001667static int ssl_sock_srv_hostcheck(const char *pattern, const char *hostname)
1668{
1669 const char *pattern_wildcard, *pattern_left_label_end, *hostname_left_label_end;
1670 size_t prefixlen, suffixlen;
1671
1672 /* Trivial case */
1673 if (strcmp(pattern, hostname) == 0)
1674 return 1;
1675
Evan Broderbe554312013-06-27 00:05:25 -07001676 /* The rest of this logic is based on RFC 6125, section 6.4.3
1677 * (http://tools.ietf.org/html/rfc6125#section-6.4.3) */
1678
Emeric Bruna848dae2013-10-08 11:27:28 +02001679 pattern_wildcard = NULL;
1680 pattern_left_label_end = pattern;
1681 while (*pattern_left_label_end != '.') {
1682 switch (*pattern_left_label_end) {
1683 case 0:
1684 /* End of label not found */
1685 return 0;
1686 case '*':
1687 /* If there is more than one wildcards */
1688 if (pattern_wildcard)
1689 return 0;
1690 pattern_wildcard = pattern_left_label_end;
1691 break;
1692 }
1693 pattern_left_label_end++;
1694 }
1695
1696 /* If it's not trivial and there is no wildcard, it can't
1697 * match */
1698 if (!pattern_wildcard)
Evan Broderbe554312013-06-27 00:05:25 -07001699 return 0;
1700
1701 /* Make sure all labels match except the leftmost */
1702 hostname_left_label_end = strchr(hostname, '.');
1703 if (!hostname_left_label_end
1704 || strcmp(pattern_left_label_end, hostname_left_label_end) != 0)
1705 return 0;
1706
1707 /* Make sure the leftmost label of the hostname is long enough
1708 * that the wildcard can match */
Emeric Brun369da852013-10-08 11:39:35 +02001709 if (hostname_left_label_end - hostname < (pattern_left_label_end - pattern) - 1)
Evan Broderbe554312013-06-27 00:05:25 -07001710 return 0;
1711
1712 /* Finally compare the string on either side of the
1713 * wildcard */
1714 prefixlen = pattern_wildcard - pattern;
1715 suffixlen = pattern_left_label_end - (pattern_wildcard + 1);
Emeric Bruna848dae2013-10-08 11:27:28 +02001716 if ((prefixlen && (memcmp(pattern, hostname, prefixlen) != 0))
1717 || (suffixlen && (memcmp(pattern_wildcard + 1, hostname_left_label_end - suffixlen, suffixlen) != 0)))
Evan Broderbe554312013-06-27 00:05:25 -07001718 return 0;
1719
1720 return 1;
1721}
1722
1723static int ssl_sock_srv_verifycbk(int ok, X509_STORE_CTX *ctx)
1724{
1725 SSL *ssl;
1726 struct connection *conn;
1727 char *servername;
1728
1729 int depth;
1730 X509 *cert;
1731 STACK_OF(GENERAL_NAME) *alt_names;
1732 int i;
1733 X509_NAME *cert_subject;
1734 char *str;
1735
1736 if (ok == 0)
1737 return ok;
1738
1739 ssl = X509_STORE_CTX_get_ex_data(ctx, SSL_get_ex_data_X509_STORE_CTX_idx());
1740 conn = (struct connection *)SSL_get_app_data(ssl);
1741
1742 servername = objt_server(conn->target)->ssl_ctx.verify_host;
1743
1744 /* We only need to verify the CN on the actual server cert,
1745 * not the indirect CAs */
1746 depth = X509_STORE_CTX_get_error_depth(ctx);
1747 if (depth != 0)
1748 return ok;
1749
1750 /* At this point, the cert is *not* OK unless we can find a
1751 * hostname match */
1752 ok = 0;
1753
1754 cert = X509_STORE_CTX_get_current_cert(ctx);
1755 /* It seems like this might happen if verify peer isn't set */
1756 if (!cert)
1757 return ok;
1758
1759 alt_names = X509_get_ext_d2i(cert, NID_subject_alt_name, NULL, NULL);
1760 if (alt_names) {
1761 for (i = 0; !ok && i < sk_GENERAL_NAME_num(alt_names); i++) {
1762 GENERAL_NAME *name = sk_GENERAL_NAME_value(alt_names, i);
1763 if (name->type == GEN_DNS) {
Emeric Bruna33410c2013-09-17 15:47:48 +02001764#if OPENSSL_VERSION_NUMBER < 0x00907000L
1765 if (ASN1_STRING_to_UTF8((unsigned char **)&str, name->d.ia5) >= 0) {
1766#else
Evan Broderbe554312013-06-27 00:05:25 -07001767 if (ASN1_STRING_to_UTF8((unsigned char **)&str, name->d.dNSName) >= 0) {
Emeric Bruna33410c2013-09-17 15:47:48 +02001768#endif
Evan Broderbe554312013-06-27 00:05:25 -07001769 ok = ssl_sock_srv_hostcheck(str, servername);
1770 OPENSSL_free(str);
1771 }
1772 }
1773 }
Emeric Brun4ad50a42013-09-17 15:19:54 +02001774 sk_GENERAL_NAME_pop_free(alt_names, GENERAL_NAME_free);
Evan Broderbe554312013-06-27 00:05:25 -07001775 }
1776
1777 cert_subject = X509_get_subject_name(cert);
1778 i = -1;
1779 while (!ok && (i = X509_NAME_get_index_by_NID(cert_subject, NID_commonName, i)) != -1) {
1780 X509_NAME_ENTRY *entry = X509_NAME_get_entry(cert_subject, i);
1781 if (ASN1_STRING_to_UTF8((unsigned char **)&str, entry->value) >= 0) {
1782 ok = ssl_sock_srv_hostcheck(str, servername);
1783 OPENSSL_free(str);
1784 }
1785 }
1786
1787 return ok;
1788}
1789
Emeric Brun94324a42012-10-11 14:00:19 +02001790/* prepare ssl context from servers options. Returns an error count */
1791int ssl_sock_prepare_srv_ctx(struct server *srv, struct proxy *curproxy)
1792{
1793 int cfgerr = 0;
Remi Gacogneaf5c3da2014-05-19 10:29:58 +02001794 long options =
Emeric Brun94324a42012-10-11 14:00:19 +02001795 SSL_OP_ALL | /* all known workarounds for bugs */
1796 SSL_OP_NO_SSLv2 |
1797 SSL_OP_NO_COMPRESSION;
Remi Gacogneaf5c3da2014-05-19 10:29:58 +02001798 long mode =
Emeric Brun94324a42012-10-11 14:00:19 +02001799 SSL_MODE_ENABLE_PARTIAL_WRITE |
1800 SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER |
1801 SSL_MODE_RELEASE_BUFFERS;
Emeric Brun850efd52014-01-29 12:24:34 +01001802 int verify = SSL_VERIFY_NONE;
Emeric Brun94324a42012-10-11 14:00:19 +02001803
Thierry Fournier383085f2013-01-24 14:15:43 +01001804 /* Make sure openssl opens /dev/urandom before the chroot */
1805 if (!ssl_initialize_random()) {
1806 Alert("OpenSSL random data generator initialization failed.\n");
1807 cfgerr++;
1808 }
1809
Emeric Brun94324a42012-10-11 14:00:19 +02001810 /* Initiate SSL context for current server */
1811 srv->ssl_ctx.reused_sess = NULL;
1812 if (srv->use_ssl)
1813 srv->xprt = &ssl_sock;
1814 if (srv->check.use_ssl)
Cyril Bonté1f96a872014-11-15 22:41:27 +01001815 srv->check.xprt = &ssl_sock;
Emeric Brun94324a42012-10-11 14:00:19 +02001816
1817 srv->ssl_ctx.ctx = SSL_CTX_new(SSLv23_client_method());
1818 if (!srv->ssl_ctx.ctx) {
1819 Alert("config : %s '%s', server '%s': unable to allocate ssl context.\n",
1820 proxy_type_str(curproxy), curproxy->id,
1821 srv->id);
1822 cfgerr++;
1823 return cfgerr;
1824 }
Emeric Bruna7aa3092012-10-26 12:58:00 +02001825 if (srv->ssl_ctx.client_crt) {
1826 if (SSL_CTX_use_PrivateKey_file(srv->ssl_ctx.ctx, srv->ssl_ctx.client_crt, SSL_FILETYPE_PEM) <= 0) {
1827 Alert("config : %s '%s', server '%s': unable to load SSL private key from PEM file '%s'.\n",
1828 proxy_type_str(curproxy), curproxy->id,
1829 srv->id, srv->ssl_ctx.client_crt);
1830 cfgerr++;
1831 }
1832 else if (SSL_CTX_use_certificate_chain_file(srv->ssl_ctx.ctx, srv->ssl_ctx.client_crt) <= 0) {
1833 Alert("config : %s '%s', server '%s': unable to load ssl certificate from PEM file '%s'.\n",
1834 proxy_type_str(curproxy), curproxy->id,
1835 srv->id, srv->ssl_ctx.client_crt);
1836 cfgerr++;
1837 }
1838 else if (SSL_CTX_check_private_key(srv->ssl_ctx.ctx) <= 0) {
1839 Alert("config : %s '%s', server '%s': inconsistencies between private key and certificate loaded from PEM file '%s'.\n",
1840 proxy_type_str(curproxy), curproxy->id,
1841 srv->id, srv->ssl_ctx.client_crt);
1842 cfgerr++;
1843 }
1844 }
Emeric Brun94324a42012-10-11 14:00:19 +02001845
1846 if (srv->ssl_ctx.options & SRV_SSL_O_NO_SSLV3)
1847 options |= SSL_OP_NO_SSLv3;
1848 if (srv->ssl_ctx.options & SRV_SSL_O_NO_TLSV10)
1849 options |= SSL_OP_NO_TLSv1;
1850 if (srv->ssl_ctx.options & SRV_SSL_O_NO_TLSV11)
1851 options |= SSL_OP_NO_TLSv1_1;
1852 if (srv->ssl_ctx.options & SRV_SSL_O_NO_TLSV12)
1853 options |= SSL_OP_NO_TLSv1_2;
Emeric Brunf9c5c472012-10-11 15:28:34 +02001854 if (srv->ssl_ctx.options & SRV_SSL_O_NO_TLS_TICKETS)
1855 options |= SSL_OP_NO_TICKET;
Emeric Brun94324a42012-10-11 14:00:19 +02001856 if (srv->ssl_ctx.options & SRV_SSL_O_USE_SSLV3)
1857 SSL_CTX_set_ssl_version(srv->ssl_ctx.ctx, SSLv3_client_method());
1858 if (srv->ssl_ctx.options & SRV_SSL_O_USE_TLSV10)
1859 SSL_CTX_set_ssl_version(srv->ssl_ctx.ctx, TLSv1_client_method());
1860#if SSL_OP_NO_TLSv1_1
1861 if (srv->ssl_ctx.options & SRV_SSL_O_USE_TLSV11)
1862 SSL_CTX_set_ssl_version(srv->ssl_ctx.ctx, TLSv1_1_client_method());
1863#endif
1864#if SSL_OP_NO_TLSv1_2
1865 if (srv->ssl_ctx.options & SRV_SSL_O_USE_TLSV12)
1866 SSL_CTX_set_ssl_version(srv->ssl_ctx.ctx, TLSv1_2_client_method());
1867#endif
1868
1869 SSL_CTX_set_options(srv->ssl_ctx.ctx, options);
1870 SSL_CTX_set_mode(srv->ssl_ctx.ctx, mode);
Emeric Brun850efd52014-01-29 12:24:34 +01001871
1872 if (global.ssl_server_verify == SSL_SERVER_VERIFY_REQUIRED)
1873 verify = SSL_VERIFY_PEER;
1874
1875 switch (srv->ssl_ctx.verify) {
1876 case SSL_SOCK_VERIFY_NONE:
1877 verify = SSL_VERIFY_NONE;
1878 break;
1879 case SSL_SOCK_VERIFY_REQUIRED:
1880 verify = SSL_VERIFY_PEER;
1881 break;
1882 }
Evan Broderbe554312013-06-27 00:05:25 -07001883 SSL_CTX_set_verify(srv->ssl_ctx.ctx,
Emeric Brun850efd52014-01-29 12:24:34 +01001884 verify,
Evan Broderbe554312013-06-27 00:05:25 -07001885 srv->ssl_ctx.verify_host ? ssl_sock_srv_verifycbk : NULL);
Emeric Brun850efd52014-01-29 12:24:34 +01001886 if (verify & SSL_VERIFY_PEER) {
Emeric Brunef42d922012-10-11 16:11:36 +02001887 if (srv->ssl_ctx.ca_file) {
1888 /* load CAfile to verify */
1889 if (!SSL_CTX_load_verify_locations(srv->ssl_ctx.ctx, srv->ssl_ctx.ca_file, NULL)) {
Willy Tarreau07ba08b2014-02-16 19:22:08 +01001890 Alert("Proxy '%s', server '%s' [%s:%d] unable to load CA file '%s'.\n",
Emeric Brunef42d922012-10-11 16:11:36 +02001891 curproxy->id, srv->id,
1892 srv->conf.file, srv->conf.line, srv->ssl_ctx.ca_file);
1893 cfgerr++;
1894 }
1895 }
Emeric Brun850efd52014-01-29 12:24:34 +01001896 else {
1897 if (global.ssl_server_verify == SSL_SERVER_VERIFY_REQUIRED)
Willy Tarreau07ba08b2014-02-16 19:22:08 +01001898 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 +01001899 curproxy->id, srv->id,
1900 srv->conf.file, srv->conf.line);
1901 else
Willy Tarreau07ba08b2014-02-16 19:22:08 +01001902 Alert("Proxy '%s', server '%s' [%s:%d] verify is enabled but no CA file specified.\n",
Emeric Brun850efd52014-01-29 12:24:34 +01001903 curproxy->id, srv->id,
1904 srv->conf.file, srv->conf.line);
1905 cfgerr++;
1906 }
Emeric Brunef42d922012-10-11 16:11:36 +02001907#ifdef X509_V_FLAG_CRL_CHECK
1908 if (srv->ssl_ctx.crl_file) {
1909 X509_STORE *store = SSL_CTX_get_cert_store(srv->ssl_ctx.ctx);
1910
1911 if (!store || !X509_STORE_load_locations(store, srv->ssl_ctx.crl_file, NULL)) {
Willy Tarreau07ba08b2014-02-16 19:22:08 +01001912 Alert("Proxy '%s', server '%s' [%s:%d] unable to configure CRL file '%s'.\n",
Emeric Brunef42d922012-10-11 16:11:36 +02001913 curproxy->id, srv->id,
1914 srv->conf.file, srv->conf.line, srv->ssl_ctx.crl_file);
1915 cfgerr++;
1916 }
1917 else {
1918 X509_STORE_set_flags(store, X509_V_FLAG_CRL_CHECK|X509_V_FLAG_CRL_CHECK_ALL);
1919 }
1920 }
1921#endif
1922 }
1923
Emeric Brun4f65bff2012-11-16 15:11:00 +01001924 if (global.tune.ssllifetime)
1925 SSL_CTX_set_timeout(srv->ssl_ctx.ctx, global.tune.ssllifetime);
1926
Emeric Brun94324a42012-10-11 14:00:19 +02001927 SSL_CTX_set_session_cache_mode(srv->ssl_ctx.ctx, SSL_SESS_CACHE_OFF);
1928 if (srv->ssl_ctx.ciphers &&
1929 !SSL_CTX_set_cipher_list(srv->ssl_ctx.ctx, srv->ssl_ctx.ciphers)) {
1930 Alert("Proxy '%s', server '%s' [%s:%d] : unable to set SSL cipher list to '%s'.\n",
1931 curproxy->id, srv->id,
1932 srv->conf.file, srv->conf.line, srv->ssl_ctx.ciphers);
1933 cfgerr++;
1934 }
1935
1936 return cfgerr;
1937}
1938
Willy Tarreau2a65ff02012-09-13 17:54:29 +02001939/* Walks down the two trees in bind_conf and prepares all certs. The pointer may
Emeric Brunfc0421f2012-09-07 17:30:07 +02001940 * be NULL, in which case nothing is done. Returns the number of errors
1941 * encountered.
1942 */
Willy Tarreau2a65ff02012-09-13 17:54:29 +02001943int ssl_sock_prepare_all_ctx(struct bind_conf *bind_conf, struct proxy *px)
Emeric Brunfc0421f2012-09-07 17:30:07 +02001944{
1945 struct ebmb_node *node;
1946 struct sni_ctx *sni;
1947 int err = 0;
1948
Willy Tarreau2a65ff02012-09-13 17:54:29 +02001949 if (!bind_conf || !bind_conf->is_ssl)
Emeric Brunfc0421f2012-09-07 17:30:07 +02001950 return 0;
1951
Emeric Brun8068b032014-10-30 19:25:24 +01001952 if (bind_conf->default_ctx)
1953 err += ssl_sock_prepare_ctx(bind_conf, bind_conf->default_ctx, px);
1954
Willy Tarreau2a65ff02012-09-13 17:54:29 +02001955 node = ebmb_first(&bind_conf->sni_ctx);
Emeric Brunfc0421f2012-09-07 17:30:07 +02001956 while (node) {
1957 sni = ebmb_entry(node, struct sni_ctx, name);
Emeric Brun8068b032014-10-30 19:25:24 +01001958 if (!sni->order && sni->ctx != bind_conf->default_ctx)
1959 /* only initialize the CTX on its first occurrence and
1960 if it is not the default_ctx */
Willy Tarreau2a65ff02012-09-13 17:54:29 +02001961 err += ssl_sock_prepare_ctx(bind_conf, sni->ctx, px);
Emeric Brunfc0421f2012-09-07 17:30:07 +02001962 node = ebmb_next(node);
1963 }
1964
Willy Tarreau2a65ff02012-09-13 17:54:29 +02001965 node = ebmb_first(&bind_conf->sni_w_ctx);
Emeric Brunfc0421f2012-09-07 17:30:07 +02001966 while (node) {
1967 sni = ebmb_entry(node, struct sni_ctx, name);
Emeric Brun8068b032014-10-30 19:25:24 +01001968 if (!sni->order && sni->ctx != bind_conf->default_ctx)
1969 /* only initialize the CTX on its first occurrence and
1970 if it is not the default_ctx */
Willy Tarreau2a65ff02012-09-13 17:54:29 +02001971 err += ssl_sock_prepare_ctx(bind_conf, sni->ctx, px);
Emeric Brunfc0421f2012-09-07 17:30:07 +02001972 node = ebmb_next(node);
1973 }
1974 return err;
1975}
1976
Willy Tarreau2a65ff02012-09-13 17:54:29 +02001977/* Walks down the two trees in bind_conf and frees all the certs. The pointer may
Emeric Brunfc0421f2012-09-07 17:30:07 +02001978 * be NULL, in which case nothing is done. The default_ctx is nullified too.
1979 */
Willy Tarreau2a65ff02012-09-13 17:54:29 +02001980void ssl_sock_free_all_ctx(struct bind_conf *bind_conf)
Emeric Brunfc0421f2012-09-07 17:30:07 +02001981{
1982 struct ebmb_node *node, *back;
1983 struct sni_ctx *sni;
1984
Willy Tarreau2a65ff02012-09-13 17:54:29 +02001985 if (!bind_conf || !bind_conf->is_ssl)
Emeric Brunfc0421f2012-09-07 17:30:07 +02001986 return;
1987
Willy Tarreau2a65ff02012-09-13 17:54:29 +02001988 node = ebmb_first(&bind_conf->sni_ctx);
Emeric Brunfc0421f2012-09-07 17:30:07 +02001989 while (node) {
1990 sni = ebmb_entry(node, struct sni_ctx, name);
1991 back = ebmb_next(node);
1992 ebmb_delete(node);
1993 if (!sni->order) /* only free the CTX on its first occurrence */
1994 SSL_CTX_free(sni->ctx);
1995 free(sni);
1996 node = back;
1997 }
1998
Willy Tarreau2a65ff02012-09-13 17:54:29 +02001999 node = ebmb_first(&bind_conf->sni_w_ctx);
Emeric Brunfc0421f2012-09-07 17:30:07 +02002000 while (node) {
2001 sni = ebmb_entry(node, struct sni_ctx, name);
2002 back = ebmb_next(node);
2003 ebmb_delete(node);
2004 if (!sni->order) /* only free the CTX on its first occurrence */
2005 SSL_CTX_free(sni->ctx);
2006 free(sni);
2007 node = back;
2008 }
2009
Willy Tarreau2a65ff02012-09-13 17:54:29 +02002010 bind_conf->default_ctx = NULL;
Emeric Brune1f38db2012-09-03 20:36:47 +02002011}
2012
Emeric Brun46591952012-05-18 15:47:34 +02002013/*
2014 * This function is called if SSL * context is not yet allocated. The function
2015 * is designed to be called before any other data-layer operation and sets the
2016 * handshake flag on the connection. It is safe to call it multiple times.
2017 * It returns 0 on success and -1 in error case.
2018 */
2019static int ssl_sock_init(struct connection *conn)
2020{
2021 /* already initialized */
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02002022 if (conn->xprt_ctx)
Emeric Brun46591952012-05-18 15:47:34 +02002023 return 0;
2024
Willy Tarreau3c728722014-01-23 13:50:42 +01002025 if (!conn_ctrl_ready(conn))
Willy Tarreauf79c8172013-10-21 16:30:56 +02002026 return 0;
2027
Willy Tarreau20879a02012-12-03 16:32:10 +01002028 if (global.maxsslconn && sslconns >= global.maxsslconn) {
2029 conn->err_code = CO_ER_SSL_TOO_MANY;
Willy Tarreau403edff2012-09-06 11:58:37 +02002030 return -1;
Willy Tarreau20879a02012-12-03 16:32:10 +01002031 }
Willy Tarreau403edff2012-09-06 11:58:37 +02002032
Emeric Brun46591952012-05-18 15:47:34 +02002033 /* If it is in client mode initiate SSL session
2034 in connect state otherwise accept state */
Willy Tarreau3fdb3662012-11-12 00:42:33 +01002035 if (objt_server(conn->target)) {
Willy Tarreau9bcc01a2014-11-13 13:48:58 +01002036 int may_retry = 1;
2037
2038 retry_connect:
Emeric Brun46591952012-05-18 15:47:34 +02002039 /* Alloc a new SSL session ctx */
Willy Tarreau3fdb3662012-11-12 00:42:33 +01002040 conn->xprt_ctx = SSL_new(objt_server(conn->target)->ssl_ctx.ctx);
Willy Tarreau20879a02012-12-03 16:32:10 +01002041 if (!conn->xprt_ctx) {
Willy Tarreau9bcc01a2014-11-13 13:48:58 +01002042 if (may_retry--) {
2043 pool_gc2();
2044 goto retry_connect;
2045 }
Willy Tarreau20879a02012-12-03 16:32:10 +01002046 conn->err_code = CO_ER_SSL_NO_MEM;
Emeric Brun46591952012-05-18 15:47:34 +02002047 return -1;
Willy Tarreau20879a02012-12-03 16:32:10 +01002048 }
Emeric Brun46591952012-05-18 15:47:34 +02002049
Emeric Brun46591952012-05-18 15:47:34 +02002050 /* set fd on SSL session context */
Emeric Brun90951492014-11-12 17:35:37 +01002051 if (!SSL_set_fd(conn->xprt_ctx, conn->t.sock.fd)) {
2052 SSL_free(conn->xprt_ctx);
2053 conn->xprt_ctx = NULL;
Willy Tarreau9bcc01a2014-11-13 13:48:58 +01002054 if (may_retry--) {
2055 pool_gc2();
2056 goto retry_connect;
2057 }
Emeric Brun90951492014-11-12 17:35:37 +01002058 conn->err_code = CO_ER_SSL_NO_MEM;
2059 return -1;
2060 }
Emeric Brun46591952012-05-18 15:47:34 +02002061
Evan Broderbe554312013-06-27 00:05:25 -07002062 /* set connection pointer */
Emeric Brun90951492014-11-12 17:35:37 +01002063 if (!SSL_set_app_data(conn->xprt_ctx, conn)) {
2064 SSL_free(conn->xprt_ctx);
2065 conn->xprt_ctx = NULL;
Willy Tarreau9bcc01a2014-11-13 13:48:58 +01002066 if (may_retry--) {
2067 pool_gc2();
2068 goto retry_connect;
2069 }
Emeric Brun90951492014-11-12 17:35:37 +01002070 conn->err_code = CO_ER_SSL_NO_MEM;
2071 return -1;
2072 }
2073
2074 SSL_set_connect_state(conn->xprt_ctx);
2075 if (objt_server(conn->target)->ssl_ctx.reused_sess) {
2076 if(!SSL_set_session(conn->xprt_ctx, objt_server(conn->target)->ssl_ctx.reused_sess)) {
2077 SSL_SESSION_free(objt_server(conn->target)->ssl_ctx.reused_sess);
2078 objt_server(conn->target)->ssl_ctx.reused_sess = NULL;
2079 }
2080 }
Evan Broderbe554312013-06-27 00:05:25 -07002081
Emeric Brun46591952012-05-18 15:47:34 +02002082 /* leave init state and start handshake */
Willy Tarreau05737472012-09-04 08:03:39 +02002083 conn->flags |= CO_FL_SSL_WAIT_HS | CO_FL_WAIT_L6_CONN;
Willy Tarreau403edff2012-09-06 11:58:37 +02002084
2085 sslconns++;
Willy Tarreau71b734c2014-01-28 15:19:44 +01002086 totalsslconns++;
Emeric Brun46591952012-05-18 15:47:34 +02002087 return 0;
2088 }
Willy Tarreau3fdb3662012-11-12 00:42:33 +01002089 else if (objt_listener(conn->target)) {
Willy Tarreau9bcc01a2014-11-13 13:48:58 +01002090 int may_retry = 1;
2091
2092 retry_accept:
Emeric Brun46591952012-05-18 15:47:34 +02002093 /* Alloc a new SSL session ctx */
Willy Tarreau3fdb3662012-11-12 00:42:33 +01002094 conn->xprt_ctx = SSL_new(objt_listener(conn->target)->bind_conf->default_ctx);
Willy Tarreau20879a02012-12-03 16:32:10 +01002095 if (!conn->xprt_ctx) {
Willy Tarreau9bcc01a2014-11-13 13:48:58 +01002096 if (may_retry--) {
2097 pool_gc2();
2098 goto retry_accept;
2099 }
Willy Tarreau20879a02012-12-03 16:32:10 +01002100 conn->err_code = CO_ER_SSL_NO_MEM;
Emeric Brun46591952012-05-18 15:47:34 +02002101 return -1;
Willy Tarreau20879a02012-12-03 16:32:10 +01002102 }
Emeric Brun46591952012-05-18 15:47:34 +02002103
Emeric Brun46591952012-05-18 15:47:34 +02002104 /* set fd on SSL session context */
Emeric Brun90951492014-11-12 17:35:37 +01002105 if (!SSL_set_fd(conn->xprt_ctx, conn->t.sock.fd)) {
2106 SSL_free(conn->xprt_ctx);
2107 conn->xprt_ctx = NULL;
Willy Tarreau9bcc01a2014-11-13 13:48:58 +01002108 if (may_retry--) {
2109 pool_gc2();
2110 goto retry_accept;
2111 }
Emeric Brun90951492014-11-12 17:35:37 +01002112 conn->err_code = CO_ER_SSL_NO_MEM;
2113 return -1;
2114 }
Emeric Brun46591952012-05-18 15:47:34 +02002115
Emeric Brune1f38db2012-09-03 20:36:47 +02002116 /* set connection pointer */
Emeric Brun90951492014-11-12 17:35:37 +01002117 if (!SSL_set_app_data(conn->xprt_ctx, conn)) {
2118 SSL_free(conn->xprt_ctx);
2119 conn->xprt_ctx = NULL;
Willy Tarreau9bcc01a2014-11-13 13:48:58 +01002120 if (may_retry--) {
2121 pool_gc2();
2122 goto retry_accept;
2123 }
Emeric Brun90951492014-11-12 17:35:37 +01002124 conn->err_code = CO_ER_SSL_NO_MEM;
2125 return -1;
2126 }
2127
2128 SSL_set_accept_state(conn->xprt_ctx);
Emeric Brune1f38db2012-09-03 20:36:47 +02002129
Emeric Brun46591952012-05-18 15:47:34 +02002130 /* leave init state and start handshake */
Willy Tarreau05737472012-09-04 08:03:39 +02002131 conn->flags |= CO_FL_SSL_WAIT_HS | CO_FL_WAIT_L6_CONN;
Willy Tarreau403edff2012-09-06 11:58:37 +02002132
2133 sslconns++;
Willy Tarreau71b734c2014-01-28 15:19:44 +01002134 totalsslconns++;
Emeric Brun46591952012-05-18 15:47:34 +02002135 return 0;
2136 }
2137 /* don't know how to handle such a target */
Willy Tarreau20879a02012-12-03 16:32:10 +01002138 conn->err_code = CO_ER_SSL_NO_TARGET;
Emeric Brun46591952012-05-18 15:47:34 +02002139 return -1;
2140}
2141
2142
2143/* This is the callback which is used when an SSL handshake is pending. It
2144 * updates the FD status if it wants some polling before being called again.
2145 * It returns 0 if it fails in a fatal way or needs to poll to go further,
2146 * otherwise it returns non-zero and removes itself from the connection's
2147 * flags (the bit is provided in <flag> by the caller).
2148 */
2149int ssl_sock_handshake(struct connection *conn, unsigned int flag)
2150{
2151 int ret;
2152
Willy Tarreau3c728722014-01-23 13:50:42 +01002153 if (!conn_ctrl_ready(conn))
Willy Tarreauf79c8172013-10-21 16:30:56 +02002154 return 0;
2155
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02002156 if (!conn->xprt_ctx)
Emeric Brun46591952012-05-18 15:47:34 +02002157 goto out_error;
2158
Emeric Brun674b7432012-11-08 19:21:55 +01002159 /* If we use SSL_do_handshake to process a reneg initiated by
2160 * the remote peer, it sometimes returns SSL_ERROR_SSL.
2161 * Usually SSL_write and SSL_read are used and process implicitly
2162 * the reneg handshake.
2163 * Here we use SSL_peek as a workaround for reneg.
2164 */
2165 if ((conn->flags & CO_FL_CONNECTED) && SSL_renegotiate_pending(conn->xprt_ctx)) {
2166 char c;
2167
2168 ret = SSL_peek(conn->xprt_ctx, &c, 1);
2169 if (ret <= 0) {
2170 /* handshake may have not been completed, let's find why */
2171 ret = SSL_get_error(conn->xprt_ctx, ret);
2172 if (ret == SSL_ERROR_WANT_WRITE) {
2173 /* SSL handshake needs to write, L4 connection may not be ready */
2174 __conn_sock_stop_recv(conn);
Willy Tarreaue1f50c42014-01-22 20:02:06 +01002175 __conn_sock_want_send(conn);
2176 fd_cant_send(conn->t.sock.fd);
Emeric Brun674b7432012-11-08 19:21:55 +01002177 return 0;
2178 }
2179 else if (ret == SSL_ERROR_WANT_READ) {
2180 /* handshake may have been completed but we have
2181 * no more data to read.
2182 */
2183 if (!SSL_renegotiate_pending(conn->xprt_ctx)) {
2184 ret = 1;
2185 goto reneg_ok;
2186 }
2187 /* SSL handshake needs to read, L4 connection is ready */
2188 if (conn->flags & CO_FL_WAIT_L4_CONN)
2189 conn->flags &= ~CO_FL_WAIT_L4_CONN;
2190 __conn_sock_stop_send(conn);
Willy Tarreaue1f50c42014-01-22 20:02:06 +01002191 __conn_sock_want_recv(conn);
2192 fd_cant_recv(conn->t.sock.fd);
Emeric Brun674b7432012-11-08 19:21:55 +01002193 return 0;
2194 }
2195 else if (ret == SSL_ERROR_SYSCALL) {
2196 /* if errno is null, then connection was successfully established */
2197 if (!errno && conn->flags & CO_FL_WAIT_L4_CONN)
2198 conn->flags &= ~CO_FL_WAIT_L4_CONN;
Willy Tarreau20879a02012-12-03 16:32:10 +01002199 if (!conn->err_code) {
Emeric Brun29f037d2014-04-25 19:05:36 +02002200 if (!((SSL *)conn->xprt_ctx)->packet_length) {
2201 if (!errno) {
2202 if (conn->xprt_st & SSL_SOCK_RECV_HEARTBEAT)
2203 conn->err_code = CO_ER_SSL_HANDSHAKE_HB;
2204 else
2205 conn->err_code = CO_ER_SSL_EMPTY;
2206 }
2207 else {
2208 if (conn->xprt_st & SSL_SOCK_RECV_HEARTBEAT)
2209 conn->err_code = CO_ER_SSL_HANDSHAKE_HB;
2210 else
2211 conn->err_code = CO_ER_SSL_ABORT;
2212 }
2213 }
2214 else {
2215 if (conn->xprt_st & SSL_SOCK_RECV_HEARTBEAT)
2216 conn->err_code = CO_ER_SSL_HANDSHAKE_HB;
Willy Tarreau20879a02012-12-03 16:32:10 +01002217 else
Emeric Brun29f037d2014-04-25 19:05:36 +02002218 conn->err_code = CO_ER_SSL_HANDSHAKE;
2219 }
Willy Tarreau20879a02012-12-03 16:32:10 +01002220 }
Emeric Brun674b7432012-11-08 19:21:55 +01002221 goto out_error;
2222 }
2223 else {
2224 /* Fail on all other handshake errors */
2225 /* Note: OpenSSL may leave unread bytes in the socket's
2226 * buffer, causing an RST to be emitted upon close() on
2227 * TCP sockets. We first try to drain possibly pending
2228 * data to avoid this as much as possible.
2229 */
Willy Tarreau46be2e52014-01-20 12:10:52 +01002230 conn_drain(conn);
Willy Tarreau20879a02012-12-03 16:32:10 +01002231 if (!conn->err_code)
Willy Tarreauf51c6982014-04-25 20:02:39 +02002232 conn->err_code = (conn->xprt_st & SSL_SOCK_RECV_HEARTBEAT) ?
2233 CO_ER_SSL_KILLED_HB : CO_ER_SSL_HANDSHAKE;
Emeric Brun674b7432012-11-08 19:21:55 +01002234 goto out_error;
2235 }
2236 }
2237 /* read some data: consider handshake completed */
2238 goto reneg_ok;
2239 }
2240
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02002241 ret = SSL_do_handshake(conn->xprt_ctx);
Emeric Brun46591952012-05-18 15:47:34 +02002242 if (ret != 1) {
2243 /* handshake did not complete, let's find why */
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02002244 ret = SSL_get_error(conn->xprt_ctx, ret);
Emeric Brun46591952012-05-18 15:47:34 +02002245
2246 if (ret == SSL_ERROR_WANT_WRITE) {
2247 /* SSL handshake needs to write, L4 connection may not be ready */
2248 __conn_sock_stop_recv(conn);
Willy Tarreaue1f50c42014-01-22 20:02:06 +01002249 __conn_sock_want_send(conn);
2250 fd_cant_send(conn->t.sock.fd);
Emeric Brun46591952012-05-18 15:47:34 +02002251 return 0;
2252 }
2253 else if (ret == SSL_ERROR_WANT_READ) {
2254 /* SSL handshake needs to read, L4 connection is ready */
2255 if (conn->flags & CO_FL_WAIT_L4_CONN)
2256 conn->flags &= ~CO_FL_WAIT_L4_CONN;
2257 __conn_sock_stop_send(conn);
Willy Tarreaue1f50c42014-01-22 20:02:06 +01002258 __conn_sock_want_recv(conn);
2259 fd_cant_recv(conn->t.sock.fd);
Emeric Brun46591952012-05-18 15:47:34 +02002260 return 0;
2261 }
Willy Tarreau89230192012-09-28 20:22:13 +02002262 else if (ret == SSL_ERROR_SYSCALL) {
2263 /* if errno is null, then connection was successfully established */
2264 if (!errno && conn->flags & CO_FL_WAIT_L4_CONN)
2265 conn->flags &= ~CO_FL_WAIT_L4_CONN;
Willy Tarreau20879a02012-12-03 16:32:10 +01002266
Emeric Brun29f037d2014-04-25 19:05:36 +02002267 if (!((SSL *)conn->xprt_ctx)->packet_length) {
2268 if (!errno) {
2269 if (conn->xprt_st & SSL_SOCK_RECV_HEARTBEAT)
2270 conn->err_code = CO_ER_SSL_HANDSHAKE_HB;
2271 else
2272 conn->err_code = CO_ER_SSL_EMPTY;
2273 }
2274 else {
2275 if (conn->xprt_st & SSL_SOCK_RECV_HEARTBEAT)
2276 conn->err_code = CO_ER_SSL_HANDSHAKE_HB;
2277 else
2278 conn->err_code = CO_ER_SSL_ABORT;
2279 }
2280 }
2281 else {
2282 if (conn->xprt_st & SSL_SOCK_RECV_HEARTBEAT)
2283 conn->err_code = CO_ER_SSL_HANDSHAKE_HB;
Willy Tarreau20879a02012-12-03 16:32:10 +01002284 else
Emeric Brun29f037d2014-04-25 19:05:36 +02002285 conn->err_code = CO_ER_SSL_HANDSHAKE;
2286 }
Willy Tarreau89230192012-09-28 20:22:13 +02002287 goto out_error;
2288 }
Emeric Brun46591952012-05-18 15:47:34 +02002289 else {
2290 /* Fail on all other handshake errors */
Willy Tarreau566dc552012-10-19 20:52:18 +02002291 /* Note: OpenSSL may leave unread bytes in the socket's
2292 * buffer, causing an RST to be emitted upon close() on
2293 * TCP sockets. We first try to drain possibly pending
2294 * data to avoid this as much as possible.
2295 */
Willy Tarreau46be2e52014-01-20 12:10:52 +01002296 conn_drain(conn);
Willy Tarreau20879a02012-12-03 16:32:10 +01002297 if (!conn->err_code)
Willy Tarreauf51c6982014-04-25 20:02:39 +02002298 conn->err_code = (conn->xprt_st & SSL_SOCK_RECV_HEARTBEAT) ?
2299 CO_ER_SSL_KILLED_HB : CO_ER_SSL_HANDSHAKE;
Emeric Brun46591952012-05-18 15:47:34 +02002300 goto out_error;
2301 }
2302 }
2303
Emeric Brun674b7432012-11-08 19:21:55 +01002304reneg_ok:
2305
Emeric Brun46591952012-05-18 15:47:34 +02002306 /* Handshake succeeded */
Willy Tarreau0c9c2722014-05-28 12:28:58 +02002307 if (!SSL_session_reused(conn->xprt_ctx)) {
2308 if (objt_server(conn->target)) {
2309 update_freq_ctr(&global.ssl_be_keys_per_sec, 1);
2310 if (global.ssl_be_keys_per_sec.curr_ctr > global.ssl_be_keys_max)
2311 global.ssl_be_keys_max = global.ssl_be_keys_per_sec.curr_ctr;
2312
Emeric Brun46591952012-05-18 15:47:34 +02002313 /* check if session was reused, if not store current session on server for reuse */
Willy Tarreau3fdb3662012-11-12 00:42:33 +01002314 if (objt_server(conn->target)->ssl_ctx.reused_sess)
2315 SSL_SESSION_free(objt_server(conn->target)->ssl_ctx.reused_sess);
Emeric Brun46591952012-05-18 15:47:34 +02002316
Willy Tarreau3fdb3662012-11-12 00:42:33 +01002317 objt_server(conn->target)->ssl_ctx.reused_sess = SSL_get1_session(conn->xprt_ctx);
Emeric Brun46591952012-05-18 15:47:34 +02002318 }
Willy Tarreau0c9c2722014-05-28 12:28:58 +02002319 else {
2320 update_freq_ctr(&global.ssl_fe_keys_per_sec, 1);
2321 if (global.ssl_fe_keys_per_sec.curr_ctr > global.ssl_fe_keys_max)
2322 global.ssl_fe_keys_max = global.ssl_fe_keys_per_sec.curr_ctr;
2323 }
Emeric Brun46591952012-05-18 15:47:34 +02002324 }
2325
2326 /* The connection is now established at both layers, it's time to leave */
2327 conn->flags &= ~(flag | CO_FL_WAIT_L4_CONN | CO_FL_WAIT_L6_CONN);
2328 return 1;
2329
2330 out_error:
Emeric Brun644cde02012-12-14 11:21:13 +01002331 /* Clear openssl global errors stack */
2332 ERR_clear_error();
2333
Emeric Brun9fa89732012-10-04 17:09:56 +02002334 /* free resumed session if exists */
Willy Tarreau3fdb3662012-11-12 00:42:33 +01002335 if (objt_server(conn->target) && objt_server(conn->target)->ssl_ctx.reused_sess) {
2336 SSL_SESSION_free(objt_server(conn->target)->ssl_ctx.reused_sess);
2337 objt_server(conn->target)->ssl_ctx.reused_sess = NULL;
Emeric Brun9fa89732012-10-04 17:09:56 +02002338 }
2339
Emeric Brun46591952012-05-18 15:47:34 +02002340 /* Fail on all other handshake errors */
2341 conn->flags |= CO_FL_ERROR;
Willy Tarreau20879a02012-12-03 16:32:10 +01002342 if (!conn->err_code)
2343 conn->err_code = CO_ER_SSL_HANDSHAKE;
Emeric Brun46591952012-05-18 15:47:34 +02002344 return 0;
2345}
2346
2347/* Receive up to <count> bytes from connection <conn>'s socket and store them
Willy Tarreauabf08d92014-01-14 11:31:27 +01002348 * into buffer <buf>. Only one call to recv() is performed, unless the
Emeric Brun46591952012-05-18 15:47:34 +02002349 * buffer wraps, in which case a second call may be performed. The connection's
2350 * flags are updated with whatever special event is detected (error, read0,
2351 * empty). The caller is responsible for taking care of those events and
2352 * avoiding the call if inappropriate. The function does not call the
2353 * connection's polling update function, so the caller is responsible for this.
2354 */
2355static int ssl_sock_to_buf(struct connection *conn, struct buffer *buf, int count)
2356{
2357 int ret, done = 0;
Willy Tarreauabf08d92014-01-14 11:31:27 +01002358 int try;
Emeric Brun46591952012-05-18 15:47:34 +02002359
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02002360 if (!conn->xprt_ctx)
Emeric Brun46591952012-05-18 15:47:34 +02002361 goto out_error;
2362
2363 if (conn->flags & CO_FL_HANDSHAKE)
2364 /* a handshake was requested */
2365 return 0;
2366
Willy Tarreauabf08d92014-01-14 11:31:27 +01002367 /* let's realign the buffer to optimize I/O */
2368 if (buffer_empty(buf))
Emeric Brun46591952012-05-18 15:47:34 +02002369 buf->p = buf->data;
Emeric Brun46591952012-05-18 15:47:34 +02002370
2371 /* read the largest possible block. For this, we perform only one call
2372 * to recv() unless the buffer wraps and we exactly fill the first hunk,
2373 * in which case we accept to do it once again. A new attempt is made on
2374 * EINTR too.
2375 */
Willy Tarreau00b0fb92014-01-17 11:09:40 +01002376 while (count > 0) {
Willy Tarreauabf08d92014-01-14 11:31:27 +01002377 /* first check if we have some room after p+i */
2378 try = buf->data + buf->size - (buf->p + buf->i);
2379 /* otherwise continue between data and p-o */
2380 if (try <= 0) {
2381 try = buf->p - (buf->data + buf->o);
2382 if (try <= 0)
2383 break;
2384 }
2385 if (try > count)
2386 try = count;
2387
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02002388 ret = SSL_read(conn->xprt_ctx, bi_end(buf), try);
Emeric Brune1f38db2012-09-03 20:36:47 +02002389 if (conn->flags & CO_FL_ERROR) {
2390 /* CO_FL_ERROR may be set by ssl_sock_infocbk */
Emeric Brun644cde02012-12-14 11:21:13 +01002391 goto out_error;
Emeric Brune1f38db2012-09-03 20:36:47 +02002392 }
Emeric Brun46591952012-05-18 15:47:34 +02002393 if (ret > 0) {
2394 buf->i += ret;
2395 done += ret;
2396 if (ret < try)
2397 break;
2398 count -= ret;
Emeric Brun46591952012-05-18 15:47:34 +02002399 }
2400 else if (ret == 0) {
Emeric Brun644cde02012-12-14 11:21:13 +01002401 ret = SSL_get_error(conn->xprt_ctx, ret);
2402 if (ret != SSL_ERROR_ZERO_RETURN) {
Emeric Brun1c646862012-12-14 12:33:41 +01002403 /* error on protocol or underlying transport */
2404 if ((ret != SSL_ERROR_SYSCALL)
2405 || (errno && (errno != EAGAIN)))
2406 conn->flags |= CO_FL_ERROR;
2407
Emeric Brun644cde02012-12-14 11:21:13 +01002408 /* Clear openssl global errors stack */
2409 ERR_clear_error();
2410 }
Emeric Brun46591952012-05-18 15:47:34 +02002411 goto read0;
2412 }
2413 else {
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02002414 ret = SSL_get_error(conn->xprt_ctx, ret);
Emeric Brun46591952012-05-18 15:47:34 +02002415 if (ret == SSL_ERROR_WANT_WRITE) {
Emeric Brun8af8dd12012-11-08 17:56:20 +01002416 /* handshake is running, and it needs to enable write */
Emeric Brun46591952012-05-18 15:47:34 +02002417 conn->flags |= CO_FL_SSL_WAIT_HS;
Emeric Brun8af8dd12012-11-08 17:56:20 +01002418 __conn_sock_want_send(conn);
Emeric Brun46591952012-05-18 15:47:34 +02002419 break;
2420 }
2421 else if (ret == SSL_ERROR_WANT_READ) {
Emeric Brun282a76a2012-11-08 18:02:56 +01002422 if (SSL_renegotiate_pending(conn->xprt_ctx)) {
2423 /* handshake is running, and it may need to re-enable read */
2424 conn->flags |= CO_FL_SSL_WAIT_HS;
2425 __conn_sock_want_recv(conn);
2426 break;
2427 }
Emeric Brun46591952012-05-18 15:47:34 +02002428 /* we need to poll for retry a read later */
Willy Tarreaue1f50c42014-01-22 20:02:06 +01002429 fd_cant_recv(conn->t.sock.fd);
Emeric Brun46591952012-05-18 15:47:34 +02002430 break;
2431 }
2432 /* otherwise it's a real error */
2433 goto out_error;
2434 }
2435 }
2436 return done;
2437
2438 read0:
2439 conn_sock_read0(conn);
2440 return done;
2441 out_error:
Emeric Brun644cde02012-12-14 11:21:13 +01002442 /* Clear openssl global errors stack */
2443 ERR_clear_error();
2444
Emeric Brun46591952012-05-18 15:47:34 +02002445 conn->flags |= CO_FL_ERROR;
2446 return done;
2447}
2448
2449
2450/* Send all pending bytes from buffer <buf> to connection <conn>'s socket.
Willy Tarreau1049b1f2014-02-02 01:51:17 +01002451 * <flags> may contain some CO_SFL_* flags to hint the system about other
2452 * pending data for example, but this flag is ignored at the moment.
Emeric Brun46591952012-05-18 15:47:34 +02002453 * Only one call to send() is performed, unless the buffer wraps, in which case
2454 * a second call may be performed. The connection's flags are updated with
2455 * whatever special event is detected (error, empty). The caller is responsible
2456 * for taking care of those events and avoiding the call if inappropriate. The
2457 * function does not call the connection's polling update function, so the caller
2458 * is responsible for this.
2459 */
2460static int ssl_sock_from_buf(struct connection *conn, struct buffer *buf, int flags)
2461{
2462 int ret, try, done;
2463
2464 done = 0;
2465
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02002466 if (!conn->xprt_ctx)
Emeric Brun46591952012-05-18 15:47:34 +02002467 goto out_error;
2468
2469 if (conn->flags & CO_FL_HANDSHAKE)
2470 /* a handshake was requested */
2471 return 0;
2472
2473 /* send the largest possible block. For this we perform only one call
2474 * to send() unless the buffer wraps and we exactly fill the first hunk,
2475 * in which case we accept to do it once again.
2476 */
2477 while (buf->o) {
Kevin Hestercad82342013-05-30 15:12:41 -07002478 try = bo_contig_data(buf);
Willy Tarreaubfd59462013-02-21 07:46:09 +01002479
Willy Tarreau7bed9452014-02-02 02:00:24 +01002480 if (!(flags & CO_SFL_STREAMER) &&
Willy Tarreau518cedd2014-02-17 15:43:01 +01002481 !(conn->xprt_st & SSL_SOCK_SEND_UNLIMITED) &&
2482 global.tune.ssl_max_record && try > global.tune.ssl_max_record) {
Willy Tarreaubfd59462013-02-21 07:46:09 +01002483 try = global.tune.ssl_max_record;
Willy Tarreau518cedd2014-02-17 15:43:01 +01002484 }
2485 else {
2486 /* we need to keep the information about the fact that
2487 * we're not limiting the upcoming send(), because if it
2488 * fails, we'll have to retry with at least as many data.
2489 */
2490 conn->xprt_st |= SSL_SOCK_SEND_UNLIMITED;
2491 }
Willy Tarreaubfd59462013-02-21 07:46:09 +01002492
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02002493 ret = SSL_write(conn->xprt_ctx, bo_ptr(buf), try);
Willy Tarreau518cedd2014-02-17 15:43:01 +01002494
Emeric Brune1f38db2012-09-03 20:36:47 +02002495 if (conn->flags & CO_FL_ERROR) {
2496 /* CO_FL_ERROR may be set by ssl_sock_infocbk */
Emeric Brun644cde02012-12-14 11:21:13 +01002497 goto out_error;
Emeric Brune1f38db2012-09-03 20:36:47 +02002498 }
Emeric Brun46591952012-05-18 15:47:34 +02002499 if (ret > 0) {
Willy Tarreau518cedd2014-02-17 15:43:01 +01002500 conn->xprt_st &= ~SSL_SOCK_SEND_UNLIMITED;
2501
Emeric Brun46591952012-05-18 15:47:34 +02002502 buf->o -= ret;
2503 done += ret;
2504
Willy Tarreau5fb38032012-12-16 19:39:09 +01002505 if (likely(buffer_empty(buf)))
Emeric Brun46591952012-05-18 15:47:34 +02002506 /* optimize data alignment in the buffer */
2507 buf->p = buf->data;
2508
2509 /* if the system buffer is full, don't insist */
2510 if (ret < try)
2511 break;
2512 }
2513 else {
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02002514 ret = SSL_get_error(conn->xprt_ctx, ret);
Emeric Brun46591952012-05-18 15:47:34 +02002515 if (ret == SSL_ERROR_WANT_WRITE) {
Emeric Brun282a76a2012-11-08 18:02:56 +01002516 if (SSL_renegotiate_pending(conn->xprt_ctx)) {
2517 /* handshake is running, and it may need to re-enable write */
2518 conn->flags |= CO_FL_SSL_WAIT_HS;
2519 __conn_sock_want_send(conn);
2520 break;
2521 }
Emeric Brun46591952012-05-18 15:47:34 +02002522 /* we need to poll to retry a write later */
Willy Tarreaue1f50c42014-01-22 20:02:06 +01002523 fd_cant_send(conn->t.sock.fd);
Emeric Brun46591952012-05-18 15:47:34 +02002524 break;
2525 }
2526 else if (ret == SSL_ERROR_WANT_READ) {
Emeric Brun8af8dd12012-11-08 17:56:20 +01002527 /* handshake is running, and it needs to enable read */
Emeric Brun46591952012-05-18 15:47:34 +02002528 conn->flags |= CO_FL_SSL_WAIT_HS;
Emeric Brun8af8dd12012-11-08 17:56:20 +01002529 __conn_sock_want_recv(conn);
Emeric Brun46591952012-05-18 15:47:34 +02002530 break;
2531 }
2532 goto out_error;
2533 }
2534 }
2535 return done;
2536
2537 out_error:
Emeric Brun644cde02012-12-14 11:21:13 +01002538 /* Clear openssl global errors stack */
2539 ERR_clear_error();
2540
Emeric Brun46591952012-05-18 15:47:34 +02002541 conn->flags |= CO_FL_ERROR;
2542 return done;
2543}
2544
Emeric Brun46591952012-05-18 15:47:34 +02002545static void ssl_sock_close(struct connection *conn) {
2546
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02002547 if (conn->xprt_ctx) {
2548 SSL_free(conn->xprt_ctx);
2549 conn->xprt_ctx = NULL;
Willy Tarreau403edff2012-09-06 11:58:37 +02002550 sslconns--;
Emeric Brun46591952012-05-18 15:47:34 +02002551 }
Emeric Brun46591952012-05-18 15:47:34 +02002552}
2553
2554/* This function tries to perform a clean shutdown on an SSL connection, and in
2555 * any case, flags the connection as reusable if no handshake was in progress.
2556 */
2557static void ssl_sock_shutw(struct connection *conn, int clean)
2558{
2559 if (conn->flags & CO_FL_HANDSHAKE)
2560 return;
2561 /* no handshake was in progress, try a clean ssl shutdown */
Emeric Brun644cde02012-12-14 11:21:13 +01002562 if (clean && (SSL_shutdown(conn->xprt_ctx) <= 0)) {
2563 /* Clear openssl global errors stack */
2564 ERR_clear_error();
2565 }
Emeric Brun46591952012-05-18 15:47:34 +02002566
2567 /* force flag on ssl to keep session in cache regardless shutdown result */
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02002568 SSL_set_shutdown(conn->xprt_ctx, SSL_SENT_SHUTDOWN);
Emeric Brun46591952012-05-18 15:47:34 +02002569}
2570
Willy Tarreauffc3fcd2012-10-12 20:17:54 +02002571/* used for logging, may be changed for a sample fetch later */
2572const char *ssl_sock_get_cipher_name(struct connection *conn)
2573{
2574 if (!conn->xprt && !conn->xprt_ctx)
2575 return NULL;
2576 return SSL_get_cipher_name(conn->xprt_ctx);
2577}
2578
2579/* used for logging, may be changed for a sample fetch later */
2580const char *ssl_sock_get_proto_version(struct connection *conn)
2581{
2582 if (!conn->xprt && !conn->xprt_ctx)
2583 return NULL;
2584 return SSL_get_version(conn->xprt_ctx);
2585}
2586
Willy Tarreau8d598402012-10-22 17:58:39 +02002587/* Extract a serial from a cert, and copy it to a chunk.
2588 * Returns 1 if serial is found and copied, 0 if no serial found and
2589 * -1 if output is not large enough.
2590 */
2591static int
2592ssl_sock_get_serial(X509 *crt, struct chunk *out)
2593{
2594 ASN1_INTEGER *serial;
2595
2596 serial = X509_get_serialNumber(crt);
2597 if (!serial)
2598 return 0;
2599
2600 if (out->size < serial->length)
2601 return -1;
2602
2603 memcpy(out->str, serial->data, serial->length);
2604 out->len = serial->length;
2605 return 1;
2606}
2607
Emeric Brunb3cc4252014-10-29 19:03:26 +01002608/* Extract a cert to der, and copy it to a chunk.
2609 * Returns 1 if cert is found and copied, 0 on der convertion failure and
2610 * -1 if output is not large enough.
2611 */
2612static int
2613ssl_sock_crt2der(X509 *crt, struct chunk *out)
2614{
2615 int len;
2616 unsigned char *p = (unsigned char *)out->str;;
2617
2618 len =i2d_X509(crt, NULL);
2619 if (len <= 0)
2620 return 1;
2621
2622 if (out->size < len)
2623 return -1;
2624
2625 i2d_X509(crt,&p);
2626 out->len = len;
2627 return 1;
2628}
2629
Emeric Brunce5ad802012-10-22 14:11:22 +02002630
2631/* Copy Date in ASN1_UTCTIME format in struct chunk out.
2632 * Returns 1 if serial is found and copied, 0 if no valid time found
2633 * and -1 if output is not large enough.
2634 */
2635static int
2636ssl_sock_get_time(ASN1_TIME *tm, struct chunk *out)
2637{
2638 if (tm->type == V_ASN1_GENERALIZEDTIME) {
2639 ASN1_GENERALIZEDTIME *gentm = (ASN1_GENERALIZEDTIME *)tm;
2640
2641 if (gentm->length < 12)
2642 return 0;
2643 if (gentm->data[0] != 0x32 || gentm->data[1] != 0x30)
2644 return 0;
2645 if (out->size < gentm->length-2)
2646 return -1;
2647
2648 memcpy(out->str, gentm->data+2, gentm->length-2);
2649 out->len = gentm->length-2;
2650 return 1;
2651 }
2652 else if (tm->type == V_ASN1_UTCTIME) {
2653 ASN1_UTCTIME *utctm = (ASN1_UTCTIME *)tm;
2654
2655 if (utctm->length < 10)
2656 return 0;
2657 if (utctm->data[0] >= 0x35)
2658 return 0;
2659 if (out->size < utctm->length)
2660 return -1;
2661
2662 memcpy(out->str, utctm->data, utctm->length);
2663 out->len = utctm->length;
2664 return 1;
2665 }
2666
2667 return 0;
2668}
2669
Emeric Brun87855892012-10-17 17:39:35 +02002670/* Extract an entry from a X509_NAME and copy its value to an output chunk.
2671 * Returns 1 if entry found, 0 if entry not found, or -1 if output not large enough.
2672 */
2673static int
2674ssl_sock_get_dn_entry(X509_NAME *a, const struct chunk *entry, int pos, struct chunk *out)
2675{
2676 X509_NAME_ENTRY *ne;
2677 int i, j, n;
2678 int cur = 0;
2679 const char *s;
2680 char tmp[128];
2681
2682 out->len = 0;
2683 for (i = 0; i < sk_X509_NAME_ENTRY_num(a->entries); i++) {
2684 if (pos < 0)
2685 j = (sk_X509_NAME_ENTRY_num(a->entries)-1) - i;
2686 else
2687 j = i;
2688
2689 ne = sk_X509_NAME_ENTRY_value(a->entries, j);
2690 n = OBJ_obj2nid(ne->object);
2691 if ((n == NID_undef) || ((s = OBJ_nid2sn(n)) == NULL)) {
2692 i2t_ASN1_OBJECT(tmp, sizeof(tmp), ne->object);
2693 s = tmp;
2694 }
2695
2696 if (chunk_strcasecmp(entry, s) != 0)
2697 continue;
2698
2699 if (pos < 0)
2700 cur--;
2701 else
2702 cur++;
2703
2704 if (cur != pos)
2705 continue;
2706
2707 if (ne->value->length > out->size)
2708 return -1;
2709
2710 memcpy(out->str, ne->value->data, ne->value->length);
2711 out->len = ne->value->length;
2712 return 1;
2713 }
2714
2715 return 0;
2716
2717}
2718
2719/* Extract and format full DN from a X509_NAME and copy result into a chunk
2720 * Returns 1 if dn entries exits, 0 if no dn entry found or -1 if output is not large enough.
2721 */
2722static int
2723ssl_sock_get_dn_oneline(X509_NAME *a, struct chunk *out)
2724{
2725 X509_NAME_ENTRY *ne;
2726 int i, n, ln;
2727 int l = 0;
2728 const char *s;
2729 char *p;
2730 char tmp[128];
2731
2732 out->len = 0;
2733 p = out->str;
2734 for (i = 0; i < sk_X509_NAME_ENTRY_num(a->entries); i++) {
2735 ne = sk_X509_NAME_ENTRY_value(a->entries, i);
2736 n = OBJ_obj2nid(ne->object);
2737 if ((n == NID_undef) || ((s = OBJ_nid2sn(n)) == NULL)) {
2738 i2t_ASN1_OBJECT(tmp, sizeof(tmp), ne->object);
2739 s = tmp;
2740 }
2741 ln = strlen(s);
2742
2743 l += 1 + ln + 1 + ne->value->length;
2744 if (l > out->size)
2745 return -1;
2746 out->len = l;
2747
2748 *(p++)='/';
2749 memcpy(p, s, ln);
2750 p += ln;
2751 *(p++)='=';
2752 memcpy(p, ne->value->data, ne->value->length);
2753 p += ne->value->length;
2754 }
2755
2756 if (!out->len)
2757 return 0;
2758
2759 return 1;
2760}
2761
David Safb76832014-05-08 23:42:08 -04002762char *ssl_sock_get_version(struct connection *conn)
2763{
2764 if (!ssl_sock_is_ssl(conn))
2765 return NULL;
2766
2767 return (char *)SSL_get_version(conn->xprt_ctx);
2768}
2769
Emeric Brun49100982014-06-24 18:26:41 +02002770/* Extract peer certificate's common name into the chunk dest
2771 * Returns
2772 * the len of the extracted common name
2773 * or 0 if no CN found in DN
2774 * or -1 on error case (i.e. no peer certificate)
2775 */
2776int ssl_sock_get_remote_common_name(struct connection *conn, struct chunk *dest)
David Safb76832014-05-08 23:42:08 -04002777{
2778 X509 *crt = NULL;
2779 X509_NAME *name;
David Safb76832014-05-08 23:42:08 -04002780 const char find_cn[] = "CN";
2781 const struct chunk find_cn_chunk = {
2782 .str = (char *)&find_cn,
2783 .len = sizeof(find_cn)-1
2784 };
Emeric Brun49100982014-06-24 18:26:41 +02002785 int result = -1;
David Safb76832014-05-08 23:42:08 -04002786
2787 if (!ssl_sock_is_ssl(conn))
Emeric Brun49100982014-06-24 18:26:41 +02002788 goto out;
David Safb76832014-05-08 23:42:08 -04002789
2790 /* SSL_get_peer_certificate, it increase X509 * ref count */
2791 crt = SSL_get_peer_certificate(conn->xprt_ctx);
2792 if (!crt)
2793 goto out;
2794
2795 name = X509_get_subject_name(crt);
2796 if (!name)
2797 goto out;
David Safb76832014-05-08 23:42:08 -04002798
Emeric Brun49100982014-06-24 18:26:41 +02002799 result = ssl_sock_get_dn_entry(name, &find_cn_chunk, 1, dest);
2800out:
David Safb76832014-05-08 23:42:08 -04002801 if (crt)
2802 X509_free(crt);
2803
2804 return result;
2805}
2806
Dave McCowand6ec6052014-07-30 10:39:13 -04002807/* returns 1 if client passed a certificate for this session, 0 if not */
2808int ssl_sock_get_cert_used_sess(struct connection *conn)
2809{
2810 X509 *crt = NULL;
2811
2812 if (!ssl_sock_is_ssl(conn))
2813 return 0;
2814
2815 /* SSL_get_peer_certificate, it increase X509 * ref count */
2816 crt = SSL_get_peer_certificate(conn->xprt_ctx);
2817 if (!crt)
2818 return 0;
2819
2820 X509_free(crt);
2821 return 1;
2822}
2823
2824/* returns 1 if client passed a certificate for this connection, 0 if not */
2825int ssl_sock_get_cert_used_conn(struct connection *conn)
David Safb76832014-05-08 23:42:08 -04002826{
2827 if (!ssl_sock_is_ssl(conn))
2828 return 0;
2829
2830 return SSL_SOCK_ST_FL_VERIFY_DONE & conn->xprt_st ? 1 : 0;
2831}
2832
2833/* returns result from SSL verify */
2834unsigned int ssl_sock_get_verify_result(struct connection *conn)
2835{
2836 if (!ssl_sock_is_ssl(conn))
2837 return (unsigned int)X509_V_ERR_APPLICATION_VERIFICATION;
2838
2839 return (unsigned int)SSL_get_verify_result(conn->xprt_ctx);
2840}
2841
Willy Tarreau7875d092012-09-10 08:20:03 +02002842/***** Below are some sample fetching functions for ACL/patterns *****/
2843
Emeric Brune64aef12012-09-21 13:15:06 +02002844/* boolean, returns true if client cert was present */
2845static int
Emeric Brun2525b6b2012-10-18 15:59:43 +02002846smp_fetch_ssl_fc_has_crt(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
Willy Tarreauef38c392013-07-22 16:29:32 +02002847 const struct arg *args, struct sample *smp, const char *kw)
Emeric Brune64aef12012-09-21 13:15:06 +02002848{
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002849 struct connection *conn;
2850
2851 if (!l4)
2852 return 0;
2853
2854 conn = objt_conn(l4->si[0].end);
2855 if (!conn || conn->xprt != &ssl_sock)
Emeric Brune64aef12012-09-21 13:15:06 +02002856 return 0;
2857
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002858 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brune64aef12012-09-21 13:15:06 +02002859 smp->flags |= SMP_F_MAY_CHANGE;
2860 return 0;
2861 }
2862
2863 smp->flags = 0;
2864 smp->type = SMP_T_BOOL;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002865 smp->data.uint = SSL_SOCK_ST_FL_VERIFY_DONE & conn->xprt_st ? 1 : 0;
Emeric Brune64aef12012-09-21 13:15:06 +02002866
2867 return 1;
2868}
2869
Emeric Brunb3cc4252014-10-29 19:03:26 +01002870/* binary, returns a certificate in a binary chunk (der/raw).
2871 * The 5th keyword char is used to know if SSL_get_certificate or SSL_get_peer_certificate
2872 * should be use.
2873 */
2874static int
2875smp_fetch_ssl_x_der(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
2876 const struct arg *args, struct sample *smp, const char *kw)
2877{
2878 int cert_peer = (kw[4] == 'c') ? 1 : 0;
2879 X509 *crt = NULL;
2880 int ret = 0;
2881 struct chunk *smp_trash;
2882 struct connection *conn;
2883
2884 if (!l4)
2885 return 0;
2886
2887 conn = objt_conn(l4->si[0].end);
2888 if (!conn || conn->xprt != &ssl_sock)
2889 return 0;
2890
2891 if (!(conn->flags & CO_FL_CONNECTED)) {
2892 smp->flags |= SMP_F_MAY_CHANGE;
2893 return 0;
2894 }
2895
2896 if (cert_peer)
2897 crt = SSL_get_peer_certificate(conn->xprt_ctx);
2898 else
2899 crt = SSL_get_certificate(conn->xprt_ctx);
2900
2901 if (!crt)
2902 goto out;
2903
2904 smp_trash = get_trash_chunk();
2905 if (ssl_sock_crt2der(crt, smp_trash) <= 0)
2906 goto out;
2907
2908 smp->data.str = *smp_trash;
2909 smp->type = SMP_T_BIN;
2910 ret = 1;
2911out:
2912 /* SSL_get_peer_certificate, it increase X509 * ref count */
2913 if (cert_peer && crt)
2914 X509_free(crt);
2915 return ret;
2916}
2917
Emeric Brunba841a12014-04-30 17:05:08 +02002918/* binary, returns serial of certificate in a binary chunk.
2919 * The 5th keyword char is used to know if SSL_get_certificate or SSL_get_peer_certificate
2920 * should be use.
2921 */
Willy Tarreau8d598402012-10-22 17:58:39 +02002922static int
Emeric Brunba841a12014-04-30 17:05:08 +02002923smp_fetch_ssl_x_serial(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
Willy Tarreauef38c392013-07-22 16:29:32 +02002924 const struct arg *args, struct sample *smp, const char *kw)
Willy Tarreau8d598402012-10-22 17:58:39 +02002925{
Emeric Brunba841a12014-04-30 17:05:08 +02002926 int cert_peer = (kw[4] == 'c') ? 1 : 0;
Willy Tarreau8d598402012-10-22 17:58:39 +02002927 X509 *crt = NULL;
2928 int ret = 0;
2929 struct chunk *smp_trash;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002930 struct connection *conn;
2931
2932 if (!l4)
2933 return 0;
Willy Tarreau8d598402012-10-22 17:58:39 +02002934
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002935 conn = objt_conn(l4->si[0].end);
2936 if (!conn || conn->xprt != &ssl_sock)
Willy Tarreau8d598402012-10-22 17:58:39 +02002937 return 0;
2938
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002939 if (!(conn->flags & CO_FL_CONNECTED)) {
Willy Tarreau8d598402012-10-22 17:58:39 +02002940 smp->flags |= SMP_F_MAY_CHANGE;
2941 return 0;
2942 }
2943
Emeric Brunba841a12014-04-30 17:05:08 +02002944 if (cert_peer)
2945 crt = SSL_get_peer_certificate(conn->xprt_ctx);
2946 else
2947 crt = SSL_get_certificate(conn->xprt_ctx);
2948
Willy Tarreau8d598402012-10-22 17:58:39 +02002949 if (!crt)
2950 goto out;
2951
Willy Tarreau47ca5452012-12-23 20:22:19 +01002952 smp_trash = get_trash_chunk();
Willy Tarreau8d598402012-10-22 17:58:39 +02002953 if (ssl_sock_get_serial(crt, smp_trash) <= 0)
2954 goto out;
2955
2956 smp->data.str = *smp_trash;
2957 smp->type = SMP_T_BIN;
2958 ret = 1;
2959out:
Emeric Brunba841a12014-04-30 17:05:08 +02002960 /* SSL_get_peer_certificate, it increase X509 * ref count */
2961 if (cert_peer && crt)
Willy Tarreau8d598402012-10-22 17:58:39 +02002962 X509_free(crt);
2963 return ret;
2964}
Emeric Brune64aef12012-09-21 13:15:06 +02002965
Emeric Brunba841a12014-04-30 17:05:08 +02002966/* binary, returns the client certificate's SHA-1 fingerprint (SHA-1 hash of DER-encoded certificate) in a binary chunk.
2967 * The 5th keyword char is used to know if SSL_get_certificate or SSL_get_peer_certificate
2968 * should be use.
2969 */
James Votha051b4a2013-05-14 20:37:59 +02002970static int
Emeric Brunba841a12014-04-30 17:05:08 +02002971smp_fetch_ssl_x_sha1(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
Willy Tarreauef38c392013-07-22 16:29:32 +02002972 const struct arg *args, struct sample *smp, const char *kw)
James Votha051b4a2013-05-14 20:37:59 +02002973{
Emeric Brunba841a12014-04-30 17:05:08 +02002974 int cert_peer = (kw[4] == 'c') ? 1 : 0;
James Votha051b4a2013-05-14 20:37:59 +02002975 X509 *crt = NULL;
2976 const EVP_MD *digest;
2977 int ret = 0;
2978 struct chunk *smp_trash;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002979 struct connection *conn;
James Votha051b4a2013-05-14 20:37:59 +02002980
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002981 if (!l4)
James Votha051b4a2013-05-14 20:37:59 +02002982 return 0;
2983
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002984 conn = objt_conn(l4->si[0].end);
2985 if (!conn || conn->xprt != &ssl_sock)
2986 return 0;
2987
2988 if (!(conn->flags & CO_FL_CONNECTED)) {
James Votha051b4a2013-05-14 20:37:59 +02002989 smp->flags |= SMP_F_MAY_CHANGE;
2990 return 0;
2991 }
2992
Emeric Brunba841a12014-04-30 17:05:08 +02002993 if (cert_peer)
2994 crt = SSL_get_peer_certificate(conn->xprt_ctx);
2995 else
2996 crt = SSL_get_certificate(conn->xprt_ctx);
James Votha051b4a2013-05-14 20:37:59 +02002997 if (!crt)
2998 goto out;
2999
3000 smp_trash = get_trash_chunk();
3001 digest = EVP_sha1();
3002 X509_digest(crt, digest, (unsigned char *)smp_trash->str, (unsigned int *)&smp_trash->len);
3003
3004 smp->data.str = *smp_trash;
3005 smp->type = SMP_T_BIN;
3006 ret = 1;
3007out:
Emeric Brunba841a12014-04-30 17:05:08 +02003008 /* SSL_get_peer_certificate, it increase X509 * ref count */
3009 if (cert_peer && crt)
James Votha051b4a2013-05-14 20:37:59 +02003010 X509_free(crt);
3011 return ret;
3012}
3013
Emeric Brunba841a12014-04-30 17:05:08 +02003014/* string, returns certificate's notafter date in ASN1_UTCTIME format.
3015 * The 5th keyword char is used to know if SSL_get_certificate or SSL_get_peer_certificate
3016 * should be use.
3017 */
Emeric Brunce5ad802012-10-22 14:11:22 +02003018static int
Emeric Brunba841a12014-04-30 17:05:08 +02003019smp_fetch_ssl_x_notafter(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
Willy Tarreauef38c392013-07-22 16:29:32 +02003020 const struct arg *args, struct sample *smp, const char *kw)
Emeric Brunce5ad802012-10-22 14:11:22 +02003021{
Emeric Brunba841a12014-04-30 17:05:08 +02003022 int cert_peer = (kw[4] == 'c') ? 1 : 0;
Emeric Brunce5ad802012-10-22 14:11:22 +02003023 X509 *crt = NULL;
3024 int ret = 0;
3025 struct chunk *smp_trash;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003026 struct connection *conn;
Emeric Brunce5ad802012-10-22 14:11:22 +02003027
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003028 if (!l4)
Emeric Brunce5ad802012-10-22 14:11:22 +02003029 return 0;
3030
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003031 conn = objt_conn(l4->si[0].end);
3032 if (!conn || conn->xprt != &ssl_sock)
3033 return 0;
3034
3035 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brunce5ad802012-10-22 14:11:22 +02003036 smp->flags |= SMP_F_MAY_CHANGE;
3037 return 0;
3038 }
3039
Emeric Brunba841a12014-04-30 17:05:08 +02003040 if (cert_peer)
3041 crt = SSL_get_peer_certificate(conn->xprt_ctx);
3042 else
3043 crt = SSL_get_certificate(conn->xprt_ctx);
Emeric Brunce5ad802012-10-22 14:11:22 +02003044 if (!crt)
3045 goto out;
3046
Willy Tarreau47ca5452012-12-23 20:22:19 +01003047 smp_trash = get_trash_chunk();
Emeric Brunce5ad802012-10-22 14:11:22 +02003048 if (ssl_sock_get_time(X509_get_notAfter(crt), smp_trash) <= 0)
3049 goto out;
3050
3051 smp->data.str = *smp_trash;
3052 smp->type = SMP_T_STR;
3053 ret = 1;
3054out:
Emeric Brunba841a12014-04-30 17:05:08 +02003055 /* SSL_get_peer_certificate, it increase X509 * ref count */
3056 if (cert_peer && crt)
Emeric Brunce5ad802012-10-22 14:11:22 +02003057 X509_free(crt);
3058 return ret;
3059}
3060
Emeric Brunba841a12014-04-30 17:05:08 +02003061/* string, returns a string of a formatted full dn \C=..\O=..\OU=.. \CN=.. of certificate's issuer
3062 * The 5th keyword char is used to know if SSL_get_certificate or SSL_get_peer_certificate
3063 * should be use.
3064 */
Emeric Brun87855892012-10-17 17:39:35 +02003065static int
Emeric Brunba841a12014-04-30 17:05:08 +02003066smp_fetch_ssl_x_i_dn(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
Willy Tarreauef38c392013-07-22 16:29:32 +02003067 const struct arg *args, struct sample *smp, const char *kw)
Emeric Brun87855892012-10-17 17:39:35 +02003068{
Emeric Brunba841a12014-04-30 17:05:08 +02003069 int cert_peer = (kw[4] == 'c') ? 1 : 0;
Emeric Brun87855892012-10-17 17:39:35 +02003070 X509 *crt = NULL;
3071 X509_NAME *name;
3072 int ret = 0;
3073 struct chunk *smp_trash;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003074 struct connection *conn;
Emeric Brun87855892012-10-17 17:39:35 +02003075
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003076 if (!l4)
Emeric Brun87855892012-10-17 17:39:35 +02003077 return 0;
3078
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003079 conn = objt_conn(l4->si[0].end);
3080 if (!conn || conn->xprt != &ssl_sock)
3081 return 0;
3082
3083 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brun87855892012-10-17 17:39:35 +02003084 smp->flags |= SMP_F_MAY_CHANGE;
3085 return 0;
3086 }
3087
Emeric Brunba841a12014-04-30 17:05:08 +02003088 if (cert_peer)
3089 crt = SSL_get_peer_certificate(conn->xprt_ctx);
3090 else
3091 crt = SSL_get_certificate(conn->xprt_ctx);
Emeric Brun87855892012-10-17 17:39:35 +02003092 if (!crt)
3093 goto out;
3094
3095 name = X509_get_issuer_name(crt);
3096 if (!name)
3097 goto out;
3098
Willy Tarreau47ca5452012-12-23 20:22:19 +01003099 smp_trash = get_trash_chunk();
Emeric Brun87855892012-10-17 17:39:35 +02003100 if (args && args[0].type == ARGT_STR) {
3101 int pos = 1;
3102
3103 if (args[1].type == ARGT_SINT)
3104 pos = args[1].data.sint;
3105 else if (args[1].type == ARGT_UINT)
3106 pos =(int)args[1].data.uint;
3107
3108 if (ssl_sock_get_dn_entry(name, &args[0].data.str, pos, smp_trash) <= 0)
3109 goto out;
3110 }
3111 else if (ssl_sock_get_dn_oneline(name, smp_trash) <= 0)
3112 goto out;
3113
3114 smp->type = SMP_T_STR;
3115 smp->data.str = *smp_trash;
3116 ret = 1;
3117out:
Emeric Brunba841a12014-04-30 17:05:08 +02003118 /* SSL_get_peer_certificate, it increase X509 * ref count */
3119 if (cert_peer && crt)
Emeric Brun87855892012-10-17 17:39:35 +02003120 X509_free(crt);
3121 return ret;
3122}
3123
Emeric Brunba841a12014-04-30 17:05:08 +02003124/* string, returns notbefore date in ASN1_UTCTIME format.
3125 * The 5th keyword char is used to know if SSL_get_certificate or SSL_get_peer_certificate
3126 * should be use.
3127 */
Emeric Brunce5ad802012-10-22 14:11:22 +02003128static int
Emeric Brunba841a12014-04-30 17:05:08 +02003129smp_fetch_ssl_x_notbefore(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
Willy Tarreauef38c392013-07-22 16:29:32 +02003130 const struct arg *args, struct sample *smp, const char *kw)
Emeric Brunce5ad802012-10-22 14:11:22 +02003131{
Emeric Brunba841a12014-04-30 17:05:08 +02003132 int cert_peer = (kw[4] == 'c') ? 1 : 0;
Emeric Brunce5ad802012-10-22 14:11:22 +02003133 X509 *crt = NULL;
3134 int ret = 0;
3135 struct chunk *smp_trash;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003136 struct connection *conn;
3137
3138 if (!l4)
3139 return 0;
Emeric Brunce5ad802012-10-22 14:11:22 +02003140
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003141 conn = objt_conn(l4->si[0].end);
3142 if (!conn || conn->xprt != &ssl_sock)
Emeric Brunce5ad802012-10-22 14:11:22 +02003143 return 0;
3144
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003145 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brunce5ad802012-10-22 14:11:22 +02003146 smp->flags |= SMP_F_MAY_CHANGE;
3147 return 0;
3148 }
3149
Emeric Brunba841a12014-04-30 17:05:08 +02003150 if (cert_peer)
3151 crt = SSL_get_peer_certificate(conn->xprt_ctx);
3152 else
3153 crt = SSL_get_certificate(conn->xprt_ctx);
Emeric Brunce5ad802012-10-22 14:11:22 +02003154 if (!crt)
3155 goto out;
3156
Willy Tarreau47ca5452012-12-23 20:22:19 +01003157 smp_trash = get_trash_chunk();
Emeric Brunce5ad802012-10-22 14:11:22 +02003158 if (ssl_sock_get_time(X509_get_notBefore(crt), smp_trash) <= 0)
3159 goto out;
3160
3161 smp->data.str = *smp_trash;
3162 smp->type = SMP_T_STR;
3163 ret = 1;
3164out:
Emeric Brunba841a12014-04-30 17:05:08 +02003165 /* SSL_get_peer_certificate, it increase X509 * ref count */
3166 if (cert_peer && crt)
Emeric Brunce5ad802012-10-22 14:11:22 +02003167 X509_free(crt);
3168 return ret;
3169}
3170
Emeric Brunba841a12014-04-30 17:05:08 +02003171/* string, returns a string of a formatted full dn \C=..\O=..\OU=.. \CN=.. of certificate's subject
3172 * The 5th keyword char is used to know if SSL_get_certificate or SSL_get_peer_certificate
3173 * should be use.
3174 */
Emeric Brun87855892012-10-17 17:39:35 +02003175static int
Emeric Brunba841a12014-04-30 17:05:08 +02003176smp_fetch_ssl_x_s_dn(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
Willy Tarreauef38c392013-07-22 16:29:32 +02003177 const struct arg *args, struct sample *smp, const char *kw)
Emeric Brun87855892012-10-17 17:39:35 +02003178{
Emeric Brunba841a12014-04-30 17:05:08 +02003179 int cert_peer = (kw[4] == 'c') ? 1 : 0;
Emeric Brun87855892012-10-17 17:39:35 +02003180 X509 *crt = NULL;
3181 X509_NAME *name;
3182 int ret = 0;
3183 struct chunk *smp_trash;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003184 struct connection *conn;
Emeric Brun87855892012-10-17 17:39:35 +02003185
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003186 if (!l4)
Emeric Brun87855892012-10-17 17:39:35 +02003187 return 0;
3188
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003189 conn = objt_conn(l4->si[0].end);
3190 if (!conn || conn->xprt != &ssl_sock)
3191 return 0;
3192
3193 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brun87855892012-10-17 17:39:35 +02003194 smp->flags |= SMP_F_MAY_CHANGE;
3195 return 0;
3196 }
3197
Emeric Brunba841a12014-04-30 17:05:08 +02003198 if (cert_peer)
3199 crt = SSL_get_peer_certificate(conn->xprt_ctx);
3200 else
3201 crt = SSL_get_certificate(conn->xprt_ctx);
Emeric Brun87855892012-10-17 17:39:35 +02003202 if (!crt)
3203 goto out;
3204
3205 name = X509_get_subject_name(crt);
3206 if (!name)
3207 goto out;
3208
Willy Tarreau47ca5452012-12-23 20:22:19 +01003209 smp_trash = get_trash_chunk();
Emeric Brun87855892012-10-17 17:39:35 +02003210 if (args && args[0].type == ARGT_STR) {
3211 int pos = 1;
3212
3213 if (args[1].type == ARGT_SINT)
3214 pos = args[1].data.sint;
3215 else if (args[1].type == ARGT_UINT)
3216 pos =(int)args[1].data.uint;
3217
3218 if (ssl_sock_get_dn_entry(name, &args[0].data.str, pos, smp_trash) <= 0)
3219 goto out;
3220 }
3221 else if (ssl_sock_get_dn_oneline(name, smp_trash) <= 0)
3222 goto out;
3223
3224 smp->type = SMP_T_STR;
3225 smp->data.str = *smp_trash;
3226 ret = 1;
3227out:
Emeric Brunba841a12014-04-30 17:05:08 +02003228 /* SSL_get_peer_certificate, it increase X509 * ref count */
3229 if (cert_peer && crt)
Emeric Brun87855892012-10-17 17:39:35 +02003230 X509_free(crt);
3231 return ret;
3232}
Emeric Brun9143d372012-12-20 15:44:16 +01003233
3234/* integer, returns true if current session use a client certificate */
3235static int
3236smp_fetch_ssl_c_used(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
Willy Tarreauef38c392013-07-22 16:29:32 +02003237 const struct arg *args, struct sample *smp, const char *kw)
Emeric Brun9143d372012-12-20 15:44:16 +01003238{
3239 X509 *crt;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003240 struct connection *conn;
Emeric Brun9143d372012-12-20 15:44:16 +01003241
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003242 if (!l4)
Emeric Brun9143d372012-12-20 15:44:16 +01003243 return 0;
3244
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003245 conn = objt_conn(l4->si[0].end);
3246 if (!conn || conn->xprt != &ssl_sock)
3247 return 0;
3248
3249 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brun9143d372012-12-20 15:44:16 +01003250 smp->flags |= SMP_F_MAY_CHANGE;
3251 return 0;
3252 }
3253
3254 /* SSL_get_peer_certificate returns a ptr on allocated X509 struct */
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003255 crt = SSL_get_peer_certificate(conn->xprt_ctx);
Emeric Brun9143d372012-12-20 15:44:16 +01003256 if (crt) {
3257 X509_free(crt);
3258 }
3259
3260 smp->type = SMP_T_BOOL;
3261 smp->data.uint = (crt != NULL);
3262 return 1;
3263}
3264
Emeric Brunba841a12014-04-30 17:05:08 +02003265/* integer, returns the certificate version
3266 * The 5th keyword char is used to know if SSL_get_certificate or SSL_get_peer_certificate
3267 * should be use.
3268 */
Emeric Bruna7359fd2012-10-17 15:03:11 +02003269static int
Emeric Brunba841a12014-04-30 17:05:08 +02003270smp_fetch_ssl_x_version(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
Willy Tarreauef38c392013-07-22 16:29:32 +02003271 const struct arg *args, struct sample *smp, const char *kw)
Emeric Bruna7359fd2012-10-17 15:03:11 +02003272{
Emeric Brunba841a12014-04-30 17:05:08 +02003273 int cert_peer = (kw[4] == 'c') ? 1 : 0;
Emeric Bruna7359fd2012-10-17 15:03:11 +02003274 X509 *crt;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003275 struct connection *conn;
3276
3277 if (!l4)
3278 return 0;
Emeric Bruna7359fd2012-10-17 15:03:11 +02003279
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003280 conn = objt_conn(l4->si[0].end);
3281 if (!conn || conn->xprt != &ssl_sock)
Emeric Bruna7359fd2012-10-17 15:03:11 +02003282 return 0;
3283
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003284 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Bruna7359fd2012-10-17 15:03:11 +02003285 smp->flags |= SMP_F_MAY_CHANGE;
3286 return 0;
3287 }
3288
Emeric Brunba841a12014-04-30 17:05:08 +02003289 if (cert_peer)
3290 crt = SSL_get_peer_certificate(conn->xprt_ctx);
3291 else
3292 crt = SSL_get_certificate(conn->xprt_ctx);
Emeric Bruna7359fd2012-10-17 15:03:11 +02003293 if (!crt)
3294 return 0;
3295
3296 smp->data.uint = (unsigned int)(1 + X509_get_version(crt));
Emeric Brunba841a12014-04-30 17:05:08 +02003297 /* SSL_get_peer_certificate increase X509 * ref count */
3298 if (cert_peer)
3299 X509_free(crt);
Emeric Bruna7359fd2012-10-17 15:03:11 +02003300 smp->type = SMP_T_UINT;
3301
3302 return 1;
3303}
3304
Emeric Brunba841a12014-04-30 17:05:08 +02003305/* string, returns the certificate's signature algorithm.
3306 * The 5th keyword char is used to know if SSL_get_certificate or SSL_get_peer_certificate
3307 * should be use.
3308 */
Emeric Brun7f56e742012-10-19 18:15:40 +02003309static int
Emeric Brunba841a12014-04-30 17:05:08 +02003310smp_fetch_ssl_x_sig_alg(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
Willy Tarreauef38c392013-07-22 16:29:32 +02003311 const struct arg *args, struct sample *smp, const char *kw)
Emeric Brun7f56e742012-10-19 18:15:40 +02003312{
Emeric Brunba841a12014-04-30 17:05:08 +02003313 int cert_peer = (kw[4] == 'c') ? 1 : 0;
Emeric Brun7f56e742012-10-19 18:15:40 +02003314 X509 *crt;
3315 int nid;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003316 struct connection *conn;
Emeric Brun7f56e742012-10-19 18:15:40 +02003317
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003318 if (!l4)
Emeric Brun7f56e742012-10-19 18:15:40 +02003319 return 0;
3320
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003321 conn = objt_conn(l4->si[0].end);
3322 if (!conn || conn->xprt != &ssl_sock)
3323 return 0;
3324
3325 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brun7f56e742012-10-19 18:15:40 +02003326 smp->flags |= SMP_F_MAY_CHANGE;
3327 return 0;
3328 }
3329
Emeric Brunba841a12014-04-30 17:05:08 +02003330 if (cert_peer)
3331 crt = SSL_get_peer_certificate(conn->xprt_ctx);
3332 else
3333 crt = SSL_get_certificate(conn->xprt_ctx);
Emeric Brun7f56e742012-10-19 18:15:40 +02003334 if (!crt)
3335 return 0;
3336
3337 nid = OBJ_obj2nid((ASN1_OBJECT *)(crt->cert_info->signature->algorithm));
3338
3339 smp->data.str.str = (char *)OBJ_nid2sn(nid);
Emeric Brun9bf3ba22013-10-07 14:31:44 +02003340 if (!smp->data.str.str) {
Emeric Brunba841a12014-04-30 17:05:08 +02003341 /* SSL_get_peer_certificate increase X509 * ref count */
3342 if (cert_peer)
3343 X509_free(crt);
Emeric Brun7f56e742012-10-19 18:15:40 +02003344 return 0;
Emeric Brun9bf3ba22013-10-07 14:31:44 +02003345 }
Emeric Brun7f56e742012-10-19 18:15:40 +02003346
Thierry FOURNIER7654c9f2013-12-17 00:20:33 +01003347 smp->type = SMP_T_STR;
3348 smp->flags |= SMP_F_CONST;
Emeric Brun7f56e742012-10-19 18:15:40 +02003349 smp->data.str.len = strlen(smp->data.str.str);
Emeric Brunba841a12014-04-30 17:05:08 +02003350 /* SSL_get_peer_certificate increase X509 * ref count */
3351 if (cert_peer)
3352 X509_free(crt);
Emeric Brun7f56e742012-10-19 18:15:40 +02003353
3354 return 1;
3355}
3356
Emeric Brunba841a12014-04-30 17:05:08 +02003357/* string, returns the certificate's key algorithm.
3358 * The 5th keyword char is used to know if SSL_get_certificate or SSL_get_peer_certificate
3359 * should be use.
3360 */
Emeric Brun521a0112012-10-22 12:22:55 +02003361static int
Emeric Brunba841a12014-04-30 17:05:08 +02003362smp_fetch_ssl_x_key_alg(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
Willy Tarreauef38c392013-07-22 16:29:32 +02003363 const struct arg *args, struct sample *smp, const char *kw)
Emeric Brun521a0112012-10-22 12:22:55 +02003364{
Emeric Brunba841a12014-04-30 17:05:08 +02003365 int cert_peer = (kw[4] == 'c') ? 1 : 0;
Emeric Brun521a0112012-10-22 12:22:55 +02003366 X509 *crt;
3367 int nid;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003368 struct connection *conn;
Emeric Brun521a0112012-10-22 12:22:55 +02003369
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003370 if (!l4)
Emeric Brun521a0112012-10-22 12:22:55 +02003371 return 0;
3372
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003373 conn = objt_conn(l4->si[0].end);
3374 if (!conn || conn->xprt != &ssl_sock)
3375 return 0;
3376
3377 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brun521a0112012-10-22 12:22:55 +02003378 smp->flags |= SMP_F_MAY_CHANGE;
3379 return 0;
3380 }
3381
Emeric Brunba841a12014-04-30 17:05:08 +02003382 if (cert_peer)
3383 crt = SSL_get_peer_certificate(conn->xprt_ctx);
3384 else
3385 crt = SSL_get_certificate(conn->xprt_ctx);
Emeric Brun521a0112012-10-22 12:22:55 +02003386 if (!crt)
3387 return 0;
3388
3389 nid = OBJ_obj2nid((ASN1_OBJECT *)(crt->cert_info->key->algor->algorithm));
3390
3391 smp->data.str.str = (char *)OBJ_nid2sn(nid);
Emeric Brun9bf3ba22013-10-07 14:31:44 +02003392 if (!smp->data.str.str) {
Emeric Brunba841a12014-04-30 17:05:08 +02003393 /* SSL_get_peer_certificate increase X509 * ref count */
3394 if (cert_peer)
3395 X509_free(crt);
Emeric Brun521a0112012-10-22 12:22:55 +02003396 return 0;
Emeric Brun9bf3ba22013-10-07 14:31:44 +02003397 }
Emeric Brun521a0112012-10-22 12:22:55 +02003398
Thierry FOURNIER7654c9f2013-12-17 00:20:33 +01003399 smp->type = SMP_T_STR;
3400 smp->flags |= SMP_F_CONST;
Emeric Brun521a0112012-10-22 12:22:55 +02003401 smp->data.str.len = strlen(smp->data.str.str);
Emeric Brunba841a12014-04-30 17:05:08 +02003402 if (cert_peer)
3403 X509_free(crt);
Emeric Brun521a0112012-10-22 12:22:55 +02003404
3405 return 1;
3406}
3407
Emeric Brun645ae792014-04-30 14:21:06 +02003408/* boolean, returns true if front conn. transport layer is SSL.
3409 * This function is also usable on backend conn if the fetch keyword 5th
3410 * char is 'b'.
3411 */
Willy Tarreau7875d092012-09-10 08:20:03 +02003412static int
Emeric Brun2525b6b2012-10-18 15:59:43 +02003413smp_fetch_ssl_fc(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
Willy Tarreauef38c392013-07-22 16:29:32 +02003414 const struct arg *args, struct sample *smp, const char *kw)
Willy Tarreau7875d092012-09-10 08:20:03 +02003415{
Emeric Brun645ae792014-04-30 14:21:06 +02003416 int back_conn = (kw[4] == 'b') ? 1 : 0;
3417 struct connection *conn = objt_conn(l4->si[back_conn].end);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003418
Willy Tarreau7875d092012-09-10 08:20:03 +02003419 smp->type = SMP_T_BOOL;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003420 smp->data.uint = (conn && conn->xprt == &ssl_sock);
Willy Tarreau7875d092012-09-10 08:20:03 +02003421 return 1;
3422}
3423
Emeric Brun2525b6b2012-10-18 15:59:43 +02003424/* boolean, returns true if client present a SNI */
Willy Tarreau7875d092012-09-10 08:20:03 +02003425static int
Emeric Brun2525b6b2012-10-18 15:59:43 +02003426smp_fetch_ssl_fc_has_sni(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
Willy Tarreauef38c392013-07-22 16:29:32 +02003427 const struct arg *args, struct sample *smp, const char *kw)
Willy Tarreau7875d092012-09-10 08:20:03 +02003428{
3429#ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003430 struct connection *conn = objt_conn(l4->si[0].end);
3431
Willy Tarreau7875d092012-09-10 08:20:03 +02003432 smp->type = SMP_T_BOOL;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003433 smp->data.uint = (conn && conn->xprt == &ssl_sock) &&
3434 conn->xprt_ctx &&
3435 SSL_get_servername(conn->xprt_ctx, TLSEXT_NAMETYPE_host_name) != NULL;
Willy Tarreau7875d092012-09-10 08:20:03 +02003436 return 1;
3437#else
3438 return 0;
3439#endif
3440}
3441
Emeric Brun645ae792014-04-30 14:21:06 +02003442/* string, returns the used cipher if front conn. transport layer is SSL.
3443 * This function is also usable on backend conn if the fetch keyword 5th
3444 * char is 'b'.
3445 */
Emeric Brun589fcad2012-10-16 14:13:26 +02003446static int
3447smp_fetch_ssl_fc_cipher(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
Willy Tarreauef38c392013-07-22 16:29:32 +02003448 const struct arg *args, struct sample *smp, const char *kw)
Emeric Brun589fcad2012-10-16 14:13:26 +02003449{
Emeric Brun645ae792014-04-30 14:21:06 +02003450 int back_conn = (kw[4] == 'b') ? 1 : 0;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003451 struct connection *conn;
3452
Emeric Brun589fcad2012-10-16 14:13:26 +02003453 smp->flags = 0;
3454
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003455 if (!l4)
3456 return 0;
3457
Emeric Brun645ae792014-04-30 14:21:06 +02003458 conn = objt_conn(l4->si[back_conn].end);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003459 if (!conn || !conn->xprt_ctx || conn->xprt != &ssl_sock)
Emeric Brun589fcad2012-10-16 14:13:26 +02003460 return 0;
3461
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003462 smp->data.str.str = (char *)SSL_get_cipher_name(conn->xprt_ctx);
Emeric Brun589fcad2012-10-16 14:13:26 +02003463 if (!smp->data.str.str)
3464 return 0;
3465
Thierry FOURNIER7654c9f2013-12-17 00:20:33 +01003466 smp->type = SMP_T_STR;
3467 smp->flags |= SMP_F_CONST;
Emeric Brun589fcad2012-10-16 14:13:26 +02003468 smp->data.str.len = strlen(smp->data.str.str);
3469
3470 return 1;
3471}
3472
Emeric Brun645ae792014-04-30 14:21:06 +02003473/* integer, returns the algoritm's keysize if front conn. transport layer
3474 * is SSL.
3475 * This function is also usable on backend conn if the fetch keyword 5th
3476 * char is 'b'.
3477 */
Emeric Brun589fcad2012-10-16 14:13:26 +02003478static int
3479smp_fetch_ssl_fc_alg_keysize(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
Willy Tarreauef38c392013-07-22 16:29:32 +02003480 const struct arg *args, struct sample *smp, const char *kw)
Emeric Brun589fcad2012-10-16 14:13:26 +02003481{
Emeric Brun645ae792014-04-30 14:21:06 +02003482 int back_conn = (kw[4] == 'b') ? 1 : 0;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003483 struct connection *conn;
3484
Emeric Brun589fcad2012-10-16 14:13:26 +02003485 smp->flags = 0;
3486
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003487 if (!l4)
Emeric Brun589fcad2012-10-16 14:13:26 +02003488 return 0;
3489
Emeric Brun645ae792014-04-30 14:21:06 +02003490 conn = objt_conn(l4->si[back_conn].end);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003491 if (!conn || !conn->xprt_ctx || conn->xprt != &ssl_sock)
Emeric Brun589fcad2012-10-16 14:13:26 +02003492 return 0;
3493
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003494 if (!SSL_get_cipher_bits(conn->xprt_ctx, (int *)&smp->data.uint))
3495 return 0;
3496
Emeric Brun589fcad2012-10-16 14:13:26 +02003497 smp->type = SMP_T_UINT;
3498
3499 return 1;
3500}
3501
Emeric Brun645ae792014-04-30 14:21:06 +02003502/* integer, returns the used keysize if front conn. transport layer is SSL.
3503 * This function is also usable on backend conn if the fetch keyword 5th
3504 * char is 'b'.
3505 */
Emeric Brun589fcad2012-10-16 14:13:26 +02003506static int
3507smp_fetch_ssl_fc_use_keysize(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
Willy Tarreauef38c392013-07-22 16:29:32 +02003508 const struct arg *args, struct sample *smp, const char *kw)
Emeric Brun589fcad2012-10-16 14:13:26 +02003509{
Emeric Brun645ae792014-04-30 14:21:06 +02003510 int back_conn = (kw[4] == 'b') ? 1 : 0;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003511 struct connection *conn;
3512
Emeric Brun589fcad2012-10-16 14:13:26 +02003513 smp->flags = 0;
3514
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003515 if (!l4)
Emeric Brun589fcad2012-10-16 14:13:26 +02003516 return 0;
3517
Emeric Brun645ae792014-04-30 14:21:06 +02003518 conn = objt_conn(l4->si[back_conn].end);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003519 if (!conn || !conn->xprt_ctx || conn->xprt != &ssl_sock)
3520 return 0;
3521
3522 smp->data.uint = (unsigned int)SSL_get_cipher_bits(conn->xprt_ctx, NULL);
Emeric Brun589fcad2012-10-16 14:13:26 +02003523 if (!smp->data.uint)
3524 return 0;
3525
3526 smp->type = SMP_T_UINT;
3527
3528 return 1;
3529}
3530
Willy Tarreau6c9a3d52012-10-18 18:57:14 +02003531#ifdef OPENSSL_NPN_NEGOTIATED
Willy Tarreau7875d092012-09-10 08:20:03 +02003532static int
Emeric Brun2525b6b2012-10-18 15:59:43 +02003533smp_fetch_ssl_fc_npn(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
Willy Tarreauef38c392013-07-22 16:29:32 +02003534 const struct arg *args, struct sample *smp, const char *kw)
Willy Tarreaua33c6542012-10-15 13:19:06 +02003535{
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003536 struct connection *conn;
3537
Thierry FOURNIER7654c9f2013-12-17 00:20:33 +01003538 smp->flags = SMP_F_CONST;
3539 smp->type = SMP_T_STR;
Willy Tarreaua33c6542012-10-15 13:19:06 +02003540
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003541 if (!l4)
Willy Tarreaua33c6542012-10-15 13:19:06 +02003542 return 0;
3543
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003544 conn = objt_conn(l4->si[0].end);
3545 if (!conn || !conn->xprt_ctx || conn->xprt != &ssl_sock)
3546 return 0;
3547
Willy Tarreaua33c6542012-10-15 13:19:06 +02003548 smp->data.str.str = NULL;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003549 SSL_get0_next_proto_negotiated(conn->xprt_ctx,
Willy Tarreaua33c6542012-10-15 13:19:06 +02003550 (const unsigned char **)&smp->data.str.str, (unsigned *)&smp->data.str.len);
3551
3552 if (!smp->data.str.str)
3553 return 0;
3554
3555 return 1;
Willy Tarreaua33c6542012-10-15 13:19:06 +02003556}
Willy Tarreau6c9a3d52012-10-18 18:57:14 +02003557#endif
Willy Tarreaua33c6542012-10-15 13:19:06 +02003558
Dirkjan Bussink48f1c4e2014-02-13 12:29:42 +01003559#ifdef TLSEXT_TYPE_application_layer_protocol_negotiation
Willy Tarreauab861d32013-04-02 02:30:41 +02003560static int
3561smp_fetch_ssl_fc_alpn(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
Willy Tarreauef38c392013-07-22 16:29:32 +02003562 const struct arg *args, struct sample *smp, const char *kw)
Willy Tarreauab861d32013-04-02 02:30:41 +02003563{
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003564 struct connection *conn;
3565
Thierry FOURNIER7654c9f2013-12-17 00:20:33 +01003566 smp->flags = SMP_F_CONST;
3567 smp->type = SMP_T_STR;
Willy Tarreauab861d32013-04-02 02:30:41 +02003568
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003569 if (!l4)
3570 return 0;
3571
3572 conn = objt_conn(l4->si[0].end);
3573 if (!conn || !conn->xprt_ctx || conn->xprt != &ssl_sock)
Willy Tarreauab861d32013-04-02 02:30:41 +02003574 return 0;
3575
3576 smp->data.str.str = NULL;
Dirkjan Bussink48f1c4e2014-02-13 12:29:42 +01003577 SSL_get0_alpn_selected(conn->xprt_ctx,
Willy Tarreauab861d32013-04-02 02:30:41 +02003578 (const unsigned char **)&smp->data.str.str, (unsigned *)&smp->data.str.len);
3579
3580 if (!smp->data.str.str)
3581 return 0;
3582
3583 return 1;
3584}
3585#endif
3586
Emeric Brun645ae792014-04-30 14:21:06 +02003587/* string, returns the used protocol if front conn. transport layer is SSL.
3588 * This function is also usable on backend conn if the fetch keyword 5th
3589 * char is 'b'.
3590 */
Willy Tarreaua33c6542012-10-15 13:19:06 +02003591static int
Emeric Brun589fcad2012-10-16 14:13:26 +02003592smp_fetch_ssl_fc_protocol(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
Willy Tarreauef38c392013-07-22 16:29:32 +02003593 const struct arg *args, struct sample *smp, const char *kw)
Emeric Brun589fcad2012-10-16 14:13:26 +02003594{
Emeric Brun645ae792014-04-30 14:21:06 +02003595 int back_conn = (kw[4] == 'b') ? 1 : 0;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003596 struct connection *conn;
3597
Emeric Brun589fcad2012-10-16 14:13:26 +02003598 smp->flags = 0;
3599
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003600 if (!l4)
Emeric Brun589fcad2012-10-16 14:13:26 +02003601 return 0;
3602
Emeric Brun645ae792014-04-30 14:21:06 +02003603 conn = objt_conn(l4->si[back_conn].end);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003604 if (!conn || !conn->xprt_ctx || conn->xprt != &ssl_sock)
3605 return 0;
3606
3607 smp->data.str.str = (char *)SSL_get_version(conn->xprt_ctx);
Emeric Brun589fcad2012-10-16 14:13:26 +02003608 if (!smp->data.str.str)
3609 return 0;
3610
Thierry FOURNIER7654c9f2013-12-17 00:20:33 +01003611 smp->type = SMP_T_STR;
3612 smp->flags = SMP_F_CONST;
Emeric Brun589fcad2012-10-16 14:13:26 +02003613 smp->data.str.len = strlen(smp->data.str.str);
3614
3615 return 1;
3616}
3617
Emeric Brun645ae792014-04-30 14:21:06 +02003618/* binary, returns the SSL session id if front conn. transport layer is SSL.
3619 * This function is also usable on backend conn if the fetch keyword 5th
3620 * char is 'b'.
3621 */
Emeric Brun589fcad2012-10-16 14:13:26 +02003622static int
Emeric Brunfe68f682012-10-16 14:59:28 +02003623smp_fetch_ssl_fc_session_id(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
Willy Tarreauef38c392013-07-22 16:29:32 +02003624 const struct arg *args, struct sample *smp, const char *kw)
Emeric Brunfe68f682012-10-16 14:59:28 +02003625{
3626#if OPENSSL_VERSION_NUMBER > 0x0090800fL
Emeric Brun645ae792014-04-30 14:21:06 +02003627 int back_conn = (kw[4] == 'b') ? 1 : 0;
Emeric Brunfe68f682012-10-16 14:59:28 +02003628 SSL_SESSION *sess;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003629 struct connection *conn;
Emeric Brunfe68f682012-10-16 14:59:28 +02003630
Thierry FOURNIER7654c9f2013-12-17 00:20:33 +01003631 smp->flags = SMP_F_CONST;
3632 smp->type = SMP_T_BIN;
Emeric Brunfe68f682012-10-16 14:59:28 +02003633
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003634 if (!l4)
Emeric Brunfe68f682012-10-16 14:59:28 +02003635 return 0;
3636
Emeric Brun645ae792014-04-30 14:21:06 +02003637 conn = objt_conn(l4->si[back_conn].end);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003638 if (!conn || !conn->xprt_ctx || conn->xprt != &ssl_sock)
3639 return 0;
3640
3641 sess = SSL_get_session(conn->xprt_ctx);
Emeric Brunfe68f682012-10-16 14:59:28 +02003642 if (!sess)
3643 return 0;
3644
3645 smp->data.str.str = (char *)SSL_SESSION_get_id(sess, (unsigned int *)&smp->data.str.len);
3646 if (!smp->data.str.str || !&smp->data.str.len)
3647 return 0;
3648
3649 return 1;
3650#else
3651 return 0;
3652#endif
3653}
3654
3655static int
Emeric Brun2525b6b2012-10-18 15:59:43 +02003656smp_fetch_ssl_fc_sni(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
Willy Tarreauef38c392013-07-22 16:29:32 +02003657 const struct arg *args, struct sample *smp, const char *kw)
Willy Tarreau7875d092012-09-10 08:20:03 +02003658{
3659#ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003660 struct connection *conn;
3661
Thierry FOURNIER7654c9f2013-12-17 00:20:33 +01003662 smp->flags = SMP_F_CONST;
3663 smp->type = SMP_T_STR;
Willy Tarreau7875d092012-09-10 08:20:03 +02003664
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003665 if (!l4)
Willy Tarreau7875d092012-09-10 08:20:03 +02003666 return 0;
3667
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003668 conn = objt_conn(l4->si[0].end);
3669 if (!conn || !conn->xprt_ctx || conn->xprt != &ssl_sock)
3670 return 0;
3671
3672 smp->data.str.str = (char *)SSL_get_servername(conn->xprt_ctx, TLSEXT_NAMETYPE_host_name);
Willy Tarreau3e394c92012-09-14 23:56:58 +02003673 if (!smp->data.str.str)
3674 return 0;
3675
Willy Tarreau7875d092012-09-10 08:20:03 +02003676 smp->data.str.len = strlen(smp->data.str.str);
3677 return 1;
3678#else
3679 return 0;
3680#endif
3681}
3682
David Sc1ad52e2014-04-08 18:48:47 -04003683static int
3684smp_fetch_ssl_fc_unique_id(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
3685 const struct arg *args, struct sample *smp, const char *kw)
3686{
3687#if OPENSSL_VERSION_NUMBER > 0x0090800fL
Emeric Brun645ae792014-04-30 14:21:06 +02003688 int back_conn = (kw[4] == 'b') ? 1 : 0;
David Sc1ad52e2014-04-08 18:48:47 -04003689 struct connection *conn;
3690 int finished_len;
David Sc1ad52e2014-04-08 18:48:47 -04003691 struct chunk *finished_trash;
David Sc1ad52e2014-04-08 18:48:47 -04003692
3693 smp->flags = 0;
3694
3695 if (!l4)
3696 return 0;
3697
Emeric Brun645ae792014-04-30 14:21:06 +02003698 conn = objt_conn(l4->si[back_conn].end);
David Sc1ad52e2014-04-08 18:48:47 -04003699 if (!conn || !conn->xprt_ctx || conn->xprt != &ssl_sock)
3700 return 0;
3701
3702 if (!(conn->flags & CO_FL_CONNECTED)) {
3703 smp->flags |= SMP_F_MAY_CHANGE;
3704 return 0;
3705 }
3706
3707 finished_trash = get_trash_chunk();
3708 if (!SSL_session_reused(conn->xprt_ctx))
3709 finished_len = SSL_get_peer_finished(conn->xprt_ctx, finished_trash->str, finished_trash->size);
3710 else
3711 finished_len = SSL_get_finished(conn->xprt_ctx, finished_trash->str, finished_trash->size);
3712
3713 if (!finished_len)
3714 return 0;
3715
Emeric Brunb73a9b02014-04-30 18:49:19 +02003716 finished_trash->len = finished_len;
3717 smp->data.str = *finished_trash;
3718 smp->type = SMP_T_BIN;
David Sc1ad52e2014-04-08 18:48:47 -04003719
3720 return 1;
3721#else
3722 return 0;
3723#endif
3724}
3725
Emeric Brun2525b6b2012-10-18 15:59:43 +02003726/* integer, returns the first verify error in CA chain of client certificate chain. */
Emeric Brunf282a812012-09-21 15:27:54 +02003727static int
Emeric Brun2525b6b2012-10-18 15:59:43 +02003728smp_fetch_ssl_c_ca_err(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
Willy Tarreauef38c392013-07-22 16:29:32 +02003729 const struct arg *args, struct sample *smp, const char *kw)
Emeric Brunf282a812012-09-21 15:27:54 +02003730{
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003731 struct connection *conn;
3732
3733 if (!l4)
Emeric Brunf282a812012-09-21 15:27:54 +02003734 return 0;
3735
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003736 conn = objt_conn(l4->si[0].end);
3737 if (!conn || conn->xprt != &ssl_sock)
3738 return 0;
3739
3740 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brunf282a812012-09-21 15:27:54 +02003741 smp->flags = SMP_F_MAY_CHANGE;
3742 return 0;
3743 }
3744
3745 smp->type = SMP_T_UINT;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003746 smp->data.uint = (unsigned int)SSL_SOCK_ST_TO_CA_ERROR(conn->xprt_st);
Emeric Brunf282a812012-09-21 15:27:54 +02003747 smp->flags = 0;
3748
3749 return 1;
3750}
3751
Emeric Brun2525b6b2012-10-18 15:59:43 +02003752/* integer, returns the depth of the first verify error in CA chain of client certificate chain. */
Emeric Brunf282a812012-09-21 15:27:54 +02003753static int
Emeric Brun2525b6b2012-10-18 15:59:43 +02003754smp_fetch_ssl_c_ca_err_depth(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
Willy Tarreauef38c392013-07-22 16:29:32 +02003755 const struct arg *args, struct sample *smp, const char *kw)
Emeric Brunf282a812012-09-21 15:27:54 +02003756{
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003757 struct connection *conn;
3758
3759 if (!l4)
3760 return 0;
3761
3762 conn = objt_conn(l4->si[0].end);
3763 if (!conn || conn->xprt != &ssl_sock)
Emeric Brunf282a812012-09-21 15:27:54 +02003764 return 0;
3765
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003766 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brunf282a812012-09-21 15:27:54 +02003767 smp->flags = SMP_F_MAY_CHANGE;
3768 return 0;
3769 }
3770
3771 smp->type = SMP_T_UINT;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003772 smp->data.uint = (unsigned int)SSL_SOCK_ST_TO_CAEDEPTH(conn->xprt_st);
Emeric Brunf282a812012-09-21 15:27:54 +02003773 smp->flags = 0;
3774
3775 return 1;
3776}
3777
Emeric Brun2525b6b2012-10-18 15:59:43 +02003778/* integer, returns the first verify error on client certificate */
Emeric Brunf282a812012-09-21 15:27:54 +02003779static int
Emeric Brun2525b6b2012-10-18 15:59:43 +02003780smp_fetch_ssl_c_err(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
Willy Tarreauef38c392013-07-22 16:29:32 +02003781 const struct arg *args, struct sample *smp, const char *kw)
Emeric Brunf282a812012-09-21 15:27:54 +02003782{
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003783 struct connection *conn;
3784
3785 if (!l4)
Emeric Brunf282a812012-09-21 15:27:54 +02003786 return 0;
3787
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003788 conn = objt_conn(l4->si[0].end);
3789 if (!conn || conn->xprt != &ssl_sock)
3790 return 0;
3791
3792 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brunf282a812012-09-21 15:27:54 +02003793 smp->flags = SMP_F_MAY_CHANGE;
3794 return 0;
3795 }
3796
3797 smp->type = SMP_T_UINT;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003798 smp->data.uint = (unsigned int)SSL_SOCK_ST_TO_CRTERROR(conn->xprt_st);
Emeric Brunf282a812012-09-21 15:27:54 +02003799 smp->flags = 0;
3800
3801 return 1;
3802}
3803
Emeric Brun2525b6b2012-10-18 15:59:43 +02003804/* integer, returns the verify result on client cert */
Emeric Brunbaf8ffb2012-09-21 15:27:20 +02003805static int
Emeric Brun2525b6b2012-10-18 15:59:43 +02003806smp_fetch_ssl_c_verify(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
Willy Tarreauef38c392013-07-22 16:29:32 +02003807 const struct arg *args, struct sample *smp, const char *kw)
Emeric Brunbaf8ffb2012-09-21 15:27:20 +02003808{
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003809 struct connection *conn;
3810
3811 if (!l4)
Emeric Brunbaf8ffb2012-09-21 15:27:20 +02003812 return 0;
3813
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003814 conn = objt_conn(l4->si[0].end);
3815 if (!conn || conn->xprt != &ssl_sock)
3816 return 0;
3817
3818 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brunbaf8ffb2012-09-21 15:27:20 +02003819 smp->flags = SMP_F_MAY_CHANGE;
3820 return 0;
3821 }
3822
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003823 if (!conn->xprt_ctx)
Emeric Brunbaf8ffb2012-09-21 15:27:20 +02003824 return 0;
3825
3826 smp->type = SMP_T_UINT;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003827 smp->data.uint = (unsigned int)SSL_get_verify_result(conn->xprt_ctx);
Emeric Brunbaf8ffb2012-09-21 15:27:20 +02003828 smp->flags = 0;
3829
3830 return 1;
3831}
3832
Emeric Brunfb510ea2012-10-05 12:00:26 +02003833/* parse the "ca-file" bind keyword */
3834static 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 +02003835{
3836 if (!*args[cur_arg + 1]) {
3837 if (err)
3838 memprintf(err, "'%s' : missing CAfile path", args[cur_arg]);
3839 return ERR_ALERT | ERR_FATAL;
3840 }
3841
Emeric Brunef42d922012-10-11 16:11:36 +02003842 if ((*args[cur_arg + 1] != '/') && global.ca_base)
3843 memprintf(&conf->ca_file, "%s/%s", global.ca_base, args[cur_arg + 1]);
3844 else
3845 memprintf(&conf->ca_file, "%s", args[cur_arg + 1]);
Emeric Brunc8e8d122012-10-02 18:42:10 +02003846
Emeric Brund94b3fe2012-09-20 18:23:56 +02003847 return 0;
3848}
3849
Willy Tarreau79eeafa2012-09-14 07:53:05 +02003850/* parse the "ciphers" bind keyword */
Willy Tarreau4348fad2012-09-20 16:48:07 +02003851static 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 +02003852{
3853 if (!*args[cur_arg + 1]) {
Willy Tarreaueb6cead2012-09-20 19:43:14 +02003854 memprintf(err, "'%s' : missing cipher suite", args[cur_arg]);
Willy Tarreau79eeafa2012-09-14 07:53:05 +02003855 return ERR_ALERT | ERR_FATAL;
3856 }
3857
Emeric Brun76d88952012-10-05 15:47:31 +02003858 free(conf->ciphers);
Willy Tarreau4348fad2012-09-20 16:48:07 +02003859 conf->ciphers = strdup(args[cur_arg + 1]);
Willy Tarreau79eeafa2012-09-14 07:53:05 +02003860 return 0;
3861}
3862
3863/* parse the "crt" bind keyword */
Willy Tarreau4348fad2012-09-20 16:48:07 +02003864static 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 +02003865{
Willy Tarreau38011032013-08-13 16:59:39 +02003866 char path[MAXPATHLEN];
Willy Tarreaub75d6922014-04-14 18:05:41 +02003867
Willy Tarreau79eeafa2012-09-14 07:53:05 +02003868 if (!*args[cur_arg + 1]) {
Willy Tarreaueb6cead2012-09-20 19:43:14 +02003869 memprintf(err, "'%s' : missing certificate location", args[cur_arg]);
Willy Tarreau79eeafa2012-09-14 07:53:05 +02003870 return ERR_ALERT | ERR_FATAL;
3871 }
3872
Emeric Brunc8e8d122012-10-02 18:42:10 +02003873 if ((*args[cur_arg + 1] != '/' ) && global.crt_base) {
Willy Tarreau38011032013-08-13 16:59:39 +02003874 if ((strlen(global.crt_base) + 1 + strlen(args[cur_arg + 1]) + 1) > MAXPATHLEN) {
Emeric Brunc8e8d122012-10-02 18:42:10 +02003875 memprintf(err, "'%s' : path too long", args[cur_arg]);
3876 return ERR_ALERT | ERR_FATAL;
3877 }
Willy Tarreaub75d6922014-04-14 18:05:41 +02003878 snprintf(path, sizeof(path), "%s/%s", global.crt_base, args[cur_arg + 1]);
Emeric Brunc8e8d122012-10-02 18:42:10 +02003879 if (ssl_sock_load_cert(path, conf, px, err) > 0)
3880 return ERR_ALERT | ERR_FATAL;
3881
3882 return 0;
3883 }
3884
Willy Tarreau4348fad2012-09-20 16:48:07 +02003885 if (ssl_sock_load_cert(args[cur_arg + 1], conf, px, err) > 0)
Willy Tarreau79eeafa2012-09-14 07:53:05 +02003886 return ERR_ALERT | ERR_FATAL;
Emeric Brund94b3fe2012-09-20 18:23:56 +02003887
3888 return 0;
3889}
3890
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01003891/* parse the "crt-list" bind keyword */
3892static int bind_parse_crt_list(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
3893{
3894 if (!*args[cur_arg + 1]) {
3895 memprintf(err, "'%s' : missing certificate location", args[cur_arg]);
3896 return ERR_ALERT | ERR_FATAL;
3897 }
3898
Willy Tarreauad1731d2013-04-02 17:35:58 +02003899 if (ssl_sock_load_cert_list_file(args[cur_arg + 1], conf, px, err) > 0) {
3900 memprintf(err, "'%s' : %s", args[cur_arg], *err);
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01003901 return ERR_ALERT | ERR_FATAL;
Willy Tarreauad1731d2013-04-02 17:35:58 +02003902 }
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01003903
3904 return 0;
3905}
3906
Emeric Brunfb510ea2012-10-05 12:00:26 +02003907/* parse the "crl-file" bind keyword */
3908static 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 +02003909{
Emeric Brun051cdab2012-10-02 19:25:50 +02003910#ifndef X509_V_FLAG_CRL_CHECK
3911 if (err)
3912 memprintf(err, "'%s' : library does not support CRL verify", args[cur_arg]);
3913 return ERR_ALERT | ERR_FATAL;
3914#else
Emeric Brund94b3fe2012-09-20 18:23:56 +02003915 if (!*args[cur_arg + 1]) {
3916 if (err)
3917 memprintf(err, "'%s' : missing CRLfile path", args[cur_arg]);
3918 return ERR_ALERT | ERR_FATAL;
3919 }
Emeric Brun2b58d042012-09-20 17:10:03 +02003920
Emeric Brunef42d922012-10-11 16:11:36 +02003921 if ((*args[cur_arg + 1] != '/') && global.ca_base)
3922 memprintf(&conf->crl_file, "%s/%s", global.ca_base, args[cur_arg + 1]);
3923 else
3924 memprintf(&conf->crl_file, "%s", args[cur_arg + 1]);
Emeric Brunc8e8d122012-10-02 18:42:10 +02003925
Emeric Brun2b58d042012-09-20 17:10:03 +02003926 return 0;
Emeric Brun051cdab2012-10-02 19:25:50 +02003927#endif
Emeric Brun2b58d042012-09-20 17:10:03 +02003928}
3929
3930/* parse the "ecdhe" bind keyword keywords */
3931static int bind_parse_ecdhe(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
3932{
3933#if OPENSSL_VERSION_NUMBER < 0x0090800fL
3934 if (err)
3935 memprintf(err, "'%s' : library does not support elliptic curve Diffie-Hellman (too old)", args[cur_arg]);
3936 return ERR_ALERT | ERR_FATAL;
3937#elif defined(OPENSSL_NO_ECDH)
3938 if (err)
3939 memprintf(err, "'%s' : library does not support elliptic curve Diffie-Hellman (disabled via OPENSSL_NO_ECDH)", args[cur_arg]);
3940 return ERR_ALERT | ERR_FATAL;
3941#else
3942 if (!*args[cur_arg + 1]) {
3943 if (err)
3944 memprintf(err, "'%s' : missing named curve", args[cur_arg]);
3945 return ERR_ALERT | ERR_FATAL;
3946 }
3947
3948 conf->ecdhe = strdup(args[cur_arg + 1]);
Willy Tarreau79eeafa2012-09-14 07:53:05 +02003949
3950 return 0;
Emeric Brun2b58d042012-09-20 17:10:03 +02003951#endif
Willy Tarreau79eeafa2012-09-14 07:53:05 +02003952}
3953
Emeric Brun81c00f02012-09-21 14:31:21 +02003954/* parse the "crt_ignerr" and "ca_ignerr" bind keywords */
3955static int bind_parse_ignore_err(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
3956{
3957 int code;
3958 char *p = args[cur_arg + 1];
3959 unsigned long long *ignerr = &conf->crt_ignerr;
3960
3961 if (!*p) {
3962 if (err)
3963 memprintf(err, "'%s' : missing error IDs list", args[cur_arg]);
3964 return ERR_ALERT | ERR_FATAL;
3965 }
3966
3967 if (strcmp(args[cur_arg], "ca-ignore-err") == 0)
3968 ignerr = &conf->ca_ignerr;
3969
3970 if (strcmp(p, "all") == 0) {
3971 *ignerr = ~0ULL;
3972 return 0;
3973 }
3974
3975 while (p) {
3976 code = atoi(p);
3977 if ((code <= 0) || (code > 63)) {
3978 if (err)
3979 memprintf(err, "'%s' : ID '%d' out of range (1..63) in error IDs list '%s'",
3980 args[cur_arg], code, args[cur_arg + 1]);
3981 return ERR_ALERT | ERR_FATAL;
3982 }
3983 *ignerr |= 1ULL << code;
3984 p = strchr(p, ',');
3985 if (p)
3986 p++;
3987 }
3988
Emeric Brun2cb7ae52012-10-05 14:14:21 +02003989 return 0;
3990}
3991
3992/* parse the "force-sslv3" bind keyword */
3993static int bind_parse_force_sslv3(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
3994{
3995 conf->ssl_options |= BC_SSL_O_USE_SSLV3;
3996 return 0;
3997}
3998
3999/* parse the "force-tlsv10" bind keyword */
4000static int bind_parse_force_tlsv10(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
4001{
4002 conf->ssl_options |= BC_SSL_O_USE_TLSV10;
Emeric Brun2d0c4822012-10-02 13:45:20 +02004003 return 0;
4004}
4005
Emeric Brun2cb7ae52012-10-05 14:14:21 +02004006/* parse the "force-tlsv11" bind keyword */
4007static int bind_parse_force_tlsv11(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
4008{
4009#if SSL_OP_NO_TLSv1_1
4010 conf->ssl_options |= BC_SSL_O_USE_TLSV11;
4011 return 0;
4012#else
4013 if (err)
4014 memprintf(err, "'%s' : library does not support protocol TLSv1.1", args[cur_arg]);
4015 return ERR_ALERT | ERR_FATAL;
4016#endif
4017}
4018
4019/* parse the "force-tlsv12" bind keyword */
4020static int bind_parse_force_tlsv12(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
4021{
4022#if SSL_OP_NO_TLSv1_2
4023 conf->ssl_options |= BC_SSL_O_USE_TLSV12;
4024 return 0;
4025#else
4026 if (err)
4027 memprintf(err, "'%s' : library does not support protocol TLSv1.2", args[cur_arg]);
4028 return ERR_ALERT | ERR_FATAL;
4029#endif
4030}
4031
4032
Emeric Brun2d0c4822012-10-02 13:45:20 +02004033/* parse the "no-tls-tickets" bind keyword */
4034static int bind_parse_no_tls_tickets(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
4035{
Emeric Brun89675492012-10-05 13:48:26 +02004036 conf->ssl_options |= BC_SSL_O_NO_TLS_TICKETS;
Emeric Brun81c00f02012-09-21 14:31:21 +02004037 return 0;
4038}
4039
Emeric Brun2d0c4822012-10-02 13:45:20 +02004040
Emeric Brun9b3009b2012-10-05 11:55:06 +02004041/* parse the "no-sslv3" bind keyword */
4042static 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 +02004043{
Emeric Brun89675492012-10-05 13:48:26 +02004044 conf->ssl_options |= BC_SSL_O_NO_SSLV3;
Willy Tarreau79eeafa2012-09-14 07:53:05 +02004045 return 0;
4046}
4047
Emeric Brun9b3009b2012-10-05 11:55:06 +02004048/* parse the "no-tlsv10" bind keyword */
4049static 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 +02004050{
Emeric Brun89675492012-10-05 13:48:26 +02004051 conf->ssl_options |= BC_SSL_O_NO_TLSV10;
Emeric Brunc0ff4922012-09-28 19:37:02 +02004052 return 0;
4053}
4054
Emeric Brun9b3009b2012-10-05 11:55:06 +02004055/* parse the "no-tlsv11" bind keyword */
4056static 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 +02004057{
Emeric Brun89675492012-10-05 13:48:26 +02004058 conf->ssl_options |= BC_SSL_O_NO_TLSV11;
Emeric Brunc0ff4922012-09-28 19:37:02 +02004059 return 0;
4060}
4061
Emeric Brun9b3009b2012-10-05 11:55:06 +02004062/* parse the "no-tlsv12" bind keyword */
4063static 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 +02004064{
Emeric Brun89675492012-10-05 13:48:26 +02004065 conf->ssl_options |= BC_SSL_O_NO_TLSV12;
Willy Tarreau79eeafa2012-09-14 07:53:05 +02004066 return 0;
4067}
4068
Willy Tarreau6c9a3d52012-10-18 18:57:14 +02004069/* parse the "npn" bind keyword */
4070static int bind_parse_npn(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
4071{
4072#ifdef OPENSSL_NPN_NEGOTIATED
4073 char *p1, *p2;
4074
4075 if (!*args[cur_arg + 1]) {
4076 memprintf(err, "'%s' : missing the comma-delimited NPN protocol suite", args[cur_arg]);
4077 return ERR_ALERT | ERR_FATAL;
4078 }
4079
4080 free(conf->npn_str);
4081
4082 /* the NPN string is built as a suite of (<len> <name>)* */
4083 conf->npn_len = strlen(args[cur_arg + 1]) + 1;
4084 conf->npn_str = calloc(1, conf->npn_len);
4085 memcpy(conf->npn_str + 1, args[cur_arg + 1], conf->npn_len);
4086
4087 /* replace commas with the name length */
4088 p1 = conf->npn_str;
4089 p2 = p1 + 1;
4090 while (1) {
4091 p2 = memchr(p1 + 1, ',', conf->npn_str + conf->npn_len - (p1 + 1));
4092 if (!p2)
4093 p2 = p1 + 1 + strlen(p1 + 1);
4094
4095 if (p2 - (p1 + 1) > 255) {
4096 *p2 = '\0';
4097 memprintf(err, "'%s' : NPN protocol name too long : '%s'", args[cur_arg], p1 + 1);
4098 return ERR_ALERT | ERR_FATAL;
4099 }
4100
4101 *p1 = p2 - (p1 + 1);
4102 p1 = p2;
4103
4104 if (!*p2)
4105 break;
4106
4107 *(p2++) = '\0';
4108 }
4109 return 0;
4110#else
4111 if (err)
4112 memprintf(err, "'%s' : library does not support TLS NPN extension", args[cur_arg]);
4113 return ERR_ALERT | ERR_FATAL;
4114#endif
4115}
4116
Willy Tarreauab861d32013-04-02 02:30:41 +02004117/* parse the "alpn" bind keyword */
4118static int bind_parse_alpn(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
4119{
Dirkjan Bussink48f1c4e2014-02-13 12:29:42 +01004120#ifdef TLSEXT_TYPE_application_layer_protocol_negotiation
Willy Tarreauab861d32013-04-02 02:30:41 +02004121 char *p1, *p2;
4122
4123 if (!*args[cur_arg + 1]) {
4124 memprintf(err, "'%s' : missing the comma-delimited ALPN protocol suite", args[cur_arg]);
4125 return ERR_ALERT | ERR_FATAL;
4126 }
4127
4128 free(conf->alpn_str);
4129
4130 /* the ALPN string is built as a suite of (<len> <name>)* */
4131 conf->alpn_len = strlen(args[cur_arg + 1]) + 1;
4132 conf->alpn_str = calloc(1, conf->alpn_len);
4133 memcpy(conf->alpn_str + 1, args[cur_arg + 1], conf->alpn_len);
4134
4135 /* replace commas with the name length */
4136 p1 = conf->alpn_str;
4137 p2 = p1 + 1;
4138 while (1) {
4139 p2 = memchr(p1 + 1, ',', conf->alpn_str + conf->alpn_len - (p1 + 1));
4140 if (!p2)
4141 p2 = p1 + 1 + strlen(p1 + 1);
4142
4143 if (p2 - (p1 + 1) > 255) {
4144 *p2 = '\0';
4145 memprintf(err, "'%s' : ALPN protocol name too long : '%s'", args[cur_arg], p1 + 1);
4146 return ERR_ALERT | ERR_FATAL;
4147 }
4148
4149 *p1 = p2 - (p1 + 1);
4150 p1 = p2;
4151
4152 if (!*p2)
4153 break;
4154
4155 *(p2++) = '\0';
4156 }
4157 return 0;
4158#else
4159 if (err)
4160 memprintf(err, "'%s' : library does not support TLS ALPN extension", args[cur_arg]);
4161 return ERR_ALERT | ERR_FATAL;
4162#endif
4163}
4164
Willy Tarreau79eeafa2012-09-14 07:53:05 +02004165/* parse the "ssl" bind keyword */
Willy Tarreau4348fad2012-09-20 16:48:07 +02004166static 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 +02004167{
Willy Tarreau81796be2012-09-22 19:11:47 +02004168 struct listener *l;
4169
Willy Tarreau4348fad2012-09-20 16:48:07 +02004170 conf->is_ssl = 1;
Emeric Brun76d88952012-10-05 15:47:31 +02004171
4172 if (global.listen_default_ciphers && !conf->ciphers)
4173 conf->ciphers = strdup(global.listen_default_ciphers);
Emeric Brun42a3e202014-10-30 15:56:50 +01004174 conf->ssl_options |= global.listen_default_ssloptions;
Emeric Brun76d88952012-10-05 15:47:31 +02004175
Willy Tarreau81796be2012-09-22 19:11:47 +02004176 list_for_each_entry(l, &conf->listeners, by_bind)
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02004177 l->xprt = &ssl_sock;
Willy Tarreau81796be2012-09-22 19:11:47 +02004178
Willy Tarreau79eeafa2012-09-14 07:53:05 +02004179 return 0;
4180}
4181
Emmanuel Hocdet65623372013-01-24 17:17:15 +01004182/* parse the "strict-sni" bind keyword */
4183static int bind_parse_strict_sni(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
4184{
4185 conf->strict_sni = 1;
4186 return 0;
4187}
4188
Emeric Brund94b3fe2012-09-20 18:23:56 +02004189/* parse the "verify" bind keyword */
4190static int bind_parse_verify(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
4191{
4192 if (!*args[cur_arg + 1]) {
4193 if (err)
4194 memprintf(err, "'%s' : missing verify method", args[cur_arg]);
4195 return ERR_ALERT | ERR_FATAL;
4196 }
4197
4198 if (strcmp(args[cur_arg + 1], "none") == 0)
Emeric Brun850efd52014-01-29 12:24:34 +01004199 conf->verify = SSL_SOCK_VERIFY_NONE;
Emeric Brund94b3fe2012-09-20 18:23:56 +02004200 else if (strcmp(args[cur_arg + 1], "optional") == 0)
Emeric Brun850efd52014-01-29 12:24:34 +01004201 conf->verify = SSL_SOCK_VERIFY_OPTIONAL;
Emeric Brund94b3fe2012-09-20 18:23:56 +02004202 else if (strcmp(args[cur_arg + 1], "required") == 0)
Emeric Brun850efd52014-01-29 12:24:34 +01004203 conf->verify = SSL_SOCK_VERIFY_REQUIRED;
Emeric Brund94b3fe2012-09-20 18:23:56 +02004204 else {
4205 if (err)
4206 memprintf(err, "'%s' : unknown verify method '%s', only 'none', 'optional', and 'required' are supported\n",
4207 args[cur_arg], args[cur_arg + 1]);
4208 return ERR_ALERT | ERR_FATAL;
4209 }
4210
4211 return 0;
4212}
4213
Willy Tarreau92faadf2012-10-10 23:04:25 +02004214/************** "server" keywords ****************/
4215
Emeric Brunef42d922012-10-11 16:11:36 +02004216/* parse the "ca-file" server keyword */
4217static int srv_parse_ca_file(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
4218{
4219 if (!*args[*cur_arg + 1]) {
4220 if (err)
4221 memprintf(err, "'%s' : missing CAfile path", args[*cur_arg]);
4222 return ERR_ALERT | ERR_FATAL;
4223 }
4224
4225 if ((*args[*cur_arg + 1] != '/') && global.ca_base)
4226 memprintf(&newsrv->ssl_ctx.ca_file, "%s/%s", global.ca_base, args[*cur_arg + 1]);
4227 else
4228 memprintf(&newsrv->ssl_ctx.ca_file, "%s", args[*cur_arg + 1]);
4229
4230 return 0;
4231}
4232
Willy Tarreau92faadf2012-10-10 23:04:25 +02004233/* parse the "check-ssl" server keyword */
4234static int srv_parse_check_ssl(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
4235{
4236 newsrv->check.use_ssl = 1;
4237 if (global.connect_default_ciphers && !newsrv->ssl_ctx.ciphers)
4238 newsrv->ssl_ctx.ciphers = strdup(global.connect_default_ciphers);
Emeric Brun42a3e202014-10-30 15:56:50 +01004239 newsrv->ssl_ctx.options |= global.connect_default_ssloptions;
Willy Tarreau92faadf2012-10-10 23:04:25 +02004240 return 0;
4241}
4242
4243/* parse the "ciphers" server keyword */
4244static int srv_parse_ciphers(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
4245{
4246 if (!*args[*cur_arg + 1]) {
4247 memprintf(err, "'%s' : missing cipher suite", args[*cur_arg]);
4248 return ERR_ALERT | ERR_FATAL;
4249 }
4250
4251 free(newsrv->ssl_ctx.ciphers);
4252 newsrv->ssl_ctx.ciphers = strdup(args[*cur_arg + 1]);
4253 return 0;
4254}
4255
Emeric Brunef42d922012-10-11 16:11:36 +02004256/* parse the "crl-file" server keyword */
4257static int srv_parse_crl_file(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
4258{
4259#ifndef X509_V_FLAG_CRL_CHECK
4260 if (err)
4261 memprintf(err, "'%s' : library does not support CRL verify", args[*cur_arg]);
4262 return ERR_ALERT | ERR_FATAL;
4263#else
4264 if (!*args[*cur_arg + 1]) {
4265 if (err)
4266 memprintf(err, "'%s' : missing CRLfile path", args[*cur_arg]);
4267 return ERR_ALERT | ERR_FATAL;
4268 }
4269
4270 if ((*args[*cur_arg + 1] != '/') && global.ca_base)
4271 memprintf(&newsrv->ssl_ctx.crl_file, "%s/%s", global.ca_base, args[*cur_arg + 1]);
4272 else
4273 memprintf(&newsrv->ssl_ctx.crl_file, "%s", args[*cur_arg + 1]);
4274
4275 return 0;
4276#endif
4277}
4278
Emeric Bruna7aa3092012-10-26 12:58:00 +02004279/* parse the "crt" server keyword */
4280static int srv_parse_crt(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
4281{
4282 if (!*args[*cur_arg + 1]) {
4283 if (err)
4284 memprintf(err, "'%s' : missing certificate file path", args[*cur_arg]);
4285 return ERR_ALERT | ERR_FATAL;
4286 }
4287
4288 if ((*args[*cur_arg + 1] != '/') && global.crt_base)
4289 memprintf(&newsrv->ssl_ctx.client_crt, "%s/%s", global.ca_base, args[*cur_arg + 1]);
4290 else
4291 memprintf(&newsrv->ssl_ctx.client_crt, "%s", args[*cur_arg + 1]);
4292
4293 return 0;
4294}
Emeric Brunef42d922012-10-11 16:11:36 +02004295
Willy Tarreau92faadf2012-10-10 23:04:25 +02004296/* parse the "force-sslv3" server keyword */
4297static int srv_parse_force_sslv3(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
4298{
4299 newsrv->ssl_ctx.options |= SRV_SSL_O_USE_SSLV3;
4300 return 0;
4301}
4302
4303/* parse the "force-tlsv10" server keyword */
4304static int srv_parse_force_tlsv10(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
4305{
4306 newsrv->ssl_ctx.options |= SRV_SSL_O_USE_TLSV10;
4307 return 0;
4308}
4309
4310/* parse the "force-tlsv11" server keyword */
4311static int srv_parse_force_tlsv11(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
4312{
4313#if SSL_OP_NO_TLSv1_1
4314 newsrv->ssl_ctx.options |= SRV_SSL_O_USE_TLSV11;
4315 return 0;
4316#else
4317 if (err)
4318 memprintf(err, "'%s' : library does not support protocol TLSv1.1", args[*cur_arg]);
4319 return ERR_ALERT | ERR_FATAL;
4320#endif
4321}
4322
4323/* parse the "force-tlsv12" server keyword */
4324static int srv_parse_force_tlsv12(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
4325{
4326#if SSL_OP_NO_TLSv1_2
4327 newsrv->ssl_ctx.options |= SRV_SSL_O_USE_TLSV12;
4328 return 0;
4329#else
4330 if (err)
4331 memprintf(err, "'%s' : library does not support protocol TLSv1.2", args[*cur_arg]);
4332 return ERR_ALERT | ERR_FATAL;
4333#endif
4334}
4335
4336/* parse the "no-sslv3" server keyword */
4337static int srv_parse_no_sslv3(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
4338{
4339 newsrv->ssl_ctx.options |= SRV_SSL_O_NO_SSLV3;
4340 return 0;
4341}
4342
4343/* parse the "no-tlsv10" server keyword */
4344static int srv_parse_no_tlsv10(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
4345{
4346 newsrv->ssl_ctx.options |= SRV_SSL_O_NO_TLSV10;
4347 return 0;
4348}
4349
4350/* parse the "no-tlsv11" server keyword */
4351static int srv_parse_no_tlsv11(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
4352{
4353 newsrv->ssl_ctx.options |= SRV_SSL_O_NO_TLSV11;
4354 return 0;
4355}
4356
4357/* parse the "no-tlsv12" server keyword */
4358static int srv_parse_no_tlsv12(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
4359{
4360 newsrv->ssl_ctx.options |= SRV_SSL_O_NO_TLSV12;
4361 return 0;
4362}
4363
Emeric Brunf9c5c472012-10-11 15:28:34 +02004364/* parse the "no-tls-tickets" server keyword */
4365static int srv_parse_no_tls_tickets(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
4366{
4367 newsrv->ssl_ctx.options |= SRV_SSL_O_NO_TLS_TICKETS;
4368 return 0;
4369}
David Safb76832014-05-08 23:42:08 -04004370/* parse the "send-proxy-v2-ssl" server keyword */
4371static int srv_parse_send_proxy_ssl(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
4372{
4373 newsrv->pp_opts |= SRV_PP_V2;
4374 newsrv->pp_opts |= SRV_PP_V2_SSL;
4375 return 0;
4376}
4377
4378/* parse the "send-proxy-v2-ssl-cn" server keyword */
4379static int srv_parse_send_proxy_cn(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
4380{
4381 newsrv->pp_opts |= SRV_PP_V2;
4382 newsrv->pp_opts |= SRV_PP_V2_SSL;
4383 newsrv->pp_opts |= SRV_PP_V2_SSL_CN;
4384 return 0;
4385}
Emeric Brunf9c5c472012-10-11 15:28:34 +02004386
Willy Tarreau92faadf2012-10-10 23:04:25 +02004387/* parse the "ssl" server keyword */
4388static int srv_parse_ssl(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
4389{
4390 newsrv->use_ssl = 1;
4391 if (global.connect_default_ciphers && !newsrv->ssl_ctx.ciphers)
4392 newsrv->ssl_ctx.ciphers = strdup(global.connect_default_ciphers);
4393 return 0;
4394}
4395
Emeric Brunef42d922012-10-11 16:11:36 +02004396/* parse the "verify" server keyword */
4397static int srv_parse_verify(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
4398{
4399 if (!*args[*cur_arg + 1]) {
4400 if (err)
4401 memprintf(err, "'%s' : missing verify method", args[*cur_arg]);
4402 return ERR_ALERT | ERR_FATAL;
4403 }
4404
4405 if (strcmp(args[*cur_arg + 1], "none") == 0)
Emeric Brun850efd52014-01-29 12:24:34 +01004406 newsrv->ssl_ctx.verify = SSL_SOCK_VERIFY_NONE;
Emeric Brunef42d922012-10-11 16:11:36 +02004407 else if (strcmp(args[*cur_arg + 1], "required") == 0)
Emeric Brun850efd52014-01-29 12:24:34 +01004408 newsrv->ssl_ctx.verify = SSL_SOCK_VERIFY_REQUIRED;
Emeric Brunef42d922012-10-11 16:11:36 +02004409 else {
4410 if (err)
4411 memprintf(err, "'%s' : unknown verify method '%s', only 'none' and 'required' are supported\n",
4412 args[*cur_arg], args[*cur_arg + 1]);
4413 return ERR_ALERT | ERR_FATAL;
4414 }
4415
Evan Broderbe554312013-06-27 00:05:25 -07004416 return 0;
4417}
4418
4419/* parse the "verifyhost" server keyword */
4420static int srv_parse_verifyhost(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
4421{
4422 if (!*args[*cur_arg + 1]) {
4423 if (err)
4424 memprintf(err, "'%s' : missing hostname to verify against", args[*cur_arg]);
4425 return ERR_ALERT | ERR_FATAL;
4426 }
4427
4428 newsrv->ssl_ctx.verify_host = strdup(args[*cur_arg + 1]);
4429
Emeric Brunef42d922012-10-11 16:11:36 +02004430 return 0;
4431}
4432
Emeric Brun42a3e202014-10-30 15:56:50 +01004433/* parse the "ssl-default-bind-options" keyword in global section */
4434static int ssl_parse_default_bind_options(char **args, int section_type, struct proxy *curpx,
4435 struct proxy *defpx, const char *file, int line,
4436 char **err) {
4437 int i = 1;
4438
4439 if (*(args[i]) == 0) {
4440 memprintf(err, "global statement '%s' expects an option as an argument.", args[0]);
4441 return -1;
4442 }
4443 while (*(args[i])) {
4444 if (!strcmp(args[i], "no-sslv3"))
4445 global.listen_default_ssloptions |= BC_SSL_O_NO_SSLV3;
4446 else if (!strcmp(args[i], "no-tlsv10"))
4447 global.listen_default_ssloptions |= BC_SSL_O_NO_TLSV10;
4448 else if (!strcmp(args[i], "no-tlsv11"))
4449 global.listen_default_ssloptions |= BC_SSL_O_NO_TLSV11;
4450 else if (!strcmp(args[i], "no-tlsv12"))
4451 global.listen_default_ssloptions |= BC_SSL_O_NO_TLSV12;
4452 else if (!strcmp(args[i], "force-sslv3"))
4453 global.listen_default_ssloptions |= BC_SSL_O_USE_SSLV3;
4454 else if (!strcmp(args[i], "force-tlsv10"))
4455 global.listen_default_ssloptions |= BC_SSL_O_USE_TLSV10;
4456 else if (!strcmp(args[i], "force-tlsv11")) {
4457#if SSL_OP_NO_TLSv1_1
4458 global.listen_default_ssloptions |= BC_SSL_O_USE_TLSV11;
4459#else
4460 memprintf(err, "'%s' '%s': library does not support protocol TLSv1.1", args[0], args[i]);
4461 return -1;
4462#endif
4463 }
4464 else if (!strcmp(args[i], "force-tlsv12")) {
4465#if SSL_OP_NO_TLSv1_2
4466 global.listen_default_ssloptions |= BC_SSL_O_USE_TLSV12;
4467#else
4468 memprintf(err, "'%s' '%s': library does not support protocol TLSv1.2", args[0], args[i]);
4469 return -1;
4470#endif
4471 }
4472 else if (!strcmp(args[i], "no-tls-tickets"))
4473 global.listen_default_ssloptions |= BC_SSL_O_NO_TLS_TICKETS;
4474 else {
4475 memprintf(err, "unknown option '%s' on global statement '%s'.", args[i], args[0]);
4476 return -1;
4477 }
4478 i++;
4479 }
4480 return 0;
4481}
4482
4483/* parse the "ssl-default-server-options" keyword in global section */
4484static int ssl_parse_default_server_options(char **args, int section_type, struct proxy *curpx,
4485 struct proxy *defpx, const char *file, int line,
4486 char **err) {
4487 int i = 1;
4488
4489 if (*(args[i]) == 0) {
4490 memprintf(err, "global statement '%s' expects an option as an argument.", args[0]);
4491 return -1;
4492 }
4493 while (*(args[i])) {
4494 if (!strcmp(args[i], "no-sslv3"))
4495 global.connect_default_ssloptions |= SRV_SSL_O_NO_SSLV3;
4496 else if (!strcmp(args[i], "no-tlsv10"))
4497 global.connect_default_ssloptions |= SRV_SSL_O_NO_TLSV10;
4498 else if (!strcmp(args[i], "no-tlsv11"))
4499 global.connect_default_ssloptions |= SRV_SSL_O_NO_TLSV11;
4500 else if (!strcmp(args[i], "no-tlsv12"))
4501 global.connect_default_ssloptions |= SRV_SSL_O_NO_TLSV12;
4502 else if (!strcmp(args[i], "force-sslv3"))
4503 global.connect_default_ssloptions |= SRV_SSL_O_USE_SSLV3;
4504 else if (!strcmp(args[i], "force-tlsv10"))
4505 global.connect_default_ssloptions |= SRV_SSL_O_USE_TLSV10;
4506 else if (!strcmp(args[i], "force-tlsv11")) {
4507#if SSL_OP_NO_TLSv1_1
4508 global.connect_default_ssloptions |= SRV_SSL_O_USE_TLSV11;
4509#else
4510 memprintf(err, "'%s' '%s': library does not support protocol TLSv1.1", args[0], args[i]);
4511 return -1;
4512#endif
4513 }
4514 else if (!strcmp(args[i], "force-tlsv12")) {
4515#if SSL_OP_NO_TLSv1_2
4516 global.connect_default_ssloptions |= SRV_SSL_O_USE_TLSV12;
4517#else
4518 memprintf(err, "'%s' '%s': library does not support protocol TLSv1.2", args[0], args[i]);
4519 return -1;
4520#endif
4521 }
4522 else if (!strcmp(args[i], "no-tls-tickets"))
4523 global.connect_default_ssloptions |= SRV_SSL_O_NO_TLS_TICKETS;
4524 else {
4525 memprintf(err, "unknown option '%s' on global statement '%s'.", args[i], args[0]);
4526 return -1;
4527 }
4528 i++;
4529 }
4530 return 0;
4531}
4532
Willy Tarreau7875d092012-09-10 08:20:03 +02004533/* Note: must not be declared <const> as its list will be overwritten.
4534 * Please take care of keeping this list alphabetically sorted.
4535 */
Willy Tarreaudc13c112013-06-21 23:16:39 +02004536static struct sample_fetch_kw_list sample_fetch_keywords = {ILH, {
Emeric Brun645ae792014-04-30 14:21:06 +02004537 { "ssl_bc", smp_fetch_ssl_fc, 0, NULL, SMP_T_BOOL, SMP_USE_L5SRV },
4538 { "ssl_bc_alg_keysize", smp_fetch_ssl_fc_alg_keysize, 0, NULL, SMP_T_UINT, SMP_USE_L5SRV },
4539 { "ssl_bc_cipher", smp_fetch_ssl_fc_cipher, 0, NULL, SMP_T_STR, SMP_USE_L5SRV },
4540 { "ssl_bc_protocol", smp_fetch_ssl_fc_protocol, 0, NULL, SMP_T_STR, SMP_USE_L5SRV },
Emeric Brunb73a9b02014-04-30 18:49:19 +02004541 { "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 +02004542 { "ssl_bc_use_keysize", smp_fetch_ssl_fc_use_keysize, 0, NULL, SMP_T_UINT, SMP_USE_L5SRV },
4543 { "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 +01004544 { "ssl_c_ca_err", smp_fetch_ssl_c_ca_err, 0, NULL, SMP_T_UINT, SMP_USE_L5CLI },
4545 { "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 +01004546 { "ssl_c_der", smp_fetch_ssl_x_der, 0, NULL, SMP_T_BIN, SMP_USE_L5CLI },
Willy Tarreau80aca902013-01-07 15:42:20 +01004547 { "ssl_c_err", smp_fetch_ssl_c_err, 0, NULL, SMP_T_UINT, SMP_USE_L5CLI },
Emeric Brunba841a12014-04-30 17:05:08 +02004548 { "ssl_c_i_dn", smp_fetch_ssl_x_i_dn, ARG2(0,STR,SINT), NULL, SMP_T_STR, SMP_USE_L5CLI },
4549 { "ssl_c_key_alg", smp_fetch_ssl_x_key_alg, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
4550 { "ssl_c_notafter", smp_fetch_ssl_x_notafter, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
4551 { "ssl_c_notbefore", smp_fetch_ssl_x_notbefore, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
4552 { "ssl_c_sig_alg", smp_fetch_ssl_x_sig_alg, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
4553 { "ssl_c_s_dn", smp_fetch_ssl_x_s_dn, ARG2(0,STR,SINT), NULL, SMP_T_STR, SMP_USE_L5CLI },
4554 { "ssl_c_serial", smp_fetch_ssl_x_serial, 0, NULL, SMP_T_BIN, SMP_USE_L5CLI },
4555 { "ssl_c_sha1", smp_fetch_ssl_x_sha1, 0, NULL, SMP_T_BIN, SMP_USE_L5CLI },
Willy Tarreau80aca902013-01-07 15:42:20 +01004556 { "ssl_c_used", smp_fetch_ssl_c_used, 0, NULL, SMP_T_BOOL, SMP_USE_L5CLI },
4557 { "ssl_c_verify", smp_fetch_ssl_c_verify, 0, NULL, SMP_T_UINT, SMP_USE_L5CLI },
Emeric Brunba841a12014-04-30 17:05:08 +02004558 { "ssl_c_version", smp_fetch_ssl_x_version, 0, NULL, SMP_T_UINT, SMP_USE_L5CLI },
Emeric Brunb3cc4252014-10-29 19:03:26 +01004559 { "ssl_f_der", smp_fetch_ssl_x_der, 0, NULL, SMP_T_BIN, SMP_USE_L5CLI },
Emeric Brunba841a12014-04-30 17:05:08 +02004560 { "ssl_f_i_dn", smp_fetch_ssl_x_i_dn, ARG2(0,STR,SINT), NULL, SMP_T_STR, SMP_USE_L5CLI },
4561 { "ssl_f_key_alg", smp_fetch_ssl_x_key_alg, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
4562 { "ssl_f_notafter", smp_fetch_ssl_x_notafter, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
4563 { "ssl_f_notbefore", smp_fetch_ssl_x_notbefore, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
4564 { "ssl_f_sig_alg", smp_fetch_ssl_x_sig_alg, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
4565 { "ssl_f_s_dn", smp_fetch_ssl_x_s_dn, ARG2(0,STR,SINT), NULL, SMP_T_STR, SMP_USE_L5CLI },
4566 { "ssl_f_serial", smp_fetch_ssl_x_serial, 0, NULL, SMP_T_BIN, SMP_USE_L5CLI },
Emeric Brun55f4fa82014-04-30 17:11:25 +02004567 { "ssl_f_sha1", smp_fetch_ssl_x_sha1, 0, NULL, SMP_T_BIN, SMP_USE_L5CLI },
Emeric Brunba841a12014-04-30 17:05:08 +02004568 { "ssl_f_version", smp_fetch_ssl_x_version, 0, NULL, SMP_T_UINT, SMP_USE_L5CLI },
Willy Tarreau80aca902013-01-07 15:42:20 +01004569 { "ssl_fc", smp_fetch_ssl_fc, 0, NULL, SMP_T_BOOL, SMP_USE_L5CLI },
4570 { "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 +01004571 { "ssl_fc_cipher", smp_fetch_ssl_fc_cipher, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
Willy Tarreau80aca902013-01-07 15:42:20 +01004572 { "ssl_fc_has_crt", smp_fetch_ssl_fc_has_crt, 0, NULL, SMP_T_BOOL, SMP_USE_L5CLI },
4573 { "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 +02004574#ifdef OPENSSL_NPN_NEGOTIATED
Thierry FOURNIER7654c9f2013-12-17 00:20:33 +01004575 { "ssl_fc_npn", smp_fetch_ssl_fc_npn, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
Willy Tarreaua33c6542012-10-15 13:19:06 +02004576#endif
Dirkjan Bussink48f1c4e2014-02-13 12:29:42 +01004577#ifdef TLSEXT_TYPE_application_layer_protocol_negotiation
Thierry FOURNIER7654c9f2013-12-17 00:20:33 +01004578 { "ssl_fc_alpn", smp_fetch_ssl_fc_alpn, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
Willy Tarreauab861d32013-04-02 02:30:41 +02004579#endif
Thierry FOURNIER7654c9f2013-12-17 00:20:33 +01004580 { "ssl_fc_protocol", smp_fetch_ssl_fc_protocol, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
Emeric Brunb73a9b02014-04-30 18:49:19 +02004581 { "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 +01004582 { "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 +01004583 { "ssl_fc_session_id", smp_fetch_ssl_fc_session_id, 0, NULL, SMP_T_BIN, SMP_USE_L5CLI },
4584 { "ssl_fc_sni", smp_fetch_ssl_fc_sni, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
Willy Tarreau7875d092012-09-10 08:20:03 +02004585 { NULL, NULL, 0, 0, 0 },
4586}};
4587
4588/* Note: must not be declared <const> as its list will be overwritten.
4589 * Please take care of keeping this list alphabetically sorted.
4590 */
Willy Tarreaudc13c112013-06-21 23:16:39 +02004591static struct acl_kw_list acl_kws = {ILH, {
Thierry FOURNIERc5a4e982014-03-05 16:07:08 +01004592 { "ssl_fc_sni_end", "ssl_fc_sni", PAT_MATCH_END },
4593 { "ssl_fc_sni_reg", "ssl_fc_sni", PAT_MATCH_REG },
Willy Tarreau8ed669b2013-01-11 15:49:37 +01004594 { /* END */ },
Willy Tarreau7875d092012-09-10 08:20:03 +02004595}};
4596
Willy Tarreau79eeafa2012-09-14 07:53:05 +02004597/* Note: must not be declared <const> as its list will be overwritten.
4598 * Please take care of keeping this list alphabetically sorted, doing so helps
4599 * all code contributors.
4600 * Optional keywords are also declared with a NULL ->parse() function so that
4601 * the config parser can report an appropriate error when a known keyword was
4602 * not enabled.
4603 */
Willy Tarreau51fb7652012-09-18 18:24:39 +02004604static struct bind_kw_list bind_kws = { "SSL", { }, {
Willy Tarreauab861d32013-04-02 02:30:41 +02004605 { "alpn", bind_parse_alpn, 1 }, /* set ALPN supported protocols */
Emeric Brunfb510ea2012-10-05 12:00:26 +02004606 { "ca-file", bind_parse_ca_file, 1 }, /* set CAfile to process verify on client cert */
Emeric Brun2d0c4822012-10-02 13:45:20 +02004607 { "ca-ignore-err", bind_parse_ignore_err, 1 }, /* set error IDs to ignore on verify depth > 0 */
4608 { "ciphers", bind_parse_ciphers, 1 }, /* set SSL cipher suite */
Emeric Brunfb510ea2012-10-05 12:00:26 +02004609 { "crl-file", bind_parse_crl_file, 1 }, /* set certificat revocation list file use on client cert verify */
Emeric Brun2d0c4822012-10-02 13:45:20 +02004610 { "crt", bind_parse_crt, 1 }, /* load SSL certificates from this location */
4611 { "crt-ignore-err", bind_parse_ignore_err, 1 }, /* set error IDs to ingore on verify depth == 0 */
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01004612 { "crt-list", bind_parse_crt_list, 1 }, /* load a list of crt from this location */
Emeric Brun2d0c4822012-10-02 13:45:20 +02004613 { "ecdhe", bind_parse_ecdhe, 1 }, /* defines named curve for elliptic curve Diffie-Hellman */
Emeric Brun2cb7ae52012-10-05 14:14:21 +02004614 { "force-sslv3", bind_parse_force_sslv3, 0 }, /* force SSLv3 */
4615 { "force-tlsv10", bind_parse_force_tlsv10, 0 }, /* force TLSv10 */
4616 { "force-tlsv11", bind_parse_force_tlsv11, 0 }, /* force TLSv11 */
4617 { "force-tlsv12", bind_parse_force_tlsv12, 0 }, /* force TLSv12 */
Emeric Brun9b3009b2012-10-05 11:55:06 +02004618 { "no-sslv3", bind_parse_no_sslv3, 0 }, /* disable SSLv3 */
4619 { "no-tlsv10", bind_parse_no_tlsv10, 0 }, /* disable TLSv10 */
4620 { "no-tlsv11", bind_parse_no_tlsv11, 0 }, /* disable TLSv11 */
4621 { "no-tlsv12", bind_parse_no_tlsv12, 0 }, /* disable TLSv12 */
Emeric Brun2d0c4822012-10-02 13:45:20 +02004622 { "no-tls-tickets", bind_parse_no_tls_tickets, 0 }, /* disable session resumption tickets */
Emeric Brun2d0c4822012-10-02 13:45:20 +02004623 { "ssl", bind_parse_ssl, 0 }, /* enable SSL processing */
Emmanuel Hocdet65623372013-01-24 17:17:15 +01004624 { "strict-sni", bind_parse_strict_sni, 0 }, /* refuse negotiation if sni doesn't match a certificate */
Emeric Brun2d0c4822012-10-02 13:45:20 +02004625 { "verify", bind_parse_verify, 1 }, /* set SSL verify method */
Willy Tarreau6c9a3d52012-10-18 18:57:14 +02004626 { "npn", bind_parse_npn, 1 }, /* set NPN supported protocols */
Willy Tarreau79eeafa2012-09-14 07:53:05 +02004627 { NULL, NULL, 0 },
4628}};
Emeric Brun46591952012-05-18 15:47:34 +02004629
Willy Tarreau92faadf2012-10-10 23:04:25 +02004630/* Note: must not be declared <const> as its list will be overwritten.
4631 * Please take care of keeping this list alphabetically sorted, doing so helps
4632 * all code contributors.
4633 * Optional keywords are also declared with a NULL ->parse() function so that
4634 * the config parser can report an appropriate error when a known keyword was
4635 * not enabled.
4636 */
4637static struct srv_kw_list srv_kws = { "SSL", { }, {
Emeric Brunef42d922012-10-11 16:11:36 +02004638 { "ca-file", srv_parse_ca_file, 1, 0 }, /* set CAfile to process verify server cert */
Emeric Brunecc91fe2012-10-11 15:05:10 +02004639 { "check-ssl", srv_parse_check_ssl, 0, 0 }, /* enable SSL for health checks */
4640 { "ciphers", srv_parse_ciphers, 1, 0 }, /* select the cipher suite */
Emeric Brunef42d922012-10-11 16:11:36 +02004641 { "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 +02004642 { "crt", srv_parse_crt, 1, 0 }, /* set client certificate */
Emeric Brunecc91fe2012-10-11 15:05:10 +02004643 { "force-sslv3", srv_parse_force_sslv3, 0, 0 }, /* force SSLv3 */
4644 { "force-tlsv10", srv_parse_force_tlsv10, 0, 0 }, /* force TLSv10 */
4645 { "force-tlsv11", srv_parse_force_tlsv11, 0, 0 }, /* force TLSv11 */
4646 { "force-tlsv12", srv_parse_force_tlsv12, 0, 0 }, /* force TLSv12 */
4647 { "no-sslv3", srv_parse_no_sslv3, 0, 0 }, /* disable SSLv3 */
4648 { "no-tlsv10", srv_parse_no_tlsv10, 0, 0 }, /* disable TLSv10 */
4649 { "no-tlsv11", srv_parse_no_tlsv11, 0, 0 }, /* disable TLSv11 */
4650 { "no-tlsv12", srv_parse_no_tlsv12, 0, 0 }, /* disable TLSv12 */
Emeric Brunf9c5c472012-10-11 15:28:34 +02004651 { "no-tls-tickets", srv_parse_no_tls_tickets, 0, 0 }, /* disable session resumption tickets */
David Safb76832014-05-08 23:42:08 -04004652 { "send-proxy-v2-ssl", srv_parse_send_proxy_ssl, 0, 0 }, /* send PROXY protocol header v2 with SSL info */
4653 { "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 +02004654 { "ssl", srv_parse_ssl, 0, 0 }, /* enable SSL processing */
Emeric Brunef42d922012-10-11 16:11:36 +02004655 { "verify", srv_parse_verify, 1, 0 }, /* set SSL verify method */
Evan Broderbe554312013-06-27 00:05:25 -07004656 { "verifyhost", srv_parse_verifyhost, 1, 0 }, /* require that SSL cert verifies for hostname */
Willy Tarreau92faadf2012-10-10 23:04:25 +02004657 { NULL, NULL, 0, 0 },
4658}};
4659
Emeric Brun42a3e202014-10-30 15:56:50 +01004660static struct cfg_kw_list cfg_kws = {ILH, {
4661 { CFG_GLOBAL, "ssl-default-bind-options", ssl_parse_default_bind_options },
4662 { CFG_GLOBAL, "ssl-default-server-options", ssl_parse_default_server_options },
4663 { 0, NULL, NULL },
4664}};
4665
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02004666/* transport-layer operations for SSL sockets */
4667struct xprt_ops ssl_sock = {
Emeric Brun46591952012-05-18 15:47:34 +02004668 .snd_buf = ssl_sock_from_buf,
4669 .rcv_buf = ssl_sock_to_buf,
4670 .rcv_pipe = NULL,
4671 .snd_pipe = NULL,
4672 .shutr = NULL,
4673 .shutw = ssl_sock_shutw,
4674 .close = ssl_sock_close,
4675 .init = ssl_sock_init,
4676};
4677
4678__attribute__((constructor))
Willy Tarreau92faadf2012-10-10 23:04:25 +02004679static void __ssl_sock_init(void)
4680{
Emeric Brun46591952012-05-18 15:47:34 +02004681 STACK_OF(SSL_COMP)* cm;
4682
Willy Tarreau610f04b2014-02-13 11:36:41 +01004683#ifdef LISTEN_DEFAULT_CIPHERS
4684 global.listen_default_ciphers = LISTEN_DEFAULT_CIPHERS;
4685#endif
4686#ifdef CONNECT_DEFAULT_CIPHERS
4687 global.connect_default_ciphers = CONNECT_DEFAULT_CIPHERS;
4688#endif
4689 if (global.listen_default_ciphers)
4690 global.listen_default_ciphers = strdup(global.listen_default_ciphers);
4691 if (global.connect_default_ciphers)
4692 global.connect_default_ciphers = strdup(global.connect_default_ciphers);
Emeric Brun42a3e202014-10-30 15:56:50 +01004693 global.listen_default_ssloptions = BC_SSL_O_NONE;
4694 global.connect_default_ssloptions = SRV_SSL_O_NONE;
Willy Tarreau610f04b2014-02-13 11:36:41 +01004695
Emeric Brun46591952012-05-18 15:47:34 +02004696 SSL_library_init();
4697 cm = SSL_COMP_get_compression_methods();
4698 sk_SSL_COMP_zero(cm);
Willy Tarreau7875d092012-09-10 08:20:03 +02004699 sample_register_fetches(&sample_fetch_keywords);
4700 acl_register_keywords(&acl_kws);
Willy Tarreau79eeafa2012-09-14 07:53:05 +02004701 bind_register_keywords(&bind_kws);
Willy Tarreau92faadf2012-10-10 23:04:25 +02004702 srv_register_keywords(&srv_kws);
Emeric Brun42a3e202014-10-30 15:56:50 +01004703 cfg_register_keywords(&cfg_kws);
Emeric Brun46591952012-05-18 15:47:34 +02004704}
4705
4706/*
4707 * Local variables:
4708 * c-indent-level: 8
4709 * c-basic-offset: 8
4710 * End:
4711 */