blob: da99a300fce408a9f51c5f63bcadb2ef822167d6 [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>
59
Emeric Brunfc0421f2012-09-07 17:30:07 +020060#include <ebsttree.h>
61
62#include <types/global.h>
63#include <types/ssl_sock.h>
64
Willy Tarreau7875d092012-09-10 08:20:03 +020065#include <proto/acl.h>
66#include <proto/arg.h>
Emeric Brun46591952012-05-18 15:47:34 +020067#include <proto/connection.h>
68#include <proto/fd.h>
69#include <proto/freq_ctr.h>
70#include <proto/frontend.h>
Willy Tarreau79eeafa2012-09-14 07:53:05 +020071#include <proto/listener.h>
Thierry FOURNIERed66c292013-11-28 11:05:19 +010072#include <proto/pattern.h>
Willy Tarreau92faadf2012-10-10 23:04:25 +020073#include <proto/server.h>
Emeric Brun46591952012-05-18 15:47:34 +020074#include <proto/log.h>
Emeric Brun94324a42012-10-11 14:00:19 +020075#include <proto/proxy.h>
Emeric Brunfc0421f2012-09-07 17:30:07 +020076#include <proto/shctx.h>
Emeric Brun46591952012-05-18 15:47:34 +020077#include <proto/ssl_sock.h>
78#include <proto/task.h>
79
Willy Tarreau518cedd2014-02-17 15:43:01 +010080/* Warning, these are bits, not integers! */
Emeric Brune64aef12012-09-21 13:15:06 +020081#define SSL_SOCK_ST_FL_VERIFY_DONE 0x00000001
Emeric Brund8b2bb52014-01-28 15:43:53 +010082#define SSL_SOCK_ST_FL_16K_WBFSIZE 0x00000002
Willy Tarreau518cedd2014-02-17 15:43:01 +010083#define SSL_SOCK_SEND_UNLIMITED 0x00000004
Emeric Brun29f037d2014-04-25 19:05:36 +020084#define SSL_SOCK_RECV_HEARTBEAT 0x00000008
85
Emeric Brunf282a812012-09-21 15:27:54 +020086/* bits 0xFFFF0000 are reserved to store verify errors */
87
88/* Verify errors macros */
89#define SSL_SOCK_CA_ERROR_TO_ST(e) (((e > 63) ? 63 : e) << (16))
90#define SSL_SOCK_CAEDEPTH_TO_ST(d) (((d > 15) ? 15 : d) << (6+16))
91#define SSL_SOCK_CRTERROR_TO_ST(e) (((e > 63) ? 63 : e) << (4+6+16))
92
93#define SSL_SOCK_ST_TO_CA_ERROR(s) ((s >> (16)) & 63)
94#define SSL_SOCK_ST_TO_CAEDEPTH(s) ((s >> (6+16)) & 15)
95#define SSL_SOCK_ST_TO_CRTERROR(s) ((s >> (4+6+16)) & 63)
Emeric Brune64aef12012-09-21 13:15:06 +020096
Emeric Brun850efd52014-01-29 12:24:34 +010097/* server and bind verify method, it uses a global value as default */
98enum {
99 SSL_SOCK_VERIFY_DEFAULT = 0,
100 SSL_SOCK_VERIFY_REQUIRED = 1,
101 SSL_SOCK_VERIFY_OPTIONAL = 2,
102 SSL_SOCK_VERIFY_NONE = 3,
103};
104
Willy Tarreau71b734c2014-01-28 15:19:44 +0100105int sslconns = 0;
106int totalsslconns = 0;
Emeric Brune1f38db2012-09-03 20:36:47 +0200107
Remi Gacogne60d7aeb2014-07-15 11:36:40 +0200108#ifndef OPENSSL_NO_DH
109static DH *local_dh_1024 = NULL;
110static DH *local_dh_2048 = NULL;
111static DH *local_dh_4096 = NULL;
112static DH *local_dh_8192 = NULL;
113#endif /* OPENSSL_NO_DH */
114
Emeric Brun4147b2e2014-06-16 18:36:30 +0200115#ifdef SSL_CTRL_SET_TLSEXT_STATUS_REQ_CB
116struct certificate_ocsp {
117 struct ebmb_node key;
118 unsigned char key_data[OCSP_MAX_CERTID_ASN1_LENGTH];
119 struct chunk response;
Emeric Brun58484372014-06-20 15:46:13 +0200120 long expire;
Emeric Brun4147b2e2014-06-16 18:36:30 +0200121};
122
Emeric Brun58484372014-06-20 15:46:13 +0200123/*
124 * This function returns the number of seconds elapsed
125 * since the Epoch, 1970-01-01 00:00:00 +0000 (UTC) and the
126 * date presented un ASN1_GENERALIZEDTIME.
127 *
128 * In parsing error case, it returns -1.
129 */
130static long asn1_generalizedtime_to_epoch(ASN1_GENERALIZEDTIME *d)
131{
132 long epoch;
133 char *p, *end;
134 const unsigned short month_offset[12] = {
135 0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334
136 };
137 int year, month;
138
139 if (!d || (d->type != V_ASN1_GENERALIZEDTIME)) return -1;
140
141 p = (char *)d->data;
142 end = p + d->length;
143
144 if (end - p < 4) return -1;
145 year = 1000 * (p[0] - '0') + 100 * (p[1] - '0') + 10 * (p[2] - '0') + p[3] - '0';
146 p += 4;
147 if (end - p < 2) return -1;
148 month = 10 * (p[0] - '0') + p[1] - '0';
149 if (month < 1 || month > 12) return -1;
150 /* Compute the number of seconds since 1 jan 1970 and the beginning of current month
151 We consider leap years and the current month (<marsh or not) */
152 epoch = ( ((year - 1970) * 365)
153 + ((year - (month < 3)) / 4 - (year - (month < 3)) / 100 + (year - (month < 3)) / 400)
154 - ((1970 - 1) / 4 - (1970 - 1) / 100 + (1970 - 1) / 400)
155 + month_offset[month-1]
156 ) * 24 * 60 * 60;
157 p += 2;
158 if (end - p < 2) return -1;
159 /* Add the number of seconds of completed days of current month */
160 epoch += (10 * (p[0] - '0') + p[1] - '0' - 1) * 24 * 60 * 60;
161 p += 2;
162 if (end - p < 2) return -1;
163 /* Add the completed hours of the current day */
164 epoch += (10 * (p[0] - '0') + p[1] - '0') * 60 * 60;
165 p += 2;
166 if (end - p < 2) return -1;
167 /* Add the completed minutes of the current hour */
168 epoch += (10 * (p[0] - '0') + p[1] - '0') * 60;
169 p += 2;
170 if (p == end) return -1;
171 /* Test if there is available seconds */
172 if (p[0] < '0' || p[0] > '9')
173 goto nosec;
174 if (end - p < 2) return -1;
175 /* Add the seconds of the current minute */
176 epoch += 10 * (p[0] - '0') + p[1] - '0';
177 p += 2;
178 if (p == end) return -1;
179 /* Ignore seconds float part if present */
180 if (p[0] == '.') {
181 do {
182 if (++p == end) return -1;
183 } while (p[0] >= '0' && p[0] <= '9');
184 }
185
186nosec:
187 if (p[0] == 'Z') {
188 if (end - p != 1) return -1;
189 return epoch;
190 }
191 else if (p[0] == '+') {
192 if (end - p != 5) return -1;
193 /* Apply timezone offset */
194 return epoch - ((10 * (p[1] - '0') + p[2] - '0') * 60 + (10 * (p[3] - '0') + p[4] - '0')) * 60;
195 }
196 else if (p[0] == '-') {
197 if (end - p != 5) return -1;
198 /* Apply timezone offset */
199 return epoch + ((10 * (p[1] - '0') + p[2] - '0') * 60 + (10 * (p[3] - '0') + p[4] - '0')) * 60;
200 }
201
202 return -1;
203}
204
Emeric Brun8d914d12014-06-20 15:37:32 +0200205static struct eb_root cert_ocsp_tree = EB_ROOT_UNIQUE;
Emeric Brun4147b2e2014-06-16 18:36:30 +0200206
207/* This function starts to check if the OCSP response (in DER format) contained
208 * in chunk 'ocsp_response' is valid (else exits on error).
209 * If 'cid' is not NULL, it will be compared to the OCSP certificate ID
210 * contained in the OCSP Response and exits on error if no match.
211 * If it's a valid OCSP Response:
212 * If 'ocsp' is not NULL, the chunk is copied in the OCSP response's container
213 * pointed by 'ocsp'.
214 * If 'ocsp' is NULL, the function looks up into the OCSP response's
215 * containers tree (using as index the ASN1 form of the OCSP Certificate ID extracted
216 * from the response) and exits on error if not found. Finally, If an OCSP response is
217 * already present in the container, it will be overwritten.
218 *
219 * Note: OCSP response containing more than one OCSP Single response is not
220 * considered valid.
221 *
222 * Returns 0 on success, 1 in error case.
223 */
224static int ssl_sock_load_ocsp_response(struct chunk *ocsp_response, struct certificate_ocsp *ocsp, OCSP_CERTID *cid, char **err)
225{
226 OCSP_RESPONSE *resp;
227 OCSP_BASICRESP *bs = NULL;
228 OCSP_SINGLERESP *sr;
229 unsigned char *p = (unsigned char *)ocsp_response->str;
230 int rc , count_sr;
Emeric Brun1135ea42014-06-20 15:44:34 +0200231 ASN1_GENERALIZEDTIME *revtime, *thisupd, *nextupd = NULL;
Emeric Brun4147b2e2014-06-16 18:36:30 +0200232 int reason;
233 int ret = 1;
234
235 resp = d2i_OCSP_RESPONSE(NULL, (const unsigned char **)&p, ocsp_response->len);
236 if (!resp) {
237 memprintf(err, "Unable to parse OCSP response");
238 goto out;
239 }
240
241 rc = OCSP_response_status(resp);
242 if (rc != OCSP_RESPONSE_STATUS_SUCCESSFUL) {
243 memprintf(err, "OCSP response status not successful");
244 goto out;
245 }
246
247 bs = OCSP_response_get1_basic(resp);
248 if (!bs) {
249 memprintf(err, "Failed to get basic response from OCSP Response");
250 goto out;
251 }
252
253 count_sr = OCSP_resp_count(bs);
254 if (count_sr > 1) {
255 memprintf(err, "OCSP response ignored because contains multiple single responses (%d)", count_sr);
256 goto out;
257 }
258
259 sr = OCSP_resp_get0(bs, 0);
260 if (!sr) {
261 memprintf(err, "Failed to get OCSP single response");
262 goto out;
263 }
264
265 rc = OCSP_single_get0_status(sr, &reason, &revtime, &thisupd, &nextupd);
266 if (rc != V_OCSP_CERTSTATUS_GOOD) {
267 memprintf(err, "OCSP single response: certificate status not good");
268 goto out;
269 }
270
Emeric Brun1135ea42014-06-20 15:44:34 +0200271 if (!nextupd) {
272 memprintf(err, "OCSP single response: missing nextupdate");
273 goto out;
274 }
275
Emeric Brunc8b27b62014-06-19 14:16:17 +0200276 rc = OCSP_check_validity(thisupd, nextupd, OCSP_MAX_RESPONSE_TIME_SKEW, -1);
Emeric Brun4147b2e2014-06-16 18:36:30 +0200277 if (!rc) {
278 memprintf(err, "OCSP single response: no longer valid.");
279 goto out;
280 }
281
282 if (cid) {
283 if (OCSP_id_cmp(sr->certId, cid)) {
284 memprintf(err, "OCSP single response: Certificate ID does not match certificate and issuer");
285 goto out;
286 }
287 }
288
289 if (!ocsp) {
290 unsigned char key[OCSP_MAX_CERTID_ASN1_LENGTH];
291 unsigned char *p;
292
293 rc = i2d_OCSP_CERTID(sr->certId, NULL);
294 if (!rc) {
295 memprintf(err, "OCSP single response: Unable to encode Certificate ID");
296 goto out;
297 }
298
299 if (rc > OCSP_MAX_CERTID_ASN1_LENGTH) {
300 memprintf(err, "OCSP single response: Certificate ID too long");
301 goto out;
302 }
303
304 p = key;
305 memset(key, 0, OCSP_MAX_CERTID_ASN1_LENGTH);
306 i2d_OCSP_CERTID(sr->certId, &p);
307 ocsp = (struct certificate_ocsp *)ebmb_lookup(&cert_ocsp_tree, key, OCSP_MAX_CERTID_ASN1_LENGTH);
308 if (!ocsp) {
309 memprintf(err, "OCSP single response: Certificate ID does not match any certificate or issuer");
310 goto out;
311 }
312 }
313
314 /* According to comments on "chunk_dup", the
315 previous chunk buffer will be freed */
316 if (!chunk_dup(&ocsp->response, ocsp_response)) {
317 memprintf(err, "OCSP response: Memory allocation error");
318 goto out;
319 }
320
Emeric Brun58484372014-06-20 15:46:13 +0200321 ocsp->expire = asn1_generalizedtime_to_epoch(nextupd) - OCSP_MAX_RESPONSE_TIME_SKEW;
322
Emeric Brun4147b2e2014-06-16 18:36:30 +0200323 ret = 0;
324out:
325 if (bs)
326 OCSP_BASICRESP_free(bs);
327
328 if (resp)
329 OCSP_RESPONSE_free(resp);
330
331 return ret;
332}
333/*
334 * External function use to update the OCSP response in the OCSP response's
335 * containers tree. The chunk 'ocsp_response' must contain the OCSP response
336 * to update in DER format.
337 *
338 * Returns 0 on success, 1 in error case.
339 */
340int ssl_sock_update_ocsp_response(struct chunk *ocsp_response, char **err)
341{
342 return ssl_sock_load_ocsp_response(ocsp_response, NULL, NULL, err);
343}
344
345/*
346 * This function load the OCSP Resonse in DER format contained in file at
347 * path 'ocsp_path' and call 'ssl_sock_load_ocsp_response'
348 *
349 * Returns 0 on success, 1 in error case.
350 */
351static int ssl_sock_load_ocsp_response_from_file(const char *ocsp_path, struct certificate_ocsp *ocsp, OCSP_CERTID *cid, char **err)
352{
353 int fd = -1;
354 int r = 0;
355 int ret = 1;
356
357 fd = open(ocsp_path, O_RDONLY);
358 if (fd == -1) {
359 memprintf(err, "Error opening OCSP response file");
360 goto end;
361 }
362
363 trash.len = 0;
364 while (trash.len < trash.size) {
365 r = read(fd, trash.str + trash.len, trash.size - trash.len);
366 if (r < 0) {
367 if (errno == EINTR)
368 continue;
369
370 memprintf(err, "Error reading OCSP response from file");
371 goto end;
372 }
373 else if (r == 0) {
374 break;
375 }
376 trash.len += r;
377 }
378
379 close(fd);
380 fd = -1;
381
382 ret = ssl_sock_load_ocsp_response(&trash, ocsp, cid, err);
383end:
384 if (fd != -1)
385 close(fd);
386
387 return ret;
388}
389
390/*
391 * Callback used to set OCSP status extension content in server hello.
392 */
393int ssl_sock_ocsp_stapling_cbk(SSL *ssl, void *arg)
394{
395 struct certificate_ocsp *ocsp = (struct certificate_ocsp *)arg;
396 char* ssl_buf;
397
398 if (!ocsp ||
399 !ocsp->response.str ||
Emeric Brun58484372014-06-20 15:46:13 +0200400 !ocsp->response.len ||
401 (ocsp->expire < now.tv_sec))
Emeric Brun4147b2e2014-06-16 18:36:30 +0200402 return SSL_TLSEXT_ERR_NOACK;
403
404 ssl_buf = OPENSSL_malloc(ocsp->response.len);
405 if (!ssl_buf)
406 return SSL_TLSEXT_ERR_NOACK;
407
408 memcpy(ssl_buf, ocsp->response.str, ocsp->response.len);
409 SSL_set_tlsext_status_ocsp_resp(ssl, ssl_buf, ocsp->response.len);
410
411 return SSL_TLSEXT_ERR_OK;
412}
413
414/*
415 * This function enables the handling of OCSP status extension on 'ctx' if a
416 * file name 'cert_path' suffixed using ".ocsp" is present.
417 * To enable OCSP status extension, the issuer's certificate is mandatory.
418 * It should be present in the certificate's extra chain builded from file
419 * 'cert_path'. If not found, the issuer certificate is loaded from a file
420 * named 'cert_path' suffixed using '.issuer'.
421 *
422 * In addition, ".ocsp" file content is loaded as a DER format of an OCSP
423 * response. If file is empty or content is not a valid OCSP response,
424 * OCSP status extension is enabled but OCSP response is ignored (a warning
425 * is displayed).
426 *
427 * Returns 1 if no ".ocsp" file found, 0 if OCSP status extension is
428 * succesfully enabled, or -1 in other error case.
429 */
430static int ssl_sock_load_ocsp(SSL_CTX *ctx, const char *cert_path)
431{
432
433 BIO *in = NULL;
434 X509 *x, *xi = NULL, *issuer = NULL;
435 STACK_OF(X509) *chain = NULL;
436 OCSP_CERTID *cid = NULL;
437 SSL *ssl;
438 char ocsp_path[MAXPATHLEN+1];
439 int i, ret = -1;
440 struct stat st;
441 struct certificate_ocsp *ocsp = NULL, *iocsp;
442 char *warn = NULL;
443 unsigned char *p;
444
445 snprintf(ocsp_path, MAXPATHLEN+1, "%s.ocsp", cert_path);
446
447 if (stat(ocsp_path, &st))
448 return 1;
449
450 ssl = SSL_new(ctx);
451 if (!ssl)
452 goto out;
453
454 x = SSL_get_certificate(ssl);
455 if (!x)
456 goto out;
457
458 /* Try to lookup for issuer in certificate extra chain */
459#ifdef SSL_CTRL_GET_EXTRA_CHAIN_CERTS
460 SSL_CTX_get_extra_chain_certs(ctx, &chain);
461#else
462 chain = ctx->extra_certs;
463#endif
464 for (i = 0; i < sk_X509_num(chain); i++) {
465 issuer = sk_X509_value(chain, i);
466 if (X509_check_issued(issuer, x) == X509_V_OK)
467 break;
468 else
469 issuer = NULL;
470 }
471
472 /* If not found try to load issuer from a suffixed file */
473 if (!issuer) {
474 char issuer_path[MAXPATHLEN+1];
475
476 in = BIO_new(BIO_s_file());
477 if (!in)
478 goto out;
479
480 snprintf(issuer_path, MAXPATHLEN+1, "%s.issuer", cert_path);
481 if (BIO_read_filename(in, issuer_path) <= 0)
482 goto out;
483
484 xi = PEM_read_bio_X509_AUX(in, NULL, ctx->default_passwd_callback, ctx->default_passwd_callback_userdata);
485 if (!xi)
486 goto out;
487
488 if (X509_check_issued(xi, x) != X509_V_OK)
489 goto out;
490
491 issuer = xi;
492 }
493
494 cid = OCSP_cert_to_id(0, x, issuer);
495 if (!cid)
496 goto out;
497
498 i = i2d_OCSP_CERTID(cid, NULL);
499 if (!i || (i > OCSP_MAX_CERTID_ASN1_LENGTH))
500 goto out;
501
502 ocsp = calloc(1, sizeof(struct certificate_ocsp));
503 if (!ocsp)
504 goto out;
505
506 p = ocsp->key_data;
507 i2d_OCSP_CERTID(cid, &p);
508
509 iocsp = (struct certificate_ocsp *)ebmb_insert(&cert_ocsp_tree, &ocsp->key, OCSP_MAX_CERTID_ASN1_LENGTH);
510 if (iocsp == ocsp)
511 ocsp = NULL;
512
513 SSL_CTX_set_tlsext_status_cb(ctx, ssl_sock_ocsp_stapling_cbk);
514 SSL_CTX_set_tlsext_status_arg(ctx, iocsp);
515
516 ret = 0;
517
518 warn = NULL;
519 if (ssl_sock_load_ocsp_response_from_file(ocsp_path, iocsp, cid, &warn)) {
520 memprintf(&warn, "Loading '%s': %s. Content will be ignored", ocsp_path, warn ? warn : "failure");
521 Warning("%s.\n", warn);
522 }
523
524out:
525 if (ssl)
526 SSL_free(ssl);
527
528 if (in)
529 BIO_free(in);
530
531 if (xi)
532 X509_free(xi);
533
534 if (cid)
535 OCSP_CERTID_free(cid);
536
537 if (ocsp)
538 free(ocsp);
539
540 if (warn)
541 free(warn);
542
543
544 return ret;
545}
546
547#endif
548
Emeric Brune1f38db2012-09-03 20:36:47 +0200549void ssl_sock_infocbk(const SSL *ssl, int where, int ret)
550{
551 struct connection *conn = (struct connection *)SSL_get_app_data(ssl);
552 (void)ret; /* shut gcc stupid warning */
Emeric Brund8b2bb52014-01-28 15:43:53 +0100553 BIO *write_bio;
Emeric Brune1f38db2012-09-03 20:36:47 +0200554
555 if (where & SSL_CB_HANDSHAKE_START) {
556 /* Disable renegotiation (CVE-2009-3555) */
Willy Tarreau20879a02012-12-03 16:32:10 +0100557 if (conn->flags & CO_FL_CONNECTED) {
Emeric Brune1f38db2012-09-03 20:36:47 +0200558 conn->flags |= CO_FL_ERROR;
Willy Tarreau20879a02012-12-03 16:32:10 +0100559 conn->err_code = CO_ER_SSL_RENEG;
560 }
Emeric Brune1f38db2012-09-03 20:36:47 +0200561 }
Emeric Brund8b2bb52014-01-28 15:43:53 +0100562
563 if ((where & SSL_CB_ACCEPT_LOOP) == SSL_CB_ACCEPT_LOOP) {
564 if (!(conn->xprt_st & SSL_SOCK_ST_FL_16K_WBFSIZE)) {
565 /* Long certificate chains optimz
566 If write and read bios are differents, we
567 consider that the buffering was activated,
568 so we rise the output buffer size from 4k
569 to 16k */
570 write_bio = SSL_get_wbio(ssl);
571 if (write_bio != SSL_get_rbio(ssl)) {
572 BIO_set_write_buffer_size(write_bio, 16384);
573 conn->xprt_st |= SSL_SOCK_ST_FL_16K_WBFSIZE;
574 }
575 }
576 }
Emeric Brunfc0421f2012-09-07 17:30:07 +0200577}
578
Emeric Brune64aef12012-09-21 13:15:06 +0200579/* Callback is called for each certificate of the chain during a verify
580 ok is set to 1 if preverify detect no error on current certificate.
581 Returns 0 to break the handshake, 1 otherwise. */
Evan Broderbe554312013-06-27 00:05:25 -0700582int ssl_sock_bind_verifycbk(int ok, X509_STORE_CTX *x_store)
Emeric Brune64aef12012-09-21 13:15:06 +0200583{
584 SSL *ssl;
585 struct connection *conn;
Emeric Brun81c00f02012-09-21 14:31:21 +0200586 int err, depth;
Emeric Brune64aef12012-09-21 13:15:06 +0200587
588 ssl = X509_STORE_CTX_get_ex_data(x_store, SSL_get_ex_data_X509_STORE_CTX_idx());
589 conn = (struct connection *)SSL_get_app_data(ssl);
590
Willy Tarreauf7bc57c2012-10-03 00:19:48 +0200591 conn->xprt_st |= SSL_SOCK_ST_FL_VERIFY_DONE;
Emeric Brune64aef12012-09-21 13:15:06 +0200592
Emeric Brun81c00f02012-09-21 14:31:21 +0200593 if (ok) /* no errors */
594 return ok;
595
596 depth = X509_STORE_CTX_get_error_depth(x_store);
597 err = X509_STORE_CTX_get_error(x_store);
598
599 /* check if CA error needs to be ignored */
600 if (depth > 0) {
Willy Tarreauf7bc57c2012-10-03 00:19:48 +0200601 if (!SSL_SOCK_ST_TO_CA_ERROR(conn->xprt_st)) {
602 conn->xprt_st |= SSL_SOCK_CA_ERROR_TO_ST(err);
603 conn->xprt_st |= SSL_SOCK_CAEDEPTH_TO_ST(depth);
Emeric Brunf282a812012-09-21 15:27:54 +0200604 }
605
Emeric Brun1eb20ef2012-12-03 13:24:29 +0100606 if (objt_listener(conn->target)->bind_conf->ca_ignerr & (1ULL << err)) {
607 ERR_clear_error();
Emeric Brun81c00f02012-09-21 14:31:21 +0200608 return 1;
Emeric Brun1eb20ef2012-12-03 13:24:29 +0100609 }
Emeric Brun81c00f02012-09-21 14:31:21 +0200610
Willy Tarreau20879a02012-12-03 16:32:10 +0100611 conn->err_code = CO_ER_SSL_CA_FAIL;
Emeric Brun81c00f02012-09-21 14:31:21 +0200612 return 0;
613 }
614
Willy Tarreauf7bc57c2012-10-03 00:19:48 +0200615 if (!SSL_SOCK_ST_TO_CRTERROR(conn->xprt_st))
616 conn->xprt_st |= SSL_SOCK_CRTERROR_TO_ST(err);
Emeric Brunf282a812012-09-21 15:27:54 +0200617
Emeric Brun81c00f02012-09-21 14:31:21 +0200618 /* check if certificate error needs to be ignored */
Emeric Brun1eb20ef2012-12-03 13:24:29 +0100619 if (objt_listener(conn->target)->bind_conf->crt_ignerr & (1ULL << err)) {
620 ERR_clear_error();
Emeric Brun81c00f02012-09-21 14:31:21 +0200621 return 1;
Emeric Brun1eb20ef2012-12-03 13:24:29 +0100622 }
Emeric Brun81c00f02012-09-21 14:31:21 +0200623
Willy Tarreau20879a02012-12-03 16:32:10 +0100624 conn->err_code = CO_ER_SSL_CRT_FAIL;
Emeric Brun81c00f02012-09-21 14:31:21 +0200625 return 0;
Emeric Brune64aef12012-09-21 13:15:06 +0200626}
627
Emeric Brun29f037d2014-04-25 19:05:36 +0200628/* Callback is called for ssl protocol analyse */
629void ssl_sock_msgcbk(int write_p, int version, int content_type, const void *buf, size_t len, SSL *ssl, void *arg)
630{
Emeric Brun29f037d2014-04-25 19:05:36 +0200631#ifdef TLS1_RT_HEARTBEAT
632 /* test heartbeat received (write_p is set to 0
633 for a received record) */
Willy Tarreauf51c6982014-04-25 20:02:39 +0200634 if ((content_type == TLS1_RT_HEARTBEAT) && (write_p == 0)) {
Willy Tarreau84815002014-04-25 21:40:27 +0200635 struct connection *conn = (struct connection *)SSL_get_app_data(ssl);
Willy Tarreauf51c6982014-04-25 20:02:39 +0200636 const unsigned char *p = buf;
637 unsigned int payload;
638
Emeric Brun29f037d2014-04-25 19:05:36 +0200639 conn->xprt_st |= SSL_SOCK_RECV_HEARTBEAT;
Willy Tarreauf51c6982014-04-25 20:02:39 +0200640
641 /* Check if this is a CVE-2014-0160 exploitation attempt. */
642 if (*p != TLS1_HB_REQUEST)
643 return;
644
Willy Tarreauaeed6722014-04-25 23:59:58 +0200645 if (len < 1 + 2 + 16) /* 1 type + 2 size + 0 payload + 16 padding */
Willy Tarreauf51c6982014-04-25 20:02:39 +0200646 goto kill_it;
647
648 payload = (p[1] * 256) + p[2];
Willy Tarreau3b2fdb62014-04-25 23:44:22 +0200649 if (3 + payload + 16 <= len)
Willy Tarreauf51c6982014-04-25 20:02:39 +0200650 return; /* OK no problem */
Willy Tarreauaeed6722014-04-25 23:59:58 +0200651 kill_it:
Willy Tarreau3b2fdb62014-04-25 23:44:22 +0200652 /* We have a clear heartbleed attack (CVE-2014-0160), the
653 * advertised payload is larger than the advertised packet
654 * length, so we have garbage in the buffer between the
655 * payload and the end of the buffer (p+len). We can't know
656 * if the SSL stack is patched, and we don't know if we can
657 * safely wipe out the area between p+3+len and payload.
658 * So instead, we prevent the response from being sent by
659 * setting the max_send_fragment to 0 and we report an SSL
660 * error, which will kill this connection. It will be reported
661 * above as SSL_ERROR_SSL while an other handshake failure with
Willy Tarreauf51c6982014-04-25 20:02:39 +0200662 * a heartbeat message will be reported as SSL_ERROR_SYSCALL.
663 */
Willy Tarreau3b2fdb62014-04-25 23:44:22 +0200664 ssl->max_send_fragment = 0;
Willy Tarreauf51c6982014-04-25 20:02:39 +0200665 SSLerr(SSL_F_TLS1_HEARTBEAT, SSL_R_SSL_HANDSHAKE_FAILURE);
666 return;
667 }
Emeric Brun29f037d2014-04-25 19:05:36 +0200668#endif
669}
670
Willy Tarreau6c9a3d52012-10-18 18:57:14 +0200671#ifdef OPENSSL_NPN_NEGOTIATED
672/* This callback is used so that the server advertises the list of
673 * negociable protocols for NPN.
674 */
675static int ssl_sock_advertise_npn_protos(SSL *s, const unsigned char **data,
676 unsigned int *len, void *arg)
677{
678 struct bind_conf *conf = arg;
679
680 *data = (const unsigned char *)conf->npn_str;
681 *len = conf->npn_len;
682 return SSL_TLSEXT_ERR_OK;
683}
684#endif
685
Dirkjan Bussink48f1c4e2014-02-13 12:29:42 +0100686#ifdef TLSEXT_TYPE_application_layer_protocol_negotiation
Willy Tarreauab861d32013-04-02 02:30:41 +0200687/* This callback is used so that the server advertises the list of
688 * negociable protocols for ALPN.
689 */
Dirkjan Bussink48f1c4e2014-02-13 12:29:42 +0100690static int ssl_sock_advertise_alpn_protos(SSL *s, const unsigned char **out,
691 unsigned char *outlen,
692 const unsigned char *server,
693 unsigned int server_len, void *arg)
Willy Tarreauab861d32013-04-02 02:30:41 +0200694{
695 struct bind_conf *conf = arg;
696
Dirkjan Bussink48f1c4e2014-02-13 12:29:42 +0100697 if (SSL_select_next_proto((unsigned char**) out, outlen, (const unsigned char *)conf->alpn_str,
698 conf->alpn_len, server, server_len) != OPENSSL_NPN_NEGOTIATED) {
699 return SSL_TLSEXT_ERR_NOACK;
700 }
Willy Tarreauab861d32013-04-02 02:30:41 +0200701 return SSL_TLSEXT_ERR_OK;
702}
703#endif
704
Emeric Brunfc0421f2012-09-07 17:30:07 +0200705#ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME
706/* Sets the SSL ctx of <ssl> to match the advertised server name. Returns a
707 * warning when no match is found, which implies the default (first) cert
708 * will keep being used.
709 */
Willy Tarreau2a65ff02012-09-13 17:54:29 +0200710static int ssl_sock_switchctx_cbk(SSL *ssl, int *al, struct bind_conf *s)
Emeric Brunfc0421f2012-09-07 17:30:07 +0200711{
712 const char *servername;
713 const char *wildp = NULL;
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +0200714 struct ebmb_node *node, *n;
Emeric Brunfc0421f2012-09-07 17:30:07 +0200715 int i;
716 (void)al; /* shut gcc stupid warning */
717
718 servername = SSL_get_servername(ssl, TLSEXT_NAMETYPE_host_name);
Emmanuel Hocdet65623372013-01-24 17:17:15 +0100719 if (!servername) {
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +0200720 return (s->strict_sni ?
721 SSL_TLSEXT_ERR_ALERT_FATAL :
Emmanuel Hocdet79274e22013-05-31 12:47:44 +0200722 SSL_TLSEXT_ERR_NOACK);
Emmanuel Hocdet65623372013-01-24 17:17:15 +0100723 }
Emeric Brunfc0421f2012-09-07 17:30:07 +0200724
Willy Tarreau19d14ef2012-10-29 16:51:55 +0100725 for (i = 0; i < trash.size; i++) {
Emeric Brunfc0421f2012-09-07 17:30:07 +0200726 if (!servername[i])
727 break;
Willy Tarreau19d14ef2012-10-29 16:51:55 +0100728 trash.str[i] = tolower(servername[i]);
729 if (!wildp && (trash.str[i] == '.'))
730 wildp = &trash.str[i];
Emeric Brunfc0421f2012-09-07 17:30:07 +0200731 }
Willy Tarreau19d14ef2012-10-29 16:51:55 +0100732 trash.str[i] = 0;
Emeric Brunfc0421f2012-09-07 17:30:07 +0200733
734 /* lookup in full qualified names */
Willy Tarreau19d14ef2012-10-29 16:51:55 +0100735 node = ebst_lookup(&s->sni_ctx, trash.str);
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +0200736
737 /* lookup a not neg filter */
738 for (n = node; n; n = ebmb_next_dup(n)) {
739 if (!container_of(n, struct sni_ctx, name)->neg) {
740 node = n;
741 break;
Emmanuel Hocdet65623372013-01-24 17:17:15 +0100742 }
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +0200743 }
744 if (!node && wildp) {
745 /* lookup in wildcards names */
Emeric Brunfc0421f2012-09-07 17:30:07 +0200746 node = ebst_lookup(&s->sni_w_ctx, wildp);
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +0200747 }
748 if (!node || container_of(node, struct sni_ctx, name)->neg) {
749 return (s->strict_sni ?
750 SSL_TLSEXT_ERR_ALERT_FATAL :
751 SSL_TLSEXT_ERR_ALERT_WARNING);
Emeric Brunfc0421f2012-09-07 17:30:07 +0200752 }
753
754 /* switch ctx */
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +0200755 SSL_set_SSL_CTX(ssl, container_of(node, struct sni_ctx, name)->ctx);
Emeric Brunfc0421f2012-09-07 17:30:07 +0200756 return SSL_TLSEXT_ERR_OK;
757}
758#endif /* SSL_CTRL_SET_TLSEXT_HOSTNAME */
759
Emeric Bruna4bcd9a2012-09-20 16:19:02 +0200760#ifndef OPENSSL_NO_DH
Remi Gacognef46cd6e2014-06-12 14:58:40 +0200761
762static DH * ssl_get_dh_1024(void)
763{
764#if OPENSSL_VERSION_NUMBER < 0x0090801fL
765 static const unsigned char rfc_2409_prime_1024[] = {
766 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xC9,0x0F,0xDA,0xA2,
767 0x21,0x68,0xC2,0x34,0xC4,0xC6,0x62,0x8B,0x80,0xDC,0x1C,0xD1,
768 0x29,0x02,0x4E,0x08,0x8A,0x67,0xCC,0x74,0x02,0x0B,0xBE,0xA6,
769 0x3B,0x13,0x9B,0x22,0x51,0x4A,0x08,0x79,0x8E,0x34,0x04,0xDD,
770 0xEF,0x95,0x19,0xB3,0xCD,0x3A,0x43,0x1B,0x30,0x2B,0x0A,0x6D,
771 0xF2,0x5F,0x14,0x37,0x4F,0xE1,0x35,0x6D,0x6D,0x51,0xC2,0x45,
772 0xE4,0x85,0xB5,0x76,0x62,0x5E,0x7E,0xC6,0xF4,0x4C,0x42,0xE9,
773 0xA6,0x37,0xED,0x6B,0x0B,0xFF,0x5C,0xB6,0xF4,0x06,0xB7,0xED,
774 0xEE,0x38,0x6B,0xFB,0x5A,0x89,0x9F,0xA5,0xAE,0x9F,0x24,0x11,
775 0x7C,0x4B,0x1F,0xE6,0x49,0x28,0x66,0x51,0xEC,0xE6,0x53,0x81,
776 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
777 };
778#endif
779 DH *dh = DH_new();
780 if (dh) {
781#if OPENSSL_VERSION_NUMBER >= 0x0090801fL
782 dh->p = get_rfc2409_prime_1024(NULL);
783#else
784 dh->p = BN_bin2bn(rfc_2409_prime_1024, sizeof rfc_2409_prime_1024, NULL);
785#endif
786 /* See RFC 2409, Section 6 "Oakley Groups"
787 for the reason why 2 is used as generator.
788 */
789 BN_dec2bn(&dh->g, "2");
790 if (!dh->p || !dh->g) {
791 DH_free(dh);
792 dh = NULL;
793 }
794 }
795 return dh;
796}
797
798static DH *ssl_get_dh_2048(void)
799{
800#if OPENSSL_VERSION_NUMBER < 0x0090801fL
801 static const unsigned char rfc_3526_prime_2048[] = {
802 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xC9,0x0F,0xDA,0xA2,
803 0x21,0x68,0xC2,0x34,0xC4,0xC6,0x62,0x8B,0x80,0xDC,0x1C,0xD1,
804 0x29,0x02,0x4E,0x08,0x8A,0x67,0xCC,0x74,0x02,0x0B,0xBE,0xA6,
805 0x3B,0x13,0x9B,0x22,0x51,0x4A,0x08,0x79,0x8E,0x34,0x04,0xDD,
806 0xEF,0x95,0x19,0xB3,0xCD,0x3A,0x43,0x1B,0x30,0x2B,0x0A,0x6D,
807 0xF2,0x5F,0x14,0x37,0x4F,0xE1,0x35,0x6D,0x6D,0x51,0xC2,0x45,
808 0xE4,0x85,0xB5,0x76,0x62,0x5E,0x7E,0xC6,0xF4,0x4C,0x42,0xE9,
809 0xA6,0x37,0xED,0x6B,0x0B,0xFF,0x5C,0xB6,0xF4,0x06,0xB7,0xED,
810 0xEE,0x38,0x6B,0xFB,0x5A,0x89,0x9F,0xA5,0xAE,0x9F,0x24,0x11,
811 0x7C,0x4B,0x1F,0xE6,0x49,0x28,0x66,0x51,0xEC,0xE4,0x5B,0x3D,
812 0xC2,0x00,0x7C,0xB8,0xA1,0x63,0xBF,0x05,0x98,0xDA,0x48,0x36,
813 0x1C,0x55,0xD3,0x9A,0x69,0x16,0x3F,0xA8,0xFD,0x24,0xCF,0x5F,
814 0x83,0x65,0x5D,0x23,0xDC,0xA3,0xAD,0x96,0x1C,0x62,0xF3,0x56,
815 0x20,0x85,0x52,0xBB,0x9E,0xD5,0x29,0x07,0x70,0x96,0x96,0x6D,
816 0x67,0x0C,0x35,0x4E,0x4A,0xBC,0x98,0x04,0xF1,0x74,0x6C,0x08,
817 0xCA,0x18,0x21,0x7C,0x32,0x90,0x5E,0x46,0x2E,0x36,0xCE,0x3B,
818 0xE3,0x9E,0x77,0x2C,0x18,0x0E,0x86,0x03,0x9B,0x27,0x83,0xA2,
819 0xEC,0x07,0xA2,0x8F,0xB5,0xC5,0x5D,0xF0,0x6F,0x4C,0x52,0xC9,
820 0xDE,0x2B,0xCB,0xF6,0x95,0x58,0x17,0x18,0x39,0x95,0x49,0x7C,
821 0xEA,0x95,0x6A,0xE5,0x15,0xD2,0x26,0x18,0x98,0xFA,0x05,0x10,
822 0x15,0x72,0x8E,0x5A,0x8A,0xAC,0xAA,0x68,0xFF,0xFF,0xFF,0xFF,
823 0xFF,0xFF,0xFF,0xFF,
824 };
825#endif
826 DH *dh = DH_new();
827 if (dh) {
828#if OPENSSL_VERSION_NUMBER >= 0x0090801fL
829 dh->p = get_rfc3526_prime_2048(NULL);
830#else
831 dh->p = BN_bin2bn(rfc_3526_prime_2048, sizeof rfc_3526_prime_2048, NULL);
832#endif
833 /* See RFC 3526, Section 3 "2048-bit MODP Group"
834 for the reason why 2 is used as generator.
835 */
836 BN_dec2bn(&dh->g, "2");
837 if (!dh->p || !dh->g) {
838 DH_free(dh);
839 dh = NULL;
840 }
841 }
842 return dh;
843}
844
845static DH *ssl_get_dh_4096(void)
846{
847#if OPENSSL_VERSION_NUMBER < 0x0090801fL
848 static const unsigned char rfc_3526_prime_4096[] = {
849 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xC9,0x0F,0xDA,0xA2,
850 0x21,0x68,0xC2,0x34,0xC4,0xC6,0x62,0x8B,0x80,0xDC,0x1C,0xD1,
851 0x29,0x02,0x4E,0x08,0x8A,0x67,0xCC,0x74,0x02,0x0B,0xBE,0xA6,
852 0x3B,0x13,0x9B,0x22,0x51,0x4A,0x08,0x79,0x8E,0x34,0x04,0xDD,
853 0xEF,0x95,0x19,0xB3,0xCD,0x3A,0x43,0x1B,0x30,0x2B,0x0A,0x6D,
854 0xF2,0x5F,0x14,0x37,0x4F,0xE1,0x35,0x6D,0x6D,0x51,0xC2,0x45,
855 0xE4,0x85,0xB5,0x76,0x62,0x5E,0x7E,0xC6,0xF4,0x4C,0x42,0xE9,
856 0xA6,0x37,0xED,0x6B,0x0B,0xFF,0x5C,0xB6,0xF4,0x06,0xB7,0xED,
857 0xEE,0x38,0x6B,0xFB,0x5A,0x89,0x9F,0xA5,0xAE,0x9F,0x24,0x11,
858 0x7C,0x4B,0x1F,0xE6,0x49,0x28,0x66,0x51,0xEC,0xE4,0x5B,0x3D,
859 0xC2,0x00,0x7C,0xB8,0xA1,0x63,0xBF,0x05,0x98,0xDA,0x48,0x36,
860 0x1C,0x55,0xD3,0x9A,0x69,0x16,0x3F,0xA8,0xFD,0x24,0xCF,0x5F,
861 0x83,0x65,0x5D,0x23,0xDC,0xA3,0xAD,0x96,0x1C,0x62,0xF3,0x56,
862 0x20,0x85,0x52,0xBB,0x9E,0xD5,0x29,0x07,0x70,0x96,0x96,0x6D,
863 0x67,0x0C,0x35,0x4E,0x4A,0xBC,0x98,0x04,0xF1,0x74,0x6C,0x08,
864 0xCA,0x18,0x21,0x7C,0x32,0x90,0x5E,0x46,0x2E,0x36,0xCE,0x3B,
865 0xE3,0x9E,0x77,0x2C,0x18,0x0E,0x86,0x03,0x9B,0x27,0x83,0xA2,
866 0xEC,0x07,0xA2,0x8F,0xB5,0xC5,0x5D,0xF0,0x6F,0x4C,0x52,0xC9,
867 0xDE,0x2B,0xCB,0xF6,0x95,0x58,0x17,0x18,0x39,0x95,0x49,0x7C,
868 0xEA,0x95,0x6A,0xE5,0x15,0xD2,0x26,0x18,0x98,0xFA,0x05,0x10,
869 0x15,0x72,0x8E,0x5A,0x8A,0xAA,0xC4,0x2D,0xAD,0x33,0x17,0x0D,
870 0x04,0x50,0x7A,0x33,0xA8,0x55,0x21,0xAB,0xDF,0x1C,0xBA,0x64,
871 0xEC,0xFB,0x85,0x04,0x58,0xDB,0xEF,0x0A,0x8A,0xEA,0x71,0x57,
872 0x5D,0x06,0x0C,0x7D,0xB3,0x97,0x0F,0x85,0xA6,0xE1,0xE4,0xC7,
873 0xAB,0xF5,0xAE,0x8C,0xDB,0x09,0x33,0xD7,0x1E,0x8C,0x94,0xE0,
874 0x4A,0x25,0x61,0x9D,0xCE,0xE3,0xD2,0x26,0x1A,0xD2,0xEE,0x6B,
875 0xF1,0x2F,0xFA,0x06,0xD9,0x8A,0x08,0x64,0xD8,0x76,0x02,0x73,
876 0x3E,0xC8,0x6A,0x64,0x52,0x1F,0x2B,0x18,0x17,0x7B,0x20,0x0C,
877 0xBB,0xE1,0x17,0x57,0x7A,0x61,0x5D,0x6C,0x77,0x09,0x88,0xC0,
878 0xBA,0xD9,0x46,0xE2,0x08,0xE2,0x4F,0xA0,0x74,0xE5,0xAB,0x31,
879 0x43,0xDB,0x5B,0xFC,0xE0,0xFD,0x10,0x8E,0x4B,0x82,0xD1,0x20,
880 0xA9,0x21,0x08,0x01,0x1A,0x72,0x3C,0x12,0xA7,0x87,0xE6,0xD7,
881 0x88,0x71,0x9A,0x10,0xBD,0xBA,0x5B,0x26,0x99,0xC3,0x27,0x18,
882 0x6A,0xF4,0xE2,0x3C,0x1A,0x94,0x68,0x34,0xB6,0x15,0x0B,0xDA,
883 0x25,0x83,0xE9,0xCA,0x2A,0xD4,0x4C,0xE8,0xDB,0xBB,0xC2,0xDB,
884 0x04,0xDE,0x8E,0xF9,0x2E,0x8E,0xFC,0x14,0x1F,0xBE,0xCA,0xA6,
885 0x28,0x7C,0x59,0x47,0x4E,0x6B,0xC0,0x5D,0x99,0xB2,0x96,0x4F,
886 0xA0,0x90,0xC3,0xA2,0x23,0x3B,0xA1,0x86,0x51,0x5B,0xE7,0xED,
887 0x1F,0x61,0x29,0x70,0xCE,0xE2,0xD7,0xAF,0xB8,0x1B,0xDD,0x76,
888 0x21,0x70,0x48,0x1C,0xD0,0x06,0x91,0x27,0xD5,0xB0,0x5A,0xA9,
889 0x93,0xB4,0xEA,0x98,0x8D,0x8F,0xDD,0xC1,0x86,0xFF,0xB7,0xDC,
890 0x90,0xA6,0xC0,0x8F,0x4D,0xF4,0x35,0xC9,0x34,0x06,0x31,0x99,
891 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
892 };
893#endif
894 DH *dh = DH_new();
895 if (dh) {
896#if OPENSSL_VERSION_NUMBER >= 0x0090801fL
897 dh->p = get_rfc3526_prime_4096(NULL);
898#else
899 dh->p = BN_bin2bn(rfc_3526_prime_4096, sizeof rfc_3526_prime_4096, NULL);
900#endif
901 /* See RFC 3526, Section 5 "4096-bit MODP Group"
902 for the reason why 2 is used as generator.
903 */
904 BN_dec2bn(&dh->g, "2");
905 if (!dh->p || !dh->g) {
906 DH_free(dh);
907 dh = NULL;
908 }
909 }
910 return dh;
911}
912
913static DH *ssl_get_dh_8192(void)
914{
915#if OPENSSL_VERSION_NUMBER < 0x0090801fL
916 static const unsigned char rfc_3526_prime_8192[] = {
917 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xC9,0x0F,0xDA,0xA2,
918 0x21,0x68,0xC2,0x34,0xC4,0xC6,0x62,0x8B,0x80,0xDC,0x1C,0xD1,
919 0x29,0x02,0x4E,0x08,0x8A,0x67,0xCC,0x74,0x02,0x0B,0xBE,0xA6,
920 0x3B,0x13,0x9B,0x22,0x51,0x4A,0x08,0x79,0x8E,0x34,0x04,0xDD,
921 0xEF,0x95,0x19,0xB3,0xCD,0x3A,0x43,0x1B,0x30,0x2B,0x0A,0x6D,
922 0xF2,0x5F,0x14,0x37,0x4F,0xE1,0x35,0x6D,0x6D,0x51,0xC2,0x45,
923 0xE4,0x85,0xB5,0x76,0x62,0x5E,0x7E,0xC6,0xF4,0x4C,0x42,0xE9,
924 0xA6,0x37,0xED,0x6B,0x0B,0xFF,0x5C,0xB6,0xF4,0x06,0xB7,0xED,
925 0xEE,0x38,0x6B,0xFB,0x5A,0x89,0x9F,0xA5,0xAE,0x9F,0x24,0x11,
926 0x7C,0x4B,0x1F,0xE6,0x49,0x28,0x66,0x51,0xEC,0xE4,0x5B,0x3D,
927 0xC2,0x00,0x7C,0xB8,0xA1,0x63,0xBF,0x05,0x98,0xDA,0x48,0x36,
928 0x1C,0x55,0xD3,0x9A,0x69,0x16,0x3F,0xA8,0xFD,0x24,0xCF,0x5F,
929 0x83,0x65,0x5D,0x23,0xDC,0xA3,0xAD,0x96,0x1C,0x62,0xF3,0x56,
930 0x20,0x85,0x52,0xBB,0x9E,0xD5,0x29,0x07,0x70,0x96,0x96,0x6D,
931 0x67,0x0C,0x35,0x4E,0x4A,0xBC,0x98,0x04,0xF1,0x74,0x6C,0x08,
932 0xCA,0x18,0x21,0x7C,0x32,0x90,0x5E,0x46,0x2E,0x36,0xCE,0x3B,
933 0xE3,0x9E,0x77,0x2C,0x18,0x0E,0x86,0x03,0x9B,0x27,0x83,0xA2,
934 0xEC,0x07,0xA2,0x8F,0xB5,0xC5,0x5D,0xF0,0x6F,0x4C,0x52,0xC9,
935 0xDE,0x2B,0xCB,0xF6,0x95,0x58,0x17,0x18,0x39,0x95,0x49,0x7C,
936 0xEA,0x95,0x6A,0xE5,0x15,0xD2,0x26,0x18,0x98,0xFA,0x05,0x10,
937 0x15,0x72,0x8E,0x5A,0x8A,0xAA,0xC4,0x2D,0xAD,0x33,0x17,0x0D,
938 0x04,0x50,0x7A,0x33,0xA8,0x55,0x21,0xAB,0xDF,0x1C,0xBA,0x64,
939 0xEC,0xFB,0x85,0x04,0x58,0xDB,0xEF,0x0A,0x8A,0xEA,0x71,0x57,
940 0x5D,0x06,0x0C,0x7D,0xB3,0x97,0x0F,0x85,0xA6,0xE1,0xE4,0xC7,
941 0xAB,0xF5,0xAE,0x8C,0xDB,0x09,0x33,0xD7,0x1E,0x8C,0x94,0xE0,
942 0x4A,0x25,0x61,0x9D,0xCE,0xE3,0xD2,0x26,0x1A,0xD2,0xEE,0x6B,
943 0xF1,0x2F,0xFA,0x06,0xD9,0x8A,0x08,0x64,0xD8,0x76,0x02,0x73,
944 0x3E,0xC8,0x6A,0x64,0x52,0x1F,0x2B,0x18,0x17,0x7B,0x20,0x0C,
945 0xBB,0xE1,0x17,0x57,0x7A,0x61,0x5D,0x6C,0x77,0x09,0x88,0xC0,
946 0xBA,0xD9,0x46,0xE2,0x08,0xE2,0x4F,0xA0,0x74,0xE5,0xAB,0x31,
947 0x43,0xDB,0x5B,0xFC,0xE0,0xFD,0x10,0x8E,0x4B,0x82,0xD1,0x20,
948 0xA9,0x21,0x08,0x01,0x1A,0x72,0x3C,0x12,0xA7,0x87,0xE6,0xD7,
949 0x88,0x71,0x9A,0x10,0xBD,0xBA,0x5B,0x26,0x99,0xC3,0x27,0x18,
950 0x6A,0xF4,0xE2,0x3C,0x1A,0x94,0x68,0x34,0xB6,0x15,0x0B,0xDA,
951 0x25,0x83,0xE9,0xCA,0x2A,0xD4,0x4C,0xE8,0xDB,0xBB,0xC2,0xDB,
952 0x04,0xDE,0x8E,0xF9,0x2E,0x8E,0xFC,0x14,0x1F,0xBE,0xCA,0xA6,
953 0x28,0x7C,0x59,0x47,0x4E,0x6B,0xC0,0x5D,0x99,0xB2,0x96,0x4F,
954 0xA0,0x90,0xC3,0xA2,0x23,0x3B,0xA1,0x86,0x51,0x5B,0xE7,0xED,
955 0x1F,0x61,0x29,0x70,0xCE,0xE2,0xD7,0xAF,0xB8,0x1B,0xDD,0x76,
956 0x21,0x70,0x48,0x1C,0xD0,0x06,0x91,0x27,0xD5,0xB0,0x5A,0xA9,
957 0x93,0xB4,0xEA,0x98,0x8D,0x8F,0xDD,0xC1,0x86,0xFF,0xB7,0xDC,
958 0x90,0xA6,0xC0,0x8F,0x4D,0xF4,0x35,0xC9,0x34,0x02,0x84,0x92,
959 0x36,0xC3,0xFA,0xB4,0xD2,0x7C,0x70,0x26,0xC1,0xD4,0xDC,0xB2,
960 0x60,0x26,0x46,0xDE,0xC9,0x75,0x1E,0x76,0x3D,0xBA,0x37,0xBD,
961 0xF8,0xFF,0x94,0x06,0xAD,0x9E,0x53,0x0E,0xE5,0xDB,0x38,0x2F,
962 0x41,0x30,0x01,0xAE,0xB0,0x6A,0x53,0xED,0x90,0x27,0xD8,0x31,
963 0x17,0x97,0x27,0xB0,0x86,0x5A,0x89,0x18,0xDA,0x3E,0xDB,0xEB,
964 0xCF,0x9B,0x14,0xED,0x44,0xCE,0x6C,0xBA,0xCE,0xD4,0xBB,0x1B,
965 0xDB,0x7F,0x14,0x47,0xE6,0xCC,0x25,0x4B,0x33,0x20,0x51,0x51,
966 0x2B,0xD7,0xAF,0x42,0x6F,0xB8,0xF4,0x01,0x37,0x8C,0xD2,0xBF,
967 0x59,0x83,0xCA,0x01,0xC6,0x4B,0x92,0xEC,0xF0,0x32,0xEA,0x15,
968 0xD1,0x72,0x1D,0x03,0xF4,0x82,0xD7,0xCE,0x6E,0x74,0xFE,0xF6,
969 0xD5,0x5E,0x70,0x2F,0x46,0x98,0x0C,0x82,0xB5,0xA8,0x40,0x31,
970 0x90,0x0B,0x1C,0x9E,0x59,0xE7,0xC9,0x7F,0xBE,0xC7,0xE8,0xF3,
971 0x23,0xA9,0x7A,0x7E,0x36,0xCC,0x88,0xBE,0x0F,0x1D,0x45,0xB7,
972 0xFF,0x58,0x5A,0xC5,0x4B,0xD4,0x07,0xB2,0x2B,0x41,0x54,0xAA,
973 0xCC,0x8F,0x6D,0x7E,0xBF,0x48,0xE1,0xD8,0x14,0xCC,0x5E,0xD2,
974 0x0F,0x80,0x37,0xE0,0xA7,0x97,0x15,0xEE,0xF2,0x9B,0xE3,0x28,
975 0x06,0xA1,0xD5,0x8B,0xB7,0xC5,0xDA,0x76,0xF5,0x50,0xAA,0x3D,
976 0x8A,0x1F,0xBF,0xF0,0xEB,0x19,0xCC,0xB1,0xA3,0x13,0xD5,0x5C,
977 0xDA,0x56,0xC9,0xEC,0x2E,0xF2,0x96,0x32,0x38,0x7F,0xE8,0xD7,
978 0x6E,0x3C,0x04,0x68,0x04,0x3E,0x8F,0x66,0x3F,0x48,0x60,0xEE,
979 0x12,0xBF,0x2D,0x5B,0x0B,0x74,0x74,0xD6,0xE6,0x94,0xF9,0x1E,
980 0x6D,0xBE,0x11,0x59,0x74,0xA3,0x92,0x6F,0x12,0xFE,0xE5,0xE4,
981 0x38,0x77,0x7C,0xB6,0xA9,0x32,0xDF,0x8C,0xD8,0xBE,0xC4,0xD0,
982 0x73,0xB9,0x31,0xBA,0x3B,0xC8,0x32,0xB6,0x8D,0x9D,0xD3,0x00,
983 0x74,0x1F,0xA7,0xBF,0x8A,0xFC,0x47,0xED,0x25,0x76,0xF6,0x93,
984 0x6B,0xA4,0x24,0x66,0x3A,0xAB,0x63,0x9C,0x5A,0xE4,0xF5,0x68,
985 0x34,0x23,0xB4,0x74,0x2B,0xF1,0xC9,0x78,0x23,0x8F,0x16,0xCB,
986 0xE3,0x9D,0x65,0x2D,0xE3,0xFD,0xB8,0xBE,0xFC,0x84,0x8A,0xD9,
987 0x22,0x22,0x2E,0x04,0xA4,0x03,0x7C,0x07,0x13,0xEB,0x57,0xA8,
988 0x1A,0x23,0xF0,0xC7,0x34,0x73,0xFC,0x64,0x6C,0xEA,0x30,0x6B,
989 0x4B,0xCB,0xC8,0x86,0x2F,0x83,0x85,0xDD,0xFA,0x9D,0x4B,0x7F,
990 0xA2,0xC0,0x87,0xE8,0x79,0x68,0x33,0x03,0xED,0x5B,0xDD,0x3A,
991 0x06,0x2B,0x3C,0xF5,0xB3,0xA2,0x78,0xA6,0x6D,0x2A,0x13,0xF8,
992 0x3F,0x44,0xF8,0x2D,0xDF,0x31,0x0E,0xE0,0x74,0xAB,0x6A,0x36,
993 0x45,0x97,0xE8,0x99,0xA0,0x25,0x5D,0xC1,0x64,0xF3,0x1C,0xC5,
994 0x08,0x46,0x85,0x1D,0xF9,0xAB,0x48,0x19,0x5D,0xED,0x7E,0xA1,
995 0xB1,0xD5,0x10,0xBD,0x7E,0xE7,0x4D,0x73,0xFA,0xF3,0x6B,0xC3,
996 0x1E,0xCF,0xA2,0x68,0x35,0x90,0x46,0xF4,0xEB,0x87,0x9F,0x92,
997 0x40,0x09,0x43,0x8B,0x48,0x1C,0x6C,0xD7,0x88,0x9A,0x00,0x2E,
998 0xD5,0xEE,0x38,0x2B,0xC9,0x19,0x0D,0xA6,0xFC,0x02,0x6E,0x47,
999 0x95,0x58,0xE4,0x47,0x56,0x77,0xE9,0xAA,0x9E,0x30,0x50,0xE2,
1000 0x76,0x56,0x94,0xDF,0xC8,0x1F,0x56,0xE8,0x80,0xB9,0x6E,0x71,
1001 0x60,0xC9,0x80,0xDD,0x98,0xED,0xD3,0xDF,0xFF,0xFF,0xFF,0xFF,
1002 0xFF,0xFF,0xFF,0xFF,
1003 };
1004#endif
1005 DH *dh = DH_new();
1006 if (dh) {
1007#if OPENSSL_VERSION_NUMBER >= 0x0090801fL
1008 dh->p = get_rfc3526_prime_8192(NULL);
1009#else
1010 dh->p = BN_bin2bn(rfc_3526_prime_8192, sizeof rfc_3526_prime_8192, NULL);
1011#endif
1012 /* See RFC 3526, Section 7 "8192-bit MODP Group"
1013 for the reason why 2 is used as generator.
1014 */
1015 BN_dec2bn(&dh->g, "2");
1016 if (!dh->p || !dh->g) {
1017 DH_free(dh);
1018 dh = NULL;
1019 }
1020 }
1021 return dh;
1022}
1023
1024/* Returns Diffie-Hellman parameters matching the private key length
1025 but not exceeding global.tune.ssl_default_dh_param */
1026static DH *ssl_get_tmp_dh(SSL *ssl, int export, int keylen)
1027{
1028 DH *dh = NULL;
1029 EVP_PKEY *pkey = SSL_get_privatekey(ssl);
1030 int type = pkey ? EVP_PKEY_type(pkey->type) : EVP_PKEY_NONE;
1031
1032 /* The keylen supplied by OpenSSL can only be 512 or 1024.
1033 See ssl3_send_server_key_exchange() in ssl/s3_srvr.c
1034 */
1035 if (type == EVP_PKEY_RSA || type == EVP_PKEY_DSA) {
1036 keylen = EVP_PKEY_bits(pkey);
1037 }
1038
1039 if (keylen > global.tune.ssl_default_dh_param) {
1040 keylen = global.tune.ssl_default_dh_param;
1041 }
1042
1043 if (keylen >= 8192) {
Remi Gacogne60d7aeb2014-07-15 11:36:40 +02001044 dh = local_dh_8192;
Remi Gacognef46cd6e2014-06-12 14:58:40 +02001045 }
1046 else if (keylen >= 4096) {
Remi Gacogne60d7aeb2014-07-15 11:36:40 +02001047 dh = local_dh_4096;
Remi Gacognef46cd6e2014-06-12 14:58:40 +02001048 }
1049 else if (keylen >= 2048) {
Remi Gacogne60d7aeb2014-07-15 11:36:40 +02001050 dh = local_dh_2048;
Remi Gacognef46cd6e2014-06-12 14:58:40 +02001051 }
1052 else {
Remi Gacogne60d7aeb2014-07-15 11:36:40 +02001053 dh = local_dh_1024;
Remi Gacognef46cd6e2014-06-12 14:58:40 +02001054 }
1055
1056 return dh;
1057}
1058
Emeric Bruna4bcd9a2012-09-20 16:19:02 +02001059/* Loads Diffie-Hellman parameter from a file. Returns 1 if loaded, else -1
1060 if an error occured, and 0 if parameter not found. */
Willy Tarreau6e774b42014-04-25 21:35:23 +02001061int ssl_sock_load_dh_params(SSL_CTX *ctx, const char *file)
Emeric Bruna4bcd9a2012-09-20 16:19:02 +02001062{
1063 int ret = -1;
1064 BIO *in;
1065 DH *dh = NULL;
1066
1067 in = BIO_new(BIO_s_file());
1068 if (in == NULL)
1069 goto end;
1070
1071 if (BIO_read_filename(in, file) <= 0)
1072 goto end;
1073
1074 dh = PEM_read_bio_DHparams(in, NULL, ctx->default_passwd_callback, ctx->default_passwd_callback_userdata);
Remi Gacognef46cd6e2014-06-12 14:58:40 +02001075 if (dh) {
1076 ret = 1;
1077 SSL_CTX_set_tmp_dh(ctx, dh);
1078 /* Setting ssl default dh param to the size of the static DH params
1079 found in the file. This way we know that there is no use
1080 complaining later about ssl-default-dh-param not being set. */
1081 global.tune.ssl_default_dh_param = DH_size(dh) * 8;
1082 }
1083 else {
Emeric Brun41fdb3c2013-04-26 11:05:44 +02001084 /* Clear openssl global errors stack */
1085 ERR_clear_error();
1086
Remi Gacognef46cd6e2014-06-12 14:58:40 +02001087 if (global.tune.ssl_default_dh_param <= 1024) {
1088 /* we are limited to DH parameter of 1024 bits anyway */
Remi Gacogne60d7aeb2014-07-15 11:36:40 +02001089 local_dh_1024 = ssl_get_dh_1024();
1090 if (local_dh_1024 == NULL)
Remi Gacognef46cd6e2014-06-12 14:58:40 +02001091 goto end;
Willy Tarreau6e774b42014-04-25 21:35:23 +02001092
Remi Gacogne60d7aeb2014-07-15 11:36:40 +02001093 SSL_CTX_set_tmp_dh(ctx, local_dh_1024);
Remi Gacognef46cd6e2014-06-12 14:58:40 +02001094 }
1095 else {
1096 SSL_CTX_set_tmp_dh_callback(ctx, ssl_get_tmp_dh);
1097 }
Willy Tarreau6e774b42014-04-25 21:35:23 +02001098
Emeric Brun41fdb3c2013-04-26 11:05:44 +02001099 ret = 0; /* DH params not found */
Emeric Bruna4bcd9a2012-09-20 16:19:02 +02001100 }
Emeric Brun644cde02012-12-14 11:21:13 +01001101
Emeric Bruna4bcd9a2012-09-20 16:19:02 +02001102end:
1103 if (dh)
1104 DH_free(dh);
1105
1106 if (in)
Emeric Brun41fdb3c2013-04-26 11:05:44 +02001107 BIO_free(in);
Emeric Bruna4bcd9a2012-09-20 16:19:02 +02001108
1109 return ret;
1110}
1111#endif
1112
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +02001113static int ssl_sock_add_cert_sni(SSL_CTX *ctx, struct bind_conf *s, char *name, int order)
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01001114{
1115 struct sni_ctx *sc;
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +02001116 int wild = 0, neg = 0;
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01001117
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +02001118 if (*name == '!') {
1119 neg = 1;
1120 name++;
1121 }
1122 if (*name == '*') {
1123 wild = 1;
1124 name++;
1125 }
1126 /* !* filter is a nop */
1127 if (neg && wild)
1128 return order;
1129 if (*name) {
1130 int j, len;
1131 len = strlen(name);
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01001132 sc = malloc(sizeof(struct sni_ctx) + len + 1);
1133 for (j = 0; j < len; j++)
1134 sc->name.key[j] = tolower(name[j]);
1135 sc->name.key[len] = 0;
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01001136 sc->ctx = ctx;
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +02001137 sc->order = order++;
1138 sc->neg = neg;
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01001139 if (wild)
1140 ebst_insert(&s->sni_w_ctx, &sc->name);
1141 else
1142 ebst_insert(&s->sni_ctx, &sc->name);
1143 }
1144 return order;
1145}
1146
Emeric Brunfc0421f2012-09-07 17:30:07 +02001147/* Loads a certificate key and CA chain from a file. Returns 0 on error, -1 if
1148 * an early error happens and the caller must call SSL_CTX_free() by itelf.
1149 */
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +02001150static 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 +02001151{
1152 BIO *in;
1153 X509 *x = NULL, *ca;
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +02001154 int i, err;
Emeric Brunfc0421f2012-09-07 17:30:07 +02001155 int ret = -1;
1156 int order = 0;
1157 X509_NAME *xname;
1158 char *str;
Emeric Brunfc0421f2012-09-07 17:30:07 +02001159#ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME
1160 STACK_OF(GENERAL_NAME) *names;
1161#endif
1162
1163 in = BIO_new(BIO_s_file());
1164 if (in == NULL)
1165 goto end;
1166
1167 if (BIO_read_filename(in, file) <= 0)
1168 goto end;
1169
1170 x = PEM_read_bio_X509_AUX(in, NULL, ctx->default_passwd_callback, ctx->default_passwd_callback_userdata);
1171 if (x == NULL)
1172 goto end;
1173
Emeric Brun50bcecc2013-04-22 13:05:23 +02001174 if (fcount) {
1175 while (fcount--)
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +02001176 order = ssl_sock_add_cert_sni(ctx, s, sni_filter[fcount], order);
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01001177 }
1178 else {
Emeric Brunfc0421f2012-09-07 17:30:07 +02001179#ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01001180 names = X509_get_ext_d2i(x, NID_subject_alt_name, NULL, NULL);
1181 if (names) {
1182 for (i = 0; i < sk_GENERAL_NAME_num(names); i++) {
1183 GENERAL_NAME *name = sk_GENERAL_NAME_value(names, i);
1184 if (name->type == GEN_DNS) {
1185 if (ASN1_STRING_to_UTF8((unsigned char **)&str, name->d.dNSName) >= 0) {
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +02001186 order = ssl_sock_add_cert_sni(ctx, s, str, order);
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01001187 OPENSSL_free(str);
Emeric Brunfc0421f2012-09-07 17:30:07 +02001188 }
Emeric Brunfc0421f2012-09-07 17:30:07 +02001189 }
1190 }
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01001191 sk_GENERAL_NAME_pop_free(names, GENERAL_NAME_free);
Emeric Brunfc0421f2012-09-07 17:30:07 +02001192 }
Emeric Brunfc0421f2012-09-07 17:30:07 +02001193#endif /* SSL_CTRL_SET_TLSEXT_HOSTNAME */
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01001194 xname = X509_get_subject_name(x);
1195 i = -1;
1196 while ((i = X509_NAME_get_index_by_NID(xname, NID_commonName, i)) != -1) {
1197 X509_NAME_ENTRY *entry = X509_NAME_get_entry(xname, i);
1198 if (ASN1_STRING_to_UTF8((unsigned char **)&str, entry->value) >= 0) {
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +02001199 order = ssl_sock_add_cert_sni(ctx, s, str, order);
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01001200 OPENSSL_free(str);
Emeric Brunfc0421f2012-09-07 17:30:07 +02001201 }
Emeric Brunfc0421f2012-09-07 17:30:07 +02001202 }
1203 }
1204
1205 ret = 0; /* the caller must not free the SSL_CTX argument anymore */
1206 if (!SSL_CTX_use_certificate(ctx, x))
1207 goto end;
1208
1209 if (ctx->extra_certs != NULL) {
1210 sk_X509_pop_free(ctx->extra_certs, X509_free);
1211 ctx->extra_certs = NULL;
1212 }
1213
1214 while ((ca = PEM_read_bio_X509(in, NULL, ctx->default_passwd_callback, ctx->default_passwd_callback_userdata))) {
1215 if (!SSL_CTX_add_extra_chain_cert(ctx, ca)) {
1216 X509_free(ca);
1217 goto end;
1218 }
1219 }
1220
1221 err = ERR_get_error();
1222 if (!err || (ERR_GET_LIB(err) == ERR_LIB_PEM && ERR_GET_REASON(err) == PEM_R_NO_START_LINE)) {
1223 /* we successfully reached the last cert in the file */
1224 ret = 1;
1225 }
1226 ERR_clear_error();
1227
1228end:
1229 if (x)
1230 X509_free(x);
1231
1232 if (in)
1233 BIO_free(in);
1234
1235 return ret;
1236}
1237
Emeric Brun50bcecc2013-04-22 13:05:23 +02001238static 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 +02001239{
1240 int ret;
1241 SSL_CTX *ctx;
1242
1243 ctx = SSL_CTX_new(SSLv23_server_method());
1244 if (!ctx) {
Willy Tarreaueb6cead2012-09-20 19:43:14 +02001245 memprintf(err, "%sunable to allocate SSL context for cert '%s'.\n",
1246 err && *err ? *err : "", path);
Emeric Brunfc0421f2012-09-07 17:30:07 +02001247 return 1;
1248 }
1249
1250 if (SSL_CTX_use_PrivateKey_file(ctx, path, SSL_FILETYPE_PEM) <= 0) {
Willy Tarreaueb6cead2012-09-20 19:43:14 +02001251 memprintf(err, "%sunable to load SSL private key from PEM file '%s'.\n",
1252 err && *err ? *err : "", path);
Emeric Brunfc0421f2012-09-07 17:30:07 +02001253 SSL_CTX_free(ctx);
1254 return 1;
1255 }
1256
Emeric Brun50bcecc2013-04-22 13:05:23 +02001257 ret = ssl_sock_load_cert_chain_file(ctx, path, bind_conf, sni_filter, fcount);
Emeric Brunfc0421f2012-09-07 17:30:07 +02001258 if (ret <= 0) {
Willy Tarreaueb6cead2012-09-20 19:43:14 +02001259 memprintf(err, "%sunable to load SSL certificate from PEM file '%s'.\n",
1260 err && *err ? *err : "", path);
Emeric Brunfc0421f2012-09-07 17:30:07 +02001261 if (ret < 0) /* serious error, must do that ourselves */
1262 SSL_CTX_free(ctx);
1263 return 1;
1264 }
Emeric Brun61694ab2012-10-26 13:35:33 +02001265
1266 if (SSL_CTX_check_private_key(ctx) <= 0) {
1267 memprintf(err, "%sinconsistencies between private key and certificate loaded from PEM file '%s'.\n",
1268 err && *err ? *err : "", path);
1269 return 1;
1270 }
1271
Emeric Brunfc0421f2012-09-07 17:30:07 +02001272 /* we must not free the SSL_CTX anymore below, since it's already in
1273 * the tree, so it will be discovered and cleaned in time.
1274 */
Emeric Bruna4bcd9a2012-09-20 16:19:02 +02001275#ifndef OPENSSL_NO_DH
1276 ret = ssl_sock_load_dh_params(ctx, path);
1277 if (ret < 0) {
1278 if (err)
1279 memprintf(err, "%sunable to load DH parameters from file '%s'.\n",
1280 *err ? *err : "", path);
1281 return 1;
1282 }
1283#endif
1284
Emeric Brun4147b2e2014-06-16 18:36:30 +02001285#ifdef SSL_CTRL_SET_TLSEXT_STATUS_REQ_CB
1286 ret = ssl_sock_load_ocsp(ctx, path);
1287 if (ret < 0) {
1288 if (err)
1289 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",
1290 *err ? *err : "", path);
1291 return 1;
1292 }
1293#endif
1294
Emeric Brunfc0421f2012-09-07 17:30:07 +02001295#ifndef SSL_CTRL_SET_TLSEXT_HOSTNAME
Willy Tarreau2a65ff02012-09-13 17:54:29 +02001296 if (bind_conf->default_ctx) {
Willy Tarreaueb6cead2012-09-20 19:43:14 +02001297 memprintf(err, "%sthis version of openssl cannot load multiple SSL certificates.\n",
1298 err && *err ? *err : "");
Emeric Brunfc0421f2012-09-07 17:30:07 +02001299 return 1;
1300 }
1301#endif
Willy Tarreau2a65ff02012-09-13 17:54:29 +02001302 if (!bind_conf->default_ctx)
1303 bind_conf->default_ctx = ctx;
Emeric Brunfc0421f2012-09-07 17:30:07 +02001304
1305 return 0;
1306}
1307
Willy Tarreau79eeafa2012-09-14 07:53:05 +02001308int ssl_sock_load_cert(char *path, struct bind_conf *bind_conf, struct proxy *curproxy, char **err)
Emeric Brunfc0421f2012-09-07 17:30:07 +02001309{
1310 struct dirent *de;
1311 DIR *dir;
1312 struct stat buf;
Willy Tarreauee2663b2012-12-06 11:36:59 +01001313 char *end;
1314 char fp[MAXPATHLEN+1];
Emeric Brunfc0421f2012-09-07 17:30:07 +02001315 int cfgerr = 0;
1316
1317 if (!(dir = opendir(path)))
Emeric Brun50bcecc2013-04-22 13:05:23 +02001318 return ssl_sock_load_cert_file(path, bind_conf, curproxy, NULL, 0, err);
Emeric Brunfc0421f2012-09-07 17:30:07 +02001319
1320 /* strip trailing slashes, including first one */
1321 for (end = path + strlen(path) - 1; end >= path && *end == '/'; end--)
1322 *end = 0;
1323
Emeric Brunfc0421f2012-09-07 17:30:07 +02001324 while ((de = readdir(dir))) {
Emeric Brun2aab7222014-06-18 18:15:09 +02001325 end = strrchr(de->d_name, '.');
1326 if (end && (!strcmp(end, ".issuer") || !strcmp(end, ".ocsp")))
1327 continue;
1328
Willy Tarreauee2663b2012-12-06 11:36:59 +01001329 snprintf(fp, sizeof(fp), "%s/%s", path, de->d_name);
Emeric Brunfc0421f2012-09-07 17:30:07 +02001330 if (stat(fp, &buf) != 0) {
Willy Tarreaueb6cead2012-09-20 19:43:14 +02001331 memprintf(err, "%sunable to stat SSL certificate from file '%s' : %s.\n",
1332 err && *err ? *err : "", fp, strerror(errno));
Emeric Brunfc0421f2012-09-07 17:30:07 +02001333 cfgerr++;
1334 continue;
1335 }
1336 if (!S_ISREG(buf.st_mode))
1337 continue;
Emeric Brun50bcecc2013-04-22 13:05:23 +02001338 cfgerr += ssl_sock_load_cert_file(fp, bind_conf, curproxy, NULL, 0, err);
Emeric Brunfc0421f2012-09-07 17:30:07 +02001339 }
Emeric Brunfc0421f2012-09-07 17:30:07 +02001340 closedir(dir);
1341 return cfgerr;
1342}
1343
Thierry Fournier383085f2013-01-24 14:15:43 +01001344/* Make sure openssl opens /dev/urandom before the chroot. The work is only
1345 * done once. Zero is returned if the operation fails. No error is returned
1346 * if the random is said as not implemented, because we expect that openssl
1347 * will use another method once needed.
1348 */
1349static int ssl_initialize_random()
1350{
1351 unsigned char random;
1352 static int random_initialized = 0;
1353
1354 if (!random_initialized && RAND_bytes(&random, 1) != 0)
1355 random_initialized = 1;
1356
1357 return random_initialized;
1358}
1359
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01001360int ssl_sock_load_cert_list_file(char *file, struct bind_conf *bind_conf, struct proxy *curproxy, char **err)
1361{
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +02001362 char thisline[LINESIZE];
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01001363 FILE *f;
1364 int linenum = 0;
1365 int cfgerr = 0;
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01001366
Willy Tarreauad1731d2013-04-02 17:35:58 +02001367 if ((f = fopen(file, "r")) == NULL) {
1368 memprintf(err, "cannot open file '%s' : %s", file, strerror(errno));
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01001369 return 1;
Willy Tarreauad1731d2013-04-02 17:35:58 +02001370 }
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01001371
1372 while (fgets(thisline, sizeof(thisline), f) != NULL) {
1373 int arg;
Emeric Brun50bcecc2013-04-22 13:05:23 +02001374 int newarg;
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01001375 char *end;
1376 char *args[MAX_LINE_ARGS + 1];
1377 char *line = thisline;
1378
1379 linenum++;
1380 end = line + strlen(line);
1381 if (end-line == sizeof(thisline)-1 && *(end-1) != '\n') {
1382 /* Check if we reached the limit and the last char is not \n.
1383 * Watch out for the last line without the terminating '\n'!
1384 */
Willy Tarreauad1731d2013-04-02 17:35:58 +02001385 memprintf(err, "line %d too long in file '%s', limit is %d characters",
1386 linenum, file, (int)sizeof(thisline)-1);
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01001387 cfgerr = 1;
Willy Tarreauad1731d2013-04-02 17:35:58 +02001388 break;
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01001389 }
1390
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01001391 arg = 0;
Emeric Brun50bcecc2013-04-22 13:05:23 +02001392 newarg = 1;
1393 while (*line) {
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01001394 if (*line == '#' || *line == '\n' || *line == '\r') {
1395 /* end of string, end of loop */
1396 *line = 0;
1397 break;
1398 }
1399 else if (isspace(*line)) {
Emeric Brun50bcecc2013-04-22 13:05:23 +02001400 newarg = 1;
1401 *line = 0;
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01001402 }
Emeric Brun50bcecc2013-04-22 13:05:23 +02001403 else if (newarg) {
1404 if (arg == MAX_LINE_ARGS) {
1405 memprintf(err, "too many args on line %d in file '%s'.",
1406 linenum, file);
1407 cfgerr = 1;
1408 break;
1409 }
1410 newarg = 0;
1411 args[arg++] = line;
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01001412 }
Emeric Brun50bcecc2013-04-22 13:05:23 +02001413 line++;
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01001414 }
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +02001415 if (cfgerr)
1416 break;
Willy Tarreauad1731d2013-04-02 17:35:58 +02001417
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01001418 /* empty line */
Emeric Brun50bcecc2013-04-22 13:05:23 +02001419 if (!arg)
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01001420 continue;
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01001421
Emeric Brun50bcecc2013-04-22 13:05:23 +02001422 cfgerr = ssl_sock_load_cert_file(args[0], bind_conf, curproxy, &args[1], arg-1, err);
Willy Tarreauad1731d2013-04-02 17:35:58 +02001423 if (cfgerr) {
1424 memprintf(err, "error processing line %d in file '%s' : %s", linenum, file, *err);
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01001425 break;
Willy Tarreauad1731d2013-04-02 17:35:58 +02001426 }
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01001427 }
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01001428 fclose(f);
1429 return cfgerr;
1430}
1431
Emeric Brunfc0421f2012-09-07 17:30:07 +02001432#ifndef SSL_OP_CIPHER_SERVER_PREFERENCE /* needs OpenSSL >= 0.9.7 */
1433#define SSL_OP_CIPHER_SERVER_PREFERENCE 0
1434#endif
1435
1436#ifndef SSL_OP_NO_SESSION_RESUMPTION_ON_RENEGOTIATION /* needs OpenSSL >= 0.9.7 */
1437#define SSL_OP_NO_SESSION_RESUMPTION_ON_RENEGOTIATION 0
Willy Tarreau7d588ee2012-11-26 18:47:31 +01001438#define SSL_renegotiate_pending(arg) 0
Emeric Brunfc0421f2012-09-07 17:30:07 +02001439#endif
Emeric Brun2b58d042012-09-20 17:10:03 +02001440#ifndef SSL_OP_SINGLE_ECDH_USE /* needs OpenSSL >= 0.9.8 */
1441#define SSL_OP_SINGLE_ECDH_USE 0
1442#endif
Emeric Brun2d0c4822012-10-02 13:45:20 +02001443#ifndef SSL_OP_NO_TICKET /* needs OpenSSL >= 0.9.8 */
1444#define SSL_OP_NO_TICKET 0
1445#endif
Emeric Brunfc0421f2012-09-07 17:30:07 +02001446#ifndef SSL_OP_NO_COMPRESSION /* needs OpenSSL >= 0.9.9 */
1447#define SSL_OP_NO_COMPRESSION 0
1448#endif
Emeric Brunc0ff4922012-09-28 19:37:02 +02001449#ifndef SSL_OP_NO_TLSv1_1 /* needs OpenSSL >= 1.0.1 */
1450#define SSL_OP_NO_TLSv1_1 0
1451#endif
1452#ifndef SSL_OP_NO_TLSv1_2 /* needs OpenSSL >= 1.0.1 */
1453#define SSL_OP_NO_TLSv1_2 0
1454#endif
Emeric Bruna4bcd9a2012-09-20 16:19:02 +02001455#ifndef SSL_OP_SINGLE_DH_USE /* needs OpenSSL >= 0.9.6 */
1456#define SSL_OP_SINGLE_DH_USE 0
1457#endif
Emeric Brun2b58d042012-09-20 17:10:03 +02001458#ifndef SSL_OP_SINGLE_ECDH_USE /* needs OpenSSL >= 1.0.0 */
1459#define SSL_OP_SINGLE_ECDH_USE 0
1460#endif
Emeric Brunfc0421f2012-09-07 17:30:07 +02001461#ifndef SSL_MODE_RELEASE_BUFFERS /* needs OpenSSL >= 1.0.0 */
1462#define SSL_MODE_RELEASE_BUFFERS 0
1463#endif
Remi Gacognef46cd6e2014-06-12 14:58:40 +02001464
Willy Tarreau2a65ff02012-09-13 17:54:29 +02001465int ssl_sock_prepare_ctx(struct bind_conf *bind_conf, SSL_CTX *ctx, struct proxy *curproxy)
Emeric Brunfc0421f2012-09-07 17:30:07 +02001466{
1467 int cfgerr = 0;
Emeric Brun850efd52014-01-29 12:24:34 +01001468 int verify = SSL_VERIFY_NONE;
Remi Gacogneaf5c3da2014-05-19 10:29:58 +02001469 long ssloptions =
Emeric Brunfc0421f2012-09-07 17:30:07 +02001470 SSL_OP_ALL | /* all known workarounds for bugs */
1471 SSL_OP_NO_SSLv2 |
1472 SSL_OP_NO_COMPRESSION |
Emeric Bruna4bcd9a2012-09-20 16:19:02 +02001473 SSL_OP_SINGLE_DH_USE |
Emeric Brun2b58d042012-09-20 17:10:03 +02001474 SSL_OP_SINGLE_ECDH_USE |
Emeric Brun3c4bc6e2012-10-04 18:44:19 +02001475 SSL_OP_NO_SESSION_RESUMPTION_ON_RENEGOTIATION |
1476 SSL_OP_CIPHER_SERVER_PREFERENCE;
Remi Gacogneaf5c3da2014-05-19 10:29:58 +02001477 long sslmode =
Emeric Brunfc0421f2012-09-07 17:30:07 +02001478 SSL_MODE_ENABLE_PARTIAL_WRITE |
1479 SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER |
1480 SSL_MODE_RELEASE_BUFFERS;
Remi Gacognef46cd6e2014-06-12 14:58:40 +02001481 STACK_OF(SSL_CIPHER) * ciphers = NULL;
1482 SSL_CIPHER * cipher = NULL;
Remi Gacognec1eab8c2014-06-12 18:20:11 +02001483 char cipher_description[128];
1484 /* The description of ciphers using an Ephemeral Diffie Hellman key exchange
1485 contains " Kx=DH " or " Kx=DH(". Beware of " Kx=DH/",
1486 which is not ephemeral DH. */
1487 const char dhe_description[] = " Kx=DH ";
1488 const char dhe_export_description[] = " Kx=DH(";
Remi Gacognef46cd6e2014-06-12 14:58:40 +02001489 int idx = 0;
1490 int dhe_found = 0;
Emeric Brunfc0421f2012-09-07 17:30:07 +02001491
Thierry Fournier383085f2013-01-24 14:15:43 +01001492 /* Make sure openssl opens /dev/urandom before the chroot */
1493 if (!ssl_initialize_random()) {
1494 Alert("OpenSSL random data generator initialization failed.\n");
1495 cfgerr++;
1496 }
1497
Emeric Brun89675492012-10-05 13:48:26 +02001498 if (bind_conf->ssl_options & BC_SSL_O_NO_SSLV3)
Emeric Brunfc0421f2012-09-07 17:30:07 +02001499 ssloptions |= SSL_OP_NO_SSLv3;
Emeric Brun89675492012-10-05 13:48:26 +02001500 if (bind_conf->ssl_options & BC_SSL_O_NO_TLSV10)
Emeric Brunfc0421f2012-09-07 17:30:07 +02001501 ssloptions |= SSL_OP_NO_TLSv1;
Emeric Brun89675492012-10-05 13:48:26 +02001502 if (bind_conf->ssl_options & BC_SSL_O_NO_TLSV11)
Emeric Brunc0ff4922012-09-28 19:37:02 +02001503 ssloptions |= SSL_OP_NO_TLSv1_1;
Emeric Brun89675492012-10-05 13:48:26 +02001504 if (bind_conf->ssl_options & BC_SSL_O_NO_TLSV12)
Emeric Brunc0ff4922012-09-28 19:37:02 +02001505 ssloptions |= SSL_OP_NO_TLSv1_2;
Emeric Brun89675492012-10-05 13:48:26 +02001506 if (bind_conf->ssl_options & BC_SSL_O_NO_TLS_TICKETS)
Emeric Brun2d0c4822012-10-02 13:45:20 +02001507 ssloptions |= SSL_OP_NO_TICKET;
Emeric Brun2cb7ae52012-10-05 14:14:21 +02001508 if (bind_conf->ssl_options & BC_SSL_O_USE_SSLV3)
1509 SSL_CTX_set_ssl_version(ctx, SSLv3_server_method());
1510 if (bind_conf->ssl_options & BC_SSL_O_USE_TLSV10)
1511 SSL_CTX_set_ssl_version(ctx, TLSv1_server_method());
1512#if SSL_OP_NO_TLSv1_1
1513 if (bind_conf->ssl_options & BC_SSL_O_USE_TLSV11)
1514 SSL_CTX_set_ssl_version(ctx, TLSv1_1_server_method());
1515#endif
1516#if SSL_OP_NO_TLSv1_2
1517 if (bind_conf->ssl_options & BC_SSL_O_USE_TLSV12)
1518 SSL_CTX_set_ssl_version(ctx, TLSv1_2_server_method());
1519#endif
Emeric Brunfc0421f2012-09-07 17:30:07 +02001520
1521 SSL_CTX_set_options(ctx, ssloptions);
1522 SSL_CTX_set_mode(ctx, sslmode);
Emeric Brun850efd52014-01-29 12:24:34 +01001523 switch (bind_conf->verify) {
1524 case SSL_SOCK_VERIFY_NONE:
1525 verify = SSL_VERIFY_NONE;
1526 break;
1527 case SSL_SOCK_VERIFY_OPTIONAL:
1528 verify = SSL_VERIFY_PEER;
1529 break;
1530 case SSL_SOCK_VERIFY_REQUIRED:
1531 verify = SSL_VERIFY_PEER|SSL_VERIFY_FAIL_IF_NO_PEER_CERT;
1532 break;
1533 }
1534 SSL_CTX_set_verify(ctx, verify, ssl_sock_bind_verifycbk);
1535 if (verify & SSL_VERIFY_PEER) {
Emeric Brunfb510ea2012-10-05 12:00:26 +02001536 if (bind_conf->ca_file) {
Emeric Brund94b3fe2012-09-20 18:23:56 +02001537 /* load CAfile to verify */
Emeric Brunfb510ea2012-10-05 12:00:26 +02001538 if (!SSL_CTX_load_verify_locations(ctx, bind_conf->ca_file, NULL)) {
Emeric Brund94b3fe2012-09-20 18:23:56 +02001539 Alert("Proxy '%s': unable to load CA file '%s' for bind '%s' at [%s:%d].\n",
Emeric Brunfb510ea2012-10-05 12:00:26 +02001540 curproxy->id, bind_conf->ca_file, bind_conf->arg, bind_conf->file, bind_conf->line);
Emeric Brund94b3fe2012-09-20 18:23:56 +02001541 cfgerr++;
1542 }
1543 /* set CA names fo client cert request, function returns void */
Emeric Brunfb510ea2012-10-05 12:00:26 +02001544 SSL_CTX_set_client_CA_list(ctx, SSL_load_client_CA_file(bind_conf->ca_file));
Emeric Brund94b3fe2012-09-20 18:23:56 +02001545 }
Emeric Brun850efd52014-01-29 12:24:34 +01001546 else {
1547 Alert("Proxy '%s': verify is enabled but no CA file specified for bind '%s' at [%s:%d].\n",
1548 curproxy->id, bind_conf->arg, bind_conf->file, bind_conf->line);
1549 cfgerr++;
1550 }
Emeric Brun051cdab2012-10-02 19:25:50 +02001551#ifdef X509_V_FLAG_CRL_CHECK
Emeric Brunfb510ea2012-10-05 12:00:26 +02001552 if (bind_conf->crl_file) {
Emeric Brund94b3fe2012-09-20 18:23:56 +02001553 X509_STORE *store = SSL_CTX_get_cert_store(ctx);
1554
Emeric Brunfb510ea2012-10-05 12:00:26 +02001555 if (!store || !X509_STORE_load_locations(store, bind_conf->crl_file, NULL)) {
Emeric Brund94b3fe2012-09-20 18:23:56 +02001556 Alert("Proxy '%s': unable to configure CRL file '%s' for bind '%s' at [%s:%d].\n",
Emeric Brunfb510ea2012-10-05 12:00:26 +02001557 curproxy->id, bind_conf->ca_file, bind_conf->arg, bind_conf->file, bind_conf->line);
Emeric Brund94b3fe2012-09-20 18:23:56 +02001558 cfgerr++;
1559 }
Emeric Brun561e5742012-10-02 15:20:55 +02001560 else {
1561 X509_STORE_set_flags(store, X509_V_FLAG_CRL_CHECK|X509_V_FLAG_CRL_CHECK_ALL);
1562 }
Emeric Brund94b3fe2012-09-20 18:23:56 +02001563 }
Emeric Brun051cdab2012-10-02 19:25:50 +02001564#endif
Emeric Brun644cde02012-12-14 11:21:13 +01001565 ERR_clear_error();
Emeric Brund94b3fe2012-09-20 18:23:56 +02001566 }
Emeric Brunfc0421f2012-09-07 17:30:07 +02001567
Emeric Brun4f65bff2012-11-16 15:11:00 +01001568 if (global.tune.ssllifetime)
1569 SSL_CTX_set_timeout(ctx, global.tune.ssllifetime);
1570
Emeric Brunfc0421f2012-09-07 17:30:07 +02001571 shared_context_set_cache(ctx);
Willy Tarreau2a65ff02012-09-13 17:54:29 +02001572 if (bind_conf->ciphers &&
1573 !SSL_CTX_set_cipher_list(ctx, bind_conf->ciphers)) {
Emeric Brunfc0421f2012-09-07 17:30:07 +02001574 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 +02001575 curproxy->id, bind_conf->ciphers, bind_conf->arg, bind_conf->file, bind_conf->line);
Emeric Brunfc0421f2012-09-07 17:30:07 +02001576 cfgerr++;
1577 }
1578
Remi Gacognef46cd6e2014-06-12 14:58:40 +02001579 /* If tune.ssl.default-dh-param has not been set and
1580 no static DH params were in the certificate file. */
1581 if (global.tune.ssl_default_dh_param == 0) {
1582 ciphers = ctx->cipher_list;
1583
1584 if (ciphers) {
1585 for (idx = 0; idx < sk_SSL_CIPHER_num(ciphers); idx++) {
1586 cipher = sk_SSL_CIPHER_value(ciphers, idx);
Remi Gacognec1eab8c2014-06-12 18:20:11 +02001587 if (SSL_CIPHER_description(cipher, cipher_description, sizeof (cipher_description)) == cipher_description) {
1588 if (strstr(cipher_description, dhe_description) != NULL ||
1589 strstr(cipher_description, dhe_export_description) != NULL) {
1590 dhe_found = 1;
1591 break;
1592 }
Remi Gacognef46cd6e2014-06-12 14:58:40 +02001593 }
1594 }
1595
1596 if (dhe_found) {
1597 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");
1598 }
1599 }
1600
1601 global.tune.ssl_default_dh_param = 1024;
1602 }
Remi Gacogne60d7aeb2014-07-15 11:36:40 +02001603
1604#ifndef OPENSSL_NO_DH
1605 if (global.tune.ssl_default_dh_param >= 1024) {
1606 if (local_dh_1024 == NULL) {
1607 local_dh_1024 = ssl_get_dh_1024();
1608 }
1609 if (global.tune.ssl_default_dh_param >= 2048) {
1610 if (local_dh_2048 == NULL) {
1611 local_dh_2048 = ssl_get_dh_2048();
1612 }
1613 if (global.tune.ssl_default_dh_param >= 4096) {
1614 if (local_dh_4096 == NULL) {
1615 local_dh_4096 = ssl_get_dh_4096();
1616 }
1617 if (global.tune.ssl_default_dh_param >= 8192 &&
1618 local_dh_8192 == NULL) {
1619 local_dh_8192 = ssl_get_dh_8192();
1620 }
1621 }
1622 }
1623 }
1624#endif /* OPENSSL_NO_DH */
Remi Gacognef46cd6e2014-06-12 14:58:40 +02001625
Emeric Brunfc0421f2012-09-07 17:30:07 +02001626 SSL_CTX_set_info_callback(ctx, ssl_sock_infocbk);
Willy Tarreau5cbe4ef2014-05-08 22:45:11 +02001627#if OPENSSL_VERSION_NUMBER >= 0x00907000L
Emeric Brun29f037d2014-04-25 19:05:36 +02001628 SSL_CTX_set_msg_callback(ctx, ssl_sock_msgcbk);
Willy Tarreau5cbe4ef2014-05-08 22:45:11 +02001629#endif
Emeric Brun29f037d2014-04-25 19:05:36 +02001630
Willy Tarreau6c9a3d52012-10-18 18:57:14 +02001631#ifdef OPENSSL_NPN_NEGOTIATED
1632 if (bind_conf->npn_str)
1633 SSL_CTX_set_next_protos_advertised_cb(ctx, ssl_sock_advertise_npn_protos, bind_conf);
1634#endif
Dirkjan Bussink48f1c4e2014-02-13 12:29:42 +01001635#ifdef TLSEXT_TYPE_application_layer_protocol_negotiation
Willy Tarreauab861d32013-04-02 02:30:41 +02001636 if (bind_conf->alpn_str)
Dirkjan Bussink48f1c4e2014-02-13 12:29:42 +01001637 SSL_CTX_set_alpn_select_cb(ctx, ssl_sock_advertise_alpn_protos, bind_conf);
Willy Tarreauab861d32013-04-02 02:30:41 +02001638#endif
Willy Tarreau6c9a3d52012-10-18 18:57:14 +02001639
Emeric Brunfc0421f2012-09-07 17:30:07 +02001640#ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME
1641 SSL_CTX_set_tlsext_servername_callback(ctx, ssl_sock_switchctx_cbk);
Willy Tarreau2a65ff02012-09-13 17:54:29 +02001642 SSL_CTX_set_tlsext_servername_arg(ctx, bind_conf);
Emeric Brunfc0421f2012-09-07 17:30:07 +02001643#endif
Emeric Brun2b58d042012-09-20 17:10:03 +02001644#if defined(SSL_CTX_set_tmp_ecdh) && !defined(OPENSSL_NO_ECDH)
Emeric Brun6924ef82013-03-06 14:08:53 +01001645 {
Emeric Brun2b58d042012-09-20 17:10:03 +02001646 int i;
1647 EC_KEY *ecdh;
1648
Emeric Brun6924ef82013-03-06 14:08:53 +01001649 i = OBJ_sn2nid(bind_conf->ecdhe ? bind_conf->ecdhe : ECDHE_DEFAULT_CURVE);
Emeric Brun2b58d042012-09-20 17:10:03 +02001650 if (!i || ((ecdh = EC_KEY_new_by_curve_name(i)) == NULL)) {
1651 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 +01001652 curproxy->id, bind_conf->ecdhe ? bind_conf->ecdhe : ECDHE_DEFAULT_CURVE,
1653 bind_conf->arg, bind_conf->file, bind_conf->line);
Emeric Brun2b58d042012-09-20 17:10:03 +02001654 cfgerr++;
1655 }
1656 else {
1657 SSL_CTX_set_tmp_ecdh(ctx, ecdh);
1658 EC_KEY_free(ecdh);
1659 }
1660 }
1661#endif
1662
Emeric Brunfc0421f2012-09-07 17:30:07 +02001663 return cfgerr;
1664}
1665
Evan Broderbe554312013-06-27 00:05:25 -07001666static int ssl_sock_srv_hostcheck(const char *pattern, const char *hostname)
1667{
1668 const char *pattern_wildcard, *pattern_left_label_end, *hostname_left_label_end;
1669 size_t prefixlen, suffixlen;
1670
1671 /* Trivial case */
1672 if (strcmp(pattern, hostname) == 0)
1673 return 1;
1674
Evan Broderbe554312013-06-27 00:05:25 -07001675 /* The rest of this logic is based on RFC 6125, section 6.4.3
1676 * (http://tools.ietf.org/html/rfc6125#section-6.4.3) */
1677
Emeric Bruna848dae2013-10-08 11:27:28 +02001678 pattern_wildcard = NULL;
1679 pattern_left_label_end = pattern;
1680 while (*pattern_left_label_end != '.') {
1681 switch (*pattern_left_label_end) {
1682 case 0:
1683 /* End of label not found */
1684 return 0;
1685 case '*':
1686 /* If there is more than one wildcards */
1687 if (pattern_wildcard)
1688 return 0;
1689 pattern_wildcard = pattern_left_label_end;
1690 break;
1691 }
1692 pattern_left_label_end++;
1693 }
1694
1695 /* If it's not trivial and there is no wildcard, it can't
1696 * match */
1697 if (!pattern_wildcard)
Evan Broderbe554312013-06-27 00:05:25 -07001698 return 0;
1699
1700 /* Make sure all labels match except the leftmost */
1701 hostname_left_label_end = strchr(hostname, '.');
1702 if (!hostname_left_label_end
1703 || strcmp(pattern_left_label_end, hostname_left_label_end) != 0)
1704 return 0;
1705
1706 /* Make sure the leftmost label of the hostname is long enough
1707 * that the wildcard can match */
Emeric Brun369da852013-10-08 11:39:35 +02001708 if (hostname_left_label_end - hostname < (pattern_left_label_end - pattern) - 1)
Evan Broderbe554312013-06-27 00:05:25 -07001709 return 0;
1710
1711 /* Finally compare the string on either side of the
1712 * wildcard */
1713 prefixlen = pattern_wildcard - pattern;
1714 suffixlen = pattern_left_label_end - (pattern_wildcard + 1);
Emeric Bruna848dae2013-10-08 11:27:28 +02001715 if ((prefixlen && (memcmp(pattern, hostname, prefixlen) != 0))
1716 || (suffixlen && (memcmp(pattern_wildcard + 1, hostname_left_label_end - suffixlen, suffixlen) != 0)))
Evan Broderbe554312013-06-27 00:05:25 -07001717 return 0;
1718
1719 return 1;
1720}
1721
1722static int ssl_sock_srv_verifycbk(int ok, X509_STORE_CTX *ctx)
1723{
1724 SSL *ssl;
1725 struct connection *conn;
1726 char *servername;
1727
1728 int depth;
1729 X509 *cert;
1730 STACK_OF(GENERAL_NAME) *alt_names;
1731 int i;
1732 X509_NAME *cert_subject;
1733 char *str;
1734
1735 if (ok == 0)
1736 return ok;
1737
1738 ssl = X509_STORE_CTX_get_ex_data(ctx, SSL_get_ex_data_X509_STORE_CTX_idx());
1739 conn = (struct connection *)SSL_get_app_data(ssl);
1740
1741 servername = objt_server(conn->target)->ssl_ctx.verify_host;
1742
1743 /* We only need to verify the CN on the actual server cert,
1744 * not the indirect CAs */
1745 depth = X509_STORE_CTX_get_error_depth(ctx);
1746 if (depth != 0)
1747 return ok;
1748
1749 /* At this point, the cert is *not* OK unless we can find a
1750 * hostname match */
1751 ok = 0;
1752
1753 cert = X509_STORE_CTX_get_current_cert(ctx);
1754 /* It seems like this might happen if verify peer isn't set */
1755 if (!cert)
1756 return ok;
1757
1758 alt_names = X509_get_ext_d2i(cert, NID_subject_alt_name, NULL, NULL);
1759 if (alt_names) {
1760 for (i = 0; !ok && i < sk_GENERAL_NAME_num(alt_names); i++) {
1761 GENERAL_NAME *name = sk_GENERAL_NAME_value(alt_names, i);
1762 if (name->type == GEN_DNS) {
Emeric Bruna33410c2013-09-17 15:47:48 +02001763#if OPENSSL_VERSION_NUMBER < 0x00907000L
1764 if (ASN1_STRING_to_UTF8((unsigned char **)&str, name->d.ia5) >= 0) {
1765#else
Evan Broderbe554312013-06-27 00:05:25 -07001766 if (ASN1_STRING_to_UTF8((unsigned char **)&str, name->d.dNSName) >= 0) {
Emeric Bruna33410c2013-09-17 15:47:48 +02001767#endif
Evan Broderbe554312013-06-27 00:05:25 -07001768 ok = ssl_sock_srv_hostcheck(str, servername);
1769 OPENSSL_free(str);
1770 }
1771 }
1772 }
Emeric Brun4ad50a42013-09-17 15:19:54 +02001773 sk_GENERAL_NAME_pop_free(alt_names, GENERAL_NAME_free);
Evan Broderbe554312013-06-27 00:05:25 -07001774 }
1775
1776 cert_subject = X509_get_subject_name(cert);
1777 i = -1;
1778 while (!ok && (i = X509_NAME_get_index_by_NID(cert_subject, NID_commonName, i)) != -1) {
1779 X509_NAME_ENTRY *entry = X509_NAME_get_entry(cert_subject, i);
1780 if (ASN1_STRING_to_UTF8((unsigned char **)&str, entry->value) >= 0) {
1781 ok = ssl_sock_srv_hostcheck(str, servername);
1782 OPENSSL_free(str);
1783 }
1784 }
1785
1786 return ok;
1787}
1788
Emeric Brun94324a42012-10-11 14:00:19 +02001789/* prepare ssl context from servers options. Returns an error count */
1790int ssl_sock_prepare_srv_ctx(struct server *srv, struct proxy *curproxy)
1791{
1792 int cfgerr = 0;
Remi Gacogneaf5c3da2014-05-19 10:29:58 +02001793 long options =
Emeric Brun94324a42012-10-11 14:00:19 +02001794 SSL_OP_ALL | /* all known workarounds for bugs */
1795 SSL_OP_NO_SSLv2 |
1796 SSL_OP_NO_COMPRESSION;
Remi Gacogneaf5c3da2014-05-19 10:29:58 +02001797 long mode =
Emeric Brun94324a42012-10-11 14:00:19 +02001798 SSL_MODE_ENABLE_PARTIAL_WRITE |
1799 SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER |
1800 SSL_MODE_RELEASE_BUFFERS;
Emeric Brun850efd52014-01-29 12:24:34 +01001801 int verify = SSL_VERIFY_NONE;
Emeric Brun94324a42012-10-11 14:00:19 +02001802
Thierry Fournier383085f2013-01-24 14:15:43 +01001803 /* Make sure openssl opens /dev/urandom before the chroot */
1804 if (!ssl_initialize_random()) {
1805 Alert("OpenSSL random data generator initialization failed.\n");
1806 cfgerr++;
1807 }
1808
Emeric Brun94324a42012-10-11 14:00:19 +02001809 /* Initiate SSL context for current server */
1810 srv->ssl_ctx.reused_sess = NULL;
1811 if (srv->use_ssl)
1812 srv->xprt = &ssl_sock;
1813 if (srv->check.use_ssl)
Simon Horman66183002013-02-23 10:16:43 +09001814 srv->check_common.xprt = &ssl_sock;
Emeric Brun94324a42012-10-11 14:00:19 +02001815
1816 srv->ssl_ctx.ctx = SSL_CTX_new(SSLv23_client_method());
1817 if (!srv->ssl_ctx.ctx) {
1818 Alert("config : %s '%s', server '%s': unable to allocate ssl context.\n",
1819 proxy_type_str(curproxy), curproxy->id,
1820 srv->id);
1821 cfgerr++;
1822 return cfgerr;
1823 }
Emeric Bruna7aa3092012-10-26 12:58:00 +02001824 if (srv->ssl_ctx.client_crt) {
1825 if (SSL_CTX_use_PrivateKey_file(srv->ssl_ctx.ctx, srv->ssl_ctx.client_crt, SSL_FILETYPE_PEM) <= 0) {
1826 Alert("config : %s '%s', server '%s': unable to load SSL private key from PEM file '%s'.\n",
1827 proxy_type_str(curproxy), curproxy->id,
1828 srv->id, srv->ssl_ctx.client_crt);
1829 cfgerr++;
1830 }
1831 else if (SSL_CTX_use_certificate_chain_file(srv->ssl_ctx.ctx, srv->ssl_ctx.client_crt) <= 0) {
1832 Alert("config : %s '%s', server '%s': unable to load ssl certificate from PEM file '%s'.\n",
1833 proxy_type_str(curproxy), curproxy->id,
1834 srv->id, srv->ssl_ctx.client_crt);
1835 cfgerr++;
1836 }
1837 else if (SSL_CTX_check_private_key(srv->ssl_ctx.ctx) <= 0) {
1838 Alert("config : %s '%s', server '%s': inconsistencies between private key and certificate loaded from PEM file '%s'.\n",
1839 proxy_type_str(curproxy), curproxy->id,
1840 srv->id, srv->ssl_ctx.client_crt);
1841 cfgerr++;
1842 }
1843 }
Emeric Brun94324a42012-10-11 14:00:19 +02001844
1845 if (srv->ssl_ctx.options & SRV_SSL_O_NO_SSLV3)
1846 options |= SSL_OP_NO_SSLv3;
1847 if (srv->ssl_ctx.options & SRV_SSL_O_NO_TLSV10)
1848 options |= SSL_OP_NO_TLSv1;
1849 if (srv->ssl_ctx.options & SRV_SSL_O_NO_TLSV11)
1850 options |= SSL_OP_NO_TLSv1_1;
1851 if (srv->ssl_ctx.options & SRV_SSL_O_NO_TLSV12)
1852 options |= SSL_OP_NO_TLSv1_2;
Emeric Brunf9c5c472012-10-11 15:28:34 +02001853 if (srv->ssl_ctx.options & SRV_SSL_O_NO_TLS_TICKETS)
1854 options |= SSL_OP_NO_TICKET;
Emeric Brun94324a42012-10-11 14:00:19 +02001855 if (srv->ssl_ctx.options & SRV_SSL_O_USE_SSLV3)
1856 SSL_CTX_set_ssl_version(srv->ssl_ctx.ctx, SSLv3_client_method());
1857 if (srv->ssl_ctx.options & SRV_SSL_O_USE_TLSV10)
1858 SSL_CTX_set_ssl_version(srv->ssl_ctx.ctx, TLSv1_client_method());
1859#if SSL_OP_NO_TLSv1_1
1860 if (srv->ssl_ctx.options & SRV_SSL_O_USE_TLSV11)
1861 SSL_CTX_set_ssl_version(srv->ssl_ctx.ctx, TLSv1_1_client_method());
1862#endif
1863#if SSL_OP_NO_TLSv1_2
1864 if (srv->ssl_ctx.options & SRV_SSL_O_USE_TLSV12)
1865 SSL_CTX_set_ssl_version(srv->ssl_ctx.ctx, TLSv1_2_client_method());
1866#endif
1867
1868 SSL_CTX_set_options(srv->ssl_ctx.ctx, options);
1869 SSL_CTX_set_mode(srv->ssl_ctx.ctx, mode);
Emeric Brun850efd52014-01-29 12:24:34 +01001870
1871 if (global.ssl_server_verify == SSL_SERVER_VERIFY_REQUIRED)
1872 verify = SSL_VERIFY_PEER;
1873
1874 switch (srv->ssl_ctx.verify) {
1875 case SSL_SOCK_VERIFY_NONE:
1876 verify = SSL_VERIFY_NONE;
1877 break;
1878 case SSL_SOCK_VERIFY_REQUIRED:
1879 verify = SSL_VERIFY_PEER;
1880 break;
1881 }
Evan Broderbe554312013-06-27 00:05:25 -07001882 SSL_CTX_set_verify(srv->ssl_ctx.ctx,
Emeric Brun850efd52014-01-29 12:24:34 +01001883 verify,
Evan Broderbe554312013-06-27 00:05:25 -07001884 srv->ssl_ctx.verify_host ? ssl_sock_srv_verifycbk : NULL);
Emeric Brun850efd52014-01-29 12:24:34 +01001885 if (verify & SSL_VERIFY_PEER) {
Emeric Brunef42d922012-10-11 16:11:36 +02001886 if (srv->ssl_ctx.ca_file) {
1887 /* load CAfile to verify */
1888 if (!SSL_CTX_load_verify_locations(srv->ssl_ctx.ctx, srv->ssl_ctx.ca_file, NULL)) {
Willy Tarreau07ba08b2014-02-16 19:22:08 +01001889 Alert("Proxy '%s', server '%s' [%s:%d] unable to load CA file '%s'.\n",
Emeric Brunef42d922012-10-11 16:11:36 +02001890 curproxy->id, srv->id,
1891 srv->conf.file, srv->conf.line, srv->ssl_ctx.ca_file);
1892 cfgerr++;
1893 }
1894 }
Emeric Brun850efd52014-01-29 12:24:34 +01001895 else {
1896 if (global.ssl_server_verify == SSL_SERVER_VERIFY_REQUIRED)
Willy Tarreau07ba08b2014-02-16 19:22:08 +01001897 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 +01001898 curproxy->id, srv->id,
1899 srv->conf.file, srv->conf.line);
1900 else
Willy Tarreau07ba08b2014-02-16 19:22:08 +01001901 Alert("Proxy '%s', server '%s' [%s:%d] verify is enabled but no CA file specified.\n",
Emeric Brun850efd52014-01-29 12:24:34 +01001902 curproxy->id, srv->id,
1903 srv->conf.file, srv->conf.line);
1904 cfgerr++;
1905 }
Emeric Brunef42d922012-10-11 16:11:36 +02001906#ifdef X509_V_FLAG_CRL_CHECK
1907 if (srv->ssl_ctx.crl_file) {
1908 X509_STORE *store = SSL_CTX_get_cert_store(srv->ssl_ctx.ctx);
1909
1910 if (!store || !X509_STORE_load_locations(store, srv->ssl_ctx.crl_file, NULL)) {
Willy Tarreau07ba08b2014-02-16 19:22:08 +01001911 Alert("Proxy '%s', server '%s' [%s:%d] unable to configure CRL file '%s'.\n",
Emeric Brunef42d922012-10-11 16:11:36 +02001912 curproxy->id, srv->id,
1913 srv->conf.file, srv->conf.line, srv->ssl_ctx.crl_file);
1914 cfgerr++;
1915 }
1916 else {
1917 X509_STORE_set_flags(store, X509_V_FLAG_CRL_CHECK|X509_V_FLAG_CRL_CHECK_ALL);
1918 }
1919 }
1920#endif
1921 }
1922
Emeric Brun4f65bff2012-11-16 15:11:00 +01001923 if (global.tune.ssllifetime)
1924 SSL_CTX_set_timeout(srv->ssl_ctx.ctx, global.tune.ssllifetime);
1925
Emeric Brun94324a42012-10-11 14:00:19 +02001926 SSL_CTX_set_session_cache_mode(srv->ssl_ctx.ctx, SSL_SESS_CACHE_OFF);
1927 if (srv->ssl_ctx.ciphers &&
1928 !SSL_CTX_set_cipher_list(srv->ssl_ctx.ctx, srv->ssl_ctx.ciphers)) {
1929 Alert("Proxy '%s', server '%s' [%s:%d] : unable to set SSL cipher list to '%s'.\n",
1930 curproxy->id, srv->id,
1931 srv->conf.file, srv->conf.line, srv->ssl_ctx.ciphers);
1932 cfgerr++;
1933 }
1934
1935 return cfgerr;
1936}
1937
Willy Tarreau2a65ff02012-09-13 17:54:29 +02001938/* Walks down the two trees in bind_conf and prepares all certs. The pointer may
Emeric Brunfc0421f2012-09-07 17:30:07 +02001939 * be NULL, in which case nothing is done. Returns the number of errors
1940 * encountered.
1941 */
Willy Tarreau2a65ff02012-09-13 17:54:29 +02001942int ssl_sock_prepare_all_ctx(struct bind_conf *bind_conf, struct proxy *px)
Emeric Brunfc0421f2012-09-07 17:30:07 +02001943{
1944 struct ebmb_node *node;
1945 struct sni_ctx *sni;
1946 int err = 0;
1947
Willy Tarreau2a65ff02012-09-13 17:54:29 +02001948 if (!bind_conf || !bind_conf->is_ssl)
Emeric Brunfc0421f2012-09-07 17:30:07 +02001949 return 0;
1950
Willy Tarreau2a65ff02012-09-13 17:54:29 +02001951 node = ebmb_first(&bind_conf->sni_ctx);
Emeric Brunfc0421f2012-09-07 17:30:07 +02001952 while (node) {
1953 sni = ebmb_entry(node, struct sni_ctx, name);
1954 if (!sni->order) /* only initialize the CTX on its first occurrence */
Willy Tarreau2a65ff02012-09-13 17:54:29 +02001955 err += ssl_sock_prepare_ctx(bind_conf, sni->ctx, px);
Emeric Brunfc0421f2012-09-07 17:30:07 +02001956 node = ebmb_next(node);
1957 }
1958
Willy Tarreau2a65ff02012-09-13 17:54:29 +02001959 node = ebmb_first(&bind_conf->sni_w_ctx);
Emeric Brunfc0421f2012-09-07 17:30:07 +02001960 while (node) {
1961 sni = ebmb_entry(node, struct sni_ctx, name);
1962 if (!sni->order) /* only initialize the CTX on its first occurrence */
Willy Tarreau2a65ff02012-09-13 17:54:29 +02001963 err += ssl_sock_prepare_ctx(bind_conf, sni->ctx, px);
Emeric Brunfc0421f2012-09-07 17:30:07 +02001964 node = ebmb_next(node);
1965 }
1966 return err;
1967}
1968
Willy Tarreau2a65ff02012-09-13 17:54:29 +02001969/* Walks down the two trees in bind_conf and frees all the certs. The pointer may
Emeric Brunfc0421f2012-09-07 17:30:07 +02001970 * be NULL, in which case nothing is done. The default_ctx is nullified too.
1971 */
Willy Tarreau2a65ff02012-09-13 17:54:29 +02001972void ssl_sock_free_all_ctx(struct bind_conf *bind_conf)
Emeric Brunfc0421f2012-09-07 17:30:07 +02001973{
1974 struct ebmb_node *node, *back;
1975 struct sni_ctx *sni;
1976
Willy Tarreau2a65ff02012-09-13 17:54:29 +02001977 if (!bind_conf || !bind_conf->is_ssl)
Emeric Brunfc0421f2012-09-07 17:30:07 +02001978 return;
1979
Willy Tarreau2a65ff02012-09-13 17:54:29 +02001980 node = ebmb_first(&bind_conf->sni_ctx);
Emeric Brunfc0421f2012-09-07 17:30:07 +02001981 while (node) {
1982 sni = ebmb_entry(node, struct sni_ctx, name);
1983 back = ebmb_next(node);
1984 ebmb_delete(node);
1985 if (!sni->order) /* only free the CTX on its first occurrence */
1986 SSL_CTX_free(sni->ctx);
1987 free(sni);
1988 node = back;
1989 }
1990
Willy Tarreau2a65ff02012-09-13 17:54:29 +02001991 node = ebmb_first(&bind_conf->sni_w_ctx);
Emeric Brunfc0421f2012-09-07 17:30:07 +02001992 while (node) {
1993 sni = ebmb_entry(node, struct sni_ctx, name);
1994 back = ebmb_next(node);
1995 ebmb_delete(node);
1996 if (!sni->order) /* only free the CTX on its first occurrence */
1997 SSL_CTX_free(sni->ctx);
1998 free(sni);
1999 node = back;
2000 }
2001
Willy Tarreau2a65ff02012-09-13 17:54:29 +02002002 bind_conf->default_ctx = NULL;
Emeric Brune1f38db2012-09-03 20:36:47 +02002003}
2004
Emeric Brun46591952012-05-18 15:47:34 +02002005/*
2006 * This function is called if SSL * context is not yet allocated. The function
2007 * is designed to be called before any other data-layer operation and sets the
2008 * handshake flag on the connection. It is safe to call it multiple times.
2009 * It returns 0 on success and -1 in error case.
2010 */
2011static int ssl_sock_init(struct connection *conn)
2012{
2013 /* already initialized */
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02002014 if (conn->xprt_ctx)
Emeric Brun46591952012-05-18 15:47:34 +02002015 return 0;
2016
Willy Tarreau3c728722014-01-23 13:50:42 +01002017 if (!conn_ctrl_ready(conn))
Willy Tarreauf79c8172013-10-21 16:30:56 +02002018 return 0;
2019
Willy Tarreau20879a02012-12-03 16:32:10 +01002020 if (global.maxsslconn && sslconns >= global.maxsslconn) {
2021 conn->err_code = CO_ER_SSL_TOO_MANY;
Willy Tarreau403edff2012-09-06 11:58:37 +02002022 return -1;
Willy Tarreau20879a02012-12-03 16:32:10 +01002023 }
Willy Tarreau403edff2012-09-06 11:58:37 +02002024
Emeric Brun46591952012-05-18 15:47:34 +02002025 /* If it is in client mode initiate SSL session
2026 in connect state otherwise accept state */
Willy Tarreau3fdb3662012-11-12 00:42:33 +01002027 if (objt_server(conn->target)) {
Emeric Brun46591952012-05-18 15:47:34 +02002028 /* Alloc a new SSL session ctx */
Willy Tarreau3fdb3662012-11-12 00:42:33 +01002029 conn->xprt_ctx = SSL_new(objt_server(conn->target)->ssl_ctx.ctx);
Willy Tarreau20879a02012-12-03 16:32:10 +01002030 if (!conn->xprt_ctx) {
2031 conn->err_code = CO_ER_SSL_NO_MEM;
Emeric Brun46591952012-05-18 15:47:34 +02002032 return -1;
Willy Tarreau20879a02012-12-03 16:32:10 +01002033 }
Emeric Brun46591952012-05-18 15:47:34 +02002034
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02002035 SSL_set_connect_state(conn->xprt_ctx);
Willy Tarreau3fdb3662012-11-12 00:42:33 +01002036 if (objt_server(conn->target)->ssl_ctx.reused_sess)
2037 SSL_set_session(conn->xprt_ctx, objt_server(conn->target)->ssl_ctx.reused_sess);
Emeric Brun46591952012-05-18 15:47:34 +02002038
2039 /* set fd on SSL session context */
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02002040 SSL_set_fd(conn->xprt_ctx, conn->t.sock.fd);
Emeric Brun46591952012-05-18 15:47:34 +02002041
Evan Broderbe554312013-06-27 00:05:25 -07002042 /* set connection pointer */
2043 SSL_set_app_data(conn->xprt_ctx, conn);
2044
Emeric Brun46591952012-05-18 15:47:34 +02002045 /* leave init state and start handshake */
Willy Tarreau05737472012-09-04 08:03:39 +02002046 conn->flags |= CO_FL_SSL_WAIT_HS | CO_FL_WAIT_L6_CONN;
Willy Tarreau403edff2012-09-06 11:58:37 +02002047
2048 sslconns++;
Willy Tarreau71b734c2014-01-28 15:19:44 +01002049 totalsslconns++;
Emeric Brun46591952012-05-18 15:47:34 +02002050 return 0;
2051 }
Willy Tarreau3fdb3662012-11-12 00:42:33 +01002052 else if (objt_listener(conn->target)) {
Emeric Brun46591952012-05-18 15:47:34 +02002053 /* Alloc a new SSL session ctx */
Willy Tarreau3fdb3662012-11-12 00:42:33 +01002054 conn->xprt_ctx = SSL_new(objt_listener(conn->target)->bind_conf->default_ctx);
Willy Tarreau20879a02012-12-03 16:32:10 +01002055 if (!conn->xprt_ctx) {
2056 conn->err_code = CO_ER_SSL_NO_MEM;
Emeric Brun46591952012-05-18 15:47:34 +02002057 return -1;
Willy Tarreau20879a02012-12-03 16:32:10 +01002058 }
Emeric Brun46591952012-05-18 15:47:34 +02002059
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02002060 SSL_set_accept_state(conn->xprt_ctx);
Emeric Brun46591952012-05-18 15:47:34 +02002061
2062 /* set fd on SSL session context */
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02002063 SSL_set_fd(conn->xprt_ctx, conn->t.sock.fd);
Emeric Brun46591952012-05-18 15:47:34 +02002064
Emeric Brune1f38db2012-09-03 20:36:47 +02002065 /* set connection pointer */
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02002066 SSL_set_app_data(conn->xprt_ctx, conn);
Emeric Brune1f38db2012-09-03 20:36:47 +02002067
Emeric Brun46591952012-05-18 15:47:34 +02002068 /* leave init state and start handshake */
Willy Tarreau05737472012-09-04 08:03:39 +02002069 conn->flags |= CO_FL_SSL_WAIT_HS | CO_FL_WAIT_L6_CONN;
Willy Tarreau403edff2012-09-06 11:58:37 +02002070
2071 sslconns++;
Willy Tarreau71b734c2014-01-28 15:19:44 +01002072 totalsslconns++;
Emeric Brun46591952012-05-18 15:47:34 +02002073 return 0;
2074 }
2075 /* don't know how to handle such a target */
Willy Tarreau20879a02012-12-03 16:32:10 +01002076 conn->err_code = CO_ER_SSL_NO_TARGET;
Emeric Brun46591952012-05-18 15:47:34 +02002077 return -1;
2078}
2079
2080
2081/* This is the callback which is used when an SSL handshake is pending. It
2082 * updates the FD status if it wants some polling before being called again.
2083 * It returns 0 if it fails in a fatal way or needs to poll to go further,
2084 * otherwise it returns non-zero and removes itself from the connection's
2085 * flags (the bit is provided in <flag> by the caller).
2086 */
2087int ssl_sock_handshake(struct connection *conn, unsigned int flag)
2088{
2089 int ret;
2090
Willy Tarreau3c728722014-01-23 13:50:42 +01002091 if (!conn_ctrl_ready(conn))
Willy Tarreauf79c8172013-10-21 16:30:56 +02002092 return 0;
2093
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02002094 if (!conn->xprt_ctx)
Emeric Brun46591952012-05-18 15:47:34 +02002095 goto out_error;
2096
Emeric Brun674b7432012-11-08 19:21:55 +01002097 /* If we use SSL_do_handshake to process a reneg initiated by
2098 * the remote peer, it sometimes returns SSL_ERROR_SSL.
2099 * Usually SSL_write and SSL_read are used and process implicitly
2100 * the reneg handshake.
2101 * Here we use SSL_peek as a workaround for reneg.
2102 */
2103 if ((conn->flags & CO_FL_CONNECTED) && SSL_renegotiate_pending(conn->xprt_ctx)) {
2104 char c;
2105
2106 ret = SSL_peek(conn->xprt_ctx, &c, 1);
2107 if (ret <= 0) {
2108 /* handshake may have not been completed, let's find why */
2109 ret = SSL_get_error(conn->xprt_ctx, ret);
2110 if (ret == SSL_ERROR_WANT_WRITE) {
2111 /* SSL handshake needs to write, L4 connection may not be ready */
2112 __conn_sock_stop_recv(conn);
Willy Tarreaue1f50c42014-01-22 20:02:06 +01002113 __conn_sock_want_send(conn);
2114 fd_cant_send(conn->t.sock.fd);
Emeric Brun674b7432012-11-08 19:21:55 +01002115 return 0;
2116 }
2117 else if (ret == SSL_ERROR_WANT_READ) {
2118 /* handshake may have been completed but we have
2119 * no more data to read.
2120 */
2121 if (!SSL_renegotiate_pending(conn->xprt_ctx)) {
2122 ret = 1;
2123 goto reneg_ok;
2124 }
2125 /* SSL handshake needs to read, L4 connection is ready */
2126 if (conn->flags & CO_FL_WAIT_L4_CONN)
2127 conn->flags &= ~CO_FL_WAIT_L4_CONN;
2128 __conn_sock_stop_send(conn);
Willy Tarreaue1f50c42014-01-22 20:02:06 +01002129 __conn_sock_want_recv(conn);
2130 fd_cant_recv(conn->t.sock.fd);
Emeric Brun674b7432012-11-08 19:21:55 +01002131 return 0;
2132 }
2133 else if (ret == SSL_ERROR_SYSCALL) {
2134 /* if errno is null, then connection was successfully established */
2135 if (!errno && conn->flags & CO_FL_WAIT_L4_CONN)
2136 conn->flags &= ~CO_FL_WAIT_L4_CONN;
Willy Tarreau20879a02012-12-03 16:32:10 +01002137 if (!conn->err_code) {
Emeric Brun29f037d2014-04-25 19:05:36 +02002138 if (!((SSL *)conn->xprt_ctx)->packet_length) {
2139 if (!errno) {
2140 if (conn->xprt_st & SSL_SOCK_RECV_HEARTBEAT)
2141 conn->err_code = CO_ER_SSL_HANDSHAKE_HB;
2142 else
2143 conn->err_code = CO_ER_SSL_EMPTY;
2144 }
2145 else {
2146 if (conn->xprt_st & SSL_SOCK_RECV_HEARTBEAT)
2147 conn->err_code = CO_ER_SSL_HANDSHAKE_HB;
2148 else
2149 conn->err_code = CO_ER_SSL_ABORT;
2150 }
2151 }
2152 else {
2153 if (conn->xprt_st & SSL_SOCK_RECV_HEARTBEAT)
2154 conn->err_code = CO_ER_SSL_HANDSHAKE_HB;
Willy Tarreau20879a02012-12-03 16:32:10 +01002155 else
Emeric Brun29f037d2014-04-25 19:05:36 +02002156 conn->err_code = CO_ER_SSL_HANDSHAKE;
2157 }
Willy Tarreau20879a02012-12-03 16:32:10 +01002158 }
Emeric Brun674b7432012-11-08 19:21:55 +01002159 goto out_error;
2160 }
2161 else {
2162 /* Fail on all other handshake errors */
2163 /* Note: OpenSSL may leave unread bytes in the socket's
2164 * buffer, causing an RST to be emitted upon close() on
2165 * TCP sockets. We first try to drain possibly pending
2166 * data to avoid this as much as possible.
2167 */
Willy Tarreau46be2e52014-01-20 12:10:52 +01002168 conn_drain(conn);
Willy Tarreau20879a02012-12-03 16:32:10 +01002169 if (!conn->err_code)
Willy Tarreauf51c6982014-04-25 20:02:39 +02002170 conn->err_code = (conn->xprt_st & SSL_SOCK_RECV_HEARTBEAT) ?
2171 CO_ER_SSL_KILLED_HB : CO_ER_SSL_HANDSHAKE;
Emeric Brun674b7432012-11-08 19:21:55 +01002172 goto out_error;
2173 }
2174 }
2175 /* read some data: consider handshake completed */
2176 goto reneg_ok;
2177 }
2178
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02002179 ret = SSL_do_handshake(conn->xprt_ctx);
Emeric Brun46591952012-05-18 15:47:34 +02002180 if (ret != 1) {
2181 /* handshake did not complete, let's find why */
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02002182 ret = SSL_get_error(conn->xprt_ctx, ret);
Emeric Brun46591952012-05-18 15:47:34 +02002183
2184 if (ret == SSL_ERROR_WANT_WRITE) {
2185 /* SSL handshake needs to write, L4 connection may not be ready */
2186 __conn_sock_stop_recv(conn);
Willy Tarreaue1f50c42014-01-22 20:02:06 +01002187 __conn_sock_want_send(conn);
2188 fd_cant_send(conn->t.sock.fd);
Emeric Brun46591952012-05-18 15:47:34 +02002189 return 0;
2190 }
2191 else if (ret == SSL_ERROR_WANT_READ) {
2192 /* SSL handshake needs to read, L4 connection is ready */
2193 if (conn->flags & CO_FL_WAIT_L4_CONN)
2194 conn->flags &= ~CO_FL_WAIT_L4_CONN;
2195 __conn_sock_stop_send(conn);
Willy Tarreaue1f50c42014-01-22 20:02:06 +01002196 __conn_sock_want_recv(conn);
2197 fd_cant_recv(conn->t.sock.fd);
Emeric Brun46591952012-05-18 15:47:34 +02002198 return 0;
2199 }
Willy Tarreau89230192012-09-28 20:22:13 +02002200 else if (ret == SSL_ERROR_SYSCALL) {
2201 /* if errno is null, then connection was successfully established */
2202 if (!errno && conn->flags & CO_FL_WAIT_L4_CONN)
2203 conn->flags &= ~CO_FL_WAIT_L4_CONN;
Willy Tarreau20879a02012-12-03 16:32:10 +01002204
Emeric Brun29f037d2014-04-25 19:05:36 +02002205 if (!((SSL *)conn->xprt_ctx)->packet_length) {
2206 if (!errno) {
2207 if (conn->xprt_st & SSL_SOCK_RECV_HEARTBEAT)
2208 conn->err_code = CO_ER_SSL_HANDSHAKE_HB;
2209 else
2210 conn->err_code = CO_ER_SSL_EMPTY;
2211 }
2212 else {
2213 if (conn->xprt_st & SSL_SOCK_RECV_HEARTBEAT)
2214 conn->err_code = CO_ER_SSL_HANDSHAKE_HB;
2215 else
2216 conn->err_code = CO_ER_SSL_ABORT;
2217 }
2218 }
2219 else {
2220 if (conn->xprt_st & SSL_SOCK_RECV_HEARTBEAT)
2221 conn->err_code = CO_ER_SSL_HANDSHAKE_HB;
Willy Tarreau20879a02012-12-03 16:32:10 +01002222 else
Emeric Brun29f037d2014-04-25 19:05:36 +02002223 conn->err_code = CO_ER_SSL_HANDSHAKE;
2224 }
Willy Tarreau89230192012-09-28 20:22:13 +02002225 goto out_error;
2226 }
Emeric Brun46591952012-05-18 15:47:34 +02002227 else {
2228 /* Fail on all other handshake errors */
Willy Tarreau566dc552012-10-19 20:52:18 +02002229 /* Note: OpenSSL may leave unread bytes in the socket's
2230 * buffer, causing an RST to be emitted upon close() on
2231 * TCP sockets. We first try to drain possibly pending
2232 * data to avoid this as much as possible.
2233 */
Willy Tarreau46be2e52014-01-20 12:10:52 +01002234 conn_drain(conn);
Willy Tarreau20879a02012-12-03 16:32:10 +01002235 if (!conn->err_code)
Willy Tarreauf51c6982014-04-25 20:02:39 +02002236 conn->err_code = (conn->xprt_st & SSL_SOCK_RECV_HEARTBEAT) ?
2237 CO_ER_SSL_KILLED_HB : CO_ER_SSL_HANDSHAKE;
Emeric Brun46591952012-05-18 15:47:34 +02002238 goto out_error;
2239 }
2240 }
2241
Emeric Brun674b7432012-11-08 19:21:55 +01002242reneg_ok:
2243
Emeric Brun46591952012-05-18 15:47:34 +02002244 /* Handshake succeeded */
Willy Tarreau0c9c2722014-05-28 12:28:58 +02002245 if (!SSL_session_reused(conn->xprt_ctx)) {
2246 if (objt_server(conn->target)) {
2247 update_freq_ctr(&global.ssl_be_keys_per_sec, 1);
2248 if (global.ssl_be_keys_per_sec.curr_ctr > global.ssl_be_keys_max)
2249 global.ssl_be_keys_max = global.ssl_be_keys_per_sec.curr_ctr;
2250
Emeric Brun46591952012-05-18 15:47:34 +02002251 /* check if session was reused, if not store current session on server for reuse */
Willy Tarreau3fdb3662012-11-12 00:42:33 +01002252 if (objt_server(conn->target)->ssl_ctx.reused_sess)
2253 SSL_SESSION_free(objt_server(conn->target)->ssl_ctx.reused_sess);
Emeric Brun46591952012-05-18 15:47:34 +02002254
Willy Tarreau3fdb3662012-11-12 00:42:33 +01002255 objt_server(conn->target)->ssl_ctx.reused_sess = SSL_get1_session(conn->xprt_ctx);
Emeric Brun46591952012-05-18 15:47:34 +02002256 }
Willy Tarreau0c9c2722014-05-28 12:28:58 +02002257 else {
2258 update_freq_ctr(&global.ssl_fe_keys_per_sec, 1);
2259 if (global.ssl_fe_keys_per_sec.curr_ctr > global.ssl_fe_keys_max)
2260 global.ssl_fe_keys_max = global.ssl_fe_keys_per_sec.curr_ctr;
2261 }
Emeric Brun46591952012-05-18 15:47:34 +02002262 }
2263
2264 /* The connection is now established at both layers, it's time to leave */
2265 conn->flags &= ~(flag | CO_FL_WAIT_L4_CONN | CO_FL_WAIT_L6_CONN);
2266 return 1;
2267
2268 out_error:
Emeric Brun644cde02012-12-14 11:21:13 +01002269 /* Clear openssl global errors stack */
2270 ERR_clear_error();
2271
Emeric Brun9fa89732012-10-04 17:09:56 +02002272 /* free resumed session if exists */
Willy Tarreau3fdb3662012-11-12 00:42:33 +01002273 if (objt_server(conn->target) && objt_server(conn->target)->ssl_ctx.reused_sess) {
2274 SSL_SESSION_free(objt_server(conn->target)->ssl_ctx.reused_sess);
2275 objt_server(conn->target)->ssl_ctx.reused_sess = NULL;
Emeric Brun9fa89732012-10-04 17:09:56 +02002276 }
2277
Emeric Brun46591952012-05-18 15:47:34 +02002278 /* Fail on all other handshake errors */
2279 conn->flags |= CO_FL_ERROR;
Willy Tarreau20879a02012-12-03 16:32:10 +01002280 if (!conn->err_code)
2281 conn->err_code = CO_ER_SSL_HANDSHAKE;
Emeric Brun46591952012-05-18 15:47:34 +02002282 return 0;
2283}
2284
2285/* Receive up to <count> bytes from connection <conn>'s socket and store them
Willy Tarreauabf08d92014-01-14 11:31:27 +01002286 * into buffer <buf>. Only one call to recv() is performed, unless the
Emeric Brun46591952012-05-18 15:47:34 +02002287 * buffer wraps, in which case a second call may be performed. The connection's
2288 * flags are updated with whatever special event is detected (error, read0,
2289 * empty). The caller is responsible for taking care of those events and
2290 * avoiding the call if inappropriate. The function does not call the
2291 * connection's polling update function, so the caller is responsible for this.
2292 */
2293static int ssl_sock_to_buf(struct connection *conn, struct buffer *buf, int count)
2294{
2295 int ret, done = 0;
Willy Tarreauabf08d92014-01-14 11:31:27 +01002296 int try;
Emeric Brun46591952012-05-18 15:47:34 +02002297
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02002298 if (!conn->xprt_ctx)
Emeric Brun46591952012-05-18 15:47:34 +02002299 goto out_error;
2300
2301 if (conn->flags & CO_FL_HANDSHAKE)
2302 /* a handshake was requested */
2303 return 0;
2304
Willy Tarreauabf08d92014-01-14 11:31:27 +01002305 /* let's realign the buffer to optimize I/O */
2306 if (buffer_empty(buf))
Emeric Brun46591952012-05-18 15:47:34 +02002307 buf->p = buf->data;
Emeric Brun46591952012-05-18 15:47:34 +02002308
2309 /* read the largest possible block. For this, we perform only one call
2310 * to recv() unless the buffer wraps and we exactly fill the first hunk,
2311 * in which case we accept to do it once again. A new attempt is made on
2312 * EINTR too.
2313 */
Willy Tarreau00b0fb92014-01-17 11:09:40 +01002314 while (count > 0) {
Willy Tarreauabf08d92014-01-14 11:31:27 +01002315 /* first check if we have some room after p+i */
2316 try = buf->data + buf->size - (buf->p + buf->i);
2317 /* otherwise continue between data and p-o */
2318 if (try <= 0) {
2319 try = buf->p - (buf->data + buf->o);
2320 if (try <= 0)
2321 break;
2322 }
2323 if (try > count)
2324 try = count;
2325
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02002326 ret = SSL_read(conn->xprt_ctx, bi_end(buf), try);
Emeric Brune1f38db2012-09-03 20:36:47 +02002327 if (conn->flags & CO_FL_ERROR) {
2328 /* CO_FL_ERROR may be set by ssl_sock_infocbk */
Emeric Brun644cde02012-12-14 11:21:13 +01002329 goto out_error;
Emeric Brune1f38db2012-09-03 20:36:47 +02002330 }
Emeric Brun46591952012-05-18 15:47:34 +02002331 if (ret > 0) {
2332 buf->i += ret;
2333 done += ret;
2334 if (ret < try)
2335 break;
2336 count -= ret;
Emeric Brun46591952012-05-18 15:47:34 +02002337 }
2338 else if (ret == 0) {
Emeric Brun644cde02012-12-14 11:21:13 +01002339 ret = SSL_get_error(conn->xprt_ctx, ret);
2340 if (ret != SSL_ERROR_ZERO_RETURN) {
Emeric Brun1c646862012-12-14 12:33:41 +01002341 /* error on protocol or underlying transport */
2342 if ((ret != SSL_ERROR_SYSCALL)
2343 || (errno && (errno != EAGAIN)))
2344 conn->flags |= CO_FL_ERROR;
2345
Emeric Brun644cde02012-12-14 11:21:13 +01002346 /* Clear openssl global errors stack */
2347 ERR_clear_error();
2348 }
Emeric Brun46591952012-05-18 15:47:34 +02002349 goto read0;
2350 }
2351 else {
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02002352 ret = SSL_get_error(conn->xprt_ctx, ret);
Emeric Brun46591952012-05-18 15:47:34 +02002353 if (ret == SSL_ERROR_WANT_WRITE) {
Emeric Brun8af8dd12012-11-08 17:56:20 +01002354 /* handshake is running, and it needs to enable write */
Emeric Brun46591952012-05-18 15:47:34 +02002355 conn->flags |= CO_FL_SSL_WAIT_HS;
Emeric Brun8af8dd12012-11-08 17:56:20 +01002356 __conn_sock_want_send(conn);
Emeric Brun46591952012-05-18 15:47:34 +02002357 break;
2358 }
2359 else if (ret == SSL_ERROR_WANT_READ) {
Emeric Brun282a76a2012-11-08 18:02:56 +01002360 if (SSL_renegotiate_pending(conn->xprt_ctx)) {
2361 /* handshake is running, and it may need to re-enable read */
2362 conn->flags |= CO_FL_SSL_WAIT_HS;
2363 __conn_sock_want_recv(conn);
2364 break;
2365 }
Emeric Brun46591952012-05-18 15:47:34 +02002366 /* we need to poll for retry a read later */
Willy Tarreaue1f50c42014-01-22 20:02:06 +01002367 fd_cant_recv(conn->t.sock.fd);
Emeric Brun46591952012-05-18 15:47:34 +02002368 break;
2369 }
2370 /* otherwise it's a real error */
2371 goto out_error;
2372 }
2373 }
2374 return done;
2375
2376 read0:
2377 conn_sock_read0(conn);
2378 return done;
2379 out_error:
Emeric Brun644cde02012-12-14 11:21:13 +01002380 /* Clear openssl global errors stack */
2381 ERR_clear_error();
2382
Emeric Brun46591952012-05-18 15:47:34 +02002383 conn->flags |= CO_FL_ERROR;
2384 return done;
2385}
2386
2387
2388/* Send all pending bytes from buffer <buf> to connection <conn>'s socket.
Willy Tarreau1049b1f2014-02-02 01:51:17 +01002389 * <flags> may contain some CO_SFL_* flags to hint the system about other
2390 * pending data for example, but this flag is ignored at the moment.
Emeric Brun46591952012-05-18 15:47:34 +02002391 * Only one call to send() is performed, unless the buffer wraps, in which case
2392 * a second call may be performed. The connection's flags are updated with
2393 * whatever special event is detected (error, empty). The caller is responsible
2394 * for taking care of those events and avoiding the call if inappropriate. The
2395 * function does not call the connection's polling update function, so the caller
2396 * is responsible for this.
2397 */
2398static int ssl_sock_from_buf(struct connection *conn, struct buffer *buf, int flags)
2399{
2400 int ret, try, done;
2401
2402 done = 0;
2403
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02002404 if (!conn->xprt_ctx)
Emeric Brun46591952012-05-18 15:47:34 +02002405 goto out_error;
2406
2407 if (conn->flags & CO_FL_HANDSHAKE)
2408 /* a handshake was requested */
2409 return 0;
2410
2411 /* send the largest possible block. For this we perform only one call
2412 * to send() unless the buffer wraps and we exactly fill the first hunk,
2413 * in which case we accept to do it once again.
2414 */
2415 while (buf->o) {
Kevin Hestercad82342013-05-30 15:12:41 -07002416 try = bo_contig_data(buf);
Willy Tarreaubfd59462013-02-21 07:46:09 +01002417
Willy Tarreau7bed9452014-02-02 02:00:24 +01002418 if (!(flags & CO_SFL_STREAMER) &&
Willy Tarreau518cedd2014-02-17 15:43:01 +01002419 !(conn->xprt_st & SSL_SOCK_SEND_UNLIMITED) &&
2420 global.tune.ssl_max_record && try > global.tune.ssl_max_record) {
Willy Tarreaubfd59462013-02-21 07:46:09 +01002421 try = global.tune.ssl_max_record;
Willy Tarreau518cedd2014-02-17 15:43:01 +01002422 }
2423 else {
2424 /* we need to keep the information about the fact that
2425 * we're not limiting the upcoming send(), because if it
2426 * fails, we'll have to retry with at least as many data.
2427 */
2428 conn->xprt_st |= SSL_SOCK_SEND_UNLIMITED;
2429 }
Willy Tarreaubfd59462013-02-21 07:46:09 +01002430
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02002431 ret = SSL_write(conn->xprt_ctx, bo_ptr(buf), try);
Willy Tarreau518cedd2014-02-17 15:43:01 +01002432
Emeric Brune1f38db2012-09-03 20:36:47 +02002433 if (conn->flags & CO_FL_ERROR) {
2434 /* CO_FL_ERROR may be set by ssl_sock_infocbk */
Emeric Brun644cde02012-12-14 11:21:13 +01002435 goto out_error;
Emeric Brune1f38db2012-09-03 20:36:47 +02002436 }
Emeric Brun46591952012-05-18 15:47:34 +02002437 if (ret > 0) {
Willy Tarreau518cedd2014-02-17 15:43:01 +01002438 conn->xprt_st &= ~SSL_SOCK_SEND_UNLIMITED;
2439
Emeric Brun46591952012-05-18 15:47:34 +02002440 buf->o -= ret;
2441 done += ret;
2442
Willy Tarreau5fb38032012-12-16 19:39:09 +01002443 if (likely(buffer_empty(buf)))
Emeric Brun46591952012-05-18 15:47:34 +02002444 /* optimize data alignment in the buffer */
2445 buf->p = buf->data;
2446
2447 /* if the system buffer is full, don't insist */
2448 if (ret < try)
2449 break;
2450 }
2451 else {
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02002452 ret = SSL_get_error(conn->xprt_ctx, ret);
Emeric Brun46591952012-05-18 15:47:34 +02002453 if (ret == SSL_ERROR_WANT_WRITE) {
Emeric Brun282a76a2012-11-08 18:02:56 +01002454 if (SSL_renegotiate_pending(conn->xprt_ctx)) {
2455 /* handshake is running, and it may need to re-enable write */
2456 conn->flags |= CO_FL_SSL_WAIT_HS;
2457 __conn_sock_want_send(conn);
2458 break;
2459 }
Emeric Brun46591952012-05-18 15:47:34 +02002460 /* we need to poll to retry a write later */
Willy Tarreaue1f50c42014-01-22 20:02:06 +01002461 fd_cant_send(conn->t.sock.fd);
Emeric Brun46591952012-05-18 15:47:34 +02002462 break;
2463 }
2464 else if (ret == SSL_ERROR_WANT_READ) {
Emeric Brun8af8dd12012-11-08 17:56:20 +01002465 /* handshake is running, and it needs to enable read */
Emeric Brun46591952012-05-18 15:47:34 +02002466 conn->flags |= CO_FL_SSL_WAIT_HS;
Emeric Brun8af8dd12012-11-08 17:56:20 +01002467 __conn_sock_want_recv(conn);
Emeric Brun46591952012-05-18 15:47:34 +02002468 break;
2469 }
2470 goto out_error;
2471 }
2472 }
2473 return done;
2474
2475 out_error:
Emeric Brun644cde02012-12-14 11:21:13 +01002476 /* Clear openssl global errors stack */
2477 ERR_clear_error();
2478
Emeric Brun46591952012-05-18 15:47:34 +02002479 conn->flags |= CO_FL_ERROR;
2480 return done;
2481}
2482
Emeric Brun46591952012-05-18 15:47:34 +02002483static void ssl_sock_close(struct connection *conn) {
2484
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02002485 if (conn->xprt_ctx) {
2486 SSL_free(conn->xprt_ctx);
2487 conn->xprt_ctx = NULL;
Willy Tarreau403edff2012-09-06 11:58:37 +02002488 sslconns--;
Emeric Brun46591952012-05-18 15:47:34 +02002489 }
Emeric Brun46591952012-05-18 15:47:34 +02002490}
2491
2492/* This function tries to perform a clean shutdown on an SSL connection, and in
2493 * any case, flags the connection as reusable if no handshake was in progress.
2494 */
2495static void ssl_sock_shutw(struct connection *conn, int clean)
2496{
2497 if (conn->flags & CO_FL_HANDSHAKE)
2498 return;
2499 /* no handshake was in progress, try a clean ssl shutdown */
Emeric Brun644cde02012-12-14 11:21:13 +01002500 if (clean && (SSL_shutdown(conn->xprt_ctx) <= 0)) {
2501 /* Clear openssl global errors stack */
2502 ERR_clear_error();
2503 }
Emeric Brun46591952012-05-18 15:47:34 +02002504
2505 /* force flag on ssl to keep session in cache regardless shutdown result */
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02002506 SSL_set_shutdown(conn->xprt_ctx, SSL_SENT_SHUTDOWN);
Emeric Brun46591952012-05-18 15:47:34 +02002507}
2508
Willy Tarreauffc3fcd2012-10-12 20:17:54 +02002509/* used for logging, may be changed for a sample fetch later */
2510const char *ssl_sock_get_cipher_name(struct connection *conn)
2511{
2512 if (!conn->xprt && !conn->xprt_ctx)
2513 return NULL;
2514 return SSL_get_cipher_name(conn->xprt_ctx);
2515}
2516
2517/* used for logging, may be changed for a sample fetch later */
2518const char *ssl_sock_get_proto_version(struct connection *conn)
2519{
2520 if (!conn->xprt && !conn->xprt_ctx)
2521 return NULL;
2522 return SSL_get_version(conn->xprt_ctx);
2523}
2524
Willy Tarreau8d598402012-10-22 17:58:39 +02002525/* Extract a serial from a cert, and copy it to a chunk.
2526 * Returns 1 if serial is found and copied, 0 if no serial found and
2527 * -1 if output is not large enough.
2528 */
2529static int
2530ssl_sock_get_serial(X509 *crt, struct chunk *out)
2531{
2532 ASN1_INTEGER *serial;
2533
2534 serial = X509_get_serialNumber(crt);
2535 if (!serial)
2536 return 0;
2537
2538 if (out->size < serial->length)
2539 return -1;
2540
2541 memcpy(out->str, serial->data, serial->length);
2542 out->len = serial->length;
2543 return 1;
2544}
2545
Emeric Brunce5ad802012-10-22 14:11:22 +02002546
2547/* Copy Date in ASN1_UTCTIME format in struct chunk out.
2548 * Returns 1 if serial is found and copied, 0 if no valid time found
2549 * and -1 if output is not large enough.
2550 */
2551static int
2552ssl_sock_get_time(ASN1_TIME *tm, struct chunk *out)
2553{
2554 if (tm->type == V_ASN1_GENERALIZEDTIME) {
2555 ASN1_GENERALIZEDTIME *gentm = (ASN1_GENERALIZEDTIME *)tm;
2556
2557 if (gentm->length < 12)
2558 return 0;
2559 if (gentm->data[0] != 0x32 || gentm->data[1] != 0x30)
2560 return 0;
2561 if (out->size < gentm->length-2)
2562 return -1;
2563
2564 memcpy(out->str, gentm->data+2, gentm->length-2);
2565 out->len = gentm->length-2;
2566 return 1;
2567 }
2568 else if (tm->type == V_ASN1_UTCTIME) {
2569 ASN1_UTCTIME *utctm = (ASN1_UTCTIME *)tm;
2570
2571 if (utctm->length < 10)
2572 return 0;
2573 if (utctm->data[0] >= 0x35)
2574 return 0;
2575 if (out->size < utctm->length)
2576 return -1;
2577
2578 memcpy(out->str, utctm->data, utctm->length);
2579 out->len = utctm->length;
2580 return 1;
2581 }
2582
2583 return 0;
2584}
2585
Emeric Brun87855892012-10-17 17:39:35 +02002586/* Extract an entry from a X509_NAME and copy its value to an output chunk.
2587 * Returns 1 if entry found, 0 if entry not found, or -1 if output not large enough.
2588 */
2589static int
2590ssl_sock_get_dn_entry(X509_NAME *a, const struct chunk *entry, int pos, struct chunk *out)
2591{
2592 X509_NAME_ENTRY *ne;
2593 int i, j, n;
2594 int cur = 0;
2595 const char *s;
2596 char tmp[128];
2597
2598 out->len = 0;
2599 for (i = 0; i < sk_X509_NAME_ENTRY_num(a->entries); i++) {
2600 if (pos < 0)
2601 j = (sk_X509_NAME_ENTRY_num(a->entries)-1) - i;
2602 else
2603 j = i;
2604
2605 ne = sk_X509_NAME_ENTRY_value(a->entries, j);
2606 n = OBJ_obj2nid(ne->object);
2607 if ((n == NID_undef) || ((s = OBJ_nid2sn(n)) == NULL)) {
2608 i2t_ASN1_OBJECT(tmp, sizeof(tmp), ne->object);
2609 s = tmp;
2610 }
2611
2612 if (chunk_strcasecmp(entry, s) != 0)
2613 continue;
2614
2615 if (pos < 0)
2616 cur--;
2617 else
2618 cur++;
2619
2620 if (cur != pos)
2621 continue;
2622
2623 if (ne->value->length > out->size)
2624 return -1;
2625
2626 memcpy(out->str, ne->value->data, ne->value->length);
2627 out->len = ne->value->length;
2628 return 1;
2629 }
2630
2631 return 0;
2632
2633}
2634
2635/* Extract and format full DN from a X509_NAME and copy result into a chunk
2636 * Returns 1 if dn entries exits, 0 if no dn entry found or -1 if output is not large enough.
2637 */
2638static int
2639ssl_sock_get_dn_oneline(X509_NAME *a, struct chunk *out)
2640{
2641 X509_NAME_ENTRY *ne;
2642 int i, n, ln;
2643 int l = 0;
2644 const char *s;
2645 char *p;
2646 char tmp[128];
2647
2648 out->len = 0;
2649 p = out->str;
2650 for (i = 0; i < sk_X509_NAME_ENTRY_num(a->entries); i++) {
2651 ne = sk_X509_NAME_ENTRY_value(a->entries, i);
2652 n = OBJ_obj2nid(ne->object);
2653 if ((n == NID_undef) || ((s = OBJ_nid2sn(n)) == NULL)) {
2654 i2t_ASN1_OBJECT(tmp, sizeof(tmp), ne->object);
2655 s = tmp;
2656 }
2657 ln = strlen(s);
2658
2659 l += 1 + ln + 1 + ne->value->length;
2660 if (l > out->size)
2661 return -1;
2662 out->len = l;
2663
2664 *(p++)='/';
2665 memcpy(p, s, ln);
2666 p += ln;
2667 *(p++)='=';
2668 memcpy(p, ne->value->data, ne->value->length);
2669 p += ne->value->length;
2670 }
2671
2672 if (!out->len)
2673 return 0;
2674
2675 return 1;
2676}
2677
David Safb76832014-05-08 23:42:08 -04002678char *ssl_sock_get_version(struct connection *conn)
2679{
2680 if (!ssl_sock_is_ssl(conn))
2681 return NULL;
2682
2683 return (char *)SSL_get_version(conn->xprt_ctx);
2684}
2685
Emeric Brun49100982014-06-24 18:26:41 +02002686/* Extract peer certificate's common name into the chunk dest
2687 * Returns
2688 * the len of the extracted common name
2689 * or 0 if no CN found in DN
2690 * or -1 on error case (i.e. no peer certificate)
2691 */
2692int ssl_sock_get_remote_common_name(struct connection *conn, struct chunk *dest)
David Safb76832014-05-08 23:42:08 -04002693{
2694 X509 *crt = NULL;
2695 X509_NAME *name;
David Safb76832014-05-08 23:42:08 -04002696 const char find_cn[] = "CN";
2697 const struct chunk find_cn_chunk = {
2698 .str = (char *)&find_cn,
2699 .len = sizeof(find_cn)-1
2700 };
Emeric Brun49100982014-06-24 18:26:41 +02002701 int result = -1;
David Safb76832014-05-08 23:42:08 -04002702
2703 if (!ssl_sock_is_ssl(conn))
Emeric Brun49100982014-06-24 18:26:41 +02002704 goto out;
David Safb76832014-05-08 23:42:08 -04002705
2706 /* SSL_get_peer_certificate, it increase X509 * ref count */
2707 crt = SSL_get_peer_certificate(conn->xprt_ctx);
2708 if (!crt)
2709 goto out;
2710
2711 name = X509_get_subject_name(crt);
2712 if (!name)
2713 goto out;
David Safb76832014-05-08 23:42:08 -04002714
Emeric Brun49100982014-06-24 18:26:41 +02002715 result = ssl_sock_get_dn_entry(name, &find_cn_chunk, 1, dest);
2716out:
David Safb76832014-05-08 23:42:08 -04002717 if (crt)
2718 X509_free(crt);
2719
2720 return result;
2721}
2722
Dave McCowand6ec6052014-07-30 10:39:13 -04002723/* returns 1 if client passed a certificate for this session, 0 if not */
2724int ssl_sock_get_cert_used_sess(struct connection *conn)
2725{
2726 X509 *crt = NULL;
2727
2728 if (!ssl_sock_is_ssl(conn))
2729 return 0;
2730
2731 /* SSL_get_peer_certificate, it increase X509 * ref count */
2732 crt = SSL_get_peer_certificate(conn->xprt_ctx);
2733 if (!crt)
2734 return 0;
2735
2736 X509_free(crt);
2737 return 1;
2738}
2739
2740/* returns 1 if client passed a certificate for this connection, 0 if not */
2741int ssl_sock_get_cert_used_conn(struct connection *conn)
David Safb76832014-05-08 23:42:08 -04002742{
2743 if (!ssl_sock_is_ssl(conn))
2744 return 0;
2745
2746 return SSL_SOCK_ST_FL_VERIFY_DONE & conn->xprt_st ? 1 : 0;
2747}
2748
2749/* returns result from SSL verify */
2750unsigned int ssl_sock_get_verify_result(struct connection *conn)
2751{
2752 if (!ssl_sock_is_ssl(conn))
2753 return (unsigned int)X509_V_ERR_APPLICATION_VERIFICATION;
2754
2755 return (unsigned int)SSL_get_verify_result(conn->xprt_ctx);
2756}
2757
Willy Tarreau7875d092012-09-10 08:20:03 +02002758/***** Below are some sample fetching functions for ACL/patterns *****/
2759
Emeric Brune64aef12012-09-21 13:15:06 +02002760/* boolean, returns true if client cert was present */
2761static int
Emeric Brun2525b6b2012-10-18 15:59:43 +02002762smp_fetch_ssl_fc_has_crt(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
Willy Tarreauef38c392013-07-22 16:29:32 +02002763 const struct arg *args, struct sample *smp, const char *kw)
Emeric Brune64aef12012-09-21 13:15:06 +02002764{
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002765 struct connection *conn;
2766
2767 if (!l4)
2768 return 0;
2769
2770 conn = objt_conn(l4->si[0].end);
2771 if (!conn || conn->xprt != &ssl_sock)
Emeric Brune64aef12012-09-21 13:15:06 +02002772 return 0;
2773
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002774 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brune64aef12012-09-21 13:15:06 +02002775 smp->flags |= SMP_F_MAY_CHANGE;
2776 return 0;
2777 }
2778
2779 smp->flags = 0;
2780 smp->type = SMP_T_BOOL;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002781 smp->data.uint = SSL_SOCK_ST_FL_VERIFY_DONE & conn->xprt_st ? 1 : 0;
Emeric Brune64aef12012-09-21 13:15:06 +02002782
2783 return 1;
2784}
2785
Emeric Brunba841a12014-04-30 17:05:08 +02002786/* binary, returns serial of certificate in a binary chunk.
2787 * The 5th keyword char is used to know if SSL_get_certificate or SSL_get_peer_certificate
2788 * should be use.
2789 */
Willy Tarreau8d598402012-10-22 17:58:39 +02002790static int
Emeric Brunba841a12014-04-30 17:05:08 +02002791smp_fetch_ssl_x_serial(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
Willy Tarreauef38c392013-07-22 16:29:32 +02002792 const struct arg *args, struct sample *smp, const char *kw)
Willy Tarreau8d598402012-10-22 17:58:39 +02002793{
Emeric Brunba841a12014-04-30 17:05:08 +02002794 int cert_peer = (kw[4] == 'c') ? 1 : 0;
Willy Tarreau8d598402012-10-22 17:58:39 +02002795 X509 *crt = NULL;
2796 int ret = 0;
2797 struct chunk *smp_trash;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002798 struct connection *conn;
2799
2800 if (!l4)
2801 return 0;
Willy Tarreau8d598402012-10-22 17:58:39 +02002802
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002803 conn = objt_conn(l4->si[0].end);
2804 if (!conn || conn->xprt != &ssl_sock)
Willy Tarreau8d598402012-10-22 17:58:39 +02002805 return 0;
2806
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002807 if (!(conn->flags & CO_FL_CONNECTED)) {
Willy Tarreau8d598402012-10-22 17:58:39 +02002808 smp->flags |= SMP_F_MAY_CHANGE;
2809 return 0;
2810 }
2811
Emeric Brunba841a12014-04-30 17:05:08 +02002812 if (cert_peer)
2813 crt = SSL_get_peer_certificate(conn->xprt_ctx);
2814 else
2815 crt = SSL_get_certificate(conn->xprt_ctx);
2816
Willy Tarreau8d598402012-10-22 17:58:39 +02002817 if (!crt)
2818 goto out;
2819
Willy Tarreau47ca5452012-12-23 20:22:19 +01002820 smp_trash = get_trash_chunk();
Willy Tarreau8d598402012-10-22 17:58:39 +02002821 if (ssl_sock_get_serial(crt, smp_trash) <= 0)
2822 goto out;
2823
2824 smp->data.str = *smp_trash;
2825 smp->type = SMP_T_BIN;
2826 ret = 1;
2827out:
Emeric Brunba841a12014-04-30 17:05:08 +02002828 /* SSL_get_peer_certificate, it increase X509 * ref count */
2829 if (cert_peer && crt)
Willy Tarreau8d598402012-10-22 17:58:39 +02002830 X509_free(crt);
2831 return ret;
2832}
Emeric Brune64aef12012-09-21 13:15:06 +02002833
Emeric Brunba841a12014-04-30 17:05:08 +02002834/* binary, returns the client certificate's SHA-1 fingerprint (SHA-1 hash of DER-encoded certificate) in a binary chunk.
2835 * The 5th keyword char is used to know if SSL_get_certificate or SSL_get_peer_certificate
2836 * should be use.
2837 */
James Votha051b4a2013-05-14 20:37:59 +02002838static int
Emeric Brunba841a12014-04-30 17:05:08 +02002839smp_fetch_ssl_x_sha1(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
Willy Tarreauef38c392013-07-22 16:29:32 +02002840 const struct arg *args, struct sample *smp, const char *kw)
James Votha051b4a2013-05-14 20:37:59 +02002841{
Emeric Brunba841a12014-04-30 17:05:08 +02002842 int cert_peer = (kw[4] == 'c') ? 1 : 0;
James Votha051b4a2013-05-14 20:37:59 +02002843 X509 *crt = NULL;
2844 const EVP_MD *digest;
2845 int ret = 0;
2846 struct chunk *smp_trash;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002847 struct connection *conn;
James Votha051b4a2013-05-14 20:37:59 +02002848
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002849 if (!l4)
James Votha051b4a2013-05-14 20:37:59 +02002850 return 0;
2851
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002852 conn = objt_conn(l4->si[0].end);
2853 if (!conn || conn->xprt != &ssl_sock)
2854 return 0;
2855
2856 if (!(conn->flags & CO_FL_CONNECTED)) {
James Votha051b4a2013-05-14 20:37:59 +02002857 smp->flags |= SMP_F_MAY_CHANGE;
2858 return 0;
2859 }
2860
Emeric Brunba841a12014-04-30 17:05:08 +02002861 if (cert_peer)
2862 crt = SSL_get_peer_certificate(conn->xprt_ctx);
2863 else
2864 crt = SSL_get_certificate(conn->xprt_ctx);
James Votha051b4a2013-05-14 20:37:59 +02002865 if (!crt)
2866 goto out;
2867
2868 smp_trash = get_trash_chunk();
2869 digest = EVP_sha1();
2870 X509_digest(crt, digest, (unsigned char *)smp_trash->str, (unsigned int *)&smp_trash->len);
2871
2872 smp->data.str = *smp_trash;
2873 smp->type = SMP_T_BIN;
2874 ret = 1;
2875out:
Emeric Brunba841a12014-04-30 17:05:08 +02002876 /* SSL_get_peer_certificate, it increase X509 * ref count */
2877 if (cert_peer && crt)
James Votha051b4a2013-05-14 20:37:59 +02002878 X509_free(crt);
2879 return ret;
2880}
2881
Emeric Brunba841a12014-04-30 17:05:08 +02002882/* string, returns certificate's notafter date in ASN1_UTCTIME format.
2883 * The 5th keyword char is used to know if SSL_get_certificate or SSL_get_peer_certificate
2884 * should be use.
2885 */
Emeric Brunce5ad802012-10-22 14:11:22 +02002886static int
Emeric Brunba841a12014-04-30 17:05:08 +02002887smp_fetch_ssl_x_notafter(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
Willy Tarreauef38c392013-07-22 16:29:32 +02002888 const struct arg *args, struct sample *smp, const char *kw)
Emeric Brunce5ad802012-10-22 14:11:22 +02002889{
Emeric Brunba841a12014-04-30 17:05:08 +02002890 int cert_peer = (kw[4] == 'c') ? 1 : 0;
Emeric Brunce5ad802012-10-22 14:11:22 +02002891 X509 *crt = NULL;
2892 int ret = 0;
2893 struct chunk *smp_trash;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002894 struct connection *conn;
Emeric Brunce5ad802012-10-22 14:11:22 +02002895
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002896 if (!l4)
Emeric Brunce5ad802012-10-22 14:11:22 +02002897 return 0;
2898
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002899 conn = objt_conn(l4->si[0].end);
2900 if (!conn || conn->xprt != &ssl_sock)
2901 return 0;
2902
2903 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brunce5ad802012-10-22 14:11:22 +02002904 smp->flags |= SMP_F_MAY_CHANGE;
2905 return 0;
2906 }
2907
Emeric Brunba841a12014-04-30 17:05:08 +02002908 if (cert_peer)
2909 crt = SSL_get_peer_certificate(conn->xprt_ctx);
2910 else
2911 crt = SSL_get_certificate(conn->xprt_ctx);
Emeric Brunce5ad802012-10-22 14:11:22 +02002912 if (!crt)
2913 goto out;
2914
Willy Tarreau47ca5452012-12-23 20:22:19 +01002915 smp_trash = get_trash_chunk();
Emeric Brunce5ad802012-10-22 14:11:22 +02002916 if (ssl_sock_get_time(X509_get_notAfter(crt), smp_trash) <= 0)
2917 goto out;
2918
2919 smp->data.str = *smp_trash;
2920 smp->type = SMP_T_STR;
2921 ret = 1;
2922out:
Emeric Brunba841a12014-04-30 17:05:08 +02002923 /* SSL_get_peer_certificate, it increase X509 * ref count */
2924 if (cert_peer && crt)
Emeric Brunce5ad802012-10-22 14:11:22 +02002925 X509_free(crt);
2926 return ret;
2927}
2928
Emeric Brunba841a12014-04-30 17:05:08 +02002929/* string, returns a string of a formatted full dn \C=..\O=..\OU=.. \CN=.. of certificate's issuer
2930 * The 5th keyword char is used to know if SSL_get_certificate or SSL_get_peer_certificate
2931 * should be use.
2932 */
Emeric Brun87855892012-10-17 17:39:35 +02002933static int
Emeric Brunba841a12014-04-30 17:05:08 +02002934smp_fetch_ssl_x_i_dn(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
Willy Tarreauef38c392013-07-22 16:29:32 +02002935 const struct arg *args, struct sample *smp, const char *kw)
Emeric Brun87855892012-10-17 17:39:35 +02002936{
Emeric Brunba841a12014-04-30 17:05:08 +02002937 int cert_peer = (kw[4] == 'c') ? 1 : 0;
Emeric Brun87855892012-10-17 17:39:35 +02002938 X509 *crt = NULL;
2939 X509_NAME *name;
2940 int ret = 0;
2941 struct chunk *smp_trash;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002942 struct connection *conn;
Emeric Brun87855892012-10-17 17:39:35 +02002943
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002944 if (!l4)
Emeric Brun87855892012-10-17 17:39:35 +02002945 return 0;
2946
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002947 conn = objt_conn(l4->si[0].end);
2948 if (!conn || conn->xprt != &ssl_sock)
2949 return 0;
2950
2951 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brun87855892012-10-17 17:39:35 +02002952 smp->flags |= SMP_F_MAY_CHANGE;
2953 return 0;
2954 }
2955
Emeric Brunba841a12014-04-30 17:05:08 +02002956 if (cert_peer)
2957 crt = SSL_get_peer_certificate(conn->xprt_ctx);
2958 else
2959 crt = SSL_get_certificate(conn->xprt_ctx);
Emeric Brun87855892012-10-17 17:39:35 +02002960 if (!crt)
2961 goto out;
2962
2963 name = X509_get_issuer_name(crt);
2964 if (!name)
2965 goto out;
2966
Willy Tarreau47ca5452012-12-23 20:22:19 +01002967 smp_trash = get_trash_chunk();
Emeric Brun87855892012-10-17 17:39:35 +02002968 if (args && args[0].type == ARGT_STR) {
2969 int pos = 1;
2970
2971 if (args[1].type == ARGT_SINT)
2972 pos = args[1].data.sint;
2973 else if (args[1].type == ARGT_UINT)
2974 pos =(int)args[1].data.uint;
2975
2976 if (ssl_sock_get_dn_entry(name, &args[0].data.str, pos, smp_trash) <= 0)
2977 goto out;
2978 }
2979 else if (ssl_sock_get_dn_oneline(name, smp_trash) <= 0)
2980 goto out;
2981
2982 smp->type = SMP_T_STR;
2983 smp->data.str = *smp_trash;
2984 ret = 1;
2985out:
Emeric Brunba841a12014-04-30 17:05:08 +02002986 /* SSL_get_peer_certificate, it increase X509 * ref count */
2987 if (cert_peer && crt)
Emeric Brun87855892012-10-17 17:39:35 +02002988 X509_free(crt);
2989 return ret;
2990}
2991
Emeric Brunba841a12014-04-30 17:05:08 +02002992/* string, returns notbefore date in ASN1_UTCTIME format.
2993 * The 5th keyword char is used to know if SSL_get_certificate or SSL_get_peer_certificate
2994 * should be use.
2995 */
Emeric Brunce5ad802012-10-22 14:11:22 +02002996static int
Emeric Brunba841a12014-04-30 17:05:08 +02002997smp_fetch_ssl_x_notbefore(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
Willy Tarreauef38c392013-07-22 16:29:32 +02002998 const struct arg *args, struct sample *smp, const char *kw)
Emeric Brunce5ad802012-10-22 14:11:22 +02002999{
Emeric Brunba841a12014-04-30 17:05:08 +02003000 int cert_peer = (kw[4] == 'c') ? 1 : 0;
Emeric Brunce5ad802012-10-22 14:11:22 +02003001 X509 *crt = NULL;
3002 int ret = 0;
3003 struct chunk *smp_trash;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003004 struct connection *conn;
3005
3006 if (!l4)
3007 return 0;
Emeric Brunce5ad802012-10-22 14:11:22 +02003008
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003009 conn = objt_conn(l4->si[0].end);
3010 if (!conn || conn->xprt != &ssl_sock)
Emeric Brunce5ad802012-10-22 14:11:22 +02003011 return 0;
3012
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003013 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brunce5ad802012-10-22 14:11:22 +02003014 smp->flags |= SMP_F_MAY_CHANGE;
3015 return 0;
3016 }
3017
Emeric Brunba841a12014-04-30 17:05:08 +02003018 if (cert_peer)
3019 crt = SSL_get_peer_certificate(conn->xprt_ctx);
3020 else
3021 crt = SSL_get_certificate(conn->xprt_ctx);
Emeric Brunce5ad802012-10-22 14:11:22 +02003022 if (!crt)
3023 goto out;
3024
Willy Tarreau47ca5452012-12-23 20:22:19 +01003025 smp_trash = get_trash_chunk();
Emeric Brunce5ad802012-10-22 14:11:22 +02003026 if (ssl_sock_get_time(X509_get_notBefore(crt), smp_trash) <= 0)
3027 goto out;
3028
3029 smp->data.str = *smp_trash;
3030 smp->type = SMP_T_STR;
3031 ret = 1;
3032out:
Emeric Brunba841a12014-04-30 17:05:08 +02003033 /* SSL_get_peer_certificate, it increase X509 * ref count */
3034 if (cert_peer && crt)
Emeric Brunce5ad802012-10-22 14:11:22 +02003035 X509_free(crt);
3036 return ret;
3037}
3038
Emeric Brunba841a12014-04-30 17:05:08 +02003039/* string, returns a string of a formatted full dn \C=..\O=..\OU=.. \CN=.. of certificate's subject
3040 * The 5th keyword char is used to know if SSL_get_certificate or SSL_get_peer_certificate
3041 * should be use.
3042 */
Emeric Brun87855892012-10-17 17:39:35 +02003043static int
Emeric Brunba841a12014-04-30 17:05:08 +02003044smp_fetch_ssl_x_s_dn(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
Willy Tarreauef38c392013-07-22 16:29:32 +02003045 const struct arg *args, struct sample *smp, const char *kw)
Emeric Brun87855892012-10-17 17:39:35 +02003046{
Emeric Brunba841a12014-04-30 17:05:08 +02003047 int cert_peer = (kw[4] == 'c') ? 1 : 0;
Emeric Brun87855892012-10-17 17:39:35 +02003048 X509 *crt = NULL;
3049 X509_NAME *name;
3050 int ret = 0;
3051 struct chunk *smp_trash;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003052 struct connection *conn;
Emeric Brun87855892012-10-17 17:39:35 +02003053
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003054 if (!l4)
Emeric Brun87855892012-10-17 17:39:35 +02003055 return 0;
3056
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003057 conn = objt_conn(l4->si[0].end);
3058 if (!conn || conn->xprt != &ssl_sock)
3059 return 0;
3060
3061 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brun87855892012-10-17 17:39:35 +02003062 smp->flags |= SMP_F_MAY_CHANGE;
3063 return 0;
3064 }
3065
Emeric Brunba841a12014-04-30 17:05:08 +02003066 if (cert_peer)
3067 crt = SSL_get_peer_certificate(conn->xprt_ctx);
3068 else
3069 crt = SSL_get_certificate(conn->xprt_ctx);
Emeric Brun87855892012-10-17 17:39:35 +02003070 if (!crt)
3071 goto out;
3072
3073 name = X509_get_subject_name(crt);
3074 if (!name)
3075 goto out;
3076
Willy Tarreau47ca5452012-12-23 20:22:19 +01003077 smp_trash = get_trash_chunk();
Emeric Brun87855892012-10-17 17:39:35 +02003078 if (args && args[0].type == ARGT_STR) {
3079 int pos = 1;
3080
3081 if (args[1].type == ARGT_SINT)
3082 pos = args[1].data.sint;
3083 else if (args[1].type == ARGT_UINT)
3084 pos =(int)args[1].data.uint;
3085
3086 if (ssl_sock_get_dn_entry(name, &args[0].data.str, pos, smp_trash) <= 0)
3087 goto out;
3088 }
3089 else if (ssl_sock_get_dn_oneline(name, smp_trash) <= 0)
3090 goto out;
3091
3092 smp->type = SMP_T_STR;
3093 smp->data.str = *smp_trash;
3094 ret = 1;
3095out:
Emeric Brunba841a12014-04-30 17:05:08 +02003096 /* SSL_get_peer_certificate, it increase X509 * ref count */
3097 if (cert_peer && crt)
Emeric Brun87855892012-10-17 17:39:35 +02003098 X509_free(crt);
3099 return ret;
3100}
Emeric Brun9143d372012-12-20 15:44:16 +01003101
3102/* integer, returns true if current session use a client certificate */
3103static int
3104smp_fetch_ssl_c_used(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
Willy Tarreauef38c392013-07-22 16:29:32 +02003105 const struct arg *args, struct sample *smp, const char *kw)
Emeric Brun9143d372012-12-20 15:44:16 +01003106{
3107 X509 *crt;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003108 struct connection *conn;
Emeric Brun9143d372012-12-20 15:44:16 +01003109
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003110 if (!l4)
Emeric Brun9143d372012-12-20 15:44:16 +01003111 return 0;
3112
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003113 conn = objt_conn(l4->si[0].end);
3114 if (!conn || conn->xprt != &ssl_sock)
3115 return 0;
3116
3117 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brun9143d372012-12-20 15:44:16 +01003118 smp->flags |= SMP_F_MAY_CHANGE;
3119 return 0;
3120 }
3121
3122 /* SSL_get_peer_certificate returns a ptr on allocated X509 struct */
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003123 crt = SSL_get_peer_certificate(conn->xprt_ctx);
Emeric Brun9143d372012-12-20 15:44:16 +01003124 if (crt) {
3125 X509_free(crt);
3126 }
3127
3128 smp->type = SMP_T_BOOL;
3129 smp->data.uint = (crt != NULL);
3130 return 1;
3131}
3132
Emeric Brunba841a12014-04-30 17:05:08 +02003133/* integer, returns the certificate version
3134 * The 5th keyword char is used to know if SSL_get_certificate or SSL_get_peer_certificate
3135 * should be use.
3136 */
Emeric Bruna7359fd2012-10-17 15:03:11 +02003137static int
Emeric Brunba841a12014-04-30 17:05:08 +02003138smp_fetch_ssl_x_version(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
Willy Tarreauef38c392013-07-22 16:29:32 +02003139 const struct arg *args, struct sample *smp, const char *kw)
Emeric Bruna7359fd2012-10-17 15:03:11 +02003140{
Emeric Brunba841a12014-04-30 17:05:08 +02003141 int cert_peer = (kw[4] == 'c') ? 1 : 0;
Emeric Bruna7359fd2012-10-17 15:03:11 +02003142 X509 *crt;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003143 struct connection *conn;
3144
3145 if (!l4)
3146 return 0;
Emeric Bruna7359fd2012-10-17 15:03:11 +02003147
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003148 conn = objt_conn(l4->si[0].end);
3149 if (!conn || conn->xprt != &ssl_sock)
Emeric Bruna7359fd2012-10-17 15:03:11 +02003150 return 0;
3151
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003152 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Bruna7359fd2012-10-17 15:03:11 +02003153 smp->flags |= SMP_F_MAY_CHANGE;
3154 return 0;
3155 }
3156
Emeric Brunba841a12014-04-30 17:05:08 +02003157 if (cert_peer)
3158 crt = SSL_get_peer_certificate(conn->xprt_ctx);
3159 else
3160 crt = SSL_get_certificate(conn->xprt_ctx);
Emeric Bruna7359fd2012-10-17 15:03:11 +02003161 if (!crt)
3162 return 0;
3163
3164 smp->data.uint = (unsigned int)(1 + X509_get_version(crt));
Emeric Brunba841a12014-04-30 17:05:08 +02003165 /* SSL_get_peer_certificate increase X509 * ref count */
3166 if (cert_peer)
3167 X509_free(crt);
Emeric Bruna7359fd2012-10-17 15:03:11 +02003168 smp->type = SMP_T_UINT;
3169
3170 return 1;
3171}
3172
Emeric Brunba841a12014-04-30 17:05:08 +02003173/* string, returns the certificate's signature algorithm.
3174 * The 5th keyword char is used to know if SSL_get_certificate or SSL_get_peer_certificate
3175 * should be use.
3176 */
Emeric Brun7f56e742012-10-19 18:15:40 +02003177static int
Emeric Brunba841a12014-04-30 17:05:08 +02003178smp_fetch_ssl_x_sig_alg(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
Willy Tarreauef38c392013-07-22 16:29:32 +02003179 const struct arg *args, struct sample *smp, const char *kw)
Emeric Brun7f56e742012-10-19 18:15:40 +02003180{
Emeric Brunba841a12014-04-30 17:05:08 +02003181 int cert_peer = (kw[4] == 'c') ? 1 : 0;
Emeric Brun7f56e742012-10-19 18:15:40 +02003182 X509 *crt;
3183 int nid;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003184 struct connection *conn;
Emeric Brun7f56e742012-10-19 18:15:40 +02003185
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003186 if (!l4)
Emeric Brun7f56e742012-10-19 18:15:40 +02003187 return 0;
3188
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003189 conn = objt_conn(l4->si[0].end);
3190 if (!conn || conn->xprt != &ssl_sock)
3191 return 0;
3192
3193 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brun7f56e742012-10-19 18:15:40 +02003194 smp->flags |= SMP_F_MAY_CHANGE;
3195 return 0;
3196 }
3197
Emeric Brunba841a12014-04-30 17:05:08 +02003198 if (cert_peer)
3199 crt = SSL_get_peer_certificate(conn->xprt_ctx);
3200 else
3201 crt = SSL_get_certificate(conn->xprt_ctx);
Emeric Brun7f56e742012-10-19 18:15:40 +02003202 if (!crt)
3203 return 0;
3204
3205 nid = OBJ_obj2nid((ASN1_OBJECT *)(crt->cert_info->signature->algorithm));
3206
3207 smp->data.str.str = (char *)OBJ_nid2sn(nid);
Emeric Brun9bf3ba22013-10-07 14:31:44 +02003208 if (!smp->data.str.str) {
Emeric Brunba841a12014-04-30 17:05:08 +02003209 /* SSL_get_peer_certificate increase X509 * ref count */
3210 if (cert_peer)
3211 X509_free(crt);
Emeric Brun7f56e742012-10-19 18:15:40 +02003212 return 0;
Emeric Brun9bf3ba22013-10-07 14:31:44 +02003213 }
Emeric Brun7f56e742012-10-19 18:15:40 +02003214
Thierry FOURNIER7654c9f2013-12-17 00:20:33 +01003215 smp->type = SMP_T_STR;
3216 smp->flags |= SMP_F_CONST;
Emeric Brun7f56e742012-10-19 18:15:40 +02003217 smp->data.str.len = strlen(smp->data.str.str);
Emeric Brunba841a12014-04-30 17:05:08 +02003218 /* SSL_get_peer_certificate increase X509 * ref count */
3219 if (cert_peer)
3220 X509_free(crt);
Emeric Brun7f56e742012-10-19 18:15:40 +02003221
3222 return 1;
3223}
3224
Emeric Brunba841a12014-04-30 17:05:08 +02003225/* string, returns the certificate's key algorithm.
3226 * The 5th keyword char is used to know if SSL_get_certificate or SSL_get_peer_certificate
3227 * should be use.
3228 */
Emeric Brun521a0112012-10-22 12:22:55 +02003229static int
Emeric Brunba841a12014-04-30 17:05:08 +02003230smp_fetch_ssl_x_key_alg(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
Willy Tarreauef38c392013-07-22 16:29:32 +02003231 const struct arg *args, struct sample *smp, const char *kw)
Emeric Brun521a0112012-10-22 12:22:55 +02003232{
Emeric Brunba841a12014-04-30 17:05:08 +02003233 int cert_peer = (kw[4] == 'c') ? 1 : 0;
Emeric Brun521a0112012-10-22 12:22:55 +02003234 X509 *crt;
3235 int nid;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003236 struct connection *conn;
Emeric Brun521a0112012-10-22 12:22:55 +02003237
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003238 if (!l4)
Emeric Brun521a0112012-10-22 12:22:55 +02003239 return 0;
3240
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003241 conn = objt_conn(l4->si[0].end);
3242 if (!conn || conn->xprt != &ssl_sock)
3243 return 0;
3244
3245 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brun521a0112012-10-22 12:22:55 +02003246 smp->flags |= SMP_F_MAY_CHANGE;
3247 return 0;
3248 }
3249
Emeric Brunba841a12014-04-30 17:05:08 +02003250 if (cert_peer)
3251 crt = SSL_get_peer_certificate(conn->xprt_ctx);
3252 else
3253 crt = SSL_get_certificate(conn->xprt_ctx);
Emeric Brun521a0112012-10-22 12:22:55 +02003254 if (!crt)
3255 return 0;
3256
3257 nid = OBJ_obj2nid((ASN1_OBJECT *)(crt->cert_info->key->algor->algorithm));
3258
3259 smp->data.str.str = (char *)OBJ_nid2sn(nid);
Emeric Brun9bf3ba22013-10-07 14:31:44 +02003260 if (!smp->data.str.str) {
Emeric Brunba841a12014-04-30 17:05:08 +02003261 /* SSL_get_peer_certificate increase X509 * ref count */
3262 if (cert_peer)
3263 X509_free(crt);
Emeric Brun521a0112012-10-22 12:22:55 +02003264 return 0;
Emeric Brun9bf3ba22013-10-07 14:31:44 +02003265 }
Emeric Brun521a0112012-10-22 12:22:55 +02003266
Thierry FOURNIER7654c9f2013-12-17 00:20:33 +01003267 smp->type = SMP_T_STR;
3268 smp->flags |= SMP_F_CONST;
Emeric Brun521a0112012-10-22 12:22:55 +02003269 smp->data.str.len = strlen(smp->data.str.str);
Emeric Brunba841a12014-04-30 17:05:08 +02003270 if (cert_peer)
3271 X509_free(crt);
Emeric Brun521a0112012-10-22 12:22:55 +02003272
3273 return 1;
3274}
3275
Emeric Brun645ae792014-04-30 14:21:06 +02003276/* boolean, returns true if front conn. transport layer is SSL.
3277 * This function is also usable on backend conn if the fetch keyword 5th
3278 * char is 'b'.
3279 */
Willy Tarreau7875d092012-09-10 08:20:03 +02003280static int
Emeric Brun2525b6b2012-10-18 15:59:43 +02003281smp_fetch_ssl_fc(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
Willy Tarreauef38c392013-07-22 16:29:32 +02003282 const struct arg *args, struct sample *smp, const char *kw)
Willy Tarreau7875d092012-09-10 08:20:03 +02003283{
Emeric Brun645ae792014-04-30 14:21:06 +02003284 int back_conn = (kw[4] == 'b') ? 1 : 0;
3285 struct connection *conn = objt_conn(l4->si[back_conn].end);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003286
Willy Tarreau7875d092012-09-10 08:20:03 +02003287 smp->type = SMP_T_BOOL;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003288 smp->data.uint = (conn && conn->xprt == &ssl_sock);
Willy Tarreau7875d092012-09-10 08:20:03 +02003289 return 1;
3290}
3291
Emeric Brun2525b6b2012-10-18 15:59:43 +02003292/* boolean, returns true if client present a SNI */
Willy Tarreau7875d092012-09-10 08:20:03 +02003293static int
Emeric Brun2525b6b2012-10-18 15:59:43 +02003294smp_fetch_ssl_fc_has_sni(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
Willy Tarreauef38c392013-07-22 16:29:32 +02003295 const struct arg *args, struct sample *smp, const char *kw)
Willy Tarreau7875d092012-09-10 08:20:03 +02003296{
3297#ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003298 struct connection *conn = objt_conn(l4->si[0].end);
3299
Willy Tarreau7875d092012-09-10 08:20:03 +02003300 smp->type = SMP_T_BOOL;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003301 smp->data.uint = (conn && conn->xprt == &ssl_sock) &&
3302 conn->xprt_ctx &&
3303 SSL_get_servername(conn->xprt_ctx, TLSEXT_NAMETYPE_host_name) != NULL;
Willy Tarreau7875d092012-09-10 08:20:03 +02003304 return 1;
3305#else
3306 return 0;
3307#endif
3308}
3309
Emeric Brun645ae792014-04-30 14:21:06 +02003310/* string, returns the used cipher if front conn. transport layer is SSL.
3311 * This function is also usable on backend conn if the fetch keyword 5th
3312 * char is 'b'.
3313 */
Emeric Brun589fcad2012-10-16 14:13:26 +02003314static int
3315smp_fetch_ssl_fc_cipher(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
Willy Tarreauef38c392013-07-22 16:29:32 +02003316 const struct arg *args, struct sample *smp, const char *kw)
Emeric Brun589fcad2012-10-16 14:13:26 +02003317{
Emeric Brun645ae792014-04-30 14:21:06 +02003318 int back_conn = (kw[4] == 'b') ? 1 : 0;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003319 struct connection *conn;
3320
Emeric Brun589fcad2012-10-16 14:13:26 +02003321 smp->flags = 0;
3322
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003323 if (!l4)
3324 return 0;
3325
Emeric Brun645ae792014-04-30 14:21:06 +02003326 conn = objt_conn(l4->si[back_conn].end);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003327 if (!conn || !conn->xprt_ctx || conn->xprt != &ssl_sock)
Emeric Brun589fcad2012-10-16 14:13:26 +02003328 return 0;
3329
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003330 smp->data.str.str = (char *)SSL_get_cipher_name(conn->xprt_ctx);
Emeric Brun589fcad2012-10-16 14:13:26 +02003331 if (!smp->data.str.str)
3332 return 0;
3333
Thierry FOURNIER7654c9f2013-12-17 00:20:33 +01003334 smp->type = SMP_T_STR;
3335 smp->flags |= SMP_F_CONST;
Emeric Brun589fcad2012-10-16 14:13:26 +02003336 smp->data.str.len = strlen(smp->data.str.str);
3337
3338 return 1;
3339}
3340
Emeric Brun645ae792014-04-30 14:21:06 +02003341/* integer, returns the algoritm's keysize if front conn. transport layer
3342 * is SSL.
3343 * This function is also usable on backend conn if the fetch keyword 5th
3344 * char is 'b'.
3345 */
Emeric Brun589fcad2012-10-16 14:13:26 +02003346static int
3347smp_fetch_ssl_fc_alg_keysize(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
Willy Tarreauef38c392013-07-22 16:29:32 +02003348 const struct arg *args, struct sample *smp, const char *kw)
Emeric Brun589fcad2012-10-16 14:13:26 +02003349{
Emeric Brun645ae792014-04-30 14:21:06 +02003350 int back_conn = (kw[4] == 'b') ? 1 : 0;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003351 struct connection *conn;
3352
Emeric Brun589fcad2012-10-16 14:13:26 +02003353 smp->flags = 0;
3354
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003355 if (!l4)
Emeric Brun589fcad2012-10-16 14:13:26 +02003356 return 0;
3357
Emeric Brun645ae792014-04-30 14:21:06 +02003358 conn = objt_conn(l4->si[back_conn].end);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003359 if (!conn || !conn->xprt_ctx || conn->xprt != &ssl_sock)
Emeric Brun589fcad2012-10-16 14:13:26 +02003360 return 0;
3361
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003362 if (!SSL_get_cipher_bits(conn->xprt_ctx, (int *)&smp->data.uint))
3363 return 0;
3364
Emeric Brun589fcad2012-10-16 14:13:26 +02003365 smp->type = SMP_T_UINT;
3366
3367 return 1;
3368}
3369
Emeric Brun645ae792014-04-30 14:21:06 +02003370/* integer, returns the used keysize if front conn. transport layer is SSL.
3371 * This function is also usable on backend conn if the fetch keyword 5th
3372 * char is 'b'.
3373 */
Emeric Brun589fcad2012-10-16 14:13:26 +02003374static int
3375smp_fetch_ssl_fc_use_keysize(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
Willy Tarreauef38c392013-07-22 16:29:32 +02003376 const struct arg *args, struct sample *smp, const char *kw)
Emeric Brun589fcad2012-10-16 14:13:26 +02003377{
Emeric Brun645ae792014-04-30 14:21:06 +02003378 int back_conn = (kw[4] == 'b') ? 1 : 0;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003379 struct connection *conn;
3380
Emeric Brun589fcad2012-10-16 14:13:26 +02003381 smp->flags = 0;
3382
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003383 if (!l4)
Emeric Brun589fcad2012-10-16 14:13:26 +02003384 return 0;
3385
Emeric Brun645ae792014-04-30 14:21:06 +02003386 conn = objt_conn(l4->si[back_conn].end);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003387 if (!conn || !conn->xprt_ctx || conn->xprt != &ssl_sock)
3388 return 0;
3389
3390 smp->data.uint = (unsigned int)SSL_get_cipher_bits(conn->xprt_ctx, NULL);
Emeric Brun589fcad2012-10-16 14:13:26 +02003391 if (!smp->data.uint)
3392 return 0;
3393
3394 smp->type = SMP_T_UINT;
3395
3396 return 1;
3397}
3398
Willy Tarreau6c9a3d52012-10-18 18:57:14 +02003399#ifdef OPENSSL_NPN_NEGOTIATED
Willy Tarreau7875d092012-09-10 08:20:03 +02003400static int
Emeric Brun2525b6b2012-10-18 15:59:43 +02003401smp_fetch_ssl_fc_npn(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
Willy Tarreauef38c392013-07-22 16:29:32 +02003402 const struct arg *args, struct sample *smp, const char *kw)
Willy Tarreaua33c6542012-10-15 13:19:06 +02003403{
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003404 struct connection *conn;
3405
Thierry FOURNIER7654c9f2013-12-17 00:20:33 +01003406 smp->flags = SMP_F_CONST;
3407 smp->type = SMP_T_STR;
Willy Tarreaua33c6542012-10-15 13:19:06 +02003408
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003409 if (!l4)
Willy Tarreaua33c6542012-10-15 13:19:06 +02003410 return 0;
3411
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003412 conn = objt_conn(l4->si[0].end);
3413 if (!conn || !conn->xprt_ctx || conn->xprt != &ssl_sock)
3414 return 0;
3415
Willy Tarreaua33c6542012-10-15 13:19:06 +02003416 smp->data.str.str = NULL;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003417 SSL_get0_next_proto_negotiated(conn->xprt_ctx,
Willy Tarreaua33c6542012-10-15 13:19:06 +02003418 (const unsigned char **)&smp->data.str.str, (unsigned *)&smp->data.str.len);
3419
3420 if (!smp->data.str.str)
3421 return 0;
3422
3423 return 1;
Willy Tarreaua33c6542012-10-15 13:19:06 +02003424}
Willy Tarreau6c9a3d52012-10-18 18:57:14 +02003425#endif
Willy Tarreaua33c6542012-10-15 13:19:06 +02003426
Dirkjan Bussink48f1c4e2014-02-13 12:29:42 +01003427#ifdef TLSEXT_TYPE_application_layer_protocol_negotiation
Willy Tarreauab861d32013-04-02 02:30:41 +02003428static int
3429smp_fetch_ssl_fc_alpn(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
Willy Tarreauef38c392013-07-22 16:29:32 +02003430 const struct arg *args, struct sample *smp, const char *kw)
Willy Tarreauab861d32013-04-02 02:30:41 +02003431{
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003432 struct connection *conn;
3433
Thierry FOURNIER7654c9f2013-12-17 00:20:33 +01003434 smp->flags = SMP_F_CONST;
3435 smp->type = SMP_T_STR;
Willy Tarreauab861d32013-04-02 02:30:41 +02003436
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003437 if (!l4)
3438 return 0;
3439
3440 conn = objt_conn(l4->si[0].end);
3441 if (!conn || !conn->xprt_ctx || conn->xprt != &ssl_sock)
Willy Tarreauab861d32013-04-02 02:30:41 +02003442 return 0;
3443
3444 smp->data.str.str = NULL;
Dirkjan Bussink48f1c4e2014-02-13 12:29:42 +01003445 SSL_get0_alpn_selected(conn->xprt_ctx,
Willy Tarreauab861d32013-04-02 02:30:41 +02003446 (const unsigned char **)&smp->data.str.str, (unsigned *)&smp->data.str.len);
3447
3448 if (!smp->data.str.str)
3449 return 0;
3450
3451 return 1;
3452}
3453#endif
3454
Emeric Brun645ae792014-04-30 14:21:06 +02003455/* string, returns the used protocol if front conn. transport layer is SSL.
3456 * This function is also usable on backend conn if the fetch keyword 5th
3457 * char is 'b'.
3458 */
Willy Tarreaua33c6542012-10-15 13:19:06 +02003459static int
Emeric Brun589fcad2012-10-16 14:13:26 +02003460smp_fetch_ssl_fc_protocol(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
Willy Tarreauef38c392013-07-22 16:29:32 +02003461 const struct arg *args, struct sample *smp, const char *kw)
Emeric Brun589fcad2012-10-16 14:13:26 +02003462{
Emeric Brun645ae792014-04-30 14:21:06 +02003463 int back_conn = (kw[4] == 'b') ? 1 : 0;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003464 struct connection *conn;
3465
Emeric Brun589fcad2012-10-16 14:13:26 +02003466 smp->flags = 0;
3467
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003468 if (!l4)
Emeric Brun589fcad2012-10-16 14:13:26 +02003469 return 0;
3470
Emeric Brun645ae792014-04-30 14:21:06 +02003471 conn = objt_conn(l4->si[back_conn].end);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003472 if (!conn || !conn->xprt_ctx || conn->xprt != &ssl_sock)
3473 return 0;
3474
3475 smp->data.str.str = (char *)SSL_get_version(conn->xprt_ctx);
Emeric Brun589fcad2012-10-16 14:13:26 +02003476 if (!smp->data.str.str)
3477 return 0;
3478
Thierry FOURNIER7654c9f2013-12-17 00:20:33 +01003479 smp->type = SMP_T_STR;
3480 smp->flags = SMP_F_CONST;
Emeric Brun589fcad2012-10-16 14:13:26 +02003481 smp->data.str.len = strlen(smp->data.str.str);
3482
3483 return 1;
3484}
3485
Emeric Brun645ae792014-04-30 14:21:06 +02003486/* binary, returns the SSL session id if front conn. transport layer is SSL.
3487 * This function is also usable on backend conn if the fetch keyword 5th
3488 * char is 'b'.
3489 */
Emeric Brun589fcad2012-10-16 14:13:26 +02003490static int
Emeric Brunfe68f682012-10-16 14:59:28 +02003491smp_fetch_ssl_fc_session_id(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
Willy Tarreauef38c392013-07-22 16:29:32 +02003492 const struct arg *args, struct sample *smp, const char *kw)
Emeric Brunfe68f682012-10-16 14:59:28 +02003493{
3494#if OPENSSL_VERSION_NUMBER > 0x0090800fL
Emeric Brun645ae792014-04-30 14:21:06 +02003495 int back_conn = (kw[4] == 'b') ? 1 : 0;
Emeric Brunfe68f682012-10-16 14:59:28 +02003496 SSL_SESSION *sess;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003497 struct connection *conn;
Emeric Brunfe68f682012-10-16 14:59:28 +02003498
Thierry FOURNIER7654c9f2013-12-17 00:20:33 +01003499 smp->flags = SMP_F_CONST;
3500 smp->type = SMP_T_BIN;
Emeric Brunfe68f682012-10-16 14:59:28 +02003501
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003502 if (!l4)
Emeric Brunfe68f682012-10-16 14:59:28 +02003503 return 0;
3504
Emeric Brun645ae792014-04-30 14:21:06 +02003505 conn = objt_conn(l4->si[back_conn].end);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003506 if (!conn || !conn->xprt_ctx || conn->xprt != &ssl_sock)
3507 return 0;
3508
3509 sess = SSL_get_session(conn->xprt_ctx);
Emeric Brunfe68f682012-10-16 14:59:28 +02003510 if (!sess)
3511 return 0;
3512
3513 smp->data.str.str = (char *)SSL_SESSION_get_id(sess, (unsigned int *)&smp->data.str.len);
3514 if (!smp->data.str.str || !&smp->data.str.len)
3515 return 0;
3516
3517 return 1;
3518#else
3519 return 0;
3520#endif
3521}
3522
3523static int
Emeric Brun2525b6b2012-10-18 15:59:43 +02003524smp_fetch_ssl_fc_sni(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
Willy Tarreauef38c392013-07-22 16:29:32 +02003525 const struct arg *args, struct sample *smp, const char *kw)
Willy Tarreau7875d092012-09-10 08:20:03 +02003526{
3527#ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003528 struct connection *conn;
3529
Thierry FOURNIER7654c9f2013-12-17 00:20:33 +01003530 smp->flags = SMP_F_CONST;
3531 smp->type = SMP_T_STR;
Willy Tarreau7875d092012-09-10 08:20:03 +02003532
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003533 if (!l4)
Willy Tarreau7875d092012-09-10 08:20:03 +02003534 return 0;
3535
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003536 conn = objt_conn(l4->si[0].end);
3537 if (!conn || !conn->xprt_ctx || conn->xprt != &ssl_sock)
3538 return 0;
3539
3540 smp->data.str.str = (char *)SSL_get_servername(conn->xprt_ctx, TLSEXT_NAMETYPE_host_name);
Willy Tarreau3e394c92012-09-14 23:56:58 +02003541 if (!smp->data.str.str)
3542 return 0;
3543
Willy Tarreau7875d092012-09-10 08:20:03 +02003544 smp->data.str.len = strlen(smp->data.str.str);
3545 return 1;
3546#else
3547 return 0;
3548#endif
3549}
3550
David Sc1ad52e2014-04-08 18:48:47 -04003551static int
3552smp_fetch_ssl_fc_unique_id(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
3553 const struct arg *args, struct sample *smp, const char *kw)
3554{
3555#if OPENSSL_VERSION_NUMBER > 0x0090800fL
Emeric Brun645ae792014-04-30 14:21:06 +02003556 int back_conn = (kw[4] == 'b') ? 1 : 0;
David Sc1ad52e2014-04-08 18:48:47 -04003557 struct connection *conn;
3558 int finished_len;
David Sc1ad52e2014-04-08 18:48:47 -04003559 struct chunk *finished_trash;
David Sc1ad52e2014-04-08 18:48:47 -04003560
3561 smp->flags = 0;
3562
3563 if (!l4)
3564 return 0;
3565
Emeric Brun645ae792014-04-30 14:21:06 +02003566 conn = objt_conn(l4->si[back_conn].end);
David Sc1ad52e2014-04-08 18:48:47 -04003567 if (!conn || !conn->xprt_ctx || conn->xprt != &ssl_sock)
3568 return 0;
3569
3570 if (!(conn->flags & CO_FL_CONNECTED)) {
3571 smp->flags |= SMP_F_MAY_CHANGE;
3572 return 0;
3573 }
3574
3575 finished_trash = get_trash_chunk();
3576 if (!SSL_session_reused(conn->xprt_ctx))
3577 finished_len = SSL_get_peer_finished(conn->xprt_ctx, finished_trash->str, finished_trash->size);
3578 else
3579 finished_len = SSL_get_finished(conn->xprt_ctx, finished_trash->str, finished_trash->size);
3580
3581 if (!finished_len)
3582 return 0;
3583
Emeric Brunb73a9b02014-04-30 18:49:19 +02003584 finished_trash->len = finished_len;
3585 smp->data.str = *finished_trash;
3586 smp->type = SMP_T_BIN;
David Sc1ad52e2014-04-08 18:48:47 -04003587
3588 return 1;
3589#else
3590 return 0;
3591#endif
3592}
3593
Emeric Brun2525b6b2012-10-18 15:59:43 +02003594/* integer, returns the first verify error in CA chain of client certificate chain. */
Emeric Brunf282a812012-09-21 15:27:54 +02003595static int
Emeric Brun2525b6b2012-10-18 15:59:43 +02003596smp_fetch_ssl_c_ca_err(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
Willy Tarreauef38c392013-07-22 16:29:32 +02003597 const struct arg *args, struct sample *smp, const char *kw)
Emeric Brunf282a812012-09-21 15:27:54 +02003598{
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003599 struct connection *conn;
3600
3601 if (!l4)
Emeric Brunf282a812012-09-21 15:27:54 +02003602 return 0;
3603
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003604 conn = objt_conn(l4->si[0].end);
3605 if (!conn || conn->xprt != &ssl_sock)
3606 return 0;
3607
3608 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brunf282a812012-09-21 15:27:54 +02003609 smp->flags = SMP_F_MAY_CHANGE;
3610 return 0;
3611 }
3612
3613 smp->type = SMP_T_UINT;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003614 smp->data.uint = (unsigned int)SSL_SOCK_ST_TO_CA_ERROR(conn->xprt_st);
Emeric Brunf282a812012-09-21 15:27:54 +02003615 smp->flags = 0;
3616
3617 return 1;
3618}
3619
Emeric Brun2525b6b2012-10-18 15:59:43 +02003620/* integer, returns the depth of the first verify error in CA chain of client certificate chain. */
Emeric Brunf282a812012-09-21 15:27:54 +02003621static int
Emeric Brun2525b6b2012-10-18 15:59:43 +02003622smp_fetch_ssl_c_ca_err_depth(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
Willy Tarreauef38c392013-07-22 16:29:32 +02003623 const struct arg *args, struct sample *smp, const char *kw)
Emeric Brunf282a812012-09-21 15:27:54 +02003624{
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003625 struct connection *conn;
3626
3627 if (!l4)
3628 return 0;
3629
3630 conn = objt_conn(l4->si[0].end);
3631 if (!conn || conn->xprt != &ssl_sock)
Emeric Brunf282a812012-09-21 15:27:54 +02003632 return 0;
3633
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003634 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brunf282a812012-09-21 15:27:54 +02003635 smp->flags = SMP_F_MAY_CHANGE;
3636 return 0;
3637 }
3638
3639 smp->type = SMP_T_UINT;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003640 smp->data.uint = (unsigned int)SSL_SOCK_ST_TO_CAEDEPTH(conn->xprt_st);
Emeric Brunf282a812012-09-21 15:27:54 +02003641 smp->flags = 0;
3642
3643 return 1;
3644}
3645
Emeric Brun2525b6b2012-10-18 15:59:43 +02003646/* integer, returns the first verify error on client certificate */
Emeric Brunf282a812012-09-21 15:27:54 +02003647static int
Emeric Brun2525b6b2012-10-18 15:59:43 +02003648smp_fetch_ssl_c_err(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
Willy Tarreauef38c392013-07-22 16:29:32 +02003649 const struct arg *args, struct sample *smp, const char *kw)
Emeric Brunf282a812012-09-21 15:27:54 +02003650{
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003651 struct connection *conn;
3652
3653 if (!l4)
Emeric Brunf282a812012-09-21 15:27:54 +02003654 return 0;
3655
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003656 conn = objt_conn(l4->si[0].end);
3657 if (!conn || conn->xprt != &ssl_sock)
3658 return 0;
3659
3660 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brunf282a812012-09-21 15:27:54 +02003661 smp->flags = SMP_F_MAY_CHANGE;
3662 return 0;
3663 }
3664
3665 smp->type = SMP_T_UINT;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003666 smp->data.uint = (unsigned int)SSL_SOCK_ST_TO_CRTERROR(conn->xprt_st);
Emeric Brunf282a812012-09-21 15:27:54 +02003667 smp->flags = 0;
3668
3669 return 1;
3670}
3671
Emeric Brun2525b6b2012-10-18 15:59:43 +02003672/* integer, returns the verify result on client cert */
Emeric Brunbaf8ffb2012-09-21 15:27:20 +02003673static int
Emeric Brun2525b6b2012-10-18 15:59:43 +02003674smp_fetch_ssl_c_verify(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
Willy Tarreauef38c392013-07-22 16:29:32 +02003675 const struct arg *args, struct sample *smp, const char *kw)
Emeric Brunbaf8ffb2012-09-21 15:27:20 +02003676{
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003677 struct connection *conn;
3678
3679 if (!l4)
Emeric Brunbaf8ffb2012-09-21 15:27:20 +02003680 return 0;
3681
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003682 conn = objt_conn(l4->si[0].end);
3683 if (!conn || conn->xprt != &ssl_sock)
3684 return 0;
3685
3686 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brunbaf8ffb2012-09-21 15:27:20 +02003687 smp->flags = SMP_F_MAY_CHANGE;
3688 return 0;
3689 }
3690
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003691 if (!conn->xprt_ctx)
Emeric Brunbaf8ffb2012-09-21 15:27:20 +02003692 return 0;
3693
3694 smp->type = SMP_T_UINT;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003695 smp->data.uint = (unsigned int)SSL_get_verify_result(conn->xprt_ctx);
Emeric Brunbaf8ffb2012-09-21 15:27:20 +02003696 smp->flags = 0;
3697
3698 return 1;
3699}
3700
Emeric Brunfb510ea2012-10-05 12:00:26 +02003701/* parse the "ca-file" bind keyword */
3702static 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 +02003703{
3704 if (!*args[cur_arg + 1]) {
3705 if (err)
3706 memprintf(err, "'%s' : missing CAfile path", args[cur_arg]);
3707 return ERR_ALERT | ERR_FATAL;
3708 }
3709
Emeric Brunef42d922012-10-11 16:11:36 +02003710 if ((*args[cur_arg + 1] != '/') && global.ca_base)
3711 memprintf(&conf->ca_file, "%s/%s", global.ca_base, args[cur_arg + 1]);
3712 else
3713 memprintf(&conf->ca_file, "%s", args[cur_arg + 1]);
Emeric Brunc8e8d122012-10-02 18:42:10 +02003714
Emeric Brund94b3fe2012-09-20 18:23:56 +02003715 return 0;
3716}
3717
Willy Tarreau79eeafa2012-09-14 07:53:05 +02003718/* parse the "ciphers" bind keyword */
Willy Tarreau4348fad2012-09-20 16:48:07 +02003719static 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 +02003720{
3721 if (!*args[cur_arg + 1]) {
Willy Tarreaueb6cead2012-09-20 19:43:14 +02003722 memprintf(err, "'%s' : missing cipher suite", args[cur_arg]);
Willy Tarreau79eeafa2012-09-14 07:53:05 +02003723 return ERR_ALERT | ERR_FATAL;
3724 }
3725
Emeric Brun76d88952012-10-05 15:47:31 +02003726 free(conf->ciphers);
Willy Tarreau4348fad2012-09-20 16:48:07 +02003727 conf->ciphers = strdup(args[cur_arg + 1]);
Willy Tarreau79eeafa2012-09-14 07:53:05 +02003728 return 0;
3729}
3730
3731/* parse the "crt" bind keyword */
Willy Tarreau4348fad2012-09-20 16:48:07 +02003732static 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 +02003733{
Willy Tarreau38011032013-08-13 16:59:39 +02003734 char path[MAXPATHLEN];
Willy Tarreaub75d6922014-04-14 18:05:41 +02003735
Willy Tarreau79eeafa2012-09-14 07:53:05 +02003736 if (!*args[cur_arg + 1]) {
Willy Tarreaueb6cead2012-09-20 19:43:14 +02003737 memprintf(err, "'%s' : missing certificate location", args[cur_arg]);
Willy Tarreau79eeafa2012-09-14 07:53:05 +02003738 return ERR_ALERT | ERR_FATAL;
3739 }
3740
Emeric Brunc8e8d122012-10-02 18:42:10 +02003741 if ((*args[cur_arg + 1] != '/' ) && global.crt_base) {
Willy Tarreau38011032013-08-13 16:59:39 +02003742 if ((strlen(global.crt_base) + 1 + strlen(args[cur_arg + 1]) + 1) > MAXPATHLEN) {
Emeric Brunc8e8d122012-10-02 18:42:10 +02003743 memprintf(err, "'%s' : path too long", args[cur_arg]);
3744 return ERR_ALERT | ERR_FATAL;
3745 }
Willy Tarreaub75d6922014-04-14 18:05:41 +02003746 snprintf(path, sizeof(path), "%s/%s", global.crt_base, args[cur_arg + 1]);
Emeric Brunc8e8d122012-10-02 18:42:10 +02003747 if (ssl_sock_load_cert(path, conf, px, err) > 0)
3748 return ERR_ALERT | ERR_FATAL;
3749
3750 return 0;
3751 }
3752
Willy Tarreau4348fad2012-09-20 16:48:07 +02003753 if (ssl_sock_load_cert(args[cur_arg + 1], conf, px, err) > 0)
Willy Tarreau79eeafa2012-09-14 07:53:05 +02003754 return ERR_ALERT | ERR_FATAL;
Emeric Brund94b3fe2012-09-20 18:23:56 +02003755
3756 return 0;
3757}
3758
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01003759/* parse the "crt-list" bind keyword */
3760static int bind_parse_crt_list(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
3761{
3762 if (!*args[cur_arg + 1]) {
3763 memprintf(err, "'%s' : missing certificate location", args[cur_arg]);
3764 return ERR_ALERT | ERR_FATAL;
3765 }
3766
Willy Tarreauad1731d2013-04-02 17:35:58 +02003767 if (ssl_sock_load_cert_list_file(args[cur_arg + 1], conf, px, err) > 0) {
3768 memprintf(err, "'%s' : %s", args[cur_arg], *err);
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01003769 return ERR_ALERT | ERR_FATAL;
Willy Tarreauad1731d2013-04-02 17:35:58 +02003770 }
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01003771
3772 return 0;
3773}
3774
Emeric Brunfb510ea2012-10-05 12:00:26 +02003775/* parse the "crl-file" bind keyword */
3776static 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 +02003777{
Emeric Brun051cdab2012-10-02 19:25:50 +02003778#ifndef X509_V_FLAG_CRL_CHECK
3779 if (err)
3780 memprintf(err, "'%s' : library does not support CRL verify", args[cur_arg]);
3781 return ERR_ALERT | ERR_FATAL;
3782#else
Emeric Brund94b3fe2012-09-20 18:23:56 +02003783 if (!*args[cur_arg + 1]) {
3784 if (err)
3785 memprintf(err, "'%s' : missing CRLfile path", args[cur_arg]);
3786 return ERR_ALERT | ERR_FATAL;
3787 }
Emeric Brun2b58d042012-09-20 17:10:03 +02003788
Emeric Brunef42d922012-10-11 16:11:36 +02003789 if ((*args[cur_arg + 1] != '/') && global.ca_base)
3790 memprintf(&conf->crl_file, "%s/%s", global.ca_base, args[cur_arg + 1]);
3791 else
3792 memprintf(&conf->crl_file, "%s", args[cur_arg + 1]);
Emeric Brunc8e8d122012-10-02 18:42:10 +02003793
Emeric Brun2b58d042012-09-20 17:10:03 +02003794 return 0;
Emeric Brun051cdab2012-10-02 19:25:50 +02003795#endif
Emeric Brun2b58d042012-09-20 17:10:03 +02003796}
3797
3798/* parse the "ecdhe" bind keyword keywords */
3799static int bind_parse_ecdhe(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
3800{
3801#if OPENSSL_VERSION_NUMBER < 0x0090800fL
3802 if (err)
3803 memprintf(err, "'%s' : library does not support elliptic curve Diffie-Hellman (too old)", args[cur_arg]);
3804 return ERR_ALERT | ERR_FATAL;
3805#elif defined(OPENSSL_NO_ECDH)
3806 if (err)
3807 memprintf(err, "'%s' : library does not support elliptic curve Diffie-Hellman (disabled via OPENSSL_NO_ECDH)", args[cur_arg]);
3808 return ERR_ALERT | ERR_FATAL;
3809#else
3810 if (!*args[cur_arg + 1]) {
3811 if (err)
3812 memprintf(err, "'%s' : missing named curve", args[cur_arg]);
3813 return ERR_ALERT | ERR_FATAL;
3814 }
3815
3816 conf->ecdhe = strdup(args[cur_arg + 1]);
Willy Tarreau79eeafa2012-09-14 07:53:05 +02003817
3818 return 0;
Emeric Brun2b58d042012-09-20 17:10:03 +02003819#endif
Willy Tarreau79eeafa2012-09-14 07:53:05 +02003820}
3821
Emeric Brun81c00f02012-09-21 14:31:21 +02003822/* parse the "crt_ignerr" and "ca_ignerr" bind keywords */
3823static int bind_parse_ignore_err(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
3824{
3825 int code;
3826 char *p = args[cur_arg + 1];
3827 unsigned long long *ignerr = &conf->crt_ignerr;
3828
3829 if (!*p) {
3830 if (err)
3831 memprintf(err, "'%s' : missing error IDs list", args[cur_arg]);
3832 return ERR_ALERT | ERR_FATAL;
3833 }
3834
3835 if (strcmp(args[cur_arg], "ca-ignore-err") == 0)
3836 ignerr = &conf->ca_ignerr;
3837
3838 if (strcmp(p, "all") == 0) {
3839 *ignerr = ~0ULL;
3840 return 0;
3841 }
3842
3843 while (p) {
3844 code = atoi(p);
3845 if ((code <= 0) || (code > 63)) {
3846 if (err)
3847 memprintf(err, "'%s' : ID '%d' out of range (1..63) in error IDs list '%s'",
3848 args[cur_arg], code, args[cur_arg + 1]);
3849 return ERR_ALERT | ERR_FATAL;
3850 }
3851 *ignerr |= 1ULL << code;
3852 p = strchr(p, ',');
3853 if (p)
3854 p++;
3855 }
3856
Emeric Brun2cb7ae52012-10-05 14:14:21 +02003857 return 0;
3858}
3859
3860/* parse the "force-sslv3" bind keyword */
3861static int bind_parse_force_sslv3(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
3862{
3863 conf->ssl_options |= BC_SSL_O_USE_SSLV3;
3864 return 0;
3865}
3866
3867/* parse the "force-tlsv10" bind keyword */
3868static int bind_parse_force_tlsv10(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
3869{
3870 conf->ssl_options |= BC_SSL_O_USE_TLSV10;
Emeric Brun2d0c4822012-10-02 13:45:20 +02003871 return 0;
3872}
3873
Emeric Brun2cb7ae52012-10-05 14:14:21 +02003874/* parse the "force-tlsv11" bind keyword */
3875static int bind_parse_force_tlsv11(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
3876{
3877#if SSL_OP_NO_TLSv1_1
3878 conf->ssl_options |= BC_SSL_O_USE_TLSV11;
3879 return 0;
3880#else
3881 if (err)
3882 memprintf(err, "'%s' : library does not support protocol TLSv1.1", args[cur_arg]);
3883 return ERR_ALERT | ERR_FATAL;
3884#endif
3885}
3886
3887/* parse the "force-tlsv12" bind keyword */
3888static int bind_parse_force_tlsv12(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
3889{
3890#if SSL_OP_NO_TLSv1_2
3891 conf->ssl_options |= BC_SSL_O_USE_TLSV12;
3892 return 0;
3893#else
3894 if (err)
3895 memprintf(err, "'%s' : library does not support protocol TLSv1.2", args[cur_arg]);
3896 return ERR_ALERT | ERR_FATAL;
3897#endif
3898}
3899
3900
Emeric Brun2d0c4822012-10-02 13:45:20 +02003901/* parse the "no-tls-tickets" bind keyword */
3902static int bind_parse_no_tls_tickets(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
3903{
Emeric Brun89675492012-10-05 13:48:26 +02003904 conf->ssl_options |= BC_SSL_O_NO_TLS_TICKETS;
Emeric Brun81c00f02012-09-21 14:31:21 +02003905 return 0;
3906}
3907
Emeric Brun2d0c4822012-10-02 13:45:20 +02003908
Emeric Brun9b3009b2012-10-05 11:55:06 +02003909/* parse the "no-sslv3" bind keyword */
3910static 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 +02003911{
Emeric Brun89675492012-10-05 13:48:26 +02003912 conf->ssl_options |= BC_SSL_O_NO_SSLV3;
Willy Tarreau79eeafa2012-09-14 07:53:05 +02003913 return 0;
3914}
3915
Emeric Brun9b3009b2012-10-05 11:55:06 +02003916/* parse the "no-tlsv10" bind keyword */
3917static 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 +02003918{
Emeric Brun89675492012-10-05 13:48:26 +02003919 conf->ssl_options |= BC_SSL_O_NO_TLSV10;
Emeric Brunc0ff4922012-09-28 19:37:02 +02003920 return 0;
3921}
3922
Emeric Brun9b3009b2012-10-05 11:55:06 +02003923/* parse the "no-tlsv11" bind keyword */
3924static 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 +02003925{
Emeric Brun89675492012-10-05 13:48:26 +02003926 conf->ssl_options |= BC_SSL_O_NO_TLSV11;
Emeric Brunc0ff4922012-09-28 19:37:02 +02003927 return 0;
3928}
3929
Emeric Brun9b3009b2012-10-05 11:55:06 +02003930/* parse the "no-tlsv12" bind keyword */
3931static 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 +02003932{
Emeric Brun89675492012-10-05 13:48:26 +02003933 conf->ssl_options |= BC_SSL_O_NO_TLSV12;
Willy Tarreau79eeafa2012-09-14 07:53:05 +02003934 return 0;
3935}
3936
Willy Tarreau6c9a3d52012-10-18 18:57:14 +02003937/* parse the "npn" bind keyword */
3938static int bind_parse_npn(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
3939{
3940#ifdef OPENSSL_NPN_NEGOTIATED
3941 char *p1, *p2;
3942
3943 if (!*args[cur_arg + 1]) {
3944 memprintf(err, "'%s' : missing the comma-delimited NPN protocol suite", args[cur_arg]);
3945 return ERR_ALERT | ERR_FATAL;
3946 }
3947
3948 free(conf->npn_str);
3949
3950 /* the NPN string is built as a suite of (<len> <name>)* */
3951 conf->npn_len = strlen(args[cur_arg + 1]) + 1;
3952 conf->npn_str = calloc(1, conf->npn_len);
3953 memcpy(conf->npn_str + 1, args[cur_arg + 1], conf->npn_len);
3954
3955 /* replace commas with the name length */
3956 p1 = conf->npn_str;
3957 p2 = p1 + 1;
3958 while (1) {
3959 p2 = memchr(p1 + 1, ',', conf->npn_str + conf->npn_len - (p1 + 1));
3960 if (!p2)
3961 p2 = p1 + 1 + strlen(p1 + 1);
3962
3963 if (p2 - (p1 + 1) > 255) {
3964 *p2 = '\0';
3965 memprintf(err, "'%s' : NPN protocol name too long : '%s'", args[cur_arg], p1 + 1);
3966 return ERR_ALERT | ERR_FATAL;
3967 }
3968
3969 *p1 = p2 - (p1 + 1);
3970 p1 = p2;
3971
3972 if (!*p2)
3973 break;
3974
3975 *(p2++) = '\0';
3976 }
3977 return 0;
3978#else
3979 if (err)
3980 memprintf(err, "'%s' : library does not support TLS NPN extension", args[cur_arg]);
3981 return ERR_ALERT | ERR_FATAL;
3982#endif
3983}
3984
Willy Tarreauab861d32013-04-02 02:30:41 +02003985/* parse the "alpn" bind keyword */
3986static int bind_parse_alpn(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
3987{
Dirkjan Bussink48f1c4e2014-02-13 12:29:42 +01003988#ifdef TLSEXT_TYPE_application_layer_protocol_negotiation
Willy Tarreauab861d32013-04-02 02:30:41 +02003989 char *p1, *p2;
3990
3991 if (!*args[cur_arg + 1]) {
3992 memprintf(err, "'%s' : missing the comma-delimited ALPN protocol suite", args[cur_arg]);
3993 return ERR_ALERT | ERR_FATAL;
3994 }
3995
3996 free(conf->alpn_str);
3997
3998 /* the ALPN string is built as a suite of (<len> <name>)* */
3999 conf->alpn_len = strlen(args[cur_arg + 1]) + 1;
4000 conf->alpn_str = calloc(1, conf->alpn_len);
4001 memcpy(conf->alpn_str + 1, args[cur_arg + 1], conf->alpn_len);
4002
4003 /* replace commas with the name length */
4004 p1 = conf->alpn_str;
4005 p2 = p1 + 1;
4006 while (1) {
4007 p2 = memchr(p1 + 1, ',', conf->alpn_str + conf->alpn_len - (p1 + 1));
4008 if (!p2)
4009 p2 = p1 + 1 + strlen(p1 + 1);
4010
4011 if (p2 - (p1 + 1) > 255) {
4012 *p2 = '\0';
4013 memprintf(err, "'%s' : ALPN protocol name too long : '%s'", args[cur_arg], p1 + 1);
4014 return ERR_ALERT | ERR_FATAL;
4015 }
4016
4017 *p1 = p2 - (p1 + 1);
4018 p1 = p2;
4019
4020 if (!*p2)
4021 break;
4022
4023 *(p2++) = '\0';
4024 }
4025 return 0;
4026#else
4027 if (err)
4028 memprintf(err, "'%s' : library does not support TLS ALPN extension", args[cur_arg]);
4029 return ERR_ALERT | ERR_FATAL;
4030#endif
4031}
4032
Willy Tarreau79eeafa2012-09-14 07:53:05 +02004033/* parse the "ssl" bind keyword */
Willy Tarreau4348fad2012-09-20 16:48:07 +02004034static 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 +02004035{
Willy Tarreau81796be2012-09-22 19:11:47 +02004036 struct listener *l;
4037
Willy Tarreau4348fad2012-09-20 16:48:07 +02004038 conf->is_ssl = 1;
Emeric Brun76d88952012-10-05 15:47:31 +02004039
4040 if (global.listen_default_ciphers && !conf->ciphers)
4041 conf->ciphers = strdup(global.listen_default_ciphers);
4042
Willy Tarreau81796be2012-09-22 19:11:47 +02004043 list_for_each_entry(l, &conf->listeners, by_bind)
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02004044 l->xprt = &ssl_sock;
Willy Tarreau81796be2012-09-22 19:11:47 +02004045
Willy Tarreau79eeafa2012-09-14 07:53:05 +02004046 return 0;
4047}
4048
Emmanuel Hocdet65623372013-01-24 17:17:15 +01004049/* parse the "strict-sni" bind keyword */
4050static int bind_parse_strict_sni(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
4051{
4052 conf->strict_sni = 1;
4053 return 0;
4054}
4055
Emeric Brund94b3fe2012-09-20 18:23:56 +02004056/* parse the "verify" bind keyword */
4057static int bind_parse_verify(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
4058{
4059 if (!*args[cur_arg + 1]) {
4060 if (err)
4061 memprintf(err, "'%s' : missing verify method", args[cur_arg]);
4062 return ERR_ALERT | ERR_FATAL;
4063 }
4064
4065 if (strcmp(args[cur_arg + 1], "none") == 0)
Emeric Brun850efd52014-01-29 12:24:34 +01004066 conf->verify = SSL_SOCK_VERIFY_NONE;
Emeric Brund94b3fe2012-09-20 18:23:56 +02004067 else if (strcmp(args[cur_arg + 1], "optional") == 0)
Emeric Brun850efd52014-01-29 12:24:34 +01004068 conf->verify = SSL_SOCK_VERIFY_OPTIONAL;
Emeric Brund94b3fe2012-09-20 18:23:56 +02004069 else if (strcmp(args[cur_arg + 1], "required") == 0)
Emeric Brun850efd52014-01-29 12:24:34 +01004070 conf->verify = SSL_SOCK_VERIFY_REQUIRED;
Emeric Brund94b3fe2012-09-20 18:23:56 +02004071 else {
4072 if (err)
4073 memprintf(err, "'%s' : unknown verify method '%s', only 'none', 'optional', and 'required' are supported\n",
4074 args[cur_arg], args[cur_arg + 1]);
4075 return ERR_ALERT | ERR_FATAL;
4076 }
4077
4078 return 0;
4079}
4080
Willy Tarreau92faadf2012-10-10 23:04:25 +02004081/************** "server" keywords ****************/
4082
Emeric Brunef42d922012-10-11 16:11:36 +02004083/* parse the "ca-file" server keyword */
4084static int srv_parse_ca_file(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
4085{
4086 if (!*args[*cur_arg + 1]) {
4087 if (err)
4088 memprintf(err, "'%s' : missing CAfile path", args[*cur_arg]);
4089 return ERR_ALERT | ERR_FATAL;
4090 }
4091
4092 if ((*args[*cur_arg + 1] != '/') && global.ca_base)
4093 memprintf(&newsrv->ssl_ctx.ca_file, "%s/%s", global.ca_base, args[*cur_arg + 1]);
4094 else
4095 memprintf(&newsrv->ssl_ctx.ca_file, "%s", args[*cur_arg + 1]);
4096
4097 return 0;
4098}
4099
Willy Tarreau92faadf2012-10-10 23:04:25 +02004100/* parse the "check-ssl" server keyword */
4101static int srv_parse_check_ssl(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
4102{
4103 newsrv->check.use_ssl = 1;
4104 if (global.connect_default_ciphers && !newsrv->ssl_ctx.ciphers)
4105 newsrv->ssl_ctx.ciphers = strdup(global.connect_default_ciphers);
4106 return 0;
4107}
4108
4109/* parse the "ciphers" server keyword */
4110static int srv_parse_ciphers(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
4111{
4112 if (!*args[*cur_arg + 1]) {
4113 memprintf(err, "'%s' : missing cipher suite", args[*cur_arg]);
4114 return ERR_ALERT | ERR_FATAL;
4115 }
4116
4117 free(newsrv->ssl_ctx.ciphers);
4118 newsrv->ssl_ctx.ciphers = strdup(args[*cur_arg + 1]);
4119 return 0;
4120}
4121
Emeric Brunef42d922012-10-11 16:11:36 +02004122/* parse the "crl-file" server keyword */
4123static int srv_parse_crl_file(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
4124{
4125#ifndef X509_V_FLAG_CRL_CHECK
4126 if (err)
4127 memprintf(err, "'%s' : library does not support CRL verify", args[*cur_arg]);
4128 return ERR_ALERT | ERR_FATAL;
4129#else
4130 if (!*args[*cur_arg + 1]) {
4131 if (err)
4132 memprintf(err, "'%s' : missing CRLfile path", args[*cur_arg]);
4133 return ERR_ALERT | ERR_FATAL;
4134 }
4135
4136 if ((*args[*cur_arg + 1] != '/') && global.ca_base)
4137 memprintf(&newsrv->ssl_ctx.crl_file, "%s/%s", global.ca_base, args[*cur_arg + 1]);
4138 else
4139 memprintf(&newsrv->ssl_ctx.crl_file, "%s", args[*cur_arg + 1]);
4140
4141 return 0;
4142#endif
4143}
4144
Emeric Bruna7aa3092012-10-26 12:58:00 +02004145/* parse the "crt" server keyword */
4146static int srv_parse_crt(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
4147{
4148 if (!*args[*cur_arg + 1]) {
4149 if (err)
4150 memprintf(err, "'%s' : missing certificate file path", args[*cur_arg]);
4151 return ERR_ALERT | ERR_FATAL;
4152 }
4153
4154 if ((*args[*cur_arg + 1] != '/') && global.crt_base)
4155 memprintf(&newsrv->ssl_ctx.client_crt, "%s/%s", global.ca_base, args[*cur_arg + 1]);
4156 else
4157 memprintf(&newsrv->ssl_ctx.client_crt, "%s", args[*cur_arg + 1]);
4158
4159 return 0;
4160}
Emeric Brunef42d922012-10-11 16:11:36 +02004161
Willy Tarreau92faadf2012-10-10 23:04:25 +02004162/* parse the "force-sslv3" server keyword */
4163static int srv_parse_force_sslv3(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
4164{
4165 newsrv->ssl_ctx.options |= SRV_SSL_O_USE_SSLV3;
4166 return 0;
4167}
4168
4169/* parse the "force-tlsv10" server keyword */
4170static int srv_parse_force_tlsv10(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
4171{
4172 newsrv->ssl_ctx.options |= SRV_SSL_O_USE_TLSV10;
4173 return 0;
4174}
4175
4176/* parse the "force-tlsv11" server keyword */
4177static int srv_parse_force_tlsv11(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
4178{
4179#if SSL_OP_NO_TLSv1_1
4180 newsrv->ssl_ctx.options |= SRV_SSL_O_USE_TLSV11;
4181 return 0;
4182#else
4183 if (err)
4184 memprintf(err, "'%s' : library does not support protocol TLSv1.1", args[*cur_arg]);
4185 return ERR_ALERT | ERR_FATAL;
4186#endif
4187}
4188
4189/* parse the "force-tlsv12" server keyword */
4190static int srv_parse_force_tlsv12(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
4191{
4192#if SSL_OP_NO_TLSv1_2
4193 newsrv->ssl_ctx.options |= SRV_SSL_O_USE_TLSV12;
4194 return 0;
4195#else
4196 if (err)
4197 memprintf(err, "'%s' : library does not support protocol TLSv1.2", args[*cur_arg]);
4198 return ERR_ALERT | ERR_FATAL;
4199#endif
4200}
4201
4202/* parse the "no-sslv3" server keyword */
4203static int srv_parse_no_sslv3(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
4204{
4205 newsrv->ssl_ctx.options |= SRV_SSL_O_NO_SSLV3;
4206 return 0;
4207}
4208
4209/* parse the "no-tlsv10" server keyword */
4210static int srv_parse_no_tlsv10(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
4211{
4212 newsrv->ssl_ctx.options |= SRV_SSL_O_NO_TLSV10;
4213 return 0;
4214}
4215
4216/* parse the "no-tlsv11" server keyword */
4217static int srv_parse_no_tlsv11(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
4218{
4219 newsrv->ssl_ctx.options |= SRV_SSL_O_NO_TLSV11;
4220 return 0;
4221}
4222
4223/* parse the "no-tlsv12" server keyword */
4224static int srv_parse_no_tlsv12(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
4225{
4226 newsrv->ssl_ctx.options |= SRV_SSL_O_NO_TLSV12;
4227 return 0;
4228}
4229
Emeric Brunf9c5c472012-10-11 15:28:34 +02004230/* parse the "no-tls-tickets" server keyword */
4231static int srv_parse_no_tls_tickets(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
4232{
4233 newsrv->ssl_ctx.options |= SRV_SSL_O_NO_TLS_TICKETS;
4234 return 0;
4235}
David Safb76832014-05-08 23:42:08 -04004236/* parse the "send-proxy-v2-ssl" server keyword */
4237static int srv_parse_send_proxy_ssl(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
4238{
4239 newsrv->pp_opts |= SRV_PP_V2;
4240 newsrv->pp_opts |= SRV_PP_V2_SSL;
4241 return 0;
4242}
4243
4244/* parse the "send-proxy-v2-ssl-cn" server keyword */
4245static int srv_parse_send_proxy_cn(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
4246{
4247 newsrv->pp_opts |= SRV_PP_V2;
4248 newsrv->pp_opts |= SRV_PP_V2_SSL;
4249 newsrv->pp_opts |= SRV_PP_V2_SSL_CN;
4250 return 0;
4251}
Emeric Brunf9c5c472012-10-11 15:28:34 +02004252
Willy Tarreau92faadf2012-10-10 23:04:25 +02004253/* parse the "ssl" server keyword */
4254static int srv_parse_ssl(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
4255{
4256 newsrv->use_ssl = 1;
4257 if (global.connect_default_ciphers && !newsrv->ssl_ctx.ciphers)
4258 newsrv->ssl_ctx.ciphers = strdup(global.connect_default_ciphers);
4259 return 0;
4260}
4261
Emeric Brunef42d922012-10-11 16:11:36 +02004262/* parse the "verify" server keyword */
4263static int srv_parse_verify(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
4264{
4265 if (!*args[*cur_arg + 1]) {
4266 if (err)
4267 memprintf(err, "'%s' : missing verify method", args[*cur_arg]);
4268 return ERR_ALERT | ERR_FATAL;
4269 }
4270
4271 if (strcmp(args[*cur_arg + 1], "none") == 0)
Emeric Brun850efd52014-01-29 12:24:34 +01004272 newsrv->ssl_ctx.verify = SSL_SOCK_VERIFY_NONE;
Emeric Brunef42d922012-10-11 16:11:36 +02004273 else if (strcmp(args[*cur_arg + 1], "required") == 0)
Emeric Brun850efd52014-01-29 12:24:34 +01004274 newsrv->ssl_ctx.verify = SSL_SOCK_VERIFY_REQUIRED;
Emeric Brunef42d922012-10-11 16:11:36 +02004275 else {
4276 if (err)
4277 memprintf(err, "'%s' : unknown verify method '%s', only 'none' and 'required' are supported\n",
4278 args[*cur_arg], args[*cur_arg + 1]);
4279 return ERR_ALERT | ERR_FATAL;
4280 }
4281
Evan Broderbe554312013-06-27 00:05:25 -07004282 return 0;
4283}
4284
4285/* parse the "verifyhost" server keyword */
4286static int srv_parse_verifyhost(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
4287{
4288 if (!*args[*cur_arg + 1]) {
4289 if (err)
4290 memprintf(err, "'%s' : missing hostname to verify against", args[*cur_arg]);
4291 return ERR_ALERT | ERR_FATAL;
4292 }
4293
4294 newsrv->ssl_ctx.verify_host = strdup(args[*cur_arg + 1]);
4295
Emeric Brunef42d922012-10-11 16:11:36 +02004296 return 0;
4297}
4298
Willy Tarreau7875d092012-09-10 08:20:03 +02004299/* Note: must not be declared <const> as its list will be overwritten.
4300 * Please take care of keeping this list alphabetically sorted.
4301 */
Willy Tarreaudc13c112013-06-21 23:16:39 +02004302static struct sample_fetch_kw_list sample_fetch_keywords = {ILH, {
Emeric Brun645ae792014-04-30 14:21:06 +02004303 { "ssl_bc", smp_fetch_ssl_fc, 0, NULL, SMP_T_BOOL, SMP_USE_L5SRV },
4304 { "ssl_bc_alg_keysize", smp_fetch_ssl_fc_alg_keysize, 0, NULL, SMP_T_UINT, SMP_USE_L5SRV },
4305 { "ssl_bc_cipher", smp_fetch_ssl_fc_cipher, 0, NULL, SMP_T_STR, SMP_USE_L5SRV },
4306 { "ssl_bc_protocol", smp_fetch_ssl_fc_protocol, 0, NULL, SMP_T_STR, SMP_USE_L5SRV },
Emeric Brunb73a9b02014-04-30 18:49:19 +02004307 { "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 +02004308 { "ssl_bc_use_keysize", smp_fetch_ssl_fc_use_keysize, 0, NULL, SMP_T_UINT, SMP_USE_L5SRV },
4309 { "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 +01004310 { "ssl_c_ca_err", smp_fetch_ssl_c_ca_err, 0, NULL, SMP_T_UINT, SMP_USE_L5CLI },
4311 { "ssl_c_ca_err_depth", smp_fetch_ssl_c_ca_err_depth, 0, NULL, SMP_T_UINT, SMP_USE_L5CLI },
4312 { "ssl_c_err", smp_fetch_ssl_c_err, 0, NULL, SMP_T_UINT, SMP_USE_L5CLI },
Emeric Brunba841a12014-04-30 17:05:08 +02004313 { "ssl_c_i_dn", smp_fetch_ssl_x_i_dn, ARG2(0,STR,SINT), NULL, SMP_T_STR, SMP_USE_L5CLI },
4314 { "ssl_c_key_alg", smp_fetch_ssl_x_key_alg, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
4315 { "ssl_c_notafter", smp_fetch_ssl_x_notafter, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
4316 { "ssl_c_notbefore", smp_fetch_ssl_x_notbefore, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
4317 { "ssl_c_sig_alg", smp_fetch_ssl_x_sig_alg, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
4318 { "ssl_c_s_dn", smp_fetch_ssl_x_s_dn, ARG2(0,STR,SINT), NULL, SMP_T_STR, SMP_USE_L5CLI },
4319 { "ssl_c_serial", smp_fetch_ssl_x_serial, 0, NULL, SMP_T_BIN, SMP_USE_L5CLI },
4320 { "ssl_c_sha1", smp_fetch_ssl_x_sha1, 0, NULL, SMP_T_BIN, SMP_USE_L5CLI },
Willy Tarreau80aca902013-01-07 15:42:20 +01004321 { "ssl_c_used", smp_fetch_ssl_c_used, 0, NULL, SMP_T_BOOL, SMP_USE_L5CLI },
4322 { "ssl_c_verify", smp_fetch_ssl_c_verify, 0, NULL, SMP_T_UINT, SMP_USE_L5CLI },
Emeric Brunba841a12014-04-30 17:05:08 +02004323 { "ssl_c_version", smp_fetch_ssl_x_version, 0, NULL, SMP_T_UINT, SMP_USE_L5CLI },
4324 { "ssl_f_i_dn", smp_fetch_ssl_x_i_dn, ARG2(0,STR,SINT), NULL, SMP_T_STR, SMP_USE_L5CLI },
4325 { "ssl_f_key_alg", smp_fetch_ssl_x_key_alg, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
4326 { "ssl_f_notafter", smp_fetch_ssl_x_notafter, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
4327 { "ssl_f_notbefore", smp_fetch_ssl_x_notbefore, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
4328 { "ssl_f_sig_alg", smp_fetch_ssl_x_sig_alg, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
4329 { "ssl_f_s_dn", smp_fetch_ssl_x_s_dn, ARG2(0,STR,SINT), NULL, SMP_T_STR, SMP_USE_L5CLI },
4330 { "ssl_f_serial", smp_fetch_ssl_x_serial, 0, NULL, SMP_T_BIN, SMP_USE_L5CLI },
Emeric Brun55f4fa82014-04-30 17:11:25 +02004331 { "ssl_f_sha1", smp_fetch_ssl_x_sha1, 0, NULL, SMP_T_BIN, SMP_USE_L5CLI },
Emeric Brunba841a12014-04-30 17:05:08 +02004332 { "ssl_f_version", smp_fetch_ssl_x_version, 0, NULL, SMP_T_UINT, SMP_USE_L5CLI },
Willy Tarreau80aca902013-01-07 15:42:20 +01004333 { "ssl_fc", smp_fetch_ssl_fc, 0, NULL, SMP_T_BOOL, SMP_USE_L5CLI },
4334 { "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 +01004335 { "ssl_fc_cipher", smp_fetch_ssl_fc_cipher, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
Willy Tarreau80aca902013-01-07 15:42:20 +01004336 { "ssl_fc_has_crt", smp_fetch_ssl_fc_has_crt, 0, NULL, SMP_T_BOOL, SMP_USE_L5CLI },
4337 { "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 +02004338#ifdef OPENSSL_NPN_NEGOTIATED
Thierry FOURNIER7654c9f2013-12-17 00:20:33 +01004339 { "ssl_fc_npn", smp_fetch_ssl_fc_npn, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
Willy Tarreaua33c6542012-10-15 13:19:06 +02004340#endif
Dirkjan Bussink48f1c4e2014-02-13 12:29:42 +01004341#ifdef TLSEXT_TYPE_application_layer_protocol_negotiation
Thierry FOURNIER7654c9f2013-12-17 00:20:33 +01004342 { "ssl_fc_alpn", smp_fetch_ssl_fc_alpn, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
Willy Tarreauab861d32013-04-02 02:30:41 +02004343#endif
Thierry FOURNIER7654c9f2013-12-17 00:20:33 +01004344 { "ssl_fc_protocol", smp_fetch_ssl_fc_protocol, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
Emeric Brunb73a9b02014-04-30 18:49:19 +02004345 { "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 +01004346 { "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 +01004347 { "ssl_fc_session_id", smp_fetch_ssl_fc_session_id, 0, NULL, SMP_T_BIN, SMP_USE_L5CLI },
4348 { "ssl_fc_sni", smp_fetch_ssl_fc_sni, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
Willy Tarreau7875d092012-09-10 08:20:03 +02004349 { NULL, NULL, 0, 0, 0 },
4350}};
4351
4352/* Note: must not be declared <const> as its list will be overwritten.
4353 * Please take care of keeping this list alphabetically sorted.
4354 */
Willy Tarreaudc13c112013-06-21 23:16:39 +02004355static struct acl_kw_list acl_kws = {ILH, {
Thierry FOURNIERc5a4e982014-03-05 16:07:08 +01004356 { "ssl_fc_sni_end", "ssl_fc_sni", PAT_MATCH_END },
4357 { "ssl_fc_sni_reg", "ssl_fc_sni", PAT_MATCH_REG },
Willy Tarreau8ed669b2013-01-11 15:49:37 +01004358 { /* END */ },
Willy Tarreau7875d092012-09-10 08:20:03 +02004359}};
4360
Willy Tarreau79eeafa2012-09-14 07:53:05 +02004361/* Note: must not be declared <const> as its list will be overwritten.
4362 * Please take care of keeping this list alphabetically sorted, doing so helps
4363 * all code contributors.
4364 * Optional keywords are also declared with a NULL ->parse() function so that
4365 * the config parser can report an appropriate error when a known keyword was
4366 * not enabled.
4367 */
Willy Tarreau51fb7652012-09-18 18:24:39 +02004368static struct bind_kw_list bind_kws = { "SSL", { }, {
Willy Tarreauab861d32013-04-02 02:30:41 +02004369 { "alpn", bind_parse_alpn, 1 }, /* set ALPN supported protocols */
Emeric Brunfb510ea2012-10-05 12:00:26 +02004370 { "ca-file", bind_parse_ca_file, 1 }, /* set CAfile to process verify on client cert */
Emeric Brun2d0c4822012-10-02 13:45:20 +02004371 { "ca-ignore-err", bind_parse_ignore_err, 1 }, /* set error IDs to ignore on verify depth > 0 */
4372 { "ciphers", bind_parse_ciphers, 1 }, /* set SSL cipher suite */
Emeric Brunfb510ea2012-10-05 12:00:26 +02004373 { "crl-file", bind_parse_crl_file, 1 }, /* set certificat revocation list file use on client cert verify */
Emeric Brun2d0c4822012-10-02 13:45:20 +02004374 { "crt", bind_parse_crt, 1 }, /* load SSL certificates from this location */
4375 { "crt-ignore-err", bind_parse_ignore_err, 1 }, /* set error IDs to ingore on verify depth == 0 */
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01004376 { "crt-list", bind_parse_crt_list, 1 }, /* load a list of crt from this location */
Emeric Brun2d0c4822012-10-02 13:45:20 +02004377 { "ecdhe", bind_parse_ecdhe, 1 }, /* defines named curve for elliptic curve Diffie-Hellman */
Emeric Brun2cb7ae52012-10-05 14:14:21 +02004378 { "force-sslv3", bind_parse_force_sslv3, 0 }, /* force SSLv3 */
4379 { "force-tlsv10", bind_parse_force_tlsv10, 0 }, /* force TLSv10 */
4380 { "force-tlsv11", bind_parse_force_tlsv11, 0 }, /* force TLSv11 */
4381 { "force-tlsv12", bind_parse_force_tlsv12, 0 }, /* force TLSv12 */
Emeric Brun9b3009b2012-10-05 11:55:06 +02004382 { "no-sslv3", bind_parse_no_sslv3, 0 }, /* disable SSLv3 */
4383 { "no-tlsv10", bind_parse_no_tlsv10, 0 }, /* disable TLSv10 */
4384 { "no-tlsv11", bind_parse_no_tlsv11, 0 }, /* disable TLSv11 */
4385 { "no-tlsv12", bind_parse_no_tlsv12, 0 }, /* disable TLSv12 */
Emeric Brun2d0c4822012-10-02 13:45:20 +02004386 { "no-tls-tickets", bind_parse_no_tls_tickets, 0 }, /* disable session resumption tickets */
Emeric Brun2d0c4822012-10-02 13:45:20 +02004387 { "ssl", bind_parse_ssl, 0 }, /* enable SSL processing */
Emmanuel Hocdet65623372013-01-24 17:17:15 +01004388 { "strict-sni", bind_parse_strict_sni, 0 }, /* refuse negotiation if sni doesn't match a certificate */
Emeric Brun2d0c4822012-10-02 13:45:20 +02004389 { "verify", bind_parse_verify, 1 }, /* set SSL verify method */
Willy Tarreau6c9a3d52012-10-18 18:57:14 +02004390 { "npn", bind_parse_npn, 1 }, /* set NPN supported protocols */
Willy Tarreau79eeafa2012-09-14 07:53:05 +02004391 { NULL, NULL, 0 },
4392}};
Emeric Brun46591952012-05-18 15:47:34 +02004393
Willy Tarreau92faadf2012-10-10 23:04:25 +02004394/* Note: must not be declared <const> as its list will be overwritten.
4395 * Please take care of keeping this list alphabetically sorted, doing so helps
4396 * all code contributors.
4397 * Optional keywords are also declared with a NULL ->parse() function so that
4398 * the config parser can report an appropriate error when a known keyword was
4399 * not enabled.
4400 */
4401static struct srv_kw_list srv_kws = { "SSL", { }, {
Emeric Brunef42d922012-10-11 16:11:36 +02004402 { "ca-file", srv_parse_ca_file, 1, 0 }, /* set CAfile to process verify server cert */
Emeric Brunecc91fe2012-10-11 15:05:10 +02004403 { "check-ssl", srv_parse_check_ssl, 0, 0 }, /* enable SSL for health checks */
4404 { "ciphers", srv_parse_ciphers, 1, 0 }, /* select the cipher suite */
Emeric Brunef42d922012-10-11 16:11:36 +02004405 { "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 +02004406 { "crt", srv_parse_crt, 1, 0 }, /* set client certificate */
Emeric Brunecc91fe2012-10-11 15:05:10 +02004407 { "force-sslv3", srv_parse_force_sslv3, 0, 0 }, /* force SSLv3 */
4408 { "force-tlsv10", srv_parse_force_tlsv10, 0, 0 }, /* force TLSv10 */
4409 { "force-tlsv11", srv_parse_force_tlsv11, 0, 0 }, /* force TLSv11 */
4410 { "force-tlsv12", srv_parse_force_tlsv12, 0, 0 }, /* force TLSv12 */
4411 { "no-sslv3", srv_parse_no_sslv3, 0, 0 }, /* disable SSLv3 */
4412 { "no-tlsv10", srv_parse_no_tlsv10, 0, 0 }, /* disable TLSv10 */
4413 { "no-tlsv11", srv_parse_no_tlsv11, 0, 0 }, /* disable TLSv11 */
4414 { "no-tlsv12", srv_parse_no_tlsv12, 0, 0 }, /* disable TLSv12 */
Emeric Brunf9c5c472012-10-11 15:28:34 +02004415 { "no-tls-tickets", srv_parse_no_tls_tickets, 0, 0 }, /* disable session resumption tickets */
David Safb76832014-05-08 23:42:08 -04004416 { "send-proxy-v2-ssl", srv_parse_send_proxy_ssl, 0, 0 }, /* send PROXY protocol header v2 with SSL info */
4417 { "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 +02004418 { "ssl", srv_parse_ssl, 0, 0 }, /* enable SSL processing */
Emeric Brunef42d922012-10-11 16:11:36 +02004419 { "verify", srv_parse_verify, 1, 0 }, /* set SSL verify method */
Evan Broderbe554312013-06-27 00:05:25 -07004420 { "verifyhost", srv_parse_verifyhost, 1, 0 }, /* require that SSL cert verifies for hostname */
Willy Tarreau92faadf2012-10-10 23:04:25 +02004421 { NULL, NULL, 0, 0 },
4422}};
4423
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02004424/* transport-layer operations for SSL sockets */
4425struct xprt_ops ssl_sock = {
Emeric Brun46591952012-05-18 15:47:34 +02004426 .snd_buf = ssl_sock_from_buf,
4427 .rcv_buf = ssl_sock_to_buf,
4428 .rcv_pipe = NULL,
4429 .snd_pipe = NULL,
4430 .shutr = NULL,
4431 .shutw = ssl_sock_shutw,
4432 .close = ssl_sock_close,
4433 .init = ssl_sock_init,
4434};
4435
4436__attribute__((constructor))
Willy Tarreau92faadf2012-10-10 23:04:25 +02004437static void __ssl_sock_init(void)
4438{
Emeric Brun46591952012-05-18 15:47:34 +02004439 STACK_OF(SSL_COMP)* cm;
4440
Willy Tarreau610f04b2014-02-13 11:36:41 +01004441#ifdef LISTEN_DEFAULT_CIPHERS
4442 global.listen_default_ciphers = LISTEN_DEFAULT_CIPHERS;
4443#endif
4444#ifdef CONNECT_DEFAULT_CIPHERS
4445 global.connect_default_ciphers = CONNECT_DEFAULT_CIPHERS;
4446#endif
4447 if (global.listen_default_ciphers)
4448 global.listen_default_ciphers = strdup(global.listen_default_ciphers);
4449 if (global.connect_default_ciphers)
4450 global.connect_default_ciphers = strdup(global.connect_default_ciphers);
4451
Emeric Brun46591952012-05-18 15:47:34 +02004452 SSL_library_init();
4453 cm = SSL_COMP_get_compression_methods();
4454 sk_SSL_COMP_zero(cm);
Willy Tarreau7875d092012-09-10 08:20:03 +02004455 sample_register_fetches(&sample_fetch_keywords);
4456 acl_register_keywords(&acl_kws);
Willy Tarreau79eeafa2012-09-14 07:53:05 +02004457 bind_register_keywords(&bind_kws);
Willy Tarreau92faadf2012-10-10 23:04:25 +02004458 srv_register_keywords(&srv_kws);
Emeric Brun46591952012-05-18 15:47:34 +02004459}
4460
4461/*
4462 * Local variables:
4463 * c-indent-level: 8
4464 * c-basic-offset: 8
4465 * End:
4466 */