blob: b095f8c1a58cbdd5f9d31bbc0bb655614705820c [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 Brun46591952012-05-18 15:47:34 +020047
48#include <common/buffer.h>
49#include <common/compat.h>
50#include <common/config.h>
51#include <common/debug.h>
Willy Tarreau79eeafa2012-09-14 07:53:05 +020052#include <common/errors.h>
Emeric Brun46591952012-05-18 15:47:34 +020053#include <common/standard.h>
54#include <common/ticks.h>
55#include <common/time.h>
56
Emeric Brunfc0421f2012-09-07 17:30:07 +020057#include <ebsttree.h>
58
59#include <types/global.h>
60#include <types/ssl_sock.h>
61
Willy Tarreau7875d092012-09-10 08:20:03 +020062#include <proto/acl.h>
63#include <proto/arg.h>
Emeric Brun46591952012-05-18 15:47:34 +020064#include <proto/connection.h>
65#include <proto/fd.h>
66#include <proto/freq_ctr.h>
67#include <proto/frontend.h>
Willy Tarreau79eeafa2012-09-14 07:53:05 +020068#include <proto/listener.h>
Thierry FOURNIERed66c292013-11-28 11:05:19 +010069#include <proto/pattern.h>
Willy Tarreau92faadf2012-10-10 23:04:25 +020070#include <proto/server.h>
Emeric Brun46591952012-05-18 15:47:34 +020071#include <proto/log.h>
Emeric Brun94324a42012-10-11 14:00:19 +020072#include <proto/proxy.h>
Emeric Brunfc0421f2012-09-07 17:30:07 +020073#include <proto/shctx.h>
Emeric Brun46591952012-05-18 15:47:34 +020074#include <proto/ssl_sock.h>
75#include <proto/task.h>
76
Willy Tarreau518cedd2014-02-17 15:43:01 +010077/* Warning, these are bits, not integers! */
Emeric Brune64aef12012-09-21 13:15:06 +020078#define SSL_SOCK_ST_FL_VERIFY_DONE 0x00000001
Emeric Brund8b2bb52014-01-28 15:43:53 +010079#define SSL_SOCK_ST_FL_16K_WBFSIZE 0x00000002
Willy Tarreau518cedd2014-02-17 15:43:01 +010080#define SSL_SOCK_SEND_UNLIMITED 0x00000004
Emeric Brunf282a812012-09-21 15:27:54 +020081/* bits 0xFFFF0000 are reserved to store verify errors */
82
83/* Verify errors macros */
84#define SSL_SOCK_CA_ERROR_TO_ST(e) (((e > 63) ? 63 : e) << (16))
85#define SSL_SOCK_CAEDEPTH_TO_ST(d) (((d > 15) ? 15 : d) << (6+16))
86#define SSL_SOCK_CRTERROR_TO_ST(e) (((e > 63) ? 63 : e) << (4+6+16))
87
88#define SSL_SOCK_ST_TO_CA_ERROR(s) ((s >> (16)) & 63)
89#define SSL_SOCK_ST_TO_CAEDEPTH(s) ((s >> (6+16)) & 15)
90#define SSL_SOCK_ST_TO_CRTERROR(s) ((s >> (4+6+16)) & 63)
Emeric Brune64aef12012-09-21 13:15:06 +020091
Emeric Brun850efd52014-01-29 12:24:34 +010092/* server and bind verify method, it uses a global value as default */
93enum {
94 SSL_SOCK_VERIFY_DEFAULT = 0,
95 SSL_SOCK_VERIFY_REQUIRED = 1,
96 SSL_SOCK_VERIFY_OPTIONAL = 2,
97 SSL_SOCK_VERIFY_NONE = 3,
98};
99
Willy Tarreau71b734c2014-01-28 15:19:44 +0100100int sslconns = 0;
101int totalsslconns = 0;
Emeric Brune1f38db2012-09-03 20:36:47 +0200102
103void ssl_sock_infocbk(const SSL *ssl, int where, int ret)
104{
105 struct connection *conn = (struct connection *)SSL_get_app_data(ssl);
106 (void)ret; /* shut gcc stupid warning */
Emeric Brund8b2bb52014-01-28 15:43:53 +0100107 BIO *write_bio;
Emeric Brune1f38db2012-09-03 20:36:47 +0200108
109 if (where & SSL_CB_HANDSHAKE_START) {
110 /* Disable renegotiation (CVE-2009-3555) */
Willy Tarreau20879a02012-12-03 16:32:10 +0100111 if (conn->flags & CO_FL_CONNECTED) {
Emeric Brune1f38db2012-09-03 20:36:47 +0200112 conn->flags |= CO_FL_ERROR;
Willy Tarreau20879a02012-12-03 16:32:10 +0100113 conn->err_code = CO_ER_SSL_RENEG;
114 }
Emeric Brune1f38db2012-09-03 20:36:47 +0200115 }
Emeric Brund8b2bb52014-01-28 15:43:53 +0100116
117 if ((where & SSL_CB_ACCEPT_LOOP) == SSL_CB_ACCEPT_LOOP) {
118 if (!(conn->xprt_st & SSL_SOCK_ST_FL_16K_WBFSIZE)) {
119 /* Long certificate chains optimz
120 If write and read bios are differents, we
121 consider that the buffering was activated,
122 so we rise the output buffer size from 4k
123 to 16k */
124 write_bio = SSL_get_wbio(ssl);
125 if (write_bio != SSL_get_rbio(ssl)) {
126 BIO_set_write_buffer_size(write_bio, 16384);
127 conn->xprt_st |= SSL_SOCK_ST_FL_16K_WBFSIZE;
128 }
129 }
130 }
Emeric Brunfc0421f2012-09-07 17:30:07 +0200131}
132
Emeric Brune64aef12012-09-21 13:15:06 +0200133/* Callback is called for each certificate of the chain during a verify
134 ok is set to 1 if preverify detect no error on current certificate.
135 Returns 0 to break the handshake, 1 otherwise. */
Evan Broderbe554312013-06-27 00:05:25 -0700136int ssl_sock_bind_verifycbk(int ok, X509_STORE_CTX *x_store)
Emeric Brune64aef12012-09-21 13:15:06 +0200137{
138 SSL *ssl;
139 struct connection *conn;
Emeric Brun81c00f02012-09-21 14:31:21 +0200140 int err, depth;
Emeric Brune64aef12012-09-21 13:15:06 +0200141
142 ssl = X509_STORE_CTX_get_ex_data(x_store, SSL_get_ex_data_X509_STORE_CTX_idx());
143 conn = (struct connection *)SSL_get_app_data(ssl);
144
Willy Tarreauf7bc57c2012-10-03 00:19:48 +0200145 conn->xprt_st |= SSL_SOCK_ST_FL_VERIFY_DONE;
Emeric Brune64aef12012-09-21 13:15:06 +0200146
Emeric Brun81c00f02012-09-21 14:31:21 +0200147 if (ok) /* no errors */
148 return ok;
149
150 depth = X509_STORE_CTX_get_error_depth(x_store);
151 err = X509_STORE_CTX_get_error(x_store);
152
153 /* check if CA error needs to be ignored */
154 if (depth > 0) {
Willy Tarreauf7bc57c2012-10-03 00:19:48 +0200155 if (!SSL_SOCK_ST_TO_CA_ERROR(conn->xprt_st)) {
156 conn->xprt_st |= SSL_SOCK_CA_ERROR_TO_ST(err);
157 conn->xprt_st |= SSL_SOCK_CAEDEPTH_TO_ST(depth);
Emeric Brunf282a812012-09-21 15:27:54 +0200158 }
159
Emeric Brun1eb20ef2012-12-03 13:24:29 +0100160 if (objt_listener(conn->target)->bind_conf->ca_ignerr & (1ULL << err)) {
161 ERR_clear_error();
Emeric Brun81c00f02012-09-21 14:31:21 +0200162 return 1;
Emeric Brun1eb20ef2012-12-03 13:24:29 +0100163 }
Emeric Brun81c00f02012-09-21 14:31:21 +0200164
Willy Tarreau20879a02012-12-03 16:32:10 +0100165 conn->err_code = CO_ER_SSL_CA_FAIL;
Emeric Brun81c00f02012-09-21 14:31:21 +0200166 return 0;
167 }
168
Willy Tarreauf7bc57c2012-10-03 00:19:48 +0200169 if (!SSL_SOCK_ST_TO_CRTERROR(conn->xprt_st))
170 conn->xprt_st |= SSL_SOCK_CRTERROR_TO_ST(err);
Emeric Brunf282a812012-09-21 15:27:54 +0200171
Emeric Brun81c00f02012-09-21 14:31:21 +0200172 /* check if certificate error needs to be ignored */
Emeric Brun1eb20ef2012-12-03 13:24:29 +0100173 if (objt_listener(conn->target)->bind_conf->crt_ignerr & (1ULL << err)) {
174 ERR_clear_error();
Emeric Brun81c00f02012-09-21 14:31:21 +0200175 return 1;
Emeric Brun1eb20ef2012-12-03 13:24:29 +0100176 }
Emeric Brun81c00f02012-09-21 14:31:21 +0200177
Willy Tarreau20879a02012-12-03 16:32:10 +0100178 conn->err_code = CO_ER_SSL_CRT_FAIL;
Emeric Brun81c00f02012-09-21 14:31:21 +0200179 return 0;
Emeric Brune64aef12012-09-21 13:15:06 +0200180}
181
Willy Tarreau6c9a3d52012-10-18 18:57:14 +0200182#ifdef OPENSSL_NPN_NEGOTIATED
183/* This callback is used so that the server advertises the list of
184 * negociable protocols for NPN.
185 */
186static int ssl_sock_advertise_npn_protos(SSL *s, const unsigned char **data,
187 unsigned int *len, void *arg)
188{
189 struct bind_conf *conf = arg;
190
191 *data = (const unsigned char *)conf->npn_str;
192 *len = conf->npn_len;
193 return SSL_TLSEXT_ERR_OK;
194}
195#endif
196
Dirkjan Bussink48f1c4e2014-02-13 12:29:42 +0100197#ifdef TLSEXT_TYPE_application_layer_protocol_negotiation
Willy Tarreauab861d32013-04-02 02:30:41 +0200198/* This callback is used so that the server advertises the list of
199 * negociable protocols for ALPN.
200 */
Dirkjan Bussink48f1c4e2014-02-13 12:29:42 +0100201static int ssl_sock_advertise_alpn_protos(SSL *s, const unsigned char **out,
202 unsigned char *outlen,
203 const unsigned char *server,
204 unsigned int server_len, void *arg)
Willy Tarreauab861d32013-04-02 02:30:41 +0200205{
206 struct bind_conf *conf = arg;
207
Dirkjan Bussink48f1c4e2014-02-13 12:29:42 +0100208 if (SSL_select_next_proto((unsigned char**) out, outlen, (const unsigned char *)conf->alpn_str,
209 conf->alpn_len, server, server_len) != OPENSSL_NPN_NEGOTIATED) {
210 return SSL_TLSEXT_ERR_NOACK;
211 }
Willy Tarreauab861d32013-04-02 02:30:41 +0200212 return SSL_TLSEXT_ERR_OK;
213}
214#endif
215
Emeric Brunfc0421f2012-09-07 17:30:07 +0200216#ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME
217/* Sets the SSL ctx of <ssl> to match the advertised server name. Returns a
218 * warning when no match is found, which implies the default (first) cert
219 * will keep being used.
220 */
Willy Tarreau2a65ff02012-09-13 17:54:29 +0200221static int ssl_sock_switchctx_cbk(SSL *ssl, int *al, struct bind_conf *s)
Emeric Brunfc0421f2012-09-07 17:30:07 +0200222{
223 const char *servername;
224 const char *wildp = NULL;
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +0200225 struct ebmb_node *node, *n;
Emeric Brunfc0421f2012-09-07 17:30:07 +0200226 int i;
227 (void)al; /* shut gcc stupid warning */
228
229 servername = SSL_get_servername(ssl, TLSEXT_NAMETYPE_host_name);
Emmanuel Hocdet65623372013-01-24 17:17:15 +0100230 if (!servername) {
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +0200231 return (s->strict_sni ?
232 SSL_TLSEXT_ERR_ALERT_FATAL :
Emmanuel Hocdet79274e22013-05-31 12:47:44 +0200233 SSL_TLSEXT_ERR_NOACK);
Emmanuel Hocdet65623372013-01-24 17:17:15 +0100234 }
Emeric Brunfc0421f2012-09-07 17:30:07 +0200235
Willy Tarreau19d14ef2012-10-29 16:51:55 +0100236 for (i = 0; i < trash.size; i++) {
Emeric Brunfc0421f2012-09-07 17:30:07 +0200237 if (!servername[i])
238 break;
Willy Tarreau19d14ef2012-10-29 16:51:55 +0100239 trash.str[i] = tolower(servername[i]);
240 if (!wildp && (trash.str[i] == '.'))
241 wildp = &trash.str[i];
Emeric Brunfc0421f2012-09-07 17:30:07 +0200242 }
Willy Tarreau19d14ef2012-10-29 16:51:55 +0100243 trash.str[i] = 0;
Emeric Brunfc0421f2012-09-07 17:30:07 +0200244
245 /* lookup in full qualified names */
Willy Tarreau19d14ef2012-10-29 16:51:55 +0100246 node = ebst_lookup(&s->sni_ctx, trash.str);
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +0200247
248 /* lookup a not neg filter */
249 for (n = node; n; n = ebmb_next_dup(n)) {
250 if (!container_of(n, struct sni_ctx, name)->neg) {
251 node = n;
252 break;
Emmanuel Hocdet65623372013-01-24 17:17:15 +0100253 }
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +0200254 }
255 if (!node && wildp) {
256 /* lookup in wildcards names */
Emeric Brunfc0421f2012-09-07 17:30:07 +0200257 node = ebst_lookup(&s->sni_w_ctx, wildp);
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +0200258 }
259 if (!node || container_of(node, struct sni_ctx, name)->neg) {
260 return (s->strict_sni ?
261 SSL_TLSEXT_ERR_ALERT_FATAL :
262 SSL_TLSEXT_ERR_ALERT_WARNING);
Emeric Brunfc0421f2012-09-07 17:30:07 +0200263 }
264
265 /* switch ctx */
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +0200266 SSL_set_SSL_CTX(ssl, container_of(node, struct sni_ctx, name)->ctx);
Emeric Brunfc0421f2012-09-07 17:30:07 +0200267 return SSL_TLSEXT_ERR_OK;
268}
269#endif /* SSL_CTRL_SET_TLSEXT_HOSTNAME */
270
Emeric Bruna4bcd9a2012-09-20 16:19:02 +0200271#ifndef OPENSSL_NO_DH
272/* Loads Diffie-Hellman parameter from a file. Returns 1 if loaded, else -1
273 if an error occured, and 0 if parameter not found. */
274int ssl_sock_load_dh_params(SSL_CTX *ctx, const char *file)
275{
276 int ret = -1;
277 BIO *in;
278 DH *dh = NULL;
Emeric Brun41fdb3c2013-04-26 11:05:44 +0200279 /* If not present, use parameters generated using 'openssl dhparam 1024 -C':
280 * -----BEGIN DH PARAMETERS-----
281 * MIGHAoGBAJJAJDXDoS5E03MNjnjK36eOL1tRqVa/9NuOVlI+lpXmPjJQbP65EvKn
282 * fSLnG7VMhoCJO4KtG88zf393ltP7loGB2bofcDSr+x+XsxBM8yA/Zj6BmQt+CQ9s
283 * TF7hoOV+wXTT6ErZ5y5qx9pq6hLfKXwTGFT78hrE6HnCO7xgtPdTAgEC
284 * -----END DH PARAMETERS-----
285 */
286 static const unsigned char dh1024_p[] = {
287 0x92, 0x40, 0x24, 0x35, 0xC3, 0xA1, 0x2E, 0x44, 0xD3, 0x73, 0x0D, 0x8E,
288 0x78, 0xCA, 0xDF, 0xA7, 0x8E, 0x2F, 0x5B, 0x51, 0xA9, 0x56, 0xBF, 0xF4,
289 0xDB, 0x8E, 0x56, 0x52, 0x3E, 0x96, 0x95, 0xE6, 0x3E, 0x32, 0x50, 0x6C,
290 0xFE, 0xB9, 0x12, 0xF2, 0xA7, 0x7D, 0x22, 0xE7, 0x1B, 0xB5, 0x4C, 0x86,
291 0x80, 0x89, 0x3B, 0x82, 0xAD, 0x1B, 0xCF, 0x33, 0x7F, 0x7F, 0x77, 0x96,
292 0xD3, 0xFB, 0x96, 0x81, 0x81, 0xD9, 0xBA, 0x1F, 0x70, 0x34, 0xAB, 0xFB,
293 0x1F, 0x97, 0xB3, 0x10, 0x4C, 0xF3, 0x20, 0x3F, 0x66, 0x3E, 0x81, 0x99,
294 0x0B, 0x7E, 0x09, 0x0F, 0x6C, 0x4C, 0x5E, 0xE1, 0xA0, 0xE5, 0x7E, 0xC1,
295 0x74, 0xD3, 0xE8, 0x4A, 0xD9, 0xE7, 0x2E, 0x6A, 0xC7, 0xDA, 0x6A, 0xEA,
296 0x12, 0xDF, 0x29, 0x7C, 0x13, 0x18, 0x54, 0xFB, 0xF2, 0x1A, 0xC4, 0xE8,
297 0x79, 0xC2, 0x3B, 0xBC, 0x60, 0xB4, 0xF7, 0x53,
298 };
299 static const unsigned char dh1024_g[] = {
300 0x02,
301 };
Emeric Bruna4bcd9a2012-09-20 16:19:02 +0200302
303 in = BIO_new(BIO_s_file());
304 if (in == NULL)
305 goto end;
306
307 if (BIO_read_filename(in, file) <= 0)
308 goto end;
309
310 dh = PEM_read_bio_DHparams(in, NULL, ctx->default_passwd_callback, ctx->default_passwd_callback_userdata);
Emeric Brun41fdb3c2013-04-26 11:05:44 +0200311 if (!dh) {
312 /* Clear openssl global errors stack */
313 ERR_clear_error();
314
315 dh = DH_new();
316 if (dh == NULL)
317 goto end;
318
319 dh->p = BN_bin2bn(dh1024_p, sizeof(dh1024_p), NULL);
320 if (dh->p == NULL)
321 goto end;
322
323 dh->g = BN_bin2bn(dh1024_g, sizeof(dh1024_g), NULL);
324 if (dh->g == NULL)
325 goto end;
326
327 ret = 0; /* DH params not found */
Emeric Bruna4bcd9a2012-09-20 16:19:02 +0200328 }
Emeric Brun41fdb3c2013-04-26 11:05:44 +0200329 else
330 ret = 1;
Emeric Bruna4bcd9a2012-09-20 16:19:02 +0200331
Emeric Brun41fdb3c2013-04-26 11:05:44 +0200332 SSL_CTX_set_tmp_dh(ctx, dh);
Emeric Brun644cde02012-12-14 11:21:13 +0100333
Emeric Bruna4bcd9a2012-09-20 16:19:02 +0200334end:
335 if (dh)
336 DH_free(dh);
337
338 if (in)
Emeric Brun41fdb3c2013-04-26 11:05:44 +0200339 BIO_free(in);
Emeric Bruna4bcd9a2012-09-20 16:19:02 +0200340
341 return ret;
342}
343#endif
344
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +0200345static int ssl_sock_add_cert_sni(SSL_CTX *ctx, struct bind_conf *s, char *name, int order)
Emmanuel Hocdetfe616562013-01-22 15:31:15 +0100346{
347 struct sni_ctx *sc;
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +0200348 int wild = 0, neg = 0;
Emmanuel Hocdetfe616562013-01-22 15:31:15 +0100349
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +0200350 if (*name == '!') {
351 neg = 1;
352 name++;
353 }
354 if (*name == '*') {
355 wild = 1;
356 name++;
357 }
358 /* !* filter is a nop */
359 if (neg && wild)
360 return order;
361 if (*name) {
362 int j, len;
363 len = strlen(name);
Emmanuel Hocdetfe616562013-01-22 15:31:15 +0100364 sc = malloc(sizeof(struct sni_ctx) + len + 1);
365 for (j = 0; j < len; j++)
366 sc->name.key[j] = tolower(name[j]);
367 sc->name.key[len] = 0;
Emmanuel Hocdetfe616562013-01-22 15:31:15 +0100368 sc->ctx = ctx;
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +0200369 sc->order = order++;
370 sc->neg = neg;
Emmanuel Hocdetfe616562013-01-22 15:31:15 +0100371 if (wild)
372 ebst_insert(&s->sni_w_ctx, &sc->name);
373 else
374 ebst_insert(&s->sni_ctx, &sc->name);
375 }
376 return order;
377}
378
Emeric Brunfc0421f2012-09-07 17:30:07 +0200379/* Loads a certificate key and CA chain from a file. Returns 0 on error, -1 if
380 * an early error happens and the caller must call SSL_CTX_free() by itelf.
381 */
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +0200382static 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 +0200383{
384 BIO *in;
385 X509 *x = NULL, *ca;
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +0200386 int i, err;
Emeric Brunfc0421f2012-09-07 17:30:07 +0200387 int ret = -1;
388 int order = 0;
389 X509_NAME *xname;
390 char *str;
Emeric Brunfc0421f2012-09-07 17:30:07 +0200391#ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME
392 STACK_OF(GENERAL_NAME) *names;
393#endif
394
395 in = BIO_new(BIO_s_file());
396 if (in == NULL)
397 goto end;
398
399 if (BIO_read_filename(in, file) <= 0)
400 goto end;
401
402 x = PEM_read_bio_X509_AUX(in, NULL, ctx->default_passwd_callback, ctx->default_passwd_callback_userdata);
403 if (x == NULL)
404 goto end;
405
Emeric Brun50bcecc2013-04-22 13:05:23 +0200406 if (fcount) {
407 while (fcount--)
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +0200408 order = ssl_sock_add_cert_sni(ctx, s, sni_filter[fcount], order);
Emmanuel Hocdetfe616562013-01-22 15:31:15 +0100409 }
410 else {
Emeric Brunfc0421f2012-09-07 17:30:07 +0200411#ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME
Emmanuel Hocdetfe616562013-01-22 15:31:15 +0100412 names = X509_get_ext_d2i(x, NID_subject_alt_name, NULL, NULL);
413 if (names) {
414 for (i = 0; i < sk_GENERAL_NAME_num(names); i++) {
415 GENERAL_NAME *name = sk_GENERAL_NAME_value(names, i);
416 if (name->type == GEN_DNS) {
417 if (ASN1_STRING_to_UTF8((unsigned char **)&str, name->d.dNSName) >= 0) {
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +0200418 order = ssl_sock_add_cert_sni(ctx, s, str, order);
Emmanuel Hocdetfe616562013-01-22 15:31:15 +0100419 OPENSSL_free(str);
Emeric Brunfc0421f2012-09-07 17:30:07 +0200420 }
Emeric Brunfc0421f2012-09-07 17:30:07 +0200421 }
422 }
Emmanuel Hocdetfe616562013-01-22 15:31:15 +0100423 sk_GENERAL_NAME_pop_free(names, GENERAL_NAME_free);
Emeric Brunfc0421f2012-09-07 17:30:07 +0200424 }
Emeric Brunfc0421f2012-09-07 17:30:07 +0200425#endif /* SSL_CTRL_SET_TLSEXT_HOSTNAME */
Emmanuel Hocdetfe616562013-01-22 15:31:15 +0100426 xname = X509_get_subject_name(x);
427 i = -1;
428 while ((i = X509_NAME_get_index_by_NID(xname, NID_commonName, i)) != -1) {
429 X509_NAME_ENTRY *entry = X509_NAME_get_entry(xname, i);
430 if (ASN1_STRING_to_UTF8((unsigned char **)&str, entry->value) >= 0) {
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +0200431 order = ssl_sock_add_cert_sni(ctx, s, str, order);
Emmanuel Hocdetfe616562013-01-22 15:31:15 +0100432 OPENSSL_free(str);
Emeric Brunfc0421f2012-09-07 17:30:07 +0200433 }
Emeric Brunfc0421f2012-09-07 17:30:07 +0200434 }
435 }
436
437 ret = 0; /* the caller must not free the SSL_CTX argument anymore */
438 if (!SSL_CTX_use_certificate(ctx, x))
439 goto end;
440
441 if (ctx->extra_certs != NULL) {
442 sk_X509_pop_free(ctx->extra_certs, X509_free);
443 ctx->extra_certs = NULL;
444 }
445
446 while ((ca = PEM_read_bio_X509(in, NULL, ctx->default_passwd_callback, ctx->default_passwd_callback_userdata))) {
447 if (!SSL_CTX_add_extra_chain_cert(ctx, ca)) {
448 X509_free(ca);
449 goto end;
450 }
451 }
452
453 err = ERR_get_error();
454 if (!err || (ERR_GET_LIB(err) == ERR_LIB_PEM && ERR_GET_REASON(err) == PEM_R_NO_START_LINE)) {
455 /* we successfully reached the last cert in the file */
456 ret = 1;
457 }
458 ERR_clear_error();
459
460end:
461 if (x)
462 X509_free(x);
463
464 if (in)
465 BIO_free(in);
466
467 return ret;
468}
469
Emeric Brun50bcecc2013-04-22 13:05:23 +0200470static 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 +0200471{
472 int ret;
473 SSL_CTX *ctx;
474
475 ctx = SSL_CTX_new(SSLv23_server_method());
476 if (!ctx) {
Willy Tarreaueb6cead2012-09-20 19:43:14 +0200477 memprintf(err, "%sunable to allocate SSL context for cert '%s'.\n",
478 err && *err ? *err : "", path);
Emeric Brunfc0421f2012-09-07 17:30:07 +0200479 return 1;
480 }
481
482 if (SSL_CTX_use_PrivateKey_file(ctx, path, SSL_FILETYPE_PEM) <= 0) {
Willy Tarreaueb6cead2012-09-20 19:43:14 +0200483 memprintf(err, "%sunable to load SSL private key from PEM file '%s'.\n",
484 err && *err ? *err : "", path);
Emeric Brunfc0421f2012-09-07 17:30:07 +0200485 SSL_CTX_free(ctx);
486 return 1;
487 }
488
Emeric Brun50bcecc2013-04-22 13:05:23 +0200489 ret = ssl_sock_load_cert_chain_file(ctx, path, bind_conf, sni_filter, fcount);
Emeric Brunfc0421f2012-09-07 17:30:07 +0200490 if (ret <= 0) {
Willy Tarreaueb6cead2012-09-20 19:43:14 +0200491 memprintf(err, "%sunable to load SSL certificate from PEM file '%s'.\n",
492 err && *err ? *err : "", path);
Emeric Brunfc0421f2012-09-07 17:30:07 +0200493 if (ret < 0) /* serious error, must do that ourselves */
494 SSL_CTX_free(ctx);
495 return 1;
496 }
Emeric Brun61694ab2012-10-26 13:35:33 +0200497
498 if (SSL_CTX_check_private_key(ctx) <= 0) {
499 memprintf(err, "%sinconsistencies between private key and certificate loaded from PEM file '%s'.\n",
500 err && *err ? *err : "", path);
501 return 1;
502 }
503
Emeric Brunfc0421f2012-09-07 17:30:07 +0200504 /* we must not free the SSL_CTX anymore below, since it's already in
505 * the tree, so it will be discovered and cleaned in time.
506 */
Emeric Bruna4bcd9a2012-09-20 16:19:02 +0200507#ifndef OPENSSL_NO_DH
508 ret = ssl_sock_load_dh_params(ctx, path);
509 if (ret < 0) {
510 if (err)
511 memprintf(err, "%sunable to load DH parameters from file '%s'.\n",
512 *err ? *err : "", path);
513 return 1;
514 }
515#endif
516
Emeric Brunfc0421f2012-09-07 17:30:07 +0200517#ifndef SSL_CTRL_SET_TLSEXT_HOSTNAME
Willy Tarreau2a65ff02012-09-13 17:54:29 +0200518 if (bind_conf->default_ctx) {
Willy Tarreaueb6cead2012-09-20 19:43:14 +0200519 memprintf(err, "%sthis version of openssl cannot load multiple SSL certificates.\n",
520 err && *err ? *err : "");
Emeric Brunfc0421f2012-09-07 17:30:07 +0200521 return 1;
522 }
523#endif
Willy Tarreau2a65ff02012-09-13 17:54:29 +0200524 if (!bind_conf->default_ctx)
525 bind_conf->default_ctx = ctx;
Emeric Brunfc0421f2012-09-07 17:30:07 +0200526
527 return 0;
528}
529
Willy Tarreau79eeafa2012-09-14 07:53:05 +0200530int ssl_sock_load_cert(char *path, struct bind_conf *bind_conf, struct proxy *curproxy, char **err)
Emeric Brunfc0421f2012-09-07 17:30:07 +0200531{
532 struct dirent *de;
533 DIR *dir;
534 struct stat buf;
Willy Tarreauee2663b2012-12-06 11:36:59 +0100535 char *end;
536 char fp[MAXPATHLEN+1];
Emeric Brunfc0421f2012-09-07 17:30:07 +0200537 int cfgerr = 0;
538
539 if (!(dir = opendir(path)))
Emeric Brun50bcecc2013-04-22 13:05:23 +0200540 return ssl_sock_load_cert_file(path, bind_conf, curproxy, NULL, 0, err);
Emeric Brunfc0421f2012-09-07 17:30:07 +0200541
542 /* strip trailing slashes, including first one */
543 for (end = path + strlen(path) - 1; end >= path && *end == '/'; end--)
544 *end = 0;
545
Emeric Brunfc0421f2012-09-07 17:30:07 +0200546 while ((de = readdir(dir))) {
Willy Tarreauee2663b2012-12-06 11:36:59 +0100547 snprintf(fp, sizeof(fp), "%s/%s", path, de->d_name);
Emeric Brunfc0421f2012-09-07 17:30:07 +0200548 if (stat(fp, &buf) != 0) {
Willy Tarreaueb6cead2012-09-20 19:43:14 +0200549 memprintf(err, "%sunable to stat SSL certificate from file '%s' : %s.\n",
550 err && *err ? *err : "", fp, strerror(errno));
Emeric Brunfc0421f2012-09-07 17:30:07 +0200551 cfgerr++;
552 continue;
553 }
554 if (!S_ISREG(buf.st_mode))
555 continue;
Emeric Brun50bcecc2013-04-22 13:05:23 +0200556 cfgerr += ssl_sock_load_cert_file(fp, bind_conf, curproxy, NULL, 0, err);
Emeric Brunfc0421f2012-09-07 17:30:07 +0200557 }
Emeric Brunfc0421f2012-09-07 17:30:07 +0200558 closedir(dir);
559 return cfgerr;
560}
561
Thierry Fournier383085f2013-01-24 14:15:43 +0100562/* Make sure openssl opens /dev/urandom before the chroot. The work is only
563 * done once. Zero is returned if the operation fails. No error is returned
564 * if the random is said as not implemented, because we expect that openssl
565 * will use another method once needed.
566 */
567static int ssl_initialize_random()
568{
569 unsigned char random;
570 static int random_initialized = 0;
571
572 if (!random_initialized && RAND_bytes(&random, 1) != 0)
573 random_initialized = 1;
574
575 return random_initialized;
576}
577
Emmanuel Hocdetfe616562013-01-22 15:31:15 +0100578int ssl_sock_load_cert_list_file(char *file, struct bind_conf *bind_conf, struct proxy *curproxy, char **err)
579{
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +0200580 char thisline[LINESIZE];
Emmanuel Hocdetfe616562013-01-22 15:31:15 +0100581 FILE *f;
582 int linenum = 0;
583 int cfgerr = 0;
Emmanuel Hocdetfe616562013-01-22 15:31:15 +0100584
Willy Tarreauad1731d2013-04-02 17:35:58 +0200585 if ((f = fopen(file, "r")) == NULL) {
586 memprintf(err, "cannot open file '%s' : %s", file, strerror(errno));
Emmanuel Hocdetfe616562013-01-22 15:31:15 +0100587 return 1;
Willy Tarreauad1731d2013-04-02 17:35:58 +0200588 }
Emmanuel Hocdetfe616562013-01-22 15:31:15 +0100589
590 while (fgets(thisline, sizeof(thisline), f) != NULL) {
591 int arg;
Emeric Brun50bcecc2013-04-22 13:05:23 +0200592 int newarg;
Emmanuel Hocdetfe616562013-01-22 15:31:15 +0100593 char *end;
594 char *args[MAX_LINE_ARGS + 1];
595 char *line = thisline;
596
597 linenum++;
598 end = line + strlen(line);
599 if (end-line == sizeof(thisline)-1 && *(end-1) != '\n') {
600 /* Check if we reached the limit and the last char is not \n.
601 * Watch out for the last line without the terminating '\n'!
602 */
Willy Tarreauad1731d2013-04-02 17:35:58 +0200603 memprintf(err, "line %d too long in file '%s', limit is %d characters",
604 linenum, file, (int)sizeof(thisline)-1);
Emmanuel Hocdetfe616562013-01-22 15:31:15 +0100605 cfgerr = 1;
Willy Tarreauad1731d2013-04-02 17:35:58 +0200606 break;
Emmanuel Hocdetfe616562013-01-22 15:31:15 +0100607 }
608
Emmanuel Hocdetfe616562013-01-22 15:31:15 +0100609 arg = 0;
Emeric Brun50bcecc2013-04-22 13:05:23 +0200610 newarg = 1;
611 while (*line) {
Emmanuel Hocdetfe616562013-01-22 15:31:15 +0100612 if (*line == '#' || *line == '\n' || *line == '\r') {
613 /* end of string, end of loop */
614 *line = 0;
615 break;
616 }
617 else if (isspace(*line)) {
Emeric Brun50bcecc2013-04-22 13:05:23 +0200618 newarg = 1;
619 *line = 0;
Emmanuel Hocdetfe616562013-01-22 15:31:15 +0100620 }
Emeric Brun50bcecc2013-04-22 13:05:23 +0200621 else if (newarg) {
622 if (arg == MAX_LINE_ARGS) {
623 memprintf(err, "too many args on line %d in file '%s'.",
624 linenum, file);
625 cfgerr = 1;
626 break;
627 }
628 newarg = 0;
629 args[arg++] = line;
Emmanuel Hocdetfe616562013-01-22 15:31:15 +0100630 }
Emeric Brun50bcecc2013-04-22 13:05:23 +0200631 line++;
Emmanuel Hocdetfe616562013-01-22 15:31:15 +0100632 }
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +0200633 if (cfgerr)
634 break;
Willy Tarreauad1731d2013-04-02 17:35:58 +0200635
Emmanuel Hocdetfe616562013-01-22 15:31:15 +0100636 /* empty line */
Emeric Brun50bcecc2013-04-22 13:05:23 +0200637 if (!arg)
Emmanuel Hocdetfe616562013-01-22 15:31:15 +0100638 continue;
Emmanuel Hocdetfe616562013-01-22 15:31:15 +0100639
Emeric Brun50bcecc2013-04-22 13:05:23 +0200640 cfgerr = ssl_sock_load_cert_file(args[0], bind_conf, curproxy, &args[1], arg-1, err);
Willy Tarreauad1731d2013-04-02 17:35:58 +0200641 if (cfgerr) {
642 memprintf(err, "error processing line %d in file '%s' : %s", linenum, file, *err);
Emmanuel Hocdetfe616562013-01-22 15:31:15 +0100643 break;
Willy Tarreauad1731d2013-04-02 17:35:58 +0200644 }
Emmanuel Hocdetfe616562013-01-22 15:31:15 +0100645 }
Emmanuel Hocdetfe616562013-01-22 15:31:15 +0100646 fclose(f);
647 return cfgerr;
648}
649
Emeric Brunfc0421f2012-09-07 17:30:07 +0200650#ifndef SSL_OP_CIPHER_SERVER_PREFERENCE /* needs OpenSSL >= 0.9.7 */
651#define SSL_OP_CIPHER_SERVER_PREFERENCE 0
652#endif
653
654#ifndef SSL_OP_NO_SESSION_RESUMPTION_ON_RENEGOTIATION /* needs OpenSSL >= 0.9.7 */
655#define SSL_OP_NO_SESSION_RESUMPTION_ON_RENEGOTIATION 0
Willy Tarreau7d588ee2012-11-26 18:47:31 +0100656#define SSL_renegotiate_pending(arg) 0
Emeric Brunfc0421f2012-09-07 17:30:07 +0200657#endif
Emeric Brun2b58d042012-09-20 17:10:03 +0200658#ifndef SSL_OP_SINGLE_ECDH_USE /* needs OpenSSL >= 0.9.8 */
659#define SSL_OP_SINGLE_ECDH_USE 0
660#endif
Emeric Brun2d0c4822012-10-02 13:45:20 +0200661#ifndef SSL_OP_NO_TICKET /* needs OpenSSL >= 0.9.8 */
662#define SSL_OP_NO_TICKET 0
663#endif
Emeric Brunfc0421f2012-09-07 17:30:07 +0200664#ifndef SSL_OP_NO_COMPRESSION /* needs OpenSSL >= 0.9.9 */
665#define SSL_OP_NO_COMPRESSION 0
666#endif
Emeric Brunc0ff4922012-09-28 19:37:02 +0200667#ifndef SSL_OP_NO_TLSv1_1 /* needs OpenSSL >= 1.0.1 */
668#define SSL_OP_NO_TLSv1_1 0
669#endif
670#ifndef SSL_OP_NO_TLSv1_2 /* needs OpenSSL >= 1.0.1 */
671#define SSL_OP_NO_TLSv1_2 0
672#endif
Emeric Bruna4bcd9a2012-09-20 16:19:02 +0200673#ifndef SSL_OP_SINGLE_DH_USE /* needs OpenSSL >= 0.9.6 */
674#define SSL_OP_SINGLE_DH_USE 0
675#endif
Emeric Brun2b58d042012-09-20 17:10:03 +0200676#ifndef SSL_OP_SINGLE_ECDH_USE /* needs OpenSSL >= 1.0.0 */
677#define SSL_OP_SINGLE_ECDH_USE 0
678#endif
Emeric Brunfc0421f2012-09-07 17:30:07 +0200679#ifndef SSL_MODE_RELEASE_BUFFERS /* needs OpenSSL >= 1.0.0 */
680#define SSL_MODE_RELEASE_BUFFERS 0
681#endif
Willy Tarreau2a65ff02012-09-13 17:54:29 +0200682int ssl_sock_prepare_ctx(struct bind_conf *bind_conf, SSL_CTX *ctx, struct proxy *curproxy)
Emeric Brunfc0421f2012-09-07 17:30:07 +0200683{
684 int cfgerr = 0;
Emeric Brun850efd52014-01-29 12:24:34 +0100685 int verify = SSL_VERIFY_NONE;
Emeric Brunfc0421f2012-09-07 17:30:07 +0200686 int ssloptions =
687 SSL_OP_ALL | /* all known workarounds for bugs */
688 SSL_OP_NO_SSLv2 |
689 SSL_OP_NO_COMPRESSION |
Emeric Bruna4bcd9a2012-09-20 16:19:02 +0200690 SSL_OP_SINGLE_DH_USE |
Emeric Brun2b58d042012-09-20 17:10:03 +0200691 SSL_OP_SINGLE_ECDH_USE |
Emeric Brun3c4bc6e2012-10-04 18:44:19 +0200692 SSL_OP_NO_SESSION_RESUMPTION_ON_RENEGOTIATION |
693 SSL_OP_CIPHER_SERVER_PREFERENCE;
Emeric Brunfc0421f2012-09-07 17:30:07 +0200694 int sslmode =
695 SSL_MODE_ENABLE_PARTIAL_WRITE |
696 SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER |
697 SSL_MODE_RELEASE_BUFFERS;
698
Thierry Fournier383085f2013-01-24 14:15:43 +0100699 /* Make sure openssl opens /dev/urandom before the chroot */
700 if (!ssl_initialize_random()) {
701 Alert("OpenSSL random data generator initialization failed.\n");
702 cfgerr++;
703 }
704
Emeric Brun89675492012-10-05 13:48:26 +0200705 if (bind_conf->ssl_options & BC_SSL_O_NO_SSLV3)
Emeric Brunfc0421f2012-09-07 17:30:07 +0200706 ssloptions |= SSL_OP_NO_SSLv3;
Emeric Brun89675492012-10-05 13:48:26 +0200707 if (bind_conf->ssl_options & BC_SSL_O_NO_TLSV10)
Emeric Brunfc0421f2012-09-07 17:30:07 +0200708 ssloptions |= SSL_OP_NO_TLSv1;
Emeric Brun89675492012-10-05 13:48:26 +0200709 if (bind_conf->ssl_options & BC_SSL_O_NO_TLSV11)
Emeric Brunc0ff4922012-09-28 19:37:02 +0200710 ssloptions |= SSL_OP_NO_TLSv1_1;
Emeric Brun89675492012-10-05 13:48:26 +0200711 if (bind_conf->ssl_options & BC_SSL_O_NO_TLSV12)
Emeric Brunc0ff4922012-09-28 19:37:02 +0200712 ssloptions |= SSL_OP_NO_TLSv1_2;
Emeric Brun89675492012-10-05 13:48:26 +0200713 if (bind_conf->ssl_options & BC_SSL_O_NO_TLS_TICKETS)
Emeric Brun2d0c4822012-10-02 13:45:20 +0200714 ssloptions |= SSL_OP_NO_TICKET;
Emeric Brun2cb7ae52012-10-05 14:14:21 +0200715 if (bind_conf->ssl_options & BC_SSL_O_USE_SSLV3)
716 SSL_CTX_set_ssl_version(ctx, SSLv3_server_method());
717 if (bind_conf->ssl_options & BC_SSL_O_USE_TLSV10)
718 SSL_CTX_set_ssl_version(ctx, TLSv1_server_method());
719#if SSL_OP_NO_TLSv1_1
720 if (bind_conf->ssl_options & BC_SSL_O_USE_TLSV11)
721 SSL_CTX_set_ssl_version(ctx, TLSv1_1_server_method());
722#endif
723#if SSL_OP_NO_TLSv1_2
724 if (bind_conf->ssl_options & BC_SSL_O_USE_TLSV12)
725 SSL_CTX_set_ssl_version(ctx, TLSv1_2_server_method());
726#endif
Emeric Brunfc0421f2012-09-07 17:30:07 +0200727
728 SSL_CTX_set_options(ctx, ssloptions);
729 SSL_CTX_set_mode(ctx, sslmode);
Emeric Brun850efd52014-01-29 12:24:34 +0100730 switch (bind_conf->verify) {
731 case SSL_SOCK_VERIFY_NONE:
732 verify = SSL_VERIFY_NONE;
733 break;
734 case SSL_SOCK_VERIFY_OPTIONAL:
735 verify = SSL_VERIFY_PEER;
736 break;
737 case SSL_SOCK_VERIFY_REQUIRED:
738 verify = SSL_VERIFY_PEER|SSL_VERIFY_FAIL_IF_NO_PEER_CERT;
739 break;
740 }
741 SSL_CTX_set_verify(ctx, verify, ssl_sock_bind_verifycbk);
742 if (verify & SSL_VERIFY_PEER) {
Emeric Brunfb510ea2012-10-05 12:00:26 +0200743 if (bind_conf->ca_file) {
Emeric Brund94b3fe2012-09-20 18:23:56 +0200744 /* load CAfile to verify */
Emeric Brunfb510ea2012-10-05 12:00:26 +0200745 if (!SSL_CTX_load_verify_locations(ctx, bind_conf->ca_file, NULL)) {
Emeric Brund94b3fe2012-09-20 18:23:56 +0200746 Alert("Proxy '%s': unable to load CA file '%s' for bind '%s' at [%s:%d].\n",
Emeric Brunfb510ea2012-10-05 12:00:26 +0200747 curproxy->id, bind_conf->ca_file, bind_conf->arg, bind_conf->file, bind_conf->line);
Emeric Brund94b3fe2012-09-20 18:23:56 +0200748 cfgerr++;
749 }
750 /* set CA names fo client cert request, function returns void */
Emeric Brunfb510ea2012-10-05 12:00:26 +0200751 SSL_CTX_set_client_CA_list(ctx, SSL_load_client_CA_file(bind_conf->ca_file));
Emeric Brund94b3fe2012-09-20 18:23:56 +0200752 }
Emeric Brun850efd52014-01-29 12:24:34 +0100753 else {
754 Alert("Proxy '%s': verify is enabled but no CA file specified for bind '%s' at [%s:%d].\n",
755 curproxy->id, bind_conf->arg, bind_conf->file, bind_conf->line);
756 cfgerr++;
757 }
Emeric Brun051cdab2012-10-02 19:25:50 +0200758#ifdef X509_V_FLAG_CRL_CHECK
Emeric Brunfb510ea2012-10-05 12:00:26 +0200759 if (bind_conf->crl_file) {
Emeric Brund94b3fe2012-09-20 18:23:56 +0200760 X509_STORE *store = SSL_CTX_get_cert_store(ctx);
761
Emeric Brunfb510ea2012-10-05 12:00:26 +0200762 if (!store || !X509_STORE_load_locations(store, bind_conf->crl_file, NULL)) {
Emeric Brund94b3fe2012-09-20 18:23:56 +0200763 Alert("Proxy '%s': unable to configure CRL file '%s' for bind '%s' at [%s:%d].\n",
Emeric Brunfb510ea2012-10-05 12:00:26 +0200764 curproxy->id, bind_conf->ca_file, bind_conf->arg, bind_conf->file, bind_conf->line);
Emeric Brund94b3fe2012-09-20 18:23:56 +0200765 cfgerr++;
766 }
Emeric Brun561e5742012-10-02 15:20:55 +0200767 else {
768 X509_STORE_set_flags(store, X509_V_FLAG_CRL_CHECK|X509_V_FLAG_CRL_CHECK_ALL);
769 }
Emeric Brund94b3fe2012-09-20 18:23:56 +0200770 }
Emeric Brun051cdab2012-10-02 19:25:50 +0200771#endif
Emeric Brun644cde02012-12-14 11:21:13 +0100772 ERR_clear_error();
Emeric Brund94b3fe2012-09-20 18:23:56 +0200773 }
Emeric Brunfc0421f2012-09-07 17:30:07 +0200774
Emeric Brun4f65bff2012-11-16 15:11:00 +0100775 if (global.tune.ssllifetime)
776 SSL_CTX_set_timeout(ctx, global.tune.ssllifetime);
777
Emeric Brunfc0421f2012-09-07 17:30:07 +0200778 shared_context_set_cache(ctx);
Willy Tarreau2a65ff02012-09-13 17:54:29 +0200779 if (bind_conf->ciphers &&
780 !SSL_CTX_set_cipher_list(ctx, bind_conf->ciphers)) {
Emeric Brunfc0421f2012-09-07 17:30:07 +0200781 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 +0200782 curproxy->id, bind_conf->ciphers, bind_conf->arg, bind_conf->file, bind_conf->line);
Emeric Brunfc0421f2012-09-07 17:30:07 +0200783 cfgerr++;
784 }
785
786 SSL_CTX_set_info_callback(ctx, ssl_sock_infocbk);
Willy Tarreau6c9a3d52012-10-18 18:57:14 +0200787#ifdef OPENSSL_NPN_NEGOTIATED
788 if (bind_conf->npn_str)
789 SSL_CTX_set_next_protos_advertised_cb(ctx, ssl_sock_advertise_npn_protos, bind_conf);
790#endif
Dirkjan Bussink48f1c4e2014-02-13 12:29:42 +0100791#ifdef TLSEXT_TYPE_application_layer_protocol_negotiation
Willy Tarreauab861d32013-04-02 02:30:41 +0200792 if (bind_conf->alpn_str)
Dirkjan Bussink48f1c4e2014-02-13 12:29:42 +0100793 SSL_CTX_set_alpn_select_cb(ctx, ssl_sock_advertise_alpn_protos, bind_conf);
Willy Tarreauab861d32013-04-02 02:30:41 +0200794#endif
Willy Tarreau6c9a3d52012-10-18 18:57:14 +0200795
Emeric Brunfc0421f2012-09-07 17:30:07 +0200796#ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME
797 SSL_CTX_set_tlsext_servername_callback(ctx, ssl_sock_switchctx_cbk);
Willy Tarreau2a65ff02012-09-13 17:54:29 +0200798 SSL_CTX_set_tlsext_servername_arg(ctx, bind_conf);
Emeric Brunfc0421f2012-09-07 17:30:07 +0200799#endif
Emeric Brun2b58d042012-09-20 17:10:03 +0200800#if defined(SSL_CTX_set_tmp_ecdh) && !defined(OPENSSL_NO_ECDH)
Emeric Brun6924ef82013-03-06 14:08:53 +0100801 {
Emeric Brun2b58d042012-09-20 17:10:03 +0200802 int i;
803 EC_KEY *ecdh;
804
Emeric Brun6924ef82013-03-06 14:08:53 +0100805 i = OBJ_sn2nid(bind_conf->ecdhe ? bind_conf->ecdhe : ECDHE_DEFAULT_CURVE);
Emeric Brun2b58d042012-09-20 17:10:03 +0200806 if (!i || ((ecdh = EC_KEY_new_by_curve_name(i)) == NULL)) {
807 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 +0100808 curproxy->id, bind_conf->ecdhe ? bind_conf->ecdhe : ECDHE_DEFAULT_CURVE,
809 bind_conf->arg, bind_conf->file, bind_conf->line);
Emeric Brun2b58d042012-09-20 17:10:03 +0200810 cfgerr++;
811 }
812 else {
813 SSL_CTX_set_tmp_ecdh(ctx, ecdh);
814 EC_KEY_free(ecdh);
815 }
816 }
817#endif
818
Emeric Brunfc0421f2012-09-07 17:30:07 +0200819 return cfgerr;
820}
821
Evan Broderbe554312013-06-27 00:05:25 -0700822static int ssl_sock_srv_hostcheck(const char *pattern, const char *hostname)
823{
824 const char *pattern_wildcard, *pattern_left_label_end, *hostname_left_label_end;
825 size_t prefixlen, suffixlen;
826
827 /* Trivial case */
828 if (strcmp(pattern, hostname) == 0)
829 return 1;
830
Evan Broderbe554312013-06-27 00:05:25 -0700831 /* The rest of this logic is based on RFC 6125, section 6.4.3
832 * (http://tools.ietf.org/html/rfc6125#section-6.4.3) */
833
Emeric Bruna848dae2013-10-08 11:27:28 +0200834 pattern_wildcard = NULL;
835 pattern_left_label_end = pattern;
836 while (*pattern_left_label_end != '.') {
837 switch (*pattern_left_label_end) {
838 case 0:
839 /* End of label not found */
840 return 0;
841 case '*':
842 /* If there is more than one wildcards */
843 if (pattern_wildcard)
844 return 0;
845 pattern_wildcard = pattern_left_label_end;
846 break;
847 }
848 pattern_left_label_end++;
849 }
850
851 /* If it's not trivial and there is no wildcard, it can't
852 * match */
853 if (!pattern_wildcard)
Evan Broderbe554312013-06-27 00:05:25 -0700854 return 0;
855
856 /* Make sure all labels match except the leftmost */
857 hostname_left_label_end = strchr(hostname, '.');
858 if (!hostname_left_label_end
859 || strcmp(pattern_left_label_end, hostname_left_label_end) != 0)
860 return 0;
861
862 /* Make sure the leftmost label of the hostname is long enough
863 * that the wildcard can match */
Emeric Brun369da852013-10-08 11:39:35 +0200864 if (hostname_left_label_end - hostname < (pattern_left_label_end - pattern) - 1)
Evan Broderbe554312013-06-27 00:05:25 -0700865 return 0;
866
867 /* Finally compare the string on either side of the
868 * wildcard */
869 prefixlen = pattern_wildcard - pattern;
870 suffixlen = pattern_left_label_end - (pattern_wildcard + 1);
Emeric Bruna848dae2013-10-08 11:27:28 +0200871 if ((prefixlen && (memcmp(pattern, hostname, prefixlen) != 0))
872 || (suffixlen && (memcmp(pattern_wildcard + 1, hostname_left_label_end - suffixlen, suffixlen) != 0)))
Evan Broderbe554312013-06-27 00:05:25 -0700873 return 0;
874
875 return 1;
876}
877
878static int ssl_sock_srv_verifycbk(int ok, X509_STORE_CTX *ctx)
879{
880 SSL *ssl;
881 struct connection *conn;
882 char *servername;
883
884 int depth;
885 X509 *cert;
886 STACK_OF(GENERAL_NAME) *alt_names;
887 int i;
888 X509_NAME *cert_subject;
889 char *str;
890
891 if (ok == 0)
892 return ok;
893
894 ssl = X509_STORE_CTX_get_ex_data(ctx, SSL_get_ex_data_X509_STORE_CTX_idx());
895 conn = (struct connection *)SSL_get_app_data(ssl);
896
897 servername = objt_server(conn->target)->ssl_ctx.verify_host;
898
899 /* We only need to verify the CN on the actual server cert,
900 * not the indirect CAs */
901 depth = X509_STORE_CTX_get_error_depth(ctx);
902 if (depth != 0)
903 return ok;
904
905 /* At this point, the cert is *not* OK unless we can find a
906 * hostname match */
907 ok = 0;
908
909 cert = X509_STORE_CTX_get_current_cert(ctx);
910 /* It seems like this might happen if verify peer isn't set */
911 if (!cert)
912 return ok;
913
914 alt_names = X509_get_ext_d2i(cert, NID_subject_alt_name, NULL, NULL);
915 if (alt_names) {
916 for (i = 0; !ok && i < sk_GENERAL_NAME_num(alt_names); i++) {
917 GENERAL_NAME *name = sk_GENERAL_NAME_value(alt_names, i);
918 if (name->type == GEN_DNS) {
Emeric Bruna33410c2013-09-17 15:47:48 +0200919#if OPENSSL_VERSION_NUMBER < 0x00907000L
920 if (ASN1_STRING_to_UTF8((unsigned char **)&str, name->d.ia5) >= 0) {
921#else
Evan Broderbe554312013-06-27 00:05:25 -0700922 if (ASN1_STRING_to_UTF8((unsigned char **)&str, name->d.dNSName) >= 0) {
Emeric Bruna33410c2013-09-17 15:47:48 +0200923#endif
Evan Broderbe554312013-06-27 00:05:25 -0700924 ok = ssl_sock_srv_hostcheck(str, servername);
925 OPENSSL_free(str);
926 }
927 }
928 }
Emeric Brun4ad50a42013-09-17 15:19:54 +0200929 sk_GENERAL_NAME_pop_free(alt_names, GENERAL_NAME_free);
Evan Broderbe554312013-06-27 00:05:25 -0700930 }
931
932 cert_subject = X509_get_subject_name(cert);
933 i = -1;
934 while (!ok && (i = X509_NAME_get_index_by_NID(cert_subject, NID_commonName, i)) != -1) {
935 X509_NAME_ENTRY *entry = X509_NAME_get_entry(cert_subject, i);
936 if (ASN1_STRING_to_UTF8((unsigned char **)&str, entry->value) >= 0) {
937 ok = ssl_sock_srv_hostcheck(str, servername);
938 OPENSSL_free(str);
939 }
940 }
941
942 return ok;
943}
944
Emeric Brun94324a42012-10-11 14:00:19 +0200945/* prepare ssl context from servers options. Returns an error count */
946int ssl_sock_prepare_srv_ctx(struct server *srv, struct proxy *curproxy)
947{
948 int cfgerr = 0;
949 int options =
950 SSL_OP_ALL | /* all known workarounds for bugs */
951 SSL_OP_NO_SSLv2 |
952 SSL_OP_NO_COMPRESSION;
953 int mode =
954 SSL_MODE_ENABLE_PARTIAL_WRITE |
955 SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER |
956 SSL_MODE_RELEASE_BUFFERS;
Emeric Brun850efd52014-01-29 12:24:34 +0100957 int verify = SSL_VERIFY_NONE;
Emeric Brun94324a42012-10-11 14:00:19 +0200958
Thierry Fournier383085f2013-01-24 14:15:43 +0100959 /* Make sure openssl opens /dev/urandom before the chroot */
960 if (!ssl_initialize_random()) {
961 Alert("OpenSSL random data generator initialization failed.\n");
962 cfgerr++;
963 }
964
Emeric Brun94324a42012-10-11 14:00:19 +0200965 /* Initiate SSL context for current server */
966 srv->ssl_ctx.reused_sess = NULL;
967 if (srv->use_ssl)
968 srv->xprt = &ssl_sock;
969 if (srv->check.use_ssl)
Simon Horman66183002013-02-23 10:16:43 +0900970 srv->check_common.xprt = &ssl_sock;
Emeric Brun94324a42012-10-11 14:00:19 +0200971
972 srv->ssl_ctx.ctx = SSL_CTX_new(SSLv23_client_method());
973 if (!srv->ssl_ctx.ctx) {
974 Alert("config : %s '%s', server '%s': unable to allocate ssl context.\n",
975 proxy_type_str(curproxy), curproxy->id,
976 srv->id);
977 cfgerr++;
978 return cfgerr;
979 }
Emeric Bruna7aa3092012-10-26 12:58:00 +0200980 if (srv->ssl_ctx.client_crt) {
981 if (SSL_CTX_use_PrivateKey_file(srv->ssl_ctx.ctx, srv->ssl_ctx.client_crt, SSL_FILETYPE_PEM) <= 0) {
982 Alert("config : %s '%s', server '%s': unable to load SSL private key from PEM file '%s'.\n",
983 proxy_type_str(curproxy), curproxy->id,
984 srv->id, srv->ssl_ctx.client_crt);
985 cfgerr++;
986 }
987 else if (SSL_CTX_use_certificate_chain_file(srv->ssl_ctx.ctx, srv->ssl_ctx.client_crt) <= 0) {
988 Alert("config : %s '%s', server '%s': unable to load ssl certificate from PEM file '%s'.\n",
989 proxy_type_str(curproxy), curproxy->id,
990 srv->id, srv->ssl_ctx.client_crt);
991 cfgerr++;
992 }
993 else if (SSL_CTX_check_private_key(srv->ssl_ctx.ctx) <= 0) {
994 Alert("config : %s '%s', server '%s': inconsistencies between private key and certificate loaded from PEM file '%s'.\n",
995 proxy_type_str(curproxy), curproxy->id,
996 srv->id, srv->ssl_ctx.client_crt);
997 cfgerr++;
998 }
999 }
Emeric Brun94324a42012-10-11 14:00:19 +02001000
1001 if (srv->ssl_ctx.options & SRV_SSL_O_NO_SSLV3)
1002 options |= SSL_OP_NO_SSLv3;
1003 if (srv->ssl_ctx.options & SRV_SSL_O_NO_TLSV10)
1004 options |= SSL_OP_NO_TLSv1;
1005 if (srv->ssl_ctx.options & SRV_SSL_O_NO_TLSV11)
1006 options |= SSL_OP_NO_TLSv1_1;
1007 if (srv->ssl_ctx.options & SRV_SSL_O_NO_TLSV12)
1008 options |= SSL_OP_NO_TLSv1_2;
Emeric Brunf9c5c472012-10-11 15:28:34 +02001009 if (srv->ssl_ctx.options & SRV_SSL_O_NO_TLS_TICKETS)
1010 options |= SSL_OP_NO_TICKET;
Emeric Brun94324a42012-10-11 14:00:19 +02001011 if (srv->ssl_ctx.options & SRV_SSL_O_USE_SSLV3)
1012 SSL_CTX_set_ssl_version(srv->ssl_ctx.ctx, SSLv3_client_method());
1013 if (srv->ssl_ctx.options & SRV_SSL_O_USE_TLSV10)
1014 SSL_CTX_set_ssl_version(srv->ssl_ctx.ctx, TLSv1_client_method());
1015#if SSL_OP_NO_TLSv1_1
1016 if (srv->ssl_ctx.options & SRV_SSL_O_USE_TLSV11)
1017 SSL_CTX_set_ssl_version(srv->ssl_ctx.ctx, TLSv1_1_client_method());
1018#endif
1019#if SSL_OP_NO_TLSv1_2
1020 if (srv->ssl_ctx.options & SRV_SSL_O_USE_TLSV12)
1021 SSL_CTX_set_ssl_version(srv->ssl_ctx.ctx, TLSv1_2_client_method());
1022#endif
1023
1024 SSL_CTX_set_options(srv->ssl_ctx.ctx, options);
1025 SSL_CTX_set_mode(srv->ssl_ctx.ctx, mode);
Emeric Brun850efd52014-01-29 12:24:34 +01001026
1027 if (global.ssl_server_verify == SSL_SERVER_VERIFY_REQUIRED)
1028 verify = SSL_VERIFY_PEER;
1029
1030 switch (srv->ssl_ctx.verify) {
1031 case SSL_SOCK_VERIFY_NONE:
1032 verify = SSL_VERIFY_NONE;
1033 break;
1034 case SSL_SOCK_VERIFY_REQUIRED:
1035 verify = SSL_VERIFY_PEER;
1036 break;
1037 }
Evan Broderbe554312013-06-27 00:05:25 -07001038 SSL_CTX_set_verify(srv->ssl_ctx.ctx,
Emeric Brun850efd52014-01-29 12:24:34 +01001039 verify,
Evan Broderbe554312013-06-27 00:05:25 -07001040 srv->ssl_ctx.verify_host ? ssl_sock_srv_verifycbk : NULL);
Emeric Brun850efd52014-01-29 12:24:34 +01001041 if (verify & SSL_VERIFY_PEER) {
Emeric Brunef42d922012-10-11 16:11:36 +02001042 if (srv->ssl_ctx.ca_file) {
1043 /* load CAfile to verify */
1044 if (!SSL_CTX_load_verify_locations(srv->ssl_ctx.ctx, srv->ssl_ctx.ca_file, NULL)) {
Willy Tarreau07ba08b2014-02-16 19:22:08 +01001045 Alert("Proxy '%s', server '%s' [%s:%d] unable to load CA file '%s'.\n",
Emeric Brunef42d922012-10-11 16:11:36 +02001046 curproxy->id, srv->id,
1047 srv->conf.file, srv->conf.line, srv->ssl_ctx.ca_file);
1048 cfgerr++;
1049 }
1050 }
Emeric Brun850efd52014-01-29 12:24:34 +01001051 else {
1052 if (global.ssl_server_verify == SSL_SERVER_VERIFY_REQUIRED)
Willy Tarreau07ba08b2014-02-16 19:22:08 +01001053 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 +01001054 curproxy->id, srv->id,
1055 srv->conf.file, srv->conf.line);
1056 else
Willy Tarreau07ba08b2014-02-16 19:22:08 +01001057 Alert("Proxy '%s', server '%s' [%s:%d] verify is enabled but no CA file specified.\n",
Emeric Brun850efd52014-01-29 12:24:34 +01001058 curproxy->id, srv->id,
1059 srv->conf.file, srv->conf.line);
1060 cfgerr++;
1061 }
Emeric Brunef42d922012-10-11 16:11:36 +02001062#ifdef X509_V_FLAG_CRL_CHECK
1063 if (srv->ssl_ctx.crl_file) {
1064 X509_STORE *store = SSL_CTX_get_cert_store(srv->ssl_ctx.ctx);
1065
1066 if (!store || !X509_STORE_load_locations(store, srv->ssl_ctx.crl_file, NULL)) {
Willy Tarreau07ba08b2014-02-16 19:22:08 +01001067 Alert("Proxy '%s', server '%s' [%s:%d] unable to configure CRL file '%s'.\n",
Emeric Brunef42d922012-10-11 16:11:36 +02001068 curproxy->id, srv->id,
1069 srv->conf.file, srv->conf.line, srv->ssl_ctx.crl_file);
1070 cfgerr++;
1071 }
1072 else {
1073 X509_STORE_set_flags(store, X509_V_FLAG_CRL_CHECK|X509_V_FLAG_CRL_CHECK_ALL);
1074 }
1075 }
1076#endif
1077 }
1078
Emeric Brun4f65bff2012-11-16 15:11:00 +01001079 if (global.tune.ssllifetime)
1080 SSL_CTX_set_timeout(srv->ssl_ctx.ctx, global.tune.ssllifetime);
1081
Emeric Brun94324a42012-10-11 14:00:19 +02001082 SSL_CTX_set_session_cache_mode(srv->ssl_ctx.ctx, SSL_SESS_CACHE_OFF);
1083 if (srv->ssl_ctx.ciphers &&
1084 !SSL_CTX_set_cipher_list(srv->ssl_ctx.ctx, srv->ssl_ctx.ciphers)) {
1085 Alert("Proxy '%s', server '%s' [%s:%d] : unable to set SSL cipher list to '%s'.\n",
1086 curproxy->id, srv->id,
1087 srv->conf.file, srv->conf.line, srv->ssl_ctx.ciphers);
1088 cfgerr++;
1089 }
1090
1091 return cfgerr;
1092}
1093
Willy Tarreau2a65ff02012-09-13 17:54:29 +02001094/* Walks down the two trees in bind_conf and prepares all certs. The pointer may
Emeric Brunfc0421f2012-09-07 17:30:07 +02001095 * be NULL, in which case nothing is done. Returns the number of errors
1096 * encountered.
1097 */
Willy Tarreau2a65ff02012-09-13 17:54:29 +02001098int ssl_sock_prepare_all_ctx(struct bind_conf *bind_conf, struct proxy *px)
Emeric Brunfc0421f2012-09-07 17:30:07 +02001099{
1100 struct ebmb_node *node;
1101 struct sni_ctx *sni;
1102 int err = 0;
1103
Willy Tarreau2a65ff02012-09-13 17:54:29 +02001104 if (!bind_conf || !bind_conf->is_ssl)
Emeric Brunfc0421f2012-09-07 17:30:07 +02001105 return 0;
1106
Willy Tarreau2a65ff02012-09-13 17:54:29 +02001107 node = ebmb_first(&bind_conf->sni_ctx);
Emeric Brunfc0421f2012-09-07 17:30:07 +02001108 while (node) {
1109 sni = ebmb_entry(node, struct sni_ctx, name);
1110 if (!sni->order) /* only initialize the CTX on its first occurrence */
Willy Tarreau2a65ff02012-09-13 17:54:29 +02001111 err += ssl_sock_prepare_ctx(bind_conf, sni->ctx, px);
Emeric Brunfc0421f2012-09-07 17:30:07 +02001112 node = ebmb_next(node);
1113 }
1114
Willy Tarreau2a65ff02012-09-13 17:54:29 +02001115 node = ebmb_first(&bind_conf->sni_w_ctx);
Emeric Brunfc0421f2012-09-07 17:30:07 +02001116 while (node) {
1117 sni = ebmb_entry(node, struct sni_ctx, name);
1118 if (!sni->order) /* only initialize the CTX on its first occurrence */
Willy Tarreau2a65ff02012-09-13 17:54:29 +02001119 err += ssl_sock_prepare_ctx(bind_conf, sni->ctx, px);
Emeric Brunfc0421f2012-09-07 17:30:07 +02001120 node = ebmb_next(node);
1121 }
1122 return err;
1123}
1124
Willy Tarreau2a65ff02012-09-13 17:54:29 +02001125/* Walks down the two trees in bind_conf and frees all the certs. The pointer may
Emeric Brunfc0421f2012-09-07 17:30:07 +02001126 * be NULL, in which case nothing is done. The default_ctx is nullified too.
1127 */
Willy Tarreau2a65ff02012-09-13 17:54:29 +02001128void ssl_sock_free_all_ctx(struct bind_conf *bind_conf)
Emeric Brunfc0421f2012-09-07 17:30:07 +02001129{
1130 struct ebmb_node *node, *back;
1131 struct sni_ctx *sni;
1132
Willy Tarreau2a65ff02012-09-13 17:54:29 +02001133 if (!bind_conf || !bind_conf->is_ssl)
Emeric Brunfc0421f2012-09-07 17:30:07 +02001134 return;
1135
Willy Tarreau2a65ff02012-09-13 17:54:29 +02001136 node = ebmb_first(&bind_conf->sni_ctx);
Emeric Brunfc0421f2012-09-07 17:30:07 +02001137 while (node) {
1138 sni = ebmb_entry(node, struct sni_ctx, name);
1139 back = ebmb_next(node);
1140 ebmb_delete(node);
1141 if (!sni->order) /* only free the CTX on its first occurrence */
1142 SSL_CTX_free(sni->ctx);
1143 free(sni);
1144 node = back;
1145 }
1146
Willy Tarreau2a65ff02012-09-13 17:54:29 +02001147 node = ebmb_first(&bind_conf->sni_w_ctx);
Emeric Brunfc0421f2012-09-07 17:30:07 +02001148 while (node) {
1149 sni = ebmb_entry(node, struct sni_ctx, name);
1150 back = ebmb_next(node);
1151 ebmb_delete(node);
1152 if (!sni->order) /* only free the CTX on its first occurrence */
1153 SSL_CTX_free(sni->ctx);
1154 free(sni);
1155 node = back;
1156 }
1157
Willy Tarreau2a65ff02012-09-13 17:54:29 +02001158 bind_conf->default_ctx = NULL;
Emeric Brune1f38db2012-09-03 20:36:47 +02001159}
1160
Emeric Brun46591952012-05-18 15:47:34 +02001161/*
1162 * This function is called if SSL * context is not yet allocated. The function
1163 * is designed to be called before any other data-layer operation and sets the
1164 * handshake flag on the connection. It is safe to call it multiple times.
1165 * It returns 0 on success and -1 in error case.
1166 */
1167static int ssl_sock_init(struct connection *conn)
1168{
1169 /* already initialized */
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02001170 if (conn->xprt_ctx)
Emeric Brun46591952012-05-18 15:47:34 +02001171 return 0;
1172
Willy Tarreau3c728722014-01-23 13:50:42 +01001173 if (!conn_ctrl_ready(conn))
Willy Tarreauf79c8172013-10-21 16:30:56 +02001174 return 0;
1175
Willy Tarreau20879a02012-12-03 16:32:10 +01001176 if (global.maxsslconn && sslconns >= global.maxsslconn) {
1177 conn->err_code = CO_ER_SSL_TOO_MANY;
Willy Tarreau403edff2012-09-06 11:58:37 +02001178 return -1;
Willy Tarreau20879a02012-12-03 16:32:10 +01001179 }
Willy Tarreau403edff2012-09-06 11:58:37 +02001180
Emeric Brun46591952012-05-18 15:47:34 +02001181 /* If it is in client mode initiate SSL session
1182 in connect state otherwise accept state */
Willy Tarreau3fdb3662012-11-12 00:42:33 +01001183 if (objt_server(conn->target)) {
Emeric Brun46591952012-05-18 15:47:34 +02001184 /* Alloc a new SSL session ctx */
Willy Tarreau3fdb3662012-11-12 00:42:33 +01001185 conn->xprt_ctx = SSL_new(objt_server(conn->target)->ssl_ctx.ctx);
Willy Tarreau20879a02012-12-03 16:32:10 +01001186 if (!conn->xprt_ctx) {
1187 conn->err_code = CO_ER_SSL_NO_MEM;
Emeric Brun46591952012-05-18 15:47:34 +02001188 return -1;
Willy Tarreau20879a02012-12-03 16:32:10 +01001189 }
Emeric Brun46591952012-05-18 15:47:34 +02001190
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02001191 SSL_set_connect_state(conn->xprt_ctx);
Willy Tarreau3fdb3662012-11-12 00:42:33 +01001192 if (objt_server(conn->target)->ssl_ctx.reused_sess)
1193 SSL_set_session(conn->xprt_ctx, objt_server(conn->target)->ssl_ctx.reused_sess);
Emeric Brun46591952012-05-18 15:47:34 +02001194
1195 /* set fd on SSL session context */
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02001196 SSL_set_fd(conn->xprt_ctx, conn->t.sock.fd);
Emeric Brun46591952012-05-18 15:47:34 +02001197
Evan Broderbe554312013-06-27 00:05:25 -07001198 /* set connection pointer */
1199 SSL_set_app_data(conn->xprt_ctx, conn);
1200
Emeric Brun46591952012-05-18 15:47:34 +02001201 /* leave init state and start handshake */
Willy Tarreau05737472012-09-04 08:03:39 +02001202 conn->flags |= CO_FL_SSL_WAIT_HS | CO_FL_WAIT_L6_CONN;
Willy Tarreau403edff2012-09-06 11:58:37 +02001203
1204 sslconns++;
Willy Tarreau71b734c2014-01-28 15:19:44 +01001205 totalsslconns++;
Emeric Brun46591952012-05-18 15:47:34 +02001206 return 0;
1207 }
Willy Tarreau3fdb3662012-11-12 00:42:33 +01001208 else if (objt_listener(conn->target)) {
Emeric Brun46591952012-05-18 15:47:34 +02001209 /* Alloc a new SSL session ctx */
Willy Tarreau3fdb3662012-11-12 00:42:33 +01001210 conn->xprt_ctx = SSL_new(objt_listener(conn->target)->bind_conf->default_ctx);
Willy Tarreau20879a02012-12-03 16:32:10 +01001211 if (!conn->xprt_ctx) {
1212 conn->err_code = CO_ER_SSL_NO_MEM;
Emeric Brun46591952012-05-18 15:47:34 +02001213 return -1;
Willy Tarreau20879a02012-12-03 16:32:10 +01001214 }
Emeric Brun46591952012-05-18 15:47:34 +02001215
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02001216 SSL_set_accept_state(conn->xprt_ctx);
Emeric Brun46591952012-05-18 15:47:34 +02001217
1218 /* set fd on SSL session context */
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02001219 SSL_set_fd(conn->xprt_ctx, conn->t.sock.fd);
Emeric Brun46591952012-05-18 15:47:34 +02001220
Emeric Brune1f38db2012-09-03 20:36:47 +02001221 /* set connection pointer */
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02001222 SSL_set_app_data(conn->xprt_ctx, conn);
Emeric Brune1f38db2012-09-03 20:36:47 +02001223
Emeric Brun46591952012-05-18 15:47:34 +02001224 /* leave init state and start handshake */
Willy Tarreau05737472012-09-04 08:03:39 +02001225 conn->flags |= CO_FL_SSL_WAIT_HS | CO_FL_WAIT_L6_CONN;
Willy Tarreau403edff2012-09-06 11:58:37 +02001226
1227 sslconns++;
Willy Tarreau71b734c2014-01-28 15:19:44 +01001228 totalsslconns++;
Emeric Brun46591952012-05-18 15:47:34 +02001229 return 0;
1230 }
1231 /* don't know how to handle such a target */
Willy Tarreau20879a02012-12-03 16:32:10 +01001232 conn->err_code = CO_ER_SSL_NO_TARGET;
Emeric Brun46591952012-05-18 15:47:34 +02001233 return -1;
1234}
1235
1236
1237/* This is the callback which is used when an SSL handshake is pending. It
1238 * updates the FD status if it wants some polling before being called again.
1239 * It returns 0 if it fails in a fatal way or needs to poll to go further,
1240 * otherwise it returns non-zero and removes itself from the connection's
1241 * flags (the bit is provided in <flag> by the caller).
1242 */
1243int ssl_sock_handshake(struct connection *conn, unsigned int flag)
1244{
1245 int ret;
1246
Willy Tarreau3c728722014-01-23 13:50:42 +01001247 if (!conn_ctrl_ready(conn))
Willy Tarreauf79c8172013-10-21 16:30:56 +02001248 return 0;
1249
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02001250 if (!conn->xprt_ctx)
Emeric Brun46591952012-05-18 15:47:34 +02001251 goto out_error;
1252
Emeric Brun674b7432012-11-08 19:21:55 +01001253 /* If we use SSL_do_handshake to process a reneg initiated by
1254 * the remote peer, it sometimes returns SSL_ERROR_SSL.
1255 * Usually SSL_write and SSL_read are used and process implicitly
1256 * the reneg handshake.
1257 * Here we use SSL_peek as a workaround for reneg.
1258 */
1259 if ((conn->flags & CO_FL_CONNECTED) && SSL_renegotiate_pending(conn->xprt_ctx)) {
1260 char c;
1261
1262 ret = SSL_peek(conn->xprt_ctx, &c, 1);
1263 if (ret <= 0) {
1264 /* handshake may have not been completed, let's find why */
1265 ret = SSL_get_error(conn->xprt_ctx, ret);
1266 if (ret == SSL_ERROR_WANT_WRITE) {
1267 /* SSL handshake needs to write, L4 connection may not be ready */
1268 __conn_sock_stop_recv(conn);
Willy Tarreaue1f50c42014-01-22 20:02:06 +01001269 __conn_sock_want_send(conn);
1270 fd_cant_send(conn->t.sock.fd);
Emeric Brun674b7432012-11-08 19:21:55 +01001271 return 0;
1272 }
1273 else if (ret == SSL_ERROR_WANT_READ) {
1274 /* handshake may have been completed but we have
1275 * no more data to read.
1276 */
1277 if (!SSL_renegotiate_pending(conn->xprt_ctx)) {
1278 ret = 1;
1279 goto reneg_ok;
1280 }
1281 /* SSL handshake needs to read, L4 connection is ready */
1282 if (conn->flags & CO_FL_WAIT_L4_CONN)
1283 conn->flags &= ~CO_FL_WAIT_L4_CONN;
1284 __conn_sock_stop_send(conn);
Willy Tarreaue1f50c42014-01-22 20:02:06 +01001285 __conn_sock_want_recv(conn);
1286 fd_cant_recv(conn->t.sock.fd);
Emeric Brun674b7432012-11-08 19:21:55 +01001287 return 0;
1288 }
1289 else if (ret == SSL_ERROR_SYSCALL) {
1290 /* if errno is null, then connection was successfully established */
1291 if (!errno && conn->flags & CO_FL_WAIT_L4_CONN)
1292 conn->flags &= ~CO_FL_WAIT_L4_CONN;
Willy Tarreau20879a02012-12-03 16:32:10 +01001293 if (!conn->err_code) {
1294 if (!((SSL *)conn->xprt_ctx)->packet_length)
1295 if (!errno)
1296 conn->err_code = CO_ER_SSL_EMPTY;
1297 else
1298 conn->err_code = CO_ER_SSL_ABORT;
1299 else
1300 conn->err_code = CO_ER_SSL_HANDSHAKE;
1301 }
Emeric Brun674b7432012-11-08 19:21:55 +01001302 goto out_error;
1303 }
1304 else {
1305 /* Fail on all other handshake errors */
1306 /* Note: OpenSSL may leave unread bytes in the socket's
1307 * buffer, causing an RST to be emitted upon close() on
1308 * TCP sockets. We first try to drain possibly pending
1309 * data to avoid this as much as possible.
1310 */
Willy Tarreau46be2e52014-01-20 12:10:52 +01001311 conn_drain(conn);
Willy Tarreau20879a02012-12-03 16:32:10 +01001312 if (!conn->err_code)
1313 conn->err_code = CO_ER_SSL_HANDSHAKE;
Emeric Brun674b7432012-11-08 19:21:55 +01001314 goto out_error;
1315 }
1316 }
1317 /* read some data: consider handshake completed */
1318 goto reneg_ok;
1319 }
1320
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02001321 ret = SSL_do_handshake(conn->xprt_ctx);
Emeric Brun46591952012-05-18 15:47:34 +02001322 if (ret != 1) {
1323 /* handshake did not complete, let's find why */
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02001324 ret = SSL_get_error(conn->xprt_ctx, ret);
Emeric Brun46591952012-05-18 15:47:34 +02001325
1326 if (ret == SSL_ERROR_WANT_WRITE) {
1327 /* SSL handshake needs to write, L4 connection may not be ready */
1328 __conn_sock_stop_recv(conn);
Willy Tarreaue1f50c42014-01-22 20:02:06 +01001329 __conn_sock_want_send(conn);
1330 fd_cant_send(conn->t.sock.fd);
Emeric Brun46591952012-05-18 15:47:34 +02001331 return 0;
1332 }
1333 else if (ret == SSL_ERROR_WANT_READ) {
1334 /* SSL handshake needs to read, L4 connection is ready */
1335 if (conn->flags & CO_FL_WAIT_L4_CONN)
1336 conn->flags &= ~CO_FL_WAIT_L4_CONN;
1337 __conn_sock_stop_send(conn);
Willy Tarreaue1f50c42014-01-22 20:02:06 +01001338 __conn_sock_want_recv(conn);
1339 fd_cant_recv(conn->t.sock.fd);
Emeric Brun46591952012-05-18 15:47:34 +02001340 return 0;
1341 }
Willy Tarreau89230192012-09-28 20:22:13 +02001342 else if (ret == SSL_ERROR_SYSCALL) {
1343 /* if errno is null, then connection was successfully established */
1344 if (!errno && conn->flags & CO_FL_WAIT_L4_CONN)
1345 conn->flags &= ~CO_FL_WAIT_L4_CONN;
Willy Tarreau20879a02012-12-03 16:32:10 +01001346
1347 if (!((SSL *)conn->xprt_ctx)->packet_length)
1348 if (!errno)
1349 conn->err_code = CO_ER_SSL_EMPTY;
1350 else
1351 conn->err_code = CO_ER_SSL_ABORT;
1352 else
1353 conn->err_code = CO_ER_SSL_HANDSHAKE;
Willy Tarreau89230192012-09-28 20:22:13 +02001354 goto out_error;
1355 }
Emeric Brun46591952012-05-18 15:47:34 +02001356 else {
1357 /* Fail on all other handshake errors */
Willy Tarreau566dc552012-10-19 20:52:18 +02001358 /* Note: OpenSSL may leave unread bytes in the socket's
1359 * buffer, causing an RST to be emitted upon close() on
1360 * TCP sockets. We first try to drain possibly pending
1361 * data to avoid this as much as possible.
1362 */
Willy Tarreau46be2e52014-01-20 12:10:52 +01001363 conn_drain(conn);
Willy Tarreau20879a02012-12-03 16:32:10 +01001364 if (!conn->err_code)
1365 conn->err_code = CO_ER_SSL_HANDSHAKE;
Emeric Brun46591952012-05-18 15:47:34 +02001366 goto out_error;
1367 }
1368 }
1369
Emeric Brun674b7432012-11-08 19:21:55 +01001370reneg_ok:
1371
Emeric Brun46591952012-05-18 15:47:34 +02001372 /* Handshake succeeded */
Willy Tarreau3fdb3662012-11-12 00:42:33 +01001373 if (objt_server(conn->target)) {
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02001374 if (!SSL_session_reused(conn->xprt_ctx)) {
Emeric Brun46591952012-05-18 15:47:34 +02001375 /* check if session was reused, if not store current session on server for reuse */
Willy Tarreau3fdb3662012-11-12 00:42:33 +01001376 if (objt_server(conn->target)->ssl_ctx.reused_sess)
1377 SSL_SESSION_free(objt_server(conn->target)->ssl_ctx.reused_sess);
Emeric Brun46591952012-05-18 15:47:34 +02001378
Willy Tarreau3fdb3662012-11-12 00:42:33 +01001379 objt_server(conn->target)->ssl_ctx.reused_sess = SSL_get1_session(conn->xprt_ctx);
Emeric Brun46591952012-05-18 15:47:34 +02001380 }
1381 }
1382
1383 /* The connection is now established at both layers, it's time to leave */
1384 conn->flags &= ~(flag | CO_FL_WAIT_L4_CONN | CO_FL_WAIT_L6_CONN);
1385 return 1;
1386
1387 out_error:
Emeric Brun644cde02012-12-14 11:21:13 +01001388 /* Clear openssl global errors stack */
1389 ERR_clear_error();
1390
Emeric Brun9fa89732012-10-04 17:09:56 +02001391 /* free resumed session if exists */
Willy Tarreau3fdb3662012-11-12 00:42:33 +01001392 if (objt_server(conn->target) && objt_server(conn->target)->ssl_ctx.reused_sess) {
1393 SSL_SESSION_free(objt_server(conn->target)->ssl_ctx.reused_sess);
1394 objt_server(conn->target)->ssl_ctx.reused_sess = NULL;
Emeric Brun9fa89732012-10-04 17:09:56 +02001395 }
1396
Emeric Brun46591952012-05-18 15:47:34 +02001397 /* Fail on all other handshake errors */
1398 conn->flags |= CO_FL_ERROR;
Willy Tarreau20879a02012-12-03 16:32:10 +01001399 if (!conn->err_code)
1400 conn->err_code = CO_ER_SSL_HANDSHAKE;
Emeric Brun46591952012-05-18 15:47:34 +02001401 return 0;
1402}
1403
1404/* Receive up to <count> bytes from connection <conn>'s socket and store them
Willy Tarreauabf08d92014-01-14 11:31:27 +01001405 * into buffer <buf>. Only one call to recv() is performed, unless the
Emeric Brun46591952012-05-18 15:47:34 +02001406 * buffer wraps, in which case a second call may be performed. The connection's
1407 * flags are updated with whatever special event is detected (error, read0,
1408 * empty). The caller is responsible for taking care of those events and
1409 * avoiding the call if inappropriate. The function does not call the
1410 * connection's polling update function, so the caller is responsible for this.
1411 */
1412static int ssl_sock_to_buf(struct connection *conn, struct buffer *buf, int count)
1413{
1414 int ret, done = 0;
Willy Tarreauabf08d92014-01-14 11:31:27 +01001415 int try;
Emeric Brun46591952012-05-18 15:47:34 +02001416
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02001417 if (!conn->xprt_ctx)
Emeric Brun46591952012-05-18 15:47:34 +02001418 goto out_error;
1419
1420 if (conn->flags & CO_FL_HANDSHAKE)
1421 /* a handshake was requested */
1422 return 0;
1423
Willy Tarreauabf08d92014-01-14 11:31:27 +01001424 /* let's realign the buffer to optimize I/O */
1425 if (buffer_empty(buf))
Emeric Brun46591952012-05-18 15:47:34 +02001426 buf->p = buf->data;
Emeric Brun46591952012-05-18 15:47:34 +02001427
1428 /* read the largest possible block. For this, we perform only one call
1429 * to recv() unless the buffer wraps and we exactly fill the first hunk,
1430 * in which case we accept to do it once again. A new attempt is made on
1431 * EINTR too.
1432 */
Willy Tarreau00b0fb92014-01-17 11:09:40 +01001433 while (count > 0) {
Willy Tarreauabf08d92014-01-14 11:31:27 +01001434 /* first check if we have some room after p+i */
1435 try = buf->data + buf->size - (buf->p + buf->i);
1436 /* otherwise continue between data and p-o */
1437 if (try <= 0) {
1438 try = buf->p - (buf->data + buf->o);
1439 if (try <= 0)
1440 break;
1441 }
1442 if (try > count)
1443 try = count;
1444
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02001445 ret = SSL_read(conn->xprt_ctx, bi_end(buf), try);
Emeric Brune1f38db2012-09-03 20:36:47 +02001446 if (conn->flags & CO_FL_ERROR) {
1447 /* CO_FL_ERROR may be set by ssl_sock_infocbk */
Emeric Brun644cde02012-12-14 11:21:13 +01001448 goto out_error;
Emeric Brune1f38db2012-09-03 20:36:47 +02001449 }
Emeric Brun46591952012-05-18 15:47:34 +02001450 if (ret > 0) {
1451 buf->i += ret;
1452 done += ret;
1453 if (ret < try)
1454 break;
1455 count -= ret;
Emeric Brun46591952012-05-18 15:47:34 +02001456 }
1457 else if (ret == 0) {
Emeric Brun644cde02012-12-14 11:21:13 +01001458 ret = SSL_get_error(conn->xprt_ctx, ret);
1459 if (ret != SSL_ERROR_ZERO_RETURN) {
Emeric Brun1c646862012-12-14 12:33:41 +01001460 /* error on protocol or underlying transport */
1461 if ((ret != SSL_ERROR_SYSCALL)
1462 || (errno && (errno != EAGAIN)))
1463 conn->flags |= CO_FL_ERROR;
1464
Emeric Brun644cde02012-12-14 11:21:13 +01001465 /* Clear openssl global errors stack */
1466 ERR_clear_error();
1467 }
Emeric Brun46591952012-05-18 15:47:34 +02001468 goto read0;
1469 }
1470 else {
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02001471 ret = SSL_get_error(conn->xprt_ctx, ret);
Emeric Brun46591952012-05-18 15:47:34 +02001472 if (ret == SSL_ERROR_WANT_WRITE) {
Emeric Brun8af8dd12012-11-08 17:56:20 +01001473 /* handshake is running, and it needs to enable write */
Emeric Brun46591952012-05-18 15:47:34 +02001474 conn->flags |= CO_FL_SSL_WAIT_HS;
Emeric Brun8af8dd12012-11-08 17:56:20 +01001475 __conn_sock_want_send(conn);
Emeric Brun46591952012-05-18 15:47:34 +02001476 break;
1477 }
1478 else if (ret == SSL_ERROR_WANT_READ) {
Emeric Brun282a76a2012-11-08 18:02:56 +01001479 if (SSL_renegotiate_pending(conn->xprt_ctx)) {
1480 /* handshake is running, and it may need to re-enable read */
1481 conn->flags |= CO_FL_SSL_WAIT_HS;
1482 __conn_sock_want_recv(conn);
1483 break;
1484 }
Emeric Brun46591952012-05-18 15:47:34 +02001485 /* we need to poll for retry a read later */
Willy Tarreaue1f50c42014-01-22 20:02:06 +01001486 fd_cant_recv(conn->t.sock.fd);
Emeric Brun46591952012-05-18 15:47:34 +02001487 break;
1488 }
1489 /* otherwise it's a real error */
1490 goto out_error;
1491 }
1492 }
1493 return done;
1494
1495 read0:
1496 conn_sock_read0(conn);
1497 return done;
1498 out_error:
Emeric Brun644cde02012-12-14 11:21:13 +01001499 /* Clear openssl global errors stack */
1500 ERR_clear_error();
1501
Emeric Brun46591952012-05-18 15:47:34 +02001502 conn->flags |= CO_FL_ERROR;
1503 return done;
1504}
1505
1506
1507/* Send all pending bytes from buffer <buf> to connection <conn>'s socket.
Willy Tarreau1049b1f2014-02-02 01:51:17 +01001508 * <flags> may contain some CO_SFL_* flags to hint the system about other
1509 * pending data for example, but this flag is ignored at the moment.
Emeric Brun46591952012-05-18 15:47:34 +02001510 * Only one call to send() is performed, unless the buffer wraps, in which case
1511 * a second call may be performed. The connection's flags are updated with
1512 * whatever special event is detected (error, empty). The caller is responsible
1513 * for taking care of those events and avoiding the call if inappropriate. The
1514 * function does not call the connection's polling update function, so the caller
1515 * is responsible for this.
1516 */
1517static int ssl_sock_from_buf(struct connection *conn, struct buffer *buf, int flags)
1518{
1519 int ret, try, done;
1520
1521 done = 0;
1522
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02001523 if (!conn->xprt_ctx)
Emeric Brun46591952012-05-18 15:47:34 +02001524 goto out_error;
1525
1526 if (conn->flags & CO_FL_HANDSHAKE)
1527 /* a handshake was requested */
1528 return 0;
1529
1530 /* send the largest possible block. For this we perform only one call
1531 * to send() unless the buffer wraps and we exactly fill the first hunk,
1532 * in which case we accept to do it once again.
1533 */
1534 while (buf->o) {
Kevin Hestercad82342013-05-30 15:12:41 -07001535 try = bo_contig_data(buf);
Willy Tarreaubfd59462013-02-21 07:46:09 +01001536
Willy Tarreau7bed9452014-02-02 02:00:24 +01001537 if (!(flags & CO_SFL_STREAMER) &&
Willy Tarreau518cedd2014-02-17 15:43:01 +01001538 !(conn->xprt_st & SSL_SOCK_SEND_UNLIMITED) &&
1539 global.tune.ssl_max_record && try > global.tune.ssl_max_record) {
Willy Tarreaubfd59462013-02-21 07:46:09 +01001540 try = global.tune.ssl_max_record;
Willy Tarreau518cedd2014-02-17 15:43:01 +01001541 }
1542 else {
1543 /* we need to keep the information about the fact that
1544 * we're not limiting the upcoming send(), because if it
1545 * fails, we'll have to retry with at least as many data.
1546 */
1547 conn->xprt_st |= SSL_SOCK_SEND_UNLIMITED;
1548 }
Willy Tarreaubfd59462013-02-21 07:46:09 +01001549
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02001550 ret = SSL_write(conn->xprt_ctx, bo_ptr(buf), try);
Willy Tarreau518cedd2014-02-17 15:43:01 +01001551
Emeric Brune1f38db2012-09-03 20:36:47 +02001552 if (conn->flags & CO_FL_ERROR) {
1553 /* CO_FL_ERROR may be set by ssl_sock_infocbk */
Emeric Brun644cde02012-12-14 11:21:13 +01001554 goto out_error;
Emeric Brune1f38db2012-09-03 20:36:47 +02001555 }
Emeric Brun46591952012-05-18 15:47:34 +02001556 if (ret > 0) {
Willy Tarreau518cedd2014-02-17 15:43:01 +01001557 conn->xprt_st &= ~SSL_SOCK_SEND_UNLIMITED;
1558
Emeric Brun46591952012-05-18 15:47:34 +02001559 buf->o -= ret;
1560 done += ret;
1561
Willy Tarreau5fb38032012-12-16 19:39:09 +01001562 if (likely(buffer_empty(buf)))
Emeric Brun46591952012-05-18 15:47:34 +02001563 /* optimize data alignment in the buffer */
1564 buf->p = buf->data;
1565
1566 /* if the system buffer is full, don't insist */
1567 if (ret < try)
1568 break;
1569 }
1570 else {
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02001571 ret = SSL_get_error(conn->xprt_ctx, ret);
Emeric Brun46591952012-05-18 15:47:34 +02001572 if (ret == SSL_ERROR_WANT_WRITE) {
Emeric Brun282a76a2012-11-08 18:02:56 +01001573 if (SSL_renegotiate_pending(conn->xprt_ctx)) {
1574 /* handshake is running, and it may need to re-enable write */
1575 conn->flags |= CO_FL_SSL_WAIT_HS;
1576 __conn_sock_want_send(conn);
1577 break;
1578 }
Emeric Brun46591952012-05-18 15:47:34 +02001579 /* we need to poll to retry a write later */
Willy Tarreaue1f50c42014-01-22 20:02:06 +01001580 fd_cant_send(conn->t.sock.fd);
Emeric Brun46591952012-05-18 15:47:34 +02001581 break;
1582 }
1583 else if (ret == SSL_ERROR_WANT_READ) {
Emeric Brun8af8dd12012-11-08 17:56:20 +01001584 /* handshake is running, and it needs to enable read */
Emeric Brun46591952012-05-18 15:47:34 +02001585 conn->flags |= CO_FL_SSL_WAIT_HS;
Emeric Brun8af8dd12012-11-08 17:56:20 +01001586 __conn_sock_want_recv(conn);
Emeric Brun46591952012-05-18 15:47:34 +02001587 break;
1588 }
1589 goto out_error;
1590 }
1591 }
1592 return done;
1593
1594 out_error:
Emeric Brun644cde02012-12-14 11:21:13 +01001595 /* Clear openssl global errors stack */
1596 ERR_clear_error();
1597
Emeric Brun46591952012-05-18 15:47:34 +02001598 conn->flags |= CO_FL_ERROR;
1599 return done;
1600}
1601
Emeric Brun46591952012-05-18 15:47:34 +02001602static void ssl_sock_close(struct connection *conn) {
1603
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02001604 if (conn->xprt_ctx) {
1605 SSL_free(conn->xprt_ctx);
1606 conn->xprt_ctx = NULL;
Willy Tarreau403edff2012-09-06 11:58:37 +02001607 sslconns--;
Emeric Brun46591952012-05-18 15:47:34 +02001608 }
Emeric Brun46591952012-05-18 15:47:34 +02001609}
1610
1611/* This function tries to perform a clean shutdown on an SSL connection, and in
1612 * any case, flags the connection as reusable if no handshake was in progress.
1613 */
1614static void ssl_sock_shutw(struct connection *conn, int clean)
1615{
1616 if (conn->flags & CO_FL_HANDSHAKE)
1617 return;
1618 /* no handshake was in progress, try a clean ssl shutdown */
Emeric Brun644cde02012-12-14 11:21:13 +01001619 if (clean && (SSL_shutdown(conn->xprt_ctx) <= 0)) {
1620 /* Clear openssl global errors stack */
1621 ERR_clear_error();
1622 }
Emeric Brun46591952012-05-18 15:47:34 +02001623
1624 /* force flag on ssl to keep session in cache regardless shutdown result */
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02001625 SSL_set_shutdown(conn->xprt_ctx, SSL_SENT_SHUTDOWN);
Emeric Brun46591952012-05-18 15:47:34 +02001626}
1627
Willy Tarreauffc3fcd2012-10-12 20:17:54 +02001628/* used for logging, may be changed for a sample fetch later */
1629const char *ssl_sock_get_cipher_name(struct connection *conn)
1630{
1631 if (!conn->xprt && !conn->xprt_ctx)
1632 return NULL;
1633 return SSL_get_cipher_name(conn->xprt_ctx);
1634}
1635
1636/* used for logging, may be changed for a sample fetch later */
1637const char *ssl_sock_get_proto_version(struct connection *conn)
1638{
1639 if (!conn->xprt && !conn->xprt_ctx)
1640 return NULL;
1641 return SSL_get_version(conn->xprt_ctx);
1642}
1643
Willy Tarreau8d598402012-10-22 17:58:39 +02001644/* Extract a serial from a cert, and copy it to a chunk.
1645 * Returns 1 if serial is found and copied, 0 if no serial found and
1646 * -1 if output is not large enough.
1647 */
1648static int
1649ssl_sock_get_serial(X509 *crt, struct chunk *out)
1650{
1651 ASN1_INTEGER *serial;
1652
1653 serial = X509_get_serialNumber(crt);
1654 if (!serial)
1655 return 0;
1656
1657 if (out->size < serial->length)
1658 return -1;
1659
1660 memcpy(out->str, serial->data, serial->length);
1661 out->len = serial->length;
1662 return 1;
1663}
1664
Emeric Brunce5ad802012-10-22 14:11:22 +02001665
1666/* Copy Date in ASN1_UTCTIME format in struct chunk out.
1667 * Returns 1 if serial is found and copied, 0 if no valid time found
1668 * and -1 if output is not large enough.
1669 */
1670static int
1671ssl_sock_get_time(ASN1_TIME *tm, struct chunk *out)
1672{
1673 if (tm->type == V_ASN1_GENERALIZEDTIME) {
1674 ASN1_GENERALIZEDTIME *gentm = (ASN1_GENERALIZEDTIME *)tm;
1675
1676 if (gentm->length < 12)
1677 return 0;
1678 if (gentm->data[0] != 0x32 || gentm->data[1] != 0x30)
1679 return 0;
1680 if (out->size < gentm->length-2)
1681 return -1;
1682
1683 memcpy(out->str, gentm->data+2, gentm->length-2);
1684 out->len = gentm->length-2;
1685 return 1;
1686 }
1687 else if (tm->type == V_ASN1_UTCTIME) {
1688 ASN1_UTCTIME *utctm = (ASN1_UTCTIME *)tm;
1689
1690 if (utctm->length < 10)
1691 return 0;
1692 if (utctm->data[0] >= 0x35)
1693 return 0;
1694 if (out->size < utctm->length)
1695 return -1;
1696
1697 memcpy(out->str, utctm->data, utctm->length);
1698 out->len = utctm->length;
1699 return 1;
1700 }
1701
1702 return 0;
1703}
1704
Emeric Brun87855892012-10-17 17:39:35 +02001705/* Extract an entry from a X509_NAME and copy its value to an output chunk.
1706 * Returns 1 if entry found, 0 if entry not found, or -1 if output not large enough.
1707 */
1708static int
1709ssl_sock_get_dn_entry(X509_NAME *a, const struct chunk *entry, int pos, struct chunk *out)
1710{
1711 X509_NAME_ENTRY *ne;
1712 int i, j, n;
1713 int cur = 0;
1714 const char *s;
1715 char tmp[128];
1716
1717 out->len = 0;
1718 for (i = 0; i < sk_X509_NAME_ENTRY_num(a->entries); i++) {
1719 if (pos < 0)
1720 j = (sk_X509_NAME_ENTRY_num(a->entries)-1) - i;
1721 else
1722 j = i;
1723
1724 ne = sk_X509_NAME_ENTRY_value(a->entries, j);
1725 n = OBJ_obj2nid(ne->object);
1726 if ((n == NID_undef) || ((s = OBJ_nid2sn(n)) == NULL)) {
1727 i2t_ASN1_OBJECT(tmp, sizeof(tmp), ne->object);
1728 s = tmp;
1729 }
1730
1731 if (chunk_strcasecmp(entry, s) != 0)
1732 continue;
1733
1734 if (pos < 0)
1735 cur--;
1736 else
1737 cur++;
1738
1739 if (cur != pos)
1740 continue;
1741
1742 if (ne->value->length > out->size)
1743 return -1;
1744
1745 memcpy(out->str, ne->value->data, ne->value->length);
1746 out->len = ne->value->length;
1747 return 1;
1748 }
1749
1750 return 0;
1751
1752}
1753
1754/* Extract and format full DN from a X509_NAME and copy result into a chunk
1755 * Returns 1 if dn entries exits, 0 if no dn entry found or -1 if output is not large enough.
1756 */
1757static int
1758ssl_sock_get_dn_oneline(X509_NAME *a, struct chunk *out)
1759{
1760 X509_NAME_ENTRY *ne;
1761 int i, n, ln;
1762 int l = 0;
1763 const char *s;
1764 char *p;
1765 char tmp[128];
1766
1767 out->len = 0;
1768 p = out->str;
1769 for (i = 0; i < sk_X509_NAME_ENTRY_num(a->entries); i++) {
1770 ne = sk_X509_NAME_ENTRY_value(a->entries, i);
1771 n = OBJ_obj2nid(ne->object);
1772 if ((n == NID_undef) || ((s = OBJ_nid2sn(n)) == NULL)) {
1773 i2t_ASN1_OBJECT(tmp, sizeof(tmp), ne->object);
1774 s = tmp;
1775 }
1776 ln = strlen(s);
1777
1778 l += 1 + ln + 1 + ne->value->length;
1779 if (l > out->size)
1780 return -1;
1781 out->len = l;
1782
1783 *(p++)='/';
1784 memcpy(p, s, ln);
1785 p += ln;
1786 *(p++)='=';
1787 memcpy(p, ne->value->data, ne->value->length);
1788 p += ne->value->length;
1789 }
1790
1791 if (!out->len)
1792 return 0;
1793
1794 return 1;
1795}
1796
Willy Tarreau7875d092012-09-10 08:20:03 +02001797/***** Below are some sample fetching functions for ACL/patterns *****/
1798
Emeric Brune64aef12012-09-21 13:15:06 +02001799/* boolean, returns true if client cert was present */
1800static int
Emeric Brun2525b6b2012-10-18 15:59:43 +02001801smp_fetch_ssl_fc_has_crt(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
Willy Tarreauef38c392013-07-22 16:29:32 +02001802 const struct arg *args, struct sample *smp, const char *kw)
Emeric Brune64aef12012-09-21 13:15:06 +02001803{
Willy Tarreaub363a1f2013-10-01 10:45:07 +02001804 struct connection *conn;
1805
1806 if (!l4)
1807 return 0;
1808
1809 conn = objt_conn(l4->si[0].end);
1810 if (!conn || conn->xprt != &ssl_sock)
Emeric Brune64aef12012-09-21 13:15:06 +02001811 return 0;
1812
Willy Tarreaub363a1f2013-10-01 10:45:07 +02001813 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brune64aef12012-09-21 13:15:06 +02001814 smp->flags |= SMP_F_MAY_CHANGE;
1815 return 0;
1816 }
1817
1818 smp->flags = 0;
1819 smp->type = SMP_T_BOOL;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02001820 smp->data.uint = SSL_SOCK_ST_FL_VERIFY_DONE & conn->xprt_st ? 1 : 0;
Emeric Brune64aef12012-09-21 13:15:06 +02001821
1822 return 1;
1823}
1824
Willy Tarreau8d598402012-10-22 17:58:39 +02001825/* bin, returns serial in a binary chunk */
1826static int
1827smp_fetch_ssl_c_serial(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
Willy Tarreauef38c392013-07-22 16:29:32 +02001828 const struct arg *args, struct sample *smp, const char *kw)
Willy Tarreau8d598402012-10-22 17:58:39 +02001829{
1830 X509 *crt = NULL;
1831 int ret = 0;
1832 struct chunk *smp_trash;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02001833 struct connection *conn;
1834
1835 if (!l4)
1836 return 0;
Willy Tarreau8d598402012-10-22 17:58:39 +02001837
Willy Tarreaub363a1f2013-10-01 10:45:07 +02001838 conn = objt_conn(l4->si[0].end);
1839 if (!conn || conn->xprt != &ssl_sock)
Willy Tarreau8d598402012-10-22 17:58:39 +02001840 return 0;
1841
Willy Tarreaub363a1f2013-10-01 10:45:07 +02001842 if (!(conn->flags & CO_FL_CONNECTED)) {
Willy Tarreau8d598402012-10-22 17:58:39 +02001843 smp->flags |= SMP_F_MAY_CHANGE;
1844 return 0;
1845 }
1846
1847 /* SSL_get_peer_certificate, it increase X509 * ref count */
Willy Tarreaub363a1f2013-10-01 10:45:07 +02001848 crt = SSL_get_peer_certificate(conn->xprt_ctx);
Willy Tarreau8d598402012-10-22 17:58:39 +02001849 if (!crt)
1850 goto out;
1851
Willy Tarreau47ca5452012-12-23 20:22:19 +01001852 smp_trash = get_trash_chunk();
Willy Tarreau8d598402012-10-22 17:58:39 +02001853 if (ssl_sock_get_serial(crt, smp_trash) <= 0)
1854 goto out;
1855
1856 smp->data.str = *smp_trash;
1857 smp->type = SMP_T_BIN;
1858 ret = 1;
1859out:
1860 if (crt)
1861 X509_free(crt);
1862 return ret;
1863}
Emeric Brune64aef12012-09-21 13:15:06 +02001864
James Votha051b4a2013-05-14 20:37:59 +02001865/* bin, returns the client certificate's SHA-1 fingerprint (SHA-1 hash of DER-encoded certificate) in a binary chunk */
1866static int
1867smp_fetch_ssl_c_sha1(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
Willy Tarreauef38c392013-07-22 16:29:32 +02001868 const struct arg *args, struct sample *smp, const char *kw)
James Votha051b4a2013-05-14 20:37:59 +02001869{
1870 X509 *crt = NULL;
1871 const EVP_MD *digest;
1872 int ret = 0;
1873 struct chunk *smp_trash;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02001874 struct connection *conn;
James Votha051b4a2013-05-14 20:37:59 +02001875
Willy Tarreaub363a1f2013-10-01 10:45:07 +02001876 if (!l4)
James Votha051b4a2013-05-14 20:37:59 +02001877 return 0;
1878
Willy Tarreaub363a1f2013-10-01 10:45:07 +02001879 conn = objt_conn(l4->si[0].end);
1880 if (!conn || conn->xprt != &ssl_sock)
1881 return 0;
1882
1883 if (!(conn->flags & CO_FL_CONNECTED)) {
James Votha051b4a2013-05-14 20:37:59 +02001884 smp->flags |= SMP_F_MAY_CHANGE;
1885 return 0;
1886 }
1887
1888 /* SSL_get_peer_certificate, it increase X509 * ref count */
Willy Tarreaub363a1f2013-10-01 10:45:07 +02001889 crt = SSL_get_peer_certificate(conn->xprt_ctx);
James Votha051b4a2013-05-14 20:37:59 +02001890 if (!crt)
1891 goto out;
1892
1893 smp_trash = get_trash_chunk();
1894 digest = EVP_sha1();
1895 X509_digest(crt, digest, (unsigned char *)smp_trash->str, (unsigned int *)&smp_trash->len);
1896
1897 smp->data.str = *smp_trash;
1898 smp->type = SMP_T_BIN;
1899 ret = 1;
1900out:
1901 if (crt)
1902 X509_free(crt);
1903 return ret;
1904}
1905
Emeric Brunce5ad802012-10-22 14:11:22 +02001906/*str, returns notafter date in ASN1_UTCTIME format */
1907static int
1908smp_fetch_ssl_c_notafter(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
Willy Tarreauef38c392013-07-22 16:29:32 +02001909 const struct arg *args, struct sample *smp, const char *kw)
Emeric Brunce5ad802012-10-22 14:11:22 +02001910{
1911 X509 *crt = NULL;
1912 int ret = 0;
1913 struct chunk *smp_trash;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02001914 struct connection *conn;
Emeric Brunce5ad802012-10-22 14:11:22 +02001915
Willy Tarreaub363a1f2013-10-01 10:45:07 +02001916 if (!l4)
Emeric Brunce5ad802012-10-22 14:11:22 +02001917 return 0;
1918
Willy Tarreaub363a1f2013-10-01 10:45:07 +02001919 conn = objt_conn(l4->si[0].end);
1920 if (!conn || conn->xprt != &ssl_sock)
1921 return 0;
1922
1923 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brunce5ad802012-10-22 14:11:22 +02001924 smp->flags |= SMP_F_MAY_CHANGE;
1925 return 0;
1926 }
1927
1928 /* SSL_get_peer_certificate, it increase X509 * ref count */
Willy Tarreaub363a1f2013-10-01 10:45:07 +02001929 crt = SSL_get_peer_certificate(conn->xprt_ctx);
Emeric Brunce5ad802012-10-22 14:11:22 +02001930 if (!crt)
1931 goto out;
1932
Willy Tarreau47ca5452012-12-23 20:22:19 +01001933 smp_trash = get_trash_chunk();
Emeric Brunce5ad802012-10-22 14:11:22 +02001934 if (ssl_sock_get_time(X509_get_notAfter(crt), smp_trash) <= 0)
1935 goto out;
1936
1937 smp->data.str = *smp_trash;
1938 smp->type = SMP_T_STR;
1939 ret = 1;
1940out:
1941 if (crt)
1942 X509_free(crt);
1943 return ret;
1944}
1945
Emeric Brun87855892012-10-17 17:39:35 +02001946/* str, returns a string of a formatted full dn \C=..\O=..\OU=.. \CN=.. */
1947static int
1948smp_fetch_ssl_c_i_dn(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
Willy Tarreauef38c392013-07-22 16:29:32 +02001949 const struct arg *args, struct sample *smp, const char *kw)
Emeric Brun87855892012-10-17 17:39:35 +02001950{
1951 X509 *crt = NULL;
1952 X509_NAME *name;
1953 int ret = 0;
1954 struct chunk *smp_trash;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02001955 struct connection *conn;
Emeric Brun87855892012-10-17 17:39:35 +02001956
Willy Tarreaub363a1f2013-10-01 10:45:07 +02001957 if (!l4)
Emeric Brun87855892012-10-17 17:39:35 +02001958 return 0;
1959
Willy Tarreaub363a1f2013-10-01 10:45:07 +02001960 conn = objt_conn(l4->si[0].end);
1961 if (!conn || conn->xprt != &ssl_sock)
1962 return 0;
1963
1964 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brun87855892012-10-17 17:39:35 +02001965 smp->flags |= SMP_F_MAY_CHANGE;
1966 return 0;
1967 }
1968
1969 /* SSL_get_peer_certificate, it increase X509 * ref count */
Willy Tarreaub363a1f2013-10-01 10:45:07 +02001970 crt = SSL_get_peer_certificate(conn->xprt_ctx);
Emeric Brun87855892012-10-17 17:39:35 +02001971 if (!crt)
1972 goto out;
1973
1974 name = X509_get_issuer_name(crt);
1975 if (!name)
1976 goto out;
1977
Willy Tarreau47ca5452012-12-23 20:22:19 +01001978 smp_trash = get_trash_chunk();
Emeric Brun87855892012-10-17 17:39:35 +02001979 if (args && args[0].type == ARGT_STR) {
1980 int pos = 1;
1981
1982 if (args[1].type == ARGT_SINT)
1983 pos = args[1].data.sint;
1984 else if (args[1].type == ARGT_UINT)
1985 pos =(int)args[1].data.uint;
1986
1987 if (ssl_sock_get_dn_entry(name, &args[0].data.str, pos, smp_trash) <= 0)
1988 goto out;
1989 }
1990 else if (ssl_sock_get_dn_oneline(name, smp_trash) <= 0)
1991 goto out;
1992
1993 smp->type = SMP_T_STR;
1994 smp->data.str = *smp_trash;
1995 ret = 1;
1996out:
1997 if (crt)
1998 X509_free(crt);
1999 return ret;
2000}
2001
Emeric Brunce5ad802012-10-22 14:11:22 +02002002/*str, returns notbefore date in ASN1_UTCTIME format */
2003static int
2004smp_fetch_ssl_c_notbefore(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
Willy Tarreauef38c392013-07-22 16:29:32 +02002005 const struct arg *args, struct sample *smp, const char *kw)
Emeric Brunce5ad802012-10-22 14:11:22 +02002006{
2007 X509 *crt = NULL;
2008 int ret = 0;
2009 struct chunk *smp_trash;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002010 struct connection *conn;
2011
2012 if (!l4)
2013 return 0;
Emeric Brunce5ad802012-10-22 14:11:22 +02002014
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002015 conn = objt_conn(l4->si[0].end);
2016 if (!conn || conn->xprt != &ssl_sock)
Emeric Brunce5ad802012-10-22 14:11:22 +02002017 return 0;
2018
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002019 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brunce5ad802012-10-22 14:11:22 +02002020 smp->flags |= SMP_F_MAY_CHANGE;
2021 return 0;
2022 }
2023
2024 /* SSL_get_peer_certificate, it increase X509 * ref count */
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002025 crt = SSL_get_peer_certificate(conn->xprt_ctx);
Emeric Brunce5ad802012-10-22 14:11:22 +02002026 if (!crt)
2027 goto out;
2028
Willy Tarreau47ca5452012-12-23 20:22:19 +01002029 smp_trash = get_trash_chunk();
Emeric Brunce5ad802012-10-22 14:11:22 +02002030 if (ssl_sock_get_time(X509_get_notBefore(crt), smp_trash) <= 0)
2031 goto out;
2032
2033 smp->data.str = *smp_trash;
2034 smp->type = SMP_T_STR;
2035 ret = 1;
2036out:
2037 if (crt)
2038 X509_free(crt);
2039 return ret;
2040}
2041
Emeric Brun87855892012-10-17 17:39:35 +02002042/* str, returns a string of a formatted full dn \C=..\O=..\OU=.. \CN=.. */
2043static int
2044smp_fetch_ssl_c_s_dn(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
Willy Tarreauef38c392013-07-22 16:29:32 +02002045 const struct arg *args, struct sample *smp, const char *kw)
Emeric Brun87855892012-10-17 17:39:35 +02002046{
2047 X509 *crt = NULL;
2048 X509_NAME *name;
2049 int ret = 0;
2050 struct chunk *smp_trash;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002051 struct connection *conn;
Emeric Brun87855892012-10-17 17:39:35 +02002052
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002053 if (!l4)
Emeric Brun87855892012-10-17 17:39:35 +02002054 return 0;
2055
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002056 conn = objt_conn(l4->si[0].end);
2057 if (!conn || conn->xprt != &ssl_sock)
2058 return 0;
2059
2060 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brun87855892012-10-17 17:39:35 +02002061 smp->flags |= SMP_F_MAY_CHANGE;
2062 return 0;
2063 }
2064
2065 /* SSL_get_peer_certificate, it increase X509 * ref count */
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002066 crt = SSL_get_peer_certificate(conn->xprt_ctx);
Emeric Brun87855892012-10-17 17:39:35 +02002067 if (!crt)
2068 goto out;
2069
2070 name = X509_get_subject_name(crt);
2071 if (!name)
2072 goto out;
2073
Willy Tarreau47ca5452012-12-23 20:22:19 +01002074 smp_trash = get_trash_chunk();
Emeric Brun87855892012-10-17 17:39:35 +02002075 if (args && args[0].type == ARGT_STR) {
2076 int pos = 1;
2077
2078 if (args[1].type == ARGT_SINT)
2079 pos = args[1].data.sint;
2080 else if (args[1].type == ARGT_UINT)
2081 pos =(int)args[1].data.uint;
2082
2083 if (ssl_sock_get_dn_entry(name, &args[0].data.str, pos, smp_trash) <= 0)
2084 goto out;
2085 }
2086 else if (ssl_sock_get_dn_oneline(name, smp_trash) <= 0)
2087 goto out;
2088
2089 smp->type = SMP_T_STR;
2090 smp->data.str = *smp_trash;
2091 ret = 1;
2092out:
2093 if (crt)
2094 X509_free(crt);
2095 return ret;
2096}
Emeric Brun9143d372012-12-20 15:44:16 +01002097
2098/* integer, returns true if current session use a client certificate */
2099static int
2100smp_fetch_ssl_c_used(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
Willy Tarreauef38c392013-07-22 16:29:32 +02002101 const struct arg *args, struct sample *smp, const char *kw)
Emeric Brun9143d372012-12-20 15:44:16 +01002102{
2103 X509 *crt;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002104 struct connection *conn;
Emeric Brun9143d372012-12-20 15:44:16 +01002105
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002106 if (!l4)
Emeric Brun9143d372012-12-20 15:44:16 +01002107 return 0;
2108
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002109 conn = objt_conn(l4->si[0].end);
2110 if (!conn || conn->xprt != &ssl_sock)
2111 return 0;
2112
2113 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brun9143d372012-12-20 15:44:16 +01002114 smp->flags |= SMP_F_MAY_CHANGE;
2115 return 0;
2116 }
2117
2118 /* SSL_get_peer_certificate returns a ptr on allocated X509 struct */
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002119 crt = SSL_get_peer_certificate(conn->xprt_ctx);
Emeric Brun9143d372012-12-20 15:44:16 +01002120 if (crt) {
2121 X509_free(crt);
2122 }
2123
2124 smp->type = SMP_T_BOOL;
2125 smp->data.uint = (crt != NULL);
2126 return 1;
2127}
2128
Emeric Bruna7359fd2012-10-17 15:03:11 +02002129/* integer, returns the client certificate version */
2130static int
2131smp_fetch_ssl_c_version(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
Willy Tarreauef38c392013-07-22 16:29:32 +02002132 const struct arg *args, struct sample *smp, const char *kw)
Emeric Bruna7359fd2012-10-17 15:03:11 +02002133{
2134 X509 *crt;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002135 struct connection *conn;
2136
2137 if (!l4)
2138 return 0;
Emeric Bruna7359fd2012-10-17 15:03:11 +02002139
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002140 conn = objt_conn(l4->si[0].end);
2141 if (!conn || conn->xprt != &ssl_sock)
Emeric Bruna7359fd2012-10-17 15:03:11 +02002142 return 0;
2143
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002144 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Bruna7359fd2012-10-17 15:03:11 +02002145 smp->flags |= SMP_F_MAY_CHANGE;
2146 return 0;
2147 }
2148
2149 /* SSL_get_peer_certificate returns a ptr on allocated X509 struct */
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002150 crt = SSL_get_peer_certificate(conn->xprt_ctx);
Emeric Bruna7359fd2012-10-17 15:03:11 +02002151 if (!crt)
2152 return 0;
2153
2154 smp->data.uint = (unsigned int)(1 + X509_get_version(crt));
2155 X509_free(crt);
2156 smp->type = SMP_T_UINT;
2157
2158 return 1;
2159}
2160
Emeric Brun7f56e742012-10-19 18:15:40 +02002161/* str, returns the client certificate sig alg */
2162static int
2163smp_fetch_ssl_c_sig_alg(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
Willy Tarreauef38c392013-07-22 16:29:32 +02002164 const struct arg *args, struct sample *smp, const char *kw)
Emeric Brun7f56e742012-10-19 18:15:40 +02002165{
2166 X509 *crt;
2167 int nid;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002168 struct connection *conn;
Emeric Brun7f56e742012-10-19 18:15:40 +02002169
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002170 if (!l4)
Emeric Brun7f56e742012-10-19 18:15:40 +02002171 return 0;
2172
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002173 conn = objt_conn(l4->si[0].end);
2174 if (!conn || conn->xprt != &ssl_sock)
2175 return 0;
2176
2177 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brun7f56e742012-10-19 18:15:40 +02002178 smp->flags |= SMP_F_MAY_CHANGE;
2179 return 0;
2180 }
2181
2182 /* SSL_get_peer_certificate increase X509 * ref count */
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002183 crt = SSL_get_peer_certificate(conn->xprt_ctx);
Emeric Brun7f56e742012-10-19 18:15:40 +02002184 if (!crt)
2185 return 0;
2186
2187 nid = OBJ_obj2nid((ASN1_OBJECT *)(crt->cert_info->signature->algorithm));
2188
2189 smp->data.str.str = (char *)OBJ_nid2sn(nid);
Emeric Brun9bf3ba22013-10-07 14:31:44 +02002190 if (!smp->data.str.str) {
2191 X509_free(crt);
Emeric Brun7f56e742012-10-19 18:15:40 +02002192 return 0;
Emeric Brun9bf3ba22013-10-07 14:31:44 +02002193 }
Emeric Brun7f56e742012-10-19 18:15:40 +02002194
2195 smp->type = SMP_T_CSTR;
2196 smp->data.str.len = strlen(smp->data.str.str);
2197 X509_free(crt);
2198
2199 return 1;
2200}
2201
Emeric Brun521a0112012-10-22 12:22:55 +02002202/* str, returns the client certificate key alg */
2203static int
2204smp_fetch_ssl_c_key_alg(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
Willy Tarreauef38c392013-07-22 16:29:32 +02002205 const struct arg *args, struct sample *smp, const char *kw)
Emeric Brun521a0112012-10-22 12:22:55 +02002206{
2207 X509 *crt;
2208 int nid;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002209 struct connection *conn;
Emeric Brun521a0112012-10-22 12:22:55 +02002210
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002211 if (!l4)
Emeric Brun521a0112012-10-22 12:22:55 +02002212 return 0;
2213
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002214 conn = objt_conn(l4->si[0].end);
2215 if (!conn || conn->xprt != &ssl_sock)
2216 return 0;
2217
2218 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brun521a0112012-10-22 12:22:55 +02002219 smp->flags |= SMP_F_MAY_CHANGE;
2220 return 0;
2221 }
2222
2223 /* SSL_get_peer_certificate increase X509 * ref count */
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002224 crt = SSL_get_peer_certificate(conn->xprt_ctx);
Emeric Brun521a0112012-10-22 12:22:55 +02002225 if (!crt)
2226 return 0;
2227
2228 nid = OBJ_obj2nid((ASN1_OBJECT *)(crt->cert_info->key->algor->algorithm));
2229
2230 smp->data.str.str = (char *)OBJ_nid2sn(nid);
Emeric Brun9bf3ba22013-10-07 14:31:44 +02002231 if (!smp->data.str.str) {
2232 X509_free(crt);
Emeric Brun521a0112012-10-22 12:22:55 +02002233 return 0;
Emeric Brun9bf3ba22013-10-07 14:31:44 +02002234 }
Emeric Brun521a0112012-10-22 12:22:55 +02002235
2236 smp->type = SMP_T_CSTR;
2237 smp->data.str.len = strlen(smp->data.str.str);
2238 X509_free(crt);
2239
2240 return 1;
2241}
2242
Emeric Brun2525b6b2012-10-18 15:59:43 +02002243/* boolean, returns true if front conn. transport layer is SSL */
Willy Tarreau7875d092012-09-10 08:20:03 +02002244static int
Emeric Brun2525b6b2012-10-18 15:59:43 +02002245smp_fetch_ssl_fc(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
Willy Tarreauef38c392013-07-22 16:29:32 +02002246 const struct arg *args, struct sample *smp, const char *kw)
Willy Tarreau7875d092012-09-10 08:20:03 +02002247{
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002248 struct connection *conn = objt_conn(l4->si[0].end);
2249
Willy Tarreau7875d092012-09-10 08:20:03 +02002250 smp->type = SMP_T_BOOL;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002251 smp->data.uint = (conn && conn->xprt == &ssl_sock);
Willy Tarreau7875d092012-09-10 08:20:03 +02002252 return 1;
2253}
2254
Emeric Brun2525b6b2012-10-18 15:59:43 +02002255/* boolean, returns true if client present a SNI */
Willy Tarreau7875d092012-09-10 08:20:03 +02002256static int
Emeric Brun2525b6b2012-10-18 15:59:43 +02002257smp_fetch_ssl_fc_has_sni(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
Willy Tarreauef38c392013-07-22 16:29:32 +02002258 const struct arg *args, struct sample *smp, const char *kw)
Willy Tarreau7875d092012-09-10 08:20:03 +02002259{
2260#ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002261 struct connection *conn = objt_conn(l4->si[0].end);
2262
Willy Tarreau7875d092012-09-10 08:20:03 +02002263 smp->type = SMP_T_BOOL;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002264 smp->data.uint = (conn && conn->xprt == &ssl_sock) &&
2265 conn->xprt_ctx &&
2266 SSL_get_servername(conn->xprt_ctx, TLSEXT_NAMETYPE_host_name) != NULL;
Willy Tarreau7875d092012-09-10 08:20:03 +02002267 return 1;
2268#else
2269 return 0;
2270#endif
2271}
2272
Willy Tarreau8d598402012-10-22 17:58:39 +02002273/* bin, returns serial in a binary chunk */
2274static int
2275smp_fetch_ssl_f_serial(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
Willy Tarreauef38c392013-07-22 16:29:32 +02002276 const struct arg *args, struct sample *smp, const char *kw)
Willy Tarreau8d598402012-10-22 17:58:39 +02002277{
2278 X509 *crt = NULL;
2279 int ret = 0;
2280 struct chunk *smp_trash;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002281 struct connection *conn;
2282
2283 if (!l4)
2284 return 0;
Willy Tarreau8d598402012-10-22 17:58:39 +02002285
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002286 conn = objt_conn(l4->si[0].end);
2287 if (!conn || conn->xprt != &ssl_sock)
Willy Tarreau8d598402012-10-22 17:58:39 +02002288 return 0;
2289
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002290 if (!(conn->flags & CO_FL_CONNECTED)) {
Willy Tarreau8d598402012-10-22 17:58:39 +02002291 smp->flags |= SMP_F_MAY_CHANGE;
2292 return 0;
2293 }
2294
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002295 crt = SSL_get_certificate(conn->xprt_ctx);
Willy Tarreau8d598402012-10-22 17:58:39 +02002296 if (!crt)
2297 goto out;
2298
Willy Tarreau47ca5452012-12-23 20:22:19 +01002299 smp_trash = get_trash_chunk();
Willy Tarreau8d598402012-10-22 17:58:39 +02002300 if (ssl_sock_get_serial(crt, smp_trash) <= 0)
2301 goto out;
2302
2303 smp->data.str = *smp_trash;
2304 smp->type = SMP_T_BIN;
2305 ret = 1;
2306out:
2307 return ret;
2308}
Emeric Brunce5ad802012-10-22 14:11:22 +02002309/*str, returns notafter date in ASN1_UTCTIME format */
2310static int
2311smp_fetch_ssl_f_notafter(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
Willy Tarreauef38c392013-07-22 16:29:32 +02002312 const struct arg *args, struct sample *smp, const char *kw)
Emeric Brunce5ad802012-10-22 14:11:22 +02002313{
2314 X509 *crt = NULL;
2315 int ret = 0;
2316 struct chunk *smp_trash;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002317 struct connection *conn;
Emeric Brunce5ad802012-10-22 14:11:22 +02002318
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002319 if (!l4)
Emeric Brunce5ad802012-10-22 14:11:22 +02002320 return 0;
2321
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002322 conn = objt_conn(l4->si[0].end);
2323 if (!conn || conn->xprt != &ssl_sock)
2324 return 0;
2325
2326 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brunce5ad802012-10-22 14:11:22 +02002327 smp->flags |= SMP_F_MAY_CHANGE;
2328 return 0;
2329 }
2330
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002331 crt = SSL_get_certificate(conn->xprt_ctx);
Emeric Brunce5ad802012-10-22 14:11:22 +02002332 if (!crt)
2333 goto out;
2334
Willy Tarreau47ca5452012-12-23 20:22:19 +01002335 smp_trash = get_trash_chunk();
Emeric Brunce5ad802012-10-22 14:11:22 +02002336 if (ssl_sock_get_time(X509_get_notAfter(crt), smp_trash) <= 0)
2337 goto out;
2338
2339 smp->data.str = *smp_trash;
2340 smp->type = SMP_T_STR;
2341 ret = 1;
2342out:
2343 return ret;
2344}
2345
2346/*str, returns notbefore date in ASN1_UTCTIME format */
2347static int
2348smp_fetch_ssl_f_notbefore(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
Willy Tarreauef38c392013-07-22 16:29:32 +02002349 const struct arg *args, struct sample *smp, const char *kw)
Emeric Brunce5ad802012-10-22 14:11:22 +02002350{
2351 X509 *crt = NULL;
2352 int ret = 0;
2353 struct chunk *smp_trash;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002354 struct connection *conn;
Emeric Brunce5ad802012-10-22 14:11:22 +02002355
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002356 if (!l4)
Emeric Brunce5ad802012-10-22 14:11:22 +02002357 return 0;
2358
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002359 conn = objt_conn(l4->si[0].end);
2360 if (!conn || conn->xprt != &ssl_sock)
2361 return 0;
2362
2363 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brunce5ad802012-10-22 14:11:22 +02002364 smp->flags |= SMP_F_MAY_CHANGE;
2365 return 0;
2366 }
2367
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002368 crt = SSL_get_certificate(conn->xprt_ctx);
Emeric Brunce5ad802012-10-22 14:11:22 +02002369 if (!crt)
2370 goto out;
2371
Willy Tarreau47ca5452012-12-23 20:22:19 +01002372 smp_trash = get_trash_chunk();
Emeric Brunce5ad802012-10-22 14:11:22 +02002373 if (ssl_sock_get_time(X509_get_notBefore(crt), smp_trash) <= 0)
2374 goto out;
2375
2376 smp->data.str = *smp_trash;
2377 smp->type = SMP_T_STR;
2378 ret = 1;
2379out:
2380 return ret;
2381}
Willy Tarreau8d598402012-10-22 17:58:39 +02002382
Emeric Bruna7359fd2012-10-17 15:03:11 +02002383/* integer, returns the frontend certificate version */
2384static int
2385smp_fetch_ssl_f_version(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
Willy Tarreauef38c392013-07-22 16:29:32 +02002386 const struct arg *args, struct sample *smp, const char *kw)
Emeric Bruna7359fd2012-10-17 15:03:11 +02002387{
2388 X509 *crt;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002389 struct connection *conn;
Emeric Bruna7359fd2012-10-17 15:03:11 +02002390
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002391 if (!l4)
Emeric Bruna7359fd2012-10-17 15:03:11 +02002392 return 0;
2393
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002394 conn = objt_conn(l4->si[0].end);
2395 if (!conn || conn->xprt != &ssl_sock)
2396 return 0;
2397
2398 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Bruna7359fd2012-10-17 15:03:11 +02002399 smp->flags |= SMP_F_MAY_CHANGE;
2400 return 0;
2401 }
2402
2403 /* SSL_get_certificate returns a ptr on an SSL * internal sub struct */
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002404 crt = SSL_get_certificate(conn->xprt_ctx);
Emeric Bruna7359fd2012-10-17 15:03:11 +02002405 if (!crt)
2406 return 0;
2407
2408 smp->data.uint = (unsigned int)(1 + X509_get_version(crt));
2409 smp->type = SMP_T_UINT;
2410
2411 return 1;
2412}
2413
Emeric Brun7f56e742012-10-19 18:15:40 +02002414/* str, returns the client certificate sig alg */
2415static int
2416smp_fetch_ssl_f_sig_alg(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
Willy Tarreauef38c392013-07-22 16:29:32 +02002417 const struct arg *args, struct sample *smp, const char *kw)
Emeric Brun7f56e742012-10-19 18:15:40 +02002418{
2419 X509 *crt;
2420 int nid;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002421 struct connection *conn;
Emeric Brun7f56e742012-10-19 18:15:40 +02002422
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002423 if (!l4)
Emeric Brun7f56e742012-10-19 18:15:40 +02002424 return 0;
2425
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002426 conn = objt_conn(l4->si[0].end);
2427 if (!conn || conn->xprt != &ssl_sock)
2428 return 0;
2429
2430 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brun7f56e742012-10-19 18:15:40 +02002431 smp->flags |= SMP_F_MAY_CHANGE;
2432 return 0;
2433 }
2434
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002435 crt = SSL_get_certificate(conn->xprt_ctx);
Emeric Brun7f56e742012-10-19 18:15:40 +02002436 if (!crt)
2437 return 0;
2438
2439 nid = OBJ_obj2nid((ASN1_OBJECT *)(crt->cert_info->signature->algorithm));
2440
2441 smp->data.str.str = (char *)OBJ_nid2sn(nid);
2442 if (!smp->data.str.str)
2443 return 0;
2444
2445 smp->type = SMP_T_CSTR;
2446 smp->data.str.len = strlen(smp->data.str.str);
2447
2448 return 1;
2449}
2450
Emeric Brun521a0112012-10-22 12:22:55 +02002451/* str, returns the client certificate key alg */
2452static int
2453smp_fetch_ssl_f_key_alg(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
Willy Tarreauef38c392013-07-22 16:29:32 +02002454 const struct arg *args, struct sample *smp, const char *kw)
Emeric Brun521a0112012-10-22 12:22:55 +02002455{
2456 X509 *crt;
2457 int nid;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002458 struct connection *conn;
2459
2460 if (!l4)
2461 return 0;
Emeric Brun521a0112012-10-22 12:22:55 +02002462
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002463 conn = objt_conn(l4->si[0].end);
2464 if (!conn || conn->xprt != &ssl_sock)
Emeric Brun521a0112012-10-22 12:22:55 +02002465 return 0;
2466
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002467 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brun521a0112012-10-22 12:22:55 +02002468 smp->flags |= SMP_F_MAY_CHANGE;
2469 return 0;
2470 }
2471
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002472 crt = SSL_get_certificate(conn->xprt_ctx);
Emeric Brun521a0112012-10-22 12:22:55 +02002473 if (!crt)
2474 return 0;
2475
2476 nid = OBJ_obj2nid((ASN1_OBJECT *)(crt->cert_info->key->algor->algorithm));
2477
2478 smp->data.str.str = (char *)OBJ_nid2sn(nid);
2479 if (!smp->data.str.str)
2480 return 0;
2481
2482 smp->type = SMP_T_CSTR;
2483 smp->data.str.len = strlen(smp->data.str.str);
2484
2485 return 1;
2486}
2487
Emeric Brun87855892012-10-17 17:39:35 +02002488/* str, returns a string of a formatted full dn \C=..\O=..\OU=.. \CN=.. */
2489static int
2490smp_fetch_ssl_f_i_dn(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
Willy Tarreauef38c392013-07-22 16:29:32 +02002491 const struct arg *args, struct sample *smp, const char *kw)
Emeric Brun87855892012-10-17 17:39:35 +02002492{
2493 X509 *crt = NULL;
2494 X509_NAME *name;
2495 int ret = 0;
2496 struct chunk *smp_trash;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002497 struct connection *conn;
2498
2499 if (!l4)
2500 return 0;
Emeric Brun87855892012-10-17 17:39:35 +02002501
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002502 conn = objt_conn(l4->si[0].end);
2503 if (!conn || conn->xprt != &ssl_sock)
Emeric Brun87855892012-10-17 17:39:35 +02002504 return 0;
2505
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002506 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brun87855892012-10-17 17:39:35 +02002507 smp->flags |= SMP_F_MAY_CHANGE;
2508 return 0;
2509 }
2510
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002511 crt = SSL_get_certificate(conn->xprt_ctx);
Emeric Brun87855892012-10-17 17:39:35 +02002512 if (!crt)
2513 goto out;
2514
2515 name = X509_get_issuer_name(crt);
2516 if (!name)
2517 goto out;
2518
Willy Tarreau47ca5452012-12-23 20:22:19 +01002519 smp_trash = get_trash_chunk();
Emeric Brun87855892012-10-17 17:39:35 +02002520 if (args && args[0].type == ARGT_STR) {
2521 int pos = 1;
2522
2523 if (args[1].type == ARGT_SINT)
2524 pos = args[1].data.sint;
2525 else if (args[1].type == ARGT_UINT)
2526 pos =(int)args[1].data.uint;
2527
2528 if (ssl_sock_get_dn_entry(name, &args[0].data.str, pos, smp_trash) <= 0)
2529 goto out;
2530 }
2531 else if (ssl_sock_get_dn_oneline(name, smp_trash) <= 0)
2532 goto out;
2533
2534 smp->type = SMP_T_STR;
2535 smp->data.str = *smp_trash;
2536 ret = 1;
2537out:
2538 return ret;
2539}
2540
2541/* str, returns a string of a formatted full dn \C=..\O=..\OU=.. \CN=.. */
2542static int
2543smp_fetch_ssl_f_s_dn(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
Willy Tarreauef38c392013-07-22 16:29:32 +02002544 const struct arg *args, struct sample *smp, const char *kw)
Emeric Brun87855892012-10-17 17:39:35 +02002545{
2546 X509 *crt = NULL;
2547 X509_NAME *name;
2548 int ret = 0;
2549 struct chunk *smp_trash;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002550 struct connection *conn;
2551
2552 if (!l4)
2553 return 0;
Emeric Brun87855892012-10-17 17:39:35 +02002554
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002555 conn = objt_conn(l4->si[0].end);
2556 if (!conn || !conn->xprt_ctx || conn->xprt != &ssl_sock)
Emeric Brun87855892012-10-17 17:39:35 +02002557 return 0;
2558
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002559 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brun87855892012-10-17 17:39:35 +02002560 smp->flags |= SMP_F_MAY_CHANGE;
2561 return 0;
2562 }
2563
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002564 crt = SSL_get_certificate(conn->xprt_ctx);
Emeric Brun87855892012-10-17 17:39:35 +02002565 if (!crt)
2566 goto out;
2567
2568 name = X509_get_subject_name(crt);
2569 if (!name)
2570 goto out;
2571
Willy Tarreau47ca5452012-12-23 20:22:19 +01002572 smp_trash = get_trash_chunk();
Emeric Brun87855892012-10-17 17:39:35 +02002573 if (args && args[0].type == ARGT_STR) {
2574 int pos = 1;
2575
2576 if (args[1].type == ARGT_SINT)
2577 pos = args[1].data.sint;
2578 else if (args[1].type == ARGT_UINT)
2579 pos =(int)args[1].data.uint;
2580
2581 if (ssl_sock_get_dn_entry(name, &args[0].data.str, pos, smp_trash) <= 0)
2582 goto out;
2583 }
2584 else if (ssl_sock_get_dn_oneline(name, smp_trash) <= 0)
2585 goto out;
2586
2587 smp->type = SMP_T_STR;
2588 smp->data.str = *smp_trash;
2589 ret = 1;
2590out:
2591 return ret;
2592}
2593
Emeric Brun589fcad2012-10-16 14:13:26 +02002594static int
2595smp_fetch_ssl_fc_cipher(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
Willy Tarreauef38c392013-07-22 16:29:32 +02002596 const struct arg *args, struct sample *smp, const char *kw)
Emeric Brun589fcad2012-10-16 14:13:26 +02002597{
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002598 struct connection *conn;
2599
Emeric Brun589fcad2012-10-16 14:13:26 +02002600 smp->flags = 0;
2601
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002602 if (!l4)
2603 return 0;
2604
2605 conn = objt_conn(l4->si[0].end);
2606 if (!conn || !conn->xprt_ctx || conn->xprt != &ssl_sock)
Emeric Brun589fcad2012-10-16 14:13:26 +02002607 return 0;
2608
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002609 smp->data.str.str = (char *)SSL_get_cipher_name(conn->xprt_ctx);
Emeric Brun589fcad2012-10-16 14:13:26 +02002610 if (!smp->data.str.str)
2611 return 0;
2612
2613 smp->type = SMP_T_CSTR;
2614 smp->data.str.len = strlen(smp->data.str.str);
2615
2616 return 1;
2617}
2618
2619static int
2620smp_fetch_ssl_fc_alg_keysize(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
Willy Tarreauef38c392013-07-22 16:29:32 +02002621 const struct arg *args, struct sample *smp, const char *kw)
Emeric Brun589fcad2012-10-16 14:13:26 +02002622{
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002623 struct connection *conn;
2624
Emeric Brun589fcad2012-10-16 14:13:26 +02002625 smp->flags = 0;
2626
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002627 if (!l4)
Emeric Brun589fcad2012-10-16 14:13:26 +02002628 return 0;
2629
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002630 conn = objt_conn(l4->si[0].end);
2631 if (!conn || !conn->xprt_ctx || conn->xprt != &ssl_sock)
Emeric Brun589fcad2012-10-16 14:13:26 +02002632 return 0;
2633
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002634 if (!SSL_get_cipher_bits(conn->xprt_ctx, (int *)&smp->data.uint))
2635 return 0;
2636
Emeric Brun589fcad2012-10-16 14:13:26 +02002637 smp->type = SMP_T_UINT;
2638
2639 return 1;
2640}
2641
2642static int
2643smp_fetch_ssl_fc_use_keysize(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
Willy Tarreauef38c392013-07-22 16:29:32 +02002644 const struct arg *args, struct sample *smp, const char *kw)
Emeric Brun589fcad2012-10-16 14:13:26 +02002645{
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002646 struct connection *conn;
2647
Emeric Brun589fcad2012-10-16 14:13:26 +02002648 smp->flags = 0;
2649
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002650 if (!l4)
Emeric Brun589fcad2012-10-16 14:13:26 +02002651 return 0;
2652
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002653 conn = objt_conn(l4->si[0].end);
2654 if (!conn || !conn->xprt_ctx || conn->xprt != &ssl_sock)
2655 return 0;
2656
2657 smp->data.uint = (unsigned int)SSL_get_cipher_bits(conn->xprt_ctx, NULL);
Emeric Brun589fcad2012-10-16 14:13:26 +02002658 if (!smp->data.uint)
2659 return 0;
2660
2661 smp->type = SMP_T_UINT;
2662
2663 return 1;
2664}
2665
Willy Tarreau6c9a3d52012-10-18 18:57:14 +02002666#ifdef OPENSSL_NPN_NEGOTIATED
Willy Tarreau7875d092012-09-10 08:20:03 +02002667static int
Emeric Brun2525b6b2012-10-18 15:59:43 +02002668smp_fetch_ssl_fc_npn(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
Willy Tarreauef38c392013-07-22 16:29:32 +02002669 const struct arg *args, struct sample *smp, const char *kw)
Willy Tarreaua33c6542012-10-15 13:19:06 +02002670{
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002671 struct connection *conn;
2672
Willy Tarreaua33c6542012-10-15 13:19:06 +02002673 smp->flags = 0;
2674 smp->type = SMP_T_CSTR;
2675
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002676 if (!l4)
Willy Tarreaua33c6542012-10-15 13:19:06 +02002677 return 0;
2678
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002679 conn = objt_conn(l4->si[0].end);
2680 if (!conn || !conn->xprt_ctx || conn->xprt != &ssl_sock)
2681 return 0;
2682
Willy Tarreaua33c6542012-10-15 13:19:06 +02002683 smp->data.str.str = NULL;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002684 SSL_get0_next_proto_negotiated(conn->xprt_ctx,
Willy Tarreaua33c6542012-10-15 13:19:06 +02002685 (const unsigned char **)&smp->data.str.str, (unsigned *)&smp->data.str.len);
2686
2687 if (!smp->data.str.str)
2688 return 0;
2689
2690 return 1;
Willy Tarreaua33c6542012-10-15 13:19:06 +02002691}
Willy Tarreau6c9a3d52012-10-18 18:57:14 +02002692#endif
Willy Tarreaua33c6542012-10-15 13:19:06 +02002693
Dirkjan Bussink48f1c4e2014-02-13 12:29:42 +01002694#ifdef TLSEXT_TYPE_application_layer_protocol_negotiation
Willy Tarreauab861d32013-04-02 02:30:41 +02002695static int
2696smp_fetch_ssl_fc_alpn(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
Willy Tarreauef38c392013-07-22 16:29:32 +02002697 const struct arg *args, struct sample *smp, const char *kw)
Willy Tarreauab861d32013-04-02 02:30:41 +02002698{
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002699 struct connection *conn;
2700
Willy Tarreauab861d32013-04-02 02:30:41 +02002701 smp->flags = 0;
2702 smp->type = SMP_T_CSTR;
2703
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002704 if (!l4)
2705 return 0;
2706
2707 conn = objt_conn(l4->si[0].end);
2708 if (!conn || !conn->xprt_ctx || conn->xprt != &ssl_sock)
Willy Tarreauab861d32013-04-02 02:30:41 +02002709 return 0;
2710
2711 smp->data.str.str = NULL;
Dirkjan Bussink48f1c4e2014-02-13 12:29:42 +01002712 SSL_get0_alpn_selected(conn->xprt_ctx,
Willy Tarreauab861d32013-04-02 02:30:41 +02002713 (const unsigned char **)&smp->data.str.str, (unsigned *)&smp->data.str.len);
2714
2715 if (!smp->data.str.str)
2716 return 0;
2717
2718 return 1;
2719}
2720#endif
2721
Willy Tarreaua33c6542012-10-15 13:19:06 +02002722static int
Emeric Brun589fcad2012-10-16 14:13:26 +02002723smp_fetch_ssl_fc_protocol(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
Willy Tarreauef38c392013-07-22 16:29:32 +02002724 const struct arg *args, struct sample *smp, const char *kw)
Emeric Brun589fcad2012-10-16 14:13:26 +02002725{
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002726 struct connection *conn;
2727
Emeric Brun589fcad2012-10-16 14:13:26 +02002728 smp->flags = 0;
2729
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002730 if (!l4)
Emeric Brun589fcad2012-10-16 14:13:26 +02002731 return 0;
2732
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002733 conn = objt_conn(l4->si[0].end);
2734 if (!conn || !conn->xprt_ctx || conn->xprt != &ssl_sock)
2735 return 0;
2736
2737 smp->data.str.str = (char *)SSL_get_version(conn->xprt_ctx);
Emeric Brun589fcad2012-10-16 14:13:26 +02002738 if (!smp->data.str.str)
2739 return 0;
2740
2741 smp->type = SMP_T_CSTR;
2742 smp->data.str.len = strlen(smp->data.str.str);
2743
2744 return 1;
2745}
2746
2747static int
Emeric Brunfe68f682012-10-16 14:59:28 +02002748smp_fetch_ssl_fc_session_id(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
Willy Tarreauef38c392013-07-22 16:29:32 +02002749 const struct arg *args, struct sample *smp, const char *kw)
Emeric Brunfe68f682012-10-16 14:59:28 +02002750{
2751#if OPENSSL_VERSION_NUMBER > 0x0090800fL
2752 SSL_SESSION *sess;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002753 struct connection *conn;
Emeric Brunfe68f682012-10-16 14:59:28 +02002754
2755 smp->flags = 0;
2756 smp->type = SMP_T_CBIN;
2757
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002758 if (!l4)
Emeric Brunfe68f682012-10-16 14:59:28 +02002759 return 0;
2760
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002761 conn = objt_conn(l4->si[0].end);
2762 if (!conn || !conn->xprt_ctx || conn->xprt != &ssl_sock)
2763 return 0;
2764
2765 sess = SSL_get_session(conn->xprt_ctx);
Emeric Brunfe68f682012-10-16 14:59:28 +02002766 if (!sess)
2767 return 0;
2768
2769 smp->data.str.str = (char *)SSL_SESSION_get_id(sess, (unsigned int *)&smp->data.str.len);
2770 if (!smp->data.str.str || !&smp->data.str.len)
2771 return 0;
2772
2773 return 1;
2774#else
2775 return 0;
2776#endif
2777}
2778
2779static int
Emeric Brun2525b6b2012-10-18 15:59:43 +02002780smp_fetch_ssl_fc_sni(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
Willy Tarreauef38c392013-07-22 16:29:32 +02002781 const struct arg *args, struct sample *smp, const char *kw)
Willy Tarreau7875d092012-09-10 08:20:03 +02002782{
2783#ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002784 struct connection *conn;
2785
Willy Tarreau7875d092012-09-10 08:20:03 +02002786 smp->flags = 0;
2787 smp->type = SMP_T_CSTR;
2788
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002789 if (!l4)
Willy Tarreau7875d092012-09-10 08:20:03 +02002790 return 0;
2791
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002792 conn = objt_conn(l4->si[0].end);
2793 if (!conn || !conn->xprt_ctx || conn->xprt != &ssl_sock)
2794 return 0;
2795
2796 smp->data.str.str = (char *)SSL_get_servername(conn->xprt_ctx, TLSEXT_NAMETYPE_host_name);
Willy Tarreau3e394c92012-09-14 23:56:58 +02002797 if (!smp->data.str.str)
2798 return 0;
2799
Willy Tarreau7875d092012-09-10 08:20:03 +02002800 smp->data.str.len = strlen(smp->data.str.str);
2801 return 1;
2802#else
2803 return 0;
2804#endif
2805}
2806
Emeric Brun2525b6b2012-10-18 15:59:43 +02002807/* integer, returns the first verify error in CA chain of client certificate chain. */
Emeric Brunf282a812012-09-21 15:27:54 +02002808static int
Emeric Brun2525b6b2012-10-18 15:59:43 +02002809smp_fetch_ssl_c_ca_err(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
Willy Tarreauef38c392013-07-22 16:29:32 +02002810 const struct arg *args, struct sample *smp, const char *kw)
Emeric Brunf282a812012-09-21 15:27:54 +02002811{
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002812 struct connection *conn;
2813
2814 if (!l4)
Emeric Brunf282a812012-09-21 15:27:54 +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 Brunf282a812012-09-21 15:27:54 +02002822 smp->flags = SMP_F_MAY_CHANGE;
2823 return 0;
2824 }
2825
2826 smp->type = SMP_T_UINT;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002827 smp->data.uint = (unsigned int)SSL_SOCK_ST_TO_CA_ERROR(conn->xprt_st);
Emeric Brunf282a812012-09-21 15:27:54 +02002828 smp->flags = 0;
2829
2830 return 1;
2831}
2832
Emeric Brun2525b6b2012-10-18 15:59:43 +02002833/* integer, returns the depth of the first verify error in CA chain of client certificate chain. */
Emeric Brunf282a812012-09-21 15:27:54 +02002834static int
Emeric Brun2525b6b2012-10-18 15:59:43 +02002835smp_fetch_ssl_c_ca_err_depth(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
Willy Tarreauef38c392013-07-22 16:29:32 +02002836 const struct arg *args, struct sample *smp, const char *kw)
Emeric Brunf282a812012-09-21 15:27:54 +02002837{
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002838 struct connection *conn;
2839
2840 if (!l4)
2841 return 0;
2842
2843 conn = objt_conn(l4->si[0].end);
2844 if (!conn || conn->xprt != &ssl_sock)
Emeric Brunf282a812012-09-21 15:27:54 +02002845 return 0;
2846
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002847 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brunf282a812012-09-21 15:27:54 +02002848 smp->flags = SMP_F_MAY_CHANGE;
2849 return 0;
2850 }
2851
2852 smp->type = SMP_T_UINT;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002853 smp->data.uint = (unsigned int)SSL_SOCK_ST_TO_CAEDEPTH(conn->xprt_st);
Emeric Brunf282a812012-09-21 15:27:54 +02002854 smp->flags = 0;
2855
2856 return 1;
2857}
2858
Emeric Brun2525b6b2012-10-18 15:59:43 +02002859/* integer, returns the first verify error on client certificate */
Emeric Brunf282a812012-09-21 15:27:54 +02002860static int
Emeric Brun2525b6b2012-10-18 15:59:43 +02002861smp_fetch_ssl_c_err(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
Willy Tarreauef38c392013-07-22 16:29:32 +02002862 const struct arg *args, struct sample *smp, const char *kw)
Emeric Brunf282a812012-09-21 15:27:54 +02002863{
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002864 struct connection *conn;
2865
2866 if (!l4)
Emeric Brunf282a812012-09-21 15:27:54 +02002867 return 0;
2868
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002869 conn = objt_conn(l4->si[0].end);
2870 if (!conn || conn->xprt != &ssl_sock)
2871 return 0;
2872
2873 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brunf282a812012-09-21 15:27:54 +02002874 smp->flags = SMP_F_MAY_CHANGE;
2875 return 0;
2876 }
2877
2878 smp->type = SMP_T_UINT;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002879 smp->data.uint = (unsigned int)SSL_SOCK_ST_TO_CRTERROR(conn->xprt_st);
Emeric Brunf282a812012-09-21 15:27:54 +02002880 smp->flags = 0;
2881
2882 return 1;
2883}
2884
Emeric Brun2525b6b2012-10-18 15:59:43 +02002885/* integer, returns the verify result on client cert */
Emeric Brunbaf8ffb2012-09-21 15:27:20 +02002886static int
Emeric Brun2525b6b2012-10-18 15:59:43 +02002887smp_fetch_ssl_c_verify(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
Willy Tarreauef38c392013-07-22 16:29:32 +02002888 const struct arg *args, struct sample *smp, const char *kw)
Emeric Brunbaf8ffb2012-09-21 15:27:20 +02002889{
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002890 struct connection *conn;
2891
2892 if (!l4)
Emeric Brunbaf8ffb2012-09-21 15:27:20 +02002893 return 0;
2894
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002895 conn = objt_conn(l4->si[0].end);
2896 if (!conn || conn->xprt != &ssl_sock)
2897 return 0;
2898
2899 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brunbaf8ffb2012-09-21 15:27:20 +02002900 smp->flags = SMP_F_MAY_CHANGE;
2901 return 0;
2902 }
2903
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002904 if (!conn->xprt_ctx)
Emeric Brunbaf8ffb2012-09-21 15:27:20 +02002905 return 0;
2906
2907 smp->type = SMP_T_UINT;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002908 smp->data.uint = (unsigned int)SSL_get_verify_result(conn->xprt_ctx);
Emeric Brunbaf8ffb2012-09-21 15:27:20 +02002909 smp->flags = 0;
2910
2911 return 1;
2912}
2913
Emeric Brunfb510ea2012-10-05 12:00:26 +02002914/* parse the "ca-file" bind keyword */
2915static 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 +02002916{
2917 if (!*args[cur_arg + 1]) {
2918 if (err)
2919 memprintf(err, "'%s' : missing CAfile path", args[cur_arg]);
2920 return ERR_ALERT | ERR_FATAL;
2921 }
2922
Emeric Brunef42d922012-10-11 16:11:36 +02002923 if ((*args[cur_arg + 1] != '/') && global.ca_base)
2924 memprintf(&conf->ca_file, "%s/%s", global.ca_base, args[cur_arg + 1]);
2925 else
2926 memprintf(&conf->ca_file, "%s", args[cur_arg + 1]);
Emeric Brunc8e8d122012-10-02 18:42:10 +02002927
Emeric Brund94b3fe2012-09-20 18:23:56 +02002928 return 0;
2929}
2930
Willy Tarreau79eeafa2012-09-14 07:53:05 +02002931/* parse the "ciphers" bind keyword */
Willy Tarreau4348fad2012-09-20 16:48:07 +02002932static 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 +02002933{
2934 if (!*args[cur_arg + 1]) {
Willy Tarreaueb6cead2012-09-20 19:43:14 +02002935 memprintf(err, "'%s' : missing cipher suite", args[cur_arg]);
Willy Tarreau79eeafa2012-09-14 07:53:05 +02002936 return ERR_ALERT | ERR_FATAL;
2937 }
2938
Emeric Brun76d88952012-10-05 15:47:31 +02002939 free(conf->ciphers);
Willy Tarreau4348fad2012-09-20 16:48:07 +02002940 conf->ciphers = strdup(args[cur_arg + 1]);
Willy Tarreau79eeafa2012-09-14 07:53:05 +02002941 return 0;
2942}
2943
2944/* parse the "crt" bind keyword */
Willy Tarreau4348fad2012-09-20 16:48:07 +02002945static 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 +02002946{
Willy Tarreau38011032013-08-13 16:59:39 +02002947 char path[MAXPATHLEN];
Willy Tarreau79eeafa2012-09-14 07:53:05 +02002948 if (!*args[cur_arg + 1]) {
Willy Tarreaueb6cead2012-09-20 19:43:14 +02002949 memprintf(err, "'%s' : missing certificate location", args[cur_arg]);
Willy Tarreau79eeafa2012-09-14 07:53:05 +02002950 return ERR_ALERT | ERR_FATAL;
2951 }
2952
Emeric Brunc8e8d122012-10-02 18:42:10 +02002953 if ((*args[cur_arg + 1] != '/' ) && global.crt_base) {
Willy Tarreau38011032013-08-13 16:59:39 +02002954 if ((strlen(global.crt_base) + 1 + strlen(args[cur_arg + 1]) + 1) > MAXPATHLEN) {
Emeric Brunc8e8d122012-10-02 18:42:10 +02002955 memprintf(err, "'%s' : path too long", args[cur_arg]);
2956 return ERR_ALERT | ERR_FATAL;
2957 }
2958 sprintf(path, "%s/%s", global.crt_base, args[cur_arg + 1]);
2959 if (ssl_sock_load_cert(path, conf, px, err) > 0)
2960 return ERR_ALERT | ERR_FATAL;
2961
2962 return 0;
2963 }
2964
Willy Tarreau4348fad2012-09-20 16:48:07 +02002965 if (ssl_sock_load_cert(args[cur_arg + 1], conf, px, err) > 0)
Willy Tarreau79eeafa2012-09-14 07:53:05 +02002966 return ERR_ALERT | ERR_FATAL;
Emeric Brund94b3fe2012-09-20 18:23:56 +02002967
2968 return 0;
2969}
2970
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01002971/* parse the "crt-list" bind keyword */
2972static int bind_parse_crt_list(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
2973{
2974 if (!*args[cur_arg + 1]) {
2975 memprintf(err, "'%s' : missing certificate location", args[cur_arg]);
2976 return ERR_ALERT | ERR_FATAL;
2977 }
2978
Willy Tarreauad1731d2013-04-02 17:35:58 +02002979 if (ssl_sock_load_cert_list_file(args[cur_arg + 1], conf, px, err) > 0) {
2980 memprintf(err, "'%s' : %s", args[cur_arg], *err);
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01002981 return ERR_ALERT | ERR_FATAL;
Willy Tarreauad1731d2013-04-02 17:35:58 +02002982 }
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01002983
2984 return 0;
2985}
2986
Emeric Brunfb510ea2012-10-05 12:00:26 +02002987/* parse the "crl-file" bind keyword */
2988static 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 +02002989{
Emeric Brun051cdab2012-10-02 19:25:50 +02002990#ifndef X509_V_FLAG_CRL_CHECK
2991 if (err)
2992 memprintf(err, "'%s' : library does not support CRL verify", args[cur_arg]);
2993 return ERR_ALERT | ERR_FATAL;
2994#else
Emeric Brund94b3fe2012-09-20 18:23:56 +02002995 if (!*args[cur_arg + 1]) {
2996 if (err)
2997 memprintf(err, "'%s' : missing CRLfile path", args[cur_arg]);
2998 return ERR_ALERT | ERR_FATAL;
2999 }
Emeric Brun2b58d042012-09-20 17:10:03 +02003000
Emeric Brunef42d922012-10-11 16:11:36 +02003001 if ((*args[cur_arg + 1] != '/') && global.ca_base)
3002 memprintf(&conf->crl_file, "%s/%s", global.ca_base, args[cur_arg + 1]);
3003 else
3004 memprintf(&conf->crl_file, "%s", args[cur_arg + 1]);
Emeric Brunc8e8d122012-10-02 18:42:10 +02003005
Emeric Brun2b58d042012-09-20 17:10:03 +02003006 return 0;
Emeric Brun051cdab2012-10-02 19:25:50 +02003007#endif
Emeric Brun2b58d042012-09-20 17:10:03 +02003008}
3009
3010/* parse the "ecdhe" bind keyword keywords */
3011static int bind_parse_ecdhe(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
3012{
3013#if OPENSSL_VERSION_NUMBER < 0x0090800fL
3014 if (err)
3015 memprintf(err, "'%s' : library does not support elliptic curve Diffie-Hellman (too old)", args[cur_arg]);
3016 return ERR_ALERT | ERR_FATAL;
3017#elif defined(OPENSSL_NO_ECDH)
3018 if (err)
3019 memprintf(err, "'%s' : library does not support elliptic curve Diffie-Hellman (disabled via OPENSSL_NO_ECDH)", args[cur_arg]);
3020 return ERR_ALERT | ERR_FATAL;
3021#else
3022 if (!*args[cur_arg + 1]) {
3023 if (err)
3024 memprintf(err, "'%s' : missing named curve", args[cur_arg]);
3025 return ERR_ALERT | ERR_FATAL;
3026 }
3027
3028 conf->ecdhe = strdup(args[cur_arg + 1]);
Willy Tarreau79eeafa2012-09-14 07:53:05 +02003029
3030 return 0;
Emeric Brun2b58d042012-09-20 17:10:03 +02003031#endif
Willy Tarreau79eeafa2012-09-14 07:53:05 +02003032}
3033
Emeric Brun81c00f02012-09-21 14:31:21 +02003034/* parse the "crt_ignerr" and "ca_ignerr" bind keywords */
3035static int bind_parse_ignore_err(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
3036{
3037 int code;
3038 char *p = args[cur_arg + 1];
3039 unsigned long long *ignerr = &conf->crt_ignerr;
3040
3041 if (!*p) {
3042 if (err)
3043 memprintf(err, "'%s' : missing error IDs list", args[cur_arg]);
3044 return ERR_ALERT | ERR_FATAL;
3045 }
3046
3047 if (strcmp(args[cur_arg], "ca-ignore-err") == 0)
3048 ignerr = &conf->ca_ignerr;
3049
3050 if (strcmp(p, "all") == 0) {
3051 *ignerr = ~0ULL;
3052 return 0;
3053 }
3054
3055 while (p) {
3056 code = atoi(p);
3057 if ((code <= 0) || (code > 63)) {
3058 if (err)
3059 memprintf(err, "'%s' : ID '%d' out of range (1..63) in error IDs list '%s'",
3060 args[cur_arg], code, args[cur_arg + 1]);
3061 return ERR_ALERT | ERR_FATAL;
3062 }
3063 *ignerr |= 1ULL << code;
3064 p = strchr(p, ',');
3065 if (p)
3066 p++;
3067 }
3068
Emeric Brun2cb7ae52012-10-05 14:14:21 +02003069 return 0;
3070}
3071
3072/* parse the "force-sslv3" bind keyword */
3073static int bind_parse_force_sslv3(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
3074{
3075 conf->ssl_options |= BC_SSL_O_USE_SSLV3;
3076 return 0;
3077}
3078
3079/* parse the "force-tlsv10" bind keyword */
3080static int bind_parse_force_tlsv10(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
3081{
3082 conf->ssl_options |= BC_SSL_O_USE_TLSV10;
Emeric Brun2d0c4822012-10-02 13:45:20 +02003083 return 0;
3084}
3085
Emeric Brun2cb7ae52012-10-05 14:14:21 +02003086/* parse the "force-tlsv11" bind keyword */
3087static int bind_parse_force_tlsv11(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
3088{
3089#if SSL_OP_NO_TLSv1_1
3090 conf->ssl_options |= BC_SSL_O_USE_TLSV11;
3091 return 0;
3092#else
3093 if (err)
3094 memprintf(err, "'%s' : library does not support protocol TLSv1.1", args[cur_arg]);
3095 return ERR_ALERT | ERR_FATAL;
3096#endif
3097}
3098
3099/* parse the "force-tlsv12" bind keyword */
3100static int bind_parse_force_tlsv12(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
3101{
3102#if SSL_OP_NO_TLSv1_2
3103 conf->ssl_options |= BC_SSL_O_USE_TLSV12;
3104 return 0;
3105#else
3106 if (err)
3107 memprintf(err, "'%s' : library does not support protocol TLSv1.2", args[cur_arg]);
3108 return ERR_ALERT | ERR_FATAL;
3109#endif
3110}
3111
3112
Emeric Brun2d0c4822012-10-02 13:45:20 +02003113/* parse the "no-tls-tickets" bind keyword */
3114static int bind_parse_no_tls_tickets(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
3115{
Emeric Brun89675492012-10-05 13:48:26 +02003116 conf->ssl_options |= BC_SSL_O_NO_TLS_TICKETS;
Emeric Brun81c00f02012-09-21 14:31:21 +02003117 return 0;
3118}
3119
Emeric Brun2d0c4822012-10-02 13:45:20 +02003120
Emeric Brun9b3009b2012-10-05 11:55:06 +02003121/* parse the "no-sslv3" bind keyword */
3122static 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 +02003123{
Emeric Brun89675492012-10-05 13:48:26 +02003124 conf->ssl_options |= BC_SSL_O_NO_SSLV3;
Willy Tarreau79eeafa2012-09-14 07:53:05 +02003125 return 0;
3126}
3127
Emeric Brun9b3009b2012-10-05 11:55:06 +02003128/* parse the "no-tlsv10" bind keyword */
3129static 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 +02003130{
Emeric Brun89675492012-10-05 13:48:26 +02003131 conf->ssl_options |= BC_SSL_O_NO_TLSV10;
Emeric Brunc0ff4922012-09-28 19:37:02 +02003132 return 0;
3133}
3134
Emeric Brun9b3009b2012-10-05 11:55:06 +02003135/* parse the "no-tlsv11" bind keyword */
3136static 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 +02003137{
Emeric Brun89675492012-10-05 13:48:26 +02003138 conf->ssl_options |= BC_SSL_O_NO_TLSV11;
Emeric Brunc0ff4922012-09-28 19:37:02 +02003139 return 0;
3140}
3141
Emeric Brun9b3009b2012-10-05 11:55:06 +02003142/* parse the "no-tlsv12" bind keyword */
3143static 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 +02003144{
Emeric Brun89675492012-10-05 13:48:26 +02003145 conf->ssl_options |= BC_SSL_O_NO_TLSV12;
Willy Tarreau79eeafa2012-09-14 07:53:05 +02003146 return 0;
3147}
3148
Willy Tarreau6c9a3d52012-10-18 18:57:14 +02003149/* parse the "npn" bind keyword */
3150static int bind_parse_npn(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
3151{
3152#ifdef OPENSSL_NPN_NEGOTIATED
3153 char *p1, *p2;
3154
3155 if (!*args[cur_arg + 1]) {
3156 memprintf(err, "'%s' : missing the comma-delimited NPN protocol suite", args[cur_arg]);
3157 return ERR_ALERT | ERR_FATAL;
3158 }
3159
3160 free(conf->npn_str);
3161
3162 /* the NPN string is built as a suite of (<len> <name>)* */
3163 conf->npn_len = strlen(args[cur_arg + 1]) + 1;
3164 conf->npn_str = calloc(1, conf->npn_len);
3165 memcpy(conf->npn_str + 1, args[cur_arg + 1], conf->npn_len);
3166
3167 /* replace commas with the name length */
3168 p1 = conf->npn_str;
3169 p2 = p1 + 1;
3170 while (1) {
3171 p2 = memchr(p1 + 1, ',', conf->npn_str + conf->npn_len - (p1 + 1));
3172 if (!p2)
3173 p2 = p1 + 1 + strlen(p1 + 1);
3174
3175 if (p2 - (p1 + 1) > 255) {
3176 *p2 = '\0';
3177 memprintf(err, "'%s' : NPN protocol name too long : '%s'", args[cur_arg], p1 + 1);
3178 return ERR_ALERT | ERR_FATAL;
3179 }
3180
3181 *p1 = p2 - (p1 + 1);
3182 p1 = p2;
3183
3184 if (!*p2)
3185 break;
3186
3187 *(p2++) = '\0';
3188 }
3189 return 0;
3190#else
3191 if (err)
3192 memprintf(err, "'%s' : library does not support TLS NPN extension", args[cur_arg]);
3193 return ERR_ALERT | ERR_FATAL;
3194#endif
3195}
3196
Willy Tarreauab861d32013-04-02 02:30:41 +02003197/* parse the "alpn" bind keyword */
3198static int bind_parse_alpn(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
3199{
Dirkjan Bussink48f1c4e2014-02-13 12:29:42 +01003200#ifdef TLSEXT_TYPE_application_layer_protocol_negotiation
Willy Tarreauab861d32013-04-02 02:30:41 +02003201 char *p1, *p2;
3202
3203 if (!*args[cur_arg + 1]) {
3204 memprintf(err, "'%s' : missing the comma-delimited ALPN protocol suite", args[cur_arg]);
3205 return ERR_ALERT | ERR_FATAL;
3206 }
3207
3208 free(conf->alpn_str);
3209
3210 /* the ALPN string is built as a suite of (<len> <name>)* */
3211 conf->alpn_len = strlen(args[cur_arg + 1]) + 1;
3212 conf->alpn_str = calloc(1, conf->alpn_len);
3213 memcpy(conf->alpn_str + 1, args[cur_arg + 1], conf->alpn_len);
3214
3215 /* replace commas with the name length */
3216 p1 = conf->alpn_str;
3217 p2 = p1 + 1;
3218 while (1) {
3219 p2 = memchr(p1 + 1, ',', conf->alpn_str + conf->alpn_len - (p1 + 1));
3220 if (!p2)
3221 p2 = p1 + 1 + strlen(p1 + 1);
3222
3223 if (p2 - (p1 + 1) > 255) {
3224 *p2 = '\0';
3225 memprintf(err, "'%s' : ALPN protocol name too long : '%s'", args[cur_arg], p1 + 1);
3226 return ERR_ALERT | ERR_FATAL;
3227 }
3228
3229 *p1 = p2 - (p1 + 1);
3230 p1 = p2;
3231
3232 if (!*p2)
3233 break;
3234
3235 *(p2++) = '\0';
3236 }
3237 return 0;
3238#else
3239 if (err)
3240 memprintf(err, "'%s' : library does not support TLS ALPN extension", args[cur_arg]);
3241 return ERR_ALERT | ERR_FATAL;
3242#endif
3243}
3244
Willy Tarreau79eeafa2012-09-14 07:53:05 +02003245/* parse the "ssl" bind keyword */
Willy Tarreau4348fad2012-09-20 16:48:07 +02003246static 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 +02003247{
Willy Tarreau81796be2012-09-22 19:11:47 +02003248 struct listener *l;
3249
Willy Tarreau4348fad2012-09-20 16:48:07 +02003250 conf->is_ssl = 1;
Emeric Brun76d88952012-10-05 15:47:31 +02003251
3252 if (global.listen_default_ciphers && !conf->ciphers)
3253 conf->ciphers = strdup(global.listen_default_ciphers);
3254
Willy Tarreau81796be2012-09-22 19:11:47 +02003255 list_for_each_entry(l, &conf->listeners, by_bind)
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02003256 l->xprt = &ssl_sock;
Willy Tarreau81796be2012-09-22 19:11:47 +02003257
Willy Tarreau79eeafa2012-09-14 07:53:05 +02003258 return 0;
3259}
3260
Emmanuel Hocdet65623372013-01-24 17:17:15 +01003261/* parse the "strict-sni" bind keyword */
3262static int bind_parse_strict_sni(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
3263{
3264 conf->strict_sni = 1;
3265 return 0;
3266}
3267
Emeric Brund94b3fe2012-09-20 18:23:56 +02003268/* parse the "verify" bind keyword */
3269static int bind_parse_verify(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
3270{
3271 if (!*args[cur_arg + 1]) {
3272 if (err)
3273 memprintf(err, "'%s' : missing verify method", args[cur_arg]);
3274 return ERR_ALERT | ERR_FATAL;
3275 }
3276
3277 if (strcmp(args[cur_arg + 1], "none") == 0)
Emeric Brun850efd52014-01-29 12:24:34 +01003278 conf->verify = SSL_SOCK_VERIFY_NONE;
Emeric Brund94b3fe2012-09-20 18:23:56 +02003279 else if (strcmp(args[cur_arg + 1], "optional") == 0)
Emeric Brun850efd52014-01-29 12:24:34 +01003280 conf->verify = SSL_SOCK_VERIFY_OPTIONAL;
Emeric Brund94b3fe2012-09-20 18:23:56 +02003281 else if (strcmp(args[cur_arg + 1], "required") == 0)
Emeric Brun850efd52014-01-29 12:24:34 +01003282 conf->verify = SSL_SOCK_VERIFY_REQUIRED;
Emeric Brund94b3fe2012-09-20 18:23:56 +02003283 else {
3284 if (err)
3285 memprintf(err, "'%s' : unknown verify method '%s', only 'none', 'optional', and 'required' are supported\n",
3286 args[cur_arg], args[cur_arg + 1]);
3287 return ERR_ALERT | ERR_FATAL;
3288 }
3289
3290 return 0;
3291}
3292
Willy Tarreau92faadf2012-10-10 23:04:25 +02003293/************** "server" keywords ****************/
3294
Emeric Brunef42d922012-10-11 16:11:36 +02003295/* parse the "ca-file" server keyword */
3296static int srv_parse_ca_file(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
3297{
3298 if (!*args[*cur_arg + 1]) {
3299 if (err)
3300 memprintf(err, "'%s' : missing CAfile path", args[*cur_arg]);
3301 return ERR_ALERT | ERR_FATAL;
3302 }
3303
3304 if ((*args[*cur_arg + 1] != '/') && global.ca_base)
3305 memprintf(&newsrv->ssl_ctx.ca_file, "%s/%s", global.ca_base, args[*cur_arg + 1]);
3306 else
3307 memprintf(&newsrv->ssl_ctx.ca_file, "%s", args[*cur_arg + 1]);
3308
3309 return 0;
3310}
3311
Willy Tarreau92faadf2012-10-10 23:04:25 +02003312/* parse the "check-ssl" server keyword */
3313static int srv_parse_check_ssl(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
3314{
3315 newsrv->check.use_ssl = 1;
3316 if (global.connect_default_ciphers && !newsrv->ssl_ctx.ciphers)
3317 newsrv->ssl_ctx.ciphers = strdup(global.connect_default_ciphers);
3318 return 0;
3319}
3320
3321/* parse the "ciphers" server keyword */
3322static int srv_parse_ciphers(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
3323{
3324 if (!*args[*cur_arg + 1]) {
3325 memprintf(err, "'%s' : missing cipher suite", args[*cur_arg]);
3326 return ERR_ALERT | ERR_FATAL;
3327 }
3328
3329 free(newsrv->ssl_ctx.ciphers);
3330 newsrv->ssl_ctx.ciphers = strdup(args[*cur_arg + 1]);
3331 return 0;
3332}
3333
Emeric Brunef42d922012-10-11 16:11:36 +02003334/* parse the "crl-file" server keyword */
3335static int srv_parse_crl_file(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
3336{
3337#ifndef X509_V_FLAG_CRL_CHECK
3338 if (err)
3339 memprintf(err, "'%s' : library does not support CRL verify", args[*cur_arg]);
3340 return ERR_ALERT | ERR_FATAL;
3341#else
3342 if (!*args[*cur_arg + 1]) {
3343 if (err)
3344 memprintf(err, "'%s' : missing CRLfile path", args[*cur_arg]);
3345 return ERR_ALERT | ERR_FATAL;
3346 }
3347
3348 if ((*args[*cur_arg + 1] != '/') && global.ca_base)
3349 memprintf(&newsrv->ssl_ctx.crl_file, "%s/%s", global.ca_base, args[*cur_arg + 1]);
3350 else
3351 memprintf(&newsrv->ssl_ctx.crl_file, "%s", args[*cur_arg + 1]);
3352
3353 return 0;
3354#endif
3355}
3356
Emeric Bruna7aa3092012-10-26 12:58:00 +02003357/* parse the "crt" server keyword */
3358static int srv_parse_crt(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
3359{
3360 if (!*args[*cur_arg + 1]) {
3361 if (err)
3362 memprintf(err, "'%s' : missing certificate file path", args[*cur_arg]);
3363 return ERR_ALERT | ERR_FATAL;
3364 }
3365
3366 if ((*args[*cur_arg + 1] != '/') && global.crt_base)
3367 memprintf(&newsrv->ssl_ctx.client_crt, "%s/%s", global.ca_base, args[*cur_arg + 1]);
3368 else
3369 memprintf(&newsrv->ssl_ctx.client_crt, "%s", args[*cur_arg + 1]);
3370
3371 return 0;
3372}
Emeric Brunef42d922012-10-11 16:11:36 +02003373
Willy Tarreau92faadf2012-10-10 23:04:25 +02003374/* parse the "force-sslv3" server keyword */
3375static int srv_parse_force_sslv3(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
3376{
3377 newsrv->ssl_ctx.options |= SRV_SSL_O_USE_SSLV3;
3378 return 0;
3379}
3380
3381/* parse the "force-tlsv10" server keyword */
3382static int srv_parse_force_tlsv10(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
3383{
3384 newsrv->ssl_ctx.options |= SRV_SSL_O_USE_TLSV10;
3385 return 0;
3386}
3387
3388/* parse the "force-tlsv11" server keyword */
3389static int srv_parse_force_tlsv11(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
3390{
3391#if SSL_OP_NO_TLSv1_1
3392 newsrv->ssl_ctx.options |= SRV_SSL_O_USE_TLSV11;
3393 return 0;
3394#else
3395 if (err)
3396 memprintf(err, "'%s' : library does not support protocol TLSv1.1", args[*cur_arg]);
3397 return ERR_ALERT | ERR_FATAL;
3398#endif
3399}
3400
3401/* parse the "force-tlsv12" server keyword */
3402static int srv_parse_force_tlsv12(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
3403{
3404#if SSL_OP_NO_TLSv1_2
3405 newsrv->ssl_ctx.options |= SRV_SSL_O_USE_TLSV12;
3406 return 0;
3407#else
3408 if (err)
3409 memprintf(err, "'%s' : library does not support protocol TLSv1.2", args[*cur_arg]);
3410 return ERR_ALERT | ERR_FATAL;
3411#endif
3412}
3413
3414/* parse the "no-sslv3" server keyword */
3415static int srv_parse_no_sslv3(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
3416{
3417 newsrv->ssl_ctx.options |= SRV_SSL_O_NO_SSLV3;
3418 return 0;
3419}
3420
3421/* parse the "no-tlsv10" server keyword */
3422static int srv_parse_no_tlsv10(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
3423{
3424 newsrv->ssl_ctx.options |= SRV_SSL_O_NO_TLSV10;
3425 return 0;
3426}
3427
3428/* parse the "no-tlsv11" server keyword */
3429static int srv_parse_no_tlsv11(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
3430{
3431 newsrv->ssl_ctx.options |= SRV_SSL_O_NO_TLSV11;
3432 return 0;
3433}
3434
3435/* parse the "no-tlsv12" server keyword */
3436static int srv_parse_no_tlsv12(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
3437{
3438 newsrv->ssl_ctx.options |= SRV_SSL_O_NO_TLSV12;
3439 return 0;
3440}
3441
Emeric Brunf9c5c472012-10-11 15:28:34 +02003442/* parse the "no-tls-tickets" server keyword */
3443static int srv_parse_no_tls_tickets(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
3444{
3445 newsrv->ssl_ctx.options |= SRV_SSL_O_NO_TLS_TICKETS;
3446 return 0;
3447}
3448
Willy Tarreau92faadf2012-10-10 23:04:25 +02003449/* parse the "ssl" server keyword */
3450static int srv_parse_ssl(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
3451{
3452 newsrv->use_ssl = 1;
3453 if (global.connect_default_ciphers && !newsrv->ssl_ctx.ciphers)
3454 newsrv->ssl_ctx.ciphers = strdup(global.connect_default_ciphers);
3455 return 0;
3456}
3457
Emeric Brunef42d922012-10-11 16:11:36 +02003458/* parse the "verify" server keyword */
3459static int srv_parse_verify(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
3460{
3461 if (!*args[*cur_arg + 1]) {
3462 if (err)
3463 memprintf(err, "'%s' : missing verify method", args[*cur_arg]);
3464 return ERR_ALERT | ERR_FATAL;
3465 }
3466
3467 if (strcmp(args[*cur_arg + 1], "none") == 0)
Emeric Brun850efd52014-01-29 12:24:34 +01003468 newsrv->ssl_ctx.verify = SSL_SOCK_VERIFY_NONE;
Emeric Brunef42d922012-10-11 16:11:36 +02003469 else if (strcmp(args[*cur_arg + 1], "required") == 0)
Emeric Brun850efd52014-01-29 12:24:34 +01003470 newsrv->ssl_ctx.verify = SSL_SOCK_VERIFY_REQUIRED;
Emeric Brunef42d922012-10-11 16:11:36 +02003471 else {
3472 if (err)
3473 memprintf(err, "'%s' : unknown verify method '%s', only 'none' and 'required' are supported\n",
3474 args[*cur_arg], args[*cur_arg + 1]);
3475 return ERR_ALERT | ERR_FATAL;
3476 }
3477
Evan Broderbe554312013-06-27 00:05:25 -07003478 return 0;
3479}
3480
3481/* parse the "verifyhost" server keyword */
3482static int srv_parse_verifyhost(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
3483{
3484 if (!*args[*cur_arg + 1]) {
3485 if (err)
3486 memprintf(err, "'%s' : missing hostname to verify against", args[*cur_arg]);
3487 return ERR_ALERT | ERR_FATAL;
3488 }
3489
3490 newsrv->ssl_ctx.verify_host = strdup(args[*cur_arg + 1]);
3491
Emeric Brunef42d922012-10-11 16:11:36 +02003492 return 0;
3493}
3494
Willy Tarreau7875d092012-09-10 08:20:03 +02003495/* Note: must not be declared <const> as its list will be overwritten.
3496 * Please take care of keeping this list alphabetically sorted.
3497 */
Willy Tarreaudc13c112013-06-21 23:16:39 +02003498static struct sample_fetch_kw_list sample_fetch_keywords = {ILH, {
Willy Tarreau80aca902013-01-07 15:42:20 +01003499 { "ssl_c_ca_err", smp_fetch_ssl_c_ca_err, 0, NULL, SMP_T_UINT, SMP_USE_L5CLI },
3500 { "ssl_c_ca_err_depth", smp_fetch_ssl_c_ca_err_depth, 0, NULL, SMP_T_UINT, SMP_USE_L5CLI },
3501 { "ssl_c_err", smp_fetch_ssl_c_err, 0, NULL, SMP_T_UINT, SMP_USE_L5CLI },
3502 { "ssl_c_i_dn", smp_fetch_ssl_c_i_dn, ARG2(0,STR,SINT), NULL, SMP_T_STR, SMP_USE_L5CLI },
3503 { "ssl_c_key_alg", smp_fetch_ssl_c_key_alg, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
3504 { "ssl_c_notafter", smp_fetch_ssl_c_notafter, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
3505 { "ssl_c_notbefore", smp_fetch_ssl_c_notbefore, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
3506 { "ssl_c_sig_alg", smp_fetch_ssl_c_sig_alg, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
3507 { "ssl_c_s_dn", smp_fetch_ssl_c_s_dn, ARG2(0,STR,SINT), NULL, SMP_T_STR, SMP_USE_L5CLI },
3508 { "ssl_c_serial", smp_fetch_ssl_c_serial, 0, NULL, SMP_T_BIN, SMP_USE_L5CLI },
James Votha051b4a2013-05-14 20:37:59 +02003509 { "ssl_c_sha1", smp_fetch_ssl_c_sha1, 0, NULL, SMP_T_BIN, SMP_USE_L5CLI },
Willy Tarreau80aca902013-01-07 15:42:20 +01003510 { "ssl_c_used", smp_fetch_ssl_c_used, 0, NULL, SMP_T_BOOL, SMP_USE_L5CLI },
3511 { "ssl_c_verify", smp_fetch_ssl_c_verify, 0, NULL, SMP_T_UINT, SMP_USE_L5CLI },
3512 { "ssl_c_version", smp_fetch_ssl_c_version, 0, NULL, SMP_T_UINT, SMP_USE_L5CLI },
3513 { "ssl_f_i_dn", smp_fetch_ssl_f_i_dn, ARG2(0,STR,SINT), NULL, SMP_T_STR, SMP_USE_L5CLI },
3514 { "ssl_f_key_alg", smp_fetch_ssl_f_key_alg, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
3515 { "ssl_f_notafter", smp_fetch_ssl_f_notafter, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
3516 { "ssl_f_notbefore", smp_fetch_ssl_f_notbefore, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
3517 { "ssl_f_sig_alg", smp_fetch_ssl_f_sig_alg, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
3518 { "ssl_f_s_dn", smp_fetch_ssl_f_s_dn, ARG2(0,STR,SINT), NULL, SMP_T_STR, SMP_USE_L5CLI },
3519 { "ssl_f_serial", smp_fetch_ssl_f_serial, 0, NULL, SMP_T_BIN, SMP_USE_L5CLI },
3520 { "ssl_f_version", smp_fetch_ssl_f_version, 0, NULL, SMP_T_UINT, SMP_USE_L5CLI },
3521 { "ssl_fc", smp_fetch_ssl_fc, 0, NULL, SMP_T_BOOL, SMP_USE_L5CLI },
3522 { "ssl_fc_alg_keysize", smp_fetch_ssl_fc_alg_keysize, 0, NULL, SMP_T_UINT, SMP_USE_L5CLI },
3523 { "ssl_fc_cipher", smp_fetch_ssl_fc_cipher, 0, NULL, SMP_T_CSTR, SMP_USE_L5CLI },
3524 { "ssl_fc_has_crt", smp_fetch_ssl_fc_has_crt, 0, NULL, SMP_T_BOOL, SMP_USE_L5CLI },
3525 { "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 +02003526#ifdef OPENSSL_NPN_NEGOTIATED
Willy Tarreau80aca902013-01-07 15:42:20 +01003527 { "ssl_fc_npn", smp_fetch_ssl_fc_npn, 0, NULL, SMP_T_CSTR, SMP_USE_L5CLI },
Willy Tarreaua33c6542012-10-15 13:19:06 +02003528#endif
Dirkjan Bussink48f1c4e2014-02-13 12:29:42 +01003529#ifdef TLSEXT_TYPE_application_layer_protocol_negotiation
Willy Tarreauab861d32013-04-02 02:30:41 +02003530 { "ssl_fc_alpn", smp_fetch_ssl_fc_alpn, 0, NULL, SMP_T_CSTR, SMP_USE_L5CLI },
3531#endif
Willy Tarreau80aca902013-01-07 15:42:20 +01003532 { "ssl_fc_protocol", smp_fetch_ssl_fc_protocol, 0, NULL, SMP_T_CSTR, SMP_USE_L5CLI },
3533 { "ssl_fc_use_keysize", smp_fetch_ssl_fc_use_keysize, 0, NULL, SMP_T_UINT, SMP_USE_L5CLI },
3534 { "ssl_fc_session_id", smp_fetch_ssl_fc_session_id, 0, NULL, SMP_T_CBIN, SMP_USE_L5CLI },
3535 { "ssl_fc_sni", smp_fetch_ssl_fc_sni, 0, NULL, SMP_T_CSTR, SMP_USE_L5CLI },
Willy Tarreau7875d092012-09-10 08:20:03 +02003536 { NULL, NULL, 0, 0, 0 },
3537}};
3538
3539/* Note: must not be declared <const> as its list will be overwritten.
3540 * Please take care of keeping this list alphabetically sorted.
3541 */
Willy Tarreaudc13c112013-06-21 23:16:39 +02003542static struct acl_kw_list acl_kws = {ILH, {
Thierry FOURNIERa65b3432013-11-28 18:22:00 +01003543 { "ssl_c_i_dn", NULL, pat_parse_str, pat_match_str },
3544 { "ssl_c_key_alg", NULL, pat_parse_str, pat_match_str },
3545 { "ssl_c_notafter", NULL, pat_parse_str, pat_match_str },
3546 { "ssl_c_notbefore", NULL, pat_parse_str, pat_match_str },
3547 { "ssl_c_sig_alg", NULL, pat_parse_str, pat_match_str },
3548 { "ssl_c_s_dn", NULL, pat_parse_str, pat_match_str },
3549 { "ssl_c_serial", NULL, pat_parse_bin, pat_match_bin },
3550 { "ssl_f_i_dn", NULL, pat_parse_str, pat_match_str },
3551 { "ssl_f_key_alg", NULL, pat_parse_str, pat_match_str },
3552 { "ssl_f_notafter", NULL, pat_parse_str, pat_match_str },
3553 { "ssl_f_notbefore", NULL, pat_parse_str, pat_match_str },
3554 { "ssl_f_sig_alg", NULL, pat_parse_str, pat_match_str },
3555 { "ssl_f_s_dn", NULL, pat_parse_str, pat_match_str },
3556 { "ssl_f_serial", NULL, pat_parse_bin, pat_match_bin },
3557 { "ssl_fc_cipher", NULL, pat_parse_str, pat_match_str },
Willy Tarreaua33c6542012-10-15 13:19:06 +02003558#ifdef OPENSSL_NPN_NEGOTIATED
Thierry FOURNIERa65b3432013-11-28 18:22:00 +01003559 { "ssl_fc_npn", NULL, pat_parse_str, pat_match_str },
Willy Tarreaua33c6542012-10-15 13:19:06 +02003560#endif
Dirkjan Bussink48f1c4e2014-02-13 12:29:42 +01003561#ifdef TLSEXT_TYPE_application_layer_protocol_negotiation
Thierry FOURNIERa65b3432013-11-28 18:22:00 +01003562 { "ssl_fc_alpn", NULL, pat_parse_str, pat_match_str },
Willy Tarreauab861d32013-04-02 02:30:41 +02003563#endif
Thierry FOURNIERa65b3432013-11-28 18:22:00 +01003564 { "ssl_fc_protocol", NULL, pat_parse_str, pat_match_str },
3565 { "ssl_fc_sni", "ssl_fc_sni", pat_parse_str, pat_match_str },
3566 { "ssl_fc_sni_end", "ssl_fc_sni", pat_parse_str, pat_match_end },
3567 { "ssl_fc_sni_reg", "ssl_fc_sni", pat_parse_reg, pat_match_reg },
Willy Tarreau8ed669b2013-01-11 15:49:37 +01003568 { /* END */ },
Willy Tarreau7875d092012-09-10 08:20:03 +02003569}};
3570
Willy Tarreau79eeafa2012-09-14 07:53:05 +02003571/* Note: must not be declared <const> as its list will be overwritten.
3572 * Please take care of keeping this list alphabetically sorted, doing so helps
3573 * all code contributors.
3574 * Optional keywords are also declared with a NULL ->parse() function so that
3575 * the config parser can report an appropriate error when a known keyword was
3576 * not enabled.
3577 */
Willy Tarreau51fb7652012-09-18 18:24:39 +02003578static struct bind_kw_list bind_kws = { "SSL", { }, {
Willy Tarreauab861d32013-04-02 02:30:41 +02003579 { "alpn", bind_parse_alpn, 1 }, /* set ALPN supported protocols */
Emeric Brunfb510ea2012-10-05 12:00:26 +02003580 { "ca-file", bind_parse_ca_file, 1 }, /* set CAfile to process verify on client cert */
Emeric Brun2d0c4822012-10-02 13:45:20 +02003581 { "ca-ignore-err", bind_parse_ignore_err, 1 }, /* set error IDs to ignore on verify depth > 0 */
3582 { "ciphers", bind_parse_ciphers, 1 }, /* set SSL cipher suite */
Emeric Brunfb510ea2012-10-05 12:00:26 +02003583 { "crl-file", bind_parse_crl_file, 1 }, /* set certificat revocation list file use on client cert verify */
Emeric Brun2d0c4822012-10-02 13:45:20 +02003584 { "crt", bind_parse_crt, 1 }, /* load SSL certificates from this location */
3585 { "crt-ignore-err", bind_parse_ignore_err, 1 }, /* set error IDs to ingore on verify depth == 0 */
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01003586 { "crt-list", bind_parse_crt_list, 1 }, /* load a list of crt from this location */
Emeric Brun2d0c4822012-10-02 13:45:20 +02003587 { "ecdhe", bind_parse_ecdhe, 1 }, /* defines named curve for elliptic curve Diffie-Hellman */
Emeric Brun2cb7ae52012-10-05 14:14:21 +02003588 { "force-sslv3", bind_parse_force_sslv3, 0 }, /* force SSLv3 */
3589 { "force-tlsv10", bind_parse_force_tlsv10, 0 }, /* force TLSv10 */
3590 { "force-tlsv11", bind_parse_force_tlsv11, 0 }, /* force TLSv11 */
3591 { "force-tlsv12", bind_parse_force_tlsv12, 0 }, /* force TLSv12 */
Emeric Brun9b3009b2012-10-05 11:55:06 +02003592 { "no-sslv3", bind_parse_no_sslv3, 0 }, /* disable SSLv3 */
3593 { "no-tlsv10", bind_parse_no_tlsv10, 0 }, /* disable TLSv10 */
3594 { "no-tlsv11", bind_parse_no_tlsv11, 0 }, /* disable TLSv11 */
3595 { "no-tlsv12", bind_parse_no_tlsv12, 0 }, /* disable TLSv12 */
Emeric Brun2d0c4822012-10-02 13:45:20 +02003596 { "no-tls-tickets", bind_parse_no_tls_tickets, 0 }, /* disable session resumption tickets */
Emeric Brun2d0c4822012-10-02 13:45:20 +02003597 { "ssl", bind_parse_ssl, 0 }, /* enable SSL processing */
Emmanuel Hocdet65623372013-01-24 17:17:15 +01003598 { "strict-sni", bind_parse_strict_sni, 0 }, /* refuse negotiation if sni doesn't match a certificate */
Emeric Brun2d0c4822012-10-02 13:45:20 +02003599 { "verify", bind_parse_verify, 1 }, /* set SSL verify method */
Willy Tarreau6c9a3d52012-10-18 18:57:14 +02003600 { "npn", bind_parse_npn, 1 }, /* set NPN supported protocols */
Willy Tarreau79eeafa2012-09-14 07:53:05 +02003601 { NULL, NULL, 0 },
3602}};
Emeric Brun46591952012-05-18 15:47:34 +02003603
Willy Tarreau92faadf2012-10-10 23:04:25 +02003604/* Note: must not be declared <const> as its list will be overwritten.
3605 * Please take care of keeping this list alphabetically sorted, doing so helps
3606 * all code contributors.
3607 * Optional keywords are also declared with a NULL ->parse() function so that
3608 * the config parser can report an appropriate error when a known keyword was
3609 * not enabled.
3610 */
3611static struct srv_kw_list srv_kws = { "SSL", { }, {
Emeric Brunef42d922012-10-11 16:11:36 +02003612 { "ca-file", srv_parse_ca_file, 1, 0 }, /* set CAfile to process verify server cert */
Emeric Brunecc91fe2012-10-11 15:05:10 +02003613 { "check-ssl", srv_parse_check_ssl, 0, 0 }, /* enable SSL for health checks */
3614 { "ciphers", srv_parse_ciphers, 1, 0 }, /* select the cipher suite */
Emeric Brunef42d922012-10-11 16:11:36 +02003615 { "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 +02003616 { "crt", srv_parse_crt, 1, 0 }, /* set client certificate */
Emeric Brunecc91fe2012-10-11 15:05:10 +02003617 { "force-sslv3", srv_parse_force_sslv3, 0, 0 }, /* force SSLv3 */
3618 { "force-tlsv10", srv_parse_force_tlsv10, 0, 0 }, /* force TLSv10 */
3619 { "force-tlsv11", srv_parse_force_tlsv11, 0, 0 }, /* force TLSv11 */
3620 { "force-tlsv12", srv_parse_force_tlsv12, 0, 0 }, /* force TLSv12 */
3621 { "no-sslv3", srv_parse_no_sslv3, 0, 0 }, /* disable SSLv3 */
3622 { "no-tlsv10", srv_parse_no_tlsv10, 0, 0 }, /* disable TLSv10 */
3623 { "no-tlsv11", srv_parse_no_tlsv11, 0, 0 }, /* disable TLSv11 */
3624 { "no-tlsv12", srv_parse_no_tlsv12, 0, 0 }, /* disable TLSv12 */
Emeric Brunf9c5c472012-10-11 15:28:34 +02003625 { "no-tls-tickets", srv_parse_no_tls_tickets, 0, 0 }, /* disable session resumption tickets */
Emeric Brunecc91fe2012-10-11 15:05:10 +02003626 { "ssl", srv_parse_ssl, 0, 0 }, /* enable SSL processing */
Emeric Brunef42d922012-10-11 16:11:36 +02003627 { "verify", srv_parse_verify, 1, 0 }, /* set SSL verify method */
Evan Broderbe554312013-06-27 00:05:25 -07003628 { "verifyhost", srv_parse_verifyhost, 1, 0 }, /* require that SSL cert verifies for hostname */
Willy Tarreau92faadf2012-10-10 23:04:25 +02003629 { NULL, NULL, 0, 0 },
3630}};
3631
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02003632/* transport-layer operations for SSL sockets */
3633struct xprt_ops ssl_sock = {
Emeric Brun46591952012-05-18 15:47:34 +02003634 .snd_buf = ssl_sock_from_buf,
3635 .rcv_buf = ssl_sock_to_buf,
3636 .rcv_pipe = NULL,
3637 .snd_pipe = NULL,
3638 .shutr = NULL,
3639 .shutw = ssl_sock_shutw,
3640 .close = ssl_sock_close,
3641 .init = ssl_sock_init,
3642};
3643
3644__attribute__((constructor))
Willy Tarreau92faadf2012-10-10 23:04:25 +02003645static void __ssl_sock_init(void)
3646{
Emeric Brun46591952012-05-18 15:47:34 +02003647 STACK_OF(SSL_COMP)* cm;
3648
Willy Tarreau610f04b2014-02-13 11:36:41 +01003649#ifdef LISTEN_DEFAULT_CIPHERS
3650 global.listen_default_ciphers = LISTEN_DEFAULT_CIPHERS;
3651#endif
3652#ifdef CONNECT_DEFAULT_CIPHERS
3653 global.connect_default_ciphers = CONNECT_DEFAULT_CIPHERS;
3654#endif
3655 if (global.listen_default_ciphers)
3656 global.listen_default_ciphers = strdup(global.listen_default_ciphers);
3657 if (global.connect_default_ciphers)
3658 global.connect_default_ciphers = strdup(global.connect_default_ciphers);
3659
Emeric Brun46591952012-05-18 15:47:34 +02003660 SSL_library_init();
3661 cm = SSL_COMP_get_compression_methods();
3662 sk_SSL_COMP_zero(cm);
Willy Tarreau7875d092012-09-10 08:20:03 +02003663 sample_register_fetches(&sample_fetch_keywords);
3664 acl_register_keywords(&acl_kws);
Willy Tarreau79eeafa2012-09-14 07:53:05 +02003665 bind_register_keywords(&bind_kws);
Willy Tarreau92faadf2012-10-10 23:04:25 +02003666 srv_register_keywords(&srv_kws);
Emeric Brun46591952012-05-18 15:47:34 +02003667}
3668
3669/*
3670 * Local variables:
3671 * c-indent-level: 8
3672 * c-basic-offset: 8
3673 * End:
3674 */