blob: 620609f2f445611a870a77e78bdfb3ad2e74e55a [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)
Simon Horman66183002013-02-23 10:16:43 +09001815 srv->check_common.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)) {
Emeric Brun46591952012-05-18 15:47:34 +02002036 /* Alloc a new SSL session ctx */
Willy Tarreau3fdb3662012-11-12 00:42:33 +01002037 conn->xprt_ctx = SSL_new(objt_server(conn->target)->ssl_ctx.ctx);
Willy Tarreau20879a02012-12-03 16:32:10 +01002038 if (!conn->xprt_ctx) {
2039 conn->err_code = CO_ER_SSL_NO_MEM;
Emeric Brun46591952012-05-18 15:47:34 +02002040 return -1;
Willy Tarreau20879a02012-12-03 16:32:10 +01002041 }
Emeric Brun46591952012-05-18 15:47:34 +02002042
Emeric Brun46591952012-05-18 15:47:34 +02002043 /* set fd on SSL session context */
Emeric Brun90951492014-11-12 17:35:37 +01002044 if (!SSL_set_fd(conn->xprt_ctx, conn->t.sock.fd)) {
2045 SSL_free(conn->xprt_ctx);
2046 conn->xprt_ctx = NULL;
2047 conn->err_code = CO_ER_SSL_NO_MEM;
2048 return -1;
2049 }
Emeric Brun46591952012-05-18 15:47:34 +02002050
Evan Broderbe554312013-06-27 00:05:25 -07002051 /* set connection pointer */
Emeric Brun90951492014-11-12 17:35:37 +01002052 if (!SSL_set_app_data(conn->xprt_ctx, conn)) {
2053 SSL_free(conn->xprt_ctx);
2054 conn->xprt_ctx = NULL;
2055 conn->err_code = CO_ER_SSL_NO_MEM;
2056 return -1;
2057 }
2058
2059 SSL_set_connect_state(conn->xprt_ctx);
2060 if (objt_server(conn->target)->ssl_ctx.reused_sess) {
2061 if(!SSL_set_session(conn->xprt_ctx, objt_server(conn->target)->ssl_ctx.reused_sess)) {
2062 SSL_SESSION_free(objt_server(conn->target)->ssl_ctx.reused_sess);
2063 objt_server(conn->target)->ssl_ctx.reused_sess = NULL;
2064 }
2065 }
Evan Broderbe554312013-06-27 00:05:25 -07002066
Emeric Brun46591952012-05-18 15:47:34 +02002067 /* leave init state and start handshake */
Willy Tarreau05737472012-09-04 08:03:39 +02002068 conn->flags |= CO_FL_SSL_WAIT_HS | CO_FL_WAIT_L6_CONN;
Willy Tarreau403edff2012-09-06 11:58:37 +02002069
2070 sslconns++;
Willy Tarreau71b734c2014-01-28 15:19:44 +01002071 totalsslconns++;
Emeric Brun46591952012-05-18 15:47:34 +02002072 return 0;
2073 }
Willy Tarreau3fdb3662012-11-12 00:42:33 +01002074 else if (objt_listener(conn->target)) {
Emeric Brun46591952012-05-18 15:47:34 +02002075 /* Alloc a new SSL session ctx */
Willy Tarreau3fdb3662012-11-12 00:42:33 +01002076 conn->xprt_ctx = SSL_new(objt_listener(conn->target)->bind_conf->default_ctx);
Willy Tarreau20879a02012-12-03 16:32:10 +01002077 if (!conn->xprt_ctx) {
2078 conn->err_code = CO_ER_SSL_NO_MEM;
Emeric Brun46591952012-05-18 15:47:34 +02002079 return -1;
Willy Tarreau20879a02012-12-03 16:32:10 +01002080 }
Emeric Brun46591952012-05-18 15:47:34 +02002081
Emeric Brun46591952012-05-18 15:47:34 +02002082 /* set fd on SSL session context */
Emeric Brun90951492014-11-12 17:35:37 +01002083 if (!SSL_set_fd(conn->xprt_ctx, conn->t.sock.fd)) {
2084 SSL_free(conn->xprt_ctx);
2085 conn->xprt_ctx = NULL;
2086 conn->err_code = CO_ER_SSL_NO_MEM;
2087 return -1;
2088 }
Emeric Brun46591952012-05-18 15:47:34 +02002089
Emeric Brune1f38db2012-09-03 20:36:47 +02002090 /* set connection pointer */
Emeric Brun90951492014-11-12 17:35:37 +01002091 if (!SSL_set_app_data(conn->xprt_ctx, conn)) {
2092 SSL_free(conn->xprt_ctx);
2093 conn->xprt_ctx = NULL;
2094 conn->err_code = CO_ER_SSL_NO_MEM;
2095 return -1;
2096 }
2097
2098 SSL_set_accept_state(conn->xprt_ctx);
Emeric Brune1f38db2012-09-03 20:36:47 +02002099
Emeric Brun46591952012-05-18 15:47:34 +02002100 /* leave init state and start handshake */
Willy Tarreau05737472012-09-04 08:03:39 +02002101 conn->flags |= CO_FL_SSL_WAIT_HS | CO_FL_WAIT_L6_CONN;
Willy Tarreau403edff2012-09-06 11:58:37 +02002102
2103 sslconns++;
Willy Tarreau71b734c2014-01-28 15:19:44 +01002104 totalsslconns++;
Emeric Brun46591952012-05-18 15:47:34 +02002105 return 0;
2106 }
2107 /* don't know how to handle such a target */
Willy Tarreau20879a02012-12-03 16:32:10 +01002108 conn->err_code = CO_ER_SSL_NO_TARGET;
Emeric Brun46591952012-05-18 15:47:34 +02002109 return -1;
2110}
2111
2112
2113/* This is the callback which is used when an SSL handshake is pending. It
2114 * updates the FD status if it wants some polling before being called again.
2115 * It returns 0 if it fails in a fatal way or needs to poll to go further,
2116 * otherwise it returns non-zero and removes itself from the connection's
2117 * flags (the bit is provided in <flag> by the caller).
2118 */
2119int ssl_sock_handshake(struct connection *conn, unsigned int flag)
2120{
2121 int ret;
2122
Willy Tarreau3c728722014-01-23 13:50:42 +01002123 if (!conn_ctrl_ready(conn))
Willy Tarreauf79c8172013-10-21 16:30:56 +02002124 return 0;
2125
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02002126 if (!conn->xprt_ctx)
Emeric Brun46591952012-05-18 15:47:34 +02002127 goto out_error;
2128
Emeric Brun674b7432012-11-08 19:21:55 +01002129 /* If we use SSL_do_handshake to process a reneg initiated by
2130 * the remote peer, it sometimes returns SSL_ERROR_SSL.
2131 * Usually SSL_write and SSL_read are used and process implicitly
2132 * the reneg handshake.
2133 * Here we use SSL_peek as a workaround for reneg.
2134 */
2135 if ((conn->flags & CO_FL_CONNECTED) && SSL_renegotiate_pending(conn->xprt_ctx)) {
2136 char c;
2137
2138 ret = SSL_peek(conn->xprt_ctx, &c, 1);
2139 if (ret <= 0) {
2140 /* handshake may have not been completed, let's find why */
2141 ret = SSL_get_error(conn->xprt_ctx, ret);
2142 if (ret == SSL_ERROR_WANT_WRITE) {
2143 /* SSL handshake needs to write, L4 connection may not be ready */
2144 __conn_sock_stop_recv(conn);
Willy Tarreaue1f50c42014-01-22 20:02:06 +01002145 __conn_sock_want_send(conn);
2146 fd_cant_send(conn->t.sock.fd);
Emeric Brun674b7432012-11-08 19:21:55 +01002147 return 0;
2148 }
2149 else if (ret == SSL_ERROR_WANT_READ) {
2150 /* handshake may have been completed but we have
2151 * no more data to read.
2152 */
2153 if (!SSL_renegotiate_pending(conn->xprt_ctx)) {
2154 ret = 1;
2155 goto reneg_ok;
2156 }
2157 /* SSL handshake needs to read, L4 connection is ready */
2158 if (conn->flags & CO_FL_WAIT_L4_CONN)
2159 conn->flags &= ~CO_FL_WAIT_L4_CONN;
2160 __conn_sock_stop_send(conn);
Willy Tarreaue1f50c42014-01-22 20:02:06 +01002161 __conn_sock_want_recv(conn);
2162 fd_cant_recv(conn->t.sock.fd);
Emeric Brun674b7432012-11-08 19:21:55 +01002163 return 0;
2164 }
2165 else if (ret == SSL_ERROR_SYSCALL) {
2166 /* if errno is null, then connection was successfully established */
2167 if (!errno && conn->flags & CO_FL_WAIT_L4_CONN)
2168 conn->flags &= ~CO_FL_WAIT_L4_CONN;
Willy Tarreau20879a02012-12-03 16:32:10 +01002169 if (!conn->err_code) {
Emeric Brun29f037d2014-04-25 19:05:36 +02002170 if (!((SSL *)conn->xprt_ctx)->packet_length) {
2171 if (!errno) {
2172 if (conn->xprt_st & SSL_SOCK_RECV_HEARTBEAT)
2173 conn->err_code = CO_ER_SSL_HANDSHAKE_HB;
2174 else
2175 conn->err_code = CO_ER_SSL_EMPTY;
2176 }
2177 else {
2178 if (conn->xprt_st & SSL_SOCK_RECV_HEARTBEAT)
2179 conn->err_code = CO_ER_SSL_HANDSHAKE_HB;
2180 else
2181 conn->err_code = CO_ER_SSL_ABORT;
2182 }
2183 }
2184 else {
2185 if (conn->xprt_st & SSL_SOCK_RECV_HEARTBEAT)
2186 conn->err_code = CO_ER_SSL_HANDSHAKE_HB;
Willy Tarreau20879a02012-12-03 16:32:10 +01002187 else
Emeric Brun29f037d2014-04-25 19:05:36 +02002188 conn->err_code = CO_ER_SSL_HANDSHAKE;
2189 }
Willy Tarreau20879a02012-12-03 16:32:10 +01002190 }
Emeric Brun674b7432012-11-08 19:21:55 +01002191 goto out_error;
2192 }
2193 else {
2194 /* Fail on all other handshake errors */
2195 /* Note: OpenSSL may leave unread bytes in the socket's
2196 * buffer, causing an RST to be emitted upon close() on
2197 * TCP sockets. We first try to drain possibly pending
2198 * data to avoid this as much as possible.
2199 */
Willy Tarreau46be2e52014-01-20 12:10:52 +01002200 conn_drain(conn);
Willy Tarreau20879a02012-12-03 16:32:10 +01002201 if (!conn->err_code)
Willy Tarreauf51c6982014-04-25 20:02:39 +02002202 conn->err_code = (conn->xprt_st & SSL_SOCK_RECV_HEARTBEAT) ?
2203 CO_ER_SSL_KILLED_HB : CO_ER_SSL_HANDSHAKE;
Emeric Brun674b7432012-11-08 19:21:55 +01002204 goto out_error;
2205 }
2206 }
2207 /* read some data: consider handshake completed */
2208 goto reneg_ok;
2209 }
2210
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02002211 ret = SSL_do_handshake(conn->xprt_ctx);
Emeric Brun46591952012-05-18 15:47:34 +02002212 if (ret != 1) {
2213 /* handshake did not complete, let's find why */
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02002214 ret = SSL_get_error(conn->xprt_ctx, ret);
Emeric Brun46591952012-05-18 15:47:34 +02002215
2216 if (ret == SSL_ERROR_WANT_WRITE) {
2217 /* SSL handshake needs to write, L4 connection may not be ready */
2218 __conn_sock_stop_recv(conn);
Willy Tarreaue1f50c42014-01-22 20:02:06 +01002219 __conn_sock_want_send(conn);
2220 fd_cant_send(conn->t.sock.fd);
Emeric Brun46591952012-05-18 15:47:34 +02002221 return 0;
2222 }
2223 else if (ret == SSL_ERROR_WANT_READ) {
2224 /* SSL handshake needs to read, L4 connection is ready */
2225 if (conn->flags & CO_FL_WAIT_L4_CONN)
2226 conn->flags &= ~CO_FL_WAIT_L4_CONN;
2227 __conn_sock_stop_send(conn);
Willy Tarreaue1f50c42014-01-22 20:02:06 +01002228 __conn_sock_want_recv(conn);
2229 fd_cant_recv(conn->t.sock.fd);
Emeric Brun46591952012-05-18 15:47:34 +02002230 return 0;
2231 }
Willy Tarreau89230192012-09-28 20:22:13 +02002232 else if (ret == SSL_ERROR_SYSCALL) {
2233 /* if errno is null, then connection was successfully established */
2234 if (!errno && conn->flags & CO_FL_WAIT_L4_CONN)
2235 conn->flags &= ~CO_FL_WAIT_L4_CONN;
Willy Tarreau20879a02012-12-03 16:32:10 +01002236
Emeric Brun29f037d2014-04-25 19:05:36 +02002237 if (!((SSL *)conn->xprt_ctx)->packet_length) {
2238 if (!errno) {
2239 if (conn->xprt_st & SSL_SOCK_RECV_HEARTBEAT)
2240 conn->err_code = CO_ER_SSL_HANDSHAKE_HB;
2241 else
2242 conn->err_code = CO_ER_SSL_EMPTY;
2243 }
2244 else {
2245 if (conn->xprt_st & SSL_SOCK_RECV_HEARTBEAT)
2246 conn->err_code = CO_ER_SSL_HANDSHAKE_HB;
2247 else
2248 conn->err_code = CO_ER_SSL_ABORT;
2249 }
2250 }
2251 else {
2252 if (conn->xprt_st & SSL_SOCK_RECV_HEARTBEAT)
2253 conn->err_code = CO_ER_SSL_HANDSHAKE_HB;
Willy Tarreau20879a02012-12-03 16:32:10 +01002254 else
Emeric Brun29f037d2014-04-25 19:05:36 +02002255 conn->err_code = CO_ER_SSL_HANDSHAKE;
2256 }
Willy Tarreau89230192012-09-28 20:22:13 +02002257 goto out_error;
2258 }
Emeric Brun46591952012-05-18 15:47:34 +02002259 else {
2260 /* Fail on all other handshake errors */
Willy Tarreau566dc552012-10-19 20:52:18 +02002261 /* Note: OpenSSL may leave unread bytes in the socket's
2262 * buffer, causing an RST to be emitted upon close() on
2263 * TCP sockets. We first try to drain possibly pending
2264 * data to avoid this as much as possible.
2265 */
Willy Tarreau46be2e52014-01-20 12:10:52 +01002266 conn_drain(conn);
Willy Tarreau20879a02012-12-03 16:32:10 +01002267 if (!conn->err_code)
Willy Tarreauf51c6982014-04-25 20:02:39 +02002268 conn->err_code = (conn->xprt_st & SSL_SOCK_RECV_HEARTBEAT) ?
2269 CO_ER_SSL_KILLED_HB : CO_ER_SSL_HANDSHAKE;
Emeric Brun46591952012-05-18 15:47:34 +02002270 goto out_error;
2271 }
2272 }
2273
Emeric Brun674b7432012-11-08 19:21:55 +01002274reneg_ok:
2275
Emeric Brun46591952012-05-18 15:47:34 +02002276 /* Handshake succeeded */
Willy Tarreau0c9c2722014-05-28 12:28:58 +02002277 if (!SSL_session_reused(conn->xprt_ctx)) {
2278 if (objt_server(conn->target)) {
2279 update_freq_ctr(&global.ssl_be_keys_per_sec, 1);
2280 if (global.ssl_be_keys_per_sec.curr_ctr > global.ssl_be_keys_max)
2281 global.ssl_be_keys_max = global.ssl_be_keys_per_sec.curr_ctr;
2282
Emeric Brun46591952012-05-18 15:47:34 +02002283 /* check if session was reused, if not store current session on server for reuse */
Willy Tarreau3fdb3662012-11-12 00:42:33 +01002284 if (objt_server(conn->target)->ssl_ctx.reused_sess)
2285 SSL_SESSION_free(objt_server(conn->target)->ssl_ctx.reused_sess);
Emeric Brun46591952012-05-18 15:47:34 +02002286
Willy Tarreau3fdb3662012-11-12 00:42:33 +01002287 objt_server(conn->target)->ssl_ctx.reused_sess = SSL_get1_session(conn->xprt_ctx);
Emeric Brun46591952012-05-18 15:47:34 +02002288 }
Willy Tarreau0c9c2722014-05-28 12:28:58 +02002289 else {
2290 update_freq_ctr(&global.ssl_fe_keys_per_sec, 1);
2291 if (global.ssl_fe_keys_per_sec.curr_ctr > global.ssl_fe_keys_max)
2292 global.ssl_fe_keys_max = global.ssl_fe_keys_per_sec.curr_ctr;
2293 }
Emeric Brun46591952012-05-18 15:47:34 +02002294 }
2295
2296 /* The connection is now established at both layers, it's time to leave */
2297 conn->flags &= ~(flag | CO_FL_WAIT_L4_CONN | CO_FL_WAIT_L6_CONN);
2298 return 1;
2299
2300 out_error:
Emeric Brun644cde02012-12-14 11:21:13 +01002301 /* Clear openssl global errors stack */
2302 ERR_clear_error();
2303
Emeric Brun9fa89732012-10-04 17:09:56 +02002304 /* free resumed session if exists */
Willy Tarreau3fdb3662012-11-12 00:42:33 +01002305 if (objt_server(conn->target) && objt_server(conn->target)->ssl_ctx.reused_sess) {
2306 SSL_SESSION_free(objt_server(conn->target)->ssl_ctx.reused_sess);
2307 objt_server(conn->target)->ssl_ctx.reused_sess = NULL;
Emeric Brun9fa89732012-10-04 17:09:56 +02002308 }
2309
Emeric Brun46591952012-05-18 15:47:34 +02002310 /* Fail on all other handshake errors */
2311 conn->flags |= CO_FL_ERROR;
Willy Tarreau20879a02012-12-03 16:32:10 +01002312 if (!conn->err_code)
2313 conn->err_code = CO_ER_SSL_HANDSHAKE;
Emeric Brun46591952012-05-18 15:47:34 +02002314 return 0;
2315}
2316
2317/* Receive up to <count> bytes from connection <conn>'s socket and store them
Willy Tarreauabf08d92014-01-14 11:31:27 +01002318 * into buffer <buf>. Only one call to recv() is performed, unless the
Emeric Brun46591952012-05-18 15:47:34 +02002319 * buffer wraps, in which case a second call may be performed. The connection's
2320 * flags are updated with whatever special event is detected (error, read0,
2321 * empty). The caller is responsible for taking care of those events and
2322 * avoiding the call if inappropriate. The function does not call the
2323 * connection's polling update function, so the caller is responsible for this.
2324 */
2325static int ssl_sock_to_buf(struct connection *conn, struct buffer *buf, int count)
2326{
2327 int ret, done = 0;
Willy Tarreauabf08d92014-01-14 11:31:27 +01002328 int try;
Emeric Brun46591952012-05-18 15:47:34 +02002329
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02002330 if (!conn->xprt_ctx)
Emeric Brun46591952012-05-18 15:47:34 +02002331 goto out_error;
2332
2333 if (conn->flags & CO_FL_HANDSHAKE)
2334 /* a handshake was requested */
2335 return 0;
2336
Willy Tarreauabf08d92014-01-14 11:31:27 +01002337 /* let's realign the buffer to optimize I/O */
2338 if (buffer_empty(buf))
Emeric Brun46591952012-05-18 15:47:34 +02002339 buf->p = buf->data;
Emeric Brun46591952012-05-18 15:47:34 +02002340
2341 /* read the largest possible block. For this, we perform only one call
2342 * to recv() unless the buffer wraps and we exactly fill the first hunk,
2343 * in which case we accept to do it once again. A new attempt is made on
2344 * EINTR too.
2345 */
Willy Tarreau00b0fb92014-01-17 11:09:40 +01002346 while (count > 0) {
Willy Tarreauabf08d92014-01-14 11:31:27 +01002347 /* first check if we have some room after p+i */
2348 try = buf->data + buf->size - (buf->p + buf->i);
2349 /* otherwise continue between data and p-o */
2350 if (try <= 0) {
2351 try = buf->p - (buf->data + buf->o);
2352 if (try <= 0)
2353 break;
2354 }
2355 if (try > count)
2356 try = count;
2357
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02002358 ret = SSL_read(conn->xprt_ctx, bi_end(buf), try);
Emeric Brune1f38db2012-09-03 20:36:47 +02002359 if (conn->flags & CO_FL_ERROR) {
2360 /* CO_FL_ERROR may be set by ssl_sock_infocbk */
Emeric Brun644cde02012-12-14 11:21:13 +01002361 goto out_error;
Emeric Brune1f38db2012-09-03 20:36:47 +02002362 }
Emeric Brun46591952012-05-18 15:47:34 +02002363 if (ret > 0) {
2364 buf->i += ret;
2365 done += ret;
2366 if (ret < try)
2367 break;
2368 count -= ret;
Emeric Brun46591952012-05-18 15:47:34 +02002369 }
2370 else if (ret == 0) {
Emeric Brun644cde02012-12-14 11:21:13 +01002371 ret = SSL_get_error(conn->xprt_ctx, ret);
2372 if (ret != SSL_ERROR_ZERO_RETURN) {
Emeric Brun1c646862012-12-14 12:33:41 +01002373 /* error on protocol or underlying transport */
2374 if ((ret != SSL_ERROR_SYSCALL)
2375 || (errno && (errno != EAGAIN)))
2376 conn->flags |= CO_FL_ERROR;
2377
Emeric Brun644cde02012-12-14 11:21:13 +01002378 /* Clear openssl global errors stack */
2379 ERR_clear_error();
2380 }
Emeric Brun46591952012-05-18 15:47:34 +02002381 goto read0;
2382 }
2383 else {
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02002384 ret = SSL_get_error(conn->xprt_ctx, ret);
Emeric Brun46591952012-05-18 15:47:34 +02002385 if (ret == SSL_ERROR_WANT_WRITE) {
Emeric Brun8af8dd12012-11-08 17:56:20 +01002386 /* handshake is running, and it needs to enable write */
Emeric Brun46591952012-05-18 15:47:34 +02002387 conn->flags |= CO_FL_SSL_WAIT_HS;
Emeric Brun8af8dd12012-11-08 17:56:20 +01002388 __conn_sock_want_send(conn);
Emeric Brun46591952012-05-18 15:47:34 +02002389 break;
2390 }
2391 else if (ret == SSL_ERROR_WANT_READ) {
Emeric Brun282a76a2012-11-08 18:02:56 +01002392 if (SSL_renegotiate_pending(conn->xprt_ctx)) {
2393 /* handshake is running, and it may need to re-enable read */
2394 conn->flags |= CO_FL_SSL_WAIT_HS;
2395 __conn_sock_want_recv(conn);
2396 break;
2397 }
Emeric Brun46591952012-05-18 15:47:34 +02002398 /* we need to poll for retry a read later */
Willy Tarreaue1f50c42014-01-22 20:02:06 +01002399 fd_cant_recv(conn->t.sock.fd);
Emeric Brun46591952012-05-18 15:47:34 +02002400 break;
2401 }
2402 /* otherwise it's a real error */
2403 goto out_error;
2404 }
2405 }
2406 return done;
2407
2408 read0:
2409 conn_sock_read0(conn);
2410 return done;
2411 out_error:
Emeric Brun644cde02012-12-14 11:21:13 +01002412 /* Clear openssl global errors stack */
2413 ERR_clear_error();
2414
Emeric Brun46591952012-05-18 15:47:34 +02002415 conn->flags |= CO_FL_ERROR;
2416 return done;
2417}
2418
2419
2420/* Send all pending bytes from buffer <buf> to connection <conn>'s socket.
Willy Tarreau1049b1f2014-02-02 01:51:17 +01002421 * <flags> may contain some CO_SFL_* flags to hint the system about other
2422 * pending data for example, but this flag is ignored at the moment.
Emeric Brun46591952012-05-18 15:47:34 +02002423 * Only one call to send() is performed, unless the buffer wraps, in which case
2424 * a second call may be performed. The connection's flags are updated with
2425 * whatever special event is detected (error, empty). The caller is responsible
2426 * for taking care of those events and avoiding the call if inappropriate. The
2427 * function does not call the connection's polling update function, so the caller
2428 * is responsible for this.
2429 */
2430static int ssl_sock_from_buf(struct connection *conn, struct buffer *buf, int flags)
2431{
2432 int ret, try, done;
2433
2434 done = 0;
2435
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02002436 if (!conn->xprt_ctx)
Emeric Brun46591952012-05-18 15:47:34 +02002437 goto out_error;
2438
2439 if (conn->flags & CO_FL_HANDSHAKE)
2440 /* a handshake was requested */
2441 return 0;
2442
2443 /* send the largest possible block. For this we perform only one call
2444 * to send() unless the buffer wraps and we exactly fill the first hunk,
2445 * in which case we accept to do it once again.
2446 */
2447 while (buf->o) {
Kevin Hestercad82342013-05-30 15:12:41 -07002448 try = bo_contig_data(buf);
Willy Tarreaubfd59462013-02-21 07:46:09 +01002449
Willy Tarreau7bed9452014-02-02 02:00:24 +01002450 if (!(flags & CO_SFL_STREAMER) &&
Willy Tarreau518cedd2014-02-17 15:43:01 +01002451 !(conn->xprt_st & SSL_SOCK_SEND_UNLIMITED) &&
2452 global.tune.ssl_max_record && try > global.tune.ssl_max_record) {
Willy Tarreaubfd59462013-02-21 07:46:09 +01002453 try = global.tune.ssl_max_record;
Willy Tarreau518cedd2014-02-17 15:43:01 +01002454 }
2455 else {
2456 /* we need to keep the information about the fact that
2457 * we're not limiting the upcoming send(), because if it
2458 * fails, we'll have to retry with at least as many data.
2459 */
2460 conn->xprt_st |= SSL_SOCK_SEND_UNLIMITED;
2461 }
Willy Tarreaubfd59462013-02-21 07:46:09 +01002462
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02002463 ret = SSL_write(conn->xprt_ctx, bo_ptr(buf), try);
Willy Tarreau518cedd2014-02-17 15:43:01 +01002464
Emeric Brune1f38db2012-09-03 20:36:47 +02002465 if (conn->flags & CO_FL_ERROR) {
2466 /* CO_FL_ERROR may be set by ssl_sock_infocbk */
Emeric Brun644cde02012-12-14 11:21:13 +01002467 goto out_error;
Emeric Brune1f38db2012-09-03 20:36:47 +02002468 }
Emeric Brun46591952012-05-18 15:47:34 +02002469 if (ret > 0) {
Willy Tarreau518cedd2014-02-17 15:43:01 +01002470 conn->xprt_st &= ~SSL_SOCK_SEND_UNLIMITED;
2471
Emeric Brun46591952012-05-18 15:47:34 +02002472 buf->o -= ret;
2473 done += ret;
2474
Willy Tarreau5fb38032012-12-16 19:39:09 +01002475 if (likely(buffer_empty(buf)))
Emeric Brun46591952012-05-18 15:47:34 +02002476 /* optimize data alignment in the buffer */
2477 buf->p = buf->data;
2478
2479 /* if the system buffer is full, don't insist */
2480 if (ret < try)
2481 break;
2482 }
2483 else {
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02002484 ret = SSL_get_error(conn->xprt_ctx, ret);
Emeric Brun46591952012-05-18 15:47:34 +02002485 if (ret == SSL_ERROR_WANT_WRITE) {
Emeric Brun282a76a2012-11-08 18:02:56 +01002486 if (SSL_renegotiate_pending(conn->xprt_ctx)) {
2487 /* handshake is running, and it may need to re-enable write */
2488 conn->flags |= CO_FL_SSL_WAIT_HS;
2489 __conn_sock_want_send(conn);
2490 break;
2491 }
Emeric Brun46591952012-05-18 15:47:34 +02002492 /* we need to poll to retry a write later */
Willy Tarreaue1f50c42014-01-22 20:02:06 +01002493 fd_cant_send(conn->t.sock.fd);
Emeric Brun46591952012-05-18 15:47:34 +02002494 break;
2495 }
2496 else if (ret == SSL_ERROR_WANT_READ) {
Emeric Brun8af8dd12012-11-08 17:56:20 +01002497 /* handshake is running, and it needs to enable read */
Emeric Brun46591952012-05-18 15:47:34 +02002498 conn->flags |= CO_FL_SSL_WAIT_HS;
Emeric Brun8af8dd12012-11-08 17:56:20 +01002499 __conn_sock_want_recv(conn);
Emeric Brun46591952012-05-18 15:47:34 +02002500 break;
2501 }
2502 goto out_error;
2503 }
2504 }
2505 return done;
2506
2507 out_error:
Emeric Brun644cde02012-12-14 11:21:13 +01002508 /* Clear openssl global errors stack */
2509 ERR_clear_error();
2510
Emeric Brun46591952012-05-18 15:47:34 +02002511 conn->flags |= CO_FL_ERROR;
2512 return done;
2513}
2514
Emeric Brun46591952012-05-18 15:47:34 +02002515static void ssl_sock_close(struct connection *conn) {
2516
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02002517 if (conn->xprt_ctx) {
2518 SSL_free(conn->xprt_ctx);
2519 conn->xprt_ctx = NULL;
Willy Tarreau403edff2012-09-06 11:58:37 +02002520 sslconns--;
Emeric Brun46591952012-05-18 15:47:34 +02002521 }
Emeric Brun46591952012-05-18 15:47:34 +02002522}
2523
2524/* This function tries to perform a clean shutdown on an SSL connection, and in
2525 * any case, flags the connection as reusable if no handshake was in progress.
2526 */
2527static void ssl_sock_shutw(struct connection *conn, int clean)
2528{
2529 if (conn->flags & CO_FL_HANDSHAKE)
2530 return;
2531 /* no handshake was in progress, try a clean ssl shutdown */
Emeric Brun644cde02012-12-14 11:21:13 +01002532 if (clean && (SSL_shutdown(conn->xprt_ctx) <= 0)) {
2533 /* Clear openssl global errors stack */
2534 ERR_clear_error();
2535 }
Emeric Brun46591952012-05-18 15:47:34 +02002536
2537 /* force flag on ssl to keep session in cache regardless shutdown result */
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02002538 SSL_set_shutdown(conn->xprt_ctx, SSL_SENT_SHUTDOWN);
Emeric Brun46591952012-05-18 15:47:34 +02002539}
2540
Willy Tarreauffc3fcd2012-10-12 20:17:54 +02002541/* used for logging, may be changed for a sample fetch later */
2542const char *ssl_sock_get_cipher_name(struct connection *conn)
2543{
2544 if (!conn->xprt && !conn->xprt_ctx)
2545 return NULL;
2546 return SSL_get_cipher_name(conn->xprt_ctx);
2547}
2548
2549/* used for logging, may be changed for a sample fetch later */
2550const char *ssl_sock_get_proto_version(struct connection *conn)
2551{
2552 if (!conn->xprt && !conn->xprt_ctx)
2553 return NULL;
2554 return SSL_get_version(conn->xprt_ctx);
2555}
2556
Willy Tarreau8d598402012-10-22 17:58:39 +02002557/* Extract a serial from a cert, and copy it to a chunk.
2558 * Returns 1 if serial is found and copied, 0 if no serial found and
2559 * -1 if output is not large enough.
2560 */
2561static int
2562ssl_sock_get_serial(X509 *crt, struct chunk *out)
2563{
2564 ASN1_INTEGER *serial;
2565
2566 serial = X509_get_serialNumber(crt);
2567 if (!serial)
2568 return 0;
2569
2570 if (out->size < serial->length)
2571 return -1;
2572
2573 memcpy(out->str, serial->data, serial->length);
2574 out->len = serial->length;
2575 return 1;
2576}
2577
Emeric Brunb3cc4252014-10-29 19:03:26 +01002578/* Extract a cert to der, and copy it to a chunk.
2579 * Returns 1 if cert is found and copied, 0 on der convertion failure and
2580 * -1 if output is not large enough.
2581 */
2582static int
2583ssl_sock_crt2der(X509 *crt, struct chunk *out)
2584{
2585 int len;
2586 unsigned char *p = (unsigned char *)out->str;;
2587
2588 len =i2d_X509(crt, NULL);
2589 if (len <= 0)
2590 return 1;
2591
2592 if (out->size < len)
2593 return -1;
2594
2595 i2d_X509(crt,&p);
2596 out->len = len;
2597 return 1;
2598}
2599
Emeric Brunce5ad802012-10-22 14:11:22 +02002600
2601/* Copy Date in ASN1_UTCTIME format in struct chunk out.
2602 * Returns 1 if serial is found and copied, 0 if no valid time found
2603 * and -1 if output is not large enough.
2604 */
2605static int
2606ssl_sock_get_time(ASN1_TIME *tm, struct chunk *out)
2607{
2608 if (tm->type == V_ASN1_GENERALIZEDTIME) {
2609 ASN1_GENERALIZEDTIME *gentm = (ASN1_GENERALIZEDTIME *)tm;
2610
2611 if (gentm->length < 12)
2612 return 0;
2613 if (gentm->data[0] != 0x32 || gentm->data[1] != 0x30)
2614 return 0;
2615 if (out->size < gentm->length-2)
2616 return -1;
2617
2618 memcpy(out->str, gentm->data+2, gentm->length-2);
2619 out->len = gentm->length-2;
2620 return 1;
2621 }
2622 else if (tm->type == V_ASN1_UTCTIME) {
2623 ASN1_UTCTIME *utctm = (ASN1_UTCTIME *)tm;
2624
2625 if (utctm->length < 10)
2626 return 0;
2627 if (utctm->data[0] >= 0x35)
2628 return 0;
2629 if (out->size < utctm->length)
2630 return -1;
2631
2632 memcpy(out->str, utctm->data, utctm->length);
2633 out->len = utctm->length;
2634 return 1;
2635 }
2636
2637 return 0;
2638}
2639
Emeric Brun87855892012-10-17 17:39:35 +02002640/* Extract an entry from a X509_NAME and copy its value to an output chunk.
2641 * Returns 1 if entry found, 0 if entry not found, or -1 if output not large enough.
2642 */
2643static int
2644ssl_sock_get_dn_entry(X509_NAME *a, const struct chunk *entry, int pos, struct chunk *out)
2645{
2646 X509_NAME_ENTRY *ne;
2647 int i, j, n;
2648 int cur = 0;
2649 const char *s;
2650 char tmp[128];
2651
2652 out->len = 0;
2653 for (i = 0; i < sk_X509_NAME_ENTRY_num(a->entries); i++) {
2654 if (pos < 0)
2655 j = (sk_X509_NAME_ENTRY_num(a->entries)-1) - i;
2656 else
2657 j = i;
2658
2659 ne = sk_X509_NAME_ENTRY_value(a->entries, j);
2660 n = OBJ_obj2nid(ne->object);
2661 if ((n == NID_undef) || ((s = OBJ_nid2sn(n)) == NULL)) {
2662 i2t_ASN1_OBJECT(tmp, sizeof(tmp), ne->object);
2663 s = tmp;
2664 }
2665
2666 if (chunk_strcasecmp(entry, s) != 0)
2667 continue;
2668
2669 if (pos < 0)
2670 cur--;
2671 else
2672 cur++;
2673
2674 if (cur != pos)
2675 continue;
2676
2677 if (ne->value->length > out->size)
2678 return -1;
2679
2680 memcpy(out->str, ne->value->data, ne->value->length);
2681 out->len = ne->value->length;
2682 return 1;
2683 }
2684
2685 return 0;
2686
2687}
2688
2689/* Extract and format full DN from a X509_NAME and copy result into a chunk
2690 * Returns 1 if dn entries exits, 0 if no dn entry found or -1 if output is not large enough.
2691 */
2692static int
2693ssl_sock_get_dn_oneline(X509_NAME *a, struct chunk *out)
2694{
2695 X509_NAME_ENTRY *ne;
2696 int i, n, ln;
2697 int l = 0;
2698 const char *s;
2699 char *p;
2700 char tmp[128];
2701
2702 out->len = 0;
2703 p = out->str;
2704 for (i = 0; i < sk_X509_NAME_ENTRY_num(a->entries); i++) {
2705 ne = sk_X509_NAME_ENTRY_value(a->entries, i);
2706 n = OBJ_obj2nid(ne->object);
2707 if ((n == NID_undef) || ((s = OBJ_nid2sn(n)) == NULL)) {
2708 i2t_ASN1_OBJECT(tmp, sizeof(tmp), ne->object);
2709 s = tmp;
2710 }
2711 ln = strlen(s);
2712
2713 l += 1 + ln + 1 + ne->value->length;
2714 if (l > out->size)
2715 return -1;
2716 out->len = l;
2717
2718 *(p++)='/';
2719 memcpy(p, s, ln);
2720 p += ln;
2721 *(p++)='=';
2722 memcpy(p, ne->value->data, ne->value->length);
2723 p += ne->value->length;
2724 }
2725
2726 if (!out->len)
2727 return 0;
2728
2729 return 1;
2730}
2731
David Safb76832014-05-08 23:42:08 -04002732char *ssl_sock_get_version(struct connection *conn)
2733{
2734 if (!ssl_sock_is_ssl(conn))
2735 return NULL;
2736
2737 return (char *)SSL_get_version(conn->xprt_ctx);
2738}
2739
Emeric Brun49100982014-06-24 18:26:41 +02002740/* Extract peer certificate's common name into the chunk dest
2741 * Returns
2742 * the len of the extracted common name
2743 * or 0 if no CN found in DN
2744 * or -1 on error case (i.e. no peer certificate)
2745 */
2746int ssl_sock_get_remote_common_name(struct connection *conn, struct chunk *dest)
David Safb76832014-05-08 23:42:08 -04002747{
2748 X509 *crt = NULL;
2749 X509_NAME *name;
David Safb76832014-05-08 23:42:08 -04002750 const char find_cn[] = "CN";
2751 const struct chunk find_cn_chunk = {
2752 .str = (char *)&find_cn,
2753 .len = sizeof(find_cn)-1
2754 };
Emeric Brun49100982014-06-24 18:26:41 +02002755 int result = -1;
David Safb76832014-05-08 23:42:08 -04002756
2757 if (!ssl_sock_is_ssl(conn))
Emeric Brun49100982014-06-24 18:26:41 +02002758 goto out;
David Safb76832014-05-08 23:42:08 -04002759
2760 /* SSL_get_peer_certificate, it increase X509 * ref count */
2761 crt = SSL_get_peer_certificate(conn->xprt_ctx);
2762 if (!crt)
2763 goto out;
2764
2765 name = X509_get_subject_name(crt);
2766 if (!name)
2767 goto out;
David Safb76832014-05-08 23:42:08 -04002768
Emeric Brun49100982014-06-24 18:26:41 +02002769 result = ssl_sock_get_dn_entry(name, &find_cn_chunk, 1, dest);
2770out:
David Safb76832014-05-08 23:42:08 -04002771 if (crt)
2772 X509_free(crt);
2773
2774 return result;
2775}
2776
Dave McCowand6ec6052014-07-30 10:39:13 -04002777/* returns 1 if client passed a certificate for this session, 0 if not */
2778int ssl_sock_get_cert_used_sess(struct connection *conn)
2779{
2780 X509 *crt = NULL;
2781
2782 if (!ssl_sock_is_ssl(conn))
2783 return 0;
2784
2785 /* SSL_get_peer_certificate, it increase X509 * ref count */
2786 crt = SSL_get_peer_certificate(conn->xprt_ctx);
2787 if (!crt)
2788 return 0;
2789
2790 X509_free(crt);
2791 return 1;
2792}
2793
2794/* returns 1 if client passed a certificate for this connection, 0 if not */
2795int ssl_sock_get_cert_used_conn(struct connection *conn)
David Safb76832014-05-08 23:42:08 -04002796{
2797 if (!ssl_sock_is_ssl(conn))
2798 return 0;
2799
2800 return SSL_SOCK_ST_FL_VERIFY_DONE & conn->xprt_st ? 1 : 0;
2801}
2802
2803/* returns result from SSL verify */
2804unsigned int ssl_sock_get_verify_result(struct connection *conn)
2805{
2806 if (!ssl_sock_is_ssl(conn))
2807 return (unsigned int)X509_V_ERR_APPLICATION_VERIFICATION;
2808
2809 return (unsigned int)SSL_get_verify_result(conn->xprt_ctx);
2810}
2811
Willy Tarreau7875d092012-09-10 08:20:03 +02002812/***** Below are some sample fetching functions for ACL/patterns *****/
2813
Emeric Brune64aef12012-09-21 13:15:06 +02002814/* boolean, returns true if client cert was present */
2815static int
Emeric Brun2525b6b2012-10-18 15:59:43 +02002816smp_fetch_ssl_fc_has_crt(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
Willy Tarreauef38c392013-07-22 16:29:32 +02002817 const struct arg *args, struct sample *smp, const char *kw)
Emeric Brune64aef12012-09-21 13:15:06 +02002818{
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002819 struct connection *conn;
2820
2821 if (!l4)
2822 return 0;
2823
2824 conn = objt_conn(l4->si[0].end);
2825 if (!conn || conn->xprt != &ssl_sock)
Emeric Brune64aef12012-09-21 13:15:06 +02002826 return 0;
2827
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002828 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brune64aef12012-09-21 13:15:06 +02002829 smp->flags |= SMP_F_MAY_CHANGE;
2830 return 0;
2831 }
2832
2833 smp->flags = 0;
2834 smp->type = SMP_T_BOOL;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002835 smp->data.uint = SSL_SOCK_ST_FL_VERIFY_DONE & conn->xprt_st ? 1 : 0;
Emeric Brune64aef12012-09-21 13:15:06 +02002836
2837 return 1;
2838}
2839
Emeric Brunb3cc4252014-10-29 19:03:26 +01002840/* binary, returns a certificate in a binary chunk (der/raw).
2841 * The 5th keyword char is used to know if SSL_get_certificate or SSL_get_peer_certificate
2842 * should be use.
2843 */
2844static int
2845smp_fetch_ssl_x_der(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
2846 const struct arg *args, struct sample *smp, const char *kw)
2847{
2848 int cert_peer = (kw[4] == 'c') ? 1 : 0;
2849 X509 *crt = NULL;
2850 int ret = 0;
2851 struct chunk *smp_trash;
2852 struct connection *conn;
2853
2854 if (!l4)
2855 return 0;
2856
2857 conn = objt_conn(l4->si[0].end);
2858 if (!conn || conn->xprt != &ssl_sock)
2859 return 0;
2860
2861 if (!(conn->flags & CO_FL_CONNECTED)) {
2862 smp->flags |= SMP_F_MAY_CHANGE;
2863 return 0;
2864 }
2865
2866 if (cert_peer)
2867 crt = SSL_get_peer_certificate(conn->xprt_ctx);
2868 else
2869 crt = SSL_get_certificate(conn->xprt_ctx);
2870
2871 if (!crt)
2872 goto out;
2873
2874 smp_trash = get_trash_chunk();
2875 if (ssl_sock_crt2der(crt, smp_trash) <= 0)
2876 goto out;
2877
2878 smp->data.str = *smp_trash;
2879 smp->type = SMP_T_BIN;
2880 ret = 1;
2881out:
2882 /* SSL_get_peer_certificate, it increase X509 * ref count */
2883 if (cert_peer && crt)
2884 X509_free(crt);
2885 return ret;
2886}
2887
Emeric Brunba841a12014-04-30 17:05:08 +02002888/* binary, returns serial of certificate in a binary chunk.
2889 * The 5th keyword char is used to know if SSL_get_certificate or SSL_get_peer_certificate
2890 * should be use.
2891 */
Willy Tarreau8d598402012-10-22 17:58:39 +02002892static int
Emeric Brunba841a12014-04-30 17:05:08 +02002893smp_fetch_ssl_x_serial(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
Willy Tarreauef38c392013-07-22 16:29:32 +02002894 const struct arg *args, struct sample *smp, const char *kw)
Willy Tarreau8d598402012-10-22 17:58:39 +02002895{
Emeric Brunba841a12014-04-30 17:05:08 +02002896 int cert_peer = (kw[4] == 'c') ? 1 : 0;
Willy Tarreau8d598402012-10-22 17:58:39 +02002897 X509 *crt = NULL;
2898 int ret = 0;
2899 struct chunk *smp_trash;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002900 struct connection *conn;
2901
2902 if (!l4)
2903 return 0;
Willy Tarreau8d598402012-10-22 17:58:39 +02002904
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002905 conn = objt_conn(l4->si[0].end);
2906 if (!conn || conn->xprt != &ssl_sock)
Willy Tarreau8d598402012-10-22 17:58:39 +02002907 return 0;
2908
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002909 if (!(conn->flags & CO_FL_CONNECTED)) {
Willy Tarreau8d598402012-10-22 17:58:39 +02002910 smp->flags |= SMP_F_MAY_CHANGE;
2911 return 0;
2912 }
2913
Emeric Brunba841a12014-04-30 17:05:08 +02002914 if (cert_peer)
2915 crt = SSL_get_peer_certificate(conn->xprt_ctx);
2916 else
2917 crt = SSL_get_certificate(conn->xprt_ctx);
2918
Willy Tarreau8d598402012-10-22 17:58:39 +02002919 if (!crt)
2920 goto out;
2921
Willy Tarreau47ca5452012-12-23 20:22:19 +01002922 smp_trash = get_trash_chunk();
Willy Tarreau8d598402012-10-22 17:58:39 +02002923 if (ssl_sock_get_serial(crt, smp_trash) <= 0)
2924 goto out;
2925
2926 smp->data.str = *smp_trash;
2927 smp->type = SMP_T_BIN;
2928 ret = 1;
2929out:
Emeric Brunba841a12014-04-30 17:05:08 +02002930 /* SSL_get_peer_certificate, it increase X509 * ref count */
2931 if (cert_peer && crt)
Willy Tarreau8d598402012-10-22 17:58:39 +02002932 X509_free(crt);
2933 return ret;
2934}
Emeric Brune64aef12012-09-21 13:15:06 +02002935
Emeric Brunba841a12014-04-30 17:05:08 +02002936/* binary, returns the client certificate's SHA-1 fingerprint (SHA-1 hash of DER-encoded certificate) in a binary chunk.
2937 * The 5th keyword char is used to know if SSL_get_certificate or SSL_get_peer_certificate
2938 * should be use.
2939 */
James Votha051b4a2013-05-14 20:37:59 +02002940static int
Emeric Brunba841a12014-04-30 17:05:08 +02002941smp_fetch_ssl_x_sha1(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
Willy Tarreauef38c392013-07-22 16:29:32 +02002942 const struct arg *args, struct sample *smp, const char *kw)
James Votha051b4a2013-05-14 20:37:59 +02002943{
Emeric Brunba841a12014-04-30 17:05:08 +02002944 int cert_peer = (kw[4] == 'c') ? 1 : 0;
James Votha051b4a2013-05-14 20:37:59 +02002945 X509 *crt = NULL;
2946 const EVP_MD *digest;
2947 int ret = 0;
2948 struct chunk *smp_trash;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002949 struct connection *conn;
James Votha051b4a2013-05-14 20:37:59 +02002950
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002951 if (!l4)
James Votha051b4a2013-05-14 20:37:59 +02002952 return 0;
2953
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002954 conn = objt_conn(l4->si[0].end);
2955 if (!conn || conn->xprt != &ssl_sock)
2956 return 0;
2957
2958 if (!(conn->flags & CO_FL_CONNECTED)) {
James Votha051b4a2013-05-14 20:37:59 +02002959 smp->flags |= SMP_F_MAY_CHANGE;
2960 return 0;
2961 }
2962
Emeric Brunba841a12014-04-30 17:05:08 +02002963 if (cert_peer)
2964 crt = SSL_get_peer_certificate(conn->xprt_ctx);
2965 else
2966 crt = SSL_get_certificate(conn->xprt_ctx);
James Votha051b4a2013-05-14 20:37:59 +02002967 if (!crt)
2968 goto out;
2969
2970 smp_trash = get_trash_chunk();
2971 digest = EVP_sha1();
2972 X509_digest(crt, digest, (unsigned char *)smp_trash->str, (unsigned int *)&smp_trash->len);
2973
2974 smp->data.str = *smp_trash;
2975 smp->type = SMP_T_BIN;
2976 ret = 1;
2977out:
Emeric Brunba841a12014-04-30 17:05:08 +02002978 /* SSL_get_peer_certificate, it increase X509 * ref count */
2979 if (cert_peer && crt)
James Votha051b4a2013-05-14 20:37:59 +02002980 X509_free(crt);
2981 return ret;
2982}
2983
Emeric Brunba841a12014-04-30 17:05:08 +02002984/* string, returns certificate's notafter date in ASN1_UTCTIME format.
2985 * The 5th keyword char is used to know if SSL_get_certificate or SSL_get_peer_certificate
2986 * should be use.
2987 */
Emeric Brunce5ad802012-10-22 14:11:22 +02002988static int
Emeric Brunba841a12014-04-30 17:05:08 +02002989smp_fetch_ssl_x_notafter(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
Willy Tarreauef38c392013-07-22 16:29:32 +02002990 const struct arg *args, struct sample *smp, const char *kw)
Emeric Brunce5ad802012-10-22 14:11:22 +02002991{
Emeric Brunba841a12014-04-30 17:05:08 +02002992 int cert_peer = (kw[4] == 'c') ? 1 : 0;
Emeric Brunce5ad802012-10-22 14:11:22 +02002993 X509 *crt = NULL;
2994 int ret = 0;
2995 struct chunk *smp_trash;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002996 struct connection *conn;
Emeric Brunce5ad802012-10-22 14:11:22 +02002997
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002998 if (!l4)
Emeric Brunce5ad802012-10-22 14:11:22 +02002999 return 0;
3000
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003001 conn = objt_conn(l4->si[0].end);
3002 if (!conn || conn->xprt != &ssl_sock)
3003 return 0;
3004
3005 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brunce5ad802012-10-22 14:11:22 +02003006 smp->flags |= SMP_F_MAY_CHANGE;
3007 return 0;
3008 }
3009
Emeric Brunba841a12014-04-30 17:05:08 +02003010 if (cert_peer)
3011 crt = SSL_get_peer_certificate(conn->xprt_ctx);
3012 else
3013 crt = SSL_get_certificate(conn->xprt_ctx);
Emeric Brunce5ad802012-10-22 14:11:22 +02003014 if (!crt)
3015 goto out;
3016
Willy Tarreau47ca5452012-12-23 20:22:19 +01003017 smp_trash = get_trash_chunk();
Emeric Brunce5ad802012-10-22 14:11:22 +02003018 if (ssl_sock_get_time(X509_get_notAfter(crt), smp_trash) <= 0)
3019 goto out;
3020
3021 smp->data.str = *smp_trash;
3022 smp->type = SMP_T_STR;
3023 ret = 1;
3024out:
Emeric Brunba841a12014-04-30 17:05:08 +02003025 /* SSL_get_peer_certificate, it increase X509 * ref count */
3026 if (cert_peer && crt)
Emeric Brunce5ad802012-10-22 14:11:22 +02003027 X509_free(crt);
3028 return ret;
3029}
3030
Emeric Brunba841a12014-04-30 17:05:08 +02003031/* string, returns a string of a formatted full dn \C=..\O=..\OU=.. \CN=.. of certificate's issuer
3032 * The 5th keyword char is used to know if SSL_get_certificate or SSL_get_peer_certificate
3033 * should be use.
3034 */
Emeric Brun87855892012-10-17 17:39:35 +02003035static int
Emeric Brunba841a12014-04-30 17:05:08 +02003036smp_fetch_ssl_x_i_dn(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
Willy Tarreauef38c392013-07-22 16:29:32 +02003037 const struct arg *args, struct sample *smp, const char *kw)
Emeric Brun87855892012-10-17 17:39:35 +02003038{
Emeric Brunba841a12014-04-30 17:05:08 +02003039 int cert_peer = (kw[4] == 'c') ? 1 : 0;
Emeric Brun87855892012-10-17 17:39:35 +02003040 X509 *crt = NULL;
3041 X509_NAME *name;
3042 int ret = 0;
3043 struct chunk *smp_trash;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003044 struct connection *conn;
Emeric Brun87855892012-10-17 17:39:35 +02003045
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003046 if (!l4)
Emeric Brun87855892012-10-17 17:39:35 +02003047 return 0;
3048
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003049 conn = objt_conn(l4->si[0].end);
3050 if (!conn || conn->xprt != &ssl_sock)
3051 return 0;
3052
3053 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brun87855892012-10-17 17:39:35 +02003054 smp->flags |= SMP_F_MAY_CHANGE;
3055 return 0;
3056 }
3057
Emeric Brunba841a12014-04-30 17:05:08 +02003058 if (cert_peer)
3059 crt = SSL_get_peer_certificate(conn->xprt_ctx);
3060 else
3061 crt = SSL_get_certificate(conn->xprt_ctx);
Emeric Brun87855892012-10-17 17:39:35 +02003062 if (!crt)
3063 goto out;
3064
3065 name = X509_get_issuer_name(crt);
3066 if (!name)
3067 goto out;
3068
Willy Tarreau47ca5452012-12-23 20:22:19 +01003069 smp_trash = get_trash_chunk();
Emeric Brun87855892012-10-17 17:39:35 +02003070 if (args && args[0].type == ARGT_STR) {
3071 int pos = 1;
3072
3073 if (args[1].type == ARGT_SINT)
3074 pos = args[1].data.sint;
3075 else if (args[1].type == ARGT_UINT)
3076 pos =(int)args[1].data.uint;
3077
3078 if (ssl_sock_get_dn_entry(name, &args[0].data.str, pos, smp_trash) <= 0)
3079 goto out;
3080 }
3081 else if (ssl_sock_get_dn_oneline(name, smp_trash) <= 0)
3082 goto out;
3083
3084 smp->type = SMP_T_STR;
3085 smp->data.str = *smp_trash;
3086 ret = 1;
3087out:
Emeric Brunba841a12014-04-30 17:05:08 +02003088 /* SSL_get_peer_certificate, it increase X509 * ref count */
3089 if (cert_peer && crt)
Emeric Brun87855892012-10-17 17:39:35 +02003090 X509_free(crt);
3091 return ret;
3092}
3093
Emeric Brunba841a12014-04-30 17:05:08 +02003094/* string, returns notbefore date in ASN1_UTCTIME format.
3095 * The 5th keyword char is used to know if SSL_get_certificate or SSL_get_peer_certificate
3096 * should be use.
3097 */
Emeric Brunce5ad802012-10-22 14:11:22 +02003098static int
Emeric Brunba841a12014-04-30 17:05:08 +02003099smp_fetch_ssl_x_notbefore(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
Willy Tarreauef38c392013-07-22 16:29:32 +02003100 const struct arg *args, struct sample *smp, const char *kw)
Emeric Brunce5ad802012-10-22 14:11:22 +02003101{
Emeric Brunba841a12014-04-30 17:05:08 +02003102 int cert_peer = (kw[4] == 'c') ? 1 : 0;
Emeric Brunce5ad802012-10-22 14:11:22 +02003103 X509 *crt = NULL;
3104 int ret = 0;
3105 struct chunk *smp_trash;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003106 struct connection *conn;
3107
3108 if (!l4)
3109 return 0;
Emeric Brunce5ad802012-10-22 14:11:22 +02003110
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003111 conn = objt_conn(l4->si[0].end);
3112 if (!conn || conn->xprt != &ssl_sock)
Emeric Brunce5ad802012-10-22 14:11:22 +02003113 return 0;
3114
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003115 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brunce5ad802012-10-22 14:11:22 +02003116 smp->flags |= SMP_F_MAY_CHANGE;
3117 return 0;
3118 }
3119
Emeric Brunba841a12014-04-30 17:05:08 +02003120 if (cert_peer)
3121 crt = SSL_get_peer_certificate(conn->xprt_ctx);
3122 else
3123 crt = SSL_get_certificate(conn->xprt_ctx);
Emeric Brunce5ad802012-10-22 14:11:22 +02003124 if (!crt)
3125 goto out;
3126
Willy Tarreau47ca5452012-12-23 20:22:19 +01003127 smp_trash = get_trash_chunk();
Emeric Brunce5ad802012-10-22 14:11:22 +02003128 if (ssl_sock_get_time(X509_get_notBefore(crt), smp_trash) <= 0)
3129 goto out;
3130
3131 smp->data.str = *smp_trash;
3132 smp->type = SMP_T_STR;
3133 ret = 1;
3134out:
Emeric Brunba841a12014-04-30 17:05:08 +02003135 /* SSL_get_peer_certificate, it increase X509 * ref count */
3136 if (cert_peer && crt)
Emeric Brunce5ad802012-10-22 14:11:22 +02003137 X509_free(crt);
3138 return ret;
3139}
3140
Emeric Brunba841a12014-04-30 17:05:08 +02003141/* string, returns a string of a formatted full dn \C=..\O=..\OU=.. \CN=.. of certificate's subject
3142 * The 5th keyword char is used to know if SSL_get_certificate or SSL_get_peer_certificate
3143 * should be use.
3144 */
Emeric Brun87855892012-10-17 17:39:35 +02003145static int
Emeric Brunba841a12014-04-30 17:05:08 +02003146smp_fetch_ssl_x_s_dn(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
Willy Tarreauef38c392013-07-22 16:29:32 +02003147 const struct arg *args, struct sample *smp, const char *kw)
Emeric Brun87855892012-10-17 17:39:35 +02003148{
Emeric Brunba841a12014-04-30 17:05:08 +02003149 int cert_peer = (kw[4] == 'c') ? 1 : 0;
Emeric Brun87855892012-10-17 17:39:35 +02003150 X509 *crt = NULL;
3151 X509_NAME *name;
3152 int ret = 0;
3153 struct chunk *smp_trash;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003154 struct connection *conn;
Emeric Brun87855892012-10-17 17:39:35 +02003155
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003156 if (!l4)
Emeric Brun87855892012-10-17 17:39:35 +02003157 return 0;
3158
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003159 conn = objt_conn(l4->si[0].end);
3160 if (!conn || conn->xprt != &ssl_sock)
3161 return 0;
3162
3163 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brun87855892012-10-17 17:39:35 +02003164 smp->flags |= SMP_F_MAY_CHANGE;
3165 return 0;
3166 }
3167
Emeric Brunba841a12014-04-30 17:05:08 +02003168 if (cert_peer)
3169 crt = SSL_get_peer_certificate(conn->xprt_ctx);
3170 else
3171 crt = SSL_get_certificate(conn->xprt_ctx);
Emeric Brun87855892012-10-17 17:39:35 +02003172 if (!crt)
3173 goto out;
3174
3175 name = X509_get_subject_name(crt);
3176 if (!name)
3177 goto out;
3178
Willy Tarreau47ca5452012-12-23 20:22:19 +01003179 smp_trash = get_trash_chunk();
Emeric Brun87855892012-10-17 17:39:35 +02003180 if (args && args[0].type == ARGT_STR) {
3181 int pos = 1;
3182
3183 if (args[1].type == ARGT_SINT)
3184 pos = args[1].data.sint;
3185 else if (args[1].type == ARGT_UINT)
3186 pos =(int)args[1].data.uint;
3187
3188 if (ssl_sock_get_dn_entry(name, &args[0].data.str, pos, smp_trash) <= 0)
3189 goto out;
3190 }
3191 else if (ssl_sock_get_dn_oneline(name, smp_trash) <= 0)
3192 goto out;
3193
3194 smp->type = SMP_T_STR;
3195 smp->data.str = *smp_trash;
3196 ret = 1;
3197out:
Emeric Brunba841a12014-04-30 17:05:08 +02003198 /* SSL_get_peer_certificate, it increase X509 * ref count */
3199 if (cert_peer && crt)
Emeric Brun87855892012-10-17 17:39:35 +02003200 X509_free(crt);
3201 return ret;
3202}
Emeric Brun9143d372012-12-20 15:44:16 +01003203
3204/* integer, returns true if current session use a client certificate */
3205static int
3206smp_fetch_ssl_c_used(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
Willy Tarreauef38c392013-07-22 16:29:32 +02003207 const struct arg *args, struct sample *smp, const char *kw)
Emeric Brun9143d372012-12-20 15:44:16 +01003208{
3209 X509 *crt;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003210 struct connection *conn;
Emeric Brun9143d372012-12-20 15:44:16 +01003211
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003212 if (!l4)
Emeric Brun9143d372012-12-20 15:44:16 +01003213 return 0;
3214
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003215 conn = objt_conn(l4->si[0].end);
3216 if (!conn || conn->xprt != &ssl_sock)
3217 return 0;
3218
3219 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brun9143d372012-12-20 15:44:16 +01003220 smp->flags |= SMP_F_MAY_CHANGE;
3221 return 0;
3222 }
3223
3224 /* SSL_get_peer_certificate returns a ptr on allocated X509 struct */
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003225 crt = SSL_get_peer_certificate(conn->xprt_ctx);
Emeric Brun9143d372012-12-20 15:44:16 +01003226 if (crt) {
3227 X509_free(crt);
3228 }
3229
3230 smp->type = SMP_T_BOOL;
3231 smp->data.uint = (crt != NULL);
3232 return 1;
3233}
3234
Emeric Brunba841a12014-04-30 17:05:08 +02003235/* integer, returns the certificate version
3236 * The 5th keyword char is used to know if SSL_get_certificate or SSL_get_peer_certificate
3237 * should be use.
3238 */
Emeric Bruna7359fd2012-10-17 15:03:11 +02003239static int
Emeric Brunba841a12014-04-30 17:05:08 +02003240smp_fetch_ssl_x_version(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
Willy Tarreauef38c392013-07-22 16:29:32 +02003241 const struct arg *args, struct sample *smp, const char *kw)
Emeric Bruna7359fd2012-10-17 15:03:11 +02003242{
Emeric Brunba841a12014-04-30 17:05:08 +02003243 int cert_peer = (kw[4] == 'c') ? 1 : 0;
Emeric Bruna7359fd2012-10-17 15:03:11 +02003244 X509 *crt;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003245 struct connection *conn;
3246
3247 if (!l4)
3248 return 0;
Emeric Bruna7359fd2012-10-17 15:03:11 +02003249
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003250 conn = objt_conn(l4->si[0].end);
3251 if (!conn || conn->xprt != &ssl_sock)
Emeric Bruna7359fd2012-10-17 15:03:11 +02003252 return 0;
3253
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003254 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Bruna7359fd2012-10-17 15:03:11 +02003255 smp->flags |= SMP_F_MAY_CHANGE;
3256 return 0;
3257 }
3258
Emeric Brunba841a12014-04-30 17:05:08 +02003259 if (cert_peer)
3260 crt = SSL_get_peer_certificate(conn->xprt_ctx);
3261 else
3262 crt = SSL_get_certificate(conn->xprt_ctx);
Emeric Bruna7359fd2012-10-17 15:03:11 +02003263 if (!crt)
3264 return 0;
3265
3266 smp->data.uint = (unsigned int)(1 + X509_get_version(crt));
Emeric Brunba841a12014-04-30 17:05:08 +02003267 /* SSL_get_peer_certificate increase X509 * ref count */
3268 if (cert_peer)
3269 X509_free(crt);
Emeric Bruna7359fd2012-10-17 15:03:11 +02003270 smp->type = SMP_T_UINT;
3271
3272 return 1;
3273}
3274
Emeric Brunba841a12014-04-30 17:05:08 +02003275/* string, returns the certificate's signature algorithm.
3276 * The 5th keyword char is used to know if SSL_get_certificate or SSL_get_peer_certificate
3277 * should be use.
3278 */
Emeric Brun7f56e742012-10-19 18:15:40 +02003279static int
Emeric Brunba841a12014-04-30 17:05:08 +02003280smp_fetch_ssl_x_sig_alg(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
Willy Tarreauef38c392013-07-22 16:29:32 +02003281 const struct arg *args, struct sample *smp, const char *kw)
Emeric Brun7f56e742012-10-19 18:15:40 +02003282{
Emeric Brunba841a12014-04-30 17:05:08 +02003283 int cert_peer = (kw[4] == 'c') ? 1 : 0;
Emeric Brun7f56e742012-10-19 18:15:40 +02003284 X509 *crt;
3285 int nid;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003286 struct connection *conn;
Emeric Brun7f56e742012-10-19 18:15:40 +02003287
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003288 if (!l4)
Emeric Brun7f56e742012-10-19 18:15:40 +02003289 return 0;
3290
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003291 conn = objt_conn(l4->si[0].end);
3292 if (!conn || conn->xprt != &ssl_sock)
3293 return 0;
3294
3295 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brun7f56e742012-10-19 18:15:40 +02003296 smp->flags |= SMP_F_MAY_CHANGE;
3297 return 0;
3298 }
3299
Emeric Brunba841a12014-04-30 17:05:08 +02003300 if (cert_peer)
3301 crt = SSL_get_peer_certificate(conn->xprt_ctx);
3302 else
3303 crt = SSL_get_certificate(conn->xprt_ctx);
Emeric Brun7f56e742012-10-19 18:15:40 +02003304 if (!crt)
3305 return 0;
3306
3307 nid = OBJ_obj2nid((ASN1_OBJECT *)(crt->cert_info->signature->algorithm));
3308
3309 smp->data.str.str = (char *)OBJ_nid2sn(nid);
Emeric Brun9bf3ba22013-10-07 14:31:44 +02003310 if (!smp->data.str.str) {
Emeric Brunba841a12014-04-30 17:05:08 +02003311 /* SSL_get_peer_certificate increase X509 * ref count */
3312 if (cert_peer)
3313 X509_free(crt);
Emeric Brun7f56e742012-10-19 18:15:40 +02003314 return 0;
Emeric Brun9bf3ba22013-10-07 14:31:44 +02003315 }
Emeric Brun7f56e742012-10-19 18:15:40 +02003316
Thierry FOURNIER7654c9f2013-12-17 00:20:33 +01003317 smp->type = SMP_T_STR;
3318 smp->flags |= SMP_F_CONST;
Emeric Brun7f56e742012-10-19 18:15:40 +02003319 smp->data.str.len = strlen(smp->data.str.str);
Emeric Brunba841a12014-04-30 17:05:08 +02003320 /* SSL_get_peer_certificate increase X509 * ref count */
3321 if (cert_peer)
3322 X509_free(crt);
Emeric Brun7f56e742012-10-19 18:15:40 +02003323
3324 return 1;
3325}
3326
Emeric Brunba841a12014-04-30 17:05:08 +02003327/* string, returns the certificate's key algorithm.
3328 * The 5th keyword char is used to know if SSL_get_certificate or SSL_get_peer_certificate
3329 * should be use.
3330 */
Emeric Brun521a0112012-10-22 12:22:55 +02003331static int
Emeric Brunba841a12014-04-30 17:05:08 +02003332smp_fetch_ssl_x_key_alg(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
Willy Tarreauef38c392013-07-22 16:29:32 +02003333 const struct arg *args, struct sample *smp, const char *kw)
Emeric Brun521a0112012-10-22 12:22:55 +02003334{
Emeric Brunba841a12014-04-30 17:05:08 +02003335 int cert_peer = (kw[4] == 'c') ? 1 : 0;
Emeric Brun521a0112012-10-22 12:22:55 +02003336 X509 *crt;
3337 int nid;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003338 struct connection *conn;
Emeric Brun521a0112012-10-22 12:22:55 +02003339
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003340 if (!l4)
Emeric Brun521a0112012-10-22 12:22:55 +02003341 return 0;
3342
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003343 conn = objt_conn(l4->si[0].end);
3344 if (!conn || conn->xprt != &ssl_sock)
3345 return 0;
3346
3347 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brun521a0112012-10-22 12:22:55 +02003348 smp->flags |= SMP_F_MAY_CHANGE;
3349 return 0;
3350 }
3351
Emeric Brunba841a12014-04-30 17:05:08 +02003352 if (cert_peer)
3353 crt = SSL_get_peer_certificate(conn->xprt_ctx);
3354 else
3355 crt = SSL_get_certificate(conn->xprt_ctx);
Emeric Brun521a0112012-10-22 12:22:55 +02003356 if (!crt)
3357 return 0;
3358
3359 nid = OBJ_obj2nid((ASN1_OBJECT *)(crt->cert_info->key->algor->algorithm));
3360
3361 smp->data.str.str = (char *)OBJ_nid2sn(nid);
Emeric Brun9bf3ba22013-10-07 14:31:44 +02003362 if (!smp->data.str.str) {
Emeric Brunba841a12014-04-30 17:05:08 +02003363 /* SSL_get_peer_certificate increase X509 * ref count */
3364 if (cert_peer)
3365 X509_free(crt);
Emeric Brun521a0112012-10-22 12:22:55 +02003366 return 0;
Emeric Brun9bf3ba22013-10-07 14:31:44 +02003367 }
Emeric Brun521a0112012-10-22 12:22:55 +02003368
Thierry FOURNIER7654c9f2013-12-17 00:20:33 +01003369 smp->type = SMP_T_STR;
3370 smp->flags |= SMP_F_CONST;
Emeric Brun521a0112012-10-22 12:22:55 +02003371 smp->data.str.len = strlen(smp->data.str.str);
Emeric Brunba841a12014-04-30 17:05:08 +02003372 if (cert_peer)
3373 X509_free(crt);
Emeric Brun521a0112012-10-22 12:22:55 +02003374
3375 return 1;
3376}
3377
Emeric Brun645ae792014-04-30 14:21:06 +02003378/* boolean, returns true if front conn. transport layer is SSL.
3379 * This function is also usable on backend conn if the fetch keyword 5th
3380 * char is 'b'.
3381 */
Willy Tarreau7875d092012-09-10 08:20:03 +02003382static int
Emeric Brun2525b6b2012-10-18 15:59:43 +02003383smp_fetch_ssl_fc(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
Willy Tarreauef38c392013-07-22 16:29:32 +02003384 const struct arg *args, struct sample *smp, const char *kw)
Willy Tarreau7875d092012-09-10 08:20:03 +02003385{
Emeric Brun645ae792014-04-30 14:21:06 +02003386 int back_conn = (kw[4] == 'b') ? 1 : 0;
3387 struct connection *conn = objt_conn(l4->si[back_conn].end);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003388
Willy Tarreau7875d092012-09-10 08:20:03 +02003389 smp->type = SMP_T_BOOL;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003390 smp->data.uint = (conn && conn->xprt == &ssl_sock);
Willy Tarreau7875d092012-09-10 08:20:03 +02003391 return 1;
3392}
3393
Emeric Brun2525b6b2012-10-18 15:59:43 +02003394/* boolean, returns true if client present a SNI */
Willy Tarreau7875d092012-09-10 08:20:03 +02003395static int
Emeric Brun2525b6b2012-10-18 15:59:43 +02003396smp_fetch_ssl_fc_has_sni(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
Willy Tarreauef38c392013-07-22 16:29:32 +02003397 const struct arg *args, struct sample *smp, const char *kw)
Willy Tarreau7875d092012-09-10 08:20:03 +02003398{
3399#ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003400 struct connection *conn = objt_conn(l4->si[0].end);
3401
Willy Tarreau7875d092012-09-10 08:20:03 +02003402 smp->type = SMP_T_BOOL;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003403 smp->data.uint = (conn && conn->xprt == &ssl_sock) &&
3404 conn->xprt_ctx &&
3405 SSL_get_servername(conn->xprt_ctx, TLSEXT_NAMETYPE_host_name) != NULL;
Willy Tarreau7875d092012-09-10 08:20:03 +02003406 return 1;
3407#else
3408 return 0;
3409#endif
3410}
3411
Emeric Brun645ae792014-04-30 14:21:06 +02003412/* string, returns the used cipher if front conn. transport layer is SSL.
3413 * This function is also usable on backend conn if the fetch keyword 5th
3414 * char is 'b'.
3415 */
Emeric Brun589fcad2012-10-16 14:13:26 +02003416static int
3417smp_fetch_ssl_fc_cipher(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
Willy Tarreauef38c392013-07-22 16:29:32 +02003418 const struct arg *args, struct sample *smp, const char *kw)
Emeric Brun589fcad2012-10-16 14:13:26 +02003419{
Emeric Brun645ae792014-04-30 14:21:06 +02003420 int back_conn = (kw[4] == 'b') ? 1 : 0;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003421 struct connection *conn;
3422
Emeric Brun589fcad2012-10-16 14:13:26 +02003423 smp->flags = 0;
3424
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003425 if (!l4)
3426 return 0;
3427
Emeric Brun645ae792014-04-30 14:21:06 +02003428 conn = objt_conn(l4->si[back_conn].end);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003429 if (!conn || !conn->xprt_ctx || conn->xprt != &ssl_sock)
Emeric Brun589fcad2012-10-16 14:13:26 +02003430 return 0;
3431
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003432 smp->data.str.str = (char *)SSL_get_cipher_name(conn->xprt_ctx);
Emeric Brun589fcad2012-10-16 14:13:26 +02003433 if (!smp->data.str.str)
3434 return 0;
3435
Thierry FOURNIER7654c9f2013-12-17 00:20:33 +01003436 smp->type = SMP_T_STR;
3437 smp->flags |= SMP_F_CONST;
Emeric Brun589fcad2012-10-16 14:13:26 +02003438 smp->data.str.len = strlen(smp->data.str.str);
3439
3440 return 1;
3441}
3442
Emeric Brun645ae792014-04-30 14:21:06 +02003443/* integer, returns the algoritm's keysize if front conn. transport layer
3444 * is SSL.
3445 * This function is also usable on backend conn if the fetch keyword 5th
3446 * char is 'b'.
3447 */
Emeric Brun589fcad2012-10-16 14:13:26 +02003448static int
3449smp_fetch_ssl_fc_alg_keysize(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
Willy Tarreauef38c392013-07-22 16:29:32 +02003450 const struct arg *args, struct sample *smp, const char *kw)
Emeric Brun589fcad2012-10-16 14:13:26 +02003451{
Emeric Brun645ae792014-04-30 14:21:06 +02003452 int back_conn = (kw[4] == 'b') ? 1 : 0;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003453 struct connection *conn;
3454
Emeric Brun589fcad2012-10-16 14:13:26 +02003455 smp->flags = 0;
3456
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003457 if (!l4)
Emeric Brun589fcad2012-10-16 14:13:26 +02003458 return 0;
3459
Emeric Brun645ae792014-04-30 14:21:06 +02003460 conn = objt_conn(l4->si[back_conn].end);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003461 if (!conn || !conn->xprt_ctx || conn->xprt != &ssl_sock)
Emeric Brun589fcad2012-10-16 14:13:26 +02003462 return 0;
3463
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003464 if (!SSL_get_cipher_bits(conn->xprt_ctx, (int *)&smp->data.uint))
3465 return 0;
3466
Emeric Brun589fcad2012-10-16 14:13:26 +02003467 smp->type = SMP_T_UINT;
3468
3469 return 1;
3470}
3471
Emeric Brun645ae792014-04-30 14:21:06 +02003472/* integer, returns the used keysize if front conn. transport layer is SSL.
3473 * This function is also usable on backend conn if the fetch keyword 5th
3474 * char is 'b'.
3475 */
Emeric Brun589fcad2012-10-16 14:13:26 +02003476static int
3477smp_fetch_ssl_fc_use_keysize(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
Willy Tarreauef38c392013-07-22 16:29:32 +02003478 const struct arg *args, struct sample *smp, const char *kw)
Emeric Brun589fcad2012-10-16 14:13:26 +02003479{
Emeric Brun645ae792014-04-30 14:21:06 +02003480 int back_conn = (kw[4] == 'b') ? 1 : 0;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003481 struct connection *conn;
3482
Emeric Brun589fcad2012-10-16 14:13:26 +02003483 smp->flags = 0;
3484
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003485 if (!l4)
Emeric Brun589fcad2012-10-16 14:13:26 +02003486 return 0;
3487
Emeric Brun645ae792014-04-30 14:21:06 +02003488 conn = objt_conn(l4->si[back_conn].end);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003489 if (!conn || !conn->xprt_ctx || conn->xprt != &ssl_sock)
3490 return 0;
3491
3492 smp->data.uint = (unsigned int)SSL_get_cipher_bits(conn->xprt_ctx, NULL);
Emeric Brun589fcad2012-10-16 14:13:26 +02003493 if (!smp->data.uint)
3494 return 0;
3495
3496 smp->type = SMP_T_UINT;
3497
3498 return 1;
3499}
3500
Willy Tarreau6c9a3d52012-10-18 18:57:14 +02003501#ifdef OPENSSL_NPN_NEGOTIATED
Willy Tarreau7875d092012-09-10 08:20:03 +02003502static int
Emeric Brun2525b6b2012-10-18 15:59:43 +02003503smp_fetch_ssl_fc_npn(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
Willy Tarreauef38c392013-07-22 16:29:32 +02003504 const struct arg *args, struct sample *smp, const char *kw)
Willy Tarreaua33c6542012-10-15 13:19:06 +02003505{
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003506 struct connection *conn;
3507
Thierry FOURNIER7654c9f2013-12-17 00:20:33 +01003508 smp->flags = SMP_F_CONST;
3509 smp->type = SMP_T_STR;
Willy Tarreaua33c6542012-10-15 13:19:06 +02003510
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003511 if (!l4)
Willy Tarreaua33c6542012-10-15 13:19:06 +02003512 return 0;
3513
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003514 conn = objt_conn(l4->si[0].end);
3515 if (!conn || !conn->xprt_ctx || conn->xprt != &ssl_sock)
3516 return 0;
3517
Willy Tarreaua33c6542012-10-15 13:19:06 +02003518 smp->data.str.str = NULL;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003519 SSL_get0_next_proto_negotiated(conn->xprt_ctx,
Willy Tarreaua33c6542012-10-15 13:19:06 +02003520 (const unsigned char **)&smp->data.str.str, (unsigned *)&smp->data.str.len);
3521
3522 if (!smp->data.str.str)
3523 return 0;
3524
3525 return 1;
Willy Tarreaua33c6542012-10-15 13:19:06 +02003526}
Willy Tarreau6c9a3d52012-10-18 18:57:14 +02003527#endif
Willy Tarreaua33c6542012-10-15 13:19:06 +02003528
Dirkjan Bussink48f1c4e2014-02-13 12:29:42 +01003529#ifdef TLSEXT_TYPE_application_layer_protocol_negotiation
Willy Tarreauab861d32013-04-02 02:30:41 +02003530static int
3531smp_fetch_ssl_fc_alpn(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
Willy Tarreauef38c392013-07-22 16:29:32 +02003532 const struct arg *args, struct sample *smp, const char *kw)
Willy Tarreauab861d32013-04-02 02:30:41 +02003533{
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003534 struct connection *conn;
3535
Thierry FOURNIER7654c9f2013-12-17 00:20:33 +01003536 smp->flags = SMP_F_CONST;
3537 smp->type = SMP_T_STR;
Willy Tarreauab861d32013-04-02 02:30:41 +02003538
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003539 if (!l4)
3540 return 0;
3541
3542 conn = objt_conn(l4->si[0].end);
3543 if (!conn || !conn->xprt_ctx || conn->xprt != &ssl_sock)
Willy Tarreauab861d32013-04-02 02:30:41 +02003544 return 0;
3545
3546 smp->data.str.str = NULL;
Dirkjan Bussink48f1c4e2014-02-13 12:29:42 +01003547 SSL_get0_alpn_selected(conn->xprt_ctx,
Willy Tarreauab861d32013-04-02 02:30:41 +02003548 (const unsigned char **)&smp->data.str.str, (unsigned *)&smp->data.str.len);
3549
3550 if (!smp->data.str.str)
3551 return 0;
3552
3553 return 1;
3554}
3555#endif
3556
Emeric Brun645ae792014-04-30 14:21:06 +02003557/* string, returns the used protocol if front conn. transport layer is SSL.
3558 * This function is also usable on backend conn if the fetch keyword 5th
3559 * char is 'b'.
3560 */
Willy Tarreaua33c6542012-10-15 13:19:06 +02003561static int
Emeric Brun589fcad2012-10-16 14:13:26 +02003562smp_fetch_ssl_fc_protocol(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
Willy Tarreauef38c392013-07-22 16:29:32 +02003563 const struct arg *args, struct sample *smp, const char *kw)
Emeric Brun589fcad2012-10-16 14:13:26 +02003564{
Emeric Brun645ae792014-04-30 14:21:06 +02003565 int back_conn = (kw[4] == 'b') ? 1 : 0;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003566 struct connection *conn;
3567
Emeric Brun589fcad2012-10-16 14:13:26 +02003568 smp->flags = 0;
3569
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003570 if (!l4)
Emeric Brun589fcad2012-10-16 14:13:26 +02003571 return 0;
3572
Emeric Brun645ae792014-04-30 14:21:06 +02003573 conn = objt_conn(l4->si[back_conn].end);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003574 if (!conn || !conn->xprt_ctx || conn->xprt != &ssl_sock)
3575 return 0;
3576
3577 smp->data.str.str = (char *)SSL_get_version(conn->xprt_ctx);
Emeric Brun589fcad2012-10-16 14:13:26 +02003578 if (!smp->data.str.str)
3579 return 0;
3580
Thierry FOURNIER7654c9f2013-12-17 00:20:33 +01003581 smp->type = SMP_T_STR;
3582 smp->flags = SMP_F_CONST;
Emeric Brun589fcad2012-10-16 14:13:26 +02003583 smp->data.str.len = strlen(smp->data.str.str);
3584
3585 return 1;
3586}
3587
Emeric Brun645ae792014-04-30 14:21:06 +02003588/* binary, returns the SSL session id if front conn. transport layer is SSL.
3589 * This function is also usable on backend conn if the fetch keyword 5th
3590 * char is 'b'.
3591 */
Emeric Brun589fcad2012-10-16 14:13:26 +02003592static int
Emeric Brunfe68f682012-10-16 14:59:28 +02003593smp_fetch_ssl_fc_session_id(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
Willy Tarreauef38c392013-07-22 16:29:32 +02003594 const struct arg *args, struct sample *smp, const char *kw)
Emeric Brunfe68f682012-10-16 14:59:28 +02003595{
3596#if OPENSSL_VERSION_NUMBER > 0x0090800fL
Emeric Brun645ae792014-04-30 14:21:06 +02003597 int back_conn = (kw[4] == 'b') ? 1 : 0;
Emeric Brunfe68f682012-10-16 14:59:28 +02003598 SSL_SESSION *sess;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003599 struct connection *conn;
Emeric Brunfe68f682012-10-16 14:59:28 +02003600
Thierry FOURNIER7654c9f2013-12-17 00:20:33 +01003601 smp->flags = SMP_F_CONST;
3602 smp->type = SMP_T_BIN;
Emeric Brunfe68f682012-10-16 14:59:28 +02003603
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003604 if (!l4)
Emeric Brunfe68f682012-10-16 14:59:28 +02003605 return 0;
3606
Emeric Brun645ae792014-04-30 14:21:06 +02003607 conn = objt_conn(l4->si[back_conn].end);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003608 if (!conn || !conn->xprt_ctx || conn->xprt != &ssl_sock)
3609 return 0;
3610
3611 sess = SSL_get_session(conn->xprt_ctx);
Emeric Brunfe68f682012-10-16 14:59:28 +02003612 if (!sess)
3613 return 0;
3614
3615 smp->data.str.str = (char *)SSL_SESSION_get_id(sess, (unsigned int *)&smp->data.str.len);
3616 if (!smp->data.str.str || !&smp->data.str.len)
3617 return 0;
3618
3619 return 1;
3620#else
3621 return 0;
3622#endif
3623}
3624
3625static int
Emeric Brun2525b6b2012-10-18 15:59:43 +02003626smp_fetch_ssl_fc_sni(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
Willy Tarreauef38c392013-07-22 16:29:32 +02003627 const struct arg *args, struct sample *smp, const char *kw)
Willy Tarreau7875d092012-09-10 08:20:03 +02003628{
3629#ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003630 struct connection *conn;
3631
Thierry FOURNIER7654c9f2013-12-17 00:20:33 +01003632 smp->flags = SMP_F_CONST;
3633 smp->type = SMP_T_STR;
Willy Tarreau7875d092012-09-10 08:20:03 +02003634
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003635 if (!l4)
Willy Tarreau7875d092012-09-10 08:20:03 +02003636 return 0;
3637
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003638 conn = objt_conn(l4->si[0].end);
3639 if (!conn || !conn->xprt_ctx || conn->xprt != &ssl_sock)
3640 return 0;
3641
3642 smp->data.str.str = (char *)SSL_get_servername(conn->xprt_ctx, TLSEXT_NAMETYPE_host_name);
Willy Tarreau3e394c92012-09-14 23:56:58 +02003643 if (!smp->data.str.str)
3644 return 0;
3645
Willy Tarreau7875d092012-09-10 08:20:03 +02003646 smp->data.str.len = strlen(smp->data.str.str);
3647 return 1;
3648#else
3649 return 0;
3650#endif
3651}
3652
David Sc1ad52e2014-04-08 18:48:47 -04003653static int
3654smp_fetch_ssl_fc_unique_id(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
3655 const struct arg *args, struct sample *smp, const char *kw)
3656{
3657#if OPENSSL_VERSION_NUMBER > 0x0090800fL
Emeric Brun645ae792014-04-30 14:21:06 +02003658 int back_conn = (kw[4] == 'b') ? 1 : 0;
David Sc1ad52e2014-04-08 18:48:47 -04003659 struct connection *conn;
3660 int finished_len;
David Sc1ad52e2014-04-08 18:48:47 -04003661 struct chunk *finished_trash;
David Sc1ad52e2014-04-08 18:48:47 -04003662
3663 smp->flags = 0;
3664
3665 if (!l4)
3666 return 0;
3667
Emeric Brun645ae792014-04-30 14:21:06 +02003668 conn = objt_conn(l4->si[back_conn].end);
David Sc1ad52e2014-04-08 18:48:47 -04003669 if (!conn || !conn->xprt_ctx || conn->xprt != &ssl_sock)
3670 return 0;
3671
3672 if (!(conn->flags & CO_FL_CONNECTED)) {
3673 smp->flags |= SMP_F_MAY_CHANGE;
3674 return 0;
3675 }
3676
3677 finished_trash = get_trash_chunk();
3678 if (!SSL_session_reused(conn->xprt_ctx))
3679 finished_len = SSL_get_peer_finished(conn->xprt_ctx, finished_trash->str, finished_trash->size);
3680 else
3681 finished_len = SSL_get_finished(conn->xprt_ctx, finished_trash->str, finished_trash->size);
3682
3683 if (!finished_len)
3684 return 0;
3685
Emeric Brunb73a9b02014-04-30 18:49:19 +02003686 finished_trash->len = finished_len;
3687 smp->data.str = *finished_trash;
3688 smp->type = SMP_T_BIN;
David Sc1ad52e2014-04-08 18:48:47 -04003689
3690 return 1;
3691#else
3692 return 0;
3693#endif
3694}
3695
Emeric Brun2525b6b2012-10-18 15:59:43 +02003696/* integer, returns the first verify error in CA chain of client certificate chain. */
Emeric Brunf282a812012-09-21 15:27:54 +02003697static int
Emeric Brun2525b6b2012-10-18 15:59:43 +02003698smp_fetch_ssl_c_ca_err(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
Willy Tarreauef38c392013-07-22 16:29:32 +02003699 const struct arg *args, struct sample *smp, const char *kw)
Emeric Brunf282a812012-09-21 15:27:54 +02003700{
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003701 struct connection *conn;
3702
3703 if (!l4)
Emeric Brunf282a812012-09-21 15:27:54 +02003704 return 0;
3705
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003706 conn = objt_conn(l4->si[0].end);
3707 if (!conn || conn->xprt != &ssl_sock)
3708 return 0;
3709
3710 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brunf282a812012-09-21 15:27:54 +02003711 smp->flags = SMP_F_MAY_CHANGE;
3712 return 0;
3713 }
3714
3715 smp->type = SMP_T_UINT;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003716 smp->data.uint = (unsigned int)SSL_SOCK_ST_TO_CA_ERROR(conn->xprt_st);
Emeric Brunf282a812012-09-21 15:27:54 +02003717 smp->flags = 0;
3718
3719 return 1;
3720}
3721
Emeric Brun2525b6b2012-10-18 15:59:43 +02003722/* integer, returns the depth of the first verify error in CA chain of client certificate chain. */
Emeric Brunf282a812012-09-21 15:27:54 +02003723static int
Emeric Brun2525b6b2012-10-18 15:59:43 +02003724smp_fetch_ssl_c_ca_err_depth(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
Willy Tarreauef38c392013-07-22 16:29:32 +02003725 const struct arg *args, struct sample *smp, const char *kw)
Emeric Brunf282a812012-09-21 15:27:54 +02003726{
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003727 struct connection *conn;
3728
3729 if (!l4)
3730 return 0;
3731
3732 conn = objt_conn(l4->si[0].end);
3733 if (!conn || conn->xprt != &ssl_sock)
Emeric Brunf282a812012-09-21 15:27:54 +02003734 return 0;
3735
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003736 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brunf282a812012-09-21 15:27:54 +02003737 smp->flags = SMP_F_MAY_CHANGE;
3738 return 0;
3739 }
3740
3741 smp->type = SMP_T_UINT;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003742 smp->data.uint = (unsigned int)SSL_SOCK_ST_TO_CAEDEPTH(conn->xprt_st);
Emeric Brunf282a812012-09-21 15:27:54 +02003743 smp->flags = 0;
3744
3745 return 1;
3746}
3747
Emeric Brun2525b6b2012-10-18 15:59:43 +02003748/* integer, returns the first verify error on client certificate */
Emeric Brunf282a812012-09-21 15:27:54 +02003749static int
Emeric Brun2525b6b2012-10-18 15:59:43 +02003750smp_fetch_ssl_c_err(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
Willy Tarreauef38c392013-07-22 16:29:32 +02003751 const struct arg *args, struct sample *smp, const char *kw)
Emeric Brunf282a812012-09-21 15:27:54 +02003752{
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003753 struct connection *conn;
3754
3755 if (!l4)
Emeric Brunf282a812012-09-21 15:27:54 +02003756 return 0;
3757
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003758 conn = objt_conn(l4->si[0].end);
3759 if (!conn || conn->xprt != &ssl_sock)
3760 return 0;
3761
3762 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brunf282a812012-09-21 15:27:54 +02003763 smp->flags = SMP_F_MAY_CHANGE;
3764 return 0;
3765 }
3766
3767 smp->type = SMP_T_UINT;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003768 smp->data.uint = (unsigned int)SSL_SOCK_ST_TO_CRTERROR(conn->xprt_st);
Emeric Brunf282a812012-09-21 15:27:54 +02003769 smp->flags = 0;
3770
3771 return 1;
3772}
3773
Emeric Brun2525b6b2012-10-18 15:59:43 +02003774/* integer, returns the verify result on client cert */
Emeric Brunbaf8ffb2012-09-21 15:27:20 +02003775static int
Emeric Brun2525b6b2012-10-18 15:59:43 +02003776smp_fetch_ssl_c_verify(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
Willy Tarreauef38c392013-07-22 16:29:32 +02003777 const struct arg *args, struct sample *smp, const char *kw)
Emeric Brunbaf8ffb2012-09-21 15:27:20 +02003778{
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003779 struct connection *conn;
3780
3781 if (!l4)
Emeric Brunbaf8ffb2012-09-21 15:27:20 +02003782 return 0;
3783
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003784 conn = objt_conn(l4->si[0].end);
3785 if (!conn || conn->xprt != &ssl_sock)
3786 return 0;
3787
3788 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brunbaf8ffb2012-09-21 15:27:20 +02003789 smp->flags = SMP_F_MAY_CHANGE;
3790 return 0;
3791 }
3792
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003793 if (!conn->xprt_ctx)
Emeric Brunbaf8ffb2012-09-21 15:27:20 +02003794 return 0;
3795
3796 smp->type = SMP_T_UINT;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003797 smp->data.uint = (unsigned int)SSL_get_verify_result(conn->xprt_ctx);
Emeric Brunbaf8ffb2012-09-21 15:27:20 +02003798 smp->flags = 0;
3799
3800 return 1;
3801}
3802
Emeric Brunfb510ea2012-10-05 12:00:26 +02003803/* parse the "ca-file" bind keyword */
3804static 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 +02003805{
3806 if (!*args[cur_arg + 1]) {
3807 if (err)
3808 memprintf(err, "'%s' : missing CAfile path", args[cur_arg]);
3809 return ERR_ALERT | ERR_FATAL;
3810 }
3811
Emeric Brunef42d922012-10-11 16:11:36 +02003812 if ((*args[cur_arg + 1] != '/') && global.ca_base)
3813 memprintf(&conf->ca_file, "%s/%s", global.ca_base, args[cur_arg + 1]);
3814 else
3815 memprintf(&conf->ca_file, "%s", args[cur_arg + 1]);
Emeric Brunc8e8d122012-10-02 18:42:10 +02003816
Emeric Brund94b3fe2012-09-20 18:23:56 +02003817 return 0;
3818}
3819
Willy Tarreau79eeafa2012-09-14 07:53:05 +02003820/* parse the "ciphers" bind keyword */
Willy Tarreau4348fad2012-09-20 16:48:07 +02003821static 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 +02003822{
3823 if (!*args[cur_arg + 1]) {
Willy Tarreaueb6cead2012-09-20 19:43:14 +02003824 memprintf(err, "'%s' : missing cipher suite", args[cur_arg]);
Willy Tarreau79eeafa2012-09-14 07:53:05 +02003825 return ERR_ALERT | ERR_FATAL;
3826 }
3827
Emeric Brun76d88952012-10-05 15:47:31 +02003828 free(conf->ciphers);
Willy Tarreau4348fad2012-09-20 16:48:07 +02003829 conf->ciphers = strdup(args[cur_arg + 1]);
Willy Tarreau79eeafa2012-09-14 07:53:05 +02003830 return 0;
3831}
3832
3833/* parse the "crt" bind keyword */
Willy Tarreau4348fad2012-09-20 16:48:07 +02003834static 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 +02003835{
Willy Tarreau38011032013-08-13 16:59:39 +02003836 char path[MAXPATHLEN];
Willy Tarreaub75d6922014-04-14 18:05:41 +02003837
Willy Tarreau79eeafa2012-09-14 07:53:05 +02003838 if (!*args[cur_arg + 1]) {
Willy Tarreaueb6cead2012-09-20 19:43:14 +02003839 memprintf(err, "'%s' : missing certificate location", args[cur_arg]);
Willy Tarreau79eeafa2012-09-14 07:53:05 +02003840 return ERR_ALERT | ERR_FATAL;
3841 }
3842
Emeric Brunc8e8d122012-10-02 18:42:10 +02003843 if ((*args[cur_arg + 1] != '/' ) && global.crt_base) {
Willy Tarreau38011032013-08-13 16:59:39 +02003844 if ((strlen(global.crt_base) + 1 + strlen(args[cur_arg + 1]) + 1) > MAXPATHLEN) {
Emeric Brunc8e8d122012-10-02 18:42:10 +02003845 memprintf(err, "'%s' : path too long", args[cur_arg]);
3846 return ERR_ALERT | ERR_FATAL;
3847 }
Willy Tarreaub75d6922014-04-14 18:05:41 +02003848 snprintf(path, sizeof(path), "%s/%s", global.crt_base, args[cur_arg + 1]);
Emeric Brunc8e8d122012-10-02 18:42:10 +02003849 if (ssl_sock_load_cert(path, conf, px, err) > 0)
3850 return ERR_ALERT | ERR_FATAL;
3851
3852 return 0;
3853 }
3854
Willy Tarreau4348fad2012-09-20 16:48:07 +02003855 if (ssl_sock_load_cert(args[cur_arg + 1], conf, px, err) > 0)
Willy Tarreau79eeafa2012-09-14 07:53:05 +02003856 return ERR_ALERT | ERR_FATAL;
Emeric Brund94b3fe2012-09-20 18:23:56 +02003857
3858 return 0;
3859}
3860
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01003861/* parse the "crt-list" bind keyword */
3862static int bind_parse_crt_list(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
3863{
3864 if (!*args[cur_arg + 1]) {
3865 memprintf(err, "'%s' : missing certificate location", args[cur_arg]);
3866 return ERR_ALERT | ERR_FATAL;
3867 }
3868
Willy Tarreauad1731d2013-04-02 17:35:58 +02003869 if (ssl_sock_load_cert_list_file(args[cur_arg + 1], conf, px, err) > 0) {
3870 memprintf(err, "'%s' : %s", args[cur_arg], *err);
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01003871 return ERR_ALERT | ERR_FATAL;
Willy Tarreauad1731d2013-04-02 17:35:58 +02003872 }
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01003873
3874 return 0;
3875}
3876
Emeric Brunfb510ea2012-10-05 12:00:26 +02003877/* parse the "crl-file" bind keyword */
3878static 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 +02003879{
Emeric Brun051cdab2012-10-02 19:25:50 +02003880#ifndef X509_V_FLAG_CRL_CHECK
3881 if (err)
3882 memprintf(err, "'%s' : library does not support CRL verify", args[cur_arg]);
3883 return ERR_ALERT | ERR_FATAL;
3884#else
Emeric Brund94b3fe2012-09-20 18:23:56 +02003885 if (!*args[cur_arg + 1]) {
3886 if (err)
3887 memprintf(err, "'%s' : missing CRLfile path", args[cur_arg]);
3888 return ERR_ALERT | ERR_FATAL;
3889 }
Emeric Brun2b58d042012-09-20 17:10:03 +02003890
Emeric Brunef42d922012-10-11 16:11:36 +02003891 if ((*args[cur_arg + 1] != '/') && global.ca_base)
3892 memprintf(&conf->crl_file, "%s/%s", global.ca_base, args[cur_arg + 1]);
3893 else
3894 memprintf(&conf->crl_file, "%s", args[cur_arg + 1]);
Emeric Brunc8e8d122012-10-02 18:42:10 +02003895
Emeric Brun2b58d042012-09-20 17:10:03 +02003896 return 0;
Emeric Brun051cdab2012-10-02 19:25:50 +02003897#endif
Emeric Brun2b58d042012-09-20 17:10:03 +02003898}
3899
3900/* parse the "ecdhe" bind keyword keywords */
3901static int bind_parse_ecdhe(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
3902{
3903#if OPENSSL_VERSION_NUMBER < 0x0090800fL
3904 if (err)
3905 memprintf(err, "'%s' : library does not support elliptic curve Diffie-Hellman (too old)", args[cur_arg]);
3906 return ERR_ALERT | ERR_FATAL;
3907#elif defined(OPENSSL_NO_ECDH)
3908 if (err)
3909 memprintf(err, "'%s' : library does not support elliptic curve Diffie-Hellman (disabled via OPENSSL_NO_ECDH)", args[cur_arg]);
3910 return ERR_ALERT | ERR_FATAL;
3911#else
3912 if (!*args[cur_arg + 1]) {
3913 if (err)
3914 memprintf(err, "'%s' : missing named curve", args[cur_arg]);
3915 return ERR_ALERT | ERR_FATAL;
3916 }
3917
3918 conf->ecdhe = strdup(args[cur_arg + 1]);
Willy Tarreau79eeafa2012-09-14 07:53:05 +02003919
3920 return 0;
Emeric Brun2b58d042012-09-20 17:10:03 +02003921#endif
Willy Tarreau79eeafa2012-09-14 07:53:05 +02003922}
3923
Emeric Brun81c00f02012-09-21 14:31:21 +02003924/* parse the "crt_ignerr" and "ca_ignerr" bind keywords */
3925static int bind_parse_ignore_err(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
3926{
3927 int code;
3928 char *p = args[cur_arg + 1];
3929 unsigned long long *ignerr = &conf->crt_ignerr;
3930
3931 if (!*p) {
3932 if (err)
3933 memprintf(err, "'%s' : missing error IDs list", args[cur_arg]);
3934 return ERR_ALERT | ERR_FATAL;
3935 }
3936
3937 if (strcmp(args[cur_arg], "ca-ignore-err") == 0)
3938 ignerr = &conf->ca_ignerr;
3939
3940 if (strcmp(p, "all") == 0) {
3941 *ignerr = ~0ULL;
3942 return 0;
3943 }
3944
3945 while (p) {
3946 code = atoi(p);
3947 if ((code <= 0) || (code > 63)) {
3948 if (err)
3949 memprintf(err, "'%s' : ID '%d' out of range (1..63) in error IDs list '%s'",
3950 args[cur_arg], code, args[cur_arg + 1]);
3951 return ERR_ALERT | ERR_FATAL;
3952 }
3953 *ignerr |= 1ULL << code;
3954 p = strchr(p, ',');
3955 if (p)
3956 p++;
3957 }
3958
Emeric Brun2cb7ae52012-10-05 14:14:21 +02003959 return 0;
3960}
3961
3962/* parse the "force-sslv3" bind keyword */
3963static int bind_parse_force_sslv3(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
3964{
3965 conf->ssl_options |= BC_SSL_O_USE_SSLV3;
3966 return 0;
3967}
3968
3969/* parse the "force-tlsv10" bind keyword */
3970static int bind_parse_force_tlsv10(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
3971{
3972 conf->ssl_options |= BC_SSL_O_USE_TLSV10;
Emeric Brun2d0c4822012-10-02 13:45:20 +02003973 return 0;
3974}
3975
Emeric Brun2cb7ae52012-10-05 14:14:21 +02003976/* parse the "force-tlsv11" bind keyword */
3977static int bind_parse_force_tlsv11(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
3978{
3979#if SSL_OP_NO_TLSv1_1
3980 conf->ssl_options |= BC_SSL_O_USE_TLSV11;
3981 return 0;
3982#else
3983 if (err)
3984 memprintf(err, "'%s' : library does not support protocol TLSv1.1", args[cur_arg]);
3985 return ERR_ALERT | ERR_FATAL;
3986#endif
3987}
3988
3989/* parse the "force-tlsv12" bind keyword */
3990static int bind_parse_force_tlsv12(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
3991{
3992#if SSL_OP_NO_TLSv1_2
3993 conf->ssl_options |= BC_SSL_O_USE_TLSV12;
3994 return 0;
3995#else
3996 if (err)
3997 memprintf(err, "'%s' : library does not support protocol TLSv1.2", args[cur_arg]);
3998 return ERR_ALERT | ERR_FATAL;
3999#endif
4000}
4001
4002
Emeric Brun2d0c4822012-10-02 13:45:20 +02004003/* parse the "no-tls-tickets" bind keyword */
4004static int bind_parse_no_tls_tickets(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
4005{
Emeric Brun89675492012-10-05 13:48:26 +02004006 conf->ssl_options |= BC_SSL_O_NO_TLS_TICKETS;
Emeric Brun81c00f02012-09-21 14:31:21 +02004007 return 0;
4008}
4009
Emeric Brun2d0c4822012-10-02 13:45:20 +02004010
Emeric Brun9b3009b2012-10-05 11:55:06 +02004011/* parse the "no-sslv3" bind keyword */
4012static 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 +02004013{
Emeric Brun89675492012-10-05 13:48:26 +02004014 conf->ssl_options |= BC_SSL_O_NO_SSLV3;
Willy Tarreau79eeafa2012-09-14 07:53:05 +02004015 return 0;
4016}
4017
Emeric Brun9b3009b2012-10-05 11:55:06 +02004018/* parse the "no-tlsv10" bind keyword */
4019static 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 +02004020{
Emeric Brun89675492012-10-05 13:48:26 +02004021 conf->ssl_options |= BC_SSL_O_NO_TLSV10;
Emeric Brunc0ff4922012-09-28 19:37:02 +02004022 return 0;
4023}
4024
Emeric Brun9b3009b2012-10-05 11:55:06 +02004025/* parse the "no-tlsv11" bind keyword */
4026static 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 +02004027{
Emeric Brun89675492012-10-05 13:48:26 +02004028 conf->ssl_options |= BC_SSL_O_NO_TLSV11;
Emeric Brunc0ff4922012-09-28 19:37:02 +02004029 return 0;
4030}
4031
Emeric Brun9b3009b2012-10-05 11:55:06 +02004032/* parse the "no-tlsv12" bind keyword */
4033static 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 +02004034{
Emeric Brun89675492012-10-05 13:48:26 +02004035 conf->ssl_options |= BC_SSL_O_NO_TLSV12;
Willy Tarreau79eeafa2012-09-14 07:53:05 +02004036 return 0;
4037}
4038
Willy Tarreau6c9a3d52012-10-18 18:57:14 +02004039/* parse the "npn" bind keyword */
4040static int bind_parse_npn(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
4041{
4042#ifdef OPENSSL_NPN_NEGOTIATED
4043 char *p1, *p2;
4044
4045 if (!*args[cur_arg + 1]) {
4046 memprintf(err, "'%s' : missing the comma-delimited NPN protocol suite", args[cur_arg]);
4047 return ERR_ALERT | ERR_FATAL;
4048 }
4049
4050 free(conf->npn_str);
4051
4052 /* the NPN string is built as a suite of (<len> <name>)* */
4053 conf->npn_len = strlen(args[cur_arg + 1]) + 1;
4054 conf->npn_str = calloc(1, conf->npn_len);
4055 memcpy(conf->npn_str + 1, args[cur_arg + 1], conf->npn_len);
4056
4057 /* replace commas with the name length */
4058 p1 = conf->npn_str;
4059 p2 = p1 + 1;
4060 while (1) {
4061 p2 = memchr(p1 + 1, ',', conf->npn_str + conf->npn_len - (p1 + 1));
4062 if (!p2)
4063 p2 = p1 + 1 + strlen(p1 + 1);
4064
4065 if (p2 - (p1 + 1) > 255) {
4066 *p2 = '\0';
4067 memprintf(err, "'%s' : NPN protocol name too long : '%s'", args[cur_arg], p1 + 1);
4068 return ERR_ALERT | ERR_FATAL;
4069 }
4070
4071 *p1 = p2 - (p1 + 1);
4072 p1 = p2;
4073
4074 if (!*p2)
4075 break;
4076
4077 *(p2++) = '\0';
4078 }
4079 return 0;
4080#else
4081 if (err)
4082 memprintf(err, "'%s' : library does not support TLS NPN extension", args[cur_arg]);
4083 return ERR_ALERT | ERR_FATAL;
4084#endif
4085}
4086
Willy Tarreauab861d32013-04-02 02:30:41 +02004087/* parse the "alpn" bind keyword */
4088static int bind_parse_alpn(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
4089{
Dirkjan Bussink48f1c4e2014-02-13 12:29:42 +01004090#ifdef TLSEXT_TYPE_application_layer_protocol_negotiation
Willy Tarreauab861d32013-04-02 02:30:41 +02004091 char *p1, *p2;
4092
4093 if (!*args[cur_arg + 1]) {
4094 memprintf(err, "'%s' : missing the comma-delimited ALPN protocol suite", args[cur_arg]);
4095 return ERR_ALERT | ERR_FATAL;
4096 }
4097
4098 free(conf->alpn_str);
4099
4100 /* the ALPN string is built as a suite of (<len> <name>)* */
4101 conf->alpn_len = strlen(args[cur_arg + 1]) + 1;
4102 conf->alpn_str = calloc(1, conf->alpn_len);
4103 memcpy(conf->alpn_str + 1, args[cur_arg + 1], conf->alpn_len);
4104
4105 /* replace commas with the name length */
4106 p1 = conf->alpn_str;
4107 p2 = p1 + 1;
4108 while (1) {
4109 p2 = memchr(p1 + 1, ',', conf->alpn_str + conf->alpn_len - (p1 + 1));
4110 if (!p2)
4111 p2 = p1 + 1 + strlen(p1 + 1);
4112
4113 if (p2 - (p1 + 1) > 255) {
4114 *p2 = '\0';
4115 memprintf(err, "'%s' : ALPN protocol name too long : '%s'", args[cur_arg], p1 + 1);
4116 return ERR_ALERT | ERR_FATAL;
4117 }
4118
4119 *p1 = p2 - (p1 + 1);
4120 p1 = p2;
4121
4122 if (!*p2)
4123 break;
4124
4125 *(p2++) = '\0';
4126 }
4127 return 0;
4128#else
4129 if (err)
4130 memprintf(err, "'%s' : library does not support TLS ALPN extension", args[cur_arg]);
4131 return ERR_ALERT | ERR_FATAL;
4132#endif
4133}
4134
Willy Tarreau79eeafa2012-09-14 07:53:05 +02004135/* parse the "ssl" bind keyword */
Willy Tarreau4348fad2012-09-20 16:48:07 +02004136static 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 +02004137{
Willy Tarreau81796be2012-09-22 19:11:47 +02004138 struct listener *l;
4139
Willy Tarreau4348fad2012-09-20 16:48:07 +02004140 conf->is_ssl = 1;
Emeric Brun76d88952012-10-05 15:47:31 +02004141
4142 if (global.listen_default_ciphers && !conf->ciphers)
4143 conf->ciphers = strdup(global.listen_default_ciphers);
Emeric Brun42a3e202014-10-30 15:56:50 +01004144 conf->ssl_options |= global.listen_default_ssloptions;
Emeric Brun76d88952012-10-05 15:47:31 +02004145
Willy Tarreau81796be2012-09-22 19:11:47 +02004146 list_for_each_entry(l, &conf->listeners, by_bind)
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02004147 l->xprt = &ssl_sock;
Willy Tarreau81796be2012-09-22 19:11:47 +02004148
Willy Tarreau79eeafa2012-09-14 07:53:05 +02004149 return 0;
4150}
4151
Emmanuel Hocdet65623372013-01-24 17:17:15 +01004152/* parse the "strict-sni" bind keyword */
4153static int bind_parse_strict_sni(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
4154{
4155 conf->strict_sni = 1;
4156 return 0;
4157}
4158
Emeric Brund94b3fe2012-09-20 18:23:56 +02004159/* parse the "verify" bind keyword */
4160static int bind_parse_verify(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
4161{
4162 if (!*args[cur_arg + 1]) {
4163 if (err)
4164 memprintf(err, "'%s' : missing verify method", args[cur_arg]);
4165 return ERR_ALERT | ERR_FATAL;
4166 }
4167
4168 if (strcmp(args[cur_arg + 1], "none") == 0)
Emeric Brun850efd52014-01-29 12:24:34 +01004169 conf->verify = SSL_SOCK_VERIFY_NONE;
Emeric Brund94b3fe2012-09-20 18:23:56 +02004170 else if (strcmp(args[cur_arg + 1], "optional") == 0)
Emeric Brun850efd52014-01-29 12:24:34 +01004171 conf->verify = SSL_SOCK_VERIFY_OPTIONAL;
Emeric Brund94b3fe2012-09-20 18:23:56 +02004172 else if (strcmp(args[cur_arg + 1], "required") == 0)
Emeric Brun850efd52014-01-29 12:24:34 +01004173 conf->verify = SSL_SOCK_VERIFY_REQUIRED;
Emeric Brund94b3fe2012-09-20 18:23:56 +02004174 else {
4175 if (err)
4176 memprintf(err, "'%s' : unknown verify method '%s', only 'none', 'optional', and 'required' are supported\n",
4177 args[cur_arg], args[cur_arg + 1]);
4178 return ERR_ALERT | ERR_FATAL;
4179 }
4180
4181 return 0;
4182}
4183
Willy Tarreau92faadf2012-10-10 23:04:25 +02004184/************** "server" keywords ****************/
4185
Emeric Brunef42d922012-10-11 16:11:36 +02004186/* parse the "ca-file" server keyword */
4187static int srv_parse_ca_file(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
4188{
4189 if (!*args[*cur_arg + 1]) {
4190 if (err)
4191 memprintf(err, "'%s' : missing CAfile path", args[*cur_arg]);
4192 return ERR_ALERT | ERR_FATAL;
4193 }
4194
4195 if ((*args[*cur_arg + 1] != '/') && global.ca_base)
4196 memprintf(&newsrv->ssl_ctx.ca_file, "%s/%s", global.ca_base, args[*cur_arg + 1]);
4197 else
4198 memprintf(&newsrv->ssl_ctx.ca_file, "%s", args[*cur_arg + 1]);
4199
4200 return 0;
4201}
4202
Willy Tarreau92faadf2012-10-10 23:04:25 +02004203/* parse the "check-ssl" server keyword */
4204static int srv_parse_check_ssl(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
4205{
4206 newsrv->check.use_ssl = 1;
4207 if (global.connect_default_ciphers && !newsrv->ssl_ctx.ciphers)
4208 newsrv->ssl_ctx.ciphers = strdup(global.connect_default_ciphers);
Emeric Brun42a3e202014-10-30 15:56:50 +01004209 newsrv->ssl_ctx.options |= global.connect_default_ssloptions;
Willy Tarreau92faadf2012-10-10 23:04:25 +02004210 return 0;
4211}
4212
4213/* parse the "ciphers" server keyword */
4214static int srv_parse_ciphers(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
4215{
4216 if (!*args[*cur_arg + 1]) {
4217 memprintf(err, "'%s' : missing cipher suite", args[*cur_arg]);
4218 return ERR_ALERT | ERR_FATAL;
4219 }
4220
4221 free(newsrv->ssl_ctx.ciphers);
4222 newsrv->ssl_ctx.ciphers = strdup(args[*cur_arg + 1]);
4223 return 0;
4224}
4225
Emeric Brunef42d922012-10-11 16:11:36 +02004226/* parse the "crl-file" server keyword */
4227static int srv_parse_crl_file(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
4228{
4229#ifndef X509_V_FLAG_CRL_CHECK
4230 if (err)
4231 memprintf(err, "'%s' : library does not support CRL verify", args[*cur_arg]);
4232 return ERR_ALERT | ERR_FATAL;
4233#else
4234 if (!*args[*cur_arg + 1]) {
4235 if (err)
4236 memprintf(err, "'%s' : missing CRLfile path", args[*cur_arg]);
4237 return ERR_ALERT | ERR_FATAL;
4238 }
4239
4240 if ((*args[*cur_arg + 1] != '/') && global.ca_base)
4241 memprintf(&newsrv->ssl_ctx.crl_file, "%s/%s", global.ca_base, args[*cur_arg + 1]);
4242 else
4243 memprintf(&newsrv->ssl_ctx.crl_file, "%s", args[*cur_arg + 1]);
4244
4245 return 0;
4246#endif
4247}
4248
Emeric Bruna7aa3092012-10-26 12:58:00 +02004249/* parse the "crt" server keyword */
4250static int srv_parse_crt(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
4251{
4252 if (!*args[*cur_arg + 1]) {
4253 if (err)
4254 memprintf(err, "'%s' : missing certificate file path", args[*cur_arg]);
4255 return ERR_ALERT | ERR_FATAL;
4256 }
4257
4258 if ((*args[*cur_arg + 1] != '/') && global.crt_base)
4259 memprintf(&newsrv->ssl_ctx.client_crt, "%s/%s", global.ca_base, args[*cur_arg + 1]);
4260 else
4261 memprintf(&newsrv->ssl_ctx.client_crt, "%s", args[*cur_arg + 1]);
4262
4263 return 0;
4264}
Emeric Brunef42d922012-10-11 16:11:36 +02004265
Willy Tarreau92faadf2012-10-10 23:04:25 +02004266/* parse the "force-sslv3" server keyword */
4267static int srv_parse_force_sslv3(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
4268{
4269 newsrv->ssl_ctx.options |= SRV_SSL_O_USE_SSLV3;
4270 return 0;
4271}
4272
4273/* parse the "force-tlsv10" server keyword */
4274static int srv_parse_force_tlsv10(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
4275{
4276 newsrv->ssl_ctx.options |= SRV_SSL_O_USE_TLSV10;
4277 return 0;
4278}
4279
4280/* parse the "force-tlsv11" server keyword */
4281static int srv_parse_force_tlsv11(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
4282{
4283#if SSL_OP_NO_TLSv1_1
4284 newsrv->ssl_ctx.options |= SRV_SSL_O_USE_TLSV11;
4285 return 0;
4286#else
4287 if (err)
4288 memprintf(err, "'%s' : library does not support protocol TLSv1.1", args[*cur_arg]);
4289 return ERR_ALERT | ERR_FATAL;
4290#endif
4291}
4292
4293/* parse the "force-tlsv12" server keyword */
4294static int srv_parse_force_tlsv12(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
4295{
4296#if SSL_OP_NO_TLSv1_2
4297 newsrv->ssl_ctx.options |= SRV_SSL_O_USE_TLSV12;
4298 return 0;
4299#else
4300 if (err)
4301 memprintf(err, "'%s' : library does not support protocol TLSv1.2", args[*cur_arg]);
4302 return ERR_ALERT | ERR_FATAL;
4303#endif
4304}
4305
4306/* parse the "no-sslv3" server keyword */
4307static int srv_parse_no_sslv3(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
4308{
4309 newsrv->ssl_ctx.options |= SRV_SSL_O_NO_SSLV3;
4310 return 0;
4311}
4312
4313/* parse the "no-tlsv10" server keyword */
4314static int srv_parse_no_tlsv10(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
4315{
4316 newsrv->ssl_ctx.options |= SRV_SSL_O_NO_TLSV10;
4317 return 0;
4318}
4319
4320/* parse the "no-tlsv11" server keyword */
4321static int srv_parse_no_tlsv11(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
4322{
4323 newsrv->ssl_ctx.options |= SRV_SSL_O_NO_TLSV11;
4324 return 0;
4325}
4326
4327/* parse the "no-tlsv12" server keyword */
4328static int srv_parse_no_tlsv12(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
4329{
4330 newsrv->ssl_ctx.options |= SRV_SSL_O_NO_TLSV12;
4331 return 0;
4332}
4333
Emeric Brunf9c5c472012-10-11 15:28:34 +02004334/* parse the "no-tls-tickets" server keyword */
4335static int srv_parse_no_tls_tickets(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
4336{
4337 newsrv->ssl_ctx.options |= SRV_SSL_O_NO_TLS_TICKETS;
4338 return 0;
4339}
David Safb76832014-05-08 23:42:08 -04004340/* parse the "send-proxy-v2-ssl" server keyword */
4341static int srv_parse_send_proxy_ssl(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
4342{
4343 newsrv->pp_opts |= SRV_PP_V2;
4344 newsrv->pp_opts |= SRV_PP_V2_SSL;
4345 return 0;
4346}
4347
4348/* parse the "send-proxy-v2-ssl-cn" server keyword */
4349static int srv_parse_send_proxy_cn(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
4350{
4351 newsrv->pp_opts |= SRV_PP_V2;
4352 newsrv->pp_opts |= SRV_PP_V2_SSL;
4353 newsrv->pp_opts |= SRV_PP_V2_SSL_CN;
4354 return 0;
4355}
Emeric Brunf9c5c472012-10-11 15:28:34 +02004356
Willy Tarreau92faadf2012-10-10 23:04:25 +02004357/* parse the "ssl" server keyword */
4358static int srv_parse_ssl(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
4359{
4360 newsrv->use_ssl = 1;
4361 if (global.connect_default_ciphers && !newsrv->ssl_ctx.ciphers)
4362 newsrv->ssl_ctx.ciphers = strdup(global.connect_default_ciphers);
4363 return 0;
4364}
4365
Emeric Brunef42d922012-10-11 16:11:36 +02004366/* parse the "verify" server keyword */
4367static int srv_parse_verify(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
4368{
4369 if (!*args[*cur_arg + 1]) {
4370 if (err)
4371 memprintf(err, "'%s' : missing verify method", args[*cur_arg]);
4372 return ERR_ALERT | ERR_FATAL;
4373 }
4374
4375 if (strcmp(args[*cur_arg + 1], "none") == 0)
Emeric Brun850efd52014-01-29 12:24:34 +01004376 newsrv->ssl_ctx.verify = SSL_SOCK_VERIFY_NONE;
Emeric Brunef42d922012-10-11 16:11:36 +02004377 else if (strcmp(args[*cur_arg + 1], "required") == 0)
Emeric Brun850efd52014-01-29 12:24:34 +01004378 newsrv->ssl_ctx.verify = SSL_SOCK_VERIFY_REQUIRED;
Emeric Brunef42d922012-10-11 16:11:36 +02004379 else {
4380 if (err)
4381 memprintf(err, "'%s' : unknown verify method '%s', only 'none' and 'required' are supported\n",
4382 args[*cur_arg], args[*cur_arg + 1]);
4383 return ERR_ALERT | ERR_FATAL;
4384 }
4385
Evan Broderbe554312013-06-27 00:05:25 -07004386 return 0;
4387}
4388
4389/* parse the "verifyhost" server keyword */
4390static int srv_parse_verifyhost(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
4391{
4392 if (!*args[*cur_arg + 1]) {
4393 if (err)
4394 memprintf(err, "'%s' : missing hostname to verify against", args[*cur_arg]);
4395 return ERR_ALERT | ERR_FATAL;
4396 }
4397
4398 newsrv->ssl_ctx.verify_host = strdup(args[*cur_arg + 1]);
4399
Emeric Brunef42d922012-10-11 16:11:36 +02004400 return 0;
4401}
4402
Emeric Brun42a3e202014-10-30 15:56:50 +01004403/* parse the "ssl-default-bind-options" keyword in global section */
4404static int ssl_parse_default_bind_options(char **args, int section_type, struct proxy *curpx,
4405 struct proxy *defpx, const char *file, int line,
4406 char **err) {
4407 int i = 1;
4408
4409 if (*(args[i]) == 0) {
4410 memprintf(err, "global statement '%s' expects an option as an argument.", args[0]);
4411 return -1;
4412 }
4413 while (*(args[i])) {
4414 if (!strcmp(args[i], "no-sslv3"))
4415 global.listen_default_ssloptions |= BC_SSL_O_NO_SSLV3;
4416 else if (!strcmp(args[i], "no-tlsv10"))
4417 global.listen_default_ssloptions |= BC_SSL_O_NO_TLSV10;
4418 else if (!strcmp(args[i], "no-tlsv11"))
4419 global.listen_default_ssloptions |= BC_SSL_O_NO_TLSV11;
4420 else if (!strcmp(args[i], "no-tlsv12"))
4421 global.listen_default_ssloptions |= BC_SSL_O_NO_TLSV12;
4422 else if (!strcmp(args[i], "force-sslv3"))
4423 global.listen_default_ssloptions |= BC_SSL_O_USE_SSLV3;
4424 else if (!strcmp(args[i], "force-tlsv10"))
4425 global.listen_default_ssloptions |= BC_SSL_O_USE_TLSV10;
4426 else if (!strcmp(args[i], "force-tlsv11")) {
4427#if SSL_OP_NO_TLSv1_1
4428 global.listen_default_ssloptions |= BC_SSL_O_USE_TLSV11;
4429#else
4430 memprintf(err, "'%s' '%s': library does not support protocol TLSv1.1", args[0], args[i]);
4431 return -1;
4432#endif
4433 }
4434 else if (!strcmp(args[i], "force-tlsv12")) {
4435#if SSL_OP_NO_TLSv1_2
4436 global.listen_default_ssloptions |= BC_SSL_O_USE_TLSV12;
4437#else
4438 memprintf(err, "'%s' '%s': library does not support protocol TLSv1.2", args[0], args[i]);
4439 return -1;
4440#endif
4441 }
4442 else if (!strcmp(args[i], "no-tls-tickets"))
4443 global.listen_default_ssloptions |= BC_SSL_O_NO_TLS_TICKETS;
4444 else {
4445 memprintf(err, "unknown option '%s' on global statement '%s'.", args[i], args[0]);
4446 return -1;
4447 }
4448 i++;
4449 }
4450 return 0;
4451}
4452
4453/* parse the "ssl-default-server-options" keyword in global section */
4454static int ssl_parse_default_server_options(char **args, int section_type, struct proxy *curpx,
4455 struct proxy *defpx, const char *file, int line,
4456 char **err) {
4457 int i = 1;
4458
4459 if (*(args[i]) == 0) {
4460 memprintf(err, "global statement '%s' expects an option as an argument.", args[0]);
4461 return -1;
4462 }
4463 while (*(args[i])) {
4464 if (!strcmp(args[i], "no-sslv3"))
4465 global.connect_default_ssloptions |= SRV_SSL_O_NO_SSLV3;
4466 else if (!strcmp(args[i], "no-tlsv10"))
4467 global.connect_default_ssloptions |= SRV_SSL_O_NO_TLSV10;
4468 else if (!strcmp(args[i], "no-tlsv11"))
4469 global.connect_default_ssloptions |= SRV_SSL_O_NO_TLSV11;
4470 else if (!strcmp(args[i], "no-tlsv12"))
4471 global.connect_default_ssloptions |= SRV_SSL_O_NO_TLSV12;
4472 else if (!strcmp(args[i], "force-sslv3"))
4473 global.connect_default_ssloptions |= SRV_SSL_O_USE_SSLV3;
4474 else if (!strcmp(args[i], "force-tlsv10"))
4475 global.connect_default_ssloptions |= SRV_SSL_O_USE_TLSV10;
4476 else if (!strcmp(args[i], "force-tlsv11")) {
4477#if SSL_OP_NO_TLSv1_1
4478 global.connect_default_ssloptions |= SRV_SSL_O_USE_TLSV11;
4479#else
4480 memprintf(err, "'%s' '%s': library does not support protocol TLSv1.1", args[0], args[i]);
4481 return -1;
4482#endif
4483 }
4484 else if (!strcmp(args[i], "force-tlsv12")) {
4485#if SSL_OP_NO_TLSv1_2
4486 global.connect_default_ssloptions |= SRV_SSL_O_USE_TLSV12;
4487#else
4488 memprintf(err, "'%s' '%s': library does not support protocol TLSv1.2", args[0], args[i]);
4489 return -1;
4490#endif
4491 }
4492 else if (!strcmp(args[i], "no-tls-tickets"))
4493 global.connect_default_ssloptions |= SRV_SSL_O_NO_TLS_TICKETS;
4494 else {
4495 memprintf(err, "unknown option '%s' on global statement '%s'.", args[i], args[0]);
4496 return -1;
4497 }
4498 i++;
4499 }
4500 return 0;
4501}
4502
Willy Tarreau7875d092012-09-10 08:20:03 +02004503/* Note: must not be declared <const> as its list will be overwritten.
4504 * Please take care of keeping this list alphabetically sorted.
4505 */
Willy Tarreaudc13c112013-06-21 23:16:39 +02004506static struct sample_fetch_kw_list sample_fetch_keywords = {ILH, {
Emeric Brun645ae792014-04-30 14:21:06 +02004507 { "ssl_bc", smp_fetch_ssl_fc, 0, NULL, SMP_T_BOOL, SMP_USE_L5SRV },
4508 { "ssl_bc_alg_keysize", smp_fetch_ssl_fc_alg_keysize, 0, NULL, SMP_T_UINT, SMP_USE_L5SRV },
4509 { "ssl_bc_cipher", smp_fetch_ssl_fc_cipher, 0, NULL, SMP_T_STR, SMP_USE_L5SRV },
4510 { "ssl_bc_protocol", smp_fetch_ssl_fc_protocol, 0, NULL, SMP_T_STR, SMP_USE_L5SRV },
Emeric Brunb73a9b02014-04-30 18:49:19 +02004511 { "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 +02004512 { "ssl_bc_use_keysize", smp_fetch_ssl_fc_use_keysize, 0, NULL, SMP_T_UINT, SMP_USE_L5SRV },
4513 { "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 +01004514 { "ssl_c_ca_err", smp_fetch_ssl_c_ca_err, 0, NULL, SMP_T_UINT, SMP_USE_L5CLI },
4515 { "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 +01004516 { "ssl_c_der", smp_fetch_ssl_x_der, 0, NULL, SMP_T_BIN, SMP_USE_L5CLI },
Willy Tarreau80aca902013-01-07 15:42:20 +01004517 { "ssl_c_err", smp_fetch_ssl_c_err, 0, NULL, SMP_T_UINT, SMP_USE_L5CLI },
Emeric Brunba841a12014-04-30 17:05:08 +02004518 { "ssl_c_i_dn", smp_fetch_ssl_x_i_dn, ARG2(0,STR,SINT), NULL, SMP_T_STR, SMP_USE_L5CLI },
4519 { "ssl_c_key_alg", smp_fetch_ssl_x_key_alg, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
4520 { "ssl_c_notafter", smp_fetch_ssl_x_notafter, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
4521 { "ssl_c_notbefore", smp_fetch_ssl_x_notbefore, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
4522 { "ssl_c_sig_alg", smp_fetch_ssl_x_sig_alg, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
4523 { "ssl_c_s_dn", smp_fetch_ssl_x_s_dn, ARG2(0,STR,SINT), NULL, SMP_T_STR, SMP_USE_L5CLI },
4524 { "ssl_c_serial", smp_fetch_ssl_x_serial, 0, NULL, SMP_T_BIN, SMP_USE_L5CLI },
4525 { "ssl_c_sha1", smp_fetch_ssl_x_sha1, 0, NULL, SMP_T_BIN, SMP_USE_L5CLI },
Willy Tarreau80aca902013-01-07 15:42:20 +01004526 { "ssl_c_used", smp_fetch_ssl_c_used, 0, NULL, SMP_T_BOOL, SMP_USE_L5CLI },
4527 { "ssl_c_verify", smp_fetch_ssl_c_verify, 0, NULL, SMP_T_UINT, SMP_USE_L5CLI },
Emeric Brunba841a12014-04-30 17:05:08 +02004528 { "ssl_c_version", smp_fetch_ssl_x_version, 0, NULL, SMP_T_UINT, SMP_USE_L5CLI },
Emeric Brunb3cc4252014-10-29 19:03:26 +01004529 { "ssl_f_der", smp_fetch_ssl_x_der, 0, NULL, SMP_T_BIN, SMP_USE_L5CLI },
Emeric Brunba841a12014-04-30 17:05:08 +02004530 { "ssl_f_i_dn", smp_fetch_ssl_x_i_dn, ARG2(0,STR,SINT), NULL, SMP_T_STR, SMP_USE_L5CLI },
4531 { "ssl_f_key_alg", smp_fetch_ssl_x_key_alg, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
4532 { "ssl_f_notafter", smp_fetch_ssl_x_notafter, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
4533 { "ssl_f_notbefore", smp_fetch_ssl_x_notbefore, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
4534 { "ssl_f_sig_alg", smp_fetch_ssl_x_sig_alg, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
4535 { "ssl_f_s_dn", smp_fetch_ssl_x_s_dn, ARG2(0,STR,SINT), NULL, SMP_T_STR, SMP_USE_L5CLI },
4536 { "ssl_f_serial", smp_fetch_ssl_x_serial, 0, NULL, SMP_T_BIN, SMP_USE_L5CLI },
Emeric Brun55f4fa82014-04-30 17:11:25 +02004537 { "ssl_f_sha1", smp_fetch_ssl_x_sha1, 0, NULL, SMP_T_BIN, SMP_USE_L5CLI },
Emeric Brunba841a12014-04-30 17:05:08 +02004538 { "ssl_f_version", smp_fetch_ssl_x_version, 0, NULL, SMP_T_UINT, SMP_USE_L5CLI },
Willy Tarreau80aca902013-01-07 15:42:20 +01004539 { "ssl_fc", smp_fetch_ssl_fc, 0, NULL, SMP_T_BOOL, SMP_USE_L5CLI },
4540 { "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 +01004541 { "ssl_fc_cipher", smp_fetch_ssl_fc_cipher, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
Willy Tarreau80aca902013-01-07 15:42:20 +01004542 { "ssl_fc_has_crt", smp_fetch_ssl_fc_has_crt, 0, NULL, SMP_T_BOOL, SMP_USE_L5CLI },
4543 { "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 +02004544#ifdef OPENSSL_NPN_NEGOTIATED
Thierry FOURNIER7654c9f2013-12-17 00:20:33 +01004545 { "ssl_fc_npn", smp_fetch_ssl_fc_npn, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
Willy Tarreaua33c6542012-10-15 13:19:06 +02004546#endif
Dirkjan Bussink48f1c4e2014-02-13 12:29:42 +01004547#ifdef TLSEXT_TYPE_application_layer_protocol_negotiation
Thierry FOURNIER7654c9f2013-12-17 00:20:33 +01004548 { "ssl_fc_alpn", smp_fetch_ssl_fc_alpn, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
Willy Tarreauab861d32013-04-02 02:30:41 +02004549#endif
Thierry FOURNIER7654c9f2013-12-17 00:20:33 +01004550 { "ssl_fc_protocol", smp_fetch_ssl_fc_protocol, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
Emeric Brunb73a9b02014-04-30 18:49:19 +02004551 { "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 +01004552 { "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 +01004553 { "ssl_fc_session_id", smp_fetch_ssl_fc_session_id, 0, NULL, SMP_T_BIN, SMP_USE_L5CLI },
4554 { "ssl_fc_sni", smp_fetch_ssl_fc_sni, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
Willy Tarreau7875d092012-09-10 08:20:03 +02004555 { NULL, NULL, 0, 0, 0 },
4556}};
4557
4558/* Note: must not be declared <const> as its list will be overwritten.
4559 * Please take care of keeping this list alphabetically sorted.
4560 */
Willy Tarreaudc13c112013-06-21 23:16:39 +02004561static struct acl_kw_list acl_kws = {ILH, {
Thierry FOURNIERc5a4e982014-03-05 16:07:08 +01004562 { "ssl_fc_sni_end", "ssl_fc_sni", PAT_MATCH_END },
4563 { "ssl_fc_sni_reg", "ssl_fc_sni", PAT_MATCH_REG },
Willy Tarreau8ed669b2013-01-11 15:49:37 +01004564 { /* END */ },
Willy Tarreau7875d092012-09-10 08:20:03 +02004565}};
4566
Willy Tarreau79eeafa2012-09-14 07:53:05 +02004567/* Note: must not be declared <const> as its list will be overwritten.
4568 * Please take care of keeping this list alphabetically sorted, doing so helps
4569 * all code contributors.
4570 * Optional keywords are also declared with a NULL ->parse() function so that
4571 * the config parser can report an appropriate error when a known keyword was
4572 * not enabled.
4573 */
Willy Tarreau51fb7652012-09-18 18:24:39 +02004574static struct bind_kw_list bind_kws = { "SSL", { }, {
Willy Tarreauab861d32013-04-02 02:30:41 +02004575 { "alpn", bind_parse_alpn, 1 }, /* set ALPN supported protocols */
Emeric Brunfb510ea2012-10-05 12:00:26 +02004576 { "ca-file", bind_parse_ca_file, 1 }, /* set CAfile to process verify on client cert */
Emeric Brun2d0c4822012-10-02 13:45:20 +02004577 { "ca-ignore-err", bind_parse_ignore_err, 1 }, /* set error IDs to ignore on verify depth > 0 */
4578 { "ciphers", bind_parse_ciphers, 1 }, /* set SSL cipher suite */
Emeric Brunfb510ea2012-10-05 12:00:26 +02004579 { "crl-file", bind_parse_crl_file, 1 }, /* set certificat revocation list file use on client cert verify */
Emeric Brun2d0c4822012-10-02 13:45:20 +02004580 { "crt", bind_parse_crt, 1 }, /* load SSL certificates from this location */
4581 { "crt-ignore-err", bind_parse_ignore_err, 1 }, /* set error IDs to ingore on verify depth == 0 */
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01004582 { "crt-list", bind_parse_crt_list, 1 }, /* load a list of crt from this location */
Emeric Brun2d0c4822012-10-02 13:45:20 +02004583 { "ecdhe", bind_parse_ecdhe, 1 }, /* defines named curve for elliptic curve Diffie-Hellman */
Emeric Brun2cb7ae52012-10-05 14:14:21 +02004584 { "force-sslv3", bind_parse_force_sslv3, 0 }, /* force SSLv3 */
4585 { "force-tlsv10", bind_parse_force_tlsv10, 0 }, /* force TLSv10 */
4586 { "force-tlsv11", bind_parse_force_tlsv11, 0 }, /* force TLSv11 */
4587 { "force-tlsv12", bind_parse_force_tlsv12, 0 }, /* force TLSv12 */
Emeric Brun9b3009b2012-10-05 11:55:06 +02004588 { "no-sslv3", bind_parse_no_sslv3, 0 }, /* disable SSLv3 */
4589 { "no-tlsv10", bind_parse_no_tlsv10, 0 }, /* disable TLSv10 */
4590 { "no-tlsv11", bind_parse_no_tlsv11, 0 }, /* disable TLSv11 */
4591 { "no-tlsv12", bind_parse_no_tlsv12, 0 }, /* disable TLSv12 */
Emeric Brun2d0c4822012-10-02 13:45:20 +02004592 { "no-tls-tickets", bind_parse_no_tls_tickets, 0 }, /* disable session resumption tickets */
Emeric Brun2d0c4822012-10-02 13:45:20 +02004593 { "ssl", bind_parse_ssl, 0 }, /* enable SSL processing */
Emmanuel Hocdet65623372013-01-24 17:17:15 +01004594 { "strict-sni", bind_parse_strict_sni, 0 }, /* refuse negotiation if sni doesn't match a certificate */
Emeric Brun2d0c4822012-10-02 13:45:20 +02004595 { "verify", bind_parse_verify, 1 }, /* set SSL verify method */
Willy Tarreau6c9a3d52012-10-18 18:57:14 +02004596 { "npn", bind_parse_npn, 1 }, /* set NPN supported protocols */
Willy Tarreau79eeafa2012-09-14 07:53:05 +02004597 { NULL, NULL, 0 },
4598}};
Emeric Brun46591952012-05-18 15:47:34 +02004599
Willy Tarreau92faadf2012-10-10 23:04:25 +02004600/* Note: must not be declared <const> as its list will be overwritten.
4601 * Please take care of keeping this list alphabetically sorted, doing so helps
4602 * all code contributors.
4603 * Optional keywords are also declared with a NULL ->parse() function so that
4604 * the config parser can report an appropriate error when a known keyword was
4605 * not enabled.
4606 */
4607static struct srv_kw_list srv_kws = { "SSL", { }, {
Emeric Brunef42d922012-10-11 16:11:36 +02004608 { "ca-file", srv_parse_ca_file, 1, 0 }, /* set CAfile to process verify server cert */
Emeric Brunecc91fe2012-10-11 15:05:10 +02004609 { "check-ssl", srv_parse_check_ssl, 0, 0 }, /* enable SSL for health checks */
4610 { "ciphers", srv_parse_ciphers, 1, 0 }, /* select the cipher suite */
Emeric Brunef42d922012-10-11 16:11:36 +02004611 { "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 +02004612 { "crt", srv_parse_crt, 1, 0 }, /* set client certificate */
Emeric Brunecc91fe2012-10-11 15:05:10 +02004613 { "force-sslv3", srv_parse_force_sslv3, 0, 0 }, /* force SSLv3 */
4614 { "force-tlsv10", srv_parse_force_tlsv10, 0, 0 }, /* force TLSv10 */
4615 { "force-tlsv11", srv_parse_force_tlsv11, 0, 0 }, /* force TLSv11 */
4616 { "force-tlsv12", srv_parse_force_tlsv12, 0, 0 }, /* force TLSv12 */
4617 { "no-sslv3", srv_parse_no_sslv3, 0, 0 }, /* disable SSLv3 */
4618 { "no-tlsv10", srv_parse_no_tlsv10, 0, 0 }, /* disable TLSv10 */
4619 { "no-tlsv11", srv_parse_no_tlsv11, 0, 0 }, /* disable TLSv11 */
4620 { "no-tlsv12", srv_parse_no_tlsv12, 0, 0 }, /* disable TLSv12 */
Emeric Brunf9c5c472012-10-11 15:28:34 +02004621 { "no-tls-tickets", srv_parse_no_tls_tickets, 0, 0 }, /* disable session resumption tickets */
David Safb76832014-05-08 23:42:08 -04004622 { "send-proxy-v2-ssl", srv_parse_send_proxy_ssl, 0, 0 }, /* send PROXY protocol header v2 with SSL info */
4623 { "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 +02004624 { "ssl", srv_parse_ssl, 0, 0 }, /* enable SSL processing */
Emeric Brunef42d922012-10-11 16:11:36 +02004625 { "verify", srv_parse_verify, 1, 0 }, /* set SSL verify method */
Evan Broderbe554312013-06-27 00:05:25 -07004626 { "verifyhost", srv_parse_verifyhost, 1, 0 }, /* require that SSL cert verifies for hostname */
Willy Tarreau92faadf2012-10-10 23:04:25 +02004627 { NULL, NULL, 0, 0 },
4628}};
4629
Emeric Brun42a3e202014-10-30 15:56:50 +01004630static struct cfg_kw_list cfg_kws = {ILH, {
4631 { CFG_GLOBAL, "ssl-default-bind-options", ssl_parse_default_bind_options },
4632 { CFG_GLOBAL, "ssl-default-server-options", ssl_parse_default_server_options },
4633 { 0, NULL, NULL },
4634}};
4635
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02004636/* transport-layer operations for SSL sockets */
4637struct xprt_ops ssl_sock = {
Emeric Brun46591952012-05-18 15:47:34 +02004638 .snd_buf = ssl_sock_from_buf,
4639 .rcv_buf = ssl_sock_to_buf,
4640 .rcv_pipe = NULL,
4641 .snd_pipe = NULL,
4642 .shutr = NULL,
4643 .shutw = ssl_sock_shutw,
4644 .close = ssl_sock_close,
4645 .init = ssl_sock_init,
4646};
4647
4648__attribute__((constructor))
Willy Tarreau92faadf2012-10-10 23:04:25 +02004649static void __ssl_sock_init(void)
4650{
Emeric Brun46591952012-05-18 15:47:34 +02004651 STACK_OF(SSL_COMP)* cm;
4652
Willy Tarreau610f04b2014-02-13 11:36:41 +01004653#ifdef LISTEN_DEFAULT_CIPHERS
4654 global.listen_default_ciphers = LISTEN_DEFAULT_CIPHERS;
4655#endif
4656#ifdef CONNECT_DEFAULT_CIPHERS
4657 global.connect_default_ciphers = CONNECT_DEFAULT_CIPHERS;
4658#endif
4659 if (global.listen_default_ciphers)
4660 global.listen_default_ciphers = strdup(global.listen_default_ciphers);
4661 if (global.connect_default_ciphers)
4662 global.connect_default_ciphers = strdup(global.connect_default_ciphers);
Emeric Brun42a3e202014-10-30 15:56:50 +01004663 global.listen_default_ssloptions = BC_SSL_O_NONE;
4664 global.connect_default_ssloptions = SRV_SSL_O_NONE;
Willy Tarreau610f04b2014-02-13 11:36:41 +01004665
Emeric Brun46591952012-05-18 15:47:34 +02004666 SSL_library_init();
4667 cm = SSL_COMP_get_compression_methods();
4668 sk_SSL_COMP_zero(cm);
Willy Tarreau7875d092012-09-10 08:20:03 +02004669 sample_register_fetches(&sample_fetch_keywords);
4670 acl_register_keywords(&acl_kws);
Willy Tarreau79eeafa2012-09-14 07:53:05 +02004671 bind_register_keywords(&bind_kws);
Willy Tarreau92faadf2012-10-10 23:04:25 +02004672 srv_register_keywords(&srv_kws);
Emeric Brun42a3e202014-10-30 15:56:50 +01004673 cfg_register_keywords(&cfg_kws);
Emeric Brun46591952012-05-18 15:47:34 +02004674}
4675
4676/*
4677 * Local variables:
4678 * c-indent-level: 8
4679 * c-basic-offset: 8
4680 * End:
4681 */