blob: 278af8bbaf87ec2a6368637c65818c36cf6d4111 [file] [log] [blame]
Emeric Brun46591952012-05-18 15:47:34 +02001/*
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02002 * SSL/TLS transport layer over SOCK_STREAM sockets
Emeric Brun46591952012-05-18 15:47:34 +02003 *
4 * Copyright (C) 2012 EXCELIANCE, Emeric Brun <ebrun@exceliance.fr>
5 *
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public License
8 * as published by the Free Software Foundation; either version
9 * 2 of the License, or (at your option) any later version.
10 *
Willy Tarreau69845df2012-09-10 09:43:09 +020011 * Acknowledgement:
12 * We'd like to specially thank the Stud project authors for a very clean
13 * and well documented code which helped us understand how the OpenSSL API
14 * ought to be used in non-blocking mode. This is one difficult part which
15 * is not easy to get from the OpenSSL doc, and reading the Stud code made
16 * it much more obvious than the examples in the OpenSSL package. Keep up
17 * the good works, guys !
18 *
19 * Stud is an extremely efficient and scalable SSL/TLS proxy which combines
20 * particularly well with haproxy. For more info about this project, visit :
21 * https://github.com/bumptech/stud
22 *
Emeric Brun46591952012-05-18 15:47:34 +020023 */
24
25#define _GNU_SOURCE
Emeric Brunfc0421f2012-09-07 17:30:07 +020026#include <ctype.h>
27#include <dirent.h>
Emeric Brun46591952012-05-18 15:47:34 +020028#include <errno.h>
29#include <fcntl.h>
30#include <stdio.h>
31#include <stdlib.h>
Emeric Brunfc0421f2012-09-07 17:30:07 +020032#include <string.h>
33#include <unistd.h>
Emeric Brun46591952012-05-18 15:47:34 +020034
35#include <sys/socket.h>
36#include <sys/stat.h>
37#include <sys/types.h>
38
39#include <netinet/tcp.h>
40
41#include <openssl/ssl.h>
Emeric Brunfc0421f2012-09-07 17:30:07 +020042#include <openssl/x509.h>
43#include <openssl/x509v3.h>
44#include <openssl/x509.h>
45#include <openssl/err.h>
Thierry Fournier383085f2013-01-24 14:15:43 +010046#include <openssl/rand.h>
Emeric Brun4147b2e2014-06-16 18:36:30 +020047#ifdef SSL_CTRL_SET_TLSEXT_STATUS_REQ_CB
48#include <openssl/ocsp.h>
49#endif
Emeric Brun46591952012-05-18 15:47:34 +020050
51#include <common/buffer.h>
52#include <common/compat.h>
53#include <common/config.h>
54#include <common/debug.h>
Willy Tarreau79eeafa2012-09-14 07:53:05 +020055#include <common/errors.h>
Emeric Brun46591952012-05-18 15:47:34 +020056#include <common/standard.h>
57#include <common/ticks.h>
58#include <common/time.h>
59
Emeric Brunfc0421f2012-09-07 17:30:07 +020060#include <ebsttree.h>
61
62#include <types/global.h>
63#include <types/ssl_sock.h>
64
Willy Tarreau7875d092012-09-10 08:20:03 +020065#include <proto/acl.h>
66#include <proto/arg.h>
Emeric Brun46591952012-05-18 15:47:34 +020067#include <proto/connection.h>
68#include <proto/fd.h>
69#include <proto/freq_ctr.h>
70#include <proto/frontend.h>
Willy Tarreau79eeafa2012-09-14 07:53:05 +020071#include <proto/listener.h>
Thierry FOURNIERed66c292013-11-28 11:05:19 +010072#include <proto/pattern.h>
Willy Tarreau92faadf2012-10-10 23:04:25 +020073#include <proto/server.h>
Emeric Brun46591952012-05-18 15:47:34 +020074#include <proto/log.h>
Emeric Brun94324a42012-10-11 14:00:19 +020075#include <proto/proxy.h>
Emeric Brunfc0421f2012-09-07 17:30:07 +020076#include <proto/shctx.h>
Emeric Brun46591952012-05-18 15:47:34 +020077#include <proto/ssl_sock.h>
78#include <proto/task.h>
79
Willy Tarreau518cedd2014-02-17 15:43:01 +010080/* Warning, these are bits, not integers! */
Emeric Brune64aef12012-09-21 13:15:06 +020081#define SSL_SOCK_ST_FL_VERIFY_DONE 0x00000001
Emeric Brund8b2bb52014-01-28 15:43:53 +010082#define SSL_SOCK_ST_FL_16K_WBFSIZE 0x00000002
Willy Tarreau518cedd2014-02-17 15:43:01 +010083#define SSL_SOCK_SEND_UNLIMITED 0x00000004
Emeric Brun29f037d2014-04-25 19:05:36 +020084#define SSL_SOCK_RECV_HEARTBEAT 0x00000008
85
Emeric Brunf282a812012-09-21 15:27:54 +020086/* bits 0xFFFF0000 are reserved to store verify errors */
87
88/* Verify errors macros */
89#define SSL_SOCK_CA_ERROR_TO_ST(e) (((e > 63) ? 63 : e) << (16))
90#define SSL_SOCK_CAEDEPTH_TO_ST(d) (((d > 15) ? 15 : d) << (6+16))
91#define SSL_SOCK_CRTERROR_TO_ST(e) (((e > 63) ? 63 : e) << (4+6+16))
92
93#define SSL_SOCK_ST_TO_CA_ERROR(s) ((s >> (16)) & 63)
94#define SSL_SOCK_ST_TO_CAEDEPTH(s) ((s >> (6+16)) & 15)
95#define SSL_SOCK_ST_TO_CRTERROR(s) ((s >> (4+6+16)) & 63)
Emeric Brune64aef12012-09-21 13:15:06 +020096
Emeric Brun850efd52014-01-29 12:24:34 +010097/* server and bind verify method, it uses a global value as default */
98enum {
99 SSL_SOCK_VERIFY_DEFAULT = 0,
100 SSL_SOCK_VERIFY_REQUIRED = 1,
101 SSL_SOCK_VERIFY_OPTIONAL = 2,
102 SSL_SOCK_VERIFY_NONE = 3,
103};
104
Willy Tarreau71b734c2014-01-28 15:19:44 +0100105int sslconns = 0;
106int totalsslconns = 0;
Emeric Brune1f38db2012-09-03 20:36:47 +0200107
Emeric Brun4147b2e2014-06-16 18:36:30 +0200108#ifdef SSL_CTRL_SET_TLSEXT_STATUS_REQ_CB
109struct certificate_ocsp {
110 struct ebmb_node key;
111 unsigned char key_data[OCSP_MAX_CERTID_ASN1_LENGTH];
112 struct chunk response;
113
114};
115
116static struct eb_root cert_ocsp_tree;
117
118/* This function starts to check if the OCSP response (in DER format) contained
119 * in chunk 'ocsp_response' is valid (else exits on error).
120 * If 'cid' is not NULL, it will be compared to the OCSP certificate ID
121 * contained in the OCSP Response and exits on error if no match.
122 * If it's a valid OCSP Response:
123 * If 'ocsp' is not NULL, the chunk is copied in the OCSP response's container
124 * pointed by 'ocsp'.
125 * If 'ocsp' is NULL, the function looks up into the OCSP response's
126 * containers tree (using as index the ASN1 form of the OCSP Certificate ID extracted
127 * from the response) and exits on error if not found. Finally, If an OCSP response is
128 * already present in the container, it will be overwritten.
129 *
130 * Note: OCSP response containing more than one OCSP Single response is not
131 * considered valid.
132 *
133 * Returns 0 on success, 1 in error case.
134 */
135static int ssl_sock_load_ocsp_response(struct chunk *ocsp_response, struct certificate_ocsp *ocsp, OCSP_CERTID *cid, char **err)
136{
137 OCSP_RESPONSE *resp;
138 OCSP_BASICRESP *bs = NULL;
139 OCSP_SINGLERESP *sr;
140 unsigned char *p = (unsigned char *)ocsp_response->str;
141 int rc , count_sr;
Emeric Brun1135ea42014-06-20 15:44:34 +0200142 ASN1_GENERALIZEDTIME *revtime, *thisupd, *nextupd = NULL;
Emeric Brun4147b2e2014-06-16 18:36:30 +0200143 int reason;
144 int ret = 1;
145
146 resp = d2i_OCSP_RESPONSE(NULL, (const unsigned char **)&p, ocsp_response->len);
147 if (!resp) {
148 memprintf(err, "Unable to parse OCSP response");
149 goto out;
150 }
151
152 rc = OCSP_response_status(resp);
153 if (rc != OCSP_RESPONSE_STATUS_SUCCESSFUL) {
154 memprintf(err, "OCSP response status not successful");
155 goto out;
156 }
157
158 bs = OCSP_response_get1_basic(resp);
159 if (!bs) {
160 memprintf(err, "Failed to get basic response from OCSP Response");
161 goto out;
162 }
163
164 count_sr = OCSP_resp_count(bs);
165 if (count_sr > 1) {
166 memprintf(err, "OCSP response ignored because contains multiple single responses (%d)", count_sr);
167 goto out;
168 }
169
170 sr = OCSP_resp_get0(bs, 0);
171 if (!sr) {
172 memprintf(err, "Failed to get OCSP single response");
173 goto out;
174 }
175
176 rc = OCSP_single_get0_status(sr, &reason, &revtime, &thisupd, &nextupd);
177 if (rc != V_OCSP_CERTSTATUS_GOOD) {
178 memprintf(err, "OCSP single response: certificate status not good");
179 goto out;
180 }
181
Emeric Brun1135ea42014-06-20 15:44:34 +0200182 if (!nextupd) {
183 memprintf(err, "OCSP single response: missing nextupdate");
184 goto out;
185 }
186
Emeric Brunc8b27b62014-06-19 14:16:17 +0200187 rc = OCSP_check_validity(thisupd, nextupd, OCSP_MAX_RESPONSE_TIME_SKEW, -1);
Emeric Brun4147b2e2014-06-16 18:36:30 +0200188 if (!rc) {
189 memprintf(err, "OCSP single response: no longer valid.");
190 goto out;
191 }
192
193 if (cid) {
194 if (OCSP_id_cmp(sr->certId, cid)) {
195 memprintf(err, "OCSP single response: Certificate ID does not match certificate and issuer");
196 goto out;
197 }
198 }
199
200 if (!ocsp) {
201 unsigned char key[OCSP_MAX_CERTID_ASN1_LENGTH];
202 unsigned char *p;
203
204 rc = i2d_OCSP_CERTID(sr->certId, NULL);
205 if (!rc) {
206 memprintf(err, "OCSP single response: Unable to encode Certificate ID");
207 goto out;
208 }
209
210 if (rc > OCSP_MAX_CERTID_ASN1_LENGTH) {
211 memprintf(err, "OCSP single response: Certificate ID too long");
212 goto out;
213 }
214
215 p = key;
216 memset(key, 0, OCSP_MAX_CERTID_ASN1_LENGTH);
217 i2d_OCSP_CERTID(sr->certId, &p);
218 ocsp = (struct certificate_ocsp *)ebmb_lookup(&cert_ocsp_tree, key, OCSP_MAX_CERTID_ASN1_LENGTH);
219 if (!ocsp) {
220 memprintf(err, "OCSP single response: Certificate ID does not match any certificate or issuer");
221 goto out;
222 }
223 }
224
225 /* According to comments on "chunk_dup", the
226 previous chunk buffer will be freed */
227 if (!chunk_dup(&ocsp->response, ocsp_response)) {
228 memprintf(err, "OCSP response: Memory allocation error");
229 goto out;
230 }
231
232 ret = 0;
233out:
234 if (bs)
235 OCSP_BASICRESP_free(bs);
236
237 if (resp)
238 OCSP_RESPONSE_free(resp);
239
240 return ret;
241}
242/*
243 * External function use to update the OCSP response in the OCSP response's
244 * containers tree. The chunk 'ocsp_response' must contain the OCSP response
245 * to update in DER format.
246 *
247 * Returns 0 on success, 1 in error case.
248 */
249int ssl_sock_update_ocsp_response(struct chunk *ocsp_response, char **err)
250{
251 return ssl_sock_load_ocsp_response(ocsp_response, NULL, NULL, err);
252}
253
254/*
255 * This function load the OCSP Resonse in DER format contained in file at
256 * path 'ocsp_path' and call 'ssl_sock_load_ocsp_response'
257 *
258 * Returns 0 on success, 1 in error case.
259 */
260static int ssl_sock_load_ocsp_response_from_file(const char *ocsp_path, struct certificate_ocsp *ocsp, OCSP_CERTID *cid, char **err)
261{
262 int fd = -1;
263 int r = 0;
264 int ret = 1;
265
266 fd = open(ocsp_path, O_RDONLY);
267 if (fd == -1) {
268 memprintf(err, "Error opening OCSP response file");
269 goto end;
270 }
271
272 trash.len = 0;
273 while (trash.len < trash.size) {
274 r = read(fd, trash.str + trash.len, trash.size - trash.len);
275 if (r < 0) {
276 if (errno == EINTR)
277 continue;
278
279 memprintf(err, "Error reading OCSP response from file");
280 goto end;
281 }
282 else if (r == 0) {
283 break;
284 }
285 trash.len += r;
286 }
287
288 close(fd);
289 fd = -1;
290
291 ret = ssl_sock_load_ocsp_response(&trash, ocsp, cid, err);
292end:
293 if (fd != -1)
294 close(fd);
295
296 return ret;
297}
298
299/*
300 * Callback used to set OCSP status extension content in server hello.
301 */
302int ssl_sock_ocsp_stapling_cbk(SSL *ssl, void *arg)
303{
304 struct certificate_ocsp *ocsp = (struct certificate_ocsp *)arg;
305 char* ssl_buf;
306
307 if (!ocsp ||
308 !ocsp->response.str ||
309 !ocsp->response.len)
310 return SSL_TLSEXT_ERR_NOACK;
311
312 ssl_buf = OPENSSL_malloc(ocsp->response.len);
313 if (!ssl_buf)
314 return SSL_TLSEXT_ERR_NOACK;
315
316 memcpy(ssl_buf, ocsp->response.str, ocsp->response.len);
317 SSL_set_tlsext_status_ocsp_resp(ssl, ssl_buf, ocsp->response.len);
318
319 return SSL_TLSEXT_ERR_OK;
320}
321
322/*
323 * This function enables the handling of OCSP status extension on 'ctx' if a
324 * file name 'cert_path' suffixed using ".ocsp" is present.
325 * To enable OCSP status extension, the issuer's certificate is mandatory.
326 * It should be present in the certificate's extra chain builded from file
327 * 'cert_path'. If not found, the issuer certificate is loaded from a file
328 * named 'cert_path' suffixed using '.issuer'.
329 *
330 * In addition, ".ocsp" file content is loaded as a DER format of an OCSP
331 * response. If file is empty or content is not a valid OCSP response,
332 * OCSP status extension is enabled but OCSP response is ignored (a warning
333 * is displayed).
334 *
335 * Returns 1 if no ".ocsp" file found, 0 if OCSP status extension is
336 * succesfully enabled, or -1 in other error case.
337 */
338static int ssl_sock_load_ocsp(SSL_CTX *ctx, const char *cert_path)
339{
340
341 BIO *in = NULL;
342 X509 *x, *xi = NULL, *issuer = NULL;
343 STACK_OF(X509) *chain = NULL;
344 OCSP_CERTID *cid = NULL;
345 SSL *ssl;
346 char ocsp_path[MAXPATHLEN+1];
347 int i, ret = -1;
348 struct stat st;
349 struct certificate_ocsp *ocsp = NULL, *iocsp;
350 char *warn = NULL;
351 unsigned char *p;
352
353 snprintf(ocsp_path, MAXPATHLEN+1, "%s.ocsp", cert_path);
354
355 if (stat(ocsp_path, &st))
356 return 1;
357
358 ssl = SSL_new(ctx);
359 if (!ssl)
360 goto out;
361
362 x = SSL_get_certificate(ssl);
363 if (!x)
364 goto out;
365
366 /* Try to lookup for issuer in certificate extra chain */
367#ifdef SSL_CTRL_GET_EXTRA_CHAIN_CERTS
368 SSL_CTX_get_extra_chain_certs(ctx, &chain);
369#else
370 chain = ctx->extra_certs;
371#endif
372 for (i = 0; i < sk_X509_num(chain); i++) {
373 issuer = sk_X509_value(chain, i);
374 if (X509_check_issued(issuer, x) == X509_V_OK)
375 break;
376 else
377 issuer = NULL;
378 }
379
380 /* If not found try to load issuer from a suffixed file */
381 if (!issuer) {
382 char issuer_path[MAXPATHLEN+1];
383
384 in = BIO_new(BIO_s_file());
385 if (!in)
386 goto out;
387
388 snprintf(issuer_path, MAXPATHLEN+1, "%s.issuer", cert_path);
389 if (BIO_read_filename(in, issuer_path) <= 0)
390 goto out;
391
392 xi = PEM_read_bio_X509_AUX(in, NULL, ctx->default_passwd_callback, ctx->default_passwd_callback_userdata);
393 if (!xi)
394 goto out;
395
396 if (X509_check_issued(xi, x) != X509_V_OK)
397 goto out;
398
399 issuer = xi;
400 }
401
402 cid = OCSP_cert_to_id(0, x, issuer);
403 if (!cid)
404 goto out;
405
406 i = i2d_OCSP_CERTID(cid, NULL);
407 if (!i || (i > OCSP_MAX_CERTID_ASN1_LENGTH))
408 goto out;
409
410 ocsp = calloc(1, sizeof(struct certificate_ocsp));
411 if (!ocsp)
412 goto out;
413
414 p = ocsp->key_data;
415 i2d_OCSP_CERTID(cid, &p);
416
417 iocsp = (struct certificate_ocsp *)ebmb_insert(&cert_ocsp_tree, &ocsp->key, OCSP_MAX_CERTID_ASN1_LENGTH);
418 if (iocsp == ocsp)
419 ocsp = NULL;
420
421 SSL_CTX_set_tlsext_status_cb(ctx, ssl_sock_ocsp_stapling_cbk);
422 SSL_CTX_set_tlsext_status_arg(ctx, iocsp);
423
424 ret = 0;
425
426 warn = NULL;
427 if (ssl_sock_load_ocsp_response_from_file(ocsp_path, iocsp, cid, &warn)) {
428 memprintf(&warn, "Loading '%s': %s. Content will be ignored", ocsp_path, warn ? warn : "failure");
429 Warning("%s.\n", warn);
430 }
431
432out:
433 if (ssl)
434 SSL_free(ssl);
435
436 if (in)
437 BIO_free(in);
438
439 if (xi)
440 X509_free(xi);
441
442 if (cid)
443 OCSP_CERTID_free(cid);
444
445 if (ocsp)
446 free(ocsp);
447
448 if (warn)
449 free(warn);
450
451
452 return ret;
453}
454
455#endif
456
Emeric Brune1f38db2012-09-03 20:36:47 +0200457void ssl_sock_infocbk(const SSL *ssl, int where, int ret)
458{
459 struct connection *conn = (struct connection *)SSL_get_app_data(ssl);
460 (void)ret; /* shut gcc stupid warning */
Emeric Brund8b2bb52014-01-28 15:43:53 +0100461 BIO *write_bio;
Emeric Brune1f38db2012-09-03 20:36:47 +0200462
463 if (where & SSL_CB_HANDSHAKE_START) {
464 /* Disable renegotiation (CVE-2009-3555) */
Willy Tarreau20879a02012-12-03 16:32:10 +0100465 if (conn->flags & CO_FL_CONNECTED) {
Emeric Brune1f38db2012-09-03 20:36:47 +0200466 conn->flags |= CO_FL_ERROR;
Willy Tarreau20879a02012-12-03 16:32:10 +0100467 conn->err_code = CO_ER_SSL_RENEG;
468 }
Emeric Brune1f38db2012-09-03 20:36:47 +0200469 }
Emeric Brund8b2bb52014-01-28 15:43:53 +0100470
471 if ((where & SSL_CB_ACCEPT_LOOP) == SSL_CB_ACCEPT_LOOP) {
472 if (!(conn->xprt_st & SSL_SOCK_ST_FL_16K_WBFSIZE)) {
473 /* Long certificate chains optimz
474 If write and read bios are differents, we
475 consider that the buffering was activated,
476 so we rise the output buffer size from 4k
477 to 16k */
478 write_bio = SSL_get_wbio(ssl);
479 if (write_bio != SSL_get_rbio(ssl)) {
480 BIO_set_write_buffer_size(write_bio, 16384);
481 conn->xprt_st |= SSL_SOCK_ST_FL_16K_WBFSIZE;
482 }
483 }
484 }
Emeric Brunfc0421f2012-09-07 17:30:07 +0200485}
486
Emeric Brune64aef12012-09-21 13:15:06 +0200487/* Callback is called for each certificate of the chain during a verify
488 ok is set to 1 if preverify detect no error on current certificate.
489 Returns 0 to break the handshake, 1 otherwise. */
Evan Broderbe554312013-06-27 00:05:25 -0700490int ssl_sock_bind_verifycbk(int ok, X509_STORE_CTX *x_store)
Emeric Brune64aef12012-09-21 13:15:06 +0200491{
492 SSL *ssl;
493 struct connection *conn;
Emeric Brun81c00f02012-09-21 14:31:21 +0200494 int err, depth;
Emeric Brune64aef12012-09-21 13:15:06 +0200495
496 ssl = X509_STORE_CTX_get_ex_data(x_store, SSL_get_ex_data_X509_STORE_CTX_idx());
497 conn = (struct connection *)SSL_get_app_data(ssl);
498
Willy Tarreauf7bc57c2012-10-03 00:19:48 +0200499 conn->xprt_st |= SSL_SOCK_ST_FL_VERIFY_DONE;
Emeric Brune64aef12012-09-21 13:15:06 +0200500
Emeric Brun81c00f02012-09-21 14:31:21 +0200501 if (ok) /* no errors */
502 return ok;
503
504 depth = X509_STORE_CTX_get_error_depth(x_store);
505 err = X509_STORE_CTX_get_error(x_store);
506
507 /* check if CA error needs to be ignored */
508 if (depth > 0) {
Willy Tarreauf7bc57c2012-10-03 00:19:48 +0200509 if (!SSL_SOCK_ST_TO_CA_ERROR(conn->xprt_st)) {
510 conn->xprt_st |= SSL_SOCK_CA_ERROR_TO_ST(err);
511 conn->xprt_st |= SSL_SOCK_CAEDEPTH_TO_ST(depth);
Emeric Brunf282a812012-09-21 15:27:54 +0200512 }
513
Emeric Brun1eb20ef2012-12-03 13:24:29 +0100514 if (objt_listener(conn->target)->bind_conf->ca_ignerr & (1ULL << err)) {
515 ERR_clear_error();
Emeric Brun81c00f02012-09-21 14:31:21 +0200516 return 1;
Emeric Brun1eb20ef2012-12-03 13:24:29 +0100517 }
Emeric Brun81c00f02012-09-21 14:31:21 +0200518
Willy Tarreau20879a02012-12-03 16:32:10 +0100519 conn->err_code = CO_ER_SSL_CA_FAIL;
Emeric Brun81c00f02012-09-21 14:31:21 +0200520 return 0;
521 }
522
Willy Tarreauf7bc57c2012-10-03 00:19:48 +0200523 if (!SSL_SOCK_ST_TO_CRTERROR(conn->xprt_st))
524 conn->xprt_st |= SSL_SOCK_CRTERROR_TO_ST(err);
Emeric Brunf282a812012-09-21 15:27:54 +0200525
Emeric Brun81c00f02012-09-21 14:31:21 +0200526 /* check if certificate error needs to be ignored */
Emeric Brun1eb20ef2012-12-03 13:24:29 +0100527 if (objt_listener(conn->target)->bind_conf->crt_ignerr & (1ULL << err)) {
528 ERR_clear_error();
Emeric Brun81c00f02012-09-21 14:31:21 +0200529 return 1;
Emeric Brun1eb20ef2012-12-03 13:24:29 +0100530 }
Emeric Brun81c00f02012-09-21 14:31:21 +0200531
Willy Tarreau20879a02012-12-03 16:32:10 +0100532 conn->err_code = CO_ER_SSL_CRT_FAIL;
Emeric Brun81c00f02012-09-21 14:31:21 +0200533 return 0;
Emeric Brune64aef12012-09-21 13:15:06 +0200534}
535
Emeric Brun29f037d2014-04-25 19:05:36 +0200536/* Callback is called for ssl protocol analyse */
537void ssl_sock_msgcbk(int write_p, int version, int content_type, const void *buf, size_t len, SSL *ssl, void *arg)
538{
Emeric Brun29f037d2014-04-25 19:05:36 +0200539#ifdef TLS1_RT_HEARTBEAT
540 /* test heartbeat received (write_p is set to 0
541 for a received record) */
Willy Tarreauf51c6982014-04-25 20:02:39 +0200542 if ((content_type == TLS1_RT_HEARTBEAT) && (write_p == 0)) {
Willy Tarreau84815002014-04-25 21:40:27 +0200543 struct connection *conn = (struct connection *)SSL_get_app_data(ssl);
Willy Tarreauf51c6982014-04-25 20:02:39 +0200544 const unsigned char *p = buf;
545 unsigned int payload;
546
Emeric Brun29f037d2014-04-25 19:05:36 +0200547 conn->xprt_st |= SSL_SOCK_RECV_HEARTBEAT;
Willy Tarreauf51c6982014-04-25 20:02:39 +0200548
549 /* Check if this is a CVE-2014-0160 exploitation attempt. */
550 if (*p != TLS1_HB_REQUEST)
551 return;
552
Willy Tarreauaeed6722014-04-25 23:59:58 +0200553 if (len < 1 + 2 + 16) /* 1 type + 2 size + 0 payload + 16 padding */
Willy Tarreauf51c6982014-04-25 20:02:39 +0200554 goto kill_it;
555
556 payload = (p[1] * 256) + p[2];
Willy Tarreau3b2fdb62014-04-25 23:44:22 +0200557 if (3 + payload + 16 <= len)
Willy Tarreauf51c6982014-04-25 20:02:39 +0200558 return; /* OK no problem */
Willy Tarreauaeed6722014-04-25 23:59:58 +0200559 kill_it:
Willy Tarreau3b2fdb62014-04-25 23:44:22 +0200560 /* We have a clear heartbleed attack (CVE-2014-0160), the
561 * advertised payload is larger than the advertised packet
562 * length, so we have garbage in the buffer between the
563 * payload and the end of the buffer (p+len). We can't know
564 * if the SSL stack is patched, and we don't know if we can
565 * safely wipe out the area between p+3+len and payload.
566 * So instead, we prevent the response from being sent by
567 * setting the max_send_fragment to 0 and we report an SSL
568 * error, which will kill this connection. It will be reported
569 * above as SSL_ERROR_SSL while an other handshake failure with
Willy Tarreauf51c6982014-04-25 20:02:39 +0200570 * a heartbeat message will be reported as SSL_ERROR_SYSCALL.
571 */
Willy Tarreau3b2fdb62014-04-25 23:44:22 +0200572 ssl->max_send_fragment = 0;
Willy Tarreauf51c6982014-04-25 20:02:39 +0200573 SSLerr(SSL_F_TLS1_HEARTBEAT, SSL_R_SSL_HANDSHAKE_FAILURE);
574 return;
575 }
Emeric Brun29f037d2014-04-25 19:05:36 +0200576#endif
577}
578
Willy Tarreau6c9a3d52012-10-18 18:57:14 +0200579#ifdef OPENSSL_NPN_NEGOTIATED
580/* This callback is used so that the server advertises the list of
581 * negociable protocols for NPN.
582 */
583static int ssl_sock_advertise_npn_protos(SSL *s, const unsigned char **data,
584 unsigned int *len, void *arg)
585{
586 struct bind_conf *conf = arg;
587
588 *data = (const unsigned char *)conf->npn_str;
589 *len = conf->npn_len;
590 return SSL_TLSEXT_ERR_OK;
591}
592#endif
593
Dirkjan Bussink48f1c4e2014-02-13 12:29:42 +0100594#ifdef TLSEXT_TYPE_application_layer_protocol_negotiation
Willy Tarreauab861d32013-04-02 02:30:41 +0200595/* This callback is used so that the server advertises the list of
596 * negociable protocols for ALPN.
597 */
Dirkjan Bussink48f1c4e2014-02-13 12:29:42 +0100598static int ssl_sock_advertise_alpn_protos(SSL *s, const unsigned char **out,
599 unsigned char *outlen,
600 const unsigned char *server,
601 unsigned int server_len, void *arg)
Willy Tarreauab861d32013-04-02 02:30:41 +0200602{
603 struct bind_conf *conf = arg;
604
Dirkjan Bussink48f1c4e2014-02-13 12:29:42 +0100605 if (SSL_select_next_proto((unsigned char**) out, outlen, (const unsigned char *)conf->alpn_str,
606 conf->alpn_len, server, server_len) != OPENSSL_NPN_NEGOTIATED) {
607 return SSL_TLSEXT_ERR_NOACK;
608 }
Willy Tarreauab861d32013-04-02 02:30:41 +0200609 return SSL_TLSEXT_ERR_OK;
610}
611#endif
612
Emeric Brunfc0421f2012-09-07 17:30:07 +0200613#ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME
614/* Sets the SSL ctx of <ssl> to match the advertised server name. Returns a
615 * warning when no match is found, which implies the default (first) cert
616 * will keep being used.
617 */
Willy Tarreau2a65ff02012-09-13 17:54:29 +0200618static int ssl_sock_switchctx_cbk(SSL *ssl, int *al, struct bind_conf *s)
Emeric Brunfc0421f2012-09-07 17:30:07 +0200619{
620 const char *servername;
621 const char *wildp = NULL;
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +0200622 struct ebmb_node *node, *n;
Emeric Brunfc0421f2012-09-07 17:30:07 +0200623 int i;
624 (void)al; /* shut gcc stupid warning */
625
626 servername = SSL_get_servername(ssl, TLSEXT_NAMETYPE_host_name);
Emmanuel Hocdet65623372013-01-24 17:17:15 +0100627 if (!servername) {
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +0200628 return (s->strict_sni ?
629 SSL_TLSEXT_ERR_ALERT_FATAL :
Emmanuel Hocdet79274e22013-05-31 12:47:44 +0200630 SSL_TLSEXT_ERR_NOACK);
Emmanuel Hocdet65623372013-01-24 17:17:15 +0100631 }
Emeric Brunfc0421f2012-09-07 17:30:07 +0200632
Willy Tarreau19d14ef2012-10-29 16:51:55 +0100633 for (i = 0; i < trash.size; i++) {
Emeric Brunfc0421f2012-09-07 17:30:07 +0200634 if (!servername[i])
635 break;
Willy Tarreau19d14ef2012-10-29 16:51:55 +0100636 trash.str[i] = tolower(servername[i]);
637 if (!wildp && (trash.str[i] == '.'))
638 wildp = &trash.str[i];
Emeric Brunfc0421f2012-09-07 17:30:07 +0200639 }
Willy Tarreau19d14ef2012-10-29 16:51:55 +0100640 trash.str[i] = 0;
Emeric Brunfc0421f2012-09-07 17:30:07 +0200641
642 /* lookup in full qualified names */
Willy Tarreau19d14ef2012-10-29 16:51:55 +0100643 node = ebst_lookup(&s->sni_ctx, trash.str);
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +0200644
645 /* lookup a not neg filter */
646 for (n = node; n; n = ebmb_next_dup(n)) {
647 if (!container_of(n, struct sni_ctx, name)->neg) {
648 node = n;
649 break;
Emmanuel Hocdet65623372013-01-24 17:17:15 +0100650 }
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +0200651 }
652 if (!node && wildp) {
653 /* lookup in wildcards names */
Emeric Brunfc0421f2012-09-07 17:30:07 +0200654 node = ebst_lookup(&s->sni_w_ctx, wildp);
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +0200655 }
656 if (!node || container_of(node, struct sni_ctx, name)->neg) {
657 return (s->strict_sni ?
658 SSL_TLSEXT_ERR_ALERT_FATAL :
659 SSL_TLSEXT_ERR_ALERT_WARNING);
Emeric Brunfc0421f2012-09-07 17:30:07 +0200660 }
661
662 /* switch ctx */
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +0200663 SSL_set_SSL_CTX(ssl, container_of(node, struct sni_ctx, name)->ctx);
Emeric Brunfc0421f2012-09-07 17:30:07 +0200664 return SSL_TLSEXT_ERR_OK;
665}
666#endif /* SSL_CTRL_SET_TLSEXT_HOSTNAME */
667
Emeric Bruna4bcd9a2012-09-20 16:19:02 +0200668#ifndef OPENSSL_NO_DH
Remi Gacognef46cd6e2014-06-12 14:58:40 +0200669
670static DH * ssl_get_dh_1024(void)
671{
672#if OPENSSL_VERSION_NUMBER < 0x0090801fL
673 static const unsigned char rfc_2409_prime_1024[] = {
674 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xC9,0x0F,0xDA,0xA2,
675 0x21,0x68,0xC2,0x34,0xC4,0xC6,0x62,0x8B,0x80,0xDC,0x1C,0xD1,
676 0x29,0x02,0x4E,0x08,0x8A,0x67,0xCC,0x74,0x02,0x0B,0xBE,0xA6,
677 0x3B,0x13,0x9B,0x22,0x51,0x4A,0x08,0x79,0x8E,0x34,0x04,0xDD,
678 0xEF,0x95,0x19,0xB3,0xCD,0x3A,0x43,0x1B,0x30,0x2B,0x0A,0x6D,
679 0xF2,0x5F,0x14,0x37,0x4F,0xE1,0x35,0x6D,0x6D,0x51,0xC2,0x45,
680 0xE4,0x85,0xB5,0x76,0x62,0x5E,0x7E,0xC6,0xF4,0x4C,0x42,0xE9,
681 0xA6,0x37,0xED,0x6B,0x0B,0xFF,0x5C,0xB6,0xF4,0x06,0xB7,0xED,
682 0xEE,0x38,0x6B,0xFB,0x5A,0x89,0x9F,0xA5,0xAE,0x9F,0x24,0x11,
683 0x7C,0x4B,0x1F,0xE6,0x49,0x28,0x66,0x51,0xEC,0xE6,0x53,0x81,
684 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
685 };
686#endif
687 DH *dh = DH_new();
688 if (dh) {
689#if OPENSSL_VERSION_NUMBER >= 0x0090801fL
690 dh->p = get_rfc2409_prime_1024(NULL);
691#else
692 dh->p = BN_bin2bn(rfc_2409_prime_1024, sizeof rfc_2409_prime_1024, NULL);
693#endif
694 /* See RFC 2409, Section 6 "Oakley Groups"
695 for the reason why 2 is used as generator.
696 */
697 BN_dec2bn(&dh->g, "2");
698 if (!dh->p || !dh->g) {
699 DH_free(dh);
700 dh = NULL;
701 }
702 }
703 return dh;
704}
705
706static DH *ssl_get_dh_2048(void)
707{
708#if OPENSSL_VERSION_NUMBER < 0x0090801fL
709 static const unsigned char rfc_3526_prime_2048[] = {
710 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xC9,0x0F,0xDA,0xA2,
711 0x21,0x68,0xC2,0x34,0xC4,0xC6,0x62,0x8B,0x80,0xDC,0x1C,0xD1,
712 0x29,0x02,0x4E,0x08,0x8A,0x67,0xCC,0x74,0x02,0x0B,0xBE,0xA6,
713 0x3B,0x13,0x9B,0x22,0x51,0x4A,0x08,0x79,0x8E,0x34,0x04,0xDD,
714 0xEF,0x95,0x19,0xB3,0xCD,0x3A,0x43,0x1B,0x30,0x2B,0x0A,0x6D,
715 0xF2,0x5F,0x14,0x37,0x4F,0xE1,0x35,0x6D,0x6D,0x51,0xC2,0x45,
716 0xE4,0x85,0xB5,0x76,0x62,0x5E,0x7E,0xC6,0xF4,0x4C,0x42,0xE9,
717 0xA6,0x37,0xED,0x6B,0x0B,0xFF,0x5C,0xB6,0xF4,0x06,0xB7,0xED,
718 0xEE,0x38,0x6B,0xFB,0x5A,0x89,0x9F,0xA5,0xAE,0x9F,0x24,0x11,
719 0x7C,0x4B,0x1F,0xE6,0x49,0x28,0x66,0x51,0xEC,0xE4,0x5B,0x3D,
720 0xC2,0x00,0x7C,0xB8,0xA1,0x63,0xBF,0x05,0x98,0xDA,0x48,0x36,
721 0x1C,0x55,0xD3,0x9A,0x69,0x16,0x3F,0xA8,0xFD,0x24,0xCF,0x5F,
722 0x83,0x65,0x5D,0x23,0xDC,0xA3,0xAD,0x96,0x1C,0x62,0xF3,0x56,
723 0x20,0x85,0x52,0xBB,0x9E,0xD5,0x29,0x07,0x70,0x96,0x96,0x6D,
724 0x67,0x0C,0x35,0x4E,0x4A,0xBC,0x98,0x04,0xF1,0x74,0x6C,0x08,
725 0xCA,0x18,0x21,0x7C,0x32,0x90,0x5E,0x46,0x2E,0x36,0xCE,0x3B,
726 0xE3,0x9E,0x77,0x2C,0x18,0x0E,0x86,0x03,0x9B,0x27,0x83,0xA2,
727 0xEC,0x07,0xA2,0x8F,0xB5,0xC5,0x5D,0xF0,0x6F,0x4C,0x52,0xC9,
728 0xDE,0x2B,0xCB,0xF6,0x95,0x58,0x17,0x18,0x39,0x95,0x49,0x7C,
729 0xEA,0x95,0x6A,0xE5,0x15,0xD2,0x26,0x18,0x98,0xFA,0x05,0x10,
730 0x15,0x72,0x8E,0x5A,0x8A,0xAC,0xAA,0x68,0xFF,0xFF,0xFF,0xFF,
731 0xFF,0xFF,0xFF,0xFF,
732 };
733#endif
734 DH *dh = DH_new();
735 if (dh) {
736#if OPENSSL_VERSION_NUMBER >= 0x0090801fL
737 dh->p = get_rfc3526_prime_2048(NULL);
738#else
739 dh->p = BN_bin2bn(rfc_3526_prime_2048, sizeof rfc_3526_prime_2048, NULL);
740#endif
741 /* See RFC 3526, Section 3 "2048-bit MODP Group"
742 for the reason why 2 is used as generator.
743 */
744 BN_dec2bn(&dh->g, "2");
745 if (!dh->p || !dh->g) {
746 DH_free(dh);
747 dh = NULL;
748 }
749 }
750 return dh;
751}
752
753static DH *ssl_get_dh_4096(void)
754{
755#if OPENSSL_VERSION_NUMBER < 0x0090801fL
756 static const unsigned char rfc_3526_prime_4096[] = {
757 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xC9,0x0F,0xDA,0xA2,
758 0x21,0x68,0xC2,0x34,0xC4,0xC6,0x62,0x8B,0x80,0xDC,0x1C,0xD1,
759 0x29,0x02,0x4E,0x08,0x8A,0x67,0xCC,0x74,0x02,0x0B,0xBE,0xA6,
760 0x3B,0x13,0x9B,0x22,0x51,0x4A,0x08,0x79,0x8E,0x34,0x04,0xDD,
761 0xEF,0x95,0x19,0xB3,0xCD,0x3A,0x43,0x1B,0x30,0x2B,0x0A,0x6D,
762 0xF2,0x5F,0x14,0x37,0x4F,0xE1,0x35,0x6D,0x6D,0x51,0xC2,0x45,
763 0xE4,0x85,0xB5,0x76,0x62,0x5E,0x7E,0xC6,0xF4,0x4C,0x42,0xE9,
764 0xA6,0x37,0xED,0x6B,0x0B,0xFF,0x5C,0xB6,0xF4,0x06,0xB7,0xED,
765 0xEE,0x38,0x6B,0xFB,0x5A,0x89,0x9F,0xA5,0xAE,0x9F,0x24,0x11,
766 0x7C,0x4B,0x1F,0xE6,0x49,0x28,0x66,0x51,0xEC,0xE4,0x5B,0x3D,
767 0xC2,0x00,0x7C,0xB8,0xA1,0x63,0xBF,0x05,0x98,0xDA,0x48,0x36,
768 0x1C,0x55,0xD3,0x9A,0x69,0x16,0x3F,0xA8,0xFD,0x24,0xCF,0x5F,
769 0x83,0x65,0x5D,0x23,0xDC,0xA3,0xAD,0x96,0x1C,0x62,0xF3,0x56,
770 0x20,0x85,0x52,0xBB,0x9E,0xD5,0x29,0x07,0x70,0x96,0x96,0x6D,
771 0x67,0x0C,0x35,0x4E,0x4A,0xBC,0x98,0x04,0xF1,0x74,0x6C,0x08,
772 0xCA,0x18,0x21,0x7C,0x32,0x90,0x5E,0x46,0x2E,0x36,0xCE,0x3B,
773 0xE3,0x9E,0x77,0x2C,0x18,0x0E,0x86,0x03,0x9B,0x27,0x83,0xA2,
774 0xEC,0x07,0xA2,0x8F,0xB5,0xC5,0x5D,0xF0,0x6F,0x4C,0x52,0xC9,
775 0xDE,0x2B,0xCB,0xF6,0x95,0x58,0x17,0x18,0x39,0x95,0x49,0x7C,
776 0xEA,0x95,0x6A,0xE5,0x15,0xD2,0x26,0x18,0x98,0xFA,0x05,0x10,
777 0x15,0x72,0x8E,0x5A,0x8A,0xAA,0xC4,0x2D,0xAD,0x33,0x17,0x0D,
778 0x04,0x50,0x7A,0x33,0xA8,0x55,0x21,0xAB,0xDF,0x1C,0xBA,0x64,
779 0xEC,0xFB,0x85,0x04,0x58,0xDB,0xEF,0x0A,0x8A,0xEA,0x71,0x57,
780 0x5D,0x06,0x0C,0x7D,0xB3,0x97,0x0F,0x85,0xA6,0xE1,0xE4,0xC7,
781 0xAB,0xF5,0xAE,0x8C,0xDB,0x09,0x33,0xD7,0x1E,0x8C,0x94,0xE0,
782 0x4A,0x25,0x61,0x9D,0xCE,0xE3,0xD2,0x26,0x1A,0xD2,0xEE,0x6B,
783 0xF1,0x2F,0xFA,0x06,0xD9,0x8A,0x08,0x64,0xD8,0x76,0x02,0x73,
784 0x3E,0xC8,0x6A,0x64,0x52,0x1F,0x2B,0x18,0x17,0x7B,0x20,0x0C,
785 0xBB,0xE1,0x17,0x57,0x7A,0x61,0x5D,0x6C,0x77,0x09,0x88,0xC0,
786 0xBA,0xD9,0x46,0xE2,0x08,0xE2,0x4F,0xA0,0x74,0xE5,0xAB,0x31,
787 0x43,0xDB,0x5B,0xFC,0xE0,0xFD,0x10,0x8E,0x4B,0x82,0xD1,0x20,
788 0xA9,0x21,0x08,0x01,0x1A,0x72,0x3C,0x12,0xA7,0x87,0xE6,0xD7,
789 0x88,0x71,0x9A,0x10,0xBD,0xBA,0x5B,0x26,0x99,0xC3,0x27,0x18,
790 0x6A,0xF4,0xE2,0x3C,0x1A,0x94,0x68,0x34,0xB6,0x15,0x0B,0xDA,
791 0x25,0x83,0xE9,0xCA,0x2A,0xD4,0x4C,0xE8,0xDB,0xBB,0xC2,0xDB,
792 0x04,0xDE,0x8E,0xF9,0x2E,0x8E,0xFC,0x14,0x1F,0xBE,0xCA,0xA6,
793 0x28,0x7C,0x59,0x47,0x4E,0x6B,0xC0,0x5D,0x99,0xB2,0x96,0x4F,
794 0xA0,0x90,0xC3,0xA2,0x23,0x3B,0xA1,0x86,0x51,0x5B,0xE7,0xED,
795 0x1F,0x61,0x29,0x70,0xCE,0xE2,0xD7,0xAF,0xB8,0x1B,0xDD,0x76,
796 0x21,0x70,0x48,0x1C,0xD0,0x06,0x91,0x27,0xD5,0xB0,0x5A,0xA9,
797 0x93,0xB4,0xEA,0x98,0x8D,0x8F,0xDD,0xC1,0x86,0xFF,0xB7,0xDC,
798 0x90,0xA6,0xC0,0x8F,0x4D,0xF4,0x35,0xC9,0x34,0x06,0x31,0x99,
799 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
800 };
801#endif
802 DH *dh = DH_new();
803 if (dh) {
804#if OPENSSL_VERSION_NUMBER >= 0x0090801fL
805 dh->p = get_rfc3526_prime_4096(NULL);
806#else
807 dh->p = BN_bin2bn(rfc_3526_prime_4096, sizeof rfc_3526_prime_4096, NULL);
808#endif
809 /* See RFC 3526, Section 5 "4096-bit MODP Group"
810 for the reason why 2 is used as generator.
811 */
812 BN_dec2bn(&dh->g, "2");
813 if (!dh->p || !dh->g) {
814 DH_free(dh);
815 dh = NULL;
816 }
817 }
818 return dh;
819}
820
821static DH *ssl_get_dh_8192(void)
822{
823#if OPENSSL_VERSION_NUMBER < 0x0090801fL
824 static const unsigned char rfc_3526_prime_8192[] = {
825 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xC9,0x0F,0xDA,0xA2,
826 0x21,0x68,0xC2,0x34,0xC4,0xC6,0x62,0x8B,0x80,0xDC,0x1C,0xD1,
827 0x29,0x02,0x4E,0x08,0x8A,0x67,0xCC,0x74,0x02,0x0B,0xBE,0xA6,
828 0x3B,0x13,0x9B,0x22,0x51,0x4A,0x08,0x79,0x8E,0x34,0x04,0xDD,
829 0xEF,0x95,0x19,0xB3,0xCD,0x3A,0x43,0x1B,0x30,0x2B,0x0A,0x6D,
830 0xF2,0x5F,0x14,0x37,0x4F,0xE1,0x35,0x6D,0x6D,0x51,0xC2,0x45,
831 0xE4,0x85,0xB5,0x76,0x62,0x5E,0x7E,0xC6,0xF4,0x4C,0x42,0xE9,
832 0xA6,0x37,0xED,0x6B,0x0B,0xFF,0x5C,0xB6,0xF4,0x06,0xB7,0xED,
833 0xEE,0x38,0x6B,0xFB,0x5A,0x89,0x9F,0xA5,0xAE,0x9F,0x24,0x11,
834 0x7C,0x4B,0x1F,0xE6,0x49,0x28,0x66,0x51,0xEC,0xE4,0x5B,0x3D,
835 0xC2,0x00,0x7C,0xB8,0xA1,0x63,0xBF,0x05,0x98,0xDA,0x48,0x36,
836 0x1C,0x55,0xD3,0x9A,0x69,0x16,0x3F,0xA8,0xFD,0x24,0xCF,0x5F,
837 0x83,0x65,0x5D,0x23,0xDC,0xA3,0xAD,0x96,0x1C,0x62,0xF3,0x56,
838 0x20,0x85,0x52,0xBB,0x9E,0xD5,0x29,0x07,0x70,0x96,0x96,0x6D,
839 0x67,0x0C,0x35,0x4E,0x4A,0xBC,0x98,0x04,0xF1,0x74,0x6C,0x08,
840 0xCA,0x18,0x21,0x7C,0x32,0x90,0x5E,0x46,0x2E,0x36,0xCE,0x3B,
841 0xE3,0x9E,0x77,0x2C,0x18,0x0E,0x86,0x03,0x9B,0x27,0x83,0xA2,
842 0xEC,0x07,0xA2,0x8F,0xB5,0xC5,0x5D,0xF0,0x6F,0x4C,0x52,0xC9,
843 0xDE,0x2B,0xCB,0xF6,0x95,0x58,0x17,0x18,0x39,0x95,0x49,0x7C,
844 0xEA,0x95,0x6A,0xE5,0x15,0xD2,0x26,0x18,0x98,0xFA,0x05,0x10,
845 0x15,0x72,0x8E,0x5A,0x8A,0xAA,0xC4,0x2D,0xAD,0x33,0x17,0x0D,
846 0x04,0x50,0x7A,0x33,0xA8,0x55,0x21,0xAB,0xDF,0x1C,0xBA,0x64,
847 0xEC,0xFB,0x85,0x04,0x58,0xDB,0xEF,0x0A,0x8A,0xEA,0x71,0x57,
848 0x5D,0x06,0x0C,0x7D,0xB3,0x97,0x0F,0x85,0xA6,0xE1,0xE4,0xC7,
849 0xAB,0xF5,0xAE,0x8C,0xDB,0x09,0x33,0xD7,0x1E,0x8C,0x94,0xE0,
850 0x4A,0x25,0x61,0x9D,0xCE,0xE3,0xD2,0x26,0x1A,0xD2,0xEE,0x6B,
851 0xF1,0x2F,0xFA,0x06,0xD9,0x8A,0x08,0x64,0xD8,0x76,0x02,0x73,
852 0x3E,0xC8,0x6A,0x64,0x52,0x1F,0x2B,0x18,0x17,0x7B,0x20,0x0C,
853 0xBB,0xE1,0x17,0x57,0x7A,0x61,0x5D,0x6C,0x77,0x09,0x88,0xC0,
854 0xBA,0xD9,0x46,0xE2,0x08,0xE2,0x4F,0xA0,0x74,0xE5,0xAB,0x31,
855 0x43,0xDB,0x5B,0xFC,0xE0,0xFD,0x10,0x8E,0x4B,0x82,0xD1,0x20,
856 0xA9,0x21,0x08,0x01,0x1A,0x72,0x3C,0x12,0xA7,0x87,0xE6,0xD7,
857 0x88,0x71,0x9A,0x10,0xBD,0xBA,0x5B,0x26,0x99,0xC3,0x27,0x18,
858 0x6A,0xF4,0xE2,0x3C,0x1A,0x94,0x68,0x34,0xB6,0x15,0x0B,0xDA,
859 0x25,0x83,0xE9,0xCA,0x2A,0xD4,0x4C,0xE8,0xDB,0xBB,0xC2,0xDB,
860 0x04,0xDE,0x8E,0xF9,0x2E,0x8E,0xFC,0x14,0x1F,0xBE,0xCA,0xA6,
861 0x28,0x7C,0x59,0x47,0x4E,0x6B,0xC0,0x5D,0x99,0xB2,0x96,0x4F,
862 0xA0,0x90,0xC3,0xA2,0x23,0x3B,0xA1,0x86,0x51,0x5B,0xE7,0xED,
863 0x1F,0x61,0x29,0x70,0xCE,0xE2,0xD7,0xAF,0xB8,0x1B,0xDD,0x76,
864 0x21,0x70,0x48,0x1C,0xD0,0x06,0x91,0x27,0xD5,0xB0,0x5A,0xA9,
865 0x93,0xB4,0xEA,0x98,0x8D,0x8F,0xDD,0xC1,0x86,0xFF,0xB7,0xDC,
866 0x90,0xA6,0xC0,0x8F,0x4D,0xF4,0x35,0xC9,0x34,0x02,0x84,0x92,
867 0x36,0xC3,0xFA,0xB4,0xD2,0x7C,0x70,0x26,0xC1,0xD4,0xDC,0xB2,
868 0x60,0x26,0x46,0xDE,0xC9,0x75,0x1E,0x76,0x3D,0xBA,0x37,0xBD,
869 0xF8,0xFF,0x94,0x06,0xAD,0x9E,0x53,0x0E,0xE5,0xDB,0x38,0x2F,
870 0x41,0x30,0x01,0xAE,0xB0,0x6A,0x53,0xED,0x90,0x27,0xD8,0x31,
871 0x17,0x97,0x27,0xB0,0x86,0x5A,0x89,0x18,0xDA,0x3E,0xDB,0xEB,
872 0xCF,0x9B,0x14,0xED,0x44,0xCE,0x6C,0xBA,0xCE,0xD4,0xBB,0x1B,
873 0xDB,0x7F,0x14,0x47,0xE6,0xCC,0x25,0x4B,0x33,0x20,0x51,0x51,
874 0x2B,0xD7,0xAF,0x42,0x6F,0xB8,0xF4,0x01,0x37,0x8C,0xD2,0xBF,
875 0x59,0x83,0xCA,0x01,0xC6,0x4B,0x92,0xEC,0xF0,0x32,0xEA,0x15,
876 0xD1,0x72,0x1D,0x03,0xF4,0x82,0xD7,0xCE,0x6E,0x74,0xFE,0xF6,
877 0xD5,0x5E,0x70,0x2F,0x46,0x98,0x0C,0x82,0xB5,0xA8,0x40,0x31,
878 0x90,0x0B,0x1C,0x9E,0x59,0xE7,0xC9,0x7F,0xBE,0xC7,0xE8,0xF3,
879 0x23,0xA9,0x7A,0x7E,0x36,0xCC,0x88,0xBE,0x0F,0x1D,0x45,0xB7,
880 0xFF,0x58,0x5A,0xC5,0x4B,0xD4,0x07,0xB2,0x2B,0x41,0x54,0xAA,
881 0xCC,0x8F,0x6D,0x7E,0xBF,0x48,0xE1,0xD8,0x14,0xCC,0x5E,0xD2,
882 0x0F,0x80,0x37,0xE0,0xA7,0x97,0x15,0xEE,0xF2,0x9B,0xE3,0x28,
883 0x06,0xA1,0xD5,0x8B,0xB7,0xC5,0xDA,0x76,0xF5,0x50,0xAA,0x3D,
884 0x8A,0x1F,0xBF,0xF0,0xEB,0x19,0xCC,0xB1,0xA3,0x13,0xD5,0x5C,
885 0xDA,0x56,0xC9,0xEC,0x2E,0xF2,0x96,0x32,0x38,0x7F,0xE8,0xD7,
886 0x6E,0x3C,0x04,0x68,0x04,0x3E,0x8F,0x66,0x3F,0x48,0x60,0xEE,
887 0x12,0xBF,0x2D,0x5B,0x0B,0x74,0x74,0xD6,0xE6,0x94,0xF9,0x1E,
888 0x6D,0xBE,0x11,0x59,0x74,0xA3,0x92,0x6F,0x12,0xFE,0xE5,0xE4,
889 0x38,0x77,0x7C,0xB6,0xA9,0x32,0xDF,0x8C,0xD8,0xBE,0xC4,0xD0,
890 0x73,0xB9,0x31,0xBA,0x3B,0xC8,0x32,0xB6,0x8D,0x9D,0xD3,0x00,
891 0x74,0x1F,0xA7,0xBF,0x8A,0xFC,0x47,0xED,0x25,0x76,0xF6,0x93,
892 0x6B,0xA4,0x24,0x66,0x3A,0xAB,0x63,0x9C,0x5A,0xE4,0xF5,0x68,
893 0x34,0x23,0xB4,0x74,0x2B,0xF1,0xC9,0x78,0x23,0x8F,0x16,0xCB,
894 0xE3,0x9D,0x65,0x2D,0xE3,0xFD,0xB8,0xBE,0xFC,0x84,0x8A,0xD9,
895 0x22,0x22,0x2E,0x04,0xA4,0x03,0x7C,0x07,0x13,0xEB,0x57,0xA8,
896 0x1A,0x23,0xF0,0xC7,0x34,0x73,0xFC,0x64,0x6C,0xEA,0x30,0x6B,
897 0x4B,0xCB,0xC8,0x86,0x2F,0x83,0x85,0xDD,0xFA,0x9D,0x4B,0x7F,
898 0xA2,0xC0,0x87,0xE8,0x79,0x68,0x33,0x03,0xED,0x5B,0xDD,0x3A,
899 0x06,0x2B,0x3C,0xF5,0xB3,0xA2,0x78,0xA6,0x6D,0x2A,0x13,0xF8,
900 0x3F,0x44,0xF8,0x2D,0xDF,0x31,0x0E,0xE0,0x74,0xAB,0x6A,0x36,
901 0x45,0x97,0xE8,0x99,0xA0,0x25,0x5D,0xC1,0x64,0xF3,0x1C,0xC5,
902 0x08,0x46,0x85,0x1D,0xF9,0xAB,0x48,0x19,0x5D,0xED,0x7E,0xA1,
903 0xB1,0xD5,0x10,0xBD,0x7E,0xE7,0x4D,0x73,0xFA,0xF3,0x6B,0xC3,
904 0x1E,0xCF,0xA2,0x68,0x35,0x90,0x46,0xF4,0xEB,0x87,0x9F,0x92,
905 0x40,0x09,0x43,0x8B,0x48,0x1C,0x6C,0xD7,0x88,0x9A,0x00,0x2E,
906 0xD5,0xEE,0x38,0x2B,0xC9,0x19,0x0D,0xA6,0xFC,0x02,0x6E,0x47,
907 0x95,0x58,0xE4,0x47,0x56,0x77,0xE9,0xAA,0x9E,0x30,0x50,0xE2,
908 0x76,0x56,0x94,0xDF,0xC8,0x1F,0x56,0xE8,0x80,0xB9,0x6E,0x71,
909 0x60,0xC9,0x80,0xDD,0x98,0xED,0xD3,0xDF,0xFF,0xFF,0xFF,0xFF,
910 0xFF,0xFF,0xFF,0xFF,
911 };
912#endif
913 DH *dh = DH_new();
914 if (dh) {
915#if OPENSSL_VERSION_NUMBER >= 0x0090801fL
916 dh->p = get_rfc3526_prime_8192(NULL);
917#else
918 dh->p = BN_bin2bn(rfc_3526_prime_8192, sizeof rfc_3526_prime_8192, NULL);
919#endif
920 /* See RFC 3526, Section 7 "8192-bit MODP Group"
921 for the reason why 2 is used as generator.
922 */
923 BN_dec2bn(&dh->g, "2");
924 if (!dh->p || !dh->g) {
925 DH_free(dh);
926 dh = NULL;
927 }
928 }
929 return dh;
930}
931
932/* Returns Diffie-Hellman parameters matching the private key length
933 but not exceeding global.tune.ssl_default_dh_param */
934static DH *ssl_get_tmp_dh(SSL *ssl, int export, int keylen)
935{
936 DH *dh = NULL;
937 EVP_PKEY *pkey = SSL_get_privatekey(ssl);
938 int type = pkey ? EVP_PKEY_type(pkey->type) : EVP_PKEY_NONE;
939
940 /* The keylen supplied by OpenSSL can only be 512 or 1024.
941 See ssl3_send_server_key_exchange() in ssl/s3_srvr.c
942 */
943 if (type == EVP_PKEY_RSA || type == EVP_PKEY_DSA) {
944 keylen = EVP_PKEY_bits(pkey);
945 }
946
947 if (keylen > global.tune.ssl_default_dh_param) {
948 keylen = global.tune.ssl_default_dh_param;
949 }
950
951 if (keylen >= 8192) {
952 dh = ssl_get_dh_8192();
953 }
954 else if (keylen >= 4096) {
955 dh = ssl_get_dh_4096();
956 }
957 else if (keylen >= 2048) {
958 dh = ssl_get_dh_2048();
959 }
960 else {
961 dh = ssl_get_dh_1024();
962 }
963
964 return dh;
965}
966
Emeric Bruna4bcd9a2012-09-20 16:19:02 +0200967/* Loads Diffie-Hellman parameter from a file. Returns 1 if loaded, else -1
968 if an error occured, and 0 if parameter not found. */
Willy Tarreau6e774b42014-04-25 21:35:23 +0200969int ssl_sock_load_dh_params(SSL_CTX *ctx, const char *file)
Emeric Bruna4bcd9a2012-09-20 16:19:02 +0200970{
971 int ret = -1;
972 BIO *in;
973 DH *dh = NULL;
974
975 in = BIO_new(BIO_s_file());
976 if (in == NULL)
977 goto end;
978
979 if (BIO_read_filename(in, file) <= 0)
980 goto end;
981
982 dh = PEM_read_bio_DHparams(in, NULL, ctx->default_passwd_callback, ctx->default_passwd_callback_userdata);
Remi Gacognef46cd6e2014-06-12 14:58:40 +0200983 if (dh) {
984 ret = 1;
985 SSL_CTX_set_tmp_dh(ctx, dh);
986 /* Setting ssl default dh param to the size of the static DH params
987 found in the file. This way we know that there is no use
988 complaining later about ssl-default-dh-param not being set. */
989 global.tune.ssl_default_dh_param = DH_size(dh) * 8;
990 }
991 else {
Emeric Brun41fdb3c2013-04-26 11:05:44 +0200992 /* Clear openssl global errors stack */
993 ERR_clear_error();
994
Remi Gacognef46cd6e2014-06-12 14:58:40 +0200995 if (global.tune.ssl_default_dh_param <= 1024) {
996 /* we are limited to DH parameter of 1024 bits anyway */
997 dh = ssl_get_dh_1024();
998 if (dh == NULL)
999 goto end;
Willy Tarreau6e774b42014-04-25 21:35:23 +02001000
Remi Gacognef46cd6e2014-06-12 14:58:40 +02001001 SSL_CTX_set_tmp_dh(ctx, dh);
1002 }
1003 else {
1004 SSL_CTX_set_tmp_dh_callback(ctx, ssl_get_tmp_dh);
1005 }
Willy Tarreau6e774b42014-04-25 21:35:23 +02001006
Emeric Brun41fdb3c2013-04-26 11:05:44 +02001007 ret = 0; /* DH params not found */
Emeric Bruna4bcd9a2012-09-20 16:19:02 +02001008 }
Emeric Brun644cde02012-12-14 11:21:13 +01001009
Emeric Bruna4bcd9a2012-09-20 16:19:02 +02001010end:
1011 if (dh)
1012 DH_free(dh);
1013
1014 if (in)
Emeric Brun41fdb3c2013-04-26 11:05:44 +02001015 BIO_free(in);
Emeric Bruna4bcd9a2012-09-20 16:19:02 +02001016
1017 return ret;
1018}
1019#endif
1020
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +02001021static int ssl_sock_add_cert_sni(SSL_CTX *ctx, struct bind_conf *s, char *name, int order)
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01001022{
1023 struct sni_ctx *sc;
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +02001024 int wild = 0, neg = 0;
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01001025
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +02001026 if (*name == '!') {
1027 neg = 1;
1028 name++;
1029 }
1030 if (*name == '*') {
1031 wild = 1;
1032 name++;
1033 }
1034 /* !* filter is a nop */
1035 if (neg && wild)
1036 return order;
1037 if (*name) {
1038 int j, len;
1039 len = strlen(name);
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01001040 sc = malloc(sizeof(struct sni_ctx) + len + 1);
1041 for (j = 0; j < len; j++)
1042 sc->name.key[j] = tolower(name[j]);
1043 sc->name.key[len] = 0;
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01001044 sc->ctx = ctx;
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +02001045 sc->order = order++;
1046 sc->neg = neg;
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01001047 if (wild)
1048 ebst_insert(&s->sni_w_ctx, &sc->name);
1049 else
1050 ebst_insert(&s->sni_ctx, &sc->name);
1051 }
1052 return order;
1053}
1054
Emeric Brunfc0421f2012-09-07 17:30:07 +02001055/* Loads a certificate key and CA chain from a file. Returns 0 on error, -1 if
1056 * an early error happens and the caller must call SSL_CTX_free() by itelf.
1057 */
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +02001058static 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 +02001059{
1060 BIO *in;
1061 X509 *x = NULL, *ca;
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +02001062 int i, err;
Emeric Brunfc0421f2012-09-07 17:30:07 +02001063 int ret = -1;
1064 int order = 0;
1065 X509_NAME *xname;
1066 char *str;
Emeric Brunfc0421f2012-09-07 17:30:07 +02001067#ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME
1068 STACK_OF(GENERAL_NAME) *names;
1069#endif
1070
1071 in = BIO_new(BIO_s_file());
1072 if (in == NULL)
1073 goto end;
1074
1075 if (BIO_read_filename(in, file) <= 0)
1076 goto end;
1077
1078 x = PEM_read_bio_X509_AUX(in, NULL, ctx->default_passwd_callback, ctx->default_passwd_callback_userdata);
1079 if (x == NULL)
1080 goto end;
1081
Emeric Brun50bcecc2013-04-22 13:05:23 +02001082 if (fcount) {
1083 while (fcount--)
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +02001084 order = ssl_sock_add_cert_sni(ctx, s, sni_filter[fcount], order);
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01001085 }
1086 else {
Emeric Brunfc0421f2012-09-07 17:30:07 +02001087#ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01001088 names = X509_get_ext_d2i(x, NID_subject_alt_name, NULL, NULL);
1089 if (names) {
1090 for (i = 0; i < sk_GENERAL_NAME_num(names); i++) {
1091 GENERAL_NAME *name = sk_GENERAL_NAME_value(names, i);
1092 if (name->type == GEN_DNS) {
1093 if (ASN1_STRING_to_UTF8((unsigned char **)&str, name->d.dNSName) >= 0) {
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +02001094 order = ssl_sock_add_cert_sni(ctx, s, str, order);
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01001095 OPENSSL_free(str);
Emeric Brunfc0421f2012-09-07 17:30:07 +02001096 }
Emeric Brunfc0421f2012-09-07 17:30:07 +02001097 }
1098 }
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01001099 sk_GENERAL_NAME_pop_free(names, GENERAL_NAME_free);
Emeric Brunfc0421f2012-09-07 17:30:07 +02001100 }
Emeric Brunfc0421f2012-09-07 17:30:07 +02001101#endif /* SSL_CTRL_SET_TLSEXT_HOSTNAME */
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01001102 xname = X509_get_subject_name(x);
1103 i = -1;
1104 while ((i = X509_NAME_get_index_by_NID(xname, NID_commonName, i)) != -1) {
1105 X509_NAME_ENTRY *entry = X509_NAME_get_entry(xname, i);
1106 if (ASN1_STRING_to_UTF8((unsigned char **)&str, entry->value) >= 0) {
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +02001107 order = ssl_sock_add_cert_sni(ctx, s, str, order);
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01001108 OPENSSL_free(str);
Emeric Brunfc0421f2012-09-07 17:30:07 +02001109 }
Emeric Brunfc0421f2012-09-07 17:30:07 +02001110 }
1111 }
1112
1113 ret = 0; /* the caller must not free the SSL_CTX argument anymore */
1114 if (!SSL_CTX_use_certificate(ctx, x))
1115 goto end;
1116
1117 if (ctx->extra_certs != NULL) {
1118 sk_X509_pop_free(ctx->extra_certs, X509_free);
1119 ctx->extra_certs = NULL;
1120 }
1121
1122 while ((ca = PEM_read_bio_X509(in, NULL, ctx->default_passwd_callback, ctx->default_passwd_callback_userdata))) {
1123 if (!SSL_CTX_add_extra_chain_cert(ctx, ca)) {
1124 X509_free(ca);
1125 goto end;
1126 }
1127 }
1128
1129 err = ERR_get_error();
1130 if (!err || (ERR_GET_LIB(err) == ERR_LIB_PEM && ERR_GET_REASON(err) == PEM_R_NO_START_LINE)) {
1131 /* we successfully reached the last cert in the file */
1132 ret = 1;
1133 }
1134 ERR_clear_error();
1135
1136end:
1137 if (x)
1138 X509_free(x);
1139
1140 if (in)
1141 BIO_free(in);
1142
1143 return ret;
1144}
1145
Emeric Brun50bcecc2013-04-22 13:05:23 +02001146static 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 +02001147{
1148 int ret;
1149 SSL_CTX *ctx;
1150
1151 ctx = SSL_CTX_new(SSLv23_server_method());
1152 if (!ctx) {
Willy Tarreaueb6cead2012-09-20 19:43:14 +02001153 memprintf(err, "%sunable to allocate SSL context for cert '%s'.\n",
1154 err && *err ? *err : "", path);
Emeric Brunfc0421f2012-09-07 17:30:07 +02001155 return 1;
1156 }
1157
1158 if (SSL_CTX_use_PrivateKey_file(ctx, path, SSL_FILETYPE_PEM) <= 0) {
Willy Tarreaueb6cead2012-09-20 19:43:14 +02001159 memprintf(err, "%sunable to load SSL private key from PEM file '%s'.\n",
1160 err && *err ? *err : "", path);
Emeric Brunfc0421f2012-09-07 17:30:07 +02001161 SSL_CTX_free(ctx);
1162 return 1;
1163 }
1164
Emeric Brun50bcecc2013-04-22 13:05:23 +02001165 ret = ssl_sock_load_cert_chain_file(ctx, path, bind_conf, sni_filter, fcount);
Emeric Brunfc0421f2012-09-07 17:30:07 +02001166 if (ret <= 0) {
Willy Tarreaueb6cead2012-09-20 19:43:14 +02001167 memprintf(err, "%sunable to load SSL certificate from PEM file '%s'.\n",
1168 err && *err ? *err : "", path);
Emeric Brunfc0421f2012-09-07 17:30:07 +02001169 if (ret < 0) /* serious error, must do that ourselves */
1170 SSL_CTX_free(ctx);
1171 return 1;
1172 }
Emeric Brun61694ab2012-10-26 13:35:33 +02001173
1174 if (SSL_CTX_check_private_key(ctx) <= 0) {
1175 memprintf(err, "%sinconsistencies between private key and certificate loaded from PEM file '%s'.\n",
1176 err && *err ? *err : "", path);
1177 return 1;
1178 }
1179
Emeric Brunfc0421f2012-09-07 17:30:07 +02001180 /* we must not free the SSL_CTX anymore below, since it's already in
1181 * the tree, so it will be discovered and cleaned in time.
1182 */
Emeric Bruna4bcd9a2012-09-20 16:19:02 +02001183#ifndef OPENSSL_NO_DH
1184 ret = ssl_sock_load_dh_params(ctx, path);
1185 if (ret < 0) {
1186 if (err)
1187 memprintf(err, "%sunable to load DH parameters from file '%s'.\n",
1188 *err ? *err : "", path);
1189 return 1;
1190 }
1191#endif
1192
Emeric Brun4147b2e2014-06-16 18:36:30 +02001193#ifdef SSL_CTRL_SET_TLSEXT_STATUS_REQ_CB
1194 ret = ssl_sock_load_ocsp(ctx, path);
1195 if (ret < 0) {
1196 if (err)
1197 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",
1198 *err ? *err : "", path);
1199 return 1;
1200 }
1201#endif
1202
Emeric Brunfc0421f2012-09-07 17:30:07 +02001203#ifndef SSL_CTRL_SET_TLSEXT_HOSTNAME
Willy Tarreau2a65ff02012-09-13 17:54:29 +02001204 if (bind_conf->default_ctx) {
Willy Tarreaueb6cead2012-09-20 19:43:14 +02001205 memprintf(err, "%sthis version of openssl cannot load multiple SSL certificates.\n",
1206 err && *err ? *err : "");
Emeric Brunfc0421f2012-09-07 17:30:07 +02001207 return 1;
1208 }
1209#endif
Willy Tarreau2a65ff02012-09-13 17:54:29 +02001210 if (!bind_conf->default_ctx)
1211 bind_conf->default_ctx = ctx;
Emeric Brunfc0421f2012-09-07 17:30:07 +02001212
1213 return 0;
1214}
1215
Willy Tarreau79eeafa2012-09-14 07:53:05 +02001216int ssl_sock_load_cert(char *path, struct bind_conf *bind_conf, struct proxy *curproxy, char **err)
Emeric Brunfc0421f2012-09-07 17:30:07 +02001217{
1218 struct dirent *de;
1219 DIR *dir;
1220 struct stat buf;
Willy Tarreauee2663b2012-12-06 11:36:59 +01001221 char *end;
1222 char fp[MAXPATHLEN+1];
Emeric Brunfc0421f2012-09-07 17:30:07 +02001223 int cfgerr = 0;
1224
1225 if (!(dir = opendir(path)))
Emeric Brun50bcecc2013-04-22 13:05:23 +02001226 return ssl_sock_load_cert_file(path, bind_conf, curproxy, NULL, 0, err);
Emeric Brunfc0421f2012-09-07 17:30:07 +02001227
1228 /* strip trailing slashes, including first one */
1229 for (end = path + strlen(path) - 1; end >= path && *end == '/'; end--)
1230 *end = 0;
1231
Emeric Brunfc0421f2012-09-07 17:30:07 +02001232 while ((de = readdir(dir))) {
Emeric Brun2aab7222014-06-18 18:15:09 +02001233 end = strrchr(de->d_name, '.');
1234 if (end && (!strcmp(end, ".issuer") || !strcmp(end, ".ocsp")))
1235 continue;
1236
Willy Tarreauee2663b2012-12-06 11:36:59 +01001237 snprintf(fp, sizeof(fp), "%s/%s", path, de->d_name);
Emeric Brunfc0421f2012-09-07 17:30:07 +02001238 if (stat(fp, &buf) != 0) {
Willy Tarreaueb6cead2012-09-20 19:43:14 +02001239 memprintf(err, "%sunable to stat SSL certificate from file '%s' : %s.\n",
1240 err && *err ? *err : "", fp, strerror(errno));
Emeric Brunfc0421f2012-09-07 17:30:07 +02001241 cfgerr++;
1242 continue;
1243 }
1244 if (!S_ISREG(buf.st_mode))
1245 continue;
Emeric Brun50bcecc2013-04-22 13:05:23 +02001246 cfgerr += ssl_sock_load_cert_file(fp, bind_conf, curproxy, NULL, 0, err);
Emeric Brunfc0421f2012-09-07 17:30:07 +02001247 }
Emeric Brunfc0421f2012-09-07 17:30:07 +02001248 closedir(dir);
1249 return cfgerr;
1250}
1251
Thierry Fournier383085f2013-01-24 14:15:43 +01001252/* Make sure openssl opens /dev/urandom before the chroot. The work is only
1253 * done once. Zero is returned if the operation fails. No error is returned
1254 * if the random is said as not implemented, because we expect that openssl
1255 * will use another method once needed.
1256 */
1257static int ssl_initialize_random()
1258{
1259 unsigned char random;
1260 static int random_initialized = 0;
1261
1262 if (!random_initialized && RAND_bytes(&random, 1) != 0)
1263 random_initialized = 1;
1264
1265 return random_initialized;
1266}
1267
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01001268int ssl_sock_load_cert_list_file(char *file, struct bind_conf *bind_conf, struct proxy *curproxy, char **err)
1269{
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +02001270 char thisline[LINESIZE];
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01001271 FILE *f;
1272 int linenum = 0;
1273 int cfgerr = 0;
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01001274
Willy Tarreauad1731d2013-04-02 17:35:58 +02001275 if ((f = fopen(file, "r")) == NULL) {
1276 memprintf(err, "cannot open file '%s' : %s", file, strerror(errno));
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01001277 return 1;
Willy Tarreauad1731d2013-04-02 17:35:58 +02001278 }
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01001279
1280 while (fgets(thisline, sizeof(thisline), f) != NULL) {
1281 int arg;
Emeric Brun50bcecc2013-04-22 13:05:23 +02001282 int newarg;
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01001283 char *end;
1284 char *args[MAX_LINE_ARGS + 1];
1285 char *line = thisline;
1286
1287 linenum++;
1288 end = line + strlen(line);
1289 if (end-line == sizeof(thisline)-1 && *(end-1) != '\n') {
1290 /* Check if we reached the limit and the last char is not \n.
1291 * Watch out for the last line without the terminating '\n'!
1292 */
Willy Tarreauad1731d2013-04-02 17:35:58 +02001293 memprintf(err, "line %d too long in file '%s', limit is %d characters",
1294 linenum, file, (int)sizeof(thisline)-1);
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01001295 cfgerr = 1;
Willy Tarreauad1731d2013-04-02 17:35:58 +02001296 break;
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01001297 }
1298
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01001299 arg = 0;
Emeric Brun50bcecc2013-04-22 13:05:23 +02001300 newarg = 1;
1301 while (*line) {
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01001302 if (*line == '#' || *line == '\n' || *line == '\r') {
1303 /* end of string, end of loop */
1304 *line = 0;
1305 break;
1306 }
1307 else if (isspace(*line)) {
Emeric Brun50bcecc2013-04-22 13:05:23 +02001308 newarg = 1;
1309 *line = 0;
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01001310 }
Emeric Brun50bcecc2013-04-22 13:05:23 +02001311 else if (newarg) {
1312 if (arg == MAX_LINE_ARGS) {
1313 memprintf(err, "too many args on line %d in file '%s'.",
1314 linenum, file);
1315 cfgerr = 1;
1316 break;
1317 }
1318 newarg = 0;
1319 args[arg++] = line;
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01001320 }
Emeric Brun50bcecc2013-04-22 13:05:23 +02001321 line++;
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01001322 }
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +02001323 if (cfgerr)
1324 break;
Willy Tarreauad1731d2013-04-02 17:35:58 +02001325
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01001326 /* empty line */
Emeric Brun50bcecc2013-04-22 13:05:23 +02001327 if (!arg)
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01001328 continue;
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01001329
Emeric Brun50bcecc2013-04-22 13:05:23 +02001330 cfgerr = ssl_sock_load_cert_file(args[0], bind_conf, curproxy, &args[1], arg-1, err);
Willy Tarreauad1731d2013-04-02 17:35:58 +02001331 if (cfgerr) {
1332 memprintf(err, "error processing line %d in file '%s' : %s", linenum, file, *err);
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01001333 break;
Willy Tarreauad1731d2013-04-02 17:35:58 +02001334 }
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01001335 }
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01001336 fclose(f);
1337 return cfgerr;
1338}
1339
Emeric Brunfc0421f2012-09-07 17:30:07 +02001340#ifndef SSL_OP_CIPHER_SERVER_PREFERENCE /* needs OpenSSL >= 0.9.7 */
1341#define SSL_OP_CIPHER_SERVER_PREFERENCE 0
1342#endif
1343
1344#ifndef SSL_OP_NO_SESSION_RESUMPTION_ON_RENEGOTIATION /* needs OpenSSL >= 0.9.7 */
1345#define SSL_OP_NO_SESSION_RESUMPTION_ON_RENEGOTIATION 0
Willy Tarreau7d588ee2012-11-26 18:47:31 +01001346#define SSL_renegotiate_pending(arg) 0
Emeric Brunfc0421f2012-09-07 17:30:07 +02001347#endif
Emeric Brun2b58d042012-09-20 17:10:03 +02001348#ifndef SSL_OP_SINGLE_ECDH_USE /* needs OpenSSL >= 0.9.8 */
1349#define SSL_OP_SINGLE_ECDH_USE 0
1350#endif
Emeric Brun2d0c4822012-10-02 13:45:20 +02001351#ifndef SSL_OP_NO_TICKET /* needs OpenSSL >= 0.9.8 */
1352#define SSL_OP_NO_TICKET 0
1353#endif
Emeric Brunfc0421f2012-09-07 17:30:07 +02001354#ifndef SSL_OP_NO_COMPRESSION /* needs OpenSSL >= 0.9.9 */
1355#define SSL_OP_NO_COMPRESSION 0
1356#endif
Emeric Brunc0ff4922012-09-28 19:37:02 +02001357#ifndef SSL_OP_NO_TLSv1_1 /* needs OpenSSL >= 1.0.1 */
1358#define SSL_OP_NO_TLSv1_1 0
1359#endif
1360#ifndef SSL_OP_NO_TLSv1_2 /* needs OpenSSL >= 1.0.1 */
1361#define SSL_OP_NO_TLSv1_2 0
1362#endif
Emeric Bruna4bcd9a2012-09-20 16:19:02 +02001363#ifndef SSL_OP_SINGLE_DH_USE /* needs OpenSSL >= 0.9.6 */
1364#define SSL_OP_SINGLE_DH_USE 0
1365#endif
Emeric Brun2b58d042012-09-20 17:10:03 +02001366#ifndef SSL_OP_SINGLE_ECDH_USE /* needs OpenSSL >= 1.0.0 */
1367#define SSL_OP_SINGLE_ECDH_USE 0
1368#endif
Emeric Brunfc0421f2012-09-07 17:30:07 +02001369#ifndef SSL_MODE_RELEASE_BUFFERS /* needs OpenSSL >= 1.0.0 */
1370#define SSL_MODE_RELEASE_BUFFERS 0
1371#endif
Remi Gacognef46cd6e2014-06-12 14:58:40 +02001372
Willy Tarreau2a65ff02012-09-13 17:54:29 +02001373int ssl_sock_prepare_ctx(struct bind_conf *bind_conf, SSL_CTX *ctx, struct proxy *curproxy)
Emeric Brunfc0421f2012-09-07 17:30:07 +02001374{
1375 int cfgerr = 0;
Emeric Brun850efd52014-01-29 12:24:34 +01001376 int verify = SSL_VERIFY_NONE;
Remi Gacogneaf5c3da2014-05-19 10:29:58 +02001377 long ssloptions =
Emeric Brunfc0421f2012-09-07 17:30:07 +02001378 SSL_OP_ALL | /* all known workarounds for bugs */
1379 SSL_OP_NO_SSLv2 |
1380 SSL_OP_NO_COMPRESSION |
Emeric Bruna4bcd9a2012-09-20 16:19:02 +02001381 SSL_OP_SINGLE_DH_USE |
Emeric Brun2b58d042012-09-20 17:10:03 +02001382 SSL_OP_SINGLE_ECDH_USE |
Emeric Brun3c4bc6e2012-10-04 18:44:19 +02001383 SSL_OP_NO_SESSION_RESUMPTION_ON_RENEGOTIATION |
1384 SSL_OP_CIPHER_SERVER_PREFERENCE;
Remi Gacogneaf5c3da2014-05-19 10:29:58 +02001385 long sslmode =
Emeric Brunfc0421f2012-09-07 17:30:07 +02001386 SSL_MODE_ENABLE_PARTIAL_WRITE |
1387 SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER |
1388 SSL_MODE_RELEASE_BUFFERS;
Remi Gacognef46cd6e2014-06-12 14:58:40 +02001389 STACK_OF(SSL_CIPHER) * ciphers = NULL;
1390 SSL_CIPHER * cipher = NULL;
Remi Gacognec1eab8c2014-06-12 18:20:11 +02001391 char cipher_description[128];
1392 /* The description of ciphers using an Ephemeral Diffie Hellman key exchange
1393 contains " Kx=DH " or " Kx=DH(". Beware of " Kx=DH/",
1394 which is not ephemeral DH. */
1395 const char dhe_description[] = " Kx=DH ";
1396 const char dhe_export_description[] = " Kx=DH(";
Remi Gacognef46cd6e2014-06-12 14:58:40 +02001397 int idx = 0;
1398 int dhe_found = 0;
Emeric Brunfc0421f2012-09-07 17:30:07 +02001399
Thierry Fournier383085f2013-01-24 14:15:43 +01001400 /* Make sure openssl opens /dev/urandom before the chroot */
1401 if (!ssl_initialize_random()) {
1402 Alert("OpenSSL random data generator initialization failed.\n");
1403 cfgerr++;
1404 }
1405
Emeric Brun89675492012-10-05 13:48:26 +02001406 if (bind_conf->ssl_options & BC_SSL_O_NO_SSLV3)
Emeric Brunfc0421f2012-09-07 17:30:07 +02001407 ssloptions |= SSL_OP_NO_SSLv3;
Emeric Brun89675492012-10-05 13:48:26 +02001408 if (bind_conf->ssl_options & BC_SSL_O_NO_TLSV10)
Emeric Brunfc0421f2012-09-07 17:30:07 +02001409 ssloptions |= SSL_OP_NO_TLSv1;
Emeric Brun89675492012-10-05 13:48:26 +02001410 if (bind_conf->ssl_options & BC_SSL_O_NO_TLSV11)
Emeric Brunc0ff4922012-09-28 19:37:02 +02001411 ssloptions |= SSL_OP_NO_TLSv1_1;
Emeric Brun89675492012-10-05 13:48:26 +02001412 if (bind_conf->ssl_options & BC_SSL_O_NO_TLSV12)
Emeric Brunc0ff4922012-09-28 19:37:02 +02001413 ssloptions |= SSL_OP_NO_TLSv1_2;
Emeric Brun89675492012-10-05 13:48:26 +02001414 if (bind_conf->ssl_options & BC_SSL_O_NO_TLS_TICKETS)
Emeric Brun2d0c4822012-10-02 13:45:20 +02001415 ssloptions |= SSL_OP_NO_TICKET;
Emeric Brun2cb7ae52012-10-05 14:14:21 +02001416 if (bind_conf->ssl_options & BC_SSL_O_USE_SSLV3)
1417 SSL_CTX_set_ssl_version(ctx, SSLv3_server_method());
1418 if (bind_conf->ssl_options & BC_SSL_O_USE_TLSV10)
1419 SSL_CTX_set_ssl_version(ctx, TLSv1_server_method());
1420#if SSL_OP_NO_TLSv1_1
1421 if (bind_conf->ssl_options & BC_SSL_O_USE_TLSV11)
1422 SSL_CTX_set_ssl_version(ctx, TLSv1_1_server_method());
1423#endif
1424#if SSL_OP_NO_TLSv1_2
1425 if (bind_conf->ssl_options & BC_SSL_O_USE_TLSV12)
1426 SSL_CTX_set_ssl_version(ctx, TLSv1_2_server_method());
1427#endif
Emeric Brunfc0421f2012-09-07 17:30:07 +02001428
1429 SSL_CTX_set_options(ctx, ssloptions);
1430 SSL_CTX_set_mode(ctx, sslmode);
Emeric Brun850efd52014-01-29 12:24:34 +01001431 switch (bind_conf->verify) {
1432 case SSL_SOCK_VERIFY_NONE:
1433 verify = SSL_VERIFY_NONE;
1434 break;
1435 case SSL_SOCK_VERIFY_OPTIONAL:
1436 verify = SSL_VERIFY_PEER;
1437 break;
1438 case SSL_SOCK_VERIFY_REQUIRED:
1439 verify = SSL_VERIFY_PEER|SSL_VERIFY_FAIL_IF_NO_PEER_CERT;
1440 break;
1441 }
1442 SSL_CTX_set_verify(ctx, verify, ssl_sock_bind_verifycbk);
1443 if (verify & SSL_VERIFY_PEER) {
Emeric Brunfb510ea2012-10-05 12:00:26 +02001444 if (bind_conf->ca_file) {
Emeric Brund94b3fe2012-09-20 18:23:56 +02001445 /* load CAfile to verify */
Emeric Brunfb510ea2012-10-05 12:00:26 +02001446 if (!SSL_CTX_load_verify_locations(ctx, bind_conf->ca_file, NULL)) {
Emeric Brund94b3fe2012-09-20 18:23:56 +02001447 Alert("Proxy '%s': unable to load CA file '%s' for bind '%s' at [%s:%d].\n",
Emeric Brunfb510ea2012-10-05 12:00:26 +02001448 curproxy->id, bind_conf->ca_file, bind_conf->arg, bind_conf->file, bind_conf->line);
Emeric Brund94b3fe2012-09-20 18:23:56 +02001449 cfgerr++;
1450 }
1451 /* set CA names fo client cert request, function returns void */
Emeric Brunfb510ea2012-10-05 12:00:26 +02001452 SSL_CTX_set_client_CA_list(ctx, SSL_load_client_CA_file(bind_conf->ca_file));
Emeric Brund94b3fe2012-09-20 18:23:56 +02001453 }
Emeric Brun850efd52014-01-29 12:24:34 +01001454 else {
1455 Alert("Proxy '%s': verify is enabled but no CA file specified for bind '%s' at [%s:%d].\n",
1456 curproxy->id, bind_conf->arg, bind_conf->file, bind_conf->line);
1457 cfgerr++;
1458 }
Emeric Brun051cdab2012-10-02 19:25:50 +02001459#ifdef X509_V_FLAG_CRL_CHECK
Emeric Brunfb510ea2012-10-05 12:00:26 +02001460 if (bind_conf->crl_file) {
Emeric Brund94b3fe2012-09-20 18:23:56 +02001461 X509_STORE *store = SSL_CTX_get_cert_store(ctx);
1462
Emeric Brunfb510ea2012-10-05 12:00:26 +02001463 if (!store || !X509_STORE_load_locations(store, bind_conf->crl_file, NULL)) {
Emeric Brund94b3fe2012-09-20 18:23:56 +02001464 Alert("Proxy '%s': unable to configure CRL file '%s' for bind '%s' at [%s:%d].\n",
Emeric Brunfb510ea2012-10-05 12:00:26 +02001465 curproxy->id, bind_conf->ca_file, bind_conf->arg, bind_conf->file, bind_conf->line);
Emeric Brund94b3fe2012-09-20 18:23:56 +02001466 cfgerr++;
1467 }
Emeric Brun561e5742012-10-02 15:20:55 +02001468 else {
1469 X509_STORE_set_flags(store, X509_V_FLAG_CRL_CHECK|X509_V_FLAG_CRL_CHECK_ALL);
1470 }
Emeric Brund94b3fe2012-09-20 18:23:56 +02001471 }
Emeric Brun051cdab2012-10-02 19:25:50 +02001472#endif
Emeric Brun644cde02012-12-14 11:21:13 +01001473 ERR_clear_error();
Emeric Brund94b3fe2012-09-20 18:23:56 +02001474 }
Emeric Brunfc0421f2012-09-07 17:30:07 +02001475
Emeric Brun4f65bff2012-11-16 15:11:00 +01001476 if (global.tune.ssllifetime)
1477 SSL_CTX_set_timeout(ctx, global.tune.ssllifetime);
1478
Emeric Brunfc0421f2012-09-07 17:30:07 +02001479 shared_context_set_cache(ctx);
Willy Tarreau2a65ff02012-09-13 17:54:29 +02001480 if (bind_conf->ciphers &&
1481 !SSL_CTX_set_cipher_list(ctx, bind_conf->ciphers)) {
Emeric Brunfc0421f2012-09-07 17:30:07 +02001482 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 +02001483 curproxy->id, bind_conf->ciphers, bind_conf->arg, bind_conf->file, bind_conf->line);
Emeric Brunfc0421f2012-09-07 17:30:07 +02001484 cfgerr++;
1485 }
1486
Remi Gacognef46cd6e2014-06-12 14:58:40 +02001487 /* If tune.ssl.default-dh-param has not been set and
1488 no static DH params were in the certificate file. */
1489 if (global.tune.ssl_default_dh_param == 0) {
1490 ciphers = ctx->cipher_list;
1491
1492 if (ciphers) {
1493 for (idx = 0; idx < sk_SSL_CIPHER_num(ciphers); idx++) {
1494 cipher = sk_SSL_CIPHER_value(ciphers, idx);
Remi Gacognec1eab8c2014-06-12 18:20:11 +02001495 if (SSL_CIPHER_description(cipher, cipher_description, sizeof (cipher_description)) == cipher_description) {
1496 if (strstr(cipher_description, dhe_description) != NULL ||
1497 strstr(cipher_description, dhe_export_description) != NULL) {
1498 dhe_found = 1;
1499 break;
1500 }
Remi Gacognef46cd6e2014-06-12 14:58:40 +02001501 }
1502 }
1503
1504 if (dhe_found) {
1505 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");
1506 }
1507 }
1508
1509 global.tune.ssl_default_dh_param = 1024;
1510 }
1511
Emeric Brunfc0421f2012-09-07 17:30:07 +02001512 SSL_CTX_set_info_callback(ctx, ssl_sock_infocbk);
Willy Tarreau5cbe4ef2014-05-08 22:45:11 +02001513#if OPENSSL_VERSION_NUMBER >= 0x00907000L
Emeric Brun29f037d2014-04-25 19:05:36 +02001514 SSL_CTX_set_msg_callback(ctx, ssl_sock_msgcbk);
Willy Tarreau5cbe4ef2014-05-08 22:45:11 +02001515#endif
Emeric Brun29f037d2014-04-25 19:05:36 +02001516
Willy Tarreau6c9a3d52012-10-18 18:57:14 +02001517#ifdef OPENSSL_NPN_NEGOTIATED
1518 if (bind_conf->npn_str)
1519 SSL_CTX_set_next_protos_advertised_cb(ctx, ssl_sock_advertise_npn_protos, bind_conf);
1520#endif
Dirkjan Bussink48f1c4e2014-02-13 12:29:42 +01001521#ifdef TLSEXT_TYPE_application_layer_protocol_negotiation
Willy Tarreauab861d32013-04-02 02:30:41 +02001522 if (bind_conf->alpn_str)
Dirkjan Bussink48f1c4e2014-02-13 12:29:42 +01001523 SSL_CTX_set_alpn_select_cb(ctx, ssl_sock_advertise_alpn_protos, bind_conf);
Willy Tarreauab861d32013-04-02 02:30:41 +02001524#endif
Willy Tarreau6c9a3d52012-10-18 18:57:14 +02001525
Emeric Brunfc0421f2012-09-07 17:30:07 +02001526#ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME
1527 SSL_CTX_set_tlsext_servername_callback(ctx, ssl_sock_switchctx_cbk);
Willy Tarreau2a65ff02012-09-13 17:54:29 +02001528 SSL_CTX_set_tlsext_servername_arg(ctx, bind_conf);
Emeric Brunfc0421f2012-09-07 17:30:07 +02001529#endif
Emeric Brun2b58d042012-09-20 17:10:03 +02001530#if defined(SSL_CTX_set_tmp_ecdh) && !defined(OPENSSL_NO_ECDH)
Emeric Brun6924ef82013-03-06 14:08:53 +01001531 {
Emeric Brun2b58d042012-09-20 17:10:03 +02001532 int i;
1533 EC_KEY *ecdh;
1534
Emeric Brun6924ef82013-03-06 14:08:53 +01001535 i = OBJ_sn2nid(bind_conf->ecdhe ? bind_conf->ecdhe : ECDHE_DEFAULT_CURVE);
Emeric Brun2b58d042012-09-20 17:10:03 +02001536 if (!i || ((ecdh = EC_KEY_new_by_curve_name(i)) == NULL)) {
1537 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 +01001538 curproxy->id, bind_conf->ecdhe ? bind_conf->ecdhe : ECDHE_DEFAULT_CURVE,
1539 bind_conf->arg, bind_conf->file, bind_conf->line);
Emeric Brun2b58d042012-09-20 17:10:03 +02001540 cfgerr++;
1541 }
1542 else {
1543 SSL_CTX_set_tmp_ecdh(ctx, ecdh);
1544 EC_KEY_free(ecdh);
1545 }
1546 }
1547#endif
1548
Emeric Brunfc0421f2012-09-07 17:30:07 +02001549 return cfgerr;
1550}
1551
Evan Broderbe554312013-06-27 00:05:25 -07001552static int ssl_sock_srv_hostcheck(const char *pattern, const char *hostname)
1553{
1554 const char *pattern_wildcard, *pattern_left_label_end, *hostname_left_label_end;
1555 size_t prefixlen, suffixlen;
1556
1557 /* Trivial case */
1558 if (strcmp(pattern, hostname) == 0)
1559 return 1;
1560
Evan Broderbe554312013-06-27 00:05:25 -07001561 /* The rest of this logic is based on RFC 6125, section 6.4.3
1562 * (http://tools.ietf.org/html/rfc6125#section-6.4.3) */
1563
Emeric Bruna848dae2013-10-08 11:27:28 +02001564 pattern_wildcard = NULL;
1565 pattern_left_label_end = pattern;
1566 while (*pattern_left_label_end != '.') {
1567 switch (*pattern_left_label_end) {
1568 case 0:
1569 /* End of label not found */
1570 return 0;
1571 case '*':
1572 /* If there is more than one wildcards */
1573 if (pattern_wildcard)
1574 return 0;
1575 pattern_wildcard = pattern_left_label_end;
1576 break;
1577 }
1578 pattern_left_label_end++;
1579 }
1580
1581 /* If it's not trivial and there is no wildcard, it can't
1582 * match */
1583 if (!pattern_wildcard)
Evan Broderbe554312013-06-27 00:05:25 -07001584 return 0;
1585
1586 /* Make sure all labels match except the leftmost */
1587 hostname_left_label_end = strchr(hostname, '.');
1588 if (!hostname_left_label_end
1589 || strcmp(pattern_left_label_end, hostname_left_label_end) != 0)
1590 return 0;
1591
1592 /* Make sure the leftmost label of the hostname is long enough
1593 * that the wildcard can match */
Emeric Brun369da852013-10-08 11:39:35 +02001594 if (hostname_left_label_end - hostname < (pattern_left_label_end - pattern) - 1)
Evan Broderbe554312013-06-27 00:05:25 -07001595 return 0;
1596
1597 /* Finally compare the string on either side of the
1598 * wildcard */
1599 prefixlen = pattern_wildcard - pattern;
1600 suffixlen = pattern_left_label_end - (pattern_wildcard + 1);
Emeric Bruna848dae2013-10-08 11:27:28 +02001601 if ((prefixlen && (memcmp(pattern, hostname, prefixlen) != 0))
1602 || (suffixlen && (memcmp(pattern_wildcard + 1, hostname_left_label_end - suffixlen, suffixlen) != 0)))
Evan Broderbe554312013-06-27 00:05:25 -07001603 return 0;
1604
1605 return 1;
1606}
1607
1608static int ssl_sock_srv_verifycbk(int ok, X509_STORE_CTX *ctx)
1609{
1610 SSL *ssl;
1611 struct connection *conn;
1612 char *servername;
1613
1614 int depth;
1615 X509 *cert;
1616 STACK_OF(GENERAL_NAME) *alt_names;
1617 int i;
1618 X509_NAME *cert_subject;
1619 char *str;
1620
1621 if (ok == 0)
1622 return ok;
1623
1624 ssl = X509_STORE_CTX_get_ex_data(ctx, SSL_get_ex_data_X509_STORE_CTX_idx());
1625 conn = (struct connection *)SSL_get_app_data(ssl);
1626
1627 servername = objt_server(conn->target)->ssl_ctx.verify_host;
1628
1629 /* We only need to verify the CN on the actual server cert,
1630 * not the indirect CAs */
1631 depth = X509_STORE_CTX_get_error_depth(ctx);
1632 if (depth != 0)
1633 return ok;
1634
1635 /* At this point, the cert is *not* OK unless we can find a
1636 * hostname match */
1637 ok = 0;
1638
1639 cert = X509_STORE_CTX_get_current_cert(ctx);
1640 /* It seems like this might happen if verify peer isn't set */
1641 if (!cert)
1642 return ok;
1643
1644 alt_names = X509_get_ext_d2i(cert, NID_subject_alt_name, NULL, NULL);
1645 if (alt_names) {
1646 for (i = 0; !ok && i < sk_GENERAL_NAME_num(alt_names); i++) {
1647 GENERAL_NAME *name = sk_GENERAL_NAME_value(alt_names, i);
1648 if (name->type == GEN_DNS) {
Emeric Bruna33410c2013-09-17 15:47:48 +02001649#if OPENSSL_VERSION_NUMBER < 0x00907000L
1650 if (ASN1_STRING_to_UTF8((unsigned char **)&str, name->d.ia5) >= 0) {
1651#else
Evan Broderbe554312013-06-27 00:05:25 -07001652 if (ASN1_STRING_to_UTF8((unsigned char **)&str, name->d.dNSName) >= 0) {
Emeric Bruna33410c2013-09-17 15:47:48 +02001653#endif
Evan Broderbe554312013-06-27 00:05:25 -07001654 ok = ssl_sock_srv_hostcheck(str, servername);
1655 OPENSSL_free(str);
1656 }
1657 }
1658 }
Emeric Brun4ad50a42013-09-17 15:19:54 +02001659 sk_GENERAL_NAME_pop_free(alt_names, GENERAL_NAME_free);
Evan Broderbe554312013-06-27 00:05:25 -07001660 }
1661
1662 cert_subject = X509_get_subject_name(cert);
1663 i = -1;
1664 while (!ok && (i = X509_NAME_get_index_by_NID(cert_subject, NID_commonName, i)) != -1) {
1665 X509_NAME_ENTRY *entry = X509_NAME_get_entry(cert_subject, i);
1666 if (ASN1_STRING_to_UTF8((unsigned char **)&str, entry->value) >= 0) {
1667 ok = ssl_sock_srv_hostcheck(str, servername);
1668 OPENSSL_free(str);
1669 }
1670 }
1671
1672 return ok;
1673}
1674
Emeric Brun94324a42012-10-11 14:00:19 +02001675/* prepare ssl context from servers options. Returns an error count */
1676int ssl_sock_prepare_srv_ctx(struct server *srv, struct proxy *curproxy)
1677{
1678 int cfgerr = 0;
Remi Gacogneaf5c3da2014-05-19 10:29:58 +02001679 long options =
Emeric Brun94324a42012-10-11 14:00:19 +02001680 SSL_OP_ALL | /* all known workarounds for bugs */
1681 SSL_OP_NO_SSLv2 |
1682 SSL_OP_NO_COMPRESSION;
Remi Gacogneaf5c3da2014-05-19 10:29:58 +02001683 long mode =
Emeric Brun94324a42012-10-11 14:00:19 +02001684 SSL_MODE_ENABLE_PARTIAL_WRITE |
1685 SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER |
1686 SSL_MODE_RELEASE_BUFFERS;
Emeric Brun850efd52014-01-29 12:24:34 +01001687 int verify = SSL_VERIFY_NONE;
Emeric Brun94324a42012-10-11 14:00:19 +02001688
Thierry Fournier383085f2013-01-24 14:15:43 +01001689 /* Make sure openssl opens /dev/urandom before the chroot */
1690 if (!ssl_initialize_random()) {
1691 Alert("OpenSSL random data generator initialization failed.\n");
1692 cfgerr++;
1693 }
1694
Emeric Brun94324a42012-10-11 14:00:19 +02001695 /* Initiate SSL context for current server */
1696 srv->ssl_ctx.reused_sess = NULL;
1697 if (srv->use_ssl)
1698 srv->xprt = &ssl_sock;
1699 if (srv->check.use_ssl)
Simon Horman66183002013-02-23 10:16:43 +09001700 srv->check_common.xprt = &ssl_sock;
Emeric Brun94324a42012-10-11 14:00:19 +02001701
1702 srv->ssl_ctx.ctx = SSL_CTX_new(SSLv23_client_method());
1703 if (!srv->ssl_ctx.ctx) {
1704 Alert("config : %s '%s', server '%s': unable to allocate ssl context.\n",
1705 proxy_type_str(curproxy), curproxy->id,
1706 srv->id);
1707 cfgerr++;
1708 return cfgerr;
1709 }
Emeric Bruna7aa3092012-10-26 12:58:00 +02001710 if (srv->ssl_ctx.client_crt) {
1711 if (SSL_CTX_use_PrivateKey_file(srv->ssl_ctx.ctx, srv->ssl_ctx.client_crt, SSL_FILETYPE_PEM) <= 0) {
1712 Alert("config : %s '%s', server '%s': unable to load SSL private key from PEM file '%s'.\n",
1713 proxy_type_str(curproxy), curproxy->id,
1714 srv->id, srv->ssl_ctx.client_crt);
1715 cfgerr++;
1716 }
1717 else if (SSL_CTX_use_certificate_chain_file(srv->ssl_ctx.ctx, srv->ssl_ctx.client_crt) <= 0) {
1718 Alert("config : %s '%s', server '%s': unable to load ssl certificate from PEM file '%s'.\n",
1719 proxy_type_str(curproxy), curproxy->id,
1720 srv->id, srv->ssl_ctx.client_crt);
1721 cfgerr++;
1722 }
1723 else if (SSL_CTX_check_private_key(srv->ssl_ctx.ctx) <= 0) {
1724 Alert("config : %s '%s', server '%s': inconsistencies between private key and certificate loaded from PEM file '%s'.\n",
1725 proxy_type_str(curproxy), curproxy->id,
1726 srv->id, srv->ssl_ctx.client_crt);
1727 cfgerr++;
1728 }
1729 }
Emeric Brun94324a42012-10-11 14:00:19 +02001730
1731 if (srv->ssl_ctx.options & SRV_SSL_O_NO_SSLV3)
1732 options |= SSL_OP_NO_SSLv3;
1733 if (srv->ssl_ctx.options & SRV_SSL_O_NO_TLSV10)
1734 options |= SSL_OP_NO_TLSv1;
1735 if (srv->ssl_ctx.options & SRV_SSL_O_NO_TLSV11)
1736 options |= SSL_OP_NO_TLSv1_1;
1737 if (srv->ssl_ctx.options & SRV_SSL_O_NO_TLSV12)
1738 options |= SSL_OP_NO_TLSv1_2;
Emeric Brunf9c5c472012-10-11 15:28:34 +02001739 if (srv->ssl_ctx.options & SRV_SSL_O_NO_TLS_TICKETS)
1740 options |= SSL_OP_NO_TICKET;
Emeric Brun94324a42012-10-11 14:00:19 +02001741 if (srv->ssl_ctx.options & SRV_SSL_O_USE_SSLV3)
1742 SSL_CTX_set_ssl_version(srv->ssl_ctx.ctx, SSLv3_client_method());
1743 if (srv->ssl_ctx.options & SRV_SSL_O_USE_TLSV10)
1744 SSL_CTX_set_ssl_version(srv->ssl_ctx.ctx, TLSv1_client_method());
1745#if SSL_OP_NO_TLSv1_1
1746 if (srv->ssl_ctx.options & SRV_SSL_O_USE_TLSV11)
1747 SSL_CTX_set_ssl_version(srv->ssl_ctx.ctx, TLSv1_1_client_method());
1748#endif
1749#if SSL_OP_NO_TLSv1_2
1750 if (srv->ssl_ctx.options & SRV_SSL_O_USE_TLSV12)
1751 SSL_CTX_set_ssl_version(srv->ssl_ctx.ctx, TLSv1_2_client_method());
1752#endif
1753
1754 SSL_CTX_set_options(srv->ssl_ctx.ctx, options);
1755 SSL_CTX_set_mode(srv->ssl_ctx.ctx, mode);
Emeric Brun850efd52014-01-29 12:24:34 +01001756
1757 if (global.ssl_server_verify == SSL_SERVER_VERIFY_REQUIRED)
1758 verify = SSL_VERIFY_PEER;
1759
1760 switch (srv->ssl_ctx.verify) {
1761 case SSL_SOCK_VERIFY_NONE:
1762 verify = SSL_VERIFY_NONE;
1763 break;
1764 case SSL_SOCK_VERIFY_REQUIRED:
1765 verify = SSL_VERIFY_PEER;
1766 break;
1767 }
Evan Broderbe554312013-06-27 00:05:25 -07001768 SSL_CTX_set_verify(srv->ssl_ctx.ctx,
Emeric Brun850efd52014-01-29 12:24:34 +01001769 verify,
Evan Broderbe554312013-06-27 00:05:25 -07001770 srv->ssl_ctx.verify_host ? ssl_sock_srv_verifycbk : NULL);
Emeric Brun850efd52014-01-29 12:24:34 +01001771 if (verify & SSL_VERIFY_PEER) {
Emeric Brunef42d922012-10-11 16:11:36 +02001772 if (srv->ssl_ctx.ca_file) {
1773 /* load CAfile to verify */
1774 if (!SSL_CTX_load_verify_locations(srv->ssl_ctx.ctx, srv->ssl_ctx.ca_file, NULL)) {
Willy Tarreau07ba08b2014-02-16 19:22:08 +01001775 Alert("Proxy '%s', server '%s' [%s:%d] unable to load CA file '%s'.\n",
Emeric Brunef42d922012-10-11 16:11:36 +02001776 curproxy->id, srv->id,
1777 srv->conf.file, srv->conf.line, srv->ssl_ctx.ca_file);
1778 cfgerr++;
1779 }
1780 }
Emeric Brun850efd52014-01-29 12:24:34 +01001781 else {
1782 if (global.ssl_server_verify == SSL_SERVER_VERIFY_REQUIRED)
Willy Tarreau07ba08b2014-02-16 19:22:08 +01001783 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 +01001784 curproxy->id, srv->id,
1785 srv->conf.file, srv->conf.line);
1786 else
Willy Tarreau07ba08b2014-02-16 19:22:08 +01001787 Alert("Proxy '%s', server '%s' [%s:%d] verify is enabled but no CA file specified.\n",
Emeric Brun850efd52014-01-29 12:24:34 +01001788 curproxy->id, srv->id,
1789 srv->conf.file, srv->conf.line);
1790 cfgerr++;
1791 }
Emeric Brunef42d922012-10-11 16:11:36 +02001792#ifdef X509_V_FLAG_CRL_CHECK
1793 if (srv->ssl_ctx.crl_file) {
1794 X509_STORE *store = SSL_CTX_get_cert_store(srv->ssl_ctx.ctx);
1795
1796 if (!store || !X509_STORE_load_locations(store, srv->ssl_ctx.crl_file, NULL)) {
Willy Tarreau07ba08b2014-02-16 19:22:08 +01001797 Alert("Proxy '%s', server '%s' [%s:%d] unable to configure CRL file '%s'.\n",
Emeric Brunef42d922012-10-11 16:11:36 +02001798 curproxy->id, srv->id,
1799 srv->conf.file, srv->conf.line, srv->ssl_ctx.crl_file);
1800 cfgerr++;
1801 }
1802 else {
1803 X509_STORE_set_flags(store, X509_V_FLAG_CRL_CHECK|X509_V_FLAG_CRL_CHECK_ALL);
1804 }
1805 }
1806#endif
1807 }
1808
Emeric Brun4f65bff2012-11-16 15:11:00 +01001809 if (global.tune.ssllifetime)
1810 SSL_CTX_set_timeout(srv->ssl_ctx.ctx, global.tune.ssllifetime);
1811
Emeric Brun94324a42012-10-11 14:00:19 +02001812 SSL_CTX_set_session_cache_mode(srv->ssl_ctx.ctx, SSL_SESS_CACHE_OFF);
1813 if (srv->ssl_ctx.ciphers &&
1814 !SSL_CTX_set_cipher_list(srv->ssl_ctx.ctx, srv->ssl_ctx.ciphers)) {
1815 Alert("Proxy '%s', server '%s' [%s:%d] : unable to set SSL cipher list to '%s'.\n",
1816 curproxy->id, srv->id,
1817 srv->conf.file, srv->conf.line, srv->ssl_ctx.ciphers);
1818 cfgerr++;
1819 }
1820
1821 return cfgerr;
1822}
1823
Willy Tarreau2a65ff02012-09-13 17:54:29 +02001824/* Walks down the two trees in bind_conf and prepares all certs. The pointer may
Emeric Brunfc0421f2012-09-07 17:30:07 +02001825 * be NULL, in which case nothing is done. Returns the number of errors
1826 * encountered.
1827 */
Willy Tarreau2a65ff02012-09-13 17:54:29 +02001828int ssl_sock_prepare_all_ctx(struct bind_conf *bind_conf, struct proxy *px)
Emeric Brunfc0421f2012-09-07 17:30:07 +02001829{
1830 struct ebmb_node *node;
1831 struct sni_ctx *sni;
1832 int err = 0;
1833
Willy Tarreau2a65ff02012-09-13 17:54:29 +02001834 if (!bind_conf || !bind_conf->is_ssl)
Emeric Brunfc0421f2012-09-07 17:30:07 +02001835 return 0;
1836
Willy Tarreau2a65ff02012-09-13 17:54:29 +02001837 node = ebmb_first(&bind_conf->sni_ctx);
Emeric Brunfc0421f2012-09-07 17:30:07 +02001838 while (node) {
1839 sni = ebmb_entry(node, struct sni_ctx, name);
1840 if (!sni->order) /* only initialize the CTX on its first occurrence */
Willy Tarreau2a65ff02012-09-13 17:54:29 +02001841 err += ssl_sock_prepare_ctx(bind_conf, sni->ctx, px);
Emeric Brunfc0421f2012-09-07 17:30:07 +02001842 node = ebmb_next(node);
1843 }
1844
Willy Tarreau2a65ff02012-09-13 17:54:29 +02001845 node = ebmb_first(&bind_conf->sni_w_ctx);
Emeric Brunfc0421f2012-09-07 17:30:07 +02001846 while (node) {
1847 sni = ebmb_entry(node, struct sni_ctx, name);
1848 if (!sni->order) /* only initialize the CTX on its first occurrence */
Willy Tarreau2a65ff02012-09-13 17:54:29 +02001849 err += ssl_sock_prepare_ctx(bind_conf, sni->ctx, px);
Emeric Brunfc0421f2012-09-07 17:30:07 +02001850 node = ebmb_next(node);
1851 }
1852 return err;
1853}
1854
Willy Tarreau2a65ff02012-09-13 17:54:29 +02001855/* Walks down the two trees in bind_conf and frees all the certs. The pointer may
Emeric Brunfc0421f2012-09-07 17:30:07 +02001856 * be NULL, in which case nothing is done. The default_ctx is nullified too.
1857 */
Willy Tarreau2a65ff02012-09-13 17:54:29 +02001858void ssl_sock_free_all_ctx(struct bind_conf *bind_conf)
Emeric Brunfc0421f2012-09-07 17:30:07 +02001859{
1860 struct ebmb_node *node, *back;
1861 struct sni_ctx *sni;
1862
Willy Tarreau2a65ff02012-09-13 17:54:29 +02001863 if (!bind_conf || !bind_conf->is_ssl)
Emeric Brunfc0421f2012-09-07 17:30:07 +02001864 return;
1865
Willy Tarreau2a65ff02012-09-13 17:54:29 +02001866 node = ebmb_first(&bind_conf->sni_ctx);
Emeric Brunfc0421f2012-09-07 17:30:07 +02001867 while (node) {
1868 sni = ebmb_entry(node, struct sni_ctx, name);
1869 back = ebmb_next(node);
1870 ebmb_delete(node);
1871 if (!sni->order) /* only free the CTX on its first occurrence */
1872 SSL_CTX_free(sni->ctx);
1873 free(sni);
1874 node = back;
1875 }
1876
Willy Tarreau2a65ff02012-09-13 17:54:29 +02001877 node = ebmb_first(&bind_conf->sni_w_ctx);
Emeric Brunfc0421f2012-09-07 17:30:07 +02001878 while (node) {
1879 sni = ebmb_entry(node, struct sni_ctx, name);
1880 back = ebmb_next(node);
1881 ebmb_delete(node);
1882 if (!sni->order) /* only free the CTX on its first occurrence */
1883 SSL_CTX_free(sni->ctx);
1884 free(sni);
1885 node = back;
1886 }
1887
Willy Tarreau2a65ff02012-09-13 17:54:29 +02001888 bind_conf->default_ctx = NULL;
Emeric Brune1f38db2012-09-03 20:36:47 +02001889}
1890
Emeric Brun46591952012-05-18 15:47:34 +02001891/*
1892 * This function is called if SSL * context is not yet allocated. The function
1893 * is designed to be called before any other data-layer operation and sets the
1894 * handshake flag on the connection. It is safe to call it multiple times.
1895 * It returns 0 on success and -1 in error case.
1896 */
1897static int ssl_sock_init(struct connection *conn)
1898{
1899 /* already initialized */
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02001900 if (conn->xprt_ctx)
Emeric Brun46591952012-05-18 15:47:34 +02001901 return 0;
1902
Willy Tarreau3c728722014-01-23 13:50:42 +01001903 if (!conn_ctrl_ready(conn))
Willy Tarreauf79c8172013-10-21 16:30:56 +02001904 return 0;
1905
Willy Tarreau20879a02012-12-03 16:32:10 +01001906 if (global.maxsslconn && sslconns >= global.maxsslconn) {
1907 conn->err_code = CO_ER_SSL_TOO_MANY;
Willy Tarreau403edff2012-09-06 11:58:37 +02001908 return -1;
Willy Tarreau20879a02012-12-03 16:32:10 +01001909 }
Willy Tarreau403edff2012-09-06 11:58:37 +02001910
Emeric Brun46591952012-05-18 15:47:34 +02001911 /* If it is in client mode initiate SSL session
1912 in connect state otherwise accept state */
Willy Tarreau3fdb3662012-11-12 00:42:33 +01001913 if (objt_server(conn->target)) {
Emeric Brun46591952012-05-18 15:47:34 +02001914 /* Alloc a new SSL session ctx */
Willy Tarreau3fdb3662012-11-12 00:42:33 +01001915 conn->xprt_ctx = SSL_new(objt_server(conn->target)->ssl_ctx.ctx);
Willy Tarreau20879a02012-12-03 16:32:10 +01001916 if (!conn->xprt_ctx) {
1917 conn->err_code = CO_ER_SSL_NO_MEM;
Emeric Brun46591952012-05-18 15:47:34 +02001918 return -1;
Willy Tarreau20879a02012-12-03 16:32:10 +01001919 }
Emeric Brun46591952012-05-18 15:47:34 +02001920
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02001921 SSL_set_connect_state(conn->xprt_ctx);
Willy Tarreau3fdb3662012-11-12 00:42:33 +01001922 if (objt_server(conn->target)->ssl_ctx.reused_sess)
1923 SSL_set_session(conn->xprt_ctx, objt_server(conn->target)->ssl_ctx.reused_sess);
Emeric Brun46591952012-05-18 15:47:34 +02001924
1925 /* set fd on SSL session context */
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02001926 SSL_set_fd(conn->xprt_ctx, conn->t.sock.fd);
Emeric Brun46591952012-05-18 15:47:34 +02001927
Evan Broderbe554312013-06-27 00:05:25 -07001928 /* set connection pointer */
1929 SSL_set_app_data(conn->xprt_ctx, conn);
1930
Emeric Brun46591952012-05-18 15:47:34 +02001931 /* leave init state and start handshake */
Willy Tarreau05737472012-09-04 08:03:39 +02001932 conn->flags |= CO_FL_SSL_WAIT_HS | CO_FL_WAIT_L6_CONN;
Willy Tarreau403edff2012-09-06 11:58:37 +02001933
1934 sslconns++;
Willy Tarreau71b734c2014-01-28 15:19:44 +01001935 totalsslconns++;
Emeric Brun46591952012-05-18 15:47:34 +02001936 return 0;
1937 }
Willy Tarreau3fdb3662012-11-12 00:42:33 +01001938 else if (objt_listener(conn->target)) {
Emeric Brun46591952012-05-18 15:47:34 +02001939 /* Alloc a new SSL session ctx */
Willy Tarreau3fdb3662012-11-12 00:42:33 +01001940 conn->xprt_ctx = SSL_new(objt_listener(conn->target)->bind_conf->default_ctx);
Willy Tarreau20879a02012-12-03 16:32:10 +01001941 if (!conn->xprt_ctx) {
1942 conn->err_code = CO_ER_SSL_NO_MEM;
Emeric Brun46591952012-05-18 15:47:34 +02001943 return -1;
Willy Tarreau20879a02012-12-03 16:32:10 +01001944 }
Emeric Brun46591952012-05-18 15:47:34 +02001945
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02001946 SSL_set_accept_state(conn->xprt_ctx);
Emeric Brun46591952012-05-18 15:47:34 +02001947
1948 /* set fd on SSL session context */
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02001949 SSL_set_fd(conn->xprt_ctx, conn->t.sock.fd);
Emeric Brun46591952012-05-18 15:47:34 +02001950
Emeric Brune1f38db2012-09-03 20:36:47 +02001951 /* set connection pointer */
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02001952 SSL_set_app_data(conn->xprt_ctx, conn);
Emeric Brune1f38db2012-09-03 20:36:47 +02001953
Emeric Brun46591952012-05-18 15:47:34 +02001954 /* leave init state and start handshake */
Willy Tarreau05737472012-09-04 08:03:39 +02001955 conn->flags |= CO_FL_SSL_WAIT_HS | CO_FL_WAIT_L6_CONN;
Willy Tarreau403edff2012-09-06 11:58:37 +02001956
1957 sslconns++;
Willy Tarreau71b734c2014-01-28 15:19:44 +01001958 totalsslconns++;
Emeric Brun46591952012-05-18 15:47:34 +02001959 return 0;
1960 }
1961 /* don't know how to handle such a target */
Willy Tarreau20879a02012-12-03 16:32:10 +01001962 conn->err_code = CO_ER_SSL_NO_TARGET;
Emeric Brun46591952012-05-18 15:47:34 +02001963 return -1;
1964}
1965
1966
1967/* This is the callback which is used when an SSL handshake is pending. It
1968 * updates the FD status if it wants some polling before being called again.
1969 * It returns 0 if it fails in a fatal way or needs to poll to go further,
1970 * otherwise it returns non-zero and removes itself from the connection's
1971 * flags (the bit is provided in <flag> by the caller).
1972 */
1973int ssl_sock_handshake(struct connection *conn, unsigned int flag)
1974{
1975 int ret;
1976
Willy Tarreau3c728722014-01-23 13:50:42 +01001977 if (!conn_ctrl_ready(conn))
Willy Tarreauf79c8172013-10-21 16:30:56 +02001978 return 0;
1979
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02001980 if (!conn->xprt_ctx)
Emeric Brun46591952012-05-18 15:47:34 +02001981 goto out_error;
1982
Emeric Brun674b7432012-11-08 19:21:55 +01001983 /* If we use SSL_do_handshake to process a reneg initiated by
1984 * the remote peer, it sometimes returns SSL_ERROR_SSL.
1985 * Usually SSL_write and SSL_read are used and process implicitly
1986 * the reneg handshake.
1987 * Here we use SSL_peek as a workaround for reneg.
1988 */
1989 if ((conn->flags & CO_FL_CONNECTED) && SSL_renegotiate_pending(conn->xprt_ctx)) {
1990 char c;
1991
1992 ret = SSL_peek(conn->xprt_ctx, &c, 1);
1993 if (ret <= 0) {
1994 /* handshake may have not been completed, let's find why */
1995 ret = SSL_get_error(conn->xprt_ctx, ret);
1996 if (ret == SSL_ERROR_WANT_WRITE) {
1997 /* SSL handshake needs to write, L4 connection may not be ready */
1998 __conn_sock_stop_recv(conn);
Willy Tarreaue1f50c42014-01-22 20:02:06 +01001999 __conn_sock_want_send(conn);
2000 fd_cant_send(conn->t.sock.fd);
Emeric Brun674b7432012-11-08 19:21:55 +01002001 return 0;
2002 }
2003 else if (ret == SSL_ERROR_WANT_READ) {
2004 /* handshake may have been completed but we have
2005 * no more data to read.
2006 */
2007 if (!SSL_renegotiate_pending(conn->xprt_ctx)) {
2008 ret = 1;
2009 goto reneg_ok;
2010 }
2011 /* SSL handshake needs to read, L4 connection is ready */
2012 if (conn->flags & CO_FL_WAIT_L4_CONN)
2013 conn->flags &= ~CO_FL_WAIT_L4_CONN;
2014 __conn_sock_stop_send(conn);
Willy Tarreaue1f50c42014-01-22 20:02:06 +01002015 __conn_sock_want_recv(conn);
2016 fd_cant_recv(conn->t.sock.fd);
Emeric Brun674b7432012-11-08 19:21:55 +01002017 return 0;
2018 }
2019 else if (ret == SSL_ERROR_SYSCALL) {
2020 /* if errno is null, then connection was successfully established */
2021 if (!errno && conn->flags & CO_FL_WAIT_L4_CONN)
2022 conn->flags &= ~CO_FL_WAIT_L4_CONN;
Willy Tarreau20879a02012-12-03 16:32:10 +01002023 if (!conn->err_code) {
Emeric Brun29f037d2014-04-25 19:05:36 +02002024 if (!((SSL *)conn->xprt_ctx)->packet_length) {
2025 if (!errno) {
2026 if (conn->xprt_st & SSL_SOCK_RECV_HEARTBEAT)
2027 conn->err_code = CO_ER_SSL_HANDSHAKE_HB;
2028 else
2029 conn->err_code = CO_ER_SSL_EMPTY;
2030 }
2031 else {
2032 if (conn->xprt_st & SSL_SOCK_RECV_HEARTBEAT)
2033 conn->err_code = CO_ER_SSL_HANDSHAKE_HB;
2034 else
2035 conn->err_code = CO_ER_SSL_ABORT;
2036 }
2037 }
2038 else {
2039 if (conn->xprt_st & SSL_SOCK_RECV_HEARTBEAT)
2040 conn->err_code = CO_ER_SSL_HANDSHAKE_HB;
Willy Tarreau20879a02012-12-03 16:32:10 +01002041 else
Emeric Brun29f037d2014-04-25 19:05:36 +02002042 conn->err_code = CO_ER_SSL_HANDSHAKE;
2043 }
Willy Tarreau20879a02012-12-03 16:32:10 +01002044 }
Emeric Brun674b7432012-11-08 19:21:55 +01002045 goto out_error;
2046 }
2047 else {
2048 /* Fail on all other handshake errors */
2049 /* Note: OpenSSL may leave unread bytes in the socket's
2050 * buffer, causing an RST to be emitted upon close() on
2051 * TCP sockets. We first try to drain possibly pending
2052 * data to avoid this as much as possible.
2053 */
Willy Tarreau46be2e52014-01-20 12:10:52 +01002054 conn_drain(conn);
Willy Tarreau20879a02012-12-03 16:32:10 +01002055 if (!conn->err_code)
Willy Tarreauf51c6982014-04-25 20:02:39 +02002056 conn->err_code = (conn->xprt_st & SSL_SOCK_RECV_HEARTBEAT) ?
2057 CO_ER_SSL_KILLED_HB : CO_ER_SSL_HANDSHAKE;
Emeric Brun674b7432012-11-08 19:21:55 +01002058 goto out_error;
2059 }
2060 }
2061 /* read some data: consider handshake completed */
2062 goto reneg_ok;
2063 }
2064
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02002065 ret = SSL_do_handshake(conn->xprt_ctx);
Emeric Brun46591952012-05-18 15:47:34 +02002066 if (ret != 1) {
2067 /* handshake did not complete, let's find why */
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02002068 ret = SSL_get_error(conn->xprt_ctx, ret);
Emeric Brun46591952012-05-18 15:47:34 +02002069
2070 if (ret == SSL_ERROR_WANT_WRITE) {
2071 /* SSL handshake needs to write, L4 connection may not be ready */
2072 __conn_sock_stop_recv(conn);
Willy Tarreaue1f50c42014-01-22 20:02:06 +01002073 __conn_sock_want_send(conn);
2074 fd_cant_send(conn->t.sock.fd);
Emeric Brun46591952012-05-18 15:47:34 +02002075 return 0;
2076 }
2077 else if (ret == SSL_ERROR_WANT_READ) {
2078 /* SSL handshake needs to read, L4 connection is ready */
2079 if (conn->flags & CO_FL_WAIT_L4_CONN)
2080 conn->flags &= ~CO_FL_WAIT_L4_CONN;
2081 __conn_sock_stop_send(conn);
Willy Tarreaue1f50c42014-01-22 20:02:06 +01002082 __conn_sock_want_recv(conn);
2083 fd_cant_recv(conn->t.sock.fd);
Emeric Brun46591952012-05-18 15:47:34 +02002084 return 0;
2085 }
Willy Tarreau89230192012-09-28 20:22:13 +02002086 else if (ret == SSL_ERROR_SYSCALL) {
2087 /* if errno is null, then connection was successfully established */
2088 if (!errno && conn->flags & CO_FL_WAIT_L4_CONN)
2089 conn->flags &= ~CO_FL_WAIT_L4_CONN;
Willy Tarreau20879a02012-12-03 16:32:10 +01002090
Emeric Brun29f037d2014-04-25 19:05:36 +02002091 if (!((SSL *)conn->xprt_ctx)->packet_length) {
2092 if (!errno) {
2093 if (conn->xprt_st & SSL_SOCK_RECV_HEARTBEAT)
2094 conn->err_code = CO_ER_SSL_HANDSHAKE_HB;
2095 else
2096 conn->err_code = CO_ER_SSL_EMPTY;
2097 }
2098 else {
2099 if (conn->xprt_st & SSL_SOCK_RECV_HEARTBEAT)
2100 conn->err_code = CO_ER_SSL_HANDSHAKE_HB;
2101 else
2102 conn->err_code = CO_ER_SSL_ABORT;
2103 }
2104 }
2105 else {
2106 if (conn->xprt_st & SSL_SOCK_RECV_HEARTBEAT)
2107 conn->err_code = CO_ER_SSL_HANDSHAKE_HB;
Willy Tarreau20879a02012-12-03 16:32:10 +01002108 else
Emeric Brun29f037d2014-04-25 19:05:36 +02002109 conn->err_code = CO_ER_SSL_HANDSHAKE;
2110 }
Willy Tarreau89230192012-09-28 20:22:13 +02002111 goto out_error;
2112 }
Emeric Brun46591952012-05-18 15:47:34 +02002113 else {
2114 /* Fail on all other handshake errors */
Willy Tarreau566dc552012-10-19 20:52:18 +02002115 /* Note: OpenSSL may leave unread bytes in the socket's
2116 * buffer, causing an RST to be emitted upon close() on
2117 * TCP sockets. We first try to drain possibly pending
2118 * data to avoid this as much as possible.
2119 */
Willy Tarreau46be2e52014-01-20 12:10:52 +01002120 conn_drain(conn);
Willy Tarreau20879a02012-12-03 16:32:10 +01002121 if (!conn->err_code)
Willy Tarreauf51c6982014-04-25 20:02:39 +02002122 conn->err_code = (conn->xprt_st & SSL_SOCK_RECV_HEARTBEAT) ?
2123 CO_ER_SSL_KILLED_HB : CO_ER_SSL_HANDSHAKE;
Emeric Brun46591952012-05-18 15:47:34 +02002124 goto out_error;
2125 }
2126 }
2127
Emeric Brun674b7432012-11-08 19:21:55 +01002128reneg_ok:
2129
Emeric Brun46591952012-05-18 15:47:34 +02002130 /* Handshake succeeded */
Willy Tarreau0c9c2722014-05-28 12:28:58 +02002131 if (!SSL_session_reused(conn->xprt_ctx)) {
2132 if (objt_server(conn->target)) {
2133 update_freq_ctr(&global.ssl_be_keys_per_sec, 1);
2134 if (global.ssl_be_keys_per_sec.curr_ctr > global.ssl_be_keys_max)
2135 global.ssl_be_keys_max = global.ssl_be_keys_per_sec.curr_ctr;
2136
Emeric Brun46591952012-05-18 15:47:34 +02002137 /* check if session was reused, if not store current session on server for reuse */
Willy Tarreau3fdb3662012-11-12 00:42:33 +01002138 if (objt_server(conn->target)->ssl_ctx.reused_sess)
2139 SSL_SESSION_free(objt_server(conn->target)->ssl_ctx.reused_sess);
Emeric Brun46591952012-05-18 15:47:34 +02002140
Willy Tarreau3fdb3662012-11-12 00:42:33 +01002141 objt_server(conn->target)->ssl_ctx.reused_sess = SSL_get1_session(conn->xprt_ctx);
Emeric Brun46591952012-05-18 15:47:34 +02002142 }
Willy Tarreau0c9c2722014-05-28 12:28:58 +02002143 else {
2144 update_freq_ctr(&global.ssl_fe_keys_per_sec, 1);
2145 if (global.ssl_fe_keys_per_sec.curr_ctr > global.ssl_fe_keys_max)
2146 global.ssl_fe_keys_max = global.ssl_fe_keys_per_sec.curr_ctr;
2147 }
Emeric Brun46591952012-05-18 15:47:34 +02002148 }
2149
2150 /* The connection is now established at both layers, it's time to leave */
2151 conn->flags &= ~(flag | CO_FL_WAIT_L4_CONN | CO_FL_WAIT_L6_CONN);
2152 return 1;
2153
2154 out_error:
Emeric Brun644cde02012-12-14 11:21:13 +01002155 /* Clear openssl global errors stack */
2156 ERR_clear_error();
2157
Emeric Brun9fa89732012-10-04 17:09:56 +02002158 /* free resumed session if exists */
Willy Tarreau3fdb3662012-11-12 00:42:33 +01002159 if (objt_server(conn->target) && objt_server(conn->target)->ssl_ctx.reused_sess) {
2160 SSL_SESSION_free(objt_server(conn->target)->ssl_ctx.reused_sess);
2161 objt_server(conn->target)->ssl_ctx.reused_sess = NULL;
Emeric Brun9fa89732012-10-04 17:09:56 +02002162 }
2163
Emeric Brun46591952012-05-18 15:47:34 +02002164 /* Fail on all other handshake errors */
2165 conn->flags |= CO_FL_ERROR;
Willy Tarreau20879a02012-12-03 16:32:10 +01002166 if (!conn->err_code)
2167 conn->err_code = CO_ER_SSL_HANDSHAKE;
Emeric Brun46591952012-05-18 15:47:34 +02002168 return 0;
2169}
2170
2171/* Receive up to <count> bytes from connection <conn>'s socket and store them
Willy Tarreauabf08d92014-01-14 11:31:27 +01002172 * into buffer <buf>. Only one call to recv() is performed, unless the
Emeric Brun46591952012-05-18 15:47:34 +02002173 * buffer wraps, in which case a second call may be performed. The connection's
2174 * flags are updated with whatever special event is detected (error, read0,
2175 * empty). The caller is responsible for taking care of those events and
2176 * avoiding the call if inappropriate. The function does not call the
2177 * connection's polling update function, so the caller is responsible for this.
2178 */
2179static int ssl_sock_to_buf(struct connection *conn, struct buffer *buf, int count)
2180{
2181 int ret, done = 0;
Willy Tarreauabf08d92014-01-14 11:31:27 +01002182 int try;
Emeric Brun46591952012-05-18 15:47:34 +02002183
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02002184 if (!conn->xprt_ctx)
Emeric Brun46591952012-05-18 15:47:34 +02002185 goto out_error;
2186
2187 if (conn->flags & CO_FL_HANDSHAKE)
2188 /* a handshake was requested */
2189 return 0;
2190
Willy Tarreauabf08d92014-01-14 11:31:27 +01002191 /* let's realign the buffer to optimize I/O */
2192 if (buffer_empty(buf))
Emeric Brun46591952012-05-18 15:47:34 +02002193 buf->p = buf->data;
Emeric Brun46591952012-05-18 15:47:34 +02002194
2195 /* read the largest possible block. For this, we perform only one call
2196 * to recv() unless the buffer wraps and we exactly fill the first hunk,
2197 * in which case we accept to do it once again. A new attempt is made on
2198 * EINTR too.
2199 */
Willy Tarreau00b0fb92014-01-17 11:09:40 +01002200 while (count > 0) {
Willy Tarreauabf08d92014-01-14 11:31:27 +01002201 /* first check if we have some room after p+i */
2202 try = buf->data + buf->size - (buf->p + buf->i);
2203 /* otherwise continue between data and p-o */
2204 if (try <= 0) {
2205 try = buf->p - (buf->data + buf->o);
2206 if (try <= 0)
2207 break;
2208 }
2209 if (try > count)
2210 try = count;
2211
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02002212 ret = SSL_read(conn->xprt_ctx, bi_end(buf), try);
Emeric Brune1f38db2012-09-03 20:36:47 +02002213 if (conn->flags & CO_FL_ERROR) {
2214 /* CO_FL_ERROR may be set by ssl_sock_infocbk */
Emeric Brun644cde02012-12-14 11:21:13 +01002215 goto out_error;
Emeric Brune1f38db2012-09-03 20:36:47 +02002216 }
Emeric Brun46591952012-05-18 15:47:34 +02002217 if (ret > 0) {
2218 buf->i += ret;
2219 done += ret;
2220 if (ret < try)
2221 break;
2222 count -= ret;
Emeric Brun46591952012-05-18 15:47:34 +02002223 }
2224 else if (ret == 0) {
Emeric Brun644cde02012-12-14 11:21:13 +01002225 ret = SSL_get_error(conn->xprt_ctx, ret);
2226 if (ret != SSL_ERROR_ZERO_RETURN) {
Emeric Brun1c646862012-12-14 12:33:41 +01002227 /* error on protocol or underlying transport */
2228 if ((ret != SSL_ERROR_SYSCALL)
2229 || (errno && (errno != EAGAIN)))
2230 conn->flags |= CO_FL_ERROR;
2231
Emeric Brun644cde02012-12-14 11:21:13 +01002232 /* Clear openssl global errors stack */
2233 ERR_clear_error();
2234 }
Emeric Brun46591952012-05-18 15:47:34 +02002235 goto read0;
2236 }
2237 else {
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02002238 ret = SSL_get_error(conn->xprt_ctx, ret);
Emeric Brun46591952012-05-18 15:47:34 +02002239 if (ret == SSL_ERROR_WANT_WRITE) {
Emeric Brun8af8dd12012-11-08 17:56:20 +01002240 /* handshake is running, and it needs to enable write */
Emeric Brun46591952012-05-18 15:47:34 +02002241 conn->flags |= CO_FL_SSL_WAIT_HS;
Emeric Brun8af8dd12012-11-08 17:56:20 +01002242 __conn_sock_want_send(conn);
Emeric Brun46591952012-05-18 15:47:34 +02002243 break;
2244 }
2245 else if (ret == SSL_ERROR_WANT_READ) {
Emeric Brun282a76a2012-11-08 18:02:56 +01002246 if (SSL_renegotiate_pending(conn->xprt_ctx)) {
2247 /* handshake is running, and it may need to re-enable read */
2248 conn->flags |= CO_FL_SSL_WAIT_HS;
2249 __conn_sock_want_recv(conn);
2250 break;
2251 }
Emeric Brun46591952012-05-18 15:47:34 +02002252 /* we need to poll for retry a read later */
Willy Tarreaue1f50c42014-01-22 20:02:06 +01002253 fd_cant_recv(conn->t.sock.fd);
Emeric Brun46591952012-05-18 15:47:34 +02002254 break;
2255 }
2256 /* otherwise it's a real error */
2257 goto out_error;
2258 }
2259 }
2260 return done;
2261
2262 read0:
2263 conn_sock_read0(conn);
2264 return done;
2265 out_error:
Emeric Brun644cde02012-12-14 11:21:13 +01002266 /* Clear openssl global errors stack */
2267 ERR_clear_error();
2268
Emeric Brun46591952012-05-18 15:47:34 +02002269 conn->flags |= CO_FL_ERROR;
2270 return done;
2271}
2272
2273
2274/* Send all pending bytes from buffer <buf> to connection <conn>'s socket.
Willy Tarreau1049b1f2014-02-02 01:51:17 +01002275 * <flags> may contain some CO_SFL_* flags to hint the system about other
2276 * pending data for example, but this flag is ignored at the moment.
Emeric Brun46591952012-05-18 15:47:34 +02002277 * Only one call to send() is performed, unless the buffer wraps, in which case
2278 * a second call may be performed. The connection's flags are updated with
2279 * whatever special event is detected (error, empty). The caller is responsible
2280 * for taking care of those events and avoiding the call if inappropriate. The
2281 * function does not call the connection's polling update function, so the caller
2282 * is responsible for this.
2283 */
2284static int ssl_sock_from_buf(struct connection *conn, struct buffer *buf, int flags)
2285{
2286 int ret, try, done;
2287
2288 done = 0;
2289
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02002290 if (!conn->xprt_ctx)
Emeric Brun46591952012-05-18 15:47:34 +02002291 goto out_error;
2292
2293 if (conn->flags & CO_FL_HANDSHAKE)
2294 /* a handshake was requested */
2295 return 0;
2296
2297 /* send the largest possible block. For this we perform only one call
2298 * to send() unless the buffer wraps and we exactly fill the first hunk,
2299 * in which case we accept to do it once again.
2300 */
2301 while (buf->o) {
Kevin Hestercad82342013-05-30 15:12:41 -07002302 try = bo_contig_data(buf);
Willy Tarreaubfd59462013-02-21 07:46:09 +01002303
Willy Tarreau7bed9452014-02-02 02:00:24 +01002304 if (!(flags & CO_SFL_STREAMER) &&
Willy Tarreau518cedd2014-02-17 15:43:01 +01002305 !(conn->xprt_st & SSL_SOCK_SEND_UNLIMITED) &&
2306 global.tune.ssl_max_record && try > global.tune.ssl_max_record) {
Willy Tarreaubfd59462013-02-21 07:46:09 +01002307 try = global.tune.ssl_max_record;
Willy Tarreau518cedd2014-02-17 15:43:01 +01002308 }
2309 else {
2310 /* we need to keep the information about the fact that
2311 * we're not limiting the upcoming send(), because if it
2312 * fails, we'll have to retry with at least as many data.
2313 */
2314 conn->xprt_st |= SSL_SOCK_SEND_UNLIMITED;
2315 }
Willy Tarreaubfd59462013-02-21 07:46:09 +01002316
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02002317 ret = SSL_write(conn->xprt_ctx, bo_ptr(buf), try);
Willy Tarreau518cedd2014-02-17 15:43:01 +01002318
Emeric Brune1f38db2012-09-03 20:36:47 +02002319 if (conn->flags & CO_FL_ERROR) {
2320 /* CO_FL_ERROR may be set by ssl_sock_infocbk */
Emeric Brun644cde02012-12-14 11:21:13 +01002321 goto out_error;
Emeric Brune1f38db2012-09-03 20:36:47 +02002322 }
Emeric Brun46591952012-05-18 15:47:34 +02002323 if (ret > 0) {
Willy Tarreau518cedd2014-02-17 15:43:01 +01002324 conn->xprt_st &= ~SSL_SOCK_SEND_UNLIMITED;
2325
Emeric Brun46591952012-05-18 15:47:34 +02002326 buf->o -= ret;
2327 done += ret;
2328
Willy Tarreau5fb38032012-12-16 19:39:09 +01002329 if (likely(buffer_empty(buf)))
Emeric Brun46591952012-05-18 15:47:34 +02002330 /* optimize data alignment in the buffer */
2331 buf->p = buf->data;
2332
2333 /* if the system buffer is full, don't insist */
2334 if (ret < try)
2335 break;
2336 }
2337 else {
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02002338 ret = SSL_get_error(conn->xprt_ctx, ret);
Emeric Brun46591952012-05-18 15:47:34 +02002339 if (ret == SSL_ERROR_WANT_WRITE) {
Emeric Brun282a76a2012-11-08 18:02:56 +01002340 if (SSL_renegotiate_pending(conn->xprt_ctx)) {
2341 /* handshake is running, and it may need to re-enable write */
2342 conn->flags |= CO_FL_SSL_WAIT_HS;
2343 __conn_sock_want_send(conn);
2344 break;
2345 }
Emeric Brun46591952012-05-18 15:47:34 +02002346 /* we need to poll to retry a write later */
Willy Tarreaue1f50c42014-01-22 20:02:06 +01002347 fd_cant_send(conn->t.sock.fd);
Emeric Brun46591952012-05-18 15:47:34 +02002348 break;
2349 }
2350 else if (ret == SSL_ERROR_WANT_READ) {
Emeric Brun8af8dd12012-11-08 17:56:20 +01002351 /* handshake is running, and it needs to enable read */
Emeric Brun46591952012-05-18 15:47:34 +02002352 conn->flags |= CO_FL_SSL_WAIT_HS;
Emeric Brun8af8dd12012-11-08 17:56:20 +01002353 __conn_sock_want_recv(conn);
Emeric Brun46591952012-05-18 15:47:34 +02002354 break;
2355 }
2356 goto out_error;
2357 }
2358 }
2359 return done;
2360
2361 out_error:
Emeric Brun644cde02012-12-14 11:21:13 +01002362 /* Clear openssl global errors stack */
2363 ERR_clear_error();
2364
Emeric Brun46591952012-05-18 15:47:34 +02002365 conn->flags |= CO_FL_ERROR;
2366 return done;
2367}
2368
Emeric Brun46591952012-05-18 15:47:34 +02002369static void ssl_sock_close(struct connection *conn) {
2370
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02002371 if (conn->xprt_ctx) {
2372 SSL_free(conn->xprt_ctx);
2373 conn->xprt_ctx = NULL;
Willy Tarreau403edff2012-09-06 11:58:37 +02002374 sslconns--;
Emeric Brun46591952012-05-18 15:47:34 +02002375 }
Emeric Brun46591952012-05-18 15:47:34 +02002376}
2377
2378/* This function tries to perform a clean shutdown on an SSL connection, and in
2379 * any case, flags the connection as reusable if no handshake was in progress.
2380 */
2381static void ssl_sock_shutw(struct connection *conn, int clean)
2382{
2383 if (conn->flags & CO_FL_HANDSHAKE)
2384 return;
2385 /* no handshake was in progress, try a clean ssl shutdown */
Emeric Brun644cde02012-12-14 11:21:13 +01002386 if (clean && (SSL_shutdown(conn->xprt_ctx) <= 0)) {
2387 /* Clear openssl global errors stack */
2388 ERR_clear_error();
2389 }
Emeric Brun46591952012-05-18 15:47:34 +02002390
2391 /* force flag on ssl to keep session in cache regardless shutdown result */
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02002392 SSL_set_shutdown(conn->xprt_ctx, SSL_SENT_SHUTDOWN);
Emeric Brun46591952012-05-18 15:47:34 +02002393}
2394
Willy Tarreauffc3fcd2012-10-12 20:17:54 +02002395/* used for logging, may be changed for a sample fetch later */
2396const char *ssl_sock_get_cipher_name(struct connection *conn)
2397{
2398 if (!conn->xprt && !conn->xprt_ctx)
2399 return NULL;
2400 return SSL_get_cipher_name(conn->xprt_ctx);
2401}
2402
2403/* used for logging, may be changed for a sample fetch later */
2404const char *ssl_sock_get_proto_version(struct connection *conn)
2405{
2406 if (!conn->xprt && !conn->xprt_ctx)
2407 return NULL;
2408 return SSL_get_version(conn->xprt_ctx);
2409}
2410
Willy Tarreau8d598402012-10-22 17:58:39 +02002411/* Extract a serial from a cert, and copy it to a chunk.
2412 * Returns 1 if serial is found and copied, 0 if no serial found and
2413 * -1 if output is not large enough.
2414 */
2415static int
2416ssl_sock_get_serial(X509 *crt, struct chunk *out)
2417{
2418 ASN1_INTEGER *serial;
2419
2420 serial = X509_get_serialNumber(crt);
2421 if (!serial)
2422 return 0;
2423
2424 if (out->size < serial->length)
2425 return -1;
2426
2427 memcpy(out->str, serial->data, serial->length);
2428 out->len = serial->length;
2429 return 1;
2430}
2431
Emeric Brunce5ad802012-10-22 14:11:22 +02002432
2433/* Copy Date in ASN1_UTCTIME format in struct chunk out.
2434 * Returns 1 if serial is found and copied, 0 if no valid time found
2435 * and -1 if output is not large enough.
2436 */
2437static int
2438ssl_sock_get_time(ASN1_TIME *tm, struct chunk *out)
2439{
2440 if (tm->type == V_ASN1_GENERALIZEDTIME) {
2441 ASN1_GENERALIZEDTIME *gentm = (ASN1_GENERALIZEDTIME *)tm;
2442
2443 if (gentm->length < 12)
2444 return 0;
2445 if (gentm->data[0] != 0x32 || gentm->data[1] != 0x30)
2446 return 0;
2447 if (out->size < gentm->length-2)
2448 return -1;
2449
2450 memcpy(out->str, gentm->data+2, gentm->length-2);
2451 out->len = gentm->length-2;
2452 return 1;
2453 }
2454 else if (tm->type == V_ASN1_UTCTIME) {
2455 ASN1_UTCTIME *utctm = (ASN1_UTCTIME *)tm;
2456
2457 if (utctm->length < 10)
2458 return 0;
2459 if (utctm->data[0] >= 0x35)
2460 return 0;
2461 if (out->size < utctm->length)
2462 return -1;
2463
2464 memcpy(out->str, utctm->data, utctm->length);
2465 out->len = utctm->length;
2466 return 1;
2467 }
2468
2469 return 0;
2470}
2471
Emeric Brun87855892012-10-17 17:39:35 +02002472/* Extract an entry from a X509_NAME and copy its value to an output chunk.
2473 * Returns 1 if entry found, 0 if entry not found, or -1 if output not large enough.
2474 */
2475static int
2476ssl_sock_get_dn_entry(X509_NAME *a, const struct chunk *entry, int pos, struct chunk *out)
2477{
2478 X509_NAME_ENTRY *ne;
2479 int i, j, n;
2480 int cur = 0;
2481 const char *s;
2482 char tmp[128];
2483
2484 out->len = 0;
2485 for (i = 0; i < sk_X509_NAME_ENTRY_num(a->entries); i++) {
2486 if (pos < 0)
2487 j = (sk_X509_NAME_ENTRY_num(a->entries)-1) - i;
2488 else
2489 j = i;
2490
2491 ne = sk_X509_NAME_ENTRY_value(a->entries, j);
2492 n = OBJ_obj2nid(ne->object);
2493 if ((n == NID_undef) || ((s = OBJ_nid2sn(n)) == NULL)) {
2494 i2t_ASN1_OBJECT(tmp, sizeof(tmp), ne->object);
2495 s = tmp;
2496 }
2497
2498 if (chunk_strcasecmp(entry, s) != 0)
2499 continue;
2500
2501 if (pos < 0)
2502 cur--;
2503 else
2504 cur++;
2505
2506 if (cur != pos)
2507 continue;
2508
2509 if (ne->value->length > out->size)
2510 return -1;
2511
2512 memcpy(out->str, ne->value->data, ne->value->length);
2513 out->len = ne->value->length;
2514 return 1;
2515 }
2516
2517 return 0;
2518
2519}
2520
2521/* Extract and format full DN from a X509_NAME and copy result into a chunk
2522 * Returns 1 if dn entries exits, 0 if no dn entry found or -1 if output is not large enough.
2523 */
2524static int
2525ssl_sock_get_dn_oneline(X509_NAME *a, struct chunk *out)
2526{
2527 X509_NAME_ENTRY *ne;
2528 int i, n, ln;
2529 int l = 0;
2530 const char *s;
2531 char *p;
2532 char tmp[128];
2533
2534 out->len = 0;
2535 p = out->str;
2536 for (i = 0; i < sk_X509_NAME_ENTRY_num(a->entries); i++) {
2537 ne = sk_X509_NAME_ENTRY_value(a->entries, i);
2538 n = OBJ_obj2nid(ne->object);
2539 if ((n == NID_undef) || ((s = OBJ_nid2sn(n)) == NULL)) {
2540 i2t_ASN1_OBJECT(tmp, sizeof(tmp), ne->object);
2541 s = tmp;
2542 }
2543 ln = strlen(s);
2544
2545 l += 1 + ln + 1 + ne->value->length;
2546 if (l > out->size)
2547 return -1;
2548 out->len = l;
2549
2550 *(p++)='/';
2551 memcpy(p, s, ln);
2552 p += ln;
2553 *(p++)='=';
2554 memcpy(p, ne->value->data, ne->value->length);
2555 p += ne->value->length;
2556 }
2557
2558 if (!out->len)
2559 return 0;
2560
2561 return 1;
2562}
2563
David Safb76832014-05-08 23:42:08 -04002564char *ssl_sock_get_version(struct connection *conn)
2565{
2566 if (!ssl_sock_is_ssl(conn))
2567 return NULL;
2568
2569 return (char *)SSL_get_version(conn->xprt_ctx);
2570}
2571
2572/* returns common name, NULL terminated, from client certificate, or NULL if none */
2573char *ssl_sock_get_common_name(struct connection *conn)
2574{
2575 X509 *crt = NULL;
2576 X509_NAME *name;
2577 struct chunk *cn_trash;
2578 const char find_cn[] = "CN";
2579 const struct chunk find_cn_chunk = {
2580 .str = (char *)&find_cn,
2581 .len = sizeof(find_cn)-1
2582 };
2583 char *result = NULL;
2584
2585 if (!ssl_sock_is_ssl(conn))
2586 return NULL;
2587
2588 /* SSL_get_peer_certificate, it increase X509 * ref count */
2589 crt = SSL_get_peer_certificate(conn->xprt_ctx);
2590 if (!crt)
2591 goto out;
2592
2593 name = X509_get_subject_name(crt);
2594 if (!name)
2595 goto out;
2596
2597 cn_trash = get_trash_chunk();
2598 if (ssl_sock_get_dn_entry(name, &find_cn_chunk, 1, cn_trash) <= 0)
2599 goto out;
2600 cn_trash->str[cn_trash->len] = '\0';
2601 result = cn_trash->str;
2602
2603 out:
2604 if (crt)
2605 X509_free(crt);
2606
2607 return result;
2608}
2609
2610/* returns 1 if client passed a certificate, 0 if not */
2611int ssl_sock_get_cert_used(struct connection *conn)
2612{
2613 if (!ssl_sock_is_ssl(conn))
2614 return 0;
2615
2616 return SSL_SOCK_ST_FL_VERIFY_DONE & conn->xprt_st ? 1 : 0;
2617}
2618
2619/* returns result from SSL verify */
2620unsigned int ssl_sock_get_verify_result(struct connection *conn)
2621{
2622 if (!ssl_sock_is_ssl(conn))
2623 return (unsigned int)X509_V_ERR_APPLICATION_VERIFICATION;
2624
2625 return (unsigned int)SSL_get_verify_result(conn->xprt_ctx);
2626}
2627
Willy Tarreau7875d092012-09-10 08:20:03 +02002628/***** Below are some sample fetching functions for ACL/patterns *****/
2629
Emeric Brune64aef12012-09-21 13:15:06 +02002630/* boolean, returns true if client cert was present */
2631static int
Emeric Brun2525b6b2012-10-18 15:59:43 +02002632smp_fetch_ssl_fc_has_crt(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
Willy Tarreauef38c392013-07-22 16:29:32 +02002633 const struct arg *args, struct sample *smp, const char *kw)
Emeric Brune64aef12012-09-21 13:15:06 +02002634{
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002635 struct connection *conn;
2636
2637 if (!l4)
2638 return 0;
2639
2640 conn = objt_conn(l4->si[0].end);
2641 if (!conn || conn->xprt != &ssl_sock)
Emeric Brune64aef12012-09-21 13:15:06 +02002642 return 0;
2643
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002644 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brune64aef12012-09-21 13:15:06 +02002645 smp->flags |= SMP_F_MAY_CHANGE;
2646 return 0;
2647 }
2648
2649 smp->flags = 0;
2650 smp->type = SMP_T_BOOL;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002651 smp->data.uint = SSL_SOCK_ST_FL_VERIFY_DONE & conn->xprt_st ? 1 : 0;
Emeric Brune64aef12012-09-21 13:15:06 +02002652
2653 return 1;
2654}
2655
Emeric Brunba841a12014-04-30 17:05:08 +02002656/* binary, returns serial of certificate in a binary chunk.
2657 * The 5th keyword char is used to know if SSL_get_certificate or SSL_get_peer_certificate
2658 * should be use.
2659 */
Willy Tarreau8d598402012-10-22 17:58:39 +02002660static int
Emeric Brunba841a12014-04-30 17:05:08 +02002661smp_fetch_ssl_x_serial(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
Willy Tarreauef38c392013-07-22 16:29:32 +02002662 const struct arg *args, struct sample *smp, const char *kw)
Willy Tarreau8d598402012-10-22 17:58:39 +02002663{
Emeric Brunba841a12014-04-30 17:05:08 +02002664 int cert_peer = (kw[4] == 'c') ? 1 : 0;
Willy Tarreau8d598402012-10-22 17:58:39 +02002665 X509 *crt = NULL;
2666 int ret = 0;
2667 struct chunk *smp_trash;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002668 struct connection *conn;
2669
2670 if (!l4)
2671 return 0;
Willy Tarreau8d598402012-10-22 17:58:39 +02002672
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002673 conn = objt_conn(l4->si[0].end);
2674 if (!conn || conn->xprt != &ssl_sock)
Willy Tarreau8d598402012-10-22 17:58:39 +02002675 return 0;
2676
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002677 if (!(conn->flags & CO_FL_CONNECTED)) {
Willy Tarreau8d598402012-10-22 17:58:39 +02002678 smp->flags |= SMP_F_MAY_CHANGE;
2679 return 0;
2680 }
2681
Emeric Brunba841a12014-04-30 17:05:08 +02002682 if (cert_peer)
2683 crt = SSL_get_peer_certificate(conn->xprt_ctx);
2684 else
2685 crt = SSL_get_certificate(conn->xprt_ctx);
2686
Willy Tarreau8d598402012-10-22 17:58:39 +02002687 if (!crt)
2688 goto out;
2689
Willy Tarreau47ca5452012-12-23 20:22:19 +01002690 smp_trash = get_trash_chunk();
Willy Tarreau8d598402012-10-22 17:58:39 +02002691 if (ssl_sock_get_serial(crt, smp_trash) <= 0)
2692 goto out;
2693
2694 smp->data.str = *smp_trash;
2695 smp->type = SMP_T_BIN;
2696 ret = 1;
2697out:
Emeric Brunba841a12014-04-30 17:05:08 +02002698 /* SSL_get_peer_certificate, it increase X509 * ref count */
2699 if (cert_peer && crt)
Willy Tarreau8d598402012-10-22 17:58:39 +02002700 X509_free(crt);
2701 return ret;
2702}
Emeric Brune64aef12012-09-21 13:15:06 +02002703
Emeric Brunba841a12014-04-30 17:05:08 +02002704/* binary, returns the client certificate's SHA-1 fingerprint (SHA-1 hash of DER-encoded certificate) in a binary chunk.
2705 * The 5th keyword char is used to know if SSL_get_certificate or SSL_get_peer_certificate
2706 * should be use.
2707 */
James Votha051b4a2013-05-14 20:37:59 +02002708static int
Emeric Brunba841a12014-04-30 17:05:08 +02002709smp_fetch_ssl_x_sha1(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
Willy Tarreauef38c392013-07-22 16:29:32 +02002710 const struct arg *args, struct sample *smp, const char *kw)
James Votha051b4a2013-05-14 20:37:59 +02002711{
Emeric Brunba841a12014-04-30 17:05:08 +02002712 int cert_peer = (kw[4] == 'c') ? 1 : 0;
James Votha051b4a2013-05-14 20:37:59 +02002713 X509 *crt = NULL;
2714 const EVP_MD *digest;
2715 int ret = 0;
2716 struct chunk *smp_trash;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002717 struct connection *conn;
James Votha051b4a2013-05-14 20:37:59 +02002718
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002719 if (!l4)
James Votha051b4a2013-05-14 20:37:59 +02002720 return 0;
2721
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002722 conn = objt_conn(l4->si[0].end);
2723 if (!conn || conn->xprt != &ssl_sock)
2724 return 0;
2725
2726 if (!(conn->flags & CO_FL_CONNECTED)) {
James Votha051b4a2013-05-14 20:37:59 +02002727 smp->flags |= SMP_F_MAY_CHANGE;
2728 return 0;
2729 }
2730
Emeric Brunba841a12014-04-30 17:05:08 +02002731 if (cert_peer)
2732 crt = SSL_get_peer_certificate(conn->xprt_ctx);
2733 else
2734 crt = SSL_get_certificate(conn->xprt_ctx);
James Votha051b4a2013-05-14 20:37:59 +02002735 if (!crt)
2736 goto out;
2737
2738 smp_trash = get_trash_chunk();
2739 digest = EVP_sha1();
2740 X509_digest(crt, digest, (unsigned char *)smp_trash->str, (unsigned int *)&smp_trash->len);
2741
2742 smp->data.str = *smp_trash;
2743 smp->type = SMP_T_BIN;
2744 ret = 1;
2745out:
Emeric Brunba841a12014-04-30 17:05:08 +02002746 /* SSL_get_peer_certificate, it increase X509 * ref count */
2747 if (cert_peer && crt)
James Votha051b4a2013-05-14 20:37:59 +02002748 X509_free(crt);
2749 return ret;
2750}
2751
Emeric Brunba841a12014-04-30 17:05:08 +02002752/* string, returns certificate's notafter date in ASN1_UTCTIME format.
2753 * The 5th keyword char is used to know if SSL_get_certificate or SSL_get_peer_certificate
2754 * should be use.
2755 */
Emeric Brunce5ad802012-10-22 14:11:22 +02002756static int
Emeric Brunba841a12014-04-30 17:05:08 +02002757smp_fetch_ssl_x_notafter(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
Willy Tarreauef38c392013-07-22 16:29:32 +02002758 const struct arg *args, struct sample *smp, const char *kw)
Emeric Brunce5ad802012-10-22 14:11:22 +02002759{
Emeric Brunba841a12014-04-30 17:05:08 +02002760 int cert_peer = (kw[4] == 'c') ? 1 : 0;
Emeric Brunce5ad802012-10-22 14:11:22 +02002761 X509 *crt = NULL;
2762 int ret = 0;
2763 struct chunk *smp_trash;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002764 struct connection *conn;
Emeric Brunce5ad802012-10-22 14:11:22 +02002765
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002766 if (!l4)
Emeric Brunce5ad802012-10-22 14:11:22 +02002767 return 0;
2768
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002769 conn = objt_conn(l4->si[0].end);
2770 if (!conn || conn->xprt != &ssl_sock)
2771 return 0;
2772
2773 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brunce5ad802012-10-22 14:11:22 +02002774 smp->flags |= SMP_F_MAY_CHANGE;
2775 return 0;
2776 }
2777
Emeric Brunba841a12014-04-30 17:05:08 +02002778 if (cert_peer)
2779 crt = SSL_get_peer_certificate(conn->xprt_ctx);
2780 else
2781 crt = SSL_get_certificate(conn->xprt_ctx);
Emeric Brunce5ad802012-10-22 14:11:22 +02002782 if (!crt)
2783 goto out;
2784
Willy Tarreau47ca5452012-12-23 20:22:19 +01002785 smp_trash = get_trash_chunk();
Emeric Brunce5ad802012-10-22 14:11:22 +02002786 if (ssl_sock_get_time(X509_get_notAfter(crt), smp_trash) <= 0)
2787 goto out;
2788
2789 smp->data.str = *smp_trash;
2790 smp->type = SMP_T_STR;
2791 ret = 1;
2792out:
Emeric Brunba841a12014-04-30 17:05:08 +02002793 /* SSL_get_peer_certificate, it increase X509 * ref count */
2794 if (cert_peer && crt)
Emeric Brunce5ad802012-10-22 14:11:22 +02002795 X509_free(crt);
2796 return ret;
2797}
2798
Emeric Brunba841a12014-04-30 17:05:08 +02002799/* string, returns a string of a formatted full dn \C=..\O=..\OU=.. \CN=.. of certificate's issuer
2800 * The 5th keyword char is used to know if SSL_get_certificate or SSL_get_peer_certificate
2801 * should be use.
2802 */
Emeric Brun87855892012-10-17 17:39:35 +02002803static int
Emeric Brunba841a12014-04-30 17:05:08 +02002804smp_fetch_ssl_x_i_dn(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
Willy Tarreauef38c392013-07-22 16:29:32 +02002805 const struct arg *args, struct sample *smp, const char *kw)
Emeric Brun87855892012-10-17 17:39:35 +02002806{
Emeric Brunba841a12014-04-30 17:05:08 +02002807 int cert_peer = (kw[4] == 'c') ? 1 : 0;
Emeric Brun87855892012-10-17 17:39:35 +02002808 X509 *crt = NULL;
2809 X509_NAME *name;
2810 int ret = 0;
2811 struct chunk *smp_trash;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002812 struct connection *conn;
Emeric Brun87855892012-10-17 17:39:35 +02002813
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002814 if (!l4)
Emeric Brun87855892012-10-17 17:39:35 +02002815 return 0;
2816
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002817 conn = objt_conn(l4->si[0].end);
2818 if (!conn || conn->xprt != &ssl_sock)
2819 return 0;
2820
2821 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brun87855892012-10-17 17:39:35 +02002822 smp->flags |= SMP_F_MAY_CHANGE;
2823 return 0;
2824 }
2825
Emeric Brunba841a12014-04-30 17:05:08 +02002826 if (cert_peer)
2827 crt = SSL_get_peer_certificate(conn->xprt_ctx);
2828 else
2829 crt = SSL_get_certificate(conn->xprt_ctx);
Emeric Brun87855892012-10-17 17:39:35 +02002830 if (!crt)
2831 goto out;
2832
2833 name = X509_get_issuer_name(crt);
2834 if (!name)
2835 goto out;
2836
Willy Tarreau47ca5452012-12-23 20:22:19 +01002837 smp_trash = get_trash_chunk();
Emeric Brun87855892012-10-17 17:39:35 +02002838 if (args && args[0].type == ARGT_STR) {
2839 int pos = 1;
2840
2841 if (args[1].type == ARGT_SINT)
2842 pos = args[1].data.sint;
2843 else if (args[1].type == ARGT_UINT)
2844 pos =(int)args[1].data.uint;
2845
2846 if (ssl_sock_get_dn_entry(name, &args[0].data.str, pos, smp_trash) <= 0)
2847 goto out;
2848 }
2849 else if (ssl_sock_get_dn_oneline(name, smp_trash) <= 0)
2850 goto out;
2851
2852 smp->type = SMP_T_STR;
2853 smp->data.str = *smp_trash;
2854 ret = 1;
2855out:
Emeric Brunba841a12014-04-30 17:05:08 +02002856 /* SSL_get_peer_certificate, it increase X509 * ref count */
2857 if (cert_peer && crt)
Emeric Brun87855892012-10-17 17:39:35 +02002858 X509_free(crt);
2859 return ret;
2860}
2861
Emeric Brunba841a12014-04-30 17:05:08 +02002862/* string, returns notbefore date in ASN1_UTCTIME format.
2863 * The 5th keyword char is used to know if SSL_get_certificate or SSL_get_peer_certificate
2864 * should be use.
2865 */
Emeric Brunce5ad802012-10-22 14:11:22 +02002866static int
Emeric Brunba841a12014-04-30 17:05:08 +02002867smp_fetch_ssl_x_notbefore(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
Willy Tarreauef38c392013-07-22 16:29:32 +02002868 const struct arg *args, struct sample *smp, const char *kw)
Emeric Brunce5ad802012-10-22 14:11:22 +02002869{
Emeric Brunba841a12014-04-30 17:05:08 +02002870 int cert_peer = (kw[4] == 'c') ? 1 : 0;
Emeric Brunce5ad802012-10-22 14:11:22 +02002871 X509 *crt = NULL;
2872 int ret = 0;
2873 struct chunk *smp_trash;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002874 struct connection *conn;
2875
2876 if (!l4)
2877 return 0;
Emeric Brunce5ad802012-10-22 14:11:22 +02002878
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002879 conn = objt_conn(l4->si[0].end);
2880 if (!conn || conn->xprt != &ssl_sock)
Emeric Brunce5ad802012-10-22 14:11:22 +02002881 return 0;
2882
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002883 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brunce5ad802012-10-22 14:11:22 +02002884 smp->flags |= SMP_F_MAY_CHANGE;
2885 return 0;
2886 }
2887
Emeric Brunba841a12014-04-30 17:05:08 +02002888 if (cert_peer)
2889 crt = SSL_get_peer_certificate(conn->xprt_ctx);
2890 else
2891 crt = SSL_get_certificate(conn->xprt_ctx);
Emeric Brunce5ad802012-10-22 14:11:22 +02002892 if (!crt)
2893 goto out;
2894
Willy Tarreau47ca5452012-12-23 20:22:19 +01002895 smp_trash = get_trash_chunk();
Emeric Brunce5ad802012-10-22 14:11:22 +02002896 if (ssl_sock_get_time(X509_get_notBefore(crt), smp_trash) <= 0)
2897 goto out;
2898
2899 smp->data.str = *smp_trash;
2900 smp->type = SMP_T_STR;
2901 ret = 1;
2902out:
Emeric Brunba841a12014-04-30 17:05:08 +02002903 /* SSL_get_peer_certificate, it increase X509 * ref count */
2904 if (cert_peer && crt)
Emeric Brunce5ad802012-10-22 14:11:22 +02002905 X509_free(crt);
2906 return ret;
2907}
2908
Emeric Brunba841a12014-04-30 17:05:08 +02002909/* string, returns a string of a formatted full dn \C=..\O=..\OU=.. \CN=.. of certificate's subject
2910 * The 5th keyword char is used to know if SSL_get_certificate or SSL_get_peer_certificate
2911 * should be use.
2912 */
Emeric Brun87855892012-10-17 17:39:35 +02002913static int
Emeric Brunba841a12014-04-30 17:05:08 +02002914smp_fetch_ssl_x_s_dn(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
Willy Tarreauef38c392013-07-22 16:29:32 +02002915 const struct arg *args, struct sample *smp, const char *kw)
Emeric Brun87855892012-10-17 17:39:35 +02002916{
Emeric Brunba841a12014-04-30 17:05:08 +02002917 int cert_peer = (kw[4] == 'c') ? 1 : 0;
Emeric Brun87855892012-10-17 17:39:35 +02002918 X509 *crt = NULL;
2919 X509_NAME *name;
2920 int ret = 0;
2921 struct chunk *smp_trash;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002922 struct connection *conn;
Emeric Brun87855892012-10-17 17:39:35 +02002923
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002924 if (!l4)
Emeric Brun87855892012-10-17 17:39:35 +02002925 return 0;
2926
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002927 conn = objt_conn(l4->si[0].end);
2928 if (!conn || conn->xprt != &ssl_sock)
2929 return 0;
2930
2931 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brun87855892012-10-17 17:39:35 +02002932 smp->flags |= SMP_F_MAY_CHANGE;
2933 return 0;
2934 }
2935
Emeric Brunba841a12014-04-30 17:05:08 +02002936 if (cert_peer)
2937 crt = SSL_get_peer_certificate(conn->xprt_ctx);
2938 else
2939 crt = SSL_get_certificate(conn->xprt_ctx);
Emeric Brun87855892012-10-17 17:39:35 +02002940 if (!crt)
2941 goto out;
2942
2943 name = X509_get_subject_name(crt);
2944 if (!name)
2945 goto out;
2946
Willy Tarreau47ca5452012-12-23 20:22:19 +01002947 smp_trash = get_trash_chunk();
Emeric Brun87855892012-10-17 17:39:35 +02002948 if (args && args[0].type == ARGT_STR) {
2949 int pos = 1;
2950
2951 if (args[1].type == ARGT_SINT)
2952 pos = args[1].data.sint;
2953 else if (args[1].type == ARGT_UINT)
2954 pos =(int)args[1].data.uint;
2955
2956 if (ssl_sock_get_dn_entry(name, &args[0].data.str, pos, smp_trash) <= 0)
2957 goto out;
2958 }
2959 else if (ssl_sock_get_dn_oneline(name, smp_trash) <= 0)
2960 goto out;
2961
2962 smp->type = SMP_T_STR;
2963 smp->data.str = *smp_trash;
2964 ret = 1;
2965out:
Emeric Brunba841a12014-04-30 17:05:08 +02002966 /* SSL_get_peer_certificate, it increase X509 * ref count */
2967 if (cert_peer && crt)
Emeric Brun87855892012-10-17 17:39:35 +02002968 X509_free(crt);
2969 return ret;
2970}
Emeric Brun9143d372012-12-20 15:44:16 +01002971
2972/* integer, returns true if current session use a client certificate */
2973static int
2974smp_fetch_ssl_c_used(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
Willy Tarreauef38c392013-07-22 16:29:32 +02002975 const struct arg *args, struct sample *smp, const char *kw)
Emeric Brun9143d372012-12-20 15:44:16 +01002976{
2977 X509 *crt;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002978 struct connection *conn;
Emeric Brun9143d372012-12-20 15:44:16 +01002979
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002980 if (!l4)
Emeric Brun9143d372012-12-20 15:44:16 +01002981 return 0;
2982
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002983 conn = objt_conn(l4->si[0].end);
2984 if (!conn || conn->xprt != &ssl_sock)
2985 return 0;
2986
2987 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brun9143d372012-12-20 15:44:16 +01002988 smp->flags |= SMP_F_MAY_CHANGE;
2989 return 0;
2990 }
2991
2992 /* SSL_get_peer_certificate returns a ptr on allocated X509 struct */
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002993 crt = SSL_get_peer_certificate(conn->xprt_ctx);
Emeric Brun9143d372012-12-20 15:44:16 +01002994 if (crt) {
2995 X509_free(crt);
2996 }
2997
2998 smp->type = SMP_T_BOOL;
2999 smp->data.uint = (crt != NULL);
3000 return 1;
3001}
3002
Emeric Brunba841a12014-04-30 17:05:08 +02003003/* integer, returns the certificate version
3004 * The 5th keyword char is used to know if SSL_get_certificate or SSL_get_peer_certificate
3005 * should be use.
3006 */
Emeric Bruna7359fd2012-10-17 15:03:11 +02003007static int
Emeric Brunba841a12014-04-30 17:05:08 +02003008smp_fetch_ssl_x_version(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
Willy Tarreauef38c392013-07-22 16:29:32 +02003009 const struct arg *args, struct sample *smp, const char *kw)
Emeric Bruna7359fd2012-10-17 15:03:11 +02003010{
Emeric Brunba841a12014-04-30 17:05:08 +02003011 int cert_peer = (kw[4] == 'c') ? 1 : 0;
Emeric Bruna7359fd2012-10-17 15:03:11 +02003012 X509 *crt;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003013 struct connection *conn;
3014
3015 if (!l4)
3016 return 0;
Emeric Bruna7359fd2012-10-17 15:03:11 +02003017
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003018 conn = objt_conn(l4->si[0].end);
3019 if (!conn || conn->xprt != &ssl_sock)
Emeric Bruna7359fd2012-10-17 15:03:11 +02003020 return 0;
3021
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003022 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Bruna7359fd2012-10-17 15:03:11 +02003023 smp->flags |= SMP_F_MAY_CHANGE;
3024 return 0;
3025 }
3026
Emeric Brunba841a12014-04-30 17:05:08 +02003027 if (cert_peer)
3028 crt = SSL_get_peer_certificate(conn->xprt_ctx);
3029 else
3030 crt = SSL_get_certificate(conn->xprt_ctx);
Emeric Bruna7359fd2012-10-17 15:03:11 +02003031 if (!crt)
3032 return 0;
3033
3034 smp->data.uint = (unsigned int)(1 + X509_get_version(crt));
Emeric Brunba841a12014-04-30 17:05:08 +02003035 /* SSL_get_peer_certificate increase X509 * ref count */
3036 if (cert_peer)
3037 X509_free(crt);
Emeric Bruna7359fd2012-10-17 15:03:11 +02003038 smp->type = SMP_T_UINT;
3039
3040 return 1;
3041}
3042
Emeric Brunba841a12014-04-30 17:05:08 +02003043/* string, returns the certificate's signature algorithm.
3044 * The 5th keyword char is used to know if SSL_get_certificate or SSL_get_peer_certificate
3045 * should be use.
3046 */
Emeric Brun7f56e742012-10-19 18:15:40 +02003047static int
Emeric Brunba841a12014-04-30 17:05:08 +02003048smp_fetch_ssl_x_sig_alg(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
Willy Tarreauef38c392013-07-22 16:29:32 +02003049 const struct arg *args, struct sample *smp, const char *kw)
Emeric Brun7f56e742012-10-19 18:15:40 +02003050{
Emeric Brunba841a12014-04-30 17:05:08 +02003051 int cert_peer = (kw[4] == 'c') ? 1 : 0;
Emeric Brun7f56e742012-10-19 18:15:40 +02003052 X509 *crt;
3053 int nid;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003054 struct connection *conn;
Emeric Brun7f56e742012-10-19 18:15:40 +02003055
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003056 if (!l4)
Emeric Brun7f56e742012-10-19 18:15:40 +02003057 return 0;
3058
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003059 conn = objt_conn(l4->si[0].end);
3060 if (!conn || conn->xprt != &ssl_sock)
3061 return 0;
3062
3063 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brun7f56e742012-10-19 18:15:40 +02003064 smp->flags |= SMP_F_MAY_CHANGE;
3065 return 0;
3066 }
3067
Emeric Brunba841a12014-04-30 17:05:08 +02003068 if (cert_peer)
3069 crt = SSL_get_peer_certificate(conn->xprt_ctx);
3070 else
3071 crt = SSL_get_certificate(conn->xprt_ctx);
Emeric Brun7f56e742012-10-19 18:15:40 +02003072 if (!crt)
3073 return 0;
3074
3075 nid = OBJ_obj2nid((ASN1_OBJECT *)(crt->cert_info->signature->algorithm));
3076
3077 smp->data.str.str = (char *)OBJ_nid2sn(nid);
Emeric Brun9bf3ba22013-10-07 14:31:44 +02003078 if (!smp->data.str.str) {
Emeric Brunba841a12014-04-30 17:05:08 +02003079 /* SSL_get_peer_certificate increase X509 * ref count */
3080 if (cert_peer)
3081 X509_free(crt);
Emeric Brun7f56e742012-10-19 18:15:40 +02003082 return 0;
Emeric Brun9bf3ba22013-10-07 14:31:44 +02003083 }
Emeric Brun7f56e742012-10-19 18:15:40 +02003084
Thierry FOURNIER7654c9f2013-12-17 00:20:33 +01003085 smp->type = SMP_T_STR;
3086 smp->flags |= SMP_F_CONST;
Emeric Brun7f56e742012-10-19 18:15:40 +02003087 smp->data.str.len = strlen(smp->data.str.str);
Emeric Brunba841a12014-04-30 17:05:08 +02003088 /* SSL_get_peer_certificate increase X509 * ref count */
3089 if (cert_peer)
3090 X509_free(crt);
Emeric Brun7f56e742012-10-19 18:15:40 +02003091
3092 return 1;
3093}
3094
Emeric Brunba841a12014-04-30 17:05:08 +02003095/* string, returns the certificate's key algorithm.
3096 * The 5th keyword char is used to know if SSL_get_certificate or SSL_get_peer_certificate
3097 * should be use.
3098 */
Emeric Brun521a0112012-10-22 12:22:55 +02003099static int
Emeric Brunba841a12014-04-30 17:05:08 +02003100smp_fetch_ssl_x_key_alg(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
Willy Tarreauef38c392013-07-22 16:29:32 +02003101 const struct arg *args, struct sample *smp, const char *kw)
Emeric Brun521a0112012-10-22 12:22:55 +02003102{
Emeric Brunba841a12014-04-30 17:05:08 +02003103 int cert_peer = (kw[4] == 'c') ? 1 : 0;
Emeric Brun521a0112012-10-22 12:22:55 +02003104 X509 *crt;
3105 int nid;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003106 struct connection *conn;
Emeric Brun521a0112012-10-22 12:22:55 +02003107
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003108 if (!l4)
Emeric Brun521a0112012-10-22 12:22:55 +02003109 return 0;
3110
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003111 conn = objt_conn(l4->si[0].end);
3112 if (!conn || conn->xprt != &ssl_sock)
3113 return 0;
3114
3115 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brun521a0112012-10-22 12:22:55 +02003116 smp->flags |= SMP_F_MAY_CHANGE;
3117 return 0;
3118 }
3119
Emeric Brunba841a12014-04-30 17:05:08 +02003120 if (cert_peer)
3121 crt = SSL_get_peer_certificate(conn->xprt_ctx);
3122 else
3123 crt = SSL_get_certificate(conn->xprt_ctx);
Emeric Brun521a0112012-10-22 12:22:55 +02003124 if (!crt)
3125 return 0;
3126
3127 nid = OBJ_obj2nid((ASN1_OBJECT *)(crt->cert_info->key->algor->algorithm));
3128
3129 smp->data.str.str = (char *)OBJ_nid2sn(nid);
Emeric Brun9bf3ba22013-10-07 14:31:44 +02003130 if (!smp->data.str.str) {
Emeric Brunba841a12014-04-30 17:05:08 +02003131 /* SSL_get_peer_certificate increase X509 * ref count */
3132 if (cert_peer)
3133 X509_free(crt);
Emeric Brun521a0112012-10-22 12:22:55 +02003134 return 0;
Emeric Brun9bf3ba22013-10-07 14:31:44 +02003135 }
Emeric Brun521a0112012-10-22 12:22:55 +02003136
Thierry FOURNIER7654c9f2013-12-17 00:20:33 +01003137 smp->type = SMP_T_STR;
3138 smp->flags |= SMP_F_CONST;
Emeric Brun521a0112012-10-22 12:22:55 +02003139 smp->data.str.len = strlen(smp->data.str.str);
Emeric Brunba841a12014-04-30 17:05:08 +02003140 if (cert_peer)
3141 X509_free(crt);
Emeric Brun521a0112012-10-22 12:22:55 +02003142
3143 return 1;
3144}
3145
Emeric Brun645ae792014-04-30 14:21:06 +02003146/* boolean, returns true if front conn. transport layer is SSL.
3147 * This function is also usable on backend conn if the fetch keyword 5th
3148 * char is 'b'.
3149 */
Willy Tarreau7875d092012-09-10 08:20:03 +02003150static int
Emeric Brun2525b6b2012-10-18 15:59:43 +02003151smp_fetch_ssl_fc(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
Willy Tarreauef38c392013-07-22 16:29:32 +02003152 const struct arg *args, struct sample *smp, const char *kw)
Willy Tarreau7875d092012-09-10 08:20:03 +02003153{
Emeric Brun645ae792014-04-30 14:21:06 +02003154 int back_conn = (kw[4] == 'b') ? 1 : 0;
3155 struct connection *conn = objt_conn(l4->si[back_conn].end);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003156
Willy Tarreau7875d092012-09-10 08:20:03 +02003157 smp->type = SMP_T_BOOL;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003158 smp->data.uint = (conn && conn->xprt == &ssl_sock);
Willy Tarreau7875d092012-09-10 08:20:03 +02003159 return 1;
3160}
3161
Emeric Brun2525b6b2012-10-18 15:59:43 +02003162/* boolean, returns true if client present a SNI */
Willy Tarreau7875d092012-09-10 08:20:03 +02003163static int
Emeric Brun2525b6b2012-10-18 15:59:43 +02003164smp_fetch_ssl_fc_has_sni(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
Willy Tarreauef38c392013-07-22 16:29:32 +02003165 const struct arg *args, struct sample *smp, const char *kw)
Willy Tarreau7875d092012-09-10 08:20:03 +02003166{
3167#ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003168 struct connection *conn = objt_conn(l4->si[0].end);
3169
Willy Tarreau7875d092012-09-10 08:20:03 +02003170 smp->type = SMP_T_BOOL;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003171 smp->data.uint = (conn && conn->xprt == &ssl_sock) &&
3172 conn->xprt_ctx &&
3173 SSL_get_servername(conn->xprt_ctx, TLSEXT_NAMETYPE_host_name) != NULL;
Willy Tarreau7875d092012-09-10 08:20:03 +02003174 return 1;
3175#else
3176 return 0;
3177#endif
3178}
3179
Emeric Brun645ae792014-04-30 14:21:06 +02003180/* string, returns the used cipher if front conn. transport layer is SSL.
3181 * This function is also usable on backend conn if the fetch keyword 5th
3182 * char is 'b'.
3183 */
Emeric Brun589fcad2012-10-16 14:13:26 +02003184static int
3185smp_fetch_ssl_fc_cipher(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
Willy Tarreauef38c392013-07-22 16:29:32 +02003186 const struct arg *args, struct sample *smp, const char *kw)
Emeric Brun589fcad2012-10-16 14:13:26 +02003187{
Emeric Brun645ae792014-04-30 14:21:06 +02003188 int back_conn = (kw[4] == 'b') ? 1 : 0;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003189 struct connection *conn;
3190
Emeric Brun589fcad2012-10-16 14:13:26 +02003191 smp->flags = 0;
3192
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003193 if (!l4)
3194 return 0;
3195
Emeric Brun645ae792014-04-30 14:21:06 +02003196 conn = objt_conn(l4->si[back_conn].end);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003197 if (!conn || !conn->xprt_ctx || conn->xprt != &ssl_sock)
Emeric Brun589fcad2012-10-16 14:13:26 +02003198 return 0;
3199
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003200 smp->data.str.str = (char *)SSL_get_cipher_name(conn->xprt_ctx);
Emeric Brun589fcad2012-10-16 14:13:26 +02003201 if (!smp->data.str.str)
3202 return 0;
3203
Thierry FOURNIER7654c9f2013-12-17 00:20:33 +01003204 smp->type = SMP_T_STR;
3205 smp->flags |= SMP_F_CONST;
Emeric Brun589fcad2012-10-16 14:13:26 +02003206 smp->data.str.len = strlen(smp->data.str.str);
3207
3208 return 1;
3209}
3210
Emeric Brun645ae792014-04-30 14:21:06 +02003211/* integer, returns the algoritm's keysize if front conn. transport layer
3212 * is SSL.
3213 * This function is also usable on backend conn if the fetch keyword 5th
3214 * char is 'b'.
3215 */
Emeric Brun589fcad2012-10-16 14:13:26 +02003216static int
3217smp_fetch_ssl_fc_alg_keysize(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
Willy Tarreauef38c392013-07-22 16:29:32 +02003218 const struct arg *args, struct sample *smp, const char *kw)
Emeric Brun589fcad2012-10-16 14:13:26 +02003219{
Emeric Brun645ae792014-04-30 14:21:06 +02003220 int back_conn = (kw[4] == 'b') ? 1 : 0;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003221 struct connection *conn;
3222
Emeric Brun589fcad2012-10-16 14:13:26 +02003223 smp->flags = 0;
3224
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003225 if (!l4)
Emeric Brun589fcad2012-10-16 14:13:26 +02003226 return 0;
3227
Emeric Brun645ae792014-04-30 14:21:06 +02003228 conn = objt_conn(l4->si[back_conn].end);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003229 if (!conn || !conn->xprt_ctx || conn->xprt != &ssl_sock)
Emeric Brun589fcad2012-10-16 14:13:26 +02003230 return 0;
3231
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003232 if (!SSL_get_cipher_bits(conn->xprt_ctx, (int *)&smp->data.uint))
3233 return 0;
3234
Emeric Brun589fcad2012-10-16 14:13:26 +02003235 smp->type = SMP_T_UINT;
3236
3237 return 1;
3238}
3239
Emeric Brun645ae792014-04-30 14:21:06 +02003240/* integer, returns the used keysize if front conn. transport layer is SSL.
3241 * This function is also usable on backend conn if the fetch keyword 5th
3242 * char is 'b'.
3243 */
Emeric Brun589fcad2012-10-16 14:13:26 +02003244static int
3245smp_fetch_ssl_fc_use_keysize(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
Willy Tarreauef38c392013-07-22 16:29:32 +02003246 const struct arg *args, struct sample *smp, const char *kw)
Emeric Brun589fcad2012-10-16 14:13:26 +02003247{
Emeric Brun645ae792014-04-30 14:21:06 +02003248 int back_conn = (kw[4] == 'b') ? 1 : 0;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003249 struct connection *conn;
3250
Emeric Brun589fcad2012-10-16 14:13:26 +02003251 smp->flags = 0;
3252
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003253 if (!l4)
Emeric Brun589fcad2012-10-16 14:13:26 +02003254 return 0;
3255
Emeric Brun645ae792014-04-30 14:21:06 +02003256 conn = objt_conn(l4->si[back_conn].end);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003257 if (!conn || !conn->xprt_ctx || conn->xprt != &ssl_sock)
3258 return 0;
3259
3260 smp->data.uint = (unsigned int)SSL_get_cipher_bits(conn->xprt_ctx, NULL);
Emeric Brun589fcad2012-10-16 14:13:26 +02003261 if (!smp->data.uint)
3262 return 0;
3263
3264 smp->type = SMP_T_UINT;
3265
3266 return 1;
3267}
3268
Willy Tarreau6c9a3d52012-10-18 18:57:14 +02003269#ifdef OPENSSL_NPN_NEGOTIATED
Willy Tarreau7875d092012-09-10 08:20:03 +02003270static int
Emeric Brun2525b6b2012-10-18 15:59:43 +02003271smp_fetch_ssl_fc_npn(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
Willy Tarreauef38c392013-07-22 16:29:32 +02003272 const struct arg *args, struct sample *smp, const char *kw)
Willy Tarreaua33c6542012-10-15 13:19:06 +02003273{
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003274 struct connection *conn;
3275
Thierry FOURNIER7654c9f2013-12-17 00:20:33 +01003276 smp->flags = SMP_F_CONST;
3277 smp->type = SMP_T_STR;
Willy Tarreaua33c6542012-10-15 13:19:06 +02003278
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003279 if (!l4)
Willy Tarreaua33c6542012-10-15 13:19:06 +02003280 return 0;
3281
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003282 conn = objt_conn(l4->si[0].end);
3283 if (!conn || !conn->xprt_ctx || conn->xprt != &ssl_sock)
3284 return 0;
3285
Willy Tarreaua33c6542012-10-15 13:19:06 +02003286 smp->data.str.str = NULL;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003287 SSL_get0_next_proto_negotiated(conn->xprt_ctx,
Willy Tarreaua33c6542012-10-15 13:19:06 +02003288 (const unsigned char **)&smp->data.str.str, (unsigned *)&smp->data.str.len);
3289
3290 if (!smp->data.str.str)
3291 return 0;
3292
3293 return 1;
Willy Tarreaua33c6542012-10-15 13:19:06 +02003294}
Willy Tarreau6c9a3d52012-10-18 18:57:14 +02003295#endif
Willy Tarreaua33c6542012-10-15 13:19:06 +02003296
Dirkjan Bussink48f1c4e2014-02-13 12:29:42 +01003297#ifdef TLSEXT_TYPE_application_layer_protocol_negotiation
Willy Tarreauab861d32013-04-02 02:30:41 +02003298static int
3299smp_fetch_ssl_fc_alpn(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
Willy Tarreauef38c392013-07-22 16:29:32 +02003300 const struct arg *args, struct sample *smp, const char *kw)
Willy Tarreauab861d32013-04-02 02:30:41 +02003301{
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003302 struct connection *conn;
3303
Thierry FOURNIER7654c9f2013-12-17 00:20:33 +01003304 smp->flags = SMP_F_CONST;
3305 smp->type = SMP_T_STR;
Willy Tarreauab861d32013-04-02 02:30:41 +02003306
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003307 if (!l4)
3308 return 0;
3309
3310 conn = objt_conn(l4->si[0].end);
3311 if (!conn || !conn->xprt_ctx || conn->xprt != &ssl_sock)
Willy Tarreauab861d32013-04-02 02:30:41 +02003312 return 0;
3313
3314 smp->data.str.str = NULL;
Dirkjan Bussink48f1c4e2014-02-13 12:29:42 +01003315 SSL_get0_alpn_selected(conn->xprt_ctx,
Willy Tarreauab861d32013-04-02 02:30:41 +02003316 (const unsigned char **)&smp->data.str.str, (unsigned *)&smp->data.str.len);
3317
3318 if (!smp->data.str.str)
3319 return 0;
3320
3321 return 1;
3322}
3323#endif
3324
Emeric Brun645ae792014-04-30 14:21:06 +02003325/* string, returns the used protocol if front conn. transport layer is SSL.
3326 * This function is also usable on backend conn if the fetch keyword 5th
3327 * char is 'b'.
3328 */
Willy Tarreaua33c6542012-10-15 13:19:06 +02003329static int
Emeric Brun589fcad2012-10-16 14:13:26 +02003330smp_fetch_ssl_fc_protocol(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
Willy Tarreauef38c392013-07-22 16:29:32 +02003331 const struct arg *args, struct sample *smp, const char *kw)
Emeric Brun589fcad2012-10-16 14:13:26 +02003332{
Emeric Brun645ae792014-04-30 14:21:06 +02003333 int back_conn = (kw[4] == 'b') ? 1 : 0;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003334 struct connection *conn;
3335
Emeric Brun589fcad2012-10-16 14:13:26 +02003336 smp->flags = 0;
3337
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003338 if (!l4)
Emeric Brun589fcad2012-10-16 14:13:26 +02003339 return 0;
3340
Emeric Brun645ae792014-04-30 14:21:06 +02003341 conn = objt_conn(l4->si[back_conn].end);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003342 if (!conn || !conn->xprt_ctx || conn->xprt != &ssl_sock)
3343 return 0;
3344
3345 smp->data.str.str = (char *)SSL_get_version(conn->xprt_ctx);
Emeric Brun589fcad2012-10-16 14:13:26 +02003346 if (!smp->data.str.str)
3347 return 0;
3348
Thierry FOURNIER7654c9f2013-12-17 00:20:33 +01003349 smp->type = SMP_T_STR;
3350 smp->flags = SMP_F_CONST;
Emeric Brun589fcad2012-10-16 14:13:26 +02003351 smp->data.str.len = strlen(smp->data.str.str);
3352
3353 return 1;
3354}
3355
Emeric Brun645ae792014-04-30 14:21:06 +02003356/* binary, returns the SSL session id if front conn. transport layer is SSL.
3357 * This function is also usable on backend conn if the fetch keyword 5th
3358 * char is 'b'.
3359 */
Emeric Brun589fcad2012-10-16 14:13:26 +02003360static int
Emeric Brunfe68f682012-10-16 14:59:28 +02003361smp_fetch_ssl_fc_session_id(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
Willy Tarreauef38c392013-07-22 16:29:32 +02003362 const struct arg *args, struct sample *smp, const char *kw)
Emeric Brunfe68f682012-10-16 14:59:28 +02003363{
3364#if OPENSSL_VERSION_NUMBER > 0x0090800fL
Emeric Brun645ae792014-04-30 14:21:06 +02003365 int back_conn = (kw[4] == 'b') ? 1 : 0;
Emeric Brunfe68f682012-10-16 14:59:28 +02003366 SSL_SESSION *sess;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003367 struct connection *conn;
Emeric Brunfe68f682012-10-16 14:59:28 +02003368
Thierry FOURNIER7654c9f2013-12-17 00:20:33 +01003369 smp->flags = SMP_F_CONST;
3370 smp->type = SMP_T_BIN;
Emeric Brunfe68f682012-10-16 14:59:28 +02003371
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003372 if (!l4)
Emeric Brunfe68f682012-10-16 14:59:28 +02003373 return 0;
3374
Emeric Brun645ae792014-04-30 14:21:06 +02003375 conn = objt_conn(l4->si[back_conn].end);
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003376 if (!conn || !conn->xprt_ctx || conn->xprt != &ssl_sock)
3377 return 0;
3378
3379 sess = SSL_get_session(conn->xprt_ctx);
Emeric Brunfe68f682012-10-16 14:59:28 +02003380 if (!sess)
3381 return 0;
3382
3383 smp->data.str.str = (char *)SSL_SESSION_get_id(sess, (unsigned int *)&smp->data.str.len);
3384 if (!smp->data.str.str || !&smp->data.str.len)
3385 return 0;
3386
3387 return 1;
3388#else
3389 return 0;
3390#endif
3391}
3392
3393static int
Emeric Brun2525b6b2012-10-18 15:59:43 +02003394smp_fetch_ssl_fc_sni(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
Willy Tarreauef38c392013-07-22 16:29:32 +02003395 const struct arg *args, struct sample *smp, const char *kw)
Willy Tarreau7875d092012-09-10 08:20:03 +02003396{
3397#ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003398 struct connection *conn;
3399
Thierry FOURNIER7654c9f2013-12-17 00:20:33 +01003400 smp->flags = SMP_F_CONST;
3401 smp->type = SMP_T_STR;
Willy Tarreau7875d092012-09-10 08:20:03 +02003402
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003403 if (!l4)
Willy Tarreau7875d092012-09-10 08:20:03 +02003404 return 0;
3405
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003406 conn = objt_conn(l4->si[0].end);
3407 if (!conn || !conn->xprt_ctx || conn->xprt != &ssl_sock)
3408 return 0;
3409
3410 smp->data.str.str = (char *)SSL_get_servername(conn->xprt_ctx, TLSEXT_NAMETYPE_host_name);
Willy Tarreau3e394c92012-09-14 23:56:58 +02003411 if (!smp->data.str.str)
3412 return 0;
3413
Willy Tarreau7875d092012-09-10 08:20:03 +02003414 smp->data.str.len = strlen(smp->data.str.str);
3415 return 1;
3416#else
3417 return 0;
3418#endif
3419}
3420
David Sc1ad52e2014-04-08 18:48:47 -04003421static int
3422smp_fetch_ssl_fc_unique_id(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
3423 const struct arg *args, struct sample *smp, const char *kw)
3424{
3425#if OPENSSL_VERSION_NUMBER > 0x0090800fL
Emeric Brun645ae792014-04-30 14:21:06 +02003426 int back_conn = (kw[4] == 'b') ? 1 : 0;
David Sc1ad52e2014-04-08 18:48:47 -04003427 struct connection *conn;
3428 int finished_len;
David Sc1ad52e2014-04-08 18:48:47 -04003429 struct chunk *finished_trash;
David Sc1ad52e2014-04-08 18:48:47 -04003430
3431 smp->flags = 0;
3432
3433 if (!l4)
3434 return 0;
3435
Emeric Brun645ae792014-04-30 14:21:06 +02003436 conn = objt_conn(l4->si[back_conn].end);
David Sc1ad52e2014-04-08 18:48:47 -04003437 if (!conn || !conn->xprt_ctx || conn->xprt != &ssl_sock)
3438 return 0;
3439
3440 if (!(conn->flags & CO_FL_CONNECTED)) {
3441 smp->flags |= SMP_F_MAY_CHANGE;
3442 return 0;
3443 }
3444
3445 finished_trash = get_trash_chunk();
3446 if (!SSL_session_reused(conn->xprt_ctx))
3447 finished_len = SSL_get_peer_finished(conn->xprt_ctx, finished_trash->str, finished_trash->size);
3448 else
3449 finished_len = SSL_get_finished(conn->xprt_ctx, finished_trash->str, finished_trash->size);
3450
3451 if (!finished_len)
3452 return 0;
3453
Emeric Brunb73a9b02014-04-30 18:49:19 +02003454 finished_trash->len = finished_len;
3455 smp->data.str = *finished_trash;
3456 smp->type = SMP_T_BIN;
David Sc1ad52e2014-04-08 18:48:47 -04003457
3458 return 1;
3459#else
3460 return 0;
3461#endif
3462}
3463
Emeric Brun2525b6b2012-10-18 15:59:43 +02003464/* integer, returns the first verify error in CA chain of client certificate chain. */
Emeric Brunf282a812012-09-21 15:27:54 +02003465static int
Emeric Brun2525b6b2012-10-18 15:59:43 +02003466smp_fetch_ssl_c_ca_err(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
Willy Tarreauef38c392013-07-22 16:29:32 +02003467 const struct arg *args, struct sample *smp, const char *kw)
Emeric Brunf282a812012-09-21 15:27:54 +02003468{
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003469 struct connection *conn;
3470
3471 if (!l4)
Emeric Brunf282a812012-09-21 15:27:54 +02003472 return 0;
3473
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003474 conn = objt_conn(l4->si[0].end);
3475 if (!conn || conn->xprt != &ssl_sock)
3476 return 0;
3477
3478 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brunf282a812012-09-21 15:27:54 +02003479 smp->flags = SMP_F_MAY_CHANGE;
3480 return 0;
3481 }
3482
3483 smp->type = SMP_T_UINT;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003484 smp->data.uint = (unsigned int)SSL_SOCK_ST_TO_CA_ERROR(conn->xprt_st);
Emeric Brunf282a812012-09-21 15:27:54 +02003485 smp->flags = 0;
3486
3487 return 1;
3488}
3489
Emeric Brun2525b6b2012-10-18 15:59:43 +02003490/* integer, returns the depth of the first verify error in CA chain of client certificate chain. */
Emeric Brunf282a812012-09-21 15:27:54 +02003491static int
Emeric Brun2525b6b2012-10-18 15:59:43 +02003492smp_fetch_ssl_c_ca_err_depth(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
Willy Tarreauef38c392013-07-22 16:29:32 +02003493 const struct arg *args, struct sample *smp, const char *kw)
Emeric Brunf282a812012-09-21 15:27:54 +02003494{
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003495 struct connection *conn;
3496
3497 if (!l4)
3498 return 0;
3499
3500 conn = objt_conn(l4->si[0].end);
3501 if (!conn || conn->xprt != &ssl_sock)
Emeric Brunf282a812012-09-21 15:27:54 +02003502 return 0;
3503
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003504 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brunf282a812012-09-21 15:27:54 +02003505 smp->flags = SMP_F_MAY_CHANGE;
3506 return 0;
3507 }
3508
3509 smp->type = SMP_T_UINT;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003510 smp->data.uint = (unsigned int)SSL_SOCK_ST_TO_CAEDEPTH(conn->xprt_st);
Emeric Brunf282a812012-09-21 15:27:54 +02003511 smp->flags = 0;
3512
3513 return 1;
3514}
3515
Emeric Brun2525b6b2012-10-18 15:59:43 +02003516/* integer, returns the first verify error on client certificate */
Emeric Brunf282a812012-09-21 15:27:54 +02003517static int
Emeric Brun2525b6b2012-10-18 15:59:43 +02003518smp_fetch_ssl_c_err(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
Willy Tarreauef38c392013-07-22 16:29:32 +02003519 const struct arg *args, struct sample *smp, const char *kw)
Emeric Brunf282a812012-09-21 15:27:54 +02003520{
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003521 struct connection *conn;
3522
3523 if (!l4)
Emeric Brunf282a812012-09-21 15:27:54 +02003524 return 0;
3525
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003526 conn = objt_conn(l4->si[0].end);
3527 if (!conn || conn->xprt != &ssl_sock)
3528 return 0;
3529
3530 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brunf282a812012-09-21 15:27:54 +02003531 smp->flags = SMP_F_MAY_CHANGE;
3532 return 0;
3533 }
3534
3535 smp->type = SMP_T_UINT;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003536 smp->data.uint = (unsigned int)SSL_SOCK_ST_TO_CRTERROR(conn->xprt_st);
Emeric Brunf282a812012-09-21 15:27:54 +02003537 smp->flags = 0;
3538
3539 return 1;
3540}
3541
Emeric Brun2525b6b2012-10-18 15:59:43 +02003542/* integer, returns the verify result on client cert */
Emeric Brunbaf8ffb2012-09-21 15:27:20 +02003543static int
Emeric Brun2525b6b2012-10-18 15:59:43 +02003544smp_fetch_ssl_c_verify(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
Willy Tarreauef38c392013-07-22 16:29:32 +02003545 const struct arg *args, struct sample *smp, const char *kw)
Emeric Brunbaf8ffb2012-09-21 15:27:20 +02003546{
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003547 struct connection *conn;
3548
3549 if (!l4)
Emeric Brunbaf8ffb2012-09-21 15:27:20 +02003550 return 0;
3551
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003552 conn = objt_conn(l4->si[0].end);
3553 if (!conn || conn->xprt != &ssl_sock)
3554 return 0;
3555
3556 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brunbaf8ffb2012-09-21 15:27:20 +02003557 smp->flags = SMP_F_MAY_CHANGE;
3558 return 0;
3559 }
3560
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003561 if (!conn->xprt_ctx)
Emeric Brunbaf8ffb2012-09-21 15:27:20 +02003562 return 0;
3563
3564 smp->type = SMP_T_UINT;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02003565 smp->data.uint = (unsigned int)SSL_get_verify_result(conn->xprt_ctx);
Emeric Brunbaf8ffb2012-09-21 15:27:20 +02003566 smp->flags = 0;
3567
3568 return 1;
3569}
3570
Emeric Brunfb510ea2012-10-05 12:00:26 +02003571/* parse the "ca-file" bind keyword */
3572static 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 +02003573{
3574 if (!*args[cur_arg + 1]) {
3575 if (err)
3576 memprintf(err, "'%s' : missing CAfile path", args[cur_arg]);
3577 return ERR_ALERT | ERR_FATAL;
3578 }
3579
Emeric Brunef42d922012-10-11 16:11:36 +02003580 if ((*args[cur_arg + 1] != '/') && global.ca_base)
3581 memprintf(&conf->ca_file, "%s/%s", global.ca_base, args[cur_arg + 1]);
3582 else
3583 memprintf(&conf->ca_file, "%s", args[cur_arg + 1]);
Emeric Brunc8e8d122012-10-02 18:42:10 +02003584
Emeric Brund94b3fe2012-09-20 18:23:56 +02003585 return 0;
3586}
3587
Willy Tarreau79eeafa2012-09-14 07:53:05 +02003588/* parse the "ciphers" bind keyword */
Willy Tarreau4348fad2012-09-20 16:48:07 +02003589static 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 +02003590{
3591 if (!*args[cur_arg + 1]) {
Willy Tarreaueb6cead2012-09-20 19:43:14 +02003592 memprintf(err, "'%s' : missing cipher suite", args[cur_arg]);
Willy Tarreau79eeafa2012-09-14 07:53:05 +02003593 return ERR_ALERT | ERR_FATAL;
3594 }
3595
Emeric Brun76d88952012-10-05 15:47:31 +02003596 free(conf->ciphers);
Willy Tarreau4348fad2012-09-20 16:48:07 +02003597 conf->ciphers = strdup(args[cur_arg + 1]);
Willy Tarreau79eeafa2012-09-14 07:53:05 +02003598 return 0;
3599}
3600
3601/* parse the "crt" bind keyword */
Willy Tarreau4348fad2012-09-20 16:48:07 +02003602static 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 +02003603{
Willy Tarreau38011032013-08-13 16:59:39 +02003604 char path[MAXPATHLEN];
Willy Tarreaub75d6922014-04-14 18:05:41 +02003605
Willy Tarreau79eeafa2012-09-14 07:53:05 +02003606 if (!*args[cur_arg + 1]) {
Willy Tarreaueb6cead2012-09-20 19:43:14 +02003607 memprintf(err, "'%s' : missing certificate location", args[cur_arg]);
Willy Tarreau79eeafa2012-09-14 07:53:05 +02003608 return ERR_ALERT | ERR_FATAL;
3609 }
3610
Emeric Brunc8e8d122012-10-02 18:42:10 +02003611 if ((*args[cur_arg + 1] != '/' ) && global.crt_base) {
Willy Tarreau38011032013-08-13 16:59:39 +02003612 if ((strlen(global.crt_base) + 1 + strlen(args[cur_arg + 1]) + 1) > MAXPATHLEN) {
Emeric Brunc8e8d122012-10-02 18:42:10 +02003613 memprintf(err, "'%s' : path too long", args[cur_arg]);
3614 return ERR_ALERT | ERR_FATAL;
3615 }
Willy Tarreaub75d6922014-04-14 18:05:41 +02003616 snprintf(path, sizeof(path), "%s/%s", global.crt_base, args[cur_arg + 1]);
Emeric Brunc8e8d122012-10-02 18:42:10 +02003617 if (ssl_sock_load_cert(path, conf, px, err) > 0)
3618 return ERR_ALERT | ERR_FATAL;
3619
3620 return 0;
3621 }
3622
Willy Tarreau4348fad2012-09-20 16:48:07 +02003623 if (ssl_sock_load_cert(args[cur_arg + 1], conf, px, err) > 0)
Willy Tarreau79eeafa2012-09-14 07:53:05 +02003624 return ERR_ALERT | ERR_FATAL;
Emeric Brund94b3fe2012-09-20 18:23:56 +02003625
3626 return 0;
3627}
3628
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01003629/* parse the "crt-list" bind keyword */
3630static int bind_parse_crt_list(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
3631{
3632 if (!*args[cur_arg + 1]) {
3633 memprintf(err, "'%s' : missing certificate location", args[cur_arg]);
3634 return ERR_ALERT | ERR_FATAL;
3635 }
3636
Willy Tarreauad1731d2013-04-02 17:35:58 +02003637 if (ssl_sock_load_cert_list_file(args[cur_arg + 1], conf, px, err) > 0) {
3638 memprintf(err, "'%s' : %s", args[cur_arg], *err);
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01003639 return ERR_ALERT | ERR_FATAL;
Willy Tarreauad1731d2013-04-02 17:35:58 +02003640 }
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01003641
3642 return 0;
3643}
3644
Emeric Brunfb510ea2012-10-05 12:00:26 +02003645/* parse the "crl-file" bind keyword */
3646static 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 +02003647{
Emeric Brun051cdab2012-10-02 19:25:50 +02003648#ifndef X509_V_FLAG_CRL_CHECK
3649 if (err)
3650 memprintf(err, "'%s' : library does not support CRL verify", args[cur_arg]);
3651 return ERR_ALERT | ERR_FATAL;
3652#else
Emeric Brund94b3fe2012-09-20 18:23:56 +02003653 if (!*args[cur_arg + 1]) {
3654 if (err)
3655 memprintf(err, "'%s' : missing CRLfile path", args[cur_arg]);
3656 return ERR_ALERT | ERR_FATAL;
3657 }
Emeric Brun2b58d042012-09-20 17:10:03 +02003658
Emeric Brunef42d922012-10-11 16:11:36 +02003659 if ((*args[cur_arg + 1] != '/') && global.ca_base)
3660 memprintf(&conf->crl_file, "%s/%s", global.ca_base, args[cur_arg + 1]);
3661 else
3662 memprintf(&conf->crl_file, "%s", args[cur_arg + 1]);
Emeric Brunc8e8d122012-10-02 18:42:10 +02003663
Emeric Brun2b58d042012-09-20 17:10:03 +02003664 return 0;
Emeric Brun051cdab2012-10-02 19:25:50 +02003665#endif
Emeric Brun2b58d042012-09-20 17:10:03 +02003666}
3667
3668/* parse the "ecdhe" bind keyword keywords */
3669static int bind_parse_ecdhe(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
3670{
3671#if OPENSSL_VERSION_NUMBER < 0x0090800fL
3672 if (err)
3673 memprintf(err, "'%s' : library does not support elliptic curve Diffie-Hellman (too old)", args[cur_arg]);
3674 return ERR_ALERT | ERR_FATAL;
3675#elif defined(OPENSSL_NO_ECDH)
3676 if (err)
3677 memprintf(err, "'%s' : library does not support elliptic curve Diffie-Hellman (disabled via OPENSSL_NO_ECDH)", args[cur_arg]);
3678 return ERR_ALERT | ERR_FATAL;
3679#else
3680 if (!*args[cur_arg + 1]) {
3681 if (err)
3682 memprintf(err, "'%s' : missing named curve", args[cur_arg]);
3683 return ERR_ALERT | ERR_FATAL;
3684 }
3685
3686 conf->ecdhe = strdup(args[cur_arg + 1]);
Willy Tarreau79eeafa2012-09-14 07:53:05 +02003687
3688 return 0;
Emeric Brun2b58d042012-09-20 17:10:03 +02003689#endif
Willy Tarreau79eeafa2012-09-14 07:53:05 +02003690}
3691
Emeric Brun81c00f02012-09-21 14:31:21 +02003692/* parse the "crt_ignerr" and "ca_ignerr" bind keywords */
3693static int bind_parse_ignore_err(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
3694{
3695 int code;
3696 char *p = args[cur_arg + 1];
3697 unsigned long long *ignerr = &conf->crt_ignerr;
3698
3699 if (!*p) {
3700 if (err)
3701 memprintf(err, "'%s' : missing error IDs list", args[cur_arg]);
3702 return ERR_ALERT | ERR_FATAL;
3703 }
3704
3705 if (strcmp(args[cur_arg], "ca-ignore-err") == 0)
3706 ignerr = &conf->ca_ignerr;
3707
3708 if (strcmp(p, "all") == 0) {
3709 *ignerr = ~0ULL;
3710 return 0;
3711 }
3712
3713 while (p) {
3714 code = atoi(p);
3715 if ((code <= 0) || (code > 63)) {
3716 if (err)
3717 memprintf(err, "'%s' : ID '%d' out of range (1..63) in error IDs list '%s'",
3718 args[cur_arg], code, args[cur_arg + 1]);
3719 return ERR_ALERT | ERR_FATAL;
3720 }
3721 *ignerr |= 1ULL << code;
3722 p = strchr(p, ',');
3723 if (p)
3724 p++;
3725 }
3726
Emeric Brun2cb7ae52012-10-05 14:14:21 +02003727 return 0;
3728}
3729
3730/* parse the "force-sslv3" bind keyword */
3731static int bind_parse_force_sslv3(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
3732{
3733 conf->ssl_options |= BC_SSL_O_USE_SSLV3;
3734 return 0;
3735}
3736
3737/* parse the "force-tlsv10" bind keyword */
3738static int bind_parse_force_tlsv10(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
3739{
3740 conf->ssl_options |= BC_SSL_O_USE_TLSV10;
Emeric Brun2d0c4822012-10-02 13:45:20 +02003741 return 0;
3742}
3743
Emeric Brun2cb7ae52012-10-05 14:14:21 +02003744/* parse the "force-tlsv11" bind keyword */
3745static int bind_parse_force_tlsv11(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
3746{
3747#if SSL_OP_NO_TLSv1_1
3748 conf->ssl_options |= BC_SSL_O_USE_TLSV11;
3749 return 0;
3750#else
3751 if (err)
3752 memprintf(err, "'%s' : library does not support protocol TLSv1.1", args[cur_arg]);
3753 return ERR_ALERT | ERR_FATAL;
3754#endif
3755}
3756
3757/* parse the "force-tlsv12" bind keyword */
3758static int bind_parse_force_tlsv12(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
3759{
3760#if SSL_OP_NO_TLSv1_2
3761 conf->ssl_options |= BC_SSL_O_USE_TLSV12;
3762 return 0;
3763#else
3764 if (err)
3765 memprintf(err, "'%s' : library does not support protocol TLSv1.2", args[cur_arg]);
3766 return ERR_ALERT | ERR_FATAL;
3767#endif
3768}
3769
3770
Emeric Brun2d0c4822012-10-02 13:45:20 +02003771/* parse the "no-tls-tickets" bind keyword */
3772static int bind_parse_no_tls_tickets(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
3773{
Emeric Brun89675492012-10-05 13:48:26 +02003774 conf->ssl_options |= BC_SSL_O_NO_TLS_TICKETS;
Emeric Brun81c00f02012-09-21 14:31:21 +02003775 return 0;
3776}
3777
Emeric Brun2d0c4822012-10-02 13:45:20 +02003778
Emeric Brun9b3009b2012-10-05 11:55:06 +02003779/* parse the "no-sslv3" bind keyword */
3780static 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 +02003781{
Emeric Brun89675492012-10-05 13:48:26 +02003782 conf->ssl_options |= BC_SSL_O_NO_SSLV3;
Willy Tarreau79eeafa2012-09-14 07:53:05 +02003783 return 0;
3784}
3785
Emeric Brun9b3009b2012-10-05 11:55:06 +02003786/* parse the "no-tlsv10" bind keyword */
3787static 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 +02003788{
Emeric Brun89675492012-10-05 13:48:26 +02003789 conf->ssl_options |= BC_SSL_O_NO_TLSV10;
Emeric Brunc0ff4922012-09-28 19:37:02 +02003790 return 0;
3791}
3792
Emeric Brun9b3009b2012-10-05 11:55:06 +02003793/* parse the "no-tlsv11" bind keyword */
3794static 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 +02003795{
Emeric Brun89675492012-10-05 13:48:26 +02003796 conf->ssl_options |= BC_SSL_O_NO_TLSV11;
Emeric Brunc0ff4922012-09-28 19:37:02 +02003797 return 0;
3798}
3799
Emeric Brun9b3009b2012-10-05 11:55:06 +02003800/* parse the "no-tlsv12" bind keyword */
3801static 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 +02003802{
Emeric Brun89675492012-10-05 13:48:26 +02003803 conf->ssl_options |= BC_SSL_O_NO_TLSV12;
Willy Tarreau79eeafa2012-09-14 07:53:05 +02003804 return 0;
3805}
3806
Willy Tarreau6c9a3d52012-10-18 18:57:14 +02003807/* parse the "npn" bind keyword */
3808static int bind_parse_npn(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
3809{
3810#ifdef OPENSSL_NPN_NEGOTIATED
3811 char *p1, *p2;
3812
3813 if (!*args[cur_arg + 1]) {
3814 memprintf(err, "'%s' : missing the comma-delimited NPN protocol suite", args[cur_arg]);
3815 return ERR_ALERT | ERR_FATAL;
3816 }
3817
3818 free(conf->npn_str);
3819
3820 /* the NPN string is built as a suite of (<len> <name>)* */
3821 conf->npn_len = strlen(args[cur_arg + 1]) + 1;
3822 conf->npn_str = calloc(1, conf->npn_len);
3823 memcpy(conf->npn_str + 1, args[cur_arg + 1], conf->npn_len);
3824
3825 /* replace commas with the name length */
3826 p1 = conf->npn_str;
3827 p2 = p1 + 1;
3828 while (1) {
3829 p2 = memchr(p1 + 1, ',', conf->npn_str + conf->npn_len - (p1 + 1));
3830 if (!p2)
3831 p2 = p1 + 1 + strlen(p1 + 1);
3832
3833 if (p2 - (p1 + 1) > 255) {
3834 *p2 = '\0';
3835 memprintf(err, "'%s' : NPN protocol name too long : '%s'", args[cur_arg], p1 + 1);
3836 return ERR_ALERT | ERR_FATAL;
3837 }
3838
3839 *p1 = p2 - (p1 + 1);
3840 p1 = p2;
3841
3842 if (!*p2)
3843 break;
3844
3845 *(p2++) = '\0';
3846 }
3847 return 0;
3848#else
3849 if (err)
3850 memprintf(err, "'%s' : library does not support TLS NPN extension", args[cur_arg]);
3851 return ERR_ALERT | ERR_FATAL;
3852#endif
3853}
3854
Willy Tarreauab861d32013-04-02 02:30:41 +02003855/* parse the "alpn" bind keyword */
3856static int bind_parse_alpn(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
3857{
Dirkjan Bussink48f1c4e2014-02-13 12:29:42 +01003858#ifdef TLSEXT_TYPE_application_layer_protocol_negotiation
Willy Tarreauab861d32013-04-02 02:30:41 +02003859 char *p1, *p2;
3860
3861 if (!*args[cur_arg + 1]) {
3862 memprintf(err, "'%s' : missing the comma-delimited ALPN protocol suite", args[cur_arg]);
3863 return ERR_ALERT | ERR_FATAL;
3864 }
3865
3866 free(conf->alpn_str);
3867
3868 /* the ALPN string is built as a suite of (<len> <name>)* */
3869 conf->alpn_len = strlen(args[cur_arg + 1]) + 1;
3870 conf->alpn_str = calloc(1, conf->alpn_len);
3871 memcpy(conf->alpn_str + 1, args[cur_arg + 1], conf->alpn_len);
3872
3873 /* replace commas with the name length */
3874 p1 = conf->alpn_str;
3875 p2 = p1 + 1;
3876 while (1) {
3877 p2 = memchr(p1 + 1, ',', conf->alpn_str + conf->alpn_len - (p1 + 1));
3878 if (!p2)
3879 p2 = p1 + 1 + strlen(p1 + 1);
3880
3881 if (p2 - (p1 + 1) > 255) {
3882 *p2 = '\0';
3883 memprintf(err, "'%s' : ALPN protocol name too long : '%s'", args[cur_arg], p1 + 1);
3884 return ERR_ALERT | ERR_FATAL;
3885 }
3886
3887 *p1 = p2 - (p1 + 1);
3888 p1 = p2;
3889
3890 if (!*p2)
3891 break;
3892
3893 *(p2++) = '\0';
3894 }
3895 return 0;
3896#else
3897 if (err)
3898 memprintf(err, "'%s' : library does not support TLS ALPN extension", args[cur_arg]);
3899 return ERR_ALERT | ERR_FATAL;
3900#endif
3901}
3902
Willy Tarreau79eeafa2012-09-14 07:53:05 +02003903/* parse the "ssl" bind keyword */
Willy Tarreau4348fad2012-09-20 16:48:07 +02003904static 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 +02003905{
Willy Tarreau81796be2012-09-22 19:11:47 +02003906 struct listener *l;
3907
Willy Tarreau4348fad2012-09-20 16:48:07 +02003908 conf->is_ssl = 1;
Emeric Brun76d88952012-10-05 15:47:31 +02003909
3910 if (global.listen_default_ciphers && !conf->ciphers)
3911 conf->ciphers = strdup(global.listen_default_ciphers);
3912
Willy Tarreau81796be2012-09-22 19:11:47 +02003913 list_for_each_entry(l, &conf->listeners, by_bind)
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02003914 l->xprt = &ssl_sock;
Willy Tarreau81796be2012-09-22 19:11:47 +02003915
Willy Tarreau79eeafa2012-09-14 07:53:05 +02003916 return 0;
3917}
3918
Emmanuel Hocdet65623372013-01-24 17:17:15 +01003919/* parse the "strict-sni" bind keyword */
3920static int bind_parse_strict_sni(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
3921{
3922 conf->strict_sni = 1;
3923 return 0;
3924}
3925
Emeric Brund94b3fe2012-09-20 18:23:56 +02003926/* parse the "verify" bind keyword */
3927static int bind_parse_verify(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
3928{
3929 if (!*args[cur_arg + 1]) {
3930 if (err)
3931 memprintf(err, "'%s' : missing verify method", args[cur_arg]);
3932 return ERR_ALERT | ERR_FATAL;
3933 }
3934
3935 if (strcmp(args[cur_arg + 1], "none") == 0)
Emeric Brun850efd52014-01-29 12:24:34 +01003936 conf->verify = SSL_SOCK_VERIFY_NONE;
Emeric Brund94b3fe2012-09-20 18:23:56 +02003937 else if (strcmp(args[cur_arg + 1], "optional") == 0)
Emeric Brun850efd52014-01-29 12:24:34 +01003938 conf->verify = SSL_SOCK_VERIFY_OPTIONAL;
Emeric Brund94b3fe2012-09-20 18:23:56 +02003939 else if (strcmp(args[cur_arg + 1], "required") == 0)
Emeric Brun850efd52014-01-29 12:24:34 +01003940 conf->verify = SSL_SOCK_VERIFY_REQUIRED;
Emeric Brund94b3fe2012-09-20 18:23:56 +02003941 else {
3942 if (err)
3943 memprintf(err, "'%s' : unknown verify method '%s', only 'none', 'optional', and 'required' are supported\n",
3944 args[cur_arg], args[cur_arg + 1]);
3945 return ERR_ALERT | ERR_FATAL;
3946 }
3947
3948 return 0;
3949}
3950
Willy Tarreau92faadf2012-10-10 23:04:25 +02003951/************** "server" keywords ****************/
3952
Emeric Brunef42d922012-10-11 16:11:36 +02003953/* parse the "ca-file" server keyword */
3954static int srv_parse_ca_file(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
3955{
3956 if (!*args[*cur_arg + 1]) {
3957 if (err)
3958 memprintf(err, "'%s' : missing CAfile path", args[*cur_arg]);
3959 return ERR_ALERT | ERR_FATAL;
3960 }
3961
3962 if ((*args[*cur_arg + 1] != '/') && global.ca_base)
3963 memprintf(&newsrv->ssl_ctx.ca_file, "%s/%s", global.ca_base, args[*cur_arg + 1]);
3964 else
3965 memprintf(&newsrv->ssl_ctx.ca_file, "%s", args[*cur_arg + 1]);
3966
3967 return 0;
3968}
3969
Willy Tarreau92faadf2012-10-10 23:04:25 +02003970/* parse the "check-ssl" server keyword */
3971static int srv_parse_check_ssl(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
3972{
3973 newsrv->check.use_ssl = 1;
3974 if (global.connect_default_ciphers && !newsrv->ssl_ctx.ciphers)
3975 newsrv->ssl_ctx.ciphers = strdup(global.connect_default_ciphers);
3976 return 0;
3977}
3978
3979/* parse the "ciphers" server keyword */
3980static int srv_parse_ciphers(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
3981{
3982 if (!*args[*cur_arg + 1]) {
3983 memprintf(err, "'%s' : missing cipher suite", args[*cur_arg]);
3984 return ERR_ALERT | ERR_FATAL;
3985 }
3986
3987 free(newsrv->ssl_ctx.ciphers);
3988 newsrv->ssl_ctx.ciphers = strdup(args[*cur_arg + 1]);
3989 return 0;
3990}
3991
Emeric Brunef42d922012-10-11 16:11:36 +02003992/* parse the "crl-file" server keyword */
3993static int srv_parse_crl_file(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
3994{
3995#ifndef X509_V_FLAG_CRL_CHECK
3996 if (err)
3997 memprintf(err, "'%s' : library does not support CRL verify", args[*cur_arg]);
3998 return ERR_ALERT | ERR_FATAL;
3999#else
4000 if (!*args[*cur_arg + 1]) {
4001 if (err)
4002 memprintf(err, "'%s' : missing CRLfile path", args[*cur_arg]);
4003 return ERR_ALERT | ERR_FATAL;
4004 }
4005
4006 if ((*args[*cur_arg + 1] != '/') && global.ca_base)
4007 memprintf(&newsrv->ssl_ctx.crl_file, "%s/%s", global.ca_base, args[*cur_arg + 1]);
4008 else
4009 memprintf(&newsrv->ssl_ctx.crl_file, "%s", args[*cur_arg + 1]);
4010
4011 return 0;
4012#endif
4013}
4014
Emeric Bruna7aa3092012-10-26 12:58:00 +02004015/* parse the "crt" server keyword */
4016static int srv_parse_crt(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
4017{
4018 if (!*args[*cur_arg + 1]) {
4019 if (err)
4020 memprintf(err, "'%s' : missing certificate file path", args[*cur_arg]);
4021 return ERR_ALERT | ERR_FATAL;
4022 }
4023
4024 if ((*args[*cur_arg + 1] != '/') && global.crt_base)
4025 memprintf(&newsrv->ssl_ctx.client_crt, "%s/%s", global.ca_base, args[*cur_arg + 1]);
4026 else
4027 memprintf(&newsrv->ssl_ctx.client_crt, "%s", args[*cur_arg + 1]);
4028
4029 return 0;
4030}
Emeric Brunef42d922012-10-11 16:11:36 +02004031
Willy Tarreau92faadf2012-10-10 23:04:25 +02004032/* parse the "force-sslv3" server keyword */
4033static int srv_parse_force_sslv3(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
4034{
4035 newsrv->ssl_ctx.options |= SRV_SSL_O_USE_SSLV3;
4036 return 0;
4037}
4038
4039/* parse the "force-tlsv10" server keyword */
4040static int srv_parse_force_tlsv10(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
4041{
4042 newsrv->ssl_ctx.options |= SRV_SSL_O_USE_TLSV10;
4043 return 0;
4044}
4045
4046/* parse the "force-tlsv11" server keyword */
4047static int srv_parse_force_tlsv11(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
4048{
4049#if SSL_OP_NO_TLSv1_1
4050 newsrv->ssl_ctx.options |= SRV_SSL_O_USE_TLSV11;
4051 return 0;
4052#else
4053 if (err)
4054 memprintf(err, "'%s' : library does not support protocol TLSv1.1", args[*cur_arg]);
4055 return ERR_ALERT | ERR_FATAL;
4056#endif
4057}
4058
4059/* parse the "force-tlsv12" server keyword */
4060static int srv_parse_force_tlsv12(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
4061{
4062#if SSL_OP_NO_TLSv1_2
4063 newsrv->ssl_ctx.options |= SRV_SSL_O_USE_TLSV12;
4064 return 0;
4065#else
4066 if (err)
4067 memprintf(err, "'%s' : library does not support protocol TLSv1.2", args[*cur_arg]);
4068 return ERR_ALERT | ERR_FATAL;
4069#endif
4070}
4071
4072/* parse the "no-sslv3" server keyword */
4073static int srv_parse_no_sslv3(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
4074{
4075 newsrv->ssl_ctx.options |= SRV_SSL_O_NO_SSLV3;
4076 return 0;
4077}
4078
4079/* parse the "no-tlsv10" server keyword */
4080static int srv_parse_no_tlsv10(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
4081{
4082 newsrv->ssl_ctx.options |= SRV_SSL_O_NO_TLSV10;
4083 return 0;
4084}
4085
4086/* parse the "no-tlsv11" server keyword */
4087static int srv_parse_no_tlsv11(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
4088{
4089 newsrv->ssl_ctx.options |= SRV_SSL_O_NO_TLSV11;
4090 return 0;
4091}
4092
4093/* parse the "no-tlsv12" server keyword */
4094static int srv_parse_no_tlsv12(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
4095{
4096 newsrv->ssl_ctx.options |= SRV_SSL_O_NO_TLSV12;
4097 return 0;
4098}
4099
Emeric Brunf9c5c472012-10-11 15:28:34 +02004100/* parse the "no-tls-tickets" server keyword */
4101static int srv_parse_no_tls_tickets(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
4102{
4103 newsrv->ssl_ctx.options |= SRV_SSL_O_NO_TLS_TICKETS;
4104 return 0;
4105}
David Safb76832014-05-08 23:42:08 -04004106/* parse the "send-proxy-v2-ssl" server keyword */
4107static int srv_parse_send_proxy_ssl(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
4108{
4109 newsrv->pp_opts |= SRV_PP_V2;
4110 newsrv->pp_opts |= SRV_PP_V2_SSL;
4111 return 0;
4112}
4113
4114/* parse the "send-proxy-v2-ssl-cn" server keyword */
4115static int srv_parse_send_proxy_cn(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
4116{
4117 newsrv->pp_opts |= SRV_PP_V2;
4118 newsrv->pp_opts |= SRV_PP_V2_SSL;
4119 newsrv->pp_opts |= SRV_PP_V2_SSL_CN;
4120 return 0;
4121}
Emeric Brunf9c5c472012-10-11 15:28:34 +02004122
Willy Tarreau92faadf2012-10-10 23:04:25 +02004123/* parse the "ssl" server keyword */
4124static int srv_parse_ssl(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
4125{
4126 newsrv->use_ssl = 1;
4127 if (global.connect_default_ciphers && !newsrv->ssl_ctx.ciphers)
4128 newsrv->ssl_ctx.ciphers = strdup(global.connect_default_ciphers);
4129 return 0;
4130}
4131
Emeric Brunef42d922012-10-11 16:11:36 +02004132/* parse the "verify" server keyword */
4133static int srv_parse_verify(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
4134{
4135 if (!*args[*cur_arg + 1]) {
4136 if (err)
4137 memprintf(err, "'%s' : missing verify method", args[*cur_arg]);
4138 return ERR_ALERT | ERR_FATAL;
4139 }
4140
4141 if (strcmp(args[*cur_arg + 1], "none") == 0)
Emeric Brun850efd52014-01-29 12:24:34 +01004142 newsrv->ssl_ctx.verify = SSL_SOCK_VERIFY_NONE;
Emeric Brunef42d922012-10-11 16:11:36 +02004143 else if (strcmp(args[*cur_arg + 1], "required") == 0)
Emeric Brun850efd52014-01-29 12:24:34 +01004144 newsrv->ssl_ctx.verify = SSL_SOCK_VERIFY_REQUIRED;
Emeric Brunef42d922012-10-11 16:11:36 +02004145 else {
4146 if (err)
4147 memprintf(err, "'%s' : unknown verify method '%s', only 'none' and 'required' are supported\n",
4148 args[*cur_arg], args[*cur_arg + 1]);
4149 return ERR_ALERT | ERR_FATAL;
4150 }
4151
Evan Broderbe554312013-06-27 00:05:25 -07004152 return 0;
4153}
4154
4155/* parse the "verifyhost" server keyword */
4156static int srv_parse_verifyhost(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
4157{
4158 if (!*args[*cur_arg + 1]) {
4159 if (err)
4160 memprintf(err, "'%s' : missing hostname to verify against", args[*cur_arg]);
4161 return ERR_ALERT | ERR_FATAL;
4162 }
4163
4164 newsrv->ssl_ctx.verify_host = strdup(args[*cur_arg + 1]);
4165
Emeric Brunef42d922012-10-11 16:11:36 +02004166 return 0;
4167}
4168
Willy Tarreau7875d092012-09-10 08:20:03 +02004169/* Note: must not be declared <const> as its list will be overwritten.
4170 * Please take care of keeping this list alphabetically sorted.
4171 */
Willy Tarreaudc13c112013-06-21 23:16:39 +02004172static struct sample_fetch_kw_list sample_fetch_keywords = {ILH, {
Emeric Brun645ae792014-04-30 14:21:06 +02004173 { "ssl_bc", smp_fetch_ssl_fc, 0, NULL, SMP_T_BOOL, SMP_USE_L5SRV },
4174 { "ssl_bc_alg_keysize", smp_fetch_ssl_fc_alg_keysize, 0, NULL, SMP_T_UINT, SMP_USE_L5SRV },
4175 { "ssl_bc_cipher", smp_fetch_ssl_fc_cipher, 0, NULL, SMP_T_STR, SMP_USE_L5SRV },
4176 { "ssl_bc_protocol", smp_fetch_ssl_fc_protocol, 0, NULL, SMP_T_STR, SMP_USE_L5SRV },
Emeric Brunb73a9b02014-04-30 18:49:19 +02004177 { "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 +02004178 { "ssl_bc_use_keysize", smp_fetch_ssl_fc_use_keysize, 0, NULL, SMP_T_UINT, SMP_USE_L5SRV },
4179 { "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 +01004180 { "ssl_c_ca_err", smp_fetch_ssl_c_ca_err, 0, NULL, SMP_T_UINT, SMP_USE_L5CLI },
4181 { "ssl_c_ca_err_depth", smp_fetch_ssl_c_ca_err_depth, 0, NULL, SMP_T_UINT, SMP_USE_L5CLI },
4182 { "ssl_c_err", smp_fetch_ssl_c_err, 0, NULL, SMP_T_UINT, SMP_USE_L5CLI },
Emeric Brunba841a12014-04-30 17:05:08 +02004183 { "ssl_c_i_dn", smp_fetch_ssl_x_i_dn, ARG2(0,STR,SINT), NULL, SMP_T_STR, SMP_USE_L5CLI },
4184 { "ssl_c_key_alg", smp_fetch_ssl_x_key_alg, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
4185 { "ssl_c_notafter", smp_fetch_ssl_x_notafter, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
4186 { "ssl_c_notbefore", smp_fetch_ssl_x_notbefore, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
4187 { "ssl_c_sig_alg", smp_fetch_ssl_x_sig_alg, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
4188 { "ssl_c_s_dn", smp_fetch_ssl_x_s_dn, ARG2(0,STR,SINT), NULL, SMP_T_STR, SMP_USE_L5CLI },
4189 { "ssl_c_serial", smp_fetch_ssl_x_serial, 0, NULL, SMP_T_BIN, SMP_USE_L5CLI },
4190 { "ssl_c_sha1", smp_fetch_ssl_x_sha1, 0, NULL, SMP_T_BIN, SMP_USE_L5CLI },
Willy Tarreau80aca902013-01-07 15:42:20 +01004191 { "ssl_c_used", smp_fetch_ssl_c_used, 0, NULL, SMP_T_BOOL, SMP_USE_L5CLI },
4192 { "ssl_c_verify", smp_fetch_ssl_c_verify, 0, NULL, SMP_T_UINT, SMP_USE_L5CLI },
Emeric Brunba841a12014-04-30 17:05:08 +02004193 { "ssl_c_version", smp_fetch_ssl_x_version, 0, NULL, SMP_T_UINT, SMP_USE_L5CLI },
4194 { "ssl_f_i_dn", smp_fetch_ssl_x_i_dn, ARG2(0,STR,SINT), NULL, SMP_T_STR, SMP_USE_L5CLI },
4195 { "ssl_f_key_alg", smp_fetch_ssl_x_key_alg, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
4196 { "ssl_f_notafter", smp_fetch_ssl_x_notafter, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
4197 { "ssl_f_notbefore", smp_fetch_ssl_x_notbefore, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
4198 { "ssl_f_sig_alg", smp_fetch_ssl_x_sig_alg, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
4199 { "ssl_f_s_dn", smp_fetch_ssl_x_s_dn, ARG2(0,STR,SINT), NULL, SMP_T_STR, SMP_USE_L5CLI },
4200 { "ssl_f_serial", smp_fetch_ssl_x_serial, 0, NULL, SMP_T_BIN, SMP_USE_L5CLI },
Emeric Brun55f4fa82014-04-30 17:11:25 +02004201 { "ssl_f_sha1", smp_fetch_ssl_x_sha1, 0, NULL, SMP_T_BIN, SMP_USE_L5CLI },
Emeric Brunba841a12014-04-30 17:05:08 +02004202 { "ssl_f_version", smp_fetch_ssl_x_version, 0, NULL, SMP_T_UINT, SMP_USE_L5CLI },
Willy Tarreau80aca902013-01-07 15:42:20 +01004203 { "ssl_fc", smp_fetch_ssl_fc, 0, NULL, SMP_T_BOOL, SMP_USE_L5CLI },
4204 { "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 +01004205 { "ssl_fc_cipher", smp_fetch_ssl_fc_cipher, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
Willy Tarreau80aca902013-01-07 15:42:20 +01004206 { "ssl_fc_has_crt", smp_fetch_ssl_fc_has_crt, 0, NULL, SMP_T_BOOL, SMP_USE_L5CLI },
4207 { "ssl_fc_has_sni", smp_fetch_ssl_fc_has_sni, 0, NULL, SMP_T_BOOL, SMP_USE_L5CLI },
Willy Tarreaua33c6542012-10-15 13:19:06 +02004208#ifdef OPENSSL_NPN_NEGOTIATED
Thierry FOURNIER7654c9f2013-12-17 00:20:33 +01004209 { "ssl_fc_npn", smp_fetch_ssl_fc_npn, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
Willy Tarreaua33c6542012-10-15 13:19:06 +02004210#endif
Dirkjan Bussink48f1c4e2014-02-13 12:29:42 +01004211#ifdef TLSEXT_TYPE_application_layer_protocol_negotiation
Thierry FOURNIER7654c9f2013-12-17 00:20:33 +01004212 { "ssl_fc_alpn", smp_fetch_ssl_fc_alpn, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
Willy Tarreauab861d32013-04-02 02:30:41 +02004213#endif
Thierry FOURNIER7654c9f2013-12-17 00:20:33 +01004214 { "ssl_fc_protocol", smp_fetch_ssl_fc_protocol, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
Emeric Brunb73a9b02014-04-30 18:49:19 +02004215 { "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 +01004216 { "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 +01004217 { "ssl_fc_session_id", smp_fetch_ssl_fc_session_id, 0, NULL, SMP_T_BIN, SMP_USE_L5CLI },
4218 { "ssl_fc_sni", smp_fetch_ssl_fc_sni, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
Willy Tarreau7875d092012-09-10 08:20:03 +02004219 { NULL, NULL, 0, 0, 0 },
4220}};
4221
4222/* Note: must not be declared <const> as its list will be overwritten.
4223 * Please take care of keeping this list alphabetically sorted.
4224 */
Willy Tarreaudc13c112013-06-21 23:16:39 +02004225static struct acl_kw_list acl_kws = {ILH, {
Thierry FOURNIERc5a4e982014-03-05 16:07:08 +01004226 { "ssl_fc_sni_end", "ssl_fc_sni", PAT_MATCH_END },
4227 { "ssl_fc_sni_reg", "ssl_fc_sni", PAT_MATCH_REG },
Willy Tarreau8ed669b2013-01-11 15:49:37 +01004228 { /* END */ },
Willy Tarreau7875d092012-09-10 08:20:03 +02004229}};
4230
Willy Tarreau79eeafa2012-09-14 07:53:05 +02004231/* Note: must not be declared <const> as its list will be overwritten.
4232 * Please take care of keeping this list alphabetically sorted, doing so helps
4233 * all code contributors.
4234 * Optional keywords are also declared with a NULL ->parse() function so that
4235 * the config parser can report an appropriate error when a known keyword was
4236 * not enabled.
4237 */
Willy Tarreau51fb7652012-09-18 18:24:39 +02004238static struct bind_kw_list bind_kws = { "SSL", { }, {
Willy Tarreauab861d32013-04-02 02:30:41 +02004239 { "alpn", bind_parse_alpn, 1 }, /* set ALPN supported protocols */
Emeric Brunfb510ea2012-10-05 12:00:26 +02004240 { "ca-file", bind_parse_ca_file, 1 }, /* set CAfile to process verify on client cert */
Emeric Brun2d0c4822012-10-02 13:45:20 +02004241 { "ca-ignore-err", bind_parse_ignore_err, 1 }, /* set error IDs to ignore on verify depth > 0 */
4242 { "ciphers", bind_parse_ciphers, 1 }, /* set SSL cipher suite */
Emeric Brunfb510ea2012-10-05 12:00:26 +02004243 { "crl-file", bind_parse_crl_file, 1 }, /* set certificat revocation list file use on client cert verify */
Emeric Brun2d0c4822012-10-02 13:45:20 +02004244 { "crt", bind_parse_crt, 1 }, /* load SSL certificates from this location */
4245 { "crt-ignore-err", bind_parse_ignore_err, 1 }, /* set error IDs to ingore on verify depth == 0 */
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01004246 { "crt-list", bind_parse_crt_list, 1 }, /* load a list of crt from this location */
Emeric Brun2d0c4822012-10-02 13:45:20 +02004247 { "ecdhe", bind_parse_ecdhe, 1 }, /* defines named curve for elliptic curve Diffie-Hellman */
Emeric Brun2cb7ae52012-10-05 14:14:21 +02004248 { "force-sslv3", bind_parse_force_sslv3, 0 }, /* force SSLv3 */
4249 { "force-tlsv10", bind_parse_force_tlsv10, 0 }, /* force TLSv10 */
4250 { "force-tlsv11", bind_parse_force_tlsv11, 0 }, /* force TLSv11 */
4251 { "force-tlsv12", bind_parse_force_tlsv12, 0 }, /* force TLSv12 */
Emeric Brun9b3009b2012-10-05 11:55:06 +02004252 { "no-sslv3", bind_parse_no_sslv3, 0 }, /* disable SSLv3 */
4253 { "no-tlsv10", bind_parse_no_tlsv10, 0 }, /* disable TLSv10 */
4254 { "no-tlsv11", bind_parse_no_tlsv11, 0 }, /* disable TLSv11 */
4255 { "no-tlsv12", bind_parse_no_tlsv12, 0 }, /* disable TLSv12 */
Emeric Brun2d0c4822012-10-02 13:45:20 +02004256 { "no-tls-tickets", bind_parse_no_tls_tickets, 0 }, /* disable session resumption tickets */
Emeric Brun2d0c4822012-10-02 13:45:20 +02004257 { "ssl", bind_parse_ssl, 0 }, /* enable SSL processing */
Emmanuel Hocdet65623372013-01-24 17:17:15 +01004258 { "strict-sni", bind_parse_strict_sni, 0 }, /* refuse negotiation if sni doesn't match a certificate */
Emeric Brun2d0c4822012-10-02 13:45:20 +02004259 { "verify", bind_parse_verify, 1 }, /* set SSL verify method */
Willy Tarreau6c9a3d52012-10-18 18:57:14 +02004260 { "npn", bind_parse_npn, 1 }, /* set NPN supported protocols */
Willy Tarreau79eeafa2012-09-14 07:53:05 +02004261 { NULL, NULL, 0 },
4262}};
Emeric Brun46591952012-05-18 15:47:34 +02004263
Willy Tarreau92faadf2012-10-10 23:04:25 +02004264/* Note: must not be declared <const> as its list will be overwritten.
4265 * Please take care of keeping this list alphabetically sorted, doing so helps
4266 * all code contributors.
4267 * Optional keywords are also declared with a NULL ->parse() function so that
4268 * the config parser can report an appropriate error when a known keyword was
4269 * not enabled.
4270 */
4271static struct srv_kw_list srv_kws = { "SSL", { }, {
Emeric Brunef42d922012-10-11 16:11:36 +02004272 { "ca-file", srv_parse_ca_file, 1, 0 }, /* set CAfile to process verify server cert */
Emeric Brunecc91fe2012-10-11 15:05:10 +02004273 { "check-ssl", srv_parse_check_ssl, 0, 0 }, /* enable SSL for health checks */
4274 { "ciphers", srv_parse_ciphers, 1, 0 }, /* select the cipher suite */
Emeric Brunef42d922012-10-11 16:11:36 +02004275 { "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 +02004276 { "crt", srv_parse_crt, 1, 0 }, /* set client certificate */
Emeric Brunecc91fe2012-10-11 15:05:10 +02004277 { "force-sslv3", srv_parse_force_sslv3, 0, 0 }, /* force SSLv3 */
4278 { "force-tlsv10", srv_parse_force_tlsv10, 0, 0 }, /* force TLSv10 */
4279 { "force-tlsv11", srv_parse_force_tlsv11, 0, 0 }, /* force TLSv11 */
4280 { "force-tlsv12", srv_parse_force_tlsv12, 0, 0 }, /* force TLSv12 */
4281 { "no-sslv3", srv_parse_no_sslv3, 0, 0 }, /* disable SSLv3 */
4282 { "no-tlsv10", srv_parse_no_tlsv10, 0, 0 }, /* disable TLSv10 */
4283 { "no-tlsv11", srv_parse_no_tlsv11, 0, 0 }, /* disable TLSv11 */
4284 { "no-tlsv12", srv_parse_no_tlsv12, 0, 0 }, /* disable TLSv12 */
Emeric Brunf9c5c472012-10-11 15:28:34 +02004285 { "no-tls-tickets", srv_parse_no_tls_tickets, 0, 0 }, /* disable session resumption tickets */
David Safb76832014-05-08 23:42:08 -04004286 { "send-proxy-v2-ssl", srv_parse_send_proxy_ssl, 0, 0 }, /* send PROXY protocol header v2 with SSL info */
4287 { "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 +02004288 { "ssl", srv_parse_ssl, 0, 0 }, /* enable SSL processing */
Emeric Brunef42d922012-10-11 16:11:36 +02004289 { "verify", srv_parse_verify, 1, 0 }, /* set SSL verify method */
Evan Broderbe554312013-06-27 00:05:25 -07004290 { "verifyhost", srv_parse_verifyhost, 1, 0 }, /* require that SSL cert verifies for hostname */
Willy Tarreau92faadf2012-10-10 23:04:25 +02004291 { NULL, NULL, 0, 0 },
4292}};
4293
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02004294/* transport-layer operations for SSL sockets */
4295struct xprt_ops ssl_sock = {
Emeric Brun46591952012-05-18 15:47:34 +02004296 .snd_buf = ssl_sock_from_buf,
4297 .rcv_buf = ssl_sock_to_buf,
4298 .rcv_pipe = NULL,
4299 .snd_pipe = NULL,
4300 .shutr = NULL,
4301 .shutw = ssl_sock_shutw,
4302 .close = ssl_sock_close,
4303 .init = ssl_sock_init,
4304};
4305
4306__attribute__((constructor))
Willy Tarreau92faadf2012-10-10 23:04:25 +02004307static void __ssl_sock_init(void)
4308{
Emeric Brun46591952012-05-18 15:47:34 +02004309 STACK_OF(SSL_COMP)* cm;
4310
Willy Tarreau610f04b2014-02-13 11:36:41 +01004311#ifdef LISTEN_DEFAULT_CIPHERS
4312 global.listen_default_ciphers = LISTEN_DEFAULT_CIPHERS;
4313#endif
4314#ifdef CONNECT_DEFAULT_CIPHERS
4315 global.connect_default_ciphers = CONNECT_DEFAULT_CIPHERS;
4316#endif
4317 if (global.listen_default_ciphers)
4318 global.listen_default_ciphers = strdup(global.listen_default_ciphers);
4319 if (global.connect_default_ciphers)
4320 global.connect_default_ciphers = strdup(global.connect_default_ciphers);
4321
Emeric Brun46591952012-05-18 15:47:34 +02004322 SSL_library_init();
4323 cm = SSL_COMP_get_compression_methods();
4324 sk_SSL_COMP_zero(cm);
Willy Tarreau7875d092012-09-10 08:20:03 +02004325 sample_register_fetches(&sample_fetch_keywords);
4326 acl_register_keywords(&acl_kws);
Willy Tarreau79eeafa2012-09-14 07:53:05 +02004327 bind_register_keywords(&bind_kws);
Willy Tarreau92faadf2012-10-10 23:04:25 +02004328 srv_register_keywords(&srv_kws);
Emeric Brun46591952012-05-18 15:47:34 +02004329}
4330
4331/*
4332 * Local variables:
4333 * c-indent-level: 8
4334 * c-basic-offset: 8
4335 * End:
4336 */