blob: 3bd6fa25491c62d50af7189fee848d754ba3bb84 [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
Remi Gacogne4f902b82015-05-28 16:23:00 +020050#ifndef OPENSSL_NO_DH
51#include <openssl/dh.h>
52#endif
Emeric Brun46591952012-05-18 15:47:34 +020053
54#include <common/buffer.h>
55#include <common/compat.h>
56#include <common/config.h>
57#include <common/debug.h>
Willy Tarreau79eeafa2012-09-14 07:53:05 +020058#include <common/errors.h>
Emeric Brun46591952012-05-18 15:47:34 +020059#include <common/standard.h>
60#include <common/ticks.h>
61#include <common/time.h>
Emeric Brun2c86cbf2014-10-30 15:56:50 +010062#include <common/cfgparse.h>
Nenad Merdanovic05552d42015-02-27 19:56:49 +010063#include <common/base64.h>
Emeric Brun46591952012-05-18 15:47:34 +020064
Emeric Brunfc0421f2012-09-07 17:30:07 +020065#include <ebsttree.h>
66
67#include <types/global.h>
68#include <types/ssl_sock.h>
69
Willy Tarreau7875d092012-09-10 08:20:03 +020070#include <proto/acl.h>
71#include <proto/arg.h>
Emeric Brun46591952012-05-18 15:47:34 +020072#include <proto/connection.h>
73#include <proto/fd.h>
74#include <proto/freq_ctr.h>
75#include <proto/frontend.h>
Willy Tarreau79eeafa2012-09-14 07:53:05 +020076#include <proto/listener.h>
Thierry FOURNIERed66c292013-11-28 11:05:19 +010077#include <proto/pattern.h>
Willy Tarreau92faadf2012-10-10 23:04:25 +020078#include <proto/server.h>
Emeric Brun46591952012-05-18 15:47:34 +020079#include <proto/log.h>
Emeric Brun94324a42012-10-11 14:00:19 +020080#include <proto/proxy.h>
Emeric Brunfc0421f2012-09-07 17:30:07 +020081#include <proto/shctx.h>
Emeric Brun46591952012-05-18 15:47:34 +020082#include <proto/ssl_sock.h>
Willy Tarreau9ad7bd42015-04-03 19:19:59 +020083#include <proto/stream.h>
Emeric Brun46591952012-05-18 15:47:34 +020084#include <proto/task.h>
85
Willy Tarreau518cedd2014-02-17 15:43:01 +010086/* Warning, these are bits, not integers! */
Emeric Brune64aef12012-09-21 13:15:06 +020087#define SSL_SOCK_ST_FL_VERIFY_DONE 0x00000001
Emeric Brund8b2bb52014-01-28 15:43:53 +010088#define SSL_SOCK_ST_FL_16K_WBFSIZE 0x00000002
Willy Tarreau518cedd2014-02-17 15:43:01 +010089#define SSL_SOCK_SEND_UNLIMITED 0x00000004
Emeric Brun29f037d2014-04-25 19:05:36 +020090#define SSL_SOCK_RECV_HEARTBEAT 0x00000008
91
Emeric Brunf282a812012-09-21 15:27:54 +020092/* bits 0xFFFF0000 are reserved to store verify errors */
93
94/* Verify errors macros */
95#define SSL_SOCK_CA_ERROR_TO_ST(e) (((e > 63) ? 63 : e) << (16))
96#define SSL_SOCK_CAEDEPTH_TO_ST(d) (((d > 15) ? 15 : d) << (6+16))
97#define SSL_SOCK_CRTERROR_TO_ST(e) (((e > 63) ? 63 : e) << (4+6+16))
98
99#define SSL_SOCK_ST_TO_CA_ERROR(s) ((s >> (16)) & 63)
100#define SSL_SOCK_ST_TO_CAEDEPTH(s) ((s >> (6+16)) & 15)
101#define SSL_SOCK_ST_TO_CRTERROR(s) ((s >> (4+6+16)) & 63)
Emeric Brune64aef12012-09-21 13:15:06 +0200102
Nenad Merdanovic05552d42015-02-27 19:56:49 +0100103/* Supported hash function for TLS tickets */
104#ifdef OPENSSL_NO_SHA256
105#define HASH_FUNCT EVP_sha1
106#else
107#define HASH_FUNCT EVP_sha256
108#endif /* OPENSSL_NO_SHA256 */
109
Emeric Brun850efd52014-01-29 12:24:34 +0100110/* server and bind verify method, it uses a global value as default */
111enum {
112 SSL_SOCK_VERIFY_DEFAULT = 0,
113 SSL_SOCK_VERIFY_REQUIRED = 1,
114 SSL_SOCK_VERIFY_OPTIONAL = 2,
115 SSL_SOCK_VERIFY_NONE = 3,
116};
117
Willy Tarreau71b734c2014-01-28 15:19:44 +0100118int sslconns = 0;
119int totalsslconns = 0;
Emeric Brune1f38db2012-09-03 20:36:47 +0200120
Nenad Merdanovic200b0fa2015-05-09 08:46:01 +0200121#if (defined SSL_CTRL_SET_TLSEXT_TICKET_KEY_CB && TLS_TICKETS_NO > 0)
122struct list tlskeys_reference = LIST_HEAD_INIT(tlskeys_reference);
123#endif
124
Remi Gacogne8de54152014-07-15 11:36:40 +0200125#ifndef OPENSSL_NO_DH
Remi Gacogne4f902b82015-05-28 16:23:00 +0200126static int ssl_dh_ptr_index = -1;
Remi Gacogne47783ef2015-05-29 15:53:22 +0200127static DH *global_dh = NULL;
Remi Gacogne8de54152014-07-15 11:36:40 +0200128static DH *local_dh_1024 = NULL;
129static DH *local_dh_2048 = NULL;
130static DH *local_dh_4096 = NULL;
Remi Gacogne8de54152014-07-15 11:36:40 +0200131#endif /* OPENSSL_NO_DH */
132
Lukas Tribuse4e30f72014-12-09 16:32:51 +0100133#if (defined SSL_CTRL_SET_TLSEXT_STATUS_REQ_CB && !defined OPENSSL_NO_OCSP)
Emeric Brun4147b2e2014-06-16 18:36:30 +0200134struct certificate_ocsp {
135 struct ebmb_node key;
136 unsigned char key_data[OCSP_MAX_CERTID_ASN1_LENGTH];
137 struct chunk response;
Emeric Brun4f3c87a2014-06-20 15:46:13 +0200138 long expire;
Emeric Brun4147b2e2014-06-16 18:36:30 +0200139};
140
Emeric Brun4f3c87a2014-06-20 15:46:13 +0200141/*
142 * This function returns the number of seconds elapsed
143 * since the Epoch, 1970-01-01 00:00:00 +0000 (UTC) and the
144 * date presented un ASN1_GENERALIZEDTIME.
145 *
146 * In parsing error case, it returns -1.
147 */
148static long asn1_generalizedtime_to_epoch(ASN1_GENERALIZEDTIME *d)
149{
150 long epoch;
151 char *p, *end;
152 const unsigned short month_offset[12] = {
153 0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334
154 };
155 int year, month;
156
157 if (!d || (d->type != V_ASN1_GENERALIZEDTIME)) return -1;
158
159 p = (char *)d->data;
160 end = p + d->length;
161
162 if (end - p < 4) return -1;
163 year = 1000 * (p[0] - '0') + 100 * (p[1] - '0') + 10 * (p[2] - '0') + p[3] - '0';
164 p += 4;
165 if (end - p < 2) return -1;
166 month = 10 * (p[0] - '0') + p[1] - '0';
167 if (month < 1 || month > 12) return -1;
168 /* Compute the number of seconds since 1 jan 1970 and the beginning of current month
169 We consider leap years and the current month (<marsh or not) */
170 epoch = ( ((year - 1970) * 365)
171 + ((year - (month < 3)) / 4 - (year - (month < 3)) / 100 + (year - (month < 3)) / 400)
172 - ((1970 - 1) / 4 - (1970 - 1) / 100 + (1970 - 1) / 400)
173 + month_offset[month-1]
174 ) * 24 * 60 * 60;
175 p += 2;
176 if (end - p < 2) return -1;
177 /* Add the number of seconds of completed days of current month */
178 epoch += (10 * (p[0] - '0') + p[1] - '0' - 1) * 24 * 60 * 60;
179 p += 2;
180 if (end - p < 2) return -1;
181 /* Add the completed hours of the current day */
182 epoch += (10 * (p[0] - '0') + p[1] - '0') * 60 * 60;
183 p += 2;
184 if (end - p < 2) return -1;
185 /* Add the completed minutes of the current hour */
186 epoch += (10 * (p[0] - '0') + p[1] - '0') * 60;
187 p += 2;
188 if (p == end) return -1;
189 /* Test if there is available seconds */
190 if (p[0] < '0' || p[0] > '9')
191 goto nosec;
192 if (end - p < 2) return -1;
193 /* Add the seconds of the current minute */
194 epoch += 10 * (p[0] - '0') + p[1] - '0';
195 p += 2;
196 if (p == end) return -1;
197 /* Ignore seconds float part if present */
198 if (p[0] == '.') {
199 do {
200 if (++p == end) return -1;
201 } while (p[0] >= '0' && p[0] <= '9');
202 }
203
204nosec:
205 if (p[0] == 'Z') {
206 if (end - p != 1) return -1;
207 return epoch;
208 }
209 else if (p[0] == '+') {
210 if (end - p != 5) return -1;
211 /* Apply timezone offset */
212 return epoch - ((10 * (p[1] - '0') + p[2] - '0') * 60 + (10 * (p[3] - '0') + p[4] - '0')) * 60;
213 }
214 else if (p[0] == '-') {
215 if (end - p != 5) return -1;
216 /* Apply timezone offset */
217 return epoch + ((10 * (p[1] - '0') + p[2] - '0') * 60 + (10 * (p[3] - '0') + p[4] - '0')) * 60;
218 }
219
220 return -1;
221}
222
Emeric Brun1d3865b2014-06-20 15:37:32 +0200223static struct eb_root cert_ocsp_tree = EB_ROOT_UNIQUE;
Emeric Brun4147b2e2014-06-16 18:36:30 +0200224
225/* This function starts to check if the OCSP response (in DER format) contained
226 * in chunk 'ocsp_response' is valid (else exits on error).
227 * If 'cid' is not NULL, it will be compared to the OCSP certificate ID
228 * contained in the OCSP Response and exits on error if no match.
229 * If it's a valid OCSP Response:
230 * If 'ocsp' is not NULL, the chunk is copied in the OCSP response's container
231 * pointed by 'ocsp'.
232 * If 'ocsp' is NULL, the function looks up into the OCSP response's
233 * containers tree (using as index the ASN1 form of the OCSP Certificate ID extracted
234 * from the response) and exits on error if not found. Finally, If an OCSP response is
235 * already present in the container, it will be overwritten.
236 *
237 * Note: OCSP response containing more than one OCSP Single response is not
238 * considered valid.
239 *
240 * Returns 0 on success, 1 in error case.
241 */
242static int ssl_sock_load_ocsp_response(struct chunk *ocsp_response, struct certificate_ocsp *ocsp, OCSP_CERTID *cid, char **err)
243{
244 OCSP_RESPONSE *resp;
245 OCSP_BASICRESP *bs = NULL;
246 OCSP_SINGLERESP *sr;
247 unsigned char *p = (unsigned char *)ocsp_response->str;
248 int rc , count_sr;
Emeric Brun13a6b482014-06-20 15:44:34 +0200249 ASN1_GENERALIZEDTIME *revtime, *thisupd, *nextupd = NULL;
Emeric Brun4147b2e2014-06-16 18:36:30 +0200250 int reason;
251 int ret = 1;
252
253 resp = d2i_OCSP_RESPONSE(NULL, (const unsigned char **)&p, ocsp_response->len);
254 if (!resp) {
255 memprintf(err, "Unable to parse OCSP response");
256 goto out;
257 }
258
259 rc = OCSP_response_status(resp);
260 if (rc != OCSP_RESPONSE_STATUS_SUCCESSFUL) {
261 memprintf(err, "OCSP response status not successful");
262 goto out;
263 }
264
265 bs = OCSP_response_get1_basic(resp);
266 if (!bs) {
267 memprintf(err, "Failed to get basic response from OCSP Response");
268 goto out;
269 }
270
271 count_sr = OCSP_resp_count(bs);
272 if (count_sr > 1) {
273 memprintf(err, "OCSP response ignored because contains multiple single responses (%d)", count_sr);
274 goto out;
275 }
276
277 sr = OCSP_resp_get0(bs, 0);
278 if (!sr) {
279 memprintf(err, "Failed to get OCSP single response");
280 goto out;
281 }
282
283 rc = OCSP_single_get0_status(sr, &reason, &revtime, &thisupd, &nextupd);
284 if (rc != V_OCSP_CERTSTATUS_GOOD) {
285 memprintf(err, "OCSP single response: certificate status not good");
286 goto out;
287 }
288
Emeric Brun13a6b482014-06-20 15:44:34 +0200289 if (!nextupd) {
290 memprintf(err, "OCSP single response: missing nextupdate");
291 goto out;
292 }
293
Emeric Brunc8b27b62014-06-19 14:16:17 +0200294 rc = OCSP_check_validity(thisupd, nextupd, OCSP_MAX_RESPONSE_TIME_SKEW, -1);
Emeric Brun4147b2e2014-06-16 18:36:30 +0200295 if (!rc) {
296 memprintf(err, "OCSP single response: no longer valid.");
297 goto out;
298 }
299
300 if (cid) {
301 if (OCSP_id_cmp(sr->certId, cid)) {
302 memprintf(err, "OCSP single response: Certificate ID does not match certificate and issuer");
303 goto out;
304 }
305 }
306
307 if (!ocsp) {
308 unsigned char key[OCSP_MAX_CERTID_ASN1_LENGTH];
309 unsigned char *p;
310
311 rc = i2d_OCSP_CERTID(sr->certId, NULL);
312 if (!rc) {
313 memprintf(err, "OCSP single response: Unable to encode Certificate ID");
314 goto out;
315 }
316
317 if (rc > OCSP_MAX_CERTID_ASN1_LENGTH) {
318 memprintf(err, "OCSP single response: Certificate ID too long");
319 goto out;
320 }
321
322 p = key;
323 memset(key, 0, OCSP_MAX_CERTID_ASN1_LENGTH);
324 i2d_OCSP_CERTID(sr->certId, &p);
325 ocsp = (struct certificate_ocsp *)ebmb_lookup(&cert_ocsp_tree, key, OCSP_MAX_CERTID_ASN1_LENGTH);
326 if (!ocsp) {
327 memprintf(err, "OCSP single response: Certificate ID does not match any certificate or issuer");
328 goto out;
329 }
330 }
331
332 /* According to comments on "chunk_dup", the
333 previous chunk buffer will be freed */
334 if (!chunk_dup(&ocsp->response, ocsp_response)) {
335 memprintf(err, "OCSP response: Memory allocation error");
336 goto out;
337 }
338
Emeric Brun4f3c87a2014-06-20 15:46:13 +0200339 ocsp->expire = asn1_generalizedtime_to_epoch(nextupd) - OCSP_MAX_RESPONSE_TIME_SKEW;
340
Emeric Brun4147b2e2014-06-16 18:36:30 +0200341 ret = 0;
342out:
343 if (bs)
344 OCSP_BASICRESP_free(bs);
345
346 if (resp)
347 OCSP_RESPONSE_free(resp);
348
349 return ret;
350}
351/*
352 * External function use to update the OCSP response in the OCSP response's
353 * containers tree. The chunk 'ocsp_response' must contain the OCSP response
354 * to update in DER format.
355 *
356 * Returns 0 on success, 1 in error case.
357 */
358int ssl_sock_update_ocsp_response(struct chunk *ocsp_response, char **err)
359{
360 return ssl_sock_load_ocsp_response(ocsp_response, NULL, NULL, err);
361}
362
363/*
364 * This function load the OCSP Resonse in DER format contained in file at
365 * path 'ocsp_path' and call 'ssl_sock_load_ocsp_response'
366 *
367 * Returns 0 on success, 1 in error case.
368 */
369static int ssl_sock_load_ocsp_response_from_file(const char *ocsp_path, struct certificate_ocsp *ocsp, OCSP_CERTID *cid, char **err)
370{
371 int fd = -1;
372 int r = 0;
373 int ret = 1;
374
375 fd = open(ocsp_path, O_RDONLY);
376 if (fd == -1) {
377 memprintf(err, "Error opening OCSP response file");
378 goto end;
379 }
380
381 trash.len = 0;
382 while (trash.len < trash.size) {
383 r = read(fd, trash.str + trash.len, trash.size - trash.len);
384 if (r < 0) {
385 if (errno == EINTR)
386 continue;
387
388 memprintf(err, "Error reading OCSP response from file");
389 goto end;
390 }
391 else if (r == 0) {
392 break;
393 }
394 trash.len += r;
395 }
396
397 close(fd);
398 fd = -1;
399
400 ret = ssl_sock_load_ocsp_response(&trash, ocsp, cid, err);
401end:
402 if (fd != -1)
403 close(fd);
404
405 return ret;
406}
407
Nenad Merdanovic05552d42015-02-27 19:56:49 +0100408#if (defined SSL_CTRL_SET_TLSEXT_TICKET_KEY_CB && TLS_TICKETS_NO > 0)
409static 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)
410{
411 struct tls_sess_key *keys;
412 struct connection *conn;
413 int head;
414 int i;
415
416 conn = (struct connection *)SSL_get_app_data(s);
Nenad Merdanovic146defa2015-05-09 08:46:00 +0200417 keys = objt_listener(conn->target)->bind_conf->keys_ref->tlskeys;
418 head = objt_listener(conn->target)->bind_conf->keys_ref->tls_ticket_enc_index;
Nenad Merdanovic05552d42015-02-27 19:56:49 +0100419
420 if (enc) {
421 memcpy(key_name, keys[head].name, 16);
422
423 if(!RAND_pseudo_bytes(iv, EVP_MAX_IV_LENGTH))
424 return -1;
425
426 if(!EVP_EncryptInit_ex(ectx, EVP_aes_128_cbc(), NULL, keys[head].aes_key, iv))
427 return -1;
428
429 HMAC_Init_ex(hctx, keys[head].hmac_key, 16, HASH_FUNCT(), NULL);
430
431 return 1;
432 } else {
433 for (i = 0; i < TLS_TICKETS_NO; i++) {
434 if (!memcmp(key_name, keys[(head + i) % TLS_TICKETS_NO].name, 16))
435 goto found;
436 }
437 return 0;
438
439 found:
440 HMAC_Init_ex(hctx, keys[(head + i) % TLS_TICKETS_NO].hmac_key, 16, HASH_FUNCT(), NULL);
441 if(!EVP_DecryptInit_ex(ectx, EVP_aes_128_cbc(), NULL, keys[(head + i) % TLS_TICKETS_NO].aes_key, iv))
442 return -1;
443 /* 2 for key renewal, 1 if current key is still valid */
444 return i ? 2 : 1;
445 }
Nenad Merdanovic200b0fa2015-05-09 08:46:01 +0200446}
447
448struct tls_keys_ref *tlskeys_ref_lookup(const char *filename)
449{
450 struct tls_keys_ref *ref;
451
452 list_for_each_entry(ref, &tlskeys_reference, list)
453 if (ref->filename && strcmp(filename, ref->filename) == 0)
454 return ref;
455 return NULL;
456}
457
458struct tls_keys_ref *tlskeys_ref_lookupid(int unique_id)
459{
460 struct tls_keys_ref *ref;
461
462 list_for_each_entry(ref, &tlskeys_reference, list)
463 if (ref->unique_id == unique_id)
464 return ref;
465 return NULL;
466}
467
468int ssl_sock_update_tlskey(char *filename, struct chunk *tlskey, char **err) {
469 struct tls_keys_ref *ref = tlskeys_ref_lookup(filename);
470
471 if(!ref) {
472 memprintf(err, "Unable to locate the referenced filename: %s", filename);
473 return 1;
474 }
475
476 memcpy((char *) (ref->tlskeys + 2 % TLS_TICKETS_NO), tlskey->str, tlskey->len);
477 ref->tls_ticket_enc_index = ref->tls_ticket_enc_index + 1 % TLS_TICKETS_NO;
478
479 return 0;
Nenad Merdanovic05552d42015-02-27 19:56:49 +0100480}
Nenad Merdanovic200b0fa2015-05-09 08:46:01 +0200481
482/* This function finalize the configuration parsing. Its set all the
483 * automatic ids
484 */
485void tlskeys_finalize_config(void)
486{
487 int i = 0;
488 struct tls_keys_ref *ref, *ref2, *ref3;
489 struct list tkr = LIST_HEAD_INIT(tkr);
490
491 list_for_each_entry(ref, &tlskeys_reference, list) {
492 if (ref->unique_id == -1) {
493 /* Look for the first free id. */
494 while (1) {
495 list_for_each_entry(ref2, &tlskeys_reference, list) {
496 if (ref2->unique_id == i) {
497 i++;
498 break;
499 }
500 }
501 if (&ref2->list == &tlskeys_reference)
502 break;
503 }
504
505 /* Uses the unique id and increment it for the next entry. */
506 ref->unique_id = i;
507 i++;
508 }
509 }
510
511 /* This sort the reference list by id. */
512 list_for_each_entry_safe(ref, ref2, &tlskeys_reference, list) {
513 LIST_DEL(&ref->list);
514 list_for_each_entry(ref3, &tkr, list) {
515 if (ref->unique_id < ref3->unique_id) {
516 LIST_ADDQ(&ref3->list, &ref->list);
517 break;
518 }
519 }
520 if (&ref3->list == &tkr)
521 LIST_ADDQ(&tkr, &ref->list);
522 }
523
524 /* swap root */
525 LIST_ADD(&tkr, &tlskeys_reference);
526 LIST_DEL(&tkr);
527}
528
Nenad Merdanovic05552d42015-02-27 19:56:49 +0100529#endif /* SSL_CTRL_SET_TLSEXT_TICKET_KEY_CB */
530
Emeric Brun4147b2e2014-06-16 18:36:30 +0200531/*
532 * Callback used to set OCSP status extension content in server hello.
533 */
534int ssl_sock_ocsp_stapling_cbk(SSL *ssl, void *arg)
535{
536 struct certificate_ocsp *ocsp = (struct certificate_ocsp *)arg;
537 char* ssl_buf;
538
539 if (!ocsp ||
540 !ocsp->response.str ||
Emeric Brun4f3c87a2014-06-20 15:46:13 +0200541 !ocsp->response.len ||
542 (ocsp->expire < now.tv_sec))
Emeric Brun4147b2e2014-06-16 18:36:30 +0200543 return SSL_TLSEXT_ERR_NOACK;
544
545 ssl_buf = OPENSSL_malloc(ocsp->response.len);
546 if (!ssl_buf)
547 return SSL_TLSEXT_ERR_NOACK;
548
549 memcpy(ssl_buf, ocsp->response.str, ocsp->response.len);
550 SSL_set_tlsext_status_ocsp_resp(ssl, ssl_buf, ocsp->response.len);
551
552 return SSL_TLSEXT_ERR_OK;
553}
554
555/*
556 * This function enables the handling of OCSP status extension on 'ctx' if a
557 * file name 'cert_path' suffixed using ".ocsp" is present.
558 * To enable OCSP status extension, the issuer's certificate is mandatory.
559 * It should be present in the certificate's extra chain builded from file
560 * 'cert_path'. If not found, the issuer certificate is loaded from a file
561 * named 'cert_path' suffixed using '.issuer'.
562 *
563 * In addition, ".ocsp" file content is loaded as a DER format of an OCSP
564 * response. If file is empty or content is not a valid OCSP response,
565 * OCSP status extension is enabled but OCSP response is ignored (a warning
566 * is displayed).
567 *
568 * Returns 1 if no ".ocsp" file found, 0 if OCSP status extension is
569 * succesfully enabled, or -1 in other error case.
570 */
571static int ssl_sock_load_ocsp(SSL_CTX *ctx, const char *cert_path)
572{
573
574 BIO *in = NULL;
575 X509 *x, *xi = NULL, *issuer = NULL;
576 STACK_OF(X509) *chain = NULL;
577 OCSP_CERTID *cid = NULL;
578 SSL *ssl;
579 char ocsp_path[MAXPATHLEN+1];
580 int i, ret = -1;
581 struct stat st;
582 struct certificate_ocsp *ocsp = NULL, *iocsp;
583 char *warn = NULL;
584 unsigned char *p;
585
586 snprintf(ocsp_path, MAXPATHLEN+1, "%s.ocsp", cert_path);
587
588 if (stat(ocsp_path, &st))
589 return 1;
590
591 ssl = SSL_new(ctx);
592 if (!ssl)
593 goto out;
594
595 x = SSL_get_certificate(ssl);
596 if (!x)
597 goto out;
598
599 /* Try to lookup for issuer in certificate extra chain */
600#ifdef SSL_CTRL_GET_EXTRA_CHAIN_CERTS
601 SSL_CTX_get_extra_chain_certs(ctx, &chain);
602#else
603 chain = ctx->extra_certs;
604#endif
605 for (i = 0; i < sk_X509_num(chain); i++) {
606 issuer = sk_X509_value(chain, i);
607 if (X509_check_issued(issuer, x) == X509_V_OK)
608 break;
609 else
610 issuer = NULL;
611 }
612
613 /* If not found try to load issuer from a suffixed file */
614 if (!issuer) {
615 char issuer_path[MAXPATHLEN+1];
616
617 in = BIO_new(BIO_s_file());
618 if (!in)
619 goto out;
620
621 snprintf(issuer_path, MAXPATHLEN+1, "%s.issuer", cert_path);
622 if (BIO_read_filename(in, issuer_path) <= 0)
623 goto out;
624
625 xi = PEM_read_bio_X509_AUX(in, NULL, ctx->default_passwd_callback, ctx->default_passwd_callback_userdata);
626 if (!xi)
627 goto out;
628
629 if (X509_check_issued(xi, x) != X509_V_OK)
630 goto out;
631
632 issuer = xi;
633 }
634
635 cid = OCSP_cert_to_id(0, x, issuer);
636 if (!cid)
637 goto out;
638
639 i = i2d_OCSP_CERTID(cid, NULL);
640 if (!i || (i > OCSP_MAX_CERTID_ASN1_LENGTH))
641 goto out;
642
643 ocsp = calloc(1, sizeof(struct certificate_ocsp));
644 if (!ocsp)
645 goto out;
646
647 p = ocsp->key_data;
648 i2d_OCSP_CERTID(cid, &p);
649
650 iocsp = (struct certificate_ocsp *)ebmb_insert(&cert_ocsp_tree, &ocsp->key, OCSP_MAX_CERTID_ASN1_LENGTH);
651 if (iocsp == ocsp)
652 ocsp = NULL;
653
654 SSL_CTX_set_tlsext_status_cb(ctx, ssl_sock_ocsp_stapling_cbk);
655 SSL_CTX_set_tlsext_status_arg(ctx, iocsp);
656
657 ret = 0;
658
659 warn = NULL;
660 if (ssl_sock_load_ocsp_response_from_file(ocsp_path, iocsp, cid, &warn)) {
661 memprintf(&warn, "Loading '%s': %s. Content will be ignored", ocsp_path, warn ? warn : "failure");
662 Warning("%s.\n", warn);
663 }
664
665out:
666 if (ssl)
667 SSL_free(ssl);
668
669 if (in)
670 BIO_free(in);
671
672 if (xi)
673 X509_free(xi);
674
675 if (cid)
676 OCSP_CERTID_free(cid);
677
678 if (ocsp)
679 free(ocsp);
680
681 if (warn)
682 free(warn);
683
684
685 return ret;
686}
687
688#endif
689
Janusz Dziemidowicz2c701b52015-03-07 23:03:59 +0100690#if (OPENSSL_VERSION_NUMBER >= 0x1000200fL && !defined OPENSSL_NO_TLSEXT && !defined OPENSSL_IS_BORINGSSL)
691
692#define CT_EXTENSION_TYPE 18
693
694static int sctl_ex_index = -1;
695
696/*
697 * Try to parse Signed Certificate Timestamp List structure. This function
698 * makes only basic test if the data seems like SCTL. No signature validation
699 * is performed.
700 */
701static int ssl_sock_parse_sctl(struct chunk *sctl)
702{
703 int ret = 1;
704 int len, pos, sct_len;
705 unsigned char *data;
706
707 if (sctl->len < 2)
708 goto out;
709
710 data = (unsigned char *)sctl->str;
711 len = (data[0] << 8) | data[1];
712
713 if (len + 2 != sctl->len)
714 goto out;
715
716 data = data + 2;
717 pos = 0;
718 while (pos < len) {
719 if (len - pos < 2)
720 goto out;
721
722 sct_len = (data[pos] << 8) | data[pos + 1];
723 if (pos + sct_len + 2 > len)
724 goto out;
725
726 pos += sct_len + 2;
727 }
728
729 ret = 0;
730
731out:
732 return ret;
733}
734
735static int ssl_sock_load_sctl_from_file(const char *sctl_path, struct chunk **sctl)
736{
737 int fd = -1;
738 int r = 0;
739 int ret = 1;
740
741 *sctl = NULL;
742
743 fd = open(sctl_path, O_RDONLY);
744 if (fd == -1)
745 goto end;
746
747 trash.len = 0;
748 while (trash.len < trash.size) {
749 r = read(fd, trash.str + trash.len, trash.size - trash.len);
750 if (r < 0) {
751 if (errno == EINTR)
752 continue;
753
754 goto end;
755 }
756 else if (r == 0) {
757 break;
758 }
759 trash.len += r;
760 }
761
762 ret = ssl_sock_parse_sctl(&trash);
763 if (ret)
764 goto end;
765
766 *sctl = calloc(1, sizeof(struct chunk));
767 if (!chunk_dup(*sctl, &trash)) {
768 free(*sctl);
769 *sctl = NULL;
770 goto end;
771 }
772
773end:
774 if (fd != -1)
775 close(fd);
776
777 return ret;
778}
779
780int ssl_sock_sctl_add_cbk(SSL *ssl, unsigned ext_type, const unsigned char **out, size_t *outlen, int *al, void *add_arg)
781{
782 struct chunk *sctl = (struct chunk *)add_arg;
783
784 *out = (unsigned char *)sctl->str;
785 *outlen = sctl->len;
786
787 return 1;
788}
789
790int ssl_sock_sctl_parse_cbk(SSL *s, unsigned int ext_type, const unsigned char *in, size_t inlen, int *al, void *parse_arg)
791{
792 return 1;
793}
794
795static int ssl_sock_load_sctl(SSL_CTX *ctx, const char *cert_path)
796{
797 char sctl_path[MAXPATHLEN+1];
798 int ret = -1;
799 struct stat st;
800 struct chunk *sctl = NULL;
801
802 snprintf(sctl_path, MAXPATHLEN+1, "%s.sctl", cert_path);
803
804 if (stat(sctl_path, &st))
805 return 1;
806
807 if (ssl_sock_load_sctl_from_file(sctl_path, &sctl))
808 goto out;
809
810 if (!SSL_CTX_add_server_custom_ext(ctx, CT_EXTENSION_TYPE, ssl_sock_sctl_add_cbk, NULL, sctl, ssl_sock_sctl_parse_cbk, NULL)) {
811 free(sctl);
812 goto out;
813 }
814
815 SSL_CTX_set_ex_data(ctx, sctl_ex_index, sctl);
816
817 ret = 0;
818
819out:
820 return ret;
821}
822
823#endif
824
Emeric Brune1f38db2012-09-03 20:36:47 +0200825void ssl_sock_infocbk(const SSL *ssl, int where, int ret)
826{
827 struct connection *conn = (struct connection *)SSL_get_app_data(ssl);
Emeric Brund8b2bb52014-01-28 15:43:53 +0100828 BIO *write_bio;
Willy Tarreau622317d2015-02-27 16:36:16 +0100829 (void)ret; /* shut gcc stupid warning */
Emeric Brune1f38db2012-09-03 20:36:47 +0200830
831 if (where & SSL_CB_HANDSHAKE_START) {
832 /* Disable renegotiation (CVE-2009-3555) */
Willy Tarreau20879a02012-12-03 16:32:10 +0100833 if (conn->flags & CO_FL_CONNECTED) {
Emeric Brune1f38db2012-09-03 20:36:47 +0200834 conn->flags |= CO_FL_ERROR;
Willy Tarreau20879a02012-12-03 16:32:10 +0100835 conn->err_code = CO_ER_SSL_RENEG;
836 }
Emeric Brune1f38db2012-09-03 20:36:47 +0200837 }
Emeric Brund8b2bb52014-01-28 15:43:53 +0100838
839 if ((where & SSL_CB_ACCEPT_LOOP) == SSL_CB_ACCEPT_LOOP) {
840 if (!(conn->xprt_st & SSL_SOCK_ST_FL_16K_WBFSIZE)) {
841 /* Long certificate chains optimz
842 If write and read bios are differents, we
843 consider that the buffering was activated,
844 so we rise the output buffer size from 4k
845 to 16k */
846 write_bio = SSL_get_wbio(ssl);
847 if (write_bio != SSL_get_rbio(ssl)) {
848 BIO_set_write_buffer_size(write_bio, 16384);
849 conn->xprt_st |= SSL_SOCK_ST_FL_16K_WBFSIZE;
850 }
851 }
852 }
Emeric Brunfc0421f2012-09-07 17:30:07 +0200853}
854
Emeric Brune64aef12012-09-21 13:15:06 +0200855/* Callback is called for each certificate of the chain during a verify
856 ok is set to 1 if preverify detect no error on current certificate.
857 Returns 0 to break the handshake, 1 otherwise. */
Evan Broderbe554312013-06-27 00:05:25 -0700858int ssl_sock_bind_verifycbk(int ok, X509_STORE_CTX *x_store)
Emeric Brune64aef12012-09-21 13:15:06 +0200859{
860 SSL *ssl;
861 struct connection *conn;
Emeric Brun81c00f02012-09-21 14:31:21 +0200862 int err, depth;
Emeric Brune64aef12012-09-21 13:15:06 +0200863
864 ssl = X509_STORE_CTX_get_ex_data(x_store, SSL_get_ex_data_X509_STORE_CTX_idx());
865 conn = (struct connection *)SSL_get_app_data(ssl);
866
Willy Tarreauf7bc57c2012-10-03 00:19:48 +0200867 conn->xprt_st |= SSL_SOCK_ST_FL_VERIFY_DONE;
Emeric Brune64aef12012-09-21 13:15:06 +0200868
Emeric Brun81c00f02012-09-21 14:31:21 +0200869 if (ok) /* no errors */
870 return ok;
871
872 depth = X509_STORE_CTX_get_error_depth(x_store);
873 err = X509_STORE_CTX_get_error(x_store);
874
875 /* check if CA error needs to be ignored */
876 if (depth > 0) {
Willy Tarreauf7bc57c2012-10-03 00:19:48 +0200877 if (!SSL_SOCK_ST_TO_CA_ERROR(conn->xprt_st)) {
878 conn->xprt_st |= SSL_SOCK_CA_ERROR_TO_ST(err);
879 conn->xprt_st |= SSL_SOCK_CAEDEPTH_TO_ST(depth);
Emeric Brunf282a812012-09-21 15:27:54 +0200880 }
881
Emeric Brun1eb20ef2012-12-03 13:24:29 +0100882 if (objt_listener(conn->target)->bind_conf->ca_ignerr & (1ULL << err)) {
883 ERR_clear_error();
Emeric Brun81c00f02012-09-21 14:31:21 +0200884 return 1;
Emeric Brun1eb20ef2012-12-03 13:24:29 +0100885 }
Emeric Brun81c00f02012-09-21 14:31:21 +0200886
Willy Tarreau20879a02012-12-03 16:32:10 +0100887 conn->err_code = CO_ER_SSL_CA_FAIL;
Emeric Brun81c00f02012-09-21 14:31:21 +0200888 return 0;
889 }
890
Willy Tarreauf7bc57c2012-10-03 00:19:48 +0200891 if (!SSL_SOCK_ST_TO_CRTERROR(conn->xprt_st))
892 conn->xprt_st |= SSL_SOCK_CRTERROR_TO_ST(err);
Emeric Brunf282a812012-09-21 15:27:54 +0200893
Emeric Brun81c00f02012-09-21 14:31:21 +0200894 /* check if certificate error needs to be ignored */
Emeric Brun1eb20ef2012-12-03 13:24:29 +0100895 if (objt_listener(conn->target)->bind_conf->crt_ignerr & (1ULL << err)) {
896 ERR_clear_error();
Emeric Brun81c00f02012-09-21 14:31:21 +0200897 return 1;
Emeric Brun1eb20ef2012-12-03 13:24:29 +0100898 }
Emeric Brun81c00f02012-09-21 14:31:21 +0200899
Willy Tarreau20879a02012-12-03 16:32:10 +0100900 conn->err_code = CO_ER_SSL_CRT_FAIL;
Emeric Brun81c00f02012-09-21 14:31:21 +0200901 return 0;
Emeric Brune64aef12012-09-21 13:15:06 +0200902}
903
Emeric Brun29f037d2014-04-25 19:05:36 +0200904/* Callback is called for ssl protocol analyse */
905void ssl_sock_msgcbk(int write_p, int version, int content_type, const void *buf, size_t len, SSL *ssl, void *arg)
906{
Emeric Brun29f037d2014-04-25 19:05:36 +0200907#ifdef TLS1_RT_HEARTBEAT
908 /* test heartbeat received (write_p is set to 0
909 for a received record) */
Willy Tarreauf51c6982014-04-25 20:02:39 +0200910 if ((content_type == TLS1_RT_HEARTBEAT) && (write_p == 0)) {
Willy Tarreau84815002014-04-25 21:40:27 +0200911 struct connection *conn = (struct connection *)SSL_get_app_data(ssl);
Willy Tarreauf51c6982014-04-25 20:02:39 +0200912 const unsigned char *p = buf;
913 unsigned int payload;
914
Emeric Brun29f037d2014-04-25 19:05:36 +0200915 conn->xprt_st |= SSL_SOCK_RECV_HEARTBEAT;
Willy Tarreauf51c6982014-04-25 20:02:39 +0200916
917 /* Check if this is a CVE-2014-0160 exploitation attempt. */
918 if (*p != TLS1_HB_REQUEST)
919 return;
920
Willy Tarreauaeed6722014-04-25 23:59:58 +0200921 if (len < 1 + 2 + 16) /* 1 type + 2 size + 0 payload + 16 padding */
Willy Tarreauf51c6982014-04-25 20:02:39 +0200922 goto kill_it;
923
924 payload = (p[1] * 256) + p[2];
Willy Tarreau3b2fdb62014-04-25 23:44:22 +0200925 if (3 + payload + 16 <= len)
Willy Tarreauf51c6982014-04-25 20:02:39 +0200926 return; /* OK no problem */
Willy Tarreauaeed6722014-04-25 23:59:58 +0200927 kill_it:
Willy Tarreau3b2fdb62014-04-25 23:44:22 +0200928 /* We have a clear heartbleed attack (CVE-2014-0160), the
929 * advertised payload is larger than the advertised packet
930 * length, so we have garbage in the buffer between the
931 * payload and the end of the buffer (p+len). We can't know
932 * if the SSL stack is patched, and we don't know if we can
933 * safely wipe out the area between p+3+len and payload.
934 * So instead, we prevent the response from being sent by
935 * setting the max_send_fragment to 0 and we report an SSL
936 * error, which will kill this connection. It will be reported
937 * above as SSL_ERROR_SSL while an other handshake failure with
Willy Tarreauf51c6982014-04-25 20:02:39 +0200938 * a heartbeat message will be reported as SSL_ERROR_SYSCALL.
939 */
Willy Tarreau3b2fdb62014-04-25 23:44:22 +0200940 ssl->max_send_fragment = 0;
Willy Tarreauf51c6982014-04-25 20:02:39 +0200941 SSLerr(SSL_F_TLS1_HEARTBEAT, SSL_R_SSL_HANDSHAKE_FAILURE);
942 return;
943 }
Emeric Brun29f037d2014-04-25 19:05:36 +0200944#endif
945}
946
Willy Tarreau6c9a3d52012-10-18 18:57:14 +0200947#ifdef OPENSSL_NPN_NEGOTIATED
948/* This callback is used so that the server advertises the list of
949 * negociable protocols for NPN.
950 */
951static int ssl_sock_advertise_npn_protos(SSL *s, const unsigned char **data,
952 unsigned int *len, void *arg)
953{
954 struct bind_conf *conf = arg;
955
956 *data = (const unsigned char *)conf->npn_str;
957 *len = conf->npn_len;
958 return SSL_TLSEXT_ERR_OK;
959}
960#endif
961
Dirkjan Bussink48f1c4e2014-02-13 12:29:42 +0100962#ifdef TLSEXT_TYPE_application_layer_protocol_negotiation
Willy Tarreauab861d32013-04-02 02:30:41 +0200963/* This callback is used so that the server advertises the list of
964 * negociable protocols for ALPN.
965 */
Dirkjan Bussink48f1c4e2014-02-13 12:29:42 +0100966static int ssl_sock_advertise_alpn_protos(SSL *s, const unsigned char **out,
967 unsigned char *outlen,
968 const unsigned char *server,
969 unsigned int server_len, void *arg)
Willy Tarreauab861d32013-04-02 02:30:41 +0200970{
971 struct bind_conf *conf = arg;
972
Dirkjan Bussink48f1c4e2014-02-13 12:29:42 +0100973 if (SSL_select_next_proto((unsigned char**) out, outlen, (const unsigned char *)conf->alpn_str,
974 conf->alpn_len, server, server_len) != OPENSSL_NPN_NEGOTIATED) {
975 return SSL_TLSEXT_ERR_NOACK;
976 }
Willy Tarreauab861d32013-04-02 02:30:41 +0200977 return SSL_TLSEXT_ERR_OK;
978}
979#endif
980
Emeric Brunfc0421f2012-09-07 17:30:07 +0200981#ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME
982/* Sets the SSL ctx of <ssl> to match the advertised server name. Returns a
983 * warning when no match is found, which implies the default (first) cert
984 * will keep being used.
985 */
Willy Tarreau2a65ff02012-09-13 17:54:29 +0200986static int ssl_sock_switchctx_cbk(SSL *ssl, int *al, struct bind_conf *s)
Emeric Brunfc0421f2012-09-07 17:30:07 +0200987{
988 const char *servername;
989 const char *wildp = NULL;
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +0200990 struct ebmb_node *node, *n;
Emeric Brunfc0421f2012-09-07 17:30:07 +0200991 int i;
992 (void)al; /* shut gcc stupid warning */
993
994 servername = SSL_get_servername(ssl, TLSEXT_NAMETYPE_host_name);
Emmanuel Hocdet65623372013-01-24 17:17:15 +0100995 if (!servername) {
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +0200996 return (s->strict_sni ?
997 SSL_TLSEXT_ERR_ALERT_FATAL :
Emmanuel Hocdet79274e22013-05-31 12:47:44 +0200998 SSL_TLSEXT_ERR_NOACK);
Emmanuel Hocdet65623372013-01-24 17:17:15 +0100999 }
Emeric Brunfc0421f2012-09-07 17:30:07 +02001000
Willy Tarreau19d14ef2012-10-29 16:51:55 +01001001 for (i = 0; i < trash.size; i++) {
Emeric Brunfc0421f2012-09-07 17:30:07 +02001002 if (!servername[i])
1003 break;
Willy Tarreau19d14ef2012-10-29 16:51:55 +01001004 trash.str[i] = tolower(servername[i]);
1005 if (!wildp && (trash.str[i] == '.'))
1006 wildp = &trash.str[i];
Emeric Brunfc0421f2012-09-07 17:30:07 +02001007 }
Willy Tarreau19d14ef2012-10-29 16:51:55 +01001008 trash.str[i] = 0;
Emeric Brunfc0421f2012-09-07 17:30:07 +02001009
1010 /* lookup in full qualified names */
Willy Tarreau19d14ef2012-10-29 16:51:55 +01001011 node = ebst_lookup(&s->sni_ctx, trash.str);
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +02001012
1013 /* lookup a not neg filter */
1014 for (n = node; n; n = ebmb_next_dup(n)) {
1015 if (!container_of(n, struct sni_ctx, name)->neg) {
1016 node = n;
1017 break;
Emmanuel Hocdet65623372013-01-24 17:17:15 +01001018 }
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +02001019 }
1020 if (!node && wildp) {
1021 /* lookup in wildcards names */
Emeric Brunfc0421f2012-09-07 17:30:07 +02001022 node = ebst_lookup(&s->sni_w_ctx, wildp);
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +02001023 }
1024 if (!node || container_of(node, struct sni_ctx, name)->neg) {
1025 return (s->strict_sni ?
1026 SSL_TLSEXT_ERR_ALERT_FATAL :
1027 SSL_TLSEXT_ERR_ALERT_WARNING);
Emeric Brunfc0421f2012-09-07 17:30:07 +02001028 }
1029
1030 /* switch ctx */
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +02001031 SSL_set_SSL_CTX(ssl, container_of(node, struct sni_ctx, name)->ctx);
Emeric Brunfc0421f2012-09-07 17:30:07 +02001032 return SSL_TLSEXT_ERR_OK;
1033}
1034#endif /* SSL_CTRL_SET_TLSEXT_HOSTNAME */
1035
Emeric Bruna4bcd9a2012-09-20 16:19:02 +02001036#ifndef OPENSSL_NO_DH
Remi Gacognef46cd6e2014-06-12 14:58:40 +02001037
1038static DH * ssl_get_dh_1024(void)
1039{
Remi Gacogned3a341a2015-05-29 16:26:17 +02001040 static unsigned char dh1024_p[]={
1041 0xFA,0xF9,0x2A,0x22,0x2A,0xA7,0x7F,0xE1,0x67,0x4E,0x53,0xF7,
1042 0x56,0x13,0xC3,0xB1,0xE3,0x29,0x6B,0x66,0x31,0x6A,0x7F,0xB3,
1043 0xC2,0x68,0x6B,0xCB,0x1D,0x57,0x39,0x1D,0x1F,0xFF,0x1C,0xC9,
1044 0xA6,0xA4,0x98,0x82,0x31,0x5D,0x25,0xFF,0x8A,0xE0,0x73,0x96,
1045 0x81,0xC8,0x83,0x79,0xC1,0x5A,0x04,0xF8,0x37,0x0D,0xA8,0x3D,
1046 0xAE,0x74,0xBC,0xDB,0xB6,0xA4,0x75,0xD9,0x71,0x8A,0xA0,0x17,
1047 0x9E,0x2D,0xC8,0xA8,0xDF,0x2C,0x5F,0x82,0x95,0xF8,0x92,0x9B,
1048 0xA7,0x33,0x5F,0x89,0x71,0xC8,0x2D,0x6B,0x18,0x86,0xC4,0x94,
1049 0x22,0xA5,0x52,0x8D,0xF6,0xF6,0xD2,0x37,0x92,0x0F,0xA5,0xCC,
1050 0xDB,0x7B,0x1D,0x3D,0xA1,0x31,0xB7,0x80,0x8F,0x0B,0x67,0x5E,
1051 0x36,0xA5,0x60,0x0C,0xF1,0x95,0x33,0x8B,
1052 };
1053 static unsigned char dh1024_g[]={
1054 0x02,
1055 };
1056
Remi Gacognef46cd6e2014-06-12 14:58:40 +02001057 DH *dh = DH_new();
1058 if (dh) {
Remi Gacogned3a341a2015-05-29 16:26:17 +02001059 dh->p = BN_bin2bn(dh1024_p, sizeof dh1024_p, NULL);
1060 dh->g = BN_bin2bn(dh1024_g, sizeof dh1024_g, NULL);
1061
Remi Gacognef46cd6e2014-06-12 14:58:40 +02001062 if (!dh->p || !dh->g) {
1063 DH_free(dh);
1064 dh = NULL;
1065 }
1066 }
1067 return dh;
1068}
1069
1070static DH *ssl_get_dh_2048(void)
1071{
Remi Gacogned3a341a2015-05-29 16:26:17 +02001072 static unsigned char dh2048_p[]={
1073 0xEC,0x86,0xF8,0x70,0xA0,0x33,0x16,0xEC,0x05,0x1A,0x73,0x59,
1074 0xCD,0x1F,0x8B,0xF8,0x29,0xE4,0xD2,0xCF,0x52,0xDD,0xC2,0x24,
1075 0x8D,0xB5,0x38,0x9A,0xFB,0x5C,0xA4,0xE4,0xB2,0xDA,0xCE,0x66,
1076 0x50,0x74,0xA6,0x85,0x4D,0x4B,0x1D,0x30,0xB8,0x2B,0xF3,0x10,
1077 0xE9,0xA7,0x2D,0x05,0x71,0xE7,0x81,0xDF,0x8B,0x59,0x52,0x3B,
1078 0x5F,0x43,0x0B,0x68,0xF1,0xDB,0x07,0xBE,0x08,0x6B,0x1B,0x23,
1079 0xEE,0x4D,0xCC,0x9E,0x0E,0x43,0xA0,0x1E,0xDF,0x43,0x8C,0xEC,
1080 0xBE,0xBE,0x90,0xB4,0x51,0x54,0xB9,0x2F,0x7B,0x64,0x76,0x4E,
1081 0x5D,0xD4,0x2E,0xAE,0xC2,0x9E,0xAE,0x51,0x43,0x59,0xC7,0x77,
1082 0x9C,0x50,0x3C,0x0E,0xED,0x73,0x04,0x5F,0xF1,0x4C,0x76,0x2A,
1083 0xD8,0xF8,0xCF,0xFC,0x34,0x40,0xD1,0xB4,0x42,0x61,0x84,0x66,
1084 0x42,0x39,0x04,0xF8,0x68,0xB2,0x62,0xD7,0x55,0xED,0x1B,0x74,
1085 0x75,0x91,0xE0,0xC5,0x69,0xC1,0x31,0x5C,0xDB,0x7B,0x44,0x2E,
1086 0xCE,0x84,0x58,0x0D,0x1E,0x66,0x0C,0xC8,0x44,0x9E,0xFD,0x40,
1087 0x08,0x67,0x5D,0xFB,0xA7,0x76,0x8F,0x00,0x11,0x87,0xE9,0x93,
1088 0xF9,0x7D,0xC4,0xBC,0x74,0x55,0x20,0xD4,0x4A,0x41,0x2F,0x43,
1089 0x42,0x1A,0xC1,0xF2,0x97,0x17,0x49,0x27,0x37,0x6B,0x2F,0x88,
1090 0x7E,0x1C,0xA0,0xA1,0x89,0x92,0x27,0xD9,0x56,0x5A,0x71,0xC1,
1091 0x56,0x37,0x7E,0x3A,0x9D,0x05,0xE7,0xEE,0x5D,0x8F,0x82,0x17,
1092 0xBC,0xE9,0xC2,0x93,0x30,0x82,0xF9,0xF4,0xC9,0xAE,0x49,0xDB,
1093 0xD0,0x54,0xB4,0xD9,0x75,0x4D,0xFA,0x06,0xB8,0xD6,0x38,0x41,
1094 0xB7,0x1F,0x77,0xF3,
1095 };
1096 static unsigned char dh2048_g[]={
1097 0x02,
1098 };
1099
Remi Gacognef46cd6e2014-06-12 14:58:40 +02001100 DH *dh = DH_new();
1101 if (dh) {
Remi Gacogned3a341a2015-05-29 16:26:17 +02001102 dh->p = BN_bin2bn(dh2048_p, sizeof dh2048_p, NULL);
1103 dh->g = BN_bin2bn(dh2048_g, sizeof dh2048_g, NULL);
1104
Remi Gacognef46cd6e2014-06-12 14:58:40 +02001105 if (!dh->p || !dh->g) {
1106 DH_free(dh);
1107 dh = NULL;
1108 }
1109 }
1110 return dh;
1111}
1112
1113static DH *ssl_get_dh_4096(void)
1114{
Remi Gacogned3a341a2015-05-29 16:26:17 +02001115 static unsigned char dh4096_p[]={
1116 0xDE,0x16,0x94,0xCD,0x99,0x58,0x07,0xF1,0xF7,0x32,0x96,0x11,
1117 0x04,0x82,0xD4,0x84,0x72,0x80,0x99,0x06,0xCA,0xF0,0xA3,0x68,
1118 0x07,0xCE,0x64,0x50,0xE7,0x74,0x45,0x20,0x80,0x5E,0x4D,0xAD,
1119 0xA5,0xB6,0xED,0xFA,0x80,0x6C,0x3B,0x35,0xC4,0x9A,0x14,0x6B,
1120 0x32,0xBB,0xFD,0x1F,0x17,0x8E,0xB7,0x1F,0xD6,0xFA,0x3F,0x7B,
1121 0xEE,0x16,0xA5,0x62,0x33,0x0D,0xED,0xBC,0x4E,0x58,0xE5,0x47,
1122 0x4D,0xE9,0xAB,0x8E,0x38,0xD3,0x6E,0x90,0x57,0xE3,0x22,0x15,
1123 0x33,0xBD,0xF6,0x43,0x45,0xB5,0x10,0x0A,0xBE,0x2C,0xB4,0x35,
1124 0xB8,0x53,0x8D,0xAD,0xFB,0xA7,0x1F,0x85,0x58,0x41,0x7A,0x79,
1125 0x20,0x68,0xB3,0xE1,0x3D,0x08,0x76,0xBF,0x86,0x0D,0x49,0xE3,
1126 0x82,0x71,0x8C,0xB4,0x8D,0x81,0x84,0xD4,0xE7,0xBE,0x91,0xDC,
1127 0x26,0x39,0x48,0x0F,0x35,0xC4,0xCA,0x65,0xE3,0x40,0x93,0x52,
1128 0x76,0x58,0x7D,0xDD,0x51,0x75,0xDC,0x69,0x61,0xBF,0x47,0x2C,
1129 0x16,0x68,0x2D,0xC9,0x29,0xD3,0xE6,0xC0,0x99,0x48,0xA0,0x9A,
1130 0xC8,0x78,0xC0,0x6D,0x81,0x67,0x12,0x61,0x3F,0x71,0xBA,0x41,
1131 0x1F,0x6C,0x89,0x44,0x03,0xBA,0x3B,0x39,0x60,0xAA,0x28,0x55,
1132 0x59,0xAE,0xB8,0xFA,0xCB,0x6F,0xA5,0x1A,0xF7,0x2B,0xDD,0x52,
1133 0x8A,0x8B,0xE2,0x71,0xA6,0x5E,0x7E,0xD8,0x2E,0x18,0xE0,0x66,
1134 0xDF,0xDD,0x22,0x21,0x99,0x52,0x73,0xA6,0x33,0x20,0x65,0x0E,
1135 0x53,0xE7,0x6B,0x9B,0xC5,0xA3,0x2F,0x97,0x65,0x76,0xD3,0x47,
1136 0x23,0x77,0x12,0xB6,0x11,0x7B,0x24,0xED,0xF1,0xEF,0xC0,0xE2,
1137 0xA3,0x7E,0x67,0x05,0x3E,0x96,0x4D,0x45,0xC2,0x18,0xD1,0x73,
1138 0x9E,0x07,0xF3,0x81,0x6E,0x52,0x63,0xF6,0x20,0x76,0xB9,0x13,
1139 0xD2,0x65,0x30,0x18,0x16,0x09,0x16,0x9E,0x8F,0xF1,0xD2,0x10,
1140 0x5A,0xD3,0xD4,0xAF,0x16,0x61,0xDA,0x55,0x2E,0x18,0x5E,0x14,
1141 0x08,0x54,0x2E,0x2A,0x25,0xA2,0x1A,0x9B,0x8B,0x32,0xA9,0xFD,
1142 0xC2,0x48,0x96,0xE1,0x80,0xCA,0xE9,0x22,0x17,0xBB,0xCE,0x3E,
1143 0x9E,0xED,0xC7,0xF1,0x1F,0xEC,0x17,0x21,0xDC,0x7B,0x82,0x48,
1144 0x8E,0xBB,0x4B,0x9D,0x5B,0x04,0x04,0xDA,0xDB,0x39,0xDF,0x01,
1145 0x40,0xC3,0xAA,0x26,0x23,0x89,0x75,0xC6,0x0B,0xD0,0xA2,0x60,
1146 0x6A,0xF1,0xCC,0x65,0x18,0x98,0x1B,0x52,0xD2,0x74,0x61,0xCC,
1147 0xBD,0x60,0xAE,0xA3,0xA0,0x66,0x6A,0x16,0x34,0x92,0x3F,0x41,
1148 0x40,0x31,0x29,0xC0,0x2C,0x63,0xB2,0x07,0x8D,0xEB,0x94,0xB8,
1149 0xE8,0x47,0x92,0x52,0x93,0x6A,0x1B,0x7E,0x1A,0x61,0xB3,0x1B,
1150 0xF0,0xD6,0x72,0x9B,0xF1,0xB0,0xAF,0xBF,0x3E,0x65,0xEF,0x23,
1151 0x1D,0x6F,0xFF,0x70,0xCD,0x8A,0x4C,0x8A,0xA0,0x72,0x9D,0xBE,
1152 0xD4,0xBB,0x24,0x47,0x4A,0x68,0xB5,0xF5,0xC6,0xD5,0x7A,0xCD,
1153 0xCA,0x06,0x41,0x07,0xAD,0xC2,0x1E,0xE6,0x54,0xA7,0xAD,0x03,
1154 0xD9,0x12,0xC1,0x9C,0x13,0xB1,0xC9,0x0A,0x43,0x8E,0x1E,0x08,
1155 0xCE,0x50,0x82,0x73,0x5F,0xA7,0x55,0x1D,0xD9,0x59,0xAC,0xB5,
1156 0xEA,0x02,0x7F,0x6C,0x5B,0x74,0x96,0x98,0x67,0x24,0xA3,0x0F,
1157 0x15,0xFC,0xA9,0x7D,0x3E,0x67,0xD1,0x70,0xF8,0x97,0xF3,0x67,
1158 0xC5,0x8C,0x88,0x44,0x08,0x02,0xC7,0x2B,
Remi Gacognef46cd6e2014-06-12 14:58:40 +02001159 };
Remi Gacogned3a341a2015-05-29 16:26:17 +02001160 static unsigned char dh4096_g[]={
1161 0x02,
1162 };
Remi Gacognef46cd6e2014-06-12 14:58:40 +02001163
Remi Gacognef46cd6e2014-06-12 14:58:40 +02001164 DH *dh = DH_new();
1165 if (dh) {
Remi Gacogned3a341a2015-05-29 16:26:17 +02001166 dh->p = BN_bin2bn(dh4096_p, sizeof dh4096_p, NULL);
1167 dh->g = BN_bin2bn(dh4096_g, sizeof dh4096_g, NULL);
1168
Remi Gacognef46cd6e2014-06-12 14:58:40 +02001169 if (!dh->p || !dh->g) {
1170 DH_free(dh);
1171 dh = NULL;
1172 }
1173 }
1174 return dh;
1175}
1176
1177/* Returns Diffie-Hellman parameters matching the private key length
1178 but not exceeding global.tune.ssl_default_dh_param */
1179static DH *ssl_get_tmp_dh(SSL *ssl, int export, int keylen)
1180{
1181 DH *dh = NULL;
1182 EVP_PKEY *pkey = SSL_get_privatekey(ssl);
1183 int type = pkey ? EVP_PKEY_type(pkey->type) : EVP_PKEY_NONE;
1184
1185 /* The keylen supplied by OpenSSL can only be 512 or 1024.
1186 See ssl3_send_server_key_exchange() in ssl/s3_srvr.c
1187 */
1188 if (type == EVP_PKEY_RSA || type == EVP_PKEY_DSA) {
1189 keylen = EVP_PKEY_bits(pkey);
1190 }
1191
1192 if (keylen > global.tune.ssl_default_dh_param) {
1193 keylen = global.tune.ssl_default_dh_param;
1194 }
1195
Remi Gacogned3a341a2015-05-29 16:26:17 +02001196 if (keylen >= 4096) {
Remi Gacogne8de54152014-07-15 11:36:40 +02001197 dh = local_dh_4096;
Remi Gacognef46cd6e2014-06-12 14:58:40 +02001198 }
1199 else if (keylen >= 2048) {
Remi Gacogne8de54152014-07-15 11:36:40 +02001200 dh = local_dh_2048;
Remi Gacognef46cd6e2014-06-12 14:58:40 +02001201 }
1202 else {
Remi Gacogne8de54152014-07-15 11:36:40 +02001203 dh = local_dh_1024;
Remi Gacognef46cd6e2014-06-12 14:58:40 +02001204 }
1205
1206 return dh;
1207}
1208
Remi Gacogne47783ef2015-05-29 15:53:22 +02001209static DH * ssl_sock_get_dh_from_file(const char *filename)
Emeric Bruna4bcd9a2012-09-20 16:19:02 +02001210{
Emeric Bruna4bcd9a2012-09-20 16:19:02 +02001211 DH *dh = NULL;
Remi Gacogne47783ef2015-05-29 15:53:22 +02001212 BIO *in = BIO_new(BIO_s_file());
Emeric Bruna4bcd9a2012-09-20 16:19:02 +02001213
Emeric Bruna4bcd9a2012-09-20 16:19:02 +02001214 if (in == NULL)
1215 goto end;
1216
Remi Gacogne47783ef2015-05-29 15:53:22 +02001217 if (BIO_read_filename(in, filename) <= 0)
Emeric Bruna4bcd9a2012-09-20 16:19:02 +02001218 goto end;
1219
Remi Gacogne47783ef2015-05-29 15:53:22 +02001220 dh = PEM_read_bio_DHparams(in, NULL, NULL, NULL);
1221
1222end:
1223 if (in)
1224 BIO_free(in);
1225
1226 return dh;
1227}
1228
1229int ssl_sock_load_global_dh_param_from_file(const char *filename)
1230{
1231 global_dh = ssl_sock_get_dh_from_file(filename);
1232
1233 if (global_dh) {
1234 return 0;
1235 }
1236
1237 return -1;
1238}
1239
1240/* Loads Diffie-Hellman parameter from a file. Returns 1 if loaded, else -1
1241 if an error occured, and 0 if parameter not found. */
1242int ssl_sock_load_dh_params(SSL_CTX *ctx, const char *file)
1243{
1244 int ret = -1;
1245 DH *dh = ssl_sock_get_dh_from_file(file);
1246
Remi Gacognef46cd6e2014-06-12 14:58:40 +02001247 if (dh) {
1248 ret = 1;
1249 SSL_CTX_set_tmp_dh(ctx, dh);
Remi Gacogne4f902b82015-05-28 16:23:00 +02001250
1251 if (ssl_dh_ptr_index >= 0) {
1252 /* store a pointer to the DH params to avoid complaining about
1253 ssl-default-dh-param not being set for this SSL_CTX */
1254 SSL_CTX_set_ex_data(ctx, ssl_dh_ptr_index, dh);
1255 }
Remi Gacognef46cd6e2014-06-12 14:58:40 +02001256 }
Remi Gacogne47783ef2015-05-29 15:53:22 +02001257 else if (global_dh) {
1258 SSL_CTX_set_tmp_dh(ctx, global_dh);
1259 ret = 0; /* DH params not found */
1260 }
Remi Gacognef46cd6e2014-06-12 14:58:40 +02001261 else {
Emeric Brun41fdb3c2013-04-26 11:05:44 +02001262 /* Clear openssl global errors stack */
1263 ERR_clear_error();
1264
Remi Gacognef46cd6e2014-06-12 14:58:40 +02001265 if (global.tune.ssl_default_dh_param <= 1024) {
1266 /* we are limited to DH parameter of 1024 bits anyway */
Remi Gacogne8de54152014-07-15 11:36:40 +02001267 local_dh_1024 = ssl_get_dh_1024();
1268 if (local_dh_1024 == NULL)
Remi Gacognef46cd6e2014-06-12 14:58:40 +02001269 goto end;
Willy Tarreau6e774b42014-04-25 21:35:23 +02001270
Remi Gacogne8de54152014-07-15 11:36:40 +02001271 SSL_CTX_set_tmp_dh(ctx, local_dh_1024);
Remi Gacognef46cd6e2014-06-12 14:58:40 +02001272 }
1273 else {
1274 SSL_CTX_set_tmp_dh_callback(ctx, ssl_get_tmp_dh);
1275 }
Willy Tarreau6e774b42014-04-25 21:35:23 +02001276
Emeric Brun41fdb3c2013-04-26 11:05:44 +02001277 ret = 0; /* DH params not found */
Emeric Bruna4bcd9a2012-09-20 16:19:02 +02001278 }
Emeric Brun644cde02012-12-14 11:21:13 +01001279
Emeric Bruna4bcd9a2012-09-20 16:19:02 +02001280end:
1281 if (dh)
1282 DH_free(dh);
1283
Emeric Bruna4bcd9a2012-09-20 16:19:02 +02001284 return ret;
1285}
1286#endif
1287
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +02001288static int ssl_sock_add_cert_sni(SSL_CTX *ctx, struct bind_conf *s, char *name, int order)
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01001289{
1290 struct sni_ctx *sc;
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +02001291 int wild = 0, neg = 0;
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01001292
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +02001293 if (*name == '!') {
1294 neg = 1;
1295 name++;
1296 }
1297 if (*name == '*') {
1298 wild = 1;
1299 name++;
1300 }
1301 /* !* filter is a nop */
1302 if (neg && wild)
1303 return order;
1304 if (*name) {
1305 int j, len;
1306 len = strlen(name);
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01001307 sc = malloc(sizeof(struct sni_ctx) + len + 1);
1308 for (j = 0; j < len; j++)
1309 sc->name.key[j] = tolower(name[j]);
1310 sc->name.key[len] = 0;
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01001311 sc->ctx = ctx;
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +02001312 sc->order = order++;
1313 sc->neg = neg;
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01001314 if (wild)
1315 ebst_insert(&s->sni_w_ctx, &sc->name);
1316 else
1317 ebst_insert(&s->sni_ctx, &sc->name);
1318 }
1319 return order;
1320}
1321
Emeric Brunfc0421f2012-09-07 17:30:07 +02001322/* Loads a certificate key and CA chain from a file. Returns 0 on error, -1 if
1323 * an early error happens and the caller must call SSL_CTX_free() by itelf.
1324 */
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +02001325static 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 +02001326{
1327 BIO *in;
1328 X509 *x = NULL, *ca;
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +02001329 int i, err;
Emeric Brunfc0421f2012-09-07 17:30:07 +02001330 int ret = -1;
1331 int order = 0;
1332 X509_NAME *xname;
1333 char *str;
Emeric Brunfc0421f2012-09-07 17:30:07 +02001334#ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME
1335 STACK_OF(GENERAL_NAME) *names;
1336#endif
1337
1338 in = BIO_new(BIO_s_file());
1339 if (in == NULL)
1340 goto end;
1341
1342 if (BIO_read_filename(in, file) <= 0)
1343 goto end;
1344
1345 x = PEM_read_bio_X509_AUX(in, NULL, ctx->default_passwd_callback, ctx->default_passwd_callback_userdata);
1346 if (x == NULL)
1347 goto end;
1348
Emeric Brun50bcecc2013-04-22 13:05:23 +02001349 if (fcount) {
1350 while (fcount--)
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +02001351 order = ssl_sock_add_cert_sni(ctx, s, sni_filter[fcount], order);
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01001352 }
1353 else {
Emeric Brunfc0421f2012-09-07 17:30:07 +02001354#ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01001355 names = X509_get_ext_d2i(x, NID_subject_alt_name, NULL, NULL);
1356 if (names) {
1357 for (i = 0; i < sk_GENERAL_NAME_num(names); i++) {
1358 GENERAL_NAME *name = sk_GENERAL_NAME_value(names, i);
1359 if (name->type == GEN_DNS) {
1360 if (ASN1_STRING_to_UTF8((unsigned char **)&str, name->d.dNSName) >= 0) {
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +02001361 order = ssl_sock_add_cert_sni(ctx, s, str, order);
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01001362 OPENSSL_free(str);
Emeric Brunfc0421f2012-09-07 17:30:07 +02001363 }
Emeric Brunfc0421f2012-09-07 17:30:07 +02001364 }
1365 }
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01001366 sk_GENERAL_NAME_pop_free(names, GENERAL_NAME_free);
Emeric Brunfc0421f2012-09-07 17:30:07 +02001367 }
Emeric Brunfc0421f2012-09-07 17:30:07 +02001368#endif /* SSL_CTRL_SET_TLSEXT_HOSTNAME */
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01001369 xname = X509_get_subject_name(x);
1370 i = -1;
1371 while ((i = X509_NAME_get_index_by_NID(xname, NID_commonName, i)) != -1) {
1372 X509_NAME_ENTRY *entry = X509_NAME_get_entry(xname, i);
1373 if (ASN1_STRING_to_UTF8((unsigned char **)&str, entry->value) >= 0) {
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +02001374 order = ssl_sock_add_cert_sni(ctx, s, str, order);
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01001375 OPENSSL_free(str);
Emeric Brunfc0421f2012-09-07 17:30:07 +02001376 }
Emeric Brunfc0421f2012-09-07 17:30:07 +02001377 }
1378 }
1379
1380 ret = 0; /* the caller must not free the SSL_CTX argument anymore */
1381 if (!SSL_CTX_use_certificate(ctx, x))
1382 goto end;
1383
1384 if (ctx->extra_certs != NULL) {
1385 sk_X509_pop_free(ctx->extra_certs, X509_free);
1386 ctx->extra_certs = NULL;
1387 }
1388
1389 while ((ca = PEM_read_bio_X509(in, NULL, ctx->default_passwd_callback, ctx->default_passwd_callback_userdata))) {
1390 if (!SSL_CTX_add_extra_chain_cert(ctx, ca)) {
1391 X509_free(ca);
1392 goto end;
1393 }
1394 }
1395
1396 err = ERR_get_error();
1397 if (!err || (ERR_GET_LIB(err) == ERR_LIB_PEM && ERR_GET_REASON(err) == PEM_R_NO_START_LINE)) {
1398 /* we successfully reached the last cert in the file */
1399 ret = 1;
1400 }
1401 ERR_clear_error();
1402
1403end:
1404 if (x)
1405 X509_free(x);
1406
1407 if (in)
1408 BIO_free(in);
1409
1410 return ret;
1411}
1412
Emeric Brun50bcecc2013-04-22 13:05:23 +02001413static 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 +02001414{
1415 int ret;
1416 SSL_CTX *ctx;
1417
1418 ctx = SSL_CTX_new(SSLv23_server_method());
1419 if (!ctx) {
Willy Tarreaueb6cead2012-09-20 19:43:14 +02001420 memprintf(err, "%sunable to allocate SSL context for cert '%s'.\n",
1421 err && *err ? *err : "", path);
Emeric Brunfc0421f2012-09-07 17:30:07 +02001422 return 1;
1423 }
1424
1425 if (SSL_CTX_use_PrivateKey_file(ctx, path, SSL_FILETYPE_PEM) <= 0) {
Willy Tarreaueb6cead2012-09-20 19:43:14 +02001426 memprintf(err, "%sunable to load SSL private key from PEM file '%s'.\n",
1427 err && *err ? *err : "", path);
Emeric Brunfc0421f2012-09-07 17:30:07 +02001428 SSL_CTX_free(ctx);
1429 return 1;
1430 }
1431
Emeric Brun50bcecc2013-04-22 13:05:23 +02001432 ret = ssl_sock_load_cert_chain_file(ctx, path, bind_conf, sni_filter, fcount);
Emeric Brunfc0421f2012-09-07 17:30:07 +02001433 if (ret <= 0) {
Willy Tarreaueb6cead2012-09-20 19:43:14 +02001434 memprintf(err, "%sunable to load SSL certificate from PEM file '%s'.\n",
1435 err && *err ? *err : "", path);
Emeric Brunfc0421f2012-09-07 17:30:07 +02001436 if (ret < 0) /* serious error, must do that ourselves */
1437 SSL_CTX_free(ctx);
1438 return 1;
1439 }
Emeric Brun61694ab2012-10-26 13:35:33 +02001440
1441 if (SSL_CTX_check_private_key(ctx) <= 0) {
1442 memprintf(err, "%sinconsistencies between private key and certificate loaded from PEM file '%s'.\n",
1443 err && *err ? *err : "", path);
1444 return 1;
1445 }
1446
Emeric Brunfc0421f2012-09-07 17:30:07 +02001447 /* we must not free the SSL_CTX anymore below, since it's already in
1448 * the tree, so it will be discovered and cleaned in time.
1449 */
Emeric Bruna4bcd9a2012-09-20 16:19:02 +02001450#ifndef OPENSSL_NO_DH
Remi Gacogne4f902b82015-05-28 16:23:00 +02001451 /* store a NULL pointer to indicate we have not yet loaded
1452 a custom DH param file */
1453 if (ssl_dh_ptr_index >= 0) {
1454 SSL_CTX_set_ex_data(ctx, ssl_dh_ptr_index, NULL);
1455 }
1456
Emeric Bruna4bcd9a2012-09-20 16:19:02 +02001457 ret = ssl_sock_load_dh_params(ctx, path);
1458 if (ret < 0) {
1459 if (err)
1460 memprintf(err, "%sunable to load DH parameters from file '%s'.\n",
1461 *err ? *err : "", path);
1462 return 1;
1463 }
1464#endif
1465
Lukas Tribuse4e30f72014-12-09 16:32:51 +01001466#if (defined SSL_CTRL_SET_TLSEXT_STATUS_REQ_CB && !defined OPENSSL_NO_OCSP)
Emeric Brun4147b2e2014-06-16 18:36:30 +02001467 ret = ssl_sock_load_ocsp(ctx, path);
1468 if (ret < 0) {
1469 if (err)
1470 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",
1471 *err ? *err : "", path);
1472 return 1;
1473 }
1474#endif
1475
Janusz Dziemidowicz2c701b52015-03-07 23:03:59 +01001476#if (OPENSSL_VERSION_NUMBER >= 0x1000200fL && !defined OPENSSL_NO_TLSEXT && !defined OPENSSL_IS_BORINGSSL)
1477 if (sctl_ex_index >= 0) {
1478 ret = ssl_sock_load_sctl(ctx, path);
1479 if (ret < 0) {
1480 if (err)
1481 memprintf(err, "%s '%s.sctl' is present but cannot be read or parsed'.\n",
1482 *err ? *err : "", path);
1483 return 1;
1484 }
1485 }
1486#endif
1487
Emeric Brunfc0421f2012-09-07 17:30:07 +02001488#ifndef SSL_CTRL_SET_TLSEXT_HOSTNAME
Willy Tarreau2a65ff02012-09-13 17:54:29 +02001489 if (bind_conf->default_ctx) {
Willy Tarreaueb6cead2012-09-20 19:43:14 +02001490 memprintf(err, "%sthis version of openssl cannot load multiple SSL certificates.\n",
1491 err && *err ? *err : "");
Emeric Brunfc0421f2012-09-07 17:30:07 +02001492 return 1;
1493 }
1494#endif
Willy Tarreau2a65ff02012-09-13 17:54:29 +02001495 if (!bind_conf->default_ctx)
1496 bind_conf->default_ctx = ctx;
Emeric Brunfc0421f2012-09-07 17:30:07 +02001497
1498 return 0;
1499}
1500
Willy Tarreau79eeafa2012-09-14 07:53:05 +02001501int ssl_sock_load_cert(char *path, struct bind_conf *bind_conf, struct proxy *curproxy, char **err)
Emeric Brunfc0421f2012-09-07 17:30:07 +02001502{
Cyril Bonté3180f7b2015-01-25 00:16:08 +01001503 struct dirent **de_list;
1504 int i, n;
Emeric Brunfc0421f2012-09-07 17:30:07 +02001505 DIR *dir;
1506 struct stat buf;
Willy Tarreauee2663b2012-12-06 11:36:59 +01001507 char *end;
1508 char fp[MAXPATHLEN+1];
Emeric Brunfc0421f2012-09-07 17:30:07 +02001509 int cfgerr = 0;
1510
1511 if (!(dir = opendir(path)))
Emeric Brun50bcecc2013-04-22 13:05:23 +02001512 return ssl_sock_load_cert_file(path, bind_conf, curproxy, NULL, 0, err);
Emeric Brunfc0421f2012-09-07 17:30:07 +02001513
1514 /* strip trailing slashes, including first one */
1515 for (end = path + strlen(path) - 1; end >= path && *end == '/'; end--)
1516 *end = 0;
1517
Cyril Bonté3180f7b2015-01-25 00:16:08 +01001518 n = scandir(path, &de_list, 0, alphasort);
1519 if (n < 0) {
1520 memprintf(err, "%sunable to scan directory '%s' : %s.\n",
1521 err && *err ? *err : "", path, strerror(errno));
1522 cfgerr++;
1523 }
1524 else {
1525 for (i = 0; i < n; i++) {
1526 struct dirent *de = de_list[i];
Emeric Brun2aab7222014-06-18 18:15:09 +02001527
Cyril Bonté3180f7b2015-01-25 00:16:08 +01001528 end = strrchr(de->d_name, '.');
Janusz Dziemidowicz2c701b52015-03-07 23:03:59 +01001529 if (end && (!strcmp(end, ".issuer") || !strcmp(end, ".ocsp") || !strcmp(end, ".sctl")))
Cyril Bonté3180f7b2015-01-25 00:16:08 +01001530 goto ignore_entry;
1531
1532 snprintf(fp, sizeof(fp), "%s/%s", path, de->d_name);
1533 if (stat(fp, &buf) != 0) {
1534 memprintf(err, "%sunable to stat SSL certificate from file '%s' : %s.\n",
1535 err && *err ? *err : "", fp, strerror(errno));
1536 cfgerr++;
1537 goto ignore_entry;
1538 }
1539 if (!S_ISREG(buf.st_mode))
1540 goto ignore_entry;
1541 cfgerr += ssl_sock_load_cert_file(fp, bind_conf, curproxy, NULL, 0, err);
1542 ignore_entry:
1543 free(de);
Emeric Brunfc0421f2012-09-07 17:30:07 +02001544 }
Cyril Bonté3180f7b2015-01-25 00:16:08 +01001545 free(de_list);
Emeric Brunfc0421f2012-09-07 17:30:07 +02001546 }
Emeric Brunfc0421f2012-09-07 17:30:07 +02001547 closedir(dir);
1548 return cfgerr;
1549}
1550
Thierry Fournier383085f2013-01-24 14:15:43 +01001551/* Make sure openssl opens /dev/urandom before the chroot. The work is only
1552 * done once. Zero is returned if the operation fails. No error is returned
1553 * if the random is said as not implemented, because we expect that openssl
1554 * will use another method once needed.
1555 */
1556static int ssl_initialize_random()
1557{
1558 unsigned char random;
1559 static int random_initialized = 0;
1560
1561 if (!random_initialized && RAND_bytes(&random, 1) != 0)
1562 random_initialized = 1;
1563
1564 return random_initialized;
1565}
1566
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01001567int ssl_sock_load_cert_list_file(char *file, struct bind_conf *bind_conf, struct proxy *curproxy, char **err)
1568{
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +02001569 char thisline[LINESIZE];
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01001570 FILE *f;
1571 int linenum = 0;
1572 int cfgerr = 0;
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01001573
Willy Tarreauad1731d2013-04-02 17:35:58 +02001574 if ((f = fopen(file, "r")) == NULL) {
1575 memprintf(err, "cannot open file '%s' : %s", file, strerror(errno));
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01001576 return 1;
Willy Tarreauad1731d2013-04-02 17:35:58 +02001577 }
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01001578
1579 while (fgets(thisline, sizeof(thisline), f) != NULL) {
1580 int arg;
Emeric Brun50bcecc2013-04-22 13:05:23 +02001581 int newarg;
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01001582 char *end;
1583 char *args[MAX_LINE_ARGS + 1];
1584 char *line = thisline;
1585
1586 linenum++;
1587 end = line + strlen(line);
1588 if (end-line == sizeof(thisline)-1 && *(end-1) != '\n') {
1589 /* Check if we reached the limit and the last char is not \n.
1590 * Watch out for the last line without the terminating '\n'!
1591 */
Willy Tarreauad1731d2013-04-02 17:35:58 +02001592 memprintf(err, "line %d too long in file '%s', limit is %d characters",
1593 linenum, file, (int)sizeof(thisline)-1);
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01001594 cfgerr = 1;
Willy Tarreauad1731d2013-04-02 17:35:58 +02001595 break;
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01001596 }
1597
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01001598 arg = 0;
Emeric Brun50bcecc2013-04-22 13:05:23 +02001599 newarg = 1;
1600 while (*line) {
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01001601 if (*line == '#' || *line == '\n' || *line == '\r') {
1602 /* end of string, end of loop */
1603 *line = 0;
1604 break;
1605 }
1606 else if (isspace(*line)) {
Emeric Brun50bcecc2013-04-22 13:05:23 +02001607 newarg = 1;
1608 *line = 0;
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01001609 }
Emeric Brun50bcecc2013-04-22 13:05:23 +02001610 else if (newarg) {
1611 if (arg == MAX_LINE_ARGS) {
1612 memprintf(err, "too many args on line %d in file '%s'.",
1613 linenum, file);
1614 cfgerr = 1;
1615 break;
1616 }
1617 newarg = 0;
1618 args[arg++] = line;
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01001619 }
Emeric Brun50bcecc2013-04-22 13:05:23 +02001620 line++;
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01001621 }
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +02001622 if (cfgerr)
1623 break;
Willy Tarreauad1731d2013-04-02 17:35:58 +02001624
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01001625 /* empty line */
Emeric Brun50bcecc2013-04-22 13:05:23 +02001626 if (!arg)
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01001627 continue;
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01001628
Emeric Brun50bcecc2013-04-22 13:05:23 +02001629 cfgerr = ssl_sock_load_cert_file(args[0], bind_conf, curproxy, &args[1], arg-1, err);
Willy Tarreauad1731d2013-04-02 17:35:58 +02001630 if (cfgerr) {
1631 memprintf(err, "error processing line %d in file '%s' : %s", linenum, file, *err);
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01001632 break;
Willy Tarreauad1731d2013-04-02 17:35:58 +02001633 }
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01001634 }
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01001635 fclose(f);
1636 return cfgerr;
1637}
1638
Emeric Brunfc0421f2012-09-07 17:30:07 +02001639#ifndef SSL_OP_CIPHER_SERVER_PREFERENCE /* needs OpenSSL >= 0.9.7 */
1640#define SSL_OP_CIPHER_SERVER_PREFERENCE 0
1641#endif
1642
1643#ifndef SSL_OP_NO_SESSION_RESUMPTION_ON_RENEGOTIATION /* needs OpenSSL >= 0.9.7 */
1644#define SSL_OP_NO_SESSION_RESUMPTION_ON_RENEGOTIATION 0
Willy Tarreau7d588ee2012-11-26 18:47:31 +01001645#define SSL_renegotiate_pending(arg) 0
Emeric Brunfc0421f2012-09-07 17:30:07 +02001646#endif
Emeric Brun2b58d042012-09-20 17:10:03 +02001647#ifndef SSL_OP_SINGLE_ECDH_USE /* needs OpenSSL >= 0.9.8 */
1648#define SSL_OP_SINGLE_ECDH_USE 0
1649#endif
Emeric Brun2d0c4822012-10-02 13:45:20 +02001650#ifndef SSL_OP_NO_TICKET /* needs OpenSSL >= 0.9.8 */
1651#define SSL_OP_NO_TICKET 0
1652#endif
Emeric Brunfc0421f2012-09-07 17:30:07 +02001653#ifndef SSL_OP_NO_COMPRESSION /* needs OpenSSL >= 0.9.9 */
1654#define SSL_OP_NO_COMPRESSION 0
1655#endif
Emeric Brunc0ff4922012-09-28 19:37:02 +02001656#ifndef SSL_OP_NO_TLSv1_1 /* needs OpenSSL >= 1.0.1 */
1657#define SSL_OP_NO_TLSv1_1 0
1658#endif
1659#ifndef SSL_OP_NO_TLSv1_2 /* needs OpenSSL >= 1.0.1 */
1660#define SSL_OP_NO_TLSv1_2 0
1661#endif
Emeric Bruna4bcd9a2012-09-20 16:19:02 +02001662#ifndef SSL_OP_SINGLE_DH_USE /* needs OpenSSL >= 0.9.6 */
1663#define SSL_OP_SINGLE_DH_USE 0
1664#endif
Emeric Brun2b58d042012-09-20 17:10:03 +02001665#ifndef SSL_OP_SINGLE_ECDH_USE /* needs OpenSSL >= 1.0.0 */
1666#define SSL_OP_SINGLE_ECDH_USE 0
1667#endif
Emeric Brunfc0421f2012-09-07 17:30:07 +02001668#ifndef SSL_MODE_RELEASE_BUFFERS /* needs OpenSSL >= 1.0.0 */
1669#define SSL_MODE_RELEASE_BUFFERS 0
1670#endif
Willy Tarreau396a1862014-11-13 14:06:52 +01001671#ifndef SSL_MODE_SMALL_BUFFERS /* needs small_records.patch */
1672#define SSL_MODE_SMALL_BUFFERS 0
1673#endif
Remi Gacognef46cd6e2014-06-12 14:58:40 +02001674
Willy Tarreau2a65ff02012-09-13 17:54:29 +02001675int ssl_sock_prepare_ctx(struct bind_conf *bind_conf, SSL_CTX *ctx, struct proxy *curproxy)
Emeric Brunfc0421f2012-09-07 17:30:07 +02001676{
1677 int cfgerr = 0;
Emeric Brun850efd52014-01-29 12:24:34 +01001678 int verify = SSL_VERIFY_NONE;
Remi Gacogneaf5c3da2014-05-19 10:29:58 +02001679 long ssloptions =
Emeric Brunfc0421f2012-09-07 17:30:07 +02001680 SSL_OP_ALL | /* all known workarounds for bugs */
1681 SSL_OP_NO_SSLv2 |
1682 SSL_OP_NO_COMPRESSION |
Emeric Bruna4bcd9a2012-09-20 16:19:02 +02001683 SSL_OP_SINGLE_DH_USE |
Emeric Brun2b58d042012-09-20 17:10:03 +02001684 SSL_OP_SINGLE_ECDH_USE |
Emeric Brun3c4bc6e2012-10-04 18:44:19 +02001685 SSL_OP_NO_SESSION_RESUMPTION_ON_RENEGOTIATION |
1686 SSL_OP_CIPHER_SERVER_PREFERENCE;
Remi Gacogneaf5c3da2014-05-19 10:29:58 +02001687 long sslmode =
Emeric Brunfc0421f2012-09-07 17:30:07 +02001688 SSL_MODE_ENABLE_PARTIAL_WRITE |
1689 SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER |
Willy Tarreau396a1862014-11-13 14:06:52 +01001690 SSL_MODE_RELEASE_BUFFERS |
1691 SSL_MODE_SMALL_BUFFERS;
Remi Gacognef46cd6e2014-06-12 14:58:40 +02001692 STACK_OF(SSL_CIPHER) * ciphers = NULL;
Willy Tarreaua616ba62014-10-26 06:49:19 +01001693 SSL_CIPHER * cipher = NULL;
Remi Gacognec1eab8c2014-06-12 18:20:11 +02001694 char cipher_description[128];
1695 /* The description of ciphers using an Ephemeral Diffie Hellman key exchange
1696 contains " Kx=DH " or " Kx=DH(". Beware of " Kx=DH/",
1697 which is not ephemeral DH. */
1698 const char dhe_description[] = " Kx=DH ";
1699 const char dhe_export_description[] = " Kx=DH(";
Remi Gacognef46cd6e2014-06-12 14:58:40 +02001700 int idx = 0;
1701 int dhe_found = 0;
Remi Gacogne23d5d372014-10-10 17:04:26 +02001702 SSL *ssl = NULL;
Emeric Brunfc0421f2012-09-07 17:30:07 +02001703
Thierry Fournier383085f2013-01-24 14:15:43 +01001704 /* Make sure openssl opens /dev/urandom before the chroot */
1705 if (!ssl_initialize_random()) {
1706 Alert("OpenSSL random data generator initialization failed.\n");
1707 cfgerr++;
1708 }
1709
Emeric Brun89675492012-10-05 13:48:26 +02001710 if (bind_conf->ssl_options & BC_SSL_O_NO_SSLV3)
Emeric Brunfc0421f2012-09-07 17:30:07 +02001711 ssloptions |= SSL_OP_NO_SSLv3;
Emeric Brun89675492012-10-05 13:48:26 +02001712 if (bind_conf->ssl_options & BC_SSL_O_NO_TLSV10)
Emeric Brunfc0421f2012-09-07 17:30:07 +02001713 ssloptions |= SSL_OP_NO_TLSv1;
Emeric Brun89675492012-10-05 13:48:26 +02001714 if (bind_conf->ssl_options & BC_SSL_O_NO_TLSV11)
Emeric Brunc0ff4922012-09-28 19:37:02 +02001715 ssloptions |= SSL_OP_NO_TLSv1_1;
Emeric Brun89675492012-10-05 13:48:26 +02001716 if (bind_conf->ssl_options & BC_SSL_O_NO_TLSV12)
Emeric Brunc0ff4922012-09-28 19:37:02 +02001717 ssloptions |= SSL_OP_NO_TLSv1_2;
Emeric Brun89675492012-10-05 13:48:26 +02001718 if (bind_conf->ssl_options & BC_SSL_O_NO_TLS_TICKETS)
Emeric Brun2d0c4822012-10-02 13:45:20 +02001719 ssloptions |= SSL_OP_NO_TICKET;
Emeric Brun2cb7ae52012-10-05 14:14:21 +02001720 if (bind_conf->ssl_options & BC_SSL_O_USE_SSLV3)
1721 SSL_CTX_set_ssl_version(ctx, SSLv3_server_method());
1722 if (bind_conf->ssl_options & BC_SSL_O_USE_TLSV10)
1723 SSL_CTX_set_ssl_version(ctx, TLSv1_server_method());
1724#if SSL_OP_NO_TLSv1_1
1725 if (bind_conf->ssl_options & BC_SSL_O_USE_TLSV11)
1726 SSL_CTX_set_ssl_version(ctx, TLSv1_1_server_method());
1727#endif
1728#if SSL_OP_NO_TLSv1_2
1729 if (bind_conf->ssl_options & BC_SSL_O_USE_TLSV12)
1730 SSL_CTX_set_ssl_version(ctx, TLSv1_2_server_method());
1731#endif
Emeric Brunfc0421f2012-09-07 17:30:07 +02001732
1733 SSL_CTX_set_options(ctx, ssloptions);
1734 SSL_CTX_set_mode(ctx, sslmode);
Emeric Brun850efd52014-01-29 12:24:34 +01001735 switch (bind_conf->verify) {
1736 case SSL_SOCK_VERIFY_NONE:
1737 verify = SSL_VERIFY_NONE;
1738 break;
1739 case SSL_SOCK_VERIFY_OPTIONAL:
1740 verify = SSL_VERIFY_PEER;
1741 break;
1742 case SSL_SOCK_VERIFY_REQUIRED:
1743 verify = SSL_VERIFY_PEER|SSL_VERIFY_FAIL_IF_NO_PEER_CERT;
1744 break;
1745 }
1746 SSL_CTX_set_verify(ctx, verify, ssl_sock_bind_verifycbk);
1747 if (verify & SSL_VERIFY_PEER) {
Emeric Brunfb510ea2012-10-05 12:00:26 +02001748 if (bind_conf->ca_file) {
Emeric Brund94b3fe2012-09-20 18:23:56 +02001749 /* load CAfile to verify */
Emeric Brunfb510ea2012-10-05 12:00:26 +02001750 if (!SSL_CTX_load_verify_locations(ctx, bind_conf->ca_file, NULL)) {
Emeric Brund94b3fe2012-09-20 18:23:56 +02001751 Alert("Proxy '%s': unable to load CA file '%s' for bind '%s' at [%s:%d].\n",
Emeric Brunfb510ea2012-10-05 12:00:26 +02001752 curproxy->id, bind_conf->ca_file, bind_conf->arg, bind_conf->file, bind_conf->line);
Emeric Brund94b3fe2012-09-20 18:23:56 +02001753 cfgerr++;
1754 }
1755 /* set CA names fo client cert request, function returns void */
Emeric Brunfb510ea2012-10-05 12:00:26 +02001756 SSL_CTX_set_client_CA_list(ctx, SSL_load_client_CA_file(bind_conf->ca_file));
Emeric Brund94b3fe2012-09-20 18:23:56 +02001757 }
Emeric Brun850efd52014-01-29 12:24:34 +01001758 else {
1759 Alert("Proxy '%s': verify is enabled but no CA file specified for bind '%s' at [%s:%d].\n",
1760 curproxy->id, bind_conf->arg, bind_conf->file, bind_conf->line);
1761 cfgerr++;
1762 }
Emeric Brun051cdab2012-10-02 19:25:50 +02001763#ifdef X509_V_FLAG_CRL_CHECK
Emeric Brunfb510ea2012-10-05 12:00:26 +02001764 if (bind_conf->crl_file) {
Emeric Brund94b3fe2012-09-20 18:23:56 +02001765 X509_STORE *store = SSL_CTX_get_cert_store(ctx);
1766
Emeric Brunfb510ea2012-10-05 12:00:26 +02001767 if (!store || !X509_STORE_load_locations(store, bind_conf->crl_file, NULL)) {
Emeric Brund94b3fe2012-09-20 18:23:56 +02001768 Alert("Proxy '%s': unable to configure CRL file '%s' for bind '%s' at [%s:%d].\n",
Alexander Rigbofc65af02015-04-07 14:02:16 +02001769 curproxy->id, bind_conf->crl_file, bind_conf->arg, bind_conf->file, bind_conf->line);
Emeric Brund94b3fe2012-09-20 18:23:56 +02001770 cfgerr++;
1771 }
Emeric Brun561e5742012-10-02 15:20:55 +02001772 else {
1773 X509_STORE_set_flags(store, X509_V_FLAG_CRL_CHECK|X509_V_FLAG_CRL_CHECK_ALL);
1774 }
Emeric Brund94b3fe2012-09-20 18:23:56 +02001775 }
Emeric Brun051cdab2012-10-02 19:25:50 +02001776#endif
Emeric Brun644cde02012-12-14 11:21:13 +01001777 ERR_clear_error();
Emeric Brund94b3fe2012-09-20 18:23:56 +02001778 }
Emeric Brunfc0421f2012-09-07 17:30:07 +02001779
Nenad Merdanovic05552d42015-02-27 19:56:49 +01001780#if (defined SSL_CTRL_SET_TLSEXT_TICKET_KEY_CB && TLS_TICKETS_NO > 0)
Nenad Merdanovic146defa2015-05-09 08:46:00 +02001781 if(bind_conf->keys_ref) {
Nenad Merdanovic05552d42015-02-27 19:56:49 +01001782 if (!SSL_CTX_set_tlsext_ticket_key_cb(ctx, ssl_tlsext_ticket_key_cb)) {
1783 Alert("Proxy '%s': unable to set callback for TLS ticket validation for bind '%s' at [%s:%d].\n",
1784 curproxy->id, bind_conf->arg, bind_conf->file, bind_conf->line);
1785 cfgerr++;
1786 }
1787 }
1788#endif
1789
Emeric Brun4f65bff2012-11-16 15:11:00 +01001790 if (global.tune.ssllifetime)
1791 SSL_CTX_set_timeout(ctx, global.tune.ssllifetime);
1792
Emeric Brunfc0421f2012-09-07 17:30:07 +02001793 shared_context_set_cache(ctx);
Willy Tarreau2a65ff02012-09-13 17:54:29 +02001794 if (bind_conf->ciphers &&
1795 !SSL_CTX_set_cipher_list(ctx, bind_conf->ciphers)) {
Emeric Brunfc0421f2012-09-07 17:30:07 +02001796 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 +02001797 curproxy->id, bind_conf->ciphers, bind_conf->arg, bind_conf->file, bind_conf->line);
Emeric Brunfc0421f2012-09-07 17:30:07 +02001798 cfgerr++;
1799 }
1800
Remi Gacogne47783ef2015-05-29 15:53:22 +02001801 /* If tune.ssl.default-dh-param has not been set,
1802 neither has ssl-default-dh-file and no static DH
1803 params were in the certificate file. */
Remi Gacogne4f902b82015-05-28 16:23:00 +02001804 if (global.tune.ssl_default_dh_param == 0 &&
Remi Gacogne47783ef2015-05-29 15:53:22 +02001805 global_dh == NULL &&
Remi Gacogne4f902b82015-05-28 16:23:00 +02001806 (ssl_dh_ptr_index == -1 ||
1807 SSL_CTX_get_ex_data(ctx, ssl_dh_ptr_index) == NULL)) {
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 }
Remi Gacogne8de54152014-07-15 11:36:40 +02001850 }
1851 }
1852 }
1853#endif /* OPENSSL_NO_DH */
Remi Gacognef46cd6e2014-06-12 14:58:40 +02001854
Emeric Brunfc0421f2012-09-07 17:30:07 +02001855 SSL_CTX_set_info_callback(ctx, ssl_sock_infocbk);
Willy Tarreau5cbe4ef2014-05-08 22:45:11 +02001856#if OPENSSL_VERSION_NUMBER >= 0x00907000L
Emeric Brun29f037d2014-04-25 19:05:36 +02001857 SSL_CTX_set_msg_callback(ctx, ssl_sock_msgcbk);
Willy Tarreau5cbe4ef2014-05-08 22:45:11 +02001858#endif
Emeric Brun29f037d2014-04-25 19:05:36 +02001859
Willy Tarreau6c9a3d52012-10-18 18:57:14 +02001860#ifdef OPENSSL_NPN_NEGOTIATED
1861 if (bind_conf->npn_str)
1862 SSL_CTX_set_next_protos_advertised_cb(ctx, ssl_sock_advertise_npn_protos, bind_conf);
1863#endif
Dirkjan Bussink48f1c4e2014-02-13 12:29:42 +01001864#ifdef TLSEXT_TYPE_application_layer_protocol_negotiation
Willy Tarreauab861d32013-04-02 02:30:41 +02001865 if (bind_conf->alpn_str)
Dirkjan Bussink48f1c4e2014-02-13 12:29:42 +01001866 SSL_CTX_set_alpn_select_cb(ctx, ssl_sock_advertise_alpn_protos, bind_conf);
Willy Tarreauab861d32013-04-02 02:30:41 +02001867#endif
Willy Tarreau6c9a3d52012-10-18 18:57:14 +02001868
Emeric Brunfc0421f2012-09-07 17:30:07 +02001869#ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME
1870 SSL_CTX_set_tlsext_servername_callback(ctx, ssl_sock_switchctx_cbk);
Willy Tarreau2a65ff02012-09-13 17:54:29 +02001871 SSL_CTX_set_tlsext_servername_arg(ctx, bind_conf);
Emeric Brunfc0421f2012-09-07 17:30:07 +02001872#endif
Emeric Brun2b58d042012-09-20 17:10:03 +02001873#if defined(SSL_CTX_set_tmp_ecdh) && !defined(OPENSSL_NO_ECDH)
Emeric Brun6924ef82013-03-06 14:08:53 +01001874 {
Emeric Brun2b58d042012-09-20 17:10:03 +02001875 int i;
1876 EC_KEY *ecdh;
1877
Emeric Brun6924ef82013-03-06 14:08:53 +01001878 i = OBJ_sn2nid(bind_conf->ecdhe ? bind_conf->ecdhe : ECDHE_DEFAULT_CURVE);
Emeric Brun2b58d042012-09-20 17:10:03 +02001879 if (!i || ((ecdh = EC_KEY_new_by_curve_name(i)) == NULL)) {
1880 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 +01001881 curproxy->id, bind_conf->ecdhe ? bind_conf->ecdhe : ECDHE_DEFAULT_CURVE,
1882 bind_conf->arg, bind_conf->file, bind_conf->line);
Emeric Brun2b58d042012-09-20 17:10:03 +02001883 cfgerr++;
1884 }
1885 else {
1886 SSL_CTX_set_tmp_ecdh(ctx, ecdh);
1887 EC_KEY_free(ecdh);
1888 }
1889 }
1890#endif
1891
Emeric Brunfc0421f2012-09-07 17:30:07 +02001892 return cfgerr;
1893}
1894
Evan Broderbe554312013-06-27 00:05:25 -07001895static int ssl_sock_srv_hostcheck(const char *pattern, const char *hostname)
1896{
1897 const char *pattern_wildcard, *pattern_left_label_end, *hostname_left_label_end;
1898 size_t prefixlen, suffixlen;
1899
1900 /* Trivial case */
1901 if (strcmp(pattern, hostname) == 0)
1902 return 1;
1903
Evan Broderbe554312013-06-27 00:05:25 -07001904 /* The rest of this logic is based on RFC 6125, section 6.4.3
1905 * (http://tools.ietf.org/html/rfc6125#section-6.4.3) */
1906
Emeric Bruna848dae2013-10-08 11:27:28 +02001907 pattern_wildcard = NULL;
1908 pattern_left_label_end = pattern;
1909 while (*pattern_left_label_end != '.') {
1910 switch (*pattern_left_label_end) {
1911 case 0:
1912 /* End of label not found */
1913 return 0;
1914 case '*':
1915 /* If there is more than one wildcards */
1916 if (pattern_wildcard)
1917 return 0;
1918 pattern_wildcard = pattern_left_label_end;
1919 break;
1920 }
1921 pattern_left_label_end++;
1922 }
1923
1924 /* If it's not trivial and there is no wildcard, it can't
1925 * match */
1926 if (!pattern_wildcard)
Evan Broderbe554312013-06-27 00:05:25 -07001927 return 0;
1928
1929 /* Make sure all labels match except the leftmost */
1930 hostname_left_label_end = strchr(hostname, '.');
1931 if (!hostname_left_label_end
1932 || strcmp(pattern_left_label_end, hostname_left_label_end) != 0)
1933 return 0;
1934
1935 /* Make sure the leftmost label of the hostname is long enough
1936 * that the wildcard can match */
Emeric Brun369da852013-10-08 11:39:35 +02001937 if (hostname_left_label_end - hostname < (pattern_left_label_end - pattern) - 1)
Evan Broderbe554312013-06-27 00:05:25 -07001938 return 0;
1939
1940 /* Finally compare the string on either side of the
1941 * wildcard */
1942 prefixlen = pattern_wildcard - pattern;
1943 suffixlen = pattern_left_label_end - (pattern_wildcard + 1);
Emeric Bruna848dae2013-10-08 11:27:28 +02001944 if ((prefixlen && (memcmp(pattern, hostname, prefixlen) != 0))
1945 || (suffixlen && (memcmp(pattern_wildcard + 1, hostname_left_label_end - suffixlen, suffixlen) != 0)))
Evan Broderbe554312013-06-27 00:05:25 -07001946 return 0;
1947
1948 return 1;
1949}
1950
1951static int ssl_sock_srv_verifycbk(int ok, X509_STORE_CTX *ctx)
1952{
1953 SSL *ssl;
1954 struct connection *conn;
1955 char *servername;
1956
1957 int depth;
1958 X509 *cert;
1959 STACK_OF(GENERAL_NAME) *alt_names;
1960 int i;
1961 X509_NAME *cert_subject;
1962 char *str;
1963
1964 if (ok == 0)
1965 return ok;
1966
1967 ssl = X509_STORE_CTX_get_ex_data(ctx, SSL_get_ex_data_X509_STORE_CTX_idx());
1968 conn = (struct connection *)SSL_get_app_data(ssl);
1969
1970 servername = objt_server(conn->target)->ssl_ctx.verify_host;
1971
1972 /* We only need to verify the CN on the actual server cert,
1973 * not the indirect CAs */
1974 depth = X509_STORE_CTX_get_error_depth(ctx);
1975 if (depth != 0)
1976 return ok;
1977
1978 /* At this point, the cert is *not* OK unless we can find a
1979 * hostname match */
1980 ok = 0;
1981
1982 cert = X509_STORE_CTX_get_current_cert(ctx);
1983 /* It seems like this might happen if verify peer isn't set */
1984 if (!cert)
1985 return ok;
1986
1987 alt_names = X509_get_ext_d2i(cert, NID_subject_alt_name, NULL, NULL);
1988 if (alt_names) {
1989 for (i = 0; !ok && i < sk_GENERAL_NAME_num(alt_names); i++) {
1990 GENERAL_NAME *name = sk_GENERAL_NAME_value(alt_names, i);
1991 if (name->type == GEN_DNS) {
Emeric Bruna33410c2013-09-17 15:47:48 +02001992#if OPENSSL_VERSION_NUMBER < 0x00907000L
1993 if (ASN1_STRING_to_UTF8((unsigned char **)&str, name->d.ia5) >= 0) {
1994#else
Evan Broderbe554312013-06-27 00:05:25 -07001995 if (ASN1_STRING_to_UTF8((unsigned char **)&str, name->d.dNSName) >= 0) {
Emeric Bruna33410c2013-09-17 15:47:48 +02001996#endif
Evan Broderbe554312013-06-27 00:05:25 -07001997 ok = ssl_sock_srv_hostcheck(str, servername);
1998 OPENSSL_free(str);
1999 }
2000 }
2001 }
Emeric Brun4ad50a42013-09-17 15:19:54 +02002002 sk_GENERAL_NAME_pop_free(alt_names, GENERAL_NAME_free);
Evan Broderbe554312013-06-27 00:05:25 -07002003 }
2004
2005 cert_subject = X509_get_subject_name(cert);
2006 i = -1;
2007 while (!ok && (i = X509_NAME_get_index_by_NID(cert_subject, NID_commonName, i)) != -1) {
2008 X509_NAME_ENTRY *entry = X509_NAME_get_entry(cert_subject, i);
2009 if (ASN1_STRING_to_UTF8((unsigned char **)&str, entry->value) >= 0) {
2010 ok = ssl_sock_srv_hostcheck(str, servername);
2011 OPENSSL_free(str);
2012 }
2013 }
2014
2015 return ok;
2016}
2017
Emeric Brun94324a42012-10-11 14:00:19 +02002018/* prepare ssl context from servers options. Returns an error count */
2019int ssl_sock_prepare_srv_ctx(struct server *srv, struct proxy *curproxy)
2020{
2021 int cfgerr = 0;
Remi Gacogneaf5c3da2014-05-19 10:29:58 +02002022 long options =
Emeric Brun94324a42012-10-11 14:00:19 +02002023 SSL_OP_ALL | /* all known workarounds for bugs */
2024 SSL_OP_NO_SSLv2 |
2025 SSL_OP_NO_COMPRESSION;
Remi Gacogneaf5c3da2014-05-19 10:29:58 +02002026 long mode =
Emeric Brun94324a42012-10-11 14:00:19 +02002027 SSL_MODE_ENABLE_PARTIAL_WRITE |
2028 SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER |
Willy Tarreau396a1862014-11-13 14:06:52 +01002029 SSL_MODE_RELEASE_BUFFERS |
2030 SSL_MODE_SMALL_BUFFERS;
Emeric Brun850efd52014-01-29 12:24:34 +01002031 int verify = SSL_VERIFY_NONE;
Emeric Brun94324a42012-10-11 14:00:19 +02002032
Thierry Fournier383085f2013-01-24 14:15:43 +01002033 /* Make sure openssl opens /dev/urandom before the chroot */
2034 if (!ssl_initialize_random()) {
2035 Alert("OpenSSL random data generator initialization failed.\n");
2036 cfgerr++;
2037 }
2038
Willy Tarreaufce03112015-01-15 21:32:40 +01002039 /* Automatic memory computations need to know we use SSL there */
2040 global.ssl_used_backend = 1;
2041
2042 /* Initiate SSL context for current server */
Emeric Brun94324a42012-10-11 14:00:19 +02002043 srv->ssl_ctx.reused_sess = NULL;
2044 if (srv->use_ssl)
2045 srv->xprt = &ssl_sock;
2046 if (srv->check.use_ssl)
Cyril Bonté9ce13112014-11-15 22:41:27 +01002047 srv->check.xprt = &ssl_sock;
Emeric Brun94324a42012-10-11 14:00:19 +02002048
2049 srv->ssl_ctx.ctx = SSL_CTX_new(SSLv23_client_method());
2050 if (!srv->ssl_ctx.ctx) {
2051 Alert("config : %s '%s', server '%s': unable to allocate ssl context.\n",
2052 proxy_type_str(curproxy), curproxy->id,
2053 srv->id);
2054 cfgerr++;
2055 return cfgerr;
2056 }
Emeric Bruna7aa3092012-10-26 12:58:00 +02002057 if (srv->ssl_ctx.client_crt) {
2058 if (SSL_CTX_use_PrivateKey_file(srv->ssl_ctx.ctx, srv->ssl_ctx.client_crt, SSL_FILETYPE_PEM) <= 0) {
2059 Alert("config : %s '%s', server '%s': unable to load SSL private key from PEM file '%s'.\n",
2060 proxy_type_str(curproxy), curproxy->id,
2061 srv->id, srv->ssl_ctx.client_crt);
2062 cfgerr++;
2063 }
2064 else if (SSL_CTX_use_certificate_chain_file(srv->ssl_ctx.ctx, srv->ssl_ctx.client_crt) <= 0) {
2065 Alert("config : %s '%s', server '%s': unable to load ssl certificate from PEM file '%s'.\n",
2066 proxy_type_str(curproxy), curproxy->id,
2067 srv->id, srv->ssl_ctx.client_crt);
2068 cfgerr++;
2069 }
2070 else if (SSL_CTX_check_private_key(srv->ssl_ctx.ctx) <= 0) {
2071 Alert("config : %s '%s', server '%s': inconsistencies between private key and certificate loaded from PEM file '%s'.\n",
2072 proxy_type_str(curproxy), curproxy->id,
2073 srv->id, srv->ssl_ctx.client_crt);
2074 cfgerr++;
2075 }
2076 }
Emeric Brun94324a42012-10-11 14:00:19 +02002077
2078 if (srv->ssl_ctx.options & SRV_SSL_O_NO_SSLV3)
2079 options |= SSL_OP_NO_SSLv3;
2080 if (srv->ssl_ctx.options & SRV_SSL_O_NO_TLSV10)
2081 options |= SSL_OP_NO_TLSv1;
2082 if (srv->ssl_ctx.options & SRV_SSL_O_NO_TLSV11)
2083 options |= SSL_OP_NO_TLSv1_1;
2084 if (srv->ssl_ctx.options & SRV_SSL_O_NO_TLSV12)
2085 options |= SSL_OP_NO_TLSv1_2;
Emeric Brunf9c5c472012-10-11 15:28:34 +02002086 if (srv->ssl_ctx.options & SRV_SSL_O_NO_TLS_TICKETS)
2087 options |= SSL_OP_NO_TICKET;
Emeric Brun94324a42012-10-11 14:00:19 +02002088 if (srv->ssl_ctx.options & SRV_SSL_O_USE_SSLV3)
2089 SSL_CTX_set_ssl_version(srv->ssl_ctx.ctx, SSLv3_client_method());
2090 if (srv->ssl_ctx.options & SRV_SSL_O_USE_TLSV10)
2091 SSL_CTX_set_ssl_version(srv->ssl_ctx.ctx, TLSv1_client_method());
2092#if SSL_OP_NO_TLSv1_1
2093 if (srv->ssl_ctx.options & SRV_SSL_O_USE_TLSV11)
2094 SSL_CTX_set_ssl_version(srv->ssl_ctx.ctx, TLSv1_1_client_method());
2095#endif
2096#if SSL_OP_NO_TLSv1_2
2097 if (srv->ssl_ctx.options & SRV_SSL_O_USE_TLSV12)
2098 SSL_CTX_set_ssl_version(srv->ssl_ctx.ctx, TLSv1_2_client_method());
2099#endif
2100
2101 SSL_CTX_set_options(srv->ssl_ctx.ctx, options);
2102 SSL_CTX_set_mode(srv->ssl_ctx.ctx, mode);
Emeric Brun850efd52014-01-29 12:24:34 +01002103
2104 if (global.ssl_server_verify == SSL_SERVER_VERIFY_REQUIRED)
2105 verify = SSL_VERIFY_PEER;
2106
2107 switch (srv->ssl_ctx.verify) {
2108 case SSL_SOCK_VERIFY_NONE:
2109 verify = SSL_VERIFY_NONE;
2110 break;
2111 case SSL_SOCK_VERIFY_REQUIRED:
2112 verify = SSL_VERIFY_PEER;
2113 break;
2114 }
Evan Broderbe554312013-06-27 00:05:25 -07002115 SSL_CTX_set_verify(srv->ssl_ctx.ctx,
Emeric Brun850efd52014-01-29 12:24:34 +01002116 verify,
Evan Broderbe554312013-06-27 00:05:25 -07002117 srv->ssl_ctx.verify_host ? ssl_sock_srv_verifycbk : NULL);
Emeric Brun850efd52014-01-29 12:24:34 +01002118 if (verify & SSL_VERIFY_PEER) {
Emeric Brunef42d922012-10-11 16:11:36 +02002119 if (srv->ssl_ctx.ca_file) {
2120 /* load CAfile to verify */
2121 if (!SSL_CTX_load_verify_locations(srv->ssl_ctx.ctx, srv->ssl_ctx.ca_file, NULL)) {
Willy Tarreau07ba08b2014-02-16 19:22:08 +01002122 Alert("Proxy '%s', server '%s' [%s:%d] unable to load CA file '%s'.\n",
Emeric Brunef42d922012-10-11 16:11:36 +02002123 curproxy->id, srv->id,
2124 srv->conf.file, srv->conf.line, srv->ssl_ctx.ca_file);
2125 cfgerr++;
2126 }
2127 }
Emeric Brun850efd52014-01-29 12:24:34 +01002128 else {
2129 if (global.ssl_server_verify == SSL_SERVER_VERIFY_REQUIRED)
Willy Tarreau07ba08b2014-02-16 19:22:08 +01002130 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 +01002131 curproxy->id, srv->id,
2132 srv->conf.file, srv->conf.line);
2133 else
Willy Tarreau07ba08b2014-02-16 19:22:08 +01002134 Alert("Proxy '%s', server '%s' [%s:%d] verify is enabled but no CA file specified.\n",
Emeric Brun850efd52014-01-29 12:24:34 +01002135 curproxy->id, srv->id,
2136 srv->conf.file, srv->conf.line);
2137 cfgerr++;
2138 }
Emeric Brunef42d922012-10-11 16:11:36 +02002139#ifdef X509_V_FLAG_CRL_CHECK
2140 if (srv->ssl_ctx.crl_file) {
2141 X509_STORE *store = SSL_CTX_get_cert_store(srv->ssl_ctx.ctx);
2142
2143 if (!store || !X509_STORE_load_locations(store, srv->ssl_ctx.crl_file, NULL)) {
Willy Tarreau07ba08b2014-02-16 19:22:08 +01002144 Alert("Proxy '%s', server '%s' [%s:%d] unable to configure CRL file '%s'.\n",
Emeric Brunef42d922012-10-11 16:11:36 +02002145 curproxy->id, srv->id,
2146 srv->conf.file, srv->conf.line, srv->ssl_ctx.crl_file);
2147 cfgerr++;
2148 }
2149 else {
2150 X509_STORE_set_flags(store, X509_V_FLAG_CRL_CHECK|X509_V_FLAG_CRL_CHECK_ALL);
2151 }
2152 }
2153#endif
2154 }
2155
Emeric Brun4f65bff2012-11-16 15:11:00 +01002156 if (global.tune.ssllifetime)
2157 SSL_CTX_set_timeout(srv->ssl_ctx.ctx, global.tune.ssllifetime);
2158
Emeric Brun94324a42012-10-11 14:00:19 +02002159 SSL_CTX_set_session_cache_mode(srv->ssl_ctx.ctx, SSL_SESS_CACHE_OFF);
2160 if (srv->ssl_ctx.ciphers &&
2161 !SSL_CTX_set_cipher_list(srv->ssl_ctx.ctx, srv->ssl_ctx.ciphers)) {
2162 Alert("Proxy '%s', server '%s' [%s:%d] : unable to set SSL cipher list to '%s'.\n",
2163 curproxy->id, srv->id,
2164 srv->conf.file, srv->conf.line, srv->ssl_ctx.ciphers);
2165 cfgerr++;
2166 }
2167
2168 return cfgerr;
2169}
2170
Willy Tarreau2a65ff02012-09-13 17:54:29 +02002171/* Walks down the two trees in bind_conf and prepares all certs. The pointer may
Emeric Brunfc0421f2012-09-07 17:30:07 +02002172 * be NULL, in which case nothing is done. Returns the number of errors
2173 * encountered.
2174 */
Willy Tarreau2a65ff02012-09-13 17:54:29 +02002175int ssl_sock_prepare_all_ctx(struct bind_conf *bind_conf, struct proxy *px)
Emeric Brunfc0421f2012-09-07 17:30:07 +02002176{
2177 struct ebmb_node *node;
2178 struct sni_ctx *sni;
2179 int err = 0;
2180
Willy Tarreau2a65ff02012-09-13 17:54:29 +02002181 if (!bind_conf || !bind_conf->is_ssl)
Emeric Brunfc0421f2012-09-07 17:30:07 +02002182 return 0;
2183
Willy Tarreaufce03112015-01-15 21:32:40 +01002184 /* Automatic memory computations need to know we use SSL there */
2185 global.ssl_used_frontend = 1;
2186
Emeric Brun0bed9942014-10-30 19:25:24 +01002187 if (bind_conf->default_ctx)
2188 err += ssl_sock_prepare_ctx(bind_conf, bind_conf->default_ctx, px);
2189
Willy Tarreau2a65ff02012-09-13 17:54:29 +02002190 node = ebmb_first(&bind_conf->sni_ctx);
Emeric Brunfc0421f2012-09-07 17:30:07 +02002191 while (node) {
2192 sni = ebmb_entry(node, struct sni_ctx, name);
Emeric Brun0bed9942014-10-30 19:25:24 +01002193 if (!sni->order && sni->ctx != bind_conf->default_ctx)
2194 /* only initialize the CTX on its first occurrence and
2195 if it is not the default_ctx */
Willy Tarreau2a65ff02012-09-13 17:54:29 +02002196 err += ssl_sock_prepare_ctx(bind_conf, sni->ctx, px);
Emeric Brunfc0421f2012-09-07 17:30:07 +02002197 node = ebmb_next(node);
2198 }
2199
Willy Tarreau2a65ff02012-09-13 17:54:29 +02002200 node = ebmb_first(&bind_conf->sni_w_ctx);
Emeric Brunfc0421f2012-09-07 17:30:07 +02002201 while (node) {
2202 sni = ebmb_entry(node, struct sni_ctx, name);
Emeric Brun0bed9942014-10-30 19:25:24 +01002203 if (!sni->order && sni->ctx != bind_conf->default_ctx)
2204 /* only initialize the CTX on its first occurrence and
2205 if it is not the default_ctx */
Willy Tarreau2a65ff02012-09-13 17:54:29 +02002206 err += ssl_sock_prepare_ctx(bind_conf, sni->ctx, px);
Emeric Brunfc0421f2012-09-07 17:30:07 +02002207 node = ebmb_next(node);
2208 }
2209 return err;
2210}
2211
Willy Tarreau2a65ff02012-09-13 17:54:29 +02002212/* Walks down the two trees in bind_conf and frees all the certs. The pointer may
Emeric Brunfc0421f2012-09-07 17:30:07 +02002213 * be NULL, in which case nothing is done. The default_ctx is nullified too.
2214 */
Willy Tarreau2a65ff02012-09-13 17:54:29 +02002215void ssl_sock_free_all_ctx(struct bind_conf *bind_conf)
Emeric Brunfc0421f2012-09-07 17:30:07 +02002216{
2217 struct ebmb_node *node, *back;
2218 struct sni_ctx *sni;
2219
Willy Tarreau2a65ff02012-09-13 17:54:29 +02002220 if (!bind_conf || !bind_conf->is_ssl)
Emeric Brunfc0421f2012-09-07 17:30:07 +02002221 return;
2222
Willy Tarreau2a65ff02012-09-13 17:54:29 +02002223 node = ebmb_first(&bind_conf->sni_ctx);
Emeric Brunfc0421f2012-09-07 17:30:07 +02002224 while (node) {
2225 sni = ebmb_entry(node, struct sni_ctx, name);
2226 back = ebmb_next(node);
2227 ebmb_delete(node);
2228 if (!sni->order) /* only free the CTX on its first occurrence */
2229 SSL_CTX_free(sni->ctx);
2230 free(sni);
2231 node = back;
2232 }
2233
Willy Tarreau2a65ff02012-09-13 17:54:29 +02002234 node = ebmb_first(&bind_conf->sni_w_ctx);
Emeric Brunfc0421f2012-09-07 17:30:07 +02002235 while (node) {
2236 sni = ebmb_entry(node, struct sni_ctx, name);
2237 back = ebmb_next(node);
2238 ebmb_delete(node);
2239 if (!sni->order) /* only free the CTX on its first occurrence */
2240 SSL_CTX_free(sni->ctx);
2241 free(sni);
2242 node = back;
2243 }
2244
Willy Tarreau2a65ff02012-09-13 17:54:29 +02002245 bind_conf->default_ctx = NULL;
Emeric Brune1f38db2012-09-03 20:36:47 +02002246}
2247
Emeric Brun46591952012-05-18 15:47:34 +02002248/*
2249 * This function is called if SSL * context is not yet allocated. The function
2250 * is designed to be called before any other data-layer operation and sets the
2251 * handshake flag on the connection. It is safe to call it multiple times.
2252 * It returns 0 on success and -1 in error case.
2253 */
2254static int ssl_sock_init(struct connection *conn)
2255{
2256 /* already initialized */
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02002257 if (conn->xprt_ctx)
Emeric Brun46591952012-05-18 15:47:34 +02002258 return 0;
2259
Willy Tarreau3c728722014-01-23 13:50:42 +01002260 if (!conn_ctrl_ready(conn))
Willy Tarreauf79c8172013-10-21 16:30:56 +02002261 return 0;
2262
Willy Tarreau20879a02012-12-03 16:32:10 +01002263 if (global.maxsslconn && sslconns >= global.maxsslconn) {
2264 conn->err_code = CO_ER_SSL_TOO_MANY;
Willy Tarreau403edff2012-09-06 11:58:37 +02002265 return -1;
Willy Tarreau20879a02012-12-03 16:32:10 +01002266 }
Willy Tarreau403edff2012-09-06 11:58:37 +02002267
Emeric Brun46591952012-05-18 15:47:34 +02002268 /* If it is in client mode initiate SSL session
2269 in connect state otherwise accept state */
Willy Tarreau3fdb3662012-11-12 00:42:33 +01002270 if (objt_server(conn->target)) {
Willy Tarreaufba03cd2014-11-13 13:48:58 +01002271 int may_retry = 1;
2272
2273 retry_connect:
Emeric Brun46591952012-05-18 15:47:34 +02002274 /* Alloc a new SSL session ctx */
Willy Tarreau3fdb3662012-11-12 00:42:33 +01002275 conn->xprt_ctx = SSL_new(objt_server(conn->target)->ssl_ctx.ctx);
Willy Tarreau20879a02012-12-03 16:32:10 +01002276 if (!conn->xprt_ctx) {
Willy Tarreaufba03cd2014-11-13 13:48:58 +01002277 if (may_retry--) {
2278 pool_gc2();
2279 goto retry_connect;
2280 }
Willy Tarreau20879a02012-12-03 16:32:10 +01002281 conn->err_code = CO_ER_SSL_NO_MEM;
Emeric Brun46591952012-05-18 15:47:34 +02002282 return -1;
Willy Tarreau20879a02012-12-03 16:32:10 +01002283 }
Emeric Brun46591952012-05-18 15:47:34 +02002284
Emeric Brun46591952012-05-18 15:47:34 +02002285 /* set fd on SSL session context */
Emeric Brun55476152014-11-12 17:35:37 +01002286 if (!SSL_set_fd(conn->xprt_ctx, conn->t.sock.fd)) {
2287 SSL_free(conn->xprt_ctx);
2288 conn->xprt_ctx = NULL;
Willy Tarreaufba03cd2014-11-13 13:48:58 +01002289 if (may_retry--) {
2290 pool_gc2();
2291 goto retry_connect;
2292 }
Emeric Brun55476152014-11-12 17:35:37 +01002293 conn->err_code = CO_ER_SSL_NO_MEM;
2294 return -1;
2295 }
Emeric Brun46591952012-05-18 15:47:34 +02002296
Evan Broderbe554312013-06-27 00:05:25 -07002297 /* set connection pointer */
Emeric Brun55476152014-11-12 17:35:37 +01002298 if (!SSL_set_app_data(conn->xprt_ctx, conn)) {
2299 SSL_free(conn->xprt_ctx);
2300 conn->xprt_ctx = NULL;
Willy Tarreaufba03cd2014-11-13 13:48:58 +01002301 if (may_retry--) {
2302 pool_gc2();
2303 goto retry_connect;
2304 }
Emeric Brun55476152014-11-12 17:35:37 +01002305 conn->err_code = CO_ER_SSL_NO_MEM;
2306 return -1;
2307 }
2308
2309 SSL_set_connect_state(conn->xprt_ctx);
2310 if (objt_server(conn->target)->ssl_ctx.reused_sess) {
2311 if(!SSL_set_session(conn->xprt_ctx, objt_server(conn->target)->ssl_ctx.reused_sess)) {
2312 SSL_SESSION_free(objt_server(conn->target)->ssl_ctx.reused_sess);
2313 objt_server(conn->target)->ssl_ctx.reused_sess = NULL;
2314 }
2315 }
Evan Broderbe554312013-06-27 00:05:25 -07002316
Emeric Brun46591952012-05-18 15:47:34 +02002317 /* leave init state and start handshake */
Willy Tarreau05737472012-09-04 08:03:39 +02002318 conn->flags |= CO_FL_SSL_WAIT_HS | CO_FL_WAIT_L6_CONN;
Willy Tarreau403edff2012-09-06 11:58:37 +02002319
2320 sslconns++;
Willy Tarreau71b734c2014-01-28 15:19:44 +01002321 totalsslconns++;
Emeric Brun46591952012-05-18 15:47:34 +02002322 return 0;
2323 }
Willy Tarreau3fdb3662012-11-12 00:42:33 +01002324 else if (objt_listener(conn->target)) {
Willy Tarreaufba03cd2014-11-13 13:48:58 +01002325 int may_retry = 1;
2326
2327 retry_accept:
Emeric Brun46591952012-05-18 15:47:34 +02002328 /* Alloc a new SSL session ctx */
Willy Tarreau3fdb3662012-11-12 00:42:33 +01002329 conn->xprt_ctx = SSL_new(objt_listener(conn->target)->bind_conf->default_ctx);
Willy Tarreau20879a02012-12-03 16:32:10 +01002330 if (!conn->xprt_ctx) {
Willy Tarreaufba03cd2014-11-13 13:48:58 +01002331 if (may_retry--) {
2332 pool_gc2();
2333 goto retry_accept;
2334 }
Willy Tarreau20879a02012-12-03 16:32:10 +01002335 conn->err_code = CO_ER_SSL_NO_MEM;
Emeric Brun46591952012-05-18 15:47:34 +02002336 return -1;
Willy Tarreau20879a02012-12-03 16:32:10 +01002337 }
Emeric Brun46591952012-05-18 15:47:34 +02002338
Emeric Brun46591952012-05-18 15:47:34 +02002339 /* set fd on SSL session context */
Emeric Brun55476152014-11-12 17:35:37 +01002340 if (!SSL_set_fd(conn->xprt_ctx, conn->t.sock.fd)) {
2341 SSL_free(conn->xprt_ctx);
2342 conn->xprt_ctx = NULL;
Willy Tarreaufba03cd2014-11-13 13:48:58 +01002343 if (may_retry--) {
2344 pool_gc2();
2345 goto retry_accept;
2346 }
Emeric Brun55476152014-11-12 17:35:37 +01002347 conn->err_code = CO_ER_SSL_NO_MEM;
2348 return -1;
2349 }
Emeric Brun46591952012-05-18 15:47:34 +02002350
Emeric Brune1f38db2012-09-03 20:36:47 +02002351 /* set connection pointer */
Emeric Brun55476152014-11-12 17:35:37 +01002352 if (!SSL_set_app_data(conn->xprt_ctx, conn)) {
2353 SSL_free(conn->xprt_ctx);
2354 conn->xprt_ctx = NULL;
Willy Tarreaufba03cd2014-11-13 13:48:58 +01002355 if (may_retry--) {
2356 pool_gc2();
2357 goto retry_accept;
2358 }
Emeric Brun55476152014-11-12 17:35:37 +01002359 conn->err_code = CO_ER_SSL_NO_MEM;
2360 return -1;
2361 }
2362
2363 SSL_set_accept_state(conn->xprt_ctx);
Emeric Brune1f38db2012-09-03 20:36:47 +02002364
Emeric Brun46591952012-05-18 15:47:34 +02002365 /* leave init state and start handshake */
Willy Tarreau05737472012-09-04 08:03:39 +02002366 conn->flags |= CO_FL_SSL_WAIT_HS | CO_FL_WAIT_L6_CONN;
Willy Tarreau403edff2012-09-06 11:58:37 +02002367
2368 sslconns++;
Willy Tarreau71b734c2014-01-28 15:19:44 +01002369 totalsslconns++;
Emeric Brun46591952012-05-18 15:47:34 +02002370 return 0;
2371 }
2372 /* don't know how to handle such a target */
Willy Tarreau20879a02012-12-03 16:32:10 +01002373 conn->err_code = CO_ER_SSL_NO_TARGET;
Emeric Brun46591952012-05-18 15:47:34 +02002374 return -1;
2375}
2376
2377
2378/* This is the callback which is used when an SSL handshake is pending. It
2379 * updates the FD status if it wants some polling before being called again.
2380 * It returns 0 if it fails in a fatal way or needs to poll to go further,
2381 * otherwise it returns non-zero and removes itself from the connection's
2382 * flags (the bit is provided in <flag> by the caller).
2383 */
2384int ssl_sock_handshake(struct connection *conn, unsigned int flag)
2385{
2386 int ret;
2387
Willy Tarreau3c728722014-01-23 13:50:42 +01002388 if (!conn_ctrl_ready(conn))
Willy Tarreauf79c8172013-10-21 16:30:56 +02002389 return 0;
2390
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02002391 if (!conn->xprt_ctx)
Emeric Brun46591952012-05-18 15:47:34 +02002392 goto out_error;
2393
Emeric Brun674b7432012-11-08 19:21:55 +01002394 /* If we use SSL_do_handshake to process a reneg initiated by
2395 * the remote peer, it sometimes returns SSL_ERROR_SSL.
2396 * Usually SSL_write and SSL_read are used and process implicitly
2397 * the reneg handshake.
2398 * Here we use SSL_peek as a workaround for reneg.
2399 */
2400 if ((conn->flags & CO_FL_CONNECTED) && SSL_renegotiate_pending(conn->xprt_ctx)) {
2401 char c;
2402
2403 ret = SSL_peek(conn->xprt_ctx, &c, 1);
2404 if (ret <= 0) {
2405 /* handshake may have not been completed, let's find why */
2406 ret = SSL_get_error(conn->xprt_ctx, ret);
2407 if (ret == SSL_ERROR_WANT_WRITE) {
2408 /* SSL handshake needs to write, L4 connection may not be ready */
2409 __conn_sock_stop_recv(conn);
Willy Tarreaue1f50c42014-01-22 20:02:06 +01002410 __conn_sock_want_send(conn);
2411 fd_cant_send(conn->t.sock.fd);
Emeric Brun674b7432012-11-08 19:21:55 +01002412 return 0;
2413 }
2414 else if (ret == SSL_ERROR_WANT_READ) {
2415 /* handshake may have been completed but we have
2416 * no more data to read.
2417 */
2418 if (!SSL_renegotiate_pending(conn->xprt_ctx)) {
2419 ret = 1;
2420 goto reneg_ok;
2421 }
2422 /* SSL handshake needs to read, L4 connection is ready */
2423 if (conn->flags & CO_FL_WAIT_L4_CONN)
2424 conn->flags &= ~CO_FL_WAIT_L4_CONN;
2425 __conn_sock_stop_send(conn);
Willy Tarreaue1f50c42014-01-22 20:02:06 +01002426 __conn_sock_want_recv(conn);
2427 fd_cant_recv(conn->t.sock.fd);
Emeric Brun674b7432012-11-08 19:21:55 +01002428 return 0;
2429 }
2430 else if (ret == SSL_ERROR_SYSCALL) {
2431 /* if errno is null, then connection was successfully established */
2432 if (!errno && conn->flags & CO_FL_WAIT_L4_CONN)
2433 conn->flags &= ~CO_FL_WAIT_L4_CONN;
Willy Tarreau20879a02012-12-03 16:32:10 +01002434 if (!conn->err_code) {
Emeric Brun29f037d2014-04-25 19:05:36 +02002435 if (!((SSL *)conn->xprt_ctx)->packet_length) {
2436 if (!errno) {
2437 if (conn->xprt_st & SSL_SOCK_RECV_HEARTBEAT)
2438 conn->err_code = CO_ER_SSL_HANDSHAKE_HB;
2439 else
2440 conn->err_code = CO_ER_SSL_EMPTY;
2441 }
2442 else {
2443 if (conn->xprt_st & SSL_SOCK_RECV_HEARTBEAT)
2444 conn->err_code = CO_ER_SSL_HANDSHAKE_HB;
2445 else
2446 conn->err_code = CO_ER_SSL_ABORT;
2447 }
2448 }
2449 else {
2450 if (conn->xprt_st & SSL_SOCK_RECV_HEARTBEAT)
2451 conn->err_code = CO_ER_SSL_HANDSHAKE_HB;
Willy Tarreau20879a02012-12-03 16:32:10 +01002452 else
Emeric Brun29f037d2014-04-25 19:05:36 +02002453 conn->err_code = CO_ER_SSL_HANDSHAKE;
2454 }
Willy Tarreau20879a02012-12-03 16:32:10 +01002455 }
Emeric Brun674b7432012-11-08 19:21:55 +01002456 goto out_error;
2457 }
2458 else {
2459 /* Fail on all other handshake errors */
2460 /* Note: OpenSSL may leave unread bytes in the socket's
2461 * buffer, causing an RST to be emitted upon close() on
2462 * TCP sockets. We first try to drain possibly pending
2463 * data to avoid this as much as possible.
2464 */
Willy Tarreaud85c4852015-03-13 00:40:28 +01002465 conn_sock_drain(conn);
Willy Tarreau20879a02012-12-03 16:32:10 +01002466 if (!conn->err_code)
Willy Tarreauf51c6982014-04-25 20:02:39 +02002467 conn->err_code = (conn->xprt_st & SSL_SOCK_RECV_HEARTBEAT) ?
2468 CO_ER_SSL_KILLED_HB : CO_ER_SSL_HANDSHAKE;
Emeric Brun674b7432012-11-08 19:21:55 +01002469 goto out_error;
2470 }
2471 }
2472 /* read some data: consider handshake completed */
2473 goto reneg_ok;
2474 }
2475
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02002476 ret = SSL_do_handshake(conn->xprt_ctx);
Emeric Brun46591952012-05-18 15:47:34 +02002477 if (ret != 1) {
2478 /* handshake did not complete, let's find why */
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02002479 ret = SSL_get_error(conn->xprt_ctx, ret);
Emeric Brun46591952012-05-18 15:47:34 +02002480
2481 if (ret == SSL_ERROR_WANT_WRITE) {
2482 /* SSL handshake needs to write, L4 connection may not be ready */
2483 __conn_sock_stop_recv(conn);
Willy Tarreaue1f50c42014-01-22 20:02:06 +01002484 __conn_sock_want_send(conn);
2485 fd_cant_send(conn->t.sock.fd);
Emeric Brun46591952012-05-18 15:47:34 +02002486 return 0;
2487 }
2488 else if (ret == SSL_ERROR_WANT_READ) {
2489 /* SSL handshake needs to read, L4 connection is ready */
2490 if (conn->flags & CO_FL_WAIT_L4_CONN)
2491 conn->flags &= ~CO_FL_WAIT_L4_CONN;
2492 __conn_sock_stop_send(conn);
Willy Tarreaue1f50c42014-01-22 20:02:06 +01002493 __conn_sock_want_recv(conn);
2494 fd_cant_recv(conn->t.sock.fd);
Emeric Brun46591952012-05-18 15:47:34 +02002495 return 0;
2496 }
Willy Tarreau89230192012-09-28 20:22:13 +02002497 else if (ret == SSL_ERROR_SYSCALL) {
2498 /* if errno is null, then connection was successfully established */
2499 if (!errno && conn->flags & CO_FL_WAIT_L4_CONN)
2500 conn->flags &= ~CO_FL_WAIT_L4_CONN;
Willy Tarreau20879a02012-12-03 16:32:10 +01002501
Emeric Brun29f037d2014-04-25 19:05:36 +02002502 if (!((SSL *)conn->xprt_ctx)->packet_length) {
2503 if (!errno) {
2504 if (conn->xprt_st & SSL_SOCK_RECV_HEARTBEAT)
2505 conn->err_code = CO_ER_SSL_HANDSHAKE_HB;
2506 else
2507 conn->err_code = CO_ER_SSL_EMPTY;
2508 }
2509 else {
2510 if (conn->xprt_st & SSL_SOCK_RECV_HEARTBEAT)
2511 conn->err_code = CO_ER_SSL_HANDSHAKE_HB;
2512 else
2513 conn->err_code = CO_ER_SSL_ABORT;
2514 }
2515 }
2516 else {
2517 if (conn->xprt_st & SSL_SOCK_RECV_HEARTBEAT)
2518 conn->err_code = CO_ER_SSL_HANDSHAKE_HB;
Willy Tarreau20879a02012-12-03 16:32:10 +01002519 else
Emeric Brun29f037d2014-04-25 19:05:36 +02002520 conn->err_code = CO_ER_SSL_HANDSHAKE;
2521 }
Willy Tarreau89230192012-09-28 20:22:13 +02002522 goto out_error;
2523 }
Emeric Brun46591952012-05-18 15:47:34 +02002524 else {
2525 /* Fail on all other handshake errors */
Willy Tarreau566dc552012-10-19 20:52:18 +02002526 /* Note: OpenSSL may leave unread bytes in the socket's
2527 * buffer, causing an RST to be emitted upon close() on
2528 * TCP sockets. We first try to drain possibly pending
2529 * data to avoid this as much as possible.
2530 */
Willy Tarreaud85c4852015-03-13 00:40:28 +01002531 conn_sock_drain(conn);
Willy Tarreau20879a02012-12-03 16:32:10 +01002532 if (!conn->err_code)
Willy Tarreauf51c6982014-04-25 20:02:39 +02002533 conn->err_code = (conn->xprt_st & SSL_SOCK_RECV_HEARTBEAT) ?
2534 CO_ER_SSL_KILLED_HB : CO_ER_SSL_HANDSHAKE;
Emeric Brun46591952012-05-18 15:47:34 +02002535 goto out_error;
2536 }
2537 }
2538
Emeric Brun674b7432012-11-08 19:21:55 +01002539reneg_ok:
2540
Emeric Brun46591952012-05-18 15:47:34 +02002541 /* Handshake succeeded */
Willy Tarreau0c9c2722014-05-28 12:28:58 +02002542 if (!SSL_session_reused(conn->xprt_ctx)) {
2543 if (objt_server(conn->target)) {
2544 update_freq_ctr(&global.ssl_be_keys_per_sec, 1);
2545 if (global.ssl_be_keys_per_sec.curr_ctr > global.ssl_be_keys_max)
2546 global.ssl_be_keys_max = global.ssl_be_keys_per_sec.curr_ctr;
2547
Emeric Brun46591952012-05-18 15:47:34 +02002548 /* check if session was reused, if not store current session on server for reuse */
Willy Tarreau3fdb3662012-11-12 00:42:33 +01002549 if (objt_server(conn->target)->ssl_ctx.reused_sess)
2550 SSL_SESSION_free(objt_server(conn->target)->ssl_ctx.reused_sess);
Emeric Brun46591952012-05-18 15:47:34 +02002551
Willy Tarreau2a3fb1c2015-02-05 16:47:07 +01002552 if (!(objt_server(conn->target)->ssl_ctx.options & SRV_SSL_O_NO_REUSE))
2553 objt_server(conn->target)->ssl_ctx.reused_sess = SSL_get1_session(conn->xprt_ctx);
Emeric Brun46591952012-05-18 15:47:34 +02002554 }
Willy Tarreau0c9c2722014-05-28 12:28:58 +02002555 else {
2556 update_freq_ctr(&global.ssl_fe_keys_per_sec, 1);
2557 if (global.ssl_fe_keys_per_sec.curr_ctr > global.ssl_fe_keys_max)
2558 global.ssl_fe_keys_max = global.ssl_fe_keys_per_sec.curr_ctr;
2559 }
Emeric Brun46591952012-05-18 15:47:34 +02002560 }
2561
2562 /* The connection is now established at both layers, it's time to leave */
2563 conn->flags &= ~(flag | CO_FL_WAIT_L4_CONN | CO_FL_WAIT_L6_CONN);
2564 return 1;
2565
2566 out_error:
Emeric Brun644cde02012-12-14 11:21:13 +01002567 /* Clear openssl global errors stack */
2568 ERR_clear_error();
2569
Emeric Brun9fa89732012-10-04 17:09:56 +02002570 /* free resumed session if exists */
Willy Tarreau3fdb3662012-11-12 00:42:33 +01002571 if (objt_server(conn->target) && objt_server(conn->target)->ssl_ctx.reused_sess) {
2572 SSL_SESSION_free(objt_server(conn->target)->ssl_ctx.reused_sess);
2573 objt_server(conn->target)->ssl_ctx.reused_sess = NULL;
Emeric Brun9fa89732012-10-04 17:09:56 +02002574 }
2575
Emeric Brun46591952012-05-18 15:47:34 +02002576 /* Fail on all other handshake errors */
2577 conn->flags |= CO_FL_ERROR;
Willy Tarreau20879a02012-12-03 16:32:10 +01002578 if (!conn->err_code)
2579 conn->err_code = CO_ER_SSL_HANDSHAKE;
Emeric Brun46591952012-05-18 15:47:34 +02002580 return 0;
2581}
2582
2583/* Receive up to <count> bytes from connection <conn>'s socket and store them
Willy Tarreauabf08d92014-01-14 11:31:27 +01002584 * into buffer <buf>. Only one call to recv() is performed, unless the
Emeric Brun46591952012-05-18 15:47:34 +02002585 * buffer wraps, in which case a second call may be performed. The connection's
2586 * flags are updated with whatever special event is detected (error, read0,
2587 * empty). The caller is responsible for taking care of those events and
2588 * avoiding the call if inappropriate. The function does not call the
2589 * connection's polling update function, so the caller is responsible for this.
2590 */
2591static int ssl_sock_to_buf(struct connection *conn, struct buffer *buf, int count)
2592{
2593 int ret, done = 0;
Willy Tarreauabf08d92014-01-14 11:31:27 +01002594 int try;
Emeric Brun46591952012-05-18 15:47:34 +02002595
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02002596 if (!conn->xprt_ctx)
Emeric Brun46591952012-05-18 15:47:34 +02002597 goto out_error;
2598
2599 if (conn->flags & CO_FL_HANDSHAKE)
2600 /* a handshake was requested */
2601 return 0;
2602
Willy Tarreauabf08d92014-01-14 11:31:27 +01002603 /* let's realign the buffer to optimize I/O */
2604 if (buffer_empty(buf))
Emeric Brun46591952012-05-18 15:47:34 +02002605 buf->p = buf->data;
Emeric Brun46591952012-05-18 15:47:34 +02002606
2607 /* read the largest possible block. For this, we perform only one call
2608 * to recv() unless the buffer wraps and we exactly fill the first hunk,
2609 * in which case we accept to do it once again. A new attempt is made on
2610 * EINTR too.
2611 */
Willy Tarreau00b0fb92014-01-17 11:09:40 +01002612 while (count > 0) {
Willy Tarreauabf08d92014-01-14 11:31:27 +01002613 /* first check if we have some room after p+i */
2614 try = buf->data + buf->size - (buf->p + buf->i);
2615 /* otherwise continue between data and p-o */
2616 if (try <= 0) {
2617 try = buf->p - (buf->data + buf->o);
2618 if (try <= 0)
2619 break;
2620 }
2621 if (try > count)
2622 try = count;
2623
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02002624 ret = SSL_read(conn->xprt_ctx, bi_end(buf), try);
Emeric Brune1f38db2012-09-03 20:36:47 +02002625 if (conn->flags & CO_FL_ERROR) {
2626 /* CO_FL_ERROR may be set by ssl_sock_infocbk */
Emeric Brun644cde02012-12-14 11:21:13 +01002627 goto out_error;
Emeric Brune1f38db2012-09-03 20:36:47 +02002628 }
Emeric Brun46591952012-05-18 15:47:34 +02002629 if (ret > 0) {
2630 buf->i += ret;
2631 done += ret;
2632 if (ret < try)
2633 break;
2634 count -= ret;
Emeric Brun46591952012-05-18 15:47:34 +02002635 }
2636 else if (ret == 0) {
Emeric Brun644cde02012-12-14 11:21:13 +01002637 ret = SSL_get_error(conn->xprt_ctx, ret);
2638 if (ret != SSL_ERROR_ZERO_RETURN) {
Emeric Brun1c646862012-12-14 12:33:41 +01002639 /* error on protocol or underlying transport */
2640 if ((ret != SSL_ERROR_SYSCALL)
2641 || (errno && (errno != EAGAIN)))
2642 conn->flags |= CO_FL_ERROR;
2643
Emeric Brun644cde02012-12-14 11:21:13 +01002644 /* Clear openssl global errors stack */
2645 ERR_clear_error();
2646 }
Emeric Brun46591952012-05-18 15:47:34 +02002647 goto read0;
2648 }
2649 else {
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02002650 ret = SSL_get_error(conn->xprt_ctx, ret);
Emeric Brun46591952012-05-18 15:47:34 +02002651 if (ret == SSL_ERROR_WANT_WRITE) {
Emeric Brun8af8dd12012-11-08 17:56:20 +01002652 /* handshake is running, and it needs to enable write */
Emeric Brun46591952012-05-18 15:47:34 +02002653 conn->flags |= CO_FL_SSL_WAIT_HS;
Emeric Brun8af8dd12012-11-08 17:56:20 +01002654 __conn_sock_want_send(conn);
Emeric Brun46591952012-05-18 15:47:34 +02002655 break;
2656 }
2657 else if (ret == SSL_ERROR_WANT_READ) {
Emeric Brun282a76a2012-11-08 18:02:56 +01002658 if (SSL_renegotiate_pending(conn->xprt_ctx)) {
2659 /* handshake is running, and it may need to re-enable read */
2660 conn->flags |= CO_FL_SSL_WAIT_HS;
2661 __conn_sock_want_recv(conn);
2662 break;
2663 }
Emeric Brun46591952012-05-18 15:47:34 +02002664 /* we need to poll for retry a read later */
Willy Tarreaue1f50c42014-01-22 20:02:06 +01002665 fd_cant_recv(conn->t.sock.fd);
Emeric Brun46591952012-05-18 15:47:34 +02002666 break;
2667 }
2668 /* otherwise it's a real error */
2669 goto out_error;
2670 }
2671 }
2672 return done;
2673
2674 read0:
2675 conn_sock_read0(conn);
2676 return done;
2677 out_error:
Emeric Brun644cde02012-12-14 11:21:13 +01002678 /* Clear openssl global errors stack */
2679 ERR_clear_error();
2680
Emeric Brun46591952012-05-18 15:47:34 +02002681 conn->flags |= CO_FL_ERROR;
2682 return done;
2683}
2684
2685
2686/* Send all pending bytes from buffer <buf> to connection <conn>'s socket.
Willy Tarreau1049b1f2014-02-02 01:51:17 +01002687 * <flags> may contain some CO_SFL_* flags to hint the system about other
2688 * pending data for example, but this flag is ignored at the moment.
Emeric Brun46591952012-05-18 15:47:34 +02002689 * Only one call to send() is performed, unless the buffer wraps, in which case
2690 * a second call may be performed. The connection's flags are updated with
2691 * whatever special event is detected (error, empty). The caller is responsible
2692 * for taking care of those events and avoiding the call if inappropriate. The
2693 * function does not call the connection's polling update function, so the caller
2694 * is responsible for this.
2695 */
2696static int ssl_sock_from_buf(struct connection *conn, struct buffer *buf, int flags)
2697{
2698 int ret, try, done;
2699
2700 done = 0;
2701
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02002702 if (!conn->xprt_ctx)
Emeric Brun46591952012-05-18 15:47:34 +02002703 goto out_error;
2704
2705 if (conn->flags & CO_FL_HANDSHAKE)
2706 /* a handshake was requested */
2707 return 0;
2708
2709 /* send the largest possible block. For this we perform only one call
2710 * to send() unless the buffer wraps and we exactly fill the first hunk,
2711 * in which case we accept to do it once again.
2712 */
2713 while (buf->o) {
Kevin Hestercad82342013-05-30 15:12:41 -07002714 try = bo_contig_data(buf);
Willy Tarreaubfd59462013-02-21 07:46:09 +01002715
Willy Tarreau7bed9452014-02-02 02:00:24 +01002716 if (!(flags & CO_SFL_STREAMER) &&
Willy Tarreau518cedd2014-02-17 15:43:01 +01002717 !(conn->xprt_st & SSL_SOCK_SEND_UNLIMITED) &&
2718 global.tune.ssl_max_record && try > global.tune.ssl_max_record) {
Willy Tarreaubfd59462013-02-21 07:46:09 +01002719 try = global.tune.ssl_max_record;
Willy Tarreau518cedd2014-02-17 15:43:01 +01002720 }
2721 else {
2722 /* we need to keep the information about the fact that
2723 * we're not limiting the upcoming send(), because if it
2724 * fails, we'll have to retry with at least as many data.
2725 */
2726 conn->xprt_st |= SSL_SOCK_SEND_UNLIMITED;
2727 }
Willy Tarreaubfd59462013-02-21 07:46:09 +01002728
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02002729 ret = SSL_write(conn->xprt_ctx, bo_ptr(buf), try);
Willy Tarreau518cedd2014-02-17 15:43:01 +01002730
Emeric Brune1f38db2012-09-03 20:36:47 +02002731 if (conn->flags & CO_FL_ERROR) {
2732 /* CO_FL_ERROR may be set by ssl_sock_infocbk */
Emeric Brun644cde02012-12-14 11:21:13 +01002733 goto out_error;
Emeric Brune1f38db2012-09-03 20:36:47 +02002734 }
Emeric Brun46591952012-05-18 15:47:34 +02002735 if (ret > 0) {
Willy Tarreau518cedd2014-02-17 15:43:01 +01002736 conn->xprt_st &= ~SSL_SOCK_SEND_UNLIMITED;
2737
Emeric Brun46591952012-05-18 15:47:34 +02002738 buf->o -= ret;
2739 done += ret;
2740
Willy Tarreau5fb38032012-12-16 19:39:09 +01002741 if (likely(buffer_empty(buf)))
Emeric Brun46591952012-05-18 15:47:34 +02002742 /* optimize data alignment in the buffer */
2743 buf->p = buf->data;
2744
2745 /* if the system buffer is full, don't insist */
2746 if (ret < try)
2747 break;
2748 }
2749 else {
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02002750 ret = SSL_get_error(conn->xprt_ctx, ret);
Emeric Brun46591952012-05-18 15:47:34 +02002751 if (ret == SSL_ERROR_WANT_WRITE) {
Emeric Brun282a76a2012-11-08 18:02:56 +01002752 if (SSL_renegotiate_pending(conn->xprt_ctx)) {
2753 /* handshake is running, and it may need to re-enable write */
2754 conn->flags |= CO_FL_SSL_WAIT_HS;
2755 __conn_sock_want_send(conn);
2756 break;
2757 }
Emeric Brun46591952012-05-18 15:47:34 +02002758 /* we need to poll to retry a write later */
Willy Tarreaue1f50c42014-01-22 20:02:06 +01002759 fd_cant_send(conn->t.sock.fd);
Emeric Brun46591952012-05-18 15:47:34 +02002760 break;
2761 }
2762 else if (ret == SSL_ERROR_WANT_READ) {
Emeric Brun8af8dd12012-11-08 17:56:20 +01002763 /* handshake is running, and it needs to enable read */
Emeric Brun46591952012-05-18 15:47:34 +02002764 conn->flags |= CO_FL_SSL_WAIT_HS;
Emeric Brun8af8dd12012-11-08 17:56:20 +01002765 __conn_sock_want_recv(conn);
Emeric Brun46591952012-05-18 15:47:34 +02002766 break;
2767 }
2768 goto out_error;
2769 }
2770 }
2771 return done;
2772
2773 out_error:
Emeric Brun644cde02012-12-14 11:21:13 +01002774 /* Clear openssl global errors stack */
2775 ERR_clear_error();
2776
Emeric Brun46591952012-05-18 15:47:34 +02002777 conn->flags |= CO_FL_ERROR;
2778 return done;
2779}
2780
Emeric Brun46591952012-05-18 15:47:34 +02002781static void ssl_sock_close(struct connection *conn) {
2782
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02002783 if (conn->xprt_ctx) {
2784 SSL_free(conn->xprt_ctx);
2785 conn->xprt_ctx = NULL;
Willy Tarreau403edff2012-09-06 11:58:37 +02002786 sslconns--;
Emeric Brun46591952012-05-18 15:47:34 +02002787 }
Emeric Brun46591952012-05-18 15:47:34 +02002788}
2789
2790/* This function tries to perform a clean shutdown on an SSL connection, and in
2791 * any case, flags the connection as reusable if no handshake was in progress.
2792 */
2793static void ssl_sock_shutw(struct connection *conn, int clean)
2794{
2795 if (conn->flags & CO_FL_HANDSHAKE)
2796 return;
2797 /* no handshake was in progress, try a clean ssl shutdown */
Emeric Brun644cde02012-12-14 11:21:13 +01002798 if (clean && (SSL_shutdown(conn->xprt_ctx) <= 0)) {
2799 /* Clear openssl global errors stack */
2800 ERR_clear_error();
2801 }
Emeric Brun46591952012-05-18 15:47:34 +02002802
2803 /* force flag on ssl to keep session in cache regardless shutdown result */
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02002804 SSL_set_shutdown(conn->xprt_ctx, SSL_SENT_SHUTDOWN);
Emeric Brun46591952012-05-18 15:47:34 +02002805}
2806
Willy Tarreauffc3fcd2012-10-12 20:17:54 +02002807/* used for logging, may be changed for a sample fetch later */
2808const char *ssl_sock_get_cipher_name(struct connection *conn)
2809{
2810 if (!conn->xprt && !conn->xprt_ctx)
2811 return NULL;
2812 return SSL_get_cipher_name(conn->xprt_ctx);
2813}
2814
2815/* used for logging, may be changed for a sample fetch later */
2816const char *ssl_sock_get_proto_version(struct connection *conn)
2817{
2818 if (!conn->xprt && !conn->xprt_ctx)
2819 return NULL;
2820 return SSL_get_version(conn->xprt_ctx);
2821}
2822
Willy Tarreau8d598402012-10-22 17:58:39 +02002823/* Extract a serial from a cert, and copy it to a chunk.
2824 * Returns 1 if serial is found and copied, 0 if no serial found and
2825 * -1 if output is not large enough.
2826 */
2827static int
2828ssl_sock_get_serial(X509 *crt, struct chunk *out)
2829{
2830 ASN1_INTEGER *serial;
2831
2832 serial = X509_get_serialNumber(crt);
2833 if (!serial)
2834 return 0;
2835
2836 if (out->size < serial->length)
2837 return -1;
2838
2839 memcpy(out->str, serial->data, serial->length);
2840 out->len = serial->length;
2841 return 1;
2842}
2843
Emeric Brun43e79582014-10-29 19:03:26 +01002844/* Extract a cert to der, and copy it to a chunk.
2845 * Returns 1 if cert is found and copied, 0 on der convertion failure and
2846 * -1 if output is not large enough.
2847 */
2848static int
2849ssl_sock_crt2der(X509 *crt, struct chunk *out)
2850{
2851 int len;
2852 unsigned char *p = (unsigned char *)out->str;;
2853
2854 len =i2d_X509(crt, NULL);
2855 if (len <= 0)
2856 return 1;
2857
2858 if (out->size < len)
2859 return -1;
2860
2861 i2d_X509(crt,&p);
2862 out->len = len;
2863 return 1;
2864}
2865
Emeric Brunce5ad802012-10-22 14:11:22 +02002866
2867/* Copy Date in ASN1_UTCTIME format in struct chunk out.
2868 * Returns 1 if serial is found and copied, 0 if no valid time found
2869 * and -1 if output is not large enough.
2870 */
2871static int
2872ssl_sock_get_time(ASN1_TIME *tm, struct chunk *out)
2873{
2874 if (tm->type == V_ASN1_GENERALIZEDTIME) {
2875 ASN1_GENERALIZEDTIME *gentm = (ASN1_GENERALIZEDTIME *)tm;
2876
2877 if (gentm->length < 12)
2878 return 0;
2879 if (gentm->data[0] != 0x32 || gentm->data[1] != 0x30)
2880 return 0;
2881 if (out->size < gentm->length-2)
2882 return -1;
2883
2884 memcpy(out->str, gentm->data+2, gentm->length-2);
2885 out->len = gentm->length-2;
2886 return 1;
2887 }
2888 else if (tm->type == V_ASN1_UTCTIME) {
2889 ASN1_UTCTIME *utctm = (ASN1_UTCTIME *)tm;
2890
2891 if (utctm->length < 10)
2892 return 0;
2893 if (utctm->data[0] >= 0x35)
2894 return 0;
2895 if (out->size < utctm->length)
2896 return -1;
2897
2898 memcpy(out->str, utctm->data, utctm->length);
2899 out->len = utctm->length;
2900 return 1;
2901 }
2902
2903 return 0;
2904}
2905
Emeric Brun87855892012-10-17 17:39:35 +02002906/* Extract an entry from a X509_NAME and copy its value to an output chunk.
2907 * Returns 1 if entry found, 0 if entry not found, or -1 if output not large enough.
2908 */
2909static int
2910ssl_sock_get_dn_entry(X509_NAME *a, const struct chunk *entry, int pos, struct chunk *out)
2911{
2912 X509_NAME_ENTRY *ne;
2913 int i, j, n;
2914 int cur = 0;
2915 const char *s;
2916 char tmp[128];
2917
2918 out->len = 0;
2919 for (i = 0; i < sk_X509_NAME_ENTRY_num(a->entries); i++) {
2920 if (pos < 0)
2921 j = (sk_X509_NAME_ENTRY_num(a->entries)-1) - i;
2922 else
2923 j = i;
2924
2925 ne = sk_X509_NAME_ENTRY_value(a->entries, j);
2926 n = OBJ_obj2nid(ne->object);
2927 if ((n == NID_undef) || ((s = OBJ_nid2sn(n)) == NULL)) {
2928 i2t_ASN1_OBJECT(tmp, sizeof(tmp), ne->object);
2929 s = tmp;
2930 }
2931
2932 if (chunk_strcasecmp(entry, s) != 0)
2933 continue;
2934
2935 if (pos < 0)
2936 cur--;
2937 else
2938 cur++;
2939
2940 if (cur != pos)
2941 continue;
2942
2943 if (ne->value->length > out->size)
2944 return -1;
2945
2946 memcpy(out->str, ne->value->data, ne->value->length);
2947 out->len = ne->value->length;
2948 return 1;
2949 }
2950
2951 return 0;
2952
2953}
2954
2955/* Extract and format full DN from a X509_NAME and copy result into a chunk
2956 * Returns 1 if dn entries exits, 0 if no dn entry found or -1 if output is not large enough.
2957 */
2958static int
2959ssl_sock_get_dn_oneline(X509_NAME *a, struct chunk *out)
2960{
2961 X509_NAME_ENTRY *ne;
2962 int i, n, ln;
2963 int l = 0;
2964 const char *s;
2965 char *p;
2966 char tmp[128];
2967
2968 out->len = 0;
2969 p = out->str;
2970 for (i = 0; i < sk_X509_NAME_ENTRY_num(a->entries); i++) {
2971 ne = sk_X509_NAME_ENTRY_value(a->entries, i);
2972 n = OBJ_obj2nid(ne->object);
2973 if ((n == NID_undef) || ((s = OBJ_nid2sn(n)) == NULL)) {
2974 i2t_ASN1_OBJECT(tmp, sizeof(tmp), ne->object);
2975 s = tmp;
2976 }
2977 ln = strlen(s);
2978
2979 l += 1 + ln + 1 + ne->value->length;
2980 if (l > out->size)
2981 return -1;
2982 out->len = l;
2983
2984 *(p++)='/';
2985 memcpy(p, s, ln);
2986 p += ln;
2987 *(p++)='=';
2988 memcpy(p, ne->value->data, ne->value->length);
2989 p += ne->value->length;
2990 }
2991
2992 if (!out->len)
2993 return 0;
2994
2995 return 1;
2996}
2997
David Safb76832014-05-08 23:42:08 -04002998char *ssl_sock_get_version(struct connection *conn)
2999{
3000 if (!ssl_sock_is_ssl(conn))
3001 return NULL;
3002
3003 return (char *)SSL_get_version(conn->xprt_ctx);
3004}
3005
Emeric Brun0abf8362014-06-24 18:26:41 +02003006/* Extract peer certificate's common name into the chunk dest
3007 * Returns
3008 * the len of the extracted common name
3009 * or 0 if no CN found in DN
3010 * or -1 on error case (i.e. no peer certificate)
3011 */
3012int ssl_sock_get_remote_common_name(struct connection *conn, struct chunk *dest)
David Safb76832014-05-08 23:42:08 -04003013{
3014 X509 *crt = NULL;
3015 X509_NAME *name;
David Safb76832014-05-08 23:42:08 -04003016 const char find_cn[] = "CN";
3017 const struct chunk find_cn_chunk = {
3018 .str = (char *)&find_cn,
3019 .len = sizeof(find_cn)-1
3020 };
Emeric Brun0abf8362014-06-24 18:26:41 +02003021 int result = -1;
David Safb76832014-05-08 23:42:08 -04003022
3023 if (!ssl_sock_is_ssl(conn))
Emeric Brun0abf8362014-06-24 18:26:41 +02003024 goto out;
David Safb76832014-05-08 23:42:08 -04003025
3026 /* SSL_get_peer_certificate, it increase X509 * ref count */
3027 crt = SSL_get_peer_certificate(conn->xprt_ctx);
3028 if (!crt)
3029 goto out;
3030
3031 name = X509_get_subject_name(crt);
3032 if (!name)
3033 goto out;
David Safb76832014-05-08 23:42:08 -04003034
Emeric Brun0abf8362014-06-24 18:26:41 +02003035 result = ssl_sock_get_dn_entry(name, &find_cn_chunk, 1, dest);
3036out:
David Safb76832014-05-08 23:42:08 -04003037 if (crt)
3038 X509_free(crt);
3039
3040 return result;
3041}
3042
Dave McCowan328fb582014-07-30 10:39:13 -04003043/* returns 1 if client passed a certificate for this session, 0 if not */
3044int ssl_sock_get_cert_used_sess(struct connection *conn)
3045{
3046 X509 *crt = NULL;
3047
3048 if (!ssl_sock_is_ssl(conn))
3049 return 0;
3050
3051 /* SSL_get_peer_certificate, it increase X509 * ref count */
3052 crt = SSL_get_peer_certificate(conn->xprt_ctx);
3053 if (!crt)
3054 return 0;
3055
3056 X509_free(crt);
3057 return 1;
3058}
3059
3060/* returns 1 if client passed a certificate for this connection, 0 if not */
3061int ssl_sock_get_cert_used_conn(struct connection *conn)
David Safb76832014-05-08 23:42:08 -04003062{
3063 if (!ssl_sock_is_ssl(conn))
3064 return 0;
3065
3066 return SSL_SOCK_ST_FL_VERIFY_DONE & conn->xprt_st ? 1 : 0;
3067}
3068
3069/* returns result from SSL verify */
3070unsigned int ssl_sock_get_verify_result(struct connection *conn)
3071{
3072 if (!ssl_sock_is_ssl(conn))
3073 return (unsigned int)X509_V_ERR_APPLICATION_VERIFICATION;
3074
3075 return (unsigned int)SSL_get_verify_result(conn->xprt_ctx);
3076}
3077
Willy Tarreau7875d092012-09-10 08:20:03 +02003078/***** Below are some sample fetching functions for ACL/patterns *****/
3079
Emeric Brune64aef12012-09-21 13:15:06 +02003080/* boolean, returns true if client cert was present */
3081static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02003082smp_fetch_ssl_fc_has_crt(const struct arg *args, struct sample *smp, const char *kw, void *private)
Emeric Brune64aef12012-09-21 13:15:06 +02003083{
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003084 struct connection *conn;
3085
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02003086 conn = objt_conn(smp->sess->origin);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003087 if (!conn || conn->xprt != &ssl_sock)
Emeric Brune64aef12012-09-21 13:15:06 +02003088 return 0;
3089
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003090 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brune64aef12012-09-21 13:15:06 +02003091 smp->flags |= SMP_F_MAY_CHANGE;
3092 return 0;
3093 }
3094
3095 smp->flags = 0;
3096 smp->type = SMP_T_BOOL;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003097 smp->data.uint = SSL_SOCK_ST_FL_VERIFY_DONE & conn->xprt_st ? 1 : 0;
Emeric Brune64aef12012-09-21 13:15:06 +02003098
3099 return 1;
3100}
3101
Emeric Brun43e79582014-10-29 19:03:26 +01003102/* binary, returns a certificate in a binary chunk (der/raw).
3103 * The 5th keyword char is used to know if SSL_get_certificate or SSL_get_peer_certificate
3104 * should be use.
3105 */
3106static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02003107smp_fetch_ssl_x_der(const struct arg *args, struct sample *smp, const char *kw, void *private)
Emeric Brun43e79582014-10-29 19:03:26 +01003108{
3109 int cert_peer = (kw[4] == 'c') ? 1 : 0;
3110 X509 *crt = NULL;
3111 int ret = 0;
3112 struct chunk *smp_trash;
3113 struct connection *conn;
3114
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02003115 conn = objt_conn(smp->sess->origin);
Emeric Brun43e79582014-10-29 19:03:26 +01003116 if (!conn || conn->xprt != &ssl_sock)
3117 return 0;
3118
3119 if (!(conn->flags & CO_FL_CONNECTED)) {
3120 smp->flags |= SMP_F_MAY_CHANGE;
3121 return 0;
3122 }
3123
3124 if (cert_peer)
3125 crt = SSL_get_peer_certificate(conn->xprt_ctx);
3126 else
3127 crt = SSL_get_certificate(conn->xprt_ctx);
3128
3129 if (!crt)
3130 goto out;
3131
3132 smp_trash = get_trash_chunk();
3133 if (ssl_sock_crt2der(crt, smp_trash) <= 0)
3134 goto out;
3135
3136 smp->data.str = *smp_trash;
3137 smp->type = SMP_T_BIN;
3138 ret = 1;
3139out:
3140 /* SSL_get_peer_certificate, it increase X509 * ref count */
3141 if (cert_peer && crt)
3142 X509_free(crt);
3143 return ret;
3144}
3145
Emeric Brunba841a12014-04-30 17:05:08 +02003146/* binary, returns serial of certificate in a binary chunk.
3147 * The 5th keyword char is used to know if SSL_get_certificate or SSL_get_peer_certificate
3148 * should be use.
3149 */
Willy Tarreau8d598402012-10-22 17:58:39 +02003150static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02003151smp_fetch_ssl_x_serial(const struct arg *args, struct sample *smp, const char *kw, void *private)
Willy Tarreau8d598402012-10-22 17:58:39 +02003152{
Emeric Brunba841a12014-04-30 17:05:08 +02003153 int cert_peer = (kw[4] == 'c') ? 1 : 0;
Willy Tarreau8d598402012-10-22 17:58:39 +02003154 X509 *crt = NULL;
3155 int ret = 0;
3156 struct chunk *smp_trash;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003157 struct connection *conn;
3158
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02003159 conn = objt_conn(smp->sess->origin);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003160 if (!conn || conn->xprt != &ssl_sock)
Willy Tarreau8d598402012-10-22 17:58:39 +02003161 return 0;
3162
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003163 if (!(conn->flags & CO_FL_CONNECTED)) {
Willy Tarreau8d598402012-10-22 17:58:39 +02003164 smp->flags |= SMP_F_MAY_CHANGE;
3165 return 0;
3166 }
3167
Emeric Brunba841a12014-04-30 17:05:08 +02003168 if (cert_peer)
3169 crt = SSL_get_peer_certificate(conn->xprt_ctx);
3170 else
3171 crt = SSL_get_certificate(conn->xprt_ctx);
3172
Willy Tarreau8d598402012-10-22 17:58:39 +02003173 if (!crt)
3174 goto out;
3175
Willy Tarreau47ca5452012-12-23 20:22:19 +01003176 smp_trash = get_trash_chunk();
Willy Tarreau8d598402012-10-22 17:58:39 +02003177 if (ssl_sock_get_serial(crt, smp_trash) <= 0)
3178 goto out;
3179
3180 smp->data.str = *smp_trash;
3181 smp->type = SMP_T_BIN;
3182 ret = 1;
3183out:
Emeric Brunba841a12014-04-30 17:05:08 +02003184 /* SSL_get_peer_certificate, it increase X509 * ref count */
3185 if (cert_peer && crt)
Willy Tarreau8d598402012-10-22 17:58:39 +02003186 X509_free(crt);
3187 return ret;
3188}
Emeric Brune64aef12012-09-21 13:15:06 +02003189
Emeric Brunba841a12014-04-30 17:05:08 +02003190/* binary, returns the client certificate's SHA-1 fingerprint (SHA-1 hash of DER-encoded certificate) in a binary chunk.
3191 * The 5th keyword char is used to know if SSL_get_certificate or SSL_get_peer_certificate
3192 * should be use.
3193 */
James Votha051b4a2013-05-14 20:37:59 +02003194static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02003195smp_fetch_ssl_x_sha1(const struct arg *args, struct sample *smp, const char *kw, void *private)
James Votha051b4a2013-05-14 20:37:59 +02003196{
Emeric Brunba841a12014-04-30 17:05:08 +02003197 int cert_peer = (kw[4] == 'c') ? 1 : 0;
James Votha051b4a2013-05-14 20:37:59 +02003198 X509 *crt = NULL;
3199 const EVP_MD *digest;
3200 int ret = 0;
3201 struct chunk *smp_trash;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003202 struct connection *conn;
James Votha051b4a2013-05-14 20:37:59 +02003203
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02003204 conn = objt_conn(smp->sess->origin);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003205 if (!conn || conn->xprt != &ssl_sock)
3206 return 0;
3207
3208 if (!(conn->flags & CO_FL_CONNECTED)) {
James Votha051b4a2013-05-14 20:37:59 +02003209 smp->flags |= SMP_F_MAY_CHANGE;
3210 return 0;
3211 }
3212
Emeric Brunba841a12014-04-30 17:05:08 +02003213 if (cert_peer)
3214 crt = SSL_get_peer_certificate(conn->xprt_ctx);
3215 else
3216 crt = SSL_get_certificate(conn->xprt_ctx);
James Votha051b4a2013-05-14 20:37:59 +02003217 if (!crt)
3218 goto out;
3219
3220 smp_trash = get_trash_chunk();
3221 digest = EVP_sha1();
3222 X509_digest(crt, digest, (unsigned char *)smp_trash->str, (unsigned int *)&smp_trash->len);
3223
3224 smp->data.str = *smp_trash;
3225 smp->type = SMP_T_BIN;
3226 ret = 1;
3227out:
Emeric Brunba841a12014-04-30 17:05:08 +02003228 /* SSL_get_peer_certificate, it increase X509 * ref count */
3229 if (cert_peer && crt)
James Votha051b4a2013-05-14 20:37:59 +02003230 X509_free(crt);
3231 return ret;
3232}
3233
Emeric Brunba841a12014-04-30 17:05:08 +02003234/* string, returns certificate's notafter date in ASN1_UTCTIME format.
3235 * The 5th keyword char is used to know if SSL_get_certificate or SSL_get_peer_certificate
3236 * should be use.
3237 */
Emeric Brunce5ad802012-10-22 14:11:22 +02003238static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02003239smp_fetch_ssl_x_notafter(const struct arg *args, struct sample *smp, const char *kw, void *private)
Emeric Brunce5ad802012-10-22 14:11:22 +02003240{
Emeric Brunba841a12014-04-30 17:05:08 +02003241 int cert_peer = (kw[4] == 'c') ? 1 : 0;
Emeric Brunce5ad802012-10-22 14:11:22 +02003242 X509 *crt = NULL;
3243 int ret = 0;
3244 struct chunk *smp_trash;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003245 struct connection *conn;
Emeric Brunce5ad802012-10-22 14:11:22 +02003246
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02003247 conn = objt_conn(smp->sess->origin);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003248 if (!conn || conn->xprt != &ssl_sock)
3249 return 0;
3250
3251 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brunce5ad802012-10-22 14:11:22 +02003252 smp->flags |= SMP_F_MAY_CHANGE;
3253 return 0;
3254 }
3255
Emeric Brunba841a12014-04-30 17:05:08 +02003256 if (cert_peer)
3257 crt = SSL_get_peer_certificate(conn->xprt_ctx);
3258 else
3259 crt = SSL_get_certificate(conn->xprt_ctx);
Emeric Brunce5ad802012-10-22 14:11:22 +02003260 if (!crt)
3261 goto out;
3262
Willy Tarreau47ca5452012-12-23 20:22:19 +01003263 smp_trash = get_trash_chunk();
Emeric Brunce5ad802012-10-22 14:11:22 +02003264 if (ssl_sock_get_time(X509_get_notAfter(crt), smp_trash) <= 0)
3265 goto out;
3266
3267 smp->data.str = *smp_trash;
3268 smp->type = SMP_T_STR;
3269 ret = 1;
3270out:
Emeric Brunba841a12014-04-30 17:05:08 +02003271 /* SSL_get_peer_certificate, it increase X509 * ref count */
3272 if (cert_peer && crt)
Emeric Brunce5ad802012-10-22 14:11:22 +02003273 X509_free(crt);
3274 return ret;
3275}
3276
Emeric Brunba841a12014-04-30 17:05:08 +02003277/* string, returns a string of a formatted full dn \C=..\O=..\OU=.. \CN=.. of certificate's issuer
3278 * The 5th keyword char is used to know if SSL_get_certificate or SSL_get_peer_certificate
3279 * should be use.
3280 */
Emeric Brun87855892012-10-17 17:39:35 +02003281static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02003282smp_fetch_ssl_x_i_dn(const struct arg *args, struct sample *smp, const char *kw, void *private)
Emeric Brun87855892012-10-17 17:39:35 +02003283{
Emeric Brunba841a12014-04-30 17:05:08 +02003284 int cert_peer = (kw[4] == 'c') ? 1 : 0;
Emeric Brun87855892012-10-17 17:39:35 +02003285 X509 *crt = NULL;
3286 X509_NAME *name;
3287 int ret = 0;
3288 struct chunk *smp_trash;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003289 struct connection *conn;
Emeric Brun87855892012-10-17 17:39:35 +02003290
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02003291 conn = objt_conn(smp->sess->origin);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003292 if (!conn || conn->xprt != &ssl_sock)
3293 return 0;
3294
3295 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brun87855892012-10-17 17:39:35 +02003296 smp->flags |= SMP_F_MAY_CHANGE;
3297 return 0;
3298 }
3299
Emeric Brunba841a12014-04-30 17:05:08 +02003300 if (cert_peer)
3301 crt = SSL_get_peer_certificate(conn->xprt_ctx);
3302 else
3303 crt = SSL_get_certificate(conn->xprt_ctx);
Emeric Brun87855892012-10-17 17:39:35 +02003304 if (!crt)
3305 goto out;
3306
3307 name = X509_get_issuer_name(crt);
3308 if (!name)
3309 goto out;
3310
Willy Tarreau47ca5452012-12-23 20:22:19 +01003311 smp_trash = get_trash_chunk();
Emeric Brun87855892012-10-17 17:39:35 +02003312 if (args && args[0].type == ARGT_STR) {
3313 int pos = 1;
3314
3315 if (args[1].type == ARGT_SINT)
3316 pos = args[1].data.sint;
3317 else if (args[1].type == ARGT_UINT)
3318 pos =(int)args[1].data.uint;
3319
3320 if (ssl_sock_get_dn_entry(name, &args[0].data.str, pos, smp_trash) <= 0)
3321 goto out;
3322 }
3323 else if (ssl_sock_get_dn_oneline(name, smp_trash) <= 0)
3324 goto out;
3325
3326 smp->type = SMP_T_STR;
3327 smp->data.str = *smp_trash;
3328 ret = 1;
3329out:
Emeric Brunba841a12014-04-30 17:05:08 +02003330 /* SSL_get_peer_certificate, it increase X509 * ref count */
3331 if (cert_peer && crt)
Emeric Brun87855892012-10-17 17:39:35 +02003332 X509_free(crt);
3333 return ret;
3334}
3335
Emeric Brunba841a12014-04-30 17:05:08 +02003336/* string, returns notbefore date in ASN1_UTCTIME format.
3337 * The 5th keyword char is used to know if SSL_get_certificate or SSL_get_peer_certificate
3338 * should be use.
3339 */
Emeric Brunce5ad802012-10-22 14:11:22 +02003340static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02003341smp_fetch_ssl_x_notbefore(const struct arg *args, struct sample *smp, const char *kw, void *private)
Emeric Brunce5ad802012-10-22 14:11:22 +02003342{
Emeric Brunba841a12014-04-30 17:05:08 +02003343 int cert_peer = (kw[4] == 'c') ? 1 : 0;
Emeric Brunce5ad802012-10-22 14:11:22 +02003344 X509 *crt = NULL;
3345 int ret = 0;
3346 struct chunk *smp_trash;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003347 struct connection *conn;
3348
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02003349 conn = objt_conn(smp->sess->origin);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003350 if (!conn || conn->xprt != &ssl_sock)
Emeric Brunce5ad802012-10-22 14:11:22 +02003351 return 0;
3352
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003353 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brunce5ad802012-10-22 14:11:22 +02003354 smp->flags |= SMP_F_MAY_CHANGE;
3355 return 0;
3356 }
3357
Emeric Brunba841a12014-04-30 17:05:08 +02003358 if (cert_peer)
3359 crt = SSL_get_peer_certificate(conn->xprt_ctx);
3360 else
3361 crt = SSL_get_certificate(conn->xprt_ctx);
Emeric Brunce5ad802012-10-22 14:11:22 +02003362 if (!crt)
3363 goto out;
3364
Willy Tarreau47ca5452012-12-23 20:22:19 +01003365 smp_trash = get_trash_chunk();
Emeric Brunce5ad802012-10-22 14:11:22 +02003366 if (ssl_sock_get_time(X509_get_notBefore(crt), smp_trash) <= 0)
3367 goto out;
3368
3369 smp->data.str = *smp_trash;
3370 smp->type = SMP_T_STR;
3371 ret = 1;
3372out:
Emeric Brunba841a12014-04-30 17:05:08 +02003373 /* SSL_get_peer_certificate, it increase X509 * ref count */
3374 if (cert_peer && crt)
Emeric Brunce5ad802012-10-22 14:11:22 +02003375 X509_free(crt);
3376 return ret;
3377}
3378
Emeric Brunba841a12014-04-30 17:05:08 +02003379/* string, returns a string of a formatted full dn \C=..\O=..\OU=.. \CN=.. of certificate's subject
3380 * The 5th keyword char is used to know if SSL_get_certificate or SSL_get_peer_certificate
3381 * should be use.
3382 */
Emeric Brun87855892012-10-17 17:39:35 +02003383static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02003384smp_fetch_ssl_x_s_dn(const struct arg *args, struct sample *smp, const char *kw, void *private)
Emeric Brun87855892012-10-17 17:39:35 +02003385{
Emeric Brunba841a12014-04-30 17:05:08 +02003386 int cert_peer = (kw[4] == 'c') ? 1 : 0;
Emeric Brun87855892012-10-17 17:39:35 +02003387 X509 *crt = NULL;
3388 X509_NAME *name;
3389 int ret = 0;
3390 struct chunk *smp_trash;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003391 struct connection *conn;
Emeric Brun87855892012-10-17 17:39:35 +02003392
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02003393 conn = objt_conn(smp->sess->origin);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003394 if (!conn || conn->xprt != &ssl_sock)
3395 return 0;
3396
3397 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brun87855892012-10-17 17:39:35 +02003398 smp->flags |= SMP_F_MAY_CHANGE;
3399 return 0;
3400 }
3401
Emeric Brunba841a12014-04-30 17:05:08 +02003402 if (cert_peer)
3403 crt = SSL_get_peer_certificate(conn->xprt_ctx);
3404 else
3405 crt = SSL_get_certificate(conn->xprt_ctx);
Emeric Brun87855892012-10-17 17:39:35 +02003406 if (!crt)
3407 goto out;
3408
3409 name = X509_get_subject_name(crt);
3410 if (!name)
3411 goto out;
3412
Willy Tarreau47ca5452012-12-23 20:22:19 +01003413 smp_trash = get_trash_chunk();
Emeric Brun87855892012-10-17 17:39:35 +02003414 if (args && args[0].type == ARGT_STR) {
3415 int pos = 1;
3416
3417 if (args[1].type == ARGT_SINT)
3418 pos = args[1].data.sint;
3419 else if (args[1].type == ARGT_UINT)
3420 pos =(int)args[1].data.uint;
3421
3422 if (ssl_sock_get_dn_entry(name, &args[0].data.str, pos, smp_trash) <= 0)
3423 goto out;
3424 }
3425 else if (ssl_sock_get_dn_oneline(name, smp_trash) <= 0)
3426 goto out;
3427
3428 smp->type = SMP_T_STR;
3429 smp->data.str = *smp_trash;
3430 ret = 1;
3431out:
Emeric Brunba841a12014-04-30 17:05:08 +02003432 /* SSL_get_peer_certificate, it increase X509 * ref count */
3433 if (cert_peer && crt)
Emeric Brun87855892012-10-17 17:39:35 +02003434 X509_free(crt);
3435 return ret;
3436}
Emeric Brun9143d372012-12-20 15:44:16 +01003437
3438/* integer, returns true if current session use a client certificate */
3439static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02003440smp_fetch_ssl_c_used(const struct arg *args, struct sample *smp, const char *kw, void *private)
Emeric Brun9143d372012-12-20 15:44:16 +01003441{
3442 X509 *crt;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003443 struct connection *conn;
Emeric Brun9143d372012-12-20 15:44:16 +01003444
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02003445 conn = objt_conn(smp->sess->origin);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003446 if (!conn || conn->xprt != &ssl_sock)
3447 return 0;
3448
3449 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brun9143d372012-12-20 15:44:16 +01003450 smp->flags |= SMP_F_MAY_CHANGE;
3451 return 0;
3452 }
3453
3454 /* SSL_get_peer_certificate returns a ptr on allocated X509 struct */
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003455 crt = SSL_get_peer_certificate(conn->xprt_ctx);
Emeric Brun9143d372012-12-20 15:44:16 +01003456 if (crt) {
3457 X509_free(crt);
3458 }
3459
3460 smp->type = SMP_T_BOOL;
3461 smp->data.uint = (crt != NULL);
3462 return 1;
3463}
3464
Emeric Brunba841a12014-04-30 17:05:08 +02003465/* integer, returns the certificate version
3466 * The 5th keyword char is used to know if SSL_get_certificate or SSL_get_peer_certificate
3467 * should be use.
3468 */
Emeric Bruna7359fd2012-10-17 15:03:11 +02003469static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02003470smp_fetch_ssl_x_version(const struct arg *args, struct sample *smp, const char *kw, void *private)
Emeric Bruna7359fd2012-10-17 15:03:11 +02003471{
Emeric Brunba841a12014-04-30 17:05:08 +02003472 int cert_peer = (kw[4] == 'c') ? 1 : 0;
Emeric Bruna7359fd2012-10-17 15:03:11 +02003473 X509 *crt;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003474 struct connection *conn;
3475
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02003476 conn = objt_conn(smp->sess->origin);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003477 if (!conn || conn->xprt != &ssl_sock)
Emeric Bruna7359fd2012-10-17 15:03:11 +02003478 return 0;
3479
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003480 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Bruna7359fd2012-10-17 15:03:11 +02003481 smp->flags |= SMP_F_MAY_CHANGE;
3482 return 0;
3483 }
3484
Emeric Brunba841a12014-04-30 17:05:08 +02003485 if (cert_peer)
3486 crt = SSL_get_peer_certificate(conn->xprt_ctx);
3487 else
3488 crt = SSL_get_certificate(conn->xprt_ctx);
Emeric Bruna7359fd2012-10-17 15:03:11 +02003489 if (!crt)
3490 return 0;
3491
3492 smp->data.uint = (unsigned int)(1 + X509_get_version(crt));
Emeric Brunba841a12014-04-30 17:05:08 +02003493 /* SSL_get_peer_certificate increase X509 * ref count */
3494 if (cert_peer)
3495 X509_free(crt);
Emeric Bruna7359fd2012-10-17 15:03:11 +02003496 smp->type = SMP_T_UINT;
3497
3498 return 1;
3499}
3500
Emeric Brunba841a12014-04-30 17:05:08 +02003501/* string, returns the certificate's signature algorithm.
3502 * The 5th keyword char is used to know if SSL_get_certificate or SSL_get_peer_certificate
3503 * should be use.
3504 */
Emeric Brun7f56e742012-10-19 18:15:40 +02003505static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02003506smp_fetch_ssl_x_sig_alg(const struct arg *args, struct sample *smp, const char *kw, void *private)
Emeric Brun7f56e742012-10-19 18:15:40 +02003507{
Emeric Brunba841a12014-04-30 17:05:08 +02003508 int cert_peer = (kw[4] == 'c') ? 1 : 0;
Emeric Brun7f56e742012-10-19 18:15:40 +02003509 X509 *crt;
3510 int nid;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003511 struct connection *conn;
Emeric Brun7f56e742012-10-19 18:15:40 +02003512
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02003513 conn = objt_conn(smp->sess->origin);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003514 if (!conn || conn->xprt != &ssl_sock)
3515 return 0;
3516
3517 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brun7f56e742012-10-19 18:15:40 +02003518 smp->flags |= SMP_F_MAY_CHANGE;
3519 return 0;
3520 }
3521
Emeric Brunba841a12014-04-30 17:05:08 +02003522 if (cert_peer)
3523 crt = SSL_get_peer_certificate(conn->xprt_ctx);
3524 else
3525 crt = SSL_get_certificate(conn->xprt_ctx);
Emeric Brun7f56e742012-10-19 18:15:40 +02003526 if (!crt)
3527 return 0;
3528
3529 nid = OBJ_obj2nid((ASN1_OBJECT *)(crt->cert_info->signature->algorithm));
3530
3531 smp->data.str.str = (char *)OBJ_nid2sn(nid);
Emeric Brun9bf3ba22013-10-07 14:31:44 +02003532 if (!smp->data.str.str) {
Emeric Brunba841a12014-04-30 17:05:08 +02003533 /* SSL_get_peer_certificate increase X509 * ref count */
3534 if (cert_peer)
3535 X509_free(crt);
Emeric Brun7f56e742012-10-19 18:15:40 +02003536 return 0;
Emeric Brun9bf3ba22013-10-07 14:31:44 +02003537 }
Emeric Brun7f56e742012-10-19 18:15:40 +02003538
Thierry FOURNIER7654c9f2013-12-17 00:20:33 +01003539 smp->type = SMP_T_STR;
3540 smp->flags |= SMP_F_CONST;
Emeric Brun7f56e742012-10-19 18:15:40 +02003541 smp->data.str.len = strlen(smp->data.str.str);
Emeric Brunba841a12014-04-30 17:05:08 +02003542 /* SSL_get_peer_certificate increase X509 * ref count */
3543 if (cert_peer)
3544 X509_free(crt);
Emeric Brun7f56e742012-10-19 18:15:40 +02003545
3546 return 1;
3547}
3548
Emeric Brunba841a12014-04-30 17:05:08 +02003549/* string, returns the certificate's key algorithm.
3550 * The 5th keyword char is used to know if SSL_get_certificate or SSL_get_peer_certificate
3551 * should be use.
3552 */
Emeric Brun521a0112012-10-22 12:22:55 +02003553static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02003554smp_fetch_ssl_x_key_alg(const struct arg *args, struct sample *smp, const char *kw, void *private)
Emeric Brun521a0112012-10-22 12:22:55 +02003555{
Emeric Brunba841a12014-04-30 17:05:08 +02003556 int cert_peer = (kw[4] == 'c') ? 1 : 0;
Emeric Brun521a0112012-10-22 12:22:55 +02003557 X509 *crt;
3558 int nid;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003559 struct connection *conn;
Emeric Brun521a0112012-10-22 12:22:55 +02003560
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02003561 conn = objt_conn(smp->sess->origin);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003562 if (!conn || conn->xprt != &ssl_sock)
3563 return 0;
3564
3565 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brun521a0112012-10-22 12:22:55 +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 Brun521a0112012-10-22 12:22:55 +02003574 if (!crt)
3575 return 0;
3576
3577 nid = OBJ_obj2nid((ASN1_OBJECT *)(crt->cert_info->key->algor->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 Brun521a0112012-10-22 12:22:55 +02003584 return 0;
Emeric Brun9bf3ba22013-10-07 14:31:44 +02003585 }
Emeric Brun521a0112012-10-22 12:22:55 +02003586
Thierry FOURNIER7654c9f2013-12-17 00:20:33 +01003587 smp->type = SMP_T_STR;
3588 smp->flags |= SMP_F_CONST;
Emeric Brun521a0112012-10-22 12:22:55 +02003589 smp->data.str.len = strlen(smp->data.str.str);
Emeric Brunba841a12014-04-30 17:05:08 +02003590 if (cert_peer)
3591 X509_free(crt);
Emeric Brun521a0112012-10-22 12:22:55 +02003592
3593 return 1;
3594}
3595
Emeric Brun645ae792014-04-30 14:21:06 +02003596/* boolean, returns true if front conn. transport layer is SSL.
3597 * This function is also usable on backend conn if the fetch keyword 5th
3598 * char is 'b'.
3599 */
Willy Tarreau7875d092012-09-10 08:20:03 +02003600static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02003601smp_fetch_ssl_fc(const struct arg *args, struct sample *smp, const char *kw, void *private)
Willy Tarreau7875d092012-09-10 08:20:03 +02003602{
Emeric Brun645ae792014-04-30 14:21:06 +02003603 int back_conn = (kw[4] == 'b') ? 1 : 0;
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02003604 struct connection *conn = objt_conn(smp->strm->si[back_conn].end);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003605
Willy Tarreau7875d092012-09-10 08:20:03 +02003606 smp->type = SMP_T_BOOL;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003607 smp->data.uint = (conn && conn->xprt == &ssl_sock);
Willy Tarreau7875d092012-09-10 08:20:03 +02003608 return 1;
3609}
3610
Emeric Brun2525b6b2012-10-18 15:59:43 +02003611/* boolean, returns true if client present a SNI */
Willy Tarreau7875d092012-09-10 08:20:03 +02003612static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02003613smp_fetch_ssl_fc_has_sni(const struct arg *args, struct sample *smp, const char *kw, void *private)
Willy Tarreau7875d092012-09-10 08:20:03 +02003614{
3615#ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02003616 struct connection *conn = objt_conn(smp->sess->origin);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003617
Willy Tarreau7875d092012-09-10 08:20:03 +02003618 smp->type = SMP_T_BOOL;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003619 smp->data.uint = (conn && conn->xprt == &ssl_sock) &&
3620 conn->xprt_ctx &&
3621 SSL_get_servername(conn->xprt_ctx, TLSEXT_NAMETYPE_host_name) != NULL;
Willy Tarreau7875d092012-09-10 08:20:03 +02003622 return 1;
3623#else
3624 return 0;
3625#endif
3626}
3627
Nenad Merdanovic26ea8222015-05-18 02:28:57 +02003628/* boolean, returns true if client session has been resumed */
3629static int
3630smp_fetch_ssl_fc_is_resumed(const struct arg *args, struct sample *smp, const char *kw, void *private)
3631{
3632 struct connection *conn = objt_conn(smp->sess->origin);
3633
3634 smp->type = SMP_T_BOOL;
3635 smp->data.uint = (conn && conn->xprt == &ssl_sock) &&
3636 conn->xprt_ctx &&
3637 SSL_session_reused(conn->xprt_ctx);
3638 return 1;
3639}
3640
Emeric Brun645ae792014-04-30 14:21:06 +02003641/* string, returns the used cipher if front conn. transport layer is SSL.
3642 * This function is also usable on backend conn if the fetch keyword 5th
3643 * char is 'b'.
3644 */
Emeric Brun589fcad2012-10-16 14:13:26 +02003645static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02003646smp_fetch_ssl_fc_cipher(const struct arg *args, struct sample *smp, const char *kw, void *private)
Emeric Brun589fcad2012-10-16 14:13:26 +02003647{
Emeric Brun645ae792014-04-30 14:21:06 +02003648 int back_conn = (kw[4] == 'b') ? 1 : 0;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003649 struct connection *conn;
3650
Emeric Brun589fcad2012-10-16 14:13:26 +02003651 smp->flags = 0;
3652
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02003653 conn = objt_conn(smp->strm->si[back_conn].end);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003654 if (!conn || !conn->xprt_ctx || conn->xprt != &ssl_sock)
Emeric Brun589fcad2012-10-16 14:13:26 +02003655 return 0;
3656
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003657 smp->data.str.str = (char *)SSL_get_cipher_name(conn->xprt_ctx);
Emeric Brun589fcad2012-10-16 14:13:26 +02003658 if (!smp->data.str.str)
3659 return 0;
3660
Thierry FOURNIER7654c9f2013-12-17 00:20:33 +01003661 smp->type = SMP_T_STR;
3662 smp->flags |= SMP_F_CONST;
Emeric Brun589fcad2012-10-16 14:13:26 +02003663 smp->data.str.len = strlen(smp->data.str.str);
3664
3665 return 1;
3666}
3667
Emeric Brun645ae792014-04-30 14:21:06 +02003668/* integer, returns the algoritm's keysize if front conn. transport layer
3669 * is SSL.
3670 * This function is also usable on backend conn if the fetch keyword 5th
3671 * char is 'b'.
3672 */
Emeric Brun589fcad2012-10-16 14:13:26 +02003673static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02003674smp_fetch_ssl_fc_alg_keysize(const struct arg *args, struct sample *smp, const char *kw, void *private)
Emeric Brun589fcad2012-10-16 14:13:26 +02003675{
Emeric Brun645ae792014-04-30 14:21:06 +02003676 int back_conn = (kw[4] == 'b') ? 1 : 0;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003677 struct connection *conn;
3678
Emeric Brun589fcad2012-10-16 14:13:26 +02003679 smp->flags = 0;
3680
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02003681 conn = objt_conn(smp->strm->si[back_conn].end);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003682 if (!conn || !conn->xprt_ctx || conn->xprt != &ssl_sock)
Emeric Brun589fcad2012-10-16 14:13:26 +02003683 return 0;
3684
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003685 if (!SSL_get_cipher_bits(conn->xprt_ctx, (int *)&smp->data.uint))
3686 return 0;
3687
Emeric Brun589fcad2012-10-16 14:13:26 +02003688 smp->type = SMP_T_UINT;
3689
3690 return 1;
3691}
3692
Emeric Brun645ae792014-04-30 14:21:06 +02003693/* integer, returns the used keysize if front conn. transport layer is SSL.
3694 * This function is also usable on backend conn if the fetch keyword 5th
3695 * char is 'b'.
3696 */
Emeric Brun589fcad2012-10-16 14:13:26 +02003697static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02003698smp_fetch_ssl_fc_use_keysize(const struct arg *args, struct sample *smp, const char *kw, void *private)
Emeric Brun589fcad2012-10-16 14:13:26 +02003699{
Emeric Brun645ae792014-04-30 14:21:06 +02003700 int back_conn = (kw[4] == 'b') ? 1 : 0;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003701 struct connection *conn;
3702
Emeric Brun589fcad2012-10-16 14:13:26 +02003703 smp->flags = 0;
3704
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02003705 conn = objt_conn(smp->strm->si[back_conn].end);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003706 if (!conn || !conn->xprt_ctx || conn->xprt != &ssl_sock)
3707 return 0;
3708
3709 smp->data.uint = (unsigned int)SSL_get_cipher_bits(conn->xprt_ctx, NULL);
Emeric Brun589fcad2012-10-16 14:13:26 +02003710 if (!smp->data.uint)
3711 return 0;
3712
3713 smp->type = SMP_T_UINT;
3714
3715 return 1;
3716}
3717
Willy Tarreau6c9a3d52012-10-18 18:57:14 +02003718#ifdef OPENSSL_NPN_NEGOTIATED
Willy Tarreau7875d092012-09-10 08:20:03 +02003719static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02003720smp_fetch_ssl_fc_npn(const struct arg *args, struct sample *smp, const char *kw, void *private)
Willy Tarreaua33c6542012-10-15 13:19:06 +02003721{
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003722 struct connection *conn;
3723
Thierry FOURNIER7654c9f2013-12-17 00:20:33 +01003724 smp->flags = SMP_F_CONST;
3725 smp->type = SMP_T_STR;
Willy Tarreaua33c6542012-10-15 13:19:06 +02003726
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02003727 conn = objt_conn(smp->sess->origin);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003728 if (!conn || !conn->xprt_ctx || conn->xprt != &ssl_sock)
3729 return 0;
3730
Willy Tarreaua33c6542012-10-15 13:19:06 +02003731 smp->data.str.str = NULL;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003732 SSL_get0_next_proto_negotiated(conn->xprt_ctx,
Willy Tarreaua33c6542012-10-15 13:19:06 +02003733 (const unsigned char **)&smp->data.str.str, (unsigned *)&smp->data.str.len);
3734
3735 if (!smp->data.str.str)
3736 return 0;
3737
3738 return 1;
Willy Tarreaua33c6542012-10-15 13:19:06 +02003739}
Willy Tarreau6c9a3d52012-10-18 18:57:14 +02003740#endif
Willy Tarreaua33c6542012-10-15 13:19:06 +02003741
Dirkjan Bussink48f1c4e2014-02-13 12:29:42 +01003742#ifdef TLSEXT_TYPE_application_layer_protocol_negotiation
Willy Tarreauab861d32013-04-02 02:30:41 +02003743static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02003744smp_fetch_ssl_fc_alpn(const struct arg *args, struct sample *smp, const char *kw, void *private)
Willy Tarreauab861d32013-04-02 02:30:41 +02003745{
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003746 struct connection *conn;
3747
Thierry FOURNIER7654c9f2013-12-17 00:20:33 +01003748 smp->flags = SMP_F_CONST;
3749 smp->type = SMP_T_STR;
Willy Tarreauab861d32013-04-02 02:30:41 +02003750
Willy Tarreaue26bf052015-05-12 10:30:12 +02003751 conn = objt_conn(smp->sess->origin);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003752 if (!conn || !conn->xprt_ctx || conn->xprt != &ssl_sock)
Willy Tarreauab861d32013-04-02 02:30:41 +02003753 return 0;
3754
3755 smp->data.str.str = NULL;
Dirkjan Bussink48f1c4e2014-02-13 12:29:42 +01003756 SSL_get0_alpn_selected(conn->xprt_ctx,
Willy Tarreauab861d32013-04-02 02:30:41 +02003757 (const unsigned char **)&smp->data.str.str, (unsigned *)&smp->data.str.len);
3758
3759 if (!smp->data.str.str)
3760 return 0;
3761
3762 return 1;
3763}
3764#endif
3765
Emeric Brun645ae792014-04-30 14:21:06 +02003766/* string, returns the used protocol if front conn. transport layer is SSL.
3767 * This function is also usable on backend conn if the fetch keyword 5th
3768 * char is 'b'.
3769 */
Willy Tarreaua33c6542012-10-15 13:19:06 +02003770static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02003771smp_fetch_ssl_fc_protocol(const struct arg *args, struct sample *smp, const char *kw, void *private)
Emeric Brun589fcad2012-10-16 14:13:26 +02003772{
Emeric Brun645ae792014-04-30 14:21:06 +02003773 int back_conn = (kw[4] == 'b') ? 1 : 0;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003774 struct connection *conn;
3775
Emeric Brun589fcad2012-10-16 14:13:26 +02003776 smp->flags = 0;
3777
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02003778 conn = objt_conn(smp->strm->si[back_conn].end);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003779 if (!conn || !conn->xprt_ctx || conn->xprt != &ssl_sock)
3780 return 0;
3781
3782 smp->data.str.str = (char *)SSL_get_version(conn->xprt_ctx);
Emeric Brun589fcad2012-10-16 14:13:26 +02003783 if (!smp->data.str.str)
3784 return 0;
3785
Thierry FOURNIER7654c9f2013-12-17 00:20:33 +01003786 smp->type = SMP_T_STR;
3787 smp->flags = SMP_F_CONST;
Emeric Brun589fcad2012-10-16 14:13:26 +02003788 smp->data.str.len = strlen(smp->data.str.str);
3789
3790 return 1;
3791}
3792
Willy Tarreau87b09662015-04-03 00:22:06 +02003793/* binary, returns the SSL stream id if front conn. transport layer is SSL.
Emeric Brun645ae792014-04-30 14:21:06 +02003794 * This function is also usable on backend conn if the fetch keyword 5th
3795 * char is 'b'.
3796 */
Emeric Brun589fcad2012-10-16 14:13:26 +02003797static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02003798smp_fetch_ssl_fc_session_id(const struct arg *args, struct sample *smp, const char *kw, void *private)
Emeric Brunfe68f682012-10-16 14:59:28 +02003799{
3800#if OPENSSL_VERSION_NUMBER > 0x0090800fL
Emeric Brun645ae792014-04-30 14:21:06 +02003801 int back_conn = (kw[4] == 'b') ? 1 : 0;
Willy Tarreau192252e2015-04-04 01:47:55 +02003802 SSL_SESSION *ssl_sess;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003803 struct connection *conn;
Emeric Brunfe68f682012-10-16 14:59:28 +02003804
Thierry FOURNIER7654c9f2013-12-17 00:20:33 +01003805 smp->flags = SMP_F_CONST;
3806 smp->type = SMP_T_BIN;
Emeric Brunfe68f682012-10-16 14:59:28 +02003807
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02003808 conn = objt_conn(smp->strm->si[back_conn].end);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003809 if (!conn || !conn->xprt_ctx || conn->xprt != &ssl_sock)
3810 return 0;
3811
Willy Tarreau192252e2015-04-04 01:47:55 +02003812 ssl_sess = SSL_get_session(conn->xprt_ctx);
3813 if (!ssl_sess)
Emeric Brunfe68f682012-10-16 14:59:28 +02003814 return 0;
3815
Willy Tarreau192252e2015-04-04 01:47:55 +02003816 smp->data.str.str = (char *)SSL_SESSION_get_id(ssl_sess, (unsigned int *)&smp->data.str.len);
Emeric Brunfe68f682012-10-16 14:59:28 +02003817 if (!smp->data.str.str || !&smp->data.str.len)
3818 return 0;
3819
3820 return 1;
3821#else
3822 return 0;
3823#endif
3824}
3825
3826static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02003827smp_fetch_ssl_fc_sni(const struct arg *args, struct sample *smp, const char *kw, void *private)
Willy Tarreau7875d092012-09-10 08:20:03 +02003828{
3829#ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003830 struct connection *conn;
3831
Thierry FOURNIER7654c9f2013-12-17 00:20:33 +01003832 smp->flags = SMP_F_CONST;
3833 smp->type = SMP_T_STR;
Willy Tarreau7875d092012-09-10 08:20:03 +02003834
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02003835 conn = objt_conn(smp->sess->origin);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003836 if (!conn || !conn->xprt_ctx || conn->xprt != &ssl_sock)
3837 return 0;
3838
3839 smp->data.str.str = (char *)SSL_get_servername(conn->xprt_ctx, TLSEXT_NAMETYPE_host_name);
Willy Tarreau3e394c92012-09-14 23:56:58 +02003840 if (!smp->data.str.str)
3841 return 0;
3842
Willy Tarreau7875d092012-09-10 08:20:03 +02003843 smp->data.str.len = strlen(smp->data.str.str);
3844 return 1;
3845#else
3846 return 0;
3847#endif
3848}
3849
David Sc1ad52e2014-04-08 18:48:47 -04003850static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02003851smp_fetch_ssl_fc_unique_id(const struct arg *args, struct sample *smp, const char *kw, void *private)
David Sc1ad52e2014-04-08 18:48:47 -04003852{
3853#if OPENSSL_VERSION_NUMBER > 0x0090800fL
Emeric Brun645ae792014-04-30 14:21:06 +02003854 int back_conn = (kw[4] == 'b') ? 1 : 0;
David Sc1ad52e2014-04-08 18:48:47 -04003855 struct connection *conn;
3856 int finished_len;
David Sc1ad52e2014-04-08 18:48:47 -04003857 struct chunk *finished_trash;
David Sc1ad52e2014-04-08 18:48:47 -04003858
3859 smp->flags = 0;
3860
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02003861 conn = objt_conn(smp->strm->si[back_conn].end);
David Sc1ad52e2014-04-08 18:48:47 -04003862 if (!conn || !conn->xprt_ctx || conn->xprt != &ssl_sock)
3863 return 0;
3864
3865 if (!(conn->flags & CO_FL_CONNECTED)) {
3866 smp->flags |= SMP_F_MAY_CHANGE;
3867 return 0;
3868 }
3869
3870 finished_trash = get_trash_chunk();
3871 if (!SSL_session_reused(conn->xprt_ctx))
3872 finished_len = SSL_get_peer_finished(conn->xprt_ctx, finished_trash->str, finished_trash->size);
3873 else
3874 finished_len = SSL_get_finished(conn->xprt_ctx, finished_trash->str, finished_trash->size);
3875
3876 if (!finished_len)
3877 return 0;
3878
Emeric Brunb73a9b02014-04-30 18:49:19 +02003879 finished_trash->len = finished_len;
3880 smp->data.str = *finished_trash;
3881 smp->type = SMP_T_BIN;
David Sc1ad52e2014-04-08 18:48:47 -04003882
3883 return 1;
3884#else
3885 return 0;
3886#endif
3887}
3888
Emeric Brun2525b6b2012-10-18 15:59:43 +02003889/* integer, returns the first verify error in CA chain of client certificate chain. */
Emeric Brunf282a812012-09-21 15:27:54 +02003890static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02003891smp_fetch_ssl_c_ca_err(const struct arg *args, struct sample *smp, const char *kw, void *private)
Emeric Brunf282a812012-09-21 15:27:54 +02003892{
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003893 struct connection *conn;
3894
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02003895 conn = objt_conn(smp->sess->origin);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003896 if (!conn || conn->xprt != &ssl_sock)
3897 return 0;
3898
3899 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brunf282a812012-09-21 15:27:54 +02003900 smp->flags = SMP_F_MAY_CHANGE;
3901 return 0;
3902 }
3903
3904 smp->type = SMP_T_UINT;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003905 smp->data.uint = (unsigned int)SSL_SOCK_ST_TO_CA_ERROR(conn->xprt_st);
Emeric Brunf282a812012-09-21 15:27:54 +02003906 smp->flags = 0;
3907
3908 return 1;
3909}
3910
Emeric Brun2525b6b2012-10-18 15:59:43 +02003911/* integer, returns the depth of the first verify error in CA chain of client certificate chain. */
Emeric Brunf282a812012-09-21 15:27:54 +02003912static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02003913smp_fetch_ssl_c_ca_err_depth(const struct arg *args, struct sample *smp, const char *kw, void *private)
Emeric Brunf282a812012-09-21 15:27:54 +02003914{
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003915 struct connection *conn;
3916
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02003917 conn = objt_conn(smp->sess->origin);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003918 if (!conn || conn->xprt != &ssl_sock)
Emeric Brunf282a812012-09-21 15:27:54 +02003919 return 0;
3920
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003921 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brunf282a812012-09-21 15:27:54 +02003922 smp->flags = SMP_F_MAY_CHANGE;
3923 return 0;
3924 }
3925
3926 smp->type = SMP_T_UINT;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003927 smp->data.uint = (unsigned int)SSL_SOCK_ST_TO_CAEDEPTH(conn->xprt_st);
Emeric Brunf282a812012-09-21 15:27:54 +02003928 smp->flags = 0;
3929
3930 return 1;
3931}
3932
Emeric Brun2525b6b2012-10-18 15:59:43 +02003933/* integer, returns the first verify error on client certificate */
Emeric Brunf282a812012-09-21 15:27:54 +02003934static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02003935smp_fetch_ssl_c_err(const struct arg *args, struct sample *smp, const char *kw, void *private)
Emeric Brunf282a812012-09-21 15:27:54 +02003936{
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003937 struct connection *conn;
3938
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02003939 conn = objt_conn(smp->sess->origin);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003940 if (!conn || conn->xprt != &ssl_sock)
3941 return 0;
3942
3943 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brunf282a812012-09-21 15:27:54 +02003944 smp->flags = SMP_F_MAY_CHANGE;
3945 return 0;
3946 }
3947
3948 smp->type = SMP_T_UINT;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003949 smp->data.uint = (unsigned int)SSL_SOCK_ST_TO_CRTERROR(conn->xprt_st);
Emeric Brunf282a812012-09-21 15:27:54 +02003950 smp->flags = 0;
3951
3952 return 1;
3953}
3954
Emeric Brun2525b6b2012-10-18 15:59:43 +02003955/* integer, returns the verify result on client cert */
Emeric Brunbaf8ffb2012-09-21 15:27:20 +02003956static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02003957smp_fetch_ssl_c_verify(const struct arg *args, struct sample *smp, const char *kw, void *private)
Emeric Brunbaf8ffb2012-09-21 15:27:20 +02003958{
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003959 struct connection *conn;
3960
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02003961 conn = objt_conn(smp->sess->origin);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003962 if (!conn || conn->xprt != &ssl_sock)
3963 return 0;
3964
3965 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brunbaf8ffb2012-09-21 15:27:20 +02003966 smp->flags = SMP_F_MAY_CHANGE;
3967 return 0;
3968 }
3969
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003970 if (!conn->xprt_ctx)
Emeric Brunbaf8ffb2012-09-21 15:27:20 +02003971 return 0;
3972
3973 smp->type = SMP_T_UINT;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003974 smp->data.uint = (unsigned int)SSL_get_verify_result(conn->xprt_ctx);
Emeric Brunbaf8ffb2012-09-21 15:27:20 +02003975 smp->flags = 0;
3976
3977 return 1;
3978}
3979
Emeric Brunfb510ea2012-10-05 12:00:26 +02003980/* parse the "ca-file" bind keyword */
3981static 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 +02003982{
3983 if (!*args[cur_arg + 1]) {
3984 if (err)
3985 memprintf(err, "'%s' : missing CAfile path", args[cur_arg]);
3986 return ERR_ALERT | ERR_FATAL;
3987 }
3988
Emeric Brunef42d922012-10-11 16:11:36 +02003989 if ((*args[cur_arg + 1] != '/') && global.ca_base)
3990 memprintf(&conf->ca_file, "%s/%s", global.ca_base, args[cur_arg + 1]);
3991 else
3992 memprintf(&conf->ca_file, "%s", args[cur_arg + 1]);
Emeric Brunc8e8d122012-10-02 18:42:10 +02003993
Emeric Brund94b3fe2012-09-20 18:23:56 +02003994 return 0;
3995}
3996
Willy Tarreau79eeafa2012-09-14 07:53:05 +02003997/* parse the "ciphers" bind keyword */
Willy Tarreau4348fad2012-09-20 16:48:07 +02003998static 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 +02003999{
4000 if (!*args[cur_arg + 1]) {
Willy Tarreaueb6cead2012-09-20 19:43:14 +02004001 memprintf(err, "'%s' : missing cipher suite", args[cur_arg]);
Willy Tarreau79eeafa2012-09-14 07:53:05 +02004002 return ERR_ALERT | ERR_FATAL;
4003 }
4004
Emeric Brun76d88952012-10-05 15:47:31 +02004005 free(conf->ciphers);
Willy Tarreau4348fad2012-09-20 16:48:07 +02004006 conf->ciphers = strdup(args[cur_arg + 1]);
Willy Tarreau79eeafa2012-09-14 07:53:05 +02004007 return 0;
4008}
4009
4010/* parse the "crt" bind keyword */
Willy Tarreau4348fad2012-09-20 16:48:07 +02004011static 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 +02004012{
Willy Tarreau38011032013-08-13 16:59:39 +02004013 char path[MAXPATHLEN];
Willy Tarreaub75d6922014-04-14 18:05:41 +02004014
Willy Tarreau79eeafa2012-09-14 07:53:05 +02004015 if (!*args[cur_arg + 1]) {
Willy Tarreaueb6cead2012-09-20 19:43:14 +02004016 memprintf(err, "'%s' : missing certificate location", args[cur_arg]);
Willy Tarreau79eeafa2012-09-14 07:53:05 +02004017 return ERR_ALERT | ERR_FATAL;
4018 }
4019
Emeric Brunc8e8d122012-10-02 18:42:10 +02004020 if ((*args[cur_arg + 1] != '/' ) && global.crt_base) {
Willy Tarreau38011032013-08-13 16:59:39 +02004021 if ((strlen(global.crt_base) + 1 + strlen(args[cur_arg + 1]) + 1) > MAXPATHLEN) {
Emeric Brunc8e8d122012-10-02 18:42:10 +02004022 memprintf(err, "'%s' : path too long", args[cur_arg]);
4023 return ERR_ALERT | ERR_FATAL;
4024 }
Willy Tarreaub75d6922014-04-14 18:05:41 +02004025 snprintf(path, sizeof(path), "%s/%s", global.crt_base, args[cur_arg + 1]);
Emeric Brunc8e8d122012-10-02 18:42:10 +02004026 if (ssl_sock_load_cert(path, conf, px, err) > 0)
4027 return ERR_ALERT | ERR_FATAL;
4028
4029 return 0;
4030 }
4031
Willy Tarreau4348fad2012-09-20 16:48:07 +02004032 if (ssl_sock_load_cert(args[cur_arg + 1], conf, px, err) > 0)
Willy Tarreau79eeafa2012-09-14 07:53:05 +02004033 return ERR_ALERT | ERR_FATAL;
Emeric Brund94b3fe2012-09-20 18:23:56 +02004034
4035 return 0;
4036}
4037
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01004038/* parse the "crt-list" bind keyword */
4039static int bind_parse_crt_list(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
4040{
4041 if (!*args[cur_arg + 1]) {
4042 memprintf(err, "'%s' : missing certificate location", args[cur_arg]);
4043 return ERR_ALERT | ERR_FATAL;
4044 }
4045
Willy Tarreauad1731d2013-04-02 17:35:58 +02004046 if (ssl_sock_load_cert_list_file(args[cur_arg + 1], conf, px, err) > 0) {
4047 memprintf(err, "'%s' : %s", args[cur_arg], *err);
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01004048 return ERR_ALERT | ERR_FATAL;
Willy Tarreauad1731d2013-04-02 17:35:58 +02004049 }
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01004050
4051 return 0;
4052}
4053
Emeric Brunfb510ea2012-10-05 12:00:26 +02004054/* parse the "crl-file" bind keyword */
4055static 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 +02004056{
Emeric Brun051cdab2012-10-02 19:25:50 +02004057#ifndef X509_V_FLAG_CRL_CHECK
4058 if (err)
4059 memprintf(err, "'%s' : library does not support CRL verify", args[cur_arg]);
4060 return ERR_ALERT | ERR_FATAL;
4061#else
Emeric Brund94b3fe2012-09-20 18:23:56 +02004062 if (!*args[cur_arg + 1]) {
4063 if (err)
4064 memprintf(err, "'%s' : missing CRLfile path", args[cur_arg]);
4065 return ERR_ALERT | ERR_FATAL;
4066 }
Emeric Brun2b58d042012-09-20 17:10:03 +02004067
Emeric Brunef42d922012-10-11 16:11:36 +02004068 if ((*args[cur_arg + 1] != '/') && global.ca_base)
4069 memprintf(&conf->crl_file, "%s/%s", global.ca_base, args[cur_arg + 1]);
4070 else
4071 memprintf(&conf->crl_file, "%s", args[cur_arg + 1]);
Emeric Brunc8e8d122012-10-02 18:42:10 +02004072
Emeric Brun2b58d042012-09-20 17:10:03 +02004073 return 0;
Emeric Brun051cdab2012-10-02 19:25:50 +02004074#endif
Emeric Brun2b58d042012-09-20 17:10:03 +02004075}
4076
4077/* parse the "ecdhe" bind keyword keywords */
4078static int bind_parse_ecdhe(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
4079{
4080#if OPENSSL_VERSION_NUMBER < 0x0090800fL
4081 if (err)
4082 memprintf(err, "'%s' : library does not support elliptic curve Diffie-Hellman (too old)", args[cur_arg]);
4083 return ERR_ALERT | ERR_FATAL;
4084#elif defined(OPENSSL_NO_ECDH)
4085 if (err)
4086 memprintf(err, "'%s' : library does not support elliptic curve Diffie-Hellman (disabled via OPENSSL_NO_ECDH)", args[cur_arg]);
4087 return ERR_ALERT | ERR_FATAL;
4088#else
4089 if (!*args[cur_arg + 1]) {
4090 if (err)
4091 memprintf(err, "'%s' : missing named curve", args[cur_arg]);
4092 return ERR_ALERT | ERR_FATAL;
4093 }
4094
4095 conf->ecdhe = strdup(args[cur_arg + 1]);
Willy Tarreau79eeafa2012-09-14 07:53:05 +02004096
4097 return 0;
Emeric Brun2b58d042012-09-20 17:10:03 +02004098#endif
Willy Tarreau79eeafa2012-09-14 07:53:05 +02004099}
4100
Emeric Brun81c00f02012-09-21 14:31:21 +02004101/* parse the "crt_ignerr" and "ca_ignerr" bind keywords */
4102static int bind_parse_ignore_err(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
4103{
4104 int code;
4105 char *p = args[cur_arg + 1];
4106 unsigned long long *ignerr = &conf->crt_ignerr;
4107
4108 if (!*p) {
4109 if (err)
4110 memprintf(err, "'%s' : missing error IDs list", args[cur_arg]);
4111 return ERR_ALERT | ERR_FATAL;
4112 }
4113
4114 if (strcmp(args[cur_arg], "ca-ignore-err") == 0)
4115 ignerr = &conf->ca_ignerr;
4116
4117 if (strcmp(p, "all") == 0) {
4118 *ignerr = ~0ULL;
4119 return 0;
4120 }
4121
4122 while (p) {
4123 code = atoi(p);
4124 if ((code <= 0) || (code > 63)) {
4125 if (err)
4126 memprintf(err, "'%s' : ID '%d' out of range (1..63) in error IDs list '%s'",
4127 args[cur_arg], code, args[cur_arg + 1]);
4128 return ERR_ALERT | ERR_FATAL;
4129 }
4130 *ignerr |= 1ULL << code;
4131 p = strchr(p, ',');
4132 if (p)
4133 p++;
4134 }
4135
Emeric Brun2cb7ae52012-10-05 14:14:21 +02004136 return 0;
4137}
4138
4139/* parse the "force-sslv3" bind keyword */
4140static int bind_parse_force_sslv3(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
4141{
4142 conf->ssl_options |= BC_SSL_O_USE_SSLV3;
4143 return 0;
4144}
4145
4146/* parse the "force-tlsv10" bind keyword */
4147static int bind_parse_force_tlsv10(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
4148{
4149 conf->ssl_options |= BC_SSL_O_USE_TLSV10;
Emeric Brun2d0c4822012-10-02 13:45:20 +02004150 return 0;
4151}
4152
Emeric Brun2cb7ae52012-10-05 14:14:21 +02004153/* parse the "force-tlsv11" bind keyword */
4154static int bind_parse_force_tlsv11(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
4155{
4156#if SSL_OP_NO_TLSv1_1
4157 conf->ssl_options |= BC_SSL_O_USE_TLSV11;
4158 return 0;
4159#else
4160 if (err)
4161 memprintf(err, "'%s' : library does not support protocol TLSv1.1", args[cur_arg]);
4162 return ERR_ALERT | ERR_FATAL;
4163#endif
4164}
4165
4166/* parse the "force-tlsv12" bind keyword */
4167static int bind_parse_force_tlsv12(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
4168{
4169#if SSL_OP_NO_TLSv1_2
4170 conf->ssl_options |= BC_SSL_O_USE_TLSV12;
4171 return 0;
4172#else
4173 if (err)
4174 memprintf(err, "'%s' : library does not support protocol TLSv1.2", args[cur_arg]);
4175 return ERR_ALERT | ERR_FATAL;
4176#endif
4177}
4178
4179
Emeric Brun2d0c4822012-10-02 13:45:20 +02004180/* parse the "no-tls-tickets" bind keyword */
4181static int bind_parse_no_tls_tickets(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
4182{
Emeric Brun89675492012-10-05 13:48:26 +02004183 conf->ssl_options |= BC_SSL_O_NO_TLS_TICKETS;
Emeric Brun81c00f02012-09-21 14:31:21 +02004184 return 0;
4185}
4186
Emeric Brun2d0c4822012-10-02 13:45:20 +02004187
Emeric Brun9b3009b2012-10-05 11:55:06 +02004188/* parse the "no-sslv3" bind keyword */
4189static 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 +02004190{
Emeric Brun89675492012-10-05 13:48:26 +02004191 conf->ssl_options |= BC_SSL_O_NO_SSLV3;
Willy Tarreau79eeafa2012-09-14 07:53:05 +02004192 return 0;
4193}
4194
Emeric Brun9b3009b2012-10-05 11:55:06 +02004195/* parse the "no-tlsv10" bind keyword */
4196static 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 +02004197{
Emeric Brun89675492012-10-05 13:48:26 +02004198 conf->ssl_options |= BC_SSL_O_NO_TLSV10;
Emeric Brunc0ff4922012-09-28 19:37:02 +02004199 return 0;
4200}
4201
Emeric Brun9b3009b2012-10-05 11:55:06 +02004202/* parse the "no-tlsv11" bind keyword */
4203static 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 +02004204{
Emeric Brun89675492012-10-05 13:48:26 +02004205 conf->ssl_options |= BC_SSL_O_NO_TLSV11;
Emeric Brunc0ff4922012-09-28 19:37:02 +02004206 return 0;
4207}
4208
Emeric Brun9b3009b2012-10-05 11:55:06 +02004209/* parse the "no-tlsv12" bind keyword */
4210static 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 +02004211{
Emeric Brun89675492012-10-05 13:48:26 +02004212 conf->ssl_options |= BC_SSL_O_NO_TLSV12;
Willy Tarreau79eeafa2012-09-14 07:53:05 +02004213 return 0;
4214}
4215
Willy Tarreau6c9a3d52012-10-18 18:57:14 +02004216/* parse the "npn" bind keyword */
4217static int bind_parse_npn(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
4218{
4219#ifdef OPENSSL_NPN_NEGOTIATED
4220 char *p1, *p2;
4221
4222 if (!*args[cur_arg + 1]) {
4223 memprintf(err, "'%s' : missing the comma-delimited NPN protocol suite", args[cur_arg]);
4224 return ERR_ALERT | ERR_FATAL;
4225 }
4226
4227 free(conf->npn_str);
4228
4229 /* the NPN string is built as a suite of (<len> <name>)* */
4230 conf->npn_len = strlen(args[cur_arg + 1]) + 1;
4231 conf->npn_str = calloc(1, conf->npn_len);
4232 memcpy(conf->npn_str + 1, args[cur_arg + 1], conf->npn_len);
4233
4234 /* replace commas with the name length */
4235 p1 = conf->npn_str;
4236 p2 = p1 + 1;
4237 while (1) {
4238 p2 = memchr(p1 + 1, ',', conf->npn_str + conf->npn_len - (p1 + 1));
4239 if (!p2)
4240 p2 = p1 + 1 + strlen(p1 + 1);
4241
4242 if (p2 - (p1 + 1) > 255) {
4243 *p2 = '\0';
4244 memprintf(err, "'%s' : NPN protocol name too long : '%s'", args[cur_arg], p1 + 1);
4245 return ERR_ALERT | ERR_FATAL;
4246 }
4247
4248 *p1 = p2 - (p1 + 1);
4249 p1 = p2;
4250
4251 if (!*p2)
4252 break;
4253
4254 *(p2++) = '\0';
4255 }
4256 return 0;
4257#else
4258 if (err)
4259 memprintf(err, "'%s' : library does not support TLS NPN extension", args[cur_arg]);
4260 return ERR_ALERT | ERR_FATAL;
4261#endif
4262}
4263
Willy Tarreauab861d32013-04-02 02:30:41 +02004264/* parse the "alpn" bind keyword */
4265static int bind_parse_alpn(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
4266{
Dirkjan Bussink48f1c4e2014-02-13 12:29:42 +01004267#ifdef TLSEXT_TYPE_application_layer_protocol_negotiation
Willy Tarreauab861d32013-04-02 02:30:41 +02004268 char *p1, *p2;
4269
4270 if (!*args[cur_arg + 1]) {
4271 memprintf(err, "'%s' : missing the comma-delimited ALPN protocol suite", args[cur_arg]);
4272 return ERR_ALERT | ERR_FATAL;
4273 }
4274
4275 free(conf->alpn_str);
4276
4277 /* the ALPN string is built as a suite of (<len> <name>)* */
4278 conf->alpn_len = strlen(args[cur_arg + 1]) + 1;
4279 conf->alpn_str = calloc(1, conf->alpn_len);
4280 memcpy(conf->alpn_str + 1, args[cur_arg + 1], conf->alpn_len);
4281
4282 /* replace commas with the name length */
4283 p1 = conf->alpn_str;
4284 p2 = p1 + 1;
4285 while (1) {
4286 p2 = memchr(p1 + 1, ',', conf->alpn_str + conf->alpn_len - (p1 + 1));
4287 if (!p2)
4288 p2 = p1 + 1 + strlen(p1 + 1);
4289
4290 if (p2 - (p1 + 1) > 255) {
4291 *p2 = '\0';
4292 memprintf(err, "'%s' : ALPN protocol name too long : '%s'", args[cur_arg], p1 + 1);
4293 return ERR_ALERT | ERR_FATAL;
4294 }
4295
4296 *p1 = p2 - (p1 + 1);
4297 p1 = p2;
4298
4299 if (!*p2)
4300 break;
4301
4302 *(p2++) = '\0';
4303 }
4304 return 0;
4305#else
4306 if (err)
4307 memprintf(err, "'%s' : library does not support TLS ALPN extension", args[cur_arg]);
4308 return ERR_ALERT | ERR_FATAL;
4309#endif
4310}
4311
Willy Tarreau79eeafa2012-09-14 07:53:05 +02004312/* parse the "ssl" bind keyword */
Willy Tarreau4348fad2012-09-20 16:48:07 +02004313static 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 +02004314{
Willy Tarreau81796be2012-09-22 19:11:47 +02004315 struct listener *l;
4316
Willy Tarreau4348fad2012-09-20 16:48:07 +02004317 conf->is_ssl = 1;
Emeric Brun76d88952012-10-05 15:47:31 +02004318
4319 if (global.listen_default_ciphers && !conf->ciphers)
4320 conf->ciphers = strdup(global.listen_default_ciphers);
Emeric Brun2c86cbf2014-10-30 15:56:50 +01004321 conf->ssl_options |= global.listen_default_ssloptions;
Emeric Brun76d88952012-10-05 15:47:31 +02004322
Willy Tarreau81796be2012-09-22 19:11:47 +02004323 list_for_each_entry(l, &conf->listeners, by_bind)
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02004324 l->xprt = &ssl_sock;
Willy Tarreau81796be2012-09-22 19:11:47 +02004325
Willy Tarreau79eeafa2012-09-14 07:53:05 +02004326 return 0;
4327}
4328
Emmanuel Hocdet65623372013-01-24 17:17:15 +01004329/* parse the "strict-sni" bind keyword */
4330static int bind_parse_strict_sni(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
4331{
4332 conf->strict_sni = 1;
4333 return 0;
Nenad Merdanovic05552d42015-02-27 19:56:49 +01004334}
4335
4336/* parse the "tls-ticket-keys" bind keyword */
4337static int bind_parse_tls_ticket_keys(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
4338{
4339#if (defined SSL_CTRL_SET_TLSEXT_TICKET_KEY_CB && TLS_TICKETS_NO > 0)
4340 FILE *f;
4341 int i = 0;
4342 char thisline[LINESIZE];
Nenad Merdanovic146defa2015-05-09 08:46:00 +02004343 struct tls_keys_ref *keys_ref;
Nenad Merdanovic05552d42015-02-27 19:56:49 +01004344
4345 if (!*args[cur_arg + 1]) {
4346 if (err)
4347 memprintf(err, "'%s' : missing TLS ticket keys file path", args[cur_arg]);
4348 return ERR_ALERT | ERR_FATAL;
4349 }
4350
Nenad Merdanovic200b0fa2015-05-09 08:46:01 +02004351 keys_ref = tlskeys_ref_lookup(args[cur_arg + 1]);
4352 if(keys_ref) {
4353 conf->keys_ref = keys_ref;
4354 return 0;
4355 }
4356
Nenad Merdanovic146defa2015-05-09 08:46:00 +02004357 keys_ref = malloc(sizeof(struct tls_keys_ref));
4358 keys_ref->tlskeys = malloc(TLS_TICKETS_NO * sizeof(struct tls_sess_key));
Nenad Merdanovic05552d42015-02-27 19:56:49 +01004359
4360 if ((f = fopen(args[cur_arg + 1], "r")) == NULL) {
4361 if (err)
4362 memprintf(err, "'%s' : unable to load ssl tickets keys file", args[cur_arg+1]);
4363 return ERR_ALERT | ERR_FATAL;
4364 }
4365
Nenad Merdanovic146defa2015-05-09 08:46:00 +02004366 keys_ref->filename = strdup(args[cur_arg + 1]);
4367
Nenad Merdanovic05552d42015-02-27 19:56:49 +01004368 while (fgets(thisline, sizeof(thisline), f) != NULL) {
4369 int len = strlen(thisline);
4370 /* Strip newline characters from the end */
4371 if(thisline[len - 1] == '\n')
4372 thisline[--len] = 0;
4373
4374 if(thisline[len - 1] == '\r')
4375 thisline[--len] = 0;
4376
Nenad Merdanovic146defa2015-05-09 08:46:00 +02004377 if (base64dec(thisline, len, (char *) (keys_ref->tlskeys + i % TLS_TICKETS_NO), sizeof(struct tls_sess_key)) != sizeof(struct tls_sess_key)) {
Nenad Merdanovic05552d42015-02-27 19:56:49 +01004378 if (err)
4379 memprintf(err, "'%s' : unable to decode base64 key on line %d", args[cur_arg+1], i + 1);
4380 return ERR_ALERT | ERR_FATAL;
4381 }
4382 i++;
4383 }
4384
4385 if (i < TLS_TICKETS_NO) {
4386 if (err)
4387 memprintf(err, "'%s' : please supply at least %d keys in the tls-tickets-file", args[cur_arg+1], TLS_TICKETS_NO);
4388 return ERR_ALERT | ERR_FATAL;
4389 }
4390
4391 fclose(f);
4392
4393 /* Use penultimate key for encryption, handle when TLS_TICKETS_NO = 1 */
4394 i-=2;
Nenad Merdanovic146defa2015-05-09 08:46:00 +02004395 keys_ref->tls_ticket_enc_index = i < 0 ? 0 : i;
Nenad Merdanovic200b0fa2015-05-09 08:46:01 +02004396 keys_ref->unique_id = -1;
Nenad Merdanovic146defa2015-05-09 08:46:00 +02004397 conf->keys_ref = keys_ref;
Nenad Merdanovic05552d42015-02-27 19:56:49 +01004398
Nenad Merdanovic200b0fa2015-05-09 08:46:01 +02004399 LIST_ADD(&tlskeys_reference, &keys_ref->list);
4400
Nenad Merdanovic05552d42015-02-27 19:56:49 +01004401 return 0;
4402#else
4403 if (err)
4404 memprintf(err, "'%s' : TLS ticket callback extension not supported", args[cur_arg]);
4405 return ERR_ALERT | ERR_FATAL;
4406#endif /* SSL_CTRL_SET_TLSEXT_TICKET_KEY_CB */
Emmanuel Hocdet65623372013-01-24 17:17:15 +01004407}
4408
Emeric Brund94b3fe2012-09-20 18:23:56 +02004409/* parse the "verify" bind keyword */
4410static int bind_parse_verify(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
4411{
4412 if (!*args[cur_arg + 1]) {
4413 if (err)
4414 memprintf(err, "'%s' : missing verify method", args[cur_arg]);
4415 return ERR_ALERT | ERR_FATAL;
4416 }
4417
4418 if (strcmp(args[cur_arg + 1], "none") == 0)
Emeric Brun850efd52014-01-29 12:24:34 +01004419 conf->verify = SSL_SOCK_VERIFY_NONE;
Emeric Brund94b3fe2012-09-20 18:23:56 +02004420 else if (strcmp(args[cur_arg + 1], "optional") == 0)
Emeric Brun850efd52014-01-29 12:24:34 +01004421 conf->verify = SSL_SOCK_VERIFY_OPTIONAL;
Emeric Brund94b3fe2012-09-20 18:23:56 +02004422 else if (strcmp(args[cur_arg + 1], "required") == 0)
Emeric Brun850efd52014-01-29 12:24:34 +01004423 conf->verify = SSL_SOCK_VERIFY_REQUIRED;
Emeric Brund94b3fe2012-09-20 18:23:56 +02004424 else {
4425 if (err)
4426 memprintf(err, "'%s' : unknown verify method '%s', only 'none', 'optional', and 'required' are supported\n",
4427 args[cur_arg], args[cur_arg + 1]);
4428 return ERR_ALERT | ERR_FATAL;
4429 }
4430
4431 return 0;
4432}
4433
Willy Tarreau92faadf2012-10-10 23:04:25 +02004434/************** "server" keywords ****************/
4435
Emeric Brunef42d922012-10-11 16:11:36 +02004436/* parse the "ca-file" server keyword */
4437static int srv_parse_ca_file(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
4438{
4439 if (!*args[*cur_arg + 1]) {
4440 if (err)
4441 memprintf(err, "'%s' : missing CAfile path", args[*cur_arg]);
4442 return ERR_ALERT | ERR_FATAL;
4443 }
4444
4445 if ((*args[*cur_arg + 1] != '/') && global.ca_base)
4446 memprintf(&newsrv->ssl_ctx.ca_file, "%s/%s", global.ca_base, args[*cur_arg + 1]);
4447 else
4448 memprintf(&newsrv->ssl_ctx.ca_file, "%s", args[*cur_arg + 1]);
4449
4450 return 0;
4451}
4452
Willy Tarreau92faadf2012-10-10 23:04:25 +02004453/* parse the "check-ssl" server keyword */
4454static int srv_parse_check_ssl(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
4455{
4456 newsrv->check.use_ssl = 1;
4457 if (global.connect_default_ciphers && !newsrv->ssl_ctx.ciphers)
4458 newsrv->ssl_ctx.ciphers = strdup(global.connect_default_ciphers);
Emeric Brun2c86cbf2014-10-30 15:56:50 +01004459 newsrv->ssl_ctx.options |= global.connect_default_ssloptions;
Willy Tarreau92faadf2012-10-10 23:04:25 +02004460 return 0;
4461}
4462
4463/* parse the "ciphers" server keyword */
4464static int srv_parse_ciphers(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
4465{
4466 if (!*args[*cur_arg + 1]) {
4467 memprintf(err, "'%s' : missing cipher suite", args[*cur_arg]);
4468 return ERR_ALERT | ERR_FATAL;
4469 }
4470
4471 free(newsrv->ssl_ctx.ciphers);
4472 newsrv->ssl_ctx.ciphers = strdup(args[*cur_arg + 1]);
4473 return 0;
4474}
4475
Emeric Brunef42d922012-10-11 16:11:36 +02004476/* parse the "crl-file" server keyword */
4477static int srv_parse_crl_file(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
4478{
4479#ifndef X509_V_FLAG_CRL_CHECK
4480 if (err)
4481 memprintf(err, "'%s' : library does not support CRL verify", args[*cur_arg]);
4482 return ERR_ALERT | ERR_FATAL;
4483#else
4484 if (!*args[*cur_arg + 1]) {
4485 if (err)
4486 memprintf(err, "'%s' : missing CRLfile path", args[*cur_arg]);
4487 return ERR_ALERT | ERR_FATAL;
4488 }
4489
4490 if ((*args[*cur_arg + 1] != '/') && global.ca_base)
4491 memprintf(&newsrv->ssl_ctx.crl_file, "%s/%s", global.ca_base, args[*cur_arg + 1]);
4492 else
4493 memprintf(&newsrv->ssl_ctx.crl_file, "%s", args[*cur_arg + 1]);
4494
4495 return 0;
4496#endif
4497}
4498
Emeric Bruna7aa3092012-10-26 12:58:00 +02004499/* parse the "crt" server keyword */
4500static int srv_parse_crt(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
4501{
4502 if (!*args[*cur_arg + 1]) {
4503 if (err)
4504 memprintf(err, "'%s' : missing certificate file path", args[*cur_arg]);
4505 return ERR_ALERT | ERR_FATAL;
4506 }
4507
4508 if ((*args[*cur_arg + 1] != '/') && global.crt_base)
4509 memprintf(&newsrv->ssl_ctx.client_crt, "%s/%s", global.ca_base, args[*cur_arg + 1]);
4510 else
4511 memprintf(&newsrv->ssl_ctx.client_crt, "%s", args[*cur_arg + 1]);
4512
4513 return 0;
4514}
Emeric Brunef42d922012-10-11 16:11:36 +02004515
Willy Tarreau92faadf2012-10-10 23:04:25 +02004516/* parse the "force-sslv3" server keyword */
4517static int srv_parse_force_sslv3(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
4518{
4519 newsrv->ssl_ctx.options |= SRV_SSL_O_USE_SSLV3;
4520 return 0;
4521}
4522
4523/* parse the "force-tlsv10" server keyword */
4524static int srv_parse_force_tlsv10(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
4525{
4526 newsrv->ssl_ctx.options |= SRV_SSL_O_USE_TLSV10;
4527 return 0;
4528}
4529
4530/* parse the "force-tlsv11" server keyword */
4531static int srv_parse_force_tlsv11(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
4532{
4533#if SSL_OP_NO_TLSv1_1
4534 newsrv->ssl_ctx.options |= SRV_SSL_O_USE_TLSV11;
4535 return 0;
4536#else
4537 if (err)
4538 memprintf(err, "'%s' : library does not support protocol TLSv1.1", args[*cur_arg]);
4539 return ERR_ALERT | ERR_FATAL;
4540#endif
4541}
4542
4543/* parse the "force-tlsv12" server keyword */
4544static int srv_parse_force_tlsv12(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
4545{
4546#if SSL_OP_NO_TLSv1_2
4547 newsrv->ssl_ctx.options |= SRV_SSL_O_USE_TLSV12;
4548 return 0;
4549#else
4550 if (err)
4551 memprintf(err, "'%s' : library does not support protocol TLSv1.2", args[*cur_arg]);
4552 return ERR_ALERT | ERR_FATAL;
4553#endif
4554}
4555
Willy Tarreau2a3fb1c2015-02-05 16:47:07 +01004556/* parse the "no-ssl-reuse" server keyword */
4557static int srv_parse_no_ssl_reuse(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
4558{
4559 newsrv->ssl_ctx.options |= SRV_SSL_O_NO_REUSE;
4560 return 0;
4561}
4562
Willy Tarreau92faadf2012-10-10 23:04:25 +02004563/* parse the "no-sslv3" server keyword */
4564static int srv_parse_no_sslv3(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
4565{
4566 newsrv->ssl_ctx.options |= SRV_SSL_O_NO_SSLV3;
4567 return 0;
4568}
4569
4570/* parse the "no-tlsv10" server keyword */
4571static int srv_parse_no_tlsv10(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
4572{
4573 newsrv->ssl_ctx.options |= SRV_SSL_O_NO_TLSV10;
4574 return 0;
4575}
4576
4577/* parse the "no-tlsv11" server keyword */
4578static int srv_parse_no_tlsv11(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
4579{
4580 newsrv->ssl_ctx.options |= SRV_SSL_O_NO_TLSV11;
4581 return 0;
4582}
4583
4584/* parse the "no-tlsv12" server keyword */
4585static int srv_parse_no_tlsv12(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
4586{
4587 newsrv->ssl_ctx.options |= SRV_SSL_O_NO_TLSV12;
4588 return 0;
4589}
4590
Emeric Brunf9c5c472012-10-11 15:28:34 +02004591/* parse the "no-tls-tickets" server keyword */
4592static int srv_parse_no_tls_tickets(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
4593{
4594 newsrv->ssl_ctx.options |= SRV_SSL_O_NO_TLS_TICKETS;
4595 return 0;
4596}
David Safb76832014-05-08 23:42:08 -04004597/* parse the "send-proxy-v2-ssl" server keyword */
4598static int srv_parse_send_proxy_ssl(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
4599{
4600 newsrv->pp_opts |= SRV_PP_V2;
4601 newsrv->pp_opts |= SRV_PP_V2_SSL;
4602 return 0;
4603}
4604
4605/* parse the "send-proxy-v2-ssl-cn" server keyword */
4606static int srv_parse_send_proxy_cn(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
4607{
4608 newsrv->pp_opts |= SRV_PP_V2;
4609 newsrv->pp_opts |= SRV_PP_V2_SSL;
4610 newsrv->pp_opts |= SRV_PP_V2_SSL_CN;
4611 return 0;
4612}
Emeric Brunf9c5c472012-10-11 15:28:34 +02004613
Willy Tarreau92faadf2012-10-10 23:04:25 +02004614/* parse the "ssl" server keyword */
4615static int srv_parse_ssl(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
4616{
4617 newsrv->use_ssl = 1;
4618 if (global.connect_default_ciphers && !newsrv->ssl_ctx.ciphers)
4619 newsrv->ssl_ctx.ciphers = strdup(global.connect_default_ciphers);
4620 return 0;
4621}
4622
Emeric Brunef42d922012-10-11 16:11:36 +02004623/* parse the "verify" server keyword */
4624static int srv_parse_verify(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
4625{
4626 if (!*args[*cur_arg + 1]) {
4627 if (err)
4628 memprintf(err, "'%s' : missing verify method", args[*cur_arg]);
4629 return ERR_ALERT | ERR_FATAL;
4630 }
4631
4632 if (strcmp(args[*cur_arg + 1], "none") == 0)
Emeric Brun850efd52014-01-29 12:24:34 +01004633 newsrv->ssl_ctx.verify = SSL_SOCK_VERIFY_NONE;
Emeric Brunef42d922012-10-11 16:11:36 +02004634 else if (strcmp(args[*cur_arg + 1], "required") == 0)
Emeric Brun850efd52014-01-29 12:24:34 +01004635 newsrv->ssl_ctx.verify = SSL_SOCK_VERIFY_REQUIRED;
Emeric Brunef42d922012-10-11 16:11:36 +02004636 else {
4637 if (err)
4638 memprintf(err, "'%s' : unknown verify method '%s', only 'none' and 'required' are supported\n",
4639 args[*cur_arg], args[*cur_arg + 1]);
4640 return ERR_ALERT | ERR_FATAL;
4641 }
4642
Evan Broderbe554312013-06-27 00:05:25 -07004643 return 0;
4644}
4645
4646/* parse the "verifyhost" server keyword */
4647static int srv_parse_verifyhost(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
4648{
4649 if (!*args[*cur_arg + 1]) {
4650 if (err)
4651 memprintf(err, "'%s' : missing hostname to verify against", args[*cur_arg]);
4652 return ERR_ALERT | ERR_FATAL;
4653 }
4654
4655 newsrv->ssl_ctx.verify_host = strdup(args[*cur_arg + 1]);
4656
Emeric Brunef42d922012-10-11 16:11:36 +02004657 return 0;
4658}
4659
Emeric Brun2c86cbf2014-10-30 15:56:50 +01004660/* parse the "ssl-default-bind-options" keyword in global section */
4661static int ssl_parse_default_bind_options(char **args, int section_type, struct proxy *curpx,
4662 struct proxy *defpx, const char *file, int line,
4663 char **err) {
4664 int i = 1;
4665
4666 if (*(args[i]) == 0) {
4667 memprintf(err, "global statement '%s' expects an option as an argument.", args[0]);
4668 return -1;
4669 }
4670 while (*(args[i])) {
4671 if (!strcmp(args[i], "no-sslv3"))
4672 global.listen_default_ssloptions |= BC_SSL_O_NO_SSLV3;
4673 else if (!strcmp(args[i], "no-tlsv10"))
4674 global.listen_default_ssloptions |= BC_SSL_O_NO_TLSV10;
4675 else if (!strcmp(args[i], "no-tlsv11"))
4676 global.listen_default_ssloptions |= BC_SSL_O_NO_TLSV11;
4677 else if (!strcmp(args[i], "no-tlsv12"))
4678 global.listen_default_ssloptions |= BC_SSL_O_NO_TLSV12;
4679 else if (!strcmp(args[i], "force-sslv3"))
4680 global.listen_default_ssloptions |= BC_SSL_O_USE_SSLV3;
4681 else if (!strcmp(args[i], "force-tlsv10"))
4682 global.listen_default_ssloptions |= BC_SSL_O_USE_TLSV10;
4683 else if (!strcmp(args[i], "force-tlsv11")) {
4684#if SSL_OP_NO_TLSv1_1
4685 global.listen_default_ssloptions |= BC_SSL_O_USE_TLSV11;
4686#else
4687 memprintf(err, "'%s' '%s': library does not support protocol TLSv1.1", args[0], args[i]);
4688 return -1;
4689#endif
4690 }
4691 else if (!strcmp(args[i], "force-tlsv12")) {
4692#if SSL_OP_NO_TLSv1_2
4693 global.listen_default_ssloptions |= BC_SSL_O_USE_TLSV12;
4694#else
4695 memprintf(err, "'%s' '%s': library does not support protocol TLSv1.2", args[0], args[i]);
4696 return -1;
4697#endif
4698 }
4699 else if (!strcmp(args[i], "no-tls-tickets"))
4700 global.listen_default_ssloptions |= BC_SSL_O_NO_TLS_TICKETS;
4701 else {
4702 memprintf(err, "unknown option '%s' on global statement '%s'.", args[i], args[0]);
4703 return -1;
4704 }
4705 i++;
4706 }
4707 return 0;
4708}
4709
4710/* parse the "ssl-default-server-options" keyword in global section */
4711static int ssl_parse_default_server_options(char **args, int section_type, struct proxy *curpx,
4712 struct proxy *defpx, const char *file, int line,
4713 char **err) {
4714 int i = 1;
4715
4716 if (*(args[i]) == 0) {
4717 memprintf(err, "global statement '%s' expects an option as an argument.", args[0]);
4718 return -1;
4719 }
4720 while (*(args[i])) {
4721 if (!strcmp(args[i], "no-sslv3"))
4722 global.connect_default_ssloptions |= SRV_SSL_O_NO_SSLV3;
4723 else if (!strcmp(args[i], "no-tlsv10"))
4724 global.connect_default_ssloptions |= SRV_SSL_O_NO_TLSV10;
4725 else if (!strcmp(args[i], "no-tlsv11"))
4726 global.connect_default_ssloptions |= SRV_SSL_O_NO_TLSV11;
4727 else if (!strcmp(args[i], "no-tlsv12"))
4728 global.connect_default_ssloptions |= SRV_SSL_O_NO_TLSV12;
4729 else if (!strcmp(args[i], "force-sslv3"))
4730 global.connect_default_ssloptions |= SRV_SSL_O_USE_SSLV3;
4731 else if (!strcmp(args[i], "force-tlsv10"))
4732 global.connect_default_ssloptions |= SRV_SSL_O_USE_TLSV10;
4733 else if (!strcmp(args[i], "force-tlsv11")) {
4734#if SSL_OP_NO_TLSv1_1
4735 global.connect_default_ssloptions |= SRV_SSL_O_USE_TLSV11;
4736#else
4737 memprintf(err, "'%s' '%s': library does not support protocol TLSv1.1", args[0], args[i]);
4738 return -1;
4739#endif
4740 }
4741 else if (!strcmp(args[i], "force-tlsv12")) {
4742#if SSL_OP_NO_TLSv1_2
4743 global.connect_default_ssloptions |= SRV_SSL_O_USE_TLSV12;
4744#else
4745 memprintf(err, "'%s' '%s': library does not support protocol TLSv1.2", args[0], args[i]);
4746 return -1;
4747#endif
4748 }
4749 else if (!strcmp(args[i], "no-tls-tickets"))
4750 global.connect_default_ssloptions |= SRV_SSL_O_NO_TLS_TICKETS;
4751 else {
4752 memprintf(err, "unknown option '%s' on global statement '%s'.", args[i], args[0]);
4753 return -1;
4754 }
4755 i++;
4756 }
4757 return 0;
4758}
4759
Willy Tarreau7875d092012-09-10 08:20:03 +02004760/* Note: must not be declared <const> as its list will be overwritten.
4761 * Please take care of keeping this list alphabetically sorted.
4762 */
Willy Tarreaudc13c112013-06-21 23:16:39 +02004763static struct sample_fetch_kw_list sample_fetch_keywords = {ILH, {
Emeric Brun645ae792014-04-30 14:21:06 +02004764 { "ssl_bc", smp_fetch_ssl_fc, 0, NULL, SMP_T_BOOL, SMP_USE_L5SRV },
4765 { "ssl_bc_alg_keysize", smp_fetch_ssl_fc_alg_keysize, 0, NULL, SMP_T_UINT, SMP_USE_L5SRV },
4766 { "ssl_bc_cipher", smp_fetch_ssl_fc_cipher, 0, NULL, SMP_T_STR, SMP_USE_L5SRV },
4767 { "ssl_bc_protocol", smp_fetch_ssl_fc_protocol, 0, NULL, SMP_T_STR, SMP_USE_L5SRV },
Emeric Brunb73a9b02014-04-30 18:49:19 +02004768 { "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 +02004769 { "ssl_bc_use_keysize", smp_fetch_ssl_fc_use_keysize, 0, NULL, SMP_T_UINT, SMP_USE_L5SRV },
4770 { "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 +01004771 { "ssl_c_ca_err", smp_fetch_ssl_c_ca_err, 0, NULL, SMP_T_UINT, SMP_USE_L5CLI },
4772 { "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 +01004773 { "ssl_c_der", smp_fetch_ssl_x_der, 0, NULL, SMP_T_BIN, SMP_USE_L5CLI },
Willy Tarreau80aca902013-01-07 15:42:20 +01004774 { "ssl_c_err", smp_fetch_ssl_c_err, 0, NULL, SMP_T_UINT, SMP_USE_L5CLI },
Emeric Brunba841a12014-04-30 17:05:08 +02004775 { "ssl_c_i_dn", smp_fetch_ssl_x_i_dn, ARG2(0,STR,SINT), NULL, SMP_T_STR, SMP_USE_L5CLI },
4776 { "ssl_c_key_alg", smp_fetch_ssl_x_key_alg, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
4777 { "ssl_c_notafter", smp_fetch_ssl_x_notafter, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
4778 { "ssl_c_notbefore", smp_fetch_ssl_x_notbefore, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
4779 { "ssl_c_sig_alg", smp_fetch_ssl_x_sig_alg, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
4780 { "ssl_c_s_dn", smp_fetch_ssl_x_s_dn, ARG2(0,STR,SINT), NULL, SMP_T_STR, SMP_USE_L5CLI },
4781 { "ssl_c_serial", smp_fetch_ssl_x_serial, 0, NULL, SMP_T_BIN, SMP_USE_L5CLI },
4782 { "ssl_c_sha1", smp_fetch_ssl_x_sha1, 0, NULL, SMP_T_BIN, SMP_USE_L5CLI },
Willy Tarreau80aca902013-01-07 15:42:20 +01004783 { "ssl_c_used", smp_fetch_ssl_c_used, 0, NULL, SMP_T_BOOL, SMP_USE_L5CLI },
4784 { "ssl_c_verify", smp_fetch_ssl_c_verify, 0, NULL, SMP_T_UINT, SMP_USE_L5CLI },
Emeric Brunba841a12014-04-30 17:05:08 +02004785 { "ssl_c_version", smp_fetch_ssl_x_version, 0, NULL, SMP_T_UINT, SMP_USE_L5CLI },
Emeric Brun43e79582014-10-29 19:03:26 +01004786 { "ssl_f_der", smp_fetch_ssl_x_der, 0, NULL, SMP_T_BIN, SMP_USE_L5CLI },
Emeric Brunba841a12014-04-30 17:05:08 +02004787 { "ssl_f_i_dn", smp_fetch_ssl_x_i_dn, ARG2(0,STR,SINT), NULL, SMP_T_STR, SMP_USE_L5CLI },
4788 { "ssl_f_key_alg", smp_fetch_ssl_x_key_alg, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
4789 { "ssl_f_notafter", smp_fetch_ssl_x_notafter, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
4790 { "ssl_f_notbefore", smp_fetch_ssl_x_notbefore, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
4791 { "ssl_f_sig_alg", smp_fetch_ssl_x_sig_alg, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
4792 { "ssl_f_s_dn", smp_fetch_ssl_x_s_dn, ARG2(0,STR,SINT), NULL, SMP_T_STR, SMP_USE_L5CLI },
4793 { "ssl_f_serial", smp_fetch_ssl_x_serial, 0, NULL, SMP_T_BIN, SMP_USE_L5CLI },
Emeric Brun55f4fa82014-04-30 17:11:25 +02004794 { "ssl_f_sha1", smp_fetch_ssl_x_sha1, 0, NULL, SMP_T_BIN, SMP_USE_L5CLI },
Emeric Brunba841a12014-04-30 17:05:08 +02004795 { "ssl_f_version", smp_fetch_ssl_x_version, 0, NULL, SMP_T_UINT, SMP_USE_L5CLI },
Willy Tarreau80aca902013-01-07 15:42:20 +01004796 { "ssl_fc", smp_fetch_ssl_fc, 0, NULL, SMP_T_BOOL, SMP_USE_L5CLI },
4797 { "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 +01004798 { "ssl_fc_cipher", smp_fetch_ssl_fc_cipher, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
Willy Tarreau80aca902013-01-07 15:42:20 +01004799 { "ssl_fc_has_crt", smp_fetch_ssl_fc_has_crt, 0, NULL, SMP_T_BOOL, SMP_USE_L5CLI },
4800 { "ssl_fc_has_sni", smp_fetch_ssl_fc_has_sni, 0, NULL, SMP_T_BOOL, SMP_USE_L5CLI },
Nenad Merdanovic26ea8222015-05-18 02:28:57 +02004801 { "ssl_fc_is_resumed", smp_fetch_ssl_fc_is_resumed, 0, NULL, SMP_T_BOOL, SMP_USE_L5CLI },
Willy Tarreaua33c6542012-10-15 13:19:06 +02004802#ifdef OPENSSL_NPN_NEGOTIATED
Thierry FOURNIER7654c9f2013-12-17 00:20:33 +01004803 { "ssl_fc_npn", smp_fetch_ssl_fc_npn, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
Willy Tarreaua33c6542012-10-15 13:19:06 +02004804#endif
Dirkjan Bussink48f1c4e2014-02-13 12:29:42 +01004805#ifdef TLSEXT_TYPE_application_layer_protocol_negotiation
Thierry FOURNIER7654c9f2013-12-17 00:20:33 +01004806 { "ssl_fc_alpn", smp_fetch_ssl_fc_alpn, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
Willy Tarreauab861d32013-04-02 02:30:41 +02004807#endif
Thierry FOURNIER7654c9f2013-12-17 00:20:33 +01004808 { "ssl_fc_protocol", smp_fetch_ssl_fc_protocol, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
Emeric Brunb73a9b02014-04-30 18:49:19 +02004809 { "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 +01004810 { "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 +01004811 { "ssl_fc_session_id", smp_fetch_ssl_fc_session_id, 0, NULL, SMP_T_BIN, SMP_USE_L5CLI },
4812 { "ssl_fc_sni", smp_fetch_ssl_fc_sni, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
Willy Tarreau7875d092012-09-10 08:20:03 +02004813 { NULL, NULL, 0, 0, 0 },
4814}};
4815
4816/* Note: must not be declared <const> as its list will be overwritten.
4817 * Please take care of keeping this list alphabetically sorted.
4818 */
Willy Tarreaudc13c112013-06-21 23:16:39 +02004819static struct acl_kw_list acl_kws = {ILH, {
Thierry FOURNIERc5a4e982014-03-05 16:07:08 +01004820 { "ssl_fc_sni_end", "ssl_fc_sni", PAT_MATCH_END },
4821 { "ssl_fc_sni_reg", "ssl_fc_sni", PAT_MATCH_REG },
Willy Tarreau8ed669b2013-01-11 15:49:37 +01004822 { /* END */ },
Willy Tarreau7875d092012-09-10 08:20:03 +02004823}};
4824
Willy Tarreau79eeafa2012-09-14 07:53:05 +02004825/* Note: must not be declared <const> as its list will be overwritten.
4826 * Please take care of keeping this list alphabetically sorted, doing so helps
4827 * all code contributors.
4828 * Optional keywords are also declared with a NULL ->parse() function so that
4829 * the config parser can report an appropriate error when a known keyword was
4830 * not enabled.
4831 */
Willy Tarreau51fb7652012-09-18 18:24:39 +02004832static struct bind_kw_list bind_kws = { "SSL", { }, {
Nenad Merdanovic05552d42015-02-27 19:56:49 +01004833 { "alpn", bind_parse_alpn, 1 }, /* set ALPN supported protocols */
4834 { "ca-file", bind_parse_ca_file, 1 }, /* set CAfile to process verify on client cert */
4835 { "ca-ignore-err", bind_parse_ignore_err, 1 }, /* set error IDs to ignore on verify depth > 0 */
4836 { "ciphers", bind_parse_ciphers, 1 }, /* set SSL cipher suite */
4837 { "crl-file", bind_parse_crl_file, 1 }, /* set certificat revocation list file use on client cert verify */
4838 { "crt", bind_parse_crt, 1 }, /* load SSL certificates from this location */
4839 { "crt-ignore-err", bind_parse_ignore_err, 1 }, /* set error IDs to ingore on verify depth == 0 */
4840 { "crt-list", bind_parse_crt_list, 1 }, /* load a list of crt from this location */
4841 { "ecdhe", bind_parse_ecdhe, 1 }, /* defines named curve for elliptic curve Diffie-Hellman */
4842 { "force-sslv3", bind_parse_force_sslv3, 0 }, /* force SSLv3 */
4843 { "force-tlsv10", bind_parse_force_tlsv10, 0 }, /* force TLSv10 */
4844 { "force-tlsv11", bind_parse_force_tlsv11, 0 }, /* force TLSv11 */
4845 { "force-tlsv12", bind_parse_force_tlsv12, 0 }, /* force TLSv12 */
4846 { "no-sslv3", bind_parse_no_sslv3, 0 }, /* disable SSLv3 */
4847 { "no-tlsv10", bind_parse_no_tlsv10, 0 }, /* disable TLSv10 */
4848 { "no-tlsv11", bind_parse_no_tlsv11, 0 }, /* disable TLSv11 */
4849 { "no-tlsv12", bind_parse_no_tlsv12, 0 }, /* disable TLSv12 */
4850 { "no-tls-tickets", bind_parse_no_tls_tickets, 0 }, /* disable session resumption tickets */
4851 { "ssl", bind_parse_ssl, 0 }, /* enable SSL processing */
4852 { "strict-sni", bind_parse_strict_sni, 0 }, /* refuse negotiation if sni doesn't match a certificate */
4853 { "tls-ticket-keys", bind_parse_tls_ticket_keys, 1 }, /* set file to load TLS ticket keys from */
4854 { "verify", bind_parse_verify, 1 }, /* set SSL verify method */
4855 { "npn", bind_parse_npn, 1 }, /* set NPN supported protocols */
Willy Tarreau79eeafa2012-09-14 07:53:05 +02004856 { NULL, NULL, 0 },
4857}};
Emeric Brun46591952012-05-18 15:47:34 +02004858
Willy Tarreau92faadf2012-10-10 23:04:25 +02004859/* Note: must not be declared <const> as its list will be overwritten.
4860 * Please take care of keeping this list alphabetically sorted, doing so helps
4861 * all code contributors.
4862 * Optional keywords are also declared with a NULL ->parse() function so that
4863 * the config parser can report an appropriate error when a known keyword was
4864 * not enabled.
4865 */
4866static struct srv_kw_list srv_kws = { "SSL", { }, {
Emeric Brunef42d922012-10-11 16:11:36 +02004867 { "ca-file", srv_parse_ca_file, 1, 0 }, /* set CAfile to process verify server cert */
Emeric Brunecc91fe2012-10-11 15:05:10 +02004868 { "check-ssl", srv_parse_check_ssl, 0, 0 }, /* enable SSL for health checks */
4869 { "ciphers", srv_parse_ciphers, 1, 0 }, /* select the cipher suite */
Emeric Brunef42d922012-10-11 16:11:36 +02004870 { "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 +02004871 { "crt", srv_parse_crt, 1, 0 }, /* set client certificate */
Emeric Brunecc91fe2012-10-11 15:05:10 +02004872 { "force-sslv3", srv_parse_force_sslv3, 0, 0 }, /* force SSLv3 */
4873 { "force-tlsv10", srv_parse_force_tlsv10, 0, 0 }, /* force TLSv10 */
4874 { "force-tlsv11", srv_parse_force_tlsv11, 0, 0 }, /* force TLSv11 */
4875 { "force-tlsv12", srv_parse_force_tlsv12, 0, 0 }, /* force TLSv12 */
Willy Tarreau2a3fb1c2015-02-05 16:47:07 +01004876 { "no-ssl-reuse", srv_parse_no_ssl_reuse, 0, 0 }, /* disable session reuse */
Emeric Brunecc91fe2012-10-11 15:05:10 +02004877 { "no-sslv3", srv_parse_no_sslv3, 0, 0 }, /* disable SSLv3 */
4878 { "no-tlsv10", srv_parse_no_tlsv10, 0, 0 }, /* disable TLSv10 */
4879 { "no-tlsv11", srv_parse_no_tlsv11, 0, 0 }, /* disable TLSv11 */
4880 { "no-tlsv12", srv_parse_no_tlsv12, 0, 0 }, /* disable TLSv12 */
Emeric Brunf9c5c472012-10-11 15:28:34 +02004881 { "no-tls-tickets", srv_parse_no_tls_tickets, 0, 0 }, /* disable session resumption tickets */
David Safb76832014-05-08 23:42:08 -04004882 { "send-proxy-v2-ssl", srv_parse_send_proxy_ssl, 0, 0 }, /* send PROXY protocol header v2 with SSL info */
4883 { "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 +02004884 { "ssl", srv_parse_ssl, 0, 0 }, /* enable SSL processing */
Emeric Brunef42d922012-10-11 16:11:36 +02004885 { "verify", srv_parse_verify, 1, 0 }, /* set SSL verify method */
Evan Broderbe554312013-06-27 00:05:25 -07004886 { "verifyhost", srv_parse_verifyhost, 1, 0 }, /* require that SSL cert verifies for hostname */
Willy Tarreau92faadf2012-10-10 23:04:25 +02004887 { NULL, NULL, 0, 0 },
4888}};
4889
Emeric Brun2c86cbf2014-10-30 15:56:50 +01004890static struct cfg_kw_list cfg_kws = {ILH, {
4891 { CFG_GLOBAL, "ssl-default-bind-options", ssl_parse_default_bind_options },
4892 { CFG_GLOBAL, "ssl-default-server-options", ssl_parse_default_server_options },
4893 { 0, NULL, NULL },
4894}};
4895
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02004896/* transport-layer operations for SSL sockets */
4897struct xprt_ops ssl_sock = {
Emeric Brun46591952012-05-18 15:47:34 +02004898 .snd_buf = ssl_sock_from_buf,
4899 .rcv_buf = ssl_sock_to_buf,
4900 .rcv_pipe = NULL,
4901 .snd_pipe = NULL,
4902 .shutr = NULL,
4903 .shutw = ssl_sock_shutw,
4904 .close = ssl_sock_close,
4905 .init = ssl_sock_init,
4906};
4907
Janusz Dziemidowicz2c701b52015-03-07 23:03:59 +01004908#if (OPENSSL_VERSION_NUMBER >= 0x1000200fL && !defined OPENSSL_NO_TLSEXT && !defined OPENSSL_IS_BORINGSSL)
4909
4910static void ssl_sock_sctl_free_func(void *parent, void *ptr, CRYPTO_EX_DATA *ad, int idx, long argl, void *argp)
4911{
4912 if (ptr) {
4913 chunk_destroy(ptr);
4914 free(ptr);
4915 }
4916}
4917
4918#endif
4919
Emeric Brun46591952012-05-18 15:47:34 +02004920__attribute__((constructor))
Willy Tarreau92faadf2012-10-10 23:04:25 +02004921static void __ssl_sock_init(void)
4922{
Emeric Brun46591952012-05-18 15:47:34 +02004923 STACK_OF(SSL_COMP)* cm;
4924
Willy Tarreau610f04b2014-02-13 11:36:41 +01004925#ifdef LISTEN_DEFAULT_CIPHERS
4926 global.listen_default_ciphers = LISTEN_DEFAULT_CIPHERS;
4927#endif
4928#ifdef CONNECT_DEFAULT_CIPHERS
4929 global.connect_default_ciphers = CONNECT_DEFAULT_CIPHERS;
4930#endif
4931 if (global.listen_default_ciphers)
4932 global.listen_default_ciphers = strdup(global.listen_default_ciphers);
4933 if (global.connect_default_ciphers)
4934 global.connect_default_ciphers = strdup(global.connect_default_ciphers);
Emeric Brun2c86cbf2014-10-30 15:56:50 +01004935 global.listen_default_ssloptions = BC_SSL_O_NONE;
4936 global.connect_default_ssloptions = SRV_SSL_O_NONE;
Willy Tarreau610f04b2014-02-13 11:36:41 +01004937
Emeric Brun46591952012-05-18 15:47:34 +02004938 SSL_library_init();
4939 cm = SSL_COMP_get_compression_methods();
4940 sk_SSL_COMP_zero(cm);
Janusz Dziemidowicz2c701b52015-03-07 23:03:59 +01004941#if (OPENSSL_VERSION_NUMBER >= 0x1000200fL && !defined OPENSSL_NO_TLSEXT && !defined OPENSSL_IS_BORINGSSL)
4942 sctl_ex_index = SSL_CTX_get_ex_new_index(0, NULL, NULL, NULL, ssl_sock_sctl_free_func);
4943#endif
Willy Tarreau7875d092012-09-10 08:20:03 +02004944 sample_register_fetches(&sample_fetch_keywords);
4945 acl_register_keywords(&acl_kws);
Willy Tarreau79eeafa2012-09-14 07:53:05 +02004946 bind_register_keywords(&bind_kws);
Willy Tarreau92faadf2012-10-10 23:04:25 +02004947 srv_register_keywords(&srv_kws);
Emeric Brun2c86cbf2014-10-30 15:56:50 +01004948 cfg_register_keywords(&cfg_kws);
Willy Tarreaud92aa5c2015-01-15 21:34:39 +01004949
4950 global.ssl_session_max_cost = SSL_SESSION_MAX_COST;
4951 global.ssl_handshake_max_cost = SSL_HANDSHAKE_MAX_COST;
Remi Gacogne4f902b82015-05-28 16:23:00 +02004952
4953#ifndef OPENSSL_NO_DH
4954 ssl_dh_ptr_index = SSL_CTX_get_ex_new_index(0, NULL, NULL, NULL, NULL);
4955#endif
Emeric Brun46591952012-05-18 15:47:34 +02004956}
4957
Remi Gacogned3a23c32015-05-28 16:39:47 +02004958__attribute__((destructor))
4959static void __ssl_sock_deinit(void)
4960{
4961#ifndef OPENSSL_NO_DH
4962 if (local_dh_1024) {
4963 DH_free(local_dh_1024);
4964 local_dh_1024 = NULL;
4965 }
4966
4967 if (local_dh_2048) {
4968 DH_free(local_dh_2048);
4969 local_dh_2048 = NULL;
4970 }
4971
4972 if (local_dh_4096) {
4973 DH_free(local_dh_4096);
4974 local_dh_4096 = NULL;
4975 }
4976
Remi Gacogne47783ef2015-05-29 15:53:22 +02004977 if (global_dh) {
4978 DH_free(global_dh);
4979 global_dh = NULL;
4980 }
Remi Gacogned3a23c32015-05-28 16:39:47 +02004981#endif
4982
4983 ERR_remove_state(0);
4984 ERR_free_strings();
4985
4986 EVP_cleanup();
4987
4988#if OPENSSL_VERSION_NUMBER >= 0x00907000L
4989 CRYPTO_cleanup_all_ex_data();
4990#endif
4991}
4992
4993
Emeric Brun46591952012-05-18 15:47:34 +02004994/*
4995 * Local variables:
4996 * c-indent-level: 8
4997 * c-basic-offset: 8
4998 * End:
4999 */