blob: aa1d2aedcb50d9cdcfdd153cfbbb706c28d19106 [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
1162 serial = XXH32(servername, strlen(servername), ssl_ctx_lru_seed);
1163 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
Emeric Brun0abf8362014-06-24 18:26:41 +02003295/* Extract peer certificate's common name into the chunk dest
3296 * Returns
3297 * the len of the extracted common name
3298 * or 0 if no CN found in DN
3299 * or -1 on error case (i.e. no peer certificate)
3300 */
3301int ssl_sock_get_remote_common_name(struct connection *conn, struct chunk *dest)
David Safb76832014-05-08 23:42:08 -04003302{
3303 X509 *crt = NULL;
3304 X509_NAME *name;
David Safb76832014-05-08 23:42:08 -04003305 const char find_cn[] = "CN";
3306 const struct chunk find_cn_chunk = {
3307 .str = (char *)&find_cn,
3308 .len = sizeof(find_cn)-1
3309 };
Emeric Brun0abf8362014-06-24 18:26:41 +02003310 int result = -1;
David Safb76832014-05-08 23:42:08 -04003311
3312 if (!ssl_sock_is_ssl(conn))
Emeric Brun0abf8362014-06-24 18:26:41 +02003313 goto out;
David Safb76832014-05-08 23:42:08 -04003314
3315 /* SSL_get_peer_certificate, it increase X509 * ref count */
3316 crt = SSL_get_peer_certificate(conn->xprt_ctx);
3317 if (!crt)
3318 goto out;
3319
3320 name = X509_get_subject_name(crt);
3321 if (!name)
3322 goto out;
David Safb76832014-05-08 23:42:08 -04003323
Emeric Brun0abf8362014-06-24 18:26:41 +02003324 result = ssl_sock_get_dn_entry(name, &find_cn_chunk, 1, dest);
3325out:
David Safb76832014-05-08 23:42:08 -04003326 if (crt)
3327 X509_free(crt);
3328
3329 return result;
3330}
3331
Dave McCowan328fb582014-07-30 10:39:13 -04003332/* returns 1 if client passed a certificate for this session, 0 if not */
3333int ssl_sock_get_cert_used_sess(struct connection *conn)
3334{
3335 X509 *crt = NULL;
3336
3337 if (!ssl_sock_is_ssl(conn))
3338 return 0;
3339
3340 /* SSL_get_peer_certificate, it increase X509 * ref count */
3341 crt = SSL_get_peer_certificate(conn->xprt_ctx);
3342 if (!crt)
3343 return 0;
3344
3345 X509_free(crt);
3346 return 1;
3347}
3348
3349/* returns 1 if client passed a certificate for this connection, 0 if not */
3350int ssl_sock_get_cert_used_conn(struct connection *conn)
David Safb76832014-05-08 23:42:08 -04003351{
3352 if (!ssl_sock_is_ssl(conn))
3353 return 0;
3354
3355 return SSL_SOCK_ST_FL_VERIFY_DONE & conn->xprt_st ? 1 : 0;
3356}
3357
3358/* returns result from SSL verify */
3359unsigned int ssl_sock_get_verify_result(struct connection *conn)
3360{
3361 if (!ssl_sock_is_ssl(conn))
3362 return (unsigned int)X509_V_ERR_APPLICATION_VERIFICATION;
3363
3364 return (unsigned int)SSL_get_verify_result(conn->xprt_ctx);
3365}
3366
Willy Tarreau7875d092012-09-10 08:20:03 +02003367/***** Below are some sample fetching functions for ACL/patterns *****/
3368
Emeric Brune64aef12012-09-21 13:15:06 +02003369/* boolean, returns true if client cert was present */
3370static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02003371smp_fetch_ssl_fc_has_crt(const struct arg *args, struct sample *smp, const char *kw, void *private)
Emeric Brune64aef12012-09-21 13:15:06 +02003372{
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003373 struct connection *conn;
3374
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02003375 conn = objt_conn(smp->sess->origin);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003376 if (!conn || conn->xprt != &ssl_sock)
Emeric Brune64aef12012-09-21 13:15:06 +02003377 return 0;
3378
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003379 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brune64aef12012-09-21 13:15:06 +02003380 smp->flags |= SMP_F_MAY_CHANGE;
3381 return 0;
3382 }
3383
3384 smp->flags = 0;
3385 smp->type = SMP_T_BOOL;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003386 smp->data.uint = SSL_SOCK_ST_FL_VERIFY_DONE & conn->xprt_st ? 1 : 0;
Emeric Brune64aef12012-09-21 13:15:06 +02003387
3388 return 1;
3389}
3390
Emeric Brun43e79582014-10-29 19:03:26 +01003391/* binary, returns a certificate in a binary chunk (der/raw).
3392 * The 5th keyword char is used to know if SSL_get_certificate or SSL_get_peer_certificate
3393 * should be use.
3394 */
3395static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02003396smp_fetch_ssl_x_der(const struct arg *args, struct sample *smp, const char *kw, void *private)
Emeric Brun43e79582014-10-29 19:03:26 +01003397{
3398 int cert_peer = (kw[4] == 'c') ? 1 : 0;
3399 X509 *crt = NULL;
3400 int ret = 0;
3401 struct chunk *smp_trash;
3402 struct connection *conn;
3403
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02003404 conn = objt_conn(smp->sess->origin);
Emeric Brun43e79582014-10-29 19:03:26 +01003405 if (!conn || conn->xprt != &ssl_sock)
3406 return 0;
3407
3408 if (!(conn->flags & CO_FL_CONNECTED)) {
3409 smp->flags |= SMP_F_MAY_CHANGE;
3410 return 0;
3411 }
3412
3413 if (cert_peer)
3414 crt = SSL_get_peer_certificate(conn->xprt_ctx);
3415 else
3416 crt = SSL_get_certificate(conn->xprt_ctx);
3417
3418 if (!crt)
3419 goto out;
3420
3421 smp_trash = get_trash_chunk();
3422 if (ssl_sock_crt2der(crt, smp_trash) <= 0)
3423 goto out;
3424
3425 smp->data.str = *smp_trash;
3426 smp->type = SMP_T_BIN;
3427 ret = 1;
3428out:
3429 /* SSL_get_peer_certificate, it increase X509 * ref count */
3430 if (cert_peer && crt)
3431 X509_free(crt);
3432 return ret;
3433}
3434
Emeric Brunba841a12014-04-30 17:05:08 +02003435/* binary, returns serial of certificate in a binary chunk.
3436 * The 5th keyword char is used to know if SSL_get_certificate or SSL_get_peer_certificate
3437 * should be use.
3438 */
Willy Tarreau8d598402012-10-22 17:58:39 +02003439static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02003440smp_fetch_ssl_x_serial(const struct arg *args, struct sample *smp, const char *kw, void *private)
Willy Tarreau8d598402012-10-22 17:58:39 +02003441{
Emeric Brunba841a12014-04-30 17:05:08 +02003442 int cert_peer = (kw[4] == 'c') ? 1 : 0;
Willy Tarreau8d598402012-10-22 17:58:39 +02003443 X509 *crt = NULL;
3444 int ret = 0;
3445 struct chunk *smp_trash;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003446 struct connection *conn;
3447
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02003448 conn = objt_conn(smp->sess->origin);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003449 if (!conn || conn->xprt != &ssl_sock)
Willy Tarreau8d598402012-10-22 17:58:39 +02003450 return 0;
3451
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003452 if (!(conn->flags & CO_FL_CONNECTED)) {
Willy Tarreau8d598402012-10-22 17:58:39 +02003453 smp->flags |= SMP_F_MAY_CHANGE;
3454 return 0;
3455 }
3456
Emeric Brunba841a12014-04-30 17:05:08 +02003457 if (cert_peer)
3458 crt = SSL_get_peer_certificate(conn->xprt_ctx);
3459 else
3460 crt = SSL_get_certificate(conn->xprt_ctx);
3461
Willy Tarreau8d598402012-10-22 17:58:39 +02003462 if (!crt)
3463 goto out;
3464
Willy Tarreau47ca5452012-12-23 20:22:19 +01003465 smp_trash = get_trash_chunk();
Willy Tarreau8d598402012-10-22 17:58:39 +02003466 if (ssl_sock_get_serial(crt, smp_trash) <= 0)
3467 goto out;
3468
3469 smp->data.str = *smp_trash;
3470 smp->type = SMP_T_BIN;
3471 ret = 1;
3472out:
Emeric Brunba841a12014-04-30 17:05:08 +02003473 /* SSL_get_peer_certificate, it increase X509 * ref count */
3474 if (cert_peer && crt)
Willy Tarreau8d598402012-10-22 17:58:39 +02003475 X509_free(crt);
3476 return ret;
3477}
Emeric Brune64aef12012-09-21 13:15:06 +02003478
Emeric Brunba841a12014-04-30 17:05:08 +02003479/* binary, returns the client certificate's SHA-1 fingerprint (SHA-1 hash of DER-encoded certificate) in a binary chunk.
3480 * The 5th keyword char is used to know if SSL_get_certificate or SSL_get_peer_certificate
3481 * should be use.
3482 */
James Votha051b4a2013-05-14 20:37:59 +02003483static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02003484smp_fetch_ssl_x_sha1(const struct arg *args, struct sample *smp, const char *kw, void *private)
James Votha051b4a2013-05-14 20:37:59 +02003485{
Emeric Brunba841a12014-04-30 17:05:08 +02003486 int cert_peer = (kw[4] == 'c') ? 1 : 0;
James Votha051b4a2013-05-14 20:37:59 +02003487 X509 *crt = NULL;
3488 const EVP_MD *digest;
3489 int ret = 0;
3490 struct chunk *smp_trash;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003491 struct connection *conn;
James Votha051b4a2013-05-14 20:37:59 +02003492
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02003493 conn = objt_conn(smp->sess->origin);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003494 if (!conn || conn->xprt != &ssl_sock)
3495 return 0;
3496
3497 if (!(conn->flags & CO_FL_CONNECTED)) {
James Votha051b4a2013-05-14 20:37:59 +02003498 smp->flags |= SMP_F_MAY_CHANGE;
3499 return 0;
3500 }
3501
Emeric Brunba841a12014-04-30 17:05:08 +02003502 if (cert_peer)
3503 crt = SSL_get_peer_certificate(conn->xprt_ctx);
3504 else
3505 crt = SSL_get_certificate(conn->xprt_ctx);
James Votha051b4a2013-05-14 20:37:59 +02003506 if (!crt)
3507 goto out;
3508
3509 smp_trash = get_trash_chunk();
3510 digest = EVP_sha1();
3511 X509_digest(crt, digest, (unsigned char *)smp_trash->str, (unsigned int *)&smp_trash->len);
3512
3513 smp->data.str = *smp_trash;
3514 smp->type = SMP_T_BIN;
3515 ret = 1;
3516out:
Emeric Brunba841a12014-04-30 17:05:08 +02003517 /* SSL_get_peer_certificate, it increase X509 * ref count */
3518 if (cert_peer && crt)
James Votha051b4a2013-05-14 20:37:59 +02003519 X509_free(crt);
3520 return ret;
3521}
3522
Emeric Brunba841a12014-04-30 17:05:08 +02003523/* string, returns certificate's notafter date in ASN1_UTCTIME format.
3524 * The 5th keyword char is used to know if SSL_get_certificate or SSL_get_peer_certificate
3525 * should be use.
3526 */
Emeric Brunce5ad802012-10-22 14:11:22 +02003527static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02003528smp_fetch_ssl_x_notafter(const struct arg *args, struct sample *smp, const char *kw, void *private)
Emeric Brunce5ad802012-10-22 14:11:22 +02003529{
Emeric Brunba841a12014-04-30 17:05:08 +02003530 int cert_peer = (kw[4] == 'c') ? 1 : 0;
Emeric Brunce5ad802012-10-22 14:11:22 +02003531 X509 *crt = NULL;
3532 int ret = 0;
3533 struct chunk *smp_trash;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003534 struct connection *conn;
Emeric Brunce5ad802012-10-22 14:11:22 +02003535
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02003536 conn = objt_conn(smp->sess->origin);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003537 if (!conn || conn->xprt != &ssl_sock)
3538 return 0;
3539
3540 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brunce5ad802012-10-22 14:11:22 +02003541 smp->flags |= SMP_F_MAY_CHANGE;
3542 return 0;
3543 }
3544
Emeric Brunba841a12014-04-30 17:05:08 +02003545 if (cert_peer)
3546 crt = SSL_get_peer_certificate(conn->xprt_ctx);
3547 else
3548 crt = SSL_get_certificate(conn->xprt_ctx);
Emeric Brunce5ad802012-10-22 14:11:22 +02003549 if (!crt)
3550 goto out;
3551
Willy Tarreau47ca5452012-12-23 20:22:19 +01003552 smp_trash = get_trash_chunk();
Emeric Brunce5ad802012-10-22 14:11:22 +02003553 if (ssl_sock_get_time(X509_get_notAfter(crt), smp_trash) <= 0)
3554 goto out;
3555
3556 smp->data.str = *smp_trash;
3557 smp->type = SMP_T_STR;
3558 ret = 1;
3559out:
Emeric Brunba841a12014-04-30 17:05:08 +02003560 /* SSL_get_peer_certificate, it increase X509 * ref count */
3561 if (cert_peer && crt)
Emeric Brunce5ad802012-10-22 14:11:22 +02003562 X509_free(crt);
3563 return ret;
3564}
3565
Emeric Brunba841a12014-04-30 17:05:08 +02003566/* string, returns a string of a formatted full dn \C=..\O=..\OU=.. \CN=.. of certificate's issuer
3567 * The 5th keyword char is used to know if SSL_get_certificate or SSL_get_peer_certificate
3568 * should be use.
3569 */
Emeric Brun87855892012-10-17 17:39:35 +02003570static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02003571smp_fetch_ssl_x_i_dn(const struct arg *args, struct sample *smp, const char *kw, void *private)
Emeric Brun87855892012-10-17 17:39:35 +02003572{
Emeric Brunba841a12014-04-30 17:05:08 +02003573 int cert_peer = (kw[4] == 'c') ? 1 : 0;
Emeric Brun87855892012-10-17 17:39:35 +02003574 X509 *crt = NULL;
3575 X509_NAME *name;
3576 int ret = 0;
3577 struct chunk *smp_trash;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003578 struct connection *conn;
Emeric Brun87855892012-10-17 17:39:35 +02003579
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02003580 conn = objt_conn(smp->sess->origin);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003581 if (!conn || conn->xprt != &ssl_sock)
3582 return 0;
3583
3584 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brun87855892012-10-17 17:39:35 +02003585 smp->flags |= SMP_F_MAY_CHANGE;
3586 return 0;
3587 }
3588
Emeric Brunba841a12014-04-30 17:05:08 +02003589 if (cert_peer)
3590 crt = SSL_get_peer_certificate(conn->xprt_ctx);
3591 else
3592 crt = SSL_get_certificate(conn->xprt_ctx);
Emeric Brun87855892012-10-17 17:39:35 +02003593 if (!crt)
3594 goto out;
3595
3596 name = X509_get_issuer_name(crt);
3597 if (!name)
3598 goto out;
3599
Willy Tarreau47ca5452012-12-23 20:22:19 +01003600 smp_trash = get_trash_chunk();
Emeric Brun87855892012-10-17 17:39:35 +02003601 if (args && args[0].type == ARGT_STR) {
3602 int pos = 1;
3603
3604 if (args[1].type == ARGT_SINT)
3605 pos = args[1].data.sint;
3606 else if (args[1].type == ARGT_UINT)
3607 pos =(int)args[1].data.uint;
3608
3609 if (ssl_sock_get_dn_entry(name, &args[0].data.str, pos, smp_trash) <= 0)
3610 goto out;
3611 }
3612 else if (ssl_sock_get_dn_oneline(name, smp_trash) <= 0)
3613 goto out;
3614
3615 smp->type = SMP_T_STR;
3616 smp->data.str = *smp_trash;
3617 ret = 1;
3618out:
Emeric Brunba841a12014-04-30 17:05:08 +02003619 /* SSL_get_peer_certificate, it increase X509 * ref count */
3620 if (cert_peer && crt)
Emeric Brun87855892012-10-17 17:39:35 +02003621 X509_free(crt);
3622 return ret;
3623}
3624
Emeric Brunba841a12014-04-30 17:05:08 +02003625/* string, returns notbefore date in ASN1_UTCTIME format.
3626 * The 5th keyword char is used to know if SSL_get_certificate or SSL_get_peer_certificate
3627 * should be use.
3628 */
Emeric Brunce5ad802012-10-22 14:11:22 +02003629static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02003630smp_fetch_ssl_x_notbefore(const struct arg *args, struct sample *smp, const char *kw, void *private)
Emeric Brunce5ad802012-10-22 14:11:22 +02003631{
Emeric Brunba841a12014-04-30 17:05:08 +02003632 int cert_peer = (kw[4] == 'c') ? 1 : 0;
Emeric Brunce5ad802012-10-22 14:11:22 +02003633 X509 *crt = NULL;
3634 int ret = 0;
3635 struct chunk *smp_trash;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003636 struct connection *conn;
3637
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02003638 conn = objt_conn(smp->sess->origin);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003639 if (!conn || conn->xprt != &ssl_sock)
Emeric Brunce5ad802012-10-22 14:11:22 +02003640 return 0;
3641
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003642 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brunce5ad802012-10-22 14:11:22 +02003643 smp->flags |= SMP_F_MAY_CHANGE;
3644 return 0;
3645 }
3646
Emeric Brunba841a12014-04-30 17:05:08 +02003647 if (cert_peer)
3648 crt = SSL_get_peer_certificate(conn->xprt_ctx);
3649 else
3650 crt = SSL_get_certificate(conn->xprt_ctx);
Emeric Brunce5ad802012-10-22 14:11:22 +02003651 if (!crt)
3652 goto out;
3653
Willy Tarreau47ca5452012-12-23 20:22:19 +01003654 smp_trash = get_trash_chunk();
Emeric Brunce5ad802012-10-22 14:11:22 +02003655 if (ssl_sock_get_time(X509_get_notBefore(crt), smp_trash) <= 0)
3656 goto out;
3657
3658 smp->data.str = *smp_trash;
3659 smp->type = SMP_T_STR;
3660 ret = 1;
3661out:
Emeric Brunba841a12014-04-30 17:05:08 +02003662 /* SSL_get_peer_certificate, it increase X509 * ref count */
3663 if (cert_peer && crt)
Emeric Brunce5ad802012-10-22 14:11:22 +02003664 X509_free(crt);
3665 return ret;
3666}
3667
Emeric Brunba841a12014-04-30 17:05:08 +02003668/* string, returns a string of a formatted full dn \C=..\O=..\OU=.. \CN=.. of certificate's subject
3669 * The 5th keyword char is used to know if SSL_get_certificate or SSL_get_peer_certificate
3670 * should be use.
3671 */
Emeric Brun87855892012-10-17 17:39:35 +02003672static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02003673smp_fetch_ssl_x_s_dn(const struct arg *args, struct sample *smp, const char *kw, void *private)
Emeric Brun87855892012-10-17 17:39:35 +02003674{
Emeric Brunba841a12014-04-30 17:05:08 +02003675 int cert_peer = (kw[4] == 'c') ? 1 : 0;
Emeric Brun87855892012-10-17 17:39:35 +02003676 X509 *crt = NULL;
3677 X509_NAME *name;
3678 int ret = 0;
3679 struct chunk *smp_trash;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003680 struct connection *conn;
Emeric Brun87855892012-10-17 17:39:35 +02003681
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02003682 conn = objt_conn(smp->sess->origin);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003683 if (!conn || conn->xprt != &ssl_sock)
3684 return 0;
3685
3686 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brun87855892012-10-17 17:39:35 +02003687 smp->flags |= SMP_F_MAY_CHANGE;
3688 return 0;
3689 }
3690
Emeric Brunba841a12014-04-30 17:05:08 +02003691 if (cert_peer)
3692 crt = SSL_get_peer_certificate(conn->xprt_ctx);
3693 else
3694 crt = SSL_get_certificate(conn->xprt_ctx);
Emeric Brun87855892012-10-17 17:39:35 +02003695 if (!crt)
3696 goto out;
3697
3698 name = X509_get_subject_name(crt);
3699 if (!name)
3700 goto out;
3701
Willy Tarreau47ca5452012-12-23 20:22:19 +01003702 smp_trash = get_trash_chunk();
Emeric Brun87855892012-10-17 17:39:35 +02003703 if (args && args[0].type == ARGT_STR) {
3704 int pos = 1;
3705
3706 if (args[1].type == ARGT_SINT)
3707 pos = args[1].data.sint;
3708 else if (args[1].type == ARGT_UINT)
3709 pos =(int)args[1].data.uint;
3710
3711 if (ssl_sock_get_dn_entry(name, &args[0].data.str, pos, smp_trash) <= 0)
3712 goto out;
3713 }
3714 else if (ssl_sock_get_dn_oneline(name, smp_trash) <= 0)
3715 goto out;
3716
3717 smp->type = SMP_T_STR;
3718 smp->data.str = *smp_trash;
3719 ret = 1;
3720out:
Emeric Brunba841a12014-04-30 17:05:08 +02003721 /* SSL_get_peer_certificate, it increase X509 * ref count */
3722 if (cert_peer && crt)
Emeric Brun87855892012-10-17 17:39:35 +02003723 X509_free(crt);
3724 return ret;
3725}
Emeric Brun9143d372012-12-20 15:44:16 +01003726
3727/* integer, returns true if current session use a client certificate */
3728static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02003729smp_fetch_ssl_c_used(const struct arg *args, struct sample *smp, const char *kw, void *private)
Emeric Brun9143d372012-12-20 15:44:16 +01003730{
3731 X509 *crt;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003732 struct connection *conn;
Emeric Brun9143d372012-12-20 15:44:16 +01003733
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02003734 conn = objt_conn(smp->sess->origin);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003735 if (!conn || conn->xprt != &ssl_sock)
3736 return 0;
3737
3738 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brun9143d372012-12-20 15:44:16 +01003739 smp->flags |= SMP_F_MAY_CHANGE;
3740 return 0;
3741 }
3742
3743 /* SSL_get_peer_certificate returns a ptr on allocated X509 struct */
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003744 crt = SSL_get_peer_certificate(conn->xprt_ctx);
Emeric Brun9143d372012-12-20 15:44:16 +01003745 if (crt) {
3746 X509_free(crt);
3747 }
3748
3749 smp->type = SMP_T_BOOL;
3750 smp->data.uint = (crt != NULL);
3751 return 1;
3752}
3753
Emeric Brunba841a12014-04-30 17:05:08 +02003754/* integer, returns the certificate version
3755 * The 5th keyword char is used to know if SSL_get_certificate or SSL_get_peer_certificate
3756 * should be use.
3757 */
Emeric Bruna7359fd2012-10-17 15:03:11 +02003758static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02003759smp_fetch_ssl_x_version(const struct arg *args, struct sample *smp, const char *kw, void *private)
Emeric Bruna7359fd2012-10-17 15:03:11 +02003760{
Emeric Brunba841a12014-04-30 17:05:08 +02003761 int cert_peer = (kw[4] == 'c') ? 1 : 0;
Emeric Bruna7359fd2012-10-17 15:03:11 +02003762 X509 *crt;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003763 struct connection *conn;
3764
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02003765 conn = objt_conn(smp->sess->origin);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003766 if (!conn || conn->xprt != &ssl_sock)
Emeric Bruna7359fd2012-10-17 15:03:11 +02003767 return 0;
3768
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003769 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Bruna7359fd2012-10-17 15:03:11 +02003770 smp->flags |= SMP_F_MAY_CHANGE;
3771 return 0;
3772 }
3773
Emeric Brunba841a12014-04-30 17:05:08 +02003774 if (cert_peer)
3775 crt = SSL_get_peer_certificate(conn->xprt_ctx);
3776 else
3777 crt = SSL_get_certificate(conn->xprt_ctx);
Emeric Bruna7359fd2012-10-17 15:03:11 +02003778 if (!crt)
3779 return 0;
3780
3781 smp->data.uint = (unsigned int)(1 + X509_get_version(crt));
Emeric Brunba841a12014-04-30 17:05:08 +02003782 /* SSL_get_peer_certificate increase X509 * ref count */
3783 if (cert_peer)
3784 X509_free(crt);
Emeric Bruna7359fd2012-10-17 15:03:11 +02003785 smp->type = SMP_T_UINT;
3786
3787 return 1;
3788}
3789
Emeric Brunba841a12014-04-30 17:05:08 +02003790/* string, returns the certificate's signature algorithm.
3791 * The 5th keyword char is used to know if SSL_get_certificate or SSL_get_peer_certificate
3792 * should be use.
3793 */
Emeric Brun7f56e742012-10-19 18:15:40 +02003794static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02003795smp_fetch_ssl_x_sig_alg(const struct arg *args, struct sample *smp, const char *kw, void *private)
Emeric Brun7f56e742012-10-19 18:15:40 +02003796{
Emeric Brunba841a12014-04-30 17:05:08 +02003797 int cert_peer = (kw[4] == 'c') ? 1 : 0;
Emeric Brun7f56e742012-10-19 18:15:40 +02003798 X509 *crt;
3799 int nid;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003800 struct connection *conn;
Emeric Brun7f56e742012-10-19 18:15:40 +02003801
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02003802 conn = objt_conn(smp->sess->origin);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003803 if (!conn || conn->xprt != &ssl_sock)
3804 return 0;
3805
3806 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brun7f56e742012-10-19 18:15:40 +02003807 smp->flags |= SMP_F_MAY_CHANGE;
3808 return 0;
3809 }
3810
Emeric Brunba841a12014-04-30 17:05:08 +02003811 if (cert_peer)
3812 crt = SSL_get_peer_certificate(conn->xprt_ctx);
3813 else
3814 crt = SSL_get_certificate(conn->xprt_ctx);
Emeric Brun7f56e742012-10-19 18:15:40 +02003815 if (!crt)
3816 return 0;
3817
3818 nid = OBJ_obj2nid((ASN1_OBJECT *)(crt->cert_info->signature->algorithm));
3819
3820 smp->data.str.str = (char *)OBJ_nid2sn(nid);
Emeric Brun9bf3ba22013-10-07 14:31:44 +02003821 if (!smp->data.str.str) {
Emeric Brunba841a12014-04-30 17:05:08 +02003822 /* SSL_get_peer_certificate increase X509 * ref count */
3823 if (cert_peer)
3824 X509_free(crt);
Emeric Brun7f56e742012-10-19 18:15:40 +02003825 return 0;
Emeric Brun9bf3ba22013-10-07 14:31:44 +02003826 }
Emeric Brun7f56e742012-10-19 18:15:40 +02003827
Thierry FOURNIER7654c9f2013-12-17 00:20:33 +01003828 smp->type = SMP_T_STR;
3829 smp->flags |= SMP_F_CONST;
Emeric Brun7f56e742012-10-19 18:15:40 +02003830 smp->data.str.len = strlen(smp->data.str.str);
Emeric Brunba841a12014-04-30 17:05:08 +02003831 /* SSL_get_peer_certificate increase X509 * ref count */
3832 if (cert_peer)
3833 X509_free(crt);
Emeric Brun7f56e742012-10-19 18:15:40 +02003834
3835 return 1;
3836}
3837
Emeric Brunba841a12014-04-30 17:05:08 +02003838/* string, returns the certificate's key algorithm.
3839 * The 5th keyword char is used to know if SSL_get_certificate or SSL_get_peer_certificate
3840 * should be use.
3841 */
Emeric Brun521a0112012-10-22 12:22:55 +02003842static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02003843smp_fetch_ssl_x_key_alg(const struct arg *args, struct sample *smp, const char *kw, void *private)
Emeric Brun521a0112012-10-22 12:22:55 +02003844{
Emeric Brunba841a12014-04-30 17:05:08 +02003845 int cert_peer = (kw[4] == 'c') ? 1 : 0;
Emeric Brun521a0112012-10-22 12:22:55 +02003846 X509 *crt;
3847 int nid;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003848 struct connection *conn;
Emeric Brun521a0112012-10-22 12:22:55 +02003849
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02003850 conn = objt_conn(smp->sess->origin);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003851 if (!conn || conn->xprt != &ssl_sock)
3852 return 0;
3853
3854 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brun521a0112012-10-22 12:22:55 +02003855 smp->flags |= SMP_F_MAY_CHANGE;
3856 return 0;
3857 }
3858
Emeric Brunba841a12014-04-30 17:05:08 +02003859 if (cert_peer)
3860 crt = SSL_get_peer_certificate(conn->xprt_ctx);
3861 else
3862 crt = SSL_get_certificate(conn->xprt_ctx);
Emeric Brun521a0112012-10-22 12:22:55 +02003863 if (!crt)
3864 return 0;
3865
3866 nid = OBJ_obj2nid((ASN1_OBJECT *)(crt->cert_info->key->algor->algorithm));
3867
3868 smp->data.str.str = (char *)OBJ_nid2sn(nid);
Emeric Brun9bf3ba22013-10-07 14:31:44 +02003869 if (!smp->data.str.str) {
Emeric Brunba841a12014-04-30 17:05:08 +02003870 /* SSL_get_peer_certificate increase X509 * ref count */
3871 if (cert_peer)
3872 X509_free(crt);
Emeric Brun521a0112012-10-22 12:22:55 +02003873 return 0;
Emeric Brun9bf3ba22013-10-07 14:31:44 +02003874 }
Emeric Brun521a0112012-10-22 12:22:55 +02003875
Thierry FOURNIER7654c9f2013-12-17 00:20:33 +01003876 smp->type = SMP_T_STR;
3877 smp->flags |= SMP_F_CONST;
Emeric Brun521a0112012-10-22 12:22:55 +02003878 smp->data.str.len = strlen(smp->data.str.str);
Emeric Brunba841a12014-04-30 17:05:08 +02003879 if (cert_peer)
3880 X509_free(crt);
Emeric Brun521a0112012-10-22 12:22:55 +02003881
3882 return 1;
3883}
3884
Emeric Brun645ae792014-04-30 14:21:06 +02003885/* boolean, returns true if front conn. transport layer is SSL.
3886 * This function is also usable on backend conn if the fetch keyword 5th
3887 * char is 'b'.
3888 */
Willy Tarreau7875d092012-09-10 08:20:03 +02003889static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02003890smp_fetch_ssl_fc(const struct arg *args, struct sample *smp, const char *kw, void *private)
Willy Tarreau7875d092012-09-10 08:20:03 +02003891{
Emeric Brun645ae792014-04-30 14:21:06 +02003892 int back_conn = (kw[4] == 'b') ? 1 : 0;
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02003893 struct connection *conn = objt_conn(smp->strm->si[back_conn].end);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003894
Willy Tarreau7875d092012-09-10 08:20:03 +02003895 smp->type = SMP_T_BOOL;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003896 smp->data.uint = (conn && conn->xprt == &ssl_sock);
Willy Tarreau7875d092012-09-10 08:20:03 +02003897 return 1;
3898}
3899
Emeric Brun2525b6b2012-10-18 15:59:43 +02003900/* boolean, returns true if client present a SNI */
Willy Tarreau7875d092012-09-10 08:20:03 +02003901static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02003902smp_fetch_ssl_fc_has_sni(const struct arg *args, struct sample *smp, const char *kw, void *private)
Willy Tarreau7875d092012-09-10 08:20:03 +02003903{
3904#ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02003905 struct connection *conn = objt_conn(smp->sess->origin);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003906
Willy Tarreau7875d092012-09-10 08:20:03 +02003907 smp->type = SMP_T_BOOL;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003908 smp->data.uint = (conn && conn->xprt == &ssl_sock) &&
3909 conn->xprt_ctx &&
3910 SSL_get_servername(conn->xprt_ctx, TLSEXT_NAMETYPE_host_name) != NULL;
Willy Tarreau7875d092012-09-10 08:20:03 +02003911 return 1;
3912#else
3913 return 0;
3914#endif
3915}
3916
Nenad Merdanovic26ea8222015-05-18 02:28:57 +02003917/* boolean, returns true if client session has been resumed */
3918static int
3919smp_fetch_ssl_fc_is_resumed(const struct arg *args, struct sample *smp, const char *kw, void *private)
3920{
3921 struct connection *conn = objt_conn(smp->sess->origin);
3922
3923 smp->type = SMP_T_BOOL;
3924 smp->data.uint = (conn && conn->xprt == &ssl_sock) &&
3925 conn->xprt_ctx &&
3926 SSL_session_reused(conn->xprt_ctx);
3927 return 1;
3928}
3929
Emeric Brun645ae792014-04-30 14:21:06 +02003930/* string, returns the used cipher if front conn. transport layer is SSL.
3931 * This function is also usable on backend conn if the fetch keyword 5th
3932 * char is 'b'.
3933 */
Emeric Brun589fcad2012-10-16 14:13:26 +02003934static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02003935smp_fetch_ssl_fc_cipher(const struct arg *args, struct sample *smp, const char *kw, void *private)
Emeric Brun589fcad2012-10-16 14:13:26 +02003936{
Emeric Brun645ae792014-04-30 14:21:06 +02003937 int back_conn = (kw[4] == 'b') ? 1 : 0;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003938 struct connection *conn;
3939
Emeric Brun589fcad2012-10-16 14:13:26 +02003940 smp->flags = 0;
3941
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02003942 conn = objt_conn(smp->strm->si[back_conn].end);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003943 if (!conn || !conn->xprt_ctx || conn->xprt != &ssl_sock)
Emeric Brun589fcad2012-10-16 14:13:26 +02003944 return 0;
3945
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003946 smp->data.str.str = (char *)SSL_get_cipher_name(conn->xprt_ctx);
Emeric Brun589fcad2012-10-16 14:13:26 +02003947 if (!smp->data.str.str)
3948 return 0;
3949
Thierry FOURNIER7654c9f2013-12-17 00:20:33 +01003950 smp->type = SMP_T_STR;
3951 smp->flags |= SMP_F_CONST;
Emeric Brun589fcad2012-10-16 14:13:26 +02003952 smp->data.str.len = strlen(smp->data.str.str);
3953
3954 return 1;
3955}
3956
Emeric Brun645ae792014-04-30 14:21:06 +02003957/* integer, returns the algoritm's keysize if front conn. transport layer
3958 * is SSL.
3959 * This function is also usable on backend conn if the fetch keyword 5th
3960 * char is 'b'.
3961 */
Emeric Brun589fcad2012-10-16 14:13:26 +02003962static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02003963smp_fetch_ssl_fc_alg_keysize(const struct arg *args, struct sample *smp, const char *kw, void *private)
Emeric Brun589fcad2012-10-16 14:13:26 +02003964{
Emeric Brun645ae792014-04-30 14:21:06 +02003965 int back_conn = (kw[4] == 'b') ? 1 : 0;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003966 struct connection *conn;
3967
Emeric Brun589fcad2012-10-16 14:13:26 +02003968 smp->flags = 0;
3969
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02003970 conn = objt_conn(smp->strm->si[back_conn].end);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003971 if (!conn || !conn->xprt_ctx || conn->xprt != &ssl_sock)
Emeric Brun589fcad2012-10-16 14:13:26 +02003972 return 0;
3973
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003974 if (!SSL_get_cipher_bits(conn->xprt_ctx, (int *)&smp->data.uint))
3975 return 0;
3976
Emeric Brun589fcad2012-10-16 14:13:26 +02003977 smp->type = SMP_T_UINT;
3978
3979 return 1;
3980}
3981
Emeric Brun645ae792014-04-30 14:21:06 +02003982/* integer, returns the used keysize if front conn. transport layer is SSL.
3983 * This function is also usable on backend conn if the fetch keyword 5th
3984 * char is 'b'.
3985 */
Emeric Brun589fcad2012-10-16 14:13:26 +02003986static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02003987smp_fetch_ssl_fc_use_keysize(const struct arg *args, struct sample *smp, const char *kw, void *private)
Emeric Brun589fcad2012-10-16 14:13:26 +02003988{
Emeric Brun645ae792014-04-30 14:21:06 +02003989 int back_conn = (kw[4] == 'b') ? 1 : 0;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003990 struct connection *conn;
3991
Emeric Brun589fcad2012-10-16 14:13:26 +02003992 smp->flags = 0;
3993
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02003994 conn = objt_conn(smp->strm->si[back_conn].end);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003995 if (!conn || !conn->xprt_ctx || conn->xprt != &ssl_sock)
3996 return 0;
3997
3998 smp->data.uint = (unsigned int)SSL_get_cipher_bits(conn->xprt_ctx, NULL);
Emeric Brun589fcad2012-10-16 14:13:26 +02003999 if (!smp->data.uint)
4000 return 0;
4001
4002 smp->type = SMP_T_UINT;
4003
4004 return 1;
4005}
4006
Willy Tarreau6c9a3d52012-10-18 18:57:14 +02004007#ifdef OPENSSL_NPN_NEGOTIATED
Willy Tarreau7875d092012-09-10 08:20:03 +02004008static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02004009smp_fetch_ssl_fc_npn(const struct arg *args, struct sample *smp, const char *kw, void *private)
Willy Tarreaua33c6542012-10-15 13:19:06 +02004010{
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004011 struct connection *conn;
4012
Thierry FOURNIER7654c9f2013-12-17 00:20:33 +01004013 smp->flags = SMP_F_CONST;
4014 smp->type = SMP_T_STR;
Willy Tarreaua33c6542012-10-15 13:19:06 +02004015
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02004016 conn = objt_conn(smp->sess->origin);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004017 if (!conn || !conn->xprt_ctx || conn->xprt != &ssl_sock)
4018 return 0;
4019
Willy Tarreaua33c6542012-10-15 13:19:06 +02004020 smp->data.str.str = NULL;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004021 SSL_get0_next_proto_negotiated(conn->xprt_ctx,
Willy Tarreaua33c6542012-10-15 13:19:06 +02004022 (const unsigned char **)&smp->data.str.str, (unsigned *)&smp->data.str.len);
4023
4024 if (!smp->data.str.str)
4025 return 0;
4026
4027 return 1;
Willy Tarreaua33c6542012-10-15 13:19:06 +02004028}
Willy Tarreau6c9a3d52012-10-18 18:57:14 +02004029#endif
Willy Tarreaua33c6542012-10-15 13:19:06 +02004030
Dirkjan Bussink48f1c4e2014-02-13 12:29:42 +01004031#ifdef TLSEXT_TYPE_application_layer_protocol_negotiation
Willy Tarreauab861d32013-04-02 02:30:41 +02004032static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02004033smp_fetch_ssl_fc_alpn(const struct arg *args, struct sample *smp, const char *kw, void *private)
Willy Tarreauab861d32013-04-02 02:30:41 +02004034{
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004035 struct connection *conn;
4036
Thierry FOURNIER7654c9f2013-12-17 00:20:33 +01004037 smp->flags = SMP_F_CONST;
4038 smp->type = SMP_T_STR;
Willy Tarreauab861d32013-04-02 02:30:41 +02004039
Willy Tarreaue26bf052015-05-12 10:30:12 +02004040 conn = objt_conn(smp->sess->origin);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004041 if (!conn || !conn->xprt_ctx || conn->xprt != &ssl_sock)
Willy Tarreauab861d32013-04-02 02:30:41 +02004042 return 0;
4043
4044 smp->data.str.str = NULL;
Dirkjan Bussink48f1c4e2014-02-13 12:29:42 +01004045 SSL_get0_alpn_selected(conn->xprt_ctx,
Willy Tarreauab861d32013-04-02 02:30:41 +02004046 (const unsigned char **)&smp->data.str.str, (unsigned *)&smp->data.str.len);
4047
4048 if (!smp->data.str.str)
4049 return 0;
4050
4051 return 1;
4052}
4053#endif
4054
Emeric Brun645ae792014-04-30 14:21:06 +02004055/* string, returns the used protocol if front conn. transport layer is SSL.
4056 * This function is also usable on backend conn if the fetch keyword 5th
4057 * char is 'b'.
4058 */
Willy Tarreaua33c6542012-10-15 13:19:06 +02004059static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02004060smp_fetch_ssl_fc_protocol(const struct arg *args, struct sample *smp, const char *kw, void *private)
Emeric Brun589fcad2012-10-16 14:13:26 +02004061{
Emeric Brun645ae792014-04-30 14:21:06 +02004062 int back_conn = (kw[4] == 'b') ? 1 : 0;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004063 struct connection *conn;
4064
Emeric Brun589fcad2012-10-16 14:13:26 +02004065 smp->flags = 0;
4066
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02004067 conn = objt_conn(smp->strm->si[back_conn].end);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004068 if (!conn || !conn->xprt_ctx || conn->xprt != &ssl_sock)
4069 return 0;
4070
4071 smp->data.str.str = (char *)SSL_get_version(conn->xprt_ctx);
Emeric Brun589fcad2012-10-16 14:13:26 +02004072 if (!smp->data.str.str)
4073 return 0;
4074
Thierry FOURNIER7654c9f2013-12-17 00:20:33 +01004075 smp->type = SMP_T_STR;
4076 smp->flags = SMP_F_CONST;
Emeric Brun589fcad2012-10-16 14:13:26 +02004077 smp->data.str.len = strlen(smp->data.str.str);
4078
4079 return 1;
4080}
4081
Willy Tarreau87b09662015-04-03 00:22:06 +02004082/* binary, returns the SSL stream id if front conn. transport layer is SSL.
Emeric Brun645ae792014-04-30 14:21:06 +02004083 * This function is also usable on backend conn if the fetch keyword 5th
4084 * char is 'b'.
4085 */
Emeric Brun589fcad2012-10-16 14:13:26 +02004086static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02004087smp_fetch_ssl_fc_session_id(const struct arg *args, struct sample *smp, const char *kw, void *private)
Emeric Brunfe68f682012-10-16 14:59:28 +02004088{
4089#if OPENSSL_VERSION_NUMBER > 0x0090800fL
Emeric Brun645ae792014-04-30 14:21:06 +02004090 int back_conn = (kw[4] == 'b') ? 1 : 0;
Willy Tarreau192252e2015-04-04 01:47:55 +02004091 SSL_SESSION *ssl_sess;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004092 struct connection *conn;
Emeric Brunfe68f682012-10-16 14:59:28 +02004093
Thierry FOURNIER7654c9f2013-12-17 00:20:33 +01004094 smp->flags = SMP_F_CONST;
4095 smp->type = SMP_T_BIN;
Emeric Brunfe68f682012-10-16 14:59:28 +02004096
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02004097 conn = objt_conn(smp->strm->si[back_conn].end);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004098 if (!conn || !conn->xprt_ctx || conn->xprt != &ssl_sock)
4099 return 0;
4100
Willy Tarreau192252e2015-04-04 01:47:55 +02004101 ssl_sess = SSL_get_session(conn->xprt_ctx);
4102 if (!ssl_sess)
Emeric Brunfe68f682012-10-16 14:59:28 +02004103 return 0;
4104
Willy Tarreau192252e2015-04-04 01:47:55 +02004105 smp->data.str.str = (char *)SSL_SESSION_get_id(ssl_sess, (unsigned int *)&smp->data.str.len);
Willy Tarreau745d4122015-06-17 18:34:14 +02004106 if (!smp->data.str.str || !smp->data.str.len)
Emeric Brunfe68f682012-10-16 14:59:28 +02004107 return 0;
4108
4109 return 1;
4110#else
4111 return 0;
4112#endif
4113}
4114
4115static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02004116smp_fetch_ssl_fc_sni(const struct arg *args, struct sample *smp, const char *kw, void *private)
Willy Tarreau7875d092012-09-10 08:20:03 +02004117{
4118#ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004119 struct connection *conn;
4120
Thierry FOURNIER7654c9f2013-12-17 00:20:33 +01004121 smp->flags = SMP_F_CONST;
4122 smp->type = SMP_T_STR;
Willy Tarreau7875d092012-09-10 08:20:03 +02004123
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02004124 conn = objt_conn(smp->sess->origin);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004125 if (!conn || !conn->xprt_ctx || conn->xprt != &ssl_sock)
4126 return 0;
4127
4128 smp->data.str.str = (char *)SSL_get_servername(conn->xprt_ctx, TLSEXT_NAMETYPE_host_name);
Willy Tarreau3e394c92012-09-14 23:56:58 +02004129 if (!smp->data.str.str)
4130 return 0;
4131
Willy Tarreau7875d092012-09-10 08:20:03 +02004132 smp->data.str.len = strlen(smp->data.str.str);
4133 return 1;
4134#else
4135 return 0;
4136#endif
4137}
4138
David Sc1ad52e2014-04-08 18:48:47 -04004139static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02004140smp_fetch_ssl_fc_unique_id(const struct arg *args, struct sample *smp, const char *kw, void *private)
David Sc1ad52e2014-04-08 18:48:47 -04004141{
4142#if OPENSSL_VERSION_NUMBER > 0x0090800fL
Emeric Brun645ae792014-04-30 14:21:06 +02004143 int back_conn = (kw[4] == 'b') ? 1 : 0;
David Sc1ad52e2014-04-08 18:48:47 -04004144 struct connection *conn;
4145 int finished_len;
David Sc1ad52e2014-04-08 18:48:47 -04004146 struct chunk *finished_trash;
David Sc1ad52e2014-04-08 18:48:47 -04004147
4148 smp->flags = 0;
4149
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02004150 conn = objt_conn(smp->strm->si[back_conn].end);
David Sc1ad52e2014-04-08 18:48:47 -04004151 if (!conn || !conn->xprt_ctx || conn->xprt != &ssl_sock)
4152 return 0;
4153
4154 if (!(conn->flags & CO_FL_CONNECTED)) {
4155 smp->flags |= SMP_F_MAY_CHANGE;
4156 return 0;
4157 }
4158
4159 finished_trash = get_trash_chunk();
4160 if (!SSL_session_reused(conn->xprt_ctx))
4161 finished_len = SSL_get_peer_finished(conn->xprt_ctx, finished_trash->str, finished_trash->size);
4162 else
4163 finished_len = SSL_get_finished(conn->xprt_ctx, finished_trash->str, finished_trash->size);
4164
4165 if (!finished_len)
4166 return 0;
4167
Emeric Brunb73a9b02014-04-30 18:49:19 +02004168 finished_trash->len = finished_len;
4169 smp->data.str = *finished_trash;
4170 smp->type = SMP_T_BIN;
David Sc1ad52e2014-04-08 18:48:47 -04004171
4172 return 1;
4173#else
4174 return 0;
4175#endif
4176}
4177
Emeric Brun2525b6b2012-10-18 15:59:43 +02004178/* integer, returns the first verify error in CA chain of client certificate chain. */
Emeric Brunf282a812012-09-21 15:27:54 +02004179static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02004180smp_fetch_ssl_c_ca_err(const struct arg *args, struct sample *smp, const char *kw, void *private)
Emeric Brunf282a812012-09-21 15:27:54 +02004181{
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004182 struct connection *conn;
4183
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02004184 conn = objt_conn(smp->sess->origin);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004185 if (!conn || conn->xprt != &ssl_sock)
4186 return 0;
4187
4188 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brunf282a812012-09-21 15:27:54 +02004189 smp->flags = SMP_F_MAY_CHANGE;
4190 return 0;
4191 }
4192
4193 smp->type = SMP_T_UINT;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004194 smp->data.uint = (unsigned int)SSL_SOCK_ST_TO_CA_ERROR(conn->xprt_st);
Emeric Brunf282a812012-09-21 15:27:54 +02004195 smp->flags = 0;
4196
4197 return 1;
4198}
4199
Emeric Brun2525b6b2012-10-18 15:59:43 +02004200/* integer, returns the depth of the first verify error in CA chain of client certificate chain. */
Emeric Brunf282a812012-09-21 15:27:54 +02004201static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02004202smp_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 +02004203{
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004204 struct connection *conn;
4205
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02004206 conn = objt_conn(smp->sess->origin);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004207 if (!conn || conn->xprt != &ssl_sock)
Emeric Brunf282a812012-09-21 15:27:54 +02004208 return 0;
4209
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004210 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brunf282a812012-09-21 15:27:54 +02004211 smp->flags = SMP_F_MAY_CHANGE;
4212 return 0;
4213 }
4214
4215 smp->type = SMP_T_UINT;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004216 smp->data.uint = (unsigned int)SSL_SOCK_ST_TO_CAEDEPTH(conn->xprt_st);
Emeric Brunf282a812012-09-21 15:27:54 +02004217 smp->flags = 0;
4218
4219 return 1;
4220}
4221
Emeric Brun2525b6b2012-10-18 15:59:43 +02004222/* integer, returns the first verify error on client certificate */
Emeric Brunf282a812012-09-21 15:27:54 +02004223static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02004224smp_fetch_ssl_c_err(const struct arg *args, struct sample *smp, const char *kw, void *private)
Emeric Brunf282a812012-09-21 15:27:54 +02004225{
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004226 struct connection *conn;
4227
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02004228 conn = objt_conn(smp->sess->origin);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004229 if (!conn || conn->xprt != &ssl_sock)
4230 return 0;
4231
4232 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brunf282a812012-09-21 15:27:54 +02004233 smp->flags = SMP_F_MAY_CHANGE;
4234 return 0;
4235 }
4236
4237 smp->type = SMP_T_UINT;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004238 smp->data.uint = (unsigned int)SSL_SOCK_ST_TO_CRTERROR(conn->xprt_st);
Emeric Brunf282a812012-09-21 15:27:54 +02004239 smp->flags = 0;
4240
4241 return 1;
4242}
4243
Emeric Brun2525b6b2012-10-18 15:59:43 +02004244/* integer, returns the verify result on client cert */
Emeric Brunbaf8ffb2012-09-21 15:27:20 +02004245static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02004246smp_fetch_ssl_c_verify(const struct arg *args, struct sample *smp, const char *kw, void *private)
Emeric Brunbaf8ffb2012-09-21 15:27:20 +02004247{
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004248 struct connection *conn;
4249
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02004250 conn = objt_conn(smp->sess->origin);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004251 if (!conn || conn->xprt != &ssl_sock)
4252 return 0;
4253
4254 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brunbaf8ffb2012-09-21 15:27:20 +02004255 smp->flags = SMP_F_MAY_CHANGE;
4256 return 0;
4257 }
4258
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004259 if (!conn->xprt_ctx)
Emeric Brunbaf8ffb2012-09-21 15:27:20 +02004260 return 0;
4261
4262 smp->type = SMP_T_UINT;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004263 smp->data.uint = (unsigned int)SSL_get_verify_result(conn->xprt_ctx);
Emeric Brunbaf8ffb2012-09-21 15:27:20 +02004264 smp->flags = 0;
4265
4266 return 1;
4267}
4268
Emeric Brunfb510ea2012-10-05 12:00:26 +02004269/* parse the "ca-file" bind keyword */
4270static 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 +02004271{
4272 if (!*args[cur_arg + 1]) {
4273 if (err)
4274 memprintf(err, "'%s' : missing CAfile path", args[cur_arg]);
4275 return ERR_ALERT | ERR_FATAL;
4276 }
4277
Emeric Brunef42d922012-10-11 16:11:36 +02004278 if ((*args[cur_arg + 1] != '/') && global.ca_base)
4279 memprintf(&conf->ca_file, "%s/%s", global.ca_base, args[cur_arg + 1]);
4280 else
4281 memprintf(&conf->ca_file, "%s", args[cur_arg + 1]);
Emeric Brunc8e8d122012-10-02 18:42:10 +02004282
Emeric Brund94b3fe2012-09-20 18:23:56 +02004283 return 0;
4284}
4285
Christopher Faulet31af49d2015-06-09 17:29:50 +02004286/* parse the "ca-sign-file" bind keyword */
4287static int bind_parse_ca_sign_file(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
4288{
4289 if (!*args[cur_arg + 1]) {
4290 if (err)
4291 memprintf(err, "'%s' : missing CAfile path", args[cur_arg]);
4292 return ERR_ALERT | ERR_FATAL;
4293 }
4294
4295 if ((*args[cur_arg + 1] != '/') && global.ca_base)
4296 memprintf(&conf->ca_sign_file, "%s/%s", global.ca_base, args[cur_arg + 1]);
4297 else
4298 memprintf(&conf->ca_sign_file, "%s", args[cur_arg + 1]);
4299
4300 return 0;
4301}
4302
4303/* parse the ca-sign-pass bind keyword */
4304
4305static int bind_parse_ca_sign_pass(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
4306{
4307 if (!*args[cur_arg + 1]) {
4308 if (err)
4309 memprintf(err, "'%s' : missing CAkey password", args[cur_arg]);
4310 return ERR_ALERT | ERR_FATAL;
4311 }
4312 memprintf(&conf->ca_sign_pass, "%s", args[cur_arg + 1]);
4313 return 0;
4314}
4315
Willy Tarreau79eeafa2012-09-14 07:53:05 +02004316/* parse the "ciphers" bind keyword */
Willy Tarreau4348fad2012-09-20 16:48:07 +02004317static 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 +02004318{
4319 if (!*args[cur_arg + 1]) {
Willy Tarreaueb6cead2012-09-20 19:43:14 +02004320 memprintf(err, "'%s' : missing cipher suite", args[cur_arg]);
Willy Tarreau79eeafa2012-09-14 07:53:05 +02004321 return ERR_ALERT | ERR_FATAL;
4322 }
4323
Emeric Brun76d88952012-10-05 15:47:31 +02004324 free(conf->ciphers);
Willy Tarreau4348fad2012-09-20 16:48:07 +02004325 conf->ciphers = strdup(args[cur_arg + 1]);
Willy Tarreau79eeafa2012-09-14 07:53:05 +02004326 return 0;
4327}
4328
4329/* parse the "crt" bind keyword */
Willy Tarreau4348fad2012-09-20 16:48:07 +02004330static 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 +02004331{
Willy Tarreau38011032013-08-13 16:59:39 +02004332 char path[MAXPATHLEN];
Willy Tarreaub75d6922014-04-14 18:05:41 +02004333
Willy Tarreau79eeafa2012-09-14 07:53:05 +02004334 if (!*args[cur_arg + 1]) {
Willy Tarreaueb6cead2012-09-20 19:43:14 +02004335 memprintf(err, "'%s' : missing certificate location", args[cur_arg]);
Willy Tarreau79eeafa2012-09-14 07:53:05 +02004336 return ERR_ALERT | ERR_FATAL;
4337 }
4338
Emeric Brunc8e8d122012-10-02 18:42:10 +02004339 if ((*args[cur_arg + 1] != '/' ) && global.crt_base) {
Willy Tarreau38011032013-08-13 16:59:39 +02004340 if ((strlen(global.crt_base) + 1 + strlen(args[cur_arg + 1]) + 1) > MAXPATHLEN) {
Emeric Brunc8e8d122012-10-02 18:42:10 +02004341 memprintf(err, "'%s' : path too long", args[cur_arg]);
4342 return ERR_ALERT | ERR_FATAL;
4343 }
Willy Tarreaub75d6922014-04-14 18:05:41 +02004344 snprintf(path, sizeof(path), "%s/%s", global.crt_base, args[cur_arg + 1]);
Emeric Brunc8e8d122012-10-02 18:42:10 +02004345 if (ssl_sock_load_cert(path, conf, px, err) > 0)
4346 return ERR_ALERT | ERR_FATAL;
4347
4348 return 0;
4349 }
4350
Willy Tarreau4348fad2012-09-20 16:48:07 +02004351 if (ssl_sock_load_cert(args[cur_arg + 1], conf, px, err) > 0)
Willy Tarreau79eeafa2012-09-14 07:53:05 +02004352 return ERR_ALERT | ERR_FATAL;
Emeric Brund94b3fe2012-09-20 18:23:56 +02004353
4354 return 0;
4355}
4356
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01004357/* parse the "crt-list" bind keyword */
4358static int bind_parse_crt_list(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
4359{
4360 if (!*args[cur_arg + 1]) {
4361 memprintf(err, "'%s' : missing certificate location", args[cur_arg]);
4362 return ERR_ALERT | ERR_FATAL;
4363 }
4364
Willy Tarreauad1731d2013-04-02 17:35:58 +02004365 if (ssl_sock_load_cert_list_file(args[cur_arg + 1], conf, px, err) > 0) {
4366 memprintf(err, "'%s' : %s", args[cur_arg], *err);
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01004367 return ERR_ALERT | ERR_FATAL;
Willy Tarreauad1731d2013-04-02 17:35:58 +02004368 }
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01004369
4370 return 0;
4371}
4372
Emeric Brunfb510ea2012-10-05 12:00:26 +02004373/* parse the "crl-file" bind keyword */
4374static 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 +02004375{
Emeric Brun051cdab2012-10-02 19:25:50 +02004376#ifndef X509_V_FLAG_CRL_CHECK
4377 if (err)
4378 memprintf(err, "'%s' : library does not support CRL verify", args[cur_arg]);
4379 return ERR_ALERT | ERR_FATAL;
4380#else
Emeric Brund94b3fe2012-09-20 18:23:56 +02004381 if (!*args[cur_arg + 1]) {
4382 if (err)
4383 memprintf(err, "'%s' : missing CRLfile path", args[cur_arg]);
4384 return ERR_ALERT | ERR_FATAL;
4385 }
Emeric Brun2b58d042012-09-20 17:10:03 +02004386
Emeric Brunef42d922012-10-11 16:11:36 +02004387 if ((*args[cur_arg + 1] != '/') && global.ca_base)
4388 memprintf(&conf->crl_file, "%s/%s", global.ca_base, args[cur_arg + 1]);
4389 else
4390 memprintf(&conf->crl_file, "%s", args[cur_arg + 1]);
Emeric Brunc8e8d122012-10-02 18:42:10 +02004391
Emeric Brun2b58d042012-09-20 17:10:03 +02004392 return 0;
Emeric Brun051cdab2012-10-02 19:25:50 +02004393#endif
Emeric Brun2b58d042012-09-20 17:10:03 +02004394}
4395
4396/* parse the "ecdhe" bind keyword keywords */
4397static int bind_parse_ecdhe(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
4398{
4399#if OPENSSL_VERSION_NUMBER < 0x0090800fL
4400 if (err)
4401 memprintf(err, "'%s' : library does not support elliptic curve Diffie-Hellman (too old)", args[cur_arg]);
4402 return ERR_ALERT | ERR_FATAL;
4403#elif defined(OPENSSL_NO_ECDH)
4404 if (err)
4405 memprintf(err, "'%s' : library does not support elliptic curve Diffie-Hellman (disabled via OPENSSL_NO_ECDH)", args[cur_arg]);
4406 return ERR_ALERT | ERR_FATAL;
4407#else
4408 if (!*args[cur_arg + 1]) {
4409 if (err)
4410 memprintf(err, "'%s' : missing named curve", args[cur_arg]);
4411 return ERR_ALERT | ERR_FATAL;
4412 }
4413
4414 conf->ecdhe = strdup(args[cur_arg + 1]);
Willy Tarreau79eeafa2012-09-14 07:53:05 +02004415
4416 return 0;
Emeric Brun2b58d042012-09-20 17:10:03 +02004417#endif
Willy Tarreau79eeafa2012-09-14 07:53:05 +02004418}
4419
Emeric Brun81c00f02012-09-21 14:31:21 +02004420/* parse the "crt_ignerr" and "ca_ignerr" bind keywords */
4421static int bind_parse_ignore_err(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
4422{
4423 int code;
4424 char *p = args[cur_arg + 1];
4425 unsigned long long *ignerr = &conf->crt_ignerr;
4426
4427 if (!*p) {
4428 if (err)
4429 memprintf(err, "'%s' : missing error IDs list", args[cur_arg]);
4430 return ERR_ALERT | ERR_FATAL;
4431 }
4432
4433 if (strcmp(args[cur_arg], "ca-ignore-err") == 0)
4434 ignerr = &conf->ca_ignerr;
4435
4436 if (strcmp(p, "all") == 0) {
4437 *ignerr = ~0ULL;
4438 return 0;
4439 }
4440
4441 while (p) {
4442 code = atoi(p);
4443 if ((code <= 0) || (code > 63)) {
4444 if (err)
4445 memprintf(err, "'%s' : ID '%d' out of range (1..63) in error IDs list '%s'",
4446 args[cur_arg], code, args[cur_arg + 1]);
4447 return ERR_ALERT | ERR_FATAL;
4448 }
4449 *ignerr |= 1ULL << code;
4450 p = strchr(p, ',');
4451 if (p)
4452 p++;
4453 }
4454
Emeric Brun2cb7ae52012-10-05 14:14:21 +02004455 return 0;
4456}
4457
4458/* parse the "force-sslv3" bind keyword */
4459static int bind_parse_force_sslv3(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
4460{
4461 conf->ssl_options |= BC_SSL_O_USE_SSLV3;
4462 return 0;
4463}
4464
4465/* parse the "force-tlsv10" bind keyword */
4466static int bind_parse_force_tlsv10(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
4467{
4468 conf->ssl_options |= BC_SSL_O_USE_TLSV10;
Emeric Brun2d0c4822012-10-02 13:45:20 +02004469 return 0;
4470}
4471
Emeric Brun2cb7ae52012-10-05 14:14:21 +02004472/* parse the "force-tlsv11" bind keyword */
4473static int bind_parse_force_tlsv11(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
4474{
4475#if SSL_OP_NO_TLSv1_1
4476 conf->ssl_options |= BC_SSL_O_USE_TLSV11;
4477 return 0;
4478#else
4479 if (err)
4480 memprintf(err, "'%s' : library does not support protocol TLSv1.1", args[cur_arg]);
4481 return ERR_ALERT | ERR_FATAL;
4482#endif
4483}
4484
4485/* parse the "force-tlsv12" bind keyword */
4486static int bind_parse_force_tlsv12(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
4487{
4488#if SSL_OP_NO_TLSv1_2
4489 conf->ssl_options |= BC_SSL_O_USE_TLSV12;
4490 return 0;
4491#else
4492 if (err)
4493 memprintf(err, "'%s' : library does not support protocol TLSv1.2", args[cur_arg]);
4494 return ERR_ALERT | ERR_FATAL;
4495#endif
4496}
4497
4498
Emeric Brun2d0c4822012-10-02 13:45:20 +02004499/* parse the "no-tls-tickets" bind keyword */
4500static int bind_parse_no_tls_tickets(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
4501{
Emeric Brun89675492012-10-05 13:48:26 +02004502 conf->ssl_options |= BC_SSL_O_NO_TLS_TICKETS;
Emeric Brun81c00f02012-09-21 14:31:21 +02004503 return 0;
4504}
4505
Emeric Brun2d0c4822012-10-02 13:45:20 +02004506
Emeric Brun9b3009b2012-10-05 11:55:06 +02004507/* parse the "no-sslv3" bind keyword */
4508static 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 +02004509{
Emeric Brun89675492012-10-05 13:48:26 +02004510 conf->ssl_options |= BC_SSL_O_NO_SSLV3;
Willy Tarreau79eeafa2012-09-14 07:53:05 +02004511 return 0;
4512}
4513
Emeric Brun9b3009b2012-10-05 11:55:06 +02004514/* parse the "no-tlsv10" bind keyword */
4515static 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 +02004516{
Emeric Brun89675492012-10-05 13:48:26 +02004517 conf->ssl_options |= BC_SSL_O_NO_TLSV10;
Emeric Brunc0ff4922012-09-28 19:37:02 +02004518 return 0;
4519}
4520
Emeric Brun9b3009b2012-10-05 11:55:06 +02004521/* parse the "no-tlsv11" bind keyword */
4522static 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 +02004523{
Emeric Brun89675492012-10-05 13:48:26 +02004524 conf->ssl_options |= BC_SSL_O_NO_TLSV11;
Emeric Brunc0ff4922012-09-28 19:37:02 +02004525 return 0;
4526}
4527
Emeric Brun9b3009b2012-10-05 11:55:06 +02004528/* parse the "no-tlsv12" bind keyword */
4529static 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 +02004530{
Emeric Brun89675492012-10-05 13:48:26 +02004531 conf->ssl_options |= BC_SSL_O_NO_TLSV12;
Willy Tarreau79eeafa2012-09-14 07:53:05 +02004532 return 0;
4533}
4534
Willy Tarreau6c9a3d52012-10-18 18:57:14 +02004535/* parse the "npn" bind keyword */
4536static int bind_parse_npn(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
4537{
4538#ifdef OPENSSL_NPN_NEGOTIATED
4539 char *p1, *p2;
4540
4541 if (!*args[cur_arg + 1]) {
4542 memprintf(err, "'%s' : missing the comma-delimited NPN protocol suite", args[cur_arg]);
4543 return ERR_ALERT | ERR_FATAL;
4544 }
4545
4546 free(conf->npn_str);
4547
4548 /* the NPN string is built as a suite of (<len> <name>)* */
4549 conf->npn_len = strlen(args[cur_arg + 1]) + 1;
4550 conf->npn_str = calloc(1, conf->npn_len);
4551 memcpy(conf->npn_str + 1, args[cur_arg + 1], conf->npn_len);
4552
4553 /* replace commas with the name length */
4554 p1 = conf->npn_str;
4555 p2 = p1 + 1;
4556 while (1) {
4557 p2 = memchr(p1 + 1, ',', conf->npn_str + conf->npn_len - (p1 + 1));
4558 if (!p2)
4559 p2 = p1 + 1 + strlen(p1 + 1);
4560
4561 if (p2 - (p1 + 1) > 255) {
4562 *p2 = '\0';
4563 memprintf(err, "'%s' : NPN protocol name too long : '%s'", args[cur_arg], p1 + 1);
4564 return ERR_ALERT | ERR_FATAL;
4565 }
4566
4567 *p1 = p2 - (p1 + 1);
4568 p1 = p2;
4569
4570 if (!*p2)
4571 break;
4572
4573 *(p2++) = '\0';
4574 }
4575 return 0;
4576#else
4577 if (err)
4578 memprintf(err, "'%s' : library does not support TLS NPN extension", args[cur_arg]);
4579 return ERR_ALERT | ERR_FATAL;
4580#endif
4581}
4582
Willy Tarreauab861d32013-04-02 02:30:41 +02004583/* parse the "alpn" bind keyword */
4584static int bind_parse_alpn(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
4585{
Dirkjan Bussink48f1c4e2014-02-13 12:29:42 +01004586#ifdef TLSEXT_TYPE_application_layer_protocol_negotiation
Willy Tarreauab861d32013-04-02 02:30:41 +02004587 char *p1, *p2;
4588
4589 if (!*args[cur_arg + 1]) {
4590 memprintf(err, "'%s' : missing the comma-delimited ALPN protocol suite", args[cur_arg]);
4591 return ERR_ALERT | ERR_FATAL;
4592 }
4593
4594 free(conf->alpn_str);
4595
4596 /* the ALPN string is built as a suite of (<len> <name>)* */
4597 conf->alpn_len = strlen(args[cur_arg + 1]) + 1;
4598 conf->alpn_str = calloc(1, conf->alpn_len);
4599 memcpy(conf->alpn_str + 1, args[cur_arg + 1], conf->alpn_len);
4600
4601 /* replace commas with the name length */
4602 p1 = conf->alpn_str;
4603 p2 = p1 + 1;
4604 while (1) {
4605 p2 = memchr(p1 + 1, ',', conf->alpn_str + conf->alpn_len - (p1 + 1));
4606 if (!p2)
4607 p2 = p1 + 1 + strlen(p1 + 1);
4608
4609 if (p2 - (p1 + 1) > 255) {
4610 *p2 = '\0';
4611 memprintf(err, "'%s' : ALPN protocol name too long : '%s'", args[cur_arg], p1 + 1);
4612 return ERR_ALERT | ERR_FATAL;
4613 }
4614
4615 *p1 = p2 - (p1 + 1);
4616 p1 = p2;
4617
4618 if (!*p2)
4619 break;
4620
4621 *(p2++) = '\0';
4622 }
4623 return 0;
4624#else
4625 if (err)
4626 memprintf(err, "'%s' : library does not support TLS ALPN extension", args[cur_arg]);
4627 return ERR_ALERT | ERR_FATAL;
4628#endif
4629}
4630
Willy Tarreau79eeafa2012-09-14 07:53:05 +02004631/* parse the "ssl" bind keyword */
Willy Tarreau4348fad2012-09-20 16:48:07 +02004632static 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 +02004633{
Willy Tarreau81796be2012-09-22 19:11:47 +02004634 struct listener *l;
4635
Willy Tarreau4348fad2012-09-20 16:48:07 +02004636 conf->is_ssl = 1;
Emeric Brun76d88952012-10-05 15:47:31 +02004637
4638 if (global.listen_default_ciphers && !conf->ciphers)
4639 conf->ciphers = strdup(global.listen_default_ciphers);
Emeric Brun2c86cbf2014-10-30 15:56:50 +01004640 conf->ssl_options |= global.listen_default_ssloptions;
Emeric Brun76d88952012-10-05 15:47:31 +02004641
Willy Tarreau81796be2012-09-22 19:11:47 +02004642 list_for_each_entry(l, &conf->listeners, by_bind)
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02004643 l->xprt = &ssl_sock;
Willy Tarreau81796be2012-09-22 19:11:47 +02004644
Willy Tarreau79eeafa2012-09-14 07:53:05 +02004645 return 0;
4646}
4647
Christopher Faulet31af49d2015-06-09 17:29:50 +02004648/* parse the "generate-certificates" bind keyword */
4649static int bind_parse_generate_certs(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
4650{
4651#ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME
4652 conf->generate_certs = 1;
4653#else
4654 memprintf(err, "%sthis version of openssl cannot generate SSL certificates.\n",
4655 err && *err ? *err : "");
4656#endif
4657 return 0;
4658}
4659
Emmanuel Hocdet65623372013-01-24 17:17:15 +01004660/* parse the "strict-sni" bind keyword */
4661static int bind_parse_strict_sni(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
4662{
4663 conf->strict_sni = 1;
4664 return 0;
Nenad Merdanovic05552d42015-02-27 19:56:49 +01004665}
4666
4667/* parse the "tls-ticket-keys" bind keyword */
4668static int bind_parse_tls_ticket_keys(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
4669{
4670#if (defined SSL_CTRL_SET_TLSEXT_TICKET_KEY_CB && TLS_TICKETS_NO > 0)
4671 FILE *f;
4672 int i = 0;
4673 char thisline[LINESIZE];
Nenad Merdanovic146defa2015-05-09 08:46:00 +02004674 struct tls_keys_ref *keys_ref;
Nenad Merdanovic05552d42015-02-27 19:56:49 +01004675
4676 if (!*args[cur_arg + 1]) {
4677 if (err)
4678 memprintf(err, "'%s' : missing TLS ticket keys file path", args[cur_arg]);
4679 return ERR_ALERT | ERR_FATAL;
4680 }
4681
Nenad Merdanovic200b0fa2015-05-09 08:46:01 +02004682 keys_ref = tlskeys_ref_lookup(args[cur_arg + 1]);
4683 if(keys_ref) {
4684 conf->keys_ref = keys_ref;
4685 return 0;
4686 }
4687
Nenad Merdanovic146defa2015-05-09 08:46:00 +02004688 keys_ref = malloc(sizeof(struct tls_keys_ref));
4689 keys_ref->tlskeys = malloc(TLS_TICKETS_NO * sizeof(struct tls_sess_key));
Nenad Merdanovic05552d42015-02-27 19:56:49 +01004690
4691 if ((f = fopen(args[cur_arg + 1], "r")) == NULL) {
4692 if (err)
4693 memprintf(err, "'%s' : unable to load ssl tickets keys file", args[cur_arg+1]);
4694 return ERR_ALERT | ERR_FATAL;
4695 }
4696
Nenad Merdanovic146defa2015-05-09 08:46:00 +02004697 keys_ref->filename = strdup(args[cur_arg + 1]);
4698
Nenad Merdanovic05552d42015-02-27 19:56:49 +01004699 while (fgets(thisline, sizeof(thisline), f) != NULL) {
4700 int len = strlen(thisline);
4701 /* Strip newline characters from the end */
4702 if(thisline[len - 1] == '\n')
4703 thisline[--len] = 0;
4704
4705 if(thisline[len - 1] == '\r')
4706 thisline[--len] = 0;
4707
Nenad Merdanovic146defa2015-05-09 08:46:00 +02004708 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 +01004709 if (err)
4710 memprintf(err, "'%s' : unable to decode base64 key on line %d", args[cur_arg+1], i + 1);
4711 return ERR_ALERT | ERR_FATAL;
4712 }
4713 i++;
4714 }
4715
4716 if (i < TLS_TICKETS_NO) {
4717 if (err)
4718 memprintf(err, "'%s' : please supply at least %d keys in the tls-tickets-file", args[cur_arg+1], TLS_TICKETS_NO);
4719 return ERR_ALERT | ERR_FATAL;
4720 }
4721
4722 fclose(f);
4723
4724 /* Use penultimate key for encryption, handle when TLS_TICKETS_NO = 1 */
4725 i-=2;
Nenad Merdanovic146defa2015-05-09 08:46:00 +02004726 keys_ref->tls_ticket_enc_index = i < 0 ? 0 : i;
Nenad Merdanovic200b0fa2015-05-09 08:46:01 +02004727 keys_ref->unique_id = -1;
Nenad Merdanovic146defa2015-05-09 08:46:00 +02004728 conf->keys_ref = keys_ref;
Nenad Merdanovic05552d42015-02-27 19:56:49 +01004729
Nenad Merdanovic200b0fa2015-05-09 08:46:01 +02004730 LIST_ADD(&tlskeys_reference, &keys_ref->list);
4731
Nenad Merdanovic05552d42015-02-27 19:56:49 +01004732 return 0;
4733#else
4734 if (err)
4735 memprintf(err, "'%s' : TLS ticket callback extension not supported", args[cur_arg]);
4736 return ERR_ALERT | ERR_FATAL;
4737#endif /* SSL_CTRL_SET_TLSEXT_TICKET_KEY_CB */
Emmanuel Hocdet65623372013-01-24 17:17:15 +01004738}
4739
Emeric Brund94b3fe2012-09-20 18:23:56 +02004740/* parse the "verify" bind keyword */
4741static int bind_parse_verify(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
4742{
4743 if (!*args[cur_arg + 1]) {
4744 if (err)
4745 memprintf(err, "'%s' : missing verify method", args[cur_arg]);
4746 return ERR_ALERT | ERR_FATAL;
4747 }
4748
4749 if (strcmp(args[cur_arg + 1], "none") == 0)
Emeric Brun850efd52014-01-29 12:24:34 +01004750 conf->verify = SSL_SOCK_VERIFY_NONE;
Emeric Brund94b3fe2012-09-20 18:23:56 +02004751 else if (strcmp(args[cur_arg + 1], "optional") == 0)
Emeric Brun850efd52014-01-29 12:24:34 +01004752 conf->verify = SSL_SOCK_VERIFY_OPTIONAL;
Emeric Brund94b3fe2012-09-20 18:23:56 +02004753 else if (strcmp(args[cur_arg + 1], "required") == 0)
Emeric Brun850efd52014-01-29 12:24:34 +01004754 conf->verify = SSL_SOCK_VERIFY_REQUIRED;
Emeric Brund94b3fe2012-09-20 18:23:56 +02004755 else {
4756 if (err)
4757 memprintf(err, "'%s' : unknown verify method '%s', only 'none', 'optional', and 'required' are supported\n",
4758 args[cur_arg], args[cur_arg + 1]);
4759 return ERR_ALERT | ERR_FATAL;
4760 }
4761
4762 return 0;
4763}
4764
Willy Tarreau92faadf2012-10-10 23:04:25 +02004765/************** "server" keywords ****************/
4766
Emeric Brunef42d922012-10-11 16:11:36 +02004767/* parse the "ca-file" server keyword */
4768static int srv_parse_ca_file(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
4769{
4770 if (!*args[*cur_arg + 1]) {
4771 if (err)
4772 memprintf(err, "'%s' : missing CAfile path", args[*cur_arg]);
4773 return ERR_ALERT | ERR_FATAL;
4774 }
4775
4776 if ((*args[*cur_arg + 1] != '/') && global.ca_base)
4777 memprintf(&newsrv->ssl_ctx.ca_file, "%s/%s", global.ca_base, args[*cur_arg + 1]);
4778 else
4779 memprintf(&newsrv->ssl_ctx.ca_file, "%s", args[*cur_arg + 1]);
4780
4781 return 0;
4782}
4783
Willy Tarreau92faadf2012-10-10 23:04:25 +02004784/* parse the "check-ssl" server keyword */
4785static int srv_parse_check_ssl(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
4786{
4787 newsrv->check.use_ssl = 1;
4788 if (global.connect_default_ciphers && !newsrv->ssl_ctx.ciphers)
4789 newsrv->ssl_ctx.ciphers = strdup(global.connect_default_ciphers);
Emeric Brun2c86cbf2014-10-30 15:56:50 +01004790 newsrv->ssl_ctx.options |= global.connect_default_ssloptions;
Willy Tarreau92faadf2012-10-10 23:04:25 +02004791 return 0;
4792}
4793
4794/* parse the "ciphers" server keyword */
4795static int srv_parse_ciphers(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
4796{
4797 if (!*args[*cur_arg + 1]) {
4798 memprintf(err, "'%s' : missing cipher suite", args[*cur_arg]);
4799 return ERR_ALERT | ERR_FATAL;
4800 }
4801
4802 free(newsrv->ssl_ctx.ciphers);
4803 newsrv->ssl_ctx.ciphers = strdup(args[*cur_arg + 1]);
4804 return 0;
4805}
4806
Emeric Brunef42d922012-10-11 16:11:36 +02004807/* parse the "crl-file" server keyword */
4808static int srv_parse_crl_file(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
4809{
4810#ifndef X509_V_FLAG_CRL_CHECK
4811 if (err)
4812 memprintf(err, "'%s' : library does not support CRL verify", args[*cur_arg]);
4813 return ERR_ALERT | ERR_FATAL;
4814#else
4815 if (!*args[*cur_arg + 1]) {
4816 if (err)
4817 memprintf(err, "'%s' : missing CRLfile path", args[*cur_arg]);
4818 return ERR_ALERT | ERR_FATAL;
4819 }
4820
4821 if ((*args[*cur_arg + 1] != '/') && global.ca_base)
4822 memprintf(&newsrv->ssl_ctx.crl_file, "%s/%s", global.ca_base, args[*cur_arg + 1]);
4823 else
4824 memprintf(&newsrv->ssl_ctx.crl_file, "%s", args[*cur_arg + 1]);
4825
4826 return 0;
4827#endif
4828}
4829
Emeric Bruna7aa3092012-10-26 12:58:00 +02004830/* parse the "crt" server keyword */
4831static int srv_parse_crt(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
4832{
4833 if (!*args[*cur_arg + 1]) {
4834 if (err)
4835 memprintf(err, "'%s' : missing certificate file path", args[*cur_arg]);
4836 return ERR_ALERT | ERR_FATAL;
4837 }
4838
4839 if ((*args[*cur_arg + 1] != '/') && global.crt_base)
4840 memprintf(&newsrv->ssl_ctx.client_crt, "%s/%s", global.ca_base, args[*cur_arg + 1]);
4841 else
4842 memprintf(&newsrv->ssl_ctx.client_crt, "%s", args[*cur_arg + 1]);
4843
4844 return 0;
4845}
Emeric Brunef42d922012-10-11 16:11:36 +02004846
Willy Tarreau92faadf2012-10-10 23:04:25 +02004847/* parse the "force-sslv3" server keyword */
4848static int srv_parse_force_sslv3(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
4849{
4850 newsrv->ssl_ctx.options |= SRV_SSL_O_USE_SSLV3;
4851 return 0;
4852}
4853
4854/* parse the "force-tlsv10" server keyword */
4855static int srv_parse_force_tlsv10(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
4856{
4857 newsrv->ssl_ctx.options |= SRV_SSL_O_USE_TLSV10;
4858 return 0;
4859}
4860
4861/* parse the "force-tlsv11" server keyword */
4862static int srv_parse_force_tlsv11(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
4863{
4864#if SSL_OP_NO_TLSv1_1
4865 newsrv->ssl_ctx.options |= SRV_SSL_O_USE_TLSV11;
4866 return 0;
4867#else
4868 if (err)
4869 memprintf(err, "'%s' : library does not support protocol TLSv1.1", args[*cur_arg]);
4870 return ERR_ALERT | ERR_FATAL;
4871#endif
4872}
4873
4874/* parse the "force-tlsv12" server keyword */
4875static int srv_parse_force_tlsv12(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
4876{
4877#if SSL_OP_NO_TLSv1_2
4878 newsrv->ssl_ctx.options |= SRV_SSL_O_USE_TLSV12;
4879 return 0;
4880#else
4881 if (err)
4882 memprintf(err, "'%s' : library does not support protocol TLSv1.2", args[*cur_arg]);
4883 return ERR_ALERT | ERR_FATAL;
4884#endif
4885}
4886
Willy Tarreau2a3fb1c2015-02-05 16:47:07 +01004887/* parse the "no-ssl-reuse" server keyword */
4888static int srv_parse_no_ssl_reuse(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
4889{
4890 newsrv->ssl_ctx.options |= SRV_SSL_O_NO_REUSE;
4891 return 0;
4892}
4893
Willy Tarreau92faadf2012-10-10 23:04:25 +02004894/* parse the "no-sslv3" server keyword */
4895static int srv_parse_no_sslv3(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
4896{
4897 newsrv->ssl_ctx.options |= SRV_SSL_O_NO_SSLV3;
4898 return 0;
4899}
4900
4901/* parse the "no-tlsv10" server keyword */
4902static int srv_parse_no_tlsv10(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
4903{
4904 newsrv->ssl_ctx.options |= SRV_SSL_O_NO_TLSV10;
4905 return 0;
4906}
4907
4908/* parse the "no-tlsv11" server keyword */
4909static int srv_parse_no_tlsv11(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
4910{
4911 newsrv->ssl_ctx.options |= SRV_SSL_O_NO_TLSV11;
4912 return 0;
4913}
4914
4915/* parse the "no-tlsv12" server keyword */
4916static int srv_parse_no_tlsv12(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
4917{
4918 newsrv->ssl_ctx.options |= SRV_SSL_O_NO_TLSV12;
4919 return 0;
4920}
4921
Emeric Brunf9c5c472012-10-11 15:28:34 +02004922/* parse the "no-tls-tickets" server keyword */
4923static int srv_parse_no_tls_tickets(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
4924{
4925 newsrv->ssl_ctx.options |= SRV_SSL_O_NO_TLS_TICKETS;
4926 return 0;
4927}
David Safb76832014-05-08 23:42:08 -04004928/* parse the "send-proxy-v2-ssl" server keyword */
4929static int srv_parse_send_proxy_ssl(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
4930{
4931 newsrv->pp_opts |= SRV_PP_V2;
4932 newsrv->pp_opts |= SRV_PP_V2_SSL;
4933 return 0;
4934}
4935
4936/* parse the "send-proxy-v2-ssl-cn" server keyword */
4937static int srv_parse_send_proxy_cn(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
4938{
4939 newsrv->pp_opts |= SRV_PP_V2;
4940 newsrv->pp_opts |= SRV_PP_V2_SSL;
4941 newsrv->pp_opts |= SRV_PP_V2_SSL_CN;
4942 return 0;
4943}
Emeric Brunf9c5c472012-10-11 15:28:34 +02004944
Willy Tarreau92faadf2012-10-10 23:04:25 +02004945/* parse the "ssl" server keyword */
4946static int srv_parse_ssl(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
4947{
4948 newsrv->use_ssl = 1;
4949 if (global.connect_default_ciphers && !newsrv->ssl_ctx.ciphers)
4950 newsrv->ssl_ctx.ciphers = strdup(global.connect_default_ciphers);
4951 return 0;
4952}
4953
Emeric Brunef42d922012-10-11 16:11:36 +02004954/* parse the "verify" server keyword */
4955static int srv_parse_verify(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
4956{
4957 if (!*args[*cur_arg + 1]) {
4958 if (err)
4959 memprintf(err, "'%s' : missing verify method", args[*cur_arg]);
4960 return ERR_ALERT | ERR_FATAL;
4961 }
4962
4963 if (strcmp(args[*cur_arg + 1], "none") == 0)
Emeric Brun850efd52014-01-29 12:24:34 +01004964 newsrv->ssl_ctx.verify = SSL_SOCK_VERIFY_NONE;
Emeric Brunef42d922012-10-11 16:11:36 +02004965 else if (strcmp(args[*cur_arg + 1], "required") == 0)
Emeric Brun850efd52014-01-29 12:24:34 +01004966 newsrv->ssl_ctx.verify = SSL_SOCK_VERIFY_REQUIRED;
Emeric Brunef42d922012-10-11 16:11:36 +02004967 else {
4968 if (err)
4969 memprintf(err, "'%s' : unknown verify method '%s', only 'none' and 'required' are supported\n",
4970 args[*cur_arg], args[*cur_arg + 1]);
4971 return ERR_ALERT | ERR_FATAL;
4972 }
4973
Evan Broderbe554312013-06-27 00:05:25 -07004974 return 0;
4975}
4976
4977/* parse the "verifyhost" server keyword */
4978static int srv_parse_verifyhost(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
4979{
4980 if (!*args[*cur_arg + 1]) {
4981 if (err)
4982 memprintf(err, "'%s' : missing hostname to verify against", args[*cur_arg]);
4983 return ERR_ALERT | ERR_FATAL;
4984 }
4985
4986 newsrv->ssl_ctx.verify_host = strdup(args[*cur_arg + 1]);
4987
Emeric Brunef42d922012-10-11 16:11:36 +02004988 return 0;
4989}
4990
Emeric Brun2c86cbf2014-10-30 15:56:50 +01004991/* parse the "ssl-default-bind-options" keyword in global section */
4992static int ssl_parse_default_bind_options(char **args, int section_type, struct proxy *curpx,
4993 struct proxy *defpx, const char *file, int line,
4994 char **err) {
4995 int i = 1;
4996
4997 if (*(args[i]) == 0) {
4998 memprintf(err, "global statement '%s' expects an option as an argument.", args[0]);
4999 return -1;
5000 }
5001 while (*(args[i])) {
5002 if (!strcmp(args[i], "no-sslv3"))
5003 global.listen_default_ssloptions |= BC_SSL_O_NO_SSLV3;
5004 else if (!strcmp(args[i], "no-tlsv10"))
5005 global.listen_default_ssloptions |= BC_SSL_O_NO_TLSV10;
5006 else if (!strcmp(args[i], "no-tlsv11"))
5007 global.listen_default_ssloptions |= BC_SSL_O_NO_TLSV11;
5008 else if (!strcmp(args[i], "no-tlsv12"))
5009 global.listen_default_ssloptions |= BC_SSL_O_NO_TLSV12;
5010 else if (!strcmp(args[i], "force-sslv3"))
5011 global.listen_default_ssloptions |= BC_SSL_O_USE_SSLV3;
5012 else if (!strcmp(args[i], "force-tlsv10"))
5013 global.listen_default_ssloptions |= BC_SSL_O_USE_TLSV10;
5014 else if (!strcmp(args[i], "force-tlsv11")) {
5015#if SSL_OP_NO_TLSv1_1
5016 global.listen_default_ssloptions |= BC_SSL_O_USE_TLSV11;
5017#else
5018 memprintf(err, "'%s' '%s': library does not support protocol TLSv1.1", args[0], args[i]);
5019 return -1;
5020#endif
5021 }
5022 else if (!strcmp(args[i], "force-tlsv12")) {
5023#if SSL_OP_NO_TLSv1_2
5024 global.listen_default_ssloptions |= BC_SSL_O_USE_TLSV12;
5025#else
5026 memprintf(err, "'%s' '%s': library does not support protocol TLSv1.2", args[0], args[i]);
5027 return -1;
5028#endif
5029 }
5030 else if (!strcmp(args[i], "no-tls-tickets"))
5031 global.listen_default_ssloptions |= BC_SSL_O_NO_TLS_TICKETS;
5032 else {
5033 memprintf(err, "unknown option '%s' on global statement '%s'.", args[i], args[0]);
5034 return -1;
5035 }
5036 i++;
5037 }
5038 return 0;
5039}
5040
5041/* parse the "ssl-default-server-options" keyword in global section */
5042static int ssl_parse_default_server_options(char **args, int section_type, struct proxy *curpx,
5043 struct proxy *defpx, const char *file, int line,
5044 char **err) {
5045 int i = 1;
5046
5047 if (*(args[i]) == 0) {
5048 memprintf(err, "global statement '%s' expects an option as an argument.", args[0]);
5049 return -1;
5050 }
5051 while (*(args[i])) {
5052 if (!strcmp(args[i], "no-sslv3"))
5053 global.connect_default_ssloptions |= SRV_SSL_O_NO_SSLV3;
5054 else if (!strcmp(args[i], "no-tlsv10"))
5055 global.connect_default_ssloptions |= SRV_SSL_O_NO_TLSV10;
5056 else if (!strcmp(args[i], "no-tlsv11"))
5057 global.connect_default_ssloptions |= SRV_SSL_O_NO_TLSV11;
5058 else if (!strcmp(args[i], "no-tlsv12"))
5059 global.connect_default_ssloptions |= SRV_SSL_O_NO_TLSV12;
5060 else if (!strcmp(args[i], "force-sslv3"))
5061 global.connect_default_ssloptions |= SRV_SSL_O_USE_SSLV3;
5062 else if (!strcmp(args[i], "force-tlsv10"))
5063 global.connect_default_ssloptions |= SRV_SSL_O_USE_TLSV10;
5064 else if (!strcmp(args[i], "force-tlsv11")) {
5065#if SSL_OP_NO_TLSv1_1
5066 global.connect_default_ssloptions |= SRV_SSL_O_USE_TLSV11;
5067#else
5068 memprintf(err, "'%s' '%s': library does not support protocol TLSv1.1", args[0], args[i]);
5069 return -1;
5070#endif
5071 }
5072 else if (!strcmp(args[i], "force-tlsv12")) {
5073#if SSL_OP_NO_TLSv1_2
5074 global.connect_default_ssloptions |= SRV_SSL_O_USE_TLSV12;
5075#else
5076 memprintf(err, "'%s' '%s': library does not support protocol TLSv1.2", args[0], args[i]);
5077 return -1;
5078#endif
5079 }
5080 else if (!strcmp(args[i], "no-tls-tickets"))
5081 global.connect_default_ssloptions |= SRV_SSL_O_NO_TLS_TICKETS;
5082 else {
5083 memprintf(err, "unknown option '%s' on global statement '%s'.", args[i], args[0]);
5084 return -1;
5085 }
5086 i++;
5087 }
5088 return 0;
5089}
5090
Willy Tarreau7875d092012-09-10 08:20:03 +02005091/* Note: must not be declared <const> as its list will be overwritten.
5092 * Please take care of keeping this list alphabetically sorted.
5093 */
Willy Tarreaudc13c112013-06-21 23:16:39 +02005094static struct sample_fetch_kw_list sample_fetch_keywords = {ILH, {
Emeric Brun645ae792014-04-30 14:21:06 +02005095 { "ssl_bc", smp_fetch_ssl_fc, 0, NULL, SMP_T_BOOL, SMP_USE_L5SRV },
5096 { "ssl_bc_alg_keysize", smp_fetch_ssl_fc_alg_keysize, 0, NULL, SMP_T_UINT, SMP_USE_L5SRV },
5097 { "ssl_bc_cipher", smp_fetch_ssl_fc_cipher, 0, NULL, SMP_T_STR, SMP_USE_L5SRV },
5098 { "ssl_bc_protocol", smp_fetch_ssl_fc_protocol, 0, NULL, SMP_T_STR, SMP_USE_L5SRV },
Emeric Brunb73a9b02014-04-30 18:49:19 +02005099 { "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 +02005100 { "ssl_bc_use_keysize", smp_fetch_ssl_fc_use_keysize, 0, NULL, SMP_T_UINT, SMP_USE_L5SRV },
5101 { "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 +01005102 { "ssl_c_ca_err", smp_fetch_ssl_c_ca_err, 0, NULL, SMP_T_UINT, SMP_USE_L5CLI },
5103 { "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 +01005104 { "ssl_c_der", smp_fetch_ssl_x_der, 0, NULL, SMP_T_BIN, SMP_USE_L5CLI },
Willy Tarreau80aca902013-01-07 15:42:20 +01005105 { "ssl_c_err", smp_fetch_ssl_c_err, 0, NULL, SMP_T_UINT, SMP_USE_L5CLI },
Emeric Brunba841a12014-04-30 17:05:08 +02005106 { "ssl_c_i_dn", smp_fetch_ssl_x_i_dn, ARG2(0,STR,SINT), NULL, SMP_T_STR, SMP_USE_L5CLI },
5107 { "ssl_c_key_alg", smp_fetch_ssl_x_key_alg, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
5108 { "ssl_c_notafter", smp_fetch_ssl_x_notafter, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
5109 { "ssl_c_notbefore", smp_fetch_ssl_x_notbefore, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
5110 { "ssl_c_sig_alg", smp_fetch_ssl_x_sig_alg, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
5111 { "ssl_c_s_dn", smp_fetch_ssl_x_s_dn, ARG2(0,STR,SINT), NULL, SMP_T_STR, SMP_USE_L5CLI },
5112 { "ssl_c_serial", smp_fetch_ssl_x_serial, 0, NULL, SMP_T_BIN, SMP_USE_L5CLI },
5113 { "ssl_c_sha1", smp_fetch_ssl_x_sha1, 0, NULL, SMP_T_BIN, SMP_USE_L5CLI },
Willy Tarreau80aca902013-01-07 15:42:20 +01005114 { "ssl_c_used", smp_fetch_ssl_c_used, 0, NULL, SMP_T_BOOL, SMP_USE_L5CLI },
5115 { "ssl_c_verify", smp_fetch_ssl_c_verify, 0, NULL, SMP_T_UINT, SMP_USE_L5CLI },
Emeric Brunba841a12014-04-30 17:05:08 +02005116 { "ssl_c_version", smp_fetch_ssl_x_version, 0, NULL, SMP_T_UINT, SMP_USE_L5CLI },
Emeric Brun43e79582014-10-29 19:03:26 +01005117 { "ssl_f_der", smp_fetch_ssl_x_der, 0, NULL, SMP_T_BIN, SMP_USE_L5CLI },
Emeric Brunba841a12014-04-30 17:05:08 +02005118 { "ssl_f_i_dn", smp_fetch_ssl_x_i_dn, ARG2(0,STR,SINT), NULL, SMP_T_STR, SMP_USE_L5CLI },
5119 { "ssl_f_key_alg", smp_fetch_ssl_x_key_alg, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
5120 { "ssl_f_notafter", smp_fetch_ssl_x_notafter, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
5121 { "ssl_f_notbefore", smp_fetch_ssl_x_notbefore, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
5122 { "ssl_f_sig_alg", smp_fetch_ssl_x_sig_alg, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
5123 { "ssl_f_s_dn", smp_fetch_ssl_x_s_dn, ARG2(0,STR,SINT), NULL, SMP_T_STR, SMP_USE_L5CLI },
5124 { "ssl_f_serial", smp_fetch_ssl_x_serial, 0, NULL, SMP_T_BIN, SMP_USE_L5CLI },
Emeric Brun55f4fa82014-04-30 17:11:25 +02005125 { "ssl_f_sha1", smp_fetch_ssl_x_sha1, 0, NULL, SMP_T_BIN, SMP_USE_L5CLI },
Emeric Brunba841a12014-04-30 17:05:08 +02005126 { "ssl_f_version", smp_fetch_ssl_x_version, 0, NULL, SMP_T_UINT, SMP_USE_L5CLI },
Willy Tarreau80aca902013-01-07 15:42:20 +01005127 { "ssl_fc", smp_fetch_ssl_fc, 0, NULL, SMP_T_BOOL, SMP_USE_L5CLI },
5128 { "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 +01005129 { "ssl_fc_cipher", smp_fetch_ssl_fc_cipher, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
Willy Tarreau80aca902013-01-07 15:42:20 +01005130 { "ssl_fc_has_crt", smp_fetch_ssl_fc_has_crt, 0, NULL, SMP_T_BOOL, SMP_USE_L5CLI },
5131 { "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 +02005132 { "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 +02005133#ifdef OPENSSL_NPN_NEGOTIATED
Thierry FOURNIER7654c9f2013-12-17 00:20:33 +01005134 { "ssl_fc_npn", smp_fetch_ssl_fc_npn, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
Willy Tarreaua33c6542012-10-15 13:19:06 +02005135#endif
Dirkjan Bussink48f1c4e2014-02-13 12:29:42 +01005136#ifdef TLSEXT_TYPE_application_layer_protocol_negotiation
Thierry FOURNIER7654c9f2013-12-17 00:20:33 +01005137 { "ssl_fc_alpn", smp_fetch_ssl_fc_alpn, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
Willy Tarreauab861d32013-04-02 02:30:41 +02005138#endif
Thierry FOURNIER7654c9f2013-12-17 00:20:33 +01005139 { "ssl_fc_protocol", smp_fetch_ssl_fc_protocol, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
Emeric Brunb73a9b02014-04-30 18:49:19 +02005140 { "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 +01005141 { "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 +01005142 { "ssl_fc_session_id", smp_fetch_ssl_fc_session_id, 0, NULL, SMP_T_BIN, SMP_USE_L5CLI },
5143 { "ssl_fc_sni", smp_fetch_ssl_fc_sni, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
Willy Tarreau7875d092012-09-10 08:20:03 +02005144 { NULL, NULL, 0, 0, 0 },
5145}};
5146
5147/* Note: must not be declared <const> as its list will be overwritten.
5148 * Please take care of keeping this list alphabetically sorted.
5149 */
Willy Tarreaudc13c112013-06-21 23:16:39 +02005150static struct acl_kw_list acl_kws = {ILH, {
Thierry FOURNIERc5a4e982014-03-05 16:07:08 +01005151 { "ssl_fc_sni_end", "ssl_fc_sni", PAT_MATCH_END },
5152 { "ssl_fc_sni_reg", "ssl_fc_sni", PAT_MATCH_REG },
Willy Tarreau8ed669b2013-01-11 15:49:37 +01005153 { /* END */ },
Willy Tarreau7875d092012-09-10 08:20:03 +02005154}};
5155
Willy Tarreau79eeafa2012-09-14 07:53:05 +02005156/* Note: must not be declared <const> as its list will be overwritten.
5157 * Please take care of keeping this list alphabetically sorted, doing so helps
5158 * all code contributors.
5159 * Optional keywords are also declared with a NULL ->parse() function so that
5160 * the config parser can report an appropriate error when a known keyword was
5161 * not enabled.
5162 */
Willy Tarreau51fb7652012-09-18 18:24:39 +02005163static struct bind_kw_list bind_kws = { "SSL", { }, {
Nenad Merdanovic05552d42015-02-27 19:56:49 +01005164 { "alpn", bind_parse_alpn, 1 }, /* set ALPN supported protocols */
5165 { "ca-file", bind_parse_ca_file, 1 }, /* set CAfile to process verify on client cert */
5166 { "ca-ignore-err", bind_parse_ignore_err, 1 }, /* set error IDs to ignore on verify depth > 0 */
Christopher Faulet31af49d2015-06-09 17:29:50 +02005167 { "ca-sign-file", bind_parse_ca_sign_file, 1 }, /* set CAFile used to generate and sign server certs */
5168 { "ca-sign-pass", bind_parse_ca_sign_pass, 1 }, /* set CAKey passphrase */
Nenad Merdanovic05552d42015-02-27 19:56:49 +01005169 { "ciphers", bind_parse_ciphers, 1 }, /* set SSL cipher suite */
5170 { "crl-file", bind_parse_crl_file, 1 }, /* set certificat revocation list file use on client cert verify */
5171 { "crt", bind_parse_crt, 1 }, /* load SSL certificates from this location */
5172 { "crt-ignore-err", bind_parse_ignore_err, 1 }, /* set error IDs to ingore on verify depth == 0 */
5173 { "crt-list", bind_parse_crt_list, 1 }, /* load a list of crt from this location */
5174 { "ecdhe", bind_parse_ecdhe, 1 }, /* defines named curve for elliptic curve Diffie-Hellman */
5175 { "force-sslv3", bind_parse_force_sslv3, 0 }, /* force SSLv3 */
5176 { "force-tlsv10", bind_parse_force_tlsv10, 0 }, /* force TLSv10 */
5177 { "force-tlsv11", bind_parse_force_tlsv11, 0 }, /* force TLSv11 */
5178 { "force-tlsv12", bind_parse_force_tlsv12, 0 }, /* force TLSv12 */
Christopher Faulet31af49d2015-06-09 17:29:50 +02005179 { "generate-certificates", bind_parse_generate_certs, 0 }, /* enable the server certificates generation */
Nenad Merdanovic05552d42015-02-27 19:56:49 +01005180 { "no-sslv3", bind_parse_no_sslv3, 0 }, /* disable SSLv3 */
5181 { "no-tlsv10", bind_parse_no_tlsv10, 0 }, /* disable TLSv10 */
5182 { "no-tlsv11", bind_parse_no_tlsv11, 0 }, /* disable TLSv11 */
5183 { "no-tlsv12", bind_parse_no_tlsv12, 0 }, /* disable TLSv12 */
5184 { "no-tls-tickets", bind_parse_no_tls_tickets, 0 }, /* disable session resumption tickets */
5185 { "ssl", bind_parse_ssl, 0 }, /* enable SSL processing */
5186 { "strict-sni", bind_parse_strict_sni, 0 }, /* refuse negotiation if sni doesn't match a certificate */
5187 { "tls-ticket-keys", bind_parse_tls_ticket_keys, 1 }, /* set file to load TLS ticket keys from */
5188 { "verify", bind_parse_verify, 1 }, /* set SSL verify method */
5189 { "npn", bind_parse_npn, 1 }, /* set NPN supported protocols */
Willy Tarreau79eeafa2012-09-14 07:53:05 +02005190 { NULL, NULL, 0 },
5191}};
Emeric Brun46591952012-05-18 15:47:34 +02005192
Willy Tarreau92faadf2012-10-10 23:04:25 +02005193/* Note: must not be declared <const> as its list will be overwritten.
5194 * Please take care of keeping this list alphabetically sorted, doing so helps
5195 * all code contributors.
5196 * Optional keywords are also declared with a NULL ->parse() function so that
5197 * the config parser can report an appropriate error when a known keyword was
5198 * not enabled.
5199 */
5200static struct srv_kw_list srv_kws = { "SSL", { }, {
Emeric Brunef42d922012-10-11 16:11:36 +02005201 { "ca-file", srv_parse_ca_file, 1, 0 }, /* set CAfile to process verify server cert */
Emeric Brunecc91fe2012-10-11 15:05:10 +02005202 { "check-ssl", srv_parse_check_ssl, 0, 0 }, /* enable SSL for health checks */
5203 { "ciphers", srv_parse_ciphers, 1, 0 }, /* select the cipher suite */
Emeric Brunef42d922012-10-11 16:11:36 +02005204 { "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 +02005205 { "crt", srv_parse_crt, 1, 0 }, /* set client certificate */
Emeric Brunecc91fe2012-10-11 15:05:10 +02005206 { "force-sslv3", srv_parse_force_sslv3, 0, 0 }, /* force SSLv3 */
5207 { "force-tlsv10", srv_parse_force_tlsv10, 0, 0 }, /* force TLSv10 */
5208 { "force-tlsv11", srv_parse_force_tlsv11, 0, 0 }, /* force TLSv11 */
5209 { "force-tlsv12", srv_parse_force_tlsv12, 0, 0 }, /* force TLSv12 */
Willy Tarreau2a3fb1c2015-02-05 16:47:07 +01005210 { "no-ssl-reuse", srv_parse_no_ssl_reuse, 0, 0 }, /* disable session reuse */
Emeric Brunecc91fe2012-10-11 15:05:10 +02005211 { "no-sslv3", srv_parse_no_sslv3, 0, 0 }, /* disable SSLv3 */
5212 { "no-tlsv10", srv_parse_no_tlsv10, 0, 0 }, /* disable TLSv10 */
5213 { "no-tlsv11", srv_parse_no_tlsv11, 0, 0 }, /* disable TLSv11 */
5214 { "no-tlsv12", srv_parse_no_tlsv12, 0, 0 }, /* disable TLSv12 */
Emeric Brunf9c5c472012-10-11 15:28:34 +02005215 { "no-tls-tickets", srv_parse_no_tls_tickets, 0, 0 }, /* disable session resumption tickets */
David Safb76832014-05-08 23:42:08 -04005216 { "send-proxy-v2-ssl", srv_parse_send_proxy_ssl, 0, 0 }, /* send PROXY protocol header v2 with SSL info */
5217 { "send-proxy-v2-ssl-cn", srv_parse_send_proxy_cn, 0, 0 }, /* send PROXY protocol header v2 with CN */
Emeric Brunecc91fe2012-10-11 15:05:10 +02005218 { "ssl", srv_parse_ssl, 0, 0 }, /* enable SSL processing */
Emeric Brunef42d922012-10-11 16:11:36 +02005219 { "verify", srv_parse_verify, 1, 0 }, /* set SSL verify method */
Evan Broderbe554312013-06-27 00:05:25 -07005220 { "verifyhost", srv_parse_verifyhost, 1, 0 }, /* require that SSL cert verifies for hostname */
Willy Tarreau92faadf2012-10-10 23:04:25 +02005221 { NULL, NULL, 0, 0 },
5222}};
5223
Emeric Brun2c86cbf2014-10-30 15:56:50 +01005224static struct cfg_kw_list cfg_kws = {ILH, {
5225 { CFG_GLOBAL, "ssl-default-bind-options", ssl_parse_default_bind_options },
5226 { CFG_GLOBAL, "ssl-default-server-options", ssl_parse_default_server_options },
5227 { 0, NULL, NULL },
5228}};
5229
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02005230/* transport-layer operations for SSL sockets */
5231struct xprt_ops ssl_sock = {
Emeric Brun46591952012-05-18 15:47:34 +02005232 .snd_buf = ssl_sock_from_buf,
5233 .rcv_buf = ssl_sock_to_buf,
5234 .rcv_pipe = NULL,
5235 .snd_pipe = NULL,
5236 .shutr = NULL,
5237 .shutw = ssl_sock_shutw,
5238 .close = ssl_sock_close,
5239 .init = ssl_sock_init,
5240};
5241
Janusz Dziemidowicz2c701b52015-03-07 23:03:59 +01005242#if (OPENSSL_VERSION_NUMBER >= 0x1000200fL && !defined OPENSSL_NO_TLSEXT && !defined OPENSSL_IS_BORINGSSL)
5243
5244static void ssl_sock_sctl_free_func(void *parent, void *ptr, CRYPTO_EX_DATA *ad, int idx, long argl, void *argp)
5245{
5246 if (ptr) {
5247 chunk_destroy(ptr);
5248 free(ptr);
5249 }
5250}
5251
5252#endif
5253
Emeric Brun46591952012-05-18 15:47:34 +02005254__attribute__((constructor))
Willy Tarreau92faadf2012-10-10 23:04:25 +02005255static void __ssl_sock_init(void)
5256{
Emeric Brun46591952012-05-18 15:47:34 +02005257 STACK_OF(SSL_COMP)* cm;
5258
Willy Tarreau610f04b2014-02-13 11:36:41 +01005259#ifdef LISTEN_DEFAULT_CIPHERS
5260 global.listen_default_ciphers = LISTEN_DEFAULT_CIPHERS;
5261#endif
5262#ifdef CONNECT_DEFAULT_CIPHERS
5263 global.connect_default_ciphers = CONNECT_DEFAULT_CIPHERS;
5264#endif
5265 if (global.listen_default_ciphers)
5266 global.listen_default_ciphers = strdup(global.listen_default_ciphers);
5267 if (global.connect_default_ciphers)
5268 global.connect_default_ciphers = strdup(global.connect_default_ciphers);
Emeric Brun2c86cbf2014-10-30 15:56:50 +01005269 global.listen_default_ssloptions = BC_SSL_O_NONE;
5270 global.connect_default_ssloptions = SRV_SSL_O_NONE;
Willy Tarreau610f04b2014-02-13 11:36:41 +01005271
Emeric Brun46591952012-05-18 15:47:34 +02005272 SSL_library_init();
5273 cm = SSL_COMP_get_compression_methods();
5274 sk_SSL_COMP_zero(cm);
Janusz Dziemidowicz2c701b52015-03-07 23:03:59 +01005275#if (OPENSSL_VERSION_NUMBER >= 0x1000200fL && !defined OPENSSL_NO_TLSEXT && !defined OPENSSL_IS_BORINGSSL)
5276 sctl_ex_index = SSL_CTX_get_ex_new_index(0, NULL, NULL, NULL, ssl_sock_sctl_free_func);
5277#endif
Willy Tarreau7875d092012-09-10 08:20:03 +02005278 sample_register_fetches(&sample_fetch_keywords);
5279 acl_register_keywords(&acl_kws);
Willy Tarreau79eeafa2012-09-14 07:53:05 +02005280 bind_register_keywords(&bind_kws);
Willy Tarreau92faadf2012-10-10 23:04:25 +02005281 srv_register_keywords(&srv_kws);
Emeric Brun2c86cbf2014-10-30 15:56:50 +01005282 cfg_register_keywords(&cfg_kws);
Willy Tarreaud92aa5c2015-01-15 21:34:39 +01005283
5284 global.ssl_session_max_cost = SSL_SESSION_MAX_COST;
5285 global.ssl_handshake_max_cost = SSL_HANDSHAKE_MAX_COST;
Remi Gacogne4f902b82015-05-28 16:23:00 +02005286
5287#ifndef OPENSSL_NO_DH
5288 ssl_dh_ptr_index = SSL_CTX_get_ex_new_index(0, NULL, NULL, NULL, NULL);
5289#endif
Christopher Faulet31af49d2015-06-09 17:29:50 +02005290
Willy Tarreauc8ad3be2015-06-17 15:48:26 +02005291#ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME
Christopher Faulet31af49d2015-06-09 17:29:50 +02005292 /* Add a global parameter for the LRU cache size */
5293 if (global.tune.ssl_ctx_cache)
5294 ssl_ctx_lru_tree = lru64_new(global.tune.ssl_ctx_cache);
5295 ssl_ctx_lru_seed = (unsigned int)time(NULL);
Willy Tarreauc8ad3be2015-06-17 15:48:26 +02005296#endif
Emeric Brun46591952012-05-18 15:47:34 +02005297}
5298
Remi Gacogned3a23c32015-05-28 16:39:47 +02005299__attribute__((destructor))
5300static void __ssl_sock_deinit(void)
5301{
Willy Tarreauc8ad3be2015-06-17 15:48:26 +02005302#ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME
Christopher Faulet31af49d2015-06-09 17:29:50 +02005303 lru64_destroy(ssl_ctx_lru_tree);
Willy Tarreauc8ad3be2015-06-17 15:48:26 +02005304#endif
Christopher Faulet31af49d2015-06-09 17:29:50 +02005305
Remi Gacogned3a23c32015-05-28 16:39:47 +02005306#ifndef OPENSSL_NO_DH
5307 if (local_dh_1024) {
5308 DH_free(local_dh_1024);
5309 local_dh_1024 = NULL;
5310 }
5311
5312 if (local_dh_2048) {
5313 DH_free(local_dh_2048);
5314 local_dh_2048 = NULL;
5315 }
5316
5317 if (local_dh_4096) {
5318 DH_free(local_dh_4096);
5319 local_dh_4096 = NULL;
5320 }
5321
Remi Gacogne47783ef2015-05-29 15:53:22 +02005322 if (global_dh) {
5323 DH_free(global_dh);
5324 global_dh = NULL;
5325 }
Remi Gacogned3a23c32015-05-28 16:39:47 +02005326#endif
5327
5328 ERR_remove_state(0);
5329 ERR_free_strings();
5330
5331 EVP_cleanup();
5332
5333#if OPENSSL_VERSION_NUMBER >= 0x00907000L
5334 CRYPTO_cleanup_all_ex_data();
5335#endif
5336}
5337
5338
Emeric Brun46591952012-05-18 15:47:34 +02005339/*
5340 * Local variables:
5341 * c-indent-level: 8
5342 * c-basic-offset: 8
5343 * End:
5344 */