blob: dcbef4c574b83f4f584643a08af905e4af3edda8 [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
1148ssl_sock_generated_cert_serial(void *data, size_t len)
1149{
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) {
Christopher Faulet30548802015-06-11 13:39:32 +02001191 struct sockaddr to;
1192 int fd;
1193
1194 if (s->generate_certs &&
1195 (fd = SSL_get_fd(ssl)) != -1 &&
1196 tcp_get_dst(fd, &to, sizeof(to), 0) != -1) {
1197 unsigned int serial = ssl_sock_generated_cert_serial(&to, sizeof(to));
1198 SSL_CTX *ctx = ssl_sock_get_generated_cert(serial, s->ca_sign_cert);
1199 if (ctx) {
1200 /* switch ctx */
1201 SSL_set_SSL_CTX(ssl, ctx);
1202 return SSL_TLSEXT_ERR_OK;
1203 }
1204 }
1205
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +02001206 return (s->strict_sni ?
1207 SSL_TLSEXT_ERR_ALERT_FATAL :
Emmanuel Hocdet79274e22013-05-31 12:47:44 +02001208 SSL_TLSEXT_ERR_NOACK);
Emmanuel Hocdet65623372013-01-24 17:17:15 +01001209 }
Emeric Brunfc0421f2012-09-07 17:30:07 +02001210
Willy Tarreau19d14ef2012-10-29 16:51:55 +01001211 for (i = 0; i < trash.size; i++) {
Emeric Brunfc0421f2012-09-07 17:30:07 +02001212 if (!servername[i])
1213 break;
Willy Tarreau19d14ef2012-10-29 16:51:55 +01001214 trash.str[i] = tolower(servername[i]);
1215 if (!wildp && (trash.str[i] == '.'))
1216 wildp = &trash.str[i];
Emeric Brunfc0421f2012-09-07 17:30:07 +02001217 }
Willy Tarreau19d14ef2012-10-29 16:51:55 +01001218 trash.str[i] = 0;
Emeric Brunfc0421f2012-09-07 17:30:07 +02001219
1220 /* lookup in full qualified names */
Willy Tarreau19d14ef2012-10-29 16:51:55 +01001221 node = ebst_lookup(&s->sni_ctx, trash.str);
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +02001222
1223 /* lookup a not neg filter */
1224 for (n = node; n; n = ebmb_next_dup(n)) {
1225 if (!container_of(n, struct sni_ctx, name)->neg) {
1226 node = n;
1227 break;
Emmanuel Hocdet65623372013-01-24 17:17:15 +01001228 }
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +02001229 }
1230 if (!node && wildp) {
1231 /* lookup in wildcards names */
Emeric Brunfc0421f2012-09-07 17:30:07 +02001232 node = ebst_lookup(&s->sni_w_ctx, wildp);
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +02001233 }
1234 if (!node || container_of(node, struct sni_ctx, name)->neg) {
Christopher Faulet31af49d2015-06-09 17:29:50 +02001235 SSL_CTX *ctx;
1236
1237 if (s->generate_certs &&
1238 (ctx = ssl_sock_generate_certificate(servername, s))) {
1239 /* switch ctx */
1240 SSL_set_SSL_CTX(ssl, ctx);
1241 return SSL_TLSEXT_ERR_OK;
1242 }
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +02001243 return (s->strict_sni ?
1244 SSL_TLSEXT_ERR_ALERT_FATAL :
1245 SSL_TLSEXT_ERR_ALERT_WARNING);
Emeric Brunfc0421f2012-09-07 17:30:07 +02001246 }
1247
1248 /* switch ctx */
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +02001249 SSL_set_SSL_CTX(ssl, container_of(node, struct sni_ctx, name)->ctx);
Emeric Brunfc0421f2012-09-07 17:30:07 +02001250 return SSL_TLSEXT_ERR_OK;
1251}
1252#endif /* SSL_CTRL_SET_TLSEXT_HOSTNAME */
1253
Emeric Bruna4bcd9a2012-09-20 16:19:02 +02001254#ifndef OPENSSL_NO_DH
Remi Gacognef46cd6e2014-06-12 14:58:40 +02001255
1256static DH * ssl_get_dh_1024(void)
1257{
Remi Gacogned3a341a2015-05-29 16:26:17 +02001258 static unsigned char dh1024_p[]={
1259 0xFA,0xF9,0x2A,0x22,0x2A,0xA7,0x7F,0xE1,0x67,0x4E,0x53,0xF7,
1260 0x56,0x13,0xC3,0xB1,0xE3,0x29,0x6B,0x66,0x31,0x6A,0x7F,0xB3,
1261 0xC2,0x68,0x6B,0xCB,0x1D,0x57,0x39,0x1D,0x1F,0xFF,0x1C,0xC9,
1262 0xA6,0xA4,0x98,0x82,0x31,0x5D,0x25,0xFF,0x8A,0xE0,0x73,0x96,
1263 0x81,0xC8,0x83,0x79,0xC1,0x5A,0x04,0xF8,0x37,0x0D,0xA8,0x3D,
1264 0xAE,0x74,0xBC,0xDB,0xB6,0xA4,0x75,0xD9,0x71,0x8A,0xA0,0x17,
1265 0x9E,0x2D,0xC8,0xA8,0xDF,0x2C,0x5F,0x82,0x95,0xF8,0x92,0x9B,
1266 0xA7,0x33,0x5F,0x89,0x71,0xC8,0x2D,0x6B,0x18,0x86,0xC4,0x94,
1267 0x22,0xA5,0x52,0x8D,0xF6,0xF6,0xD2,0x37,0x92,0x0F,0xA5,0xCC,
1268 0xDB,0x7B,0x1D,0x3D,0xA1,0x31,0xB7,0x80,0x8F,0x0B,0x67,0x5E,
1269 0x36,0xA5,0x60,0x0C,0xF1,0x95,0x33,0x8B,
1270 };
1271 static unsigned char dh1024_g[]={
1272 0x02,
1273 };
1274
Remi Gacognef46cd6e2014-06-12 14:58:40 +02001275 DH *dh = DH_new();
1276 if (dh) {
Remi Gacogned3a341a2015-05-29 16:26:17 +02001277 dh->p = BN_bin2bn(dh1024_p, sizeof dh1024_p, NULL);
1278 dh->g = BN_bin2bn(dh1024_g, sizeof dh1024_g, NULL);
1279
Remi Gacognef46cd6e2014-06-12 14:58:40 +02001280 if (!dh->p || !dh->g) {
1281 DH_free(dh);
1282 dh = NULL;
1283 }
1284 }
1285 return dh;
1286}
1287
1288static DH *ssl_get_dh_2048(void)
1289{
Remi Gacogned3a341a2015-05-29 16:26:17 +02001290 static unsigned char dh2048_p[]={
1291 0xEC,0x86,0xF8,0x70,0xA0,0x33,0x16,0xEC,0x05,0x1A,0x73,0x59,
1292 0xCD,0x1F,0x8B,0xF8,0x29,0xE4,0xD2,0xCF,0x52,0xDD,0xC2,0x24,
1293 0x8D,0xB5,0x38,0x9A,0xFB,0x5C,0xA4,0xE4,0xB2,0xDA,0xCE,0x66,
1294 0x50,0x74,0xA6,0x85,0x4D,0x4B,0x1D,0x30,0xB8,0x2B,0xF3,0x10,
1295 0xE9,0xA7,0x2D,0x05,0x71,0xE7,0x81,0xDF,0x8B,0x59,0x52,0x3B,
1296 0x5F,0x43,0x0B,0x68,0xF1,0xDB,0x07,0xBE,0x08,0x6B,0x1B,0x23,
1297 0xEE,0x4D,0xCC,0x9E,0x0E,0x43,0xA0,0x1E,0xDF,0x43,0x8C,0xEC,
1298 0xBE,0xBE,0x90,0xB4,0x51,0x54,0xB9,0x2F,0x7B,0x64,0x76,0x4E,
1299 0x5D,0xD4,0x2E,0xAE,0xC2,0x9E,0xAE,0x51,0x43,0x59,0xC7,0x77,
1300 0x9C,0x50,0x3C,0x0E,0xED,0x73,0x04,0x5F,0xF1,0x4C,0x76,0x2A,
1301 0xD8,0xF8,0xCF,0xFC,0x34,0x40,0xD1,0xB4,0x42,0x61,0x84,0x66,
1302 0x42,0x39,0x04,0xF8,0x68,0xB2,0x62,0xD7,0x55,0xED,0x1B,0x74,
1303 0x75,0x91,0xE0,0xC5,0x69,0xC1,0x31,0x5C,0xDB,0x7B,0x44,0x2E,
1304 0xCE,0x84,0x58,0x0D,0x1E,0x66,0x0C,0xC8,0x44,0x9E,0xFD,0x40,
1305 0x08,0x67,0x5D,0xFB,0xA7,0x76,0x8F,0x00,0x11,0x87,0xE9,0x93,
1306 0xF9,0x7D,0xC4,0xBC,0x74,0x55,0x20,0xD4,0x4A,0x41,0x2F,0x43,
1307 0x42,0x1A,0xC1,0xF2,0x97,0x17,0x49,0x27,0x37,0x6B,0x2F,0x88,
1308 0x7E,0x1C,0xA0,0xA1,0x89,0x92,0x27,0xD9,0x56,0x5A,0x71,0xC1,
1309 0x56,0x37,0x7E,0x3A,0x9D,0x05,0xE7,0xEE,0x5D,0x8F,0x82,0x17,
1310 0xBC,0xE9,0xC2,0x93,0x30,0x82,0xF9,0xF4,0xC9,0xAE,0x49,0xDB,
1311 0xD0,0x54,0xB4,0xD9,0x75,0x4D,0xFA,0x06,0xB8,0xD6,0x38,0x41,
1312 0xB7,0x1F,0x77,0xF3,
1313 };
1314 static unsigned char dh2048_g[]={
1315 0x02,
1316 };
1317
Remi Gacognef46cd6e2014-06-12 14:58:40 +02001318 DH *dh = DH_new();
1319 if (dh) {
Remi Gacogned3a341a2015-05-29 16:26:17 +02001320 dh->p = BN_bin2bn(dh2048_p, sizeof dh2048_p, NULL);
1321 dh->g = BN_bin2bn(dh2048_g, sizeof dh2048_g, NULL);
1322
Remi Gacognef46cd6e2014-06-12 14:58:40 +02001323 if (!dh->p || !dh->g) {
1324 DH_free(dh);
1325 dh = NULL;
1326 }
1327 }
1328 return dh;
1329}
1330
1331static DH *ssl_get_dh_4096(void)
1332{
Remi Gacogned3a341a2015-05-29 16:26:17 +02001333 static unsigned char dh4096_p[]={
1334 0xDE,0x16,0x94,0xCD,0x99,0x58,0x07,0xF1,0xF7,0x32,0x96,0x11,
1335 0x04,0x82,0xD4,0x84,0x72,0x80,0x99,0x06,0xCA,0xF0,0xA3,0x68,
1336 0x07,0xCE,0x64,0x50,0xE7,0x74,0x45,0x20,0x80,0x5E,0x4D,0xAD,
1337 0xA5,0xB6,0xED,0xFA,0x80,0x6C,0x3B,0x35,0xC4,0x9A,0x14,0x6B,
1338 0x32,0xBB,0xFD,0x1F,0x17,0x8E,0xB7,0x1F,0xD6,0xFA,0x3F,0x7B,
1339 0xEE,0x16,0xA5,0x62,0x33,0x0D,0xED,0xBC,0x4E,0x58,0xE5,0x47,
1340 0x4D,0xE9,0xAB,0x8E,0x38,0xD3,0x6E,0x90,0x57,0xE3,0x22,0x15,
1341 0x33,0xBD,0xF6,0x43,0x45,0xB5,0x10,0x0A,0xBE,0x2C,0xB4,0x35,
1342 0xB8,0x53,0x8D,0xAD,0xFB,0xA7,0x1F,0x85,0x58,0x41,0x7A,0x79,
1343 0x20,0x68,0xB3,0xE1,0x3D,0x08,0x76,0xBF,0x86,0x0D,0x49,0xE3,
1344 0x82,0x71,0x8C,0xB4,0x8D,0x81,0x84,0xD4,0xE7,0xBE,0x91,0xDC,
1345 0x26,0x39,0x48,0x0F,0x35,0xC4,0xCA,0x65,0xE3,0x40,0x93,0x52,
1346 0x76,0x58,0x7D,0xDD,0x51,0x75,0xDC,0x69,0x61,0xBF,0x47,0x2C,
1347 0x16,0x68,0x2D,0xC9,0x29,0xD3,0xE6,0xC0,0x99,0x48,0xA0,0x9A,
1348 0xC8,0x78,0xC0,0x6D,0x81,0x67,0x12,0x61,0x3F,0x71,0xBA,0x41,
1349 0x1F,0x6C,0x89,0x44,0x03,0xBA,0x3B,0x39,0x60,0xAA,0x28,0x55,
1350 0x59,0xAE,0xB8,0xFA,0xCB,0x6F,0xA5,0x1A,0xF7,0x2B,0xDD,0x52,
1351 0x8A,0x8B,0xE2,0x71,0xA6,0x5E,0x7E,0xD8,0x2E,0x18,0xE0,0x66,
1352 0xDF,0xDD,0x22,0x21,0x99,0x52,0x73,0xA6,0x33,0x20,0x65,0x0E,
1353 0x53,0xE7,0x6B,0x9B,0xC5,0xA3,0x2F,0x97,0x65,0x76,0xD3,0x47,
1354 0x23,0x77,0x12,0xB6,0x11,0x7B,0x24,0xED,0xF1,0xEF,0xC0,0xE2,
1355 0xA3,0x7E,0x67,0x05,0x3E,0x96,0x4D,0x45,0xC2,0x18,0xD1,0x73,
1356 0x9E,0x07,0xF3,0x81,0x6E,0x52,0x63,0xF6,0x20,0x76,0xB9,0x13,
1357 0xD2,0x65,0x30,0x18,0x16,0x09,0x16,0x9E,0x8F,0xF1,0xD2,0x10,
1358 0x5A,0xD3,0xD4,0xAF,0x16,0x61,0xDA,0x55,0x2E,0x18,0x5E,0x14,
1359 0x08,0x54,0x2E,0x2A,0x25,0xA2,0x1A,0x9B,0x8B,0x32,0xA9,0xFD,
1360 0xC2,0x48,0x96,0xE1,0x80,0xCA,0xE9,0x22,0x17,0xBB,0xCE,0x3E,
1361 0x9E,0xED,0xC7,0xF1,0x1F,0xEC,0x17,0x21,0xDC,0x7B,0x82,0x48,
1362 0x8E,0xBB,0x4B,0x9D,0x5B,0x04,0x04,0xDA,0xDB,0x39,0xDF,0x01,
1363 0x40,0xC3,0xAA,0x26,0x23,0x89,0x75,0xC6,0x0B,0xD0,0xA2,0x60,
1364 0x6A,0xF1,0xCC,0x65,0x18,0x98,0x1B,0x52,0xD2,0x74,0x61,0xCC,
1365 0xBD,0x60,0xAE,0xA3,0xA0,0x66,0x6A,0x16,0x34,0x92,0x3F,0x41,
1366 0x40,0x31,0x29,0xC0,0x2C,0x63,0xB2,0x07,0x8D,0xEB,0x94,0xB8,
1367 0xE8,0x47,0x92,0x52,0x93,0x6A,0x1B,0x7E,0x1A,0x61,0xB3,0x1B,
1368 0xF0,0xD6,0x72,0x9B,0xF1,0xB0,0xAF,0xBF,0x3E,0x65,0xEF,0x23,
1369 0x1D,0x6F,0xFF,0x70,0xCD,0x8A,0x4C,0x8A,0xA0,0x72,0x9D,0xBE,
1370 0xD4,0xBB,0x24,0x47,0x4A,0x68,0xB5,0xF5,0xC6,0xD5,0x7A,0xCD,
1371 0xCA,0x06,0x41,0x07,0xAD,0xC2,0x1E,0xE6,0x54,0xA7,0xAD,0x03,
1372 0xD9,0x12,0xC1,0x9C,0x13,0xB1,0xC9,0x0A,0x43,0x8E,0x1E,0x08,
1373 0xCE,0x50,0x82,0x73,0x5F,0xA7,0x55,0x1D,0xD9,0x59,0xAC,0xB5,
1374 0xEA,0x02,0x7F,0x6C,0x5B,0x74,0x96,0x98,0x67,0x24,0xA3,0x0F,
1375 0x15,0xFC,0xA9,0x7D,0x3E,0x67,0xD1,0x70,0xF8,0x97,0xF3,0x67,
1376 0xC5,0x8C,0x88,0x44,0x08,0x02,0xC7,0x2B,
Remi Gacognef46cd6e2014-06-12 14:58:40 +02001377 };
Remi Gacogned3a341a2015-05-29 16:26:17 +02001378 static unsigned char dh4096_g[]={
1379 0x02,
1380 };
Remi Gacognef46cd6e2014-06-12 14:58:40 +02001381
Remi Gacognef46cd6e2014-06-12 14:58:40 +02001382 DH *dh = DH_new();
1383 if (dh) {
Remi Gacogned3a341a2015-05-29 16:26:17 +02001384 dh->p = BN_bin2bn(dh4096_p, sizeof dh4096_p, NULL);
1385 dh->g = BN_bin2bn(dh4096_g, sizeof dh4096_g, NULL);
1386
Remi Gacognef46cd6e2014-06-12 14:58:40 +02001387 if (!dh->p || !dh->g) {
1388 DH_free(dh);
1389 dh = NULL;
1390 }
1391 }
1392 return dh;
1393}
1394
1395/* Returns Diffie-Hellman parameters matching the private key length
1396 but not exceeding global.tune.ssl_default_dh_param */
1397static DH *ssl_get_tmp_dh(SSL *ssl, int export, int keylen)
1398{
1399 DH *dh = NULL;
1400 EVP_PKEY *pkey = SSL_get_privatekey(ssl);
1401 int type = pkey ? EVP_PKEY_type(pkey->type) : EVP_PKEY_NONE;
1402
1403 /* The keylen supplied by OpenSSL can only be 512 or 1024.
1404 See ssl3_send_server_key_exchange() in ssl/s3_srvr.c
1405 */
1406 if (type == EVP_PKEY_RSA || type == EVP_PKEY_DSA) {
1407 keylen = EVP_PKEY_bits(pkey);
1408 }
1409
1410 if (keylen > global.tune.ssl_default_dh_param) {
1411 keylen = global.tune.ssl_default_dh_param;
1412 }
1413
Remi Gacogned3a341a2015-05-29 16:26:17 +02001414 if (keylen >= 4096) {
Remi Gacogne8de54152014-07-15 11:36:40 +02001415 dh = local_dh_4096;
Remi Gacognef46cd6e2014-06-12 14:58:40 +02001416 }
1417 else if (keylen >= 2048) {
Remi Gacogne8de54152014-07-15 11:36:40 +02001418 dh = local_dh_2048;
Remi Gacognef46cd6e2014-06-12 14:58:40 +02001419 }
1420 else {
Remi Gacogne8de54152014-07-15 11:36:40 +02001421 dh = local_dh_1024;
Remi Gacognef46cd6e2014-06-12 14:58:40 +02001422 }
1423
1424 return dh;
1425}
1426
Remi Gacogne47783ef2015-05-29 15:53:22 +02001427static DH * ssl_sock_get_dh_from_file(const char *filename)
Emeric Bruna4bcd9a2012-09-20 16:19:02 +02001428{
Emeric Bruna4bcd9a2012-09-20 16:19:02 +02001429 DH *dh = NULL;
Remi Gacogne47783ef2015-05-29 15:53:22 +02001430 BIO *in = BIO_new(BIO_s_file());
Emeric Bruna4bcd9a2012-09-20 16:19:02 +02001431
Emeric Bruna4bcd9a2012-09-20 16:19:02 +02001432 if (in == NULL)
1433 goto end;
1434
Remi Gacogne47783ef2015-05-29 15:53:22 +02001435 if (BIO_read_filename(in, filename) <= 0)
Emeric Bruna4bcd9a2012-09-20 16:19:02 +02001436 goto end;
1437
Remi Gacogne47783ef2015-05-29 15:53:22 +02001438 dh = PEM_read_bio_DHparams(in, NULL, NULL, NULL);
1439
1440end:
1441 if (in)
1442 BIO_free(in);
1443
1444 return dh;
1445}
1446
1447int ssl_sock_load_global_dh_param_from_file(const char *filename)
1448{
1449 global_dh = ssl_sock_get_dh_from_file(filename);
1450
1451 if (global_dh) {
1452 return 0;
1453 }
1454
1455 return -1;
1456}
1457
1458/* Loads Diffie-Hellman parameter from a file. Returns 1 if loaded, else -1
1459 if an error occured, and 0 if parameter not found. */
1460int ssl_sock_load_dh_params(SSL_CTX *ctx, const char *file)
1461{
1462 int ret = -1;
1463 DH *dh = ssl_sock_get_dh_from_file(file);
1464
Remi Gacognef46cd6e2014-06-12 14:58:40 +02001465 if (dh) {
1466 ret = 1;
1467 SSL_CTX_set_tmp_dh(ctx, dh);
Remi Gacogne4f902b82015-05-28 16:23:00 +02001468
1469 if (ssl_dh_ptr_index >= 0) {
1470 /* store a pointer to the DH params to avoid complaining about
1471 ssl-default-dh-param not being set for this SSL_CTX */
1472 SSL_CTX_set_ex_data(ctx, ssl_dh_ptr_index, dh);
1473 }
Remi Gacognef46cd6e2014-06-12 14:58:40 +02001474 }
Remi Gacogne47783ef2015-05-29 15:53:22 +02001475 else if (global_dh) {
1476 SSL_CTX_set_tmp_dh(ctx, global_dh);
1477 ret = 0; /* DH params not found */
1478 }
Remi Gacognef46cd6e2014-06-12 14:58:40 +02001479 else {
Emeric Brun41fdb3c2013-04-26 11:05:44 +02001480 /* Clear openssl global errors stack */
1481 ERR_clear_error();
1482
Remi Gacognef46cd6e2014-06-12 14:58:40 +02001483 if (global.tune.ssl_default_dh_param <= 1024) {
1484 /* we are limited to DH parameter of 1024 bits anyway */
Remi Gacogne8de54152014-07-15 11:36:40 +02001485 local_dh_1024 = ssl_get_dh_1024();
1486 if (local_dh_1024 == NULL)
Remi Gacognef46cd6e2014-06-12 14:58:40 +02001487 goto end;
Willy Tarreau6e774b42014-04-25 21:35:23 +02001488
Remi Gacogne8de54152014-07-15 11:36:40 +02001489 SSL_CTX_set_tmp_dh(ctx, local_dh_1024);
Remi Gacognef46cd6e2014-06-12 14:58:40 +02001490 }
1491 else {
1492 SSL_CTX_set_tmp_dh_callback(ctx, ssl_get_tmp_dh);
1493 }
Willy Tarreau6e774b42014-04-25 21:35:23 +02001494
Emeric Brun41fdb3c2013-04-26 11:05:44 +02001495 ret = 0; /* DH params not found */
Emeric Bruna4bcd9a2012-09-20 16:19:02 +02001496 }
Emeric Brun644cde02012-12-14 11:21:13 +01001497
Emeric Bruna4bcd9a2012-09-20 16:19:02 +02001498end:
1499 if (dh)
1500 DH_free(dh);
1501
Emeric Bruna4bcd9a2012-09-20 16:19:02 +02001502 return ret;
1503}
1504#endif
1505
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +02001506static int ssl_sock_add_cert_sni(SSL_CTX *ctx, struct bind_conf *s, char *name, int order)
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01001507{
1508 struct sni_ctx *sc;
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +02001509 int wild = 0, neg = 0;
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01001510
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +02001511 if (*name == '!') {
1512 neg = 1;
1513 name++;
1514 }
1515 if (*name == '*') {
1516 wild = 1;
1517 name++;
1518 }
1519 /* !* filter is a nop */
1520 if (neg && wild)
1521 return order;
1522 if (*name) {
1523 int j, len;
1524 len = strlen(name);
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01001525 sc = malloc(sizeof(struct sni_ctx) + len + 1);
1526 for (j = 0; j < len; j++)
1527 sc->name.key[j] = tolower(name[j]);
1528 sc->name.key[len] = 0;
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01001529 sc->ctx = ctx;
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +02001530 sc->order = order++;
1531 sc->neg = neg;
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01001532 if (wild)
1533 ebst_insert(&s->sni_w_ctx, &sc->name);
1534 else
1535 ebst_insert(&s->sni_ctx, &sc->name);
1536 }
1537 return order;
1538}
1539
Emeric Brunfc0421f2012-09-07 17:30:07 +02001540/* Loads a certificate key and CA chain from a file. Returns 0 on error, -1 if
1541 * an early error happens and the caller must call SSL_CTX_free() by itelf.
1542 */
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +02001543static 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 +02001544{
1545 BIO *in;
1546 X509 *x = NULL, *ca;
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +02001547 int i, err;
Emeric Brunfc0421f2012-09-07 17:30:07 +02001548 int ret = -1;
1549 int order = 0;
1550 X509_NAME *xname;
1551 char *str;
Emeric Brunfc0421f2012-09-07 17:30:07 +02001552#ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME
1553 STACK_OF(GENERAL_NAME) *names;
1554#endif
1555
1556 in = BIO_new(BIO_s_file());
1557 if (in == NULL)
1558 goto end;
1559
1560 if (BIO_read_filename(in, file) <= 0)
1561 goto end;
1562
1563 x = PEM_read_bio_X509_AUX(in, NULL, ctx->default_passwd_callback, ctx->default_passwd_callback_userdata);
1564 if (x == NULL)
1565 goto end;
1566
Emeric Brun50bcecc2013-04-22 13:05:23 +02001567 if (fcount) {
1568 while (fcount--)
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +02001569 order = ssl_sock_add_cert_sni(ctx, s, sni_filter[fcount], order);
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01001570 }
1571 else {
Emeric Brunfc0421f2012-09-07 17:30:07 +02001572#ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01001573 names = X509_get_ext_d2i(x, NID_subject_alt_name, NULL, NULL);
1574 if (names) {
1575 for (i = 0; i < sk_GENERAL_NAME_num(names); i++) {
1576 GENERAL_NAME *name = sk_GENERAL_NAME_value(names, i);
1577 if (name->type == GEN_DNS) {
1578 if (ASN1_STRING_to_UTF8((unsigned char **)&str, name->d.dNSName) >= 0) {
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +02001579 order = ssl_sock_add_cert_sni(ctx, s, str, order);
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01001580 OPENSSL_free(str);
Emeric Brunfc0421f2012-09-07 17:30:07 +02001581 }
Emeric Brunfc0421f2012-09-07 17:30:07 +02001582 }
1583 }
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01001584 sk_GENERAL_NAME_pop_free(names, GENERAL_NAME_free);
Emeric Brunfc0421f2012-09-07 17:30:07 +02001585 }
Emeric Brunfc0421f2012-09-07 17:30:07 +02001586#endif /* SSL_CTRL_SET_TLSEXT_HOSTNAME */
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01001587 xname = X509_get_subject_name(x);
1588 i = -1;
1589 while ((i = X509_NAME_get_index_by_NID(xname, NID_commonName, i)) != -1) {
1590 X509_NAME_ENTRY *entry = X509_NAME_get_entry(xname, i);
1591 if (ASN1_STRING_to_UTF8((unsigned char **)&str, entry->value) >= 0) {
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +02001592 order = ssl_sock_add_cert_sni(ctx, s, str, order);
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01001593 OPENSSL_free(str);
Emeric Brunfc0421f2012-09-07 17:30:07 +02001594 }
Emeric Brunfc0421f2012-09-07 17:30:07 +02001595 }
1596 }
1597
1598 ret = 0; /* the caller must not free the SSL_CTX argument anymore */
1599 if (!SSL_CTX_use_certificate(ctx, x))
1600 goto end;
1601
1602 if (ctx->extra_certs != NULL) {
1603 sk_X509_pop_free(ctx->extra_certs, X509_free);
1604 ctx->extra_certs = NULL;
1605 }
1606
1607 while ((ca = PEM_read_bio_X509(in, NULL, ctx->default_passwd_callback, ctx->default_passwd_callback_userdata))) {
1608 if (!SSL_CTX_add_extra_chain_cert(ctx, ca)) {
1609 X509_free(ca);
1610 goto end;
1611 }
1612 }
1613
1614 err = ERR_get_error();
1615 if (!err || (ERR_GET_LIB(err) == ERR_LIB_PEM && ERR_GET_REASON(err) == PEM_R_NO_START_LINE)) {
1616 /* we successfully reached the last cert in the file */
1617 ret = 1;
1618 }
1619 ERR_clear_error();
1620
1621end:
1622 if (x)
1623 X509_free(x);
1624
1625 if (in)
1626 BIO_free(in);
1627
1628 return ret;
1629}
1630
Emeric Brun50bcecc2013-04-22 13:05:23 +02001631static 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 +02001632{
1633 int ret;
1634 SSL_CTX *ctx;
1635
1636 ctx = SSL_CTX_new(SSLv23_server_method());
1637 if (!ctx) {
Willy Tarreaueb6cead2012-09-20 19:43:14 +02001638 memprintf(err, "%sunable to allocate SSL context for cert '%s'.\n",
1639 err && *err ? *err : "", path);
Emeric Brunfc0421f2012-09-07 17:30:07 +02001640 return 1;
1641 }
1642
1643 if (SSL_CTX_use_PrivateKey_file(ctx, path, SSL_FILETYPE_PEM) <= 0) {
Willy Tarreaueb6cead2012-09-20 19:43:14 +02001644 memprintf(err, "%sunable to load SSL private key from PEM file '%s'.\n",
1645 err && *err ? *err : "", path);
Emeric Brunfc0421f2012-09-07 17:30:07 +02001646 SSL_CTX_free(ctx);
1647 return 1;
1648 }
1649
Emeric Brun50bcecc2013-04-22 13:05:23 +02001650 ret = ssl_sock_load_cert_chain_file(ctx, path, bind_conf, sni_filter, fcount);
Emeric Brunfc0421f2012-09-07 17:30:07 +02001651 if (ret <= 0) {
Willy Tarreaueb6cead2012-09-20 19:43:14 +02001652 memprintf(err, "%sunable to load SSL certificate from PEM file '%s'.\n",
1653 err && *err ? *err : "", path);
Emeric Brunfc0421f2012-09-07 17:30:07 +02001654 if (ret < 0) /* serious error, must do that ourselves */
1655 SSL_CTX_free(ctx);
1656 return 1;
1657 }
Emeric Brun61694ab2012-10-26 13:35:33 +02001658
1659 if (SSL_CTX_check_private_key(ctx) <= 0) {
1660 memprintf(err, "%sinconsistencies between private key and certificate loaded from PEM file '%s'.\n",
1661 err && *err ? *err : "", path);
1662 return 1;
1663 }
1664
Emeric Brunfc0421f2012-09-07 17:30:07 +02001665 /* we must not free the SSL_CTX anymore below, since it's already in
1666 * the tree, so it will be discovered and cleaned in time.
1667 */
Emeric Bruna4bcd9a2012-09-20 16:19:02 +02001668#ifndef OPENSSL_NO_DH
Remi Gacogne4f902b82015-05-28 16:23:00 +02001669 /* store a NULL pointer to indicate we have not yet loaded
1670 a custom DH param file */
1671 if (ssl_dh_ptr_index >= 0) {
1672 SSL_CTX_set_ex_data(ctx, ssl_dh_ptr_index, NULL);
1673 }
1674
Emeric Bruna4bcd9a2012-09-20 16:19:02 +02001675 ret = ssl_sock_load_dh_params(ctx, path);
1676 if (ret < 0) {
1677 if (err)
1678 memprintf(err, "%sunable to load DH parameters from file '%s'.\n",
1679 *err ? *err : "", path);
1680 return 1;
1681 }
1682#endif
1683
Lukas Tribuse4e30f72014-12-09 16:32:51 +01001684#if (defined SSL_CTRL_SET_TLSEXT_STATUS_REQ_CB && !defined OPENSSL_NO_OCSP)
Emeric Brun4147b2e2014-06-16 18:36:30 +02001685 ret = ssl_sock_load_ocsp(ctx, path);
1686 if (ret < 0) {
1687 if (err)
1688 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",
1689 *err ? *err : "", path);
1690 return 1;
1691 }
1692#endif
1693
Janusz Dziemidowicz2c701b52015-03-07 23:03:59 +01001694#if (OPENSSL_VERSION_NUMBER >= 0x1000200fL && !defined OPENSSL_NO_TLSEXT && !defined OPENSSL_IS_BORINGSSL)
1695 if (sctl_ex_index >= 0) {
1696 ret = ssl_sock_load_sctl(ctx, path);
1697 if (ret < 0) {
1698 if (err)
1699 memprintf(err, "%s '%s.sctl' is present but cannot be read or parsed'.\n",
1700 *err ? *err : "", path);
1701 return 1;
1702 }
1703 }
1704#endif
1705
Emeric Brunfc0421f2012-09-07 17:30:07 +02001706#ifndef SSL_CTRL_SET_TLSEXT_HOSTNAME
Willy Tarreau2a65ff02012-09-13 17:54:29 +02001707 if (bind_conf->default_ctx) {
Willy Tarreaueb6cead2012-09-20 19:43:14 +02001708 memprintf(err, "%sthis version of openssl cannot load multiple SSL certificates.\n",
1709 err && *err ? *err : "");
Emeric Brunfc0421f2012-09-07 17:30:07 +02001710 return 1;
1711 }
1712#endif
Willy Tarreau2a65ff02012-09-13 17:54:29 +02001713 if (!bind_conf->default_ctx)
1714 bind_conf->default_ctx = ctx;
Emeric Brunfc0421f2012-09-07 17:30:07 +02001715
1716 return 0;
1717}
1718
Willy Tarreau79eeafa2012-09-14 07:53:05 +02001719int ssl_sock_load_cert(char *path, struct bind_conf *bind_conf, struct proxy *curproxy, char **err)
Emeric Brunfc0421f2012-09-07 17:30:07 +02001720{
Cyril Bonté3180f7b2015-01-25 00:16:08 +01001721 struct dirent **de_list;
1722 int i, n;
Emeric Brunfc0421f2012-09-07 17:30:07 +02001723 DIR *dir;
1724 struct stat buf;
Willy Tarreauee2663b2012-12-06 11:36:59 +01001725 char *end;
1726 char fp[MAXPATHLEN+1];
Emeric Brunfc0421f2012-09-07 17:30:07 +02001727 int cfgerr = 0;
1728
1729 if (!(dir = opendir(path)))
Emeric Brun50bcecc2013-04-22 13:05:23 +02001730 return ssl_sock_load_cert_file(path, bind_conf, curproxy, NULL, 0, err);
Emeric Brunfc0421f2012-09-07 17:30:07 +02001731
1732 /* strip trailing slashes, including first one */
1733 for (end = path + strlen(path) - 1; end >= path && *end == '/'; end--)
1734 *end = 0;
1735
Cyril Bonté3180f7b2015-01-25 00:16:08 +01001736 n = scandir(path, &de_list, 0, alphasort);
1737 if (n < 0) {
1738 memprintf(err, "%sunable to scan directory '%s' : %s.\n",
1739 err && *err ? *err : "", path, strerror(errno));
1740 cfgerr++;
1741 }
1742 else {
1743 for (i = 0; i < n; i++) {
1744 struct dirent *de = de_list[i];
Emeric Brun2aab7222014-06-18 18:15:09 +02001745
Cyril Bonté3180f7b2015-01-25 00:16:08 +01001746 end = strrchr(de->d_name, '.');
Janusz Dziemidowicz2c701b52015-03-07 23:03:59 +01001747 if (end && (!strcmp(end, ".issuer") || !strcmp(end, ".ocsp") || !strcmp(end, ".sctl")))
Cyril Bonté3180f7b2015-01-25 00:16:08 +01001748 goto ignore_entry;
1749
1750 snprintf(fp, sizeof(fp), "%s/%s", path, de->d_name);
1751 if (stat(fp, &buf) != 0) {
1752 memprintf(err, "%sunable to stat SSL certificate from file '%s' : %s.\n",
1753 err && *err ? *err : "", fp, strerror(errno));
1754 cfgerr++;
1755 goto ignore_entry;
1756 }
1757 if (!S_ISREG(buf.st_mode))
1758 goto ignore_entry;
1759 cfgerr += ssl_sock_load_cert_file(fp, bind_conf, curproxy, NULL, 0, err);
1760 ignore_entry:
1761 free(de);
Emeric Brunfc0421f2012-09-07 17:30:07 +02001762 }
Cyril Bonté3180f7b2015-01-25 00:16:08 +01001763 free(de_list);
Emeric Brunfc0421f2012-09-07 17:30:07 +02001764 }
Emeric Brunfc0421f2012-09-07 17:30:07 +02001765 closedir(dir);
1766 return cfgerr;
1767}
1768
Thierry Fournier383085f2013-01-24 14:15:43 +01001769/* Make sure openssl opens /dev/urandom before the chroot. The work is only
1770 * done once. Zero is returned if the operation fails. No error is returned
1771 * if the random is said as not implemented, because we expect that openssl
1772 * will use another method once needed.
1773 */
1774static int ssl_initialize_random()
1775{
1776 unsigned char random;
1777 static int random_initialized = 0;
1778
1779 if (!random_initialized && RAND_bytes(&random, 1) != 0)
1780 random_initialized = 1;
1781
1782 return random_initialized;
1783}
1784
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01001785int ssl_sock_load_cert_list_file(char *file, struct bind_conf *bind_conf, struct proxy *curproxy, char **err)
1786{
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +02001787 char thisline[LINESIZE];
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01001788 FILE *f;
1789 int linenum = 0;
1790 int cfgerr = 0;
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01001791
Willy Tarreauad1731d2013-04-02 17:35:58 +02001792 if ((f = fopen(file, "r")) == NULL) {
1793 memprintf(err, "cannot open file '%s' : %s", file, strerror(errno));
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01001794 return 1;
Willy Tarreauad1731d2013-04-02 17:35:58 +02001795 }
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01001796
1797 while (fgets(thisline, sizeof(thisline), f) != NULL) {
1798 int arg;
Emeric Brun50bcecc2013-04-22 13:05:23 +02001799 int newarg;
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01001800 char *end;
1801 char *args[MAX_LINE_ARGS + 1];
1802 char *line = thisline;
1803
1804 linenum++;
1805 end = line + strlen(line);
1806 if (end-line == sizeof(thisline)-1 && *(end-1) != '\n') {
1807 /* Check if we reached the limit and the last char is not \n.
1808 * Watch out for the last line without the terminating '\n'!
1809 */
Willy Tarreauad1731d2013-04-02 17:35:58 +02001810 memprintf(err, "line %d too long in file '%s', limit is %d characters",
1811 linenum, file, (int)sizeof(thisline)-1);
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01001812 cfgerr = 1;
Willy Tarreauad1731d2013-04-02 17:35:58 +02001813 break;
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01001814 }
1815
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01001816 arg = 0;
Emeric Brun50bcecc2013-04-22 13:05:23 +02001817 newarg = 1;
1818 while (*line) {
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01001819 if (*line == '#' || *line == '\n' || *line == '\r') {
1820 /* end of string, end of loop */
1821 *line = 0;
1822 break;
1823 }
1824 else if (isspace(*line)) {
Emeric Brun50bcecc2013-04-22 13:05:23 +02001825 newarg = 1;
1826 *line = 0;
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01001827 }
Emeric Brun50bcecc2013-04-22 13:05:23 +02001828 else if (newarg) {
1829 if (arg == MAX_LINE_ARGS) {
1830 memprintf(err, "too many args on line %d in file '%s'.",
1831 linenum, file);
1832 cfgerr = 1;
1833 break;
1834 }
1835 newarg = 0;
1836 args[arg++] = line;
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01001837 }
Emeric Brun50bcecc2013-04-22 13:05:23 +02001838 line++;
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01001839 }
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +02001840 if (cfgerr)
1841 break;
Willy Tarreauad1731d2013-04-02 17:35:58 +02001842
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01001843 /* empty line */
Emeric Brun50bcecc2013-04-22 13:05:23 +02001844 if (!arg)
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01001845 continue;
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01001846
Emeric Brun50bcecc2013-04-22 13:05:23 +02001847 cfgerr = ssl_sock_load_cert_file(args[0], bind_conf, curproxy, &args[1], arg-1, err);
Willy Tarreauad1731d2013-04-02 17:35:58 +02001848 if (cfgerr) {
1849 memprintf(err, "error processing line %d in file '%s' : %s", linenum, file, *err);
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01001850 break;
Willy Tarreauad1731d2013-04-02 17:35:58 +02001851 }
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01001852 }
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01001853 fclose(f);
1854 return cfgerr;
1855}
1856
Emeric Brunfc0421f2012-09-07 17:30:07 +02001857#ifndef SSL_OP_CIPHER_SERVER_PREFERENCE /* needs OpenSSL >= 0.9.7 */
1858#define SSL_OP_CIPHER_SERVER_PREFERENCE 0
1859#endif
1860
1861#ifndef SSL_OP_NO_SESSION_RESUMPTION_ON_RENEGOTIATION /* needs OpenSSL >= 0.9.7 */
1862#define SSL_OP_NO_SESSION_RESUMPTION_ON_RENEGOTIATION 0
Willy Tarreau7d588ee2012-11-26 18:47:31 +01001863#define SSL_renegotiate_pending(arg) 0
Emeric Brunfc0421f2012-09-07 17:30:07 +02001864#endif
Emeric Brun2b58d042012-09-20 17:10:03 +02001865#ifndef SSL_OP_SINGLE_ECDH_USE /* needs OpenSSL >= 0.9.8 */
1866#define SSL_OP_SINGLE_ECDH_USE 0
1867#endif
Emeric Brun2d0c4822012-10-02 13:45:20 +02001868#ifndef SSL_OP_NO_TICKET /* needs OpenSSL >= 0.9.8 */
1869#define SSL_OP_NO_TICKET 0
1870#endif
Emeric Brunfc0421f2012-09-07 17:30:07 +02001871#ifndef SSL_OP_NO_COMPRESSION /* needs OpenSSL >= 0.9.9 */
1872#define SSL_OP_NO_COMPRESSION 0
1873#endif
Emeric Brunc0ff4922012-09-28 19:37:02 +02001874#ifndef SSL_OP_NO_TLSv1_1 /* needs OpenSSL >= 1.0.1 */
1875#define SSL_OP_NO_TLSv1_1 0
1876#endif
1877#ifndef SSL_OP_NO_TLSv1_2 /* needs OpenSSL >= 1.0.1 */
1878#define SSL_OP_NO_TLSv1_2 0
1879#endif
Emeric Bruna4bcd9a2012-09-20 16:19:02 +02001880#ifndef SSL_OP_SINGLE_DH_USE /* needs OpenSSL >= 0.9.6 */
1881#define SSL_OP_SINGLE_DH_USE 0
1882#endif
Emeric Brun2b58d042012-09-20 17:10:03 +02001883#ifndef SSL_OP_SINGLE_ECDH_USE /* needs OpenSSL >= 1.0.0 */
1884#define SSL_OP_SINGLE_ECDH_USE 0
1885#endif
Emeric Brunfc0421f2012-09-07 17:30:07 +02001886#ifndef SSL_MODE_RELEASE_BUFFERS /* needs OpenSSL >= 1.0.0 */
1887#define SSL_MODE_RELEASE_BUFFERS 0
1888#endif
Willy Tarreau396a1862014-11-13 14:06:52 +01001889#ifndef SSL_MODE_SMALL_BUFFERS /* needs small_records.patch */
1890#define SSL_MODE_SMALL_BUFFERS 0
1891#endif
Remi Gacognef46cd6e2014-06-12 14:58:40 +02001892
Willy Tarreau2a65ff02012-09-13 17:54:29 +02001893int ssl_sock_prepare_ctx(struct bind_conf *bind_conf, SSL_CTX *ctx, struct proxy *curproxy)
Emeric Brunfc0421f2012-09-07 17:30:07 +02001894{
1895 int cfgerr = 0;
Emeric Brun850efd52014-01-29 12:24:34 +01001896 int verify = SSL_VERIFY_NONE;
Remi Gacogneaf5c3da2014-05-19 10:29:58 +02001897 long ssloptions =
Emeric Brunfc0421f2012-09-07 17:30:07 +02001898 SSL_OP_ALL | /* all known workarounds for bugs */
1899 SSL_OP_NO_SSLv2 |
1900 SSL_OP_NO_COMPRESSION |
Emeric Bruna4bcd9a2012-09-20 16:19:02 +02001901 SSL_OP_SINGLE_DH_USE |
Emeric Brun2b58d042012-09-20 17:10:03 +02001902 SSL_OP_SINGLE_ECDH_USE |
Emeric Brun3c4bc6e2012-10-04 18:44:19 +02001903 SSL_OP_NO_SESSION_RESUMPTION_ON_RENEGOTIATION |
1904 SSL_OP_CIPHER_SERVER_PREFERENCE;
Remi Gacogneaf5c3da2014-05-19 10:29:58 +02001905 long sslmode =
Emeric Brunfc0421f2012-09-07 17:30:07 +02001906 SSL_MODE_ENABLE_PARTIAL_WRITE |
1907 SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER |
Willy Tarreau396a1862014-11-13 14:06:52 +01001908 SSL_MODE_RELEASE_BUFFERS |
1909 SSL_MODE_SMALL_BUFFERS;
Remi Gacognef46cd6e2014-06-12 14:58:40 +02001910 STACK_OF(SSL_CIPHER) * ciphers = NULL;
Willy Tarreaua616ba62014-10-26 06:49:19 +01001911 SSL_CIPHER * cipher = NULL;
Remi Gacognec1eab8c2014-06-12 18:20:11 +02001912 char cipher_description[128];
1913 /* The description of ciphers using an Ephemeral Diffie Hellman key exchange
1914 contains " Kx=DH " or " Kx=DH(". Beware of " Kx=DH/",
1915 which is not ephemeral DH. */
1916 const char dhe_description[] = " Kx=DH ";
1917 const char dhe_export_description[] = " Kx=DH(";
Remi Gacognef46cd6e2014-06-12 14:58:40 +02001918 int idx = 0;
1919 int dhe_found = 0;
Remi Gacogne23d5d372014-10-10 17:04:26 +02001920 SSL *ssl = NULL;
Emeric Brunfc0421f2012-09-07 17:30:07 +02001921
Thierry Fournier383085f2013-01-24 14:15:43 +01001922 /* Make sure openssl opens /dev/urandom before the chroot */
1923 if (!ssl_initialize_random()) {
1924 Alert("OpenSSL random data generator initialization failed.\n");
1925 cfgerr++;
1926 }
1927
Emeric Brun89675492012-10-05 13:48:26 +02001928 if (bind_conf->ssl_options & BC_SSL_O_NO_SSLV3)
Emeric Brunfc0421f2012-09-07 17:30:07 +02001929 ssloptions |= SSL_OP_NO_SSLv3;
Emeric Brun89675492012-10-05 13:48:26 +02001930 if (bind_conf->ssl_options & BC_SSL_O_NO_TLSV10)
Emeric Brunfc0421f2012-09-07 17:30:07 +02001931 ssloptions |= SSL_OP_NO_TLSv1;
Emeric Brun89675492012-10-05 13:48:26 +02001932 if (bind_conf->ssl_options & BC_SSL_O_NO_TLSV11)
Emeric Brunc0ff4922012-09-28 19:37:02 +02001933 ssloptions |= SSL_OP_NO_TLSv1_1;
Emeric Brun89675492012-10-05 13:48:26 +02001934 if (bind_conf->ssl_options & BC_SSL_O_NO_TLSV12)
Emeric Brunc0ff4922012-09-28 19:37:02 +02001935 ssloptions |= SSL_OP_NO_TLSv1_2;
Emeric Brun89675492012-10-05 13:48:26 +02001936 if (bind_conf->ssl_options & BC_SSL_O_NO_TLS_TICKETS)
Emeric Brun2d0c4822012-10-02 13:45:20 +02001937 ssloptions |= SSL_OP_NO_TICKET;
Emeric Brun2cb7ae52012-10-05 14:14:21 +02001938 if (bind_conf->ssl_options & BC_SSL_O_USE_SSLV3)
1939 SSL_CTX_set_ssl_version(ctx, SSLv3_server_method());
1940 if (bind_conf->ssl_options & BC_SSL_O_USE_TLSV10)
1941 SSL_CTX_set_ssl_version(ctx, TLSv1_server_method());
1942#if SSL_OP_NO_TLSv1_1
1943 if (bind_conf->ssl_options & BC_SSL_O_USE_TLSV11)
1944 SSL_CTX_set_ssl_version(ctx, TLSv1_1_server_method());
1945#endif
1946#if SSL_OP_NO_TLSv1_2
1947 if (bind_conf->ssl_options & BC_SSL_O_USE_TLSV12)
1948 SSL_CTX_set_ssl_version(ctx, TLSv1_2_server_method());
1949#endif
Emeric Brunfc0421f2012-09-07 17:30:07 +02001950
1951 SSL_CTX_set_options(ctx, ssloptions);
1952 SSL_CTX_set_mode(ctx, sslmode);
Emeric Brun850efd52014-01-29 12:24:34 +01001953 switch (bind_conf->verify) {
1954 case SSL_SOCK_VERIFY_NONE:
1955 verify = SSL_VERIFY_NONE;
1956 break;
1957 case SSL_SOCK_VERIFY_OPTIONAL:
1958 verify = SSL_VERIFY_PEER;
1959 break;
1960 case SSL_SOCK_VERIFY_REQUIRED:
1961 verify = SSL_VERIFY_PEER|SSL_VERIFY_FAIL_IF_NO_PEER_CERT;
1962 break;
1963 }
1964 SSL_CTX_set_verify(ctx, verify, ssl_sock_bind_verifycbk);
1965 if (verify & SSL_VERIFY_PEER) {
Emeric Brunfb510ea2012-10-05 12:00:26 +02001966 if (bind_conf->ca_file) {
Emeric Brund94b3fe2012-09-20 18:23:56 +02001967 /* load CAfile to verify */
Emeric Brunfb510ea2012-10-05 12:00:26 +02001968 if (!SSL_CTX_load_verify_locations(ctx, bind_conf->ca_file, NULL)) {
Emeric Brund94b3fe2012-09-20 18:23:56 +02001969 Alert("Proxy '%s': unable to load CA file '%s' for bind '%s' at [%s:%d].\n",
Emeric Brunfb510ea2012-10-05 12:00:26 +02001970 curproxy->id, bind_conf->ca_file, bind_conf->arg, bind_conf->file, bind_conf->line);
Emeric Brund94b3fe2012-09-20 18:23:56 +02001971 cfgerr++;
1972 }
1973 /* set CA names fo client cert request, function returns void */
Emeric Brunfb510ea2012-10-05 12:00:26 +02001974 SSL_CTX_set_client_CA_list(ctx, SSL_load_client_CA_file(bind_conf->ca_file));
Emeric Brund94b3fe2012-09-20 18:23:56 +02001975 }
Emeric Brun850efd52014-01-29 12:24:34 +01001976 else {
1977 Alert("Proxy '%s': verify is enabled but no CA file specified for bind '%s' at [%s:%d].\n",
1978 curproxy->id, bind_conf->arg, bind_conf->file, bind_conf->line);
1979 cfgerr++;
1980 }
Emeric Brun051cdab2012-10-02 19:25:50 +02001981#ifdef X509_V_FLAG_CRL_CHECK
Emeric Brunfb510ea2012-10-05 12:00:26 +02001982 if (bind_conf->crl_file) {
Emeric Brund94b3fe2012-09-20 18:23:56 +02001983 X509_STORE *store = SSL_CTX_get_cert_store(ctx);
1984
Emeric Brunfb510ea2012-10-05 12:00:26 +02001985 if (!store || !X509_STORE_load_locations(store, bind_conf->crl_file, NULL)) {
Emeric Brund94b3fe2012-09-20 18:23:56 +02001986 Alert("Proxy '%s': unable to configure CRL file '%s' for bind '%s' at [%s:%d].\n",
Alexander Rigbofc65af02015-04-07 14:02:16 +02001987 curproxy->id, bind_conf->crl_file, bind_conf->arg, bind_conf->file, bind_conf->line);
Emeric Brund94b3fe2012-09-20 18:23:56 +02001988 cfgerr++;
1989 }
Emeric Brun561e5742012-10-02 15:20:55 +02001990 else {
1991 X509_STORE_set_flags(store, X509_V_FLAG_CRL_CHECK|X509_V_FLAG_CRL_CHECK_ALL);
1992 }
Emeric Brund94b3fe2012-09-20 18:23:56 +02001993 }
Emeric Brun051cdab2012-10-02 19:25:50 +02001994#endif
Emeric Brun644cde02012-12-14 11:21:13 +01001995 ERR_clear_error();
Emeric Brund94b3fe2012-09-20 18:23:56 +02001996 }
Emeric Brunfc0421f2012-09-07 17:30:07 +02001997
Nenad Merdanovic05552d42015-02-27 19:56:49 +01001998#if (defined SSL_CTRL_SET_TLSEXT_TICKET_KEY_CB && TLS_TICKETS_NO > 0)
Nenad Merdanovic146defa2015-05-09 08:46:00 +02001999 if(bind_conf->keys_ref) {
Nenad Merdanovic05552d42015-02-27 19:56:49 +01002000 if (!SSL_CTX_set_tlsext_ticket_key_cb(ctx, ssl_tlsext_ticket_key_cb)) {
2001 Alert("Proxy '%s': unable to set callback for TLS ticket validation for bind '%s' at [%s:%d].\n",
2002 curproxy->id, bind_conf->arg, bind_conf->file, bind_conf->line);
2003 cfgerr++;
2004 }
2005 }
2006#endif
2007
Emeric Brun4f65bff2012-11-16 15:11:00 +01002008 if (global.tune.ssllifetime)
2009 SSL_CTX_set_timeout(ctx, global.tune.ssllifetime);
2010
Emeric Brunfc0421f2012-09-07 17:30:07 +02002011 shared_context_set_cache(ctx);
Willy Tarreau2a65ff02012-09-13 17:54:29 +02002012 if (bind_conf->ciphers &&
2013 !SSL_CTX_set_cipher_list(ctx, bind_conf->ciphers)) {
Emeric Brunfc0421f2012-09-07 17:30:07 +02002014 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 +02002015 curproxy->id, bind_conf->ciphers, bind_conf->arg, bind_conf->file, bind_conf->line);
Emeric Brunfc0421f2012-09-07 17:30:07 +02002016 cfgerr++;
2017 }
2018
Remi Gacogne47783ef2015-05-29 15:53:22 +02002019 /* If tune.ssl.default-dh-param has not been set,
2020 neither has ssl-default-dh-file and no static DH
2021 params were in the certificate file. */
Remi Gacogne4f902b82015-05-28 16:23:00 +02002022 if (global.tune.ssl_default_dh_param == 0 &&
Remi Gacogne47783ef2015-05-29 15:53:22 +02002023 global_dh == NULL &&
Remi Gacogne4f902b82015-05-28 16:23:00 +02002024 (ssl_dh_ptr_index == -1 ||
2025 SSL_CTX_get_ex_data(ctx, ssl_dh_ptr_index) == NULL)) {
Lukas Tribus90132722014-08-18 00:56:33 +02002026
Remi Gacogne23d5d372014-10-10 17:04:26 +02002027 ssl = SSL_new(ctx);
Remi Gacognef46cd6e2014-06-12 14:58:40 +02002028
Remi Gacogne23d5d372014-10-10 17:04:26 +02002029 if (ssl) {
2030 ciphers = SSL_get_ciphers(ssl);
2031
2032 if (ciphers) {
2033 for (idx = 0; idx < sk_SSL_CIPHER_num(ciphers); idx++) {
2034 cipher = sk_SSL_CIPHER_value(ciphers, idx);
2035 if (SSL_CIPHER_description(cipher, cipher_description, sizeof (cipher_description)) == cipher_description) {
2036 if (strstr(cipher_description, dhe_description) != NULL ||
2037 strstr(cipher_description, dhe_export_description) != NULL) {
2038 dhe_found = 1;
2039 break;
2040 }
Remi Gacognec1eab8c2014-06-12 18:20:11 +02002041 }
Remi Gacognef46cd6e2014-06-12 14:58:40 +02002042 }
2043 }
Remi Gacogne23d5d372014-10-10 17:04:26 +02002044 SSL_free(ssl);
2045 ssl = NULL;
Lukas Tribus90132722014-08-18 00:56:33 +02002046 }
Remi Gacognef46cd6e2014-06-12 14:58:40 +02002047
Lukas Tribus90132722014-08-18 00:56:33 +02002048 if (dhe_found) {
2049 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 +02002050 }
2051
2052 global.tune.ssl_default_dh_param = 1024;
2053 }
Remi Gacogne8de54152014-07-15 11:36:40 +02002054
2055#ifndef OPENSSL_NO_DH
2056 if (global.tune.ssl_default_dh_param >= 1024) {
2057 if (local_dh_1024 == NULL) {
2058 local_dh_1024 = ssl_get_dh_1024();
2059 }
2060 if (global.tune.ssl_default_dh_param >= 2048) {
2061 if (local_dh_2048 == NULL) {
2062 local_dh_2048 = ssl_get_dh_2048();
2063 }
2064 if (global.tune.ssl_default_dh_param >= 4096) {
2065 if (local_dh_4096 == NULL) {
2066 local_dh_4096 = ssl_get_dh_4096();
2067 }
Remi Gacogne8de54152014-07-15 11:36:40 +02002068 }
2069 }
2070 }
2071#endif /* OPENSSL_NO_DH */
Remi Gacognef46cd6e2014-06-12 14:58:40 +02002072
Emeric Brunfc0421f2012-09-07 17:30:07 +02002073 SSL_CTX_set_info_callback(ctx, ssl_sock_infocbk);
Willy Tarreau5cbe4ef2014-05-08 22:45:11 +02002074#if OPENSSL_VERSION_NUMBER >= 0x00907000L
Emeric Brun29f037d2014-04-25 19:05:36 +02002075 SSL_CTX_set_msg_callback(ctx, ssl_sock_msgcbk);
Willy Tarreau5cbe4ef2014-05-08 22:45:11 +02002076#endif
Emeric Brun29f037d2014-04-25 19:05:36 +02002077
Willy Tarreau6c9a3d52012-10-18 18:57:14 +02002078#ifdef OPENSSL_NPN_NEGOTIATED
2079 if (bind_conf->npn_str)
2080 SSL_CTX_set_next_protos_advertised_cb(ctx, ssl_sock_advertise_npn_protos, bind_conf);
2081#endif
Dirkjan Bussink48f1c4e2014-02-13 12:29:42 +01002082#ifdef TLSEXT_TYPE_application_layer_protocol_negotiation
Willy Tarreauab861d32013-04-02 02:30:41 +02002083 if (bind_conf->alpn_str)
Dirkjan Bussink48f1c4e2014-02-13 12:29:42 +01002084 SSL_CTX_set_alpn_select_cb(ctx, ssl_sock_advertise_alpn_protos, bind_conf);
Willy Tarreauab861d32013-04-02 02:30:41 +02002085#endif
Willy Tarreau6c9a3d52012-10-18 18:57:14 +02002086
Emeric Brunfc0421f2012-09-07 17:30:07 +02002087#ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME
2088 SSL_CTX_set_tlsext_servername_callback(ctx, ssl_sock_switchctx_cbk);
Willy Tarreau2a65ff02012-09-13 17:54:29 +02002089 SSL_CTX_set_tlsext_servername_arg(ctx, bind_conf);
Emeric Brunfc0421f2012-09-07 17:30:07 +02002090#endif
Emeric Brun2b58d042012-09-20 17:10:03 +02002091#if defined(SSL_CTX_set_tmp_ecdh) && !defined(OPENSSL_NO_ECDH)
Emeric Brun6924ef82013-03-06 14:08:53 +01002092 {
Emeric Brun2b58d042012-09-20 17:10:03 +02002093 int i;
2094 EC_KEY *ecdh;
2095
Emeric Brun6924ef82013-03-06 14:08:53 +01002096 i = OBJ_sn2nid(bind_conf->ecdhe ? bind_conf->ecdhe : ECDHE_DEFAULT_CURVE);
Emeric Brun2b58d042012-09-20 17:10:03 +02002097 if (!i || ((ecdh = EC_KEY_new_by_curve_name(i)) == NULL)) {
2098 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 +01002099 curproxy->id, bind_conf->ecdhe ? bind_conf->ecdhe : ECDHE_DEFAULT_CURVE,
2100 bind_conf->arg, bind_conf->file, bind_conf->line);
Emeric Brun2b58d042012-09-20 17:10:03 +02002101 cfgerr++;
2102 }
2103 else {
2104 SSL_CTX_set_tmp_ecdh(ctx, ecdh);
2105 EC_KEY_free(ecdh);
2106 }
2107 }
2108#endif
2109
Emeric Brunfc0421f2012-09-07 17:30:07 +02002110 return cfgerr;
2111}
2112
Evan Broderbe554312013-06-27 00:05:25 -07002113static int ssl_sock_srv_hostcheck(const char *pattern, const char *hostname)
2114{
2115 const char *pattern_wildcard, *pattern_left_label_end, *hostname_left_label_end;
2116 size_t prefixlen, suffixlen;
2117
2118 /* Trivial case */
2119 if (strcmp(pattern, hostname) == 0)
2120 return 1;
2121
Evan Broderbe554312013-06-27 00:05:25 -07002122 /* The rest of this logic is based on RFC 6125, section 6.4.3
2123 * (http://tools.ietf.org/html/rfc6125#section-6.4.3) */
2124
Emeric Bruna848dae2013-10-08 11:27:28 +02002125 pattern_wildcard = NULL;
2126 pattern_left_label_end = pattern;
2127 while (*pattern_left_label_end != '.') {
2128 switch (*pattern_left_label_end) {
2129 case 0:
2130 /* End of label not found */
2131 return 0;
2132 case '*':
2133 /* If there is more than one wildcards */
2134 if (pattern_wildcard)
2135 return 0;
2136 pattern_wildcard = pattern_left_label_end;
2137 break;
2138 }
2139 pattern_left_label_end++;
2140 }
2141
2142 /* If it's not trivial and there is no wildcard, it can't
2143 * match */
2144 if (!pattern_wildcard)
Evan Broderbe554312013-06-27 00:05:25 -07002145 return 0;
2146
2147 /* Make sure all labels match except the leftmost */
2148 hostname_left_label_end = strchr(hostname, '.');
2149 if (!hostname_left_label_end
2150 || strcmp(pattern_left_label_end, hostname_left_label_end) != 0)
2151 return 0;
2152
2153 /* Make sure the leftmost label of the hostname is long enough
2154 * that the wildcard can match */
Emeric Brun369da852013-10-08 11:39:35 +02002155 if (hostname_left_label_end - hostname < (pattern_left_label_end - pattern) - 1)
Evan Broderbe554312013-06-27 00:05:25 -07002156 return 0;
2157
2158 /* Finally compare the string on either side of the
2159 * wildcard */
2160 prefixlen = pattern_wildcard - pattern;
2161 suffixlen = pattern_left_label_end - (pattern_wildcard + 1);
Emeric Bruna848dae2013-10-08 11:27:28 +02002162 if ((prefixlen && (memcmp(pattern, hostname, prefixlen) != 0))
2163 || (suffixlen && (memcmp(pattern_wildcard + 1, hostname_left_label_end - suffixlen, suffixlen) != 0)))
Evan Broderbe554312013-06-27 00:05:25 -07002164 return 0;
2165
2166 return 1;
2167}
2168
2169static int ssl_sock_srv_verifycbk(int ok, X509_STORE_CTX *ctx)
2170{
2171 SSL *ssl;
2172 struct connection *conn;
2173 char *servername;
2174
2175 int depth;
2176 X509 *cert;
2177 STACK_OF(GENERAL_NAME) *alt_names;
2178 int i;
2179 X509_NAME *cert_subject;
2180 char *str;
2181
2182 if (ok == 0)
2183 return ok;
2184
2185 ssl = X509_STORE_CTX_get_ex_data(ctx, SSL_get_ex_data_X509_STORE_CTX_idx());
2186 conn = (struct connection *)SSL_get_app_data(ssl);
2187
2188 servername = objt_server(conn->target)->ssl_ctx.verify_host;
2189
2190 /* We only need to verify the CN on the actual server cert,
2191 * not the indirect CAs */
2192 depth = X509_STORE_CTX_get_error_depth(ctx);
2193 if (depth != 0)
2194 return ok;
2195
2196 /* At this point, the cert is *not* OK unless we can find a
2197 * hostname match */
2198 ok = 0;
2199
2200 cert = X509_STORE_CTX_get_current_cert(ctx);
2201 /* It seems like this might happen if verify peer isn't set */
2202 if (!cert)
2203 return ok;
2204
2205 alt_names = X509_get_ext_d2i(cert, NID_subject_alt_name, NULL, NULL);
2206 if (alt_names) {
2207 for (i = 0; !ok && i < sk_GENERAL_NAME_num(alt_names); i++) {
2208 GENERAL_NAME *name = sk_GENERAL_NAME_value(alt_names, i);
2209 if (name->type == GEN_DNS) {
Emeric Bruna33410c2013-09-17 15:47:48 +02002210#if OPENSSL_VERSION_NUMBER < 0x00907000L
2211 if (ASN1_STRING_to_UTF8((unsigned char **)&str, name->d.ia5) >= 0) {
2212#else
Evan Broderbe554312013-06-27 00:05:25 -07002213 if (ASN1_STRING_to_UTF8((unsigned char **)&str, name->d.dNSName) >= 0) {
Emeric Bruna33410c2013-09-17 15:47:48 +02002214#endif
Evan Broderbe554312013-06-27 00:05:25 -07002215 ok = ssl_sock_srv_hostcheck(str, servername);
2216 OPENSSL_free(str);
2217 }
2218 }
2219 }
Emeric Brun4ad50a42013-09-17 15:19:54 +02002220 sk_GENERAL_NAME_pop_free(alt_names, GENERAL_NAME_free);
Evan Broderbe554312013-06-27 00:05:25 -07002221 }
2222
2223 cert_subject = X509_get_subject_name(cert);
2224 i = -1;
2225 while (!ok && (i = X509_NAME_get_index_by_NID(cert_subject, NID_commonName, i)) != -1) {
2226 X509_NAME_ENTRY *entry = X509_NAME_get_entry(cert_subject, i);
2227 if (ASN1_STRING_to_UTF8((unsigned char **)&str, entry->value) >= 0) {
2228 ok = ssl_sock_srv_hostcheck(str, servername);
2229 OPENSSL_free(str);
2230 }
2231 }
2232
2233 return ok;
2234}
2235
Emeric Brun94324a42012-10-11 14:00:19 +02002236/* prepare ssl context from servers options. Returns an error count */
2237int ssl_sock_prepare_srv_ctx(struct server *srv, struct proxy *curproxy)
2238{
2239 int cfgerr = 0;
Remi Gacogneaf5c3da2014-05-19 10:29:58 +02002240 long options =
Emeric Brun94324a42012-10-11 14:00:19 +02002241 SSL_OP_ALL | /* all known workarounds for bugs */
2242 SSL_OP_NO_SSLv2 |
2243 SSL_OP_NO_COMPRESSION;
Remi Gacogneaf5c3da2014-05-19 10:29:58 +02002244 long mode =
Emeric Brun94324a42012-10-11 14:00:19 +02002245 SSL_MODE_ENABLE_PARTIAL_WRITE |
2246 SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER |
Willy Tarreau396a1862014-11-13 14:06:52 +01002247 SSL_MODE_RELEASE_BUFFERS |
2248 SSL_MODE_SMALL_BUFFERS;
Emeric Brun850efd52014-01-29 12:24:34 +01002249 int verify = SSL_VERIFY_NONE;
Emeric Brun94324a42012-10-11 14:00:19 +02002250
Thierry Fournier383085f2013-01-24 14:15:43 +01002251 /* Make sure openssl opens /dev/urandom before the chroot */
2252 if (!ssl_initialize_random()) {
2253 Alert("OpenSSL random data generator initialization failed.\n");
2254 cfgerr++;
2255 }
2256
Willy Tarreaufce03112015-01-15 21:32:40 +01002257 /* Automatic memory computations need to know we use SSL there */
2258 global.ssl_used_backend = 1;
2259
2260 /* Initiate SSL context for current server */
Emeric Brun94324a42012-10-11 14:00:19 +02002261 srv->ssl_ctx.reused_sess = NULL;
2262 if (srv->use_ssl)
2263 srv->xprt = &ssl_sock;
2264 if (srv->check.use_ssl)
Cyril Bonté9ce13112014-11-15 22:41:27 +01002265 srv->check.xprt = &ssl_sock;
Emeric Brun94324a42012-10-11 14:00:19 +02002266
2267 srv->ssl_ctx.ctx = SSL_CTX_new(SSLv23_client_method());
2268 if (!srv->ssl_ctx.ctx) {
2269 Alert("config : %s '%s', server '%s': unable to allocate ssl context.\n",
2270 proxy_type_str(curproxy), curproxy->id,
2271 srv->id);
2272 cfgerr++;
2273 return cfgerr;
2274 }
Emeric Bruna7aa3092012-10-26 12:58:00 +02002275 if (srv->ssl_ctx.client_crt) {
2276 if (SSL_CTX_use_PrivateKey_file(srv->ssl_ctx.ctx, srv->ssl_ctx.client_crt, SSL_FILETYPE_PEM) <= 0) {
2277 Alert("config : %s '%s', server '%s': unable to load SSL private key from PEM file '%s'.\n",
2278 proxy_type_str(curproxy), curproxy->id,
2279 srv->id, srv->ssl_ctx.client_crt);
2280 cfgerr++;
2281 }
2282 else if (SSL_CTX_use_certificate_chain_file(srv->ssl_ctx.ctx, srv->ssl_ctx.client_crt) <= 0) {
2283 Alert("config : %s '%s', server '%s': unable to load ssl certificate from PEM file '%s'.\n",
2284 proxy_type_str(curproxy), curproxy->id,
2285 srv->id, srv->ssl_ctx.client_crt);
2286 cfgerr++;
2287 }
2288 else if (SSL_CTX_check_private_key(srv->ssl_ctx.ctx) <= 0) {
2289 Alert("config : %s '%s', server '%s': inconsistencies between private key and certificate loaded from PEM file '%s'.\n",
2290 proxy_type_str(curproxy), curproxy->id,
2291 srv->id, srv->ssl_ctx.client_crt);
2292 cfgerr++;
2293 }
2294 }
Emeric Brun94324a42012-10-11 14:00:19 +02002295
2296 if (srv->ssl_ctx.options & SRV_SSL_O_NO_SSLV3)
2297 options |= SSL_OP_NO_SSLv3;
2298 if (srv->ssl_ctx.options & SRV_SSL_O_NO_TLSV10)
2299 options |= SSL_OP_NO_TLSv1;
2300 if (srv->ssl_ctx.options & SRV_SSL_O_NO_TLSV11)
2301 options |= SSL_OP_NO_TLSv1_1;
2302 if (srv->ssl_ctx.options & SRV_SSL_O_NO_TLSV12)
2303 options |= SSL_OP_NO_TLSv1_2;
Emeric Brunf9c5c472012-10-11 15:28:34 +02002304 if (srv->ssl_ctx.options & SRV_SSL_O_NO_TLS_TICKETS)
2305 options |= SSL_OP_NO_TICKET;
Emeric Brun94324a42012-10-11 14:00:19 +02002306 if (srv->ssl_ctx.options & SRV_SSL_O_USE_SSLV3)
2307 SSL_CTX_set_ssl_version(srv->ssl_ctx.ctx, SSLv3_client_method());
2308 if (srv->ssl_ctx.options & SRV_SSL_O_USE_TLSV10)
2309 SSL_CTX_set_ssl_version(srv->ssl_ctx.ctx, TLSv1_client_method());
2310#if SSL_OP_NO_TLSv1_1
2311 if (srv->ssl_ctx.options & SRV_SSL_O_USE_TLSV11)
2312 SSL_CTX_set_ssl_version(srv->ssl_ctx.ctx, TLSv1_1_client_method());
2313#endif
2314#if SSL_OP_NO_TLSv1_2
2315 if (srv->ssl_ctx.options & SRV_SSL_O_USE_TLSV12)
2316 SSL_CTX_set_ssl_version(srv->ssl_ctx.ctx, TLSv1_2_client_method());
2317#endif
2318
2319 SSL_CTX_set_options(srv->ssl_ctx.ctx, options);
2320 SSL_CTX_set_mode(srv->ssl_ctx.ctx, mode);
Emeric Brun850efd52014-01-29 12:24:34 +01002321
2322 if (global.ssl_server_verify == SSL_SERVER_VERIFY_REQUIRED)
2323 verify = SSL_VERIFY_PEER;
2324
2325 switch (srv->ssl_ctx.verify) {
2326 case SSL_SOCK_VERIFY_NONE:
2327 verify = SSL_VERIFY_NONE;
2328 break;
2329 case SSL_SOCK_VERIFY_REQUIRED:
2330 verify = SSL_VERIFY_PEER;
2331 break;
2332 }
Evan Broderbe554312013-06-27 00:05:25 -07002333 SSL_CTX_set_verify(srv->ssl_ctx.ctx,
Emeric Brun850efd52014-01-29 12:24:34 +01002334 verify,
Evan Broderbe554312013-06-27 00:05:25 -07002335 srv->ssl_ctx.verify_host ? ssl_sock_srv_verifycbk : NULL);
Emeric Brun850efd52014-01-29 12:24:34 +01002336 if (verify & SSL_VERIFY_PEER) {
Emeric Brunef42d922012-10-11 16:11:36 +02002337 if (srv->ssl_ctx.ca_file) {
2338 /* load CAfile to verify */
2339 if (!SSL_CTX_load_verify_locations(srv->ssl_ctx.ctx, srv->ssl_ctx.ca_file, NULL)) {
Willy Tarreau07ba08b2014-02-16 19:22:08 +01002340 Alert("Proxy '%s', server '%s' [%s:%d] unable to load CA file '%s'.\n",
Emeric Brunef42d922012-10-11 16:11:36 +02002341 curproxy->id, srv->id,
2342 srv->conf.file, srv->conf.line, srv->ssl_ctx.ca_file);
2343 cfgerr++;
2344 }
2345 }
Emeric Brun850efd52014-01-29 12:24:34 +01002346 else {
2347 if (global.ssl_server_verify == SSL_SERVER_VERIFY_REQUIRED)
Willy Tarreau07ba08b2014-02-16 19:22:08 +01002348 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 +01002349 curproxy->id, srv->id,
2350 srv->conf.file, srv->conf.line);
2351 else
Willy Tarreau07ba08b2014-02-16 19:22:08 +01002352 Alert("Proxy '%s', server '%s' [%s:%d] verify is enabled but no CA file specified.\n",
Emeric Brun850efd52014-01-29 12:24:34 +01002353 curproxy->id, srv->id,
2354 srv->conf.file, srv->conf.line);
2355 cfgerr++;
2356 }
Emeric Brunef42d922012-10-11 16:11:36 +02002357#ifdef X509_V_FLAG_CRL_CHECK
2358 if (srv->ssl_ctx.crl_file) {
2359 X509_STORE *store = SSL_CTX_get_cert_store(srv->ssl_ctx.ctx);
2360
2361 if (!store || !X509_STORE_load_locations(store, srv->ssl_ctx.crl_file, NULL)) {
Willy Tarreau07ba08b2014-02-16 19:22:08 +01002362 Alert("Proxy '%s', server '%s' [%s:%d] unable to configure CRL file '%s'.\n",
Emeric Brunef42d922012-10-11 16:11:36 +02002363 curproxy->id, srv->id,
2364 srv->conf.file, srv->conf.line, srv->ssl_ctx.crl_file);
2365 cfgerr++;
2366 }
2367 else {
2368 X509_STORE_set_flags(store, X509_V_FLAG_CRL_CHECK|X509_V_FLAG_CRL_CHECK_ALL);
2369 }
2370 }
2371#endif
2372 }
2373
Emeric Brun4f65bff2012-11-16 15:11:00 +01002374 if (global.tune.ssllifetime)
2375 SSL_CTX_set_timeout(srv->ssl_ctx.ctx, global.tune.ssllifetime);
2376
Emeric Brun94324a42012-10-11 14:00:19 +02002377 SSL_CTX_set_session_cache_mode(srv->ssl_ctx.ctx, SSL_SESS_CACHE_OFF);
2378 if (srv->ssl_ctx.ciphers &&
2379 !SSL_CTX_set_cipher_list(srv->ssl_ctx.ctx, srv->ssl_ctx.ciphers)) {
2380 Alert("Proxy '%s', server '%s' [%s:%d] : unable to set SSL cipher list to '%s'.\n",
2381 curproxy->id, srv->id,
2382 srv->conf.file, srv->conf.line, srv->ssl_ctx.ciphers);
2383 cfgerr++;
2384 }
2385
2386 return cfgerr;
2387}
2388
Willy Tarreau2a65ff02012-09-13 17:54:29 +02002389/* Walks down the two trees in bind_conf and prepares all certs. The pointer may
Emeric Brunfc0421f2012-09-07 17:30:07 +02002390 * be NULL, in which case nothing is done. Returns the number of errors
2391 * encountered.
2392 */
Willy Tarreau2a65ff02012-09-13 17:54:29 +02002393int ssl_sock_prepare_all_ctx(struct bind_conf *bind_conf, struct proxy *px)
Emeric Brunfc0421f2012-09-07 17:30:07 +02002394{
2395 struct ebmb_node *node;
2396 struct sni_ctx *sni;
2397 int err = 0;
2398
Willy Tarreau2a65ff02012-09-13 17:54:29 +02002399 if (!bind_conf || !bind_conf->is_ssl)
Emeric Brunfc0421f2012-09-07 17:30:07 +02002400 return 0;
2401
Willy Tarreaufce03112015-01-15 21:32:40 +01002402 /* Automatic memory computations need to know we use SSL there */
2403 global.ssl_used_frontend = 1;
2404
Emeric Brun0bed9942014-10-30 19:25:24 +01002405 if (bind_conf->default_ctx)
2406 err += ssl_sock_prepare_ctx(bind_conf, bind_conf->default_ctx, px);
2407
Willy Tarreau2a65ff02012-09-13 17:54:29 +02002408 node = ebmb_first(&bind_conf->sni_ctx);
Emeric Brunfc0421f2012-09-07 17:30:07 +02002409 while (node) {
2410 sni = ebmb_entry(node, struct sni_ctx, name);
Emeric Brun0bed9942014-10-30 19:25:24 +01002411 if (!sni->order && sni->ctx != bind_conf->default_ctx)
2412 /* only initialize the CTX on its first occurrence and
2413 if it is not the default_ctx */
Willy Tarreau2a65ff02012-09-13 17:54:29 +02002414 err += ssl_sock_prepare_ctx(bind_conf, sni->ctx, px);
Emeric Brunfc0421f2012-09-07 17:30:07 +02002415 node = ebmb_next(node);
2416 }
2417
Willy Tarreau2a65ff02012-09-13 17:54:29 +02002418 node = ebmb_first(&bind_conf->sni_w_ctx);
Emeric Brunfc0421f2012-09-07 17:30:07 +02002419 while (node) {
2420 sni = ebmb_entry(node, struct sni_ctx, name);
Emeric Brun0bed9942014-10-30 19:25:24 +01002421 if (!sni->order && sni->ctx != bind_conf->default_ctx)
2422 /* only initialize the CTX on its first occurrence and
2423 if it is not the default_ctx */
Willy Tarreau2a65ff02012-09-13 17:54:29 +02002424 err += ssl_sock_prepare_ctx(bind_conf, sni->ctx, px);
Emeric Brunfc0421f2012-09-07 17:30:07 +02002425 node = ebmb_next(node);
2426 }
2427 return err;
2428}
2429
Willy Tarreau2a65ff02012-09-13 17:54:29 +02002430/* Walks down the two trees in bind_conf and frees all the certs. The pointer may
Emeric Brunfc0421f2012-09-07 17:30:07 +02002431 * be NULL, in which case nothing is done. The default_ctx is nullified too.
2432 */
Willy Tarreau2a65ff02012-09-13 17:54:29 +02002433void ssl_sock_free_all_ctx(struct bind_conf *bind_conf)
Emeric Brunfc0421f2012-09-07 17:30:07 +02002434{
2435 struct ebmb_node *node, *back;
2436 struct sni_ctx *sni;
2437
Willy Tarreau2a65ff02012-09-13 17:54:29 +02002438 if (!bind_conf || !bind_conf->is_ssl)
Emeric Brunfc0421f2012-09-07 17:30:07 +02002439 return;
2440
Willy Tarreau2a65ff02012-09-13 17:54:29 +02002441 node = ebmb_first(&bind_conf->sni_ctx);
Emeric Brunfc0421f2012-09-07 17:30:07 +02002442 while (node) {
2443 sni = ebmb_entry(node, struct sni_ctx, name);
2444 back = ebmb_next(node);
2445 ebmb_delete(node);
2446 if (!sni->order) /* only free the CTX on its first occurrence */
2447 SSL_CTX_free(sni->ctx);
2448 free(sni);
2449 node = back;
2450 }
2451
Willy Tarreau2a65ff02012-09-13 17:54:29 +02002452 node = ebmb_first(&bind_conf->sni_w_ctx);
Emeric Brunfc0421f2012-09-07 17:30:07 +02002453 while (node) {
2454 sni = ebmb_entry(node, struct sni_ctx, name);
2455 back = ebmb_next(node);
2456 ebmb_delete(node);
2457 if (!sni->order) /* only free the CTX on its first occurrence */
2458 SSL_CTX_free(sni->ctx);
2459 free(sni);
2460 node = back;
2461 }
2462
Willy Tarreau2a65ff02012-09-13 17:54:29 +02002463 bind_conf->default_ctx = NULL;
Emeric Brune1f38db2012-09-03 20:36:47 +02002464}
2465
Christopher Faulet31af49d2015-06-09 17:29:50 +02002466/* Load CA cert file and private key used to generate certificates */
2467int
2468ssl_sock_load_ca(struct bind_conf *bind_conf, struct proxy *px)
2469{
2470 FILE *fp;
2471 X509 *cacert = NULL;
2472 EVP_PKEY *capkey = NULL;
2473 int err = 0;
2474
2475 if (!bind_conf || !bind_conf->generate_certs)
2476 return err;
2477
2478 if (!bind_conf->ca_sign_file) {
2479 Alert("Proxy '%s': cannot enable certificate generation, "
2480 "no CA certificate File configured at [%s:%d].\n",
2481 px->id, bind_conf->file, bind_conf->line);
2482 err++;
2483 }
2484
2485 if (err)
2486 goto load_error;
2487
2488 /* read in the CA certificate */
2489 if (!(fp = fopen(bind_conf->ca_sign_file, "r"))) {
2490 Alert("Proxy '%s': Failed to read CA certificate file '%s' at [%s:%d].\n",
2491 px->id, bind_conf->ca_sign_file, bind_conf->file, bind_conf->line);
2492 err++;
2493 goto load_error;
2494 }
2495 if (!(cacert = PEM_read_X509(fp, NULL, NULL, NULL))) {
2496 Alert("Proxy '%s': Failed to read CA certificate file '%s' at [%s:%d].\n",
2497 px->id, bind_conf->ca_sign_file, bind_conf->file, bind_conf->line);
2498 fclose (fp);
2499 err++;
2500 goto load_error;
2501 }
2502 if (!(capkey = PEM_read_PrivateKey(fp, NULL, NULL, bind_conf->ca_sign_pass))) {
2503 Alert("Proxy '%s': Failed to read CA private key file '%s' at [%s:%d].\n",
2504 px->id, bind_conf->ca_sign_file, bind_conf->file, bind_conf->line);
2505 fclose (fp);
2506 err++;
2507 goto load_error;
2508 }
2509 fclose (fp);
2510
2511 bind_conf->ca_sign_cert = cacert;
2512 bind_conf->ca_sign_pkey = capkey;
2513 return err;
2514
2515 load_error:
2516 bind_conf->generate_certs = 0;
2517 if (capkey) EVP_PKEY_free(capkey);
2518 if (cacert) X509_free(cacert);
2519 return err;
2520}
2521
2522/* Release CA cert and private key used to generate certificated */
2523void
2524ssl_sock_free_ca(struct bind_conf *bind_conf)
2525{
2526 if (!bind_conf)
2527 return;
2528
2529 if (bind_conf->ca_sign_pkey)
2530 EVP_PKEY_free(bind_conf->ca_sign_pkey);
2531 if (bind_conf->ca_sign_cert)
2532 X509_free(bind_conf->ca_sign_cert);
2533}
2534
Emeric Brun46591952012-05-18 15:47:34 +02002535/*
2536 * This function is called if SSL * context is not yet allocated. The function
2537 * is designed to be called before any other data-layer operation and sets the
2538 * handshake flag on the connection. It is safe to call it multiple times.
2539 * It returns 0 on success and -1 in error case.
2540 */
2541static int ssl_sock_init(struct connection *conn)
2542{
2543 /* already initialized */
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02002544 if (conn->xprt_ctx)
Emeric Brun46591952012-05-18 15:47:34 +02002545 return 0;
2546
Willy Tarreau3c728722014-01-23 13:50:42 +01002547 if (!conn_ctrl_ready(conn))
Willy Tarreauf79c8172013-10-21 16:30:56 +02002548 return 0;
2549
Willy Tarreau20879a02012-12-03 16:32:10 +01002550 if (global.maxsslconn && sslconns >= global.maxsslconn) {
2551 conn->err_code = CO_ER_SSL_TOO_MANY;
Willy Tarreau403edff2012-09-06 11:58:37 +02002552 return -1;
Willy Tarreau20879a02012-12-03 16:32:10 +01002553 }
Willy Tarreau403edff2012-09-06 11:58:37 +02002554
Emeric Brun46591952012-05-18 15:47:34 +02002555 /* If it is in client mode initiate SSL session
2556 in connect state otherwise accept state */
Willy Tarreau3fdb3662012-11-12 00:42:33 +01002557 if (objt_server(conn->target)) {
Willy Tarreaufba03cd2014-11-13 13:48:58 +01002558 int may_retry = 1;
2559
2560 retry_connect:
Emeric Brun46591952012-05-18 15:47:34 +02002561 /* Alloc a new SSL session ctx */
Willy Tarreau3fdb3662012-11-12 00:42:33 +01002562 conn->xprt_ctx = SSL_new(objt_server(conn->target)->ssl_ctx.ctx);
Willy Tarreau20879a02012-12-03 16:32:10 +01002563 if (!conn->xprt_ctx) {
Willy Tarreaufba03cd2014-11-13 13:48:58 +01002564 if (may_retry--) {
2565 pool_gc2();
2566 goto retry_connect;
2567 }
Willy Tarreau20879a02012-12-03 16:32:10 +01002568 conn->err_code = CO_ER_SSL_NO_MEM;
Emeric Brun46591952012-05-18 15:47:34 +02002569 return -1;
Willy Tarreau20879a02012-12-03 16:32:10 +01002570 }
Emeric Brun46591952012-05-18 15:47:34 +02002571
Emeric Brun46591952012-05-18 15:47:34 +02002572 /* set fd on SSL session context */
Emeric Brun55476152014-11-12 17:35:37 +01002573 if (!SSL_set_fd(conn->xprt_ctx, conn->t.sock.fd)) {
2574 SSL_free(conn->xprt_ctx);
2575 conn->xprt_ctx = NULL;
Willy Tarreaufba03cd2014-11-13 13:48:58 +01002576 if (may_retry--) {
2577 pool_gc2();
2578 goto retry_connect;
2579 }
Emeric Brun55476152014-11-12 17:35:37 +01002580 conn->err_code = CO_ER_SSL_NO_MEM;
2581 return -1;
2582 }
Emeric Brun46591952012-05-18 15:47:34 +02002583
Evan Broderbe554312013-06-27 00:05:25 -07002584 /* set connection pointer */
Emeric Brun55476152014-11-12 17:35:37 +01002585 if (!SSL_set_app_data(conn->xprt_ctx, conn)) {
2586 SSL_free(conn->xprt_ctx);
2587 conn->xprt_ctx = NULL;
Willy Tarreaufba03cd2014-11-13 13:48:58 +01002588 if (may_retry--) {
2589 pool_gc2();
2590 goto retry_connect;
2591 }
Emeric Brun55476152014-11-12 17:35:37 +01002592 conn->err_code = CO_ER_SSL_NO_MEM;
2593 return -1;
2594 }
2595
2596 SSL_set_connect_state(conn->xprt_ctx);
2597 if (objt_server(conn->target)->ssl_ctx.reused_sess) {
2598 if(!SSL_set_session(conn->xprt_ctx, objt_server(conn->target)->ssl_ctx.reused_sess)) {
2599 SSL_SESSION_free(objt_server(conn->target)->ssl_ctx.reused_sess);
2600 objt_server(conn->target)->ssl_ctx.reused_sess = NULL;
2601 }
2602 }
Evan Broderbe554312013-06-27 00:05:25 -07002603
Emeric Brun46591952012-05-18 15:47:34 +02002604 /* leave init state and start handshake */
Willy Tarreau05737472012-09-04 08:03:39 +02002605 conn->flags |= CO_FL_SSL_WAIT_HS | CO_FL_WAIT_L6_CONN;
Willy Tarreau403edff2012-09-06 11:58:37 +02002606
2607 sslconns++;
Willy Tarreau71b734c2014-01-28 15:19:44 +01002608 totalsslconns++;
Emeric Brun46591952012-05-18 15:47:34 +02002609 return 0;
2610 }
Willy Tarreau3fdb3662012-11-12 00:42:33 +01002611 else if (objt_listener(conn->target)) {
Willy Tarreaufba03cd2014-11-13 13:48:58 +01002612 int may_retry = 1;
2613
2614 retry_accept:
Emeric Brun46591952012-05-18 15:47:34 +02002615 /* Alloc a new SSL session ctx */
Willy Tarreau3fdb3662012-11-12 00:42:33 +01002616 conn->xprt_ctx = SSL_new(objt_listener(conn->target)->bind_conf->default_ctx);
Willy Tarreau20879a02012-12-03 16:32:10 +01002617 if (!conn->xprt_ctx) {
Willy Tarreaufba03cd2014-11-13 13:48:58 +01002618 if (may_retry--) {
2619 pool_gc2();
2620 goto retry_accept;
2621 }
Willy Tarreau20879a02012-12-03 16:32:10 +01002622 conn->err_code = CO_ER_SSL_NO_MEM;
Emeric Brun46591952012-05-18 15:47:34 +02002623 return -1;
Willy Tarreau20879a02012-12-03 16:32:10 +01002624 }
Emeric Brun46591952012-05-18 15:47:34 +02002625
Emeric Brun46591952012-05-18 15:47:34 +02002626 /* set fd on SSL session context */
Emeric Brun55476152014-11-12 17:35:37 +01002627 if (!SSL_set_fd(conn->xprt_ctx, conn->t.sock.fd)) {
2628 SSL_free(conn->xprt_ctx);
2629 conn->xprt_ctx = NULL;
Willy Tarreaufba03cd2014-11-13 13:48:58 +01002630 if (may_retry--) {
2631 pool_gc2();
2632 goto retry_accept;
2633 }
Emeric Brun55476152014-11-12 17:35:37 +01002634 conn->err_code = CO_ER_SSL_NO_MEM;
2635 return -1;
2636 }
Emeric Brun46591952012-05-18 15:47:34 +02002637
Emeric Brune1f38db2012-09-03 20:36:47 +02002638 /* set connection pointer */
Emeric Brun55476152014-11-12 17:35:37 +01002639 if (!SSL_set_app_data(conn->xprt_ctx, conn)) {
2640 SSL_free(conn->xprt_ctx);
2641 conn->xprt_ctx = NULL;
Willy Tarreaufba03cd2014-11-13 13:48:58 +01002642 if (may_retry--) {
2643 pool_gc2();
2644 goto retry_accept;
2645 }
Emeric Brun55476152014-11-12 17:35:37 +01002646 conn->err_code = CO_ER_SSL_NO_MEM;
2647 return -1;
2648 }
2649
2650 SSL_set_accept_state(conn->xprt_ctx);
Emeric Brune1f38db2012-09-03 20:36:47 +02002651
Emeric Brun46591952012-05-18 15:47:34 +02002652 /* leave init state and start handshake */
Willy Tarreau05737472012-09-04 08:03:39 +02002653 conn->flags |= CO_FL_SSL_WAIT_HS | CO_FL_WAIT_L6_CONN;
Willy Tarreau403edff2012-09-06 11:58:37 +02002654
2655 sslconns++;
Willy Tarreau71b734c2014-01-28 15:19:44 +01002656 totalsslconns++;
Emeric Brun46591952012-05-18 15:47:34 +02002657 return 0;
2658 }
2659 /* don't know how to handle such a target */
Willy Tarreau20879a02012-12-03 16:32:10 +01002660 conn->err_code = CO_ER_SSL_NO_TARGET;
Emeric Brun46591952012-05-18 15:47:34 +02002661 return -1;
2662}
2663
2664
2665/* This is the callback which is used when an SSL handshake is pending. It
2666 * updates the FD status if it wants some polling before being called again.
2667 * It returns 0 if it fails in a fatal way or needs to poll to go further,
2668 * otherwise it returns non-zero and removes itself from the connection's
2669 * flags (the bit is provided in <flag> by the caller).
2670 */
2671int ssl_sock_handshake(struct connection *conn, unsigned int flag)
2672{
2673 int ret;
2674
Willy Tarreau3c728722014-01-23 13:50:42 +01002675 if (!conn_ctrl_ready(conn))
Willy Tarreauf79c8172013-10-21 16:30:56 +02002676 return 0;
2677
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02002678 if (!conn->xprt_ctx)
Emeric Brun46591952012-05-18 15:47:34 +02002679 goto out_error;
2680
Emeric Brun674b7432012-11-08 19:21:55 +01002681 /* If we use SSL_do_handshake to process a reneg initiated by
2682 * the remote peer, it sometimes returns SSL_ERROR_SSL.
2683 * Usually SSL_write and SSL_read are used and process implicitly
2684 * the reneg handshake.
2685 * Here we use SSL_peek as a workaround for reneg.
2686 */
2687 if ((conn->flags & CO_FL_CONNECTED) && SSL_renegotiate_pending(conn->xprt_ctx)) {
2688 char c;
2689
2690 ret = SSL_peek(conn->xprt_ctx, &c, 1);
2691 if (ret <= 0) {
2692 /* handshake may have not been completed, let's find why */
2693 ret = SSL_get_error(conn->xprt_ctx, ret);
2694 if (ret == SSL_ERROR_WANT_WRITE) {
2695 /* SSL handshake needs to write, L4 connection may not be ready */
2696 __conn_sock_stop_recv(conn);
Willy Tarreaue1f50c42014-01-22 20:02:06 +01002697 __conn_sock_want_send(conn);
2698 fd_cant_send(conn->t.sock.fd);
Emeric Brun674b7432012-11-08 19:21:55 +01002699 return 0;
2700 }
2701 else if (ret == SSL_ERROR_WANT_READ) {
2702 /* handshake may have been completed but we have
2703 * no more data to read.
2704 */
2705 if (!SSL_renegotiate_pending(conn->xprt_ctx)) {
2706 ret = 1;
2707 goto reneg_ok;
2708 }
2709 /* SSL handshake needs to read, L4 connection is ready */
2710 if (conn->flags & CO_FL_WAIT_L4_CONN)
2711 conn->flags &= ~CO_FL_WAIT_L4_CONN;
2712 __conn_sock_stop_send(conn);
Willy Tarreaue1f50c42014-01-22 20:02:06 +01002713 __conn_sock_want_recv(conn);
2714 fd_cant_recv(conn->t.sock.fd);
Emeric Brun674b7432012-11-08 19:21:55 +01002715 return 0;
2716 }
2717 else if (ret == SSL_ERROR_SYSCALL) {
2718 /* if errno is null, then connection was successfully established */
2719 if (!errno && conn->flags & CO_FL_WAIT_L4_CONN)
2720 conn->flags &= ~CO_FL_WAIT_L4_CONN;
Willy Tarreau20879a02012-12-03 16:32:10 +01002721 if (!conn->err_code) {
Emeric Brun29f037d2014-04-25 19:05:36 +02002722 if (!((SSL *)conn->xprt_ctx)->packet_length) {
2723 if (!errno) {
2724 if (conn->xprt_st & SSL_SOCK_RECV_HEARTBEAT)
2725 conn->err_code = CO_ER_SSL_HANDSHAKE_HB;
2726 else
2727 conn->err_code = CO_ER_SSL_EMPTY;
2728 }
2729 else {
2730 if (conn->xprt_st & SSL_SOCK_RECV_HEARTBEAT)
2731 conn->err_code = CO_ER_SSL_HANDSHAKE_HB;
2732 else
2733 conn->err_code = CO_ER_SSL_ABORT;
2734 }
2735 }
2736 else {
2737 if (conn->xprt_st & SSL_SOCK_RECV_HEARTBEAT)
2738 conn->err_code = CO_ER_SSL_HANDSHAKE_HB;
Willy Tarreau20879a02012-12-03 16:32:10 +01002739 else
Emeric Brun29f037d2014-04-25 19:05:36 +02002740 conn->err_code = CO_ER_SSL_HANDSHAKE;
2741 }
Willy Tarreau20879a02012-12-03 16:32:10 +01002742 }
Emeric Brun674b7432012-11-08 19:21:55 +01002743 goto out_error;
2744 }
2745 else {
2746 /* Fail on all other handshake errors */
2747 /* Note: OpenSSL may leave unread bytes in the socket's
2748 * buffer, causing an RST to be emitted upon close() on
2749 * TCP sockets. We first try to drain possibly pending
2750 * data to avoid this as much as possible.
2751 */
Willy Tarreaud85c4852015-03-13 00:40:28 +01002752 conn_sock_drain(conn);
Willy Tarreau20879a02012-12-03 16:32:10 +01002753 if (!conn->err_code)
Willy Tarreauf51c6982014-04-25 20:02:39 +02002754 conn->err_code = (conn->xprt_st & SSL_SOCK_RECV_HEARTBEAT) ?
2755 CO_ER_SSL_KILLED_HB : CO_ER_SSL_HANDSHAKE;
Emeric Brun674b7432012-11-08 19:21:55 +01002756 goto out_error;
2757 }
2758 }
2759 /* read some data: consider handshake completed */
2760 goto reneg_ok;
2761 }
2762
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02002763 ret = SSL_do_handshake(conn->xprt_ctx);
Emeric Brun46591952012-05-18 15:47:34 +02002764 if (ret != 1) {
2765 /* handshake did not complete, let's find why */
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02002766 ret = SSL_get_error(conn->xprt_ctx, ret);
Emeric Brun46591952012-05-18 15:47:34 +02002767
2768 if (ret == SSL_ERROR_WANT_WRITE) {
2769 /* SSL handshake needs to write, L4 connection may not be ready */
2770 __conn_sock_stop_recv(conn);
Willy Tarreaue1f50c42014-01-22 20:02:06 +01002771 __conn_sock_want_send(conn);
2772 fd_cant_send(conn->t.sock.fd);
Emeric Brun46591952012-05-18 15:47:34 +02002773 return 0;
2774 }
2775 else if (ret == SSL_ERROR_WANT_READ) {
2776 /* SSL handshake needs to read, L4 connection is ready */
2777 if (conn->flags & CO_FL_WAIT_L4_CONN)
2778 conn->flags &= ~CO_FL_WAIT_L4_CONN;
2779 __conn_sock_stop_send(conn);
Willy Tarreaue1f50c42014-01-22 20:02:06 +01002780 __conn_sock_want_recv(conn);
2781 fd_cant_recv(conn->t.sock.fd);
Emeric Brun46591952012-05-18 15:47:34 +02002782 return 0;
2783 }
Willy Tarreau89230192012-09-28 20:22:13 +02002784 else if (ret == SSL_ERROR_SYSCALL) {
2785 /* if errno is null, then connection was successfully established */
2786 if (!errno && conn->flags & CO_FL_WAIT_L4_CONN)
2787 conn->flags &= ~CO_FL_WAIT_L4_CONN;
Willy Tarreau20879a02012-12-03 16:32:10 +01002788
Emeric Brun29f037d2014-04-25 19:05:36 +02002789 if (!((SSL *)conn->xprt_ctx)->packet_length) {
2790 if (!errno) {
2791 if (conn->xprt_st & SSL_SOCK_RECV_HEARTBEAT)
2792 conn->err_code = CO_ER_SSL_HANDSHAKE_HB;
2793 else
2794 conn->err_code = CO_ER_SSL_EMPTY;
2795 }
2796 else {
2797 if (conn->xprt_st & SSL_SOCK_RECV_HEARTBEAT)
2798 conn->err_code = CO_ER_SSL_HANDSHAKE_HB;
2799 else
2800 conn->err_code = CO_ER_SSL_ABORT;
2801 }
2802 }
2803 else {
2804 if (conn->xprt_st & SSL_SOCK_RECV_HEARTBEAT)
2805 conn->err_code = CO_ER_SSL_HANDSHAKE_HB;
Willy Tarreau20879a02012-12-03 16:32:10 +01002806 else
Emeric Brun29f037d2014-04-25 19:05:36 +02002807 conn->err_code = CO_ER_SSL_HANDSHAKE;
2808 }
Willy Tarreau89230192012-09-28 20:22:13 +02002809 goto out_error;
2810 }
Emeric Brun46591952012-05-18 15:47:34 +02002811 else {
2812 /* Fail on all other handshake errors */
Willy Tarreau566dc552012-10-19 20:52:18 +02002813 /* Note: OpenSSL may leave unread bytes in the socket's
2814 * buffer, causing an RST to be emitted upon close() on
2815 * TCP sockets. We first try to drain possibly pending
2816 * data to avoid this as much as possible.
2817 */
Willy Tarreaud85c4852015-03-13 00:40:28 +01002818 conn_sock_drain(conn);
Willy Tarreau20879a02012-12-03 16:32:10 +01002819 if (!conn->err_code)
Willy Tarreauf51c6982014-04-25 20:02:39 +02002820 conn->err_code = (conn->xprt_st & SSL_SOCK_RECV_HEARTBEAT) ?
2821 CO_ER_SSL_KILLED_HB : CO_ER_SSL_HANDSHAKE;
Emeric Brun46591952012-05-18 15:47:34 +02002822 goto out_error;
2823 }
2824 }
2825
Emeric Brun674b7432012-11-08 19:21:55 +01002826reneg_ok:
2827
Emeric Brun46591952012-05-18 15:47:34 +02002828 /* Handshake succeeded */
Willy Tarreau0c9c2722014-05-28 12:28:58 +02002829 if (!SSL_session_reused(conn->xprt_ctx)) {
2830 if (objt_server(conn->target)) {
2831 update_freq_ctr(&global.ssl_be_keys_per_sec, 1);
2832 if (global.ssl_be_keys_per_sec.curr_ctr > global.ssl_be_keys_max)
2833 global.ssl_be_keys_max = global.ssl_be_keys_per_sec.curr_ctr;
2834
Emeric Brun46591952012-05-18 15:47:34 +02002835 /* check if session was reused, if not store current session on server for reuse */
Willy Tarreau3fdb3662012-11-12 00:42:33 +01002836 if (objt_server(conn->target)->ssl_ctx.reused_sess)
2837 SSL_SESSION_free(objt_server(conn->target)->ssl_ctx.reused_sess);
Emeric Brun46591952012-05-18 15:47:34 +02002838
Willy Tarreau2a3fb1c2015-02-05 16:47:07 +01002839 if (!(objt_server(conn->target)->ssl_ctx.options & SRV_SSL_O_NO_REUSE))
2840 objt_server(conn->target)->ssl_ctx.reused_sess = SSL_get1_session(conn->xprt_ctx);
Emeric Brun46591952012-05-18 15:47:34 +02002841 }
Willy Tarreau0c9c2722014-05-28 12:28:58 +02002842 else {
2843 update_freq_ctr(&global.ssl_fe_keys_per_sec, 1);
2844 if (global.ssl_fe_keys_per_sec.curr_ctr > global.ssl_fe_keys_max)
2845 global.ssl_fe_keys_max = global.ssl_fe_keys_per_sec.curr_ctr;
2846 }
Emeric Brun46591952012-05-18 15:47:34 +02002847 }
2848
2849 /* The connection is now established at both layers, it's time to leave */
2850 conn->flags &= ~(flag | CO_FL_WAIT_L4_CONN | CO_FL_WAIT_L6_CONN);
2851 return 1;
2852
2853 out_error:
Emeric Brun644cde02012-12-14 11:21:13 +01002854 /* Clear openssl global errors stack */
2855 ERR_clear_error();
2856
Emeric Brun9fa89732012-10-04 17:09:56 +02002857 /* free resumed session if exists */
Willy Tarreau3fdb3662012-11-12 00:42:33 +01002858 if (objt_server(conn->target) && objt_server(conn->target)->ssl_ctx.reused_sess) {
2859 SSL_SESSION_free(objt_server(conn->target)->ssl_ctx.reused_sess);
2860 objt_server(conn->target)->ssl_ctx.reused_sess = NULL;
Emeric Brun9fa89732012-10-04 17:09:56 +02002861 }
2862
Emeric Brun46591952012-05-18 15:47:34 +02002863 /* Fail on all other handshake errors */
2864 conn->flags |= CO_FL_ERROR;
Willy Tarreau20879a02012-12-03 16:32:10 +01002865 if (!conn->err_code)
2866 conn->err_code = CO_ER_SSL_HANDSHAKE;
Emeric Brun46591952012-05-18 15:47:34 +02002867 return 0;
2868}
2869
2870/* Receive up to <count> bytes from connection <conn>'s socket and store them
Willy Tarreauabf08d92014-01-14 11:31:27 +01002871 * into buffer <buf>. Only one call to recv() is performed, unless the
Emeric Brun46591952012-05-18 15:47:34 +02002872 * buffer wraps, in which case a second call may be performed. The connection's
2873 * flags are updated with whatever special event is detected (error, read0,
2874 * empty). The caller is responsible for taking care of those events and
2875 * avoiding the call if inappropriate. The function does not call the
2876 * connection's polling update function, so the caller is responsible for this.
2877 */
2878static int ssl_sock_to_buf(struct connection *conn, struct buffer *buf, int count)
2879{
2880 int ret, done = 0;
Willy Tarreauabf08d92014-01-14 11:31:27 +01002881 int try;
Emeric Brun46591952012-05-18 15:47:34 +02002882
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02002883 if (!conn->xprt_ctx)
Emeric Brun46591952012-05-18 15:47:34 +02002884 goto out_error;
2885
2886 if (conn->flags & CO_FL_HANDSHAKE)
2887 /* a handshake was requested */
2888 return 0;
2889
Willy Tarreauabf08d92014-01-14 11:31:27 +01002890 /* let's realign the buffer to optimize I/O */
2891 if (buffer_empty(buf))
Emeric Brun46591952012-05-18 15:47:34 +02002892 buf->p = buf->data;
Emeric Brun46591952012-05-18 15:47:34 +02002893
2894 /* read the largest possible block. For this, we perform only one call
2895 * to recv() unless the buffer wraps and we exactly fill the first hunk,
2896 * in which case we accept to do it once again. A new attempt is made on
2897 * EINTR too.
2898 */
Willy Tarreau00b0fb92014-01-17 11:09:40 +01002899 while (count > 0) {
Willy Tarreauabf08d92014-01-14 11:31:27 +01002900 /* first check if we have some room after p+i */
2901 try = buf->data + buf->size - (buf->p + buf->i);
2902 /* otherwise continue between data and p-o */
2903 if (try <= 0) {
2904 try = buf->p - (buf->data + buf->o);
2905 if (try <= 0)
2906 break;
2907 }
2908 if (try > count)
2909 try = count;
2910
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02002911 ret = SSL_read(conn->xprt_ctx, bi_end(buf), try);
Emeric Brune1f38db2012-09-03 20:36:47 +02002912 if (conn->flags & CO_FL_ERROR) {
2913 /* CO_FL_ERROR may be set by ssl_sock_infocbk */
Emeric Brun644cde02012-12-14 11:21:13 +01002914 goto out_error;
Emeric Brune1f38db2012-09-03 20:36:47 +02002915 }
Emeric Brun46591952012-05-18 15:47:34 +02002916 if (ret > 0) {
2917 buf->i += ret;
2918 done += ret;
2919 if (ret < try)
2920 break;
2921 count -= ret;
Emeric Brun46591952012-05-18 15:47:34 +02002922 }
2923 else if (ret == 0) {
Emeric Brun644cde02012-12-14 11:21:13 +01002924 ret = SSL_get_error(conn->xprt_ctx, ret);
2925 if (ret != SSL_ERROR_ZERO_RETURN) {
Emeric Brun1c646862012-12-14 12:33:41 +01002926 /* error on protocol or underlying transport */
2927 if ((ret != SSL_ERROR_SYSCALL)
2928 || (errno && (errno != EAGAIN)))
2929 conn->flags |= CO_FL_ERROR;
2930
Emeric Brun644cde02012-12-14 11:21:13 +01002931 /* Clear openssl global errors stack */
2932 ERR_clear_error();
2933 }
Emeric Brun46591952012-05-18 15:47:34 +02002934 goto read0;
2935 }
2936 else {
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02002937 ret = SSL_get_error(conn->xprt_ctx, ret);
Emeric Brun46591952012-05-18 15:47:34 +02002938 if (ret == SSL_ERROR_WANT_WRITE) {
Emeric Brun8af8dd12012-11-08 17:56:20 +01002939 /* handshake is running, and it needs to enable write */
Emeric Brun46591952012-05-18 15:47:34 +02002940 conn->flags |= CO_FL_SSL_WAIT_HS;
Emeric Brun8af8dd12012-11-08 17:56:20 +01002941 __conn_sock_want_send(conn);
Emeric Brun46591952012-05-18 15:47:34 +02002942 break;
2943 }
2944 else if (ret == SSL_ERROR_WANT_READ) {
Emeric Brun282a76a2012-11-08 18:02:56 +01002945 if (SSL_renegotiate_pending(conn->xprt_ctx)) {
2946 /* handshake is running, and it may need to re-enable read */
2947 conn->flags |= CO_FL_SSL_WAIT_HS;
2948 __conn_sock_want_recv(conn);
2949 break;
2950 }
Emeric Brun46591952012-05-18 15:47:34 +02002951 /* we need to poll for retry a read later */
Willy Tarreaue1f50c42014-01-22 20:02:06 +01002952 fd_cant_recv(conn->t.sock.fd);
Emeric Brun46591952012-05-18 15:47:34 +02002953 break;
2954 }
2955 /* otherwise it's a real error */
2956 goto out_error;
2957 }
2958 }
2959 return done;
2960
2961 read0:
2962 conn_sock_read0(conn);
2963 return done;
2964 out_error:
Emeric Brun644cde02012-12-14 11:21:13 +01002965 /* Clear openssl global errors stack */
2966 ERR_clear_error();
2967
Emeric Brun46591952012-05-18 15:47:34 +02002968 conn->flags |= CO_FL_ERROR;
2969 return done;
2970}
2971
2972
2973/* Send all pending bytes from buffer <buf> to connection <conn>'s socket.
Willy Tarreau1049b1f2014-02-02 01:51:17 +01002974 * <flags> may contain some CO_SFL_* flags to hint the system about other
2975 * pending data for example, but this flag is ignored at the moment.
Emeric Brun46591952012-05-18 15:47:34 +02002976 * Only one call to send() is performed, unless the buffer wraps, in which case
2977 * a second call may be performed. The connection's flags are updated with
2978 * whatever special event is detected (error, empty). The caller is responsible
2979 * for taking care of those events and avoiding the call if inappropriate. The
2980 * function does not call the connection's polling update function, so the caller
2981 * is responsible for this.
2982 */
2983static int ssl_sock_from_buf(struct connection *conn, struct buffer *buf, int flags)
2984{
2985 int ret, try, done;
2986
2987 done = 0;
2988
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02002989 if (!conn->xprt_ctx)
Emeric Brun46591952012-05-18 15:47:34 +02002990 goto out_error;
2991
2992 if (conn->flags & CO_FL_HANDSHAKE)
2993 /* a handshake was requested */
2994 return 0;
2995
2996 /* send the largest possible block. For this we perform only one call
2997 * to send() unless the buffer wraps and we exactly fill the first hunk,
2998 * in which case we accept to do it once again.
2999 */
3000 while (buf->o) {
Kevin Hestercad82342013-05-30 15:12:41 -07003001 try = bo_contig_data(buf);
Willy Tarreaubfd59462013-02-21 07:46:09 +01003002
Willy Tarreau7bed9452014-02-02 02:00:24 +01003003 if (!(flags & CO_SFL_STREAMER) &&
Willy Tarreau518cedd2014-02-17 15:43:01 +01003004 !(conn->xprt_st & SSL_SOCK_SEND_UNLIMITED) &&
3005 global.tune.ssl_max_record && try > global.tune.ssl_max_record) {
Willy Tarreaubfd59462013-02-21 07:46:09 +01003006 try = global.tune.ssl_max_record;
Willy Tarreau518cedd2014-02-17 15:43:01 +01003007 }
3008 else {
3009 /* we need to keep the information about the fact that
3010 * we're not limiting the upcoming send(), because if it
3011 * fails, we'll have to retry with at least as many data.
3012 */
3013 conn->xprt_st |= SSL_SOCK_SEND_UNLIMITED;
3014 }
Willy Tarreaubfd59462013-02-21 07:46:09 +01003015
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02003016 ret = SSL_write(conn->xprt_ctx, bo_ptr(buf), try);
Willy Tarreau518cedd2014-02-17 15:43:01 +01003017
Emeric Brune1f38db2012-09-03 20:36:47 +02003018 if (conn->flags & CO_FL_ERROR) {
3019 /* CO_FL_ERROR may be set by ssl_sock_infocbk */
Emeric Brun644cde02012-12-14 11:21:13 +01003020 goto out_error;
Emeric Brune1f38db2012-09-03 20:36:47 +02003021 }
Emeric Brun46591952012-05-18 15:47:34 +02003022 if (ret > 0) {
Willy Tarreau518cedd2014-02-17 15:43:01 +01003023 conn->xprt_st &= ~SSL_SOCK_SEND_UNLIMITED;
3024
Emeric Brun46591952012-05-18 15:47:34 +02003025 buf->o -= ret;
3026 done += ret;
3027
Willy Tarreau5fb38032012-12-16 19:39:09 +01003028 if (likely(buffer_empty(buf)))
Emeric Brun46591952012-05-18 15:47:34 +02003029 /* optimize data alignment in the buffer */
3030 buf->p = buf->data;
3031
3032 /* if the system buffer is full, don't insist */
3033 if (ret < try)
3034 break;
3035 }
3036 else {
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02003037 ret = SSL_get_error(conn->xprt_ctx, ret);
Emeric Brun46591952012-05-18 15:47:34 +02003038 if (ret == SSL_ERROR_WANT_WRITE) {
Emeric Brun282a76a2012-11-08 18:02:56 +01003039 if (SSL_renegotiate_pending(conn->xprt_ctx)) {
3040 /* handshake is running, and it may need to re-enable write */
3041 conn->flags |= CO_FL_SSL_WAIT_HS;
3042 __conn_sock_want_send(conn);
3043 break;
3044 }
Emeric Brun46591952012-05-18 15:47:34 +02003045 /* we need to poll to retry a write later */
Willy Tarreaue1f50c42014-01-22 20:02:06 +01003046 fd_cant_send(conn->t.sock.fd);
Emeric Brun46591952012-05-18 15:47:34 +02003047 break;
3048 }
3049 else if (ret == SSL_ERROR_WANT_READ) {
Emeric Brun8af8dd12012-11-08 17:56:20 +01003050 /* handshake is running, and it needs to enable read */
Emeric Brun46591952012-05-18 15:47:34 +02003051 conn->flags |= CO_FL_SSL_WAIT_HS;
Emeric Brun8af8dd12012-11-08 17:56:20 +01003052 __conn_sock_want_recv(conn);
Emeric Brun46591952012-05-18 15:47:34 +02003053 break;
3054 }
3055 goto out_error;
3056 }
3057 }
3058 return done;
3059
3060 out_error:
Emeric Brun644cde02012-12-14 11:21:13 +01003061 /* Clear openssl global errors stack */
3062 ERR_clear_error();
3063
Emeric Brun46591952012-05-18 15:47:34 +02003064 conn->flags |= CO_FL_ERROR;
3065 return done;
3066}
3067
Emeric Brun46591952012-05-18 15:47:34 +02003068static void ssl_sock_close(struct connection *conn) {
3069
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02003070 if (conn->xprt_ctx) {
3071 SSL_free(conn->xprt_ctx);
3072 conn->xprt_ctx = NULL;
Willy Tarreau403edff2012-09-06 11:58:37 +02003073 sslconns--;
Emeric Brun46591952012-05-18 15:47:34 +02003074 }
Emeric Brun46591952012-05-18 15:47:34 +02003075}
3076
3077/* This function tries to perform a clean shutdown on an SSL connection, and in
3078 * any case, flags the connection as reusable if no handshake was in progress.
3079 */
3080static void ssl_sock_shutw(struct connection *conn, int clean)
3081{
3082 if (conn->flags & CO_FL_HANDSHAKE)
3083 return;
3084 /* no handshake was in progress, try a clean ssl shutdown */
Emeric Brun644cde02012-12-14 11:21:13 +01003085 if (clean && (SSL_shutdown(conn->xprt_ctx) <= 0)) {
3086 /* Clear openssl global errors stack */
3087 ERR_clear_error();
3088 }
Emeric Brun46591952012-05-18 15:47:34 +02003089
3090 /* force flag on ssl to keep session in cache regardless shutdown result */
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02003091 SSL_set_shutdown(conn->xprt_ctx, SSL_SENT_SHUTDOWN);
Emeric Brun46591952012-05-18 15:47:34 +02003092}
3093
Willy Tarreauffc3fcd2012-10-12 20:17:54 +02003094/* used for logging, may be changed for a sample fetch later */
3095const char *ssl_sock_get_cipher_name(struct connection *conn)
3096{
3097 if (!conn->xprt && !conn->xprt_ctx)
3098 return NULL;
3099 return SSL_get_cipher_name(conn->xprt_ctx);
3100}
3101
3102/* used for logging, may be changed for a sample fetch later */
3103const char *ssl_sock_get_proto_version(struct connection *conn)
3104{
3105 if (!conn->xprt && !conn->xprt_ctx)
3106 return NULL;
3107 return SSL_get_version(conn->xprt_ctx);
3108}
3109
Willy Tarreau8d598402012-10-22 17:58:39 +02003110/* Extract a serial from a cert, and copy it to a chunk.
3111 * Returns 1 if serial is found and copied, 0 if no serial found and
3112 * -1 if output is not large enough.
3113 */
3114static int
3115ssl_sock_get_serial(X509 *crt, struct chunk *out)
3116{
3117 ASN1_INTEGER *serial;
3118
3119 serial = X509_get_serialNumber(crt);
3120 if (!serial)
3121 return 0;
3122
3123 if (out->size < serial->length)
3124 return -1;
3125
3126 memcpy(out->str, serial->data, serial->length);
3127 out->len = serial->length;
3128 return 1;
3129}
3130
Emeric Brun43e79582014-10-29 19:03:26 +01003131/* Extract a cert to der, and copy it to a chunk.
3132 * Returns 1 if cert is found and copied, 0 on der convertion failure and
3133 * -1 if output is not large enough.
3134 */
3135static int
3136ssl_sock_crt2der(X509 *crt, struct chunk *out)
3137{
3138 int len;
3139 unsigned char *p = (unsigned char *)out->str;;
3140
3141 len =i2d_X509(crt, NULL);
3142 if (len <= 0)
3143 return 1;
3144
3145 if (out->size < len)
3146 return -1;
3147
3148 i2d_X509(crt,&p);
3149 out->len = len;
3150 return 1;
3151}
3152
Emeric Brunce5ad802012-10-22 14:11:22 +02003153
3154/* Copy Date in ASN1_UTCTIME format in struct chunk out.
3155 * Returns 1 if serial is found and copied, 0 if no valid time found
3156 * and -1 if output is not large enough.
3157 */
3158static int
3159ssl_sock_get_time(ASN1_TIME *tm, struct chunk *out)
3160{
3161 if (tm->type == V_ASN1_GENERALIZEDTIME) {
3162 ASN1_GENERALIZEDTIME *gentm = (ASN1_GENERALIZEDTIME *)tm;
3163
3164 if (gentm->length < 12)
3165 return 0;
3166 if (gentm->data[0] != 0x32 || gentm->data[1] != 0x30)
3167 return 0;
3168 if (out->size < gentm->length-2)
3169 return -1;
3170
3171 memcpy(out->str, gentm->data+2, gentm->length-2);
3172 out->len = gentm->length-2;
3173 return 1;
3174 }
3175 else if (tm->type == V_ASN1_UTCTIME) {
3176 ASN1_UTCTIME *utctm = (ASN1_UTCTIME *)tm;
3177
3178 if (utctm->length < 10)
3179 return 0;
3180 if (utctm->data[0] >= 0x35)
3181 return 0;
3182 if (out->size < utctm->length)
3183 return -1;
3184
3185 memcpy(out->str, utctm->data, utctm->length);
3186 out->len = utctm->length;
3187 return 1;
3188 }
3189
3190 return 0;
3191}
3192
Emeric Brun87855892012-10-17 17:39:35 +02003193/* Extract an entry from a X509_NAME and copy its value to an output chunk.
3194 * Returns 1 if entry found, 0 if entry not found, or -1 if output not large enough.
3195 */
3196static int
3197ssl_sock_get_dn_entry(X509_NAME *a, const struct chunk *entry, int pos, struct chunk *out)
3198{
3199 X509_NAME_ENTRY *ne;
3200 int i, j, n;
3201 int cur = 0;
3202 const char *s;
3203 char tmp[128];
3204
3205 out->len = 0;
3206 for (i = 0; i < sk_X509_NAME_ENTRY_num(a->entries); i++) {
3207 if (pos < 0)
3208 j = (sk_X509_NAME_ENTRY_num(a->entries)-1) - i;
3209 else
3210 j = i;
3211
3212 ne = sk_X509_NAME_ENTRY_value(a->entries, j);
3213 n = OBJ_obj2nid(ne->object);
3214 if ((n == NID_undef) || ((s = OBJ_nid2sn(n)) == NULL)) {
3215 i2t_ASN1_OBJECT(tmp, sizeof(tmp), ne->object);
3216 s = tmp;
3217 }
3218
3219 if (chunk_strcasecmp(entry, s) != 0)
3220 continue;
3221
3222 if (pos < 0)
3223 cur--;
3224 else
3225 cur++;
3226
3227 if (cur != pos)
3228 continue;
3229
3230 if (ne->value->length > out->size)
3231 return -1;
3232
3233 memcpy(out->str, ne->value->data, ne->value->length);
3234 out->len = ne->value->length;
3235 return 1;
3236 }
3237
3238 return 0;
3239
3240}
3241
3242/* Extract and format full DN from a X509_NAME and copy result into a chunk
3243 * Returns 1 if dn entries exits, 0 if no dn entry found or -1 if output is not large enough.
3244 */
3245static int
3246ssl_sock_get_dn_oneline(X509_NAME *a, struct chunk *out)
3247{
3248 X509_NAME_ENTRY *ne;
3249 int i, n, ln;
3250 int l = 0;
3251 const char *s;
3252 char *p;
3253 char tmp[128];
3254
3255 out->len = 0;
3256 p = out->str;
3257 for (i = 0; i < sk_X509_NAME_ENTRY_num(a->entries); i++) {
3258 ne = sk_X509_NAME_ENTRY_value(a->entries, i);
3259 n = OBJ_obj2nid(ne->object);
3260 if ((n == NID_undef) || ((s = OBJ_nid2sn(n)) == NULL)) {
3261 i2t_ASN1_OBJECT(tmp, sizeof(tmp), ne->object);
3262 s = tmp;
3263 }
3264 ln = strlen(s);
3265
3266 l += 1 + ln + 1 + ne->value->length;
3267 if (l > out->size)
3268 return -1;
3269 out->len = l;
3270
3271 *(p++)='/';
3272 memcpy(p, s, ln);
3273 p += ln;
3274 *(p++)='=';
3275 memcpy(p, ne->value->data, ne->value->length);
3276 p += ne->value->length;
3277 }
3278
3279 if (!out->len)
3280 return 0;
3281
3282 return 1;
3283}
3284
David Safb76832014-05-08 23:42:08 -04003285char *ssl_sock_get_version(struct connection *conn)
3286{
3287 if (!ssl_sock_is_ssl(conn))
3288 return NULL;
3289
3290 return (char *)SSL_get_version(conn->xprt_ctx);
3291}
3292
Emeric Brun0abf8362014-06-24 18:26:41 +02003293/* Extract peer certificate's common name into the chunk dest
3294 * Returns
3295 * the len of the extracted common name
3296 * or 0 if no CN found in DN
3297 * or -1 on error case (i.e. no peer certificate)
3298 */
3299int ssl_sock_get_remote_common_name(struct connection *conn, struct chunk *dest)
David Safb76832014-05-08 23:42:08 -04003300{
3301 X509 *crt = NULL;
3302 X509_NAME *name;
David Safb76832014-05-08 23:42:08 -04003303 const char find_cn[] = "CN";
3304 const struct chunk find_cn_chunk = {
3305 .str = (char *)&find_cn,
3306 .len = sizeof(find_cn)-1
3307 };
Emeric Brun0abf8362014-06-24 18:26:41 +02003308 int result = -1;
David Safb76832014-05-08 23:42:08 -04003309
3310 if (!ssl_sock_is_ssl(conn))
Emeric Brun0abf8362014-06-24 18:26:41 +02003311 goto out;
David Safb76832014-05-08 23:42:08 -04003312
3313 /* SSL_get_peer_certificate, it increase X509 * ref count */
3314 crt = SSL_get_peer_certificate(conn->xprt_ctx);
3315 if (!crt)
3316 goto out;
3317
3318 name = X509_get_subject_name(crt);
3319 if (!name)
3320 goto out;
David Safb76832014-05-08 23:42:08 -04003321
Emeric Brun0abf8362014-06-24 18:26:41 +02003322 result = ssl_sock_get_dn_entry(name, &find_cn_chunk, 1, dest);
3323out:
David Safb76832014-05-08 23:42:08 -04003324 if (crt)
3325 X509_free(crt);
3326
3327 return result;
3328}
3329
Dave McCowan328fb582014-07-30 10:39:13 -04003330/* returns 1 if client passed a certificate for this session, 0 if not */
3331int ssl_sock_get_cert_used_sess(struct connection *conn)
3332{
3333 X509 *crt = NULL;
3334
3335 if (!ssl_sock_is_ssl(conn))
3336 return 0;
3337
3338 /* SSL_get_peer_certificate, it increase X509 * ref count */
3339 crt = SSL_get_peer_certificate(conn->xprt_ctx);
3340 if (!crt)
3341 return 0;
3342
3343 X509_free(crt);
3344 return 1;
3345}
3346
3347/* returns 1 if client passed a certificate for this connection, 0 if not */
3348int ssl_sock_get_cert_used_conn(struct connection *conn)
David Safb76832014-05-08 23:42:08 -04003349{
3350 if (!ssl_sock_is_ssl(conn))
3351 return 0;
3352
3353 return SSL_SOCK_ST_FL_VERIFY_DONE & conn->xprt_st ? 1 : 0;
3354}
3355
3356/* returns result from SSL verify */
3357unsigned int ssl_sock_get_verify_result(struct connection *conn)
3358{
3359 if (!ssl_sock_is_ssl(conn))
3360 return (unsigned int)X509_V_ERR_APPLICATION_VERIFICATION;
3361
3362 return (unsigned int)SSL_get_verify_result(conn->xprt_ctx);
3363}
3364
Willy Tarreau7875d092012-09-10 08:20:03 +02003365/***** Below are some sample fetching functions for ACL/patterns *****/
3366
Emeric Brune64aef12012-09-21 13:15:06 +02003367/* boolean, returns true if client cert was present */
3368static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02003369smp_fetch_ssl_fc_has_crt(const struct arg *args, struct sample *smp, const char *kw, void *private)
Emeric Brune64aef12012-09-21 13:15:06 +02003370{
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003371 struct connection *conn;
3372
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02003373 conn = objt_conn(smp->sess->origin);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003374 if (!conn || conn->xprt != &ssl_sock)
Emeric Brune64aef12012-09-21 13:15:06 +02003375 return 0;
3376
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003377 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brune64aef12012-09-21 13:15:06 +02003378 smp->flags |= SMP_F_MAY_CHANGE;
3379 return 0;
3380 }
3381
3382 smp->flags = 0;
3383 smp->type = SMP_T_BOOL;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003384 smp->data.uint = SSL_SOCK_ST_FL_VERIFY_DONE & conn->xprt_st ? 1 : 0;
Emeric Brune64aef12012-09-21 13:15:06 +02003385
3386 return 1;
3387}
3388
Emeric Brun43e79582014-10-29 19:03:26 +01003389/* binary, returns a certificate in a binary chunk (der/raw).
3390 * The 5th keyword char is used to know if SSL_get_certificate or SSL_get_peer_certificate
3391 * should be use.
3392 */
3393static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02003394smp_fetch_ssl_x_der(const struct arg *args, struct sample *smp, const char *kw, void *private)
Emeric Brun43e79582014-10-29 19:03:26 +01003395{
3396 int cert_peer = (kw[4] == 'c') ? 1 : 0;
3397 X509 *crt = NULL;
3398 int ret = 0;
3399 struct chunk *smp_trash;
3400 struct connection *conn;
3401
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02003402 conn = objt_conn(smp->sess->origin);
Emeric Brun43e79582014-10-29 19:03:26 +01003403 if (!conn || conn->xprt != &ssl_sock)
3404 return 0;
3405
3406 if (!(conn->flags & CO_FL_CONNECTED)) {
3407 smp->flags |= SMP_F_MAY_CHANGE;
3408 return 0;
3409 }
3410
3411 if (cert_peer)
3412 crt = SSL_get_peer_certificate(conn->xprt_ctx);
3413 else
3414 crt = SSL_get_certificate(conn->xprt_ctx);
3415
3416 if (!crt)
3417 goto out;
3418
3419 smp_trash = get_trash_chunk();
3420 if (ssl_sock_crt2der(crt, smp_trash) <= 0)
3421 goto out;
3422
3423 smp->data.str = *smp_trash;
3424 smp->type = SMP_T_BIN;
3425 ret = 1;
3426out:
3427 /* SSL_get_peer_certificate, it increase X509 * ref count */
3428 if (cert_peer && crt)
3429 X509_free(crt);
3430 return ret;
3431}
3432
Emeric Brunba841a12014-04-30 17:05:08 +02003433/* binary, returns serial of certificate in a binary chunk.
3434 * The 5th keyword char is used to know if SSL_get_certificate or SSL_get_peer_certificate
3435 * should be use.
3436 */
Willy Tarreau8d598402012-10-22 17:58:39 +02003437static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02003438smp_fetch_ssl_x_serial(const struct arg *args, struct sample *smp, const char *kw, void *private)
Willy Tarreau8d598402012-10-22 17:58:39 +02003439{
Emeric Brunba841a12014-04-30 17:05:08 +02003440 int cert_peer = (kw[4] == 'c') ? 1 : 0;
Willy Tarreau8d598402012-10-22 17:58:39 +02003441 X509 *crt = NULL;
3442 int ret = 0;
3443 struct chunk *smp_trash;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003444 struct connection *conn;
3445
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02003446 conn = objt_conn(smp->sess->origin);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003447 if (!conn || conn->xprt != &ssl_sock)
Willy Tarreau8d598402012-10-22 17:58:39 +02003448 return 0;
3449
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003450 if (!(conn->flags & CO_FL_CONNECTED)) {
Willy Tarreau8d598402012-10-22 17:58:39 +02003451 smp->flags |= SMP_F_MAY_CHANGE;
3452 return 0;
3453 }
3454
Emeric Brunba841a12014-04-30 17:05:08 +02003455 if (cert_peer)
3456 crt = SSL_get_peer_certificate(conn->xprt_ctx);
3457 else
3458 crt = SSL_get_certificate(conn->xprt_ctx);
3459
Willy Tarreau8d598402012-10-22 17:58:39 +02003460 if (!crt)
3461 goto out;
3462
Willy Tarreau47ca5452012-12-23 20:22:19 +01003463 smp_trash = get_trash_chunk();
Willy Tarreau8d598402012-10-22 17:58:39 +02003464 if (ssl_sock_get_serial(crt, smp_trash) <= 0)
3465 goto out;
3466
3467 smp->data.str = *smp_trash;
3468 smp->type = SMP_T_BIN;
3469 ret = 1;
3470out:
Emeric Brunba841a12014-04-30 17:05:08 +02003471 /* SSL_get_peer_certificate, it increase X509 * ref count */
3472 if (cert_peer && crt)
Willy Tarreau8d598402012-10-22 17:58:39 +02003473 X509_free(crt);
3474 return ret;
3475}
Emeric Brune64aef12012-09-21 13:15:06 +02003476
Emeric Brunba841a12014-04-30 17:05:08 +02003477/* binary, returns the client certificate's SHA-1 fingerprint (SHA-1 hash of DER-encoded certificate) in a binary chunk.
3478 * The 5th keyword char is used to know if SSL_get_certificate or SSL_get_peer_certificate
3479 * should be use.
3480 */
James Votha051b4a2013-05-14 20:37:59 +02003481static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02003482smp_fetch_ssl_x_sha1(const struct arg *args, struct sample *smp, const char *kw, void *private)
James Votha051b4a2013-05-14 20:37:59 +02003483{
Emeric Brunba841a12014-04-30 17:05:08 +02003484 int cert_peer = (kw[4] == 'c') ? 1 : 0;
James Votha051b4a2013-05-14 20:37:59 +02003485 X509 *crt = NULL;
3486 const EVP_MD *digest;
3487 int ret = 0;
3488 struct chunk *smp_trash;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003489 struct connection *conn;
James Votha051b4a2013-05-14 20:37:59 +02003490
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02003491 conn = objt_conn(smp->sess->origin);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003492 if (!conn || conn->xprt != &ssl_sock)
3493 return 0;
3494
3495 if (!(conn->flags & CO_FL_CONNECTED)) {
James Votha051b4a2013-05-14 20:37:59 +02003496 smp->flags |= SMP_F_MAY_CHANGE;
3497 return 0;
3498 }
3499
Emeric Brunba841a12014-04-30 17:05:08 +02003500 if (cert_peer)
3501 crt = SSL_get_peer_certificate(conn->xprt_ctx);
3502 else
3503 crt = SSL_get_certificate(conn->xprt_ctx);
James Votha051b4a2013-05-14 20:37:59 +02003504 if (!crt)
3505 goto out;
3506
3507 smp_trash = get_trash_chunk();
3508 digest = EVP_sha1();
3509 X509_digest(crt, digest, (unsigned char *)smp_trash->str, (unsigned int *)&smp_trash->len);
3510
3511 smp->data.str = *smp_trash;
3512 smp->type = SMP_T_BIN;
3513 ret = 1;
3514out:
Emeric Brunba841a12014-04-30 17:05:08 +02003515 /* SSL_get_peer_certificate, it increase X509 * ref count */
3516 if (cert_peer && crt)
James Votha051b4a2013-05-14 20:37:59 +02003517 X509_free(crt);
3518 return ret;
3519}
3520
Emeric Brunba841a12014-04-30 17:05:08 +02003521/* string, returns certificate's notafter date in ASN1_UTCTIME format.
3522 * The 5th keyword char is used to know if SSL_get_certificate or SSL_get_peer_certificate
3523 * should be use.
3524 */
Emeric Brunce5ad802012-10-22 14:11:22 +02003525static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02003526smp_fetch_ssl_x_notafter(const struct arg *args, struct sample *smp, const char *kw, void *private)
Emeric Brunce5ad802012-10-22 14:11:22 +02003527{
Emeric Brunba841a12014-04-30 17:05:08 +02003528 int cert_peer = (kw[4] == 'c') ? 1 : 0;
Emeric Brunce5ad802012-10-22 14:11:22 +02003529 X509 *crt = NULL;
3530 int ret = 0;
3531 struct chunk *smp_trash;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003532 struct connection *conn;
Emeric Brunce5ad802012-10-22 14:11:22 +02003533
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02003534 conn = objt_conn(smp->sess->origin);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003535 if (!conn || conn->xprt != &ssl_sock)
3536 return 0;
3537
3538 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brunce5ad802012-10-22 14:11:22 +02003539 smp->flags |= SMP_F_MAY_CHANGE;
3540 return 0;
3541 }
3542
Emeric Brunba841a12014-04-30 17:05:08 +02003543 if (cert_peer)
3544 crt = SSL_get_peer_certificate(conn->xprt_ctx);
3545 else
3546 crt = SSL_get_certificate(conn->xprt_ctx);
Emeric Brunce5ad802012-10-22 14:11:22 +02003547 if (!crt)
3548 goto out;
3549
Willy Tarreau47ca5452012-12-23 20:22:19 +01003550 smp_trash = get_trash_chunk();
Emeric Brunce5ad802012-10-22 14:11:22 +02003551 if (ssl_sock_get_time(X509_get_notAfter(crt), smp_trash) <= 0)
3552 goto out;
3553
3554 smp->data.str = *smp_trash;
3555 smp->type = SMP_T_STR;
3556 ret = 1;
3557out:
Emeric Brunba841a12014-04-30 17:05:08 +02003558 /* SSL_get_peer_certificate, it increase X509 * ref count */
3559 if (cert_peer && crt)
Emeric Brunce5ad802012-10-22 14:11:22 +02003560 X509_free(crt);
3561 return ret;
3562}
3563
Emeric Brunba841a12014-04-30 17:05:08 +02003564/* string, returns a string of a formatted full dn \C=..\O=..\OU=.. \CN=.. of certificate's issuer
3565 * The 5th keyword char is used to know if SSL_get_certificate or SSL_get_peer_certificate
3566 * should be use.
3567 */
Emeric Brun87855892012-10-17 17:39:35 +02003568static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02003569smp_fetch_ssl_x_i_dn(const struct arg *args, struct sample *smp, const char *kw, void *private)
Emeric Brun87855892012-10-17 17:39:35 +02003570{
Emeric Brunba841a12014-04-30 17:05:08 +02003571 int cert_peer = (kw[4] == 'c') ? 1 : 0;
Emeric Brun87855892012-10-17 17:39:35 +02003572 X509 *crt = NULL;
3573 X509_NAME *name;
3574 int ret = 0;
3575 struct chunk *smp_trash;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003576 struct connection *conn;
Emeric Brun87855892012-10-17 17:39:35 +02003577
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02003578 conn = objt_conn(smp->sess->origin);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003579 if (!conn || conn->xprt != &ssl_sock)
3580 return 0;
3581
3582 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brun87855892012-10-17 17:39:35 +02003583 smp->flags |= SMP_F_MAY_CHANGE;
3584 return 0;
3585 }
3586
Emeric Brunba841a12014-04-30 17:05:08 +02003587 if (cert_peer)
3588 crt = SSL_get_peer_certificate(conn->xprt_ctx);
3589 else
3590 crt = SSL_get_certificate(conn->xprt_ctx);
Emeric Brun87855892012-10-17 17:39:35 +02003591 if (!crt)
3592 goto out;
3593
3594 name = X509_get_issuer_name(crt);
3595 if (!name)
3596 goto out;
3597
Willy Tarreau47ca5452012-12-23 20:22:19 +01003598 smp_trash = get_trash_chunk();
Emeric Brun87855892012-10-17 17:39:35 +02003599 if (args && args[0].type == ARGT_STR) {
3600 int pos = 1;
3601
3602 if (args[1].type == ARGT_SINT)
3603 pos = args[1].data.sint;
3604 else if (args[1].type == ARGT_UINT)
3605 pos =(int)args[1].data.uint;
3606
3607 if (ssl_sock_get_dn_entry(name, &args[0].data.str, pos, smp_trash) <= 0)
3608 goto out;
3609 }
3610 else if (ssl_sock_get_dn_oneline(name, smp_trash) <= 0)
3611 goto out;
3612
3613 smp->type = SMP_T_STR;
3614 smp->data.str = *smp_trash;
3615 ret = 1;
3616out:
Emeric Brunba841a12014-04-30 17:05:08 +02003617 /* SSL_get_peer_certificate, it increase X509 * ref count */
3618 if (cert_peer && crt)
Emeric Brun87855892012-10-17 17:39:35 +02003619 X509_free(crt);
3620 return ret;
3621}
3622
Emeric Brunba841a12014-04-30 17:05:08 +02003623/* string, returns notbefore date in ASN1_UTCTIME format.
3624 * The 5th keyword char is used to know if SSL_get_certificate or SSL_get_peer_certificate
3625 * should be use.
3626 */
Emeric Brunce5ad802012-10-22 14:11:22 +02003627static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02003628smp_fetch_ssl_x_notbefore(const struct arg *args, struct sample *smp, const char *kw, void *private)
Emeric Brunce5ad802012-10-22 14:11:22 +02003629{
Emeric Brunba841a12014-04-30 17:05:08 +02003630 int cert_peer = (kw[4] == 'c') ? 1 : 0;
Emeric Brunce5ad802012-10-22 14:11:22 +02003631 X509 *crt = NULL;
3632 int ret = 0;
3633 struct chunk *smp_trash;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003634 struct connection *conn;
3635
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02003636 conn = objt_conn(smp->sess->origin);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003637 if (!conn || conn->xprt != &ssl_sock)
Emeric Brunce5ad802012-10-22 14:11:22 +02003638 return 0;
3639
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003640 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brunce5ad802012-10-22 14:11:22 +02003641 smp->flags |= SMP_F_MAY_CHANGE;
3642 return 0;
3643 }
3644
Emeric Brunba841a12014-04-30 17:05:08 +02003645 if (cert_peer)
3646 crt = SSL_get_peer_certificate(conn->xprt_ctx);
3647 else
3648 crt = SSL_get_certificate(conn->xprt_ctx);
Emeric Brunce5ad802012-10-22 14:11:22 +02003649 if (!crt)
3650 goto out;
3651
Willy Tarreau47ca5452012-12-23 20:22:19 +01003652 smp_trash = get_trash_chunk();
Emeric Brunce5ad802012-10-22 14:11:22 +02003653 if (ssl_sock_get_time(X509_get_notBefore(crt), smp_trash) <= 0)
3654 goto out;
3655
3656 smp->data.str = *smp_trash;
3657 smp->type = SMP_T_STR;
3658 ret = 1;
3659out:
Emeric Brunba841a12014-04-30 17:05:08 +02003660 /* SSL_get_peer_certificate, it increase X509 * ref count */
3661 if (cert_peer && crt)
Emeric Brunce5ad802012-10-22 14:11:22 +02003662 X509_free(crt);
3663 return ret;
3664}
3665
Emeric Brunba841a12014-04-30 17:05:08 +02003666/* string, returns a string of a formatted full dn \C=..\O=..\OU=.. \CN=.. of certificate's subject
3667 * The 5th keyword char is used to know if SSL_get_certificate or SSL_get_peer_certificate
3668 * should be use.
3669 */
Emeric Brun87855892012-10-17 17:39:35 +02003670static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02003671smp_fetch_ssl_x_s_dn(const struct arg *args, struct sample *smp, const char *kw, void *private)
Emeric Brun87855892012-10-17 17:39:35 +02003672{
Emeric Brunba841a12014-04-30 17:05:08 +02003673 int cert_peer = (kw[4] == 'c') ? 1 : 0;
Emeric Brun87855892012-10-17 17:39:35 +02003674 X509 *crt = NULL;
3675 X509_NAME *name;
3676 int ret = 0;
3677 struct chunk *smp_trash;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003678 struct connection *conn;
Emeric Brun87855892012-10-17 17:39:35 +02003679
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02003680 conn = objt_conn(smp->sess->origin);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003681 if (!conn || conn->xprt != &ssl_sock)
3682 return 0;
3683
3684 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brun87855892012-10-17 17:39:35 +02003685 smp->flags |= SMP_F_MAY_CHANGE;
3686 return 0;
3687 }
3688
Emeric Brunba841a12014-04-30 17:05:08 +02003689 if (cert_peer)
3690 crt = SSL_get_peer_certificate(conn->xprt_ctx);
3691 else
3692 crt = SSL_get_certificate(conn->xprt_ctx);
Emeric Brun87855892012-10-17 17:39:35 +02003693 if (!crt)
3694 goto out;
3695
3696 name = X509_get_subject_name(crt);
3697 if (!name)
3698 goto out;
3699
Willy Tarreau47ca5452012-12-23 20:22:19 +01003700 smp_trash = get_trash_chunk();
Emeric Brun87855892012-10-17 17:39:35 +02003701 if (args && args[0].type == ARGT_STR) {
3702 int pos = 1;
3703
3704 if (args[1].type == ARGT_SINT)
3705 pos = args[1].data.sint;
3706 else if (args[1].type == ARGT_UINT)
3707 pos =(int)args[1].data.uint;
3708
3709 if (ssl_sock_get_dn_entry(name, &args[0].data.str, pos, smp_trash) <= 0)
3710 goto out;
3711 }
3712 else if (ssl_sock_get_dn_oneline(name, smp_trash) <= 0)
3713 goto out;
3714
3715 smp->type = SMP_T_STR;
3716 smp->data.str = *smp_trash;
3717 ret = 1;
3718out:
Emeric Brunba841a12014-04-30 17:05:08 +02003719 /* SSL_get_peer_certificate, it increase X509 * ref count */
3720 if (cert_peer && crt)
Emeric Brun87855892012-10-17 17:39:35 +02003721 X509_free(crt);
3722 return ret;
3723}
Emeric Brun9143d372012-12-20 15:44:16 +01003724
3725/* integer, returns true if current session use a client certificate */
3726static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02003727smp_fetch_ssl_c_used(const struct arg *args, struct sample *smp, const char *kw, void *private)
Emeric Brun9143d372012-12-20 15:44:16 +01003728{
3729 X509 *crt;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003730 struct connection *conn;
Emeric Brun9143d372012-12-20 15:44:16 +01003731
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02003732 conn = objt_conn(smp->sess->origin);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003733 if (!conn || conn->xprt != &ssl_sock)
3734 return 0;
3735
3736 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brun9143d372012-12-20 15:44:16 +01003737 smp->flags |= SMP_F_MAY_CHANGE;
3738 return 0;
3739 }
3740
3741 /* SSL_get_peer_certificate returns a ptr on allocated X509 struct */
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003742 crt = SSL_get_peer_certificate(conn->xprt_ctx);
Emeric Brun9143d372012-12-20 15:44:16 +01003743 if (crt) {
3744 X509_free(crt);
3745 }
3746
3747 smp->type = SMP_T_BOOL;
3748 smp->data.uint = (crt != NULL);
3749 return 1;
3750}
3751
Emeric Brunba841a12014-04-30 17:05:08 +02003752/* integer, returns the certificate version
3753 * The 5th keyword char is used to know if SSL_get_certificate or SSL_get_peer_certificate
3754 * should be use.
3755 */
Emeric Bruna7359fd2012-10-17 15:03:11 +02003756static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02003757smp_fetch_ssl_x_version(const struct arg *args, struct sample *smp, const char *kw, void *private)
Emeric Bruna7359fd2012-10-17 15:03:11 +02003758{
Emeric Brunba841a12014-04-30 17:05:08 +02003759 int cert_peer = (kw[4] == 'c') ? 1 : 0;
Emeric Bruna7359fd2012-10-17 15:03:11 +02003760 X509 *crt;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003761 struct connection *conn;
3762
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02003763 conn = objt_conn(smp->sess->origin);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003764 if (!conn || conn->xprt != &ssl_sock)
Emeric Bruna7359fd2012-10-17 15:03:11 +02003765 return 0;
3766
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003767 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Bruna7359fd2012-10-17 15:03:11 +02003768 smp->flags |= SMP_F_MAY_CHANGE;
3769 return 0;
3770 }
3771
Emeric Brunba841a12014-04-30 17:05:08 +02003772 if (cert_peer)
3773 crt = SSL_get_peer_certificate(conn->xprt_ctx);
3774 else
3775 crt = SSL_get_certificate(conn->xprt_ctx);
Emeric Bruna7359fd2012-10-17 15:03:11 +02003776 if (!crt)
3777 return 0;
3778
3779 smp->data.uint = (unsigned int)(1 + X509_get_version(crt));
Emeric Brunba841a12014-04-30 17:05:08 +02003780 /* SSL_get_peer_certificate increase X509 * ref count */
3781 if (cert_peer)
3782 X509_free(crt);
Emeric Bruna7359fd2012-10-17 15:03:11 +02003783 smp->type = SMP_T_UINT;
3784
3785 return 1;
3786}
3787
Emeric Brunba841a12014-04-30 17:05:08 +02003788/* string, returns the certificate's signature algorithm.
3789 * The 5th keyword char is used to know if SSL_get_certificate or SSL_get_peer_certificate
3790 * should be use.
3791 */
Emeric Brun7f56e742012-10-19 18:15:40 +02003792static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02003793smp_fetch_ssl_x_sig_alg(const struct arg *args, struct sample *smp, const char *kw, void *private)
Emeric Brun7f56e742012-10-19 18:15:40 +02003794{
Emeric Brunba841a12014-04-30 17:05:08 +02003795 int cert_peer = (kw[4] == 'c') ? 1 : 0;
Emeric Brun7f56e742012-10-19 18:15:40 +02003796 X509 *crt;
3797 int nid;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003798 struct connection *conn;
Emeric Brun7f56e742012-10-19 18:15:40 +02003799
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02003800 conn = objt_conn(smp->sess->origin);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003801 if (!conn || conn->xprt != &ssl_sock)
3802 return 0;
3803
3804 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brun7f56e742012-10-19 18:15:40 +02003805 smp->flags |= SMP_F_MAY_CHANGE;
3806 return 0;
3807 }
3808
Emeric Brunba841a12014-04-30 17:05:08 +02003809 if (cert_peer)
3810 crt = SSL_get_peer_certificate(conn->xprt_ctx);
3811 else
3812 crt = SSL_get_certificate(conn->xprt_ctx);
Emeric Brun7f56e742012-10-19 18:15:40 +02003813 if (!crt)
3814 return 0;
3815
3816 nid = OBJ_obj2nid((ASN1_OBJECT *)(crt->cert_info->signature->algorithm));
3817
3818 smp->data.str.str = (char *)OBJ_nid2sn(nid);
Emeric Brun9bf3ba22013-10-07 14:31:44 +02003819 if (!smp->data.str.str) {
Emeric Brunba841a12014-04-30 17:05:08 +02003820 /* SSL_get_peer_certificate increase X509 * ref count */
3821 if (cert_peer)
3822 X509_free(crt);
Emeric Brun7f56e742012-10-19 18:15:40 +02003823 return 0;
Emeric Brun9bf3ba22013-10-07 14:31:44 +02003824 }
Emeric Brun7f56e742012-10-19 18:15:40 +02003825
Thierry FOURNIER7654c9f2013-12-17 00:20:33 +01003826 smp->type = SMP_T_STR;
3827 smp->flags |= SMP_F_CONST;
Emeric Brun7f56e742012-10-19 18:15:40 +02003828 smp->data.str.len = strlen(smp->data.str.str);
Emeric Brunba841a12014-04-30 17:05:08 +02003829 /* SSL_get_peer_certificate increase X509 * ref count */
3830 if (cert_peer)
3831 X509_free(crt);
Emeric Brun7f56e742012-10-19 18:15:40 +02003832
3833 return 1;
3834}
3835
Emeric Brunba841a12014-04-30 17:05:08 +02003836/* string, returns the certificate's key algorithm.
3837 * The 5th keyword char is used to know if SSL_get_certificate or SSL_get_peer_certificate
3838 * should be use.
3839 */
Emeric Brun521a0112012-10-22 12:22:55 +02003840static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02003841smp_fetch_ssl_x_key_alg(const struct arg *args, struct sample *smp, const char *kw, void *private)
Emeric Brun521a0112012-10-22 12:22:55 +02003842{
Emeric Brunba841a12014-04-30 17:05:08 +02003843 int cert_peer = (kw[4] == 'c') ? 1 : 0;
Emeric Brun521a0112012-10-22 12:22:55 +02003844 X509 *crt;
3845 int nid;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003846 struct connection *conn;
Emeric Brun521a0112012-10-22 12:22:55 +02003847
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02003848 conn = objt_conn(smp->sess->origin);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003849 if (!conn || conn->xprt != &ssl_sock)
3850 return 0;
3851
3852 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brun521a0112012-10-22 12:22:55 +02003853 smp->flags |= SMP_F_MAY_CHANGE;
3854 return 0;
3855 }
3856
Emeric Brunba841a12014-04-30 17:05:08 +02003857 if (cert_peer)
3858 crt = SSL_get_peer_certificate(conn->xprt_ctx);
3859 else
3860 crt = SSL_get_certificate(conn->xprt_ctx);
Emeric Brun521a0112012-10-22 12:22:55 +02003861 if (!crt)
3862 return 0;
3863
3864 nid = OBJ_obj2nid((ASN1_OBJECT *)(crt->cert_info->key->algor->algorithm));
3865
3866 smp->data.str.str = (char *)OBJ_nid2sn(nid);
Emeric Brun9bf3ba22013-10-07 14:31:44 +02003867 if (!smp->data.str.str) {
Emeric Brunba841a12014-04-30 17:05:08 +02003868 /* SSL_get_peer_certificate increase X509 * ref count */
3869 if (cert_peer)
3870 X509_free(crt);
Emeric Brun521a0112012-10-22 12:22:55 +02003871 return 0;
Emeric Brun9bf3ba22013-10-07 14:31:44 +02003872 }
Emeric Brun521a0112012-10-22 12:22:55 +02003873
Thierry FOURNIER7654c9f2013-12-17 00:20:33 +01003874 smp->type = SMP_T_STR;
3875 smp->flags |= SMP_F_CONST;
Emeric Brun521a0112012-10-22 12:22:55 +02003876 smp->data.str.len = strlen(smp->data.str.str);
Emeric Brunba841a12014-04-30 17:05:08 +02003877 if (cert_peer)
3878 X509_free(crt);
Emeric Brun521a0112012-10-22 12:22:55 +02003879
3880 return 1;
3881}
3882
Emeric Brun645ae792014-04-30 14:21:06 +02003883/* boolean, returns true if front conn. transport layer is SSL.
3884 * This function is also usable on backend conn if the fetch keyword 5th
3885 * char is 'b'.
3886 */
Willy Tarreau7875d092012-09-10 08:20:03 +02003887static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02003888smp_fetch_ssl_fc(const struct arg *args, struct sample *smp, const char *kw, void *private)
Willy Tarreau7875d092012-09-10 08:20:03 +02003889{
Emeric Brun645ae792014-04-30 14:21:06 +02003890 int back_conn = (kw[4] == 'b') ? 1 : 0;
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02003891 struct connection *conn = objt_conn(smp->strm->si[back_conn].end);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003892
Willy Tarreau7875d092012-09-10 08:20:03 +02003893 smp->type = SMP_T_BOOL;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003894 smp->data.uint = (conn && conn->xprt == &ssl_sock);
Willy Tarreau7875d092012-09-10 08:20:03 +02003895 return 1;
3896}
3897
Emeric Brun2525b6b2012-10-18 15:59:43 +02003898/* boolean, returns true if client present a SNI */
Willy Tarreau7875d092012-09-10 08:20:03 +02003899static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02003900smp_fetch_ssl_fc_has_sni(const struct arg *args, struct sample *smp, const char *kw, void *private)
Willy Tarreau7875d092012-09-10 08:20:03 +02003901{
3902#ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02003903 struct connection *conn = objt_conn(smp->sess->origin);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003904
Willy Tarreau7875d092012-09-10 08:20:03 +02003905 smp->type = SMP_T_BOOL;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003906 smp->data.uint = (conn && conn->xprt == &ssl_sock) &&
3907 conn->xprt_ctx &&
3908 SSL_get_servername(conn->xprt_ctx, TLSEXT_NAMETYPE_host_name) != NULL;
Willy Tarreau7875d092012-09-10 08:20:03 +02003909 return 1;
3910#else
3911 return 0;
3912#endif
3913}
3914
Nenad Merdanovic26ea8222015-05-18 02:28:57 +02003915/* boolean, returns true if client session has been resumed */
3916static int
3917smp_fetch_ssl_fc_is_resumed(const struct arg *args, struct sample *smp, const char *kw, void *private)
3918{
3919 struct connection *conn = objt_conn(smp->sess->origin);
3920
3921 smp->type = SMP_T_BOOL;
3922 smp->data.uint = (conn && conn->xprt == &ssl_sock) &&
3923 conn->xprt_ctx &&
3924 SSL_session_reused(conn->xprt_ctx);
3925 return 1;
3926}
3927
Emeric Brun645ae792014-04-30 14:21:06 +02003928/* string, returns the used cipher if front conn. transport layer is SSL.
3929 * This function is also usable on backend conn if the fetch keyword 5th
3930 * char is 'b'.
3931 */
Emeric Brun589fcad2012-10-16 14:13:26 +02003932static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02003933smp_fetch_ssl_fc_cipher(const struct arg *args, struct sample *smp, const char *kw, void *private)
Emeric Brun589fcad2012-10-16 14:13:26 +02003934{
Emeric Brun645ae792014-04-30 14:21:06 +02003935 int back_conn = (kw[4] == 'b') ? 1 : 0;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003936 struct connection *conn;
3937
Emeric Brun589fcad2012-10-16 14:13:26 +02003938 smp->flags = 0;
3939
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02003940 conn = objt_conn(smp->strm->si[back_conn].end);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003941 if (!conn || !conn->xprt_ctx || conn->xprt != &ssl_sock)
Emeric Brun589fcad2012-10-16 14:13:26 +02003942 return 0;
3943
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003944 smp->data.str.str = (char *)SSL_get_cipher_name(conn->xprt_ctx);
Emeric Brun589fcad2012-10-16 14:13:26 +02003945 if (!smp->data.str.str)
3946 return 0;
3947
Thierry FOURNIER7654c9f2013-12-17 00:20:33 +01003948 smp->type = SMP_T_STR;
3949 smp->flags |= SMP_F_CONST;
Emeric Brun589fcad2012-10-16 14:13:26 +02003950 smp->data.str.len = strlen(smp->data.str.str);
3951
3952 return 1;
3953}
3954
Emeric Brun645ae792014-04-30 14:21:06 +02003955/* integer, returns the algoritm's keysize if front conn. transport layer
3956 * is SSL.
3957 * This function is also usable on backend conn if the fetch keyword 5th
3958 * char is 'b'.
3959 */
Emeric Brun589fcad2012-10-16 14:13:26 +02003960static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02003961smp_fetch_ssl_fc_alg_keysize(const struct arg *args, struct sample *smp, const char *kw, void *private)
Emeric Brun589fcad2012-10-16 14:13:26 +02003962{
Emeric Brun645ae792014-04-30 14:21:06 +02003963 int back_conn = (kw[4] == 'b') ? 1 : 0;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003964 struct connection *conn;
3965
Emeric Brun589fcad2012-10-16 14:13:26 +02003966 smp->flags = 0;
3967
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02003968 conn = objt_conn(smp->strm->si[back_conn].end);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003969 if (!conn || !conn->xprt_ctx || conn->xprt != &ssl_sock)
Emeric Brun589fcad2012-10-16 14:13:26 +02003970 return 0;
3971
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003972 if (!SSL_get_cipher_bits(conn->xprt_ctx, (int *)&smp->data.uint))
3973 return 0;
3974
Emeric Brun589fcad2012-10-16 14:13:26 +02003975 smp->type = SMP_T_UINT;
3976
3977 return 1;
3978}
3979
Emeric Brun645ae792014-04-30 14:21:06 +02003980/* integer, returns the used keysize if front conn. transport layer is SSL.
3981 * This function is also usable on backend conn if the fetch keyword 5th
3982 * char is 'b'.
3983 */
Emeric Brun589fcad2012-10-16 14:13:26 +02003984static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02003985smp_fetch_ssl_fc_use_keysize(const struct arg *args, struct sample *smp, const char *kw, void *private)
Emeric Brun589fcad2012-10-16 14:13:26 +02003986{
Emeric Brun645ae792014-04-30 14:21:06 +02003987 int back_conn = (kw[4] == 'b') ? 1 : 0;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003988 struct connection *conn;
3989
Emeric Brun589fcad2012-10-16 14:13:26 +02003990 smp->flags = 0;
3991
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02003992 conn = objt_conn(smp->strm->si[back_conn].end);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003993 if (!conn || !conn->xprt_ctx || conn->xprt != &ssl_sock)
3994 return 0;
3995
3996 smp->data.uint = (unsigned int)SSL_get_cipher_bits(conn->xprt_ctx, NULL);
Emeric Brun589fcad2012-10-16 14:13:26 +02003997 if (!smp->data.uint)
3998 return 0;
3999
4000 smp->type = SMP_T_UINT;
4001
4002 return 1;
4003}
4004
Willy Tarreau6c9a3d52012-10-18 18:57:14 +02004005#ifdef OPENSSL_NPN_NEGOTIATED
Willy Tarreau7875d092012-09-10 08:20:03 +02004006static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02004007smp_fetch_ssl_fc_npn(const struct arg *args, struct sample *smp, const char *kw, void *private)
Willy Tarreaua33c6542012-10-15 13:19:06 +02004008{
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004009 struct connection *conn;
4010
Thierry FOURNIER7654c9f2013-12-17 00:20:33 +01004011 smp->flags = SMP_F_CONST;
4012 smp->type = SMP_T_STR;
Willy Tarreaua33c6542012-10-15 13:19:06 +02004013
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02004014 conn = objt_conn(smp->sess->origin);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004015 if (!conn || !conn->xprt_ctx || conn->xprt != &ssl_sock)
4016 return 0;
4017
Willy Tarreaua33c6542012-10-15 13:19:06 +02004018 smp->data.str.str = NULL;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004019 SSL_get0_next_proto_negotiated(conn->xprt_ctx,
Willy Tarreaua33c6542012-10-15 13:19:06 +02004020 (const unsigned char **)&smp->data.str.str, (unsigned *)&smp->data.str.len);
4021
4022 if (!smp->data.str.str)
4023 return 0;
4024
4025 return 1;
Willy Tarreaua33c6542012-10-15 13:19:06 +02004026}
Willy Tarreau6c9a3d52012-10-18 18:57:14 +02004027#endif
Willy Tarreaua33c6542012-10-15 13:19:06 +02004028
Dirkjan Bussink48f1c4e2014-02-13 12:29:42 +01004029#ifdef TLSEXT_TYPE_application_layer_protocol_negotiation
Willy Tarreauab861d32013-04-02 02:30:41 +02004030static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02004031smp_fetch_ssl_fc_alpn(const struct arg *args, struct sample *smp, const char *kw, void *private)
Willy Tarreauab861d32013-04-02 02:30:41 +02004032{
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004033 struct connection *conn;
4034
Thierry FOURNIER7654c9f2013-12-17 00:20:33 +01004035 smp->flags = SMP_F_CONST;
4036 smp->type = SMP_T_STR;
Willy Tarreauab861d32013-04-02 02:30:41 +02004037
Willy Tarreaue26bf052015-05-12 10:30:12 +02004038 conn = objt_conn(smp->sess->origin);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004039 if (!conn || !conn->xprt_ctx || conn->xprt != &ssl_sock)
Willy Tarreauab861d32013-04-02 02:30:41 +02004040 return 0;
4041
4042 smp->data.str.str = NULL;
Dirkjan Bussink48f1c4e2014-02-13 12:29:42 +01004043 SSL_get0_alpn_selected(conn->xprt_ctx,
Willy Tarreauab861d32013-04-02 02:30:41 +02004044 (const unsigned char **)&smp->data.str.str, (unsigned *)&smp->data.str.len);
4045
4046 if (!smp->data.str.str)
4047 return 0;
4048
4049 return 1;
4050}
4051#endif
4052
Emeric Brun645ae792014-04-30 14:21:06 +02004053/* string, returns the used protocol if front conn. transport layer is SSL.
4054 * This function is also usable on backend conn if the fetch keyword 5th
4055 * char is 'b'.
4056 */
Willy Tarreaua33c6542012-10-15 13:19:06 +02004057static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02004058smp_fetch_ssl_fc_protocol(const struct arg *args, struct sample *smp, const char *kw, void *private)
Emeric Brun589fcad2012-10-16 14:13:26 +02004059{
Emeric Brun645ae792014-04-30 14:21:06 +02004060 int back_conn = (kw[4] == 'b') ? 1 : 0;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004061 struct connection *conn;
4062
Emeric Brun589fcad2012-10-16 14:13:26 +02004063 smp->flags = 0;
4064
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02004065 conn = objt_conn(smp->strm->si[back_conn].end);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004066 if (!conn || !conn->xprt_ctx || conn->xprt != &ssl_sock)
4067 return 0;
4068
4069 smp->data.str.str = (char *)SSL_get_version(conn->xprt_ctx);
Emeric Brun589fcad2012-10-16 14:13:26 +02004070 if (!smp->data.str.str)
4071 return 0;
4072
Thierry FOURNIER7654c9f2013-12-17 00:20:33 +01004073 smp->type = SMP_T_STR;
4074 smp->flags = SMP_F_CONST;
Emeric Brun589fcad2012-10-16 14:13:26 +02004075 smp->data.str.len = strlen(smp->data.str.str);
4076
4077 return 1;
4078}
4079
Willy Tarreau87b09662015-04-03 00:22:06 +02004080/* binary, returns the SSL stream id if front conn. transport layer is SSL.
Emeric Brun645ae792014-04-30 14:21:06 +02004081 * This function is also usable on backend conn if the fetch keyword 5th
4082 * char is 'b'.
4083 */
Emeric Brun589fcad2012-10-16 14:13:26 +02004084static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02004085smp_fetch_ssl_fc_session_id(const struct arg *args, struct sample *smp, const char *kw, void *private)
Emeric Brunfe68f682012-10-16 14:59:28 +02004086{
4087#if OPENSSL_VERSION_NUMBER > 0x0090800fL
Emeric Brun645ae792014-04-30 14:21:06 +02004088 int back_conn = (kw[4] == 'b') ? 1 : 0;
Willy Tarreau192252e2015-04-04 01:47:55 +02004089 SSL_SESSION *ssl_sess;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004090 struct connection *conn;
Emeric Brunfe68f682012-10-16 14:59:28 +02004091
Thierry FOURNIER7654c9f2013-12-17 00:20:33 +01004092 smp->flags = SMP_F_CONST;
4093 smp->type = SMP_T_BIN;
Emeric Brunfe68f682012-10-16 14:59:28 +02004094
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02004095 conn = objt_conn(smp->strm->si[back_conn].end);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004096 if (!conn || !conn->xprt_ctx || conn->xprt != &ssl_sock)
4097 return 0;
4098
Willy Tarreau192252e2015-04-04 01:47:55 +02004099 ssl_sess = SSL_get_session(conn->xprt_ctx);
4100 if (!ssl_sess)
Emeric Brunfe68f682012-10-16 14:59:28 +02004101 return 0;
4102
Willy Tarreau192252e2015-04-04 01:47:55 +02004103 smp->data.str.str = (char *)SSL_SESSION_get_id(ssl_sess, (unsigned int *)&smp->data.str.len);
Willy Tarreau745d4122015-06-17 18:34:14 +02004104 if (!smp->data.str.str || !smp->data.str.len)
Emeric Brunfe68f682012-10-16 14:59:28 +02004105 return 0;
4106
4107 return 1;
4108#else
4109 return 0;
4110#endif
4111}
4112
4113static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02004114smp_fetch_ssl_fc_sni(const struct arg *args, struct sample *smp, const char *kw, void *private)
Willy Tarreau7875d092012-09-10 08:20:03 +02004115{
4116#ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004117 struct connection *conn;
4118
Thierry FOURNIER7654c9f2013-12-17 00:20:33 +01004119 smp->flags = SMP_F_CONST;
4120 smp->type = SMP_T_STR;
Willy Tarreau7875d092012-09-10 08:20:03 +02004121
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02004122 conn = objt_conn(smp->sess->origin);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004123 if (!conn || !conn->xprt_ctx || conn->xprt != &ssl_sock)
4124 return 0;
4125
4126 smp->data.str.str = (char *)SSL_get_servername(conn->xprt_ctx, TLSEXT_NAMETYPE_host_name);
Willy Tarreau3e394c92012-09-14 23:56:58 +02004127 if (!smp->data.str.str)
4128 return 0;
4129
Willy Tarreau7875d092012-09-10 08:20:03 +02004130 smp->data.str.len = strlen(smp->data.str.str);
4131 return 1;
4132#else
4133 return 0;
4134#endif
4135}
4136
David Sc1ad52e2014-04-08 18:48:47 -04004137static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02004138smp_fetch_ssl_fc_unique_id(const struct arg *args, struct sample *smp, const char *kw, void *private)
David Sc1ad52e2014-04-08 18:48:47 -04004139{
4140#if OPENSSL_VERSION_NUMBER > 0x0090800fL
Emeric Brun645ae792014-04-30 14:21:06 +02004141 int back_conn = (kw[4] == 'b') ? 1 : 0;
David Sc1ad52e2014-04-08 18:48:47 -04004142 struct connection *conn;
4143 int finished_len;
David Sc1ad52e2014-04-08 18:48:47 -04004144 struct chunk *finished_trash;
David Sc1ad52e2014-04-08 18:48:47 -04004145
4146 smp->flags = 0;
4147
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02004148 conn = objt_conn(smp->strm->si[back_conn].end);
David Sc1ad52e2014-04-08 18:48:47 -04004149 if (!conn || !conn->xprt_ctx || conn->xprt != &ssl_sock)
4150 return 0;
4151
4152 if (!(conn->flags & CO_FL_CONNECTED)) {
4153 smp->flags |= SMP_F_MAY_CHANGE;
4154 return 0;
4155 }
4156
4157 finished_trash = get_trash_chunk();
4158 if (!SSL_session_reused(conn->xprt_ctx))
4159 finished_len = SSL_get_peer_finished(conn->xprt_ctx, finished_trash->str, finished_trash->size);
4160 else
4161 finished_len = SSL_get_finished(conn->xprt_ctx, finished_trash->str, finished_trash->size);
4162
4163 if (!finished_len)
4164 return 0;
4165
Emeric Brunb73a9b02014-04-30 18:49:19 +02004166 finished_trash->len = finished_len;
4167 smp->data.str = *finished_trash;
4168 smp->type = SMP_T_BIN;
David Sc1ad52e2014-04-08 18:48:47 -04004169
4170 return 1;
4171#else
4172 return 0;
4173#endif
4174}
4175
Emeric Brun2525b6b2012-10-18 15:59:43 +02004176/* integer, returns the first verify error in CA chain of client certificate chain. */
Emeric Brunf282a812012-09-21 15:27:54 +02004177static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02004178smp_fetch_ssl_c_ca_err(const struct arg *args, struct sample *smp, const char *kw, void *private)
Emeric Brunf282a812012-09-21 15:27:54 +02004179{
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004180 struct connection *conn;
4181
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02004182 conn = objt_conn(smp->sess->origin);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004183 if (!conn || conn->xprt != &ssl_sock)
4184 return 0;
4185
4186 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brunf282a812012-09-21 15:27:54 +02004187 smp->flags = SMP_F_MAY_CHANGE;
4188 return 0;
4189 }
4190
4191 smp->type = SMP_T_UINT;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004192 smp->data.uint = (unsigned int)SSL_SOCK_ST_TO_CA_ERROR(conn->xprt_st);
Emeric Brunf282a812012-09-21 15:27:54 +02004193 smp->flags = 0;
4194
4195 return 1;
4196}
4197
Emeric Brun2525b6b2012-10-18 15:59:43 +02004198/* integer, returns the depth of the first verify error in CA chain of client certificate chain. */
Emeric Brunf282a812012-09-21 15:27:54 +02004199static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02004200smp_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 +02004201{
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004202 struct connection *conn;
4203
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02004204 conn = objt_conn(smp->sess->origin);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004205 if (!conn || conn->xprt != &ssl_sock)
Emeric Brunf282a812012-09-21 15:27:54 +02004206 return 0;
4207
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004208 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brunf282a812012-09-21 15:27:54 +02004209 smp->flags = SMP_F_MAY_CHANGE;
4210 return 0;
4211 }
4212
4213 smp->type = SMP_T_UINT;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004214 smp->data.uint = (unsigned int)SSL_SOCK_ST_TO_CAEDEPTH(conn->xprt_st);
Emeric Brunf282a812012-09-21 15:27:54 +02004215 smp->flags = 0;
4216
4217 return 1;
4218}
4219
Emeric Brun2525b6b2012-10-18 15:59:43 +02004220/* integer, returns the first verify error on client certificate */
Emeric Brunf282a812012-09-21 15:27:54 +02004221static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02004222smp_fetch_ssl_c_err(const struct arg *args, struct sample *smp, const char *kw, void *private)
Emeric Brunf282a812012-09-21 15:27:54 +02004223{
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004224 struct connection *conn;
4225
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02004226 conn = objt_conn(smp->sess->origin);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004227 if (!conn || conn->xprt != &ssl_sock)
4228 return 0;
4229
4230 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brunf282a812012-09-21 15:27:54 +02004231 smp->flags = SMP_F_MAY_CHANGE;
4232 return 0;
4233 }
4234
4235 smp->type = SMP_T_UINT;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004236 smp->data.uint = (unsigned int)SSL_SOCK_ST_TO_CRTERROR(conn->xprt_st);
Emeric Brunf282a812012-09-21 15:27:54 +02004237 smp->flags = 0;
4238
4239 return 1;
4240}
4241
Emeric Brun2525b6b2012-10-18 15:59:43 +02004242/* integer, returns the verify result on client cert */
Emeric Brunbaf8ffb2012-09-21 15:27:20 +02004243static int
Thierry FOURNIER0786d052015-05-11 15:42:45 +02004244smp_fetch_ssl_c_verify(const struct arg *args, struct sample *smp, const char *kw, void *private)
Emeric Brunbaf8ffb2012-09-21 15:27:20 +02004245{
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004246 struct connection *conn;
4247
Thierry FOURNIER0a9a2b82015-05-11 15:20:49 +02004248 conn = objt_conn(smp->sess->origin);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004249 if (!conn || conn->xprt != &ssl_sock)
4250 return 0;
4251
4252 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brunbaf8ffb2012-09-21 15:27:20 +02004253 smp->flags = SMP_F_MAY_CHANGE;
4254 return 0;
4255 }
4256
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004257 if (!conn->xprt_ctx)
Emeric Brunbaf8ffb2012-09-21 15:27:20 +02004258 return 0;
4259
4260 smp->type = SMP_T_UINT;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02004261 smp->data.uint = (unsigned int)SSL_get_verify_result(conn->xprt_ctx);
Emeric Brunbaf8ffb2012-09-21 15:27:20 +02004262 smp->flags = 0;
4263
4264 return 1;
4265}
4266
Emeric Brunfb510ea2012-10-05 12:00:26 +02004267/* parse the "ca-file" bind keyword */
4268static 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 +02004269{
4270 if (!*args[cur_arg + 1]) {
4271 if (err)
4272 memprintf(err, "'%s' : missing CAfile path", args[cur_arg]);
4273 return ERR_ALERT | ERR_FATAL;
4274 }
4275
Emeric Brunef42d922012-10-11 16:11:36 +02004276 if ((*args[cur_arg + 1] != '/') && global.ca_base)
4277 memprintf(&conf->ca_file, "%s/%s", global.ca_base, args[cur_arg + 1]);
4278 else
4279 memprintf(&conf->ca_file, "%s", args[cur_arg + 1]);
Emeric Brunc8e8d122012-10-02 18:42:10 +02004280
Emeric Brund94b3fe2012-09-20 18:23:56 +02004281 return 0;
4282}
4283
Christopher Faulet31af49d2015-06-09 17:29:50 +02004284/* parse the "ca-sign-file" bind keyword */
4285static int bind_parse_ca_sign_file(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
4286{
4287 if (!*args[cur_arg + 1]) {
4288 if (err)
4289 memprintf(err, "'%s' : missing CAfile path", args[cur_arg]);
4290 return ERR_ALERT | ERR_FATAL;
4291 }
4292
4293 if ((*args[cur_arg + 1] != '/') && global.ca_base)
4294 memprintf(&conf->ca_sign_file, "%s/%s", global.ca_base, args[cur_arg + 1]);
4295 else
4296 memprintf(&conf->ca_sign_file, "%s", args[cur_arg + 1]);
4297
4298 return 0;
4299}
4300
4301/* parse the ca-sign-pass bind keyword */
4302
4303static int bind_parse_ca_sign_pass(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
4304{
4305 if (!*args[cur_arg + 1]) {
4306 if (err)
4307 memprintf(err, "'%s' : missing CAkey password", args[cur_arg]);
4308 return ERR_ALERT | ERR_FATAL;
4309 }
4310 memprintf(&conf->ca_sign_pass, "%s", args[cur_arg + 1]);
4311 return 0;
4312}
4313
Willy Tarreau79eeafa2012-09-14 07:53:05 +02004314/* parse the "ciphers" bind keyword */
Willy Tarreau4348fad2012-09-20 16:48:07 +02004315static 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 +02004316{
4317 if (!*args[cur_arg + 1]) {
Willy Tarreaueb6cead2012-09-20 19:43:14 +02004318 memprintf(err, "'%s' : missing cipher suite", args[cur_arg]);
Willy Tarreau79eeafa2012-09-14 07:53:05 +02004319 return ERR_ALERT | ERR_FATAL;
4320 }
4321
Emeric Brun76d88952012-10-05 15:47:31 +02004322 free(conf->ciphers);
Willy Tarreau4348fad2012-09-20 16:48:07 +02004323 conf->ciphers = strdup(args[cur_arg + 1]);
Willy Tarreau79eeafa2012-09-14 07:53:05 +02004324 return 0;
4325}
4326
4327/* parse the "crt" bind keyword */
Willy Tarreau4348fad2012-09-20 16:48:07 +02004328static 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 +02004329{
Willy Tarreau38011032013-08-13 16:59:39 +02004330 char path[MAXPATHLEN];
Willy Tarreaub75d6922014-04-14 18:05:41 +02004331
Willy Tarreau79eeafa2012-09-14 07:53:05 +02004332 if (!*args[cur_arg + 1]) {
Willy Tarreaueb6cead2012-09-20 19:43:14 +02004333 memprintf(err, "'%s' : missing certificate location", args[cur_arg]);
Willy Tarreau79eeafa2012-09-14 07:53:05 +02004334 return ERR_ALERT | ERR_FATAL;
4335 }
4336
Emeric Brunc8e8d122012-10-02 18:42:10 +02004337 if ((*args[cur_arg + 1] != '/' ) && global.crt_base) {
Willy Tarreau38011032013-08-13 16:59:39 +02004338 if ((strlen(global.crt_base) + 1 + strlen(args[cur_arg + 1]) + 1) > MAXPATHLEN) {
Emeric Brunc8e8d122012-10-02 18:42:10 +02004339 memprintf(err, "'%s' : path too long", args[cur_arg]);
4340 return ERR_ALERT | ERR_FATAL;
4341 }
Willy Tarreaub75d6922014-04-14 18:05:41 +02004342 snprintf(path, sizeof(path), "%s/%s", global.crt_base, args[cur_arg + 1]);
Emeric Brunc8e8d122012-10-02 18:42:10 +02004343 if (ssl_sock_load_cert(path, conf, px, err) > 0)
4344 return ERR_ALERT | ERR_FATAL;
4345
4346 return 0;
4347 }
4348
Willy Tarreau4348fad2012-09-20 16:48:07 +02004349 if (ssl_sock_load_cert(args[cur_arg + 1], conf, px, err) > 0)
Willy Tarreau79eeafa2012-09-14 07:53:05 +02004350 return ERR_ALERT | ERR_FATAL;
Emeric Brund94b3fe2012-09-20 18:23:56 +02004351
4352 return 0;
4353}
4354
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01004355/* parse the "crt-list" bind keyword */
4356static int bind_parse_crt_list(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
4357{
4358 if (!*args[cur_arg + 1]) {
4359 memprintf(err, "'%s' : missing certificate location", args[cur_arg]);
4360 return ERR_ALERT | ERR_FATAL;
4361 }
4362
Willy Tarreauad1731d2013-04-02 17:35:58 +02004363 if (ssl_sock_load_cert_list_file(args[cur_arg + 1], conf, px, err) > 0) {
4364 memprintf(err, "'%s' : %s", args[cur_arg], *err);
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01004365 return ERR_ALERT | ERR_FATAL;
Willy Tarreauad1731d2013-04-02 17:35:58 +02004366 }
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01004367
4368 return 0;
4369}
4370
Emeric Brunfb510ea2012-10-05 12:00:26 +02004371/* parse the "crl-file" bind keyword */
4372static 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 +02004373{
Emeric Brun051cdab2012-10-02 19:25:50 +02004374#ifndef X509_V_FLAG_CRL_CHECK
4375 if (err)
4376 memprintf(err, "'%s' : library does not support CRL verify", args[cur_arg]);
4377 return ERR_ALERT | ERR_FATAL;
4378#else
Emeric Brund94b3fe2012-09-20 18:23:56 +02004379 if (!*args[cur_arg + 1]) {
4380 if (err)
4381 memprintf(err, "'%s' : missing CRLfile path", args[cur_arg]);
4382 return ERR_ALERT | ERR_FATAL;
4383 }
Emeric Brun2b58d042012-09-20 17:10:03 +02004384
Emeric Brunef42d922012-10-11 16:11:36 +02004385 if ((*args[cur_arg + 1] != '/') && global.ca_base)
4386 memprintf(&conf->crl_file, "%s/%s", global.ca_base, args[cur_arg + 1]);
4387 else
4388 memprintf(&conf->crl_file, "%s", args[cur_arg + 1]);
Emeric Brunc8e8d122012-10-02 18:42:10 +02004389
Emeric Brun2b58d042012-09-20 17:10:03 +02004390 return 0;
Emeric Brun051cdab2012-10-02 19:25:50 +02004391#endif
Emeric Brun2b58d042012-09-20 17:10:03 +02004392}
4393
4394/* parse the "ecdhe" bind keyword keywords */
4395static int bind_parse_ecdhe(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
4396{
4397#if OPENSSL_VERSION_NUMBER < 0x0090800fL
4398 if (err)
4399 memprintf(err, "'%s' : library does not support elliptic curve Diffie-Hellman (too old)", args[cur_arg]);
4400 return ERR_ALERT | ERR_FATAL;
4401#elif defined(OPENSSL_NO_ECDH)
4402 if (err)
4403 memprintf(err, "'%s' : library does not support elliptic curve Diffie-Hellman (disabled via OPENSSL_NO_ECDH)", args[cur_arg]);
4404 return ERR_ALERT | ERR_FATAL;
4405#else
4406 if (!*args[cur_arg + 1]) {
4407 if (err)
4408 memprintf(err, "'%s' : missing named curve", args[cur_arg]);
4409 return ERR_ALERT | ERR_FATAL;
4410 }
4411
4412 conf->ecdhe = strdup(args[cur_arg + 1]);
Willy Tarreau79eeafa2012-09-14 07:53:05 +02004413
4414 return 0;
Emeric Brun2b58d042012-09-20 17:10:03 +02004415#endif
Willy Tarreau79eeafa2012-09-14 07:53:05 +02004416}
4417
Emeric Brun81c00f02012-09-21 14:31:21 +02004418/* parse the "crt_ignerr" and "ca_ignerr" bind keywords */
4419static int bind_parse_ignore_err(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
4420{
4421 int code;
4422 char *p = args[cur_arg + 1];
4423 unsigned long long *ignerr = &conf->crt_ignerr;
4424
4425 if (!*p) {
4426 if (err)
4427 memprintf(err, "'%s' : missing error IDs list", args[cur_arg]);
4428 return ERR_ALERT | ERR_FATAL;
4429 }
4430
4431 if (strcmp(args[cur_arg], "ca-ignore-err") == 0)
4432 ignerr = &conf->ca_ignerr;
4433
4434 if (strcmp(p, "all") == 0) {
4435 *ignerr = ~0ULL;
4436 return 0;
4437 }
4438
4439 while (p) {
4440 code = atoi(p);
4441 if ((code <= 0) || (code > 63)) {
4442 if (err)
4443 memprintf(err, "'%s' : ID '%d' out of range (1..63) in error IDs list '%s'",
4444 args[cur_arg], code, args[cur_arg + 1]);
4445 return ERR_ALERT | ERR_FATAL;
4446 }
4447 *ignerr |= 1ULL << code;
4448 p = strchr(p, ',');
4449 if (p)
4450 p++;
4451 }
4452
Emeric Brun2cb7ae52012-10-05 14:14:21 +02004453 return 0;
4454}
4455
4456/* parse the "force-sslv3" bind keyword */
4457static int bind_parse_force_sslv3(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
4458{
4459 conf->ssl_options |= BC_SSL_O_USE_SSLV3;
4460 return 0;
4461}
4462
4463/* parse the "force-tlsv10" bind keyword */
4464static int bind_parse_force_tlsv10(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
4465{
4466 conf->ssl_options |= BC_SSL_O_USE_TLSV10;
Emeric Brun2d0c4822012-10-02 13:45:20 +02004467 return 0;
4468}
4469
Emeric Brun2cb7ae52012-10-05 14:14:21 +02004470/* parse the "force-tlsv11" bind keyword */
4471static int bind_parse_force_tlsv11(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
4472{
4473#if SSL_OP_NO_TLSv1_1
4474 conf->ssl_options |= BC_SSL_O_USE_TLSV11;
4475 return 0;
4476#else
4477 if (err)
4478 memprintf(err, "'%s' : library does not support protocol TLSv1.1", args[cur_arg]);
4479 return ERR_ALERT | ERR_FATAL;
4480#endif
4481}
4482
4483/* parse the "force-tlsv12" bind keyword */
4484static int bind_parse_force_tlsv12(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
4485{
4486#if SSL_OP_NO_TLSv1_2
4487 conf->ssl_options |= BC_SSL_O_USE_TLSV12;
4488 return 0;
4489#else
4490 if (err)
4491 memprintf(err, "'%s' : library does not support protocol TLSv1.2", args[cur_arg]);
4492 return ERR_ALERT | ERR_FATAL;
4493#endif
4494}
4495
4496
Emeric Brun2d0c4822012-10-02 13:45:20 +02004497/* parse the "no-tls-tickets" bind keyword */
4498static int bind_parse_no_tls_tickets(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
4499{
Emeric Brun89675492012-10-05 13:48:26 +02004500 conf->ssl_options |= BC_SSL_O_NO_TLS_TICKETS;
Emeric Brun81c00f02012-09-21 14:31:21 +02004501 return 0;
4502}
4503
Emeric Brun2d0c4822012-10-02 13:45:20 +02004504
Emeric Brun9b3009b2012-10-05 11:55:06 +02004505/* parse the "no-sslv3" bind keyword */
4506static 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 +02004507{
Emeric Brun89675492012-10-05 13:48:26 +02004508 conf->ssl_options |= BC_SSL_O_NO_SSLV3;
Willy Tarreau79eeafa2012-09-14 07:53:05 +02004509 return 0;
4510}
4511
Emeric Brun9b3009b2012-10-05 11:55:06 +02004512/* parse the "no-tlsv10" bind keyword */
4513static 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 +02004514{
Emeric Brun89675492012-10-05 13:48:26 +02004515 conf->ssl_options |= BC_SSL_O_NO_TLSV10;
Emeric Brunc0ff4922012-09-28 19:37:02 +02004516 return 0;
4517}
4518
Emeric Brun9b3009b2012-10-05 11:55:06 +02004519/* parse the "no-tlsv11" bind keyword */
4520static 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 +02004521{
Emeric Brun89675492012-10-05 13:48:26 +02004522 conf->ssl_options |= BC_SSL_O_NO_TLSV11;
Emeric Brunc0ff4922012-09-28 19:37:02 +02004523 return 0;
4524}
4525
Emeric Brun9b3009b2012-10-05 11:55:06 +02004526/* parse the "no-tlsv12" bind keyword */
4527static 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 +02004528{
Emeric Brun89675492012-10-05 13:48:26 +02004529 conf->ssl_options |= BC_SSL_O_NO_TLSV12;
Willy Tarreau79eeafa2012-09-14 07:53:05 +02004530 return 0;
4531}
4532
Willy Tarreau6c9a3d52012-10-18 18:57:14 +02004533/* parse the "npn" bind keyword */
4534static int bind_parse_npn(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
4535{
4536#ifdef OPENSSL_NPN_NEGOTIATED
4537 char *p1, *p2;
4538
4539 if (!*args[cur_arg + 1]) {
4540 memprintf(err, "'%s' : missing the comma-delimited NPN protocol suite", args[cur_arg]);
4541 return ERR_ALERT | ERR_FATAL;
4542 }
4543
4544 free(conf->npn_str);
4545
4546 /* the NPN string is built as a suite of (<len> <name>)* */
4547 conf->npn_len = strlen(args[cur_arg + 1]) + 1;
4548 conf->npn_str = calloc(1, conf->npn_len);
4549 memcpy(conf->npn_str + 1, args[cur_arg + 1], conf->npn_len);
4550
4551 /* replace commas with the name length */
4552 p1 = conf->npn_str;
4553 p2 = p1 + 1;
4554 while (1) {
4555 p2 = memchr(p1 + 1, ',', conf->npn_str + conf->npn_len - (p1 + 1));
4556 if (!p2)
4557 p2 = p1 + 1 + strlen(p1 + 1);
4558
4559 if (p2 - (p1 + 1) > 255) {
4560 *p2 = '\0';
4561 memprintf(err, "'%s' : NPN protocol name too long : '%s'", args[cur_arg], p1 + 1);
4562 return ERR_ALERT | ERR_FATAL;
4563 }
4564
4565 *p1 = p2 - (p1 + 1);
4566 p1 = p2;
4567
4568 if (!*p2)
4569 break;
4570
4571 *(p2++) = '\0';
4572 }
4573 return 0;
4574#else
4575 if (err)
4576 memprintf(err, "'%s' : library does not support TLS NPN extension", args[cur_arg]);
4577 return ERR_ALERT | ERR_FATAL;
4578#endif
4579}
4580
Willy Tarreauab861d32013-04-02 02:30:41 +02004581/* parse the "alpn" bind keyword */
4582static int bind_parse_alpn(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
4583{
Dirkjan Bussink48f1c4e2014-02-13 12:29:42 +01004584#ifdef TLSEXT_TYPE_application_layer_protocol_negotiation
Willy Tarreauab861d32013-04-02 02:30:41 +02004585 char *p1, *p2;
4586
4587 if (!*args[cur_arg + 1]) {
4588 memprintf(err, "'%s' : missing the comma-delimited ALPN protocol suite", args[cur_arg]);
4589 return ERR_ALERT | ERR_FATAL;
4590 }
4591
4592 free(conf->alpn_str);
4593
4594 /* the ALPN string is built as a suite of (<len> <name>)* */
4595 conf->alpn_len = strlen(args[cur_arg + 1]) + 1;
4596 conf->alpn_str = calloc(1, conf->alpn_len);
4597 memcpy(conf->alpn_str + 1, args[cur_arg + 1], conf->alpn_len);
4598
4599 /* replace commas with the name length */
4600 p1 = conf->alpn_str;
4601 p2 = p1 + 1;
4602 while (1) {
4603 p2 = memchr(p1 + 1, ',', conf->alpn_str + conf->alpn_len - (p1 + 1));
4604 if (!p2)
4605 p2 = p1 + 1 + strlen(p1 + 1);
4606
4607 if (p2 - (p1 + 1) > 255) {
4608 *p2 = '\0';
4609 memprintf(err, "'%s' : ALPN protocol name too long : '%s'", args[cur_arg], p1 + 1);
4610 return ERR_ALERT | ERR_FATAL;
4611 }
4612
4613 *p1 = p2 - (p1 + 1);
4614 p1 = p2;
4615
4616 if (!*p2)
4617 break;
4618
4619 *(p2++) = '\0';
4620 }
4621 return 0;
4622#else
4623 if (err)
4624 memprintf(err, "'%s' : library does not support TLS ALPN extension", args[cur_arg]);
4625 return ERR_ALERT | ERR_FATAL;
4626#endif
4627}
4628
Willy Tarreau79eeafa2012-09-14 07:53:05 +02004629/* parse the "ssl" bind keyword */
Willy Tarreau4348fad2012-09-20 16:48:07 +02004630static 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 +02004631{
Willy Tarreau81796be2012-09-22 19:11:47 +02004632 struct listener *l;
4633
Willy Tarreau4348fad2012-09-20 16:48:07 +02004634 conf->is_ssl = 1;
Emeric Brun76d88952012-10-05 15:47:31 +02004635
4636 if (global.listen_default_ciphers && !conf->ciphers)
4637 conf->ciphers = strdup(global.listen_default_ciphers);
Emeric Brun2c86cbf2014-10-30 15:56:50 +01004638 conf->ssl_options |= global.listen_default_ssloptions;
Emeric Brun76d88952012-10-05 15:47:31 +02004639
Willy Tarreau81796be2012-09-22 19:11:47 +02004640 list_for_each_entry(l, &conf->listeners, by_bind)
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02004641 l->xprt = &ssl_sock;
Willy Tarreau81796be2012-09-22 19:11:47 +02004642
Willy Tarreau79eeafa2012-09-14 07:53:05 +02004643 return 0;
4644}
4645
Christopher Faulet31af49d2015-06-09 17:29:50 +02004646/* parse the "generate-certificates" bind keyword */
4647static int bind_parse_generate_certs(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
4648{
4649#ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME
4650 conf->generate_certs = 1;
4651#else
4652 memprintf(err, "%sthis version of openssl cannot generate SSL certificates.\n",
4653 err && *err ? *err : "");
4654#endif
4655 return 0;
4656}
4657
Emmanuel Hocdet65623372013-01-24 17:17:15 +01004658/* parse the "strict-sni" bind keyword */
4659static int bind_parse_strict_sni(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
4660{
4661 conf->strict_sni = 1;
4662 return 0;
Nenad Merdanovic05552d42015-02-27 19:56:49 +01004663}
4664
4665/* parse the "tls-ticket-keys" bind keyword */
4666static int bind_parse_tls_ticket_keys(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
4667{
4668#if (defined SSL_CTRL_SET_TLSEXT_TICKET_KEY_CB && TLS_TICKETS_NO > 0)
4669 FILE *f;
4670 int i = 0;
4671 char thisline[LINESIZE];
Nenad Merdanovic146defa2015-05-09 08:46:00 +02004672 struct tls_keys_ref *keys_ref;
Nenad Merdanovic05552d42015-02-27 19:56:49 +01004673
4674 if (!*args[cur_arg + 1]) {
4675 if (err)
4676 memprintf(err, "'%s' : missing TLS ticket keys file path", args[cur_arg]);
4677 return ERR_ALERT | ERR_FATAL;
4678 }
4679
Nenad Merdanovic200b0fa2015-05-09 08:46:01 +02004680 keys_ref = tlskeys_ref_lookup(args[cur_arg + 1]);
4681 if(keys_ref) {
4682 conf->keys_ref = keys_ref;
4683 return 0;
4684 }
4685
Nenad Merdanovic146defa2015-05-09 08:46:00 +02004686 keys_ref = malloc(sizeof(struct tls_keys_ref));
4687 keys_ref->tlskeys = malloc(TLS_TICKETS_NO * sizeof(struct tls_sess_key));
Nenad Merdanovic05552d42015-02-27 19:56:49 +01004688
4689 if ((f = fopen(args[cur_arg + 1], "r")) == NULL) {
4690 if (err)
4691 memprintf(err, "'%s' : unable to load ssl tickets keys file", args[cur_arg+1]);
4692 return ERR_ALERT | ERR_FATAL;
4693 }
4694
Nenad Merdanovic146defa2015-05-09 08:46:00 +02004695 keys_ref->filename = strdup(args[cur_arg + 1]);
4696
Nenad Merdanovic05552d42015-02-27 19:56:49 +01004697 while (fgets(thisline, sizeof(thisline), f) != NULL) {
4698 int len = strlen(thisline);
4699 /* Strip newline characters from the end */
4700 if(thisline[len - 1] == '\n')
4701 thisline[--len] = 0;
4702
4703 if(thisline[len - 1] == '\r')
4704 thisline[--len] = 0;
4705
Nenad Merdanovic146defa2015-05-09 08:46:00 +02004706 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 +01004707 if (err)
4708 memprintf(err, "'%s' : unable to decode base64 key on line %d", args[cur_arg+1], i + 1);
4709 return ERR_ALERT | ERR_FATAL;
4710 }
4711 i++;
4712 }
4713
4714 if (i < TLS_TICKETS_NO) {
4715 if (err)
4716 memprintf(err, "'%s' : please supply at least %d keys in the tls-tickets-file", args[cur_arg+1], TLS_TICKETS_NO);
4717 return ERR_ALERT | ERR_FATAL;
4718 }
4719
4720 fclose(f);
4721
4722 /* Use penultimate key for encryption, handle when TLS_TICKETS_NO = 1 */
4723 i-=2;
Nenad Merdanovic146defa2015-05-09 08:46:00 +02004724 keys_ref->tls_ticket_enc_index = i < 0 ? 0 : i;
Nenad Merdanovic200b0fa2015-05-09 08:46:01 +02004725 keys_ref->unique_id = -1;
Nenad Merdanovic146defa2015-05-09 08:46:00 +02004726 conf->keys_ref = keys_ref;
Nenad Merdanovic05552d42015-02-27 19:56:49 +01004727
Nenad Merdanovic200b0fa2015-05-09 08:46:01 +02004728 LIST_ADD(&tlskeys_reference, &keys_ref->list);
4729
Nenad Merdanovic05552d42015-02-27 19:56:49 +01004730 return 0;
4731#else
4732 if (err)
4733 memprintf(err, "'%s' : TLS ticket callback extension not supported", args[cur_arg]);
4734 return ERR_ALERT | ERR_FATAL;
4735#endif /* SSL_CTRL_SET_TLSEXT_TICKET_KEY_CB */
Emmanuel Hocdet65623372013-01-24 17:17:15 +01004736}
4737
Emeric Brund94b3fe2012-09-20 18:23:56 +02004738/* parse the "verify" bind keyword */
4739static int bind_parse_verify(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
4740{
4741 if (!*args[cur_arg + 1]) {
4742 if (err)
4743 memprintf(err, "'%s' : missing verify method", args[cur_arg]);
4744 return ERR_ALERT | ERR_FATAL;
4745 }
4746
4747 if (strcmp(args[cur_arg + 1], "none") == 0)
Emeric Brun850efd52014-01-29 12:24:34 +01004748 conf->verify = SSL_SOCK_VERIFY_NONE;
Emeric Brund94b3fe2012-09-20 18:23:56 +02004749 else if (strcmp(args[cur_arg + 1], "optional") == 0)
Emeric Brun850efd52014-01-29 12:24:34 +01004750 conf->verify = SSL_SOCK_VERIFY_OPTIONAL;
Emeric Brund94b3fe2012-09-20 18:23:56 +02004751 else if (strcmp(args[cur_arg + 1], "required") == 0)
Emeric Brun850efd52014-01-29 12:24:34 +01004752 conf->verify = SSL_SOCK_VERIFY_REQUIRED;
Emeric Brund94b3fe2012-09-20 18:23:56 +02004753 else {
4754 if (err)
4755 memprintf(err, "'%s' : unknown verify method '%s', only 'none', 'optional', and 'required' are supported\n",
4756 args[cur_arg], args[cur_arg + 1]);
4757 return ERR_ALERT | ERR_FATAL;
4758 }
4759
4760 return 0;
4761}
4762
Willy Tarreau92faadf2012-10-10 23:04:25 +02004763/************** "server" keywords ****************/
4764
Emeric Brunef42d922012-10-11 16:11:36 +02004765/* parse the "ca-file" server keyword */
4766static int srv_parse_ca_file(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
4767{
4768 if (!*args[*cur_arg + 1]) {
4769 if (err)
4770 memprintf(err, "'%s' : missing CAfile path", args[*cur_arg]);
4771 return ERR_ALERT | ERR_FATAL;
4772 }
4773
4774 if ((*args[*cur_arg + 1] != '/') && global.ca_base)
4775 memprintf(&newsrv->ssl_ctx.ca_file, "%s/%s", global.ca_base, args[*cur_arg + 1]);
4776 else
4777 memprintf(&newsrv->ssl_ctx.ca_file, "%s", args[*cur_arg + 1]);
4778
4779 return 0;
4780}
4781
Willy Tarreau92faadf2012-10-10 23:04:25 +02004782/* parse the "check-ssl" server keyword */
4783static int srv_parse_check_ssl(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
4784{
4785 newsrv->check.use_ssl = 1;
4786 if (global.connect_default_ciphers && !newsrv->ssl_ctx.ciphers)
4787 newsrv->ssl_ctx.ciphers = strdup(global.connect_default_ciphers);
Emeric Brun2c86cbf2014-10-30 15:56:50 +01004788 newsrv->ssl_ctx.options |= global.connect_default_ssloptions;
Willy Tarreau92faadf2012-10-10 23:04:25 +02004789 return 0;
4790}
4791
4792/* parse the "ciphers" server keyword */
4793static int srv_parse_ciphers(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
4794{
4795 if (!*args[*cur_arg + 1]) {
4796 memprintf(err, "'%s' : missing cipher suite", args[*cur_arg]);
4797 return ERR_ALERT | ERR_FATAL;
4798 }
4799
4800 free(newsrv->ssl_ctx.ciphers);
4801 newsrv->ssl_ctx.ciphers = strdup(args[*cur_arg + 1]);
4802 return 0;
4803}
4804
Emeric Brunef42d922012-10-11 16:11:36 +02004805/* parse the "crl-file" server keyword */
4806static int srv_parse_crl_file(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
4807{
4808#ifndef X509_V_FLAG_CRL_CHECK
4809 if (err)
4810 memprintf(err, "'%s' : library does not support CRL verify", args[*cur_arg]);
4811 return ERR_ALERT | ERR_FATAL;
4812#else
4813 if (!*args[*cur_arg + 1]) {
4814 if (err)
4815 memprintf(err, "'%s' : missing CRLfile path", args[*cur_arg]);
4816 return ERR_ALERT | ERR_FATAL;
4817 }
4818
4819 if ((*args[*cur_arg + 1] != '/') && global.ca_base)
4820 memprintf(&newsrv->ssl_ctx.crl_file, "%s/%s", global.ca_base, args[*cur_arg + 1]);
4821 else
4822 memprintf(&newsrv->ssl_ctx.crl_file, "%s", args[*cur_arg + 1]);
4823
4824 return 0;
4825#endif
4826}
4827
Emeric Bruna7aa3092012-10-26 12:58:00 +02004828/* parse the "crt" server keyword */
4829static int srv_parse_crt(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
4830{
4831 if (!*args[*cur_arg + 1]) {
4832 if (err)
4833 memprintf(err, "'%s' : missing certificate file path", args[*cur_arg]);
4834 return ERR_ALERT | ERR_FATAL;
4835 }
4836
4837 if ((*args[*cur_arg + 1] != '/') && global.crt_base)
4838 memprintf(&newsrv->ssl_ctx.client_crt, "%s/%s", global.ca_base, args[*cur_arg + 1]);
4839 else
4840 memprintf(&newsrv->ssl_ctx.client_crt, "%s", args[*cur_arg + 1]);
4841
4842 return 0;
4843}
Emeric Brunef42d922012-10-11 16:11:36 +02004844
Willy Tarreau92faadf2012-10-10 23:04:25 +02004845/* parse the "force-sslv3" server keyword */
4846static int srv_parse_force_sslv3(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
4847{
4848 newsrv->ssl_ctx.options |= SRV_SSL_O_USE_SSLV3;
4849 return 0;
4850}
4851
4852/* parse the "force-tlsv10" server keyword */
4853static int srv_parse_force_tlsv10(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
4854{
4855 newsrv->ssl_ctx.options |= SRV_SSL_O_USE_TLSV10;
4856 return 0;
4857}
4858
4859/* parse the "force-tlsv11" server keyword */
4860static int srv_parse_force_tlsv11(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
4861{
4862#if SSL_OP_NO_TLSv1_1
4863 newsrv->ssl_ctx.options |= SRV_SSL_O_USE_TLSV11;
4864 return 0;
4865#else
4866 if (err)
4867 memprintf(err, "'%s' : library does not support protocol TLSv1.1", args[*cur_arg]);
4868 return ERR_ALERT | ERR_FATAL;
4869#endif
4870}
4871
4872/* parse the "force-tlsv12" server keyword */
4873static int srv_parse_force_tlsv12(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
4874{
4875#if SSL_OP_NO_TLSv1_2
4876 newsrv->ssl_ctx.options |= SRV_SSL_O_USE_TLSV12;
4877 return 0;
4878#else
4879 if (err)
4880 memprintf(err, "'%s' : library does not support protocol TLSv1.2", args[*cur_arg]);
4881 return ERR_ALERT | ERR_FATAL;
4882#endif
4883}
4884
Willy Tarreau2a3fb1c2015-02-05 16:47:07 +01004885/* parse the "no-ssl-reuse" server keyword */
4886static int srv_parse_no_ssl_reuse(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
4887{
4888 newsrv->ssl_ctx.options |= SRV_SSL_O_NO_REUSE;
4889 return 0;
4890}
4891
Willy Tarreau92faadf2012-10-10 23:04:25 +02004892/* parse the "no-sslv3" server keyword */
4893static int srv_parse_no_sslv3(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
4894{
4895 newsrv->ssl_ctx.options |= SRV_SSL_O_NO_SSLV3;
4896 return 0;
4897}
4898
4899/* parse the "no-tlsv10" server keyword */
4900static int srv_parse_no_tlsv10(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
4901{
4902 newsrv->ssl_ctx.options |= SRV_SSL_O_NO_TLSV10;
4903 return 0;
4904}
4905
4906/* parse the "no-tlsv11" server keyword */
4907static int srv_parse_no_tlsv11(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
4908{
4909 newsrv->ssl_ctx.options |= SRV_SSL_O_NO_TLSV11;
4910 return 0;
4911}
4912
4913/* parse the "no-tlsv12" server keyword */
4914static int srv_parse_no_tlsv12(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
4915{
4916 newsrv->ssl_ctx.options |= SRV_SSL_O_NO_TLSV12;
4917 return 0;
4918}
4919
Emeric Brunf9c5c472012-10-11 15:28:34 +02004920/* parse the "no-tls-tickets" server keyword */
4921static int srv_parse_no_tls_tickets(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
4922{
4923 newsrv->ssl_ctx.options |= SRV_SSL_O_NO_TLS_TICKETS;
4924 return 0;
4925}
David Safb76832014-05-08 23:42:08 -04004926/* parse the "send-proxy-v2-ssl" server keyword */
4927static int srv_parse_send_proxy_ssl(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
4928{
4929 newsrv->pp_opts |= SRV_PP_V2;
4930 newsrv->pp_opts |= SRV_PP_V2_SSL;
4931 return 0;
4932}
4933
4934/* parse the "send-proxy-v2-ssl-cn" server keyword */
4935static int srv_parse_send_proxy_cn(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
4936{
4937 newsrv->pp_opts |= SRV_PP_V2;
4938 newsrv->pp_opts |= SRV_PP_V2_SSL;
4939 newsrv->pp_opts |= SRV_PP_V2_SSL_CN;
4940 return 0;
4941}
Emeric Brunf9c5c472012-10-11 15:28:34 +02004942
Willy Tarreau92faadf2012-10-10 23:04:25 +02004943/* parse the "ssl" server keyword */
4944static int srv_parse_ssl(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
4945{
4946 newsrv->use_ssl = 1;
4947 if (global.connect_default_ciphers && !newsrv->ssl_ctx.ciphers)
4948 newsrv->ssl_ctx.ciphers = strdup(global.connect_default_ciphers);
4949 return 0;
4950}
4951
Emeric Brunef42d922012-10-11 16:11:36 +02004952/* parse the "verify" server keyword */
4953static int srv_parse_verify(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
4954{
4955 if (!*args[*cur_arg + 1]) {
4956 if (err)
4957 memprintf(err, "'%s' : missing verify method", args[*cur_arg]);
4958 return ERR_ALERT | ERR_FATAL;
4959 }
4960
4961 if (strcmp(args[*cur_arg + 1], "none") == 0)
Emeric Brun850efd52014-01-29 12:24:34 +01004962 newsrv->ssl_ctx.verify = SSL_SOCK_VERIFY_NONE;
Emeric Brunef42d922012-10-11 16:11:36 +02004963 else if (strcmp(args[*cur_arg + 1], "required") == 0)
Emeric Brun850efd52014-01-29 12:24:34 +01004964 newsrv->ssl_ctx.verify = SSL_SOCK_VERIFY_REQUIRED;
Emeric Brunef42d922012-10-11 16:11:36 +02004965 else {
4966 if (err)
4967 memprintf(err, "'%s' : unknown verify method '%s', only 'none' and 'required' are supported\n",
4968 args[*cur_arg], args[*cur_arg + 1]);
4969 return ERR_ALERT | ERR_FATAL;
4970 }
4971
Evan Broderbe554312013-06-27 00:05:25 -07004972 return 0;
4973}
4974
4975/* parse the "verifyhost" server keyword */
4976static int srv_parse_verifyhost(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
4977{
4978 if (!*args[*cur_arg + 1]) {
4979 if (err)
4980 memprintf(err, "'%s' : missing hostname to verify against", args[*cur_arg]);
4981 return ERR_ALERT | ERR_FATAL;
4982 }
4983
4984 newsrv->ssl_ctx.verify_host = strdup(args[*cur_arg + 1]);
4985
Emeric Brunef42d922012-10-11 16:11:36 +02004986 return 0;
4987}
4988
Emeric Brun2c86cbf2014-10-30 15:56:50 +01004989/* parse the "ssl-default-bind-options" keyword in global section */
4990static int ssl_parse_default_bind_options(char **args, int section_type, struct proxy *curpx,
4991 struct proxy *defpx, const char *file, int line,
4992 char **err) {
4993 int i = 1;
4994
4995 if (*(args[i]) == 0) {
4996 memprintf(err, "global statement '%s' expects an option as an argument.", args[0]);
4997 return -1;
4998 }
4999 while (*(args[i])) {
5000 if (!strcmp(args[i], "no-sslv3"))
5001 global.listen_default_ssloptions |= BC_SSL_O_NO_SSLV3;
5002 else if (!strcmp(args[i], "no-tlsv10"))
5003 global.listen_default_ssloptions |= BC_SSL_O_NO_TLSV10;
5004 else if (!strcmp(args[i], "no-tlsv11"))
5005 global.listen_default_ssloptions |= BC_SSL_O_NO_TLSV11;
5006 else if (!strcmp(args[i], "no-tlsv12"))
5007 global.listen_default_ssloptions |= BC_SSL_O_NO_TLSV12;
5008 else if (!strcmp(args[i], "force-sslv3"))
5009 global.listen_default_ssloptions |= BC_SSL_O_USE_SSLV3;
5010 else if (!strcmp(args[i], "force-tlsv10"))
5011 global.listen_default_ssloptions |= BC_SSL_O_USE_TLSV10;
5012 else if (!strcmp(args[i], "force-tlsv11")) {
5013#if SSL_OP_NO_TLSv1_1
5014 global.listen_default_ssloptions |= BC_SSL_O_USE_TLSV11;
5015#else
5016 memprintf(err, "'%s' '%s': library does not support protocol TLSv1.1", args[0], args[i]);
5017 return -1;
5018#endif
5019 }
5020 else if (!strcmp(args[i], "force-tlsv12")) {
5021#if SSL_OP_NO_TLSv1_2
5022 global.listen_default_ssloptions |= BC_SSL_O_USE_TLSV12;
5023#else
5024 memprintf(err, "'%s' '%s': library does not support protocol TLSv1.2", args[0], args[i]);
5025 return -1;
5026#endif
5027 }
5028 else if (!strcmp(args[i], "no-tls-tickets"))
5029 global.listen_default_ssloptions |= BC_SSL_O_NO_TLS_TICKETS;
5030 else {
5031 memprintf(err, "unknown option '%s' on global statement '%s'.", args[i], args[0]);
5032 return -1;
5033 }
5034 i++;
5035 }
5036 return 0;
5037}
5038
5039/* parse the "ssl-default-server-options" keyword in global section */
5040static int ssl_parse_default_server_options(char **args, int section_type, struct proxy *curpx,
5041 struct proxy *defpx, const char *file, int line,
5042 char **err) {
5043 int i = 1;
5044
5045 if (*(args[i]) == 0) {
5046 memprintf(err, "global statement '%s' expects an option as an argument.", args[0]);
5047 return -1;
5048 }
5049 while (*(args[i])) {
5050 if (!strcmp(args[i], "no-sslv3"))
5051 global.connect_default_ssloptions |= SRV_SSL_O_NO_SSLV3;
5052 else if (!strcmp(args[i], "no-tlsv10"))
5053 global.connect_default_ssloptions |= SRV_SSL_O_NO_TLSV10;
5054 else if (!strcmp(args[i], "no-tlsv11"))
5055 global.connect_default_ssloptions |= SRV_SSL_O_NO_TLSV11;
5056 else if (!strcmp(args[i], "no-tlsv12"))
5057 global.connect_default_ssloptions |= SRV_SSL_O_NO_TLSV12;
5058 else if (!strcmp(args[i], "force-sslv3"))
5059 global.connect_default_ssloptions |= SRV_SSL_O_USE_SSLV3;
5060 else if (!strcmp(args[i], "force-tlsv10"))
5061 global.connect_default_ssloptions |= SRV_SSL_O_USE_TLSV10;
5062 else if (!strcmp(args[i], "force-tlsv11")) {
5063#if SSL_OP_NO_TLSv1_1
5064 global.connect_default_ssloptions |= SRV_SSL_O_USE_TLSV11;
5065#else
5066 memprintf(err, "'%s' '%s': library does not support protocol TLSv1.1", args[0], args[i]);
5067 return -1;
5068#endif
5069 }
5070 else if (!strcmp(args[i], "force-tlsv12")) {
5071#if SSL_OP_NO_TLSv1_2
5072 global.connect_default_ssloptions |= SRV_SSL_O_USE_TLSV12;
5073#else
5074 memprintf(err, "'%s' '%s': library does not support protocol TLSv1.2", args[0], args[i]);
5075 return -1;
5076#endif
5077 }
5078 else if (!strcmp(args[i], "no-tls-tickets"))
5079 global.connect_default_ssloptions |= SRV_SSL_O_NO_TLS_TICKETS;
5080 else {
5081 memprintf(err, "unknown option '%s' on global statement '%s'.", args[i], args[0]);
5082 return -1;
5083 }
5084 i++;
5085 }
5086 return 0;
5087}
5088
Willy Tarreau7875d092012-09-10 08:20:03 +02005089/* Note: must not be declared <const> as its list will be overwritten.
5090 * Please take care of keeping this list alphabetically sorted.
5091 */
Willy Tarreaudc13c112013-06-21 23:16:39 +02005092static struct sample_fetch_kw_list sample_fetch_keywords = {ILH, {
Emeric Brun645ae792014-04-30 14:21:06 +02005093 { "ssl_bc", smp_fetch_ssl_fc, 0, NULL, SMP_T_BOOL, SMP_USE_L5SRV },
5094 { "ssl_bc_alg_keysize", smp_fetch_ssl_fc_alg_keysize, 0, NULL, SMP_T_UINT, SMP_USE_L5SRV },
5095 { "ssl_bc_cipher", smp_fetch_ssl_fc_cipher, 0, NULL, SMP_T_STR, SMP_USE_L5SRV },
5096 { "ssl_bc_protocol", smp_fetch_ssl_fc_protocol, 0, NULL, SMP_T_STR, SMP_USE_L5SRV },
Emeric Brunb73a9b02014-04-30 18:49:19 +02005097 { "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 +02005098 { "ssl_bc_use_keysize", smp_fetch_ssl_fc_use_keysize, 0, NULL, SMP_T_UINT, SMP_USE_L5SRV },
5099 { "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 +01005100 { "ssl_c_ca_err", smp_fetch_ssl_c_ca_err, 0, NULL, SMP_T_UINT, SMP_USE_L5CLI },
5101 { "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 +01005102 { "ssl_c_der", smp_fetch_ssl_x_der, 0, NULL, SMP_T_BIN, SMP_USE_L5CLI },
Willy Tarreau80aca902013-01-07 15:42:20 +01005103 { "ssl_c_err", smp_fetch_ssl_c_err, 0, NULL, SMP_T_UINT, SMP_USE_L5CLI },
Emeric Brunba841a12014-04-30 17:05:08 +02005104 { "ssl_c_i_dn", smp_fetch_ssl_x_i_dn, ARG2(0,STR,SINT), NULL, SMP_T_STR, SMP_USE_L5CLI },
5105 { "ssl_c_key_alg", smp_fetch_ssl_x_key_alg, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
5106 { "ssl_c_notafter", smp_fetch_ssl_x_notafter, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
5107 { "ssl_c_notbefore", smp_fetch_ssl_x_notbefore, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
5108 { "ssl_c_sig_alg", smp_fetch_ssl_x_sig_alg, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
5109 { "ssl_c_s_dn", smp_fetch_ssl_x_s_dn, ARG2(0,STR,SINT), NULL, SMP_T_STR, SMP_USE_L5CLI },
5110 { "ssl_c_serial", smp_fetch_ssl_x_serial, 0, NULL, SMP_T_BIN, SMP_USE_L5CLI },
5111 { "ssl_c_sha1", smp_fetch_ssl_x_sha1, 0, NULL, SMP_T_BIN, SMP_USE_L5CLI },
Willy Tarreau80aca902013-01-07 15:42:20 +01005112 { "ssl_c_used", smp_fetch_ssl_c_used, 0, NULL, SMP_T_BOOL, SMP_USE_L5CLI },
5113 { "ssl_c_verify", smp_fetch_ssl_c_verify, 0, NULL, SMP_T_UINT, SMP_USE_L5CLI },
Emeric Brunba841a12014-04-30 17:05:08 +02005114 { "ssl_c_version", smp_fetch_ssl_x_version, 0, NULL, SMP_T_UINT, SMP_USE_L5CLI },
Emeric Brun43e79582014-10-29 19:03:26 +01005115 { "ssl_f_der", smp_fetch_ssl_x_der, 0, NULL, SMP_T_BIN, SMP_USE_L5CLI },
Emeric Brunba841a12014-04-30 17:05:08 +02005116 { "ssl_f_i_dn", smp_fetch_ssl_x_i_dn, ARG2(0,STR,SINT), NULL, SMP_T_STR, SMP_USE_L5CLI },
5117 { "ssl_f_key_alg", smp_fetch_ssl_x_key_alg, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
5118 { "ssl_f_notafter", smp_fetch_ssl_x_notafter, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
5119 { "ssl_f_notbefore", smp_fetch_ssl_x_notbefore, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
5120 { "ssl_f_sig_alg", smp_fetch_ssl_x_sig_alg, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
5121 { "ssl_f_s_dn", smp_fetch_ssl_x_s_dn, ARG2(0,STR,SINT), NULL, SMP_T_STR, SMP_USE_L5CLI },
5122 { "ssl_f_serial", smp_fetch_ssl_x_serial, 0, NULL, SMP_T_BIN, SMP_USE_L5CLI },
Emeric Brun55f4fa82014-04-30 17:11:25 +02005123 { "ssl_f_sha1", smp_fetch_ssl_x_sha1, 0, NULL, SMP_T_BIN, SMP_USE_L5CLI },
Emeric Brunba841a12014-04-30 17:05:08 +02005124 { "ssl_f_version", smp_fetch_ssl_x_version, 0, NULL, SMP_T_UINT, SMP_USE_L5CLI },
Willy Tarreau80aca902013-01-07 15:42:20 +01005125 { "ssl_fc", smp_fetch_ssl_fc, 0, NULL, SMP_T_BOOL, SMP_USE_L5CLI },
5126 { "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 +01005127 { "ssl_fc_cipher", smp_fetch_ssl_fc_cipher, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
Willy Tarreau80aca902013-01-07 15:42:20 +01005128 { "ssl_fc_has_crt", smp_fetch_ssl_fc_has_crt, 0, NULL, SMP_T_BOOL, SMP_USE_L5CLI },
5129 { "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 +02005130 { "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 +02005131#ifdef OPENSSL_NPN_NEGOTIATED
Thierry FOURNIER7654c9f2013-12-17 00:20:33 +01005132 { "ssl_fc_npn", smp_fetch_ssl_fc_npn, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
Willy Tarreaua33c6542012-10-15 13:19:06 +02005133#endif
Dirkjan Bussink48f1c4e2014-02-13 12:29:42 +01005134#ifdef TLSEXT_TYPE_application_layer_protocol_negotiation
Thierry FOURNIER7654c9f2013-12-17 00:20:33 +01005135 { "ssl_fc_alpn", smp_fetch_ssl_fc_alpn, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
Willy Tarreauab861d32013-04-02 02:30:41 +02005136#endif
Thierry FOURNIER7654c9f2013-12-17 00:20:33 +01005137 { "ssl_fc_protocol", smp_fetch_ssl_fc_protocol, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
Emeric Brunb73a9b02014-04-30 18:49:19 +02005138 { "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 +01005139 { "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 +01005140 { "ssl_fc_session_id", smp_fetch_ssl_fc_session_id, 0, NULL, SMP_T_BIN, SMP_USE_L5CLI },
5141 { "ssl_fc_sni", smp_fetch_ssl_fc_sni, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
Willy Tarreau7875d092012-09-10 08:20:03 +02005142 { NULL, NULL, 0, 0, 0 },
5143}};
5144
5145/* Note: must not be declared <const> as its list will be overwritten.
5146 * Please take care of keeping this list alphabetically sorted.
5147 */
Willy Tarreaudc13c112013-06-21 23:16:39 +02005148static struct acl_kw_list acl_kws = {ILH, {
Thierry FOURNIERc5a4e982014-03-05 16:07:08 +01005149 { "ssl_fc_sni_end", "ssl_fc_sni", PAT_MATCH_END },
5150 { "ssl_fc_sni_reg", "ssl_fc_sni", PAT_MATCH_REG },
Willy Tarreau8ed669b2013-01-11 15:49:37 +01005151 { /* END */ },
Willy Tarreau7875d092012-09-10 08:20:03 +02005152}};
5153
Willy Tarreau79eeafa2012-09-14 07:53:05 +02005154/* Note: must not be declared <const> as its list will be overwritten.
5155 * Please take care of keeping this list alphabetically sorted, doing so helps
5156 * all code contributors.
5157 * Optional keywords are also declared with a NULL ->parse() function so that
5158 * the config parser can report an appropriate error when a known keyword was
5159 * not enabled.
5160 */
Willy Tarreau51fb7652012-09-18 18:24:39 +02005161static struct bind_kw_list bind_kws = { "SSL", { }, {
Nenad Merdanovic05552d42015-02-27 19:56:49 +01005162 { "alpn", bind_parse_alpn, 1 }, /* set ALPN supported protocols */
5163 { "ca-file", bind_parse_ca_file, 1 }, /* set CAfile to process verify on client cert */
5164 { "ca-ignore-err", bind_parse_ignore_err, 1 }, /* set error IDs to ignore on verify depth > 0 */
Christopher Faulet31af49d2015-06-09 17:29:50 +02005165 { "ca-sign-file", bind_parse_ca_sign_file, 1 }, /* set CAFile used to generate and sign server certs */
5166 { "ca-sign-pass", bind_parse_ca_sign_pass, 1 }, /* set CAKey passphrase */
Nenad Merdanovic05552d42015-02-27 19:56:49 +01005167 { "ciphers", bind_parse_ciphers, 1 }, /* set SSL cipher suite */
5168 { "crl-file", bind_parse_crl_file, 1 }, /* set certificat revocation list file use on client cert verify */
5169 { "crt", bind_parse_crt, 1 }, /* load SSL certificates from this location */
5170 { "crt-ignore-err", bind_parse_ignore_err, 1 }, /* set error IDs to ingore on verify depth == 0 */
5171 { "crt-list", bind_parse_crt_list, 1 }, /* load a list of crt from this location */
5172 { "ecdhe", bind_parse_ecdhe, 1 }, /* defines named curve for elliptic curve Diffie-Hellman */
5173 { "force-sslv3", bind_parse_force_sslv3, 0 }, /* force SSLv3 */
5174 { "force-tlsv10", bind_parse_force_tlsv10, 0 }, /* force TLSv10 */
5175 { "force-tlsv11", bind_parse_force_tlsv11, 0 }, /* force TLSv11 */
5176 { "force-tlsv12", bind_parse_force_tlsv12, 0 }, /* force TLSv12 */
Christopher Faulet31af49d2015-06-09 17:29:50 +02005177 { "generate-certificates", bind_parse_generate_certs, 0 }, /* enable the server certificates generation */
Nenad Merdanovic05552d42015-02-27 19:56:49 +01005178 { "no-sslv3", bind_parse_no_sslv3, 0 }, /* disable SSLv3 */
5179 { "no-tlsv10", bind_parse_no_tlsv10, 0 }, /* disable TLSv10 */
5180 { "no-tlsv11", bind_parse_no_tlsv11, 0 }, /* disable TLSv11 */
5181 { "no-tlsv12", bind_parse_no_tlsv12, 0 }, /* disable TLSv12 */
5182 { "no-tls-tickets", bind_parse_no_tls_tickets, 0 }, /* disable session resumption tickets */
5183 { "ssl", bind_parse_ssl, 0 }, /* enable SSL processing */
5184 { "strict-sni", bind_parse_strict_sni, 0 }, /* refuse negotiation if sni doesn't match a certificate */
5185 { "tls-ticket-keys", bind_parse_tls_ticket_keys, 1 }, /* set file to load TLS ticket keys from */
5186 { "verify", bind_parse_verify, 1 }, /* set SSL verify method */
5187 { "npn", bind_parse_npn, 1 }, /* set NPN supported protocols */
Willy Tarreau79eeafa2012-09-14 07:53:05 +02005188 { NULL, NULL, 0 },
5189}};
Emeric Brun46591952012-05-18 15:47:34 +02005190
Willy Tarreau92faadf2012-10-10 23:04:25 +02005191/* Note: must not be declared <const> as its list will be overwritten.
5192 * Please take care of keeping this list alphabetically sorted, doing so helps
5193 * all code contributors.
5194 * Optional keywords are also declared with a NULL ->parse() function so that
5195 * the config parser can report an appropriate error when a known keyword was
5196 * not enabled.
5197 */
5198static struct srv_kw_list srv_kws = { "SSL", { }, {
Emeric Brunef42d922012-10-11 16:11:36 +02005199 { "ca-file", srv_parse_ca_file, 1, 0 }, /* set CAfile to process verify server cert */
Emeric Brunecc91fe2012-10-11 15:05:10 +02005200 { "check-ssl", srv_parse_check_ssl, 0, 0 }, /* enable SSL for health checks */
5201 { "ciphers", srv_parse_ciphers, 1, 0 }, /* select the cipher suite */
Emeric Brunef42d922012-10-11 16:11:36 +02005202 { "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 +02005203 { "crt", srv_parse_crt, 1, 0 }, /* set client certificate */
Emeric Brunecc91fe2012-10-11 15:05:10 +02005204 { "force-sslv3", srv_parse_force_sslv3, 0, 0 }, /* force SSLv3 */
5205 { "force-tlsv10", srv_parse_force_tlsv10, 0, 0 }, /* force TLSv10 */
5206 { "force-tlsv11", srv_parse_force_tlsv11, 0, 0 }, /* force TLSv11 */
5207 { "force-tlsv12", srv_parse_force_tlsv12, 0, 0 }, /* force TLSv12 */
Willy Tarreau2a3fb1c2015-02-05 16:47:07 +01005208 { "no-ssl-reuse", srv_parse_no_ssl_reuse, 0, 0 }, /* disable session reuse */
Emeric Brunecc91fe2012-10-11 15:05:10 +02005209 { "no-sslv3", srv_parse_no_sslv3, 0, 0 }, /* disable SSLv3 */
5210 { "no-tlsv10", srv_parse_no_tlsv10, 0, 0 }, /* disable TLSv10 */
5211 { "no-tlsv11", srv_parse_no_tlsv11, 0, 0 }, /* disable TLSv11 */
5212 { "no-tlsv12", srv_parse_no_tlsv12, 0, 0 }, /* disable TLSv12 */
Emeric Brunf9c5c472012-10-11 15:28:34 +02005213 { "no-tls-tickets", srv_parse_no_tls_tickets, 0, 0 }, /* disable session resumption tickets */
David Safb76832014-05-08 23:42:08 -04005214 { "send-proxy-v2-ssl", srv_parse_send_proxy_ssl, 0, 0 }, /* send PROXY protocol header v2 with SSL info */
5215 { "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 +02005216 { "ssl", srv_parse_ssl, 0, 0 }, /* enable SSL processing */
Emeric Brunef42d922012-10-11 16:11:36 +02005217 { "verify", srv_parse_verify, 1, 0 }, /* set SSL verify method */
Evan Broderbe554312013-06-27 00:05:25 -07005218 { "verifyhost", srv_parse_verifyhost, 1, 0 }, /* require that SSL cert verifies for hostname */
Willy Tarreau92faadf2012-10-10 23:04:25 +02005219 { NULL, NULL, 0, 0 },
5220}};
5221
Emeric Brun2c86cbf2014-10-30 15:56:50 +01005222static struct cfg_kw_list cfg_kws = {ILH, {
5223 { CFG_GLOBAL, "ssl-default-bind-options", ssl_parse_default_bind_options },
5224 { CFG_GLOBAL, "ssl-default-server-options", ssl_parse_default_server_options },
5225 { 0, NULL, NULL },
5226}};
5227
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02005228/* transport-layer operations for SSL sockets */
5229struct xprt_ops ssl_sock = {
Emeric Brun46591952012-05-18 15:47:34 +02005230 .snd_buf = ssl_sock_from_buf,
5231 .rcv_buf = ssl_sock_to_buf,
5232 .rcv_pipe = NULL,
5233 .snd_pipe = NULL,
5234 .shutr = NULL,
5235 .shutw = ssl_sock_shutw,
5236 .close = ssl_sock_close,
5237 .init = ssl_sock_init,
5238};
5239
Janusz Dziemidowicz2c701b52015-03-07 23:03:59 +01005240#if (OPENSSL_VERSION_NUMBER >= 0x1000200fL && !defined OPENSSL_NO_TLSEXT && !defined OPENSSL_IS_BORINGSSL)
5241
5242static void ssl_sock_sctl_free_func(void *parent, void *ptr, CRYPTO_EX_DATA *ad, int idx, long argl, void *argp)
5243{
5244 if (ptr) {
5245 chunk_destroy(ptr);
5246 free(ptr);
5247 }
5248}
5249
5250#endif
5251
Emeric Brun46591952012-05-18 15:47:34 +02005252__attribute__((constructor))
Willy Tarreau92faadf2012-10-10 23:04:25 +02005253static void __ssl_sock_init(void)
5254{
Emeric Brun46591952012-05-18 15:47:34 +02005255 STACK_OF(SSL_COMP)* cm;
5256
Willy Tarreau610f04b2014-02-13 11:36:41 +01005257#ifdef LISTEN_DEFAULT_CIPHERS
5258 global.listen_default_ciphers = LISTEN_DEFAULT_CIPHERS;
5259#endif
5260#ifdef CONNECT_DEFAULT_CIPHERS
5261 global.connect_default_ciphers = CONNECT_DEFAULT_CIPHERS;
5262#endif
5263 if (global.listen_default_ciphers)
5264 global.listen_default_ciphers = strdup(global.listen_default_ciphers);
5265 if (global.connect_default_ciphers)
5266 global.connect_default_ciphers = strdup(global.connect_default_ciphers);
Emeric Brun2c86cbf2014-10-30 15:56:50 +01005267 global.listen_default_ssloptions = BC_SSL_O_NONE;
5268 global.connect_default_ssloptions = SRV_SSL_O_NONE;
Willy Tarreau610f04b2014-02-13 11:36:41 +01005269
Emeric Brun46591952012-05-18 15:47:34 +02005270 SSL_library_init();
5271 cm = SSL_COMP_get_compression_methods();
5272 sk_SSL_COMP_zero(cm);
Janusz Dziemidowicz2c701b52015-03-07 23:03:59 +01005273#if (OPENSSL_VERSION_NUMBER >= 0x1000200fL && !defined OPENSSL_NO_TLSEXT && !defined OPENSSL_IS_BORINGSSL)
5274 sctl_ex_index = SSL_CTX_get_ex_new_index(0, NULL, NULL, NULL, ssl_sock_sctl_free_func);
5275#endif
Willy Tarreau7875d092012-09-10 08:20:03 +02005276 sample_register_fetches(&sample_fetch_keywords);
5277 acl_register_keywords(&acl_kws);
Willy Tarreau79eeafa2012-09-14 07:53:05 +02005278 bind_register_keywords(&bind_kws);
Willy Tarreau92faadf2012-10-10 23:04:25 +02005279 srv_register_keywords(&srv_kws);
Emeric Brun2c86cbf2014-10-30 15:56:50 +01005280 cfg_register_keywords(&cfg_kws);
Willy Tarreaud92aa5c2015-01-15 21:34:39 +01005281
5282 global.ssl_session_max_cost = SSL_SESSION_MAX_COST;
5283 global.ssl_handshake_max_cost = SSL_HANDSHAKE_MAX_COST;
Remi Gacogne4f902b82015-05-28 16:23:00 +02005284
5285#ifndef OPENSSL_NO_DH
5286 ssl_dh_ptr_index = SSL_CTX_get_ex_new_index(0, NULL, NULL, NULL, NULL);
5287#endif
Christopher Faulet31af49d2015-06-09 17:29:50 +02005288
Willy Tarreauc8ad3be2015-06-17 15:48:26 +02005289#ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME
Christopher Faulet31af49d2015-06-09 17:29:50 +02005290 /* Add a global parameter for the LRU cache size */
5291 if (global.tune.ssl_ctx_cache)
5292 ssl_ctx_lru_tree = lru64_new(global.tune.ssl_ctx_cache);
5293 ssl_ctx_lru_seed = (unsigned int)time(NULL);
Willy Tarreauc8ad3be2015-06-17 15:48:26 +02005294#endif
Emeric Brun46591952012-05-18 15:47:34 +02005295}
5296
Remi Gacogned3a23c32015-05-28 16:39:47 +02005297__attribute__((destructor))
5298static void __ssl_sock_deinit(void)
5299{
Willy Tarreauc8ad3be2015-06-17 15:48:26 +02005300#ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME
Christopher Faulet31af49d2015-06-09 17:29:50 +02005301 lru64_destroy(ssl_ctx_lru_tree);
Willy Tarreauc8ad3be2015-06-17 15:48:26 +02005302#endif
Christopher Faulet31af49d2015-06-09 17:29:50 +02005303
Remi Gacogned3a23c32015-05-28 16:39:47 +02005304#ifndef OPENSSL_NO_DH
5305 if (local_dh_1024) {
5306 DH_free(local_dh_1024);
5307 local_dh_1024 = NULL;
5308 }
5309
5310 if (local_dh_2048) {
5311 DH_free(local_dh_2048);
5312 local_dh_2048 = NULL;
5313 }
5314
5315 if (local_dh_4096) {
5316 DH_free(local_dh_4096);
5317 local_dh_4096 = NULL;
5318 }
5319
Remi Gacogne47783ef2015-05-29 15:53:22 +02005320 if (global_dh) {
5321 DH_free(global_dh);
5322 global_dh = NULL;
5323 }
Remi Gacogned3a23c32015-05-28 16:39:47 +02005324#endif
5325
5326 ERR_remove_state(0);
5327 ERR_free_strings();
5328
5329 EVP_cleanup();
5330
5331#if OPENSSL_VERSION_NUMBER >= 0x00907000L
5332 CRYPTO_cleanup_all_ex_data();
5333#endif
5334}
5335
5336
Emeric Brun46591952012-05-18 15:47:34 +02005337/*
5338 * Local variables:
5339 * c-indent-level: 8
5340 * c-basic-offset: 8
5341 * End:
5342 */