blob: 4e755494240402f5760e222f73c01631d690902e [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>
Christopher Faulet31af49d2015-06-09 17:29:50 +020038#include <netdb.h>
Emeric Brun46591952012-05-18 15:47:34 +020039#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
Christopher Faulet31af49d2015-06-09 17:29:50 +020054#include <import/lru.h>
55#include <import/xxhash.h>
56
Emeric Brun46591952012-05-18 15:47:34 +020057#include <common/buffer.h>
58#include <common/compat.h>
59#include <common/config.h>
60#include <common/debug.h>
Willy Tarreau79eeafa2012-09-14 07:53:05 +020061#include <common/errors.h>
Emeric Brun46591952012-05-18 15:47:34 +020062#include <common/standard.h>
63#include <common/ticks.h>
64#include <common/time.h>
Emeric Brun2c86cbf2014-10-30 15:56:50 +010065#include <common/cfgparse.h>
Nenad Merdanovic05552d42015-02-27 19:56:49 +010066#include <common/base64.h>
Emeric Brun46591952012-05-18 15:47:34 +020067
Emeric Brunfc0421f2012-09-07 17:30:07 +020068#include <ebsttree.h>
69
70#include <types/global.h>
71#include <types/ssl_sock.h>
72
Willy Tarreau7875d092012-09-10 08:20:03 +020073#include <proto/acl.h>
74#include <proto/arg.h>
Emeric Brun46591952012-05-18 15:47:34 +020075#include <proto/connection.h>
76#include <proto/fd.h>
77#include <proto/freq_ctr.h>
78#include <proto/frontend.h>
Willy Tarreau79eeafa2012-09-14 07:53:05 +020079#include <proto/listener.h>
Thierry FOURNIERed66c292013-11-28 11:05:19 +010080#include <proto/pattern.h>
Christopher Faulet31af49d2015-06-09 17:29:50 +020081#include <proto/proto_tcp.h>
Willy Tarreau92faadf2012-10-10 23:04:25 +020082#include <proto/server.h>
Emeric Brun46591952012-05-18 15:47:34 +020083#include <proto/log.h>
Emeric Brun94324a42012-10-11 14:00:19 +020084#include <proto/proxy.h>
Emeric Brunfc0421f2012-09-07 17:30:07 +020085#include <proto/shctx.h>
Emeric Brun46591952012-05-18 15:47:34 +020086#include <proto/ssl_sock.h>
Willy Tarreau9ad7bd42015-04-03 19:19:59 +020087#include <proto/stream.h>
Emeric Brun46591952012-05-18 15:47:34 +020088#include <proto/task.h>
89
Willy Tarreau518cedd2014-02-17 15:43:01 +010090/* Warning, these are bits, not integers! */
Emeric Brune64aef12012-09-21 13:15:06 +020091#define SSL_SOCK_ST_FL_VERIFY_DONE 0x00000001
Emeric Brund8b2bb52014-01-28 15:43:53 +010092#define SSL_SOCK_ST_FL_16K_WBFSIZE 0x00000002
Willy Tarreau518cedd2014-02-17 15:43:01 +010093#define SSL_SOCK_SEND_UNLIMITED 0x00000004
Emeric Brun29f037d2014-04-25 19:05:36 +020094#define SSL_SOCK_RECV_HEARTBEAT 0x00000008
95
Emeric Brunf282a812012-09-21 15:27:54 +020096/* bits 0xFFFF0000 are reserved to store verify errors */
97
98/* Verify errors macros */
99#define SSL_SOCK_CA_ERROR_TO_ST(e) (((e > 63) ? 63 : e) << (16))
100#define SSL_SOCK_CAEDEPTH_TO_ST(d) (((d > 15) ? 15 : d) << (6+16))
101#define SSL_SOCK_CRTERROR_TO_ST(e) (((e > 63) ? 63 : e) << (4+6+16))
102
103#define SSL_SOCK_ST_TO_CA_ERROR(s) ((s >> (16)) & 63)
104#define SSL_SOCK_ST_TO_CAEDEPTH(s) ((s >> (6+16)) & 15)
105#define SSL_SOCK_ST_TO_CRTERROR(s) ((s >> (4+6+16)) & 63)
Emeric Brune64aef12012-09-21 13:15:06 +0200106
Nenad Merdanovic05552d42015-02-27 19:56:49 +0100107/* Supported hash function for TLS tickets */
108#ifdef OPENSSL_NO_SHA256
109#define HASH_FUNCT EVP_sha1
110#else
111#define HASH_FUNCT EVP_sha256
112#endif /* OPENSSL_NO_SHA256 */
113
Emeric Brun850efd52014-01-29 12:24:34 +0100114/* server and bind verify method, it uses a global value as default */
115enum {
116 SSL_SOCK_VERIFY_DEFAULT = 0,
117 SSL_SOCK_VERIFY_REQUIRED = 1,
118 SSL_SOCK_VERIFY_OPTIONAL = 2,
119 SSL_SOCK_VERIFY_NONE = 3,
120};
121
Willy Tarreau71b734c2014-01-28 15:19:44 +0100122int sslconns = 0;
123int totalsslconns = 0;
Emeric Brune1f38db2012-09-03 20:36:47 +0200124
Nenad Merdanovic200b0fa2015-05-09 08:46:01 +0200125#if (defined SSL_CTRL_SET_TLSEXT_TICKET_KEY_CB && TLS_TICKETS_NO > 0)
126struct list tlskeys_reference = LIST_HEAD_INIT(tlskeys_reference);
127#endif
128
Remi Gacogne8de54152014-07-15 11:36:40 +0200129#ifndef OPENSSL_NO_DH
Remi Gacogne4f902b82015-05-28 16:23:00 +0200130static int ssl_dh_ptr_index = -1;
Remi Gacogne47783ef2015-05-29 15:53:22 +0200131static DH *global_dh = NULL;
Remi Gacogne8de54152014-07-15 11:36:40 +0200132static DH *local_dh_1024 = NULL;
133static DH *local_dh_2048 = NULL;
134static DH *local_dh_4096 = NULL;
Remi Gacogne8de54152014-07-15 11:36:40 +0200135#endif /* OPENSSL_NO_DH */
136
Willy Tarreauc8ad3be2015-06-17 15:48:26 +0200137#ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME
Christopher Faulet31af49d2015-06-09 17:29:50 +0200138/* X509V3 Extensions that will be added on generated certificates */
139#define X509V3_EXT_SIZE 5
140static char *x509v3_ext_names[X509V3_EXT_SIZE] = {
141 "basicConstraints",
142 "nsComment",
143 "subjectKeyIdentifier",
144 "authorityKeyIdentifier",
145 "keyUsage",
146};
147static char *x509v3_ext_values[X509V3_EXT_SIZE] = {
148 "CA:FALSE",
149 "\"OpenSSL Generated Certificate\"",
150 "hash",
151 "keyid,issuer:always",
152 "nonRepudiation,digitalSignature,keyEncipherment"
153};
154
155/* LRU cache to store generated certificate */
156static struct lru64_head *ssl_ctx_lru_tree = NULL;
157static unsigned int ssl_ctx_lru_seed = 0;
Willy Tarreauc8ad3be2015-06-17 15:48:26 +0200158#endif // SSL_CTRL_SET_TLSEXT_HOSTNAME
159
160#if (defined SSL_CTRL_SET_TLSEXT_STATUS_REQ_CB && !defined OPENSSL_NO_OCSP)
161struct certificate_ocsp {
162 struct ebmb_node key;
163 unsigned char key_data[OCSP_MAX_CERTID_ASN1_LENGTH];
164 struct chunk response;
165 long expire;
166};
Christopher Faulet31af49d2015-06-09 17:29:50 +0200167
Emeric Brun4f3c87a2014-06-20 15:46:13 +0200168/*
169 * This function returns the number of seconds elapsed
170 * since the Epoch, 1970-01-01 00:00:00 +0000 (UTC) and the
171 * date presented un ASN1_GENERALIZEDTIME.
172 *
173 * In parsing error case, it returns -1.
174 */
175static long asn1_generalizedtime_to_epoch(ASN1_GENERALIZEDTIME *d)
176{
177 long epoch;
178 char *p, *end;
179 const unsigned short month_offset[12] = {
180 0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334
181 };
182 int year, month;
183
184 if (!d || (d->type != V_ASN1_GENERALIZEDTIME)) return -1;
185
186 p = (char *)d->data;
187 end = p + d->length;
188
189 if (end - p < 4) return -1;
190 year = 1000 * (p[0] - '0') + 100 * (p[1] - '0') + 10 * (p[2] - '0') + p[3] - '0';
191 p += 4;
192 if (end - p < 2) return -1;
193 month = 10 * (p[0] - '0') + p[1] - '0';
194 if (month < 1 || month > 12) return -1;
195 /* Compute the number of seconds since 1 jan 1970 and the beginning of current month
196 We consider leap years and the current month (<marsh or not) */
197 epoch = ( ((year - 1970) * 365)
198 + ((year - (month < 3)) / 4 - (year - (month < 3)) / 100 + (year - (month < 3)) / 400)
199 - ((1970 - 1) / 4 - (1970 - 1) / 100 + (1970 - 1) / 400)
200 + month_offset[month-1]
201 ) * 24 * 60 * 60;
202 p += 2;
203 if (end - p < 2) return -1;
204 /* Add the number of seconds of completed days of current month */
205 epoch += (10 * (p[0] - '0') + p[1] - '0' - 1) * 24 * 60 * 60;
206 p += 2;
207 if (end - p < 2) return -1;
208 /* Add the completed hours of the current day */
209 epoch += (10 * (p[0] - '0') + p[1] - '0') * 60 * 60;
210 p += 2;
211 if (end - p < 2) return -1;
212 /* Add the completed minutes of the current hour */
213 epoch += (10 * (p[0] - '0') + p[1] - '0') * 60;
214 p += 2;
215 if (p == end) return -1;
216 /* Test if there is available seconds */
217 if (p[0] < '0' || p[0] > '9')
218 goto nosec;
219 if (end - p < 2) return -1;
220 /* Add the seconds of the current minute */
221 epoch += 10 * (p[0] - '0') + p[1] - '0';
222 p += 2;
223 if (p == end) return -1;
224 /* Ignore seconds float part if present */
225 if (p[0] == '.') {
226 do {
227 if (++p == end) return -1;
228 } while (p[0] >= '0' && p[0] <= '9');
229 }
230
231nosec:
232 if (p[0] == 'Z') {
233 if (end - p != 1) return -1;
234 return epoch;
235 }
236 else if (p[0] == '+') {
237 if (end - p != 5) return -1;
238 /* Apply timezone offset */
239 return epoch - ((10 * (p[1] - '0') + p[2] - '0') * 60 + (10 * (p[3] - '0') + p[4] - '0')) * 60;
240 }
241 else if (p[0] == '-') {
242 if (end - p != 5) return -1;
243 /* Apply timezone offset */
244 return epoch + ((10 * (p[1] - '0') + p[2] - '0') * 60 + (10 * (p[3] - '0') + p[4] - '0')) * 60;
245 }
246
247 return -1;
248}
249
Emeric Brun1d3865b2014-06-20 15:37:32 +0200250static struct eb_root cert_ocsp_tree = EB_ROOT_UNIQUE;
Emeric Brun4147b2e2014-06-16 18:36:30 +0200251
252/* This function starts to check if the OCSP response (in DER format) contained
253 * in chunk 'ocsp_response' is valid (else exits on error).
254 * If 'cid' is not NULL, it will be compared to the OCSP certificate ID
255 * contained in the OCSP Response and exits on error if no match.
256 * If it's a valid OCSP Response:
257 * If 'ocsp' is not NULL, the chunk is copied in the OCSP response's container
258 * pointed by 'ocsp'.
259 * If 'ocsp' is NULL, the function looks up into the OCSP response's
260 * containers tree (using as index the ASN1 form of the OCSP Certificate ID extracted
261 * from the response) and exits on error if not found. Finally, If an OCSP response is
262 * already present in the container, it will be overwritten.
263 *
264 * Note: OCSP response containing more than one OCSP Single response is not
265 * considered valid.
266 *
267 * Returns 0 on success, 1 in error case.
268 */
269static int ssl_sock_load_ocsp_response(struct chunk *ocsp_response, struct certificate_ocsp *ocsp, OCSP_CERTID *cid, char **err)
270{
271 OCSP_RESPONSE *resp;
272 OCSP_BASICRESP *bs = NULL;
273 OCSP_SINGLERESP *sr;
274 unsigned char *p = (unsigned char *)ocsp_response->str;
275 int rc , count_sr;
Emeric Brun13a6b482014-06-20 15:44:34 +0200276 ASN1_GENERALIZEDTIME *revtime, *thisupd, *nextupd = NULL;
Emeric Brun4147b2e2014-06-16 18:36:30 +0200277 int reason;
278 int ret = 1;
279
280 resp = d2i_OCSP_RESPONSE(NULL, (const unsigned char **)&p, ocsp_response->len);
281 if (!resp) {
282 memprintf(err, "Unable to parse OCSP response");
283 goto out;
284 }
285
286 rc = OCSP_response_status(resp);
287 if (rc != OCSP_RESPONSE_STATUS_SUCCESSFUL) {
288 memprintf(err, "OCSP response status not successful");
289 goto out;
290 }
291
292 bs = OCSP_response_get1_basic(resp);
293 if (!bs) {
294 memprintf(err, "Failed to get basic response from OCSP Response");
295 goto out;
296 }
297
298 count_sr = OCSP_resp_count(bs);
299 if (count_sr > 1) {
300 memprintf(err, "OCSP response ignored because contains multiple single responses (%d)", count_sr);
301 goto out;
302 }
303
304 sr = OCSP_resp_get0(bs, 0);
305 if (!sr) {
306 memprintf(err, "Failed to get OCSP single response");
307 goto out;
308 }
309
310 rc = OCSP_single_get0_status(sr, &reason, &revtime, &thisupd, &nextupd);
311 if (rc != V_OCSP_CERTSTATUS_GOOD) {
312 memprintf(err, "OCSP single response: certificate status not good");
313 goto out;
314 }
315
Emeric Brun13a6b482014-06-20 15:44:34 +0200316 if (!nextupd) {
317 memprintf(err, "OCSP single response: missing nextupdate");
318 goto out;
319 }
320
Emeric Brunc8b27b62014-06-19 14:16:17 +0200321 rc = OCSP_check_validity(thisupd, nextupd, OCSP_MAX_RESPONSE_TIME_SKEW, -1);
Emeric Brun4147b2e2014-06-16 18:36:30 +0200322 if (!rc) {
323 memprintf(err, "OCSP single response: no longer valid.");
324 goto out;
325 }
326
327 if (cid) {
328 if (OCSP_id_cmp(sr->certId, cid)) {
329 memprintf(err, "OCSP single response: Certificate ID does not match certificate and issuer");
330 goto out;
331 }
332 }
333
334 if (!ocsp) {
335 unsigned char key[OCSP_MAX_CERTID_ASN1_LENGTH];
336 unsigned char *p;
337
338 rc = i2d_OCSP_CERTID(sr->certId, NULL);
339 if (!rc) {
340 memprintf(err, "OCSP single response: Unable to encode Certificate ID");
341 goto out;
342 }
343
344 if (rc > OCSP_MAX_CERTID_ASN1_LENGTH) {
345 memprintf(err, "OCSP single response: Certificate ID too long");
346 goto out;
347 }
348
349 p = key;
350 memset(key, 0, OCSP_MAX_CERTID_ASN1_LENGTH);
351 i2d_OCSP_CERTID(sr->certId, &p);
352 ocsp = (struct certificate_ocsp *)ebmb_lookup(&cert_ocsp_tree, key, OCSP_MAX_CERTID_ASN1_LENGTH);
353 if (!ocsp) {
354 memprintf(err, "OCSP single response: Certificate ID does not match any certificate or issuer");
355 goto out;
356 }
357 }
358
359 /* According to comments on "chunk_dup", the
360 previous chunk buffer will be freed */
361 if (!chunk_dup(&ocsp->response, ocsp_response)) {
362 memprintf(err, "OCSP response: Memory allocation error");
363 goto out;
364 }
365
Emeric Brun4f3c87a2014-06-20 15:46:13 +0200366 ocsp->expire = asn1_generalizedtime_to_epoch(nextupd) - OCSP_MAX_RESPONSE_TIME_SKEW;
367
Emeric Brun4147b2e2014-06-16 18:36:30 +0200368 ret = 0;
369out:
370 if (bs)
371 OCSP_BASICRESP_free(bs);
372
373 if (resp)
374 OCSP_RESPONSE_free(resp);
375
376 return ret;
377}
378/*
379 * External function use to update the OCSP response in the OCSP response's
380 * containers tree. The chunk 'ocsp_response' must contain the OCSP response
381 * to update in DER format.
382 *
383 * Returns 0 on success, 1 in error case.
384 */
385int ssl_sock_update_ocsp_response(struct chunk *ocsp_response, char **err)
386{
387 return ssl_sock_load_ocsp_response(ocsp_response, NULL, NULL, err);
388}
389
390/*
391 * This function load the OCSP Resonse in DER format contained in file at
392 * path 'ocsp_path' and call 'ssl_sock_load_ocsp_response'
393 *
394 * Returns 0 on success, 1 in error case.
395 */
396static int ssl_sock_load_ocsp_response_from_file(const char *ocsp_path, struct certificate_ocsp *ocsp, OCSP_CERTID *cid, char **err)
397{
398 int fd = -1;
399 int r = 0;
400 int ret = 1;
401
402 fd = open(ocsp_path, O_RDONLY);
403 if (fd == -1) {
404 memprintf(err, "Error opening OCSP response file");
405 goto end;
406 }
407
408 trash.len = 0;
409 while (trash.len < trash.size) {
410 r = read(fd, trash.str + trash.len, trash.size - trash.len);
411 if (r < 0) {
412 if (errno == EINTR)
413 continue;
414
415 memprintf(err, "Error reading OCSP response from file");
416 goto end;
417 }
418 else if (r == 0) {
419 break;
420 }
421 trash.len += r;
422 }
423
424 close(fd);
425 fd = -1;
426
427 ret = ssl_sock_load_ocsp_response(&trash, ocsp, cid, err);
428end:
429 if (fd != -1)
430 close(fd);
431
432 return ret;
433}
434
Nenad Merdanovic05552d42015-02-27 19:56:49 +0100435#if (defined SSL_CTRL_SET_TLSEXT_TICKET_KEY_CB && TLS_TICKETS_NO > 0)
436static 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)
437{
438 struct tls_sess_key *keys;
439 struct connection *conn;
440 int head;
441 int i;
442
443 conn = (struct connection *)SSL_get_app_data(s);
Nenad Merdanovic146defa2015-05-09 08:46:00 +0200444 keys = objt_listener(conn->target)->bind_conf->keys_ref->tlskeys;
445 head = objt_listener(conn->target)->bind_conf->keys_ref->tls_ticket_enc_index;
Nenad Merdanovic05552d42015-02-27 19:56:49 +0100446
447 if (enc) {
448 memcpy(key_name, keys[head].name, 16);
449
450 if(!RAND_pseudo_bytes(iv, EVP_MAX_IV_LENGTH))
451 return -1;
452
453 if(!EVP_EncryptInit_ex(ectx, EVP_aes_128_cbc(), NULL, keys[head].aes_key, iv))
454 return -1;
455
456 HMAC_Init_ex(hctx, keys[head].hmac_key, 16, HASH_FUNCT(), NULL);
457
458 return 1;
459 } else {
460 for (i = 0; i < TLS_TICKETS_NO; i++) {
461 if (!memcmp(key_name, keys[(head + i) % TLS_TICKETS_NO].name, 16))
462 goto found;
463 }
464 return 0;
465
466 found:
467 HMAC_Init_ex(hctx, keys[(head + i) % TLS_TICKETS_NO].hmac_key, 16, HASH_FUNCT(), NULL);
468 if(!EVP_DecryptInit_ex(ectx, EVP_aes_128_cbc(), NULL, keys[(head + i) % TLS_TICKETS_NO].aes_key, iv))
469 return -1;
470 /* 2 for key renewal, 1 if current key is still valid */
471 return i ? 2 : 1;
472 }
Nenad Merdanovic200b0fa2015-05-09 08:46:01 +0200473}
474
475struct tls_keys_ref *tlskeys_ref_lookup(const char *filename)
476{
477 struct tls_keys_ref *ref;
478
479 list_for_each_entry(ref, &tlskeys_reference, list)
480 if (ref->filename && strcmp(filename, ref->filename) == 0)
481 return ref;
482 return NULL;
483}
484
485struct tls_keys_ref *tlskeys_ref_lookupid(int unique_id)
486{
487 struct tls_keys_ref *ref;
488
489 list_for_each_entry(ref, &tlskeys_reference, list)
490 if (ref->unique_id == unique_id)
491 return ref;
492 return NULL;
493}
494
495int ssl_sock_update_tlskey(char *filename, struct chunk *tlskey, char **err) {
496 struct tls_keys_ref *ref = tlskeys_ref_lookup(filename);
497
498 if(!ref) {
499 memprintf(err, "Unable to locate the referenced filename: %s", filename);
500 return 1;
501 }
502
503 memcpy((char *) (ref->tlskeys + 2 % TLS_TICKETS_NO), tlskey->str, tlskey->len);
504 ref->tls_ticket_enc_index = ref->tls_ticket_enc_index + 1 % TLS_TICKETS_NO;
505
506 return 0;
Nenad Merdanovic05552d42015-02-27 19:56:49 +0100507}
Nenad Merdanovic200b0fa2015-05-09 08:46:01 +0200508
509/* This function finalize the configuration parsing. Its set all the
510 * automatic ids
511 */
512void tlskeys_finalize_config(void)
513{
514 int i = 0;
515 struct tls_keys_ref *ref, *ref2, *ref3;
516 struct list tkr = LIST_HEAD_INIT(tkr);
517
518 list_for_each_entry(ref, &tlskeys_reference, list) {
519 if (ref->unique_id == -1) {
520 /* Look for the first free id. */
521 while (1) {
522 list_for_each_entry(ref2, &tlskeys_reference, list) {
523 if (ref2->unique_id == i) {
524 i++;
525 break;
526 }
527 }
528 if (&ref2->list == &tlskeys_reference)
529 break;
530 }
531
532 /* Uses the unique id and increment it for the next entry. */
533 ref->unique_id = i;
534 i++;
535 }
536 }
537
538 /* This sort the reference list by id. */
539 list_for_each_entry_safe(ref, ref2, &tlskeys_reference, list) {
540 LIST_DEL(&ref->list);
541 list_for_each_entry(ref3, &tkr, list) {
542 if (ref->unique_id < ref3->unique_id) {
543 LIST_ADDQ(&ref3->list, &ref->list);
544 break;
545 }
546 }
547 if (&ref3->list == &tkr)
548 LIST_ADDQ(&tkr, &ref->list);
549 }
550
551 /* swap root */
552 LIST_ADD(&tkr, &tlskeys_reference);
553 LIST_DEL(&tkr);
554}
555
Nenad Merdanovic05552d42015-02-27 19:56:49 +0100556#endif /* SSL_CTRL_SET_TLSEXT_TICKET_KEY_CB */
557
Emeric Brun4147b2e2014-06-16 18:36:30 +0200558/*
559 * Callback used to set OCSP status extension content in server hello.
560 */
561int ssl_sock_ocsp_stapling_cbk(SSL *ssl, void *arg)
562{
563 struct certificate_ocsp *ocsp = (struct certificate_ocsp *)arg;
564 char* ssl_buf;
565
566 if (!ocsp ||
567 !ocsp->response.str ||
Emeric Brun4f3c87a2014-06-20 15:46:13 +0200568 !ocsp->response.len ||
569 (ocsp->expire < now.tv_sec))
Emeric Brun4147b2e2014-06-16 18:36:30 +0200570 return SSL_TLSEXT_ERR_NOACK;
571
572 ssl_buf = OPENSSL_malloc(ocsp->response.len);
573 if (!ssl_buf)
574 return SSL_TLSEXT_ERR_NOACK;
575
576 memcpy(ssl_buf, ocsp->response.str, ocsp->response.len);
577 SSL_set_tlsext_status_ocsp_resp(ssl, ssl_buf, ocsp->response.len);
578
579 return SSL_TLSEXT_ERR_OK;
580}
581
582/*
583 * This function enables the handling of OCSP status extension on 'ctx' if a
584 * file name 'cert_path' suffixed using ".ocsp" is present.
585 * To enable OCSP status extension, the issuer's certificate is mandatory.
586 * It should be present in the certificate's extra chain builded from file
587 * 'cert_path'. If not found, the issuer certificate is loaded from a file
588 * named 'cert_path' suffixed using '.issuer'.
589 *
590 * In addition, ".ocsp" file content is loaded as a DER format of an OCSP
591 * response. If file is empty or content is not a valid OCSP response,
592 * OCSP status extension is enabled but OCSP response is ignored (a warning
593 * is displayed).
594 *
595 * Returns 1 if no ".ocsp" file found, 0 if OCSP status extension is
596 * succesfully enabled, or -1 in other error case.
597 */
598static int ssl_sock_load_ocsp(SSL_CTX *ctx, const char *cert_path)
599{
600
601 BIO *in = NULL;
602 X509 *x, *xi = NULL, *issuer = NULL;
603 STACK_OF(X509) *chain = NULL;
604 OCSP_CERTID *cid = NULL;
605 SSL *ssl;
606 char ocsp_path[MAXPATHLEN+1];
607 int i, ret = -1;
608 struct stat st;
609 struct certificate_ocsp *ocsp = NULL, *iocsp;
610 char *warn = NULL;
611 unsigned char *p;
612
613 snprintf(ocsp_path, MAXPATHLEN+1, "%s.ocsp", cert_path);
614
615 if (stat(ocsp_path, &st))
616 return 1;
617
618 ssl = SSL_new(ctx);
619 if (!ssl)
620 goto out;
621
622 x = SSL_get_certificate(ssl);
623 if (!x)
624 goto out;
625
626 /* Try to lookup for issuer in certificate extra chain */
627#ifdef SSL_CTRL_GET_EXTRA_CHAIN_CERTS
628 SSL_CTX_get_extra_chain_certs(ctx, &chain);
629#else
630 chain = ctx->extra_certs;
631#endif
632 for (i = 0; i < sk_X509_num(chain); i++) {
633 issuer = sk_X509_value(chain, i);
634 if (X509_check_issued(issuer, x) == X509_V_OK)
635 break;
636 else
637 issuer = NULL;
638 }
639
640 /* If not found try to load issuer from a suffixed file */
641 if (!issuer) {
642 char issuer_path[MAXPATHLEN+1];
643
644 in = BIO_new(BIO_s_file());
645 if (!in)
646 goto out;
647
648 snprintf(issuer_path, MAXPATHLEN+1, "%s.issuer", cert_path);
649 if (BIO_read_filename(in, issuer_path) <= 0)
650 goto out;
651
652 xi = PEM_read_bio_X509_AUX(in, NULL, ctx->default_passwd_callback, ctx->default_passwd_callback_userdata);
653 if (!xi)
654 goto out;
655
656 if (X509_check_issued(xi, x) != X509_V_OK)
657 goto out;
658
659 issuer = xi;
660 }
661
662 cid = OCSP_cert_to_id(0, x, issuer);
663 if (!cid)
664 goto out;
665
666 i = i2d_OCSP_CERTID(cid, NULL);
667 if (!i || (i > OCSP_MAX_CERTID_ASN1_LENGTH))
668 goto out;
669
670 ocsp = calloc(1, sizeof(struct certificate_ocsp));
671 if (!ocsp)
672 goto out;
673
674 p = ocsp->key_data;
675 i2d_OCSP_CERTID(cid, &p);
676
677 iocsp = (struct certificate_ocsp *)ebmb_insert(&cert_ocsp_tree, &ocsp->key, OCSP_MAX_CERTID_ASN1_LENGTH);
678 if (iocsp == ocsp)
679 ocsp = NULL;
680
681 SSL_CTX_set_tlsext_status_cb(ctx, ssl_sock_ocsp_stapling_cbk);
682 SSL_CTX_set_tlsext_status_arg(ctx, iocsp);
683
684 ret = 0;
685
686 warn = NULL;
687 if (ssl_sock_load_ocsp_response_from_file(ocsp_path, iocsp, cid, &warn)) {
688 memprintf(&warn, "Loading '%s': %s. Content will be ignored", ocsp_path, warn ? warn : "failure");
689 Warning("%s.\n", warn);
690 }
691
692out:
693 if (ssl)
694 SSL_free(ssl);
695
696 if (in)
697 BIO_free(in);
698
699 if (xi)
700 X509_free(xi);
701
702 if (cid)
703 OCSP_CERTID_free(cid);
704
705 if (ocsp)
706 free(ocsp);
707
708 if (warn)
709 free(warn);
710
711
712 return ret;
713}
714
715#endif
716
Janusz Dziemidowicz2c701b52015-03-07 23:03:59 +0100717#if (OPENSSL_VERSION_NUMBER >= 0x1000200fL && !defined OPENSSL_NO_TLSEXT && !defined OPENSSL_IS_BORINGSSL)
718
719#define CT_EXTENSION_TYPE 18
720
721static int sctl_ex_index = -1;
722
723/*
724 * Try to parse Signed Certificate Timestamp List structure. This function
725 * makes only basic test if the data seems like SCTL. No signature validation
726 * is performed.
727 */
728static int ssl_sock_parse_sctl(struct chunk *sctl)
729{
730 int ret = 1;
731 int len, pos, sct_len;
732 unsigned char *data;
733
734 if (sctl->len < 2)
735 goto out;
736
737 data = (unsigned char *)sctl->str;
738 len = (data[0] << 8) | data[1];
739
740 if (len + 2 != sctl->len)
741 goto out;
742
743 data = data + 2;
744 pos = 0;
745 while (pos < len) {
746 if (len - pos < 2)
747 goto out;
748
749 sct_len = (data[pos] << 8) | data[pos + 1];
750 if (pos + sct_len + 2 > len)
751 goto out;
752
753 pos += sct_len + 2;
754 }
755
756 ret = 0;
757
758out:
759 return ret;
760}
761
762static int ssl_sock_load_sctl_from_file(const char *sctl_path, struct chunk **sctl)
763{
764 int fd = -1;
765 int r = 0;
766 int ret = 1;
767
768 *sctl = NULL;
769
770 fd = open(sctl_path, O_RDONLY);
771 if (fd == -1)
772 goto end;
773
774 trash.len = 0;
775 while (trash.len < trash.size) {
776 r = read(fd, trash.str + trash.len, trash.size - trash.len);
777 if (r < 0) {
778 if (errno == EINTR)
779 continue;
780
781 goto end;
782 }
783 else if (r == 0) {
784 break;
785 }
786 trash.len += r;
787 }
788
789 ret = ssl_sock_parse_sctl(&trash);
790 if (ret)
791 goto end;
792
793 *sctl = calloc(1, sizeof(struct chunk));
794 if (!chunk_dup(*sctl, &trash)) {
795 free(*sctl);
796 *sctl = NULL;
797 goto end;
798 }
799
800end:
801 if (fd != -1)
802 close(fd);
803
804 return ret;
805}
806
807int ssl_sock_sctl_add_cbk(SSL *ssl, unsigned ext_type, const unsigned char **out, size_t *outlen, int *al, void *add_arg)
808{
809 struct chunk *sctl = (struct chunk *)add_arg;
810
811 *out = (unsigned char *)sctl->str;
812 *outlen = sctl->len;
813
814 return 1;
815}
816
817int ssl_sock_sctl_parse_cbk(SSL *s, unsigned int ext_type, const unsigned char *in, size_t inlen, int *al, void *parse_arg)
818{
819 return 1;
820}
821
822static int ssl_sock_load_sctl(SSL_CTX *ctx, const char *cert_path)
823{
824 char sctl_path[MAXPATHLEN+1];
825 int ret = -1;
826 struct stat st;
827 struct chunk *sctl = NULL;
828
829 snprintf(sctl_path, MAXPATHLEN+1, "%s.sctl", cert_path);
830
831 if (stat(sctl_path, &st))
832 return 1;
833
834 if (ssl_sock_load_sctl_from_file(sctl_path, &sctl))
835 goto out;
836
837 if (!SSL_CTX_add_server_custom_ext(ctx, CT_EXTENSION_TYPE, ssl_sock_sctl_add_cbk, NULL, sctl, ssl_sock_sctl_parse_cbk, NULL)) {
838 free(sctl);
839 goto out;
840 }
841
842 SSL_CTX_set_ex_data(ctx, sctl_ex_index, sctl);
843
844 ret = 0;
845
846out:
847 return ret;
848}
849
850#endif
851
Emeric Brune1f38db2012-09-03 20:36:47 +0200852void ssl_sock_infocbk(const SSL *ssl, int where, int ret)
853{
854 struct connection *conn = (struct connection *)SSL_get_app_data(ssl);
Emeric Brund8b2bb52014-01-28 15:43:53 +0100855 BIO *write_bio;
Willy Tarreau622317d2015-02-27 16:36:16 +0100856 (void)ret; /* shut gcc stupid warning */
Emeric Brune1f38db2012-09-03 20:36:47 +0200857
858 if (where & SSL_CB_HANDSHAKE_START) {
859 /* Disable renegotiation (CVE-2009-3555) */
Willy Tarreau20879a02012-12-03 16:32:10 +0100860 if (conn->flags & CO_FL_CONNECTED) {
Emeric Brune1f38db2012-09-03 20:36:47 +0200861 conn->flags |= CO_FL_ERROR;
Willy Tarreau20879a02012-12-03 16:32:10 +0100862 conn->err_code = CO_ER_SSL_RENEG;
863 }
Emeric Brune1f38db2012-09-03 20:36:47 +0200864 }
Emeric Brund8b2bb52014-01-28 15:43:53 +0100865
866 if ((where & SSL_CB_ACCEPT_LOOP) == SSL_CB_ACCEPT_LOOP) {
867 if (!(conn->xprt_st & SSL_SOCK_ST_FL_16K_WBFSIZE)) {
868 /* Long certificate chains optimz
869 If write and read bios are differents, we
870 consider that the buffering was activated,
871 so we rise the output buffer size from 4k
872 to 16k */
873 write_bio = SSL_get_wbio(ssl);
874 if (write_bio != SSL_get_rbio(ssl)) {
875 BIO_set_write_buffer_size(write_bio, 16384);
876 conn->xprt_st |= SSL_SOCK_ST_FL_16K_WBFSIZE;
877 }
878 }
879 }
Emeric Brunfc0421f2012-09-07 17:30:07 +0200880}
881
Emeric Brune64aef12012-09-21 13:15:06 +0200882/* Callback is called for each certificate of the chain during a verify
883 ok is set to 1 if preverify detect no error on current certificate.
884 Returns 0 to break the handshake, 1 otherwise. */
Evan Broderbe554312013-06-27 00:05:25 -0700885int ssl_sock_bind_verifycbk(int ok, X509_STORE_CTX *x_store)
Emeric Brune64aef12012-09-21 13:15:06 +0200886{
887 SSL *ssl;
888 struct connection *conn;
Emeric Brun81c00f02012-09-21 14:31:21 +0200889 int err, depth;
Emeric Brune64aef12012-09-21 13:15:06 +0200890
891 ssl = X509_STORE_CTX_get_ex_data(x_store, SSL_get_ex_data_X509_STORE_CTX_idx());
892 conn = (struct connection *)SSL_get_app_data(ssl);
893
Willy Tarreauf7bc57c2012-10-03 00:19:48 +0200894 conn->xprt_st |= SSL_SOCK_ST_FL_VERIFY_DONE;
Emeric Brune64aef12012-09-21 13:15:06 +0200895
Emeric Brun81c00f02012-09-21 14:31:21 +0200896 if (ok) /* no errors */
897 return ok;
898
899 depth = X509_STORE_CTX_get_error_depth(x_store);
900 err = X509_STORE_CTX_get_error(x_store);
901
902 /* check if CA error needs to be ignored */
903 if (depth > 0) {
Willy Tarreauf7bc57c2012-10-03 00:19:48 +0200904 if (!SSL_SOCK_ST_TO_CA_ERROR(conn->xprt_st)) {
905 conn->xprt_st |= SSL_SOCK_CA_ERROR_TO_ST(err);
906 conn->xprt_st |= SSL_SOCK_CAEDEPTH_TO_ST(depth);
Emeric Brunf282a812012-09-21 15:27:54 +0200907 }
908
Emeric Brun1eb20ef2012-12-03 13:24:29 +0100909 if (objt_listener(conn->target)->bind_conf->ca_ignerr & (1ULL << err)) {
910 ERR_clear_error();
Emeric Brun81c00f02012-09-21 14:31:21 +0200911 return 1;
Emeric Brun1eb20ef2012-12-03 13:24:29 +0100912 }
Emeric Brun81c00f02012-09-21 14:31:21 +0200913
Willy Tarreau20879a02012-12-03 16:32:10 +0100914 conn->err_code = CO_ER_SSL_CA_FAIL;
Emeric Brun81c00f02012-09-21 14:31:21 +0200915 return 0;
916 }
917
Willy Tarreauf7bc57c2012-10-03 00:19:48 +0200918 if (!SSL_SOCK_ST_TO_CRTERROR(conn->xprt_st))
919 conn->xprt_st |= SSL_SOCK_CRTERROR_TO_ST(err);
Emeric Brunf282a812012-09-21 15:27:54 +0200920
Emeric Brun81c00f02012-09-21 14:31:21 +0200921 /* check if certificate error needs to be ignored */
Emeric Brun1eb20ef2012-12-03 13:24:29 +0100922 if (objt_listener(conn->target)->bind_conf->crt_ignerr & (1ULL << err)) {
923 ERR_clear_error();
Emeric Brun81c00f02012-09-21 14:31:21 +0200924 return 1;
Emeric Brun1eb20ef2012-12-03 13:24:29 +0100925 }
Emeric Brun81c00f02012-09-21 14:31:21 +0200926
Willy Tarreau20879a02012-12-03 16:32:10 +0100927 conn->err_code = CO_ER_SSL_CRT_FAIL;
Emeric Brun81c00f02012-09-21 14:31:21 +0200928 return 0;
Emeric Brune64aef12012-09-21 13:15:06 +0200929}
930
Emeric Brun29f037d2014-04-25 19:05:36 +0200931/* Callback is called for ssl protocol analyse */
932void ssl_sock_msgcbk(int write_p, int version, int content_type, const void *buf, size_t len, SSL *ssl, void *arg)
933{
Emeric Brun29f037d2014-04-25 19:05:36 +0200934#ifdef TLS1_RT_HEARTBEAT
935 /* test heartbeat received (write_p is set to 0
936 for a received record) */
Willy Tarreauf51c6982014-04-25 20:02:39 +0200937 if ((content_type == TLS1_RT_HEARTBEAT) && (write_p == 0)) {
Willy Tarreau84815002014-04-25 21:40:27 +0200938 struct connection *conn = (struct connection *)SSL_get_app_data(ssl);
Willy Tarreauf51c6982014-04-25 20:02:39 +0200939 const unsigned char *p = buf;
940 unsigned int payload;
941
Emeric Brun29f037d2014-04-25 19:05:36 +0200942 conn->xprt_st |= SSL_SOCK_RECV_HEARTBEAT;
Willy Tarreauf51c6982014-04-25 20:02:39 +0200943
944 /* Check if this is a CVE-2014-0160 exploitation attempt. */
945 if (*p != TLS1_HB_REQUEST)
946 return;
947
Willy Tarreauaeed6722014-04-25 23:59:58 +0200948 if (len < 1 + 2 + 16) /* 1 type + 2 size + 0 payload + 16 padding */
Willy Tarreauf51c6982014-04-25 20:02:39 +0200949 goto kill_it;
950
951 payload = (p[1] * 256) + p[2];
Willy Tarreau3b2fdb62014-04-25 23:44:22 +0200952 if (3 + payload + 16 <= len)
Willy Tarreauf51c6982014-04-25 20:02:39 +0200953 return; /* OK no problem */
Willy Tarreauaeed6722014-04-25 23:59:58 +0200954 kill_it:
Willy Tarreau3b2fdb62014-04-25 23:44:22 +0200955 /* We have a clear heartbleed attack (CVE-2014-0160), the
956 * advertised payload is larger than the advertised packet
957 * length, so we have garbage in the buffer between the
958 * payload and the end of the buffer (p+len). We can't know
959 * if the SSL stack is patched, and we don't know if we can
960 * safely wipe out the area between p+3+len and payload.
961 * So instead, we prevent the response from being sent by
962 * setting the max_send_fragment to 0 and we report an SSL
963 * error, which will kill this connection. It will be reported
964 * above as SSL_ERROR_SSL while an other handshake failure with
Willy Tarreauf51c6982014-04-25 20:02:39 +0200965 * a heartbeat message will be reported as SSL_ERROR_SYSCALL.
966 */
Willy Tarreau3b2fdb62014-04-25 23:44:22 +0200967 ssl->max_send_fragment = 0;
Willy Tarreauf51c6982014-04-25 20:02:39 +0200968 SSLerr(SSL_F_TLS1_HEARTBEAT, SSL_R_SSL_HANDSHAKE_FAILURE);
969 return;
970 }
Emeric Brun29f037d2014-04-25 19:05:36 +0200971#endif
972}
973
Willy Tarreau6c9a3d52012-10-18 18:57:14 +0200974#ifdef OPENSSL_NPN_NEGOTIATED
975/* This callback is used so that the server advertises the list of
976 * negociable protocols for NPN.
977 */
978static int ssl_sock_advertise_npn_protos(SSL *s, const unsigned char **data,
979 unsigned int *len, void *arg)
980{
981 struct bind_conf *conf = arg;
982
983 *data = (const unsigned char *)conf->npn_str;
984 *len = conf->npn_len;
985 return SSL_TLSEXT_ERR_OK;
986}
987#endif
988
Dirkjan Bussink48f1c4e2014-02-13 12:29:42 +0100989#ifdef TLSEXT_TYPE_application_layer_protocol_negotiation
Willy Tarreauab861d32013-04-02 02:30:41 +0200990/* This callback is used so that the server advertises the list of
991 * negociable protocols for ALPN.
992 */
Dirkjan Bussink48f1c4e2014-02-13 12:29:42 +0100993static int ssl_sock_advertise_alpn_protos(SSL *s, const unsigned char **out,
994 unsigned char *outlen,
995 const unsigned char *server,
996 unsigned int server_len, void *arg)
Willy Tarreauab861d32013-04-02 02:30:41 +0200997{
998 struct bind_conf *conf = arg;
999
Dirkjan Bussink48f1c4e2014-02-13 12:29:42 +01001000 if (SSL_select_next_proto((unsigned char**) out, outlen, (const unsigned char *)conf->alpn_str,
1001 conf->alpn_len, server, server_len) != OPENSSL_NPN_NEGOTIATED) {
1002 return SSL_TLSEXT_ERR_NOACK;
1003 }
Willy Tarreauab861d32013-04-02 02:30:41 +02001004 return SSL_TLSEXT_ERR_OK;
1005}
1006#endif
1007
Willy Tarreauc8ad3be2015-06-17 15:48:26 +02001008#ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME
Christopher Faulet30548802015-06-11 13:39:32 +02001009/* Create a X509 certificate with the specified servername and serial. This
1010 * function returns a SSL_CTX object or NULL if an error occurs. */
1011SSL_CTX *
Christopher Faulet31af49d2015-06-09 17:29:50 +02001012ssl_sock_create_cert(const char *servername, unsigned int serial, X509 *cacert, EVP_PKEY *capkey)
1013{
1014 SSL_CTX *ssl_ctx = NULL;
1015 X509 *newcrt = NULL;
1016 EVP_PKEY *pkey = NULL;
1017 RSA *rsa;
1018 X509_NAME *name;
1019 const EVP_MD *digest;
1020 X509V3_CTX ctx;
1021 unsigned int i;
1022
1023 /* Generate the public key */
1024 if (!(rsa = RSA_generate_key(2048, 3, NULL, NULL)))
1025 goto mkcert_error;
1026 if (!(pkey = EVP_PKEY_new()))
1027 goto mkcert_error;
1028 if (EVP_PKEY_assign_RSA(pkey, rsa) != 1)
1029 goto mkcert_error;
1030
1031 /* Create the certificate */
1032 if (!(newcrt = X509_new()))
1033 goto mkcert_error;
1034
1035 /* Set version number for the certificate (X509v3) and the serial
1036 * number */
1037 if (X509_set_version(newcrt, 2L) != 1)
1038 goto mkcert_error;
1039 ASN1_INTEGER_set(X509_get_serialNumber(newcrt), serial);
1040
1041 /* Set duration for the certificate */
1042 if (!X509_gmtime_adj(X509_get_notBefore(newcrt), (long)-60*60*24) ||
1043 !X509_gmtime_adj(X509_get_notAfter(newcrt),(long)60*60*24*365))
1044 goto mkcert_error;
1045
1046 /* set public key in the certificate */
1047 if (X509_set_pubkey(newcrt, pkey) != 1)
1048 goto mkcert_error;
1049
1050 /* Set issuer name from the CA */
1051 if (!(name = X509_get_subject_name(cacert)))
1052 goto mkcert_error;
1053 if (X509_set_issuer_name(newcrt, name) != 1)
1054 goto mkcert_error;
1055
1056 /* Set the subject name using the same, but the CN */
1057 name = X509_NAME_dup(name);
1058 if (X509_NAME_add_entry_by_txt(name, "CN", MBSTRING_ASC,
1059 (const unsigned char *)servername,
1060 -1, -1, 0) != 1) {
1061 X509_NAME_free(name);
1062 goto mkcert_error;
1063 }
1064 if (X509_set_subject_name(newcrt, name) != 1) {
1065 X509_NAME_free(name);
1066 goto mkcert_error;
1067 }
1068 X509_NAME_free(name);
1069
1070 /* Add x509v3 extensions as specified */
1071 X509V3_set_ctx(&ctx, cacert, newcrt, NULL, NULL, 0);
1072 for (i = 0; i < X509V3_EXT_SIZE; i++) {
1073 X509_EXTENSION *ext;
1074
1075 if (!(ext = X509V3_EXT_conf(NULL, &ctx, x509v3_ext_names[i], x509v3_ext_values[i])))
1076 goto mkcert_error;
1077 if (!X509_add_ext(newcrt, ext, -1)) {
1078 X509_EXTENSION_free(ext);
1079 goto mkcert_error;
1080 }
1081 X509_EXTENSION_free(ext);
1082 }
1083
1084 /* Sign the certificate with the CA private key */
1085 if (EVP_PKEY_type(capkey->type) == EVP_PKEY_DSA)
1086 digest = EVP_dss1();
1087 else if (EVP_PKEY_type (capkey->type) == EVP_PKEY_RSA)
1088 digest = EVP_sha256();
1089 else
1090 goto mkcert_error;
1091 if (!(X509_sign(newcrt, capkey, digest)))
1092 goto mkcert_error;
1093
1094 /* Create and set the new SSL_CTX */
1095 if (!(ssl_ctx = SSL_CTX_new(SSLv23_server_method())))
1096 goto mkcert_error;
1097 if (!SSL_CTX_use_PrivateKey(ssl_ctx, pkey))
1098 goto mkcert_error;
1099 if (!SSL_CTX_use_certificate(ssl_ctx, newcrt))
1100 goto mkcert_error;
1101 if (!SSL_CTX_check_private_key(ssl_ctx))
1102 goto mkcert_error;
1103
1104 if (newcrt) X509_free(newcrt);
1105 if (pkey) EVP_PKEY_free(pkey);
1106 return ssl_ctx;
1107
1108 mkcert_error:
1109 if (ssl_ctx) SSL_CTX_free(ssl_ctx);
1110 if (newcrt) X509_free(newcrt);
1111 if (pkey) EVP_PKEY_free(pkey);
1112 return NULL;
1113}
1114
Christopher Faulet30548802015-06-11 13:39:32 +02001115/* Do a lookup for a certificate in the LRU cache used to store generated
1116 * certificates. */
1117SSL_CTX *
1118ssl_sock_get_generated_cert(unsigned int serial, X509 *cacert)
1119{
1120 struct lru64 *lru = NULL;
1121
1122 if (ssl_ctx_lru_tree) {
1123 lru = lru64_lookup(serial, ssl_ctx_lru_tree, cacert, 0);
1124 if (lru && lru->domain)
1125 return (SSL_CTX *)lru->data;
1126 }
1127 return NULL;
1128}
1129
1130/* Set a certificate int the LRU cache used to store generated certificate. */
1131void
1132ssl_sock_set_generated_cert(SSL_CTX *ssl_ctx, unsigned int serial, X509 *cacert)
1133{
1134 struct lru64 *lru = NULL;
1135
1136 if (ssl_ctx_lru_tree) {
1137 lru = lru64_get(serial, ssl_ctx_lru_tree, cacert, 0);
1138 if (!lru)
1139 return;
1140 if (lru->domain && lru->data)
1141 lru->free((SSL_CTX *)lru->data);
1142 lru64_commit(lru, ssl_ctx, cacert, 0, (void (*)(void *))SSL_CTX_free);
1143 }
1144}
1145
1146/* Compute the serial that will be used to create/set/get a certificate. */
1147unsigned int
Willy Tarreau646b8642015-07-07 18:09:15 +02001148ssl_sock_generated_cert_serial(const void *data, size_t len)
Christopher Faulet30548802015-06-11 13:39:32 +02001149{
1150 return XXH32(data, len, ssl_ctx_lru_seed);
1151}
1152
Christopher Faulet31af49d2015-06-09 17:29:50 +02001153static SSL_CTX *
1154ssl_sock_generate_certificate(const char *servername, struct bind_conf *bind_conf)
1155{
1156 X509 *cacert = bind_conf->ca_sign_cert;
1157 EVP_PKEY *capkey = bind_conf->ca_sign_pkey;
1158 SSL_CTX *ssl_ctx = NULL;
1159 struct lru64 *lru = NULL;
1160 unsigned int serial;
1161
Willy Tarreaufc017fe2015-07-07 18:09:34 +02001162 serial = ssl_sock_generated_cert_serial(servername, strlen(servername));
Christopher Faulet31af49d2015-06-09 17:29:50 +02001163 if (ssl_ctx_lru_tree) {
1164 lru = lru64_get(serial, ssl_ctx_lru_tree, cacert, 0);
1165 if (lru && lru->domain)
1166 ssl_ctx = (SSL_CTX *)lru->data;
1167 }
1168
1169 if (!ssl_ctx) {
1170 ssl_ctx = ssl_sock_create_cert(servername, serial, cacert, capkey);
1171 if (lru)
1172 lru64_commit(lru, ssl_ctx, cacert, 0, (void (*)(void *))SSL_CTX_free);
1173 }
1174 return ssl_ctx;
1175}
1176
Emeric Brunfc0421f2012-09-07 17:30:07 +02001177/* Sets the SSL ctx of <ssl> to match the advertised server name. Returns a
1178 * warning when no match is found, which implies the default (first) cert
1179 * will keep being used.
1180 */
Willy Tarreau2a65ff02012-09-13 17:54:29 +02001181static int ssl_sock_switchctx_cbk(SSL *ssl, int *al, struct bind_conf *s)
Emeric Brunfc0421f2012-09-07 17:30:07 +02001182{
1183 const char *servername;
1184 const char *wildp = NULL;
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +02001185 struct ebmb_node *node, *n;
Emeric Brunfc0421f2012-09-07 17:30:07 +02001186 int i;
1187 (void)al; /* shut gcc stupid warning */
1188
1189 servername = SSL_get_servername(ssl, TLSEXT_NAMETYPE_host_name);
Emmanuel Hocdet65623372013-01-24 17:17:15 +01001190 if (!servername) {
Willy Tarreauf6721452015-07-07 18:04:38 +02001191 if (s->generate_certs) {
1192 struct connection *conn = (struct connection *)SSL_get_app_data(ssl);
1193 unsigned int serial;
1194 SSL_CTX *ctx;
Christopher Faulet30548802015-06-11 13:39:32 +02001195
Willy Tarreauf6721452015-07-07 18:04:38 +02001196 conn_get_to_addr(conn);
1197 if (conn->flags & CO_FL_ADDR_TO_SET) {
1198 serial = ssl_sock_generated_cert_serial(&conn->addr.to, get_addr_len(&conn->addr.to));
1199 ctx = ssl_sock_get_generated_cert(serial, s->ca_sign_cert);
1200 if (ctx) {
1201 /* switch ctx */
1202 SSL_set_SSL_CTX(ssl, ctx);
1203 return SSL_TLSEXT_ERR_OK;
1204 }
Christopher Faulet30548802015-06-11 13:39:32 +02001205 }
1206 }
1207
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +02001208 return (s->strict_sni ?
1209 SSL_TLSEXT_ERR_ALERT_FATAL :
Emmanuel Hocdet79274e22013-05-31 12:47:44 +02001210 SSL_TLSEXT_ERR_NOACK);
Emmanuel Hocdet65623372013-01-24 17:17:15 +01001211 }
Emeric Brunfc0421f2012-09-07 17:30:07 +02001212
Willy Tarreau19d14ef2012-10-29 16:51:55 +01001213 for (i = 0; i < trash.size; i++) {
Emeric Brunfc0421f2012-09-07 17:30:07 +02001214 if (!servername[i])
1215 break;
Willy Tarreau19d14ef2012-10-29 16:51:55 +01001216 trash.str[i] = tolower(servername[i]);
1217 if (!wildp && (trash.str[i] == '.'))
1218 wildp = &trash.str[i];
Emeric Brunfc0421f2012-09-07 17:30:07 +02001219 }
Willy Tarreau19d14ef2012-10-29 16:51:55 +01001220 trash.str[i] = 0;
Emeric Brunfc0421f2012-09-07 17:30:07 +02001221
1222 /* lookup in full qualified names */
Willy Tarreau19d14ef2012-10-29 16:51:55 +01001223 node = ebst_lookup(&s->sni_ctx, trash.str);
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +02001224
1225 /* lookup a not neg filter */
1226 for (n = node; n; n = ebmb_next_dup(n)) {
1227 if (!container_of(n, struct sni_ctx, name)->neg) {
1228 node = n;
1229 break;
Emmanuel Hocdet65623372013-01-24 17:17:15 +01001230 }
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +02001231 }
1232 if (!node && wildp) {
1233 /* lookup in wildcards names */
Emeric Brunfc0421f2012-09-07 17:30:07 +02001234 node = ebst_lookup(&s->sni_w_ctx, wildp);
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +02001235 }
1236 if (!node || container_of(node, struct sni_ctx, name)->neg) {
Christopher Faulet31af49d2015-06-09 17:29:50 +02001237 SSL_CTX *ctx;
1238
1239 if (s->generate_certs &&
1240 (ctx = ssl_sock_generate_certificate(servername, s))) {
1241 /* switch ctx */
1242 SSL_set_SSL_CTX(ssl, ctx);
1243 return SSL_TLSEXT_ERR_OK;
1244 }
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +02001245 return (s->strict_sni ?
1246 SSL_TLSEXT_ERR_ALERT_FATAL :
1247 SSL_TLSEXT_ERR_ALERT_WARNING);
Emeric Brunfc0421f2012-09-07 17:30:07 +02001248 }
1249
1250 /* switch ctx */
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +02001251 SSL_set_SSL_CTX(ssl, container_of(node, struct sni_ctx, name)->ctx);
Emeric Brunfc0421f2012-09-07 17:30:07 +02001252 return SSL_TLSEXT_ERR_OK;
1253}
1254#endif /* SSL_CTRL_SET_TLSEXT_HOSTNAME */
1255
Emeric Bruna4bcd9a2012-09-20 16:19:02 +02001256#ifndef OPENSSL_NO_DH
Remi Gacognef46cd6e2014-06-12 14:58:40 +02001257
1258static DH * ssl_get_dh_1024(void)
1259{
Remi Gacogned3a341a2015-05-29 16:26:17 +02001260 static unsigned char dh1024_p[]={
1261 0xFA,0xF9,0x2A,0x22,0x2A,0xA7,0x7F,0xE1,0x67,0x4E,0x53,0xF7,
1262 0x56,0x13,0xC3,0xB1,0xE3,0x29,0x6B,0x66,0x31,0x6A,0x7F,0xB3,
1263 0xC2,0x68,0x6B,0xCB,0x1D,0x57,0x39,0x1D,0x1F,0xFF,0x1C,0xC9,
1264 0xA6,0xA4,0x98,0x82,0x31,0x5D,0x25,0xFF,0x8A,0xE0,0x73,0x96,
1265 0x81,0xC8,0x83,0x79,0xC1,0x5A,0x04,0xF8,0x37,0x0D,0xA8,0x3D,
1266 0xAE,0x74,0xBC,0xDB,0xB6,0xA4,0x75,0xD9,0x71,0x8A,0xA0,0x17,
1267 0x9E,0x2D,0xC8,0xA8,0xDF,0x2C,0x5F,0x82,0x95,0xF8,0x92,0x9B,
1268 0xA7,0x33,0x5F,0x89,0x71,0xC8,0x2D,0x6B,0x18,0x86,0xC4,0x94,
1269 0x22,0xA5,0x52,0x8D,0xF6,0xF6,0xD2,0x37,0x92,0x0F,0xA5,0xCC,
1270 0xDB,0x7B,0x1D,0x3D,0xA1,0x31,0xB7,0x80,0x8F,0x0B,0x67,0x5E,
1271 0x36,0xA5,0x60,0x0C,0xF1,0x95,0x33,0x8B,
1272 };
1273 static unsigned char dh1024_g[]={
1274 0x02,
1275 };
1276
Remi Gacognef46cd6e2014-06-12 14:58:40 +02001277 DH *dh = DH_new();
1278 if (dh) {
Remi Gacogned3a341a2015-05-29 16:26:17 +02001279 dh->p = BN_bin2bn(dh1024_p, sizeof dh1024_p, NULL);
1280 dh->g = BN_bin2bn(dh1024_g, sizeof dh1024_g, NULL);
1281
Remi Gacognef46cd6e2014-06-12 14:58:40 +02001282 if (!dh->p || !dh->g) {
1283 DH_free(dh);
1284 dh = NULL;
1285 }
1286 }
1287 return dh;
1288}
1289
1290static DH *ssl_get_dh_2048(void)
1291{
Remi Gacogned3a341a2015-05-29 16:26:17 +02001292 static unsigned char dh2048_p[]={
1293 0xEC,0x86,0xF8,0x70,0xA0,0x33,0x16,0xEC,0x05,0x1A,0x73,0x59,
1294 0xCD,0x1F,0x8B,0xF8,0x29,0xE4,0xD2,0xCF,0x52,0xDD,0xC2,0x24,
1295 0x8D,0xB5,0x38,0x9A,0xFB,0x5C,0xA4,0xE4,0xB2,0xDA,0xCE,0x66,
1296 0x50,0x74,0xA6,0x85,0x4D,0x4B,0x1D,0x30,0xB8,0x2B,0xF3,0x10,
1297 0xE9,0xA7,0x2D,0x05,0x71,0xE7,0x81,0xDF,0x8B,0x59,0x52,0x3B,
1298 0x5F,0x43,0x0B,0x68,0xF1,0xDB,0x07,0xBE,0x08,0x6B,0x1B,0x23,
1299 0xEE,0x4D,0xCC,0x9E,0x0E,0x43,0xA0,0x1E,0xDF,0x43,0x8C,0xEC,
1300 0xBE,0xBE,0x90,0xB4,0x51,0x54,0xB9,0x2F,0x7B,0x64,0x76,0x4E,
1301 0x5D,0xD4,0x2E,0xAE,0xC2,0x9E,0xAE,0x51,0x43,0x59,0xC7,0x77,
1302 0x9C,0x50,0x3C,0x0E,0xED,0x73,0x04,0x5F,0xF1,0x4C,0x76,0x2A,
1303 0xD8,0xF8,0xCF,0xFC,0x34,0x40,0xD1,0xB4,0x42,0x61,0x84,0x66,
1304 0x42,0x39,0x04,0xF8,0x68,0xB2,0x62,0xD7,0x55,0xED,0x1B,0x74,
1305 0x75,0x91,0xE0,0xC5,0x69,0xC1,0x31,0x5C,0xDB,0x7B,0x44,0x2E,
1306 0xCE,0x84,0x58,0x0D,0x1E,0x66,0x0C,0xC8,0x44,0x9E,0xFD,0x40,
1307 0x08,0x67,0x5D,0xFB,0xA7,0x76,0x8F,0x00,0x11,0x87,0xE9,0x93,
1308 0xF9,0x7D,0xC4,0xBC,0x74,0x55,0x20,0xD4,0x4A,0x41,0x2F,0x43,
1309 0x42,0x1A,0xC1,0xF2,0x97,0x17,0x49,0x27,0x37,0x6B,0x2F,0x88,
1310 0x7E,0x1C,0xA0,0xA1,0x89,0x92,0x27,0xD9,0x56,0x5A,0x71,0xC1,
1311 0x56,0x37,0x7E,0x3A,0x9D,0x05,0xE7,0xEE,0x5D,0x8F,0x82,0x17,
1312 0xBC,0xE9,0xC2,0x93,0x30,0x82,0xF9,0xF4,0xC9,0xAE,0x49,0xDB,
1313 0xD0,0x54,0xB4,0xD9,0x75,0x4D,0xFA,0x06,0xB8,0xD6,0x38,0x41,
1314 0xB7,0x1F,0x77,0xF3,
1315 };
1316 static unsigned char dh2048_g[]={
1317 0x02,
1318 };
1319
Remi Gacognef46cd6e2014-06-12 14:58:40 +02001320 DH *dh = DH_new();
1321 if (dh) {
Remi Gacogned3a341a2015-05-29 16:26:17 +02001322 dh->p = BN_bin2bn(dh2048_p, sizeof dh2048_p, NULL);
1323 dh->g = BN_bin2bn(dh2048_g, sizeof dh2048_g, NULL);
1324
Remi Gacognef46cd6e2014-06-12 14:58:40 +02001325 if (!dh->p || !dh->g) {
1326 DH_free(dh);
1327 dh = NULL;
1328 }
1329 }
1330 return dh;
1331}
1332
1333static DH *ssl_get_dh_4096(void)
1334{
Remi Gacogned3a341a2015-05-29 16:26:17 +02001335 static unsigned char dh4096_p[]={
1336 0xDE,0x16,0x94,0xCD,0x99,0x58,0x07,0xF1,0xF7,0x32,0x96,0x11,
1337 0x04,0x82,0xD4,0x84,0x72,0x80,0x99,0x06,0xCA,0xF0,0xA3,0x68,
1338 0x07,0xCE,0x64,0x50,0xE7,0x74,0x45,0x20,0x80,0x5E,0x4D,0xAD,
1339 0xA5,0xB6,0xED,0xFA,0x80,0x6C,0x3B,0x35,0xC4,0x9A,0x14,0x6B,
1340 0x32,0xBB,0xFD,0x1F,0x17,0x8E,0xB7,0x1F,0xD6,0xFA,0x3F,0x7B,
1341 0xEE,0x16,0xA5,0x62,0x33,0x0D,0xED,0xBC,0x4E,0x58,0xE5,0x47,
1342 0x4D,0xE9,0xAB,0x8E,0x38,0xD3,0x6E,0x90,0x57,0xE3,0x22,0x15,
1343 0x33,0xBD,0xF6,0x43,0x45,0xB5,0x10,0x0A,0xBE,0x2C,0xB4,0x35,
1344 0xB8,0x53,0x8D,0xAD,0xFB,0xA7,0x1F,0x85,0x58,0x41,0x7A,0x79,
1345 0x20,0x68,0xB3,0xE1,0x3D,0x08,0x76,0xBF,0x86,0x0D,0x49,0xE3,
1346 0x82,0x71,0x8C,0xB4,0x8D,0x81,0x84,0xD4,0xE7,0xBE,0x91,0xDC,
1347 0x26,0x39,0x48,0x0F,0x35,0xC4,0xCA,0x65,0xE3,0x40,0x93,0x52,
1348 0x76,0x58,0x7D,0xDD,0x51,0x75,0xDC,0x69,0x61,0xBF,0x47,0x2C,
1349 0x16,0x68,0x2D,0xC9,0x29,0xD3,0xE6,0xC0,0x99,0x48,0xA0,0x9A,
1350 0xC8,0x78,0xC0,0x6D,0x81,0x67,0x12,0x61,0x3F,0x71,0xBA,0x41,
1351 0x1F,0x6C,0x89,0x44,0x03,0xBA,0x3B,0x39,0x60,0xAA,0x28,0x55,
1352 0x59,0xAE,0xB8,0xFA,0xCB,0x6F,0xA5,0x1A,0xF7,0x2B,0xDD,0x52,
1353 0x8A,0x8B,0xE2,0x71,0xA6,0x5E,0x7E,0xD8,0x2E,0x18,0xE0,0x66,
1354 0xDF,0xDD,0x22,0x21,0x99,0x52,0x73,0xA6,0x33,0x20,0x65,0x0E,
1355 0x53,0xE7,0x6B,0x9B,0xC5,0xA3,0x2F,0x97,0x65,0x76,0xD3,0x47,
1356 0x23,0x77,0x12,0xB6,0x11,0x7B,0x24,0xED,0xF1,0xEF,0xC0,0xE2,
1357 0xA3,0x7E,0x67,0x05,0x3E,0x96,0x4D,0x45,0xC2,0x18,0xD1,0x73,
1358 0x9E,0x07,0xF3,0x81,0x6E,0x52,0x63,0xF6,0x20,0x76,0xB9,0x13,
1359 0xD2,0x65,0x30,0x18,0x16,0x09,0x16,0x9E,0x8F,0xF1,0xD2,0x10,
1360 0x5A,0xD3,0xD4,0xAF,0x16,0x61,0xDA,0x55,0x2E,0x18,0x5E,0x14,
1361 0x08,0x54,0x2E,0x2A,0x25,0xA2,0x1A,0x9B,0x8B,0x32,0xA9,0xFD,
1362 0xC2,0x48,0x96,0xE1,0x80,0xCA,0xE9,0x22,0x17,0xBB,0xCE,0x3E,
1363 0x9E,0xED,0xC7,0xF1,0x1F,0xEC,0x17,0x21,0xDC,0x7B,0x82,0x48,
1364 0x8E,0xBB,0x4B,0x9D,0x5B,0x04,0x04,0xDA,0xDB,0x39,0xDF,0x01,
1365 0x40,0xC3,0xAA,0x26,0x23,0x89,0x75,0xC6,0x0B,0xD0,0xA2,0x60,
1366 0x6A,0xF1,0xCC,0x65,0x18,0x98,0x1B,0x52,0xD2,0x74,0x61,0xCC,
1367 0xBD,0x60,0xAE,0xA3,0xA0,0x66,0x6A,0x16,0x34,0x92,0x3F,0x41,
1368 0x40,0x31,0x29,0xC0,0x2C,0x63,0xB2,0x07,0x8D,0xEB,0x94,0xB8,
1369 0xE8,0x47,0x92,0x52,0x93,0x6A,0x1B,0x7E,0x1A,0x61,0xB3,0x1B,
1370 0xF0,0xD6,0x72,0x9B,0xF1,0xB0,0xAF,0xBF,0x3E,0x65,0xEF,0x23,
1371 0x1D,0x6F,0xFF,0x70,0xCD,0x8A,0x4C,0x8A,0xA0,0x72,0x9D,0xBE,
1372 0xD4,0xBB,0x24,0x47,0x4A,0x68,0xB5,0xF5,0xC6,0xD5,0x7A,0xCD,
1373 0xCA,0x06,0x41,0x07,0xAD,0xC2,0x1E,0xE6,0x54,0xA7,0xAD,0x03,
1374 0xD9,0x12,0xC1,0x9C,0x13,0xB1,0xC9,0x0A,0x43,0x8E,0x1E,0x08,
1375 0xCE,0x50,0x82,0x73,0x5F,0xA7,0x55,0x1D,0xD9,0x59,0xAC,0xB5,
1376 0xEA,0x02,0x7F,0x6C,0x5B,0x74,0x96,0x98,0x67,0x24,0xA3,0x0F,
1377 0x15,0xFC,0xA9,0x7D,0x3E,0x67,0xD1,0x70,0xF8,0x97,0xF3,0x67,
1378 0xC5,0x8C,0x88,0x44,0x08,0x02,0xC7,0x2B,
Remi Gacognef46cd6e2014-06-12 14:58:40 +02001379 };
Remi Gacogned3a341a2015-05-29 16:26:17 +02001380 static unsigned char dh4096_g[]={
1381 0x02,
1382 };
Remi Gacognef46cd6e2014-06-12 14:58:40 +02001383
Remi Gacognef46cd6e2014-06-12 14:58:40 +02001384 DH *dh = DH_new();
1385 if (dh) {
Remi Gacogned3a341a2015-05-29 16:26:17 +02001386 dh->p = BN_bin2bn(dh4096_p, sizeof dh4096_p, NULL);
1387 dh->g = BN_bin2bn(dh4096_g, sizeof dh4096_g, NULL);
1388
Remi Gacognef46cd6e2014-06-12 14:58:40 +02001389 if (!dh->p || !dh->g) {
1390 DH_free(dh);
1391 dh = NULL;
1392 }
1393 }
1394 return dh;
1395}
1396
1397/* Returns Diffie-Hellman parameters matching the private key length
1398 but not exceeding global.tune.ssl_default_dh_param */
1399static DH *ssl_get_tmp_dh(SSL *ssl, int export, int keylen)
1400{
1401 DH *dh = NULL;
1402 EVP_PKEY *pkey = SSL_get_privatekey(ssl);
1403 int type = pkey ? EVP_PKEY_type(pkey->type) : EVP_PKEY_NONE;
1404
1405 /* The keylen supplied by OpenSSL can only be 512 or 1024.
1406 See ssl3_send_server_key_exchange() in ssl/s3_srvr.c
1407 */
1408 if (type == EVP_PKEY_RSA || type == EVP_PKEY_DSA) {
1409 keylen = EVP_PKEY_bits(pkey);
1410 }
1411
1412 if (keylen > global.tune.ssl_default_dh_param) {
1413 keylen = global.tune.ssl_default_dh_param;
1414 }
1415
Remi Gacogned3a341a2015-05-29 16:26:17 +02001416 if (keylen >= 4096) {
Remi Gacogne8de54152014-07-15 11:36:40 +02001417 dh = local_dh_4096;
Remi Gacognef46cd6e2014-06-12 14:58:40 +02001418 }
1419 else if (keylen >= 2048) {
Remi Gacogne8de54152014-07-15 11:36:40 +02001420 dh = local_dh_2048;
Remi Gacognef46cd6e2014-06-12 14:58:40 +02001421 }
1422 else {
Remi Gacogne8de54152014-07-15 11:36:40 +02001423 dh = local_dh_1024;
Remi Gacognef46cd6e2014-06-12 14:58:40 +02001424 }
1425
1426 return dh;
1427}
1428
Remi Gacogne47783ef2015-05-29 15:53:22 +02001429static DH * ssl_sock_get_dh_from_file(const char *filename)
Emeric Bruna4bcd9a2012-09-20 16:19:02 +02001430{
Emeric Bruna4bcd9a2012-09-20 16:19:02 +02001431 DH *dh = NULL;
Remi Gacogne47783ef2015-05-29 15:53:22 +02001432 BIO *in = BIO_new(BIO_s_file());
Emeric Bruna4bcd9a2012-09-20 16:19:02 +02001433
Emeric Bruna4bcd9a2012-09-20 16:19:02 +02001434 if (in == NULL)
1435 goto end;
1436
Remi Gacogne47783ef2015-05-29 15:53:22 +02001437 if (BIO_read_filename(in, filename) <= 0)
Emeric Bruna4bcd9a2012-09-20 16:19:02 +02001438 goto end;
1439
Remi Gacogne47783ef2015-05-29 15:53:22 +02001440 dh = PEM_read_bio_DHparams(in, NULL, NULL, NULL);
1441
1442end:
1443 if (in)
1444 BIO_free(in);
1445
1446 return dh;
1447}
1448
1449int ssl_sock_load_global_dh_param_from_file(const char *filename)
1450{
1451 global_dh = ssl_sock_get_dh_from_file(filename);
1452
1453 if (global_dh) {
1454 return 0;
1455 }
1456
1457 return -1;
1458}
1459
1460/* Loads Diffie-Hellman parameter from a file. Returns 1 if loaded, else -1
1461 if an error occured, and 0 if parameter not found. */
1462int ssl_sock_load_dh_params(SSL_CTX *ctx, const char *file)
1463{
1464 int ret = -1;
1465 DH *dh = ssl_sock_get_dh_from_file(file);
1466
Remi Gacognef46cd6e2014-06-12 14:58:40 +02001467 if (dh) {
1468 ret = 1;
1469 SSL_CTX_set_tmp_dh(ctx, dh);
Remi Gacogne4f902b82015-05-28 16:23:00 +02001470
1471 if (ssl_dh_ptr_index >= 0) {
1472 /* store a pointer to the DH params to avoid complaining about
1473 ssl-default-dh-param not being set for this SSL_CTX */
1474 SSL_CTX_set_ex_data(ctx, ssl_dh_ptr_index, dh);
1475 }
Remi Gacognef46cd6e2014-06-12 14:58:40 +02001476 }
Remi Gacogne47783ef2015-05-29 15:53:22 +02001477 else if (global_dh) {
1478 SSL_CTX_set_tmp_dh(ctx, global_dh);
1479 ret = 0; /* DH params not found */
1480 }
Remi Gacognef46cd6e2014-06-12 14:58:40 +02001481 else {
Emeric Brun41fdb3c2013-04-26 11:05:44 +02001482 /* Clear openssl global errors stack */
1483 ERR_clear_error();
1484
Remi Gacognef46cd6e2014-06-12 14:58:40 +02001485 if (global.tune.ssl_default_dh_param <= 1024) {
1486 /* we are limited to DH parameter of 1024 bits anyway */
Remi Gacogne8de54152014-07-15 11:36:40 +02001487 local_dh_1024 = ssl_get_dh_1024();
1488 if (local_dh_1024 == NULL)
Remi Gacognef46cd6e2014-06-12 14:58:40 +02001489 goto end;
Willy Tarreau6e774b42014-04-25 21:35:23 +02001490
Remi Gacogne8de54152014-07-15 11:36:40 +02001491 SSL_CTX_set_tmp_dh(ctx, local_dh_1024);
Remi Gacognef46cd6e2014-06-12 14:58:40 +02001492 }
1493 else {
1494 SSL_CTX_set_tmp_dh_callback(ctx, ssl_get_tmp_dh);
1495 }
Willy Tarreau6e774b42014-04-25 21:35:23 +02001496
Emeric Brun41fdb3c2013-04-26 11:05:44 +02001497 ret = 0; /* DH params not found */
Emeric Bruna4bcd9a2012-09-20 16:19:02 +02001498 }
Emeric Brun644cde02012-12-14 11:21:13 +01001499
Emeric Bruna4bcd9a2012-09-20 16:19:02 +02001500end:
1501 if (dh)
1502 DH_free(dh);
1503
Emeric Bruna4bcd9a2012-09-20 16:19:02 +02001504 return ret;
1505}
1506#endif
1507
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +02001508static int ssl_sock_add_cert_sni(SSL_CTX *ctx, struct bind_conf *s, char *name, int order)
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01001509{
1510 struct sni_ctx *sc;
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +02001511 int wild = 0, neg = 0;
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01001512
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +02001513 if (*name == '!') {
1514 neg = 1;
1515 name++;
1516 }
1517 if (*name == '*') {
1518 wild = 1;
1519 name++;
1520 }
1521 /* !* filter is a nop */
1522 if (neg && wild)
1523 return order;
1524 if (*name) {
1525 int j, len;
1526 len = strlen(name);
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01001527 sc = malloc(sizeof(struct sni_ctx) + len + 1);
1528 for (j = 0; j < len; j++)
1529 sc->name.key[j] = tolower(name[j]);
1530 sc->name.key[len] = 0;
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01001531 sc->ctx = ctx;
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +02001532 sc->order = order++;
1533 sc->neg = neg;
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01001534 if (wild)
1535 ebst_insert(&s->sni_w_ctx, &sc->name);
1536 else
1537 ebst_insert(&s->sni_ctx, &sc->name);
1538 }
1539 return order;
1540}
1541
Emeric Brunfc0421f2012-09-07 17:30:07 +02001542/* Loads a certificate key and CA chain from a file. Returns 0 on error, -1 if
1543 * an early error happens and the caller must call SSL_CTX_free() by itelf.
1544 */
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +02001545static 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 +02001546{
1547 BIO *in;
1548 X509 *x = NULL, *ca;
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +02001549 int i, err;
Emeric Brunfc0421f2012-09-07 17:30:07 +02001550 int ret = -1;
1551 int order = 0;
1552 X509_NAME *xname;
1553 char *str;
Emeric Brunfc0421f2012-09-07 17:30:07 +02001554#ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME
1555 STACK_OF(GENERAL_NAME) *names;
1556#endif
1557
1558 in = BIO_new(BIO_s_file());
1559 if (in == NULL)
1560 goto end;
1561
1562 if (BIO_read_filename(in, file) <= 0)
1563 goto end;
1564
1565 x = PEM_read_bio_X509_AUX(in, NULL, ctx->default_passwd_callback, ctx->default_passwd_callback_userdata);
1566 if (x == NULL)
1567 goto end;
1568
Emeric Brun50bcecc2013-04-22 13:05:23 +02001569 if (fcount) {
1570 while (fcount--)
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +02001571 order = ssl_sock_add_cert_sni(ctx, s, sni_filter[fcount], order);
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01001572 }
1573 else {
Emeric Brunfc0421f2012-09-07 17:30:07 +02001574#ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01001575 names = X509_get_ext_d2i(x, NID_subject_alt_name, NULL, NULL);
1576 if (names) {
1577 for (i = 0; i < sk_GENERAL_NAME_num(names); i++) {
1578 GENERAL_NAME *name = sk_GENERAL_NAME_value(names, i);
1579 if (name->type == GEN_DNS) {
1580 if (ASN1_STRING_to_UTF8((unsigned char **)&str, name->d.dNSName) >= 0) {
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +02001581 order = ssl_sock_add_cert_sni(ctx, s, str, order);
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01001582 OPENSSL_free(str);
Emeric Brunfc0421f2012-09-07 17:30:07 +02001583 }
Emeric Brunfc0421f2012-09-07 17:30:07 +02001584 }
1585 }
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01001586 sk_GENERAL_NAME_pop_free(names, GENERAL_NAME_free);
Emeric Brunfc0421f2012-09-07 17:30:07 +02001587 }
Emeric Brunfc0421f2012-09-07 17:30:07 +02001588#endif /* SSL_CTRL_SET_TLSEXT_HOSTNAME */
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01001589 xname = X509_get_subject_name(x);
1590 i = -1;
1591 while ((i = X509_NAME_get_index_by_NID(xname, NID_commonName, i)) != -1) {
1592 X509_NAME_ENTRY *entry = X509_NAME_get_entry(xname, i);
1593 if (ASN1_STRING_to_UTF8((unsigned char **)&str, entry->value) >= 0) {
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +02001594 order = ssl_sock_add_cert_sni(ctx, s, str, order);
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01001595 OPENSSL_free(str);
Emeric Brunfc0421f2012-09-07 17:30:07 +02001596 }
Emeric Brunfc0421f2012-09-07 17:30:07 +02001597 }
1598 }
1599
1600 ret = 0; /* the caller must not free the SSL_CTX argument anymore */
1601 if (!SSL_CTX_use_certificate(ctx, x))
1602 goto end;
1603
1604 if (ctx->extra_certs != NULL) {
1605 sk_X509_pop_free(ctx->extra_certs, X509_free);
1606 ctx->extra_certs = NULL;
1607 }
1608
1609 while ((ca = PEM_read_bio_X509(in, NULL, ctx->default_passwd_callback, ctx->default_passwd_callback_userdata))) {
1610 if (!SSL_CTX_add_extra_chain_cert(ctx, ca)) {
1611 X509_free(ca);
1612 goto end;
1613 }
1614 }
1615
1616 err = ERR_get_error();
1617 if (!err || (ERR_GET_LIB(err) == ERR_LIB_PEM && ERR_GET_REASON(err) == PEM_R_NO_START_LINE)) {
1618 /* we successfully reached the last cert in the file */
1619 ret = 1;
1620 }
1621 ERR_clear_error();
1622
1623end:
1624 if (x)
1625 X509_free(x);
1626
1627 if (in)
1628 BIO_free(in);
1629
1630 return ret;
1631}
1632
Emeric Brun50bcecc2013-04-22 13:05:23 +02001633static 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 +02001634{
1635 int ret;
1636 SSL_CTX *ctx;
1637
1638 ctx = SSL_CTX_new(SSLv23_server_method());
1639 if (!ctx) {
Willy Tarreaueb6cead2012-09-20 19:43:14 +02001640 memprintf(err, "%sunable to allocate SSL context for cert '%s'.\n",
1641 err && *err ? *err : "", path);
Emeric Brunfc0421f2012-09-07 17:30:07 +02001642 return 1;
1643 }
1644
1645 if (SSL_CTX_use_PrivateKey_file(ctx, path, SSL_FILETYPE_PEM) <= 0) {
Willy Tarreaueb6cead2012-09-20 19:43:14 +02001646 memprintf(err, "%sunable to load SSL private key from PEM file '%s'.\n",
1647 err && *err ? *err : "", path);
Emeric Brunfc0421f2012-09-07 17:30:07 +02001648 SSL_CTX_free(ctx);
1649 return 1;
1650 }
1651
Emeric Brun50bcecc2013-04-22 13:05:23 +02001652 ret = ssl_sock_load_cert_chain_file(ctx, path, bind_conf, sni_filter, fcount);
Emeric Brunfc0421f2012-09-07 17:30:07 +02001653 if (ret <= 0) {
Willy Tarreaueb6cead2012-09-20 19:43:14 +02001654 memprintf(err, "%sunable to load SSL certificate from PEM file '%s'.\n",
1655 err && *err ? *err : "", path);
Emeric Brunfc0421f2012-09-07 17:30:07 +02001656 if (ret < 0) /* serious error, must do that ourselves */
1657 SSL_CTX_free(ctx);
1658 return 1;
1659 }
Emeric Brun61694ab2012-10-26 13:35:33 +02001660
1661 if (SSL_CTX_check_private_key(ctx) <= 0) {
1662 memprintf(err, "%sinconsistencies between private key and certificate loaded from PEM file '%s'.\n",
1663 err && *err ? *err : "", path);
1664 return 1;
1665 }
1666
Emeric Brunfc0421f2012-09-07 17:30:07 +02001667 /* we must not free the SSL_CTX anymore below, since it's already in
1668 * the tree, so it will be discovered and cleaned in time.
1669 */
Emeric Bruna4bcd9a2012-09-20 16:19:02 +02001670#ifndef OPENSSL_NO_DH
Remi Gacogne4f902b82015-05-28 16:23:00 +02001671 /* store a NULL pointer to indicate we have not yet loaded
1672 a custom DH param file */
1673 if (ssl_dh_ptr_index >= 0) {
1674 SSL_CTX_set_ex_data(ctx, ssl_dh_ptr_index, NULL);
1675 }
1676
Emeric Bruna4bcd9a2012-09-20 16:19:02 +02001677 ret = ssl_sock_load_dh_params(ctx, path);
1678 if (ret < 0) {
1679 if (err)
1680 memprintf(err, "%sunable to load DH parameters from file '%s'.\n",
1681 *err ? *err : "", path);
1682 return 1;
1683 }
1684#endif
1685
Lukas Tribuse4e30f72014-12-09 16:32:51 +01001686#if (defined SSL_CTRL_SET_TLSEXT_STATUS_REQ_CB && !defined OPENSSL_NO_OCSP)
Emeric Brun4147b2e2014-06-16 18:36:30 +02001687 ret = ssl_sock_load_ocsp(ctx, path);
1688 if (ret < 0) {
1689 if (err)
1690 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",
1691 *err ? *err : "", path);
1692 return 1;
1693 }
1694#endif
1695
Janusz Dziemidowicz2c701b52015-03-07 23:03:59 +01001696#if (OPENSSL_VERSION_NUMBER >= 0x1000200fL && !defined OPENSSL_NO_TLSEXT && !defined OPENSSL_IS_BORINGSSL)
1697 if (sctl_ex_index >= 0) {
1698 ret = ssl_sock_load_sctl(ctx, path);
1699 if (ret < 0) {
1700 if (err)
1701 memprintf(err, "%s '%s.sctl' is present but cannot be read or parsed'.\n",
1702 *err ? *err : "", path);
1703 return 1;
1704 }
1705 }
1706#endif
1707
Emeric Brunfc0421f2012-09-07 17:30:07 +02001708#ifndef SSL_CTRL_SET_TLSEXT_HOSTNAME
Willy Tarreau2a65ff02012-09-13 17:54:29 +02001709 if (bind_conf->default_ctx) {
Willy Tarreaueb6cead2012-09-20 19:43:14 +02001710 memprintf(err, "%sthis version of openssl cannot load multiple SSL certificates.\n",
1711 err && *err ? *err : "");
Emeric Brunfc0421f2012-09-07 17:30:07 +02001712 return 1;
1713 }
1714#endif
Willy Tarreau2a65ff02012-09-13 17:54:29 +02001715 if (!bind_conf->default_ctx)
1716 bind_conf->default_ctx = ctx;
Emeric Brunfc0421f2012-09-07 17:30:07 +02001717
1718 return 0;
1719}
1720
Willy Tarreau79eeafa2012-09-14 07:53:05 +02001721int ssl_sock_load_cert(char *path, struct bind_conf *bind_conf, struct proxy *curproxy, char **err)
Emeric Brunfc0421f2012-09-07 17:30:07 +02001722{
Cyril Bonté3180f7b2015-01-25 00:16:08 +01001723 struct dirent **de_list;
1724 int i, n;
Emeric Brunfc0421f2012-09-07 17:30:07 +02001725 DIR *dir;
1726 struct stat buf;
Willy Tarreauee2663b2012-12-06 11:36:59 +01001727 char *end;
1728 char fp[MAXPATHLEN+1];
Emeric Brunfc0421f2012-09-07 17:30:07 +02001729 int cfgerr = 0;
1730
1731 if (!(dir = opendir(path)))
Emeric Brun50bcecc2013-04-22 13:05:23 +02001732 return ssl_sock_load_cert_file(path, bind_conf, curproxy, NULL, 0, err);
Emeric Brunfc0421f2012-09-07 17:30:07 +02001733
1734 /* strip trailing slashes, including first one */
1735 for (end = path + strlen(path) - 1; end >= path && *end == '/'; end--)
1736 *end = 0;
1737
Cyril Bonté3180f7b2015-01-25 00:16:08 +01001738 n = scandir(path, &de_list, 0, alphasort);
1739 if (n < 0) {
1740 memprintf(err, "%sunable to scan directory '%s' : %s.\n",
1741 err && *err ? *err : "", path, strerror(errno));
1742 cfgerr++;
1743 }
1744 else {
1745 for (i = 0; i < n; i++) {
1746 struct dirent *de = de_list[i];
Emeric Brun2aab7222014-06-18 18:15:09 +02001747
Cyril Bonté3180f7b2015-01-25 00:16:08 +01001748 end = strrchr(de->d_name, '.');
Janusz Dziemidowicz2c701b52015-03-07 23:03:59 +01001749 if (end && (!strcmp(end, ".issuer") || !strcmp(end, ".ocsp") || !strcmp(end, ".sctl")))
Cyril Bonté3180f7b2015-01-25 00:16:08 +01001750 goto ignore_entry;
1751
1752 snprintf(fp, sizeof(fp), "%s/%s", path, de->d_name);
1753 if (stat(fp, &buf) != 0) {
1754 memprintf(err, "%sunable to stat SSL certificate from file '%s' : %s.\n",
1755 err && *err ? *err : "", fp, strerror(errno));
1756 cfgerr++;
1757 goto ignore_entry;
1758 }
1759 if (!S_ISREG(buf.st_mode))
1760 goto ignore_entry;
1761 cfgerr += ssl_sock_load_cert_file(fp, bind_conf, curproxy, NULL, 0, err);
1762 ignore_entry:
1763 free(de);
Emeric Brunfc0421f2012-09-07 17:30:07 +02001764 }
Cyril Bonté3180f7b2015-01-25 00:16:08 +01001765 free(de_list);
Emeric Brunfc0421f2012-09-07 17:30:07 +02001766 }
Emeric Brunfc0421f2012-09-07 17:30:07 +02001767 closedir(dir);
1768 return cfgerr;
1769}
1770
Thierry Fournier383085f2013-01-24 14:15:43 +01001771/* Make sure openssl opens /dev/urandom before the chroot. The work is only
1772 * done once. Zero is returned if the operation fails. No error is returned
1773 * if the random is said as not implemented, because we expect that openssl
1774 * will use another method once needed.
1775 */
1776static int ssl_initialize_random()
1777{
1778 unsigned char random;
1779 static int random_initialized = 0;
1780
1781 if (!random_initialized && RAND_bytes(&random, 1) != 0)
1782 random_initialized = 1;
1783
1784 return random_initialized;
1785}
1786
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01001787int ssl_sock_load_cert_list_file(char *file, struct bind_conf *bind_conf, struct proxy *curproxy, char **err)
1788{
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +02001789 char thisline[LINESIZE];
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01001790 FILE *f;
1791 int linenum = 0;
1792 int cfgerr = 0;
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01001793
Willy Tarreauad1731d2013-04-02 17:35:58 +02001794 if ((f = fopen(file, "r")) == NULL) {
1795 memprintf(err, "cannot open file '%s' : %s", file, strerror(errno));
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01001796 return 1;
Willy Tarreauad1731d2013-04-02 17:35:58 +02001797 }
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01001798
1799 while (fgets(thisline, sizeof(thisline), f) != NULL) {
1800 int arg;
Emeric Brun50bcecc2013-04-22 13:05:23 +02001801 int newarg;
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01001802 char *end;
1803 char *args[MAX_LINE_ARGS + 1];
1804 char *line = thisline;
1805
1806 linenum++;
1807 end = line + strlen(line);
1808 if (end-line == sizeof(thisline)-1 && *(end-1) != '\n') {
1809 /* Check if we reached the limit and the last char is not \n.
1810 * Watch out for the last line without the terminating '\n'!
1811 */
Willy Tarreauad1731d2013-04-02 17:35:58 +02001812 memprintf(err, "line %d too long in file '%s', limit is %d characters",
1813 linenum, file, (int)sizeof(thisline)-1);
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01001814 cfgerr = 1;
Willy Tarreauad1731d2013-04-02 17:35:58 +02001815 break;
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01001816 }
1817
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01001818 arg = 0;
Emeric Brun50bcecc2013-04-22 13:05:23 +02001819 newarg = 1;
1820 while (*line) {
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01001821 if (*line == '#' || *line == '\n' || *line == '\r') {
1822 /* end of string, end of loop */
1823 *line = 0;
1824 break;
1825 }
1826 else if (isspace(*line)) {
Emeric Brun50bcecc2013-04-22 13:05:23 +02001827 newarg = 1;
1828 *line = 0;
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01001829 }
Emeric Brun50bcecc2013-04-22 13:05:23 +02001830 else if (newarg) {
1831 if (arg == MAX_LINE_ARGS) {
1832 memprintf(err, "too many args on line %d in file '%s'.",
1833 linenum, file);
1834 cfgerr = 1;
1835 break;
1836 }
1837 newarg = 0;
1838 args[arg++] = line;
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01001839 }
Emeric Brun50bcecc2013-04-22 13:05:23 +02001840 line++;
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01001841 }
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +02001842 if (cfgerr)
1843 break;
Willy Tarreauad1731d2013-04-02 17:35:58 +02001844
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01001845 /* empty line */
Emeric Brun50bcecc2013-04-22 13:05:23 +02001846 if (!arg)
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01001847 continue;
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01001848
Emeric Brun50bcecc2013-04-22 13:05:23 +02001849 cfgerr = ssl_sock_load_cert_file(args[0], bind_conf, curproxy, &args[1], arg-1, err);
Willy Tarreauad1731d2013-04-02 17:35:58 +02001850 if (cfgerr) {
1851 memprintf(err, "error processing line %d in file '%s' : %s", linenum, file, *err);
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01001852 break;
Willy Tarreauad1731d2013-04-02 17:35:58 +02001853 }
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01001854 }
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01001855 fclose(f);
1856 return cfgerr;
1857}
1858
Emeric Brunfc0421f2012-09-07 17:30:07 +02001859#ifndef SSL_OP_CIPHER_SERVER_PREFERENCE /* needs OpenSSL >= 0.9.7 */
1860#define SSL_OP_CIPHER_SERVER_PREFERENCE 0
1861#endif
1862
1863#ifndef SSL_OP_NO_SESSION_RESUMPTION_ON_RENEGOTIATION /* needs OpenSSL >= 0.9.7 */
1864#define SSL_OP_NO_SESSION_RESUMPTION_ON_RENEGOTIATION 0
Willy Tarreau7d588ee2012-11-26 18:47:31 +01001865#define SSL_renegotiate_pending(arg) 0
Emeric Brunfc0421f2012-09-07 17:30:07 +02001866#endif
Emeric Brun2b58d042012-09-20 17:10:03 +02001867#ifndef SSL_OP_SINGLE_ECDH_USE /* needs OpenSSL >= 0.9.8 */
1868#define SSL_OP_SINGLE_ECDH_USE 0
1869#endif
Emeric Brun2d0c4822012-10-02 13:45:20 +02001870#ifndef SSL_OP_NO_TICKET /* needs OpenSSL >= 0.9.8 */
1871#define SSL_OP_NO_TICKET 0
1872#endif
Emeric Brunfc0421f2012-09-07 17:30:07 +02001873#ifndef SSL_OP_NO_COMPRESSION /* needs OpenSSL >= 0.9.9 */
1874#define SSL_OP_NO_COMPRESSION 0
1875#endif
Emeric Brunc0ff4922012-09-28 19:37:02 +02001876#ifndef SSL_OP_NO_TLSv1_1 /* needs OpenSSL >= 1.0.1 */
1877#define SSL_OP_NO_TLSv1_1 0
1878#endif
1879#ifndef SSL_OP_NO_TLSv1_2 /* needs OpenSSL >= 1.0.1 */
1880#define SSL_OP_NO_TLSv1_2 0
1881#endif
Emeric Bruna4bcd9a2012-09-20 16:19:02 +02001882#ifndef SSL_OP_SINGLE_DH_USE /* needs OpenSSL >= 0.9.6 */
1883#define SSL_OP_SINGLE_DH_USE 0
1884#endif
Emeric Brun2b58d042012-09-20 17:10:03 +02001885#ifndef SSL_OP_SINGLE_ECDH_USE /* needs OpenSSL >= 1.0.0 */
1886#define SSL_OP_SINGLE_ECDH_USE 0
1887#endif
Emeric Brunfc0421f2012-09-07 17:30:07 +02001888#ifndef SSL_MODE_RELEASE_BUFFERS /* needs OpenSSL >= 1.0.0 */
1889#define SSL_MODE_RELEASE_BUFFERS 0
1890#endif
Willy Tarreau396a1862014-11-13 14:06:52 +01001891#ifndef SSL_MODE_SMALL_BUFFERS /* needs small_records.patch */
1892#define SSL_MODE_SMALL_BUFFERS 0
1893#endif
Remi Gacognef46cd6e2014-06-12 14:58:40 +02001894
Willy Tarreau2a65ff02012-09-13 17:54:29 +02001895int ssl_sock_prepare_ctx(struct bind_conf *bind_conf, SSL_CTX *ctx, struct proxy *curproxy)
Emeric Brunfc0421f2012-09-07 17:30:07 +02001896{
1897 int cfgerr = 0;
Emeric Brun850efd52014-01-29 12:24:34 +01001898 int verify = SSL_VERIFY_NONE;
Remi Gacogneaf5c3da2014-05-19 10:29:58 +02001899 long ssloptions =
Emeric Brunfc0421f2012-09-07 17:30:07 +02001900 SSL_OP_ALL | /* all known workarounds for bugs */
1901 SSL_OP_NO_SSLv2 |
1902 SSL_OP_NO_COMPRESSION |
Emeric Bruna4bcd9a2012-09-20 16:19:02 +02001903 SSL_OP_SINGLE_DH_USE |
Emeric Brun2b58d042012-09-20 17:10:03 +02001904 SSL_OP_SINGLE_ECDH_USE |
Emeric Brun3c4bc6e2012-10-04 18:44:19 +02001905 SSL_OP_NO_SESSION_RESUMPTION_ON_RENEGOTIATION |
1906 SSL_OP_CIPHER_SERVER_PREFERENCE;
Remi Gacogneaf5c3da2014-05-19 10:29:58 +02001907 long sslmode =
Emeric Brunfc0421f2012-09-07 17:30:07 +02001908 SSL_MODE_ENABLE_PARTIAL_WRITE |
1909 SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER |
Willy Tarreau396a1862014-11-13 14:06:52 +01001910 SSL_MODE_RELEASE_BUFFERS |
1911 SSL_MODE_SMALL_BUFFERS;
Remi Gacognef46cd6e2014-06-12 14:58:40 +02001912 STACK_OF(SSL_CIPHER) * ciphers = NULL;
Willy Tarreaua616ba62014-10-26 06:49:19 +01001913 SSL_CIPHER * cipher = NULL;
Remi Gacognec1eab8c2014-06-12 18:20:11 +02001914 char cipher_description[128];
1915 /* The description of ciphers using an Ephemeral Diffie Hellman key exchange
1916 contains " Kx=DH " or " Kx=DH(". Beware of " Kx=DH/",
1917 which is not ephemeral DH. */
1918 const char dhe_description[] = " Kx=DH ";
1919 const char dhe_export_description[] = " Kx=DH(";
Remi Gacognef46cd6e2014-06-12 14:58:40 +02001920 int idx = 0;
1921 int dhe_found = 0;
Remi Gacogne23d5d372014-10-10 17:04:26 +02001922 SSL *ssl = NULL;
Emeric Brunfc0421f2012-09-07 17:30:07 +02001923
Thierry Fournier383085f2013-01-24 14:15:43 +01001924 /* Make sure openssl opens /dev/urandom before the chroot */
1925 if (!ssl_initialize_random()) {
1926 Alert("OpenSSL random data generator initialization failed.\n");
1927 cfgerr++;
1928 }
1929
Emeric Brun89675492012-10-05 13:48:26 +02001930 if (bind_conf->ssl_options & BC_SSL_O_NO_SSLV3)
Emeric Brunfc0421f2012-09-07 17:30:07 +02001931 ssloptions |= SSL_OP_NO_SSLv3;
Emeric Brun89675492012-10-05 13:48:26 +02001932 if (bind_conf->ssl_options & BC_SSL_O_NO_TLSV10)
Emeric Brunfc0421f2012-09-07 17:30:07 +02001933 ssloptions |= SSL_OP_NO_TLSv1;
Emeric Brun89675492012-10-05 13:48:26 +02001934 if (bind_conf->ssl_options & BC_SSL_O_NO_TLSV11)
Emeric Brunc0ff4922012-09-28 19:37:02 +02001935 ssloptions |= SSL_OP_NO_TLSv1_1;
Emeric Brun89675492012-10-05 13:48:26 +02001936 if (bind_conf->ssl_options & BC_SSL_O_NO_TLSV12)
Emeric Brunc0ff4922012-09-28 19:37:02 +02001937 ssloptions |= SSL_OP_NO_TLSv1_2;
Emeric Brun89675492012-10-05 13:48:26 +02001938 if (bind_conf->ssl_options & BC_SSL_O_NO_TLS_TICKETS)
Emeric Brun2d0c4822012-10-02 13:45:20 +02001939 ssloptions |= SSL_OP_NO_TICKET;
Emeric Brun2cb7ae52012-10-05 14:14:21 +02001940 if (bind_conf->ssl_options & BC_SSL_O_USE_SSLV3)
1941 SSL_CTX_set_ssl_version(ctx, SSLv3_server_method());
1942 if (bind_conf->ssl_options & BC_SSL_O_USE_TLSV10)
1943 SSL_CTX_set_ssl_version(ctx, TLSv1_server_method());
1944#if SSL_OP_NO_TLSv1_1
1945 if (bind_conf->ssl_options & BC_SSL_O_USE_TLSV11)
1946 SSL_CTX_set_ssl_version(ctx, TLSv1_1_server_method());
1947#endif
1948#if SSL_OP_NO_TLSv1_2
1949 if (bind_conf->ssl_options & BC_SSL_O_USE_TLSV12)
1950 SSL_CTX_set_ssl_version(ctx, TLSv1_2_server_method());
1951#endif
Emeric Brunfc0421f2012-09-07 17:30:07 +02001952
1953 SSL_CTX_set_options(ctx, ssloptions);
1954 SSL_CTX_set_mode(ctx, sslmode);
Emeric Brun850efd52014-01-29 12:24:34 +01001955 switch (bind_conf->verify) {
1956 case SSL_SOCK_VERIFY_NONE:
1957 verify = SSL_VERIFY_NONE;
1958 break;
1959 case SSL_SOCK_VERIFY_OPTIONAL:
1960 verify = SSL_VERIFY_PEER;
1961 break;
1962 case SSL_SOCK_VERIFY_REQUIRED:
1963 verify = SSL_VERIFY_PEER|SSL_VERIFY_FAIL_IF_NO_PEER_CERT;
1964 break;
1965 }
1966 SSL_CTX_set_verify(ctx, verify, ssl_sock_bind_verifycbk);
1967 if (verify & SSL_VERIFY_PEER) {
Emeric Brunfb510ea2012-10-05 12:00:26 +02001968 if (bind_conf->ca_file) {
Emeric Brund94b3fe2012-09-20 18:23:56 +02001969 /* load CAfile to verify */
Emeric Brunfb510ea2012-10-05 12:00:26 +02001970 if (!SSL_CTX_load_verify_locations(ctx, bind_conf->ca_file, NULL)) {
Emeric Brund94b3fe2012-09-20 18:23:56 +02001971 Alert("Proxy '%s': unable to load CA file '%s' for bind '%s' at [%s:%d].\n",
Emeric Brunfb510ea2012-10-05 12:00:26 +02001972 curproxy->id, bind_conf->ca_file, bind_conf->arg, bind_conf->file, bind_conf->line);
Emeric Brund94b3fe2012-09-20 18:23:56 +02001973 cfgerr++;
1974 }
1975 /* set CA names fo client cert request, function returns void */
Emeric Brunfb510ea2012-10-05 12:00:26 +02001976 SSL_CTX_set_client_CA_list(ctx, SSL_load_client_CA_file(bind_conf->ca_file));
Emeric Brund94b3fe2012-09-20 18:23:56 +02001977 }
Emeric Brun850efd52014-01-29 12:24:34 +01001978 else {
1979 Alert("Proxy '%s': verify is enabled but no CA file specified for bind '%s' at [%s:%d].\n",
1980 curproxy->id, bind_conf->arg, bind_conf->file, bind_conf->line);
1981 cfgerr++;
1982 }
Emeric Brun051cdab2012-10-02 19:25:50 +02001983#ifdef X509_V_FLAG_CRL_CHECK
Emeric Brunfb510ea2012-10-05 12:00:26 +02001984 if (bind_conf->crl_file) {
Emeric Brund94b3fe2012-09-20 18:23:56 +02001985 X509_STORE *store = SSL_CTX_get_cert_store(ctx);
1986
Emeric Brunfb510ea2012-10-05 12:00:26 +02001987 if (!store || !X509_STORE_load_locations(store, bind_conf->crl_file, NULL)) {
Emeric Brund94b3fe2012-09-20 18:23:56 +02001988 Alert("Proxy '%s': unable to configure CRL file '%s' for bind '%s' at [%s:%d].\n",
Alexander Rigbofc65af02015-04-07 14:02:16 +02001989 curproxy->id, bind_conf->crl_file, bind_conf->arg, bind_conf->file, bind_conf->line);
Emeric Brund94b3fe2012-09-20 18:23:56 +02001990 cfgerr++;
1991 }
Emeric Brun561e5742012-10-02 15:20:55 +02001992 else {
1993 X509_STORE_set_flags(store, X509_V_FLAG_CRL_CHECK|X509_V_FLAG_CRL_CHECK_ALL);
1994 }
Emeric Brund94b3fe2012-09-20 18:23:56 +02001995 }
Emeric Brun051cdab2012-10-02 19:25:50 +02001996#endif
Emeric Brun644cde02012-12-14 11:21:13 +01001997 ERR_clear_error();
Emeric Brund94b3fe2012-09-20 18:23:56 +02001998 }
Emeric Brunfc0421f2012-09-07 17:30:07 +02001999
Nenad Merdanovic05552d42015-02-27 19:56:49 +01002000#if (defined SSL_CTRL_SET_TLSEXT_TICKET_KEY_CB && TLS_TICKETS_NO > 0)
Nenad Merdanovic146defa2015-05-09 08:46:00 +02002001 if(bind_conf->keys_ref) {
Nenad Merdanovic05552d42015-02-27 19:56:49 +01002002 if (!SSL_CTX_set_tlsext_ticket_key_cb(ctx, ssl_tlsext_ticket_key_cb)) {
2003 Alert("Proxy '%s': unable to set callback for TLS ticket validation for bind '%s' at [%s:%d].\n",
2004 curproxy->id, bind_conf->arg, bind_conf->file, bind_conf->line);
2005 cfgerr++;
2006 }
2007 }
2008#endif
2009
Emeric Brun4f65bff2012-11-16 15:11:00 +01002010 if (global.tune.ssllifetime)
2011 SSL_CTX_set_timeout(ctx, global.tune.ssllifetime);
2012
Emeric Brunfc0421f2012-09-07 17:30:07 +02002013 shared_context_set_cache(ctx);
Willy Tarreau2a65ff02012-09-13 17:54:29 +02002014 if (bind_conf->ciphers &&
2015 !SSL_CTX_set_cipher_list(ctx, bind_conf->ciphers)) {
Emeric Brunfc0421f2012-09-07 17:30:07 +02002016 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 +02002017 curproxy->id, bind_conf->ciphers, bind_conf->arg, bind_conf->file, bind_conf->line);
Emeric Brunfc0421f2012-09-07 17:30:07 +02002018 cfgerr++;
2019 }
2020
Remi Gacogne47783ef2015-05-29 15:53:22 +02002021 /* If tune.ssl.default-dh-param has not been set,
2022 neither has ssl-default-dh-file and no static DH
2023 params were in the certificate file. */
Remi Gacogne4f902b82015-05-28 16:23:00 +02002024 if (global.tune.ssl_default_dh_param == 0 &&
Remi Gacogne47783ef2015-05-29 15:53:22 +02002025 global_dh == NULL &&
Remi Gacogne4f902b82015-05-28 16:23:00 +02002026 (ssl_dh_ptr_index == -1 ||
2027 SSL_CTX_get_ex_data(ctx, ssl_dh_ptr_index) == NULL)) {
Lukas Tribus90132722014-08-18 00:56:33 +02002028
Remi Gacogne23d5d372014-10-10 17:04:26 +02002029 ssl = SSL_new(ctx);
Remi Gacognef46cd6e2014-06-12 14:58:40 +02002030
Remi Gacogne23d5d372014-10-10 17:04:26 +02002031 if (ssl) {
2032 ciphers = SSL_get_ciphers(ssl);
2033
2034 if (ciphers) {
2035 for (idx = 0; idx < sk_SSL_CIPHER_num(ciphers); idx++) {
2036 cipher = sk_SSL_CIPHER_value(ciphers, idx);
2037 if (SSL_CIPHER_description(cipher, cipher_description, sizeof (cipher_description)) == cipher_description) {
2038 if (strstr(cipher_description, dhe_description) != NULL ||
2039 strstr(cipher_description, dhe_export_description) != NULL) {
2040 dhe_found = 1;
2041 break;
2042 }
Remi Gacognec1eab8c2014-06-12 18:20:11 +02002043 }
Remi Gacognef46cd6e2014-06-12 14:58:40 +02002044 }
2045 }
Remi Gacogne23d5d372014-10-10 17:04:26 +02002046 SSL_free(ssl);
2047 ssl = NULL;
Lukas Tribus90132722014-08-18 00:56:33 +02002048 }
Remi Gacognef46cd6e2014-06-12 14:58:40 +02002049
Lukas Tribus90132722014-08-18 00:56:33 +02002050 if (dhe_found) {
2051 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 +02002052 }
2053
2054 global.tune.ssl_default_dh_param = 1024;
2055 }
Remi Gacogne8de54152014-07-15 11:36:40 +02002056
2057#ifndef OPENSSL_NO_DH
2058 if (global.tune.ssl_default_dh_param >= 1024) {
2059 if (local_dh_1024 == NULL) {
2060 local_dh_1024 = ssl_get_dh_1024();
2061 }
2062 if (global.tune.ssl_default_dh_param >= 2048) {
2063 if (local_dh_2048 == NULL) {
2064 local_dh_2048 = ssl_get_dh_2048();
2065 }
2066 if (global.tune.ssl_default_dh_param >= 4096) {
2067 if (local_dh_4096 == NULL) {
2068 local_dh_4096 = ssl_get_dh_4096();
2069 }
Remi Gacogne8de54152014-07-15 11:36:40 +02002070 }
2071 }
2072 }
2073#endif /* OPENSSL_NO_DH */
Remi Gacognef46cd6e2014-06-12 14:58:40 +02002074
Emeric Brunfc0421f2012-09-07 17:30:07 +02002075 SSL_CTX_set_info_callback(ctx, ssl_sock_infocbk);
Willy Tarreau5cbe4ef2014-05-08 22:45:11 +02002076#if OPENSSL_VERSION_NUMBER >= 0x00907000L
Emeric Brun29f037d2014-04-25 19:05:36 +02002077 SSL_CTX_set_msg_callback(ctx, ssl_sock_msgcbk);
Willy Tarreau5cbe4ef2014-05-08 22:45:11 +02002078#endif
Emeric Brun29f037d2014-04-25 19:05:36 +02002079
Willy Tarreau6c9a3d52012-10-18 18:57:14 +02002080#ifdef OPENSSL_NPN_NEGOTIATED
2081 if (bind_conf->npn_str)
2082 SSL_CTX_set_next_protos_advertised_cb(ctx, ssl_sock_advertise_npn_protos, bind_conf);
2083#endif
Dirkjan Bussink48f1c4e2014-02-13 12:29:42 +01002084#ifdef TLSEXT_TYPE_application_layer_protocol_negotiation
Willy Tarreauab861d32013-04-02 02:30:41 +02002085 if (bind_conf->alpn_str)
Dirkjan Bussink48f1c4e2014-02-13 12:29:42 +01002086 SSL_CTX_set_alpn_select_cb(ctx, ssl_sock_advertise_alpn_protos, bind_conf);
Willy Tarreauab861d32013-04-02 02:30:41 +02002087#endif
Willy Tarreau6c9a3d52012-10-18 18:57:14 +02002088
Emeric Brunfc0421f2012-09-07 17:30:07 +02002089#ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME
2090 SSL_CTX_set_tlsext_servername_callback(ctx, ssl_sock_switchctx_cbk);
Willy Tarreau2a65ff02012-09-13 17:54:29 +02002091 SSL_CTX_set_tlsext_servername_arg(ctx, bind_conf);
Emeric Brunfc0421f2012-09-07 17:30:07 +02002092#endif
Emeric Brun2b58d042012-09-20 17:10:03 +02002093#if defined(SSL_CTX_set_tmp_ecdh) && !defined(OPENSSL_NO_ECDH)
Emeric Brun6924ef82013-03-06 14:08:53 +01002094 {
Emeric Brun2b58d042012-09-20 17:10:03 +02002095 int i;
2096 EC_KEY *ecdh;
2097
Emeric Brun6924ef82013-03-06 14:08:53 +01002098 i = OBJ_sn2nid(bind_conf->ecdhe ? bind_conf->ecdhe : ECDHE_DEFAULT_CURVE);
Emeric Brun2b58d042012-09-20 17:10:03 +02002099 if (!i || ((ecdh = EC_KEY_new_by_curve_name(i)) == NULL)) {
2100 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 +01002101 curproxy->id, bind_conf->ecdhe ? bind_conf->ecdhe : ECDHE_DEFAULT_CURVE,
2102 bind_conf->arg, bind_conf->file, bind_conf->line);
Emeric Brun2b58d042012-09-20 17:10:03 +02002103 cfgerr++;
2104 }
2105 else {
2106 SSL_CTX_set_tmp_ecdh(ctx, ecdh);
2107 EC_KEY_free(ecdh);
2108 }
2109 }
2110#endif
2111
Emeric Brunfc0421f2012-09-07 17:30:07 +02002112 return cfgerr;
2113}
2114
Evan Broderbe554312013-06-27 00:05:25 -07002115static int ssl_sock_srv_hostcheck(const char *pattern, const char *hostname)
2116{
2117 const char *pattern_wildcard, *pattern_left_label_end, *hostname_left_label_end;
2118 size_t prefixlen, suffixlen;
2119
2120 /* Trivial case */
2121 if (strcmp(pattern, hostname) == 0)
2122 return 1;
2123
Evan Broderbe554312013-06-27 00:05:25 -07002124 /* The rest of this logic is based on RFC 6125, section 6.4.3
2125 * (http://tools.ietf.org/html/rfc6125#section-6.4.3) */
2126
Emeric Bruna848dae2013-10-08 11:27:28 +02002127 pattern_wildcard = NULL;
2128 pattern_left_label_end = pattern;
2129 while (*pattern_left_label_end != '.') {
2130 switch (*pattern_left_label_end) {
2131 case 0:
2132 /* End of label not found */
2133 return 0;
2134 case '*':
2135 /* If there is more than one wildcards */
2136 if (pattern_wildcard)
2137 return 0;
2138 pattern_wildcard = pattern_left_label_end;
2139 break;
2140 }
2141 pattern_left_label_end++;
2142 }
2143
2144 /* If it's not trivial and there is no wildcard, it can't
2145 * match */
2146 if (!pattern_wildcard)
Evan Broderbe554312013-06-27 00:05:25 -07002147 return 0;
2148
2149 /* Make sure all labels match except the leftmost */
2150 hostname_left_label_end = strchr(hostname, '.');
2151 if (!hostname_left_label_end
2152 || strcmp(pattern_left_label_end, hostname_left_label_end) != 0)
2153 return 0;
2154
2155 /* Make sure the leftmost label of the hostname is long enough
2156 * that the wildcard can match */
Emeric Brun369da852013-10-08 11:39:35 +02002157 if (hostname_left_label_end - hostname < (pattern_left_label_end - pattern) - 1)
Evan Broderbe554312013-06-27 00:05:25 -07002158 return 0;
2159
2160 /* Finally compare the string on either side of the
2161 * wildcard */
2162 prefixlen = pattern_wildcard - pattern;
2163 suffixlen = pattern_left_label_end - (pattern_wildcard + 1);
Emeric Bruna848dae2013-10-08 11:27:28 +02002164 if ((prefixlen && (memcmp(pattern, hostname, prefixlen) != 0))
2165 || (suffixlen && (memcmp(pattern_wildcard + 1, hostname_left_label_end - suffixlen, suffixlen) != 0)))
Evan Broderbe554312013-06-27 00:05:25 -07002166 return 0;
2167
2168 return 1;
2169}
2170
2171static int ssl_sock_srv_verifycbk(int ok, X509_STORE_CTX *ctx)
2172{
2173 SSL *ssl;
2174 struct connection *conn;
2175 char *servername;
2176
2177 int depth;
2178 X509 *cert;
2179 STACK_OF(GENERAL_NAME) *alt_names;
2180 int i;
2181 X509_NAME *cert_subject;
2182 char *str;
2183
2184 if (ok == 0)
2185 return ok;
2186
2187 ssl = X509_STORE_CTX_get_ex_data(ctx, SSL_get_ex_data_X509_STORE_CTX_idx());
2188 conn = (struct connection *)SSL_get_app_data(ssl);
2189
2190 servername = objt_server(conn->target)->ssl_ctx.verify_host;
2191
2192 /* We only need to verify the CN on the actual server cert,
2193 * not the indirect CAs */
2194 depth = X509_STORE_CTX_get_error_depth(ctx);
2195 if (depth != 0)
2196 return ok;
2197
2198 /* At this point, the cert is *not* OK unless we can find a
2199 * hostname match */
2200 ok = 0;
2201
2202 cert = X509_STORE_CTX_get_current_cert(ctx);
2203 /* It seems like this might happen if verify peer isn't set */
2204 if (!cert)
2205 return ok;
2206
2207 alt_names = X509_get_ext_d2i(cert, NID_subject_alt_name, NULL, NULL);
2208 if (alt_names) {
2209 for (i = 0; !ok && i < sk_GENERAL_NAME_num(alt_names); i++) {
2210 GENERAL_NAME *name = sk_GENERAL_NAME_value(alt_names, i);
2211 if (name->type == GEN_DNS) {
Emeric Bruna33410c2013-09-17 15:47:48 +02002212#if OPENSSL_VERSION_NUMBER < 0x00907000L
2213 if (ASN1_STRING_to_UTF8((unsigned char **)&str, name->d.ia5) >= 0) {
2214#else
Evan Broderbe554312013-06-27 00:05:25 -07002215 if (ASN1_STRING_to_UTF8((unsigned char **)&str, name->d.dNSName) >= 0) {
Emeric Bruna33410c2013-09-17 15:47:48 +02002216#endif
Evan Broderbe554312013-06-27 00:05:25 -07002217 ok = ssl_sock_srv_hostcheck(str, servername);
2218 OPENSSL_free(str);
2219 }
2220 }
2221 }
Emeric Brun4ad50a42013-09-17 15:19:54 +02002222 sk_GENERAL_NAME_pop_free(alt_names, GENERAL_NAME_free);
Evan Broderbe554312013-06-27 00:05:25 -07002223 }
2224
2225 cert_subject = X509_get_subject_name(cert);
2226 i = -1;
2227 while (!ok && (i = X509_NAME_get_index_by_NID(cert_subject, NID_commonName, i)) != -1) {
2228 X509_NAME_ENTRY *entry = X509_NAME_get_entry(cert_subject, i);
2229 if (ASN1_STRING_to_UTF8((unsigned char **)&str, entry->value) >= 0) {
2230 ok = ssl_sock_srv_hostcheck(str, servername);
2231 OPENSSL_free(str);
2232 }
2233 }
2234
2235 return ok;
2236}
2237
Emeric Brun94324a42012-10-11 14:00:19 +02002238/* prepare ssl context from servers options. Returns an error count */
2239int ssl_sock_prepare_srv_ctx(struct server *srv, struct proxy *curproxy)
2240{
2241 int cfgerr = 0;
Remi Gacogneaf5c3da2014-05-19 10:29:58 +02002242 long options =
Emeric Brun94324a42012-10-11 14:00:19 +02002243 SSL_OP_ALL | /* all known workarounds for bugs */
2244 SSL_OP_NO_SSLv2 |
2245 SSL_OP_NO_COMPRESSION;
Remi Gacogneaf5c3da2014-05-19 10:29:58 +02002246 long mode =
Emeric Brun94324a42012-10-11 14:00:19 +02002247 SSL_MODE_ENABLE_PARTIAL_WRITE |
2248 SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER |
Willy Tarreau396a1862014-11-13 14:06:52 +01002249 SSL_MODE_RELEASE_BUFFERS |
2250 SSL_MODE_SMALL_BUFFERS;
Emeric Brun850efd52014-01-29 12:24:34 +01002251 int verify = SSL_VERIFY_NONE;
Emeric Brun94324a42012-10-11 14:00:19 +02002252
Thierry Fournier383085f2013-01-24 14:15:43 +01002253 /* Make sure openssl opens /dev/urandom before the chroot */
2254 if (!ssl_initialize_random()) {
2255 Alert("OpenSSL random data generator initialization failed.\n");
2256 cfgerr++;
2257 }
2258
Willy Tarreaufce03112015-01-15 21:32:40 +01002259 /* Automatic memory computations need to know we use SSL there */
2260 global.ssl_used_backend = 1;
2261
2262 /* Initiate SSL context for current server */
Emeric Brun94324a42012-10-11 14:00:19 +02002263 srv->ssl_ctx.reused_sess = NULL;
2264 if (srv->use_ssl)
2265 srv->xprt = &ssl_sock;
2266 if (srv->check.use_ssl)
Cyril Bonté9ce13112014-11-15 22:41:27 +01002267 srv->check.xprt = &ssl_sock;
Emeric Brun94324a42012-10-11 14:00:19 +02002268
2269 srv->ssl_ctx.ctx = SSL_CTX_new(SSLv23_client_method());
2270 if (!srv->ssl_ctx.ctx) {
2271 Alert("config : %s '%s', server '%s': unable to allocate ssl context.\n",
2272 proxy_type_str(curproxy), curproxy->id,
2273 srv->id);
2274 cfgerr++;
2275 return cfgerr;
2276 }
Emeric Bruna7aa3092012-10-26 12:58:00 +02002277 if (srv->ssl_ctx.client_crt) {
2278 if (SSL_CTX_use_PrivateKey_file(srv->ssl_ctx.ctx, srv->ssl_ctx.client_crt, SSL_FILETYPE_PEM) <= 0) {
2279 Alert("config : %s '%s', server '%s': unable to load SSL private key from PEM file '%s'.\n",
2280 proxy_type_str(curproxy), curproxy->id,
2281 srv->id, srv->ssl_ctx.client_crt);
2282 cfgerr++;
2283 }
2284 else if (SSL_CTX_use_certificate_chain_file(srv->ssl_ctx.ctx, srv->ssl_ctx.client_crt) <= 0) {
2285 Alert("config : %s '%s', server '%s': unable to load ssl certificate from PEM file '%s'.\n",
2286 proxy_type_str(curproxy), curproxy->id,
2287 srv->id, srv->ssl_ctx.client_crt);
2288 cfgerr++;
2289 }
2290 else if (SSL_CTX_check_private_key(srv->ssl_ctx.ctx) <= 0) {
2291 Alert("config : %s '%s', server '%s': inconsistencies between private key and certificate loaded from PEM file '%s'.\n",
2292 proxy_type_str(curproxy), curproxy->id,
2293 srv->id, srv->ssl_ctx.client_crt);
2294 cfgerr++;
2295 }
2296 }
Emeric Brun94324a42012-10-11 14:00:19 +02002297
2298 if (srv->ssl_ctx.options & SRV_SSL_O_NO_SSLV3)
2299 options |= SSL_OP_NO_SSLv3;
2300 if (srv->ssl_ctx.options & SRV_SSL_O_NO_TLSV10)
2301 options |= SSL_OP_NO_TLSv1;
2302 if (srv->ssl_ctx.options & SRV_SSL_O_NO_TLSV11)
2303 options |= SSL_OP_NO_TLSv1_1;
2304 if (srv->ssl_ctx.options & SRV_SSL_O_NO_TLSV12)
2305 options |= SSL_OP_NO_TLSv1_2;
Emeric Brunf9c5c472012-10-11 15:28:34 +02002306 if (srv->ssl_ctx.options & SRV_SSL_O_NO_TLS_TICKETS)
2307 options |= SSL_OP_NO_TICKET;
Emeric Brun94324a42012-10-11 14:00:19 +02002308 if (srv->ssl_ctx.options & SRV_SSL_O_USE_SSLV3)
2309 SSL_CTX_set_ssl_version(srv->ssl_ctx.ctx, SSLv3_client_method());
2310 if (srv->ssl_ctx.options & SRV_SSL_O_USE_TLSV10)
2311 SSL_CTX_set_ssl_version(srv->ssl_ctx.ctx, TLSv1_client_method());
2312#if SSL_OP_NO_TLSv1_1
2313 if (srv->ssl_ctx.options & SRV_SSL_O_USE_TLSV11)
2314 SSL_CTX_set_ssl_version(srv->ssl_ctx.ctx, TLSv1_1_client_method());
2315#endif
2316#if SSL_OP_NO_TLSv1_2
2317 if (srv->ssl_ctx.options & SRV_SSL_O_USE_TLSV12)
2318 SSL_CTX_set_ssl_version(srv->ssl_ctx.ctx, TLSv1_2_client_method());
2319#endif
2320
2321 SSL_CTX_set_options(srv->ssl_ctx.ctx, options);
2322 SSL_CTX_set_mode(srv->ssl_ctx.ctx, mode);
Emeric Brun850efd52014-01-29 12:24:34 +01002323
2324 if (global.ssl_server_verify == SSL_SERVER_VERIFY_REQUIRED)
2325 verify = SSL_VERIFY_PEER;
2326
2327 switch (srv->ssl_ctx.verify) {
2328 case SSL_SOCK_VERIFY_NONE:
2329 verify = SSL_VERIFY_NONE;
2330 break;
2331 case SSL_SOCK_VERIFY_REQUIRED:
2332 verify = SSL_VERIFY_PEER;
2333 break;
2334 }
Evan Broderbe554312013-06-27 00:05:25 -07002335 SSL_CTX_set_verify(srv->ssl_ctx.ctx,
Emeric Brun850efd52014-01-29 12:24:34 +01002336 verify,
Evan Broderbe554312013-06-27 00:05:25 -07002337 srv->ssl_ctx.verify_host ? ssl_sock_srv_verifycbk : NULL);
Emeric Brun850efd52014-01-29 12:24:34 +01002338 if (verify & SSL_VERIFY_PEER) {
Emeric Brunef42d922012-10-11 16:11:36 +02002339 if (srv->ssl_ctx.ca_file) {
2340 /* load CAfile to verify */
2341 if (!SSL_CTX_load_verify_locations(srv->ssl_ctx.ctx, srv->ssl_ctx.ca_file, NULL)) {
Willy Tarreau07ba08b2014-02-16 19:22:08 +01002342 Alert("Proxy '%s', server '%s' [%s:%d] unable to load CA file '%s'.\n",
Emeric Brunef42d922012-10-11 16:11:36 +02002343 curproxy->id, srv->id,
2344 srv->conf.file, srv->conf.line, srv->ssl_ctx.ca_file);
2345 cfgerr++;
2346 }
2347 }
Emeric Brun850efd52014-01-29 12:24:34 +01002348 else {
2349 if (global.ssl_server_verify == SSL_SERVER_VERIFY_REQUIRED)
Willy Tarreau07ba08b2014-02-16 19:22:08 +01002350 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 +01002351 curproxy->id, srv->id,
2352 srv->conf.file, srv->conf.line);
2353 else
Willy Tarreau07ba08b2014-02-16 19:22:08 +01002354 Alert("Proxy '%s', server '%s' [%s:%d] verify is enabled but no CA file specified.\n",
Emeric Brun850efd52014-01-29 12:24:34 +01002355 curproxy->id, srv->id,
2356 srv->conf.file, srv->conf.line);
2357 cfgerr++;
2358 }
Emeric Brunef42d922012-10-11 16:11:36 +02002359#ifdef X509_V_FLAG_CRL_CHECK
2360 if (srv->ssl_ctx.crl_file) {
2361 X509_STORE *store = SSL_CTX_get_cert_store(srv->ssl_ctx.ctx);
2362
2363 if (!store || !X509_STORE_load_locations(store, srv->ssl_ctx.crl_file, NULL)) {
Willy Tarreau07ba08b2014-02-16 19:22:08 +01002364 Alert("Proxy '%s', server '%s' [%s:%d] unable to configure CRL file '%s'.\n",
Emeric Brunef42d922012-10-11 16:11:36 +02002365 curproxy->id, srv->id,
2366 srv->conf.file, srv->conf.line, srv->ssl_ctx.crl_file);
2367 cfgerr++;
2368 }
2369 else {
2370 X509_STORE_set_flags(store, X509_V_FLAG_CRL_CHECK|X509_V_FLAG_CRL_CHECK_ALL);
2371 }
2372 }
2373#endif
2374 }
2375
Emeric Brun4f65bff2012-11-16 15:11:00 +01002376 if (global.tune.ssllifetime)
2377 SSL_CTX_set_timeout(srv->ssl_ctx.ctx, global.tune.ssllifetime);
2378
Emeric Brun94324a42012-10-11 14:00:19 +02002379 SSL_CTX_set_session_cache_mode(srv->ssl_ctx.ctx, SSL_SESS_CACHE_OFF);
2380 if (srv->ssl_ctx.ciphers &&
2381 !SSL_CTX_set_cipher_list(srv->ssl_ctx.ctx, srv->ssl_ctx.ciphers)) {
2382 Alert("Proxy '%s', server '%s' [%s:%d] : unable to set SSL cipher list to '%s'.\n",
2383 curproxy->id, srv->id,
2384 srv->conf.file, srv->conf.line, srv->ssl_ctx.ciphers);
2385 cfgerr++;
2386 }
2387
2388 return cfgerr;
2389}
2390
Willy Tarreau2a65ff02012-09-13 17:54:29 +02002391/* Walks down the two trees in bind_conf and prepares all certs. The pointer may
Emeric Brunfc0421f2012-09-07 17:30:07 +02002392 * be NULL, in which case nothing is done. Returns the number of errors
2393 * encountered.
2394 */
Willy Tarreau2a65ff02012-09-13 17:54:29 +02002395int ssl_sock_prepare_all_ctx(struct bind_conf *bind_conf, struct proxy *px)
Emeric Brunfc0421f2012-09-07 17:30:07 +02002396{
2397 struct ebmb_node *node;
2398 struct sni_ctx *sni;
2399 int err = 0;
2400
Willy Tarreau2a65ff02012-09-13 17:54:29 +02002401 if (!bind_conf || !bind_conf->is_ssl)
Emeric Brunfc0421f2012-09-07 17:30:07 +02002402 return 0;
2403
Willy Tarreaufce03112015-01-15 21:32:40 +01002404 /* Automatic memory computations need to know we use SSL there */
2405 global.ssl_used_frontend = 1;
2406
Emeric Brun0bed9942014-10-30 19:25:24 +01002407 if (bind_conf->default_ctx)
2408 err += ssl_sock_prepare_ctx(bind_conf, bind_conf->default_ctx, px);
2409
Willy Tarreau2a65ff02012-09-13 17:54:29 +02002410 node = ebmb_first(&bind_conf->sni_ctx);
Emeric Brunfc0421f2012-09-07 17:30:07 +02002411 while (node) {
2412 sni = ebmb_entry(node, struct sni_ctx, name);
Emeric Brun0bed9942014-10-30 19:25:24 +01002413 if (!sni->order && sni->ctx != bind_conf->default_ctx)
2414 /* only initialize the CTX on its first occurrence and
2415 if it is not the default_ctx */
Willy Tarreau2a65ff02012-09-13 17:54:29 +02002416 err += ssl_sock_prepare_ctx(bind_conf, sni->ctx, px);
Emeric Brunfc0421f2012-09-07 17:30:07 +02002417 node = ebmb_next(node);
2418 }
2419
Willy Tarreau2a65ff02012-09-13 17:54:29 +02002420 node = ebmb_first(&bind_conf->sni_w_ctx);
Emeric Brunfc0421f2012-09-07 17:30:07 +02002421 while (node) {
2422 sni = ebmb_entry(node, struct sni_ctx, name);
Emeric Brun0bed9942014-10-30 19:25:24 +01002423 if (!sni->order && sni->ctx != bind_conf->default_ctx)
2424 /* only initialize the CTX on its first occurrence and
2425 if it is not the default_ctx */
Willy Tarreau2a65ff02012-09-13 17:54:29 +02002426 err += ssl_sock_prepare_ctx(bind_conf, sni->ctx, px);
Emeric Brunfc0421f2012-09-07 17:30:07 +02002427 node = ebmb_next(node);
2428 }
2429 return err;
2430}
2431
Willy Tarreau2a65ff02012-09-13 17:54:29 +02002432/* Walks down the two trees in bind_conf and frees all the certs. The pointer may
Emeric Brunfc0421f2012-09-07 17:30:07 +02002433 * be NULL, in which case nothing is done. The default_ctx is nullified too.
2434 */
Willy Tarreau2a65ff02012-09-13 17:54:29 +02002435void ssl_sock_free_all_ctx(struct bind_conf *bind_conf)
Emeric Brunfc0421f2012-09-07 17:30:07 +02002436{
2437 struct ebmb_node *node, *back;
2438 struct sni_ctx *sni;
2439
Willy Tarreau2a65ff02012-09-13 17:54:29 +02002440 if (!bind_conf || !bind_conf->is_ssl)
Emeric Brunfc0421f2012-09-07 17:30:07 +02002441 return;
2442
Willy Tarreau2a65ff02012-09-13 17:54:29 +02002443 node = ebmb_first(&bind_conf->sni_ctx);
Emeric Brunfc0421f2012-09-07 17:30:07 +02002444 while (node) {
2445 sni = ebmb_entry(node, struct sni_ctx, name);
2446 back = ebmb_next(node);
2447 ebmb_delete(node);
2448 if (!sni->order) /* only free the CTX on its first occurrence */
2449 SSL_CTX_free(sni->ctx);
2450 free(sni);
2451 node = back;
2452 }
2453
Willy Tarreau2a65ff02012-09-13 17:54:29 +02002454 node = ebmb_first(&bind_conf->sni_w_ctx);
Emeric Brunfc0421f2012-09-07 17:30:07 +02002455 while (node) {
2456 sni = ebmb_entry(node, struct sni_ctx, name);
2457 back = ebmb_next(node);
2458 ebmb_delete(node);
2459 if (!sni->order) /* only free the CTX on its first occurrence */
2460 SSL_CTX_free(sni->ctx);
2461 free(sni);
2462 node = back;
2463 }
2464
Willy Tarreau2a65ff02012-09-13 17:54:29 +02002465 bind_conf->default_ctx = NULL;
Emeric Brune1f38db2012-09-03 20:36:47 +02002466}
2467
Christopher Faulet31af49d2015-06-09 17:29:50 +02002468/* Load CA cert file and private key used to generate certificates */
2469int
2470ssl_sock_load_ca(struct bind_conf *bind_conf, struct proxy *px)
2471{
2472 FILE *fp;
2473 X509 *cacert = NULL;
2474 EVP_PKEY *capkey = NULL;
2475 int err = 0;
2476
2477 if (!bind_conf || !bind_conf->generate_certs)
2478 return err;
2479
2480 if (!bind_conf->ca_sign_file) {
2481 Alert("Proxy '%s': cannot enable certificate generation, "
2482 "no CA certificate File configured at [%s:%d].\n",
2483 px->id, bind_conf->file, bind_conf->line);
2484 err++;
2485 }
2486
2487 if (err)
2488 goto load_error;
2489
2490 /* read in the CA certificate */
2491 if (!(fp = fopen(bind_conf->ca_sign_file, "r"))) {
2492 Alert("Proxy '%s': Failed to read CA certificate file '%s' at [%s:%d].\n",
2493 px->id, bind_conf->ca_sign_file, bind_conf->file, bind_conf->line);
2494 err++;
2495 goto load_error;
2496 }
2497 if (!(cacert = PEM_read_X509(fp, NULL, NULL, NULL))) {
2498 Alert("Proxy '%s': Failed to read CA certificate file '%s' at [%s:%d].\n",
2499 px->id, bind_conf->ca_sign_file, bind_conf->file, bind_conf->line);
2500 fclose (fp);
2501 err++;
2502 goto load_error;
2503 }
2504 if (!(capkey = PEM_read_PrivateKey(fp, NULL, NULL, bind_conf->ca_sign_pass))) {
2505 Alert("Proxy '%s': Failed to read CA private key file '%s' at [%s:%d].\n",
2506 px->id, bind_conf->ca_sign_file, bind_conf->file, bind_conf->line);
2507 fclose (fp);
2508 err++;
2509 goto load_error;
2510 }
2511 fclose (fp);
2512
2513 bind_conf->ca_sign_cert = cacert;
2514 bind_conf->ca_sign_pkey = capkey;
2515 return err;
2516
2517 load_error:
2518 bind_conf->generate_certs = 0;
2519 if (capkey) EVP_PKEY_free(capkey);
2520 if (cacert) X509_free(cacert);
2521 return err;
2522}
2523
2524/* Release CA cert and private key used to generate certificated */
2525void
2526ssl_sock_free_ca(struct bind_conf *bind_conf)
2527{
2528 if (!bind_conf)
2529 return;
2530
2531 if (bind_conf->ca_sign_pkey)
2532 EVP_PKEY_free(bind_conf->ca_sign_pkey);
2533 if (bind_conf->ca_sign_cert)
2534 X509_free(bind_conf->ca_sign_cert);
2535}
2536
Emeric Brun46591952012-05-18 15:47:34 +02002537/*
2538 * This function is called if SSL * context is not yet allocated. The function
2539 * is designed to be called before any other data-layer operation and sets the
2540 * handshake flag on the connection. It is safe to call it multiple times.
2541 * It returns 0 on success and -1 in error case.
2542 */
2543static int ssl_sock_init(struct connection *conn)
2544{
2545 /* already initialized */
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02002546 if (conn->xprt_ctx)
Emeric Brun46591952012-05-18 15:47:34 +02002547 return 0;
2548
Willy Tarreau3c728722014-01-23 13:50:42 +01002549 if (!conn_ctrl_ready(conn))
Willy Tarreauf79c8172013-10-21 16:30:56 +02002550 return 0;
2551
Willy Tarreau20879a02012-12-03 16:32:10 +01002552 if (global.maxsslconn && sslconns >= global.maxsslconn) {
2553 conn->err_code = CO_ER_SSL_TOO_MANY;
Willy Tarreau403edff2012-09-06 11:58:37 +02002554 return -1;
Willy Tarreau20879a02012-12-03 16:32:10 +01002555 }
Willy Tarreau403edff2012-09-06 11:58:37 +02002556
Emeric Brun46591952012-05-18 15:47:34 +02002557 /* If it is in client mode initiate SSL session
2558 in connect state otherwise accept state */
Willy Tarreau3fdb3662012-11-12 00:42:33 +01002559 if (objt_server(conn->target)) {
Willy Tarreaufba03cd2014-11-13 13:48:58 +01002560 int may_retry = 1;
2561
2562 retry_connect:
Emeric Brun46591952012-05-18 15:47:34 +02002563 /* Alloc a new SSL session ctx */
Willy Tarreau3fdb3662012-11-12 00:42:33 +01002564 conn->xprt_ctx = SSL_new(objt_server(conn->target)->ssl_ctx.ctx);
Willy Tarreau20879a02012-12-03 16:32:10 +01002565 if (!conn->xprt_ctx) {
Willy Tarreaufba03cd2014-11-13 13:48:58 +01002566 if (may_retry--) {
2567 pool_gc2();
2568 goto retry_connect;
2569 }
Willy Tarreau20879a02012-12-03 16:32:10 +01002570 conn->err_code = CO_ER_SSL_NO_MEM;
Emeric Brun46591952012-05-18 15:47:34 +02002571 return -1;
Willy Tarreau20879a02012-12-03 16:32:10 +01002572 }
Emeric Brun46591952012-05-18 15:47:34 +02002573
Emeric Brun46591952012-05-18 15:47:34 +02002574 /* set fd on SSL session context */
Emeric Brun55476152014-11-12 17:35:37 +01002575 if (!SSL_set_fd(conn->xprt_ctx, conn->t.sock.fd)) {
2576 SSL_free(conn->xprt_ctx);
2577 conn->xprt_ctx = NULL;
Willy Tarreaufba03cd2014-11-13 13:48:58 +01002578 if (may_retry--) {
2579 pool_gc2();
2580 goto retry_connect;
2581 }
Emeric Brun55476152014-11-12 17:35:37 +01002582 conn->err_code = CO_ER_SSL_NO_MEM;
2583 return -1;
2584 }
Emeric Brun46591952012-05-18 15:47:34 +02002585
Evan Broderbe554312013-06-27 00:05:25 -07002586 /* set connection pointer */
Emeric Brun55476152014-11-12 17:35:37 +01002587 if (!SSL_set_app_data(conn->xprt_ctx, conn)) {
2588 SSL_free(conn->xprt_ctx);
2589 conn->xprt_ctx = NULL;
Willy Tarreaufba03cd2014-11-13 13:48:58 +01002590 if (may_retry--) {
2591 pool_gc2();
2592 goto retry_connect;
2593 }
Emeric Brun55476152014-11-12 17:35:37 +01002594 conn->err_code = CO_ER_SSL_NO_MEM;
2595 return -1;
2596 }
2597
2598 SSL_set_connect_state(conn->xprt_ctx);
2599 if (objt_server(conn->target)->ssl_ctx.reused_sess) {
2600 if(!SSL_set_session(conn->xprt_ctx, objt_server(conn->target)->ssl_ctx.reused_sess)) {
2601 SSL_SESSION_free(objt_server(conn->target)->ssl_ctx.reused_sess);
2602 objt_server(conn->target)->ssl_ctx.reused_sess = NULL;
2603 }
2604 }
Evan Broderbe554312013-06-27 00:05:25 -07002605
Emeric Brun46591952012-05-18 15:47:34 +02002606 /* leave init state and start handshake */
Willy Tarreau05737472012-09-04 08:03:39 +02002607 conn->flags |= CO_FL_SSL_WAIT_HS | CO_FL_WAIT_L6_CONN;
Willy Tarreau403edff2012-09-06 11:58:37 +02002608
2609 sslconns++;
Willy Tarreau71b734c2014-01-28 15:19:44 +01002610 totalsslconns++;
Emeric Brun46591952012-05-18 15:47:34 +02002611 return 0;
2612 }
Willy Tarreau3fdb3662012-11-12 00:42:33 +01002613 else if (objt_listener(conn->target)) {
Willy Tarreaufba03cd2014-11-13 13:48:58 +01002614 int may_retry = 1;
2615
2616 retry_accept:
Emeric Brun46591952012-05-18 15:47:34 +02002617 /* Alloc a new SSL session ctx */
Willy Tarreau3fdb3662012-11-12 00:42:33 +01002618 conn->xprt_ctx = SSL_new(objt_listener(conn->target)->bind_conf->default_ctx);
Willy Tarreau20879a02012-12-03 16:32:10 +01002619 if (!conn->xprt_ctx) {
Willy Tarreaufba03cd2014-11-13 13:48:58 +01002620 if (may_retry--) {
2621 pool_gc2();
2622 goto retry_accept;
2623 }
Willy Tarreau20879a02012-12-03 16:32:10 +01002624 conn->err_code = CO_ER_SSL_NO_MEM;
Emeric Brun46591952012-05-18 15:47:34 +02002625 return -1;
Willy Tarreau20879a02012-12-03 16:32:10 +01002626 }
Emeric Brun46591952012-05-18 15:47:34 +02002627
Emeric Brun46591952012-05-18 15:47:34 +02002628 /* set fd on SSL session context */
Emeric Brun55476152014-11-12 17:35:37 +01002629 if (!SSL_set_fd(conn->xprt_ctx, conn->t.sock.fd)) {
2630 SSL_free(conn->xprt_ctx);
2631 conn->xprt_ctx = NULL;
Willy Tarreaufba03cd2014-11-13 13:48:58 +01002632 if (may_retry--) {
2633 pool_gc2();
2634 goto retry_accept;
2635 }
Emeric Brun55476152014-11-12 17:35:37 +01002636 conn->err_code = CO_ER_SSL_NO_MEM;
2637 return -1;
2638 }
Emeric Brun46591952012-05-18 15:47:34 +02002639
Emeric Brune1f38db2012-09-03 20:36:47 +02002640 /* set connection pointer */
Emeric Brun55476152014-11-12 17:35:37 +01002641 if (!SSL_set_app_data(conn->xprt_ctx, conn)) {
2642 SSL_free(conn->xprt_ctx);
2643 conn->xprt_ctx = NULL;
Willy Tarreaufba03cd2014-11-13 13:48:58 +01002644 if (may_retry--) {
2645 pool_gc2();
2646 goto retry_accept;
2647 }
Emeric Brun55476152014-11-12 17:35:37 +01002648 conn->err_code = CO_ER_SSL_NO_MEM;
2649 return -1;
2650 }
2651
2652 SSL_set_accept_state(conn->xprt_ctx);
Emeric Brune1f38db2012-09-03 20:36:47 +02002653
Emeric Brun46591952012-05-18 15:47:34 +02002654 /* leave init state and start handshake */
Willy Tarreau05737472012-09-04 08:03:39 +02002655 conn->flags |= CO_FL_SSL_WAIT_HS | CO_FL_WAIT_L6_CONN;
Willy Tarreau403edff2012-09-06 11:58:37 +02002656
2657 sslconns++;
Willy Tarreau71b734c2014-01-28 15:19:44 +01002658 totalsslconns++;
Emeric Brun46591952012-05-18 15:47:34 +02002659 return 0;
2660 }
2661 /* don't know how to handle such a target */
Willy Tarreau20879a02012-12-03 16:32:10 +01002662 conn->err_code = CO_ER_SSL_NO_TARGET;
Emeric Brun46591952012-05-18 15:47:34 +02002663 return -1;
2664}
2665
2666
2667/* This is the callback which is used when an SSL handshake is pending. It
2668 * updates the FD status if it wants some polling before being called again.
2669 * It returns 0 if it fails in a fatal way or needs to poll to go further,
2670 * otherwise it returns non-zero and removes itself from the connection's
2671 * flags (the bit is provided in <flag> by the caller).
2672 */
2673int ssl_sock_handshake(struct connection *conn, unsigned int flag)
2674{
2675 int ret;
2676
Willy Tarreau3c728722014-01-23 13:50:42 +01002677 if (!conn_ctrl_ready(conn))
Willy Tarreauf79c8172013-10-21 16:30:56 +02002678 return 0;
2679
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02002680 if (!conn->xprt_ctx)
Emeric Brun46591952012-05-18 15:47:34 +02002681 goto out_error;
2682
Emeric Brun674b7432012-11-08 19:21:55 +01002683 /* If we use SSL_do_handshake to process a reneg initiated by
2684 * the remote peer, it sometimes returns SSL_ERROR_SSL.
2685 * Usually SSL_write and SSL_read are used and process implicitly
2686 * the reneg handshake.
2687 * Here we use SSL_peek as a workaround for reneg.
2688 */
2689 if ((conn->flags & CO_FL_CONNECTED) && SSL_renegotiate_pending(conn->xprt_ctx)) {
2690 char c;
2691
2692 ret = SSL_peek(conn->xprt_ctx, &c, 1);
2693 if (ret <= 0) {
2694 /* handshake may have not been completed, let's find why */
2695 ret = SSL_get_error(conn->xprt_ctx, ret);
2696 if (ret == SSL_ERROR_WANT_WRITE) {
2697 /* SSL handshake needs to write, L4 connection may not be ready */
2698 __conn_sock_stop_recv(conn);
Willy Tarreaue1f50c42014-01-22 20:02:06 +01002699 __conn_sock_want_send(conn);
2700 fd_cant_send(conn->t.sock.fd);
Emeric Brun674b7432012-11-08 19:21:55 +01002701 return 0;
2702 }
2703 else if (ret == SSL_ERROR_WANT_READ) {
2704 /* handshake may have been completed but we have
2705 * no more data to read.
2706 */
2707 if (!SSL_renegotiate_pending(conn->xprt_ctx)) {
2708 ret = 1;
2709 goto reneg_ok;
2710 }
2711 /* SSL handshake needs to read, L4 connection is ready */
2712 if (conn->flags & CO_FL_WAIT_L4_CONN)
2713 conn->flags &= ~CO_FL_WAIT_L4_CONN;
2714 __conn_sock_stop_send(conn);
Willy Tarreaue1f50c42014-01-22 20:02:06 +01002715 __conn_sock_want_recv(conn);
2716 fd_cant_recv(conn->t.sock.fd);
Emeric Brun674b7432012-11-08 19:21:55 +01002717 return 0;
2718 }
2719 else if (ret == SSL_ERROR_SYSCALL) {
2720 /* if errno is null, then connection was successfully established */
2721 if (!errno && conn->flags & CO_FL_WAIT_L4_CONN)
2722 conn->flags &= ~CO_FL_WAIT_L4_CONN;
Willy Tarreau20879a02012-12-03 16:32:10 +01002723 if (!conn->err_code) {
Emeric Brun29f037d2014-04-25 19:05:36 +02002724 if (!((SSL *)conn->xprt_ctx)->packet_length) {
2725 if (!errno) {
2726 if (conn->xprt_st & SSL_SOCK_RECV_HEARTBEAT)
2727 conn->err_code = CO_ER_SSL_HANDSHAKE_HB;
2728 else
2729 conn->err_code = CO_ER_SSL_EMPTY;
2730 }
2731 else {
2732 if (conn->xprt_st & SSL_SOCK_RECV_HEARTBEAT)
2733 conn->err_code = CO_ER_SSL_HANDSHAKE_HB;
2734 else
2735 conn->err_code = CO_ER_SSL_ABORT;
2736 }
2737 }
2738 else {
2739 if (conn->xprt_st & SSL_SOCK_RECV_HEARTBEAT)
2740 conn->err_code = CO_ER_SSL_HANDSHAKE_HB;
Willy Tarreau20879a02012-12-03 16:32:10 +01002741 else
Emeric Brun29f037d2014-04-25 19:05:36 +02002742 conn->err_code = CO_ER_SSL_HANDSHAKE;
2743 }
Willy Tarreau20879a02012-12-03 16:32:10 +01002744 }
Emeric Brun674b7432012-11-08 19:21:55 +01002745 goto out_error;
2746 }
2747 else {
2748 /* Fail on all other handshake errors */
2749 /* Note: OpenSSL may leave unread bytes in the socket's
2750 * buffer, causing an RST to be emitted upon close() on
2751 * TCP sockets. We first try to drain possibly pending
2752 * data to avoid this as much as possible.
2753 */
Willy Tarreaud85c4852015-03-13 00:40:28 +01002754 conn_sock_drain(conn);
Willy Tarreau20879a02012-12-03 16:32:10 +01002755 if (!conn->err_code)
Willy Tarreauf51c6982014-04-25 20:02:39 +02002756 conn->err_code = (conn->xprt_st & SSL_SOCK_RECV_HEARTBEAT) ?
2757 CO_ER_SSL_KILLED_HB : CO_ER_SSL_HANDSHAKE;
Emeric Brun674b7432012-11-08 19:21:55 +01002758 goto out_error;
2759 }
2760 }
2761 /* read some data: consider handshake completed */
2762 goto reneg_ok;
2763 }
2764
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02002765 ret = SSL_do_handshake(conn->xprt_ctx);
Emeric Brun46591952012-05-18 15:47:34 +02002766 if (ret != 1) {
2767 /* handshake did not complete, let's find why */
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02002768 ret = SSL_get_error(conn->xprt_ctx, ret);
Emeric Brun46591952012-05-18 15:47:34 +02002769
2770 if (ret == SSL_ERROR_WANT_WRITE) {
2771 /* SSL handshake needs to write, L4 connection may not be ready */
2772 __conn_sock_stop_recv(conn);
Willy Tarreaue1f50c42014-01-22 20:02:06 +01002773 __conn_sock_want_send(conn);
2774 fd_cant_send(conn->t.sock.fd);
Emeric Brun46591952012-05-18 15:47:34 +02002775 return 0;
2776 }
2777 else if (ret == SSL_ERROR_WANT_READ) {
2778 /* SSL handshake needs to read, L4 connection is ready */
2779 if (conn->flags & CO_FL_WAIT_L4_CONN)
2780 conn->flags &= ~CO_FL_WAIT_L4_CONN;
2781 __conn_sock_stop_send(conn);
Willy Tarreaue1f50c42014-01-22 20:02:06 +01002782 __conn_sock_want_recv(conn);
2783 fd_cant_recv(conn->t.sock.fd);
Emeric Brun46591952012-05-18 15:47:34 +02002784 return 0;
2785 }
Willy Tarreau89230192012-09-28 20:22:13 +02002786 else if (ret == SSL_ERROR_SYSCALL) {
2787 /* if errno is null, then connection was successfully established */
2788 if (!errno && conn->flags & CO_FL_WAIT_L4_CONN)
2789 conn->flags &= ~CO_FL_WAIT_L4_CONN;
Willy Tarreau20879a02012-12-03 16:32:10 +01002790
Emeric Brun29f037d2014-04-25 19:05:36 +02002791 if (!((SSL *)conn->xprt_ctx)->packet_length) {
2792 if (!errno) {
2793 if (conn->xprt_st & SSL_SOCK_RECV_HEARTBEAT)
2794 conn->err_code = CO_ER_SSL_HANDSHAKE_HB;
2795 else
2796 conn->err_code = CO_ER_SSL_EMPTY;
2797 }
2798 else {
2799 if (conn->xprt_st & SSL_SOCK_RECV_HEARTBEAT)
2800 conn->err_code = CO_ER_SSL_HANDSHAKE_HB;
2801 else
2802 conn->err_code = CO_ER_SSL_ABORT;
2803 }
2804 }
2805 else {
2806 if (conn->xprt_st & SSL_SOCK_RECV_HEARTBEAT)
2807 conn->err_code = CO_ER_SSL_HANDSHAKE_HB;
Willy Tarreau20879a02012-12-03 16:32:10 +01002808 else
Emeric Brun29f037d2014-04-25 19:05:36 +02002809 conn->err_code = CO_ER_SSL_HANDSHAKE;
2810 }
Willy Tarreau89230192012-09-28 20:22:13 +02002811 goto out_error;
2812 }
Emeric Brun46591952012-05-18 15:47:34 +02002813 else {
2814 /* Fail on all other handshake errors */
Willy Tarreau566dc552012-10-19 20:52:18 +02002815 /* Note: OpenSSL may leave unread bytes in the socket's
2816 * buffer, causing an RST to be emitted upon close() on
2817 * TCP sockets. We first try to drain possibly pending
2818 * data to avoid this as much as possible.
2819 */
Willy Tarreaud85c4852015-03-13 00:40:28 +01002820 conn_sock_drain(conn);
Willy Tarreau20879a02012-12-03 16:32:10 +01002821 if (!conn->err_code)
Willy Tarreauf51c6982014-04-25 20:02:39 +02002822 conn->err_code = (conn->xprt_st & SSL_SOCK_RECV_HEARTBEAT) ?
2823 CO_ER_SSL_KILLED_HB : CO_ER_SSL_HANDSHAKE;
Emeric Brun46591952012-05-18 15:47:34 +02002824 goto out_error;
2825 }
2826 }
2827
Emeric Brun674b7432012-11-08 19:21:55 +01002828reneg_ok:
2829
Emeric Brun46591952012-05-18 15:47:34 +02002830 /* Handshake succeeded */
Willy Tarreau0c9c2722014-05-28 12:28:58 +02002831 if (!SSL_session_reused(conn->xprt_ctx)) {
2832 if (objt_server(conn->target)) {
2833 update_freq_ctr(&global.ssl_be_keys_per_sec, 1);
2834 if (global.ssl_be_keys_per_sec.curr_ctr > global.ssl_be_keys_max)
2835 global.ssl_be_keys_max = global.ssl_be_keys_per_sec.curr_ctr;
2836
Emeric Brun46591952012-05-18 15:47:34 +02002837 /* check if session was reused, if not store current session on server for reuse */
Willy Tarreau3fdb3662012-11-12 00:42:33 +01002838 if (objt_server(conn->target)->ssl_ctx.reused_sess)
2839 SSL_SESSION_free(objt_server(conn->target)->ssl_ctx.reused_sess);
Emeric Brun46591952012-05-18 15:47:34 +02002840
Willy Tarreau2a3fb1c2015-02-05 16:47:07 +01002841 if (!(objt_server(conn->target)->ssl_ctx.options & SRV_SSL_O_NO_REUSE))
2842 objt_server(conn->target)->ssl_ctx.reused_sess = SSL_get1_session(conn->xprt_ctx);
Emeric Brun46591952012-05-18 15:47:34 +02002843 }
Willy Tarreau0c9c2722014-05-28 12:28:58 +02002844 else {
2845 update_freq_ctr(&global.ssl_fe_keys_per_sec, 1);
2846 if (global.ssl_fe_keys_per_sec.curr_ctr > global.ssl_fe_keys_max)
2847 global.ssl_fe_keys_max = global.ssl_fe_keys_per_sec.curr_ctr;
2848 }
Emeric Brun46591952012-05-18 15:47:34 +02002849 }
2850
2851 /* The connection is now established at both layers, it's time to leave */
2852 conn->flags &= ~(flag | CO_FL_WAIT_L4_CONN | CO_FL_WAIT_L6_CONN);
2853 return 1;
2854
2855 out_error:
Emeric Brun644cde02012-12-14 11:21:13 +01002856 /* Clear openssl global errors stack */
2857 ERR_clear_error();
2858
Emeric Brun9fa89732012-10-04 17:09:56 +02002859 /* free resumed session if exists */
Willy Tarreau3fdb3662012-11-12 00:42:33 +01002860 if (objt_server(conn->target) && objt_server(conn->target)->ssl_ctx.reused_sess) {
2861 SSL_SESSION_free(objt_server(conn->target)->ssl_ctx.reused_sess);
2862 objt_server(conn->target)->ssl_ctx.reused_sess = NULL;
Emeric Brun9fa89732012-10-04 17:09:56 +02002863 }
2864
Emeric Brun46591952012-05-18 15:47:34 +02002865 /* Fail on all other handshake errors */
2866 conn->flags |= CO_FL_ERROR;
Willy Tarreau20879a02012-12-03 16:32:10 +01002867 if (!conn->err_code)
2868 conn->err_code = CO_ER_SSL_HANDSHAKE;
Emeric Brun46591952012-05-18 15:47:34 +02002869 return 0;
2870}
2871
2872/* Receive up to <count> bytes from connection <conn>'s socket and store them
Willy Tarreauabf08d92014-01-14 11:31:27 +01002873 * into buffer <buf>. Only one call to recv() is performed, unless the
Emeric Brun46591952012-05-18 15:47:34 +02002874 * buffer wraps, in which case a second call may be performed. The connection's
2875 * flags are updated with whatever special event is detected (error, read0,
2876 * empty). The caller is responsible for taking care of those events and
2877 * avoiding the call if inappropriate. The function does not call the
2878 * connection's polling update function, so the caller is responsible for this.
2879 */
2880static int ssl_sock_to_buf(struct connection *conn, struct buffer *buf, int count)
2881{
2882 int ret, done = 0;
Willy Tarreauabf08d92014-01-14 11:31:27 +01002883 int try;
Emeric Brun46591952012-05-18 15:47:34 +02002884
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02002885 if (!conn->xprt_ctx)
Emeric Brun46591952012-05-18 15:47:34 +02002886 goto out_error;
2887
2888 if (conn->flags & CO_FL_HANDSHAKE)
2889 /* a handshake was requested */
2890 return 0;
2891
Willy Tarreauabf08d92014-01-14 11:31:27 +01002892 /* let's realign the buffer to optimize I/O */
2893 if (buffer_empty(buf))
Emeric Brun46591952012-05-18 15:47:34 +02002894 buf->p = buf->data;
Emeric Brun46591952012-05-18 15:47:34 +02002895
2896 /* read the largest possible block. For this, we perform only one call
2897 * to recv() unless the buffer wraps and we exactly fill the first hunk,
2898 * in which case we accept to do it once again. A new attempt is made on
2899 * EINTR too.
2900 */
Willy Tarreau00b0fb92014-01-17 11:09:40 +01002901 while (count > 0) {
Willy Tarreauabf08d92014-01-14 11:31:27 +01002902 /* first check if we have some room after p+i */
2903 try = buf->data + buf->size - (buf->p + buf->i);
2904 /* otherwise continue between data and p-o */
2905 if (try <= 0) {
2906 try = buf->p - (buf->data + buf->o);
2907 if (try <= 0)
2908 break;
2909 }
2910 if (try > count)
2911 try = count;
2912
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02002913 ret = SSL_read(conn->xprt_ctx, bi_end(buf), try);
Emeric Brune1f38db2012-09-03 20:36:47 +02002914 if (conn->flags & CO_FL_ERROR) {
2915 /* CO_FL_ERROR may be set by ssl_sock_infocbk */
Emeric Brun644cde02012-12-14 11:21:13 +01002916 goto out_error;
Emeric Brune1f38db2012-09-03 20:36:47 +02002917 }
Emeric Brun46591952012-05-18 15:47:34 +02002918 if (ret > 0) {
2919 buf->i += ret;
2920 done += ret;
2921 if (ret < try)
2922 break;
2923 count -= ret;
Emeric Brun46591952012-05-18 15:47:34 +02002924 }
2925 else if (ret == 0) {
Emeric Brun644cde02012-12-14 11:21:13 +01002926 ret = SSL_get_error(conn->xprt_ctx, ret);
2927 if (ret != SSL_ERROR_ZERO_RETURN) {
Emeric Brun1c646862012-12-14 12:33:41 +01002928 /* error on protocol or underlying transport */
2929 if ((ret != SSL_ERROR_SYSCALL)
2930 || (errno && (errno != EAGAIN)))
2931 conn->flags |= CO_FL_ERROR;
2932
Emeric Brun644cde02012-12-14 11:21:13 +01002933 /* Clear openssl global errors stack */
2934 ERR_clear_error();
2935 }
Emeric Brun46591952012-05-18 15:47:34 +02002936 goto read0;
2937 }
2938 else {
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02002939 ret = SSL_get_error(conn->xprt_ctx, ret);
Emeric Brun46591952012-05-18 15:47:34 +02002940 if (ret == SSL_ERROR_WANT_WRITE) {
Emeric Brun8af8dd12012-11-08 17:56:20 +01002941 /* handshake is running, and it needs to enable write */
Emeric Brun46591952012-05-18 15:47:34 +02002942 conn->flags |= CO_FL_SSL_WAIT_HS;
Emeric Brun8af8dd12012-11-08 17:56:20 +01002943 __conn_sock_want_send(conn);
Emeric Brun46591952012-05-18 15:47:34 +02002944 break;
2945 }
2946 else if (ret == SSL_ERROR_WANT_READ) {
Emeric Brun282a76a2012-11-08 18:02:56 +01002947 if (SSL_renegotiate_pending(conn->xprt_ctx)) {
2948 /* handshake is running, and it may need to re-enable read */
2949 conn->flags |= CO_FL_SSL_WAIT_HS;
2950 __conn_sock_want_recv(conn);
2951 break;
2952 }
Emeric Brun46591952012-05-18 15:47:34 +02002953 /* we need to poll for retry a read later */
Willy Tarreaue1f50c42014-01-22 20:02:06 +01002954 fd_cant_recv(conn->t.sock.fd);
Emeric Brun46591952012-05-18 15:47:34 +02002955 break;
2956 }
2957 /* otherwise it's a real error */
2958 goto out_error;
2959 }
2960 }
2961 return done;
2962
2963 read0:
2964 conn_sock_read0(conn);
2965 return done;
2966 out_error:
Emeric Brun644cde02012-12-14 11:21:13 +01002967 /* Clear openssl global errors stack */
2968 ERR_clear_error();
2969
Emeric Brun46591952012-05-18 15:47:34 +02002970 conn->flags |= CO_FL_ERROR;
2971 return done;
2972}
2973
2974
2975/* Send all pending bytes from buffer <buf> to connection <conn>'s socket.
Willy Tarreau1049b1f2014-02-02 01:51:17 +01002976 * <flags> may contain some CO_SFL_* flags to hint the system about other
2977 * pending data for example, but this flag is ignored at the moment.
Emeric Brun46591952012-05-18 15:47:34 +02002978 * Only one call to send() is performed, unless the buffer wraps, in which case
2979 * a second call may be performed. The connection's flags are updated with
2980 * whatever special event is detected (error, empty). The caller is responsible
2981 * for taking care of those events and avoiding the call if inappropriate. The
2982 * function does not call the connection's polling update function, so the caller
2983 * is responsible for this.
2984 */
2985static int ssl_sock_from_buf(struct connection *conn, struct buffer *buf, int flags)
2986{
2987 int ret, try, done;
2988
2989 done = 0;
2990
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02002991 if (!conn->xprt_ctx)
Emeric Brun46591952012-05-18 15:47:34 +02002992 goto out_error;
2993
2994 if (conn->flags & CO_FL_HANDSHAKE)
2995 /* a handshake was requested */
2996 return 0;
2997
2998 /* send the largest possible block. For this we perform only one call
2999 * to send() unless the buffer wraps and we exactly fill the first hunk,
3000 * in which case we accept to do it once again.
3001 */
3002 while (buf->o) {
Kevin Hestercad82342013-05-30 15:12:41 -07003003 try = bo_contig_data(buf);
Willy Tarreaubfd59462013-02-21 07:46:09 +01003004
Willy Tarreau7bed9452014-02-02 02:00:24 +01003005 if (!(flags & CO_SFL_STREAMER) &&
Willy Tarreau518cedd2014-02-17 15:43:01 +01003006 !(conn->xprt_st & SSL_SOCK_SEND_UNLIMITED) &&
3007 global.tune.ssl_max_record && try > global.tune.ssl_max_record) {
Willy Tarreaubfd59462013-02-21 07:46:09 +01003008 try = global.tune.ssl_max_record;
Willy Tarreau518cedd2014-02-17 15:43:01 +01003009 }
3010 else {
3011 /* we need to keep the information about the fact that
3012 * we're not limiting the upcoming send(), because if it
3013 * fails, we'll have to retry with at least as many data.
3014 */
3015 conn->xprt_st |= SSL_SOCK_SEND_UNLIMITED;
3016 }
Willy Tarreaubfd59462013-02-21 07:46:09 +01003017
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02003018 ret = SSL_write(conn->xprt_ctx, bo_ptr(buf), try);
Willy Tarreau518cedd2014-02-17 15:43:01 +01003019
Emeric Brune1f38db2012-09-03 20:36:47 +02003020 if (conn->flags & CO_FL_ERROR) {
3021 /* CO_FL_ERROR may be set by ssl_sock_infocbk */
Emeric Brun644cde02012-12-14 11:21:13 +01003022 goto out_error;
Emeric Brune1f38db2012-09-03 20:36:47 +02003023 }
Emeric Brun46591952012-05-18 15:47:34 +02003024 if (ret > 0) {
Willy Tarreau518cedd2014-02-17 15:43:01 +01003025 conn->xprt_st &= ~SSL_SOCK_SEND_UNLIMITED;
3026
Emeric Brun46591952012-05-18 15:47:34 +02003027 buf->o -= ret;
3028 done += ret;
3029
Willy Tarreau5fb38032012-12-16 19:39:09 +01003030 if (likely(buffer_empty(buf)))
Emeric Brun46591952012-05-18 15:47:34 +02003031 /* optimize data alignment in the buffer */
3032 buf->p = buf->data;
3033
3034 /* if the system buffer is full, don't insist */
3035 if (ret < try)
3036 break;
3037 }
3038 else {
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02003039 ret = SSL_get_error(conn->xprt_ctx, ret);
Emeric Brun46591952012-05-18 15:47:34 +02003040 if (ret == SSL_ERROR_WANT_WRITE) {
Emeric Brun282a76a2012-11-08 18:02:56 +01003041 if (SSL_renegotiate_pending(conn->xprt_ctx)) {
3042 /* handshake is running, and it may need to re-enable write */
3043 conn->flags |= CO_FL_SSL_WAIT_HS;
3044 __conn_sock_want_send(conn);
3045 break;
3046 }
Emeric Brun46591952012-05-18 15:47:34 +02003047 /* we need to poll to retry a write later */
Willy Tarreaue1f50c42014-01-22 20:02:06 +01003048 fd_cant_send(conn->t.sock.fd);
Emeric Brun46591952012-05-18 15:47:34 +02003049 break;
3050 }
3051 else if (ret == SSL_ERROR_WANT_READ) {
Emeric Brun8af8dd12012-11-08 17:56:20 +01003052 /* handshake is running, and it needs to enable read */
Emeric Brun46591952012-05-18 15:47:34 +02003053 conn->flags |= CO_FL_SSL_WAIT_HS;
Emeric Brun8af8dd12012-11-08 17:56:20 +01003054 __conn_sock_want_recv(conn);
Emeric Brun46591952012-05-18 15:47:34 +02003055 break;
3056 }
3057 goto out_error;
3058 }
3059 }
3060 return done;
3061
3062 out_error:
Emeric Brun644cde02012-12-14 11:21:13 +01003063 /* Clear openssl global errors stack */
3064 ERR_clear_error();
3065
Emeric Brun46591952012-05-18 15:47:34 +02003066 conn->flags |= CO_FL_ERROR;
3067 return done;
3068}
3069
Emeric Brun46591952012-05-18 15:47:34 +02003070static void ssl_sock_close(struct connection *conn) {
3071
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02003072 if (conn->xprt_ctx) {
3073 SSL_free(conn->xprt_ctx);
3074 conn->xprt_ctx = NULL;
Willy Tarreau403edff2012-09-06 11:58:37 +02003075 sslconns--;
Emeric Brun46591952012-05-18 15:47:34 +02003076 }
Emeric Brun46591952012-05-18 15:47:34 +02003077}
3078
3079/* This function tries to perform a clean shutdown on an SSL connection, and in
3080 * any case, flags the connection as reusable if no handshake was in progress.
3081 */
3082static void ssl_sock_shutw(struct connection *conn, int clean)
3083{
3084 if (conn->flags & CO_FL_HANDSHAKE)
3085 return;
3086 /* no handshake was in progress, try a clean ssl shutdown */
Emeric Brun644cde02012-12-14 11:21:13 +01003087 if (clean && (SSL_shutdown(conn->xprt_ctx) <= 0)) {
3088 /* Clear openssl global errors stack */
3089 ERR_clear_error();
3090 }
Emeric Brun46591952012-05-18 15:47:34 +02003091
3092 /* force flag on ssl to keep session in cache regardless shutdown result */
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02003093 SSL_set_shutdown(conn->xprt_ctx, SSL_SENT_SHUTDOWN);
Emeric Brun46591952012-05-18 15:47:34 +02003094}
3095
Willy Tarreauffc3fcd2012-10-12 20:17:54 +02003096/* used for logging, may be changed for a sample fetch later */
3097const char *ssl_sock_get_cipher_name(struct connection *conn)
3098{
3099 if (!conn->xprt && !conn->xprt_ctx)
3100 return NULL;
3101 return SSL_get_cipher_name(conn->xprt_ctx);
3102}
3103
3104/* used for logging, may be changed for a sample fetch later */
3105const char *ssl_sock_get_proto_version(struct connection *conn)
3106{
3107 if (!conn->xprt && !conn->xprt_ctx)
3108 return NULL;
3109 return SSL_get_version(conn->xprt_ctx);
3110}
3111
Willy Tarreau8d598402012-10-22 17:58:39 +02003112/* Extract a serial from a cert, and copy it to a chunk.
3113 * Returns 1 if serial is found and copied, 0 if no serial found and
3114 * -1 if output is not large enough.
3115 */
3116static int
3117ssl_sock_get_serial(X509 *crt, struct chunk *out)
3118{
3119 ASN1_INTEGER *serial;
3120
3121 serial = X509_get_serialNumber(crt);
3122 if (!serial)
3123 return 0;
3124
3125 if (out->size < serial->length)
3126 return -1;
3127
3128 memcpy(out->str, serial->data, serial->length);
3129 out->len = serial->length;
3130 return 1;
3131}
3132
Emeric Brun43e79582014-10-29 19:03:26 +01003133/* Extract a cert to der, and copy it to a chunk.
3134 * Returns 1 if cert is found and copied, 0 on der convertion failure and
3135 * -1 if output is not large enough.
3136 */
3137static int
3138ssl_sock_crt2der(X509 *crt, struct chunk *out)
3139{
3140 int len;
3141 unsigned char *p = (unsigned char *)out->str;;
3142
3143 len =i2d_X509(crt, NULL);
3144 if (len <= 0)
3145 return 1;
3146
3147 if (out->size < len)
3148 return -1;
3149
3150 i2d_X509(crt,&p);
3151 out->len = len;
3152 return 1;
3153}
3154
Emeric Brunce5ad802012-10-22 14:11:22 +02003155
3156/* Copy Date in ASN1_UTCTIME format in struct chunk out.
3157 * Returns 1 if serial is found and copied, 0 if no valid time found
3158 * and -1 if output is not large enough.
3159 */
3160static int
3161ssl_sock_get_time(ASN1_TIME *tm, struct chunk *out)
3162{
3163 if (tm->type == V_ASN1_GENERALIZEDTIME) {
3164 ASN1_GENERALIZEDTIME *gentm = (ASN1_GENERALIZEDTIME *)tm;
3165
3166 if (gentm->length < 12)
3167 return 0;
3168 if (gentm->data[0] != 0x32 || gentm->data[1] != 0x30)
3169 return 0;
3170 if (out->size < gentm->length-2)
3171 return -1;
3172
3173 memcpy(out->str, gentm->data+2, gentm->length-2);
3174 out->len = gentm->length-2;
3175 return 1;
3176 }
3177 else if (tm->type == V_ASN1_UTCTIME) {
3178 ASN1_UTCTIME *utctm = (ASN1_UTCTIME *)tm;
3179
3180 if (utctm->length < 10)
3181 return 0;
3182 if (utctm->data[0] >= 0x35)
3183 return 0;
3184 if (out->size < utctm->length)
3185 return -1;
3186
3187 memcpy(out->str, utctm->data, utctm->length);
3188 out->len = utctm->length;
3189 return 1;
3190 }
3191
3192 return 0;
3193}
3194
Emeric Brun87855892012-10-17 17:39:35 +02003195/* Extract an entry from a X509_NAME and copy its value to an output chunk.
3196 * Returns 1 if entry found, 0 if entry not found, or -1 if output not large enough.
3197 */
3198static int
3199ssl_sock_get_dn_entry(X509_NAME *a, const struct chunk *entry, int pos, struct chunk *out)
3200{
3201 X509_NAME_ENTRY *ne;
3202 int i, j, n;
3203 int cur = 0;
3204 const char *s;
3205 char tmp[128];
3206
3207 out->len = 0;
3208 for (i = 0; i < sk_X509_NAME_ENTRY_num(a->entries); i++) {
3209 if (pos < 0)
3210 j = (sk_X509_NAME_ENTRY_num(a->entries)-1) - i;
3211 else
3212 j = i;
3213
3214 ne = sk_X509_NAME_ENTRY_value(a->entries, j);
3215 n = OBJ_obj2nid(ne->object);
3216 if ((n == NID_undef) || ((s = OBJ_nid2sn(n)) == NULL)) {
3217 i2t_ASN1_OBJECT(tmp, sizeof(tmp), ne->object);
3218 s = tmp;
3219 }
3220
3221 if (chunk_strcasecmp(entry, s) != 0)
3222 continue;
3223
3224 if (pos < 0)
3225 cur--;
3226 else
3227 cur++;
3228
3229 if (cur != pos)
3230 continue;
3231
3232 if (ne->value->length > out->size)
3233 return -1;
3234
3235 memcpy(out->str, ne->value->data, ne->value->length);
3236 out->len = ne->value->length;
3237 return 1;
3238 }
3239
3240 return 0;
3241
3242}
3243
3244/* Extract and format full DN from a X509_NAME and copy result into a chunk
3245 * Returns 1 if dn entries exits, 0 if no dn entry found or -1 if output is not large enough.
3246 */
3247static int
3248ssl_sock_get_dn_oneline(X509_NAME *a, struct chunk *out)
3249{
3250 X509_NAME_ENTRY *ne;
3251 int i, n, ln;
3252 int l = 0;
3253 const char *s;
3254 char *p;
3255 char tmp[128];
3256
3257 out->len = 0;
3258 p = out->str;
3259 for (i = 0; i < sk_X509_NAME_ENTRY_num(a->entries); i++) {
3260 ne = sk_X509_NAME_ENTRY_value(a->entries, i);
3261 n = OBJ_obj2nid(ne->object);
3262 if ((n == NID_undef) || ((s = OBJ_nid2sn(n)) == NULL)) {
3263 i2t_ASN1_OBJECT(tmp, sizeof(tmp), ne->object);
3264 s = tmp;
3265 }
3266 ln = strlen(s);
3267
3268 l += 1 + ln + 1 + ne->value->length;
3269 if (l > out->size)
3270 return -1;
3271 out->len = l;
3272
3273 *(p++)='/';
3274 memcpy(p, s, ln);
3275 p += ln;
3276 *(p++)='=';
3277 memcpy(p, ne->value->data, ne->value->length);
3278 p += ne->value->length;
3279 }
3280
3281 if (!out->len)
3282 return 0;
3283
3284 return 1;
3285}
3286
David Safb76832014-05-08 23:42:08 -04003287char *ssl_sock_get_version(struct connection *conn)
3288{
3289 if (!ssl_sock_is_ssl(conn))
3290 return NULL;
3291
3292 return (char *)SSL_get_version(conn->xprt_ctx);
3293}
3294
Willy Tarreau63076412015-07-10 11:33:32 +02003295void ssl_sock_set_servername(struct connection *conn, const char *hostname)
3296{
3297#ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME
3298 if (!ssl_sock_is_ssl(conn))
3299 return;
3300
3301 SSL_set_tlsext_host_name(conn->xprt_ctx, hostname);
3302#endif
3303}
3304
Emeric Brun0abf8362014-06-24 18:26:41 +02003305/* Extract peer certificate's common name into the chunk dest
3306 * Returns
3307 * the len of the extracted common name
3308 * or 0 if no CN found in DN
3309 * or -1 on error case (i.e. no peer certificate)
3310 */
3311int ssl_sock_get_remote_common_name(struct connection *conn, struct chunk *dest)
David Safb76832014-05-08 23:42:08 -04003312{
3313 X509 *crt = NULL;
3314 X509_NAME *name;
David Safb76832014-05-08 23:42:08 -04003315 const char find_cn[] = "CN";
3316 const struct chunk find_cn_chunk = {
3317 .str = (char *)&find_cn,
3318 .len = sizeof(find_cn)-1
3319 };
Emeric Brun0abf8362014-06-24 18:26:41 +02003320 int result = -1;
David Safb76832014-05-08 23:42:08 -04003321
3322 if (!ssl_sock_is_ssl(conn))
Emeric Brun0abf8362014-06-24 18:26:41 +02003323 goto out;
David Safb76832014-05-08 23:42:08 -04003324
3325 /* SSL_get_peer_certificate, it increase X509 * ref count */
3326 crt = SSL_get_peer_certificate(conn->xprt_ctx);
3327 if (!crt)
3328 goto out;
3329
3330 name = X509_get_subject_name(crt);
3331 if (!name)
3332 goto out;
David Safb76832014-05-08 23:42:08 -04003333
Emeric Brun0abf8362014-06-24 18:26:41 +02003334 result = ssl_sock_get_dn_entry(name, &find_cn_chunk, 1, dest);
3335out:
David Safb76832014-05-08 23:42:08 -04003336 if (crt)
3337 X509_free(crt);
3338
3339 return result;
3340}
3341
Dave McCowan328fb582014-07-30 10:39:13 -04003342/* returns 1 if client passed a certificate for this session, 0 if not */
3343int ssl_sock_get_cert_used_sess(struct connection *conn)
3344{
3345 X509 *crt = NULL;
3346
3347 if (!ssl_sock_is_ssl(conn))
3348 return 0;
3349
3350 /* SSL_get_peer_certificate, it increase X509 * ref count */
3351 crt = SSL_get_peer_certificate(conn->xprt_ctx);
3352 if (!crt)
3353 return 0;
3354
3355 X509_free(crt);
3356 return 1;
3357}
3358
3359/* returns 1 if client passed a certificate for this connection, 0 if not */
3360int ssl_sock_get_cert_used_conn(struct connection *conn)
David Safb76832014-05-08 23:42:08 -04003361{
3362 if (!ssl_sock_is_ssl(conn))
3363 return 0;
3364
3365 return SSL_SOCK_ST_FL_VERIFY_DONE & conn->xprt_st ? 1 : 0;
3366}
3367
3368/* returns result from SSL verify */
3369unsigned int ssl_sock_get_verify_result(struct connection *conn)
3370{
3371 if (!ssl_sock_is_ssl(conn))
3372 return (unsigned int)X509_V_ERR_APPLICATION_VERIFICATION;
3373
3374 return (unsigned int)SSL_get_verify_result(conn->xprt_ctx);
3375}
3376
Willy Tarreau7875d092012-09-10 08:20:03 +02003377/***** Below are some sample fetching functions for ACL/patterns *****/
3378
Emeric Brune64aef12012-09-21 13:15:06 +02003379/* boolean, returns true if client cert was present */
3380static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02003381smp_fetch_ssl_fc_has_crt(const struct arg *args, struct sample *smp, const char *kw, void *private)
Emeric Brune64aef12012-09-21 13:15:06 +02003382{
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003383 struct connection *conn;
3384
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02003385 conn = objt_conn(smp->sess->origin);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003386 if (!conn || conn->xprt != &ssl_sock)
Emeric Brune64aef12012-09-21 13:15:06 +02003387 return 0;
3388
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003389 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brune64aef12012-09-21 13:15:06 +02003390 smp->flags |= SMP_F_MAY_CHANGE;
3391 return 0;
3392 }
3393
3394 smp->flags = 0;
3395 smp->type = SMP_T_BOOL;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003396 smp->data.uint = SSL_SOCK_ST_FL_VERIFY_DONE & conn->xprt_st ? 1 : 0;
Emeric Brune64aef12012-09-21 13:15:06 +02003397
3398 return 1;
3399}
3400
Emeric Brun43e79582014-10-29 19:03:26 +01003401/* binary, returns a certificate in a binary chunk (der/raw).
3402 * The 5th keyword char is used to know if SSL_get_certificate or SSL_get_peer_certificate
3403 * should be use.
3404 */
3405static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02003406smp_fetch_ssl_x_der(const struct arg *args, struct sample *smp, const char *kw, void *private)
Emeric Brun43e79582014-10-29 19:03:26 +01003407{
3408 int cert_peer = (kw[4] == 'c') ? 1 : 0;
3409 X509 *crt = NULL;
3410 int ret = 0;
3411 struct chunk *smp_trash;
3412 struct connection *conn;
3413
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02003414 conn = objt_conn(smp->sess->origin);
Emeric Brun43e79582014-10-29 19:03:26 +01003415 if (!conn || conn->xprt != &ssl_sock)
3416 return 0;
3417
3418 if (!(conn->flags & CO_FL_CONNECTED)) {
3419 smp->flags |= SMP_F_MAY_CHANGE;
3420 return 0;
3421 }
3422
3423 if (cert_peer)
3424 crt = SSL_get_peer_certificate(conn->xprt_ctx);
3425 else
3426 crt = SSL_get_certificate(conn->xprt_ctx);
3427
3428 if (!crt)
3429 goto out;
3430
3431 smp_trash = get_trash_chunk();
3432 if (ssl_sock_crt2der(crt, smp_trash) <= 0)
3433 goto out;
3434
3435 smp->data.str = *smp_trash;
3436 smp->type = SMP_T_BIN;
3437 ret = 1;
3438out:
3439 /* SSL_get_peer_certificate, it increase X509 * ref count */
3440 if (cert_peer && crt)
3441 X509_free(crt);
3442 return ret;
3443}
3444
Emeric Brunba841a12014-04-30 17:05:08 +02003445/* binary, returns serial of certificate in a binary chunk.
3446 * The 5th keyword char is used to know if SSL_get_certificate or SSL_get_peer_certificate
3447 * should be use.
3448 */
Willy Tarreau8d598402012-10-22 17:58:39 +02003449static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02003450smp_fetch_ssl_x_serial(const struct arg *args, struct sample *smp, const char *kw, void *private)
Willy Tarreau8d598402012-10-22 17:58:39 +02003451{
Emeric Brunba841a12014-04-30 17:05:08 +02003452 int cert_peer = (kw[4] == 'c') ? 1 : 0;
Willy Tarreau8d598402012-10-22 17:58:39 +02003453 X509 *crt = NULL;
3454 int ret = 0;
3455 struct chunk *smp_trash;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003456 struct connection *conn;
3457
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02003458 conn = objt_conn(smp->sess->origin);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003459 if (!conn || conn->xprt != &ssl_sock)
Willy Tarreau8d598402012-10-22 17:58:39 +02003460 return 0;
3461
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003462 if (!(conn->flags & CO_FL_CONNECTED)) {
Willy Tarreau8d598402012-10-22 17:58:39 +02003463 smp->flags |= SMP_F_MAY_CHANGE;
3464 return 0;
3465 }
3466
Emeric Brunba841a12014-04-30 17:05:08 +02003467 if (cert_peer)
3468 crt = SSL_get_peer_certificate(conn->xprt_ctx);
3469 else
3470 crt = SSL_get_certificate(conn->xprt_ctx);
3471
Willy Tarreau8d598402012-10-22 17:58:39 +02003472 if (!crt)
3473 goto out;
3474
Willy Tarreau47ca5452012-12-23 20:22:19 +01003475 smp_trash = get_trash_chunk();
Willy Tarreau8d598402012-10-22 17:58:39 +02003476 if (ssl_sock_get_serial(crt, smp_trash) <= 0)
3477 goto out;
3478
3479 smp->data.str = *smp_trash;
3480 smp->type = SMP_T_BIN;
3481 ret = 1;
3482out:
Emeric Brunba841a12014-04-30 17:05:08 +02003483 /* SSL_get_peer_certificate, it increase X509 * ref count */
3484 if (cert_peer && crt)
Willy Tarreau8d598402012-10-22 17:58:39 +02003485 X509_free(crt);
3486 return ret;
3487}
Emeric Brune64aef12012-09-21 13:15:06 +02003488
Emeric Brunba841a12014-04-30 17:05:08 +02003489/* binary, returns the client certificate's SHA-1 fingerprint (SHA-1 hash of DER-encoded certificate) in a binary chunk.
3490 * The 5th keyword char is used to know if SSL_get_certificate or SSL_get_peer_certificate
3491 * should be use.
3492 */
James Votha051b4a2013-05-14 20:37:59 +02003493static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02003494smp_fetch_ssl_x_sha1(const struct arg *args, struct sample *smp, const char *kw, void *private)
James Votha051b4a2013-05-14 20:37:59 +02003495{
Emeric Brunba841a12014-04-30 17:05:08 +02003496 int cert_peer = (kw[4] == 'c') ? 1 : 0;
James Votha051b4a2013-05-14 20:37:59 +02003497 X509 *crt = NULL;
3498 const EVP_MD *digest;
3499 int ret = 0;
3500 struct chunk *smp_trash;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003501 struct connection *conn;
James Votha051b4a2013-05-14 20:37:59 +02003502
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02003503 conn = objt_conn(smp->sess->origin);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003504 if (!conn || conn->xprt != &ssl_sock)
3505 return 0;
3506
3507 if (!(conn->flags & CO_FL_CONNECTED)) {
James Votha051b4a2013-05-14 20:37:59 +02003508 smp->flags |= SMP_F_MAY_CHANGE;
3509 return 0;
3510 }
3511
Emeric Brunba841a12014-04-30 17:05:08 +02003512 if (cert_peer)
3513 crt = SSL_get_peer_certificate(conn->xprt_ctx);
3514 else
3515 crt = SSL_get_certificate(conn->xprt_ctx);
James Votha051b4a2013-05-14 20:37:59 +02003516 if (!crt)
3517 goto out;
3518
3519 smp_trash = get_trash_chunk();
3520 digest = EVP_sha1();
3521 X509_digest(crt, digest, (unsigned char *)smp_trash->str, (unsigned int *)&smp_trash->len);
3522
3523 smp->data.str = *smp_trash;
3524 smp->type = SMP_T_BIN;
3525 ret = 1;
3526out:
Emeric Brunba841a12014-04-30 17:05:08 +02003527 /* SSL_get_peer_certificate, it increase X509 * ref count */
3528 if (cert_peer && crt)
James Votha051b4a2013-05-14 20:37:59 +02003529 X509_free(crt);
3530 return ret;
3531}
3532
Emeric Brunba841a12014-04-30 17:05:08 +02003533/* string, returns certificate's notafter date in ASN1_UTCTIME format.
3534 * The 5th keyword char is used to know if SSL_get_certificate or SSL_get_peer_certificate
3535 * should be use.
3536 */
Emeric Brunce5ad802012-10-22 14:11:22 +02003537static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02003538smp_fetch_ssl_x_notafter(const struct arg *args, struct sample *smp, const char *kw, void *private)
Emeric Brunce5ad802012-10-22 14:11:22 +02003539{
Emeric Brunba841a12014-04-30 17:05:08 +02003540 int cert_peer = (kw[4] == 'c') ? 1 : 0;
Emeric Brunce5ad802012-10-22 14:11:22 +02003541 X509 *crt = NULL;
3542 int ret = 0;
3543 struct chunk *smp_trash;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003544 struct connection *conn;
Emeric Brunce5ad802012-10-22 14:11:22 +02003545
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02003546 conn = objt_conn(smp->sess->origin);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003547 if (!conn || conn->xprt != &ssl_sock)
3548 return 0;
3549
3550 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brunce5ad802012-10-22 14:11:22 +02003551 smp->flags |= SMP_F_MAY_CHANGE;
3552 return 0;
3553 }
3554
Emeric Brunba841a12014-04-30 17:05:08 +02003555 if (cert_peer)
3556 crt = SSL_get_peer_certificate(conn->xprt_ctx);
3557 else
3558 crt = SSL_get_certificate(conn->xprt_ctx);
Emeric Brunce5ad802012-10-22 14:11:22 +02003559 if (!crt)
3560 goto out;
3561
Willy Tarreau47ca5452012-12-23 20:22:19 +01003562 smp_trash = get_trash_chunk();
Emeric Brunce5ad802012-10-22 14:11:22 +02003563 if (ssl_sock_get_time(X509_get_notAfter(crt), smp_trash) <= 0)
3564 goto out;
3565
3566 smp->data.str = *smp_trash;
3567 smp->type = SMP_T_STR;
3568 ret = 1;
3569out:
Emeric Brunba841a12014-04-30 17:05:08 +02003570 /* SSL_get_peer_certificate, it increase X509 * ref count */
3571 if (cert_peer && crt)
Emeric Brunce5ad802012-10-22 14:11:22 +02003572 X509_free(crt);
3573 return ret;
3574}
3575
Emeric Brunba841a12014-04-30 17:05:08 +02003576/* string, returns a string of a formatted full dn \C=..\O=..\OU=.. \CN=.. of certificate's issuer
3577 * The 5th keyword char is used to know if SSL_get_certificate or SSL_get_peer_certificate
3578 * should be use.
3579 */
Emeric Brun87855892012-10-17 17:39:35 +02003580static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02003581smp_fetch_ssl_x_i_dn(const struct arg *args, struct sample *smp, const char *kw, void *private)
Emeric Brun87855892012-10-17 17:39:35 +02003582{
Emeric Brunba841a12014-04-30 17:05:08 +02003583 int cert_peer = (kw[4] == 'c') ? 1 : 0;
Emeric Brun87855892012-10-17 17:39:35 +02003584 X509 *crt = NULL;
3585 X509_NAME *name;
3586 int ret = 0;
3587 struct chunk *smp_trash;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003588 struct connection *conn;
Emeric Brun87855892012-10-17 17:39:35 +02003589
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02003590 conn = objt_conn(smp->sess->origin);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003591 if (!conn || conn->xprt != &ssl_sock)
3592 return 0;
3593
3594 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brun87855892012-10-17 17:39:35 +02003595 smp->flags |= SMP_F_MAY_CHANGE;
3596 return 0;
3597 }
3598
Emeric Brunba841a12014-04-30 17:05:08 +02003599 if (cert_peer)
3600 crt = SSL_get_peer_certificate(conn->xprt_ctx);
3601 else
3602 crt = SSL_get_certificate(conn->xprt_ctx);
Emeric Brun87855892012-10-17 17:39:35 +02003603 if (!crt)
3604 goto out;
3605
3606 name = X509_get_issuer_name(crt);
3607 if (!name)
3608 goto out;
3609
Willy Tarreau47ca5452012-12-23 20:22:19 +01003610 smp_trash = get_trash_chunk();
Emeric Brun87855892012-10-17 17:39:35 +02003611 if (args && args[0].type == ARGT_STR) {
3612 int pos = 1;
3613
3614 if (args[1].type == ARGT_SINT)
3615 pos = args[1].data.sint;
3616 else if (args[1].type == ARGT_UINT)
3617 pos =(int)args[1].data.uint;
3618
3619 if (ssl_sock_get_dn_entry(name, &args[0].data.str, pos, smp_trash) <= 0)
3620 goto out;
3621 }
3622 else if (ssl_sock_get_dn_oneline(name, smp_trash) <= 0)
3623 goto out;
3624
3625 smp->type = SMP_T_STR;
3626 smp->data.str = *smp_trash;
3627 ret = 1;
3628out:
Emeric Brunba841a12014-04-30 17:05:08 +02003629 /* SSL_get_peer_certificate, it increase X509 * ref count */
3630 if (cert_peer && crt)
Emeric Brun87855892012-10-17 17:39:35 +02003631 X509_free(crt);
3632 return ret;
3633}
3634
Emeric Brunba841a12014-04-30 17:05:08 +02003635/* string, returns notbefore date in ASN1_UTCTIME format.
3636 * The 5th keyword char is used to know if SSL_get_certificate or SSL_get_peer_certificate
3637 * should be use.
3638 */
Emeric Brunce5ad802012-10-22 14:11:22 +02003639static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02003640smp_fetch_ssl_x_notbefore(const struct arg *args, struct sample *smp, const char *kw, void *private)
Emeric Brunce5ad802012-10-22 14:11:22 +02003641{
Emeric Brunba841a12014-04-30 17:05:08 +02003642 int cert_peer = (kw[4] == 'c') ? 1 : 0;
Emeric Brunce5ad802012-10-22 14:11:22 +02003643 X509 *crt = NULL;
3644 int ret = 0;
3645 struct chunk *smp_trash;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003646 struct connection *conn;
3647
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02003648 conn = objt_conn(smp->sess->origin);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003649 if (!conn || conn->xprt != &ssl_sock)
Emeric Brunce5ad802012-10-22 14:11:22 +02003650 return 0;
3651
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003652 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brunce5ad802012-10-22 14:11:22 +02003653 smp->flags |= SMP_F_MAY_CHANGE;
3654 return 0;
3655 }
3656
Emeric Brunba841a12014-04-30 17:05:08 +02003657 if (cert_peer)
3658 crt = SSL_get_peer_certificate(conn->xprt_ctx);
3659 else
3660 crt = SSL_get_certificate(conn->xprt_ctx);
Emeric Brunce5ad802012-10-22 14:11:22 +02003661 if (!crt)
3662 goto out;
3663
Willy Tarreau47ca5452012-12-23 20:22:19 +01003664 smp_trash = get_trash_chunk();
Emeric Brunce5ad802012-10-22 14:11:22 +02003665 if (ssl_sock_get_time(X509_get_notBefore(crt), smp_trash) <= 0)
3666 goto out;
3667
3668 smp->data.str = *smp_trash;
3669 smp->type = SMP_T_STR;
3670 ret = 1;
3671out:
Emeric Brunba841a12014-04-30 17:05:08 +02003672 /* SSL_get_peer_certificate, it increase X509 * ref count */
3673 if (cert_peer && crt)
Emeric Brunce5ad802012-10-22 14:11:22 +02003674 X509_free(crt);
3675 return ret;
3676}
3677
Emeric Brunba841a12014-04-30 17:05:08 +02003678/* string, returns a string of a formatted full dn \C=..\O=..\OU=.. \CN=.. of certificate's subject
3679 * The 5th keyword char is used to know if SSL_get_certificate or SSL_get_peer_certificate
3680 * should be use.
3681 */
Emeric Brun87855892012-10-17 17:39:35 +02003682static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02003683smp_fetch_ssl_x_s_dn(const struct arg *args, struct sample *smp, const char *kw, void *private)
Emeric Brun87855892012-10-17 17:39:35 +02003684{
Emeric Brunba841a12014-04-30 17:05:08 +02003685 int cert_peer = (kw[4] == 'c') ? 1 : 0;
Emeric Brun87855892012-10-17 17:39:35 +02003686 X509 *crt = NULL;
3687 X509_NAME *name;
3688 int ret = 0;
3689 struct chunk *smp_trash;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003690 struct connection *conn;
Emeric Brun87855892012-10-17 17:39:35 +02003691
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02003692 conn = objt_conn(smp->sess->origin);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003693 if (!conn || conn->xprt != &ssl_sock)
3694 return 0;
3695
3696 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brun87855892012-10-17 17:39:35 +02003697 smp->flags |= SMP_F_MAY_CHANGE;
3698 return 0;
3699 }
3700
Emeric Brunba841a12014-04-30 17:05:08 +02003701 if (cert_peer)
3702 crt = SSL_get_peer_certificate(conn->xprt_ctx);
3703 else
3704 crt = SSL_get_certificate(conn->xprt_ctx);
Emeric Brun87855892012-10-17 17:39:35 +02003705 if (!crt)
3706 goto out;
3707
3708 name = X509_get_subject_name(crt);
3709 if (!name)
3710 goto out;
3711
Willy Tarreau47ca5452012-12-23 20:22:19 +01003712 smp_trash = get_trash_chunk();
Emeric Brun87855892012-10-17 17:39:35 +02003713 if (args && args[0].type == ARGT_STR) {
3714 int pos = 1;
3715
3716 if (args[1].type == ARGT_SINT)
3717 pos = args[1].data.sint;
3718 else if (args[1].type == ARGT_UINT)
3719 pos =(int)args[1].data.uint;
3720
3721 if (ssl_sock_get_dn_entry(name, &args[0].data.str, pos, smp_trash) <= 0)
3722 goto out;
3723 }
3724 else if (ssl_sock_get_dn_oneline(name, smp_trash) <= 0)
3725 goto out;
3726
3727 smp->type = SMP_T_STR;
3728 smp->data.str = *smp_trash;
3729 ret = 1;
3730out:
Emeric Brunba841a12014-04-30 17:05:08 +02003731 /* SSL_get_peer_certificate, it increase X509 * ref count */
3732 if (cert_peer && crt)
Emeric Brun87855892012-10-17 17:39:35 +02003733 X509_free(crt);
3734 return ret;
3735}
Emeric Brun9143d372012-12-20 15:44:16 +01003736
3737/* integer, returns true if current session use a client certificate */
3738static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02003739smp_fetch_ssl_c_used(const struct arg *args, struct sample *smp, const char *kw, void *private)
Emeric Brun9143d372012-12-20 15:44:16 +01003740{
3741 X509 *crt;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003742 struct connection *conn;
Emeric Brun9143d372012-12-20 15:44:16 +01003743
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02003744 conn = objt_conn(smp->sess->origin);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003745 if (!conn || conn->xprt != &ssl_sock)
3746 return 0;
3747
3748 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brun9143d372012-12-20 15:44:16 +01003749 smp->flags |= SMP_F_MAY_CHANGE;
3750 return 0;
3751 }
3752
3753 /* SSL_get_peer_certificate returns a ptr on allocated X509 struct */
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003754 crt = SSL_get_peer_certificate(conn->xprt_ctx);
Emeric Brun9143d372012-12-20 15:44:16 +01003755 if (crt) {
3756 X509_free(crt);
3757 }
3758
3759 smp->type = SMP_T_BOOL;
3760 smp->data.uint = (crt != NULL);
3761 return 1;
3762}
3763
Emeric Brunba841a12014-04-30 17:05:08 +02003764/* integer, returns the certificate version
3765 * The 5th keyword char is used to know if SSL_get_certificate or SSL_get_peer_certificate
3766 * should be use.
3767 */
Emeric Bruna7359fd2012-10-17 15:03:11 +02003768static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02003769smp_fetch_ssl_x_version(const struct arg *args, struct sample *smp, const char *kw, void *private)
Emeric Bruna7359fd2012-10-17 15:03:11 +02003770{
Emeric Brunba841a12014-04-30 17:05:08 +02003771 int cert_peer = (kw[4] == 'c') ? 1 : 0;
Emeric Bruna7359fd2012-10-17 15:03:11 +02003772 X509 *crt;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003773 struct connection *conn;
3774
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02003775 conn = objt_conn(smp->sess->origin);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003776 if (!conn || conn->xprt != &ssl_sock)
Emeric Bruna7359fd2012-10-17 15:03:11 +02003777 return 0;
3778
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003779 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Bruna7359fd2012-10-17 15:03:11 +02003780 smp->flags |= SMP_F_MAY_CHANGE;
3781 return 0;
3782 }
3783
Emeric Brunba841a12014-04-30 17:05:08 +02003784 if (cert_peer)
3785 crt = SSL_get_peer_certificate(conn->xprt_ctx);
3786 else
3787 crt = SSL_get_certificate(conn->xprt_ctx);
Emeric Bruna7359fd2012-10-17 15:03:11 +02003788 if (!crt)
3789 return 0;
3790
3791 smp->data.uint = (unsigned int)(1 + X509_get_version(crt));
Emeric Brunba841a12014-04-30 17:05:08 +02003792 /* SSL_get_peer_certificate increase X509 * ref count */
3793 if (cert_peer)
3794 X509_free(crt);
Emeric Bruna7359fd2012-10-17 15:03:11 +02003795 smp->type = SMP_T_UINT;
3796
3797 return 1;
3798}
3799
Emeric Brunba841a12014-04-30 17:05:08 +02003800/* string, returns the certificate's signature algorithm.
3801 * The 5th keyword char is used to know if SSL_get_certificate or SSL_get_peer_certificate
3802 * should be use.
3803 */
Emeric Brun7f56e742012-10-19 18:15:40 +02003804static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02003805smp_fetch_ssl_x_sig_alg(const struct arg *args, struct sample *smp, const char *kw, void *private)
Emeric Brun7f56e742012-10-19 18:15:40 +02003806{
Emeric Brunba841a12014-04-30 17:05:08 +02003807 int cert_peer = (kw[4] == 'c') ? 1 : 0;
Emeric Brun7f56e742012-10-19 18:15:40 +02003808 X509 *crt;
3809 int nid;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003810 struct connection *conn;
Emeric Brun7f56e742012-10-19 18:15:40 +02003811
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02003812 conn = objt_conn(smp->sess->origin);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003813 if (!conn || conn->xprt != &ssl_sock)
3814 return 0;
3815
3816 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brun7f56e742012-10-19 18:15:40 +02003817 smp->flags |= SMP_F_MAY_CHANGE;
3818 return 0;
3819 }
3820
Emeric Brunba841a12014-04-30 17:05:08 +02003821 if (cert_peer)
3822 crt = SSL_get_peer_certificate(conn->xprt_ctx);
3823 else
3824 crt = SSL_get_certificate(conn->xprt_ctx);
Emeric Brun7f56e742012-10-19 18:15:40 +02003825 if (!crt)
3826 return 0;
3827
3828 nid = OBJ_obj2nid((ASN1_OBJECT *)(crt->cert_info->signature->algorithm));
3829
3830 smp->data.str.str = (char *)OBJ_nid2sn(nid);
Emeric Brun9bf3ba22013-10-07 14:31:44 +02003831 if (!smp->data.str.str) {
Emeric Brunba841a12014-04-30 17:05:08 +02003832 /* SSL_get_peer_certificate increase X509 * ref count */
3833 if (cert_peer)
3834 X509_free(crt);
Emeric Brun7f56e742012-10-19 18:15:40 +02003835 return 0;
Emeric Brun9bf3ba22013-10-07 14:31:44 +02003836 }
Emeric Brun7f56e742012-10-19 18:15:40 +02003837
Thierry FOURNIER7654c9f2013-12-17 00:20:33 +01003838 smp->type = SMP_T_STR;
3839 smp->flags |= SMP_F_CONST;
Emeric Brun7f56e742012-10-19 18:15:40 +02003840 smp->data.str.len = strlen(smp->data.str.str);
Emeric Brunba841a12014-04-30 17:05:08 +02003841 /* SSL_get_peer_certificate increase X509 * ref count */
3842 if (cert_peer)
3843 X509_free(crt);
Emeric Brun7f56e742012-10-19 18:15:40 +02003844
3845 return 1;
3846}
3847
Emeric Brunba841a12014-04-30 17:05:08 +02003848/* string, returns the certificate's key algorithm.
3849 * The 5th keyword char is used to know if SSL_get_certificate or SSL_get_peer_certificate
3850 * should be use.
3851 */
Emeric Brun521a0112012-10-22 12:22:55 +02003852static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02003853smp_fetch_ssl_x_key_alg(const struct arg *args, struct sample *smp, const char *kw, void *private)
Emeric Brun521a0112012-10-22 12:22:55 +02003854{
Emeric Brunba841a12014-04-30 17:05:08 +02003855 int cert_peer = (kw[4] == 'c') ? 1 : 0;
Emeric Brun521a0112012-10-22 12:22:55 +02003856 X509 *crt;
3857 int nid;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003858 struct connection *conn;
Emeric Brun521a0112012-10-22 12:22:55 +02003859
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02003860 conn = objt_conn(smp->sess->origin);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003861 if (!conn || conn->xprt != &ssl_sock)
3862 return 0;
3863
3864 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brun521a0112012-10-22 12:22:55 +02003865 smp->flags |= SMP_F_MAY_CHANGE;
3866 return 0;
3867 }
3868
Emeric Brunba841a12014-04-30 17:05:08 +02003869 if (cert_peer)
3870 crt = SSL_get_peer_certificate(conn->xprt_ctx);
3871 else
3872 crt = SSL_get_certificate(conn->xprt_ctx);
Emeric Brun521a0112012-10-22 12:22:55 +02003873 if (!crt)
3874 return 0;
3875
3876 nid = OBJ_obj2nid((ASN1_OBJECT *)(crt->cert_info->key->algor->algorithm));
3877
3878 smp->data.str.str = (char *)OBJ_nid2sn(nid);
Emeric Brun9bf3ba22013-10-07 14:31:44 +02003879 if (!smp->data.str.str) {
Emeric Brunba841a12014-04-30 17:05:08 +02003880 /* SSL_get_peer_certificate increase X509 * ref count */
3881 if (cert_peer)
3882 X509_free(crt);
Emeric Brun521a0112012-10-22 12:22:55 +02003883 return 0;
Emeric Brun9bf3ba22013-10-07 14:31:44 +02003884 }
Emeric Brun521a0112012-10-22 12:22:55 +02003885
Thierry FOURNIER7654c9f2013-12-17 00:20:33 +01003886 smp->type = SMP_T_STR;
3887 smp->flags |= SMP_F_CONST;
Emeric Brun521a0112012-10-22 12:22:55 +02003888 smp->data.str.len = strlen(smp->data.str.str);
Emeric Brunba841a12014-04-30 17:05:08 +02003889 if (cert_peer)
3890 X509_free(crt);
Emeric Brun521a0112012-10-22 12:22:55 +02003891
3892 return 1;
3893}
3894
Emeric Brun645ae792014-04-30 14:21:06 +02003895/* boolean, returns true if front conn. transport layer is SSL.
3896 * This function is also usable on backend conn if the fetch keyword 5th
3897 * char is 'b'.
3898 */
Willy Tarreau7875d092012-09-10 08:20:03 +02003899static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02003900smp_fetch_ssl_fc(const struct arg *args, struct sample *smp, const char *kw, void *private)
Willy Tarreau7875d092012-09-10 08:20:03 +02003901{
Emeric Brun645ae792014-04-30 14:21:06 +02003902 int back_conn = (kw[4] == 'b') ? 1 : 0;
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02003903 struct connection *conn = objt_conn(smp->strm->si[back_conn].end);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003904
Willy Tarreau7875d092012-09-10 08:20:03 +02003905 smp->type = SMP_T_BOOL;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003906 smp->data.uint = (conn && conn->xprt == &ssl_sock);
Willy Tarreau7875d092012-09-10 08:20:03 +02003907 return 1;
3908}
3909
Emeric Brun2525b6b2012-10-18 15:59:43 +02003910/* boolean, returns true if client present a SNI */
Willy Tarreau7875d092012-09-10 08:20:03 +02003911static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02003912smp_fetch_ssl_fc_has_sni(const struct arg *args, struct sample *smp, const char *kw, void *private)
Willy Tarreau7875d092012-09-10 08:20:03 +02003913{
3914#ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02003915 struct connection *conn = objt_conn(smp->sess->origin);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003916
Willy Tarreau7875d092012-09-10 08:20:03 +02003917 smp->type = SMP_T_BOOL;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003918 smp->data.uint = (conn && conn->xprt == &ssl_sock) &&
3919 conn->xprt_ctx &&
3920 SSL_get_servername(conn->xprt_ctx, TLSEXT_NAMETYPE_host_name) != NULL;
Willy Tarreau7875d092012-09-10 08:20:03 +02003921 return 1;
3922#else
3923 return 0;
3924#endif
3925}
3926
Nenad Merdanovic26ea8222015-05-18 02:28:57 +02003927/* boolean, returns true if client session has been resumed */
3928static int
3929smp_fetch_ssl_fc_is_resumed(const struct arg *args, struct sample *smp, const char *kw, void *private)
3930{
3931 struct connection *conn = objt_conn(smp->sess->origin);
3932
3933 smp->type = SMP_T_BOOL;
3934 smp->data.uint = (conn && conn->xprt == &ssl_sock) &&
3935 conn->xprt_ctx &&
3936 SSL_session_reused(conn->xprt_ctx);
3937 return 1;
3938}
3939
Emeric Brun645ae792014-04-30 14:21:06 +02003940/* string, returns the used cipher if front conn. transport layer is SSL.
3941 * This function is also usable on backend conn if the fetch keyword 5th
3942 * char is 'b'.
3943 */
Emeric Brun589fcad2012-10-16 14:13:26 +02003944static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02003945smp_fetch_ssl_fc_cipher(const struct arg *args, struct sample *smp, const char *kw, void *private)
Emeric Brun589fcad2012-10-16 14:13:26 +02003946{
Emeric Brun645ae792014-04-30 14:21:06 +02003947 int back_conn = (kw[4] == 'b') ? 1 : 0;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003948 struct connection *conn;
3949
Emeric Brun589fcad2012-10-16 14:13:26 +02003950 smp->flags = 0;
3951
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02003952 conn = objt_conn(smp->strm->si[back_conn].end);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003953 if (!conn || !conn->xprt_ctx || conn->xprt != &ssl_sock)
Emeric Brun589fcad2012-10-16 14:13:26 +02003954 return 0;
3955
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003956 smp->data.str.str = (char *)SSL_get_cipher_name(conn->xprt_ctx);
Emeric Brun589fcad2012-10-16 14:13:26 +02003957 if (!smp->data.str.str)
3958 return 0;
3959
Thierry FOURNIER7654c9f2013-12-17 00:20:33 +01003960 smp->type = SMP_T_STR;
3961 smp->flags |= SMP_F_CONST;
Emeric Brun589fcad2012-10-16 14:13:26 +02003962 smp->data.str.len = strlen(smp->data.str.str);
3963
3964 return 1;
3965}
3966
Emeric Brun645ae792014-04-30 14:21:06 +02003967/* integer, returns the algoritm's keysize if front conn. transport layer
3968 * is SSL.
3969 * This function is also usable on backend conn if the fetch keyword 5th
3970 * char is 'b'.
3971 */
Emeric Brun589fcad2012-10-16 14:13:26 +02003972static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02003973smp_fetch_ssl_fc_alg_keysize(const struct arg *args, struct sample *smp, const char *kw, void *private)
Emeric Brun589fcad2012-10-16 14:13:26 +02003974{
Emeric Brun645ae792014-04-30 14:21:06 +02003975 int back_conn = (kw[4] == 'b') ? 1 : 0;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003976 struct connection *conn;
3977
Emeric Brun589fcad2012-10-16 14:13:26 +02003978 smp->flags = 0;
3979
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02003980 conn = objt_conn(smp->strm->si[back_conn].end);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003981 if (!conn || !conn->xprt_ctx || conn->xprt != &ssl_sock)
Emeric Brun589fcad2012-10-16 14:13:26 +02003982 return 0;
3983
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003984 if (!SSL_get_cipher_bits(conn->xprt_ctx, (int *)&smp->data.uint))
3985 return 0;
3986
Emeric Brun589fcad2012-10-16 14:13:26 +02003987 smp->type = SMP_T_UINT;
3988
3989 return 1;
3990}
3991
Emeric Brun645ae792014-04-30 14:21:06 +02003992/* integer, returns the used keysize if front conn. transport layer is SSL.
3993 * This function is also usable on backend conn if the fetch keyword 5th
3994 * char is 'b'.
3995 */
Emeric Brun589fcad2012-10-16 14:13:26 +02003996static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02003997smp_fetch_ssl_fc_use_keysize(const struct arg *args, struct sample *smp, const char *kw, void *private)
Emeric Brun589fcad2012-10-16 14:13:26 +02003998{
Emeric Brun645ae792014-04-30 14:21:06 +02003999 int back_conn = (kw[4] == 'b') ? 1 : 0;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004000 struct connection *conn;
4001
Emeric Brun589fcad2012-10-16 14:13:26 +02004002 smp->flags = 0;
4003
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02004004 conn = objt_conn(smp->strm->si[back_conn].end);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004005 if (!conn || !conn->xprt_ctx || conn->xprt != &ssl_sock)
4006 return 0;
4007
4008 smp->data.uint = (unsigned int)SSL_get_cipher_bits(conn->xprt_ctx, NULL);
Emeric Brun589fcad2012-10-16 14:13:26 +02004009 if (!smp->data.uint)
4010 return 0;
4011
4012 smp->type = SMP_T_UINT;
4013
4014 return 1;
4015}
4016
Willy Tarreau6c9a3d52012-10-18 18:57:14 +02004017#ifdef OPENSSL_NPN_NEGOTIATED
Willy Tarreau7875d092012-09-10 08:20:03 +02004018static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02004019smp_fetch_ssl_fc_npn(const struct arg *args, struct sample *smp, const char *kw, void *private)
Willy Tarreaua33c6542012-10-15 13:19:06 +02004020{
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004021 struct connection *conn;
4022
Thierry FOURNIER7654c9f2013-12-17 00:20:33 +01004023 smp->flags = SMP_F_CONST;
4024 smp->type = SMP_T_STR;
Willy Tarreaua33c6542012-10-15 13:19:06 +02004025
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02004026 conn = objt_conn(smp->sess->origin);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004027 if (!conn || !conn->xprt_ctx || conn->xprt != &ssl_sock)
4028 return 0;
4029
Willy Tarreaua33c6542012-10-15 13:19:06 +02004030 smp->data.str.str = NULL;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004031 SSL_get0_next_proto_negotiated(conn->xprt_ctx,
Willy Tarreaua33c6542012-10-15 13:19:06 +02004032 (const unsigned char **)&smp->data.str.str, (unsigned *)&smp->data.str.len);
4033
4034 if (!smp->data.str.str)
4035 return 0;
4036
4037 return 1;
Willy Tarreaua33c6542012-10-15 13:19:06 +02004038}
Willy Tarreau6c9a3d52012-10-18 18:57:14 +02004039#endif
Willy Tarreaua33c6542012-10-15 13:19:06 +02004040
Dirkjan Bussink48f1c4e2014-02-13 12:29:42 +01004041#ifdef TLSEXT_TYPE_application_layer_protocol_negotiation
Willy Tarreauab861d32013-04-02 02:30:41 +02004042static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02004043smp_fetch_ssl_fc_alpn(const struct arg *args, struct sample *smp, const char *kw, void *private)
Willy Tarreauab861d32013-04-02 02:30:41 +02004044{
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004045 struct connection *conn;
4046
Thierry FOURNIER7654c9f2013-12-17 00:20:33 +01004047 smp->flags = SMP_F_CONST;
4048 smp->type = SMP_T_STR;
Willy Tarreauab861d32013-04-02 02:30:41 +02004049
Willy Tarreaue26bf052015-05-12 10:30:12 +02004050 conn = objt_conn(smp->sess->origin);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004051 if (!conn || !conn->xprt_ctx || conn->xprt != &ssl_sock)
Willy Tarreauab861d32013-04-02 02:30:41 +02004052 return 0;
4053
4054 smp->data.str.str = NULL;
Dirkjan Bussink48f1c4e2014-02-13 12:29:42 +01004055 SSL_get0_alpn_selected(conn->xprt_ctx,
Willy Tarreauab861d32013-04-02 02:30:41 +02004056 (const unsigned char **)&smp->data.str.str, (unsigned *)&smp->data.str.len);
4057
4058 if (!smp->data.str.str)
4059 return 0;
4060
4061 return 1;
4062}
4063#endif
4064
Emeric Brun645ae792014-04-30 14:21:06 +02004065/* string, returns the used protocol if front conn. transport layer is SSL.
4066 * This function is also usable on backend conn if the fetch keyword 5th
4067 * char is 'b'.
4068 */
Willy Tarreaua33c6542012-10-15 13:19:06 +02004069static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02004070smp_fetch_ssl_fc_protocol(const struct arg *args, struct sample *smp, const char *kw, void *private)
Emeric Brun589fcad2012-10-16 14:13:26 +02004071{
Emeric Brun645ae792014-04-30 14:21:06 +02004072 int back_conn = (kw[4] == 'b') ? 1 : 0;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004073 struct connection *conn;
4074
Emeric Brun589fcad2012-10-16 14:13:26 +02004075 smp->flags = 0;
4076
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02004077 conn = objt_conn(smp->strm->si[back_conn].end);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004078 if (!conn || !conn->xprt_ctx || conn->xprt != &ssl_sock)
4079 return 0;
4080
4081 smp->data.str.str = (char *)SSL_get_version(conn->xprt_ctx);
Emeric Brun589fcad2012-10-16 14:13:26 +02004082 if (!smp->data.str.str)
4083 return 0;
4084
Thierry FOURNIER7654c9f2013-12-17 00:20:33 +01004085 smp->type = SMP_T_STR;
4086 smp->flags = SMP_F_CONST;
Emeric Brun589fcad2012-10-16 14:13:26 +02004087 smp->data.str.len = strlen(smp->data.str.str);
4088
4089 return 1;
4090}
4091
Willy Tarreau87b09662015-04-03 00:22:06 +02004092/* binary, returns the SSL stream id if front conn. transport layer is SSL.
Emeric Brun645ae792014-04-30 14:21:06 +02004093 * This function is also usable on backend conn if the fetch keyword 5th
4094 * char is 'b'.
4095 */
Emeric Brun589fcad2012-10-16 14:13:26 +02004096static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02004097smp_fetch_ssl_fc_session_id(const struct arg *args, struct sample *smp, const char *kw, void *private)
Emeric Brunfe68f682012-10-16 14:59:28 +02004098{
4099#if OPENSSL_VERSION_NUMBER > 0x0090800fL
Emeric Brun645ae792014-04-30 14:21:06 +02004100 int back_conn = (kw[4] == 'b') ? 1 : 0;
Willy Tarreau192252e2015-04-04 01:47:55 +02004101 SSL_SESSION *ssl_sess;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004102 struct connection *conn;
Emeric Brunfe68f682012-10-16 14:59:28 +02004103
Thierry FOURNIER7654c9f2013-12-17 00:20:33 +01004104 smp->flags = SMP_F_CONST;
4105 smp->type = SMP_T_BIN;
Emeric Brunfe68f682012-10-16 14:59:28 +02004106
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02004107 conn = objt_conn(smp->strm->si[back_conn].end);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004108 if (!conn || !conn->xprt_ctx || conn->xprt != &ssl_sock)
4109 return 0;
4110
Willy Tarreau192252e2015-04-04 01:47:55 +02004111 ssl_sess = SSL_get_session(conn->xprt_ctx);
4112 if (!ssl_sess)
Emeric Brunfe68f682012-10-16 14:59:28 +02004113 return 0;
4114
Willy Tarreau192252e2015-04-04 01:47:55 +02004115 smp->data.str.str = (char *)SSL_SESSION_get_id(ssl_sess, (unsigned int *)&smp->data.str.len);
Willy Tarreau745d4122015-06-17 18:34:14 +02004116 if (!smp->data.str.str || !smp->data.str.len)
Emeric Brunfe68f682012-10-16 14:59:28 +02004117 return 0;
4118
4119 return 1;
4120#else
4121 return 0;
4122#endif
4123}
4124
4125static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02004126smp_fetch_ssl_fc_sni(const struct arg *args, struct sample *smp, const char *kw, void *private)
Willy Tarreau7875d092012-09-10 08:20:03 +02004127{
4128#ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004129 struct connection *conn;
4130
Thierry FOURNIER7654c9f2013-12-17 00:20:33 +01004131 smp->flags = SMP_F_CONST;
4132 smp->type = SMP_T_STR;
Willy Tarreau7875d092012-09-10 08:20:03 +02004133
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02004134 conn = objt_conn(smp->sess->origin);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004135 if (!conn || !conn->xprt_ctx || conn->xprt != &ssl_sock)
4136 return 0;
4137
4138 smp->data.str.str = (char *)SSL_get_servername(conn->xprt_ctx, TLSEXT_NAMETYPE_host_name);
Willy Tarreau3e394c92012-09-14 23:56:58 +02004139 if (!smp->data.str.str)
4140 return 0;
4141
Willy Tarreau7875d092012-09-10 08:20:03 +02004142 smp->data.str.len = strlen(smp->data.str.str);
4143 return 1;
4144#else
4145 return 0;
4146#endif
4147}
4148
David Sc1ad52e2014-04-08 18:48:47 -04004149static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02004150smp_fetch_ssl_fc_unique_id(const struct arg *args, struct sample *smp, const char *kw, void *private)
David Sc1ad52e2014-04-08 18:48:47 -04004151{
4152#if OPENSSL_VERSION_NUMBER > 0x0090800fL
Emeric Brun645ae792014-04-30 14:21:06 +02004153 int back_conn = (kw[4] == 'b') ? 1 : 0;
David Sc1ad52e2014-04-08 18:48:47 -04004154 struct connection *conn;
4155 int finished_len;
David Sc1ad52e2014-04-08 18:48:47 -04004156 struct chunk *finished_trash;
David Sc1ad52e2014-04-08 18:48:47 -04004157
4158 smp->flags = 0;
4159
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02004160 conn = objt_conn(smp->strm->si[back_conn].end);
David Sc1ad52e2014-04-08 18:48:47 -04004161 if (!conn || !conn->xprt_ctx || conn->xprt != &ssl_sock)
4162 return 0;
4163
4164 if (!(conn->flags & CO_FL_CONNECTED)) {
4165 smp->flags |= SMP_F_MAY_CHANGE;
4166 return 0;
4167 }
4168
4169 finished_trash = get_trash_chunk();
4170 if (!SSL_session_reused(conn->xprt_ctx))
4171 finished_len = SSL_get_peer_finished(conn->xprt_ctx, finished_trash->str, finished_trash->size);
4172 else
4173 finished_len = SSL_get_finished(conn->xprt_ctx, finished_trash->str, finished_trash->size);
4174
4175 if (!finished_len)
4176 return 0;
4177
Emeric Brunb73a9b02014-04-30 18:49:19 +02004178 finished_trash->len = finished_len;
4179 smp->data.str = *finished_trash;
4180 smp->type = SMP_T_BIN;
David Sc1ad52e2014-04-08 18:48:47 -04004181
4182 return 1;
4183#else
4184 return 0;
4185#endif
4186}
4187
Emeric Brun2525b6b2012-10-18 15:59:43 +02004188/* integer, returns the first verify error in CA chain of client certificate chain. */
Emeric Brunf282a812012-09-21 15:27:54 +02004189static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02004190smp_fetch_ssl_c_ca_err(const struct arg *args, struct sample *smp, const char *kw, void *private)
Emeric Brunf282a812012-09-21 15:27:54 +02004191{
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004192 struct connection *conn;
4193
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02004194 conn = objt_conn(smp->sess->origin);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004195 if (!conn || conn->xprt != &ssl_sock)
4196 return 0;
4197
4198 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brunf282a812012-09-21 15:27:54 +02004199 smp->flags = SMP_F_MAY_CHANGE;
4200 return 0;
4201 }
4202
4203 smp->type = SMP_T_UINT;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004204 smp->data.uint = (unsigned int)SSL_SOCK_ST_TO_CA_ERROR(conn->xprt_st);
Emeric Brunf282a812012-09-21 15:27:54 +02004205 smp->flags = 0;
4206
4207 return 1;
4208}
4209
Emeric Brun2525b6b2012-10-18 15:59:43 +02004210/* integer, returns the depth of the first verify error in CA chain of client certificate chain. */
Emeric Brunf282a812012-09-21 15:27:54 +02004211static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02004212smp_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 +02004213{
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004214 struct connection *conn;
4215
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02004216 conn = objt_conn(smp->sess->origin);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004217 if (!conn || conn->xprt != &ssl_sock)
Emeric Brunf282a812012-09-21 15:27:54 +02004218 return 0;
4219
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004220 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brunf282a812012-09-21 15:27:54 +02004221 smp->flags = SMP_F_MAY_CHANGE;
4222 return 0;
4223 }
4224
4225 smp->type = SMP_T_UINT;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004226 smp->data.uint = (unsigned int)SSL_SOCK_ST_TO_CAEDEPTH(conn->xprt_st);
Emeric Brunf282a812012-09-21 15:27:54 +02004227 smp->flags = 0;
4228
4229 return 1;
4230}
4231
Emeric Brun2525b6b2012-10-18 15:59:43 +02004232/* integer, returns the first verify error on client certificate */
Emeric Brunf282a812012-09-21 15:27:54 +02004233static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02004234smp_fetch_ssl_c_err(const struct arg *args, struct sample *smp, const char *kw, void *private)
Emeric Brunf282a812012-09-21 15:27:54 +02004235{
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004236 struct connection *conn;
4237
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02004238 conn = objt_conn(smp->sess->origin);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004239 if (!conn || conn->xprt != &ssl_sock)
4240 return 0;
4241
4242 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brunf282a812012-09-21 15:27:54 +02004243 smp->flags = SMP_F_MAY_CHANGE;
4244 return 0;
4245 }
4246
4247 smp->type = SMP_T_UINT;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004248 smp->data.uint = (unsigned int)SSL_SOCK_ST_TO_CRTERROR(conn->xprt_st);
Emeric Brunf282a812012-09-21 15:27:54 +02004249 smp->flags = 0;
4250
4251 return 1;
4252}
4253
Emeric Brun2525b6b2012-10-18 15:59:43 +02004254/* integer, returns the verify result on client cert */
Emeric Brunbaf8ffb2012-09-21 15:27:20 +02004255static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02004256smp_fetch_ssl_c_verify(const struct arg *args, struct sample *smp, const char *kw, void *private)
Emeric Brunbaf8ffb2012-09-21 15:27:20 +02004257{
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004258 struct connection *conn;
4259
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02004260 conn = objt_conn(smp->sess->origin);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004261 if (!conn || conn->xprt != &ssl_sock)
4262 return 0;
4263
4264 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brunbaf8ffb2012-09-21 15:27:20 +02004265 smp->flags = SMP_F_MAY_CHANGE;
4266 return 0;
4267 }
4268
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004269 if (!conn->xprt_ctx)
Emeric Brunbaf8ffb2012-09-21 15:27:20 +02004270 return 0;
4271
4272 smp->type = SMP_T_UINT;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004273 smp->data.uint = (unsigned int)SSL_get_verify_result(conn->xprt_ctx);
Emeric Brunbaf8ffb2012-09-21 15:27:20 +02004274 smp->flags = 0;
4275
4276 return 1;
4277}
4278
Emeric Brunfb510ea2012-10-05 12:00:26 +02004279/* parse the "ca-file" bind keyword */
4280static 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 +02004281{
4282 if (!*args[cur_arg + 1]) {
4283 if (err)
4284 memprintf(err, "'%s' : missing CAfile path", args[cur_arg]);
4285 return ERR_ALERT | ERR_FATAL;
4286 }
4287
Emeric Brunef42d922012-10-11 16:11:36 +02004288 if ((*args[cur_arg + 1] != '/') && global.ca_base)
4289 memprintf(&conf->ca_file, "%s/%s", global.ca_base, args[cur_arg + 1]);
4290 else
4291 memprintf(&conf->ca_file, "%s", args[cur_arg + 1]);
Emeric Brunc8e8d122012-10-02 18:42:10 +02004292
Emeric Brund94b3fe2012-09-20 18:23:56 +02004293 return 0;
4294}
4295
Christopher Faulet31af49d2015-06-09 17:29:50 +02004296/* parse the "ca-sign-file" bind keyword */
4297static int bind_parse_ca_sign_file(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
4298{
4299 if (!*args[cur_arg + 1]) {
4300 if (err)
4301 memprintf(err, "'%s' : missing CAfile path", args[cur_arg]);
4302 return ERR_ALERT | ERR_FATAL;
4303 }
4304
4305 if ((*args[cur_arg + 1] != '/') && global.ca_base)
4306 memprintf(&conf->ca_sign_file, "%s/%s", global.ca_base, args[cur_arg + 1]);
4307 else
4308 memprintf(&conf->ca_sign_file, "%s", args[cur_arg + 1]);
4309
4310 return 0;
4311}
4312
4313/* parse the ca-sign-pass bind keyword */
4314
4315static int bind_parse_ca_sign_pass(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
4316{
4317 if (!*args[cur_arg + 1]) {
4318 if (err)
4319 memprintf(err, "'%s' : missing CAkey password", args[cur_arg]);
4320 return ERR_ALERT | ERR_FATAL;
4321 }
4322 memprintf(&conf->ca_sign_pass, "%s", args[cur_arg + 1]);
4323 return 0;
4324}
4325
Willy Tarreau79eeafa2012-09-14 07:53:05 +02004326/* parse the "ciphers" bind keyword */
Willy Tarreau4348fad2012-09-20 16:48:07 +02004327static 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 +02004328{
4329 if (!*args[cur_arg + 1]) {
Willy Tarreaueb6cead2012-09-20 19:43:14 +02004330 memprintf(err, "'%s' : missing cipher suite", args[cur_arg]);
Willy Tarreau79eeafa2012-09-14 07:53:05 +02004331 return ERR_ALERT | ERR_FATAL;
4332 }
4333
Emeric Brun76d88952012-10-05 15:47:31 +02004334 free(conf->ciphers);
Willy Tarreau4348fad2012-09-20 16:48:07 +02004335 conf->ciphers = strdup(args[cur_arg + 1]);
Willy Tarreau79eeafa2012-09-14 07:53:05 +02004336 return 0;
4337}
4338
4339/* parse the "crt" bind keyword */
Willy Tarreau4348fad2012-09-20 16:48:07 +02004340static 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 +02004341{
Willy Tarreau38011032013-08-13 16:59:39 +02004342 char path[MAXPATHLEN];
Willy Tarreaub75d6922014-04-14 18:05:41 +02004343
Willy Tarreau79eeafa2012-09-14 07:53:05 +02004344 if (!*args[cur_arg + 1]) {
Willy Tarreaueb6cead2012-09-20 19:43:14 +02004345 memprintf(err, "'%s' : missing certificate location", args[cur_arg]);
Willy Tarreau79eeafa2012-09-14 07:53:05 +02004346 return ERR_ALERT | ERR_FATAL;
4347 }
4348
Emeric Brunc8e8d122012-10-02 18:42:10 +02004349 if ((*args[cur_arg + 1] != '/' ) && global.crt_base) {
Willy Tarreau38011032013-08-13 16:59:39 +02004350 if ((strlen(global.crt_base) + 1 + strlen(args[cur_arg + 1]) + 1) > MAXPATHLEN) {
Emeric Brunc8e8d122012-10-02 18:42:10 +02004351 memprintf(err, "'%s' : path too long", args[cur_arg]);
4352 return ERR_ALERT | ERR_FATAL;
4353 }
Willy Tarreaub75d6922014-04-14 18:05:41 +02004354 snprintf(path, sizeof(path), "%s/%s", global.crt_base, args[cur_arg + 1]);
Emeric Brunc8e8d122012-10-02 18:42:10 +02004355 if (ssl_sock_load_cert(path, conf, px, err) > 0)
4356 return ERR_ALERT | ERR_FATAL;
4357
4358 return 0;
4359 }
4360
Willy Tarreau4348fad2012-09-20 16:48:07 +02004361 if (ssl_sock_load_cert(args[cur_arg + 1], conf, px, err) > 0)
Willy Tarreau79eeafa2012-09-14 07:53:05 +02004362 return ERR_ALERT | ERR_FATAL;
Emeric Brund94b3fe2012-09-20 18:23:56 +02004363
4364 return 0;
4365}
4366
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01004367/* parse the "crt-list" bind keyword */
4368static int bind_parse_crt_list(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
4369{
4370 if (!*args[cur_arg + 1]) {
4371 memprintf(err, "'%s' : missing certificate location", args[cur_arg]);
4372 return ERR_ALERT | ERR_FATAL;
4373 }
4374
Willy Tarreauad1731d2013-04-02 17:35:58 +02004375 if (ssl_sock_load_cert_list_file(args[cur_arg + 1], conf, px, err) > 0) {
4376 memprintf(err, "'%s' : %s", args[cur_arg], *err);
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01004377 return ERR_ALERT | ERR_FATAL;
Willy Tarreauad1731d2013-04-02 17:35:58 +02004378 }
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01004379
4380 return 0;
4381}
4382
Emeric Brunfb510ea2012-10-05 12:00:26 +02004383/* parse the "crl-file" bind keyword */
4384static 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 +02004385{
Emeric Brun051cdab2012-10-02 19:25:50 +02004386#ifndef X509_V_FLAG_CRL_CHECK
4387 if (err)
4388 memprintf(err, "'%s' : library does not support CRL verify", args[cur_arg]);
4389 return ERR_ALERT | ERR_FATAL;
4390#else
Emeric Brund94b3fe2012-09-20 18:23:56 +02004391 if (!*args[cur_arg + 1]) {
4392 if (err)
4393 memprintf(err, "'%s' : missing CRLfile path", args[cur_arg]);
4394 return ERR_ALERT | ERR_FATAL;
4395 }
Emeric Brun2b58d042012-09-20 17:10:03 +02004396
Emeric Brunef42d922012-10-11 16:11:36 +02004397 if ((*args[cur_arg + 1] != '/') && global.ca_base)
4398 memprintf(&conf->crl_file, "%s/%s", global.ca_base, args[cur_arg + 1]);
4399 else
4400 memprintf(&conf->crl_file, "%s", args[cur_arg + 1]);
Emeric Brunc8e8d122012-10-02 18:42:10 +02004401
Emeric Brun2b58d042012-09-20 17:10:03 +02004402 return 0;
Emeric Brun051cdab2012-10-02 19:25:50 +02004403#endif
Emeric Brun2b58d042012-09-20 17:10:03 +02004404}
4405
4406/* parse the "ecdhe" bind keyword keywords */
4407static int bind_parse_ecdhe(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
4408{
4409#if OPENSSL_VERSION_NUMBER < 0x0090800fL
4410 if (err)
4411 memprintf(err, "'%s' : library does not support elliptic curve Diffie-Hellman (too old)", args[cur_arg]);
4412 return ERR_ALERT | ERR_FATAL;
4413#elif defined(OPENSSL_NO_ECDH)
4414 if (err)
4415 memprintf(err, "'%s' : library does not support elliptic curve Diffie-Hellman (disabled via OPENSSL_NO_ECDH)", args[cur_arg]);
4416 return ERR_ALERT | ERR_FATAL;
4417#else
4418 if (!*args[cur_arg + 1]) {
4419 if (err)
4420 memprintf(err, "'%s' : missing named curve", args[cur_arg]);
4421 return ERR_ALERT | ERR_FATAL;
4422 }
4423
4424 conf->ecdhe = strdup(args[cur_arg + 1]);
Willy Tarreau79eeafa2012-09-14 07:53:05 +02004425
4426 return 0;
Emeric Brun2b58d042012-09-20 17:10:03 +02004427#endif
Willy Tarreau79eeafa2012-09-14 07:53:05 +02004428}
4429
Emeric Brun81c00f02012-09-21 14:31:21 +02004430/* parse the "crt_ignerr" and "ca_ignerr" bind keywords */
4431static int bind_parse_ignore_err(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
4432{
4433 int code;
4434 char *p = args[cur_arg + 1];
4435 unsigned long long *ignerr = &conf->crt_ignerr;
4436
4437 if (!*p) {
4438 if (err)
4439 memprintf(err, "'%s' : missing error IDs list", args[cur_arg]);
4440 return ERR_ALERT | ERR_FATAL;
4441 }
4442
4443 if (strcmp(args[cur_arg], "ca-ignore-err") == 0)
4444 ignerr = &conf->ca_ignerr;
4445
4446 if (strcmp(p, "all") == 0) {
4447 *ignerr = ~0ULL;
4448 return 0;
4449 }
4450
4451 while (p) {
4452 code = atoi(p);
4453 if ((code <= 0) || (code > 63)) {
4454 if (err)
4455 memprintf(err, "'%s' : ID '%d' out of range (1..63) in error IDs list '%s'",
4456 args[cur_arg], code, args[cur_arg + 1]);
4457 return ERR_ALERT | ERR_FATAL;
4458 }
4459 *ignerr |= 1ULL << code;
4460 p = strchr(p, ',');
4461 if (p)
4462 p++;
4463 }
4464
Emeric Brun2cb7ae52012-10-05 14:14:21 +02004465 return 0;
4466}
4467
4468/* parse the "force-sslv3" bind keyword */
4469static int bind_parse_force_sslv3(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
4470{
4471 conf->ssl_options |= BC_SSL_O_USE_SSLV3;
4472 return 0;
4473}
4474
4475/* parse the "force-tlsv10" bind keyword */
4476static int bind_parse_force_tlsv10(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
4477{
4478 conf->ssl_options |= BC_SSL_O_USE_TLSV10;
Emeric Brun2d0c4822012-10-02 13:45:20 +02004479 return 0;
4480}
4481
Emeric Brun2cb7ae52012-10-05 14:14:21 +02004482/* parse the "force-tlsv11" bind keyword */
4483static int bind_parse_force_tlsv11(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
4484{
4485#if SSL_OP_NO_TLSv1_1
4486 conf->ssl_options |= BC_SSL_O_USE_TLSV11;
4487 return 0;
4488#else
4489 if (err)
4490 memprintf(err, "'%s' : library does not support protocol TLSv1.1", args[cur_arg]);
4491 return ERR_ALERT | ERR_FATAL;
4492#endif
4493}
4494
4495/* parse the "force-tlsv12" bind keyword */
4496static int bind_parse_force_tlsv12(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
4497{
4498#if SSL_OP_NO_TLSv1_2
4499 conf->ssl_options |= BC_SSL_O_USE_TLSV12;
4500 return 0;
4501#else
4502 if (err)
4503 memprintf(err, "'%s' : library does not support protocol TLSv1.2", args[cur_arg]);
4504 return ERR_ALERT | ERR_FATAL;
4505#endif
4506}
4507
4508
Emeric Brun2d0c4822012-10-02 13:45:20 +02004509/* parse the "no-tls-tickets" bind keyword */
4510static int bind_parse_no_tls_tickets(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
4511{
Emeric Brun89675492012-10-05 13:48:26 +02004512 conf->ssl_options |= BC_SSL_O_NO_TLS_TICKETS;
Emeric Brun81c00f02012-09-21 14:31:21 +02004513 return 0;
4514}
4515
Emeric Brun2d0c4822012-10-02 13:45:20 +02004516
Emeric Brun9b3009b2012-10-05 11:55:06 +02004517/* parse the "no-sslv3" bind keyword */
4518static 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 +02004519{
Emeric Brun89675492012-10-05 13:48:26 +02004520 conf->ssl_options |= BC_SSL_O_NO_SSLV3;
Willy Tarreau79eeafa2012-09-14 07:53:05 +02004521 return 0;
4522}
4523
Emeric Brun9b3009b2012-10-05 11:55:06 +02004524/* parse the "no-tlsv10" bind keyword */
4525static 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 +02004526{
Emeric Brun89675492012-10-05 13:48:26 +02004527 conf->ssl_options |= BC_SSL_O_NO_TLSV10;
Emeric Brunc0ff4922012-09-28 19:37:02 +02004528 return 0;
4529}
4530
Emeric Brun9b3009b2012-10-05 11:55:06 +02004531/* parse the "no-tlsv11" bind keyword */
4532static 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 +02004533{
Emeric Brun89675492012-10-05 13:48:26 +02004534 conf->ssl_options |= BC_SSL_O_NO_TLSV11;
Emeric Brunc0ff4922012-09-28 19:37:02 +02004535 return 0;
4536}
4537
Emeric Brun9b3009b2012-10-05 11:55:06 +02004538/* parse the "no-tlsv12" bind keyword */
4539static 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 +02004540{
Emeric Brun89675492012-10-05 13:48:26 +02004541 conf->ssl_options |= BC_SSL_O_NO_TLSV12;
Willy Tarreau79eeafa2012-09-14 07:53:05 +02004542 return 0;
4543}
4544
Willy Tarreau6c9a3d52012-10-18 18:57:14 +02004545/* parse the "npn" bind keyword */
4546static int bind_parse_npn(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
4547{
4548#ifdef OPENSSL_NPN_NEGOTIATED
4549 char *p1, *p2;
4550
4551 if (!*args[cur_arg + 1]) {
4552 memprintf(err, "'%s' : missing the comma-delimited NPN protocol suite", args[cur_arg]);
4553 return ERR_ALERT | ERR_FATAL;
4554 }
4555
4556 free(conf->npn_str);
4557
4558 /* the NPN string is built as a suite of (<len> <name>)* */
4559 conf->npn_len = strlen(args[cur_arg + 1]) + 1;
4560 conf->npn_str = calloc(1, conf->npn_len);
4561 memcpy(conf->npn_str + 1, args[cur_arg + 1], conf->npn_len);
4562
4563 /* replace commas with the name length */
4564 p1 = conf->npn_str;
4565 p2 = p1 + 1;
4566 while (1) {
4567 p2 = memchr(p1 + 1, ',', conf->npn_str + conf->npn_len - (p1 + 1));
4568 if (!p2)
4569 p2 = p1 + 1 + strlen(p1 + 1);
4570
4571 if (p2 - (p1 + 1) > 255) {
4572 *p2 = '\0';
4573 memprintf(err, "'%s' : NPN protocol name too long : '%s'", args[cur_arg], p1 + 1);
4574 return ERR_ALERT | ERR_FATAL;
4575 }
4576
4577 *p1 = p2 - (p1 + 1);
4578 p1 = p2;
4579
4580 if (!*p2)
4581 break;
4582
4583 *(p2++) = '\0';
4584 }
4585 return 0;
4586#else
4587 if (err)
4588 memprintf(err, "'%s' : library does not support TLS NPN extension", args[cur_arg]);
4589 return ERR_ALERT | ERR_FATAL;
4590#endif
4591}
4592
Willy Tarreauab861d32013-04-02 02:30:41 +02004593/* parse the "alpn" bind keyword */
4594static int bind_parse_alpn(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
4595{
Dirkjan Bussink48f1c4e2014-02-13 12:29:42 +01004596#ifdef TLSEXT_TYPE_application_layer_protocol_negotiation
Willy Tarreauab861d32013-04-02 02:30:41 +02004597 char *p1, *p2;
4598
4599 if (!*args[cur_arg + 1]) {
4600 memprintf(err, "'%s' : missing the comma-delimited ALPN protocol suite", args[cur_arg]);
4601 return ERR_ALERT | ERR_FATAL;
4602 }
4603
4604 free(conf->alpn_str);
4605
4606 /* the ALPN string is built as a suite of (<len> <name>)* */
4607 conf->alpn_len = strlen(args[cur_arg + 1]) + 1;
4608 conf->alpn_str = calloc(1, conf->alpn_len);
4609 memcpy(conf->alpn_str + 1, args[cur_arg + 1], conf->alpn_len);
4610
4611 /* replace commas with the name length */
4612 p1 = conf->alpn_str;
4613 p2 = p1 + 1;
4614 while (1) {
4615 p2 = memchr(p1 + 1, ',', conf->alpn_str + conf->alpn_len - (p1 + 1));
4616 if (!p2)
4617 p2 = p1 + 1 + strlen(p1 + 1);
4618
4619 if (p2 - (p1 + 1) > 255) {
4620 *p2 = '\0';
4621 memprintf(err, "'%s' : ALPN protocol name too long : '%s'", args[cur_arg], p1 + 1);
4622 return ERR_ALERT | ERR_FATAL;
4623 }
4624
4625 *p1 = p2 - (p1 + 1);
4626 p1 = p2;
4627
4628 if (!*p2)
4629 break;
4630
4631 *(p2++) = '\0';
4632 }
4633 return 0;
4634#else
4635 if (err)
4636 memprintf(err, "'%s' : library does not support TLS ALPN extension", args[cur_arg]);
4637 return ERR_ALERT | ERR_FATAL;
4638#endif
4639}
4640
Willy Tarreau79eeafa2012-09-14 07:53:05 +02004641/* parse the "ssl" bind keyword */
Willy Tarreau4348fad2012-09-20 16:48:07 +02004642static 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 +02004643{
Willy Tarreau81796be2012-09-22 19:11:47 +02004644 struct listener *l;
4645
Willy Tarreau4348fad2012-09-20 16:48:07 +02004646 conf->is_ssl = 1;
Emeric Brun76d88952012-10-05 15:47:31 +02004647
4648 if (global.listen_default_ciphers && !conf->ciphers)
4649 conf->ciphers = strdup(global.listen_default_ciphers);
Emeric Brun2c86cbf2014-10-30 15:56:50 +01004650 conf->ssl_options |= global.listen_default_ssloptions;
Emeric Brun76d88952012-10-05 15:47:31 +02004651
Willy Tarreau81796be2012-09-22 19:11:47 +02004652 list_for_each_entry(l, &conf->listeners, by_bind)
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02004653 l->xprt = &ssl_sock;
Willy Tarreau81796be2012-09-22 19:11:47 +02004654
Willy Tarreau79eeafa2012-09-14 07:53:05 +02004655 return 0;
4656}
4657
Christopher Faulet31af49d2015-06-09 17:29:50 +02004658/* parse the "generate-certificates" bind keyword */
4659static int bind_parse_generate_certs(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
4660{
4661#ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME
4662 conf->generate_certs = 1;
4663#else
4664 memprintf(err, "%sthis version of openssl cannot generate SSL certificates.\n",
4665 err && *err ? *err : "");
4666#endif
4667 return 0;
4668}
4669
Emmanuel Hocdet65623372013-01-24 17:17:15 +01004670/* parse the "strict-sni" bind keyword */
4671static int bind_parse_strict_sni(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
4672{
4673 conf->strict_sni = 1;
4674 return 0;
Nenad Merdanovic05552d42015-02-27 19:56:49 +01004675}
4676
4677/* parse the "tls-ticket-keys" bind keyword */
4678static int bind_parse_tls_ticket_keys(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
4679{
4680#if (defined SSL_CTRL_SET_TLSEXT_TICKET_KEY_CB && TLS_TICKETS_NO > 0)
4681 FILE *f;
4682 int i = 0;
4683 char thisline[LINESIZE];
Nenad Merdanovic146defa2015-05-09 08:46:00 +02004684 struct tls_keys_ref *keys_ref;
Nenad Merdanovic05552d42015-02-27 19:56:49 +01004685
4686 if (!*args[cur_arg + 1]) {
4687 if (err)
4688 memprintf(err, "'%s' : missing TLS ticket keys file path", args[cur_arg]);
4689 return ERR_ALERT | ERR_FATAL;
4690 }
4691
Nenad Merdanovic200b0fa2015-05-09 08:46:01 +02004692 keys_ref = tlskeys_ref_lookup(args[cur_arg + 1]);
4693 if(keys_ref) {
4694 conf->keys_ref = keys_ref;
4695 return 0;
4696 }
4697
Nenad Merdanovic146defa2015-05-09 08:46:00 +02004698 keys_ref = malloc(sizeof(struct tls_keys_ref));
4699 keys_ref->tlskeys = malloc(TLS_TICKETS_NO * sizeof(struct tls_sess_key));
Nenad Merdanovic05552d42015-02-27 19:56:49 +01004700
4701 if ((f = fopen(args[cur_arg + 1], "r")) == NULL) {
4702 if (err)
4703 memprintf(err, "'%s' : unable to load ssl tickets keys file", args[cur_arg+1]);
4704 return ERR_ALERT | ERR_FATAL;
4705 }
4706
Nenad Merdanovic146defa2015-05-09 08:46:00 +02004707 keys_ref->filename = strdup(args[cur_arg + 1]);
4708
Nenad Merdanovic05552d42015-02-27 19:56:49 +01004709 while (fgets(thisline, sizeof(thisline), f) != NULL) {
4710 int len = strlen(thisline);
4711 /* Strip newline characters from the end */
4712 if(thisline[len - 1] == '\n')
4713 thisline[--len] = 0;
4714
4715 if(thisline[len - 1] == '\r')
4716 thisline[--len] = 0;
4717
Nenad Merdanovic146defa2015-05-09 08:46:00 +02004718 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 +01004719 if (err)
4720 memprintf(err, "'%s' : unable to decode base64 key on line %d", args[cur_arg+1], i + 1);
4721 return ERR_ALERT | ERR_FATAL;
4722 }
4723 i++;
4724 }
4725
4726 if (i < TLS_TICKETS_NO) {
4727 if (err)
4728 memprintf(err, "'%s' : please supply at least %d keys in the tls-tickets-file", args[cur_arg+1], TLS_TICKETS_NO);
4729 return ERR_ALERT | ERR_FATAL;
4730 }
4731
4732 fclose(f);
4733
4734 /* Use penultimate key for encryption, handle when TLS_TICKETS_NO = 1 */
4735 i-=2;
Nenad Merdanovic146defa2015-05-09 08:46:00 +02004736 keys_ref->tls_ticket_enc_index = i < 0 ? 0 : i;
Nenad Merdanovic200b0fa2015-05-09 08:46:01 +02004737 keys_ref->unique_id = -1;
Nenad Merdanovic146defa2015-05-09 08:46:00 +02004738 conf->keys_ref = keys_ref;
Nenad Merdanovic05552d42015-02-27 19:56:49 +01004739
Nenad Merdanovic200b0fa2015-05-09 08:46:01 +02004740 LIST_ADD(&tlskeys_reference, &keys_ref->list);
4741
Nenad Merdanovic05552d42015-02-27 19:56:49 +01004742 return 0;
4743#else
4744 if (err)
4745 memprintf(err, "'%s' : TLS ticket callback extension not supported", args[cur_arg]);
4746 return ERR_ALERT | ERR_FATAL;
4747#endif /* SSL_CTRL_SET_TLSEXT_TICKET_KEY_CB */
Emmanuel Hocdet65623372013-01-24 17:17:15 +01004748}
4749
Emeric Brund94b3fe2012-09-20 18:23:56 +02004750/* parse the "verify" bind keyword */
4751static int bind_parse_verify(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
4752{
4753 if (!*args[cur_arg + 1]) {
4754 if (err)
4755 memprintf(err, "'%s' : missing verify method", args[cur_arg]);
4756 return ERR_ALERT | ERR_FATAL;
4757 }
4758
4759 if (strcmp(args[cur_arg + 1], "none") == 0)
Emeric Brun850efd52014-01-29 12:24:34 +01004760 conf->verify = SSL_SOCK_VERIFY_NONE;
Emeric Brund94b3fe2012-09-20 18:23:56 +02004761 else if (strcmp(args[cur_arg + 1], "optional") == 0)
Emeric Brun850efd52014-01-29 12:24:34 +01004762 conf->verify = SSL_SOCK_VERIFY_OPTIONAL;
Emeric Brund94b3fe2012-09-20 18:23:56 +02004763 else if (strcmp(args[cur_arg + 1], "required") == 0)
Emeric Brun850efd52014-01-29 12:24:34 +01004764 conf->verify = SSL_SOCK_VERIFY_REQUIRED;
Emeric Brund94b3fe2012-09-20 18:23:56 +02004765 else {
4766 if (err)
4767 memprintf(err, "'%s' : unknown verify method '%s', only 'none', 'optional', and 'required' are supported\n",
4768 args[cur_arg], args[cur_arg + 1]);
4769 return ERR_ALERT | ERR_FATAL;
4770 }
4771
4772 return 0;
4773}
4774
Willy Tarreau92faadf2012-10-10 23:04:25 +02004775/************** "server" keywords ****************/
4776
Emeric Brunef42d922012-10-11 16:11:36 +02004777/* parse the "ca-file" server keyword */
4778static int srv_parse_ca_file(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
4779{
4780 if (!*args[*cur_arg + 1]) {
4781 if (err)
4782 memprintf(err, "'%s' : missing CAfile path", args[*cur_arg]);
4783 return ERR_ALERT | ERR_FATAL;
4784 }
4785
4786 if ((*args[*cur_arg + 1] != '/') && global.ca_base)
4787 memprintf(&newsrv->ssl_ctx.ca_file, "%s/%s", global.ca_base, args[*cur_arg + 1]);
4788 else
4789 memprintf(&newsrv->ssl_ctx.ca_file, "%s", args[*cur_arg + 1]);
4790
4791 return 0;
4792}
4793
Willy Tarreau92faadf2012-10-10 23:04:25 +02004794/* parse the "check-ssl" server keyword */
4795static int srv_parse_check_ssl(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
4796{
4797 newsrv->check.use_ssl = 1;
4798 if (global.connect_default_ciphers && !newsrv->ssl_ctx.ciphers)
4799 newsrv->ssl_ctx.ciphers = strdup(global.connect_default_ciphers);
Emeric Brun2c86cbf2014-10-30 15:56:50 +01004800 newsrv->ssl_ctx.options |= global.connect_default_ssloptions;
Willy Tarreau92faadf2012-10-10 23:04:25 +02004801 return 0;
4802}
4803
4804/* parse the "ciphers" server keyword */
4805static int srv_parse_ciphers(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
4806{
4807 if (!*args[*cur_arg + 1]) {
4808 memprintf(err, "'%s' : missing cipher suite", args[*cur_arg]);
4809 return ERR_ALERT | ERR_FATAL;
4810 }
4811
4812 free(newsrv->ssl_ctx.ciphers);
4813 newsrv->ssl_ctx.ciphers = strdup(args[*cur_arg + 1]);
4814 return 0;
4815}
4816
Emeric Brunef42d922012-10-11 16:11:36 +02004817/* parse the "crl-file" server keyword */
4818static int srv_parse_crl_file(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
4819{
4820#ifndef X509_V_FLAG_CRL_CHECK
4821 if (err)
4822 memprintf(err, "'%s' : library does not support CRL verify", args[*cur_arg]);
4823 return ERR_ALERT | ERR_FATAL;
4824#else
4825 if (!*args[*cur_arg + 1]) {
4826 if (err)
4827 memprintf(err, "'%s' : missing CRLfile path", args[*cur_arg]);
4828 return ERR_ALERT | ERR_FATAL;
4829 }
4830
4831 if ((*args[*cur_arg + 1] != '/') && global.ca_base)
4832 memprintf(&newsrv->ssl_ctx.crl_file, "%s/%s", global.ca_base, args[*cur_arg + 1]);
4833 else
4834 memprintf(&newsrv->ssl_ctx.crl_file, "%s", args[*cur_arg + 1]);
4835
4836 return 0;
4837#endif
4838}
4839
Emeric Bruna7aa3092012-10-26 12:58:00 +02004840/* parse the "crt" server keyword */
4841static int srv_parse_crt(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
4842{
4843 if (!*args[*cur_arg + 1]) {
4844 if (err)
4845 memprintf(err, "'%s' : missing certificate file path", args[*cur_arg]);
4846 return ERR_ALERT | ERR_FATAL;
4847 }
4848
4849 if ((*args[*cur_arg + 1] != '/') && global.crt_base)
4850 memprintf(&newsrv->ssl_ctx.client_crt, "%s/%s", global.ca_base, args[*cur_arg + 1]);
4851 else
4852 memprintf(&newsrv->ssl_ctx.client_crt, "%s", args[*cur_arg + 1]);
4853
4854 return 0;
4855}
Emeric Brunef42d922012-10-11 16:11:36 +02004856
Willy Tarreau92faadf2012-10-10 23:04:25 +02004857/* parse the "force-sslv3" server keyword */
4858static int srv_parse_force_sslv3(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
4859{
4860 newsrv->ssl_ctx.options |= SRV_SSL_O_USE_SSLV3;
4861 return 0;
4862}
4863
4864/* parse the "force-tlsv10" server keyword */
4865static int srv_parse_force_tlsv10(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
4866{
4867 newsrv->ssl_ctx.options |= SRV_SSL_O_USE_TLSV10;
4868 return 0;
4869}
4870
4871/* parse the "force-tlsv11" server keyword */
4872static int srv_parse_force_tlsv11(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
4873{
4874#if SSL_OP_NO_TLSv1_1
4875 newsrv->ssl_ctx.options |= SRV_SSL_O_USE_TLSV11;
4876 return 0;
4877#else
4878 if (err)
4879 memprintf(err, "'%s' : library does not support protocol TLSv1.1", args[*cur_arg]);
4880 return ERR_ALERT | ERR_FATAL;
4881#endif
4882}
4883
4884/* parse the "force-tlsv12" server keyword */
4885static int srv_parse_force_tlsv12(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
4886{
4887#if SSL_OP_NO_TLSv1_2
4888 newsrv->ssl_ctx.options |= SRV_SSL_O_USE_TLSV12;
4889 return 0;
4890#else
4891 if (err)
4892 memprintf(err, "'%s' : library does not support protocol TLSv1.2", args[*cur_arg]);
4893 return ERR_ALERT | ERR_FATAL;
4894#endif
4895}
4896
Willy Tarreau2a3fb1c2015-02-05 16:47:07 +01004897/* parse the "no-ssl-reuse" server keyword */
4898static int srv_parse_no_ssl_reuse(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
4899{
4900 newsrv->ssl_ctx.options |= SRV_SSL_O_NO_REUSE;
4901 return 0;
4902}
4903
Willy Tarreau92faadf2012-10-10 23:04:25 +02004904/* parse the "no-sslv3" server keyword */
4905static int srv_parse_no_sslv3(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
4906{
4907 newsrv->ssl_ctx.options |= SRV_SSL_O_NO_SSLV3;
4908 return 0;
4909}
4910
4911/* parse the "no-tlsv10" server keyword */
4912static int srv_parse_no_tlsv10(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
4913{
4914 newsrv->ssl_ctx.options |= SRV_SSL_O_NO_TLSV10;
4915 return 0;
4916}
4917
4918/* parse the "no-tlsv11" server keyword */
4919static int srv_parse_no_tlsv11(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
4920{
4921 newsrv->ssl_ctx.options |= SRV_SSL_O_NO_TLSV11;
4922 return 0;
4923}
4924
4925/* parse the "no-tlsv12" server keyword */
4926static int srv_parse_no_tlsv12(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
4927{
4928 newsrv->ssl_ctx.options |= SRV_SSL_O_NO_TLSV12;
4929 return 0;
4930}
4931
Emeric Brunf9c5c472012-10-11 15:28:34 +02004932/* parse the "no-tls-tickets" server keyword */
4933static int srv_parse_no_tls_tickets(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
4934{
4935 newsrv->ssl_ctx.options |= SRV_SSL_O_NO_TLS_TICKETS;
4936 return 0;
4937}
David Safb76832014-05-08 23:42:08 -04004938/* parse the "send-proxy-v2-ssl" server keyword */
4939static int srv_parse_send_proxy_ssl(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
4940{
4941 newsrv->pp_opts |= SRV_PP_V2;
4942 newsrv->pp_opts |= SRV_PP_V2_SSL;
4943 return 0;
4944}
4945
4946/* parse the "send-proxy-v2-ssl-cn" server keyword */
4947static int srv_parse_send_proxy_cn(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
4948{
4949 newsrv->pp_opts |= SRV_PP_V2;
4950 newsrv->pp_opts |= SRV_PP_V2_SSL;
4951 newsrv->pp_opts |= SRV_PP_V2_SSL_CN;
4952 return 0;
4953}
Emeric Brunf9c5c472012-10-11 15:28:34 +02004954
Willy Tarreau732eac42015-07-09 11:40:25 +02004955/* parse the "sni" server keyword */
4956static int srv_parse_sni(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
4957{
4958#ifndef SSL_CTRL_SET_TLSEXT_HOSTNAME
4959 memprintf(err, "'%s' : the current SSL library doesn't support the SNI TLS extension", args[*cur_arg]);
4960 return ERR_ALERT | ERR_FATAL;
4961#else
4962 struct sample_expr *expr;
4963
4964 if (!*args[*cur_arg + 1]) {
4965 memprintf(err, "'%s' : missing sni expression", args[*cur_arg]);
4966 return ERR_ALERT | ERR_FATAL;
4967 }
4968
4969 (*cur_arg)++;
4970 proxy->conf.args.ctx = ARGC_SRV;
4971
4972 expr = sample_parse_expr((char **)args, cur_arg, px->conf.file, px->conf.line, err, &proxy->conf.args);
4973 if (!expr) {
4974 memprintf(err, "error detected while parsing sni expression : %s", *err);
4975 return ERR_ALERT | ERR_FATAL;
4976 }
4977
4978 if (!(expr->fetch->val & SMP_VAL_BE_SRV_CON)) {
4979 memprintf(err, "error detected while parsing sni expression : "
4980 " fetch method '%s' extracts information from '%s', none of which is available here.\n",
4981 args[*cur_arg-1], sample_src_names(expr->fetch->use));
4982 return ERR_ALERT | ERR_FATAL;
4983 }
4984
4985 px->http_needed |= !!(expr->fetch->use & SMP_USE_HTTP_ANY);
4986 newsrv->ssl_ctx.sni = expr;
4987 return 0;
4988#endif
4989}
4990
Willy Tarreau92faadf2012-10-10 23:04:25 +02004991/* parse the "ssl" server keyword */
4992static int srv_parse_ssl(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
4993{
4994 newsrv->use_ssl = 1;
4995 if (global.connect_default_ciphers && !newsrv->ssl_ctx.ciphers)
4996 newsrv->ssl_ctx.ciphers = strdup(global.connect_default_ciphers);
4997 return 0;
4998}
4999
Emeric Brunef42d922012-10-11 16:11:36 +02005000/* parse the "verify" server keyword */
5001static int srv_parse_verify(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
5002{
5003 if (!*args[*cur_arg + 1]) {
5004 if (err)
5005 memprintf(err, "'%s' : missing verify method", args[*cur_arg]);
5006 return ERR_ALERT | ERR_FATAL;
5007 }
5008
5009 if (strcmp(args[*cur_arg + 1], "none") == 0)
Emeric Brun850efd52014-01-29 12:24:34 +01005010 newsrv->ssl_ctx.verify = SSL_SOCK_VERIFY_NONE;
Emeric Brunef42d922012-10-11 16:11:36 +02005011 else if (strcmp(args[*cur_arg + 1], "required") == 0)
Emeric Brun850efd52014-01-29 12:24:34 +01005012 newsrv->ssl_ctx.verify = SSL_SOCK_VERIFY_REQUIRED;
Emeric Brunef42d922012-10-11 16:11:36 +02005013 else {
5014 if (err)
5015 memprintf(err, "'%s' : unknown verify method '%s', only 'none' and 'required' are supported\n",
5016 args[*cur_arg], args[*cur_arg + 1]);
5017 return ERR_ALERT | ERR_FATAL;
5018 }
5019
Evan Broderbe554312013-06-27 00:05:25 -07005020 return 0;
5021}
5022
5023/* parse the "verifyhost" server keyword */
5024static int srv_parse_verifyhost(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
5025{
5026 if (!*args[*cur_arg + 1]) {
5027 if (err)
5028 memprintf(err, "'%s' : missing hostname to verify against", args[*cur_arg]);
5029 return ERR_ALERT | ERR_FATAL;
5030 }
5031
5032 newsrv->ssl_ctx.verify_host = strdup(args[*cur_arg + 1]);
5033
Emeric Brunef42d922012-10-11 16:11:36 +02005034 return 0;
5035}
5036
Emeric Brun2c86cbf2014-10-30 15:56:50 +01005037/* parse the "ssl-default-bind-options" keyword in global section */
5038static int ssl_parse_default_bind_options(char **args, int section_type, struct proxy *curpx,
5039 struct proxy *defpx, const char *file, int line,
5040 char **err) {
5041 int i = 1;
5042
5043 if (*(args[i]) == 0) {
5044 memprintf(err, "global statement '%s' expects an option as an argument.", args[0]);
5045 return -1;
5046 }
5047 while (*(args[i])) {
5048 if (!strcmp(args[i], "no-sslv3"))
5049 global.listen_default_ssloptions |= BC_SSL_O_NO_SSLV3;
5050 else if (!strcmp(args[i], "no-tlsv10"))
5051 global.listen_default_ssloptions |= BC_SSL_O_NO_TLSV10;
5052 else if (!strcmp(args[i], "no-tlsv11"))
5053 global.listen_default_ssloptions |= BC_SSL_O_NO_TLSV11;
5054 else if (!strcmp(args[i], "no-tlsv12"))
5055 global.listen_default_ssloptions |= BC_SSL_O_NO_TLSV12;
5056 else if (!strcmp(args[i], "force-sslv3"))
5057 global.listen_default_ssloptions |= BC_SSL_O_USE_SSLV3;
5058 else if (!strcmp(args[i], "force-tlsv10"))
5059 global.listen_default_ssloptions |= BC_SSL_O_USE_TLSV10;
5060 else if (!strcmp(args[i], "force-tlsv11")) {
5061#if SSL_OP_NO_TLSv1_1
5062 global.listen_default_ssloptions |= BC_SSL_O_USE_TLSV11;
5063#else
5064 memprintf(err, "'%s' '%s': library does not support protocol TLSv1.1", args[0], args[i]);
5065 return -1;
5066#endif
5067 }
5068 else if (!strcmp(args[i], "force-tlsv12")) {
5069#if SSL_OP_NO_TLSv1_2
5070 global.listen_default_ssloptions |= BC_SSL_O_USE_TLSV12;
5071#else
5072 memprintf(err, "'%s' '%s': library does not support protocol TLSv1.2", args[0], args[i]);
5073 return -1;
5074#endif
5075 }
5076 else if (!strcmp(args[i], "no-tls-tickets"))
5077 global.listen_default_ssloptions |= BC_SSL_O_NO_TLS_TICKETS;
5078 else {
5079 memprintf(err, "unknown option '%s' on global statement '%s'.", args[i], args[0]);
5080 return -1;
5081 }
5082 i++;
5083 }
5084 return 0;
5085}
5086
5087/* parse the "ssl-default-server-options" keyword in global section */
5088static int ssl_parse_default_server_options(char **args, int section_type, struct proxy *curpx,
5089 struct proxy *defpx, const char *file, int line,
5090 char **err) {
5091 int i = 1;
5092
5093 if (*(args[i]) == 0) {
5094 memprintf(err, "global statement '%s' expects an option as an argument.", args[0]);
5095 return -1;
5096 }
5097 while (*(args[i])) {
5098 if (!strcmp(args[i], "no-sslv3"))
5099 global.connect_default_ssloptions |= SRV_SSL_O_NO_SSLV3;
5100 else if (!strcmp(args[i], "no-tlsv10"))
5101 global.connect_default_ssloptions |= SRV_SSL_O_NO_TLSV10;
5102 else if (!strcmp(args[i], "no-tlsv11"))
5103 global.connect_default_ssloptions |= SRV_SSL_O_NO_TLSV11;
5104 else if (!strcmp(args[i], "no-tlsv12"))
5105 global.connect_default_ssloptions |= SRV_SSL_O_NO_TLSV12;
5106 else if (!strcmp(args[i], "force-sslv3"))
5107 global.connect_default_ssloptions |= SRV_SSL_O_USE_SSLV3;
5108 else if (!strcmp(args[i], "force-tlsv10"))
5109 global.connect_default_ssloptions |= SRV_SSL_O_USE_TLSV10;
5110 else if (!strcmp(args[i], "force-tlsv11")) {
5111#if SSL_OP_NO_TLSv1_1
5112 global.connect_default_ssloptions |= SRV_SSL_O_USE_TLSV11;
5113#else
5114 memprintf(err, "'%s' '%s': library does not support protocol TLSv1.1", args[0], args[i]);
5115 return -1;
5116#endif
5117 }
5118 else if (!strcmp(args[i], "force-tlsv12")) {
5119#if SSL_OP_NO_TLSv1_2
5120 global.connect_default_ssloptions |= SRV_SSL_O_USE_TLSV12;
5121#else
5122 memprintf(err, "'%s' '%s': library does not support protocol TLSv1.2", args[0], args[i]);
5123 return -1;
5124#endif
5125 }
5126 else if (!strcmp(args[i], "no-tls-tickets"))
5127 global.connect_default_ssloptions |= SRV_SSL_O_NO_TLS_TICKETS;
5128 else {
5129 memprintf(err, "unknown option '%s' on global statement '%s'.", args[i], args[0]);
5130 return -1;
5131 }
5132 i++;
5133 }
5134 return 0;
5135}
5136
Willy Tarreau7875d092012-09-10 08:20:03 +02005137/* Note: must not be declared <const> as its list will be overwritten.
5138 * Please take care of keeping this list alphabetically sorted.
5139 */
Willy Tarreaudc13c112013-06-21 23:16:39 +02005140static struct sample_fetch_kw_list sample_fetch_keywords = {ILH, {
Emeric Brun645ae792014-04-30 14:21:06 +02005141 { "ssl_bc", smp_fetch_ssl_fc, 0, NULL, SMP_T_BOOL, SMP_USE_L5SRV },
5142 { "ssl_bc_alg_keysize", smp_fetch_ssl_fc_alg_keysize, 0, NULL, SMP_T_UINT, SMP_USE_L5SRV },
5143 { "ssl_bc_cipher", smp_fetch_ssl_fc_cipher, 0, NULL, SMP_T_STR, SMP_USE_L5SRV },
5144 { "ssl_bc_protocol", smp_fetch_ssl_fc_protocol, 0, NULL, SMP_T_STR, SMP_USE_L5SRV },
Emeric Brunb73a9b02014-04-30 18:49:19 +02005145 { "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 +02005146 { "ssl_bc_use_keysize", smp_fetch_ssl_fc_use_keysize, 0, NULL, SMP_T_UINT, SMP_USE_L5SRV },
5147 { "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 +01005148 { "ssl_c_ca_err", smp_fetch_ssl_c_ca_err, 0, NULL, SMP_T_UINT, SMP_USE_L5CLI },
5149 { "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 +01005150 { "ssl_c_der", smp_fetch_ssl_x_der, 0, NULL, SMP_T_BIN, SMP_USE_L5CLI },
Willy Tarreau80aca902013-01-07 15:42:20 +01005151 { "ssl_c_err", smp_fetch_ssl_c_err, 0, NULL, SMP_T_UINT, SMP_USE_L5CLI },
Emeric Brunba841a12014-04-30 17:05:08 +02005152 { "ssl_c_i_dn", smp_fetch_ssl_x_i_dn, ARG2(0,STR,SINT), NULL, SMP_T_STR, SMP_USE_L5CLI },
5153 { "ssl_c_key_alg", smp_fetch_ssl_x_key_alg, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
5154 { "ssl_c_notafter", smp_fetch_ssl_x_notafter, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
5155 { "ssl_c_notbefore", smp_fetch_ssl_x_notbefore, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
5156 { "ssl_c_sig_alg", smp_fetch_ssl_x_sig_alg, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
5157 { "ssl_c_s_dn", smp_fetch_ssl_x_s_dn, ARG2(0,STR,SINT), NULL, SMP_T_STR, SMP_USE_L5CLI },
5158 { "ssl_c_serial", smp_fetch_ssl_x_serial, 0, NULL, SMP_T_BIN, SMP_USE_L5CLI },
5159 { "ssl_c_sha1", smp_fetch_ssl_x_sha1, 0, NULL, SMP_T_BIN, SMP_USE_L5CLI },
Willy Tarreau80aca902013-01-07 15:42:20 +01005160 { "ssl_c_used", smp_fetch_ssl_c_used, 0, NULL, SMP_T_BOOL, SMP_USE_L5CLI },
5161 { "ssl_c_verify", smp_fetch_ssl_c_verify, 0, NULL, SMP_T_UINT, SMP_USE_L5CLI },
Emeric Brunba841a12014-04-30 17:05:08 +02005162 { "ssl_c_version", smp_fetch_ssl_x_version, 0, NULL, SMP_T_UINT, SMP_USE_L5CLI },
Emeric Brun43e79582014-10-29 19:03:26 +01005163 { "ssl_f_der", smp_fetch_ssl_x_der, 0, NULL, SMP_T_BIN, SMP_USE_L5CLI },
Emeric Brunba841a12014-04-30 17:05:08 +02005164 { "ssl_f_i_dn", smp_fetch_ssl_x_i_dn, ARG2(0,STR,SINT), NULL, SMP_T_STR, SMP_USE_L5CLI },
5165 { "ssl_f_key_alg", smp_fetch_ssl_x_key_alg, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
5166 { "ssl_f_notafter", smp_fetch_ssl_x_notafter, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
5167 { "ssl_f_notbefore", smp_fetch_ssl_x_notbefore, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
5168 { "ssl_f_sig_alg", smp_fetch_ssl_x_sig_alg, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
5169 { "ssl_f_s_dn", smp_fetch_ssl_x_s_dn, ARG2(0,STR,SINT), NULL, SMP_T_STR, SMP_USE_L5CLI },
5170 { "ssl_f_serial", smp_fetch_ssl_x_serial, 0, NULL, SMP_T_BIN, SMP_USE_L5CLI },
Emeric Brun55f4fa82014-04-30 17:11:25 +02005171 { "ssl_f_sha1", smp_fetch_ssl_x_sha1, 0, NULL, SMP_T_BIN, SMP_USE_L5CLI },
Emeric Brunba841a12014-04-30 17:05:08 +02005172 { "ssl_f_version", smp_fetch_ssl_x_version, 0, NULL, SMP_T_UINT, SMP_USE_L5CLI },
Willy Tarreau80aca902013-01-07 15:42:20 +01005173 { "ssl_fc", smp_fetch_ssl_fc, 0, NULL, SMP_T_BOOL, SMP_USE_L5CLI },
5174 { "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 +01005175 { "ssl_fc_cipher", smp_fetch_ssl_fc_cipher, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
Willy Tarreau80aca902013-01-07 15:42:20 +01005176 { "ssl_fc_has_crt", smp_fetch_ssl_fc_has_crt, 0, NULL, SMP_T_BOOL, SMP_USE_L5CLI },
5177 { "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 +02005178 { "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 +02005179#ifdef OPENSSL_NPN_NEGOTIATED
Thierry FOURNIER7654c9f2013-12-17 00:20:33 +01005180 { "ssl_fc_npn", smp_fetch_ssl_fc_npn, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
Willy Tarreaua33c6542012-10-15 13:19:06 +02005181#endif
Dirkjan Bussink48f1c4e2014-02-13 12:29:42 +01005182#ifdef TLSEXT_TYPE_application_layer_protocol_negotiation
Thierry FOURNIER7654c9f2013-12-17 00:20:33 +01005183 { "ssl_fc_alpn", smp_fetch_ssl_fc_alpn, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
Willy Tarreauab861d32013-04-02 02:30:41 +02005184#endif
Thierry FOURNIER7654c9f2013-12-17 00:20:33 +01005185 { "ssl_fc_protocol", smp_fetch_ssl_fc_protocol, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
Emeric Brunb73a9b02014-04-30 18:49:19 +02005186 { "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 +01005187 { "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 +01005188 { "ssl_fc_session_id", smp_fetch_ssl_fc_session_id, 0, NULL, SMP_T_BIN, SMP_USE_L5CLI },
5189 { "ssl_fc_sni", smp_fetch_ssl_fc_sni, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
Willy Tarreau7875d092012-09-10 08:20:03 +02005190 { NULL, NULL, 0, 0, 0 },
5191}};
5192
5193/* Note: must not be declared <const> as its list will be overwritten.
5194 * Please take care of keeping this list alphabetically sorted.
5195 */
Willy Tarreaudc13c112013-06-21 23:16:39 +02005196static struct acl_kw_list acl_kws = {ILH, {
Thierry FOURNIERc5a4e982014-03-05 16:07:08 +01005197 { "ssl_fc_sni_end", "ssl_fc_sni", PAT_MATCH_END },
5198 { "ssl_fc_sni_reg", "ssl_fc_sni", PAT_MATCH_REG },
Willy Tarreau8ed669b2013-01-11 15:49:37 +01005199 { /* END */ },
Willy Tarreau7875d092012-09-10 08:20:03 +02005200}};
5201
Willy Tarreau79eeafa2012-09-14 07:53:05 +02005202/* Note: must not be declared <const> as its list will be overwritten.
5203 * Please take care of keeping this list alphabetically sorted, doing so helps
5204 * all code contributors.
5205 * Optional keywords are also declared with a NULL ->parse() function so that
5206 * the config parser can report an appropriate error when a known keyword was
5207 * not enabled.
5208 */
Willy Tarreau51fb7652012-09-18 18:24:39 +02005209static struct bind_kw_list bind_kws = { "SSL", { }, {
Nenad Merdanovic05552d42015-02-27 19:56:49 +01005210 { "alpn", bind_parse_alpn, 1 }, /* set ALPN supported protocols */
5211 { "ca-file", bind_parse_ca_file, 1 }, /* set CAfile to process verify on client cert */
5212 { "ca-ignore-err", bind_parse_ignore_err, 1 }, /* set error IDs to ignore on verify depth > 0 */
Christopher Faulet31af49d2015-06-09 17:29:50 +02005213 { "ca-sign-file", bind_parse_ca_sign_file, 1 }, /* set CAFile used to generate and sign server certs */
5214 { "ca-sign-pass", bind_parse_ca_sign_pass, 1 }, /* set CAKey passphrase */
Nenad Merdanovic05552d42015-02-27 19:56:49 +01005215 { "ciphers", bind_parse_ciphers, 1 }, /* set SSL cipher suite */
5216 { "crl-file", bind_parse_crl_file, 1 }, /* set certificat revocation list file use on client cert verify */
5217 { "crt", bind_parse_crt, 1 }, /* load SSL certificates from this location */
5218 { "crt-ignore-err", bind_parse_ignore_err, 1 }, /* set error IDs to ingore on verify depth == 0 */
5219 { "crt-list", bind_parse_crt_list, 1 }, /* load a list of crt from this location */
5220 { "ecdhe", bind_parse_ecdhe, 1 }, /* defines named curve for elliptic curve Diffie-Hellman */
5221 { "force-sslv3", bind_parse_force_sslv3, 0 }, /* force SSLv3 */
5222 { "force-tlsv10", bind_parse_force_tlsv10, 0 }, /* force TLSv10 */
5223 { "force-tlsv11", bind_parse_force_tlsv11, 0 }, /* force TLSv11 */
5224 { "force-tlsv12", bind_parse_force_tlsv12, 0 }, /* force TLSv12 */
Christopher Faulet31af49d2015-06-09 17:29:50 +02005225 { "generate-certificates", bind_parse_generate_certs, 0 }, /* enable the server certificates generation */
Nenad Merdanovic05552d42015-02-27 19:56:49 +01005226 { "no-sslv3", bind_parse_no_sslv3, 0 }, /* disable SSLv3 */
5227 { "no-tlsv10", bind_parse_no_tlsv10, 0 }, /* disable TLSv10 */
5228 { "no-tlsv11", bind_parse_no_tlsv11, 0 }, /* disable TLSv11 */
5229 { "no-tlsv12", bind_parse_no_tlsv12, 0 }, /* disable TLSv12 */
5230 { "no-tls-tickets", bind_parse_no_tls_tickets, 0 }, /* disable session resumption tickets */
5231 { "ssl", bind_parse_ssl, 0 }, /* enable SSL processing */
5232 { "strict-sni", bind_parse_strict_sni, 0 }, /* refuse negotiation if sni doesn't match a certificate */
5233 { "tls-ticket-keys", bind_parse_tls_ticket_keys, 1 }, /* set file to load TLS ticket keys from */
5234 { "verify", bind_parse_verify, 1 }, /* set SSL verify method */
5235 { "npn", bind_parse_npn, 1 }, /* set NPN supported protocols */
Willy Tarreau79eeafa2012-09-14 07:53:05 +02005236 { NULL, NULL, 0 },
5237}};
Emeric Brun46591952012-05-18 15:47:34 +02005238
Willy Tarreau92faadf2012-10-10 23:04:25 +02005239/* Note: must not be declared <const> as its list will be overwritten.
5240 * Please take care of keeping this list alphabetically sorted, doing so helps
5241 * all code contributors.
5242 * Optional keywords are also declared with a NULL ->parse() function so that
5243 * the config parser can report an appropriate error when a known keyword was
5244 * not enabled.
5245 */
5246static struct srv_kw_list srv_kws = { "SSL", { }, {
Emeric Brunef42d922012-10-11 16:11:36 +02005247 { "ca-file", srv_parse_ca_file, 1, 0 }, /* set CAfile to process verify server cert */
Emeric Brunecc91fe2012-10-11 15:05:10 +02005248 { "check-ssl", srv_parse_check_ssl, 0, 0 }, /* enable SSL for health checks */
5249 { "ciphers", srv_parse_ciphers, 1, 0 }, /* select the cipher suite */
Emeric Brunef42d922012-10-11 16:11:36 +02005250 { "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 +02005251 { "crt", srv_parse_crt, 1, 0 }, /* set client certificate */
Emeric Brunecc91fe2012-10-11 15:05:10 +02005252 { "force-sslv3", srv_parse_force_sslv3, 0, 0 }, /* force SSLv3 */
5253 { "force-tlsv10", srv_parse_force_tlsv10, 0, 0 }, /* force TLSv10 */
5254 { "force-tlsv11", srv_parse_force_tlsv11, 0, 0 }, /* force TLSv11 */
5255 { "force-tlsv12", srv_parse_force_tlsv12, 0, 0 }, /* force TLSv12 */
Willy Tarreau2a3fb1c2015-02-05 16:47:07 +01005256 { "no-ssl-reuse", srv_parse_no_ssl_reuse, 0, 0 }, /* disable session reuse */
Emeric Brunecc91fe2012-10-11 15:05:10 +02005257 { "no-sslv3", srv_parse_no_sslv3, 0, 0 }, /* disable SSLv3 */
5258 { "no-tlsv10", srv_parse_no_tlsv10, 0, 0 }, /* disable TLSv10 */
5259 { "no-tlsv11", srv_parse_no_tlsv11, 0, 0 }, /* disable TLSv11 */
5260 { "no-tlsv12", srv_parse_no_tlsv12, 0, 0 }, /* disable TLSv12 */
Emeric Brunf9c5c472012-10-11 15:28:34 +02005261 { "no-tls-tickets", srv_parse_no_tls_tickets, 0, 0 }, /* disable session resumption tickets */
David Safb76832014-05-08 23:42:08 -04005262 { "send-proxy-v2-ssl", srv_parse_send_proxy_ssl, 0, 0 }, /* send PROXY protocol header v2 with SSL info */
5263 { "send-proxy-v2-ssl-cn", srv_parse_send_proxy_cn, 0, 0 }, /* send PROXY protocol header v2 with CN */
Willy Tarreau732eac42015-07-09 11:40:25 +02005264 { "sni", srv_parse_sni, 1, 0 }, /* send SNI extension */
Emeric Brunecc91fe2012-10-11 15:05:10 +02005265 { "ssl", srv_parse_ssl, 0, 0 }, /* enable SSL processing */
Emeric Brunef42d922012-10-11 16:11:36 +02005266 { "verify", srv_parse_verify, 1, 0 }, /* set SSL verify method */
Evan Broderbe554312013-06-27 00:05:25 -07005267 { "verifyhost", srv_parse_verifyhost, 1, 0 }, /* require that SSL cert verifies for hostname */
Willy Tarreau92faadf2012-10-10 23:04:25 +02005268 { NULL, NULL, 0, 0 },
5269}};
5270
Emeric Brun2c86cbf2014-10-30 15:56:50 +01005271static struct cfg_kw_list cfg_kws = {ILH, {
5272 { CFG_GLOBAL, "ssl-default-bind-options", ssl_parse_default_bind_options },
5273 { CFG_GLOBAL, "ssl-default-server-options", ssl_parse_default_server_options },
5274 { 0, NULL, NULL },
5275}};
5276
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02005277/* transport-layer operations for SSL sockets */
5278struct xprt_ops ssl_sock = {
Emeric Brun46591952012-05-18 15:47:34 +02005279 .snd_buf = ssl_sock_from_buf,
5280 .rcv_buf = ssl_sock_to_buf,
5281 .rcv_pipe = NULL,
5282 .snd_pipe = NULL,
5283 .shutr = NULL,
5284 .shutw = ssl_sock_shutw,
5285 .close = ssl_sock_close,
5286 .init = ssl_sock_init,
5287};
5288
Janusz Dziemidowicz2c701b52015-03-07 23:03:59 +01005289#if (OPENSSL_VERSION_NUMBER >= 0x1000200fL && !defined OPENSSL_NO_TLSEXT && !defined OPENSSL_IS_BORINGSSL)
5290
5291static void ssl_sock_sctl_free_func(void *parent, void *ptr, CRYPTO_EX_DATA *ad, int idx, long argl, void *argp)
5292{
5293 if (ptr) {
5294 chunk_destroy(ptr);
5295 free(ptr);
5296 }
5297}
5298
5299#endif
5300
Emeric Brun46591952012-05-18 15:47:34 +02005301__attribute__((constructor))
Willy Tarreau92faadf2012-10-10 23:04:25 +02005302static void __ssl_sock_init(void)
5303{
Emeric Brun46591952012-05-18 15:47:34 +02005304 STACK_OF(SSL_COMP)* cm;
5305
Willy Tarreau610f04b2014-02-13 11:36:41 +01005306#ifdef LISTEN_DEFAULT_CIPHERS
5307 global.listen_default_ciphers = LISTEN_DEFAULT_CIPHERS;
5308#endif
5309#ifdef CONNECT_DEFAULT_CIPHERS
5310 global.connect_default_ciphers = CONNECT_DEFAULT_CIPHERS;
5311#endif
5312 if (global.listen_default_ciphers)
5313 global.listen_default_ciphers = strdup(global.listen_default_ciphers);
5314 if (global.connect_default_ciphers)
5315 global.connect_default_ciphers = strdup(global.connect_default_ciphers);
Emeric Brun2c86cbf2014-10-30 15:56:50 +01005316 global.listen_default_ssloptions = BC_SSL_O_NONE;
5317 global.connect_default_ssloptions = SRV_SSL_O_NONE;
Willy Tarreau610f04b2014-02-13 11:36:41 +01005318
Emeric Brun46591952012-05-18 15:47:34 +02005319 SSL_library_init();
5320 cm = SSL_COMP_get_compression_methods();
5321 sk_SSL_COMP_zero(cm);
Janusz Dziemidowicz2c701b52015-03-07 23:03:59 +01005322#if (OPENSSL_VERSION_NUMBER >= 0x1000200fL && !defined OPENSSL_NO_TLSEXT && !defined OPENSSL_IS_BORINGSSL)
5323 sctl_ex_index = SSL_CTX_get_ex_new_index(0, NULL, NULL, NULL, ssl_sock_sctl_free_func);
5324#endif
Willy Tarreau7875d092012-09-10 08:20:03 +02005325 sample_register_fetches(&sample_fetch_keywords);
5326 acl_register_keywords(&acl_kws);
Willy Tarreau79eeafa2012-09-14 07:53:05 +02005327 bind_register_keywords(&bind_kws);
Willy Tarreau92faadf2012-10-10 23:04:25 +02005328 srv_register_keywords(&srv_kws);
Emeric Brun2c86cbf2014-10-30 15:56:50 +01005329 cfg_register_keywords(&cfg_kws);
Willy Tarreaud92aa5c2015-01-15 21:34:39 +01005330
5331 global.ssl_session_max_cost = SSL_SESSION_MAX_COST;
5332 global.ssl_handshake_max_cost = SSL_HANDSHAKE_MAX_COST;
Remi Gacogne4f902b82015-05-28 16:23:00 +02005333
5334#ifndef OPENSSL_NO_DH
5335 ssl_dh_ptr_index = SSL_CTX_get_ex_new_index(0, NULL, NULL, NULL, NULL);
5336#endif
Christopher Faulet31af49d2015-06-09 17:29:50 +02005337
Willy Tarreauc8ad3be2015-06-17 15:48:26 +02005338#ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME
Christopher Faulet31af49d2015-06-09 17:29:50 +02005339 /* Add a global parameter for the LRU cache size */
5340 if (global.tune.ssl_ctx_cache)
5341 ssl_ctx_lru_tree = lru64_new(global.tune.ssl_ctx_cache);
5342 ssl_ctx_lru_seed = (unsigned int)time(NULL);
Willy Tarreauc8ad3be2015-06-17 15:48:26 +02005343#endif
Emeric Brun46591952012-05-18 15:47:34 +02005344}
5345
Remi Gacogned3a23c32015-05-28 16:39:47 +02005346__attribute__((destructor))
5347static void __ssl_sock_deinit(void)
5348{
Willy Tarreauc8ad3be2015-06-17 15:48:26 +02005349#ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME
Christopher Faulet31af49d2015-06-09 17:29:50 +02005350 lru64_destroy(ssl_ctx_lru_tree);
Willy Tarreauc8ad3be2015-06-17 15:48:26 +02005351#endif
Christopher Faulet31af49d2015-06-09 17:29:50 +02005352
Remi Gacogned3a23c32015-05-28 16:39:47 +02005353#ifndef OPENSSL_NO_DH
5354 if (local_dh_1024) {
5355 DH_free(local_dh_1024);
5356 local_dh_1024 = NULL;
5357 }
5358
5359 if (local_dh_2048) {
5360 DH_free(local_dh_2048);
5361 local_dh_2048 = NULL;
5362 }
5363
5364 if (local_dh_4096) {
5365 DH_free(local_dh_4096);
5366 local_dh_4096 = NULL;
5367 }
5368
Remi Gacogne47783ef2015-05-29 15:53:22 +02005369 if (global_dh) {
5370 DH_free(global_dh);
5371 global_dh = NULL;
5372 }
Remi Gacogned3a23c32015-05-28 16:39:47 +02005373#endif
5374
5375 ERR_remove_state(0);
5376 ERR_free_strings();
5377
5378 EVP_cleanup();
5379
5380#if OPENSSL_VERSION_NUMBER >= 0x00907000L
5381 CRYPTO_cleanup_all_ex_data();
5382#endif
5383}
5384
5385
Emeric Brun46591952012-05-18 15:47:34 +02005386/*
5387 * Local variables:
5388 * c-indent-level: 8
5389 * c-basic-offset: 8
5390 * End:
5391 */