blob: 77c44904de04995fec29f9f22827095d23c739da [file] [log] [blame]
Emeric Brun46591952012-05-18 15:47:34 +02001/*
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02002 * SSL/TLS transport layer over SOCK_STREAM sockets
Emeric Brun46591952012-05-18 15:47:34 +02003 *
4 * Copyright (C) 2012 EXCELIANCE, Emeric Brun <ebrun@exceliance.fr>
5 *
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public License
8 * as published by the Free Software Foundation; either version
9 * 2 of the License, or (at your option) any later version.
10 *
Willy Tarreau69845df2012-09-10 09:43:09 +020011 * Acknowledgement:
12 * We'd like to specially thank the Stud project authors for a very clean
13 * and well documented code which helped us understand how the OpenSSL API
14 * ought to be used in non-blocking mode. This is one difficult part which
15 * is not easy to get from the OpenSSL doc, and reading the Stud code made
16 * it much more obvious than the examples in the OpenSSL package. Keep up
17 * the good works, guys !
18 *
19 * Stud is an extremely efficient and scalable SSL/TLS proxy which combines
20 * particularly well with haproxy. For more info about this project, visit :
21 * https://github.com/bumptech/stud
22 *
Emeric Brun46591952012-05-18 15:47:34 +020023 */
24
25#define _GNU_SOURCE
Emeric Brunfc0421f2012-09-07 17:30:07 +020026#include <ctype.h>
27#include <dirent.h>
Emeric Brun46591952012-05-18 15:47:34 +020028#include <errno.h>
29#include <fcntl.h>
30#include <stdio.h>
31#include <stdlib.h>
Emeric Brunfc0421f2012-09-07 17:30:07 +020032#include <string.h>
33#include <unistd.h>
Emeric Brun46591952012-05-18 15:47:34 +020034
35#include <sys/socket.h>
36#include <sys/stat.h>
37#include <sys/types.h>
38
39#include <netinet/tcp.h>
40
41#include <openssl/ssl.h>
Emeric Brunfc0421f2012-09-07 17:30:07 +020042#include <openssl/x509.h>
43#include <openssl/x509v3.h>
44#include <openssl/x509.h>
45#include <openssl/err.h>
Thierry Fournier383085f2013-01-24 14:15:43 +010046#include <openssl/rand.h>
Lukas Tribuse4e30f72014-12-09 16:32:51 +010047#if (defined SSL_CTRL_SET_TLSEXT_STATUS_REQ_CB && !defined OPENSSL_NO_OCSP)
Emeric Brun4147b2e2014-06-16 18:36:30 +020048#include <openssl/ocsp.h>
49#endif
Emeric Brun46591952012-05-18 15:47:34 +020050
51#include <common/buffer.h>
52#include <common/compat.h>
53#include <common/config.h>
54#include <common/debug.h>
Willy Tarreau79eeafa2012-09-14 07:53:05 +020055#include <common/errors.h>
Emeric Brun46591952012-05-18 15:47:34 +020056#include <common/standard.h>
57#include <common/ticks.h>
58#include <common/time.h>
Emeric Brun2c86cbf2014-10-30 15:56:50 +010059#include <common/cfgparse.h>
Nenad Merdanovic05552d42015-02-27 19:56:49 +010060#include <common/base64.h>
Emeric Brun46591952012-05-18 15:47:34 +020061
Emeric Brunfc0421f2012-09-07 17:30:07 +020062#include <ebsttree.h>
63
64#include <types/global.h>
65#include <types/ssl_sock.h>
66
Willy Tarreau7875d092012-09-10 08:20:03 +020067#include <proto/acl.h>
68#include <proto/arg.h>
Emeric Brun46591952012-05-18 15:47:34 +020069#include <proto/connection.h>
70#include <proto/fd.h>
71#include <proto/freq_ctr.h>
72#include <proto/frontend.h>
Willy Tarreau79eeafa2012-09-14 07:53:05 +020073#include <proto/listener.h>
Thierry FOURNIERed66c292013-11-28 11:05:19 +010074#include <proto/pattern.h>
Willy Tarreau92faadf2012-10-10 23:04:25 +020075#include <proto/server.h>
Emeric Brun46591952012-05-18 15:47:34 +020076#include <proto/log.h>
Emeric Brun94324a42012-10-11 14:00:19 +020077#include <proto/proxy.h>
Emeric Brunfc0421f2012-09-07 17:30:07 +020078#include <proto/shctx.h>
Emeric Brun46591952012-05-18 15:47:34 +020079#include <proto/ssl_sock.h>
80#include <proto/task.h>
81
Willy Tarreau518cedd2014-02-17 15:43:01 +010082/* Warning, these are bits, not integers! */
Emeric Brune64aef12012-09-21 13:15:06 +020083#define SSL_SOCK_ST_FL_VERIFY_DONE 0x00000001
Emeric Brund8b2bb52014-01-28 15:43:53 +010084#define SSL_SOCK_ST_FL_16K_WBFSIZE 0x00000002
Willy Tarreau518cedd2014-02-17 15:43:01 +010085#define SSL_SOCK_SEND_UNLIMITED 0x00000004
Emeric Brun29f037d2014-04-25 19:05:36 +020086#define SSL_SOCK_RECV_HEARTBEAT 0x00000008
87
Emeric Brunf282a812012-09-21 15:27:54 +020088/* bits 0xFFFF0000 are reserved to store verify errors */
89
90/* Verify errors macros */
91#define SSL_SOCK_CA_ERROR_TO_ST(e) (((e > 63) ? 63 : e) << (16))
92#define SSL_SOCK_CAEDEPTH_TO_ST(d) (((d > 15) ? 15 : d) << (6+16))
93#define SSL_SOCK_CRTERROR_TO_ST(e) (((e > 63) ? 63 : e) << (4+6+16))
94
95#define SSL_SOCK_ST_TO_CA_ERROR(s) ((s >> (16)) & 63)
96#define SSL_SOCK_ST_TO_CAEDEPTH(s) ((s >> (6+16)) & 15)
97#define SSL_SOCK_ST_TO_CRTERROR(s) ((s >> (4+6+16)) & 63)
Emeric Brune64aef12012-09-21 13:15:06 +020098
Nenad Merdanovic05552d42015-02-27 19:56:49 +010099/* Supported hash function for TLS tickets */
100#ifdef OPENSSL_NO_SHA256
101#define HASH_FUNCT EVP_sha1
102#else
103#define HASH_FUNCT EVP_sha256
104#endif /* OPENSSL_NO_SHA256 */
105
Emeric Brun850efd52014-01-29 12:24:34 +0100106/* server and bind verify method, it uses a global value as default */
107enum {
108 SSL_SOCK_VERIFY_DEFAULT = 0,
109 SSL_SOCK_VERIFY_REQUIRED = 1,
110 SSL_SOCK_VERIFY_OPTIONAL = 2,
111 SSL_SOCK_VERIFY_NONE = 3,
112};
113
Willy Tarreau71b734c2014-01-28 15:19:44 +0100114int sslconns = 0;
115int totalsslconns = 0;
Emeric Brune1f38db2012-09-03 20:36:47 +0200116
Remi Gacogne8de54152014-07-15 11:36:40 +0200117#ifndef OPENSSL_NO_DH
118static DH *local_dh_1024 = NULL;
119static DH *local_dh_2048 = NULL;
120static DH *local_dh_4096 = NULL;
121static DH *local_dh_8192 = NULL;
122#endif /* OPENSSL_NO_DH */
123
Lukas Tribuse4e30f72014-12-09 16:32:51 +0100124#if (defined SSL_CTRL_SET_TLSEXT_STATUS_REQ_CB && !defined OPENSSL_NO_OCSP)
Emeric Brun4147b2e2014-06-16 18:36:30 +0200125struct certificate_ocsp {
126 struct ebmb_node key;
127 unsigned char key_data[OCSP_MAX_CERTID_ASN1_LENGTH];
128 struct chunk response;
Emeric Brun4f3c87a2014-06-20 15:46:13 +0200129 long expire;
Emeric Brun4147b2e2014-06-16 18:36:30 +0200130};
131
Emeric Brun4f3c87a2014-06-20 15:46:13 +0200132/*
133 * This function returns the number of seconds elapsed
134 * since the Epoch, 1970-01-01 00:00:00 +0000 (UTC) and the
135 * date presented un ASN1_GENERALIZEDTIME.
136 *
137 * In parsing error case, it returns -1.
138 */
139static long asn1_generalizedtime_to_epoch(ASN1_GENERALIZEDTIME *d)
140{
141 long epoch;
142 char *p, *end;
143 const unsigned short month_offset[12] = {
144 0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334
145 };
146 int year, month;
147
148 if (!d || (d->type != V_ASN1_GENERALIZEDTIME)) return -1;
149
150 p = (char *)d->data;
151 end = p + d->length;
152
153 if (end - p < 4) return -1;
154 year = 1000 * (p[0] - '0') + 100 * (p[1] - '0') + 10 * (p[2] - '0') + p[3] - '0';
155 p += 4;
156 if (end - p < 2) return -1;
157 month = 10 * (p[0] - '0') + p[1] - '0';
158 if (month < 1 || month > 12) return -1;
159 /* Compute the number of seconds since 1 jan 1970 and the beginning of current month
160 We consider leap years and the current month (<marsh or not) */
161 epoch = ( ((year - 1970) * 365)
162 + ((year - (month < 3)) / 4 - (year - (month < 3)) / 100 + (year - (month < 3)) / 400)
163 - ((1970 - 1) / 4 - (1970 - 1) / 100 + (1970 - 1) / 400)
164 + month_offset[month-1]
165 ) * 24 * 60 * 60;
166 p += 2;
167 if (end - p < 2) return -1;
168 /* Add the number of seconds of completed days of current month */
169 epoch += (10 * (p[0] - '0') + p[1] - '0' - 1) * 24 * 60 * 60;
170 p += 2;
171 if (end - p < 2) return -1;
172 /* Add the completed hours of the current day */
173 epoch += (10 * (p[0] - '0') + p[1] - '0') * 60 * 60;
174 p += 2;
175 if (end - p < 2) return -1;
176 /* Add the completed minutes of the current hour */
177 epoch += (10 * (p[0] - '0') + p[1] - '0') * 60;
178 p += 2;
179 if (p == end) return -1;
180 /* Test if there is available seconds */
181 if (p[0] < '0' || p[0] > '9')
182 goto nosec;
183 if (end - p < 2) return -1;
184 /* Add the seconds of the current minute */
185 epoch += 10 * (p[0] - '0') + p[1] - '0';
186 p += 2;
187 if (p == end) return -1;
188 /* Ignore seconds float part if present */
189 if (p[0] == '.') {
190 do {
191 if (++p == end) return -1;
192 } while (p[0] >= '0' && p[0] <= '9');
193 }
194
195nosec:
196 if (p[0] == 'Z') {
197 if (end - p != 1) return -1;
198 return epoch;
199 }
200 else if (p[0] == '+') {
201 if (end - p != 5) return -1;
202 /* Apply timezone offset */
203 return epoch - ((10 * (p[1] - '0') + p[2] - '0') * 60 + (10 * (p[3] - '0') + p[4] - '0')) * 60;
204 }
205 else if (p[0] == '-') {
206 if (end - p != 5) return -1;
207 /* Apply timezone offset */
208 return epoch + ((10 * (p[1] - '0') + p[2] - '0') * 60 + (10 * (p[3] - '0') + p[4] - '0')) * 60;
209 }
210
211 return -1;
212}
213
Emeric Brun1d3865b2014-06-20 15:37:32 +0200214static struct eb_root cert_ocsp_tree = EB_ROOT_UNIQUE;
Emeric Brun4147b2e2014-06-16 18:36:30 +0200215
216/* This function starts to check if the OCSP response (in DER format) contained
217 * in chunk 'ocsp_response' is valid (else exits on error).
218 * If 'cid' is not NULL, it will be compared to the OCSP certificate ID
219 * contained in the OCSP Response and exits on error if no match.
220 * If it's a valid OCSP Response:
221 * If 'ocsp' is not NULL, the chunk is copied in the OCSP response's container
222 * pointed by 'ocsp'.
223 * If 'ocsp' is NULL, the function looks up into the OCSP response's
224 * containers tree (using as index the ASN1 form of the OCSP Certificate ID extracted
225 * from the response) and exits on error if not found. Finally, If an OCSP response is
226 * already present in the container, it will be overwritten.
227 *
228 * Note: OCSP response containing more than one OCSP Single response is not
229 * considered valid.
230 *
231 * Returns 0 on success, 1 in error case.
232 */
233static int ssl_sock_load_ocsp_response(struct chunk *ocsp_response, struct certificate_ocsp *ocsp, OCSP_CERTID *cid, char **err)
234{
235 OCSP_RESPONSE *resp;
236 OCSP_BASICRESP *bs = NULL;
237 OCSP_SINGLERESP *sr;
238 unsigned char *p = (unsigned char *)ocsp_response->str;
239 int rc , count_sr;
Emeric Brun13a6b482014-06-20 15:44:34 +0200240 ASN1_GENERALIZEDTIME *revtime, *thisupd, *nextupd = NULL;
Emeric Brun4147b2e2014-06-16 18:36:30 +0200241 int reason;
242 int ret = 1;
243
244 resp = d2i_OCSP_RESPONSE(NULL, (const unsigned char **)&p, ocsp_response->len);
245 if (!resp) {
246 memprintf(err, "Unable to parse OCSP response");
247 goto out;
248 }
249
250 rc = OCSP_response_status(resp);
251 if (rc != OCSP_RESPONSE_STATUS_SUCCESSFUL) {
252 memprintf(err, "OCSP response status not successful");
253 goto out;
254 }
255
256 bs = OCSP_response_get1_basic(resp);
257 if (!bs) {
258 memprintf(err, "Failed to get basic response from OCSP Response");
259 goto out;
260 }
261
262 count_sr = OCSP_resp_count(bs);
263 if (count_sr > 1) {
264 memprintf(err, "OCSP response ignored because contains multiple single responses (%d)", count_sr);
265 goto out;
266 }
267
268 sr = OCSP_resp_get0(bs, 0);
269 if (!sr) {
270 memprintf(err, "Failed to get OCSP single response");
271 goto out;
272 }
273
274 rc = OCSP_single_get0_status(sr, &reason, &revtime, &thisupd, &nextupd);
275 if (rc != V_OCSP_CERTSTATUS_GOOD) {
276 memprintf(err, "OCSP single response: certificate status not good");
277 goto out;
278 }
279
Emeric Brun13a6b482014-06-20 15:44:34 +0200280 if (!nextupd) {
281 memprintf(err, "OCSP single response: missing nextupdate");
282 goto out;
283 }
284
Emeric Brunc8b27b62014-06-19 14:16:17 +0200285 rc = OCSP_check_validity(thisupd, nextupd, OCSP_MAX_RESPONSE_TIME_SKEW, -1);
Emeric Brun4147b2e2014-06-16 18:36:30 +0200286 if (!rc) {
287 memprintf(err, "OCSP single response: no longer valid.");
288 goto out;
289 }
290
291 if (cid) {
292 if (OCSP_id_cmp(sr->certId, cid)) {
293 memprintf(err, "OCSP single response: Certificate ID does not match certificate and issuer");
294 goto out;
295 }
296 }
297
298 if (!ocsp) {
299 unsigned char key[OCSP_MAX_CERTID_ASN1_LENGTH];
300 unsigned char *p;
301
302 rc = i2d_OCSP_CERTID(sr->certId, NULL);
303 if (!rc) {
304 memprintf(err, "OCSP single response: Unable to encode Certificate ID");
305 goto out;
306 }
307
308 if (rc > OCSP_MAX_CERTID_ASN1_LENGTH) {
309 memprintf(err, "OCSP single response: Certificate ID too long");
310 goto out;
311 }
312
313 p = key;
314 memset(key, 0, OCSP_MAX_CERTID_ASN1_LENGTH);
315 i2d_OCSP_CERTID(sr->certId, &p);
316 ocsp = (struct certificate_ocsp *)ebmb_lookup(&cert_ocsp_tree, key, OCSP_MAX_CERTID_ASN1_LENGTH);
317 if (!ocsp) {
318 memprintf(err, "OCSP single response: Certificate ID does not match any certificate or issuer");
319 goto out;
320 }
321 }
322
323 /* According to comments on "chunk_dup", the
324 previous chunk buffer will be freed */
325 if (!chunk_dup(&ocsp->response, ocsp_response)) {
326 memprintf(err, "OCSP response: Memory allocation error");
327 goto out;
328 }
329
Emeric Brun4f3c87a2014-06-20 15:46:13 +0200330 ocsp->expire = asn1_generalizedtime_to_epoch(nextupd) - OCSP_MAX_RESPONSE_TIME_SKEW;
331
Emeric Brun4147b2e2014-06-16 18:36:30 +0200332 ret = 0;
333out:
334 if (bs)
335 OCSP_BASICRESP_free(bs);
336
337 if (resp)
338 OCSP_RESPONSE_free(resp);
339
340 return ret;
341}
342/*
343 * External function use to update the OCSP response in the OCSP response's
344 * containers tree. The chunk 'ocsp_response' must contain the OCSP response
345 * to update in DER format.
346 *
347 * Returns 0 on success, 1 in error case.
348 */
349int ssl_sock_update_ocsp_response(struct chunk *ocsp_response, char **err)
350{
351 return ssl_sock_load_ocsp_response(ocsp_response, NULL, NULL, err);
352}
353
354/*
355 * This function load the OCSP Resonse in DER format contained in file at
356 * path 'ocsp_path' and call 'ssl_sock_load_ocsp_response'
357 *
358 * Returns 0 on success, 1 in error case.
359 */
360static int ssl_sock_load_ocsp_response_from_file(const char *ocsp_path, struct certificate_ocsp *ocsp, OCSP_CERTID *cid, char **err)
361{
362 int fd = -1;
363 int r = 0;
364 int ret = 1;
365
366 fd = open(ocsp_path, O_RDONLY);
367 if (fd == -1) {
368 memprintf(err, "Error opening OCSP response file");
369 goto end;
370 }
371
372 trash.len = 0;
373 while (trash.len < trash.size) {
374 r = read(fd, trash.str + trash.len, trash.size - trash.len);
375 if (r < 0) {
376 if (errno == EINTR)
377 continue;
378
379 memprintf(err, "Error reading OCSP response from file");
380 goto end;
381 }
382 else if (r == 0) {
383 break;
384 }
385 trash.len += r;
386 }
387
388 close(fd);
389 fd = -1;
390
391 ret = ssl_sock_load_ocsp_response(&trash, ocsp, cid, err);
392end:
393 if (fd != -1)
394 close(fd);
395
396 return ret;
397}
398
Nenad Merdanovic05552d42015-02-27 19:56:49 +0100399#if (defined SSL_CTRL_SET_TLSEXT_TICKET_KEY_CB && TLS_TICKETS_NO > 0)
400static int ssl_tlsext_ticket_key_cb(SSL *s, unsigned char key_name[16], unsigned char *iv, EVP_CIPHER_CTX *ectx, HMAC_CTX *hctx, int enc)
401{
402 struct tls_sess_key *keys;
403 struct connection *conn;
404 int head;
405 int i;
406
407 conn = (struct connection *)SSL_get_app_data(s);
408 keys = objt_listener(conn->target)->bind_conf->tls_ticket_keys;
409 head = objt_listener(conn->target)->bind_conf->tls_ticket_enc_index;
410
411 if (enc) {
412 memcpy(key_name, keys[head].name, 16);
413
414 if(!RAND_pseudo_bytes(iv, EVP_MAX_IV_LENGTH))
415 return -1;
416
417 if(!EVP_EncryptInit_ex(ectx, EVP_aes_128_cbc(), NULL, keys[head].aes_key, iv))
418 return -1;
419
420 HMAC_Init_ex(hctx, keys[head].hmac_key, 16, HASH_FUNCT(), NULL);
421
422 return 1;
423 } else {
424 for (i = 0; i < TLS_TICKETS_NO; i++) {
425 if (!memcmp(key_name, keys[(head + i) % TLS_TICKETS_NO].name, 16))
426 goto found;
427 }
428 return 0;
429
430 found:
431 HMAC_Init_ex(hctx, keys[(head + i) % TLS_TICKETS_NO].hmac_key, 16, HASH_FUNCT(), NULL);
432 if(!EVP_DecryptInit_ex(ectx, EVP_aes_128_cbc(), NULL, keys[(head + i) % TLS_TICKETS_NO].aes_key, iv))
433 return -1;
434 /* 2 for key renewal, 1 if current key is still valid */
435 return i ? 2 : 1;
436 }
437}
438#endif /* SSL_CTRL_SET_TLSEXT_TICKET_KEY_CB */
439
Emeric Brun4147b2e2014-06-16 18:36:30 +0200440/*
441 * Callback used to set OCSP status extension content in server hello.
442 */
443int ssl_sock_ocsp_stapling_cbk(SSL *ssl, void *arg)
444{
445 struct certificate_ocsp *ocsp = (struct certificate_ocsp *)arg;
446 char* ssl_buf;
447
448 if (!ocsp ||
449 !ocsp->response.str ||
Emeric Brun4f3c87a2014-06-20 15:46:13 +0200450 !ocsp->response.len ||
451 (ocsp->expire < now.tv_sec))
Emeric Brun4147b2e2014-06-16 18:36:30 +0200452 return SSL_TLSEXT_ERR_NOACK;
453
454 ssl_buf = OPENSSL_malloc(ocsp->response.len);
455 if (!ssl_buf)
456 return SSL_TLSEXT_ERR_NOACK;
457
458 memcpy(ssl_buf, ocsp->response.str, ocsp->response.len);
459 SSL_set_tlsext_status_ocsp_resp(ssl, ssl_buf, ocsp->response.len);
460
461 return SSL_TLSEXT_ERR_OK;
462}
463
464/*
465 * This function enables the handling of OCSP status extension on 'ctx' if a
466 * file name 'cert_path' suffixed using ".ocsp" is present.
467 * To enable OCSP status extension, the issuer's certificate is mandatory.
468 * It should be present in the certificate's extra chain builded from file
469 * 'cert_path'. If not found, the issuer certificate is loaded from a file
470 * named 'cert_path' suffixed using '.issuer'.
471 *
472 * In addition, ".ocsp" file content is loaded as a DER format of an OCSP
473 * response. If file is empty or content is not a valid OCSP response,
474 * OCSP status extension is enabled but OCSP response is ignored (a warning
475 * is displayed).
476 *
477 * Returns 1 if no ".ocsp" file found, 0 if OCSP status extension is
478 * succesfully enabled, or -1 in other error case.
479 */
480static int ssl_sock_load_ocsp(SSL_CTX *ctx, const char *cert_path)
481{
482
483 BIO *in = NULL;
484 X509 *x, *xi = NULL, *issuer = NULL;
485 STACK_OF(X509) *chain = NULL;
486 OCSP_CERTID *cid = NULL;
487 SSL *ssl;
488 char ocsp_path[MAXPATHLEN+1];
489 int i, ret = -1;
490 struct stat st;
491 struct certificate_ocsp *ocsp = NULL, *iocsp;
492 char *warn = NULL;
493 unsigned char *p;
494
495 snprintf(ocsp_path, MAXPATHLEN+1, "%s.ocsp", cert_path);
496
497 if (stat(ocsp_path, &st))
498 return 1;
499
500 ssl = SSL_new(ctx);
501 if (!ssl)
502 goto out;
503
504 x = SSL_get_certificate(ssl);
505 if (!x)
506 goto out;
507
508 /* Try to lookup for issuer in certificate extra chain */
509#ifdef SSL_CTRL_GET_EXTRA_CHAIN_CERTS
510 SSL_CTX_get_extra_chain_certs(ctx, &chain);
511#else
512 chain = ctx->extra_certs;
513#endif
514 for (i = 0; i < sk_X509_num(chain); i++) {
515 issuer = sk_X509_value(chain, i);
516 if (X509_check_issued(issuer, x) == X509_V_OK)
517 break;
518 else
519 issuer = NULL;
520 }
521
522 /* If not found try to load issuer from a suffixed file */
523 if (!issuer) {
524 char issuer_path[MAXPATHLEN+1];
525
526 in = BIO_new(BIO_s_file());
527 if (!in)
528 goto out;
529
530 snprintf(issuer_path, MAXPATHLEN+1, "%s.issuer", cert_path);
531 if (BIO_read_filename(in, issuer_path) <= 0)
532 goto out;
533
534 xi = PEM_read_bio_X509_AUX(in, NULL, ctx->default_passwd_callback, ctx->default_passwd_callback_userdata);
535 if (!xi)
536 goto out;
537
538 if (X509_check_issued(xi, x) != X509_V_OK)
539 goto out;
540
541 issuer = xi;
542 }
543
544 cid = OCSP_cert_to_id(0, x, issuer);
545 if (!cid)
546 goto out;
547
548 i = i2d_OCSP_CERTID(cid, NULL);
549 if (!i || (i > OCSP_MAX_CERTID_ASN1_LENGTH))
550 goto out;
551
552 ocsp = calloc(1, sizeof(struct certificate_ocsp));
553 if (!ocsp)
554 goto out;
555
556 p = ocsp->key_data;
557 i2d_OCSP_CERTID(cid, &p);
558
559 iocsp = (struct certificate_ocsp *)ebmb_insert(&cert_ocsp_tree, &ocsp->key, OCSP_MAX_CERTID_ASN1_LENGTH);
560 if (iocsp == ocsp)
561 ocsp = NULL;
562
563 SSL_CTX_set_tlsext_status_cb(ctx, ssl_sock_ocsp_stapling_cbk);
564 SSL_CTX_set_tlsext_status_arg(ctx, iocsp);
565
566 ret = 0;
567
568 warn = NULL;
569 if (ssl_sock_load_ocsp_response_from_file(ocsp_path, iocsp, cid, &warn)) {
570 memprintf(&warn, "Loading '%s': %s. Content will be ignored", ocsp_path, warn ? warn : "failure");
571 Warning("%s.\n", warn);
572 }
573
574out:
575 if (ssl)
576 SSL_free(ssl);
577
578 if (in)
579 BIO_free(in);
580
581 if (xi)
582 X509_free(xi);
583
584 if (cid)
585 OCSP_CERTID_free(cid);
586
587 if (ocsp)
588 free(ocsp);
589
590 if (warn)
591 free(warn);
592
593
594 return ret;
595}
596
597#endif
598
Janusz Dziemidowicz2c701b52015-03-07 23:03:59 +0100599#if (OPENSSL_VERSION_NUMBER >= 0x1000200fL && !defined OPENSSL_NO_TLSEXT && !defined OPENSSL_IS_BORINGSSL)
600
601#define CT_EXTENSION_TYPE 18
602
603static int sctl_ex_index = -1;
604
605/*
606 * Try to parse Signed Certificate Timestamp List structure. This function
607 * makes only basic test if the data seems like SCTL. No signature validation
608 * is performed.
609 */
610static int ssl_sock_parse_sctl(struct chunk *sctl)
611{
612 int ret = 1;
613 int len, pos, sct_len;
614 unsigned char *data;
615
616 if (sctl->len < 2)
617 goto out;
618
619 data = (unsigned char *)sctl->str;
620 len = (data[0] << 8) | data[1];
621
622 if (len + 2 != sctl->len)
623 goto out;
624
625 data = data + 2;
626 pos = 0;
627 while (pos < len) {
628 if (len - pos < 2)
629 goto out;
630
631 sct_len = (data[pos] << 8) | data[pos + 1];
632 if (pos + sct_len + 2 > len)
633 goto out;
634
635 pos += sct_len + 2;
636 }
637
638 ret = 0;
639
640out:
641 return ret;
642}
643
644static int ssl_sock_load_sctl_from_file(const char *sctl_path, struct chunk **sctl)
645{
646 int fd = -1;
647 int r = 0;
648 int ret = 1;
649
650 *sctl = NULL;
651
652 fd = open(sctl_path, O_RDONLY);
653 if (fd == -1)
654 goto end;
655
656 trash.len = 0;
657 while (trash.len < trash.size) {
658 r = read(fd, trash.str + trash.len, trash.size - trash.len);
659 if (r < 0) {
660 if (errno == EINTR)
661 continue;
662
663 goto end;
664 }
665 else if (r == 0) {
666 break;
667 }
668 trash.len += r;
669 }
670
671 ret = ssl_sock_parse_sctl(&trash);
672 if (ret)
673 goto end;
674
675 *sctl = calloc(1, sizeof(struct chunk));
676 if (!chunk_dup(*sctl, &trash)) {
677 free(*sctl);
678 *sctl = NULL;
679 goto end;
680 }
681
682end:
683 if (fd != -1)
684 close(fd);
685
686 return ret;
687}
688
689int ssl_sock_sctl_add_cbk(SSL *ssl, unsigned ext_type, const unsigned char **out, size_t *outlen, int *al, void *add_arg)
690{
691 struct chunk *sctl = (struct chunk *)add_arg;
692
693 *out = (unsigned char *)sctl->str;
694 *outlen = sctl->len;
695
696 return 1;
697}
698
699int ssl_sock_sctl_parse_cbk(SSL *s, unsigned int ext_type, const unsigned char *in, size_t inlen, int *al, void *parse_arg)
700{
701 return 1;
702}
703
704static int ssl_sock_load_sctl(SSL_CTX *ctx, const char *cert_path)
705{
706 char sctl_path[MAXPATHLEN+1];
707 int ret = -1;
708 struct stat st;
709 struct chunk *sctl = NULL;
710
711 snprintf(sctl_path, MAXPATHLEN+1, "%s.sctl", cert_path);
712
713 if (stat(sctl_path, &st))
714 return 1;
715
716 if (ssl_sock_load_sctl_from_file(sctl_path, &sctl))
717 goto out;
718
719 if (!SSL_CTX_add_server_custom_ext(ctx, CT_EXTENSION_TYPE, ssl_sock_sctl_add_cbk, NULL, sctl, ssl_sock_sctl_parse_cbk, NULL)) {
720 free(sctl);
721 goto out;
722 }
723
724 SSL_CTX_set_ex_data(ctx, sctl_ex_index, sctl);
725
726 ret = 0;
727
728out:
729 return ret;
730}
731
732#endif
733
Emeric Brune1f38db2012-09-03 20:36:47 +0200734void ssl_sock_infocbk(const SSL *ssl, int where, int ret)
735{
736 struct connection *conn = (struct connection *)SSL_get_app_data(ssl);
Emeric Brund8b2bb52014-01-28 15:43:53 +0100737 BIO *write_bio;
Willy Tarreau622317d2015-02-27 16:36:16 +0100738 (void)ret; /* shut gcc stupid warning */
Emeric Brune1f38db2012-09-03 20:36:47 +0200739
740 if (where & SSL_CB_HANDSHAKE_START) {
741 /* Disable renegotiation (CVE-2009-3555) */
Willy Tarreau20879a02012-12-03 16:32:10 +0100742 if (conn->flags & CO_FL_CONNECTED) {
Emeric Brune1f38db2012-09-03 20:36:47 +0200743 conn->flags |= CO_FL_ERROR;
Willy Tarreau20879a02012-12-03 16:32:10 +0100744 conn->err_code = CO_ER_SSL_RENEG;
745 }
Emeric Brune1f38db2012-09-03 20:36:47 +0200746 }
Emeric Brund8b2bb52014-01-28 15:43:53 +0100747
748 if ((where & SSL_CB_ACCEPT_LOOP) == SSL_CB_ACCEPT_LOOP) {
749 if (!(conn->xprt_st & SSL_SOCK_ST_FL_16K_WBFSIZE)) {
750 /* Long certificate chains optimz
751 If write and read bios are differents, we
752 consider that the buffering was activated,
753 so we rise the output buffer size from 4k
754 to 16k */
755 write_bio = SSL_get_wbio(ssl);
756 if (write_bio != SSL_get_rbio(ssl)) {
757 BIO_set_write_buffer_size(write_bio, 16384);
758 conn->xprt_st |= SSL_SOCK_ST_FL_16K_WBFSIZE;
759 }
760 }
761 }
Emeric Brunfc0421f2012-09-07 17:30:07 +0200762}
763
Emeric Brune64aef12012-09-21 13:15:06 +0200764/* Callback is called for each certificate of the chain during a verify
765 ok is set to 1 if preverify detect no error on current certificate.
766 Returns 0 to break the handshake, 1 otherwise. */
Evan Broderbe554312013-06-27 00:05:25 -0700767int ssl_sock_bind_verifycbk(int ok, X509_STORE_CTX *x_store)
Emeric Brune64aef12012-09-21 13:15:06 +0200768{
769 SSL *ssl;
770 struct connection *conn;
Emeric Brun81c00f02012-09-21 14:31:21 +0200771 int err, depth;
Emeric Brune64aef12012-09-21 13:15:06 +0200772
773 ssl = X509_STORE_CTX_get_ex_data(x_store, SSL_get_ex_data_X509_STORE_CTX_idx());
774 conn = (struct connection *)SSL_get_app_data(ssl);
775
Willy Tarreauf7bc57c2012-10-03 00:19:48 +0200776 conn->xprt_st |= SSL_SOCK_ST_FL_VERIFY_DONE;
Emeric Brune64aef12012-09-21 13:15:06 +0200777
Emeric Brun81c00f02012-09-21 14:31:21 +0200778 if (ok) /* no errors */
779 return ok;
780
781 depth = X509_STORE_CTX_get_error_depth(x_store);
782 err = X509_STORE_CTX_get_error(x_store);
783
784 /* check if CA error needs to be ignored */
785 if (depth > 0) {
Willy Tarreauf7bc57c2012-10-03 00:19:48 +0200786 if (!SSL_SOCK_ST_TO_CA_ERROR(conn->xprt_st)) {
787 conn->xprt_st |= SSL_SOCK_CA_ERROR_TO_ST(err);
788 conn->xprt_st |= SSL_SOCK_CAEDEPTH_TO_ST(depth);
Emeric Brunf282a812012-09-21 15:27:54 +0200789 }
790
Emeric Brun1eb20ef2012-12-03 13:24:29 +0100791 if (objt_listener(conn->target)->bind_conf->ca_ignerr & (1ULL << err)) {
792 ERR_clear_error();
Emeric Brun81c00f02012-09-21 14:31:21 +0200793 return 1;
Emeric Brun1eb20ef2012-12-03 13:24:29 +0100794 }
Emeric Brun81c00f02012-09-21 14:31:21 +0200795
Willy Tarreau20879a02012-12-03 16:32:10 +0100796 conn->err_code = CO_ER_SSL_CA_FAIL;
Emeric Brun81c00f02012-09-21 14:31:21 +0200797 return 0;
798 }
799
Willy Tarreauf7bc57c2012-10-03 00:19:48 +0200800 if (!SSL_SOCK_ST_TO_CRTERROR(conn->xprt_st))
801 conn->xprt_st |= SSL_SOCK_CRTERROR_TO_ST(err);
Emeric Brunf282a812012-09-21 15:27:54 +0200802
Emeric Brun81c00f02012-09-21 14:31:21 +0200803 /* check if certificate error needs to be ignored */
Emeric Brun1eb20ef2012-12-03 13:24:29 +0100804 if (objt_listener(conn->target)->bind_conf->crt_ignerr & (1ULL << err)) {
805 ERR_clear_error();
Emeric Brun81c00f02012-09-21 14:31:21 +0200806 return 1;
Emeric Brun1eb20ef2012-12-03 13:24:29 +0100807 }
Emeric Brun81c00f02012-09-21 14:31:21 +0200808
Willy Tarreau20879a02012-12-03 16:32:10 +0100809 conn->err_code = CO_ER_SSL_CRT_FAIL;
Emeric Brun81c00f02012-09-21 14:31:21 +0200810 return 0;
Emeric Brune64aef12012-09-21 13:15:06 +0200811}
812
Emeric Brun29f037d2014-04-25 19:05:36 +0200813/* Callback is called for ssl protocol analyse */
814void ssl_sock_msgcbk(int write_p, int version, int content_type, const void *buf, size_t len, SSL *ssl, void *arg)
815{
Emeric Brun29f037d2014-04-25 19:05:36 +0200816#ifdef TLS1_RT_HEARTBEAT
817 /* test heartbeat received (write_p is set to 0
818 for a received record) */
Willy Tarreauf51c6982014-04-25 20:02:39 +0200819 if ((content_type == TLS1_RT_HEARTBEAT) && (write_p == 0)) {
Willy Tarreau84815002014-04-25 21:40:27 +0200820 struct connection *conn = (struct connection *)SSL_get_app_data(ssl);
Willy Tarreauf51c6982014-04-25 20:02:39 +0200821 const unsigned char *p = buf;
822 unsigned int payload;
823
Emeric Brun29f037d2014-04-25 19:05:36 +0200824 conn->xprt_st |= SSL_SOCK_RECV_HEARTBEAT;
Willy Tarreauf51c6982014-04-25 20:02:39 +0200825
826 /* Check if this is a CVE-2014-0160 exploitation attempt. */
827 if (*p != TLS1_HB_REQUEST)
828 return;
829
Willy Tarreauaeed6722014-04-25 23:59:58 +0200830 if (len < 1 + 2 + 16) /* 1 type + 2 size + 0 payload + 16 padding */
Willy Tarreauf51c6982014-04-25 20:02:39 +0200831 goto kill_it;
832
833 payload = (p[1] * 256) + p[2];
Willy Tarreau3b2fdb62014-04-25 23:44:22 +0200834 if (3 + payload + 16 <= len)
Willy Tarreauf51c6982014-04-25 20:02:39 +0200835 return; /* OK no problem */
Willy Tarreauaeed6722014-04-25 23:59:58 +0200836 kill_it:
Willy Tarreau3b2fdb62014-04-25 23:44:22 +0200837 /* We have a clear heartbleed attack (CVE-2014-0160), the
838 * advertised payload is larger than the advertised packet
839 * length, so we have garbage in the buffer between the
840 * payload and the end of the buffer (p+len). We can't know
841 * if the SSL stack is patched, and we don't know if we can
842 * safely wipe out the area between p+3+len and payload.
843 * So instead, we prevent the response from being sent by
844 * setting the max_send_fragment to 0 and we report an SSL
845 * error, which will kill this connection. It will be reported
846 * above as SSL_ERROR_SSL while an other handshake failure with
Willy Tarreauf51c6982014-04-25 20:02:39 +0200847 * a heartbeat message will be reported as SSL_ERROR_SYSCALL.
848 */
Willy Tarreau3b2fdb62014-04-25 23:44:22 +0200849 ssl->max_send_fragment = 0;
Willy Tarreauf51c6982014-04-25 20:02:39 +0200850 SSLerr(SSL_F_TLS1_HEARTBEAT, SSL_R_SSL_HANDSHAKE_FAILURE);
851 return;
852 }
Emeric Brun29f037d2014-04-25 19:05:36 +0200853#endif
854}
855
Willy Tarreau6c9a3d52012-10-18 18:57:14 +0200856#ifdef OPENSSL_NPN_NEGOTIATED
857/* This callback is used so that the server advertises the list of
858 * negociable protocols for NPN.
859 */
860static int ssl_sock_advertise_npn_protos(SSL *s, const unsigned char **data,
861 unsigned int *len, void *arg)
862{
863 struct bind_conf *conf = arg;
864
865 *data = (const unsigned char *)conf->npn_str;
866 *len = conf->npn_len;
867 return SSL_TLSEXT_ERR_OK;
868}
869#endif
870
Dirkjan Bussink48f1c4e2014-02-13 12:29:42 +0100871#ifdef TLSEXT_TYPE_application_layer_protocol_negotiation
Willy Tarreauab861d32013-04-02 02:30:41 +0200872/* This callback is used so that the server advertises the list of
873 * negociable protocols for ALPN.
874 */
Dirkjan Bussink48f1c4e2014-02-13 12:29:42 +0100875static int ssl_sock_advertise_alpn_protos(SSL *s, const unsigned char **out,
876 unsigned char *outlen,
877 const unsigned char *server,
878 unsigned int server_len, void *arg)
Willy Tarreauab861d32013-04-02 02:30:41 +0200879{
880 struct bind_conf *conf = arg;
881
Dirkjan Bussink48f1c4e2014-02-13 12:29:42 +0100882 if (SSL_select_next_proto((unsigned char**) out, outlen, (const unsigned char *)conf->alpn_str,
883 conf->alpn_len, server, server_len) != OPENSSL_NPN_NEGOTIATED) {
884 return SSL_TLSEXT_ERR_NOACK;
885 }
Willy Tarreauab861d32013-04-02 02:30:41 +0200886 return SSL_TLSEXT_ERR_OK;
887}
888#endif
889
Emeric Brunfc0421f2012-09-07 17:30:07 +0200890#ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME
891/* Sets the SSL ctx of <ssl> to match the advertised server name. Returns a
892 * warning when no match is found, which implies the default (first) cert
893 * will keep being used.
894 */
Willy Tarreau2a65ff02012-09-13 17:54:29 +0200895static int ssl_sock_switchctx_cbk(SSL *ssl, int *al, struct bind_conf *s)
Emeric Brunfc0421f2012-09-07 17:30:07 +0200896{
897 const char *servername;
898 const char *wildp = NULL;
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +0200899 struct ebmb_node *node, *n;
Emeric Brunfc0421f2012-09-07 17:30:07 +0200900 int i;
901 (void)al; /* shut gcc stupid warning */
902
903 servername = SSL_get_servername(ssl, TLSEXT_NAMETYPE_host_name);
Emmanuel Hocdet65623372013-01-24 17:17:15 +0100904 if (!servername) {
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +0200905 return (s->strict_sni ?
906 SSL_TLSEXT_ERR_ALERT_FATAL :
Emmanuel Hocdet79274e22013-05-31 12:47:44 +0200907 SSL_TLSEXT_ERR_NOACK);
Emmanuel Hocdet65623372013-01-24 17:17:15 +0100908 }
Emeric Brunfc0421f2012-09-07 17:30:07 +0200909
Willy Tarreau19d14ef2012-10-29 16:51:55 +0100910 for (i = 0; i < trash.size; i++) {
Emeric Brunfc0421f2012-09-07 17:30:07 +0200911 if (!servername[i])
912 break;
Willy Tarreau19d14ef2012-10-29 16:51:55 +0100913 trash.str[i] = tolower(servername[i]);
914 if (!wildp && (trash.str[i] == '.'))
915 wildp = &trash.str[i];
Emeric Brunfc0421f2012-09-07 17:30:07 +0200916 }
Willy Tarreau19d14ef2012-10-29 16:51:55 +0100917 trash.str[i] = 0;
Emeric Brunfc0421f2012-09-07 17:30:07 +0200918
919 /* lookup in full qualified names */
Willy Tarreau19d14ef2012-10-29 16:51:55 +0100920 node = ebst_lookup(&s->sni_ctx, trash.str);
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +0200921
922 /* lookup a not neg filter */
923 for (n = node; n; n = ebmb_next_dup(n)) {
924 if (!container_of(n, struct sni_ctx, name)->neg) {
925 node = n;
926 break;
Emmanuel Hocdet65623372013-01-24 17:17:15 +0100927 }
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +0200928 }
929 if (!node && wildp) {
930 /* lookup in wildcards names */
Emeric Brunfc0421f2012-09-07 17:30:07 +0200931 node = ebst_lookup(&s->sni_w_ctx, wildp);
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +0200932 }
933 if (!node || container_of(node, struct sni_ctx, name)->neg) {
934 return (s->strict_sni ?
935 SSL_TLSEXT_ERR_ALERT_FATAL :
936 SSL_TLSEXT_ERR_ALERT_WARNING);
Emeric Brunfc0421f2012-09-07 17:30:07 +0200937 }
938
939 /* switch ctx */
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +0200940 SSL_set_SSL_CTX(ssl, container_of(node, struct sni_ctx, name)->ctx);
Emeric Brunfc0421f2012-09-07 17:30:07 +0200941 return SSL_TLSEXT_ERR_OK;
942}
943#endif /* SSL_CTRL_SET_TLSEXT_HOSTNAME */
944
Emeric Bruna4bcd9a2012-09-20 16:19:02 +0200945#ifndef OPENSSL_NO_DH
Remi Gacognef46cd6e2014-06-12 14:58:40 +0200946
947static DH * ssl_get_dh_1024(void)
948{
Lukas Tribus4c0d45a2014-08-18 00:56:32 +0200949#if (OPENSSL_VERSION_NUMBER < 0x0090801fL || defined OPENSSL_IS_BORINGSSL)
Remi Gacognef46cd6e2014-06-12 14:58:40 +0200950 static const unsigned char rfc_2409_prime_1024[] = {
951 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xC9,0x0F,0xDA,0xA2,
952 0x21,0x68,0xC2,0x34,0xC4,0xC6,0x62,0x8B,0x80,0xDC,0x1C,0xD1,
953 0x29,0x02,0x4E,0x08,0x8A,0x67,0xCC,0x74,0x02,0x0B,0xBE,0xA6,
954 0x3B,0x13,0x9B,0x22,0x51,0x4A,0x08,0x79,0x8E,0x34,0x04,0xDD,
955 0xEF,0x95,0x19,0xB3,0xCD,0x3A,0x43,0x1B,0x30,0x2B,0x0A,0x6D,
956 0xF2,0x5F,0x14,0x37,0x4F,0xE1,0x35,0x6D,0x6D,0x51,0xC2,0x45,
957 0xE4,0x85,0xB5,0x76,0x62,0x5E,0x7E,0xC6,0xF4,0x4C,0x42,0xE9,
958 0xA6,0x37,0xED,0x6B,0x0B,0xFF,0x5C,0xB6,0xF4,0x06,0xB7,0xED,
959 0xEE,0x38,0x6B,0xFB,0x5A,0x89,0x9F,0xA5,0xAE,0x9F,0x24,0x11,
960 0x7C,0x4B,0x1F,0xE6,0x49,0x28,0x66,0x51,0xEC,0xE6,0x53,0x81,
961 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
962 };
963#endif
964 DH *dh = DH_new();
965 if (dh) {
Lukas Tribus4c0d45a2014-08-18 00:56:32 +0200966#if (OPENSSL_VERSION_NUMBER >= 0x0090801fL && !defined OPENSSL_IS_BORINGSSL)
Remi Gacognef46cd6e2014-06-12 14:58:40 +0200967 dh->p = get_rfc2409_prime_1024(NULL);
968#else
969 dh->p = BN_bin2bn(rfc_2409_prime_1024, sizeof rfc_2409_prime_1024, NULL);
970#endif
971 /* See RFC 2409, Section 6 "Oakley Groups"
972 for the reason why 2 is used as generator.
973 */
974 BN_dec2bn(&dh->g, "2");
975 if (!dh->p || !dh->g) {
976 DH_free(dh);
977 dh = NULL;
978 }
979 }
980 return dh;
981}
982
983static DH *ssl_get_dh_2048(void)
984{
Lukas Tribus4c0d45a2014-08-18 00:56:32 +0200985#if (OPENSSL_VERSION_NUMBER < 0x0090801fL || defined OPENSSL_IS_BORINGSSL)
Remi Gacognef46cd6e2014-06-12 14:58:40 +0200986 static const unsigned char rfc_3526_prime_2048[] = {
987 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xC9,0x0F,0xDA,0xA2,
988 0x21,0x68,0xC2,0x34,0xC4,0xC6,0x62,0x8B,0x80,0xDC,0x1C,0xD1,
989 0x29,0x02,0x4E,0x08,0x8A,0x67,0xCC,0x74,0x02,0x0B,0xBE,0xA6,
990 0x3B,0x13,0x9B,0x22,0x51,0x4A,0x08,0x79,0x8E,0x34,0x04,0xDD,
991 0xEF,0x95,0x19,0xB3,0xCD,0x3A,0x43,0x1B,0x30,0x2B,0x0A,0x6D,
992 0xF2,0x5F,0x14,0x37,0x4F,0xE1,0x35,0x6D,0x6D,0x51,0xC2,0x45,
993 0xE4,0x85,0xB5,0x76,0x62,0x5E,0x7E,0xC6,0xF4,0x4C,0x42,0xE9,
994 0xA6,0x37,0xED,0x6B,0x0B,0xFF,0x5C,0xB6,0xF4,0x06,0xB7,0xED,
995 0xEE,0x38,0x6B,0xFB,0x5A,0x89,0x9F,0xA5,0xAE,0x9F,0x24,0x11,
996 0x7C,0x4B,0x1F,0xE6,0x49,0x28,0x66,0x51,0xEC,0xE4,0x5B,0x3D,
997 0xC2,0x00,0x7C,0xB8,0xA1,0x63,0xBF,0x05,0x98,0xDA,0x48,0x36,
998 0x1C,0x55,0xD3,0x9A,0x69,0x16,0x3F,0xA8,0xFD,0x24,0xCF,0x5F,
999 0x83,0x65,0x5D,0x23,0xDC,0xA3,0xAD,0x96,0x1C,0x62,0xF3,0x56,
1000 0x20,0x85,0x52,0xBB,0x9E,0xD5,0x29,0x07,0x70,0x96,0x96,0x6D,
1001 0x67,0x0C,0x35,0x4E,0x4A,0xBC,0x98,0x04,0xF1,0x74,0x6C,0x08,
1002 0xCA,0x18,0x21,0x7C,0x32,0x90,0x5E,0x46,0x2E,0x36,0xCE,0x3B,
1003 0xE3,0x9E,0x77,0x2C,0x18,0x0E,0x86,0x03,0x9B,0x27,0x83,0xA2,
1004 0xEC,0x07,0xA2,0x8F,0xB5,0xC5,0x5D,0xF0,0x6F,0x4C,0x52,0xC9,
1005 0xDE,0x2B,0xCB,0xF6,0x95,0x58,0x17,0x18,0x39,0x95,0x49,0x7C,
1006 0xEA,0x95,0x6A,0xE5,0x15,0xD2,0x26,0x18,0x98,0xFA,0x05,0x10,
1007 0x15,0x72,0x8E,0x5A,0x8A,0xAC,0xAA,0x68,0xFF,0xFF,0xFF,0xFF,
1008 0xFF,0xFF,0xFF,0xFF,
1009 };
1010#endif
1011 DH *dh = DH_new();
1012 if (dh) {
Lukas Tribus4c0d45a2014-08-18 00:56:32 +02001013#if (OPENSSL_VERSION_NUMBER >= 0x0090801fL && !defined OPENSSL_IS_BORINGSSL)
Remi Gacognef46cd6e2014-06-12 14:58:40 +02001014 dh->p = get_rfc3526_prime_2048(NULL);
1015#else
1016 dh->p = BN_bin2bn(rfc_3526_prime_2048, sizeof rfc_3526_prime_2048, NULL);
1017#endif
1018 /* See RFC 3526, Section 3 "2048-bit MODP Group"
1019 for the reason why 2 is used as generator.
1020 */
1021 BN_dec2bn(&dh->g, "2");
1022 if (!dh->p || !dh->g) {
1023 DH_free(dh);
1024 dh = NULL;
1025 }
1026 }
1027 return dh;
1028}
1029
1030static DH *ssl_get_dh_4096(void)
1031{
Lukas Tribus4c0d45a2014-08-18 00:56:32 +02001032#if (OPENSSL_VERSION_NUMBER < 0x0090801fL || defined OPENSSL_IS_BORINGSSL)
Remi Gacognef46cd6e2014-06-12 14:58:40 +02001033 static const unsigned char rfc_3526_prime_4096[] = {
1034 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xC9,0x0F,0xDA,0xA2,
1035 0x21,0x68,0xC2,0x34,0xC4,0xC6,0x62,0x8B,0x80,0xDC,0x1C,0xD1,
1036 0x29,0x02,0x4E,0x08,0x8A,0x67,0xCC,0x74,0x02,0x0B,0xBE,0xA6,
1037 0x3B,0x13,0x9B,0x22,0x51,0x4A,0x08,0x79,0x8E,0x34,0x04,0xDD,
1038 0xEF,0x95,0x19,0xB3,0xCD,0x3A,0x43,0x1B,0x30,0x2B,0x0A,0x6D,
1039 0xF2,0x5F,0x14,0x37,0x4F,0xE1,0x35,0x6D,0x6D,0x51,0xC2,0x45,
1040 0xE4,0x85,0xB5,0x76,0x62,0x5E,0x7E,0xC6,0xF4,0x4C,0x42,0xE9,
1041 0xA6,0x37,0xED,0x6B,0x0B,0xFF,0x5C,0xB6,0xF4,0x06,0xB7,0xED,
1042 0xEE,0x38,0x6B,0xFB,0x5A,0x89,0x9F,0xA5,0xAE,0x9F,0x24,0x11,
1043 0x7C,0x4B,0x1F,0xE6,0x49,0x28,0x66,0x51,0xEC,0xE4,0x5B,0x3D,
1044 0xC2,0x00,0x7C,0xB8,0xA1,0x63,0xBF,0x05,0x98,0xDA,0x48,0x36,
1045 0x1C,0x55,0xD3,0x9A,0x69,0x16,0x3F,0xA8,0xFD,0x24,0xCF,0x5F,
1046 0x83,0x65,0x5D,0x23,0xDC,0xA3,0xAD,0x96,0x1C,0x62,0xF3,0x56,
1047 0x20,0x85,0x52,0xBB,0x9E,0xD5,0x29,0x07,0x70,0x96,0x96,0x6D,
1048 0x67,0x0C,0x35,0x4E,0x4A,0xBC,0x98,0x04,0xF1,0x74,0x6C,0x08,
1049 0xCA,0x18,0x21,0x7C,0x32,0x90,0x5E,0x46,0x2E,0x36,0xCE,0x3B,
1050 0xE3,0x9E,0x77,0x2C,0x18,0x0E,0x86,0x03,0x9B,0x27,0x83,0xA2,
1051 0xEC,0x07,0xA2,0x8F,0xB5,0xC5,0x5D,0xF0,0x6F,0x4C,0x52,0xC9,
1052 0xDE,0x2B,0xCB,0xF6,0x95,0x58,0x17,0x18,0x39,0x95,0x49,0x7C,
1053 0xEA,0x95,0x6A,0xE5,0x15,0xD2,0x26,0x18,0x98,0xFA,0x05,0x10,
1054 0x15,0x72,0x8E,0x5A,0x8A,0xAA,0xC4,0x2D,0xAD,0x33,0x17,0x0D,
1055 0x04,0x50,0x7A,0x33,0xA8,0x55,0x21,0xAB,0xDF,0x1C,0xBA,0x64,
1056 0xEC,0xFB,0x85,0x04,0x58,0xDB,0xEF,0x0A,0x8A,0xEA,0x71,0x57,
1057 0x5D,0x06,0x0C,0x7D,0xB3,0x97,0x0F,0x85,0xA6,0xE1,0xE4,0xC7,
1058 0xAB,0xF5,0xAE,0x8C,0xDB,0x09,0x33,0xD7,0x1E,0x8C,0x94,0xE0,
1059 0x4A,0x25,0x61,0x9D,0xCE,0xE3,0xD2,0x26,0x1A,0xD2,0xEE,0x6B,
1060 0xF1,0x2F,0xFA,0x06,0xD9,0x8A,0x08,0x64,0xD8,0x76,0x02,0x73,
1061 0x3E,0xC8,0x6A,0x64,0x52,0x1F,0x2B,0x18,0x17,0x7B,0x20,0x0C,
1062 0xBB,0xE1,0x17,0x57,0x7A,0x61,0x5D,0x6C,0x77,0x09,0x88,0xC0,
1063 0xBA,0xD9,0x46,0xE2,0x08,0xE2,0x4F,0xA0,0x74,0xE5,0xAB,0x31,
1064 0x43,0xDB,0x5B,0xFC,0xE0,0xFD,0x10,0x8E,0x4B,0x82,0xD1,0x20,
1065 0xA9,0x21,0x08,0x01,0x1A,0x72,0x3C,0x12,0xA7,0x87,0xE6,0xD7,
1066 0x88,0x71,0x9A,0x10,0xBD,0xBA,0x5B,0x26,0x99,0xC3,0x27,0x18,
1067 0x6A,0xF4,0xE2,0x3C,0x1A,0x94,0x68,0x34,0xB6,0x15,0x0B,0xDA,
1068 0x25,0x83,0xE9,0xCA,0x2A,0xD4,0x4C,0xE8,0xDB,0xBB,0xC2,0xDB,
1069 0x04,0xDE,0x8E,0xF9,0x2E,0x8E,0xFC,0x14,0x1F,0xBE,0xCA,0xA6,
1070 0x28,0x7C,0x59,0x47,0x4E,0x6B,0xC0,0x5D,0x99,0xB2,0x96,0x4F,
1071 0xA0,0x90,0xC3,0xA2,0x23,0x3B,0xA1,0x86,0x51,0x5B,0xE7,0xED,
1072 0x1F,0x61,0x29,0x70,0xCE,0xE2,0xD7,0xAF,0xB8,0x1B,0xDD,0x76,
1073 0x21,0x70,0x48,0x1C,0xD0,0x06,0x91,0x27,0xD5,0xB0,0x5A,0xA9,
1074 0x93,0xB4,0xEA,0x98,0x8D,0x8F,0xDD,0xC1,0x86,0xFF,0xB7,0xDC,
1075 0x90,0xA6,0xC0,0x8F,0x4D,0xF4,0x35,0xC9,0x34,0x06,0x31,0x99,
1076 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
1077 };
1078#endif
1079 DH *dh = DH_new();
1080 if (dh) {
Lukas Tribus4c0d45a2014-08-18 00:56:32 +02001081#if (OPENSSL_VERSION_NUMBER >= 0x0090801fL && !defined OPENSSL_IS_BORINGSSL)
Remi Gacognef46cd6e2014-06-12 14:58:40 +02001082 dh->p = get_rfc3526_prime_4096(NULL);
1083#else
1084 dh->p = BN_bin2bn(rfc_3526_prime_4096, sizeof rfc_3526_prime_4096, NULL);
1085#endif
1086 /* See RFC 3526, Section 5 "4096-bit MODP Group"
1087 for the reason why 2 is used as generator.
1088 */
1089 BN_dec2bn(&dh->g, "2");
1090 if (!dh->p || !dh->g) {
1091 DH_free(dh);
1092 dh = NULL;
1093 }
1094 }
1095 return dh;
1096}
1097
1098static DH *ssl_get_dh_8192(void)
1099{
Lukas Tribus4c0d45a2014-08-18 00:56:32 +02001100#if (OPENSSL_VERSION_NUMBER < 0x0090801fL || defined OPENSSL_IS_BORINGSSL)
Remi Gacognef46cd6e2014-06-12 14:58:40 +02001101 static const unsigned char rfc_3526_prime_8192[] = {
1102 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xC9,0x0F,0xDA,0xA2,
1103 0x21,0x68,0xC2,0x34,0xC4,0xC6,0x62,0x8B,0x80,0xDC,0x1C,0xD1,
1104 0x29,0x02,0x4E,0x08,0x8A,0x67,0xCC,0x74,0x02,0x0B,0xBE,0xA6,
1105 0x3B,0x13,0x9B,0x22,0x51,0x4A,0x08,0x79,0x8E,0x34,0x04,0xDD,
1106 0xEF,0x95,0x19,0xB3,0xCD,0x3A,0x43,0x1B,0x30,0x2B,0x0A,0x6D,
1107 0xF2,0x5F,0x14,0x37,0x4F,0xE1,0x35,0x6D,0x6D,0x51,0xC2,0x45,
1108 0xE4,0x85,0xB5,0x76,0x62,0x5E,0x7E,0xC6,0xF4,0x4C,0x42,0xE9,
1109 0xA6,0x37,0xED,0x6B,0x0B,0xFF,0x5C,0xB6,0xF4,0x06,0xB7,0xED,
1110 0xEE,0x38,0x6B,0xFB,0x5A,0x89,0x9F,0xA5,0xAE,0x9F,0x24,0x11,
1111 0x7C,0x4B,0x1F,0xE6,0x49,0x28,0x66,0x51,0xEC,0xE4,0x5B,0x3D,
1112 0xC2,0x00,0x7C,0xB8,0xA1,0x63,0xBF,0x05,0x98,0xDA,0x48,0x36,
1113 0x1C,0x55,0xD3,0x9A,0x69,0x16,0x3F,0xA8,0xFD,0x24,0xCF,0x5F,
1114 0x83,0x65,0x5D,0x23,0xDC,0xA3,0xAD,0x96,0x1C,0x62,0xF3,0x56,
1115 0x20,0x85,0x52,0xBB,0x9E,0xD5,0x29,0x07,0x70,0x96,0x96,0x6D,
1116 0x67,0x0C,0x35,0x4E,0x4A,0xBC,0x98,0x04,0xF1,0x74,0x6C,0x08,
1117 0xCA,0x18,0x21,0x7C,0x32,0x90,0x5E,0x46,0x2E,0x36,0xCE,0x3B,
1118 0xE3,0x9E,0x77,0x2C,0x18,0x0E,0x86,0x03,0x9B,0x27,0x83,0xA2,
1119 0xEC,0x07,0xA2,0x8F,0xB5,0xC5,0x5D,0xF0,0x6F,0x4C,0x52,0xC9,
1120 0xDE,0x2B,0xCB,0xF6,0x95,0x58,0x17,0x18,0x39,0x95,0x49,0x7C,
1121 0xEA,0x95,0x6A,0xE5,0x15,0xD2,0x26,0x18,0x98,0xFA,0x05,0x10,
1122 0x15,0x72,0x8E,0x5A,0x8A,0xAA,0xC4,0x2D,0xAD,0x33,0x17,0x0D,
1123 0x04,0x50,0x7A,0x33,0xA8,0x55,0x21,0xAB,0xDF,0x1C,0xBA,0x64,
1124 0xEC,0xFB,0x85,0x04,0x58,0xDB,0xEF,0x0A,0x8A,0xEA,0x71,0x57,
1125 0x5D,0x06,0x0C,0x7D,0xB3,0x97,0x0F,0x85,0xA6,0xE1,0xE4,0xC7,
1126 0xAB,0xF5,0xAE,0x8C,0xDB,0x09,0x33,0xD7,0x1E,0x8C,0x94,0xE0,
1127 0x4A,0x25,0x61,0x9D,0xCE,0xE3,0xD2,0x26,0x1A,0xD2,0xEE,0x6B,
1128 0xF1,0x2F,0xFA,0x06,0xD9,0x8A,0x08,0x64,0xD8,0x76,0x02,0x73,
1129 0x3E,0xC8,0x6A,0x64,0x52,0x1F,0x2B,0x18,0x17,0x7B,0x20,0x0C,
1130 0xBB,0xE1,0x17,0x57,0x7A,0x61,0x5D,0x6C,0x77,0x09,0x88,0xC0,
1131 0xBA,0xD9,0x46,0xE2,0x08,0xE2,0x4F,0xA0,0x74,0xE5,0xAB,0x31,
1132 0x43,0xDB,0x5B,0xFC,0xE0,0xFD,0x10,0x8E,0x4B,0x82,0xD1,0x20,
1133 0xA9,0x21,0x08,0x01,0x1A,0x72,0x3C,0x12,0xA7,0x87,0xE6,0xD7,
1134 0x88,0x71,0x9A,0x10,0xBD,0xBA,0x5B,0x26,0x99,0xC3,0x27,0x18,
1135 0x6A,0xF4,0xE2,0x3C,0x1A,0x94,0x68,0x34,0xB6,0x15,0x0B,0xDA,
1136 0x25,0x83,0xE9,0xCA,0x2A,0xD4,0x4C,0xE8,0xDB,0xBB,0xC2,0xDB,
1137 0x04,0xDE,0x8E,0xF9,0x2E,0x8E,0xFC,0x14,0x1F,0xBE,0xCA,0xA6,
1138 0x28,0x7C,0x59,0x47,0x4E,0x6B,0xC0,0x5D,0x99,0xB2,0x96,0x4F,
1139 0xA0,0x90,0xC3,0xA2,0x23,0x3B,0xA1,0x86,0x51,0x5B,0xE7,0xED,
1140 0x1F,0x61,0x29,0x70,0xCE,0xE2,0xD7,0xAF,0xB8,0x1B,0xDD,0x76,
1141 0x21,0x70,0x48,0x1C,0xD0,0x06,0x91,0x27,0xD5,0xB0,0x5A,0xA9,
1142 0x93,0xB4,0xEA,0x98,0x8D,0x8F,0xDD,0xC1,0x86,0xFF,0xB7,0xDC,
1143 0x90,0xA6,0xC0,0x8F,0x4D,0xF4,0x35,0xC9,0x34,0x02,0x84,0x92,
1144 0x36,0xC3,0xFA,0xB4,0xD2,0x7C,0x70,0x26,0xC1,0xD4,0xDC,0xB2,
1145 0x60,0x26,0x46,0xDE,0xC9,0x75,0x1E,0x76,0x3D,0xBA,0x37,0xBD,
1146 0xF8,0xFF,0x94,0x06,0xAD,0x9E,0x53,0x0E,0xE5,0xDB,0x38,0x2F,
1147 0x41,0x30,0x01,0xAE,0xB0,0x6A,0x53,0xED,0x90,0x27,0xD8,0x31,
1148 0x17,0x97,0x27,0xB0,0x86,0x5A,0x89,0x18,0xDA,0x3E,0xDB,0xEB,
1149 0xCF,0x9B,0x14,0xED,0x44,0xCE,0x6C,0xBA,0xCE,0xD4,0xBB,0x1B,
1150 0xDB,0x7F,0x14,0x47,0xE6,0xCC,0x25,0x4B,0x33,0x20,0x51,0x51,
1151 0x2B,0xD7,0xAF,0x42,0x6F,0xB8,0xF4,0x01,0x37,0x8C,0xD2,0xBF,
1152 0x59,0x83,0xCA,0x01,0xC6,0x4B,0x92,0xEC,0xF0,0x32,0xEA,0x15,
1153 0xD1,0x72,0x1D,0x03,0xF4,0x82,0xD7,0xCE,0x6E,0x74,0xFE,0xF6,
1154 0xD5,0x5E,0x70,0x2F,0x46,0x98,0x0C,0x82,0xB5,0xA8,0x40,0x31,
1155 0x90,0x0B,0x1C,0x9E,0x59,0xE7,0xC9,0x7F,0xBE,0xC7,0xE8,0xF3,
1156 0x23,0xA9,0x7A,0x7E,0x36,0xCC,0x88,0xBE,0x0F,0x1D,0x45,0xB7,
1157 0xFF,0x58,0x5A,0xC5,0x4B,0xD4,0x07,0xB2,0x2B,0x41,0x54,0xAA,
1158 0xCC,0x8F,0x6D,0x7E,0xBF,0x48,0xE1,0xD8,0x14,0xCC,0x5E,0xD2,
1159 0x0F,0x80,0x37,0xE0,0xA7,0x97,0x15,0xEE,0xF2,0x9B,0xE3,0x28,
1160 0x06,0xA1,0xD5,0x8B,0xB7,0xC5,0xDA,0x76,0xF5,0x50,0xAA,0x3D,
1161 0x8A,0x1F,0xBF,0xF0,0xEB,0x19,0xCC,0xB1,0xA3,0x13,0xD5,0x5C,
1162 0xDA,0x56,0xC9,0xEC,0x2E,0xF2,0x96,0x32,0x38,0x7F,0xE8,0xD7,
1163 0x6E,0x3C,0x04,0x68,0x04,0x3E,0x8F,0x66,0x3F,0x48,0x60,0xEE,
1164 0x12,0xBF,0x2D,0x5B,0x0B,0x74,0x74,0xD6,0xE6,0x94,0xF9,0x1E,
1165 0x6D,0xBE,0x11,0x59,0x74,0xA3,0x92,0x6F,0x12,0xFE,0xE5,0xE4,
1166 0x38,0x77,0x7C,0xB6,0xA9,0x32,0xDF,0x8C,0xD8,0xBE,0xC4,0xD0,
1167 0x73,0xB9,0x31,0xBA,0x3B,0xC8,0x32,0xB6,0x8D,0x9D,0xD3,0x00,
1168 0x74,0x1F,0xA7,0xBF,0x8A,0xFC,0x47,0xED,0x25,0x76,0xF6,0x93,
1169 0x6B,0xA4,0x24,0x66,0x3A,0xAB,0x63,0x9C,0x5A,0xE4,0xF5,0x68,
1170 0x34,0x23,0xB4,0x74,0x2B,0xF1,0xC9,0x78,0x23,0x8F,0x16,0xCB,
1171 0xE3,0x9D,0x65,0x2D,0xE3,0xFD,0xB8,0xBE,0xFC,0x84,0x8A,0xD9,
1172 0x22,0x22,0x2E,0x04,0xA4,0x03,0x7C,0x07,0x13,0xEB,0x57,0xA8,
1173 0x1A,0x23,0xF0,0xC7,0x34,0x73,0xFC,0x64,0x6C,0xEA,0x30,0x6B,
1174 0x4B,0xCB,0xC8,0x86,0x2F,0x83,0x85,0xDD,0xFA,0x9D,0x4B,0x7F,
1175 0xA2,0xC0,0x87,0xE8,0x79,0x68,0x33,0x03,0xED,0x5B,0xDD,0x3A,
1176 0x06,0x2B,0x3C,0xF5,0xB3,0xA2,0x78,0xA6,0x6D,0x2A,0x13,0xF8,
1177 0x3F,0x44,0xF8,0x2D,0xDF,0x31,0x0E,0xE0,0x74,0xAB,0x6A,0x36,
1178 0x45,0x97,0xE8,0x99,0xA0,0x25,0x5D,0xC1,0x64,0xF3,0x1C,0xC5,
1179 0x08,0x46,0x85,0x1D,0xF9,0xAB,0x48,0x19,0x5D,0xED,0x7E,0xA1,
1180 0xB1,0xD5,0x10,0xBD,0x7E,0xE7,0x4D,0x73,0xFA,0xF3,0x6B,0xC3,
1181 0x1E,0xCF,0xA2,0x68,0x35,0x90,0x46,0xF4,0xEB,0x87,0x9F,0x92,
1182 0x40,0x09,0x43,0x8B,0x48,0x1C,0x6C,0xD7,0x88,0x9A,0x00,0x2E,
1183 0xD5,0xEE,0x38,0x2B,0xC9,0x19,0x0D,0xA6,0xFC,0x02,0x6E,0x47,
1184 0x95,0x58,0xE4,0x47,0x56,0x77,0xE9,0xAA,0x9E,0x30,0x50,0xE2,
1185 0x76,0x56,0x94,0xDF,0xC8,0x1F,0x56,0xE8,0x80,0xB9,0x6E,0x71,
1186 0x60,0xC9,0x80,0xDD,0x98,0xED,0xD3,0xDF,0xFF,0xFF,0xFF,0xFF,
1187 0xFF,0xFF,0xFF,0xFF,
1188 };
1189#endif
1190 DH *dh = DH_new();
1191 if (dh) {
Lukas Tribus4c0d45a2014-08-18 00:56:32 +02001192#if (OPENSSL_VERSION_NUMBER >= 0x0090801fL && !defined OPENSSL_IS_BORINGSSL)
Remi Gacognef46cd6e2014-06-12 14:58:40 +02001193 dh->p = get_rfc3526_prime_8192(NULL);
1194#else
1195 dh->p = BN_bin2bn(rfc_3526_prime_8192, sizeof rfc_3526_prime_8192, NULL);
1196#endif
1197 /* See RFC 3526, Section 7 "8192-bit MODP Group"
1198 for the reason why 2 is used as generator.
1199 */
1200 BN_dec2bn(&dh->g, "2");
1201 if (!dh->p || !dh->g) {
1202 DH_free(dh);
1203 dh = NULL;
1204 }
1205 }
1206 return dh;
1207}
1208
1209/* Returns Diffie-Hellman parameters matching the private key length
1210 but not exceeding global.tune.ssl_default_dh_param */
1211static DH *ssl_get_tmp_dh(SSL *ssl, int export, int keylen)
1212{
1213 DH *dh = NULL;
1214 EVP_PKEY *pkey = SSL_get_privatekey(ssl);
1215 int type = pkey ? EVP_PKEY_type(pkey->type) : EVP_PKEY_NONE;
1216
1217 /* The keylen supplied by OpenSSL can only be 512 or 1024.
1218 See ssl3_send_server_key_exchange() in ssl/s3_srvr.c
1219 */
1220 if (type == EVP_PKEY_RSA || type == EVP_PKEY_DSA) {
1221 keylen = EVP_PKEY_bits(pkey);
1222 }
1223
1224 if (keylen > global.tune.ssl_default_dh_param) {
1225 keylen = global.tune.ssl_default_dh_param;
1226 }
1227
1228 if (keylen >= 8192) {
Remi Gacogne8de54152014-07-15 11:36:40 +02001229 dh = local_dh_8192;
Remi Gacognef46cd6e2014-06-12 14:58:40 +02001230 }
1231 else if (keylen >= 4096) {
Remi Gacogne8de54152014-07-15 11:36:40 +02001232 dh = local_dh_4096;
Remi Gacognef46cd6e2014-06-12 14:58:40 +02001233 }
1234 else if (keylen >= 2048) {
Remi Gacogne8de54152014-07-15 11:36:40 +02001235 dh = local_dh_2048;
Remi Gacognef46cd6e2014-06-12 14:58:40 +02001236 }
1237 else {
Remi Gacogne8de54152014-07-15 11:36:40 +02001238 dh = local_dh_1024;
Remi Gacognef46cd6e2014-06-12 14:58:40 +02001239 }
1240
1241 return dh;
1242}
1243
Emeric Bruna4bcd9a2012-09-20 16:19:02 +02001244/* Loads Diffie-Hellman parameter from a file. Returns 1 if loaded, else -1
1245 if an error occured, and 0 if parameter not found. */
Willy Tarreau6e774b42014-04-25 21:35:23 +02001246int ssl_sock_load_dh_params(SSL_CTX *ctx, const char *file)
Emeric Bruna4bcd9a2012-09-20 16:19:02 +02001247{
1248 int ret = -1;
1249 BIO *in;
1250 DH *dh = NULL;
1251
1252 in = BIO_new(BIO_s_file());
1253 if (in == NULL)
1254 goto end;
1255
1256 if (BIO_read_filename(in, file) <= 0)
1257 goto end;
1258
1259 dh = PEM_read_bio_DHparams(in, NULL, ctx->default_passwd_callback, ctx->default_passwd_callback_userdata);
Remi Gacognef46cd6e2014-06-12 14:58:40 +02001260 if (dh) {
1261 ret = 1;
1262 SSL_CTX_set_tmp_dh(ctx, dh);
1263 /* Setting ssl default dh param to the size of the static DH params
1264 found in the file. This way we know that there is no use
1265 complaining later about ssl-default-dh-param not being set. */
1266 global.tune.ssl_default_dh_param = DH_size(dh) * 8;
1267 }
1268 else {
Emeric Brun41fdb3c2013-04-26 11:05:44 +02001269 /* Clear openssl global errors stack */
1270 ERR_clear_error();
1271
Remi Gacognef46cd6e2014-06-12 14:58:40 +02001272 if (global.tune.ssl_default_dh_param <= 1024) {
1273 /* we are limited to DH parameter of 1024 bits anyway */
Remi Gacogne8de54152014-07-15 11:36:40 +02001274 local_dh_1024 = ssl_get_dh_1024();
1275 if (local_dh_1024 == NULL)
Remi Gacognef46cd6e2014-06-12 14:58:40 +02001276 goto end;
Willy Tarreau6e774b42014-04-25 21:35:23 +02001277
Remi Gacogne8de54152014-07-15 11:36:40 +02001278 SSL_CTX_set_tmp_dh(ctx, local_dh_1024);
Remi Gacognef46cd6e2014-06-12 14:58:40 +02001279 }
1280 else {
1281 SSL_CTX_set_tmp_dh_callback(ctx, ssl_get_tmp_dh);
1282 }
Willy Tarreau6e774b42014-04-25 21:35:23 +02001283
Emeric Brun41fdb3c2013-04-26 11:05:44 +02001284 ret = 0; /* DH params not found */
Emeric Bruna4bcd9a2012-09-20 16:19:02 +02001285 }
Emeric Brun644cde02012-12-14 11:21:13 +01001286
Emeric Bruna4bcd9a2012-09-20 16:19:02 +02001287end:
1288 if (dh)
1289 DH_free(dh);
1290
1291 if (in)
Emeric Brun41fdb3c2013-04-26 11:05:44 +02001292 BIO_free(in);
Emeric Bruna4bcd9a2012-09-20 16:19:02 +02001293
1294 return ret;
1295}
1296#endif
1297
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +02001298static int ssl_sock_add_cert_sni(SSL_CTX *ctx, struct bind_conf *s, char *name, int order)
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01001299{
1300 struct sni_ctx *sc;
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +02001301 int wild = 0, neg = 0;
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01001302
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +02001303 if (*name == '!') {
1304 neg = 1;
1305 name++;
1306 }
1307 if (*name == '*') {
1308 wild = 1;
1309 name++;
1310 }
1311 /* !* filter is a nop */
1312 if (neg && wild)
1313 return order;
1314 if (*name) {
1315 int j, len;
1316 len = strlen(name);
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01001317 sc = malloc(sizeof(struct sni_ctx) + len + 1);
1318 for (j = 0; j < len; j++)
1319 sc->name.key[j] = tolower(name[j]);
1320 sc->name.key[len] = 0;
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01001321 sc->ctx = ctx;
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +02001322 sc->order = order++;
1323 sc->neg = neg;
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01001324 if (wild)
1325 ebst_insert(&s->sni_w_ctx, &sc->name);
1326 else
1327 ebst_insert(&s->sni_ctx, &sc->name);
1328 }
1329 return order;
1330}
1331
Emeric Brunfc0421f2012-09-07 17:30:07 +02001332/* Loads a certificate key and CA chain from a file. Returns 0 on error, -1 if
1333 * an early error happens and the caller must call SSL_CTX_free() by itelf.
1334 */
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +02001335static 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 +02001336{
1337 BIO *in;
1338 X509 *x = NULL, *ca;
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +02001339 int i, err;
Emeric Brunfc0421f2012-09-07 17:30:07 +02001340 int ret = -1;
1341 int order = 0;
1342 X509_NAME *xname;
1343 char *str;
Emeric Brunfc0421f2012-09-07 17:30:07 +02001344#ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME
1345 STACK_OF(GENERAL_NAME) *names;
1346#endif
1347
1348 in = BIO_new(BIO_s_file());
1349 if (in == NULL)
1350 goto end;
1351
1352 if (BIO_read_filename(in, file) <= 0)
1353 goto end;
1354
1355 x = PEM_read_bio_X509_AUX(in, NULL, ctx->default_passwd_callback, ctx->default_passwd_callback_userdata);
1356 if (x == NULL)
1357 goto end;
1358
Emeric Brun50bcecc2013-04-22 13:05:23 +02001359 if (fcount) {
1360 while (fcount--)
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +02001361 order = ssl_sock_add_cert_sni(ctx, s, sni_filter[fcount], order);
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01001362 }
1363 else {
Emeric Brunfc0421f2012-09-07 17:30:07 +02001364#ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01001365 names = X509_get_ext_d2i(x, NID_subject_alt_name, NULL, NULL);
1366 if (names) {
1367 for (i = 0; i < sk_GENERAL_NAME_num(names); i++) {
1368 GENERAL_NAME *name = sk_GENERAL_NAME_value(names, i);
1369 if (name->type == GEN_DNS) {
1370 if (ASN1_STRING_to_UTF8((unsigned char **)&str, name->d.dNSName) >= 0) {
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +02001371 order = ssl_sock_add_cert_sni(ctx, s, str, order);
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01001372 OPENSSL_free(str);
Emeric Brunfc0421f2012-09-07 17:30:07 +02001373 }
Emeric Brunfc0421f2012-09-07 17:30:07 +02001374 }
1375 }
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01001376 sk_GENERAL_NAME_pop_free(names, GENERAL_NAME_free);
Emeric Brunfc0421f2012-09-07 17:30:07 +02001377 }
Emeric Brunfc0421f2012-09-07 17:30:07 +02001378#endif /* SSL_CTRL_SET_TLSEXT_HOSTNAME */
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01001379 xname = X509_get_subject_name(x);
1380 i = -1;
1381 while ((i = X509_NAME_get_index_by_NID(xname, NID_commonName, i)) != -1) {
1382 X509_NAME_ENTRY *entry = X509_NAME_get_entry(xname, i);
1383 if (ASN1_STRING_to_UTF8((unsigned char **)&str, entry->value) >= 0) {
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +02001384 order = ssl_sock_add_cert_sni(ctx, s, str, order);
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01001385 OPENSSL_free(str);
Emeric Brunfc0421f2012-09-07 17:30:07 +02001386 }
Emeric Brunfc0421f2012-09-07 17:30:07 +02001387 }
1388 }
1389
1390 ret = 0; /* the caller must not free the SSL_CTX argument anymore */
1391 if (!SSL_CTX_use_certificate(ctx, x))
1392 goto end;
1393
1394 if (ctx->extra_certs != NULL) {
1395 sk_X509_pop_free(ctx->extra_certs, X509_free);
1396 ctx->extra_certs = NULL;
1397 }
1398
1399 while ((ca = PEM_read_bio_X509(in, NULL, ctx->default_passwd_callback, ctx->default_passwd_callback_userdata))) {
1400 if (!SSL_CTX_add_extra_chain_cert(ctx, ca)) {
1401 X509_free(ca);
1402 goto end;
1403 }
1404 }
1405
1406 err = ERR_get_error();
1407 if (!err || (ERR_GET_LIB(err) == ERR_LIB_PEM && ERR_GET_REASON(err) == PEM_R_NO_START_LINE)) {
1408 /* we successfully reached the last cert in the file */
1409 ret = 1;
1410 }
1411 ERR_clear_error();
1412
1413end:
1414 if (x)
1415 X509_free(x);
1416
1417 if (in)
1418 BIO_free(in);
1419
1420 return ret;
1421}
1422
Emeric Brun50bcecc2013-04-22 13:05:23 +02001423static 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 +02001424{
1425 int ret;
1426 SSL_CTX *ctx;
1427
1428 ctx = SSL_CTX_new(SSLv23_server_method());
1429 if (!ctx) {
Willy Tarreaueb6cead2012-09-20 19:43:14 +02001430 memprintf(err, "%sunable to allocate SSL context for cert '%s'.\n",
1431 err && *err ? *err : "", path);
Emeric Brunfc0421f2012-09-07 17:30:07 +02001432 return 1;
1433 }
1434
1435 if (SSL_CTX_use_PrivateKey_file(ctx, path, SSL_FILETYPE_PEM) <= 0) {
Willy Tarreaueb6cead2012-09-20 19:43:14 +02001436 memprintf(err, "%sunable to load SSL private key from PEM file '%s'.\n",
1437 err && *err ? *err : "", path);
Emeric Brunfc0421f2012-09-07 17:30:07 +02001438 SSL_CTX_free(ctx);
1439 return 1;
1440 }
1441
Emeric Brun50bcecc2013-04-22 13:05:23 +02001442 ret = ssl_sock_load_cert_chain_file(ctx, path, bind_conf, sni_filter, fcount);
Emeric Brunfc0421f2012-09-07 17:30:07 +02001443 if (ret <= 0) {
Willy Tarreaueb6cead2012-09-20 19:43:14 +02001444 memprintf(err, "%sunable to load SSL certificate from PEM file '%s'.\n",
1445 err && *err ? *err : "", path);
Emeric Brunfc0421f2012-09-07 17:30:07 +02001446 if (ret < 0) /* serious error, must do that ourselves */
1447 SSL_CTX_free(ctx);
1448 return 1;
1449 }
Emeric Brun61694ab2012-10-26 13:35:33 +02001450
1451 if (SSL_CTX_check_private_key(ctx) <= 0) {
1452 memprintf(err, "%sinconsistencies between private key and certificate loaded from PEM file '%s'.\n",
1453 err && *err ? *err : "", path);
1454 return 1;
1455 }
1456
Emeric Brunfc0421f2012-09-07 17:30:07 +02001457 /* we must not free the SSL_CTX anymore below, since it's already in
1458 * the tree, so it will be discovered and cleaned in time.
1459 */
Emeric Bruna4bcd9a2012-09-20 16:19:02 +02001460#ifndef OPENSSL_NO_DH
1461 ret = ssl_sock_load_dh_params(ctx, path);
1462 if (ret < 0) {
1463 if (err)
1464 memprintf(err, "%sunable to load DH parameters from file '%s'.\n",
1465 *err ? *err : "", path);
1466 return 1;
1467 }
1468#endif
1469
Lukas Tribuse4e30f72014-12-09 16:32:51 +01001470#if (defined SSL_CTRL_SET_TLSEXT_STATUS_REQ_CB && !defined OPENSSL_NO_OCSP)
Emeric Brun4147b2e2014-06-16 18:36:30 +02001471 ret = ssl_sock_load_ocsp(ctx, path);
1472 if (ret < 0) {
1473 if (err)
1474 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",
1475 *err ? *err : "", path);
1476 return 1;
1477 }
1478#endif
1479
Janusz Dziemidowicz2c701b52015-03-07 23:03:59 +01001480#if (OPENSSL_VERSION_NUMBER >= 0x1000200fL && !defined OPENSSL_NO_TLSEXT && !defined OPENSSL_IS_BORINGSSL)
1481 if (sctl_ex_index >= 0) {
1482 ret = ssl_sock_load_sctl(ctx, path);
1483 if (ret < 0) {
1484 if (err)
1485 memprintf(err, "%s '%s.sctl' is present but cannot be read or parsed'.\n",
1486 *err ? *err : "", path);
1487 return 1;
1488 }
1489 }
1490#endif
1491
Emeric Brunfc0421f2012-09-07 17:30:07 +02001492#ifndef SSL_CTRL_SET_TLSEXT_HOSTNAME
Willy Tarreau2a65ff02012-09-13 17:54:29 +02001493 if (bind_conf->default_ctx) {
Willy Tarreaueb6cead2012-09-20 19:43:14 +02001494 memprintf(err, "%sthis version of openssl cannot load multiple SSL certificates.\n",
1495 err && *err ? *err : "");
Emeric Brunfc0421f2012-09-07 17:30:07 +02001496 return 1;
1497 }
1498#endif
Willy Tarreau2a65ff02012-09-13 17:54:29 +02001499 if (!bind_conf->default_ctx)
1500 bind_conf->default_ctx = ctx;
Emeric Brunfc0421f2012-09-07 17:30:07 +02001501
1502 return 0;
1503}
1504
Willy Tarreau79eeafa2012-09-14 07:53:05 +02001505int ssl_sock_load_cert(char *path, struct bind_conf *bind_conf, struct proxy *curproxy, char **err)
Emeric Brunfc0421f2012-09-07 17:30:07 +02001506{
Cyril Bonté3180f7b2015-01-25 00:16:08 +01001507 struct dirent **de_list;
1508 int i, n;
Emeric Brunfc0421f2012-09-07 17:30:07 +02001509 DIR *dir;
1510 struct stat buf;
Willy Tarreauee2663b2012-12-06 11:36:59 +01001511 char *end;
1512 char fp[MAXPATHLEN+1];
Emeric Brunfc0421f2012-09-07 17:30:07 +02001513 int cfgerr = 0;
1514
1515 if (!(dir = opendir(path)))
Emeric Brun50bcecc2013-04-22 13:05:23 +02001516 return ssl_sock_load_cert_file(path, bind_conf, curproxy, NULL, 0, err);
Emeric Brunfc0421f2012-09-07 17:30:07 +02001517
1518 /* strip trailing slashes, including first one */
1519 for (end = path + strlen(path) - 1; end >= path && *end == '/'; end--)
1520 *end = 0;
1521
Cyril Bonté3180f7b2015-01-25 00:16:08 +01001522 n = scandir(path, &de_list, 0, alphasort);
1523 if (n < 0) {
1524 memprintf(err, "%sunable to scan directory '%s' : %s.\n",
1525 err && *err ? *err : "", path, strerror(errno));
1526 cfgerr++;
1527 }
1528 else {
1529 for (i = 0; i < n; i++) {
1530 struct dirent *de = de_list[i];
Emeric Brun2aab7222014-06-18 18:15:09 +02001531
Cyril Bonté3180f7b2015-01-25 00:16:08 +01001532 end = strrchr(de->d_name, '.');
Janusz Dziemidowicz2c701b52015-03-07 23:03:59 +01001533 if (end && (!strcmp(end, ".issuer") || !strcmp(end, ".ocsp") || !strcmp(end, ".sctl")))
Cyril Bonté3180f7b2015-01-25 00:16:08 +01001534 goto ignore_entry;
1535
1536 snprintf(fp, sizeof(fp), "%s/%s", path, de->d_name);
1537 if (stat(fp, &buf) != 0) {
1538 memprintf(err, "%sunable to stat SSL certificate from file '%s' : %s.\n",
1539 err && *err ? *err : "", fp, strerror(errno));
1540 cfgerr++;
1541 goto ignore_entry;
1542 }
1543 if (!S_ISREG(buf.st_mode))
1544 goto ignore_entry;
1545 cfgerr += ssl_sock_load_cert_file(fp, bind_conf, curproxy, NULL, 0, err);
1546 ignore_entry:
1547 free(de);
Emeric Brunfc0421f2012-09-07 17:30:07 +02001548 }
Cyril Bonté3180f7b2015-01-25 00:16:08 +01001549 free(de_list);
Emeric Brunfc0421f2012-09-07 17:30:07 +02001550 }
Emeric Brunfc0421f2012-09-07 17:30:07 +02001551 closedir(dir);
1552 return cfgerr;
1553}
1554
Thierry Fournier383085f2013-01-24 14:15:43 +01001555/* Make sure openssl opens /dev/urandom before the chroot. The work is only
1556 * done once. Zero is returned if the operation fails. No error is returned
1557 * if the random is said as not implemented, because we expect that openssl
1558 * will use another method once needed.
1559 */
1560static int ssl_initialize_random()
1561{
1562 unsigned char random;
1563 static int random_initialized = 0;
1564
1565 if (!random_initialized && RAND_bytes(&random, 1) != 0)
1566 random_initialized = 1;
1567
1568 return random_initialized;
1569}
1570
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01001571int ssl_sock_load_cert_list_file(char *file, struct bind_conf *bind_conf, struct proxy *curproxy, char **err)
1572{
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +02001573 char thisline[LINESIZE];
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01001574 FILE *f;
1575 int linenum = 0;
1576 int cfgerr = 0;
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01001577
Willy Tarreauad1731d2013-04-02 17:35:58 +02001578 if ((f = fopen(file, "r")) == NULL) {
1579 memprintf(err, "cannot open file '%s' : %s", file, strerror(errno));
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01001580 return 1;
Willy Tarreauad1731d2013-04-02 17:35:58 +02001581 }
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01001582
1583 while (fgets(thisline, sizeof(thisline), f) != NULL) {
1584 int arg;
Emeric Brun50bcecc2013-04-22 13:05:23 +02001585 int newarg;
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01001586 char *end;
1587 char *args[MAX_LINE_ARGS + 1];
1588 char *line = thisline;
1589
1590 linenum++;
1591 end = line + strlen(line);
1592 if (end-line == sizeof(thisline)-1 && *(end-1) != '\n') {
1593 /* Check if we reached the limit and the last char is not \n.
1594 * Watch out for the last line without the terminating '\n'!
1595 */
Willy Tarreauad1731d2013-04-02 17:35:58 +02001596 memprintf(err, "line %d too long in file '%s', limit is %d characters",
1597 linenum, file, (int)sizeof(thisline)-1);
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01001598 cfgerr = 1;
Willy Tarreauad1731d2013-04-02 17:35:58 +02001599 break;
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01001600 }
1601
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01001602 arg = 0;
Emeric Brun50bcecc2013-04-22 13:05:23 +02001603 newarg = 1;
1604 while (*line) {
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01001605 if (*line == '#' || *line == '\n' || *line == '\r') {
1606 /* end of string, end of loop */
1607 *line = 0;
1608 break;
1609 }
1610 else if (isspace(*line)) {
Emeric Brun50bcecc2013-04-22 13:05:23 +02001611 newarg = 1;
1612 *line = 0;
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01001613 }
Emeric Brun50bcecc2013-04-22 13:05:23 +02001614 else if (newarg) {
1615 if (arg == MAX_LINE_ARGS) {
1616 memprintf(err, "too many args on line %d in file '%s'.",
1617 linenum, file);
1618 cfgerr = 1;
1619 break;
1620 }
1621 newarg = 0;
1622 args[arg++] = line;
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01001623 }
Emeric Brun50bcecc2013-04-22 13:05:23 +02001624 line++;
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01001625 }
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +02001626 if (cfgerr)
1627 break;
Willy Tarreauad1731d2013-04-02 17:35:58 +02001628
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01001629 /* empty line */
Emeric Brun50bcecc2013-04-22 13:05:23 +02001630 if (!arg)
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01001631 continue;
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01001632
Emeric Brun50bcecc2013-04-22 13:05:23 +02001633 cfgerr = ssl_sock_load_cert_file(args[0], bind_conf, curproxy, &args[1], arg-1, err);
Willy Tarreauad1731d2013-04-02 17:35:58 +02001634 if (cfgerr) {
1635 memprintf(err, "error processing line %d in file '%s' : %s", linenum, file, *err);
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01001636 break;
Willy Tarreauad1731d2013-04-02 17:35:58 +02001637 }
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01001638 }
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01001639 fclose(f);
1640 return cfgerr;
1641}
1642
Emeric Brunfc0421f2012-09-07 17:30:07 +02001643#ifndef SSL_OP_CIPHER_SERVER_PREFERENCE /* needs OpenSSL >= 0.9.7 */
1644#define SSL_OP_CIPHER_SERVER_PREFERENCE 0
1645#endif
1646
1647#ifndef SSL_OP_NO_SESSION_RESUMPTION_ON_RENEGOTIATION /* needs OpenSSL >= 0.9.7 */
1648#define SSL_OP_NO_SESSION_RESUMPTION_ON_RENEGOTIATION 0
Willy Tarreau7d588ee2012-11-26 18:47:31 +01001649#define SSL_renegotiate_pending(arg) 0
Emeric Brunfc0421f2012-09-07 17:30:07 +02001650#endif
Emeric Brun2b58d042012-09-20 17:10:03 +02001651#ifndef SSL_OP_SINGLE_ECDH_USE /* needs OpenSSL >= 0.9.8 */
1652#define SSL_OP_SINGLE_ECDH_USE 0
1653#endif
Emeric Brun2d0c4822012-10-02 13:45:20 +02001654#ifndef SSL_OP_NO_TICKET /* needs OpenSSL >= 0.9.8 */
1655#define SSL_OP_NO_TICKET 0
1656#endif
Emeric Brunfc0421f2012-09-07 17:30:07 +02001657#ifndef SSL_OP_NO_COMPRESSION /* needs OpenSSL >= 0.9.9 */
1658#define SSL_OP_NO_COMPRESSION 0
1659#endif
Emeric Brunc0ff4922012-09-28 19:37:02 +02001660#ifndef SSL_OP_NO_TLSv1_1 /* needs OpenSSL >= 1.0.1 */
1661#define SSL_OP_NO_TLSv1_1 0
1662#endif
1663#ifndef SSL_OP_NO_TLSv1_2 /* needs OpenSSL >= 1.0.1 */
1664#define SSL_OP_NO_TLSv1_2 0
1665#endif
Emeric Bruna4bcd9a2012-09-20 16:19:02 +02001666#ifndef SSL_OP_SINGLE_DH_USE /* needs OpenSSL >= 0.9.6 */
1667#define SSL_OP_SINGLE_DH_USE 0
1668#endif
Emeric Brun2b58d042012-09-20 17:10:03 +02001669#ifndef SSL_OP_SINGLE_ECDH_USE /* needs OpenSSL >= 1.0.0 */
1670#define SSL_OP_SINGLE_ECDH_USE 0
1671#endif
Emeric Brunfc0421f2012-09-07 17:30:07 +02001672#ifndef SSL_MODE_RELEASE_BUFFERS /* needs OpenSSL >= 1.0.0 */
1673#define SSL_MODE_RELEASE_BUFFERS 0
1674#endif
Willy Tarreau396a1862014-11-13 14:06:52 +01001675#ifndef SSL_MODE_SMALL_BUFFERS /* needs small_records.patch */
1676#define SSL_MODE_SMALL_BUFFERS 0
1677#endif
Remi Gacognef46cd6e2014-06-12 14:58:40 +02001678
Willy Tarreau2a65ff02012-09-13 17:54:29 +02001679int ssl_sock_prepare_ctx(struct bind_conf *bind_conf, SSL_CTX *ctx, struct proxy *curproxy)
Emeric Brunfc0421f2012-09-07 17:30:07 +02001680{
1681 int cfgerr = 0;
Emeric Brun850efd52014-01-29 12:24:34 +01001682 int verify = SSL_VERIFY_NONE;
Remi Gacogneaf5c3da2014-05-19 10:29:58 +02001683 long ssloptions =
Emeric Brunfc0421f2012-09-07 17:30:07 +02001684 SSL_OP_ALL | /* all known workarounds for bugs */
1685 SSL_OP_NO_SSLv2 |
1686 SSL_OP_NO_COMPRESSION |
Emeric Bruna4bcd9a2012-09-20 16:19:02 +02001687 SSL_OP_SINGLE_DH_USE |
Emeric Brun2b58d042012-09-20 17:10:03 +02001688 SSL_OP_SINGLE_ECDH_USE |
Emeric Brun3c4bc6e2012-10-04 18:44:19 +02001689 SSL_OP_NO_SESSION_RESUMPTION_ON_RENEGOTIATION |
1690 SSL_OP_CIPHER_SERVER_PREFERENCE;
Remi Gacogneaf5c3da2014-05-19 10:29:58 +02001691 long sslmode =
Emeric Brunfc0421f2012-09-07 17:30:07 +02001692 SSL_MODE_ENABLE_PARTIAL_WRITE |
1693 SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER |
Willy Tarreau396a1862014-11-13 14:06:52 +01001694 SSL_MODE_RELEASE_BUFFERS |
1695 SSL_MODE_SMALL_BUFFERS;
Remi Gacognef46cd6e2014-06-12 14:58:40 +02001696 STACK_OF(SSL_CIPHER) * ciphers = NULL;
Willy Tarreaua616ba62014-10-26 06:49:19 +01001697 SSL_CIPHER * cipher = NULL;
Remi Gacognec1eab8c2014-06-12 18:20:11 +02001698 char cipher_description[128];
1699 /* The description of ciphers using an Ephemeral Diffie Hellman key exchange
1700 contains " Kx=DH " or " Kx=DH(". Beware of " Kx=DH/",
1701 which is not ephemeral DH. */
1702 const char dhe_description[] = " Kx=DH ";
1703 const char dhe_export_description[] = " Kx=DH(";
Remi Gacognef46cd6e2014-06-12 14:58:40 +02001704 int idx = 0;
1705 int dhe_found = 0;
Remi Gacogne23d5d372014-10-10 17:04:26 +02001706 SSL *ssl = NULL;
Emeric Brunfc0421f2012-09-07 17:30:07 +02001707
Thierry Fournier383085f2013-01-24 14:15:43 +01001708 /* Make sure openssl opens /dev/urandom before the chroot */
1709 if (!ssl_initialize_random()) {
1710 Alert("OpenSSL random data generator initialization failed.\n");
1711 cfgerr++;
1712 }
1713
Emeric Brun89675492012-10-05 13:48:26 +02001714 if (bind_conf->ssl_options & BC_SSL_O_NO_SSLV3)
Emeric Brunfc0421f2012-09-07 17:30:07 +02001715 ssloptions |= SSL_OP_NO_SSLv3;
Emeric Brun89675492012-10-05 13:48:26 +02001716 if (bind_conf->ssl_options & BC_SSL_O_NO_TLSV10)
Emeric Brunfc0421f2012-09-07 17:30:07 +02001717 ssloptions |= SSL_OP_NO_TLSv1;
Emeric Brun89675492012-10-05 13:48:26 +02001718 if (bind_conf->ssl_options & BC_SSL_O_NO_TLSV11)
Emeric Brunc0ff4922012-09-28 19:37:02 +02001719 ssloptions |= SSL_OP_NO_TLSv1_1;
Emeric Brun89675492012-10-05 13:48:26 +02001720 if (bind_conf->ssl_options & BC_SSL_O_NO_TLSV12)
Emeric Brunc0ff4922012-09-28 19:37:02 +02001721 ssloptions |= SSL_OP_NO_TLSv1_2;
Emeric Brun89675492012-10-05 13:48:26 +02001722 if (bind_conf->ssl_options & BC_SSL_O_NO_TLS_TICKETS)
Emeric Brun2d0c4822012-10-02 13:45:20 +02001723 ssloptions |= SSL_OP_NO_TICKET;
Emeric Brun2cb7ae52012-10-05 14:14:21 +02001724 if (bind_conf->ssl_options & BC_SSL_O_USE_SSLV3)
1725 SSL_CTX_set_ssl_version(ctx, SSLv3_server_method());
1726 if (bind_conf->ssl_options & BC_SSL_O_USE_TLSV10)
1727 SSL_CTX_set_ssl_version(ctx, TLSv1_server_method());
1728#if SSL_OP_NO_TLSv1_1
1729 if (bind_conf->ssl_options & BC_SSL_O_USE_TLSV11)
1730 SSL_CTX_set_ssl_version(ctx, TLSv1_1_server_method());
1731#endif
1732#if SSL_OP_NO_TLSv1_2
1733 if (bind_conf->ssl_options & BC_SSL_O_USE_TLSV12)
1734 SSL_CTX_set_ssl_version(ctx, TLSv1_2_server_method());
1735#endif
Emeric Brunfc0421f2012-09-07 17:30:07 +02001736
1737 SSL_CTX_set_options(ctx, ssloptions);
1738 SSL_CTX_set_mode(ctx, sslmode);
Emeric Brun850efd52014-01-29 12:24:34 +01001739 switch (bind_conf->verify) {
1740 case SSL_SOCK_VERIFY_NONE:
1741 verify = SSL_VERIFY_NONE;
1742 break;
1743 case SSL_SOCK_VERIFY_OPTIONAL:
1744 verify = SSL_VERIFY_PEER;
1745 break;
1746 case SSL_SOCK_VERIFY_REQUIRED:
1747 verify = SSL_VERIFY_PEER|SSL_VERIFY_FAIL_IF_NO_PEER_CERT;
1748 break;
1749 }
1750 SSL_CTX_set_verify(ctx, verify, ssl_sock_bind_verifycbk);
1751 if (verify & SSL_VERIFY_PEER) {
Emeric Brunfb510ea2012-10-05 12:00:26 +02001752 if (bind_conf->ca_file) {
Emeric Brund94b3fe2012-09-20 18:23:56 +02001753 /* load CAfile to verify */
Emeric Brunfb510ea2012-10-05 12:00:26 +02001754 if (!SSL_CTX_load_verify_locations(ctx, bind_conf->ca_file, NULL)) {
Emeric Brund94b3fe2012-09-20 18:23:56 +02001755 Alert("Proxy '%s': unable to load CA file '%s' for bind '%s' at [%s:%d].\n",
Emeric Brunfb510ea2012-10-05 12:00:26 +02001756 curproxy->id, bind_conf->ca_file, bind_conf->arg, bind_conf->file, bind_conf->line);
Emeric Brund94b3fe2012-09-20 18:23:56 +02001757 cfgerr++;
1758 }
1759 /* set CA names fo client cert request, function returns void */
Emeric Brunfb510ea2012-10-05 12:00:26 +02001760 SSL_CTX_set_client_CA_list(ctx, SSL_load_client_CA_file(bind_conf->ca_file));
Emeric Brund94b3fe2012-09-20 18:23:56 +02001761 }
Emeric Brun850efd52014-01-29 12:24:34 +01001762 else {
1763 Alert("Proxy '%s': verify is enabled but no CA file specified for bind '%s' at [%s:%d].\n",
1764 curproxy->id, bind_conf->arg, bind_conf->file, bind_conf->line);
1765 cfgerr++;
1766 }
Emeric Brun051cdab2012-10-02 19:25:50 +02001767#ifdef X509_V_FLAG_CRL_CHECK
Emeric Brunfb510ea2012-10-05 12:00:26 +02001768 if (bind_conf->crl_file) {
Emeric Brund94b3fe2012-09-20 18:23:56 +02001769 X509_STORE *store = SSL_CTX_get_cert_store(ctx);
1770
Emeric Brunfb510ea2012-10-05 12:00:26 +02001771 if (!store || !X509_STORE_load_locations(store, bind_conf->crl_file, NULL)) {
Emeric Brund94b3fe2012-09-20 18:23:56 +02001772 Alert("Proxy '%s': unable to configure CRL file '%s' for bind '%s' at [%s:%d].\n",
Emeric Brunfb510ea2012-10-05 12:00:26 +02001773 curproxy->id, bind_conf->ca_file, bind_conf->arg, bind_conf->file, bind_conf->line);
Emeric Brund94b3fe2012-09-20 18:23:56 +02001774 cfgerr++;
1775 }
Emeric Brun561e5742012-10-02 15:20:55 +02001776 else {
1777 X509_STORE_set_flags(store, X509_V_FLAG_CRL_CHECK|X509_V_FLAG_CRL_CHECK_ALL);
1778 }
Emeric Brund94b3fe2012-09-20 18:23:56 +02001779 }
Emeric Brun051cdab2012-10-02 19:25:50 +02001780#endif
Emeric Brun644cde02012-12-14 11:21:13 +01001781 ERR_clear_error();
Emeric Brund94b3fe2012-09-20 18:23:56 +02001782 }
Emeric Brunfc0421f2012-09-07 17:30:07 +02001783
Nenad Merdanovic05552d42015-02-27 19:56:49 +01001784#if (defined SSL_CTRL_SET_TLSEXT_TICKET_KEY_CB && TLS_TICKETS_NO > 0)
1785 if(bind_conf->tls_ticket_keys) {
1786 if (!SSL_CTX_set_tlsext_ticket_key_cb(ctx, ssl_tlsext_ticket_key_cb)) {
1787 Alert("Proxy '%s': unable to set callback for TLS ticket validation for bind '%s' at [%s:%d].\n",
1788 curproxy->id, bind_conf->arg, bind_conf->file, bind_conf->line);
1789 cfgerr++;
1790 }
1791 }
1792#endif
1793
Emeric Brun4f65bff2012-11-16 15:11:00 +01001794 if (global.tune.ssllifetime)
1795 SSL_CTX_set_timeout(ctx, global.tune.ssllifetime);
1796
Emeric Brunfc0421f2012-09-07 17:30:07 +02001797 shared_context_set_cache(ctx);
Willy Tarreau2a65ff02012-09-13 17:54:29 +02001798 if (bind_conf->ciphers &&
1799 !SSL_CTX_set_cipher_list(ctx, bind_conf->ciphers)) {
Emeric Brunfc0421f2012-09-07 17:30:07 +02001800 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 +02001801 curproxy->id, bind_conf->ciphers, bind_conf->arg, bind_conf->file, bind_conf->line);
Emeric Brunfc0421f2012-09-07 17:30:07 +02001802 cfgerr++;
1803 }
1804
Remi Gacognef46cd6e2014-06-12 14:58:40 +02001805 /* If tune.ssl.default-dh-param has not been set and
1806 no static DH params were in the certificate file. */
1807 if (global.tune.ssl_default_dh_param == 0) {
Lukas Tribus90132722014-08-18 00:56:33 +02001808
Remi Gacogne23d5d372014-10-10 17:04:26 +02001809 ssl = SSL_new(ctx);
Remi Gacognef46cd6e2014-06-12 14:58:40 +02001810
Remi Gacogne23d5d372014-10-10 17:04:26 +02001811 if (ssl) {
1812 ciphers = SSL_get_ciphers(ssl);
1813
1814 if (ciphers) {
1815 for (idx = 0; idx < sk_SSL_CIPHER_num(ciphers); idx++) {
1816 cipher = sk_SSL_CIPHER_value(ciphers, idx);
1817 if (SSL_CIPHER_description(cipher, cipher_description, sizeof (cipher_description)) == cipher_description) {
1818 if (strstr(cipher_description, dhe_description) != NULL ||
1819 strstr(cipher_description, dhe_export_description) != NULL) {
1820 dhe_found = 1;
1821 break;
1822 }
Remi Gacognec1eab8c2014-06-12 18:20:11 +02001823 }
Remi Gacognef46cd6e2014-06-12 14:58:40 +02001824 }
1825 }
Remi Gacogne23d5d372014-10-10 17:04:26 +02001826 SSL_free(ssl);
1827 ssl = NULL;
Lukas Tribus90132722014-08-18 00:56:33 +02001828 }
Remi Gacognef46cd6e2014-06-12 14:58:40 +02001829
Lukas Tribus90132722014-08-18 00:56:33 +02001830 if (dhe_found) {
1831 Warning("Setting tune.ssl.default-dh-param to 1024 by default, if your workload permits it you should set it to at least 2048. Please set a value >= 1024 to make this warning disappear.\n");
Remi Gacognef46cd6e2014-06-12 14:58:40 +02001832 }
1833
1834 global.tune.ssl_default_dh_param = 1024;
1835 }
Remi Gacogne8de54152014-07-15 11:36:40 +02001836
1837#ifndef OPENSSL_NO_DH
1838 if (global.tune.ssl_default_dh_param >= 1024) {
1839 if (local_dh_1024 == NULL) {
1840 local_dh_1024 = ssl_get_dh_1024();
1841 }
1842 if (global.tune.ssl_default_dh_param >= 2048) {
1843 if (local_dh_2048 == NULL) {
1844 local_dh_2048 = ssl_get_dh_2048();
1845 }
1846 if (global.tune.ssl_default_dh_param >= 4096) {
1847 if (local_dh_4096 == NULL) {
1848 local_dh_4096 = ssl_get_dh_4096();
1849 }
1850 if (global.tune.ssl_default_dh_param >= 8192 &&
1851 local_dh_8192 == NULL) {
1852 local_dh_8192 = ssl_get_dh_8192();
1853 }
1854 }
1855 }
1856 }
1857#endif /* OPENSSL_NO_DH */
Remi Gacognef46cd6e2014-06-12 14:58:40 +02001858
Emeric Brunfc0421f2012-09-07 17:30:07 +02001859 SSL_CTX_set_info_callback(ctx, ssl_sock_infocbk);
Willy Tarreau5cbe4ef2014-05-08 22:45:11 +02001860#if OPENSSL_VERSION_NUMBER >= 0x00907000L
Emeric Brun29f037d2014-04-25 19:05:36 +02001861 SSL_CTX_set_msg_callback(ctx, ssl_sock_msgcbk);
Willy Tarreau5cbe4ef2014-05-08 22:45:11 +02001862#endif
Emeric Brun29f037d2014-04-25 19:05:36 +02001863
Willy Tarreau6c9a3d52012-10-18 18:57:14 +02001864#ifdef OPENSSL_NPN_NEGOTIATED
1865 if (bind_conf->npn_str)
1866 SSL_CTX_set_next_protos_advertised_cb(ctx, ssl_sock_advertise_npn_protos, bind_conf);
1867#endif
Dirkjan Bussink48f1c4e2014-02-13 12:29:42 +01001868#ifdef TLSEXT_TYPE_application_layer_protocol_negotiation
Willy Tarreauab861d32013-04-02 02:30:41 +02001869 if (bind_conf->alpn_str)
Dirkjan Bussink48f1c4e2014-02-13 12:29:42 +01001870 SSL_CTX_set_alpn_select_cb(ctx, ssl_sock_advertise_alpn_protos, bind_conf);
Willy Tarreauab861d32013-04-02 02:30:41 +02001871#endif
Willy Tarreau6c9a3d52012-10-18 18:57:14 +02001872
Emeric Brunfc0421f2012-09-07 17:30:07 +02001873#ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME
1874 SSL_CTX_set_tlsext_servername_callback(ctx, ssl_sock_switchctx_cbk);
Willy Tarreau2a65ff02012-09-13 17:54:29 +02001875 SSL_CTX_set_tlsext_servername_arg(ctx, bind_conf);
Emeric Brunfc0421f2012-09-07 17:30:07 +02001876#endif
Emeric Brun2b58d042012-09-20 17:10:03 +02001877#if defined(SSL_CTX_set_tmp_ecdh) && !defined(OPENSSL_NO_ECDH)
Emeric Brun6924ef82013-03-06 14:08:53 +01001878 {
Emeric Brun2b58d042012-09-20 17:10:03 +02001879 int i;
1880 EC_KEY *ecdh;
1881
Emeric Brun6924ef82013-03-06 14:08:53 +01001882 i = OBJ_sn2nid(bind_conf->ecdhe ? bind_conf->ecdhe : ECDHE_DEFAULT_CURVE);
Emeric Brun2b58d042012-09-20 17:10:03 +02001883 if (!i || ((ecdh = EC_KEY_new_by_curve_name(i)) == NULL)) {
1884 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 +01001885 curproxy->id, bind_conf->ecdhe ? bind_conf->ecdhe : ECDHE_DEFAULT_CURVE,
1886 bind_conf->arg, bind_conf->file, bind_conf->line);
Emeric Brun2b58d042012-09-20 17:10:03 +02001887 cfgerr++;
1888 }
1889 else {
1890 SSL_CTX_set_tmp_ecdh(ctx, ecdh);
1891 EC_KEY_free(ecdh);
1892 }
1893 }
1894#endif
1895
Emeric Brunfc0421f2012-09-07 17:30:07 +02001896 return cfgerr;
1897}
1898
Evan Broderbe554312013-06-27 00:05:25 -07001899static int ssl_sock_srv_hostcheck(const char *pattern, const char *hostname)
1900{
1901 const char *pattern_wildcard, *pattern_left_label_end, *hostname_left_label_end;
1902 size_t prefixlen, suffixlen;
1903
1904 /* Trivial case */
1905 if (strcmp(pattern, hostname) == 0)
1906 return 1;
1907
Evan Broderbe554312013-06-27 00:05:25 -07001908 /* The rest of this logic is based on RFC 6125, section 6.4.3
1909 * (http://tools.ietf.org/html/rfc6125#section-6.4.3) */
1910
Emeric Bruna848dae2013-10-08 11:27:28 +02001911 pattern_wildcard = NULL;
1912 pattern_left_label_end = pattern;
1913 while (*pattern_left_label_end != '.') {
1914 switch (*pattern_left_label_end) {
1915 case 0:
1916 /* End of label not found */
1917 return 0;
1918 case '*':
1919 /* If there is more than one wildcards */
1920 if (pattern_wildcard)
1921 return 0;
1922 pattern_wildcard = pattern_left_label_end;
1923 break;
1924 }
1925 pattern_left_label_end++;
1926 }
1927
1928 /* If it's not trivial and there is no wildcard, it can't
1929 * match */
1930 if (!pattern_wildcard)
Evan Broderbe554312013-06-27 00:05:25 -07001931 return 0;
1932
1933 /* Make sure all labels match except the leftmost */
1934 hostname_left_label_end = strchr(hostname, '.');
1935 if (!hostname_left_label_end
1936 || strcmp(pattern_left_label_end, hostname_left_label_end) != 0)
1937 return 0;
1938
1939 /* Make sure the leftmost label of the hostname is long enough
1940 * that the wildcard can match */
Emeric Brun369da852013-10-08 11:39:35 +02001941 if (hostname_left_label_end - hostname < (pattern_left_label_end - pattern) - 1)
Evan Broderbe554312013-06-27 00:05:25 -07001942 return 0;
1943
1944 /* Finally compare the string on either side of the
1945 * wildcard */
1946 prefixlen = pattern_wildcard - pattern;
1947 suffixlen = pattern_left_label_end - (pattern_wildcard + 1);
Emeric Bruna848dae2013-10-08 11:27:28 +02001948 if ((prefixlen && (memcmp(pattern, hostname, prefixlen) != 0))
1949 || (suffixlen && (memcmp(pattern_wildcard + 1, hostname_left_label_end - suffixlen, suffixlen) != 0)))
Evan Broderbe554312013-06-27 00:05:25 -07001950 return 0;
1951
1952 return 1;
1953}
1954
1955static int ssl_sock_srv_verifycbk(int ok, X509_STORE_CTX *ctx)
1956{
1957 SSL *ssl;
1958 struct connection *conn;
1959 char *servername;
1960
1961 int depth;
1962 X509 *cert;
1963 STACK_OF(GENERAL_NAME) *alt_names;
1964 int i;
1965 X509_NAME *cert_subject;
1966 char *str;
1967
1968 if (ok == 0)
1969 return ok;
1970
1971 ssl = X509_STORE_CTX_get_ex_data(ctx, SSL_get_ex_data_X509_STORE_CTX_idx());
1972 conn = (struct connection *)SSL_get_app_data(ssl);
1973
1974 servername = objt_server(conn->target)->ssl_ctx.verify_host;
1975
1976 /* We only need to verify the CN on the actual server cert,
1977 * not the indirect CAs */
1978 depth = X509_STORE_CTX_get_error_depth(ctx);
1979 if (depth != 0)
1980 return ok;
1981
1982 /* At this point, the cert is *not* OK unless we can find a
1983 * hostname match */
1984 ok = 0;
1985
1986 cert = X509_STORE_CTX_get_current_cert(ctx);
1987 /* It seems like this might happen if verify peer isn't set */
1988 if (!cert)
1989 return ok;
1990
1991 alt_names = X509_get_ext_d2i(cert, NID_subject_alt_name, NULL, NULL);
1992 if (alt_names) {
1993 for (i = 0; !ok && i < sk_GENERAL_NAME_num(alt_names); i++) {
1994 GENERAL_NAME *name = sk_GENERAL_NAME_value(alt_names, i);
1995 if (name->type == GEN_DNS) {
Emeric Bruna33410c2013-09-17 15:47:48 +02001996#if OPENSSL_VERSION_NUMBER < 0x00907000L
1997 if (ASN1_STRING_to_UTF8((unsigned char **)&str, name->d.ia5) >= 0) {
1998#else
Evan Broderbe554312013-06-27 00:05:25 -07001999 if (ASN1_STRING_to_UTF8((unsigned char **)&str, name->d.dNSName) >= 0) {
Emeric Bruna33410c2013-09-17 15:47:48 +02002000#endif
Evan Broderbe554312013-06-27 00:05:25 -07002001 ok = ssl_sock_srv_hostcheck(str, servername);
2002 OPENSSL_free(str);
2003 }
2004 }
2005 }
Emeric Brun4ad50a42013-09-17 15:19:54 +02002006 sk_GENERAL_NAME_pop_free(alt_names, GENERAL_NAME_free);
Evan Broderbe554312013-06-27 00:05:25 -07002007 }
2008
2009 cert_subject = X509_get_subject_name(cert);
2010 i = -1;
2011 while (!ok && (i = X509_NAME_get_index_by_NID(cert_subject, NID_commonName, i)) != -1) {
2012 X509_NAME_ENTRY *entry = X509_NAME_get_entry(cert_subject, i);
2013 if (ASN1_STRING_to_UTF8((unsigned char **)&str, entry->value) >= 0) {
2014 ok = ssl_sock_srv_hostcheck(str, servername);
2015 OPENSSL_free(str);
2016 }
2017 }
2018
2019 return ok;
2020}
2021
Emeric Brun94324a42012-10-11 14:00:19 +02002022/* prepare ssl context from servers options. Returns an error count */
2023int ssl_sock_prepare_srv_ctx(struct server *srv, struct proxy *curproxy)
2024{
2025 int cfgerr = 0;
Remi Gacogneaf5c3da2014-05-19 10:29:58 +02002026 long options =
Emeric Brun94324a42012-10-11 14:00:19 +02002027 SSL_OP_ALL | /* all known workarounds for bugs */
2028 SSL_OP_NO_SSLv2 |
2029 SSL_OP_NO_COMPRESSION;
Remi Gacogneaf5c3da2014-05-19 10:29:58 +02002030 long mode =
Emeric Brun94324a42012-10-11 14:00:19 +02002031 SSL_MODE_ENABLE_PARTIAL_WRITE |
2032 SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER |
Willy Tarreau396a1862014-11-13 14:06:52 +01002033 SSL_MODE_RELEASE_BUFFERS |
2034 SSL_MODE_SMALL_BUFFERS;
Emeric Brun850efd52014-01-29 12:24:34 +01002035 int verify = SSL_VERIFY_NONE;
Emeric Brun94324a42012-10-11 14:00:19 +02002036
Thierry Fournier383085f2013-01-24 14:15:43 +01002037 /* Make sure openssl opens /dev/urandom before the chroot */
2038 if (!ssl_initialize_random()) {
2039 Alert("OpenSSL random data generator initialization failed.\n");
2040 cfgerr++;
2041 }
2042
Willy Tarreaufce03112015-01-15 21:32:40 +01002043 /* Automatic memory computations need to know we use SSL there */
2044 global.ssl_used_backend = 1;
2045
2046 /* Initiate SSL context for current server */
Emeric Brun94324a42012-10-11 14:00:19 +02002047 srv->ssl_ctx.reused_sess = NULL;
2048 if (srv->use_ssl)
2049 srv->xprt = &ssl_sock;
2050 if (srv->check.use_ssl)
Cyril Bonté9ce13112014-11-15 22:41:27 +01002051 srv->check.xprt = &ssl_sock;
Emeric Brun94324a42012-10-11 14:00:19 +02002052
2053 srv->ssl_ctx.ctx = SSL_CTX_new(SSLv23_client_method());
2054 if (!srv->ssl_ctx.ctx) {
2055 Alert("config : %s '%s', server '%s': unable to allocate ssl context.\n",
2056 proxy_type_str(curproxy), curproxy->id,
2057 srv->id);
2058 cfgerr++;
2059 return cfgerr;
2060 }
Emeric Bruna7aa3092012-10-26 12:58:00 +02002061 if (srv->ssl_ctx.client_crt) {
2062 if (SSL_CTX_use_PrivateKey_file(srv->ssl_ctx.ctx, srv->ssl_ctx.client_crt, SSL_FILETYPE_PEM) <= 0) {
2063 Alert("config : %s '%s', server '%s': unable to load SSL private key from PEM file '%s'.\n",
2064 proxy_type_str(curproxy), curproxy->id,
2065 srv->id, srv->ssl_ctx.client_crt);
2066 cfgerr++;
2067 }
2068 else if (SSL_CTX_use_certificate_chain_file(srv->ssl_ctx.ctx, srv->ssl_ctx.client_crt) <= 0) {
2069 Alert("config : %s '%s', server '%s': unable to load ssl certificate from PEM file '%s'.\n",
2070 proxy_type_str(curproxy), curproxy->id,
2071 srv->id, srv->ssl_ctx.client_crt);
2072 cfgerr++;
2073 }
2074 else if (SSL_CTX_check_private_key(srv->ssl_ctx.ctx) <= 0) {
2075 Alert("config : %s '%s', server '%s': inconsistencies between private key and certificate loaded from PEM file '%s'.\n",
2076 proxy_type_str(curproxy), curproxy->id,
2077 srv->id, srv->ssl_ctx.client_crt);
2078 cfgerr++;
2079 }
2080 }
Emeric Brun94324a42012-10-11 14:00:19 +02002081
2082 if (srv->ssl_ctx.options & SRV_SSL_O_NO_SSLV3)
2083 options |= SSL_OP_NO_SSLv3;
2084 if (srv->ssl_ctx.options & SRV_SSL_O_NO_TLSV10)
2085 options |= SSL_OP_NO_TLSv1;
2086 if (srv->ssl_ctx.options & SRV_SSL_O_NO_TLSV11)
2087 options |= SSL_OP_NO_TLSv1_1;
2088 if (srv->ssl_ctx.options & SRV_SSL_O_NO_TLSV12)
2089 options |= SSL_OP_NO_TLSv1_2;
Emeric Brunf9c5c472012-10-11 15:28:34 +02002090 if (srv->ssl_ctx.options & SRV_SSL_O_NO_TLS_TICKETS)
2091 options |= SSL_OP_NO_TICKET;
Emeric Brun94324a42012-10-11 14:00:19 +02002092 if (srv->ssl_ctx.options & SRV_SSL_O_USE_SSLV3)
2093 SSL_CTX_set_ssl_version(srv->ssl_ctx.ctx, SSLv3_client_method());
2094 if (srv->ssl_ctx.options & SRV_SSL_O_USE_TLSV10)
2095 SSL_CTX_set_ssl_version(srv->ssl_ctx.ctx, TLSv1_client_method());
2096#if SSL_OP_NO_TLSv1_1
2097 if (srv->ssl_ctx.options & SRV_SSL_O_USE_TLSV11)
2098 SSL_CTX_set_ssl_version(srv->ssl_ctx.ctx, TLSv1_1_client_method());
2099#endif
2100#if SSL_OP_NO_TLSv1_2
2101 if (srv->ssl_ctx.options & SRV_SSL_O_USE_TLSV12)
2102 SSL_CTX_set_ssl_version(srv->ssl_ctx.ctx, TLSv1_2_client_method());
2103#endif
2104
2105 SSL_CTX_set_options(srv->ssl_ctx.ctx, options);
2106 SSL_CTX_set_mode(srv->ssl_ctx.ctx, mode);
Emeric Brun850efd52014-01-29 12:24:34 +01002107
2108 if (global.ssl_server_verify == SSL_SERVER_VERIFY_REQUIRED)
2109 verify = SSL_VERIFY_PEER;
2110
2111 switch (srv->ssl_ctx.verify) {
2112 case SSL_SOCK_VERIFY_NONE:
2113 verify = SSL_VERIFY_NONE;
2114 break;
2115 case SSL_SOCK_VERIFY_REQUIRED:
2116 verify = SSL_VERIFY_PEER;
2117 break;
2118 }
Evan Broderbe554312013-06-27 00:05:25 -07002119 SSL_CTX_set_verify(srv->ssl_ctx.ctx,
Emeric Brun850efd52014-01-29 12:24:34 +01002120 verify,
Evan Broderbe554312013-06-27 00:05:25 -07002121 srv->ssl_ctx.verify_host ? ssl_sock_srv_verifycbk : NULL);
Emeric Brun850efd52014-01-29 12:24:34 +01002122 if (verify & SSL_VERIFY_PEER) {
Emeric Brunef42d922012-10-11 16:11:36 +02002123 if (srv->ssl_ctx.ca_file) {
2124 /* load CAfile to verify */
2125 if (!SSL_CTX_load_verify_locations(srv->ssl_ctx.ctx, srv->ssl_ctx.ca_file, NULL)) {
Willy Tarreau07ba08b2014-02-16 19:22:08 +01002126 Alert("Proxy '%s', server '%s' [%s:%d] unable to load CA file '%s'.\n",
Emeric Brunef42d922012-10-11 16:11:36 +02002127 curproxy->id, srv->id,
2128 srv->conf.file, srv->conf.line, srv->ssl_ctx.ca_file);
2129 cfgerr++;
2130 }
2131 }
Emeric Brun850efd52014-01-29 12:24:34 +01002132 else {
2133 if (global.ssl_server_verify == SSL_SERVER_VERIFY_REQUIRED)
Willy Tarreau07ba08b2014-02-16 19:22:08 +01002134 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 +01002135 curproxy->id, srv->id,
2136 srv->conf.file, srv->conf.line);
2137 else
Willy Tarreau07ba08b2014-02-16 19:22:08 +01002138 Alert("Proxy '%s', server '%s' [%s:%d] verify is enabled but no CA file specified.\n",
Emeric Brun850efd52014-01-29 12:24:34 +01002139 curproxy->id, srv->id,
2140 srv->conf.file, srv->conf.line);
2141 cfgerr++;
2142 }
Emeric Brunef42d922012-10-11 16:11:36 +02002143#ifdef X509_V_FLAG_CRL_CHECK
2144 if (srv->ssl_ctx.crl_file) {
2145 X509_STORE *store = SSL_CTX_get_cert_store(srv->ssl_ctx.ctx);
2146
2147 if (!store || !X509_STORE_load_locations(store, srv->ssl_ctx.crl_file, NULL)) {
Willy Tarreau07ba08b2014-02-16 19:22:08 +01002148 Alert("Proxy '%s', server '%s' [%s:%d] unable to configure CRL file '%s'.\n",
Emeric Brunef42d922012-10-11 16:11:36 +02002149 curproxy->id, srv->id,
2150 srv->conf.file, srv->conf.line, srv->ssl_ctx.crl_file);
2151 cfgerr++;
2152 }
2153 else {
2154 X509_STORE_set_flags(store, X509_V_FLAG_CRL_CHECK|X509_V_FLAG_CRL_CHECK_ALL);
2155 }
2156 }
2157#endif
2158 }
2159
Emeric Brun4f65bff2012-11-16 15:11:00 +01002160 if (global.tune.ssllifetime)
2161 SSL_CTX_set_timeout(srv->ssl_ctx.ctx, global.tune.ssllifetime);
2162
Emeric Brun94324a42012-10-11 14:00:19 +02002163 SSL_CTX_set_session_cache_mode(srv->ssl_ctx.ctx, SSL_SESS_CACHE_OFF);
2164 if (srv->ssl_ctx.ciphers &&
2165 !SSL_CTX_set_cipher_list(srv->ssl_ctx.ctx, srv->ssl_ctx.ciphers)) {
2166 Alert("Proxy '%s', server '%s' [%s:%d] : unable to set SSL cipher list to '%s'.\n",
2167 curproxy->id, srv->id,
2168 srv->conf.file, srv->conf.line, srv->ssl_ctx.ciphers);
2169 cfgerr++;
2170 }
2171
2172 return cfgerr;
2173}
2174
Willy Tarreau2a65ff02012-09-13 17:54:29 +02002175/* Walks down the two trees in bind_conf and prepares all certs. The pointer may
Emeric Brunfc0421f2012-09-07 17:30:07 +02002176 * be NULL, in which case nothing is done. Returns the number of errors
2177 * encountered.
2178 */
Willy Tarreau2a65ff02012-09-13 17:54:29 +02002179int ssl_sock_prepare_all_ctx(struct bind_conf *bind_conf, struct proxy *px)
Emeric Brunfc0421f2012-09-07 17:30:07 +02002180{
2181 struct ebmb_node *node;
2182 struct sni_ctx *sni;
2183 int err = 0;
2184
Willy Tarreau2a65ff02012-09-13 17:54:29 +02002185 if (!bind_conf || !bind_conf->is_ssl)
Emeric Brunfc0421f2012-09-07 17:30:07 +02002186 return 0;
2187
Willy Tarreaufce03112015-01-15 21:32:40 +01002188 /* Automatic memory computations need to know we use SSL there */
2189 global.ssl_used_frontend = 1;
2190
Emeric Brun0bed9942014-10-30 19:25:24 +01002191 if (bind_conf->default_ctx)
2192 err += ssl_sock_prepare_ctx(bind_conf, bind_conf->default_ctx, px);
2193
Willy Tarreau2a65ff02012-09-13 17:54:29 +02002194 node = ebmb_first(&bind_conf->sni_ctx);
Emeric Brunfc0421f2012-09-07 17:30:07 +02002195 while (node) {
2196 sni = ebmb_entry(node, struct sni_ctx, name);
Emeric Brun0bed9942014-10-30 19:25:24 +01002197 if (!sni->order && sni->ctx != bind_conf->default_ctx)
2198 /* only initialize the CTX on its first occurrence and
2199 if it is not the default_ctx */
Willy Tarreau2a65ff02012-09-13 17:54:29 +02002200 err += ssl_sock_prepare_ctx(bind_conf, sni->ctx, px);
Emeric Brunfc0421f2012-09-07 17:30:07 +02002201 node = ebmb_next(node);
2202 }
2203
Willy Tarreau2a65ff02012-09-13 17:54:29 +02002204 node = ebmb_first(&bind_conf->sni_w_ctx);
Emeric Brunfc0421f2012-09-07 17:30:07 +02002205 while (node) {
2206 sni = ebmb_entry(node, struct sni_ctx, name);
Emeric Brun0bed9942014-10-30 19:25:24 +01002207 if (!sni->order && sni->ctx != bind_conf->default_ctx)
2208 /* only initialize the CTX on its first occurrence and
2209 if it is not the default_ctx */
Willy Tarreau2a65ff02012-09-13 17:54:29 +02002210 err += ssl_sock_prepare_ctx(bind_conf, sni->ctx, px);
Emeric Brunfc0421f2012-09-07 17:30:07 +02002211 node = ebmb_next(node);
2212 }
2213 return err;
2214}
2215
Willy Tarreau2a65ff02012-09-13 17:54:29 +02002216/* Walks down the two trees in bind_conf and frees all the certs. The pointer may
Emeric Brunfc0421f2012-09-07 17:30:07 +02002217 * be NULL, in which case nothing is done. The default_ctx is nullified too.
2218 */
Willy Tarreau2a65ff02012-09-13 17:54:29 +02002219void ssl_sock_free_all_ctx(struct bind_conf *bind_conf)
Emeric Brunfc0421f2012-09-07 17:30:07 +02002220{
2221 struct ebmb_node *node, *back;
2222 struct sni_ctx *sni;
2223
Willy Tarreau2a65ff02012-09-13 17:54:29 +02002224 if (!bind_conf || !bind_conf->is_ssl)
Emeric Brunfc0421f2012-09-07 17:30:07 +02002225 return;
2226
Willy Tarreau2a65ff02012-09-13 17:54:29 +02002227 node = ebmb_first(&bind_conf->sni_ctx);
Emeric Brunfc0421f2012-09-07 17:30:07 +02002228 while (node) {
2229 sni = ebmb_entry(node, struct sni_ctx, name);
2230 back = ebmb_next(node);
2231 ebmb_delete(node);
2232 if (!sni->order) /* only free the CTX on its first occurrence */
2233 SSL_CTX_free(sni->ctx);
2234 free(sni);
2235 node = back;
2236 }
2237
Willy Tarreau2a65ff02012-09-13 17:54:29 +02002238 node = ebmb_first(&bind_conf->sni_w_ctx);
Emeric Brunfc0421f2012-09-07 17:30:07 +02002239 while (node) {
2240 sni = ebmb_entry(node, struct sni_ctx, name);
2241 back = ebmb_next(node);
2242 ebmb_delete(node);
2243 if (!sni->order) /* only free the CTX on its first occurrence */
2244 SSL_CTX_free(sni->ctx);
2245 free(sni);
2246 node = back;
2247 }
2248
Willy Tarreau2a65ff02012-09-13 17:54:29 +02002249 bind_conf->default_ctx = NULL;
Emeric Brune1f38db2012-09-03 20:36:47 +02002250}
2251
Emeric Brun46591952012-05-18 15:47:34 +02002252/*
2253 * This function is called if SSL * context is not yet allocated. The function
2254 * is designed to be called before any other data-layer operation and sets the
2255 * handshake flag on the connection. It is safe to call it multiple times.
2256 * It returns 0 on success and -1 in error case.
2257 */
2258static int ssl_sock_init(struct connection *conn)
2259{
2260 /* already initialized */
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02002261 if (conn->xprt_ctx)
Emeric Brun46591952012-05-18 15:47:34 +02002262 return 0;
2263
Willy Tarreau3c728722014-01-23 13:50:42 +01002264 if (!conn_ctrl_ready(conn))
Willy Tarreauf79c8172013-10-21 16:30:56 +02002265 return 0;
2266
Willy Tarreau20879a02012-12-03 16:32:10 +01002267 if (global.maxsslconn && sslconns >= global.maxsslconn) {
2268 conn->err_code = CO_ER_SSL_TOO_MANY;
Willy Tarreau403edff2012-09-06 11:58:37 +02002269 return -1;
Willy Tarreau20879a02012-12-03 16:32:10 +01002270 }
Willy Tarreau403edff2012-09-06 11:58:37 +02002271
Emeric Brun46591952012-05-18 15:47:34 +02002272 /* If it is in client mode initiate SSL session
2273 in connect state otherwise accept state */
Willy Tarreau3fdb3662012-11-12 00:42:33 +01002274 if (objt_server(conn->target)) {
Willy Tarreaufba03cd2014-11-13 13:48:58 +01002275 int may_retry = 1;
2276
2277 retry_connect:
Emeric Brun46591952012-05-18 15:47:34 +02002278 /* Alloc a new SSL session ctx */
Willy Tarreau3fdb3662012-11-12 00:42:33 +01002279 conn->xprt_ctx = SSL_new(objt_server(conn->target)->ssl_ctx.ctx);
Willy Tarreau20879a02012-12-03 16:32:10 +01002280 if (!conn->xprt_ctx) {
Willy Tarreaufba03cd2014-11-13 13:48:58 +01002281 if (may_retry--) {
2282 pool_gc2();
2283 goto retry_connect;
2284 }
Willy Tarreau20879a02012-12-03 16:32:10 +01002285 conn->err_code = CO_ER_SSL_NO_MEM;
Emeric Brun46591952012-05-18 15:47:34 +02002286 return -1;
Willy Tarreau20879a02012-12-03 16:32:10 +01002287 }
Emeric Brun46591952012-05-18 15:47:34 +02002288
Emeric Brun46591952012-05-18 15:47:34 +02002289 /* set fd on SSL session context */
Emeric Brun55476152014-11-12 17:35:37 +01002290 if (!SSL_set_fd(conn->xprt_ctx, conn->t.sock.fd)) {
2291 SSL_free(conn->xprt_ctx);
2292 conn->xprt_ctx = NULL;
Willy Tarreaufba03cd2014-11-13 13:48:58 +01002293 if (may_retry--) {
2294 pool_gc2();
2295 goto retry_connect;
2296 }
Emeric Brun55476152014-11-12 17:35:37 +01002297 conn->err_code = CO_ER_SSL_NO_MEM;
2298 return -1;
2299 }
Emeric Brun46591952012-05-18 15:47:34 +02002300
Evan Broderbe554312013-06-27 00:05:25 -07002301 /* set connection pointer */
Emeric Brun55476152014-11-12 17:35:37 +01002302 if (!SSL_set_app_data(conn->xprt_ctx, conn)) {
2303 SSL_free(conn->xprt_ctx);
2304 conn->xprt_ctx = NULL;
Willy Tarreaufba03cd2014-11-13 13:48:58 +01002305 if (may_retry--) {
2306 pool_gc2();
2307 goto retry_connect;
2308 }
Emeric Brun55476152014-11-12 17:35:37 +01002309 conn->err_code = CO_ER_SSL_NO_MEM;
2310 return -1;
2311 }
2312
2313 SSL_set_connect_state(conn->xprt_ctx);
2314 if (objt_server(conn->target)->ssl_ctx.reused_sess) {
2315 if(!SSL_set_session(conn->xprt_ctx, objt_server(conn->target)->ssl_ctx.reused_sess)) {
2316 SSL_SESSION_free(objt_server(conn->target)->ssl_ctx.reused_sess);
2317 objt_server(conn->target)->ssl_ctx.reused_sess = NULL;
2318 }
2319 }
Evan Broderbe554312013-06-27 00:05:25 -07002320
Emeric Brun46591952012-05-18 15:47:34 +02002321 /* leave init state and start handshake */
Willy Tarreau05737472012-09-04 08:03:39 +02002322 conn->flags |= CO_FL_SSL_WAIT_HS | CO_FL_WAIT_L6_CONN;
Willy Tarreau403edff2012-09-06 11:58:37 +02002323
2324 sslconns++;
Willy Tarreau71b734c2014-01-28 15:19:44 +01002325 totalsslconns++;
Emeric Brun46591952012-05-18 15:47:34 +02002326 return 0;
2327 }
Willy Tarreau3fdb3662012-11-12 00:42:33 +01002328 else if (objt_listener(conn->target)) {
Willy Tarreaufba03cd2014-11-13 13:48:58 +01002329 int may_retry = 1;
2330
2331 retry_accept:
Emeric Brun46591952012-05-18 15:47:34 +02002332 /* Alloc a new SSL session ctx */
Willy Tarreau3fdb3662012-11-12 00:42:33 +01002333 conn->xprt_ctx = SSL_new(objt_listener(conn->target)->bind_conf->default_ctx);
Willy Tarreau20879a02012-12-03 16:32:10 +01002334 if (!conn->xprt_ctx) {
Willy Tarreaufba03cd2014-11-13 13:48:58 +01002335 if (may_retry--) {
2336 pool_gc2();
2337 goto retry_accept;
2338 }
Willy Tarreau20879a02012-12-03 16:32:10 +01002339 conn->err_code = CO_ER_SSL_NO_MEM;
Emeric Brun46591952012-05-18 15:47:34 +02002340 return -1;
Willy Tarreau20879a02012-12-03 16:32:10 +01002341 }
Emeric Brun46591952012-05-18 15:47:34 +02002342
Emeric Brun46591952012-05-18 15:47:34 +02002343 /* set fd on SSL session context */
Emeric Brun55476152014-11-12 17:35:37 +01002344 if (!SSL_set_fd(conn->xprt_ctx, conn->t.sock.fd)) {
2345 SSL_free(conn->xprt_ctx);
2346 conn->xprt_ctx = NULL;
Willy Tarreaufba03cd2014-11-13 13:48:58 +01002347 if (may_retry--) {
2348 pool_gc2();
2349 goto retry_accept;
2350 }
Emeric Brun55476152014-11-12 17:35:37 +01002351 conn->err_code = CO_ER_SSL_NO_MEM;
2352 return -1;
2353 }
Emeric Brun46591952012-05-18 15:47:34 +02002354
Emeric Brune1f38db2012-09-03 20:36:47 +02002355 /* set connection pointer */
Emeric Brun55476152014-11-12 17:35:37 +01002356 if (!SSL_set_app_data(conn->xprt_ctx, conn)) {
2357 SSL_free(conn->xprt_ctx);
2358 conn->xprt_ctx = NULL;
Willy Tarreaufba03cd2014-11-13 13:48:58 +01002359 if (may_retry--) {
2360 pool_gc2();
2361 goto retry_accept;
2362 }
Emeric Brun55476152014-11-12 17:35:37 +01002363 conn->err_code = CO_ER_SSL_NO_MEM;
2364 return -1;
2365 }
2366
2367 SSL_set_accept_state(conn->xprt_ctx);
Emeric Brune1f38db2012-09-03 20:36:47 +02002368
Emeric Brun46591952012-05-18 15:47:34 +02002369 /* leave init state and start handshake */
Willy Tarreau05737472012-09-04 08:03:39 +02002370 conn->flags |= CO_FL_SSL_WAIT_HS | CO_FL_WAIT_L6_CONN;
Willy Tarreau403edff2012-09-06 11:58:37 +02002371
2372 sslconns++;
Willy Tarreau71b734c2014-01-28 15:19:44 +01002373 totalsslconns++;
Emeric Brun46591952012-05-18 15:47:34 +02002374 return 0;
2375 }
2376 /* don't know how to handle such a target */
Willy Tarreau20879a02012-12-03 16:32:10 +01002377 conn->err_code = CO_ER_SSL_NO_TARGET;
Emeric Brun46591952012-05-18 15:47:34 +02002378 return -1;
2379}
2380
2381
2382/* This is the callback which is used when an SSL handshake is pending. It
2383 * updates the FD status if it wants some polling before being called again.
2384 * It returns 0 if it fails in a fatal way or needs to poll to go further,
2385 * otherwise it returns non-zero and removes itself from the connection's
2386 * flags (the bit is provided in <flag> by the caller).
2387 */
2388int ssl_sock_handshake(struct connection *conn, unsigned int flag)
2389{
2390 int ret;
2391
Willy Tarreau3c728722014-01-23 13:50:42 +01002392 if (!conn_ctrl_ready(conn))
Willy Tarreauf79c8172013-10-21 16:30:56 +02002393 return 0;
2394
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02002395 if (!conn->xprt_ctx)
Emeric Brun46591952012-05-18 15:47:34 +02002396 goto out_error;
2397
Emeric Brun674b7432012-11-08 19:21:55 +01002398 /* If we use SSL_do_handshake to process a reneg initiated by
2399 * the remote peer, it sometimes returns SSL_ERROR_SSL.
2400 * Usually SSL_write and SSL_read are used and process implicitly
2401 * the reneg handshake.
2402 * Here we use SSL_peek as a workaround for reneg.
2403 */
2404 if ((conn->flags & CO_FL_CONNECTED) && SSL_renegotiate_pending(conn->xprt_ctx)) {
2405 char c;
2406
2407 ret = SSL_peek(conn->xprt_ctx, &c, 1);
2408 if (ret <= 0) {
2409 /* handshake may have not been completed, let's find why */
2410 ret = SSL_get_error(conn->xprt_ctx, ret);
2411 if (ret == SSL_ERROR_WANT_WRITE) {
2412 /* SSL handshake needs to write, L4 connection may not be ready */
2413 __conn_sock_stop_recv(conn);
Willy Tarreaue1f50c42014-01-22 20:02:06 +01002414 __conn_sock_want_send(conn);
2415 fd_cant_send(conn->t.sock.fd);
Emeric Brun674b7432012-11-08 19:21:55 +01002416 return 0;
2417 }
2418 else if (ret == SSL_ERROR_WANT_READ) {
2419 /* handshake may have been completed but we have
2420 * no more data to read.
2421 */
2422 if (!SSL_renegotiate_pending(conn->xprt_ctx)) {
2423 ret = 1;
2424 goto reneg_ok;
2425 }
2426 /* SSL handshake needs to read, L4 connection is ready */
2427 if (conn->flags & CO_FL_WAIT_L4_CONN)
2428 conn->flags &= ~CO_FL_WAIT_L4_CONN;
2429 __conn_sock_stop_send(conn);
Willy Tarreaue1f50c42014-01-22 20:02:06 +01002430 __conn_sock_want_recv(conn);
2431 fd_cant_recv(conn->t.sock.fd);
Emeric Brun674b7432012-11-08 19:21:55 +01002432 return 0;
2433 }
2434 else if (ret == SSL_ERROR_SYSCALL) {
2435 /* if errno is null, then connection was successfully established */
2436 if (!errno && conn->flags & CO_FL_WAIT_L4_CONN)
2437 conn->flags &= ~CO_FL_WAIT_L4_CONN;
Willy Tarreau20879a02012-12-03 16:32:10 +01002438 if (!conn->err_code) {
Emeric Brun29f037d2014-04-25 19:05:36 +02002439 if (!((SSL *)conn->xprt_ctx)->packet_length) {
2440 if (!errno) {
2441 if (conn->xprt_st & SSL_SOCK_RECV_HEARTBEAT)
2442 conn->err_code = CO_ER_SSL_HANDSHAKE_HB;
2443 else
2444 conn->err_code = CO_ER_SSL_EMPTY;
2445 }
2446 else {
2447 if (conn->xprt_st & SSL_SOCK_RECV_HEARTBEAT)
2448 conn->err_code = CO_ER_SSL_HANDSHAKE_HB;
2449 else
2450 conn->err_code = CO_ER_SSL_ABORT;
2451 }
2452 }
2453 else {
2454 if (conn->xprt_st & SSL_SOCK_RECV_HEARTBEAT)
2455 conn->err_code = CO_ER_SSL_HANDSHAKE_HB;
Willy Tarreau20879a02012-12-03 16:32:10 +01002456 else
Emeric Brun29f037d2014-04-25 19:05:36 +02002457 conn->err_code = CO_ER_SSL_HANDSHAKE;
2458 }
Willy Tarreau20879a02012-12-03 16:32:10 +01002459 }
Emeric Brun674b7432012-11-08 19:21:55 +01002460 goto out_error;
2461 }
2462 else {
2463 /* Fail on all other handshake errors */
2464 /* Note: OpenSSL may leave unread bytes in the socket's
2465 * buffer, causing an RST to be emitted upon close() on
2466 * TCP sockets. We first try to drain possibly pending
2467 * data to avoid this as much as possible.
2468 */
Willy Tarreaud85c4852015-03-13 00:40:28 +01002469 conn_sock_drain(conn);
Willy Tarreau20879a02012-12-03 16:32:10 +01002470 if (!conn->err_code)
Willy Tarreauf51c6982014-04-25 20:02:39 +02002471 conn->err_code = (conn->xprt_st & SSL_SOCK_RECV_HEARTBEAT) ?
2472 CO_ER_SSL_KILLED_HB : CO_ER_SSL_HANDSHAKE;
Emeric Brun674b7432012-11-08 19:21:55 +01002473 goto out_error;
2474 }
2475 }
2476 /* read some data: consider handshake completed */
2477 goto reneg_ok;
2478 }
2479
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02002480 ret = SSL_do_handshake(conn->xprt_ctx);
Emeric Brun46591952012-05-18 15:47:34 +02002481 if (ret != 1) {
2482 /* handshake did not complete, let's find why */
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02002483 ret = SSL_get_error(conn->xprt_ctx, ret);
Emeric Brun46591952012-05-18 15:47:34 +02002484
2485 if (ret == SSL_ERROR_WANT_WRITE) {
2486 /* SSL handshake needs to write, L4 connection may not be ready */
2487 __conn_sock_stop_recv(conn);
Willy Tarreaue1f50c42014-01-22 20:02:06 +01002488 __conn_sock_want_send(conn);
2489 fd_cant_send(conn->t.sock.fd);
Emeric Brun46591952012-05-18 15:47:34 +02002490 return 0;
2491 }
2492 else if (ret == SSL_ERROR_WANT_READ) {
2493 /* SSL handshake needs to read, L4 connection is ready */
2494 if (conn->flags & CO_FL_WAIT_L4_CONN)
2495 conn->flags &= ~CO_FL_WAIT_L4_CONN;
2496 __conn_sock_stop_send(conn);
Willy Tarreaue1f50c42014-01-22 20:02:06 +01002497 __conn_sock_want_recv(conn);
2498 fd_cant_recv(conn->t.sock.fd);
Emeric Brun46591952012-05-18 15:47:34 +02002499 return 0;
2500 }
Willy Tarreau89230192012-09-28 20:22:13 +02002501 else if (ret == SSL_ERROR_SYSCALL) {
2502 /* if errno is null, then connection was successfully established */
2503 if (!errno && conn->flags & CO_FL_WAIT_L4_CONN)
2504 conn->flags &= ~CO_FL_WAIT_L4_CONN;
Willy Tarreau20879a02012-12-03 16:32:10 +01002505
Emeric Brun29f037d2014-04-25 19:05:36 +02002506 if (!((SSL *)conn->xprt_ctx)->packet_length) {
2507 if (!errno) {
2508 if (conn->xprt_st & SSL_SOCK_RECV_HEARTBEAT)
2509 conn->err_code = CO_ER_SSL_HANDSHAKE_HB;
2510 else
2511 conn->err_code = CO_ER_SSL_EMPTY;
2512 }
2513 else {
2514 if (conn->xprt_st & SSL_SOCK_RECV_HEARTBEAT)
2515 conn->err_code = CO_ER_SSL_HANDSHAKE_HB;
2516 else
2517 conn->err_code = CO_ER_SSL_ABORT;
2518 }
2519 }
2520 else {
2521 if (conn->xprt_st & SSL_SOCK_RECV_HEARTBEAT)
2522 conn->err_code = CO_ER_SSL_HANDSHAKE_HB;
Willy Tarreau20879a02012-12-03 16:32:10 +01002523 else
Emeric Brun29f037d2014-04-25 19:05:36 +02002524 conn->err_code = CO_ER_SSL_HANDSHAKE;
2525 }
Willy Tarreau89230192012-09-28 20:22:13 +02002526 goto out_error;
2527 }
Emeric Brun46591952012-05-18 15:47:34 +02002528 else {
2529 /* Fail on all other handshake errors */
Willy Tarreau566dc552012-10-19 20:52:18 +02002530 /* Note: OpenSSL may leave unread bytes in the socket's
2531 * buffer, causing an RST to be emitted upon close() on
2532 * TCP sockets. We first try to drain possibly pending
2533 * data to avoid this as much as possible.
2534 */
Willy Tarreaud85c4852015-03-13 00:40:28 +01002535 conn_sock_drain(conn);
Willy Tarreau20879a02012-12-03 16:32:10 +01002536 if (!conn->err_code)
Willy Tarreauf51c6982014-04-25 20:02:39 +02002537 conn->err_code = (conn->xprt_st & SSL_SOCK_RECV_HEARTBEAT) ?
2538 CO_ER_SSL_KILLED_HB : CO_ER_SSL_HANDSHAKE;
Emeric Brun46591952012-05-18 15:47:34 +02002539 goto out_error;
2540 }
2541 }
2542
Emeric Brun674b7432012-11-08 19:21:55 +01002543reneg_ok:
2544
Emeric Brun46591952012-05-18 15:47:34 +02002545 /* Handshake succeeded */
Willy Tarreau0c9c2722014-05-28 12:28:58 +02002546 if (!SSL_session_reused(conn->xprt_ctx)) {
2547 if (objt_server(conn->target)) {
2548 update_freq_ctr(&global.ssl_be_keys_per_sec, 1);
2549 if (global.ssl_be_keys_per_sec.curr_ctr > global.ssl_be_keys_max)
2550 global.ssl_be_keys_max = global.ssl_be_keys_per_sec.curr_ctr;
2551
Emeric Brun46591952012-05-18 15:47:34 +02002552 /* check if session was reused, if not store current session on server for reuse */
Willy Tarreau3fdb3662012-11-12 00:42:33 +01002553 if (objt_server(conn->target)->ssl_ctx.reused_sess)
2554 SSL_SESSION_free(objt_server(conn->target)->ssl_ctx.reused_sess);
Emeric Brun46591952012-05-18 15:47:34 +02002555
Willy Tarreau2a3fb1c2015-02-05 16:47:07 +01002556 if (!(objt_server(conn->target)->ssl_ctx.options & SRV_SSL_O_NO_REUSE))
2557 objt_server(conn->target)->ssl_ctx.reused_sess = SSL_get1_session(conn->xprt_ctx);
Emeric Brun46591952012-05-18 15:47:34 +02002558 }
Willy Tarreau0c9c2722014-05-28 12:28:58 +02002559 else {
2560 update_freq_ctr(&global.ssl_fe_keys_per_sec, 1);
2561 if (global.ssl_fe_keys_per_sec.curr_ctr > global.ssl_fe_keys_max)
2562 global.ssl_fe_keys_max = global.ssl_fe_keys_per_sec.curr_ctr;
2563 }
Emeric Brun46591952012-05-18 15:47:34 +02002564 }
2565
2566 /* The connection is now established at both layers, it's time to leave */
2567 conn->flags &= ~(flag | CO_FL_WAIT_L4_CONN | CO_FL_WAIT_L6_CONN);
2568 return 1;
2569
2570 out_error:
Emeric Brun644cde02012-12-14 11:21:13 +01002571 /* Clear openssl global errors stack */
2572 ERR_clear_error();
2573
Emeric Brun9fa89732012-10-04 17:09:56 +02002574 /* free resumed session if exists */
Willy Tarreau3fdb3662012-11-12 00:42:33 +01002575 if (objt_server(conn->target) && objt_server(conn->target)->ssl_ctx.reused_sess) {
2576 SSL_SESSION_free(objt_server(conn->target)->ssl_ctx.reused_sess);
2577 objt_server(conn->target)->ssl_ctx.reused_sess = NULL;
Emeric Brun9fa89732012-10-04 17:09:56 +02002578 }
2579
Emeric Brun46591952012-05-18 15:47:34 +02002580 /* Fail on all other handshake errors */
2581 conn->flags |= CO_FL_ERROR;
Willy Tarreau20879a02012-12-03 16:32:10 +01002582 if (!conn->err_code)
2583 conn->err_code = CO_ER_SSL_HANDSHAKE;
Emeric Brun46591952012-05-18 15:47:34 +02002584 return 0;
2585}
2586
2587/* Receive up to <count> bytes from connection <conn>'s socket and store them
Willy Tarreauabf08d92014-01-14 11:31:27 +01002588 * into buffer <buf>. Only one call to recv() is performed, unless the
Emeric Brun46591952012-05-18 15:47:34 +02002589 * buffer wraps, in which case a second call may be performed. The connection's
2590 * flags are updated with whatever special event is detected (error, read0,
2591 * empty). The caller is responsible for taking care of those events and
2592 * avoiding the call if inappropriate. The function does not call the
2593 * connection's polling update function, so the caller is responsible for this.
2594 */
2595static int ssl_sock_to_buf(struct connection *conn, struct buffer *buf, int count)
2596{
2597 int ret, done = 0;
Willy Tarreauabf08d92014-01-14 11:31:27 +01002598 int try;
Emeric Brun46591952012-05-18 15:47:34 +02002599
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02002600 if (!conn->xprt_ctx)
Emeric Brun46591952012-05-18 15:47:34 +02002601 goto out_error;
2602
2603 if (conn->flags & CO_FL_HANDSHAKE)
2604 /* a handshake was requested */
2605 return 0;
2606
Willy Tarreauabf08d92014-01-14 11:31:27 +01002607 /* let's realign the buffer to optimize I/O */
2608 if (buffer_empty(buf))
Emeric Brun46591952012-05-18 15:47:34 +02002609 buf->p = buf->data;
Emeric Brun46591952012-05-18 15:47:34 +02002610
2611 /* read the largest possible block. For this, we perform only one call
2612 * to recv() unless the buffer wraps and we exactly fill the first hunk,
2613 * in which case we accept to do it once again. A new attempt is made on
2614 * EINTR too.
2615 */
Willy Tarreau00b0fb92014-01-17 11:09:40 +01002616 while (count > 0) {
Willy Tarreauabf08d92014-01-14 11:31:27 +01002617 /* first check if we have some room after p+i */
2618 try = buf->data + buf->size - (buf->p + buf->i);
2619 /* otherwise continue between data and p-o */
2620 if (try <= 0) {
2621 try = buf->p - (buf->data + buf->o);
2622 if (try <= 0)
2623 break;
2624 }
2625 if (try > count)
2626 try = count;
2627
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02002628 ret = SSL_read(conn->xprt_ctx, bi_end(buf), try);
Emeric Brune1f38db2012-09-03 20:36:47 +02002629 if (conn->flags & CO_FL_ERROR) {
2630 /* CO_FL_ERROR may be set by ssl_sock_infocbk */
Emeric Brun644cde02012-12-14 11:21:13 +01002631 goto out_error;
Emeric Brune1f38db2012-09-03 20:36:47 +02002632 }
Emeric Brun46591952012-05-18 15:47:34 +02002633 if (ret > 0) {
2634 buf->i += ret;
2635 done += ret;
2636 if (ret < try)
2637 break;
2638 count -= ret;
Emeric Brun46591952012-05-18 15:47:34 +02002639 }
2640 else if (ret == 0) {
Emeric Brun644cde02012-12-14 11:21:13 +01002641 ret = SSL_get_error(conn->xprt_ctx, ret);
2642 if (ret != SSL_ERROR_ZERO_RETURN) {
Emeric Brun1c646862012-12-14 12:33:41 +01002643 /* error on protocol or underlying transport */
2644 if ((ret != SSL_ERROR_SYSCALL)
2645 || (errno && (errno != EAGAIN)))
2646 conn->flags |= CO_FL_ERROR;
2647
Emeric Brun644cde02012-12-14 11:21:13 +01002648 /* Clear openssl global errors stack */
2649 ERR_clear_error();
2650 }
Emeric Brun46591952012-05-18 15:47:34 +02002651 goto read0;
2652 }
2653 else {
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02002654 ret = SSL_get_error(conn->xprt_ctx, ret);
Emeric Brun46591952012-05-18 15:47:34 +02002655 if (ret == SSL_ERROR_WANT_WRITE) {
Emeric Brun8af8dd12012-11-08 17:56:20 +01002656 /* handshake is running, and it needs to enable write */
Emeric Brun46591952012-05-18 15:47:34 +02002657 conn->flags |= CO_FL_SSL_WAIT_HS;
Emeric Brun8af8dd12012-11-08 17:56:20 +01002658 __conn_sock_want_send(conn);
Emeric Brun46591952012-05-18 15:47:34 +02002659 break;
2660 }
2661 else if (ret == SSL_ERROR_WANT_READ) {
Emeric Brun282a76a2012-11-08 18:02:56 +01002662 if (SSL_renegotiate_pending(conn->xprt_ctx)) {
2663 /* handshake is running, and it may need to re-enable read */
2664 conn->flags |= CO_FL_SSL_WAIT_HS;
2665 __conn_sock_want_recv(conn);
2666 break;
2667 }
Emeric Brun46591952012-05-18 15:47:34 +02002668 /* we need to poll for retry a read later */
Willy Tarreaue1f50c42014-01-22 20:02:06 +01002669 fd_cant_recv(conn->t.sock.fd);
Emeric Brun46591952012-05-18 15:47:34 +02002670 break;
2671 }
2672 /* otherwise it's a real error */
2673 goto out_error;
2674 }
2675 }
2676 return done;
2677
2678 read0:
2679 conn_sock_read0(conn);
2680 return done;
2681 out_error:
Emeric Brun644cde02012-12-14 11:21:13 +01002682 /* Clear openssl global errors stack */
2683 ERR_clear_error();
2684
Emeric Brun46591952012-05-18 15:47:34 +02002685 conn->flags |= CO_FL_ERROR;
2686 return done;
2687}
2688
2689
2690/* Send all pending bytes from buffer <buf> to connection <conn>'s socket.
Willy Tarreau1049b1f2014-02-02 01:51:17 +01002691 * <flags> may contain some CO_SFL_* flags to hint the system about other
2692 * pending data for example, but this flag is ignored at the moment.
Emeric Brun46591952012-05-18 15:47:34 +02002693 * Only one call to send() is performed, unless the buffer wraps, in which case
2694 * a second call may be performed. The connection's flags are updated with
2695 * whatever special event is detected (error, empty). The caller is responsible
2696 * for taking care of those events and avoiding the call if inappropriate. The
2697 * function does not call the connection's polling update function, so the caller
2698 * is responsible for this.
2699 */
2700static int ssl_sock_from_buf(struct connection *conn, struct buffer *buf, int flags)
2701{
2702 int ret, try, done;
2703
2704 done = 0;
2705
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02002706 if (!conn->xprt_ctx)
Emeric Brun46591952012-05-18 15:47:34 +02002707 goto out_error;
2708
2709 if (conn->flags & CO_FL_HANDSHAKE)
2710 /* a handshake was requested */
2711 return 0;
2712
2713 /* send the largest possible block. For this we perform only one call
2714 * to send() unless the buffer wraps and we exactly fill the first hunk,
2715 * in which case we accept to do it once again.
2716 */
2717 while (buf->o) {
Kevin Hestercad82342013-05-30 15:12:41 -07002718 try = bo_contig_data(buf);
Willy Tarreaubfd59462013-02-21 07:46:09 +01002719
Willy Tarreau7bed9452014-02-02 02:00:24 +01002720 if (!(flags & CO_SFL_STREAMER) &&
Willy Tarreau518cedd2014-02-17 15:43:01 +01002721 !(conn->xprt_st & SSL_SOCK_SEND_UNLIMITED) &&
2722 global.tune.ssl_max_record && try > global.tune.ssl_max_record) {
Willy Tarreaubfd59462013-02-21 07:46:09 +01002723 try = global.tune.ssl_max_record;
Willy Tarreau518cedd2014-02-17 15:43:01 +01002724 }
2725 else {
2726 /* we need to keep the information about the fact that
2727 * we're not limiting the upcoming send(), because if it
2728 * fails, we'll have to retry with at least as many data.
2729 */
2730 conn->xprt_st |= SSL_SOCK_SEND_UNLIMITED;
2731 }
Willy Tarreaubfd59462013-02-21 07:46:09 +01002732
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02002733 ret = SSL_write(conn->xprt_ctx, bo_ptr(buf), try);
Willy Tarreau518cedd2014-02-17 15:43:01 +01002734
Emeric Brune1f38db2012-09-03 20:36:47 +02002735 if (conn->flags & CO_FL_ERROR) {
2736 /* CO_FL_ERROR may be set by ssl_sock_infocbk */
Emeric Brun644cde02012-12-14 11:21:13 +01002737 goto out_error;
Emeric Brune1f38db2012-09-03 20:36:47 +02002738 }
Emeric Brun46591952012-05-18 15:47:34 +02002739 if (ret > 0) {
Willy Tarreau518cedd2014-02-17 15:43:01 +01002740 conn->xprt_st &= ~SSL_SOCK_SEND_UNLIMITED;
2741
Emeric Brun46591952012-05-18 15:47:34 +02002742 buf->o -= ret;
2743 done += ret;
2744
Willy Tarreau5fb38032012-12-16 19:39:09 +01002745 if (likely(buffer_empty(buf)))
Emeric Brun46591952012-05-18 15:47:34 +02002746 /* optimize data alignment in the buffer */
2747 buf->p = buf->data;
2748
2749 /* if the system buffer is full, don't insist */
2750 if (ret < try)
2751 break;
2752 }
2753 else {
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02002754 ret = SSL_get_error(conn->xprt_ctx, ret);
Emeric Brun46591952012-05-18 15:47:34 +02002755 if (ret == SSL_ERROR_WANT_WRITE) {
Emeric Brun282a76a2012-11-08 18:02:56 +01002756 if (SSL_renegotiate_pending(conn->xprt_ctx)) {
2757 /* handshake is running, and it may need to re-enable write */
2758 conn->flags |= CO_FL_SSL_WAIT_HS;
2759 __conn_sock_want_send(conn);
2760 break;
2761 }
Emeric Brun46591952012-05-18 15:47:34 +02002762 /* we need to poll to retry a write later */
Willy Tarreaue1f50c42014-01-22 20:02:06 +01002763 fd_cant_send(conn->t.sock.fd);
Emeric Brun46591952012-05-18 15:47:34 +02002764 break;
2765 }
2766 else if (ret == SSL_ERROR_WANT_READ) {
Emeric Brun8af8dd12012-11-08 17:56:20 +01002767 /* handshake is running, and it needs to enable read */
Emeric Brun46591952012-05-18 15:47:34 +02002768 conn->flags |= CO_FL_SSL_WAIT_HS;
Emeric Brun8af8dd12012-11-08 17:56:20 +01002769 __conn_sock_want_recv(conn);
Emeric Brun46591952012-05-18 15:47:34 +02002770 break;
2771 }
2772 goto out_error;
2773 }
2774 }
2775 return done;
2776
2777 out_error:
Emeric Brun644cde02012-12-14 11:21:13 +01002778 /* Clear openssl global errors stack */
2779 ERR_clear_error();
2780
Emeric Brun46591952012-05-18 15:47:34 +02002781 conn->flags |= CO_FL_ERROR;
2782 return done;
2783}
2784
Emeric Brun46591952012-05-18 15:47:34 +02002785static void ssl_sock_close(struct connection *conn) {
2786
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02002787 if (conn->xprt_ctx) {
2788 SSL_free(conn->xprt_ctx);
2789 conn->xprt_ctx = NULL;
Willy Tarreau403edff2012-09-06 11:58:37 +02002790 sslconns--;
Emeric Brun46591952012-05-18 15:47:34 +02002791 }
Emeric Brun46591952012-05-18 15:47:34 +02002792}
2793
2794/* This function tries to perform a clean shutdown on an SSL connection, and in
2795 * any case, flags the connection as reusable if no handshake was in progress.
2796 */
2797static void ssl_sock_shutw(struct connection *conn, int clean)
2798{
2799 if (conn->flags & CO_FL_HANDSHAKE)
2800 return;
2801 /* no handshake was in progress, try a clean ssl shutdown */
Emeric Brun644cde02012-12-14 11:21:13 +01002802 if (clean && (SSL_shutdown(conn->xprt_ctx) <= 0)) {
2803 /* Clear openssl global errors stack */
2804 ERR_clear_error();
2805 }
Emeric Brun46591952012-05-18 15:47:34 +02002806
2807 /* force flag on ssl to keep session in cache regardless shutdown result */
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02002808 SSL_set_shutdown(conn->xprt_ctx, SSL_SENT_SHUTDOWN);
Emeric Brun46591952012-05-18 15:47:34 +02002809}
2810
Willy Tarreauffc3fcd2012-10-12 20:17:54 +02002811/* used for logging, may be changed for a sample fetch later */
2812const char *ssl_sock_get_cipher_name(struct connection *conn)
2813{
2814 if (!conn->xprt && !conn->xprt_ctx)
2815 return NULL;
2816 return SSL_get_cipher_name(conn->xprt_ctx);
2817}
2818
2819/* used for logging, may be changed for a sample fetch later */
2820const char *ssl_sock_get_proto_version(struct connection *conn)
2821{
2822 if (!conn->xprt && !conn->xprt_ctx)
2823 return NULL;
2824 return SSL_get_version(conn->xprt_ctx);
2825}
2826
Willy Tarreau8d598402012-10-22 17:58:39 +02002827/* Extract a serial from a cert, and copy it to a chunk.
2828 * Returns 1 if serial is found and copied, 0 if no serial found and
2829 * -1 if output is not large enough.
2830 */
2831static int
2832ssl_sock_get_serial(X509 *crt, struct chunk *out)
2833{
2834 ASN1_INTEGER *serial;
2835
2836 serial = X509_get_serialNumber(crt);
2837 if (!serial)
2838 return 0;
2839
2840 if (out->size < serial->length)
2841 return -1;
2842
2843 memcpy(out->str, serial->data, serial->length);
2844 out->len = serial->length;
2845 return 1;
2846}
2847
Emeric Brun43e79582014-10-29 19:03:26 +01002848/* Extract a cert to der, and copy it to a chunk.
2849 * Returns 1 if cert is found and copied, 0 on der convertion failure and
2850 * -1 if output is not large enough.
2851 */
2852static int
2853ssl_sock_crt2der(X509 *crt, struct chunk *out)
2854{
2855 int len;
2856 unsigned char *p = (unsigned char *)out->str;;
2857
2858 len =i2d_X509(crt, NULL);
2859 if (len <= 0)
2860 return 1;
2861
2862 if (out->size < len)
2863 return -1;
2864
2865 i2d_X509(crt,&p);
2866 out->len = len;
2867 return 1;
2868}
2869
Emeric Brunce5ad802012-10-22 14:11:22 +02002870
2871/* Copy Date in ASN1_UTCTIME format in struct chunk out.
2872 * Returns 1 if serial is found and copied, 0 if no valid time found
2873 * and -1 if output is not large enough.
2874 */
2875static int
2876ssl_sock_get_time(ASN1_TIME *tm, struct chunk *out)
2877{
2878 if (tm->type == V_ASN1_GENERALIZEDTIME) {
2879 ASN1_GENERALIZEDTIME *gentm = (ASN1_GENERALIZEDTIME *)tm;
2880
2881 if (gentm->length < 12)
2882 return 0;
2883 if (gentm->data[0] != 0x32 || gentm->data[1] != 0x30)
2884 return 0;
2885 if (out->size < gentm->length-2)
2886 return -1;
2887
2888 memcpy(out->str, gentm->data+2, gentm->length-2);
2889 out->len = gentm->length-2;
2890 return 1;
2891 }
2892 else if (tm->type == V_ASN1_UTCTIME) {
2893 ASN1_UTCTIME *utctm = (ASN1_UTCTIME *)tm;
2894
2895 if (utctm->length < 10)
2896 return 0;
2897 if (utctm->data[0] >= 0x35)
2898 return 0;
2899 if (out->size < utctm->length)
2900 return -1;
2901
2902 memcpy(out->str, utctm->data, utctm->length);
2903 out->len = utctm->length;
2904 return 1;
2905 }
2906
2907 return 0;
2908}
2909
Emeric Brun87855892012-10-17 17:39:35 +02002910/* Extract an entry from a X509_NAME and copy its value to an output chunk.
2911 * Returns 1 if entry found, 0 if entry not found, or -1 if output not large enough.
2912 */
2913static int
2914ssl_sock_get_dn_entry(X509_NAME *a, const struct chunk *entry, int pos, struct chunk *out)
2915{
2916 X509_NAME_ENTRY *ne;
2917 int i, j, n;
2918 int cur = 0;
2919 const char *s;
2920 char tmp[128];
2921
2922 out->len = 0;
2923 for (i = 0; i < sk_X509_NAME_ENTRY_num(a->entries); i++) {
2924 if (pos < 0)
2925 j = (sk_X509_NAME_ENTRY_num(a->entries)-1) - i;
2926 else
2927 j = i;
2928
2929 ne = sk_X509_NAME_ENTRY_value(a->entries, j);
2930 n = OBJ_obj2nid(ne->object);
2931 if ((n == NID_undef) || ((s = OBJ_nid2sn(n)) == NULL)) {
2932 i2t_ASN1_OBJECT(tmp, sizeof(tmp), ne->object);
2933 s = tmp;
2934 }
2935
2936 if (chunk_strcasecmp(entry, s) != 0)
2937 continue;
2938
2939 if (pos < 0)
2940 cur--;
2941 else
2942 cur++;
2943
2944 if (cur != pos)
2945 continue;
2946
2947 if (ne->value->length > out->size)
2948 return -1;
2949
2950 memcpy(out->str, ne->value->data, ne->value->length);
2951 out->len = ne->value->length;
2952 return 1;
2953 }
2954
2955 return 0;
2956
2957}
2958
2959/* Extract and format full DN from a X509_NAME and copy result into a chunk
2960 * Returns 1 if dn entries exits, 0 if no dn entry found or -1 if output is not large enough.
2961 */
2962static int
2963ssl_sock_get_dn_oneline(X509_NAME *a, struct chunk *out)
2964{
2965 X509_NAME_ENTRY *ne;
2966 int i, n, ln;
2967 int l = 0;
2968 const char *s;
2969 char *p;
2970 char tmp[128];
2971
2972 out->len = 0;
2973 p = out->str;
2974 for (i = 0; i < sk_X509_NAME_ENTRY_num(a->entries); i++) {
2975 ne = sk_X509_NAME_ENTRY_value(a->entries, i);
2976 n = OBJ_obj2nid(ne->object);
2977 if ((n == NID_undef) || ((s = OBJ_nid2sn(n)) == NULL)) {
2978 i2t_ASN1_OBJECT(tmp, sizeof(tmp), ne->object);
2979 s = tmp;
2980 }
2981 ln = strlen(s);
2982
2983 l += 1 + ln + 1 + ne->value->length;
2984 if (l > out->size)
2985 return -1;
2986 out->len = l;
2987
2988 *(p++)='/';
2989 memcpy(p, s, ln);
2990 p += ln;
2991 *(p++)='=';
2992 memcpy(p, ne->value->data, ne->value->length);
2993 p += ne->value->length;
2994 }
2995
2996 if (!out->len)
2997 return 0;
2998
2999 return 1;
3000}
3001
David Safb76832014-05-08 23:42:08 -04003002char *ssl_sock_get_version(struct connection *conn)
3003{
3004 if (!ssl_sock_is_ssl(conn))
3005 return NULL;
3006
3007 return (char *)SSL_get_version(conn->xprt_ctx);
3008}
3009
Emeric Brun0abf8362014-06-24 18:26:41 +02003010/* Extract peer certificate's common name into the chunk dest
3011 * Returns
3012 * the len of the extracted common name
3013 * or 0 if no CN found in DN
3014 * or -1 on error case (i.e. no peer certificate)
3015 */
3016int ssl_sock_get_remote_common_name(struct connection *conn, struct chunk *dest)
David Safb76832014-05-08 23:42:08 -04003017{
3018 X509 *crt = NULL;
3019 X509_NAME *name;
David Safb76832014-05-08 23:42:08 -04003020 const char find_cn[] = "CN";
3021 const struct chunk find_cn_chunk = {
3022 .str = (char *)&find_cn,
3023 .len = sizeof(find_cn)-1
3024 };
Emeric Brun0abf8362014-06-24 18:26:41 +02003025 int result = -1;
David Safb76832014-05-08 23:42:08 -04003026
3027 if (!ssl_sock_is_ssl(conn))
Emeric Brun0abf8362014-06-24 18:26:41 +02003028 goto out;
David Safb76832014-05-08 23:42:08 -04003029
3030 /* SSL_get_peer_certificate, it increase X509 * ref count */
3031 crt = SSL_get_peer_certificate(conn->xprt_ctx);
3032 if (!crt)
3033 goto out;
3034
3035 name = X509_get_subject_name(crt);
3036 if (!name)
3037 goto out;
David Safb76832014-05-08 23:42:08 -04003038
Emeric Brun0abf8362014-06-24 18:26:41 +02003039 result = ssl_sock_get_dn_entry(name, &find_cn_chunk, 1, dest);
3040out:
David Safb76832014-05-08 23:42:08 -04003041 if (crt)
3042 X509_free(crt);
3043
3044 return result;
3045}
3046
Dave McCowan328fb582014-07-30 10:39:13 -04003047/* returns 1 if client passed a certificate for this session, 0 if not */
3048int ssl_sock_get_cert_used_sess(struct connection *conn)
3049{
3050 X509 *crt = NULL;
3051
3052 if (!ssl_sock_is_ssl(conn))
3053 return 0;
3054
3055 /* SSL_get_peer_certificate, it increase X509 * ref count */
3056 crt = SSL_get_peer_certificate(conn->xprt_ctx);
3057 if (!crt)
3058 return 0;
3059
3060 X509_free(crt);
3061 return 1;
3062}
3063
3064/* returns 1 if client passed a certificate for this connection, 0 if not */
3065int ssl_sock_get_cert_used_conn(struct connection *conn)
David Safb76832014-05-08 23:42:08 -04003066{
3067 if (!ssl_sock_is_ssl(conn))
3068 return 0;
3069
3070 return SSL_SOCK_ST_FL_VERIFY_DONE & conn->xprt_st ? 1 : 0;
3071}
3072
3073/* returns result from SSL verify */
3074unsigned int ssl_sock_get_verify_result(struct connection *conn)
3075{
3076 if (!ssl_sock_is_ssl(conn))
3077 return (unsigned int)X509_V_ERR_APPLICATION_VERIFICATION;
3078
3079 return (unsigned int)SSL_get_verify_result(conn->xprt_ctx);
3080}
3081
Willy Tarreau7875d092012-09-10 08:20:03 +02003082/***** Below are some sample fetching functions for ACL/patterns *****/
3083
Emeric Brune64aef12012-09-21 13:15:06 +02003084/* boolean, returns true if client cert was present */
3085static int
Emeric Brun2525b6b2012-10-18 15:59:43 +02003086smp_fetch_ssl_fc_has_crt(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
Thierry FOURNIERf41a8092014-12-07 18:37:57 +01003087 const struct arg *args, struct sample *smp, const char *kw, void *private)
Emeric Brune64aef12012-09-21 13:15:06 +02003088{
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003089 struct connection *conn;
3090
3091 if (!l4)
3092 return 0;
3093
3094 conn = objt_conn(l4->si[0].end);
3095 if (!conn || conn->xprt != &ssl_sock)
Emeric Brune64aef12012-09-21 13:15:06 +02003096 return 0;
3097
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003098 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brune64aef12012-09-21 13:15:06 +02003099 smp->flags |= SMP_F_MAY_CHANGE;
3100 return 0;
3101 }
3102
3103 smp->flags = 0;
3104 smp->type = SMP_T_BOOL;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003105 smp->data.uint = SSL_SOCK_ST_FL_VERIFY_DONE & conn->xprt_st ? 1 : 0;
Emeric Brune64aef12012-09-21 13:15:06 +02003106
3107 return 1;
3108}
3109
Emeric Brun43e79582014-10-29 19:03:26 +01003110/* binary, returns a certificate in a binary chunk (der/raw).
3111 * The 5th keyword char is used to know if SSL_get_certificate or SSL_get_peer_certificate
3112 * should be use.
3113 */
3114static int
3115smp_fetch_ssl_x_der(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
Thierry FOURNIERf41a8092014-12-07 18:37:57 +01003116 const struct arg *args, struct sample *smp, const char *kw, void *private)
Emeric Brun43e79582014-10-29 19:03:26 +01003117{
3118 int cert_peer = (kw[4] == 'c') ? 1 : 0;
3119 X509 *crt = NULL;
3120 int ret = 0;
3121 struct chunk *smp_trash;
3122 struct connection *conn;
3123
3124 if (!l4)
3125 return 0;
3126
3127 conn = objt_conn(l4->si[0].end);
3128 if (!conn || conn->xprt != &ssl_sock)
3129 return 0;
3130
3131 if (!(conn->flags & CO_FL_CONNECTED)) {
3132 smp->flags |= SMP_F_MAY_CHANGE;
3133 return 0;
3134 }
3135
3136 if (cert_peer)
3137 crt = SSL_get_peer_certificate(conn->xprt_ctx);
3138 else
3139 crt = SSL_get_certificate(conn->xprt_ctx);
3140
3141 if (!crt)
3142 goto out;
3143
3144 smp_trash = get_trash_chunk();
3145 if (ssl_sock_crt2der(crt, smp_trash) <= 0)
3146 goto out;
3147
3148 smp->data.str = *smp_trash;
3149 smp->type = SMP_T_BIN;
3150 ret = 1;
3151out:
3152 /* SSL_get_peer_certificate, it increase X509 * ref count */
3153 if (cert_peer && crt)
3154 X509_free(crt);
3155 return ret;
3156}
3157
Emeric Brunba841a12014-04-30 17:05:08 +02003158/* binary, returns serial of certificate in a binary chunk.
3159 * The 5th keyword char is used to know if SSL_get_certificate or SSL_get_peer_certificate
3160 * should be use.
3161 */
Willy Tarreau8d598402012-10-22 17:58:39 +02003162static int
Emeric Brunba841a12014-04-30 17:05:08 +02003163smp_fetch_ssl_x_serial(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
Thierry FOURNIERf41a8092014-12-07 18:37:57 +01003164 const struct arg *args, struct sample *smp, const char *kw, void *private)
Willy Tarreau8d598402012-10-22 17:58:39 +02003165{
Emeric Brunba841a12014-04-30 17:05:08 +02003166 int cert_peer = (kw[4] == 'c') ? 1 : 0;
Willy Tarreau8d598402012-10-22 17:58:39 +02003167 X509 *crt = NULL;
3168 int ret = 0;
3169 struct chunk *smp_trash;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003170 struct connection *conn;
3171
3172 if (!l4)
3173 return 0;
Willy Tarreau8d598402012-10-22 17:58:39 +02003174
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003175 conn = objt_conn(l4->si[0].end);
3176 if (!conn || conn->xprt != &ssl_sock)
Willy Tarreau8d598402012-10-22 17:58:39 +02003177 return 0;
3178
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003179 if (!(conn->flags & CO_FL_CONNECTED)) {
Willy Tarreau8d598402012-10-22 17:58:39 +02003180 smp->flags |= SMP_F_MAY_CHANGE;
3181 return 0;
3182 }
3183
Emeric Brunba841a12014-04-30 17:05:08 +02003184 if (cert_peer)
3185 crt = SSL_get_peer_certificate(conn->xprt_ctx);
3186 else
3187 crt = SSL_get_certificate(conn->xprt_ctx);
3188
Willy Tarreau8d598402012-10-22 17:58:39 +02003189 if (!crt)
3190 goto out;
3191
Willy Tarreau47ca5452012-12-23 20:22:19 +01003192 smp_trash = get_trash_chunk();
Willy Tarreau8d598402012-10-22 17:58:39 +02003193 if (ssl_sock_get_serial(crt, smp_trash) <= 0)
3194 goto out;
3195
3196 smp->data.str = *smp_trash;
3197 smp->type = SMP_T_BIN;
3198 ret = 1;
3199out:
Emeric Brunba841a12014-04-30 17:05:08 +02003200 /* SSL_get_peer_certificate, it increase X509 * ref count */
3201 if (cert_peer && crt)
Willy Tarreau8d598402012-10-22 17:58:39 +02003202 X509_free(crt);
3203 return ret;
3204}
Emeric Brune64aef12012-09-21 13:15:06 +02003205
Emeric Brunba841a12014-04-30 17:05:08 +02003206/* binary, returns the client certificate's SHA-1 fingerprint (SHA-1 hash of DER-encoded certificate) in a binary chunk.
3207 * The 5th keyword char is used to know if SSL_get_certificate or SSL_get_peer_certificate
3208 * should be use.
3209 */
James Votha051b4a2013-05-14 20:37:59 +02003210static int
Emeric Brunba841a12014-04-30 17:05:08 +02003211smp_fetch_ssl_x_sha1(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
Thierry FOURNIERf41a8092014-12-07 18:37:57 +01003212 const struct arg *args, struct sample *smp, const char *kw, void *private)
James Votha051b4a2013-05-14 20:37:59 +02003213{
Emeric Brunba841a12014-04-30 17:05:08 +02003214 int cert_peer = (kw[4] == 'c') ? 1 : 0;
James Votha051b4a2013-05-14 20:37:59 +02003215 X509 *crt = NULL;
3216 const EVP_MD *digest;
3217 int ret = 0;
3218 struct chunk *smp_trash;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003219 struct connection *conn;
James Votha051b4a2013-05-14 20:37:59 +02003220
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003221 if (!l4)
James Votha051b4a2013-05-14 20:37:59 +02003222 return 0;
3223
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003224 conn = objt_conn(l4->si[0].end);
3225 if (!conn || conn->xprt != &ssl_sock)
3226 return 0;
3227
3228 if (!(conn->flags & CO_FL_CONNECTED)) {
James Votha051b4a2013-05-14 20:37:59 +02003229 smp->flags |= SMP_F_MAY_CHANGE;
3230 return 0;
3231 }
3232
Emeric Brunba841a12014-04-30 17:05:08 +02003233 if (cert_peer)
3234 crt = SSL_get_peer_certificate(conn->xprt_ctx);
3235 else
3236 crt = SSL_get_certificate(conn->xprt_ctx);
James Votha051b4a2013-05-14 20:37:59 +02003237 if (!crt)
3238 goto out;
3239
3240 smp_trash = get_trash_chunk();
3241 digest = EVP_sha1();
3242 X509_digest(crt, digest, (unsigned char *)smp_trash->str, (unsigned int *)&smp_trash->len);
3243
3244 smp->data.str = *smp_trash;
3245 smp->type = SMP_T_BIN;
3246 ret = 1;
3247out:
Emeric Brunba841a12014-04-30 17:05:08 +02003248 /* SSL_get_peer_certificate, it increase X509 * ref count */
3249 if (cert_peer && crt)
James Votha051b4a2013-05-14 20:37:59 +02003250 X509_free(crt);
3251 return ret;
3252}
3253
Emeric Brunba841a12014-04-30 17:05:08 +02003254/* string, returns certificate's notafter date in ASN1_UTCTIME format.
3255 * The 5th keyword char is used to know if SSL_get_certificate or SSL_get_peer_certificate
3256 * should be use.
3257 */
Emeric Brunce5ad802012-10-22 14:11:22 +02003258static int
Emeric Brunba841a12014-04-30 17:05:08 +02003259smp_fetch_ssl_x_notafter(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
Thierry FOURNIERf41a8092014-12-07 18:37:57 +01003260 const struct arg *args, struct sample *smp, const char *kw, void *private)
Emeric Brunce5ad802012-10-22 14:11:22 +02003261{
Emeric Brunba841a12014-04-30 17:05:08 +02003262 int cert_peer = (kw[4] == 'c') ? 1 : 0;
Emeric Brunce5ad802012-10-22 14:11:22 +02003263 X509 *crt = NULL;
3264 int ret = 0;
3265 struct chunk *smp_trash;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003266 struct connection *conn;
Emeric Brunce5ad802012-10-22 14:11:22 +02003267
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003268 if (!l4)
Emeric Brunce5ad802012-10-22 14:11:22 +02003269 return 0;
3270
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003271 conn = objt_conn(l4->si[0].end);
3272 if (!conn || conn->xprt != &ssl_sock)
3273 return 0;
3274
3275 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brunce5ad802012-10-22 14:11:22 +02003276 smp->flags |= SMP_F_MAY_CHANGE;
3277 return 0;
3278 }
3279
Emeric Brunba841a12014-04-30 17:05:08 +02003280 if (cert_peer)
3281 crt = SSL_get_peer_certificate(conn->xprt_ctx);
3282 else
3283 crt = SSL_get_certificate(conn->xprt_ctx);
Emeric Brunce5ad802012-10-22 14:11:22 +02003284 if (!crt)
3285 goto out;
3286
Willy Tarreau47ca5452012-12-23 20:22:19 +01003287 smp_trash = get_trash_chunk();
Emeric Brunce5ad802012-10-22 14:11:22 +02003288 if (ssl_sock_get_time(X509_get_notAfter(crt), smp_trash) <= 0)
3289 goto out;
3290
3291 smp->data.str = *smp_trash;
3292 smp->type = SMP_T_STR;
3293 ret = 1;
3294out:
Emeric Brunba841a12014-04-30 17:05:08 +02003295 /* SSL_get_peer_certificate, it increase X509 * ref count */
3296 if (cert_peer && crt)
Emeric Brunce5ad802012-10-22 14:11:22 +02003297 X509_free(crt);
3298 return ret;
3299}
3300
Emeric Brunba841a12014-04-30 17:05:08 +02003301/* string, returns a string of a formatted full dn \C=..\O=..\OU=.. \CN=.. of certificate's issuer
3302 * The 5th keyword char is used to know if SSL_get_certificate or SSL_get_peer_certificate
3303 * should be use.
3304 */
Emeric Brun87855892012-10-17 17:39:35 +02003305static int
Emeric Brunba841a12014-04-30 17:05:08 +02003306smp_fetch_ssl_x_i_dn(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
Thierry FOURNIERf41a8092014-12-07 18:37:57 +01003307 const struct arg *args, struct sample *smp, const char *kw, void *private)
Emeric Brun87855892012-10-17 17:39:35 +02003308{
Emeric Brunba841a12014-04-30 17:05:08 +02003309 int cert_peer = (kw[4] == 'c') ? 1 : 0;
Emeric Brun87855892012-10-17 17:39:35 +02003310 X509 *crt = NULL;
3311 X509_NAME *name;
3312 int ret = 0;
3313 struct chunk *smp_trash;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003314 struct connection *conn;
Emeric Brun87855892012-10-17 17:39:35 +02003315
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003316 if (!l4)
Emeric Brun87855892012-10-17 17:39:35 +02003317 return 0;
3318
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003319 conn = objt_conn(l4->si[0].end);
3320 if (!conn || conn->xprt != &ssl_sock)
3321 return 0;
3322
3323 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brun87855892012-10-17 17:39:35 +02003324 smp->flags |= SMP_F_MAY_CHANGE;
3325 return 0;
3326 }
3327
Emeric Brunba841a12014-04-30 17:05:08 +02003328 if (cert_peer)
3329 crt = SSL_get_peer_certificate(conn->xprt_ctx);
3330 else
3331 crt = SSL_get_certificate(conn->xprt_ctx);
Emeric Brun87855892012-10-17 17:39:35 +02003332 if (!crt)
3333 goto out;
3334
3335 name = X509_get_issuer_name(crt);
3336 if (!name)
3337 goto out;
3338
Willy Tarreau47ca5452012-12-23 20:22:19 +01003339 smp_trash = get_trash_chunk();
Emeric Brun87855892012-10-17 17:39:35 +02003340 if (args && args[0].type == ARGT_STR) {
3341 int pos = 1;
3342
3343 if (args[1].type == ARGT_SINT)
3344 pos = args[1].data.sint;
3345 else if (args[1].type == ARGT_UINT)
3346 pos =(int)args[1].data.uint;
3347
3348 if (ssl_sock_get_dn_entry(name, &args[0].data.str, pos, smp_trash) <= 0)
3349 goto out;
3350 }
3351 else if (ssl_sock_get_dn_oneline(name, smp_trash) <= 0)
3352 goto out;
3353
3354 smp->type = SMP_T_STR;
3355 smp->data.str = *smp_trash;
3356 ret = 1;
3357out:
Emeric Brunba841a12014-04-30 17:05:08 +02003358 /* SSL_get_peer_certificate, it increase X509 * ref count */
3359 if (cert_peer && crt)
Emeric Brun87855892012-10-17 17:39:35 +02003360 X509_free(crt);
3361 return ret;
3362}
3363
Emeric Brunba841a12014-04-30 17:05:08 +02003364/* string, returns notbefore date in ASN1_UTCTIME format.
3365 * The 5th keyword char is used to know if SSL_get_certificate or SSL_get_peer_certificate
3366 * should be use.
3367 */
Emeric Brunce5ad802012-10-22 14:11:22 +02003368static int
Emeric Brunba841a12014-04-30 17:05:08 +02003369smp_fetch_ssl_x_notbefore(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
Thierry FOURNIERf41a8092014-12-07 18:37:57 +01003370 const struct arg *args, struct sample *smp, const char *kw, void *private)
Emeric Brunce5ad802012-10-22 14:11:22 +02003371{
Emeric Brunba841a12014-04-30 17:05:08 +02003372 int cert_peer = (kw[4] == 'c') ? 1 : 0;
Emeric Brunce5ad802012-10-22 14:11:22 +02003373 X509 *crt = NULL;
3374 int ret = 0;
3375 struct chunk *smp_trash;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003376 struct connection *conn;
3377
3378 if (!l4)
3379 return 0;
Emeric Brunce5ad802012-10-22 14:11:22 +02003380
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003381 conn = objt_conn(l4->si[0].end);
3382 if (!conn || conn->xprt != &ssl_sock)
Emeric Brunce5ad802012-10-22 14:11:22 +02003383 return 0;
3384
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003385 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brunce5ad802012-10-22 14:11:22 +02003386 smp->flags |= SMP_F_MAY_CHANGE;
3387 return 0;
3388 }
3389
Emeric Brunba841a12014-04-30 17:05:08 +02003390 if (cert_peer)
3391 crt = SSL_get_peer_certificate(conn->xprt_ctx);
3392 else
3393 crt = SSL_get_certificate(conn->xprt_ctx);
Emeric Brunce5ad802012-10-22 14:11:22 +02003394 if (!crt)
3395 goto out;
3396
Willy Tarreau47ca5452012-12-23 20:22:19 +01003397 smp_trash = get_trash_chunk();
Emeric Brunce5ad802012-10-22 14:11:22 +02003398 if (ssl_sock_get_time(X509_get_notBefore(crt), smp_trash) <= 0)
3399 goto out;
3400
3401 smp->data.str = *smp_trash;
3402 smp->type = SMP_T_STR;
3403 ret = 1;
3404out:
Emeric Brunba841a12014-04-30 17:05:08 +02003405 /* SSL_get_peer_certificate, it increase X509 * ref count */
3406 if (cert_peer && crt)
Emeric Brunce5ad802012-10-22 14:11:22 +02003407 X509_free(crt);
3408 return ret;
3409}
3410
Emeric Brunba841a12014-04-30 17:05:08 +02003411/* string, returns a string of a formatted full dn \C=..\O=..\OU=.. \CN=.. of certificate's subject
3412 * The 5th keyword char is used to know if SSL_get_certificate or SSL_get_peer_certificate
3413 * should be use.
3414 */
Emeric Brun87855892012-10-17 17:39:35 +02003415static int
Emeric Brunba841a12014-04-30 17:05:08 +02003416smp_fetch_ssl_x_s_dn(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
Thierry FOURNIERf41a8092014-12-07 18:37:57 +01003417 const struct arg *args, struct sample *smp, const char *kw, void *private)
Emeric Brun87855892012-10-17 17:39:35 +02003418{
Emeric Brunba841a12014-04-30 17:05:08 +02003419 int cert_peer = (kw[4] == 'c') ? 1 : 0;
Emeric Brun87855892012-10-17 17:39:35 +02003420 X509 *crt = NULL;
3421 X509_NAME *name;
3422 int ret = 0;
3423 struct chunk *smp_trash;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003424 struct connection *conn;
Emeric Brun87855892012-10-17 17:39:35 +02003425
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003426 if (!l4)
Emeric Brun87855892012-10-17 17:39:35 +02003427 return 0;
3428
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003429 conn = objt_conn(l4->si[0].end);
3430 if (!conn || conn->xprt != &ssl_sock)
3431 return 0;
3432
3433 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brun87855892012-10-17 17:39:35 +02003434 smp->flags |= SMP_F_MAY_CHANGE;
3435 return 0;
3436 }
3437
Emeric Brunba841a12014-04-30 17:05:08 +02003438 if (cert_peer)
3439 crt = SSL_get_peer_certificate(conn->xprt_ctx);
3440 else
3441 crt = SSL_get_certificate(conn->xprt_ctx);
Emeric Brun87855892012-10-17 17:39:35 +02003442 if (!crt)
3443 goto out;
3444
3445 name = X509_get_subject_name(crt);
3446 if (!name)
3447 goto out;
3448
Willy Tarreau47ca5452012-12-23 20:22:19 +01003449 smp_trash = get_trash_chunk();
Emeric Brun87855892012-10-17 17:39:35 +02003450 if (args && args[0].type == ARGT_STR) {
3451 int pos = 1;
3452
3453 if (args[1].type == ARGT_SINT)
3454 pos = args[1].data.sint;
3455 else if (args[1].type == ARGT_UINT)
3456 pos =(int)args[1].data.uint;
3457
3458 if (ssl_sock_get_dn_entry(name, &args[0].data.str, pos, smp_trash) <= 0)
3459 goto out;
3460 }
3461 else if (ssl_sock_get_dn_oneline(name, smp_trash) <= 0)
3462 goto out;
3463
3464 smp->type = SMP_T_STR;
3465 smp->data.str = *smp_trash;
3466 ret = 1;
3467out:
Emeric Brunba841a12014-04-30 17:05:08 +02003468 /* SSL_get_peer_certificate, it increase X509 * ref count */
3469 if (cert_peer && crt)
Emeric Brun87855892012-10-17 17:39:35 +02003470 X509_free(crt);
3471 return ret;
3472}
Emeric Brun9143d372012-12-20 15:44:16 +01003473
3474/* integer, returns true if current session use a client certificate */
3475static int
3476smp_fetch_ssl_c_used(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
Thierry FOURNIERf41a8092014-12-07 18:37:57 +01003477 const struct arg *args, struct sample *smp, const char *kw, void *private)
Emeric Brun9143d372012-12-20 15:44:16 +01003478{
3479 X509 *crt;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003480 struct connection *conn;
Emeric Brun9143d372012-12-20 15:44:16 +01003481
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003482 if (!l4)
Emeric Brun9143d372012-12-20 15:44:16 +01003483 return 0;
3484
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003485 conn = objt_conn(l4->si[0].end);
3486 if (!conn || conn->xprt != &ssl_sock)
3487 return 0;
3488
3489 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brun9143d372012-12-20 15:44:16 +01003490 smp->flags |= SMP_F_MAY_CHANGE;
3491 return 0;
3492 }
3493
3494 /* SSL_get_peer_certificate returns a ptr on allocated X509 struct */
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003495 crt = SSL_get_peer_certificate(conn->xprt_ctx);
Emeric Brun9143d372012-12-20 15:44:16 +01003496 if (crt) {
3497 X509_free(crt);
3498 }
3499
3500 smp->type = SMP_T_BOOL;
3501 smp->data.uint = (crt != NULL);
3502 return 1;
3503}
3504
Emeric Brunba841a12014-04-30 17:05:08 +02003505/* integer, returns the certificate version
3506 * The 5th keyword char is used to know if SSL_get_certificate or SSL_get_peer_certificate
3507 * should be use.
3508 */
Emeric Bruna7359fd2012-10-17 15:03:11 +02003509static int
Emeric Brunba841a12014-04-30 17:05:08 +02003510smp_fetch_ssl_x_version(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
Thierry FOURNIERf41a8092014-12-07 18:37:57 +01003511 const struct arg *args, struct sample *smp, const char *kw, void *private)
Emeric Bruna7359fd2012-10-17 15:03:11 +02003512{
Emeric Brunba841a12014-04-30 17:05:08 +02003513 int cert_peer = (kw[4] == 'c') ? 1 : 0;
Emeric Bruna7359fd2012-10-17 15:03:11 +02003514 X509 *crt;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003515 struct connection *conn;
3516
3517 if (!l4)
3518 return 0;
Emeric Bruna7359fd2012-10-17 15:03:11 +02003519
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003520 conn = objt_conn(l4->si[0].end);
3521 if (!conn || conn->xprt != &ssl_sock)
Emeric Bruna7359fd2012-10-17 15:03:11 +02003522 return 0;
3523
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003524 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Bruna7359fd2012-10-17 15:03:11 +02003525 smp->flags |= SMP_F_MAY_CHANGE;
3526 return 0;
3527 }
3528
Emeric Brunba841a12014-04-30 17:05:08 +02003529 if (cert_peer)
3530 crt = SSL_get_peer_certificate(conn->xprt_ctx);
3531 else
3532 crt = SSL_get_certificate(conn->xprt_ctx);
Emeric Bruna7359fd2012-10-17 15:03:11 +02003533 if (!crt)
3534 return 0;
3535
3536 smp->data.uint = (unsigned int)(1 + X509_get_version(crt));
Emeric Brunba841a12014-04-30 17:05:08 +02003537 /* SSL_get_peer_certificate increase X509 * ref count */
3538 if (cert_peer)
3539 X509_free(crt);
Emeric Bruna7359fd2012-10-17 15:03:11 +02003540 smp->type = SMP_T_UINT;
3541
3542 return 1;
3543}
3544
Emeric Brunba841a12014-04-30 17:05:08 +02003545/* string, returns the certificate's signature algorithm.
3546 * The 5th keyword char is used to know if SSL_get_certificate or SSL_get_peer_certificate
3547 * should be use.
3548 */
Emeric Brun7f56e742012-10-19 18:15:40 +02003549static int
Emeric Brunba841a12014-04-30 17:05:08 +02003550smp_fetch_ssl_x_sig_alg(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
Thierry FOURNIERf41a8092014-12-07 18:37:57 +01003551 const struct arg *args, struct sample *smp, const char *kw, void *private)
Emeric Brun7f56e742012-10-19 18:15:40 +02003552{
Emeric Brunba841a12014-04-30 17:05:08 +02003553 int cert_peer = (kw[4] == 'c') ? 1 : 0;
Emeric Brun7f56e742012-10-19 18:15:40 +02003554 X509 *crt;
3555 int nid;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003556 struct connection *conn;
Emeric Brun7f56e742012-10-19 18:15:40 +02003557
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003558 if (!l4)
Emeric Brun7f56e742012-10-19 18:15:40 +02003559 return 0;
3560
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003561 conn = objt_conn(l4->si[0].end);
3562 if (!conn || conn->xprt != &ssl_sock)
3563 return 0;
3564
3565 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brun7f56e742012-10-19 18:15:40 +02003566 smp->flags |= SMP_F_MAY_CHANGE;
3567 return 0;
3568 }
3569
Emeric Brunba841a12014-04-30 17:05:08 +02003570 if (cert_peer)
3571 crt = SSL_get_peer_certificate(conn->xprt_ctx);
3572 else
3573 crt = SSL_get_certificate(conn->xprt_ctx);
Emeric Brun7f56e742012-10-19 18:15:40 +02003574 if (!crt)
3575 return 0;
3576
3577 nid = OBJ_obj2nid((ASN1_OBJECT *)(crt->cert_info->signature->algorithm));
3578
3579 smp->data.str.str = (char *)OBJ_nid2sn(nid);
Emeric Brun9bf3ba22013-10-07 14:31:44 +02003580 if (!smp->data.str.str) {
Emeric Brunba841a12014-04-30 17:05:08 +02003581 /* SSL_get_peer_certificate increase X509 * ref count */
3582 if (cert_peer)
3583 X509_free(crt);
Emeric Brun7f56e742012-10-19 18:15:40 +02003584 return 0;
Emeric Brun9bf3ba22013-10-07 14:31:44 +02003585 }
Emeric Brun7f56e742012-10-19 18:15:40 +02003586
Thierry FOURNIER7654c9f2013-12-17 00:20:33 +01003587 smp->type = SMP_T_STR;
3588 smp->flags |= SMP_F_CONST;
Emeric Brun7f56e742012-10-19 18:15:40 +02003589 smp->data.str.len = strlen(smp->data.str.str);
Emeric Brunba841a12014-04-30 17:05:08 +02003590 /* SSL_get_peer_certificate increase X509 * ref count */
3591 if (cert_peer)
3592 X509_free(crt);
Emeric Brun7f56e742012-10-19 18:15:40 +02003593
3594 return 1;
3595}
3596
Emeric Brunba841a12014-04-30 17:05:08 +02003597/* string, returns the certificate's key algorithm.
3598 * The 5th keyword char is used to know if SSL_get_certificate or SSL_get_peer_certificate
3599 * should be use.
3600 */
Emeric Brun521a0112012-10-22 12:22:55 +02003601static int
Emeric Brunba841a12014-04-30 17:05:08 +02003602smp_fetch_ssl_x_key_alg(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
Thierry FOURNIERf41a8092014-12-07 18:37:57 +01003603 const struct arg *args, struct sample *smp, const char *kw, void *private)
Emeric Brun521a0112012-10-22 12:22:55 +02003604{
Emeric Brunba841a12014-04-30 17:05:08 +02003605 int cert_peer = (kw[4] == 'c') ? 1 : 0;
Emeric Brun521a0112012-10-22 12:22:55 +02003606 X509 *crt;
3607 int nid;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003608 struct connection *conn;
Emeric Brun521a0112012-10-22 12:22:55 +02003609
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003610 if (!l4)
Emeric Brun521a0112012-10-22 12:22:55 +02003611 return 0;
3612
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003613 conn = objt_conn(l4->si[0].end);
3614 if (!conn || conn->xprt != &ssl_sock)
3615 return 0;
3616
3617 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brun521a0112012-10-22 12:22:55 +02003618 smp->flags |= SMP_F_MAY_CHANGE;
3619 return 0;
3620 }
3621
Emeric Brunba841a12014-04-30 17:05:08 +02003622 if (cert_peer)
3623 crt = SSL_get_peer_certificate(conn->xprt_ctx);
3624 else
3625 crt = SSL_get_certificate(conn->xprt_ctx);
Emeric Brun521a0112012-10-22 12:22:55 +02003626 if (!crt)
3627 return 0;
3628
3629 nid = OBJ_obj2nid((ASN1_OBJECT *)(crt->cert_info->key->algor->algorithm));
3630
3631 smp->data.str.str = (char *)OBJ_nid2sn(nid);
Emeric Brun9bf3ba22013-10-07 14:31:44 +02003632 if (!smp->data.str.str) {
Emeric Brunba841a12014-04-30 17:05:08 +02003633 /* SSL_get_peer_certificate increase X509 * ref count */
3634 if (cert_peer)
3635 X509_free(crt);
Emeric Brun521a0112012-10-22 12:22:55 +02003636 return 0;
Emeric Brun9bf3ba22013-10-07 14:31:44 +02003637 }
Emeric Brun521a0112012-10-22 12:22:55 +02003638
Thierry FOURNIER7654c9f2013-12-17 00:20:33 +01003639 smp->type = SMP_T_STR;
3640 smp->flags |= SMP_F_CONST;
Emeric Brun521a0112012-10-22 12:22:55 +02003641 smp->data.str.len = strlen(smp->data.str.str);
Emeric Brunba841a12014-04-30 17:05:08 +02003642 if (cert_peer)
3643 X509_free(crt);
Emeric Brun521a0112012-10-22 12:22:55 +02003644
3645 return 1;
3646}
3647
Emeric Brun645ae792014-04-30 14:21:06 +02003648/* boolean, returns true if front conn. transport layer is SSL.
3649 * This function is also usable on backend conn if the fetch keyword 5th
3650 * char is 'b'.
3651 */
Willy Tarreau7875d092012-09-10 08:20:03 +02003652static int
Emeric Brun2525b6b2012-10-18 15:59:43 +02003653smp_fetch_ssl_fc(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
Thierry FOURNIERf41a8092014-12-07 18:37:57 +01003654 const struct arg *args, struct sample *smp, const char *kw, void *private)
Willy Tarreau7875d092012-09-10 08:20:03 +02003655{
Emeric Brun645ae792014-04-30 14:21:06 +02003656 int back_conn = (kw[4] == 'b') ? 1 : 0;
3657 struct connection *conn = objt_conn(l4->si[back_conn].end);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003658
Willy Tarreau7875d092012-09-10 08:20:03 +02003659 smp->type = SMP_T_BOOL;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003660 smp->data.uint = (conn && conn->xprt == &ssl_sock);
Willy Tarreau7875d092012-09-10 08:20:03 +02003661 return 1;
3662}
3663
Emeric Brun2525b6b2012-10-18 15:59:43 +02003664/* boolean, returns true if client present a SNI */
Willy Tarreau7875d092012-09-10 08:20:03 +02003665static int
Emeric Brun2525b6b2012-10-18 15:59:43 +02003666smp_fetch_ssl_fc_has_sni(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
Thierry FOURNIERf41a8092014-12-07 18:37:57 +01003667 const struct arg *args, struct sample *smp, const char *kw, void *private)
Willy Tarreau7875d092012-09-10 08:20:03 +02003668{
3669#ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003670 struct connection *conn = objt_conn(l4->si[0].end);
3671
Willy Tarreau7875d092012-09-10 08:20:03 +02003672 smp->type = SMP_T_BOOL;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003673 smp->data.uint = (conn && conn->xprt == &ssl_sock) &&
3674 conn->xprt_ctx &&
3675 SSL_get_servername(conn->xprt_ctx, TLSEXT_NAMETYPE_host_name) != NULL;
Willy Tarreau7875d092012-09-10 08:20:03 +02003676 return 1;
3677#else
3678 return 0;
3679#endif
3680}
3681
Emeric Brun645ae792014-04-30 14:21:06 +02003682/* string, returns the used cipher if front conn. transport layer is SSL.
3683 * This function is also usable on backend conn if the fetch keyword 5th
3684 * char is 'b'.
3685 */
Emeric Brun589fcad2012-10-16 14:13:26 +02003686static int
3687smp_fetch_ssl_fc_cipher(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
Thierry FOURNIERf41a8092014-12-07 18:37:57 +01003688 const struct arg *args, struct sample *smp, const char *kw, void *private)
Emeric Brun589fcad2012-10-16 14:13:26 +02003689{
Emeric Brun645ae792014-04-30 14:21:06 +02003690 int back_conn = (kw[4] == 'b') ? 1 : 0;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003691 struct connection *conn;
3692
Emeric Brun589fcad2012-10-16 14:13:26 +02003693 smp->flags = 0;
3694
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003695 if (!l4)
3696 return 0;
3697
Emeric Brun645ae792014-04-30 14:21:06 +02003698 conn = objt_conn(l4->si[back_conn].end);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003699 if (!conn || !conn->xprt_ctx || conn->xprt != &ssl_sock)
Emeric Brun589fcad2012-10-16 14:13:26 +02003700 return 0;
3701
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003702 smp->data.str.str = (char *)SSL_get_cipher_name(conn->xprt_ctx);
Emeric Brun589fcad2012-10-16 14:13:26 +02003703 if (!smp->data.str.str)
3704 return 0;
3705
Thierry FOURNIER7654c9f2013-12-17 00:20:33 +01003706 smp->type = SMP_T_STR;
3707 smp->flags |= SMP_F_CONST;
Emeric Brun589fcad2012-10-16 14:13:26 +02003708 smp->data.str.len = strlen(smp->data.str.str);
3709
3710 return 1;
3711}
3712
Emeric Brun645ae792014-04-30 14:21:06 +02003713/* integer, returns the algoritm's keysize if front conn. transport layer
3714 * is SSL.
3715 * This function is also usable on backend conn if the fetch keyword 5th
3716 * char is 'b'.
3717 */
Emeric Brun589fcad2012-10-16 14:13:26 +02003718static int
3719smp_fetch_ssl_fc_alg_keysize(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
Thierry FOURNIERf41a8092014-12-07 18:37:57 +01003720 const struct arg *args, struct sample *smp, const char *kw, void *private)
Emeric Brun589fcad2012-10-16 14:13:26 +02003721{
Emeric Brun645ae792014-04-30 14:21:06 +02003722 int back_conn = (kw[4] == 'b') ? 1 : 0;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003723 struct connection *conn;
3724
Emeric Brun589fcad2012-10-16 14:13:26 +02003725 smp->flags = 0;
3726
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003727 if (!l4)
Emeric Brun589fcad2012-10-16 14:13:26 +02003728 return 0;
3729
Emeric Brun645ae792014-04-30 14:21:06 +02003730 conn = objt_conn(l4->si[back_conn].end);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003731 if (!conn || !conn->xprt_ctx || conn->xprt != &ssl_sock)
Emeric Brun589fcad2012-10-16 14:13:26 +02003732 return 0;
3733
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003734 if (!SSL_get_cipher_bits(conn->xprt_ctx, (int *)&smp->data.uint))
3735 return 0;
3736
Emeric Brun589fcad2012-10-16 14:13:26 +02003737 smp->type = SMP_T_UINT;
3738
3739 return 1;
3740}
3741
Emeric Brun645ae792014-04-30 14:21:06 +02003742/* integer, returns the used keysize if front conn. transport layer is SSL.
3743 * This function is also usable on backend conn if the fetch keyword 5th
3744 * char is 'b'.
3745 */
Emeric Brun589fcad2012-10-16 14:13:26 +02003746static int
3747smp_fetch_ssl_fc_use_keysize(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
Thierry FOURNIERf41a8092014-12-07 18:37:57 +01003748 const struct arg *args, struct sample *smp, const char *kw, void *private)
Emeric Brun589fcad2012-10-16 14:13:26 +02003749{
Emeric Brun645ae792014-04-30 14:21:06 +02003750 int back_conn = (kw[4] == 'b') ? 1 : 0;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003751 struct connection *conn;
3752
Emeric Brun589fcad2012-10-16 14:13:26 +02003753 smp->flags = 0;
3754
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003755 if (!l4)
Emeric Brun589fcad2012-10-16 14:13:26 +02003756 return 0;
3757
Emeric Brun645ae792014-04-30 14:21:06 +02003758 conn = objt_conn(l4->si[back_conn].end);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003759 if (!conn || !conn->xprt_ctx || conn->xprt != &ssl_sock)
3760 return 0;
3761
3762 smp->data.uint = (unsigned int)SSL_get_cipher_bits(conn->xprt_ctx, NULL);
Emeric Brun589fcad2012-10-16 14:13:26 +02003763 if (!smp->data.uint)
3764 return 0;
3765
3766 smp->type = SMP_T_UINT;
3767
3768 return 1;
3769}
3770
Willy Tarreau6c9a3d52012-10-18 18:57:14 +02003771#ifdef OPENSSL_NPN_NEGOTIATED
Willy Tarreau7875d092012-09-10 08:20:03 +02003772static int
Emeric Brun2525b6b2012-10-18 15:59:43 +02003773smp_fetch_ssl_fc_npn(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
Thierry FOURNIERf41a8092014-12-07 18:37:57 +01003774 const struct arg *args, struct sample *smp, const char *kw, void *private)
Willy Tarreaua33c6542012-10-15 13:19:06 +02003775{
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003776 struct connection *conn;
3777
Thierry FOURNIER7654c9f2013-12-17 00:20:33 +01003778 smp->flags = SMP_F_CONST;
3779 smp->type = SMP_T_STR;
Willy Tarreaua33c6542012-10-15 13:19:06 +02003780
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003781 if (!l4)
Willy Tarreaua33c6542012-10-15 13:19:06 +02003782 return 0;
3783
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003784 conn = objt_conn(l4->si[0].end);
3785 if (!conn || !conn->xprt_ctx || conn->xprt != &ssl_sock)
3786 return 0;
3787
Willy Tarreaua33c6542012-10-15 13:19:06 +02003788 smp->data.str.str = NULL;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003789 SSL_get0_next_proto_negotiated(conn->xprt_ctx,
Willy Tarreaua33c6542012-10-15 13:19:06 +02003790 (const unsigned char **)&smp->data.str.str, (unsigned *)&smp->data.str.len);
3791
3792 if (!smp->data.str.str)
3793 return 0;
3794
3795 return 1;
Willy Tarreaua33c6542012-10-15 13:19:06 +02003796}
Willy Tarreau6c9a3d52012-10-18 18:57:14 +02003797#endif
Willy Tarreaua33c6542012-10-15 13:19:06 +02003798
Dirkjan Bussink48f1c4e2014-02-13 12:29:42 +01003799#ifdef TLSEXT_TYPE_application_layer_protocol_negotiation
Willy Tarreauab861d32013-04-02 02:30:41 +02003800static int
3801smp_fetch_ssl_fc_alpn(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
Thierry FOURNIERf41a8092014-12-07 18:37:57 +01003802 const struct arg *args, struct sample *smp, const char *kw, void *private)
Willy Tarreauab861d32013-04-02 02:30:41 +02003803{
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003804 struct connection *conn;
3805
Thierry FOURNIER7654c9f2013-12-17 00:20:33 +01003806 smp->flags = SMP_F_CONST;
3807 smp->type = SMP_T_STR;
Willy Tarreauab861d32013-04-02 02:30:41 +02003808
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003809 if (!l4)
3810 return 0;
3811
3812 conn = objt_conn(l4->si[0].end);
3813 if (!conn || !conn->xprt_ctx || conn->xprt != &ssl_sock)
Willy Tarreauab861d32013-04-02 02:30:41 +02003814 return 0;
3815
3816 smp->data.str.str = NULL;
Dirkjan Bussink48f1c4e2014-02-13 12:29:42 +01003817 SSL_get0_alpn_selected(conn->xprt_ctx,
Willy Tarreauab861d32013-04-02 02:30:41 +02003818 (const unsigned char **)&smp->data.str.str, (unsigned *)&smp->data.str.len);
3819
3820 if (!smp->data.str.str)
3821 return 0;
3822
3823 return 1;
3824}
3825#endif
3826
Emeric Brun645ae792014-04-30 14:21:06 +02003827/* string, returns the used protocol if front conn. transport layer is SSL.
3828 * This function is also usable on backend conn if the fetch keyword 5th
3829 * char is 'b'.
3830 */
Willy Tarreaua33c6542012-10-15 13:19:06 +02003831static int
Emeric Brun589fcad2012-10-16 14:13:26 +02003832smp_fetch_ssl_fc_protocol(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
Thierry FOURNIERf41a8092014-12-07 18:37:57 +01003833 const struct arg *args, struct sample *smp, const char *kw, void *private)
Emeric Brun589fcad2012-10-16 14:13:26 +02003834{
Emeric Brun645ae792014-04-30 14:21:06 +02003835 int back_conn = (kw[4] == 'b') ? 1 : 0;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003836 struct connection *conn;
3837
Emeric Brun589fcad2012-10-16 14:13:26 +02003838 smp->flags = 0;
3839
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003840 if (!l4)
Emeric Brun589fcad2012-10-16 14:13:26 +02003841 return 0;
3842
Emeric Brun645ae792014-04-30 14:21:06 +02003843 conn = objt_conn(l4->si[back_conn].end);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003844 if (!conn || !conn->xprt_ctx || conn->xprt != &ssl_sock)
3845 return 0;
3846
3847 smp->data.str.str = (char *)SSL_get_version(conn->xprt_ctx);
Emeric Brun589fcad2012-10-16 14:13:26 +02003848 if (!smp->data.str.str)
3849 return 0;
3850
Thierry FOURNIER7654c9f2013-12-17 00:20:33 +01003851 smp->type = SMP_T_STR;
3852 smp->flags = SMP_F_CONST;
Emeric Brun589fcad2012-10-16 14:13:26 +02003853 smp->data.str.len = strlen(smp->data.str.str);
3854
3855 return 1;
3856}
3857
Emeric Brun645ae792014-04-30 14:21:06 +02003858/* binary, returns the SSL session id if front conn. transport layer is SSL.
3859 * This function is also usable on backend conn if the fetch keyword 5th
3860 * char is 'b'.
3861 */
Emeric Brun589fcad2012-10-16 14:13:26 +02003862static int
Emeric Brunfe68f682012-10-16 14:59:28 +02003863smp_fetch_ssl_fc_session_id(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
Thierry FOURNIERf41a8092014-12-07 18:37:57 +01003864 const struct arg *args, struct sample *smp, const char *kw, void *private)
Emeric Brunfe68f682012-10-16 14:59:28 +02003865{
3866#if OPENSSL_VERSION_NUMBER > 0x0090800fL
Emeric Brun645ae792014-04-30 14:21:06 +02003867 int back_conn = (kw[4] == 'b') ? 1 : 0;
Emeric Brunfe68f682012-10-16 14:59:28 +02003868 SSL_SESSION *sess;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003869 struct connection *conn;
Emeric Brunfe68f682012-10-16 14:59:28 +02003870
Thierry FOURNIER7654c9f2013-12-17 00:20:33 +01003871 smp->flags = SMP_F_CONST;
3872 smp->type = SMP_T_BIN;
Emeric Brunfe68f682012-10-16 14:59:28 +02003873
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003874 if (!l4)
Emeric Brunfe68f682012-10-16 14:59:28 +02003875 return 0;
3876
Emeric Brun645ae792014-04-30 14:21:06 +02003877 conn = objt_conn(l4->si[back_conn].end);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003878 if (!conn || !conn->xprt_ctx || conn->xprt != &ssl_sock)
3879 return 0;
3880
3881 sess = SSL_get_session(conn->xprt_ctx);
Emeric Brunfe68f682012-10-16 14:59:28 +02003882 if (!sess)
3883 return 0;
3884
3885 smp->data.str.str = (char *)SSL_SESSION_get_id(sess, (unsigned int *)&smp->data.str.len);
3886 if (!smp->data.str.str || !&smp->data.str.len)
3887 return 0;
3888
3889 return 1;
3890#else
3891 return 0;
3892#endif
3893}
3894
3895static int
Emeric Brun2525b6b2012-10-18 15:59:43 +02003896smp_fetch_ssl_fc_sni(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
Thierry FOURNIERf41a8092014-12-07 18:37:57 +01003897 const struct arg *args, struct sample *smp, const char *kw, void *private)
Willy Tarreau7875d092012-09-10 08:20:03 +02003898{
3899#ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003900 struct connection *conn;
3901
Thierry FOURNIER7654c9f2013-12-17 00:20:33 +01003902 smp->flags = SMP_F_CONST;
3903 smp->type = SMP_T_STR;
Willy Tarreau7875d092012-09-10 08:20:03 +02003904
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003905 if (!l4)
Willy Tarreau7875d092012-09-10 08:20:03 +02003906 return 0;
3907
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003908 conn = objt_conn(l4->si[0].end);
3909 if (!conn || !conn->xprt_ctx || conn->xprt != &ssl_sock)
3910 return 0;
3911
3912 smp->data.str.str = (char *)SSL_get_servername(conn->xprt_ctx, TLSEXT_NAMETYPE_host_name);
Willy Tarreau3e394c92012-09-14 23:56:58 +02003913 if (!smp->data.str.str)
3914 return 0;
3915
Willy Tarreau7875d092012-09-10 08:20:03 +02003916 smp->data.str.len = strlen(smp->data.str.str);
3917 return 1;
3918#else
3919 return 0;
3920#endif
3921}
3922
David Sc1ad52e2014-04-08 18:48:47 -04003923static int
3924smp_fetch_ssl_fc_unique_id(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
Thierry FOURNIERf41a8092014-12-07 18:37:57 +01003925 const struct arg *args, struct sample *smp, const char *kw, void *private)
David Sc1ad52e2014-04-08 18:48:47 -04003926{
3927#if OPENSSL_VERSION_NUMBER > 0x0090800fL
Emeric Brun645ae792014-04-30 14:21:06 +02003928 int back_conn = (kw[4] == 'b') ? 1 : 0;
David Sc1ad52e2014-04-08 18:48:47 -04003929 struct connection *conn;
3930 int finished_len;
David Sc1ad52e2014-04-08 18:48:47 -04003931 struct chunk *finished_trash;
David Sc1ad52e2014-04-08 18:48:47 -04003932
3933 smp->flags = 0;
3934
3935 if (!l4)
3936 return 0;
3937
Emeric Brun645ae792014-04-30 14:21:06 +02003938 conn = objt_conn(l4->si[back_conn].end);
David Sc1ad52e2014-04-08 18:48:47 -04003939 if (!conn || !conn->xprt_ctx || conn->xprt != &ssl_sock)
3940 return 0;
3941
3942 if (!(conn->flags & CO_FL_CONNECTED)) {
3943 smp->flags |= SMP_F_MAY_CHANGE;
3944 return 0;
3945 }
3946
3947 finished_trash = get_trash_chunk();
3948 if (!SSL_session_reused(conn->xprt_ctx))
3949 finished_len = SSL_get_peer_finished(conn->xprt_ctx, finished_trash->str, finished_trash->size);
3950 else
3951 finished_len = SSL_get_finished(conn->xprt_ctx, finished_trash->str, finished_trash->size);
3952
3953 if (!finished_len)
3954 return 0;
3955
Emeric Brunb73a9b02014-04-30 18:49:19 +02003956 finished_trash->len = finished_len;
3957 smp->data.str = *finished_trash;
3958 smp->type = SMP_T_BIN;
David Sc1ad52e2014-04-08 18:48:47 -04003959
3960 return 1;
3961#else
3962 return 0;
3963#endif
3964}
3965
Emeric Brun2525b6b2012-10-18 15:59:43 +02003966/* integer, returns the first verify error in CA chain of client certificate chain. */
Emeric Brunf282a812012-09-21 15:27:54 +02003967static int
Emeric Brun2525b6b2012-10-18 15:59:43 +02003968smp_fetch_ssl_c_ca_err(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
Thierry FOURNIERf41a8092014-12-07 18:37:57 +01003969 const struct arg *args, struct sample *smp, const char *kw, void *private)
Emeric Brunf282a812012-09-21 15:27:54 +02003970{
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003971 struct connection *conn;
3972
3973 if (!l4)
Emeric Brunf282a812012-09-21 15:27:54 +02003974 return 0;
3975
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003976 conn = objt_conn(l4->si[0].end);
3977 if (!conn || conn->xprt != &ssl_sock)
3978 return 0;
3979
3980 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brunf282a812012-09-21 15:27:54 +02003981 smp->flags = SMP_F_MAY_CHANGE;
3982 return 0;
3983 }
3984
3985 smp->type = SMP_T_UINT;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003986 smp->data.uint = (unsigned int)SSL_SOCK_ST_TO_CA_ERROR(conn->xprt_st);
Emeric Brunf282a812012-09-21 15:27:54 +02003987 smp->flags = 0;
3988
3989 return 1;
3990}
3991
Emeric Brun2525b6b2012-10-18 15:59:43 +02003992/* integer, returns the depth of the first verify error in CA chain of client certificate chain. */
Emeric Brunf282a812012-09-21 15:27:54 +02003993static int
Emeric Brun2525b6b2012-10-18 15:59:43 +02003994smp_fetch_ssl_c_ca_err_depth(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
Thierry FOURNIERf41a8092014-12-07 18:37:57 +01003995 const struct arg *args, struct sample *smp, const char *kw, void *private)
Emeric Brunf282a812012-09-21 15:27:54 +02003996{
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003997 struct connection *conn;
3998
3999 if (!l4)
4000 return 0;
4001
4002 conn = objt_conn(l4->si[0].end);
4003 if (!conn || conn->xprt != &ssl_sock)
Emeric Brunf282a812012-09-21 15:27:54 +02004004 return 0;
4005
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004006 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brunf282a812012-09-21 15:27:54 +02004007 smp->flags = SMP_F_MAY_CHANGE;
4008 return 0;
4009 }
4010
4011 smp->type = SMP_T_UINT;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004012 smp->data.uint = (unsigned int)SSL_SOCK_ST_TO_CAEDEPTH(conn->xprt_st);
Emeric Brunf282a812012-09-21 15:27:54 +02004013 smp->flags = 0;
4014
4015 return 1;
4016}
4017
Emeric Brun2525b6b2012-10-18 15:59:43 +02004018/* integer, returns the first verify error on client certificate */
Emeric Brunf282a812012-09-21 15:27:54 +02004019static int
Emeric Brun2525b6b2012-10-18 15:59:43 +02004020smp_fetch_ssl_c_err(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
Thierry FOURNIERf41a8092014-12-07 18:37:57 +01004021 const struct arg *args, struct sample *smp, const char *kw, void *private)
Emeric Brunf282a812012-09-21 15:27:54 +02004022{
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004023 struct connection *conn;
4024
4025 if (!l4)
Emeric Brunf282a812012-09-21 15:27:54 +02004026 return 0;
4027
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004028 conn = objt_conn(l4->si[0].end);
4029 if (!conn || conn->xprt != &ssl_sock)
4030 return 0;
4031
4032 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brunf282a812012-09-21 15:27:54 +02004033 smp->flags = SMP_F_MAY_CHANGE;
4034 return 0;
4035 }
4036
4037 smp->type = SMP_T_UINT;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004038 smp->data.uint = (unsigned int)SSL_SOCK_ST_TO_CRTERROR(conn->xprt_st);
Emeric Brunf282a812012-09-21 15:27:54 +02004039 smp->flags = 0;
4040
4041 return 1;
4042}
4043
Emeric Brun2525b6b2012-10-18 15:59:43 +02004044/* integer, returns the verify result on client cert */
Emeric Brunbaf8ffb2012-09-21 15:27:20 +02004045static int
Emeric Brun2525b6b2012-10-18 15:59:43 +02004046smp_fetch_ssl_c_verify(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
Thierry FOURNIERf41a8092014-12-07 18:37:57 +01004047 const struct arg *args, struct sample *smp, const char *kw, void *private)
Emeric Brunbaf8ffb2012-09-21 15:27:20 +02004048{
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004049 struct connection *conn;
4050
4051 if (!l4)
Emeric Brunbaf8ffb2012-09-21 15:27:20 +02004052 return 0;
4053
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004054 conn = objt_conn(l4->si[0].end);
4055 if (!conn || conn->xprt != &ssl_sock)
4056 return 0;
4057
4058 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brunbaf8ffb2012-09-21 15:27:20 +02004059 smp->flags = SMP_F_MAY_CHANGE;
4060 return 0;
4061 }
4062
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004063 if (!conn->xprt_ctx)
Emeric Brunbaf8ffb2012-09-21 15:27:20 +02004064 return 0;
4065
4066 smp->type = SMP_T_UINT;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004067 smp->data.uint = (unsigned int)SSL_get_verify_result(conn->xprt_ctx);
Emeric Brunbaf8ffb2012-09-21 15:27:20 +02004068 smp->flags = 0;
4069
4070 return 1;
4071}
4072
Emeric Brunfb510ea2012-10-05 12:00:26 +02004073/* parse the "ca-file" bind keyword */
4074static 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 +02004075{
4076 if (!*args[cur_arg + 1]) {
4077 if (err)
4078 memprintf(err, "'%s' : missing CAfile path", args[cur_arg]);
4079 return ERR_ALERT | ERR_FATAL;
4080 }
4081
Emeric Brunef42d922012-10-11 16:11:36 +02004082 if ((*args[cur_arg + 1] != '/') && global.ca_base)
4083 memprintf(&conf->ca_file, "%s/%s", global.ca_base, args[cur_arg + 1]);
4084 else
4085 memprintf(&conf->ca_file, "%s", args[cur_arg + 1]);
Emeric Brunc8e8d122012-10-02 18:42:10 +02004086
Emeric Brund94b3fe2012-09-20 18:23:56 +02004087 return 0;
4088}
4089
Willy Tarreau79eeafa2012-09-14 07:53:05 +02004090/* parse the "ciphers" bind keyword */
Willy Tarreau4348fad2012-09-20 16:48:07 +02004091static 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 +02004092{
4093 if (!*args[cur_arg + 1]) {
Willy Tarreaueb6cead2012-09-20 19:43:14 +02004094 memprintf(err, "'%s' : missing cipher suite", args[cur_arg]);
Willy Tarreau79eeafa2012-09-14 07:53:05 +02004095 return ERR_ALERT | ERR_FATAL;
4096 }
4097
Emeric Brun76d88952012-10-05 15:47:31 +02004098 free(conf->ciphers);
Willy Tarreau4348fad2012-09-20 16:48:07 +02004099 conf->ciphers = strdup(args[cur_arg + 1]);
Willy Tarreau79eeafa2012-09-14 07:53:05 +02004100 return 0;
4101}
4102
4103/* parse the "crt" bind keyword */
Willy Tarreau4348fad2012-09-20 16:48:07 +02004104static 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 +02004105{
Willy Tarreau38011032013-08-13 16:59:39 +02004106 char path[MAXPATHLEN];
Willy Tarreaub75d6922014-04-14 18:05:41 +02004107
Willy Tarreau79eeafa2012-09-14 07:53:05 +02004108 if (!*args[cur_arg + 1]) {
Willy Tarreaueb6cead2012-09-20 19:43:14 +02004109 memprintf(err, "'%s' : missing certificate location", args[cur_arg]);
Willy Tarreau79eeafa2012-09-14 07:53:05 +02004110 return ERR_ALERT | ERR_FATAL;
4111 }
4112
Emeric Brunc8e8d122012-10-02 18:42:10 +02004113 if ((*args[cur_arg + 1] != '/' ) && global.crt_base) {
Willy Tarreau38011032013-08-13 16:59:39 +02004114 if ((strlen(global.crt_base) + 1 + strlen(args[cur_arg + 1]) + 1) > MAXPATHLEN) {
Emeric Brunc8e8d122012-10-02 18:42:10 +02004115 memprintf(err, "'%s' : path too long", args[cur_arg]);
4116 return ERR_ALERT | ERR_FATAL;
4117 }
Willy Tarreaub75d6922014-04-14 18:05:41 +02004118 snprintf(path, sizeof(path), "%s/%s", global.crt_base, args[cur_arg + 1]);
Emeric Brunc8e8d122012-10-02 18:42:10 +02004119 if (ssl_sock_load_cert(path, conf, px, err) > 0)
4120 return ERR_ALERT | ERR_FATAL;
4121
4122 return 0;
4123 }
4124
Willy Tarreau4348fad2012-09-20 16:48:07 +02004125 if (ssl_sock_load_cert(args[cur_arg + 1], conf, px, err) > 0)
Willy Tarreau79eeafa2012-09-14 07:53:05 +02004126 return ERR_ALERT | ERR_FATAL;
Emeric Brund94b3fe2012-09-20 18:23:56 +02004127
4128 return 0;
4129}
4130
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01004131/* parse the "crt-list" bind keyword */
4132static int bind_parse_crt_list(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
4133{
4134 if (!*args[cur_arg + 1]) {
4135 memprintf(err, "'%s' : missing certificate location", args[cur_arg]);
4136 return ERR_ALERT | ERR_FATAL;
4137 }
4138
Willy Tarreauad1731d2013-04-02 17:35:58 +02004139 if (ssl_sock_load_cert_list_file(args[cur_arg + 1], conf, px, err) > 0) {
4140 memprintf(err, "'%s' : %s", args[cur_arg], *err);
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01004141 return ERR_ALERT | ERR_FATAL;
Willy Tarreauad1731d2013-04-02 17:35:58 +02004142 }
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01004143
4144 return 0;
4145}
4146
Emeric Brunfb510ea2012-10-05 12:00:26 +02004147/* parse the "crl-file" bind keyword */
4148static 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 +02004149{
Emeric Brun051cdab2012-10-02 19:25:50 +02004150#ifndef X509_V_FLAG_CRL_CHECK
4151 if (err)
4152 memprintf(err, "'%s' : library does not support CRL verify", args[cur_arg]);
4153 return ERR_ALERT | ERR_FATAL;
4154#else
Emeric Brund94b3fe2012-09-20 18:23:56 +02004155 if (!*args[cur_arg + 1]) {
4156 if (err)
4157 memprintf(err, "'%s' : missing CRLfile path", args[cur_arg]);
4158 return ERR_ALERT | ERR_FATAL;
4159 }
Emeric Brun2b58d042012-09-20 17:10:03 +02004160
Emeric Brunef42d922012-10-11 16:11:36 +02004161 if ((*args[cur_arg + 1] != '/') && global.ca_base)
4162 memprintf(&conf->crl_file, "%s/%s", global.ca_base, args[cur_arg + 1]);
4163 else
4164 memprintf(&conf->crl_file, "%s", args[cur_arg + 1]);
Emeric Brunc8e8d122012-10-02 18:42:10 +02004165
Emeric Brun2b58d042012-09-20 17:10:03 +02004166 return 0;
Emeric Brun051cdab2012-10-02 19:25:50 +02004167#endif
Emeric Brun2b58d042012-09-20 17:10:03 +02004168}
4169
4170/* parse the "ecdhe" bind keyword keywords */
4171static int bind_parse_ecdhe(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
4172{
4173#if OPENSSL_VERSION_NUMBER < 0x0090800fL
4174 if (err)
4175 memprintf(err, "'%s' : library does not support elliptic curve Diffie-Hellman (too old)", args[cur_arg]);
4176 return ERR_ALERT | ERR_FATAL;
4177#elif defined(OPENSSL_NO_ECDH)
4178 if (err)
4179 memprintf(err, "'%s' : library does not support elliptic curve Diffie-Hellman (disabled via OPENSSL_NO_ECDH)", args[cur_arg]);
4180 return ERR_ALERT | ERR_FATAL;
4181#else
4182 if (!*args[cur_arg + 1]) {
4183 if (err)
4184 memprintf(err, "'%s' : missing named curve", args[cur_arg]);
4185 return ERR_ALERT | ERR_FATAL;
4186 }
4187
4188 conf->ecdhe = strdup(args[cur_arg + 1]);
Willy Tarreau79eeafa2012-09-14 07:53:05 +02004189
4190 return 0;
Emeric Brun2b58d042012-09-20 17:10:03 +02004191#endif
Willy Tarreau79eeafa2012-09-14 07:53:05 +02004192}
4193
Emeric Brun81c00f02012-09-21 14:31:21 +02004194/* parse the "crt_ignerr" and "ca_ignerr" bind keywords */
4195static int bind_parse_ignore_err(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
4196{
4197 int code;
4198 char *p = args[cur_arg + 1];
4199 unsigned long long *ignerr = &conf->crt_ignerr;
4200
4201 if (!*p) {
4202 if (err)
4203 memprintf(err, "'%s' : missing error IDs list", args[cur_arg]);
4204 return ERR_ALERT | ERR_FATAL;
4205 }
4206
4207 if (strcmp(args[cur_arg], "ca-ignore-err") == 0)
4208 ignerr = &conf->ca_ignerr;
4209
4210 if (strcmp(p, "all") == 0) {
4211 *ignerr = ~0ULL;
4212 return 0;
4213 }
4214
4215 while (p) {
4216 code = atoi(p);
4217 if ((code <= 0) || (code > 63)) {
4218 if (err)
4219 memprintf(err, "'%s' : ID '%d' out of range (1..63) in error IDs list '%s'",
4220 args[cur_arg], code, args[cur_arg + 1]);
4221 return ERR_ALERT | ERR_FATAL;
4222 }
4223 *ignerr |= 1ULL << code;
4224 p = strchr(p, ',');
4225 if (p)
4226 p++;
4227 }
4228
Emeric Brun2cb7ae52012-10-05 14:14:21 +02004229 return 0;
4230}
4231
4232/* parse the "force-sslv3" bind keyword */
4233static int bind_parse_force_sslv3(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
4234{
4235 conf->ssl_options |= BC_SSL_O_USE_SSLV3;
4236 return 0;
4237}
4238
4239/* parse the "force-tlsv10" bind keyword */
4240static int bind_parse_force_tlsv10(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
4241{
4242 conf->ssl_options |= BC_SSL_O_USE_TLSV10;
Emeric Brun2d0c4822012-10-02 13:45:20 +02004243 return 0;
4244}
4245
Emeric Brun2cb7ae52012-10-05 14:14:21 +02004246/* parse the "force-tlsv11" bind keyword */
4247static int bind_parse_force_tlsv11(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
4248{
4249#if SSL_OP_NO_TLSv1_1
4250 conf->ssl_options |= BC_SSL_O_USE_TLSV11;
4251 return 0;
4252#else
4253 if (err)
4254 memprintf(err, "'%s' : library does not support protocol TLSv1.1", args[cur_arg]);
4255 return ERR_ALERT | ERR_FATAL;
4256#endif
4257}
4258
4259/* parse the "force-tlsv12" bind keyword */
4260static int bind_parse_force_tlsv12(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
4261{
4262#if SSL_OP_NO_TLSv1_2
4263 conf->ssl_options |= BC_SSL_O_USE_TLSV12;
4264 return 0;
4265#else
4266 if (err)
4267 memprintf(err, "'%s' : library does not support protocol TLSv1.2", args[cur_arg]);
4268 return ERR_ALERT | ERR_FATAL;
4269#endif
4270}
4271
4272
Emeric Brun2d0c4822012-10-02 13:45:20 +02004273/* parse the "no-tls-tickets" bind keyword */
4274static int bind_parse_no_tls_tickets(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
4275{
Emeric Brun89675492012-10-05 13:48:26 +02004276 conf->ssl_options |= BC_SSL_O_NO_TLS_TICKETS;
Emeric Brun81c00f02012-09-21 14:31:21 +02004277 return 0;
4278}
4279
Emeric Brun2d0c4822012-10-02 13:45:20 +02004280
Emeric Brun9b3009b2012-10-05 11:55:06 +02004281/* parse the "no-sslv3" bind keyword */
4282static 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 +02004283{
Emeric Brun89675492012-10-05 13:48:26 +02004284 conf->ssl_options |= BC_SSL_O_NO_SSLV3;
Willy Tarreau79eeafa2012-09-14 07:53:05 +02004285 return 0;
4286}
4287
Emeric Brun9b3009b2012-10-05 11:55:06 +02004288/* parse the "no-tlsv10" bind keyword */
4289static 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 +02004290{
Emeric Brun89675492012-10-05 13:48:26 +02004291 conf->ssl_options |= BC_SSL_O_NO_TLSV10;
Emeric Brunc0ff4922012-09-28 19:37:02 +02004292 return 0;
4293}
4294
Emeric Brun9b3009b2012-10-05 11:55:06 +02004295/* parse the "no-tlsv11" bind keyword */
4296static 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 +02004297{
Emeric Brun89675492012-10-05 13:48:26 +02004298 conf->ssl_options |= BC_SSL_O_NO_TLSV11;
Emeric Brunc0ff4922012-09-28 19:37:02 +02004299 return 0;
4300}
4301
Emeric Brun9b3009b2012-10-05 11:55:06 +02004302/* parse the "no-tlsv12" bind keyword */
4303static 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 +02004304{
Emeric Brun89675492012-10-05 13:48:26 +02004305 conf->ssl_options |= BC_SSL_O_NO_TLSV12;
Willy Tarreau79eeafa2012-09-14 07:53:05 +02004306 return 0;
4307}
4308
Willy Tarreau6c9a3d52012-10-18 18:57:14 +02004309/* parse the "npn" bind keyword */
4310static int bind_parse_npn(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
4311{
4312#ifdef OPENSSL_NPN_NEGOTIATED
4313 char *p1, *p2;
4314
4315 if (!*args[cur_arg + 1]) {
4316 memprintf(err, "'%s' : missing the comma-delimited NPN protocol suite", args[cur_arg]);
4317 return ERR_ALERT | ERR_FATAL;
4318 }
4319
4320 free(conf->npn_str);
4321
4322 /* the NPN string is built as a suite of (<len> <name>)* */
4323 conf->npn_len = strlen(args[cur_arg + 1]) + 1;
4324 conf->npn_str = calloc(1, conf->npn_len);
4325 memcpy(conf->npn_str + 1, args[cur_arg + 1], conf->npn_len);
4326
4327 /* replace commas with the name length */
4328 p1 = conf->npn_str;
4329 p2 = p1 + 1;
4330 while (1) {
4331 p2 = memchr(p1 + 1, ',', conf->npn_str + conf->npn_len - (p1 + 1));
4332 if (!p2)
4333 p2 = p1 + 1 + strlen(p1 + 1);
4334
4335 if (p2 - (p1 + 1) > 255) {
4336 *p2 = '\0';
4337 memprintf(err, "'%s' : NPN protocol name too long : '%s'", args[cur_arg], p1 + 1);
4338 return ERR_ALERT | ERR_FATAL;
4339 }
4340
4341 *p1 = p2 - (p1 + 1);
4342 p1 = p2;
4343
4344 if (!*p2)
4345 break;
4346
4347 *(p2++) = '\0';
4348 }
4349 return 0;
4350#else
4351 if (err)
4352 memprintf(err, "'%s' : library does not support TLS NPN extension", args[cur_arg]);
4353 return ERR_ALERT | ERR_FATAL;
4354#endif
4355}
4356
Willy Tarreauab861d32013-04-02 02:30:41 +02004357/* parse the "alpn" bind keyword */
4358static int bind_parse_alpn(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
4359{
Dirkjan Bussink48f1c4e2014-02-13 12:29:42 +01004360#ifdef TLSEXT_TYPE_application_layer_protocol_negotiation
Willy Tarreauab861d32013-04-02 02:30:41 +02004361 char *p1, *p2;
4362
4363 if (!*args[cur_arg + 1]) {
4364 memprintf(err, "'%s' : missing the comma-delimited ALPN protocol suite", args[cur_arg]);
4365 return ERR_ALERT | ERR_FATAL;
4366 }
4367
4368 free(conf->alpn_str);
4369
4370 /* the ALPN string is built as a suite of (<len> <name>)* */
4371 conf->alpn_len = strlen(args[cur_arg + 1]) + 1;
4372 conf->alpn_str = calloc(1, conf->alpn_len);
4373 memcpy(conf->alpn_str + 1, args[cur_arg + 1], conf->alpn_len);
4374
4375 /* replace commas with the name length */
4376 p1 = conf->alpn_str;
4377 p2 = p1 + 1;
4378 while (1) {
4379 p2 = memchr(p1 + 1, ',', conf->alpn_str + conf->alpn_len - (p1 + 1));
4380 if (!p2)
4381 p2 = p1 + 1 + strlen(p1 + 1);
4382
4383 if (p2 - (p1 + 1) > 255) {
4384 *p2 = '\0';
4385 memprintf(err, "'%s' : ALPN protocol name too long : '%s'", args[cur_arg], p1 + 1);
4386 return ERR_ALERT | ERR_FATAL;
4387 }
4388
4389 *p1 = p2 - (p1 + 1);
4390 p1 = p2;
4391
4392 if (!*p2)
4393 break;
4394
4395 *(p2++) = '\0';
4396 }
4397 return 0;
4398#else
4399 if (err)
4400 memprintf(err, "'%s' : library does not support TLS ALPN extension", args[cur_arg]);
4401 return ERR_ALERT | ERR_FATAL;
4402#endif
4403}
4404
Willy Tarreau79eeafa2012-09-14 07:53:05 +02004405/* parse the "ssl" bind keyword */
Willy Tarreau4348fad2012-09-20 16:48:07 +02004406static 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 +02004407{
Willy Tarreau81796be2012-09-22 19:11:47 +02004408 struct listener *l;
4409
Willy Tarreau4348fad2012-09-20 16:48:07 +02004410 conf->is_ssl = 1;
Emeric Brun76d88952012-10-05 15:47:31 +02004411
4412 if (global.listen_default_ciphers && !conf->ciphers)
4413 conf->ciphers = strdup(global.listen_default_ciphers);
Emeric Brun2c86cbf2014-10-30 15:56:50 +01004414 conf->ssl_options |= global.listen_default_ssloptions;
Emeric Brun76d88952012-10-05 15:47:31 +02004415
Willy Tarreau81796be2012-09-22 19:11:47 +02004416 list_for_each_entry(l, &conf->listeners, by_bind)
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02004417 l->xprt = &ssl_sock;
Willy Tarreau81796be2012-09-22 19:11:47 +02004418
Willy Tarreau79eeafa2012-09-14 07:53:05 +02004419 return 0;
4420}
4421
Emmanuel Hocdet65623372013-01-24 17:17:15 +01004422/* parse the "strict-sni" bind keyword */
4423static int bind_parse_strict_sni(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
4424{
4425 conf->strict_sni = 1;
4426 return 0;
Nenad Merdanovic05552d42015-02-27 19:56:49 +01004427}
4428
4429/* parse the "tls-ticket-keys" bind keyword */
4430static int bind_parse_tls_ticket_keys(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
4431{
4432#if (defined SSL_CTRL_SET_TLSEXT_TICKET_KEY_CB && TLS_TICKETS_NO > 0)
4433 FILE *f;
4434 int i = 0;
4435 char thisline[LINESIZE];
4436
4437 if (!*args[cur_arg + 1]) {
4438 if (err)
4439 memprintf(err, "'%s' : missing TLS ticket keys file path", args[cur_arg]);
4440 return ERR_ALERT | ERR_FATAL;
4441 }
4442
4443 conf->tls_ticket_keys = malloc(TLS_TICKETS_NO * sizeof(struct tls_sess_key));
4444
4445 if ((f = fopen(args[cur_arg + 1], "r")) == NULL) {
4446 if (err)
4447 memprintf(err, "'%s' : unable to load ssl tickets keys file", args[cur_arg+1]);
4448 return ERR_ALERT | ERR_FATAL;
4449 }
4450
4451 while (fgets(thisline, sizeof(thisline), f) != NULL) {
4452 int len = strlen(thisline);
4453 /* Strip newline characters from the end */
4454 if(thisline[len - 1] == '\n')
4455 thisline[--len] = 0;
4456
4457 if(thisline[len - 1] == '\r')
4458 thisline[--len] = 0;
4459
4460 if (base64dec(thisline, len, (char *) (conf->tls_ticket_keys + i % TLS_TICKETS_NO), sizeof(struct tls_sess_key)) != sizeof(struct tls_sess_key)) {
4461 if (err)
4462 memprintf(err, "'%s' : unable to decode base64 key on line %d", args[cur_arg+1], i + 1);
4463 return ERR_ALERT | ERR_FATAL;
4464 }
4465 i++;
4466 }
4467
4468 if (i < TLS_TICKETS_NO) {
4469 if (err)
4470 memprintf(err, "'%s' : please supply at least %d keys in the tls-tickets-file", args[cur_arg+1], TLS_TICKETS_NO);
4471 return ERR_ALERT | ERR_FATAL;
4472 }
4473
4474 fclose(f);
4475
4476 /* Use penultimate key for encryption, handle when TLS_TICKETS_NO = 1 */
4477 i-=2;
4478 conf->tls_ticket_enc_index = i < 0 ? 0 : i;
4479
4480 return 0;
4481#else
4482 if (err)
4483 memprintf(err, "'%s' : TLS ticket callback extension not supported", args[cur_arg]);
4484 return ERR_ALERT | ERR_FATAL;
4485#endif /* SSL_CTRL_SET_TLSEXT_TICKET_KEY_CB */
Emmanuel Hocdet65623372013-01-24 17:17:15 +01004486}
4487
Emeric Brund94b3fe2012-09-20 18:23:56 +02004488/* parse the "verify" bind keyword */
4489static int bind_parse_verify(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
4490{
4491 if (!*args[cur_arg + 1]) {
4492 if (err)
4493 memprintf(err, "'%s' : missing verify method", args[cur_arg]);
4494 return ERR_ALERT | ERR_FATAL;
4495 }
4496
4497 if (strcmp(args[cur_arg + 1], "none") == 0)
Emeric Brun850efd52014-01-29 12:24:34 +01004498 conf->verify = SSL_SOCK_VERIFY_NONE;
Emeric Brund94b3fe2012-09-20 18:23:56 +02004499 else if (strcmp(args[cur_arg + 1], "optional") == 0)
Emeric Brun850efd52014-01-29 12:24:34 +01004500 conf->verify = SSL_SOCK_VERIFY_OPTIONAL;
Emeric Brund94b3fe2012-09-20 18:23:56 +02004501 else if (strcmp(args[cur_arg + 1], "required") == 0)
Emeric Brun850efd52014-01-29 12:24:34 +01004502 conf->verify = SSL_SOCK_VERIFY_REQUIRED;
Emeric Brund94b3fe2012-09-20 18:23:56 +02004503 else {
4504 if (err)
4505 memprintf(err, "'%s' : unknown verify method '%s', only 'none', 'optional', and 'required' are supported\n",
4506 args[cur_arg], args[cur_arg + 1]);
4507 return ERR_ALERT | ERR_FATAL;
4508 }
4509
4510 return 0;
4511}
4512
Willy Tarreau92faadf2012-10-10 23:04:25 +02004513/************** "server" keywords ****************/
4514
Emeric Brunef42d922012-10-11 16:11:36 +02004515/* parse the "ca-file" server keyword */
4516static int srv_parse_ca_file(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
4517{
4518 if (!*args[*cur_arg + 1]) {
4519 if (err)
4520 memprintf(err, "'%s' : missing CAfile path", args[*cur_arg]);
4521 return ERR_ALERT | ERR_FATAL;
4522 }
4523
4524 if ((*args[*cur_arg + 1] != '/') && global.ca_base)
4525 memprintf(&newsrv->ssl_ctx.ca_file, "%s/%s", global.ca_base, args[*cur_arg + 1]);
4526 else
4527 memprintf(&newsrv->ssl_ctx.ca_file, "%s", args[*cur_arg + 1]);
4528
4529 return 0;
4530}
4531
Willy Tarreau92faadf2012-10-10 23:04:25 +02004532/* parse the "check-ssl" server keyword */
4533static int srv_parse_check_ssl(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
4534{
4535 newsrv->check.use_ssl = 1;
4536 if (global.connect_default_ciphers && !newsrv->ssl_ctx.ciphers)
4537 newsrv->ssl_ctx.ciphers = strdup(global.connect_default_ciphers);
Emeric Brun2c86cbf2014-10-30 15:56:50 +01004538 newsrv->ssl_ctx.options |= global.connect_default_ssloptions;
Willy Tarreau92faadf2012-10-10 23:04:25 +02004539 return 0;
4540}
4541
4542/* parse the "ciphers" server keyword */
4543static int srv_parse_ciphers(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
4544{
4545 if (!*args[*cur_arg + 1]) {
4546 memprintf(err, "'%s' : missing cipher suite", args[*cur_arg]);
4547 return ERR_ALERT | ERR_FATAL;
4548 }
4549
4550 free(newsrv->ssl_ctx.ciphers);
4551 newsrv->ssl_ctx.ciphers = strdup(args[*cur_arg + 1]);
4552 return 0;
4553}
4554
Emeric Brunef42d922012-10-11 16:11:36 +02004555/* parse the "crl-file" server keyword */
4556static int srv_parse_crl_file(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
4557{
4558#ifndef X509_V_FLAG_CRL_CHECK
4559 if (err)
4560 memprintf(err, "'%s' : library does not support CRL verify", args[*cur_arg]);
4561 return ERR_ALERT | ERR_FATAL;
4562#else
4563 if (!*args[*cur_arg + 1]) {
4564 if (err)
4565 memprintf(err, "'%s' : missing CRLfile path", args[*cur_arg]);
4566 return ERR_ALERT | ERR_FATAL;
4567 }
4568
4569 if ((*args[*cur_arg + 1] != '/') && global.ca_base)
4570 memprintf(&newsrv->ssl_ctx.crl_file, "%s/%s", global.ca_base, args[*cur_arg + 1]);
4571 else
4572 memprintf(&newsrv->ssl_ctx.crl_file, "%s", args[*cur_arg + 1]);
4573
4574 return 0;
4575#endif
4576}
4577
Emeric Bruna7aa3092012-10-26 12:58:00 +02004578/* parse the "crt" server keyword */
4579static int srv_parse_crt(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
4580{
4581 if (!*args[*cur_arg + 1]) {
4582 if (err)
4583 memprintf(err, "'%s' : missing certificate file path", args[*cur_arg]);
4584 return ERR_ALERT | ERR_FATAL;
4585 }
4586
4587 if ((*args[*cur_arg + 1] != '/') && global.crt_base)
4588 memprintf(&newsrv->ssl_ctx.client_crt, "%s/%s", global.ca_base, args[*cur_arg + 1]);
4589 else
4590 memprintf(&newsrv->ssl_ctx.client_crt, "%s", args[*cur_arg + 1]);
4591
4592 return 0;
4593}
Emeric Brunef42d922012-10-11 16:11:36 +02004594
Willy Tarreau92faadf2012-10-10 23:04:25 +02004595/* parse the "force-sslv3" server keyword */
4596static int srv_parse_force_sslv3(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
4597{
4598 newsrv->ssl_ctx.options |= SRV_SSL_O_USE_SSLV3;
4599 return 0;
4600}
4601
4602/* parse the "force-tlsv10" server keyword */
4603static int srv_parse_force_tlsv10(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
4604{
4605 newsrv->ssl_ctx.options |= SRV_SSL_O_USE_TLSV10;
4606 return 0;
4607}
4608
4609/* parse the "force-tlsv11" server keyword */
4610static int srv_parse_force_tlsv11(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
4611{
4612#if SSL_OP_NO_TLSv1_1
4613 newsrv->ssl_ctx.options |= SRV_SSL_O_USE_TLSV11;
4614 return 0;
4615#else
4616 if (err)
4617 memprintf(err, "'%s' : library does not support protocol TLSv1.1", args[*cur_arg]);
4618 return ERR_ALERT | ERR_FATAL;
4619#endif
4620}
4621
4622/* parse the "force-tlsv12" server keyword */
4623static int srv_parse_force_tlsv12(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
4624{
4625#if SSL_OP_NO_TLSv1_2
4626 newsrv->ssl_ctx.options |= SRV_SSL_O_USE_TLSV12;
4627 return 0;
4628#else
4629 if (err)
4630 memprintf(err, "'%s' : library does not support protocol TLSv1.2", args[*cur_arg]);
4631 return ERR_ALERT | ERR_FATAL;
4632#endif
4633}
4634
Willy Tarreau2a3fb1c2015-02-05 16:47:07 +01004635/* parse the "no-ssl-reuse" server keyword */
4636static int srv_parse_no_ssl_reuse(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
4637{
4638 newsrv->ssl_ctx.options |= SRV_SSL_O_NO_REUSE;
4639 return 0;
4640}
4641
Willy Tarreau92faadf2012-10-10 23:04:25 +02004642/* parse the "no-sslv3" server keyword */
4643static int srv_parse_no_sslv3(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
4644{
4645 newsrv->ssl_ctx.options |= SRV_SSL_O_NO_SSLV3;
4646 return 0;
4647}
4648
4649/* parse the "no-tlsv10" server keyword */
4650static int srv_parse_no_tlsv10(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
4651{
4652 newsrv->ssl_ctx.options |= SRV_SSL_O_NO_TLSV10;
4653 return 0;
4654}
4655
4656/* parse the "no-tlsv11" server keyword */
4657static int srv_parse_no_tlsv11(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
4658{
4659 newsrv->ssl_ctx.options |= SRV_SSL_O_NO_TLSV11;
4660 return 0;
4661}
4662
4663/* parse the "no-tlsv12" server keyword */
4664static int srv_parse_no_tlsv12(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
4665{
4666 newsrv->ssl_ctx.options |= SRV_SSL_O_NO_TLSV12;
4667 return 0;
4668}
4669
Emeric Brunf9c5c472012-10-11 15:28:34 +02004670/* parse the "no-tls-tickets" server keyword */
4671static int srv_parse_no_tls_tickets(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
4672{
4673 newsrv->ssl_ctx.options |= SRV_SSL_O_NO_TLS_TICKETS;
4674 return 0;
4675}
David Safb76832014-05-08 23:42:08 -04004676/* parse the "send-proxy-v2-ssl" server keyword */
4677static int srv_parse_send_proxy_ssl(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
4678{
4679 newsrv->pp_opts |= SRV_PP_V2;
4680 newsrv->pp_opts |= SRV_PP_V2_SSL;
4681 return 0;
4682}
4683
4684/* parse the "send-proxy-v2-ssl-cn" server keyword */
4685static int srv_parse_send_proxy_cn(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
4686{
4687 newsrv->pp_opts |= SRV_PP_V2;
4688 newsrv->pp_opts |= SRV_PP_V2_SSL;
4689 newsrv->pp_opts |= SRV_PP_V2_SSL_CN;
4690 return 0;
4691}
Emeric Brunf9c5c472012-10-11 15:28:34 +02004692
Willy Tarreau92faadf2012-10-10 23:04:25 +02004693/* parse the "ssl" server keyword */
4694static int srv_parse_ssl(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
4695{
4696 newsrv->use_ssl = 1;
4697 if (global.connect_default_ciphers && !newsrv->ssl_ctx.ciphers)
4698 newsrv->ssl_ctx.ciphers = strdup(global.connect_default_ciphers);
4699 return 0;
4700}
4701
Emeric Brunef42d922012-10-11 16:11:36 +02004702/* parse the "verify" server keyword */
4703static int srv_parse_verify(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
4704{
4705 if (!*args[*cur_arg + 1]) {
4706 if (err)
4707 memprintf(err, "'%s' : missing verify method", args[*cur_arg]);
4708 return ERR_ALERT | ERR_FATAL;
4709 }
4710
4711 if (strcmp(args[*cur_arg + 1], "none") == 0)
Emeric Brun850efd52014-01-29 12:24:34 +01004712 newsrv->ssl_ctx.verify = SSL_SOCK_VERIFY_NONE;
Emeric Brunef42d922012-10-11 16:11:36 +02004713 else if (strcmp(args[*cur_arg + 1], "required") == 0)
Emeric Brun850efd52014-01-29 12:24:34 +01004714 newsrv->ssl_ctx.verify = SSL_SOCK_VERIFY_REQUIRED;
Emeric Brunef42d922012-10-11 16:11:36 +02004715 else {
4716 if (err)
4717 memprintf(err, "'%s' : unknown verify method '%s', only 'none' and 'required' are supported\n",
4718 args[*cur_arg], args[*cur_arg + 1]);
4719 return ERR_ALERT | ERR_FATAL;
4720 }
4721
Evan Broderbe554312013-06-27 00:05:25 -07004722 return 0;
4723}
4724
4725/* parse the "verifyhost" server keyword */
4726static int srv_parse_verifyhost(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
4727{
4728 if (!*args[*cur_arg + 1]) {
4729 if (err)
4730 memprintf(err, "'%s' : missing hostname to verify against", args[*cur_arg]);
4731 return ERR_ALERT | ERR_FATAL;
4732 }
4733
4734 newsrv->ssl_ctx.verify_host = strdup(args[*cur_arg + 1]);
4735
Emeric Brunef42d922012-10-11 16:11:36 +02004736 return 0;
4737}
4738
Emeric Brun2c86cbf2014-10-30 15:56:50 +01004739/* parse the "ssl-default-bind-options" keyword in global section */
4740static int ssl_parse_default_bind_options(char **args, int section_type, struct proxy *curpx,
4741 struct proxy *defpx, const char *file, int line,
4742 char **err) {
4743 int i = 1;
4744
4745 if (*(args[i]) == 0) {
4746 memprintf(err, "global statement '%s' expects an option as an argument.", args[0]);
4747 return -1;
4748 }
4749 while (*(args[i])) {
4750 if (!strcmp(args[i], "no-sslv3"))
4751 global.listen_default_ssloptions |= BC_SSL_O_NO_SSLV3;
4752 else if (!strcmp(args[i], "no-tlsv10"))
4753 global.listen_default_ssloptions |= BC_SSL_O_NO_TLSV10;
4754 else if (!strcmp(args[i], "no-tlsv11"))
4755 global.listen_default_ssloptions |= BC_SSL_O_NO_TLSV11;
4756 else if (!strcmp(args[i], "no-tlsv12"))
4757 global.listen_default_ssloptions |= BC_SSL_O_NO_TLSV12;
4758 else if (!strcmp(args[i], "force-sslv3"))
4759 global.listen_default_ssloptions |= BC_SSL_O_USE_SSLV3;
4760 else if (!strcmp(args[i], "force-tlsv10"))
4761 global.listen_default_ssloptions |= BC_SSL_O_USE_TLSV10;
4762 else if (!strcmp(args[i], "force-tlsv11")) {
4763#if SSL_OP_NO_TLSv1_1
4764 global.listen_default_ssloptions |= BC_SSL_O_USE_TLSV11;
4765#else
4766 memprintf(err, "'%s' '%s': library does not support protocol TLSv1.1", args[0], args[i]);
4767 return -1;
4768#endif
4769 }
4770 else if (!strcmp(args[i], "force-tlsv12")) {
4771#if SSL_OP_NO_TLSv1_2
4772 global.listen_default_ssloptions |= BC_SSL_O_USE_TLSV12;
4773#else
4774 memprintf(err, "'%s' '%s': library does not support protocol TLSv1.2", args[0], args[i]);
4775 return -1;
4776#endif
4777 }
4778 else if (!strcmp(args[i], "no-tls-tickets"))
4779 global.listen_default_ssloptions |= BC_SSL_O_NO_TLS_TICKETS;
4780 else {
4781 memprintf(err, "unknown option '%s' on global statement '%s'.", args[i], args[0]);
4782 return -1;
4783 }
4784 i++;
4785 }
4786 return 0;
4787}
4788
4789/* parse the "ssl-default-server-options" keyword in global section */
4790static int ssl_parse_default_server_options(char **args, int section_type, struct proxy *curpx,
4791 struct proxy *defpx, const char *file, int line,
4792 char **err) {
4793 int i = 1;
4794
4795 if (*(args[i]) == 0) {
4796 memprintf(err, "global statement '%s' expects an option as an argument.", args[0]);
4797 return -1;
4798 }
4799 while (*(args[i])) {
4800 if (!strcmp(args[i], "no-sslv3"))
4801 global.connect_default_ssloptions |= SRV_SSL_O_NO_SSLV3;
4802 else if (!strcmp(args[i], "no-tlsv10"))
4803 global.connect_default_ssloptions |= SRV_SSL_O_NO_TLSV10;
4804 else if (!strcmp(args[i], "no-tlsv11"))
4805 global.connect_default_ssloptions |= SRV_SSL_O_NO_TLSV11;
4806 else if (!strcmp(args[i], "no-tlsv12"))
4807 global.connect_default_ssloptions |= SRV_SSL_O_NO_TLSV12;
4808 else if (!strcmp(args[i], "force-sslv3"))
4809 global.connect_default_ssloptions |= SRV_SSL_O_USE_SSLV3;
4810 else if (!strcmp(args[i], "force-tlsv10"))
4811 global.connect_default_ssloptions |= SRV_SSL_O_USE_TLSV10;
4812 else if (!strcmp(args[i], "force-tlsv11")) {
4813#if SSL_OP_NO_TLSv1_1
4814 global.connect_default_ssloptions |= SRV_SSL_O_USE_TLSV11;
4815#else
4816 memprintf(err, "'%s' '%s': library does not support protocol TLSv1.1", args[0], args[i]);
4817 return -1;
4818#endif
4819 }
4820 else if (!strcmp(args[i], "force-tlsv12")) {
4821#if SSL_OP_NO_TLSv1_2
4822 global.connect_default_ssloptions |= SRV_SSL_O_USE_TLSV12;
4823#else
4824 memprintf(err, "'%s' '%s': library does not support protocol TLSv1.2", args[0], args[i]);
4825 return -1;
4826#endif
4827 }
4828 else if (!strcmp(args[i], "no-tls-tickets"))
4829 global.connect_default_ssloptions |= SRV_SSL_O_NO_TLS_TICKETS;
4830 else {
4831 memprintf(err, "unknown option '%s' on global statement '%s'.", args[i], args[0]);
4832 return -1;
4833 }
4834 i++;
4835 }
4836 return 0;
4837}
4838
Willy Tarreau7875d092012-09-10 08:20:03 +02004839/* Note: must not be declared <const> as its list will be overwritten.
4840 * Please take care of keeping this list alphabetically sorted.
4841 */
Willy Tarreaudc13c112013-06-21 23:16:39 +02004842static struct sample_fetch_kw_list sample_fetch_keywords = {ILH, {
Emeric Brun645ae792014-04-30 14:21:06 +02004843 { "ssl_bc", smp_fetch_ssl_fc, 0, NULL, SMP_T_BOOL, SMP_USE_L5SRV },
4844 { "ssl_bc_alg_keysize", smp_fetch_ssl_fc_alg_keysize, 0, NULL, SMP_T_UINT, SMP_USE_L5SRV },
4845 { "ssl_bc_cipher", smp_fetch_ssl_fc_cipher, 0, NULL, SMP_T_STR, SMP_USE_L5SRV },
4846 { "ssl_bc_protocol", smp_fetch_ssl_fc_protocol, 0, NULL, SMP_T_STR, SMP_USE_L5SRV },
Emeric Brunb73a9b02014-04-30 18:49:19 +02004847 { "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 +02004848 { "ssl_bc_use_keysize", smp_fetch_ssl_fc_use_keysize, 0, NULL, SMP_T_UINT, SMP_USE_L5SRV },
4849 { "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 +01004850 { "ssl_c_ca_err", smp_fetch_ssl_c_ca_err, 0, NULL, SMP_T_UINT, SMP_USE_L5CLI },
4851 { "ssl_c_ca_err_depth", smp_fetch_ssl_c_ca_err_depth, 0, NULL, SMP_T_UINT, SMP_USE_L5CLI },
Emeric Brun43e79582014-10-29 19:03:26 +01004852 { "ssl_c_der", smp_fetch_ssl_x_der, 0, NULL, SMP_T_BIN, SMP_USE_L5CLI },
Willy Tarreau80aca902013-01-07 15:42:20 +01004853 { "ssl_c_err", smp_fetch_ssl_c_err, 0, NULL, SMP_T_UINT, SMP_USE_L5CLI },
Emeric Brunba841a12014-04-30 17:05:08 +02004854 { "ssl_c_i_dn", smp_fetch_ssl_x_i_dn, ARG2(0,STR,SINT), NULL, SMP_T_STR, SMP_USE_L5CLI },
4855 { "ssl_c_key_alg", smp_fetch_ssl_x_key_alg, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
4856 { "ssl_c_notafter", smp_fetch_ssl_x_notafter, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
4857 { "ssl_c_notbefore", smp_fetch_ssl_x_notbefore, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
4858 { "ssl_c_sig_alg", smp_fetch_ssl_x_sig_alg, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
4859 { "ssl_c_s_dn", smp_fetch_ssl_x_s_dn, ARG2(0,STR,SINT), NULL, SMP_T_STR, SMP_USE_L5CLI },
4860 { "ssl_c_serial", smp_fetch_ssl_x_serial, 0, NULL, SMP_T_BIN, SMP_USE_L5CLI },
4861 { "ssl_c_sha1", smp_fetch_ssl_x_sha1, 0, NULL, SMP_T_BIN, SMP_USE_L5CLI },
Willy Tarreau80aca902013-01-07 15:42:20 +01004862 { "ssl_c_used", smp_fetch_ssl_c_used, 0, NULL, SMP_T_BOOL, SMP_USE_L5CLI },
4863 { "ssl_c_verify", smp_fetch_ssl_c_verify, 0, NULL, SMP_T_UINT, SMP_USE_L5CLI },
Emeric Brunba841a12014-04-30 17:05:08 +02004864 { "ssl_c_version", smp_fetch_ssl_x_version, 0, NULL, SMP_T_UINT, SMP_USE_L5CLI },
Emeric Brun43e79582014-10-29 19:03:26 +01004865 { "ssl_f_der", smp_fetch_ssl_x_der, 0, NULL, SMP_T_BIN, SMP_USE_L5CLI },
Emeric Brunba841a12014-04-30 17:05:08 +02004866 { "ssl_f_i_dn", smp_fetch_ssl_x_i_dn, ARG2(0,STR,SINT), NULL, SMP_T_STR, SMP_USE_L5CLI },
4867 { "ssl_f_key_alg", smp_fetch_ssl_x_key_alg, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
4868 { "ssl_f_notafter", smp_fetch_ssl_x_notafter, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
4869 { "ssl_f_notbefore", smp_fetch_ssl_x_notbefore, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
4870 { "ssl_f_sig_alg", smp_fetch_ssl_x_sig_alg, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
4871 { "ssl_f_s_dn", smp_fetch_ssl_x_s_dn, ARG2(0,STR,SINT), NULL, SMP_T_STR, SMP_USE_L5CLI },
4872 { "ssl_f_serial", smp_fetch_ssl_x_serial, 0, NULL, SMP_T_BIN, SMP_USE_L5CLI },
Emeric Brun55f4fa82014-04-30 17:11:25 +02004873 { "ssl_f_sha1", smp_fetch_ssl_x_sha1, 0, NULL, SMP_T_BIN, SMP_USE_L5CLI },
Emeric Brunba841a12014-04-30 17:05:08 +02004874 { "ssl_f_version", smp_fetch_ssl_x_version, 0, NULL, SMP_T_UINT, SMP_USE_L5CLI },
Willy Tarreau80aca902013-01-07 15:42:20 +01004875 { "ssl_fc", smp_fetch_ssl_fc, 0, NULL, SMP_T_BOOL, SMP_USE_L5CLI },
4876 { "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 +01004877 { "ssl_fc_cipher", smp_fetch_ssl_fc_cipher, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
Willy Tarreau80aca902013-01-07 15:42:20 +01004878 { "ssl_fc_has_crt", smp_fetch_ssl_fc_has_crt, 0, NULL, SMP_T_BOOL, SMP_USE_L5CLI },
4879 { "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 +02004880#ifdef OPENSSL_NPN_NEGOTIATED
Thierry FOURNIER7654c9f2013-12-17 00:20:33 +01004881 { "ssl_fc_npn", smp_fetch_ssl_fc_npn, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
Willy Tarreaua33c6542012-10-15 13:19:06 +02004882#endif
Dirkjan Bussink48f1c4e2014-02-13 12:29:42 +01004883#ifdef TLSEXT_TYPE_application_layer_protocol_negotiation
Thierry FOURNIER7654c9f2013-12-17 00:20:33 +01004884 { "ssl_fc_alpn", smp_fetch_ssl_fc_alpn, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
Willy Tarreauab861d32013-04-02 02:30:41 +02004885#endif
Thierry FOURNIER7654c9f2013-12-17 00:20:33 +01004886 { "ssl_fc_protocol", smp_fetch_ssl_fc_protocol, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
Emeric Brunb73a9b02014-04-30 18:49:19 +02004887 { "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 +01004888 { "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 +01004889 { "ssl_fc_session_id", smp_fetch_ssl_fc_session_id, 0, NULL, SMP_T_BIN, SMP_USE_L5CLI },
4890 { "ssl_fc_sni", smp_fetch_ssl_fc_sni, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
Willy Tarreau7875d092012-09-10 08:20:03 +02004891 { NULL, NULL, 0, 0, 0 },
4892}};
4893
4894/* Note: must not be declared <const> as its list will be overwritten.
4895 * Please take care of keeping this list alphabetically sorted.
4896 */
Willy Tarreaudc13c112013-06-21 23:16:39 +02004897static struct acl_kw_list acl_kws = {ILH, {
Thierry FOURNIERc5a4e982014-03-05 16:07:08 +01004898 { "ssl_fc_sni_end", "ssl_fc_sni", PAT_MATCH_END },
4899 { "ssl_fc_sni_reg", "ssl_fc_sni", PAT_MATCH_REG },
Willy Tarreau8ed669b2013-01-11 15:49:37 +01004900 { /* END */ },
Willy Tarreau7875d092012-09-10 08:20:03 +02004901}};
4902
Willy Tarreau79eeafa2012-09-14 07:53:05 +02004903/* Note: must not be declared <const> as its list will be overwritten.
4904 * Please take care of keeping this list alphabetically sorted, doing so helps
4905 * all code contributors.
4906 * Optional keywords are also declared with a NULL ->parse() function so that
4907 * the config parser can report an appropriate error when a known keyword was
4908 * not enabled.
4909 */
Willy Tarreau51fb7652012-09-18 18:24:39 +02004910static struct bind_kw_list bind_kws = { "SSL", { }, {
Nenad Merdanovic05552d42015-02-27 19:56:49 +01004911 { "alpn", bind_parse_alpn, 1 }, /* set ALPN supported protocols */
4912 { "ca-file", bind_parse_ca_file, 1 }, /* set CAfile to process verify on client cert */
4913 { "ca-ignore-err", bind_parse_ignore_err, 1 }, /* set error IDs to ignore on verify depth > 0 */
4914 { "ciphers", bind_parse_ciphers, 1 }, /* set SSL cipher suite */
4915 { "crl-file", bind_parse_crl_file, 1 }, /* set certificat revocation list file use on client cert verify */
4916 { "crt", bind_parse_crt, 1 }, /* load SSL certificates from this location */
4917 { "crt-ignore-err", bind_parse_ignore_err, 1 }, /* set error IDs to ingore on verify depth == 0 */
4918 { "crt-list", bind_parse_crt_list, 1 }, /* load a list of crt from this location */
4919 { "ecdhe", bind_parse_ecdhe, 1 }, /* defines named curve for elliptic curve Diffie-Hellman */
4920 { "force-sslv3", bind_parse_force_sslv3, 0 }, /* force SSLv3 */
4921 { "force-tlsv10", bind_parse_force_tlsv10, 0 }, /* force TLSv10 */
4922 { "force-tlsv11", bind_parse_force_tlsv11, 0 }, /* force TLSv11 */
4923 { "force-tlsv12", bind_parse_force_tlsv12, 0 }, /* force TLSv12 */
4924 { "no-sslv3", bind_parse_no_sslv3, 0 }, /* disable SSLv3 */
4925 { "no-tlsv10", bind_parse_no_tlsv10, 0 }, /* disable TLSv10 */
4926 { "no-tlsv11", bind_parse_no_tlsv11, 0 }, /* disable TLSv11 */
4927 { "no-tlsv12", bind_parse_no_tlsv12, 0 }, /* disable TLSv12 */
4928 { "no-tls-tickets", bind_parse_no_tls_tickets, 0 }, /* disable session resumption tickets */
4929 { "ssl", bind_parse_ssl, 0 }, /* enable SSL processing */
4930 { "strict-sni", bind_parse_strict_sni, 0 }, /* refuse negotiation if sni doesn't match a certificate */
4931 { "tls-ticket-keys", bind_parse_tls_ticket_keys, 1 }, /* set file to load TLS ticket keys from */
4932 { "verify", bind_parse_verify, 1 }, /* set SSL verify method */
4933 { "npn", bind_parse_npn, 1 }, /* set NPN supported protocols */
Willy Tarreau79eeafa2012-09-14 07:53:05 +02004934 { NULL, NULL, 0 },
4935}};
Emeric Brun46591952012-05-18 15:47:34 +02004936
Willy Tarreau92faadf2012-10-10 23:04:25 +02004937/* Note: must not be declared <const> as its list will be overwritten.
4938 * Please take care of keeping this list alphabetically sorted, doing so helps
4939 * all code contributors.
4940 * Optional keywords are also declared with a NULL ->parse() function so that
4941 * the config parser can report an appropriate error when a known keyword was
4942 * not enabled.
4943 */
4944static struct srv_kw_list srv_kws = { "SSL", { }, {
Emeric Brunef42d922012-10-11 16:11:36 +02004945 { "ca-file", srv_parse_ca_file, 1, 0 }, /* set CAfile to process verify server cert */
Emeric Brunecc91fe2012-10-11 15:05:10 +02004946 { "check-ssl", srv_parse_check_ssl, 0, 0 }, /* enable SSL for health checks */
4947 { "ciphers", srv_parse_ciphers, 1, 0 }, /* select the cipher suite */
Emeric Brunef42d922012-10-11 16:11:36 +02004948 { "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 +02004949 { "crt", srv_parse_crt, 1, 0 }, /* set client certificate */
Emeric Brunecc91fe2012-10-11 15:05:10 +02004950 { "force-sslv3", srv_parse_force_sslv3, 0, 0 }, /* force SSLv3 */
4951 { "force-tlsv10", srv_parse_force_tlsv10, 0, 0 }, /* force TLSv10 */
4952 { "force-tlsv11", srv_parse_force_tlsv11, 0, 0 }, /* force TLSv11 */
4953 { "force-tlsv12", srv_parse_force_tlsv12, 0, 0 }, /* force TLSv12 */
Willy Tarreau2a3fb1c2015-02-05 16:47:07 +01004954 { "no-ssl-reuse", srv_parse_no_ssl_reuse, 0, 0 }, /* disable session reuse */
Emeric Brunecc91fe2012-10-11 15:05:10 +02004955 { "no-sslv3", srv_parse_no_sslv3, 0, 0 }, /* disable SSLv3 */
4956 { "no-tlsv10", srv_parse_no_tlsv10, 0, 0 }, /* disable TLSv10 */
4957 { "no-tlsv11", srv_parse_no_tlsv11, 0, 0 }, /* disable TLSv11 */
4958 { "no-tlsv12", srv_parse_no_tlsv12, 0, 0 }, /* disable TLSv12 */
Emeric Brunf9c5c472012-10-11 15:28:34 +02004959 { "no-tls-tickets", srv_parse_no_tls_tickets, 0, 0 }, /* disable session resumption tickets */
David Safb76832014-05-08 23:42:08 -04004960 { "send-proxy-v2-ssl", srv_parse_send_proxy_ssl, 0, 0 }, /* send PROXY protocol header v2 with SSL info */
4961 { "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 +02004962 { "ssl", srv_parse_ssl, 0, 0 }, /* enable SSL processing */
Emeric Brunef42d922012-10-11 16:11:36 +02004963 { "verify", srv_parse_verify, 1, 0 }, /* set SSL verify method */
Evan Broderbe554312013-06-27 00:05:25 -07004964 { "verifyhost", srv_parse_verifyhost, 1, 0 }, /* require that SSL cert verifies for hostname */
Willy Tarreau92faadf2012-10-10 23:04:25 +02004965 { NULL, NULL, 0, 0 },
4966}};
4967
Emeric Brun2c86cbf2014-10-30 15:56:50 +01004968static struct cfg_kw_list cfg_kws = {ILH, {
4969 { CFG_GLOBAL, "ssl-default-bind-options", ssl_parse_default_bind_options },
4970 { CFG_GLOBAL, "ssl-default-server-options", ssl_parse_default_server_options },
4971 { 0, NULL, NULL },
4972}};
4973
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02004974/* transport-layer operations for SSL sockets */
4975struct xprt_ops ssl_sock = {
Emeric Brun46591952012-05-18 15:47:34 +02004976 .snd_buf = ssl_sock_from_buf,
4977 .rcv_buf = ssl_sock_to_buf,
4978 .rcv_pipe = NULL,
4979 .snd_pipe = NULL,
4980 .shutr = NULL,
4981 .shutw = ssl_sock_shutw,
4982 .close = ssl_sock_close,
4983 .init = ssl_sock_init,
4984};
4985
Janusz Dziemidowicz2c701b52015-03-07 23:03:59 +01004986#if (OPENSSL_VERSION_NUMBER >= 0x1000200fL && !defined OPENSSL_NO_TLSEXT && !defined OPENSSL_IS_BORINGSSL)
4987
4988static void ssl_sock_sctl_free_func(void *parent, void *ptr, CRYPTO_EX_DATA *ad, int idx, long argl, void *argp)
4989{
4990 if (ptr) {
4991 chunk_destroy(ptr);
4992 free(ptr);
4993 }
4994}
4995
4996#endif
4997
Emeric Brun46591952012-05-18 15:47:34 +02004998__attribute__((constructor))
Willy Tarreau92faadf2012-10-10 23:04:25 +02004999static void __ssl_sock_init(void)
5000{
Emeric Brun46591952012-05-18 15:47:34 +02005001 STACK_OF(SSL_COMP)* cm;
5002
Willy Tarreau610f04b2014-02-13 11:36:41 +01005003#ifdef LISTEN_DEFAULT_CIPHERS
5004 global.listen_default_ciphers = LISTEN_DEFAULT_CIPHERS;
5005#endif
5006#ifdef CONNECT_DEFAULT_CIPHERS
5007 global.connect_default_ciphers = CONNECT_DEFAULT_CIPHERS;
5008#endif
5009 if (global.listen_default_ciphers)
5010 global.listen_default_ciphers = strdup(global.listen_default_ciphers);
5011 if (global.connect_default_ciphers)
5012 global.connect_default_ciphers = strdup(global.connect_default_ciphers);
Emeric Brun2c86cbf2014-10-30 15:56:50 +01005013 global.listen_default_ssloptions = BC_SSL_O_NONE;
5014 global.connect_default_ssloptions = SRV_SSL_O_NONE;
Willy Tarreau610f04b2014-02-13 11:36:41 +01005015
Emeric Brun46591952012-05-18 15:47:34 +02005016 SSL_library_init();
5017 cm = SSL_COMP_get_compression_methods();
5018 sk_SSL_COMP_zero(cm);
Janusz Dziemidowicz2c701b52015-03-07 23:03:59 +01005019#if (OPENSSL_VERSION_NUMBER >= 0x1000200fL && !defined OPENSSL_NO_TLSEXT && !defined OPENSSL_IS_BORINGSSL)
5020 sctl_ex_index = SSL_CTX_get_ex_new_index(0, NULL, NULL, NULL, ssl_sock_sctl_free_func);
5021#endif
Willy Tarreau7875d092012-09-10 08:20:03 +02005022 sample_register_fetches(&sample_fetch_keywords);
5023 acl_register_keywords(&acl_kws);
Willy Tarreau79eeafa2012-09-14 07:53:05 +02005024 bind_register_keywords(&bind_kws);
Willy Tarreau92faadf2012-10-10 23:04:25 +02005025 srv_register_keywords(&srv_kws);
Emeric Brun2c86cbf2014-10-30 15:56:50 +01005026 cfg_register_keywords(&cfg_kws);
Willy Tarreaud92aa5c2015-01-15 21:34:39 +01005027
5028 global.ssl_session_max_cost = SSL_SESSION_MAX_COST;
5029 global.ssl_handshake_max_cost = SSL_HANDSHAKE_MAX_COST;
Emeric Brun46591952012-05-18 15:47:34 +02005030}
5031
5032/*
5033 * Local variables:
5034 * c-indent-level: 8
5035 * c-basic-offset: 8
5036 * End:
5037 */