blob: b3f051d82a45878e384753c42266e9a3a5e41f15 [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
Thierry FOURNIER7654c9f2013-12-17 00:20:33 +01002195 smp->type = SMP_T_STR;
2196 smp->flags |= SMP_F_CONST;
Emeric Brun7f56e742012-10-19 18:15:40 +02002197 smp->data.str.len = strlen(smp->data.str.str);
2198 X509_free(crt);
2199
2200 return 1;
2201}
2202
Emeric Brun521a0112012-10-22 12:22:55 +02002203/* str, returns the client certificate key alg */
2204static int
2205smp_fetch_ssl_c_key_alg(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
Willy Tarreauef38c392013-07-22 16:29:32 +02002206 const struct arg *args, struct sample *smp, const char *kw)
Emeric Brun521a0112012-10-22 12:22:55 +02002207{
2208 X509 *crt;
2209 int nid;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002210 struct connection *conn;
Emeric Brun521a0112012-10-22 12:22:55 +02002211
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002212 if (!l4)
Emeric Brun521a0112012-10-22 12:22:55 +02002213 return 0;
2214
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002215 conn = objt_conn(l4->si[0].end);
2216 if (!conn || conn->xprt != &ssl_sock)
2217 return 0;
2218
2219 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brun521a0112012-10-22 12:22:55 +02002220 smp->flags |= SMP_F_MAY_CHANGE;
2221 return 0;
2222 }
2223
2224 /* SSL_get_peer_certificate increase X509 * ref count */
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002225 crt = SSL_get_peer_certificate(conn->xprt_ctx);
Emeric Brun521a0112012-10-22 12:22:55 +02002226 if (!crt)
2227 return 0;
2228
2229 nid = OBJ_obj2nid((ASN1_OBJECT *)(crt->cert_info->key->algor->algorithm));
2230
2231 smp->data.str.str = (char *)OBJ_nid2sn(nid);
Emeric Brun9bf3ba22013-10-07 14:31:44 +02002232 if (!smp->data.str.str) {
2233 X509_free(crt);
Emeric Brun521a0112012-10-22 12:22:55 +02002234 return 0;
Emeric Brun9bf3ba22013-10-07 14:31:44 +02002235 }
Emeric Brun521a0112012-10-22 12:22:55 +02002236
Thierry FOURNIER7654c9f2013-12-17 00:20:33 +01002237 smp->type = SMP_T_STR;
2238 smp->flags |= SMP_F_CONST;
Emeric Brun521a0112012-10-22 12:22:55 +02002239 smp->data.str.len = strlen(smp->data.str.str);
2240 X509_free(crt);
2241
2242 return 1;
2243}
2244
Emeric Brun2525b6b2012-10-18 15:59:43 +02002245/* boolean, returns true if front conn. transport layer is SSL */
Willy Tarreau7875d092012-09-10 08:20:03 +02002246static int
Emeric Brun2525b6b2012-10-18 15:59:43 +02002247smp_fetch_ssl_fc(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
Willy Tarreauef38c392013-07-22 16:29:32 +02002248 const struct arg *args, struct sample *smp, const char *kw)
Willy Tarreau7875d092012-09-10 08:20:03 +02002249{
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002250 struct connection *conn = objt_conn(l4->si[0].end);
2251
Willy Tarreau7875d092012-09-10 08:20:03 +02002252 smp->type = SMP_T_BOOL;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002253 smp->data.uint = (conn && conn->xprt == &ssl_sock);
Willy Tarreau7875d092012-09-10 08:20:03 +02002254 return 1;
2255}
2256
Emeric Brun2525b6b2012-10-18 15:59:43 +02002257/* boolean, returns true if client present a SNI */
Willy Tarreau7875d092012-09-10 08:20:03 +02002258static int
Emeric Brun2525b6b2012-10-18 15:59:43 +02002259smp_fetch_ssl_fc_has_sni(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
Willy Tarreauef38c392013-07-22 16:29:32 +02002260 const struct arg *args, struct sample *smp, const char *kw)
Willy Tarreau7875d092012-09-10 08:20:03 +02002261{
2262#ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002263 struct connection *conn = objt_conn(l4->si[0].end);
2264
Willy Tarreau7875d092012-09-10 08:20:03 +02002265 smp->type = SMP_T_BOOL;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002266 smp->data.uint = (conn && conn->xprt == &ssl_sock) &&
2267 conn->xprt_ctx &&
2268 SSL_get_servername(conn->xprt_ctx, TLSEXT_NAMETYPE_host_name) != NULL;
Willy Tarreau7875d092012-09-10 08:20:03 +02002269 return 1;
2270#else
2271 return 0;
2272#endif
2273}
2274
Willy Tarreau8d598402012-10-22 17:58:39 +02002275/* bin, returns serial in a binary chunk */
2276static int
2277smp_fetch_ssl_f_serial(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
Willy Tarreauef38c392013-07-22 16:29:32 +02002278 const struct arg *args, struct sample *smp, const char *kw)
Willy Tarreau8d598402012-10-22 17:58:39 +02002279{
2280 X509 *crt = NULL;
2281 int ret = 0;
2282 struct chunk *smp_trash;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002283 struct connection *conn;
2284
2285 if (!l4)
2286 return 0;
Willy Tarreau8d598402012-10-22 17:58:39 +02002287
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002288 conn = objt_conn(l4->si[0].end);
2289 if (!conn || conn->xprt != &ssl_sock)
Willy Tarreau8d598402012-10-22 17:58:39 +02002290 return 0;
2291
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002292 if (!(conn->flags & CO_FL_CONNECTED)) {
Willy Tarreau8d598402012-10-22 17:58:39 +02002293 smp->flags |= SMP_F_MAY_CHANGE;
2294 return 0;
2295 }
2296
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002297 crt = SSL_get_certificate(conn->xprt_ctx);
Willy Tarreau8d598402012-10-22 17:58:39 +02002298 if (!crt)
2299 goto out;
2300
Willy Tarreau47ca5452012-12-23 20:22:19 +01002301 smp_trash = get_trash_chunk();
Willy Tarreau8d598402012-10-22 17:58:39 +02002302 if (ssl_sock_get_serial(crt, smp_trash) <= 0)
2303 goto out;
2304
2305 smp->data.str = *smp_trash;
2306 smp->type = SMP_T_BIN;
2307 ret = 1;
2308out:
2309 return ret;
2310}
Emeric Brunce5ad802012-10-22 14:11:22 +02002311/*str, returns notafter date in ASN1_UTCTIME format */
2312static int
2313smp_fetch_ssl_f_notafter(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
Willy Tarreauef38c392013-07-22 16:29:32 +02002314 const struct arg *args, struct sample *smp, const char *kw)
Emeric Brunce5ad802012-10-22 14:11:22 +02002315{
2316 X509 *crt = NULL;
2317 int ret = 0;
2318 struct chunk *smp_trash;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002319 struct connection *conn;
Emeric Brunce5ad802012-10-22 14:11:22 +02002320
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002321 if (!l4)
Emeric Brunce5ad802012-10-22 14:11:22 +02002322 return 0;
2323
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002324 conn = objt_conn(l4->si[0].end);
2325 if (!conn || conn->xprt != &ssl_sock)
2326 return 0;
2327
2328 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brunce5ad802012-10-22 14:11:22 +02002329 smp->flags |= SMP_F_MAY_CHANGE;
2330 return 0;
2331 }
2332
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002333 crt = SSL_get_certificate(conn->xprt_ctx);
Emeric Brunce5ad802012-10-22 14:11:22 +02002334 if (!crt)
2335 goto out;
2336
Willy Tarreau47ca5452012-12-23 20:22:19 +01002337 smp_trash = get_trash_chunk();
Emeric Brunce5ad802012-10-22 14:11:22 +02002338 if (ssl_sock_get_time(X509_get_notAfter(crt), smp_trash) <= 0)
2339 goto out;
2340
2341 smp->data.str = *smp_trash;
2342 smp->type = SMP_T_STR;
2343 ret = 1;
2344out:
2345 return ret;
2346}
2347
2348/*str, returns notbefore date in ASN1_UTCTIME format */
2349static int
2350smp_fetch_ssl_f_notbefore(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
Willy Tarreauef38c392013-07-22 16:29:32 +02002351 const struct arg *args, struct sample *smp, const char *kw)
Emeric Brunce5ad802012-10-22 14:11:22 +02002352{
2353 X509 *crt = NULL;
2354 int ret = 0;
2355 struct chunk *smp_trash;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002356 struct connection *conn;
Emeric Brunce5ad802012-10-22 14:11:22 +02002357
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002358 if (!l4)
Emeric Brunce5ad802012-10-22 14:11:22 +02002359 return 0;
2360
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002361 conn = objt_conn(l4->si[0].end);
2362 if (!conn || conn->xprt != &ssl_sock)
2363 return 0;
2364
2365 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brunce5ad802012-10-22 14:11:22 +02002366 smp->flags |= SMP_F_MAY_CHANGE;
2367 return 0;
2368 }
2369
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002370 crt = SSL_get_certificate(conn->xprt_ctx);
Emeric Brunce5ad802012-10-22 14:11:22 +02002371 if (!crt)
2372 goto out;
2373
Willy Tarreau47ca5452012-12-23 20:22:19 +01002374 smp_trash = get_trash_chunk();
Emeric Brunce5ad802012-10-22 14:11:22 +02002375 if (ssl_sock_get_time(X509_get_notBefore(crt), smp_trash) <= 0)
2376 goto out;
2377
2378 smp->data.str = *smp_trash;
2379 smp->type = SMP_T_STR;
2380 ret = 1;
2381out:
2382 return ret;
2383}
Willy Tarreau8d598402012-10-22 17:58:39 +02002384
Emeric Bruna7359fd2012-10-17 15:03:11 +02002385/* integer, returns the frontend certificate version */
2386static int
2387smp_fetch_ssl_f_version(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
Willy Tarreauef38c392013-07-22 16:29:32 +02002388 const struct arg *args, struct sample *smp, const char *kw)
Emeric Bruna7359fd2012-10-17 15:03:11 +02002389{
2390 X509 *crt;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002391 struct connection *conn;
Emeric Bruna7359fd2012-10-17 15:03:11 +02002392
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002393 if (!l4)
Emeric Bruna7359fd2012-10-17 15:03:11 +02002394 return 0;
2395
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002396 conn = objt_conn(l4->si[0].end);
2397 if (!conn || conn->xprt != &ssl_sock)
2398 return 0;
2399
2400 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Bruna7359fd2012-10-17 15:03:11 +02002401 smp->flags |= SMP_F_MAY_CHANGE;
2402 return 0;
2403 }
2404
2405 /* SSL_get_certificate returns a ptr on an SSL * internal sub struct */
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002406 crt = SSL_get_certificate(conn->xprt_ctx);
Emeric Bruna7359fd2012-10-17 15:03:11 +02002407 if (!crt)
2408 return 0;
2409
2410 smp->data.uint = (unsigned int)(1 + X509_get_version(crt));
2411 smp->type = SMP_T_UINT;
2412
2413 return 1;
2414}
2415
Emeric Brun7f56e742012-10-19 18:15:40 +02002416/* str, returns the client certificate sig alg */
2417static int
2418smp_fetch_ssl_f_sig_alg(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
Willy Tarreauef38c392013-07-22 16:29:32 +02002419 const struct arg *args, struct sample *smp, const char *kw)
Emeric Brun7f56e742012-10-19 18:15:40 +02002420{
2421 X509 *crt;
2422 int nid;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002423 struct connection *conn;
Emeric Brun7f56e742012-10-19 18:15:40 +02002424
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002425 if (!l4)
Emeric Brun7f56e742012-10-19 18:15:40 +02002426 return 0;
2427
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002428 conn = objt_conn(l4->si[0].end);
2429 if (!conn || conn->xprt != &ssl_sock)
2430 return 0;
2431
2432 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brun7f56e742012-10-19 18:15:40 +02002433 smp->flags |= SMP_F_MAY_CHANGE;
2434 return 0;
2435 }
2436
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002437 crt = SSL_get_certificate(conn->xprt_ctx);
Emeric Brun7f56e742012-10-19 18:15:40 +02002438 if (!crt)
2439 return 0;
2440
2441 nid = OBJ_obj2nid((ASN1_OBJECT *)(crt->cert_info->signature->algorithm));
2442
2443 smp->data.str.str = (char *)OBJ_nid2sn(nid);
2444 if (!smp->data.str.str)
2445 return 0;
2446
Thierry FOURNIER7654c9f2013-12-17 00:20:33 +01002447 smp->type = SMP_T_STR;
2448 smp->flags |= SMP_F_CONST;
Emeric Brun7f56e742012-10-19 18:15:40 +02002449 smp->data.str.len = strlen(smp->data.str.str);
2450
2451 return 1;
2452}
2453
Emeric Brun521a0112012-10-22 12:22:55 +02002454/* str, returns the client certificate key alg */
2455static int
2456smp_fetch_ssl_f_key_alg(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
Willy Tarreauef38c392013-07-22 16:29:32 +02002457 const struct arg *args, struct sample *smp, const char *kw)
Emeric Brun521a0112012-10-22 12:22:55 +02002458{
2459 X509 *crt;
2460 int nid;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002461 struct connection *conn;
2462
2463 if (!l4)
2464 return 0;
Emeric Brun521a0112012-10-22 12:22:55 +02002465
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002466 conn = objt_conn(l4->si[0].end);
2467 if (!conn || conn->xprt != &ssl_sock)
Emeric Brun521a0112012-10-22 12:22:55 +02002468 return 0;
2469
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002470 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brun521a0112012-10-22 12:22:55 +02002471 smp->flags |= SMP_F_MAY_CHANGE;
2472 return 0;
2473 }
2474
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002475 crt = SSL_get_certificate(conn->xprt_ctx);
Emeric Brun521a0112012-10-22 12:22:55 +02002476 if (!crt)
2477 return 0;
2478
2479 nid = OBJ_obj2nid((ASN1_OBJECT *)(crt->cert_info->key->algor->algorithm));
2480
2481 smp->data.str.str = (char *)OBJ_nid2sn(nid);
2482 if (!smp->data.str.str)
2483 return 0;
2484
Thierry FOURNIER7654c9f2013-12-17 00:20:33 +01002485 smp->type = SMP_T_STR;
2486 smp->flags |= SMP_F_CONST;
Emeric Brun521a0112012-10-22 12:22:55 +02002487 smp->data.str.len = strlen(smp->data.str.str);
2488
2489 return 1;
2490}
2491
Emeric Brun87855892012-10-17 17:39:35 +02002492/* str, returns a string of a formatted full dn \C=..\O=..\OU=.. \CN=.. */
2493static int
2494smp_fetch_ssl_f_i_dn(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
Willy Tarreauef38c392013-07-22 16:29:32 +02002495 const struct arg *args, struct sample *smp, const char *kw)
Emeric Brun87855892012-10-17 17:39:35 +02002496{
2497 X509 *crt = NULL;
2498 X509_NAME *name;
2499 int ret = 0;
2500 struct chunk *smp_trash;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002501 struct connection *conn;
2502
2503 if (!l4)
2504 return 0;
Emeric Brun87855892012-10-17 17:39:35 +02002505
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002506 conn = objt_conn(l4->si[0].end);
2507 if (!conn || conn->xprt != &ssl_sock)
Emeric Brun87855892012-10-17 17:39:35 +02002508 return 0;
2509
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002510 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brun87855892012-10-17 17:39:35 +02002511 smp->flags |= SMP_F_MAY_CHANGE;
2512 return 0;
2513 }
2514
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002515 crt = SSL_get_certificate(conn->xprt_ctx);
Emeric Brun87855892012-10-17 17:39:35 +02002516 if (!crt)
2517 goto out;
2518
2519 name = X509_get_issuer_name(crt);
2520 if (!name)
2521 goto out;
2522
Willy Tarreau47ca5452012-12-23 20:22:19 +01002523 smp_trash = get_trash_chunk();
Emeric Brun87855892012-10-17 17:39:35 +02002524 if (args && args[0].type == ARGT_STR) {
2525 int pos = 1;
2526
2527 if (args[1].type == ARGT_SINT)
2528 pos = args[1].data.sint;
2529 else if (args[1].type == ARGT_UINT)
2530 pos =(int)args[1].data.uint;
2531
2532 if (ssl_sock_get_dn_entry(name, &args[0].data.str, pos, smp_trash) <= 0)
2533 goto out;
2534 }
2535 else if (ssl_sock_get_dn_oneline(name, smp_trash) <= 0)
2536 goto out;
2537
2538 smp->type = SMP_T_STR;
2539 smp->data.str = *smp_trash;
2540 ret = 1;
2541out:
2542 return ret;
2543}
2544
2545/* str, returns a string of a formatted full dn \C=..\O=..\OU=.. \CN=.. */
2546static int
2547smp_fetch_ssl_f_s_dn(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
Willy Tarreauef38c392013-07-22 16:29:32 +02002548 const struct arg *args, struct sample *smp, const char *kw)
Emeric Brun87855892012-10-17 17:39:35 +02002549{
2550 X509 *crt = NULL;
2551 X509_NAME *name;
2552 int ret = 0;
2553 struct chunk *smp_trash;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002554 struct connection *conn;
2555
2556 if (!l4)
2557 return 0;
Emeric Brun87855892012-10-17 17:39:35 +02002558
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002559 conn = objt_conn(l4->si[0].end);
2560 if (!conn || !conn->xprt_ctx || conn->xprt != &ssl_sock)
Emeric Brun87855892012-10-17 17:39:35 +02002561 return 0;
2562
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002563 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brun87855892012-10-17 17:39:35 +02002564 smp->flags |= SMP_F_MAY_CHANGE;
2565 return 0;
2566 }
2567
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002568 crt = SSL_get_certificate(conn->xprt_ctx);
Emeric Brun87855892012-10-17 17:39:35 +02002569 if (!crt)
2570 goto out;
2571
2572 name = X509_get_subject_name(crt);
2573 if (!name)
2574 goto out;
2575
Willy Tarreau47ca5452012-12-23 20:22:19 +01002576 smp_trash = get_trash_chunk();
Emeric Brun87855892012-10-17 17:39:35 +02002577 if (args && args[0].type == ARGT_STR) {
2578 int pos = 1;
2579
2580 if (args[1].type == ARGT_SINT)
2581 pos = args[1].data.sint;
2582 else if (args[1].type == ARGT_UINT)
2583 pos =(int)args[1].data.uint;
2584
2585 if (ssl_sock_get_dn_entry(name, &args[0].data.str, pos, smp_trash) <= 0)
2586 goto out;
2587 }
2588 else if (ssl_sock_get_dn_oneline(name, smp_trash) <= 0)
2589 goto out;
2590
2591 smp->type = SMP_T_STR;
2592 smp->data.str = *smp_trash;
2593 ret = 1;
2594out:
2595 return ret;
2596}
2597
Emeric Brun589fcad2012-10-16 14:13:26 +02002598static int
2599smp_fetch_ssl_fc_cipher(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
Willy Tarreauef38c392013-07-22 16:29:32 +02002600 const struct arg *args, struct sample *smp, const char *kw)
Emeric Brun589fcad2012-10-16 14:13:26 +02002601{
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002602 struct connection *conn;
2603
Emeric Brun589fcad2012-10-16 14:13:26 +02002604 smp->flags = 0;
2605
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002606 if (!l4)
2607 return 0;
2608
2609 conn = objt_conn(l4->si[0].end);
2610 if (!conn || !conn->xprt_ctx || conn->xprt != &ssl_sock)
Emeric Brun589fcad2012-10-16 14:13:26 +02002611 return 0;
2612
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002613 smp->data.str.str = (char *)SSL_get_cipher_name(conn->xprt_ctx);
Emeric Brun589fcad2012-10-16 14:13:26 +02002614 if (!smp->data.str.str)
2615 return 0;
2616
Thierry FOURNIER7654c9f2013-12-17 00:20:33 +01002617 smp->type = SMP_T_STR;
2618 smp->flags |= SMP_F_CONST;
Emeric Brun589fcad2012-10-16 14:13:26 +02002619 smp->data.str.len = strlen(smp->data.str.str);
2620
2621 return 1;
2622}
2623
2624static int
2625smp_fetch_ssl_fc_alg_keysize(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
Willy Tarreauef38c392013-07-22 16:29:32 +02002626 const struct arg *args, struct sample *smp, const char *kw)
Emeric Brun589fcad2012-10-16 14:13:26 +02002627{
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002628 struct connection *conn;
2629
Emeric Brun589fcad2012-10-16 14:13:26 +02002630 smp->flags = 0;
2631
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002632 if (!l4)
Emeric Brun589fcad2012-10-16 14:13:26 +02002633 return 0;
2634
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002635 conn = objt_conn(l4->si[0].end);
2636 if (!conn || !conn->xprt_ctx || conn->xprt != &ssl_sock)
Emeric Brun589fcad2012-10-16 14:13:26 +02002637 return 0;
2638
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002639 if (!SSL_get_cipher_bits(conn->xprt_ctx, (int *)&smp->data.uint))
2640 return 0;
2641
Emeric Brun589fcad2012-10-16 14:13:26 +02002642 smp->type = SMP_T_UINT;
2643
2644 return 1;
2645}
2646
2647static int
2648smp_fetch_ssl_fc_use_keysize(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
Willy Tarreauef38c392013-07-22 16:29:32 +02002649 const struct arg *args, struct sample *smp, const char *kw)
Emeric Brun589fcad2012-10-16 14:13:26 +02002650{
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002651 struct connection *conn;
2652
Emeric Brun589fcad2012-10-16 14:13:26 +02002653 smp->flags = 0;
2654
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002655 if (!l4)
Emeric Brun589fcad2012-10-16 14:13:26 +02002656 return 0;
2657
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002658 conn = objt_conn(l4->si[0].end);
2659 if (!conn || !conn->xprt_ctx || conn->xprt != &ssl_sock)
2660 return 0;
2661
2662 smp->data.uint = (unsigned int)SSL_get_cipher_bits(conn->xprt_ctx, NULL);
Emeric Brun589fcad2012-10-16 14:13:26 +02002663 if (!smp->data.uint)
2664 return 0;
2665
2666 smp->type = SMP_T_UINT;
2667
2668 return 1;
2669}
2670
Willy Tarreau6c9a3d52012-10-18 18:57:14 +02002671#ifdef OPENSSL_NPN_NEGOTIATED
Willy Tarreau7875d092012-09-10 08:20:03 +02002672static int
Emeric Brun2525b6b2012-10-18 15:59:43 +02002673smp_fetch_ssl_fc_npn(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
Willy Tarreauef38c392013-07-22 16:29:32 +02002674 const struct arg *args, struct sample *smp, const char *kw)
Willy Tarreaua33c6542012-10-15 13:19:06 +02002675{
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002676 struct connection *conn;
2677
Thierry FOURNIER7654c9f2013-12-17 00:20:33 +01002678 smp->flags = SMP_F_CONST;
2679 smp->type = SMP_T_STR;
Willy Tarreaua33c6542012-10-15 13:19:06 +02002680
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002681 if (!l4)
Willy Tarreaua33c6542012-10-15 13:19:06 +02002682 return 0;
2683
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002684 conn = objt_conn(l4->si[0].end);
2685 if (!conn || !conn->xprt_ctx || conn->xprt != &ssl_sock)
2686 return 0;
2687
Willy Tarreaua33c6542012-10-15 13:19:06 +02002688 smp->data.str.str = NULL;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002689 SSL_get0_next_proto_negotiated(conn->xprt_ctx,
Willy Tarreaua33c6542012-10-15 13:19:06 +02002690 (const unsigned char **)&smp->data.str.str, (unsigned *)&smp->data.str.len);
2691
2692 if (!smp->data.str.str)
2693 return 0;
2694
2695 return 1;
Willy Tarreaua33c6542012-10-15 13:19:06 +02002696}
Willy Tarreau6c9a3d52012-10-18 18:57:14 +02002697#endif
Willy Tarreaua33c6542012-10-15 13:19:06 +02002698
Dirkjan Bussink48f1c4e2014-02-13 12:29:42 +01002699#ifdef TLSEXT_TYPE_application_layer_protocol_negotiation
Willy Tarreauab861d32013-04-02 02:30:41 +02002700static int
2701smp_fetch_ssl_fc_alpn(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
Willy Tarreauef38c392013-07-22 16:29:32 +02002702 const struct arg *args, struct sample *smp, const char *kw)
Willy Tarreauab861d32013-04-02 02:30:41 +02002703{
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002704 struct connection *conn;
2705
Thierry FOURNIER7654c9f2013-12-17 00:20:33 +01002706 smp->flags = SMP_F_CONST;
2707 smp->type = SMP_T_STR;
Willy Tarreauab861d32013-04-02 02:30:41 +02002708
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002709 if (!l4)
2710 return 0;
2711
2712 conn = objt_conn(l4->si[0].end);
2713 if (!conn || !conn->xprt_ctx || conn->xprt != &ssl_sock)
Willy Tarreauab861d32013-04-02 02:30:41 +02002714 return 0;
2715
2716 smp->data.str.str = NULL;
Dirkjan Bussink48f1c4e2014-02-13 12:29:42 +01002717 SSL_get0_alpn_selected(conn->xprt_ctx,
Willy Tarreauab861d32013-04-02 02:30:41 +02002718 (const unsigned char **)&smp->data.str.str, (unsigned *)&smp->data.str.len);
2719
2720 if (!smp->data.str.str)
2721 return 0;
2722
2723 return 1;
2724}
2725#endif
2726
Willy Tarreaua33c6542012-10-15 13:19:06 +02002727static int
Emeric Brun589fcad2012-10-16 14:13:26 +02002728smp_fetch_ssl_fc_protocol(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
Willy Tarreauef38c392013-07-22 16:29:32 +02002729 const struct arg *args, struct sample *smp, const char *kw)
Emeric Brun589fcad2012-10-16 14:13:26 +02002730{
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002731 struct connection *conn;
2732
Emeric Brun589fcad2012-10-16 14:13:26 +02002733 smp->flags = 0;
2734
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002735 if (!l4)
Emeric Brun589fcad2012-10-16 14:13:26 +02002736 return 0;
2737
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002738 conn = objt_conn(l4->si[0].end);
2739 if (!conn || !conn->xprt_ctx || conn->xprt != &ssl_sock)
2740 return 0;
2741
2742 smp->data.str.str = (char *)SSL_get_version(conn->xprt_ctx);
Emeric Brun589fcad2012-10-16 14:13:26 +02002743 if (!smp->data.str.str)
2744 return 0;
2745
Thierry FOURNIER7654c9f2013-12-17 00:20:33 +01002746 smp->type = SMP_T_STR;
2747 smp->flags = SMP_F_CONST;
Emeric Brun589fcad2012-10-16 14:13:26 +02002748 smp->data.str.len = strlen(smp->data.str.str);
2749
2750 return 1;
2751}
2752
2753static int
Emeric Brunfe68f682012-10-16 14:59:28 +02002754smp_fetch_ssl_fc_session_id(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
Willy Tarreauef38c392013-07-22 16:29:32 +02002755 const struct arg *args, struct sample *smp, const char *kw)
Emeric Brunfe68f682012-10-16 14:59:28 +02002756{
2757#if OPENSSL_VERSION_NUMBER > 0x0090800fL
2758 SSL_SESSION *sess;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002759 struct connection *conn;
Emeric Brunfe68f682012-10-16 14:59:28 +02002760
Thierry FOURNIER7654c9f2013-12-17 00:20:33 +01002761 smp->flags = SMP_F_CONST;
2762 smp->type = SMP_T_BIN;
Emeric Brunfe68f682012-10-16 14:59:28 +02002763
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002764 if (!l4)
Emeric Brunfe68f682012-10-16 14:59:28 +02002765 return 0;
2766
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002767 conn = objt_conn(l4->si[0].end);
2768 if (!conn || !conn->xprt_ctx || conn->xprt != &ssl_sock)
2769 return 0;
2770
2771 sess = SSL_get_session(conn->xprt_ctx);
Emeric Brunfe68f682012-10-16 14:59:28 +02002772 if (!sess)
2773 return 0;
2774
2775 smp->data.str.str = (char *)SSL_SESSION_get_id(sess, (unsigned int *)&smp->data.str.len);
2776 if (!smp->data.str.str || !&smp->data.str.len)
2777 return 0;
2778
2779 return 1;
2780#else
2781 return 0;
2782#endif
2783}
2784
2785static int
Emeric Brun2525b6b2012-10-18 15:59:43 +02002786smp_fetch_ssl_fc_sni(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
Willy Tarreauef38c392013-07-22 16:29:32 +02002787 const struct arg *args, struct sample *smp, const char *kw)
Willy Tarreau7875d092012-09-10 08:20:03 +02002788{
2789#ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002790 struct connection *conn;
2791
Thierry FOURNIER7654c9f2013-12-17 00:20:33 +01002792 smp->flags = SMP_F_CONST;
2793 smp->type = SMP_T_STR;
Willy Tarreau7875d092012-09-10 08:20:03 +02002794
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002795 if (!l4)
Willy Tarreau7875d092012-09-10 08:20:03 +02002796 return 0;
2797
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002798 conn = objt_conn(l4->si[0].end);
2799 if (!conn || !conn->xprt_ctx || conn->xprt != &ssl_sock)
2800 return 0;
2801
2802 smp->data.str.str = (char *)SSL_get_servername(conn->xprt_ctx, TLSEXT_NAMETYPE_host_name);
Willy Tarreau3e394c92012-09-14 23:56:58 +02002803 if (!smp->data.str.str)
2804 return 0;
2805
Willy Tarreau7875d092012-09-10 08:20:03 +02002806 smp->data.str.len = strlen(smp->data.str.str);
2807 return 1;
2808#else
2809 return 0;
2810#endif
2811}
2812
Emeric Brun2525b6b2012-10-18 15:59:43 +02002813/* integer, returns the first verify error in CA chain of client certificate chain. */
Emeric Brunf282a812012-09-21 15:27:54 +02002814static int
Emeric Brun2525b6b2012-10-18 15:59:43 +02002815smp_fetch_ssl_c_ca_err(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
Willy Tarreauef38c392013-07-22 16:29:32 +02002816 const struct arg *args, struct sample *smp, const char *kw)
Emeric Brunf282a812012-09-21 15:27:54 +02002817{
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002818 struct connection *conn;
2819
2820 if (!l4)
Emeric Brunf282a812012-09-21 15:27:54 +02002821 return 0;
2822
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002823 conn = objt_conn(l4->si[0].end);
2824 if (!conn || conn->xprt != &ssl_sock)
2825 return 0;
2826
2827 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brunf282a812012-09-21 15:27:54 +02002828 smp->flags = SMP_F_MAY_CHANGE;
2829 return 0;
2830 }
2831
2832 smp->type = SMP_T_UINT;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002833 smp->data.uint = (unsigned int)SSL_SOCK_ST_TO_CA_ERROR(conn->xprt_st);
Emeric Brunf282a812012-09-21 15:27:54 +02002834 smp->flags = 0;
2835
2836 return 1;
2837}
2838
Emeric Brun2525b6b2012-10-18 15:59:43 +02002839/* integer, returns the depth of the first verify error in CA chain of client certificate chain. */
Emeric Brunf282a812012-09-21 15:27:54 +02002840static int
Emeric Brun2525b6b2012-10-18 15:59:43 +02002841smp_fetch_ssl_c_ca_err_depth(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
Willy Tarreauef38c392013-07-22 16:29:32 +02002842 const struct arg *args, struct sample *smp, const char *kw)
Emeric Brunf282a812012-09-21 15:27:54 +02002843{
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002844 struct connection *conn;
2845
2846 if (!l4)
2847 return 0;
2848
2849 conn = objt_conn(l4->si[0].end);
2850 if (!conn || conn->xprt != &ssl_sock)
Emeric Brunf282a812012-09-21 15:27:54 +02002851 return 0;
2852
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002853 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brunf282a812012-09-21 15:27:54 +02002854 smp->flags = SMP_F_MAY_CHANGE;
2855 return 0;
2856 }
2857
2858 smp->type = SMP_T_UINT;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002859 smp->data.uint = (unsigned int)SSL_SOCK_ST_TO_CAEDEPTH(conn->xprt_st);
Emeric Brunf282a812012-09-21 15:27:54 +02002860 smp->flags = 0;
2861
2862 return 1;
2863}
2864
Emeric Brun2525b6b2012-10-18 15:59:43 +02002865/* integer, returns the first verify error on client certificate */
Emeric Brunf282a812012-09-21 15:27:54 +02002866static int
Emeric Brun2525b6b2012-10-18 15:59:43 +02002867smp_fetch_ssl_c_err(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
Willy Tarreauef38c392013-07-22 16:29:32 +02002868 const struct arg *args, struct sample *smp, const char *kw)
Emeric Brunf282a812012-09-21 15:27:54 +02002869{
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002870 struct connection *conn;
2871
2872 if (!l4)
Emeric Brunf282a812012-09-21 15:27:54 +02002873 return 0;
2874
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002875 conn = objt_conn(l4->si[0].end);
2876 if (!conn || conn->xprt != &ssl_sock)
2877 return 0;
2878
2879 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brunf282a812012-09-21 15:27:54 +02002880 smp->flags = SMP_F_MAY_CHANGE;
2881 return 0;
2882 }
2883
2884 smp->type = SMP_T_UINT;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002885 smp->data.uint = (unsigned int)SSL_SOCK_ST_TO_CRTERROR(conn->xprt_st);
Emeric Brunf282a812012-09-21 15:27:54 +02002886 smp->flags = 0;
2887
2888 return 1;
2889}
2890
Emeric Brun2525b6b2012-10-18 15:59:43 +02002891/* integer, returns the verify result on client cert */
Emeric Brunbaf8ffb2012-09-21 15:27:20 +02002892static int
Emeric Brun2525b6b2012-10-18 15:59:43 +02002893smp_fetch_ssl_c_verify(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
Willy Tarreauef38c392013-07-22 16:29:32 +02002894 const struct arg *args, struct sample *smp, const char *kw)
Emeric Brunbaf8ffb2012-09-21 15:27:20 +02002895{
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002896 struct connection *conn;
2897
2898 if (!l4)
Emeric Brunbaf8ffb2012-09-21 15:27:20 +02002899 return 0;
2900
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002901 conn = objt_conn(l4->si[0].end);
2902 if (!conn || conn->xprt != &ssl_sock)
2903 return 0;
2904
2905 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brunbaf8ffb2012-09-21 15:27:20 +02002906 smp->flags = SMP_F_MAY_CHANGE;
2907 return 0;
2908 }
2909
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002910 if (!conn->xprt_ctx)
Emeric Brunbaf8ffb2012-09-21 15:27:20 +02002911 return 0;
2912
2913 smp->type = SMP_T_UINT;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002914 smp->data.uint = (unsigned int)SSL_get_verify_result(conn->xprt_ctx);
Emeric Brunbaf8ffb2012-09-21 15:27:20 +02002915 smp->flags = 0;
2916
2917 return 1;
2918}
2919
Emeric Brunfb510ea2012-10-05 12:00:26 +02002920/* parse the "ca-file" bind keyword */
2921static 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 +02002922{
2923 if (!*args[cur_arg + 1]) {
2924 if (err)
2925 memprintf(err, "'%s' : missing CAfile path", args[cur_arg]);
2926 return ERR_ALERT | ERR_FATAL;
2927 }
2928
Emeric Brunef42d922012-10-11 16:11:36 +02002929 if ((*args[cur_arg + 1] != '/') && global.ca_base)
2930 memprintf(&conf->ca_file, "%s/%s", global.ca_base, args[cur_arg + 1]);
2931 else
2932 memprintf(&conf->ca_file, "%s", args[cur_arg + 1]);
Emeric Brunc8e8d122012-10-02 18:42:10 +02002933
Emeric Brund94b3fe2012-09-20 18:23:56 +02002934 return 0;
2935}
2936
Willy Tarreau79eeafa2012-09-14 07:53:05 +02002937/* parse the "ciphers" bind keyword */
Willy Tarreau4348fad2012-09-20 16:48:07 +02002938static 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 +02002939{
2940 if (!*args[cur_arg + 1]) {
Willy Tarreaueb6cead2012-09-20 19:43:14 +02002941 memprintf(err, "'%s' : missing cipher suite", args[cur_arg]);
Willy Tarreau79eeafa2012-09-14 07:53:05 +02002942 return ERR_ALERT | ERR_FATAL;
2943 }
2944
Emeric Brun76d88952012-10-05 15:47:31 +02002945 free(conf->ciphers);
Willy Tarreau4348fad2012-09-20 16:48:07 +02002946 conf->ciphers = strdup(args[cur_arg + 1]);
Willy Tarreau79eeafa2012-09-14 07:53:05 +02002947 return 0;
2948}
2949
2950/* parse the "crt" bind keyword */
Willy Tarreau4348fad2012-09-20 16:48:07 +02002951static 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 +02002952{
Willy Tarreau38011032013-08-13 16:59:39 +02002953 char path[MAXPATHLEN];
Willy Tarreau79eeafa2012-09-14 07:53:05 +02002954 if (!*args[cur_arg + 1]) {
Willy Tarreaueb6cead2012-09-20 19:43:14 +02002955 memprintf(err, "'%s' : missing certificate location", args[cur_arg]);
Willy Tarreau79eeafa2012-09-14 07:53:05 +02002956 return ERR_ALERT | ERR_FATAL;
2957 }
2958
Emeric Brunc8e8d122012-10-02 18:42:10 +02002959 if ((*args[cur_arg + 1] != '/' ) && global.crt_base) {
Willy Tarreau38011032013-08-13 16:59:39 +02002960 if ((strlen(global.crt_base) + 1 + strlen(args[cur_arg + 1]) + 1) > MAXPATHLEN) {
Emeric Brunc8e8d122012-10-02 18:42:10 +02002961 memprintf(err, "'%s' : path too long", args[cur_arg]);
2962 return ERR_ALERT | ERR_FATAL;
2963 }
2964 sprintf(path, "%s/%s", global.crt_base, args[cur_arg + 1]);
2965 if (ssl_sock_load_cert(path, conf, px, err) > 0)
2966 return ERR_ALERT | ERR_FATAL;
2967
2968 return 0;
2969 }
2970
Willy Tarreau4348fad2012-09-20 16:48:07 +02002971 if (ssl_sock_load_cert(args[cur_arg + 1], conf, px, err) > 0)
Willy Tarreau79eeafa2012-09-14 07:53:05 +02002972 return ERR_ALERT | ERR_FATAL;
Emeric Brund94b3fe2012-09-20 18:23:56 +02002973
2974 return 0;
2975}
2976
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01002977/* parse the "crt-list" bind keyword */
2978static int bind_parse_crt_list(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
2979{
2980 if (!*args[cur_arg + 1]) {
2981 memprintf(err, "'%s' : missing certificate location", args[cur_arg]);
2982 return ERR_ALERT | ERR_FATAL;
2983 }
2984
Willy Tarreauad1731d2013-04-02 17:35:58 +02002985 if (ssl_sock_load_cert_list_file(args[cur_arg + 1], conf, px, err) > 0) {
2986 memprintf(err, "'%s' : %s", args[cur_arg], *err);
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01002987 return ERR_ALERT | ERR_FATAL;
Willy Tarreauad1731d2013-04-02 17:35:58 +02002988 }
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01002989
2990 return 0;
2991}
2992
Emeric Brunfb510ea2012-10-05 12:00:26 +02002993/* parse the "crl-file" bind keyword */
2994static 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 +02002995{
Emeric Brun051cdab2012-10-02 19:25:50 +02002996#ifndef X509_V_FLAG_CRL_CHECK
2997 if (err)
2998 memprintf(err, "'%s' : library does not support CRL verify", args[cur_arg]);
2999 return ERR_ALERT | ERR_FATAL;
3000#else
Emeric Brund94b3fe2012-09-20 18:23:56 +02003001 if (!*args[cur_arg + 1]) {
3002 if (err)
3003 memprintf(err, "'%s' : missing CRLfile path", args[cur_arg]);
3004 return ERR_ALERT | ERR_FATAL;
3005 }
Emeric Brun2b58d042012-09-20 17:10:03 +02003006
Emeric Brunef42d922012-10-11 16:11:36 +02003007 if ((*args[cur_arg + 1] != '/') && global.ca_base)
3008 memprintf(&conf->crl_file, "%s/%s", global.ca_base, args[cur_arg + 1]);
3009 else
3010 memprintf(&conf->crl_file, "%s", args[cur_arg + 1]);
Emeric Brunc8e8d122012-10-02 18:42:10 +02003011
Emeric Brun2b58d042012-09-20 17:10:03 +02003012 return 0;
Emeric Brun051cdab2012-10-02 19:25:50 +02003013#endif
Emeric Brun2b58d042012-09-20 17:10:03 +02003014}
3015
3016/* parse the "ecdhe" bind keyword keywords */
3017static int bind_parse_ecdhe(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
3018{
3019#if OPENSSL_VERSION_NUMBER < 0x0090800fL
3020 if (err)
3021 memprintf(err, "'%s' : library does not support elliptic curve Diffie-Hellman (too old)", args[cur_arg]);
3022 return ERR_ALERT | ERR_FATAL;
3023#elif defined(OPENSSL_NO_ECDH)
3024 if (err)
3025 memprintf(err, "'%s' : library does not support elliptic curve Diffie-Hellman (disabled via OPENSSL_NO_ECDH)", args[cur_arg]);
3026 return ERR_ALERT | ERR_FATAL;
3027#else
3028 if (!*args[cur_arg + 1]) {
3029 if (err)
3030 memprintf(err, "'%s' : missing named curve", args[cur_arg]);
3031 return ERR_ALERT | ERR_FATAL;
3032 }
3033
3034 conf->ecdhe = strdup(args[cur_arg + 1]);
Willy Tarreau79eeafa2012-09-14 07:53:05 +02003035
3036 return 0;
Emeric Brun2b58d042012-09-20 17:10:03 +02003037#endif
Willy Tarreau79eeafa2012-09-14 07:53:05 +02003038}
3039
Emeric Brun81c00f02012-09-21 14:31:21 +02003040/* parse the "crt_ignerr" and "ca_ignerr" bind keywords */
3041static int bind_parse_ignore_err(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
3042{
3043 int code;
3044 char *p = args[cur_arg + 1];
3045 unsigned long long *ignerr = &conf->crt_ignerr;
3046
3047 if (!*p) {
3048 if (err)
3049 memprintf(err, "'%s' : missing error IDs list", args[cur_arg]);
3050 return ERR_ALERT | ERR_FATAL;
3051 }
3052
3053 if (strcmp(args[cur_arg], "ca-ignore-err") == 0)
3054 ignerr = &conf->ca_ignerr;
3055
3056 if (strcmp(p, "all") == 0) {
3057 *ignerr = ~0ULL;
3058 return 0;
3059 }
3060
3061 while (p) {
3062 code = atoi(p);
3063 if ((code <= 0) || (code > 63)) {
3064 if (err)
3065 memprintf(err, "'%s' : ID '%d' out of range (1..63) in error IDs list '%s'",
3066 args[cur_arg], code, args[cur_arg + 1]);
3067 return ERR_ALERT | ERR_FATAL;
3068 }
3069 *ignerr |= 1ULL << code;
3070 p = strchr(p, ',');
3071 if (p)
3072 p++;
3073 }
3074
Emeric Brun2cb7ae52012-10-05 14:14:21 +02003075 return 0;
3076}
3077
3078/* parse the "force-sslv3" bind keyword */
3079static int bind_parse_force_sslv3(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
3080{
3081 conf->ssl_options |= BC_SSL_O_USE_SSLV3;
3082 return 0;
3083}
3084
3085/* parse the "force-tlsv10" bind keyword */
3086static int bind_parse_force_tlsv10(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
3087{
3088 conf->ssl_options |= BC_SSL_O_USE_TLSV10;
Emeric Brun2d0c4822012-10-02 13:45:20 +02003089 return 0;
3090}
3091
Emeric Brun2cb7ae52012-10-05 14:14:21 +02003092/* parse the "force-tlsv11" bind keyword */
3093static int bind_parse_force_tlsv11(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
3094{
3095#if SSL_OP_NO_TLSv1_1
3096 conf->ssl_options |= BC_SSL_O_USE_TLSV11;
3097 return 0;
3098#else
3099 if (err)
3100 memprintf(err, "'%s' : library does not support protocol TLSv1.1", args[cur_arg]);
3101 return ERR_ALERT | ERR_FATAL;
3102#endif
3103}
3104
3105/* parse the "force-tlsv12" bind keyword */
3106static int bind_parse_force_tlsv12(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
3107{
3108#if SSL_OP_NO_TLSv1_2
3109 conf->ssl_options |= BC_SSL_O_USE_TLSV12;
3110 return 0;
3111#else
3112 if (err)
3113 memprintf(err, "'%s' : library does not support protocol TLSv1.2", args[cur_arg]);
3114 return ERR_ALERT | ERR_FATAL;
3115#endif
3116}
3117
3118
Emeric Brun2d0c4822012-10-02 13:45:20 +02003119/* parse the "no-tls-tickets" bind keyword */
3120static int bind_parse_no_tls_tickets(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
3121{
Emeric Brun89675492012-10-05 13:48:26 +02003122 conf->ssl_options |= BC_SSL_O_NO_TLS_TICKETS;
Emeric Brun81c00f02012-09-21 14:31:21 +02003123 return 0;
3124}
3125
Emeric Brun2d0c4822012-10-02 13:45:20 +02003126
Emeric Brun9b3009b2012-10-05 11:55:06 +02003127/* parse the "no-sslv3" bind keyword */
3128static 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 +02003129{
Emeric Brun89675492012-10-05 13:48:26 +02003130 conf->ssl_options |= BC_SSL_O_NO_SSLV3;
Willy Tarreau79eeafa2012-09-14 07:53:05 +02003131 return 0;
3132}
3133
Emeric Brun9b3009b2012-10-05 11:55:06 +02003134/* parse the "no-tlsv10" bind keyword */
3135static 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 +02003136{
Emeric Brun89675492012-10-05 13:48:26 +02003137 conf->ssl_options |= BC_SSL_O_NO_TLSV10;
Emeric Brunc0ff4922012-09-28 19:37:02 +02003138 return 0;
3139}
3140
Emeric Brun9b3009b2012-10-05 11:55:06 +02003141/* parse the "no-tlsv11" bind keyword */
3142static 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 +02003143{
Emeric Brun89675492012-10-05 13:48:26 +02003144 conf->ssl_options |= BC_SSL_O_NO_TLSV11;
Emeric Brunc0ff4922012-09-28 19:37:02 +02003145 return 0;
3146}
3147
Emeric Brun9b3009b2012-10-05 11:55:06 +02003148/* parse the "no-tlsv12" bind keyword */
3149static 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 +02003150{
Emeric Brun89675492012-10-05 13:48:26 +02003151 conf->ssl_options |= BC_SSL_O_NO_TLSV12;
Willy Tarreau79eeafa2012-09-14 07:53:05 +02003152 return 0;
3153}
3154
Willy Tarreau6c9a3d52012-10-18 18:57:14 +02003155/* parse the "npn" bind keyword */
3156static int bind_parse_npn(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
3157{
3158#ifdef OPENSSL_NPN_NEGOTIATED
3159 char *p1, *p2;
3160
3161 if (!*args[cur_arg + 1]) {
3162 memprintf(err, "'%s' : missing the comma-delimited NPN protocol suite", args[cur_arg]);
3163 return ERR_ALERT | ERR_FATAL;
3164 }
3165
3166 free(conf->npn_str);
3167
3168 /* the NPN string is built as a suite of (<len> <name>)* */
3169 conf->npn_len = strlen(args[cur_arg + 1]) + 1;
3170 conf->npn_str = calloc(1, conf->npn_len);
3171 memcpy(conf->npn_str + 1, args[cur_arg + 1], conf->npn_len);
3172
3173 /* replace commas with the name length */
3174 p1 = conf->npn_str;
3175 p2 = p1 + 1;
3176 while (1) {
3177 p2 = memchr(p1 + 1, ',', conf->npn_str + conf->npn_len - (p1 + 1));
3178 if (!p2)
3179 p2 = p1 + 1 + strlen(p1 + 1);
3180
3181 if (p2 - (p1 + 1) > 255) {
3182 *p2 = '\0';
3183 memprintf(err, "'%s' : NPN protocol name too long : '%s'", args[cur_arg], p1 + 1);
3184 return ERR_ALERT | ERR_FATAL;
3185 }
3186
3187 *p1 = p2 - (p1 + 1);
3188 p1 = p2;
3189
3190 if (!*p2)
3191 break;
3192
3193 *(p2++) = '\0';
3194 }
3195 return 0;
3196#else
3197 if (err)
3198 memprintf(err, "'%s' : library does not support TLS NPN extension", args[cur_arg]);
3199 return ERR_ALERT | ERR_FATAL;
3200#endif
3201}
3202
Willy Tarreauab861d32013-04-02 02:30:41 +02003203/* parse the "alpn" bind keyword */
3204static int bind_parse_alpn(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
3205{
Dirkjan Bussink48f1c4e2014-02-13 12:29:42 +01003206#ifdef TLSEXT_TYPE_application_layer_protocol_negotiation
Willy Tarreauab861d32013-04-02 02:30:41 +02003207 char *p1, *p2;
3208
3209 if (!*args[cur_arg + 1]) {
3210 memprintf(err, "'%s' : missing the comma-delimited ALPN protocol suite", args[cur_arg]);
3211 return ERR_ALERT | ERR_FATAL;
3212 }
3213
3214 free(conf->alpn_str);
3215
3216 /* the ALPN string is built as a suite of (<len> <name>)* */
3217 conf->alpn_len = strlen(args[cur_arg + 1]) + 1;
3218 conf->alpn_str = calloc(1, conf->alpn_len);
3219 memcpy(conf->alpn_str + 1, args[cur_arg + 1], conf->alpn_len);
3220
3221 /* replace commas with the name length */
3222 p1 = conf->alpn_str;
3223 p2 = p1 + 1;
3224 while (1) {
3225 p2 = memchr(p1 + 1, ',', conf->alpn_str + conf->alpn_len - (p1 + 1));
3226 if (!p2)
3227 p2 = p1 + 1 + strlen(p1 + 1);
3228
3229 if (p2 - (p1 + 1) > 255) {
3230 *p2 = '\0';
3231 memprintf(err, "'%s' : ALPN protocol name too long : '%s'", args[cur_arg], p1 + 1);
3232 return ERR_ALERT | ERR_FATAL;
3233 }
3234
3235 *p1 = p2 - (p1 + 1);
3236 p1 = p2;
3237
3238 if (!*p2)
3239 break;
3240
3241 *(p2++) = '\0';
3242 }
3243 return 0;
3244#else
3245 if (err)
3246 memprintf(err, "'%s' : library does not support TLS ALPN extension", args[cur_arg]);
3247 return ERR_ALERT | ERR_FATAL;
3248#endif
3249}
3250
Willy Tarreau79eeafa2012-09-14 07:53:05 +02003251/* parse the "ssl" bind keyword */
Willy Tarreau4348fad2012-09-20 16:48:07 +02003252static 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 +02003253{
Willy Tarreau81796be2012-09-22 19:11:47 +02003254 struct listener *l;
3255
Willy Tarreau4348fad2012-09-20 16:48:07 +02003256 conf->is_ssl = 1;
Emeric Brun76d88952012-10-05 15:47:31 +02003257
3258 if (global.listen_default_ciphers && !conf->ciphers)
3259 conf->ciphers = strdup(global.listen_default_ciphers);
3260
Willy Tarreau81796be2012-09-22 19:11:47 +02003261 list_for_each_entry(l, &conf->listeners, by_bind)
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02003262 l->xprt = &ssl_sock;
Willy Tarreau81796be2012-09-22 19:11:47 +02003263
Willy Tarreau79eeafa2012-09-14 07:53:05 +02003264 return 0;
3265}
3266
Emmanuel Hocdet65623372013-01-24 17:17:15 +01003267/* parse the "strict-sni" bind keyword */
3268static int bind_parse_strict_sni(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
3269{
3270 conf->strict_sni = 1;
3271 return 0;
3272}
3273
Emeric Brund94b3fe2012-09-20 18:23:56 +02003274/* parse the "verify" bind keyword */
3275static int bind_parse_verify(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
3276{
3277 if (!*args[cur_arg + 1]) {
3278 if (err)
3279 memprintf(err, "'%s' : missing verify method", args[cur_arg]);
3280 return ERR_ALERT | ERR_FATAL;
3281 }
3282
3283 if (strcmp(args[cur_arg + 1], "none") == 0)
Emeric Brun850efd52014-01-29 12:24:34 +01003284 conf->verify = SSL_SOCK_VERIFY_NONE;
Emeric Brund94b3fe2012-09-20 18:23:56 +02003285 else if (strcmp(args[cur_arg + 1], "optional") == 0)
Emeric Brun850efd52014-01-29 12:24:34 +01003286 conf->verify = SSL_SOCK_VERIFY_OPTIONAL;
Emeric Brund94b3fe2012-09-20 18:23:56 +02003287 else if (strcmp(args[cur_arg + 1], "required") == 0)
Emeric Brun850efd52014-01-29 12:24:34 +01003288 conf->verify = SSL_SOCK_VERIFY_REQUIRED;
Emeric Brund94b3fe2012-09-20 18:23:56 +02003289 else {
3290 if (err)
3291 memprintf(err, "'%s' : unknown verify method '%s', only 'none', 'optional', and 'required' are supported\n",
3292 args[cur_arg], args[cur_arg + 1]);
3293 return ERR_ALERT | ERR_FATAL;
3294 }
3295
3296 return 0;
3297}
3298
Willy Tarreau92faadf2012-10-10 23:04:25 +02003299/************** "server" keywords ****************/
3300
Emeric Brunef42d922012-10-11 16:11:36 +02003301/* parse the "ca-file" server keyword */
3302static int srv_parse_ca_file(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
3303{
3304 if (!*args[*cur_arg + 1]) {
3305 if (err)
3306 memprintf(err, "'%s' : missing CAfile path", args[*cur_arg]);
3307 return ERR_ALERT | ERR_FATAL;
3308 }
3309
3310 if ((*args[*cur_arg + 1] != '/') && global.ca_base)
3311 memprintf(&newsrv->ssl_ctx.ca_file, "%s/%s", global.ca_base, args[*cur_arg + 1]);
3312 else
3313 memprintf(&newsrv->ssl_ctx.ca_file, "%s", args[*cur_arg + 1]);
3314
3315 return 0;
3316}
3317
Willy Tarreau92faadf2012-10-10 23:04:25 +02003318/* parse the "check-ssl" server keyword */
3319static int srv_parse_check_ssl(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
3320{
3321 newsrv->check.use_ssl = 1;
3322 if (global.connect_default_ciphers && !newsrv->ssl_ctx.ciphers)
3323 newsrv->ssl_ctx.ciphers = strdup(global.connect_default_ciphers);
3324 return 0;
3325}
3326
3327/* parse the "ciphers" server keyword */
3328static int srv_parse_ciphers(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
3329{
3330 if (!*args[*cur_arg + 1]) {
3331 memprintf(err, "'%s' : missing cipher suite", args[*cur_arg]);
3332 return ERR_ALERT | ERR_FATAL;
3333 }
3334
3335 free(newsrv->ssl_ctx.ciphers);
3336 newsrv->ssl_ctx.ciphers = strdup(args[*cur_arg + 1]);
3337 return 0;
3338}
3339
Emeric Brunef42d922012-10-11 16:11:36 +02003340/* parse the "crl-file" server keyword */
3341static int srv_parse_crl_file(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
3342{
3343#ifndef X509_V_FLAG_CRL_CHECK
3344 if (err)
3345 memprintf(err, "'%s' : library does not support CRL verify", args[*cur_arg]);
3346 return ERR_ALERT | ERR_FATAL;
3347#else
3348 if (!*args[*cur_arg + 1]) {
3349 if (err)
3350 memprintf(err, "'%s' : missing CRLfile path", args[*cur_arg]);
3351 return ERR_ALERT | ERR_FATAL;
3352 }
3353
3354 if ((*args[*cur_arg + 1] != '/') && global.ca_base)
3355 memprintf(&newsrv->ssl_ctx.crl_file, "%s/%s", global.ca_base, args[*cur_arg + 1]);
3356 else
3357 memprintf(&newsrv->ssl_ctx.crl_file, "%s", args[*cur_arg + 1]);
3358
3359 return 0;
3360#endif
3361}
3362
Emeric Bruna7aa3092012-10-26 12:58:00 +02003363/* parse the "crt" server keyword */
3364static int srv_parse_crt(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
3365{
3366 if (!*args[*cur_arg + 1]) {
3367 if (err)
3368 memprintf(err, "'%s' : missing certificate file path", args[*cur_arg]);
3369 return ERR_ALERT | ERR_FATAL;
3370 }
3371
3372 if ((*args[*cur_arg + 1] != '/') && global.crt_base)
3373 memprintf(&newsrv->ssl_ctx.client_crt, "%s/%s", global.ca_base, args[*cur_arg + 1]);
3374 else
3375 memprintf(&newsrv->ssl_ctx.client_crt, "%s", args[*cur_arg + 1]);
3376
3377 return 0;
3378}
Emeric Brunef42d922012-10-11 16:11:36 +02003379
Willy Tarreau92faadf2012-10-10 23:04:25 +02003380/* parse the "force-sslv3" server keyword */
3381static int srv_parse_force_sslv3(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
3382{
3383 newsrv->ssl_ctx.options |= SRV_SSL_O_USE_SSLV3;
3384 return 0;
3385}
3386
3387/* parse the "force-tlsv10" server keyword */
3388static int srv_parse_force_tlsv10(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
3389{
3390 newsrv->ssl_ctx.options |= SRV_SSL_O_USE_TLSV10;
3391 return 0;
3392}
3393
3394/* parse the "force-tlsv11" server keyword */
3395static int srv_parse_force_tlsv11(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
3396{
3397#if SSL_OP_NO_TLSv1_1
3398 newsrv->ssl_ctx.options |= SRV_SSL_O_USE_TLSV11;
3399 return 0;
3400#else
3401 if (err)
3402 memprintf(err, "'%s' : library does not support protocol TLSv1.1", args[*cur_arg]);
3403 return ERR_ALERT | ERR_FATAL;
3404#endif
3405}
3406
3407/* parse the "force-tlsv12" server keyword */
3408static int srv_parse_force_tlsv12(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
3409{
3410#if SSL_OP_NO_TLSv1_2
3411 newsrv->ssl_ctx.options |= SRV_SSL_O_USE_TLSV12;
3412 return 0;
3413#else
3414 if (err)
3415 memprintf(err, "'%s' : library does not support protocol TLSv1.2", args[*cur_arg]);
3416 return ERR_ALERT | ERR_FATAL;
3417#endif
3418}
3419
3420/* parse the "no-sslv3" server keyword */
3421static int srv_parse_no_sslv3(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
3422{
3423 newsrv->ssl_ctx.options |= SRV_SSL_O_NO_SSLV3;
3424 return 0;
3425}
3426
3427/* parse the "no-tlsv10" server keyword */
3428static int srv_parse_no_tlsv10(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
3429{
3430 newsrv->ssl_ctx.options |= SRV_SSL_O_NO_TLSV10;
3431 return 0;
3432}
3433
3434/* parse the "no-tlsv11" server keyword */
3435static int srv_parse_no_tlsv11(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
3436{
3437 newsrv->ssl_ctx.options |= SRV_SSL_O_NO_TLSV11;
3438 return 0;
3439}
3440
3441/* parse the "no-tlsv12" server keyword */
3442static int srv_parse_no_tlsv12(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
3443{
3444 newsrv->ssl_ctx.options |= SRV_SSL_O_NO_TLSV12;
3445 return 0;
3446}
3447
Emeric Brunf9c5c472012-10-11 15:28:34 +02003448/* parse the "no-tls-tickets" server keyword */
3449static int srv_parse_no_tls_tickets(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
3450{
3451 newsrv->ssl_ctx.options |= SRV_SSL_O_NO_TLS_TICKETS;
3452 return 0;
3453}
3454
Willy Tarreau92faadf2012-10-10 23:04:25 +02003455/* parse the "ssl" server keyword */
3456static int srv_parse_ssl(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
3457{
3458 newsrv->use_ssl = 1;
3459 if (global.connect_default_ciphers && !newsrv->ssl_ctx.ciphers)
3460 newsrv->ssl_ctx.ciphers = strdup(global.connect_default_ciphers);
3461 return 0;
3462}
3463
Emeric Brunef42d922012-10-11 16:11:36 +02003464/* parse the "verify" server keyword */
3465static int srv_parse_verify(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
3466{
3467 if (!*args[*cur_arg + 1]) {
3468 if (err)
3469 memprintf(err, "'%s' : missing verify method", args[*cur_arg]);
3470 return ERR_ALERT | ERR_FATAL;
3471 }
3472
3473 if (strcmp(args[*cur_arg + 1], "none") == 0)
Emeric Brun850efd52014-01-29 12:24:34 +01003474 newsrv->ssl_ctx.verify = SSL_SOCK_VERIFY_NONE;
Emeric Brunef42d922012-10-11 16:11:36 +02003475 else if (strcmp(args[*cur_arg + 1], "required") == 0)
Emeric Brun850efd52014-01-29 12:24:34 +01003476 newsrv->ssl_ctx.verify = SSL_SOCK_VERIFY_REQUIRED;
Emeric Brunef42d922012-10-11 16:11:36 +02003477 else {
3478 if (err)
3479 memprintf(err, "'%s' : unknown verify method '%s', only 'none' and 'required' are supported\n",
3480 args[*cur_arg], args[*cur_arg + 1]);
3481 return ERR_ALERT | ERR_FATAL;
3482 }
3483
Evan Broderbe554312013-06-27 00:05:25 -07003484 return 0;
3485}
3486
3487/* parse the "verifyhost" server keyword */
3488static int srv_parse_verifyhost(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
3489{
3490 if (!*args[*cur_arg + 1]) {
3491 if (err)
3492 memprintf(err, "'%s' : missing hostname to verify against", args[*cur_arg]);
3493 return ERR_ALERT | ERR_FATAL;
3494 }
3495
3496 newsrv->ssl_ctx.verify_host = strdup(args[*cur_arg + 1]);
3497
Emeric Brunef42d922012-10-11 16:11:36 +02003498 return 0;
3499}
3500
Willy Tarreau7875d092012-09-10 08:20:03 +02003501/* Note: must not be declared <const> as its list will be overwritten.
3502 * Please take care of keeping this list alphabetically sorted.
3503 */
Willy Tarreaudc13c112013-06-21 23:16:39 +02003504static struct sample_fetch_kw_list sample_fetch_keywords = {ILH, {
Willy Tarreau80aca902013-01-07 15:42:20 +01003505 { "ssl_c_ca_err", smp_fetch_ssl_c_ca_err, 0, NULL, SMP_T_UINT, SMP_USE_L5CLI },
3506 { "ssl_c_ca_err_depth", smp_fetch_ssl_c_ca_err_depth, 0, NULL, SMP_T_UINT, SMP_USE_L5CLI },
3507 { "ssl_c_err", smp_fetch_ssl_c_err, 0, NULL, SMP_T_UINT, SMP_USE_L5CLI },
3508 { "ssl_c_i_dn", smp_fetch_ssl_c_i_dn, ARG2(0,STR,SINT), NULL, SMP_T_STR, SMP_USE_L5CLI },
3509 { "ssl_c_key_alg", smp_fetch_ssl_c_key_alg, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
3510 { "ssl_c_notafter", smp_fetch_ssl_c_notafter, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
3511 { "ssl_c_notbefore", smp_fetch_ssl_c_notbefore, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
3512 { "ssl_c_sig_alg", smp_fetch_ssl_c_sig_alg, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
3513 { "ssl_c_s_dn", smp_fetch_ssl_c_s_dn, ARG2(0,STR,SINT), NULL, SMP_T_STR, SMP_USE_L5CLI },
3514 { "ssl_c_serial", smp_fetch_ssl_c_serial, 0, NULL, SMP_T_BIN, SMP_USE_L5CLI },
James Votha051b4a2013-05-14 20:37:59 +02003515 { "ssl_c_sha1", smp_fetch_ssl_c_sha1, 0, NULL, SMP_T_BIN, SMP_USE_L5CLI },
Willy Tarreau80aca902013-01-07 15:42:20 +01003516 { "ssl_c_used", smp_fetch_ssl_c_used, 0, NULL, SMP_T_BOOL, SMP_USE_L5CLI },
3517 { "ssl_c_verify", smp_fetch_ssl_c_verify, 0, NULL, SMP_T_UINT, SMP_USE_L5CLI },
3518 { "ssl_c_version", smp_fetch_ssl_c_version, 0, NULL, SMP_T_UINT, SMP_USE_L5CLI },
3519 { "ssl_f_i_dn", smp_fetch_ssl_f_i_dn, ARG2(0,STR,SINT), NULL, SMP_T_STR, SMP_USE_L5CLI },
3520 { "ssl_f_key_alg", smp_fetch_ssl_f_key_alg, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
3521 { "ssl_f_notafter", smp_fetch_ssl_f_notafter, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
3522 { "ssl_f_notbefore", smp_fetch_ssl_f_notbefore, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
3523 { "ssl_f_sig_alg", smp_fetch_ssl_f_sig_alg, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
3524 { "ssl_f_s_dn", smp_fetch_ssl_f_s_dn, ARG2(0,STR,SINT), NULL, SMP_T_STR, SMP_USE_L5CLI },
3525 { "ssl_f_serial", smp_fetch_ssl_f_serial, 0, NULL, SMP_T_BIN, SMP_USE_L5CLI },
3526 { "ssl_f_version", smp_fetch_ssl_f_version, 0, NULL, SMP_T_UINT, SMP_USE_L5CLI },
3527 { "ssl_fc", smp_fetch_ssl_fc, 0, NULL, SMP_T_BOOL, SMP_USE_L5CLI },
3528 { "ssl_fc_alg_keysize", smp_fetch_ssl_fc_alg_keysize, 0, NULL, SMP_T_UINT, SMP_USE_L5CLI },
Thierry FOURNIER7654c9f2013-12-17 00:20:33 +01003529 { "ssl_fc_cipher", smp_fetch_ssl_fc_cipher, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
Willy Tarreau80aca902013-01-07 15:42:20 +01003530 { "ssl_fc_has_crt", smp_fetch_ssl_fc_has_crt, 0, NULL, SMP_T_BOOL, SMP_USE_L5CLI },
3531 { "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 +02003532#ifdef OPENSSL_NPN_NEGOTIATED
Thierry FOURNIER7654c9f2013-12-17 00:20:33 +01003533 { "ssl_fc_npn", smp_fetch_ssl_fc_npn, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
Willy Tarreaua33c6542012-10-15 13:19:06 +02003534#endif
Dirkjan Bussink48f1c4e2014-02-13 12:29:42 +01003535#ifdef TLSEXT_TYPE_application_layer_protocol_negotiation
Thierry FOURNIER7654c9f2013-12-17 00:20:33 +01003536 { "ssl_fc_alpn", smp_fetch_ssl_fc_alpn, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
Willy Tarreauab861d32013-04-02 02:30:41 +02003537#endif
Thierry FOURNIER7654c9f2013-12-17 00:20:33 +01003538 { "ssl_fc_protocol", smp_fetch_ssl_fc_protocol, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
Willy Tarreau80aca902013-01-07 15:42:20 +01003539 { "ssl_fc_use_keysize", smp_fetch_ssl_fc_use_keysize, 0, NULL, SMP_T_UINT, SMP_USE_L5CLI },
Thierry FOURNIER7654c9f2013-12-17 00:20:33 +01003540 { "ssl_fc_session_id", smp_fetch_ssl_fc_session_id, 0, NULL, SMP_T_BIN, SMP_USE_L5CLI },
3541 { "ssl_fc_sni", smp_fetch_ssl_fc_sni, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
Willy Tarreau7875d092012-09-10 08:20:03 +02003542 { NULL, NULL, 0, 0, 0 },
3543}};
3544
3545/* Note: must not be declared <const> as its list will be overwritten.
3546 * Please take care of keeping this list alphabetically sorted.
3547 */
Willy Tarreaudc13c112013-06-21 23:16:39 +02003548static struct acl_kw_list acl_kws = {ILH, {
Thierry FOURNIERe369ca22014-01-29 16:24:55 +01003549 { "ssl_c_i_dn", NULL, pat_parse_str, pat_idx_tree_str, pat_del_tree_str, pat_prune_ptr, pat_match_str },
3550 { "ssl_c_key_alg", NULL, pat_parse_str, pat_idx_tree_str, pat_del_tree_str, pat_prune_ptr, pat_match_str },
3551 { "ssl_c_notafter", NULL, pat_parse_str, pat_idx_tree_str, pat_del_tree_str, pat_prune_ptr, pat_match_str },
3552 { "ssl_c_notbefore", NULL, pat_parse_str, pat_idx_tree_str, pat_del_tree_str, pat_prune_ptr, pat_match_str },
3553 { "ssl_c_sig_alg", NULL, pat_parse_str, pat_idx_tree_str, pat_del_tree_str, pat_prune_ptr, pat_match_str },
3554 { "ssl_c_s_dn", NULL, pat_parse_str, pat_idx_tree_str, pat_del_tree_str, pat_prune_ptr, pat_match_str },
3555 { "ssl_c_serial", NULL, pat_parse_bin, pat_idx_list_ptr, pat_del_list_ptr, pat_prune_ptr, pat_match_bin },
3556 { "ssl_f_i_dn", NULL, pat_parse_str, pat_idx_tree_str, pat_del_tree_str, pat_prune_ptr, pat_match_str },
3557 { "ssl_f_key_alg", NULL, pat_parse_str, pat_idx_tree_str, pat_del_tree_str, pat_prune_ptr, pat_match_str },
3558 { "ssl_f_notafter", NULL, pat_parse_str, pat_idx_tree_str, pat_del_tree_str, pat_prune_ptr, pat_match_str },
3559 { "ssl_f_notbefore", NULL, pat_parse_str, pat_idx_tree_str, pat_del_tree_str, pat_prune_ptr, pat_match_str },
3560 { "ssl_f_sig_alg", NULL, pat_parse_str, pat_idx_tree_str, pat_del_tree_str, pat_prune_ptr, pat_match_str },
3561 { "ssl_f_s_dn", NULL, pat_parse_str, pat_idx_tree_str, pat_del_tree_str, pat_prune_ptr, pat_match_str },
3562 { "ssl_f_serial", NULL, pat_parse_bin, pat_idx_list_ptr, pat_del_list_ptr, pat_prune_ptr, pat_match_bin },
3563 { "ssl_fc_cipher", NULL, pat_parse_str, pat_idx_tree_str, pat_del_tree_str, pat_prune_ptr, pat_match_str },
Willy Tarreaua33c6542012-10-15 13:19:06 +02003564#ifdef OPENSSL_NPN_NEGOTIATED
Thierry FOURNIERe369ca22014-01-29 16:24:55 +01003565 { "ssl_fc_npn", NULL, pat_parse_str, pat_idx_tree_str, pat_del_tree_str, pat_prune_ptr, pat_match_str },
Willy Tarreaua33c6542012-10-15 13:19:06 +02003566#endif
Dirkjan Bussink48f1c4e2014-02-13 12:29:42 +01003567#ifdef TLSEXT_TYPE_application_layer_protocol_negotiation
Thierry FOURNIERe369ca22014-01-29 16:24:55 +01003568 { "ssl_fc_alpn", NULL, pat_parse_str, pat_idx_tree_str, pat_del_tree_str, pat_prune_ptr, pat_match_str },
Willy Tarreauab861d32013-04-02 02:30:41 +02003569#endif
Thierry FOURNIERe369ca22014-01-29 16:24:55 +01003570 { "ssl_fc_protocol", NULL, pat_parse_str, pat_idx_tree_str, pat_del_tree_str, pat_prune_ptr, pat_match_str },
3571 { "ssl_fc_sni", "ssl_fc_sni", pat_parse_str, pat_idx_tree_str, pat_del_tree_str, pat_prune_ptr, pat_match_str },
3572 { "ssl_fc_sni_end", "ssl_fc_sni", pat_parse_str, pat_idx_list_str, pat_del_list_ptr, pat_prune_ptr, pat_match_end },
3573 { "ssl_fc_sni_reg", "ssl_fc_sni", pat_parse_reg, pat_idx_list_reg, pat_del_list_reg, pat_prune_reg, pat_match_reg },
Willy Tarreau8ed669b2013-01-11 15:49:37 +01003574 { /* END */ },
Willy Tarreau7875d092012-09-10 08:20:03 +02003575}};
3576
Willy Tarreau79eeafa2012-09-14 07:53:05 +02003577/* Note: must not be declared <const> as its list will be overwritten.
3578 * Please take care of keeping this list alphabetically sorted, doing so helps
3579 * all code contributors.
3580 * Optional keywords are also declared with a NULL ->parse() function so that
3581 * the config parser can report an appropriate error when a known keyword was
3582 * not enabled.
3583 */
Willy Tarreau51fb7652012-09-18 18:24:39 +02003584static struct bind_kw_list bind_kws = { "SSL", { }, {
Willy Tarreauab861d32013-04-02 02:30:41 +02003585 { "alpn", bind_parse_alpn, 1 }, /* set ALPN supported protocols */
Emeric Brunfb510ea2012-10-05 12:00:26 +02003586 { "ca-file", bind_parse_ca_file, 1 }, /* set CAfile to process verify on client cert */
Emeric Brun2d0c4822012-10-02 13:45:20 +02003587 { "ca-ignore-err", bind_parse_ignore_err, 1 }, /* set error IDs to ignore on verify depth > 0 */
3588 { "ciphers", bind_parse_ciphers, 1 }, /* set SSL cipher suite */
Emeric Brunfb510ea2012-10-05 12:00:26 +02003589 { "crl-file", bind_parse_crl_file, 1 }, /* set certificat revocation list file use on client cert verify */
Emeric Brun2d0c4822012-10-02 13:45:20 +02003590 { "crt", bind_parse_crt, 1 }, /* load SSL certificates from this location */
3591 { "crt-ignore-err", bind_parse_ignore_err, 1 }, /* set error IDs to ingore on verify depth == 0 */
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01003592 { "crt-list", bind_parse_crt_list, 1 }, /* load a list of crt from this location */
Emeric Brun2d0c4822012-10-02 13:45:20 +02003593 { "ecdhe", bind_parse_ecdhe, 1 }, /* defines named curve for elliptic curve Diffie-Hellman */
Emeric Brun2cb7ae52012-10-05 14:14:21 +02003594 { "force-sslv3", bind_parse_force_sslv3, 0 }, /* force SSLv3 */
3595 { "force-tlsv10", bind_parse_force_tlsv10, 0 }, /* force TLSv10 */
3596 { "force-tlsv11", bind_parse_force_tlsv11, 0 }, /* force TLSv11 */
3597 { "force-tlsv12", bind_parse_force_tlsv12, 0 }, /* force TLSv12 */
Emeric Brun9b3009b2012-10-05 11:55:06 +02003598 { "no-sslv3", bind_parse_no_sslv3, 0 }, /* disable SSLv3 */
3599 { "no-tlsv10", bind_parse_no_tlsv10, 0 }, /* disable TLSv10 */
3600 { "no-tlsv11", bind_parse_no_tlsv11, 0 }, /* disable TLSv11 */
3601 { "no-tlsv12", bind_parse_no_tlsv12, 0 }, /* disable TLSv12 */
Emeric Brun2d0c4822012-10-02 13:45:20 +02003602 { "no-tls-tickets", bind_parse_no_tls_tickets, 0 }, /* disable session resumption tickets */
Emeric Brun2d0c4822012-10-02 13:45:20 +02003603 { "ssl", bind_parse_ssl, 0 }, /* enable SSL processing */
Emmanuel Hocdet65623372013-01-24 17:17:15 +01003604 { "strict-sni", bind_parse_strict_sni, 0 }, /* refuse negotiation if sni doesn't match a certificate */
Emeric Brun2d0c4822012-10-02 13:45:20 +02003605 { "verify", bind_parse_verify, 1 }, /* set SSL verify method */
Willy Tarreau6c9a3d52012-10-18 18:57:14 +02003606 { "npn", bind_parse_npn, 1 }, /* set NPN supported protocols */
Willy Tarreau79eeafa2012-09-14 07:53:05 +02003607 { NULL, NULL, 0 },
3608}};
Emeric Brun46591952012-05-18 15:47:34 +02003609
Willy Tarreau92faadf2012-10-10 23:04:25 +02003610/* Note: must not be declared <const> as its list will be overwritten.
3611 * Please take care of keeping this list alphabetically sorted, doing so helps
3612 * all code contributors.
3613 * Optional keywords are also declared with a NULL ->parse() function so that
3614 * the config parser can report an appropriate error when a known keyword was
3615 * not enabled.
3616 */
3617static struct srv_kw_list srv_kws = { "SSL", { }, {
Emeric Brunef42d922012-10-11 16:11:36 +02003618 { "ca-file", srv_parse_ca_file, 1, 0 }, /* set CAfile to process verify server cert */
Emeric Brunecc91fe2012-10-11 15:05:10 +02003619 { "check-ssl", srv_parse_check_ssl, 0, 0 }, /* enable SSL for health checks */
3620 { "ciphers", srv_parse_ciphers, 1, 0 }, /* select the cipher suite */
Emeric Brunef42d922012-10-11 16:11:36 +02003621 { "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 +02003622 { "crt", srv_parse_crt, 1, 0 }, /* set client certificate */
Emeric Brunecc91fe2012-10-11 15:05:10 +02003623 { "force-sslv3", srv_parse_force_sslv3, 0, 0 }, /* force SSLv3 */
3624 { "force-tlsv10", srv_parse_force_tlsv10, 0, 0 }, /* force TLSv10 */
3625 { "force-tlsv11", srv_parse_force_tlsv11, 0, 0 }, /* force TLSv11 */
3626 { "force-tlsv12", srv_parse_force_tlsv12, 0, 0 }, /* force TLSv12 */
3627 { "no-sslv3", srv_parse_no_sslv3, 0, 0 }, /* disable SSLv3 */
3628 { "no-tlsv10", srv_parse_no_tlsv10, 0, 0 }, /* disable TLSv10 */
3629 { "no-tlsv11", srv_parse_no_tlsv11, 0, 0 }, /* disable TLSv11 */
3630 { "no-tlsv12", srv_parse_no_tlsv12, 0, 0 }, /* disable TLSv12 */
Emeric Brunf9c5c472012-10-11 15:28:34 +02003631 { "no-tls-tickets", srv_parse_no_tls_tickets, 0, 0 }, /* disable session resumption tickets */
Emeric Brunecc91fe2012-10-11 15:05:10 +02003632 { "ssl", srv_parse_ssl, 0, 0 }, /* enable SSL processing */
Emeric Brunef42d922012-10-11 16:11:36 +02003633 { "verify", srv_parse_verify, 1, 0 }, /* set SSL verify method */
Evan Broderbe554312013-06-27 00:05:25 -07003634 { "verifyhost", srv_parse_verifyhost, 1, 0 }, /* require that SSL cert verifies for hostname */
Willy Tarreau92faadf2012-10-10 23:04:25 +02003635 { NULL, NULL, 0, 0 },
3636}};
3637
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02003638/* transport-layer operations for SSL sockets */
3639struct xprt_ops ssl_sock = {
Emeric Brun46591952012-05-18 15:47:34 +02003640 .snd_buf = ssl_sock_from_buf,
3641 .rcv_buf = ssl_sock_to_buf,
3642 .rcv_pipe = NULL,
3643 .snd_pipe = NULL,
3644 .shutr = NULL,
3645 .shutw = ssl_sock_shutw,
3646 .close = ssl_sock_close,
3647 .init = ssl_sock_init,
3648};
3649
3650__attribute__((constructor))
Willy Tarreau92faadf2012-10-10 23:04:25 +02003651static void __ssl_sock_init(void)
3652{
Emeric Brun46591952012-05-18 15:47:34 +02003653 STACK_OF(SSL_COMP)* cm;
3654
Willy Tarreau610f04b2014-02-13 11:36:41 +01003655#ifdef LISTEN_DEFAULT_CIPHERS
3656 global.listen_default_ciphers = LISTEN_DEFAULT_CIPHERS;
3657#endif
3658#ifdef CONNECT_DEFAULT_CIPHERS
3659 global.connect_default_ciphers = CONNECT_DEFAULT_CIPHERS;
3660#endif
3661 if (global.listen_default_ciphers)
3662 global.listen_default_ciphers = strdup(global.listen_default_ciphers);
3663 if (global.connect_default_ciphers)
3664 global.connect_default_ciphers = strdup(global.connect_default_ciphers);
3665
Emeric Brun46591952012-05-18 15:47:34 +02003666 SSL_library_init();
3667 cm = SSL_COMP_get_compression_methods();
3668 sk_SSL_COMP_zero(cm);
Willy Tarreau7875d092012-09-10 08:20:03 +02003669 sample_register_fetches(&sample_fetch_keywords);
3670 acl_register_keywords(&acl_kws);
Willy Tarreau79eeafa2012-09-14 07:53:05 +02003671 bind_register_keywords(&bind_kws);
Willy Tarreau92faadf2012-10-10 23:04:25 +02003672 srv_register_keywords(&srv_kws);
Emeric Brun46591952012-05-18 15:47:34 +02003673}
3674
3675/*
3676 * Local variables:
3677 * c-indent-level: 8
3678 * c-basic-offset: 8
3679 * End:
3680 */