blob: 5ac2b0653cc4931e50c9b0c7d1afd7612aa29b1d [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
Emeric Brune64aef12012-09-21 13:15:06 +020077#define SSL_SOCK_ST_FL_VERIFY_DONE 0x00000001
Emeric Brund8b2bb52014-01-28 15:43:53 +010078#define SSL_SOCK_ST_FL_16K_WBFSIZE 0x00000002
Emeric Brunf282a812012-09-21 15:27:54 +020079/* bits 0xFFFF0000 are reserved to store verify errors */
80
81/* Verify errors macros */
82#define SSL_SOCK_CA_ERROR_TO_ST(e) (((e > 63) ? 63 : e) << (16))
83#define SSL_SOCK_CAEDEPTH_TO_ST(d) (((d > 15) ? 15 : d) << (6+16))
84#define SSL_SOCK_CRTERROR_TO_ST(e) (((e > 63) ? 63 : e) << (4+6+16))
85
86#define SSL_SOCK_ST_TO_CA_ERROR(s) ((s >> (16)) & 63)
87#define SSL_SOCK_ST_TO_CAEDEPTH(s) ((s >> (6+16)) & 15)
88#define SSL_SOCK_ST_TO_CRTERROR(s) ((s >> (4+6+16)) & 63)
Emeric Brune64aef12012-09-21 13:15:06 +020089
Emeric Brun850efd52014-01-29 12:24:34 +010090/* server and bind verify method, it uses a global value as default */
91enum {
92 SSL_SOCK_VERIFY_DEFAULT = 0,
93 SSL_SOCK_VERIFY_REQUIRED = 1,
94 SSL_SOCK_VERIFY_OPTIONAL = 2,
95 SSL_SOCK_VERIFY_NONE = 3,
96};
97
Willy Tarreau71b734c2014-01-28 15:19:44 +010098int sslconns = 0;
99int totalsslconns = 0;
Emeric Brune1f38db2012-09-03 20:36:47 +0200100
101void ssl_sock_infocbk(const SSL *ssl, int where, int ret)
102{
103 struct connection *conn = (struct connection *)SSL_get_app_data(ssl);
104 (void)ret; /* shut gcc stupid warning */
Emeric Brund8b2bb52014-01-28 15:43:53 +0100105 BIO *write_bio;
Emeric Brune1f38db2012-09-03 20:36:47 +0200106
107 if (where & SSL_CB_HANDSHAKE_START) {
108 /* Disable renegotiation (CVE-2009-3555) */
Willy Tarreau20879a02012-12-03 16:32:10 +0100109 if (conn->flags & CO_FL_CONNECTED) {
Emeric Brune1f38db2012-09-03 20:36:47 +0200110 conn->flags |= CO_FL_ERROR;
Willy Tarreau20879a02012-12-03 16:32:10 +0100111 conn->err_code = CO_ER_SSL_RENEG;
112 }
Emeric Brune1f38db2012-09-03 20:36:47 +0200113 }
Emeric Brund8b2bb52014-01-28 15:43:53 +0100114
115 if ((where & SSL_CB_ACCEPT_LOOP) == SSL_CB_ACCEPT_LOOP) {
116 if (!(conn->xprt_st & SSL_SOCK_ST_FL_16K_WBFSIZE)) {
117 /* Long certificate chains optimz
118 If write and read bios are differents, we
119 consider that the buffering was activated,
120 so we rise the output buffer size from 4k
121 to 16k */
122 write_bio = SSL_get_wbio(ssl);
123 if (write_bio != SSL_get_rbio(ssl)) {
124 BIO_set_write_buffer_size(write_bio, 16384);
125 conn->xprt_st |= SSL_SOCK_ST_FL_16K_WBFSIZE;
126 }
127 }
128 }
Emeric Brunfc0421f2012-09-07 17:30:07 +0200129}
130
Emeric Brune64aef12012-09-21 13:15:06 +0200131/* Callback is called for each certificate of the chain during a verify
132 ok is set to 1 if preverify detect no error on current certificate.
133 Returns 0 to break the handshake, 1 otherwise. */
Evan Broderbe554312013-06-27 00:05:25 -0700134int ssl_sock_bind_verifycbk(int ok, X509_STORE_CTX *x_store)
Emeric Brune64aef12012-09-21 13:15:06 +0200135{
136 SSL *ssl;
137 struct connection *conn;
Emeric Brun81c00f02012-09-21 14:31:21 +0200138 int err, depth;
Emeric Brune64aef12012-09-21 13:15:06 +0200139
140 ssl = X509_STORE_CTX_get_ex_data(x_store, SSL_get_ex_data_X509_STORE_CTX_idx());
141 conn = (struct connection *)SSL_get_app_data(ssl);
142
Willy Tarreauf7bc57c2012-10-03 00:19:48 +0200143 conn->xprt_st |= SSL_SOCK_ST_FL_VERIFY_DONE;
Emeric Brune64aef12012-09-21 13:15:06 +0200144
Emeric Brun81c00f02012-09-21 14:31:21 +0200145 if (ok) /* no errors */
146 return ok;
147
148 depth = X509_STORE_CTX_get_error_depth(x_store);
149 err = X509_STORE_CTX_get_error(x_store);
150
151 /* check if CA error needs to be ignored */
152 if (depth > 0) {
Willy Tarreauf7bc57c2012-10-03 00:19:48 +0200153 if (!SSL_SOCK_ST_TO_CA_ERROR(conn->xprt_st)) {
154 conn->xprt_st |= SSL_SOCK_CA_ERROR_TO_ST(err);
155 conn->xprt_st |= SSL_SOCK_CAEDEPTH_TO_ST(depth);
Emeric Brunf282a812012-09-21 15:27:54 +0200156 }
157
Emeric Brun1eb20ef2012-12-03 13:24:29 +0100158 if (objt_listener(conn->target)->bind_conf->ca_ignerr & (1ULL << err)) {
159 ERR_clear_error();
Emeric Brun81c00f02012-09-21 14:31:21 +0200160 return 1;
Emeric Brun1eb20ef2012-12-03 13:24:29 +0100161 }
Emeric Brun81c00f02012-09-21 14:31:21 +0200162
Willy Tarreau20879a02012-12-03 16:32:10 +0100163 conn->err_code = CO_ER_SSL_CA_FAIL;
Emeric Brun81c00f02012-09-21 14:31:21 +0200164 return 0;
165 }
166
Willy Tarreauf7bc57c2012-10-03 00:19:48 +0200167 if (!SSL_SOCK_ST_TO_CRTERROR(conn->xprt_st))
168 conn->xprt_st |= SSL_SOCK_CRTERROR_TO_ST(err);
Emeric Brunf282a812012-09-21 15:27:54 +0200169
Emeric Brun81c00f02012-09-21 14:31:21 +0200170 /* check if certificate error needs to be ignored */
Emeric Brun1eb20ef2012-12-03 13:24:29 +0100171 if (objt_listener(conn->target)->bind_conf->crt_ignerr & (1ULL << err)) {
172 ERR_clear_error();
Emeric Brun81c00f02012-09-21 14:31:21 +0200173 return 1;
Emeric Brun1eb20ef2012-12-03 13:24:29 +0100174 }
Emeric Brun81c00f02012-09-21 14:31:21 +0200175
Willy Tarreau20879a02012-12-03 16:32:10 +0100176 conn->err_code = CO_ER_SSL_CRT_FAIL;
Emeric Brun81c00f02012-09-21 14:31:21 +0200177 return 0;
Emeric Brune64aef12012-09-21 13:15:06 +0200178}
179
Willy Tarreau6c9a3d52012-10-18 18:57:14 +0200180#ifdef OPENSSL_NPN_NEGOTIATED
181/* This callback is used so that the server advertises the list of
182 * negociable protocols for NPN.
183 */
184static int ssl_sock_advertise_npn_protos(SSL *s, const unsigned char **data,
185 unsigned int *len, void *arg)
186{
187 struct bind_conf *conf = arg;
188
189 *data = (const unsigned char *)conf->npn_str;
190 *len = conf->npn_len;
191 return SSL_TLSEXT_ERR_OK;
192}
193#endif
194
Willy Tarreauab861d32013-04-02 02:30:41 +0200195#ifdef OPENSSL_ALPN_NEGOTIATED
196/* This callback is used so that the server advertises the list of
197 * negociable protocols for ALPN.
198 */
199static int ssl_sock_advertise_alpn_protos(SSL *s, const unsigned char **data,
200 unsigned int *len, void *arg)
201{
202 struct bind_conf *conf = arg;
203
204 *data = (const unsigned char *)conf->alpn_str;
205 *len = conf->alpn_len;
206 return SSL_TLSEXT_ERR_OK;
207}
208#endif
209
Emeric Brunfc0421f2012-09-07 17:30:07 +0200210#ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME
211/* Sets the SSL ctx of <ssl> to match the advertised server name. Returns a
212 * warning when no match is found, which implies the default (first) cert
213 * will keep being used.
214 */
Willy Tarreau2a65ff02012-09-13 17:54:29 +0200215static int ssl_sock_switchctx_cbk(SSL *ssl, int *al, struct bind_conf *s)
Emeric Brunfc0421f2012-09-07 17:30:07 +0200216{
217 const char *servername;
218 const char *wildp = NULL;
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +0200219 struct ebmb_node *node, *n;
Emeric Brunfc0421f2012-09-07 17:30:07 +0200220 int i;
221 (void)al; /* shut gcc stupid warning */
222
223 servername = SSL_get_servername(ssl, TLSEXT_NAMETYPE_host_name);
Emmanuel Hocdet65623372013-01-24 17:17:15 +0100224 if (!servername) {
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +0200225 return (s->strict_sni ?
226 SSL_TLSEXT_ERR_ALERT_FATAL :
Emmanuel Hocdet79274e22013-05-31 12:47:44 +0200227 SSL_TLSEXT_ERR_NOACK);
Emmanuel Hocdet65623372013-01-24 17:17:15 +0100228 }
Emeric Brunfc0421f2012-09-07 17:30:07 +0200229
Willy Tarreau19d14ef2012-10-29 16:51:55 +0100230 for (i = 0; i < trash.size; i++) {
Emeric Brunfc0421f2012-09-07 17:30:07 +0200231 if (!servername[i])
232 break;
Willy Tarreau19d14ef2012-10-29 16:51:55 +0100233 trash.str[i] = tolower(servername[i]);
234 if (!wildp && (trash.str[i] == '.'))
235 wildp = &trash.str[i];
Emeric Brunfc0421f2012-09-07 17:30:07 +0200236 }
Willy Tarreau19d14ef2012-10-29 16:51:55 +0100237 trash.str[i] = 0;
Emeric Brunfc0421f2012-09-07 17:30:07 +0200238
239 /* lookup in full qualified names */
Willy Tarreau19d14ef2012-10-29 16:51:55 +0100240 node = ebst_lookup(&s->sni_ctx, trash.str);
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +0200241
242 /* lookup a not neg filter */
243 for (n = node; n; n = ebmb_next_dup(n)) {
244 if (!container_of(n, struct sni_ctx, name)->neg) {
245 node = n;
246 break;
Emmanuel Hocdet65623372013-01-24 17:17:15 +0100247 }
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +0200248 }
249 if (!node && wildp) {
250 /* lookup in wildcards names */
Emeric Brunfc0421f2012-09-07 17:30:07 +0200251 node = ebst_lookup(&s->sni_w_ctx, wildp);
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +0200252 }
253 if (!node || container_of(node, struct sni_ctx, name)->neg) {
254 return (s->strict_sni ?
255 SSL_TLSEXT_ERR_ALERT_FATAL :
256 SSL_TLSEXT_ERR_ALERT_WARNING);
Emeric Brunfc0421f2012-09-07 17:30:07 +0200257 }
258
259 /* switch ctx */
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +0200260 SSL_set_SSL_CTX(ssl, container_of(node, struct sni_ctx, name)->ctx);
Emeric Brunfc0421f2012-09-07 17:30:07 +0200261 return SSL_TLSEXT_ERR_OK;
262}
263#endif /* SSL_CTRL_SET_TLSEXT_HOSTNAME */
264
Emeric Bruna4bcd9a2012-09-20 16:19:02 +0200265#ifndef OPENSSL_NO_DH
266/* Loads Diffie-Hellman parameter from a file. Returns 1 if loaded, else -1
267 if an error occured, and 0 if parameter not found. */
268int ssl_sock_load_dh_params(SSL_CTX *ctx, const char *file)
269{
270 int ret = -1;
271 BIO *in;
272 DH *dh = NULL;
Emeric Brun41fdb3c2013-04-26 11:05:44 +0200273 /* If not present, use parameters generated using 'openssl dhparam 1024 -C':
274 * -----BEGIN DH PARAMETERS-----
275 * MIGHAoGBAJJAJDXDoS5E03MNjnjK36eOL1tRqVa/9NuOVlI+lpXmPjJQbP65EvKn
276 * fSLnG7VMhoCJO4KtG88zf393ltP7loGB2bofcDSr+x+XsxBM8yA/Zj6BmQt+CQ9s
277 * TF7hoOV+wXTT6ErZ5y5qx9pq6hLfKXwTGFT78hrE6HnCO7xgtPdTAgEC
278 * -----END DH PARAMETERS-----
279 */
280 static const unsigned char dh1024_p[] = {
281 0x92, 0x40, 0x24, 0x35, 0xC3, 0xA1, 0x2E, 0x44, 0xD3, 0x73, 0x0D, 0x8E,
282 0x78, 0xCA, 0xDF, 0xA7, 0x8E, 0x2F, 0x5B, 0x51, 0xA9, 0x56, 0xBF, 0xF4,
283 0xDB, 0x8E, 0x56, 0x52, 0x3E, 0x96, 0x95, 0xE6, 0x3E, 0x32, 0x50, 0x6C,
284 0xFE, 0xB9, 0x12, 0xF2, 0xA7, 0x7D, 0x22, 0xE7, 0x1B, 0xB5, 0x4C, 0x86,
285 0x80, 0x89, 0x3B, 0x82, 0xAD, 0x1B, 0xCF, 0x33, 0x7F, 0x7F, 0x77, 0x96,
286 0xD3, 0xFB, 0x96, 0x81, 0x81, 0xD9, 0xBA, 0x1F, 0x70, 0x34, 0xAB, 0xFB,
287 0x1F, 0x97, 0xB3, 0x10, 0x4C, 0xF3, 0x20, 0x3F, 0x66, 0x3E, 0x81, 0x99,
288 0x0B, 0x7E, 0x09, 0x0F, 0x6C, 0x4C, 0x5E, 0xE1, 0xA0, 0xE5, 0x7E, 0xC1,
289 0x74, 0xD3, 0xE8, 0x4A, 0xD9, 0xE7, 0x2E, 0x6A, 0xC7, 0xDA, 0x6A, 0xEA,
290 0x12, 0xDF, 0x29, 0x7C, 0x13, 0x18, 0x54, 0xFB, 0xF2, 0x1A, 0xC4, 0xE8,
291 0x79, 0xC2, 0x3B, 0xBC, 0x60, 0xB4, 0xF7, 0x53,
292 };
293 static const unsigned char dh1024_g[] = {
294 0x02,
295 };
Emeric Bruna4bcd9a2012-09-20 16:19:02 +0200296
297 in = BIO_new(BIO_s_file());
298 if (in == NULL)
299 goto end;
300
301 if (BIO_read_filename(in, file) <= 0)
302 goto end;
303
304 dh = PEM_read_bio_DHparams(in, NULL, ctx->default_passwd_callback, ctx->default_passwd_callback_userdata);
Emeric Brun41fdb3c2013-04-26 11:05:44 +0200305 if (!dh) {
306 /* Clear openssl global errors stack */
307 ERR_clear_error();
308
309 dh = DH_new();
310 if (dh == NULL)
311 goto end;
312
313 dh->p = BN_bin2bn(dh1024_p, sizeof(dh1024_p), NULL);
314 if (dh->p == NULL)
315 goto end;
316
317 dh->g = BN_bin2bn(dh1024_g, sizeof(dh1024_g), NULL);
318 if (dh->g == NULL)
319 goto end;
320
321 ret = 0; /* DH params not found */
Emeric Bruna4bcd9a2012-09-20 16:19:02 +0200322 }
Emeric Brun41fdb3c2013-04-26 11:05:44 +0200323 else
324 ret = 1;
Emeric Bruna4bcd9a2012-09-20 16:19:02 +0200325
Emeric Brun41fdb3c2013-04-26 11:05:44 +0200326 SSL_CTX_set_tmp_dh(ctx, dh);
Emeric Brun644cde02012-12-14 11:21:13 +0100327
Emeric Bruna4bcd9a2012-09-20 16:19:02 +0200328end:
329 if (dh)
330 DH_free(dh);
331
332 if (in)
Emeric Brun41fdb3c2013-04-26 11:05:44 +0200333 BIO_free(in);
Emeric Bruna4bcd9a2012-09-20 16:19:02 +0200334
335 return ret;
336}
337#endif
338
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +0200339static int ssl_sock_add_cert_sni(SSL_CTX *ctx, struct bind_conf *s, char *name, int order)
Emmanuel Hocdetfe616562013-01-22 15:31:15 +0100340{
341 struct sni_ctx *sc;
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +0200342 int wild = 0, neg = 0;
Emmanuel Hocdetfe616562013-01-22 15:31:15 +0100343
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +0200344 if (*name == '!') {
345 neg = 1;
346 name++;
347 }
348 if (*name == '*') {
349 wild = 1;
350 name++;
351 }
352 /* !* filter is a nop */
353 if (neg && wild)
354 return order;
355 if (*name) {
356 int j, len;
357 len = strlen(name);
Emmanuel Hocdetfe616562013-01-22 15:31:15 +0100358 sc = malloc(sizeof(struct sni_ctx) + len + 1);
359 for (j = 0; j < len; j++)
360 sc->name.key[j] = tolower(name[j]);
361 sc->name.key[len] = 0;
Emmanuel Hocdetfe616562013-01-22 15:31:15 +0100362 sc->ctx = ctx;
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +0200363 sc->order = order++;
364 sc->neg = neg;
Emmanuel Hocdetfe616562013-01-22 15:31:15 +0100365 if (wild)
366 ebst_insert(&s->sni_w_ctx, &sc->name);
367 else
368 ebst_insert(&s->sni_ctx, &sc->name);
369 }
370 return order;
371}
372
Emeric Brunfc0421f2012-09-07 17:30:07 +0200373/* Loads a certificate key and CA chain from a file. Returns 0 on error, -1 if
374 * an early error happens and the caller must call SSL_CTX_free() by itelf.
375 */
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +0200376static 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 +0200377{
378 BIO *in;
379 X509 *x = NULL, *ca;
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +0200380 int i, err;
Emeric Brunfc0421f2012-09-07 17:30:07 +0200381 int ret = -1;
382 int order = 0;
383 X509_NAME *xname;
384 char *str;
Emeric Brunfc0421f2012-09-07 17:30:07 +0200385#ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME
386 STACK_OF(GENERAL_NAME) *names;
387#endif
388
389 in = BIO_new(BIO_s_file());
390 if (in == NULL)
391 goto end;
392
393 if (BIO_read_filename(in, file) <= 0)
394 goto end;
395
396 x = PEM_read_bio_X509_AUX(in, NULL, ctx->default_passwd_callback, ctx->default_passwd_callback_userdata);
397 if (x == NULL)
398 goto end;
399
Emeric Brun50bcecc2013-04-22 13:05:23 +0200400 if (fcount) {
401 while (fcount--)
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +0200402 order = ssl_sock_add_cert_sni(ctx, s, sni_filter[fcount], order);
Emmanuel Hocdetfe616562013-01-22 15:31:15 +0100403 }
404 else {
Emeric Brunfc0421f2012-09-07 17:30:07 +0200405#ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME
Emmanuel Hocdetfe616562013-01-22 15:31:15 +0100406 names = X509_get_ext_d2i(x, NID_subject_alt_name, NULL, NULL);
407 if (names) {
408 for (i = 0; i < sk_GENERAL_NAME_num(names); i++) {
409 GENERAL_NAME *name = sk_GENERAL_NAME_value(names, i);
410 if (name->type == GEN_DNS) {
411 if (ASN1_STRING_to_UTF8((unsigned char **)&str, name->d.dNSName) >= 0) {
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +0200412 order = ssl_sock_add_cert_sni(ctx, s, str, order);
Emmanuel Hocdetfe616562013-01-22 15:31:15 +0100413 OPENSSL_free(str);
Emeric Brunfc0421f2012-09-07 17:30:07 +0200414 }
Emeric Brunfc0421f2012-09-07 17:30:07 +0200415 }
416 }
Emmanuel Hocdetfe616562013-01-22 15:31:15 +0100417 sk_GENERAL_NAME_pop_free(names, GENERAL_NAME_free);
Emeric Brunfc0421f2012-09-07 17:30:07 +0200418 }
Emeric Brunfc0421f2012-09-07 17:30:07 +0200419#endif /* SSL_CTRL_SET_TLSEXT_HOSTNAME */
Emmanuel Hocdetfe616562013-01-22 15:31:15 +0100420 xname = X509_get_subject_name(x);
421 i = -1;
422 while ((i = X509_NAME_get_index_by_NID(xname, NID_commonName, i)) != -1) {
423 X509_NAME_ENTRY *entry = X509_NAME_get_entry(xname, i);
424 if (ASN1_STRING_to_UTF8((unsigned char **)&str, entry->value) >= 0) {
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +0200425 order = ssl_sock_add_cert_sni(ctx, s, str, order);
Emmanuel Hocdetfe616562013-01-22 15:31:15 +0100426 OPENSSL_free(str);
Emeric Brunfc0421f2012-09-07 17:30:07 +0200427 }
Emeric Brunfc0421f2012-09-07 17:30:07 +0200428 }
429 }
430
431 ret = 0; /* the caller must not free the SSL_CTX argument anymore */
432 if (!SSL_CTX_use_certificate(ctx, x))
433 goto end;
434
435 if (ctx->extra_certs != NULL) {
436 sk_X509_pop_free(ctx->extra_certs, X509_free);
437 ctx->extra_certs = NULL;
438 }
439
440 while ((ca = PEM_read_bio_X509(in, NULL, ctx->default_passwd_callback, ctx->default_passwd_callback_userdata))) {
441 if (!SSL_CTX_add_extra_chain_cert(ctx, ca)) {
442 X509_free(ca);
443 goto end;
444 }
445 }
446
447 err = ERR_get_error();
448 if (!err || (ERR_GET_LIB(err) == ERR_LIB_PEM && ERR_GET_REASON(err) == PEM_R_NO_START_LINE)) {
449 /* we successfully reached the last cert in the file */
450 ret = 1;
451 }
452 ERR_clear_error();
453
454end:
455 if (x)
456 X509_free(x);
457
458 if (in)
459 BIO_free(in);
460
461 return ret;
462}
463
Emeric Brun50bcecc2013-04-22 13:05:23 +0200464static 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 +0200465{
466 int ret;
467 SSL_CTX *ctx;
468
469 ctx = SSL_CTX_new(SSLv23_server_method());
470 if (!ctx) {
Willy Tarreaueb6cead2012-09-20 19:43:14 +0200471 memprintf(err, "%sunable to allocate SSL context for cert '%s'.\n",
472 err && *err ? *err : "", path);
Emeric Brunfc0421f2012-09-07 17:30:07 +0200473 return 1;
474 }
475
476 if (SSL_CTX_use_PrivateKey_file(ctx, path, SSL_FILETYPE_PEM) <= 0) {
Willy Tarreaueb6cead2012-09-20 19:43:14 +0200477 memprintf(err, "%sunable to load SSL private key from PEM file '%s'.\n",
478 err && *err ? *err : "", path);
Emeric Brunfc0421f2012-09-07 17:30:07 +0200479 SSL_CTX_free(ctx);
480 return 1;
481 }
482
Emeric Brun50bcecc2013-04-22 13:05:23 +0200483 ret = ssl_sock_load_cert_chain_file(ctx, path, bind_conf, sni_filter, fcount);
Emeric Brunfc0421f2012-09-07 17:30:07 +0200484 if (ret <= 0) {
Willy Tarreaueb6cead2012-09-20 19:43:14 +0200485 memprintf(err, "%sunable to load SSL certificate from PEM file '%s'.\n",
486 err && *err ? *err : "", path);
Emeric Brunfc0421f2012-09-07 17:30:07 +0200487 if (ret < 0) /* serious error, must do that ourselves */
488 SSL_CTX_free(ctx);
489 return 1;
490 }
Emeric Brun61694ab2012-10-26 13:35:33 +0200491
492 if (SSL_CTX_check_private_key(ctx) <= 0) {
493 memprintf(err, "%sinconsistencies between private key and certificate loaded from PEM file '%s'.\n",
494 err && *err ? *err : "", path);
495 return 1;
496 }
497
Emeric Brunfc0421f2012-09-07 17:30:07 +0200498 /* we must not free the SSL_CTX anymore below, since it's already in
499 * the tree, so it will be discovered and cleaned in time.
500 */
Emeric Bruna4bcd9a2012-09-20 16:19:02 +0200501#ifndef OPENSSL_NO_DH
502 ret = ssl_sock_load_dh_params(ctx, path);
503 if (ret < 0) {
504 if (err)
505 memprintf(err, "%sunable to load DH parameters from file '%s'.\n",
506 *err ? *err : "", path);
507 return 1;
508 }
509#endif
510
Emeric Brunfc0421f2012-09-07 17:30:07 +0200511#ifndef SSL_CTRL_SET_TLSEXT_HOSTNAME
Willy Tarreau2a65ff02012-09-13 17:54:29 +0200512 if (bind_conf->default_ctx) {
Willy Tarreaueb6cead2012-09-20 19:43:14 +0200513 memprintf(err, "%sthis version of openssl cannot load multiple SSL certificates.\n",
514 err && *err ? *err : "");
Emeric Brunfc0421f2012-09-07 17:30:07 +0200515 return 1;
516 }
517#endif
Willy Tarreau2a65ff02012-09-13 17:54:29 +0200518 if (!bind_conf->default_ctx)
519 bind_conf->default_ctx = ctx;
Emeric Brunfc0421f2012-09-07 17:30:07 +0200520
521 return 0;
522}
523
Willy Tarreau79eeafa2012-09-14 07:53:05 +0200524int ssl_sock_load_cert(char *path, struct bind_conf *bind_conf, struct proxy *curproxy, char **err)
Emeric Brunfc0421f2012-09-07 17:30:07 +0200525{
526 struct dirent *de;
527 DIR *dir;
528 struct stat buf;
Willy Tarreauee2663b2012-12-06 11:36:59 +0100529 char *end;
530 char fp[MAXPATHLEN+1];
Emeric Brunfc0421f2012-09-07 17:30:07 +0200531 int cfgerr = 0;
532
533 if (!(dir = opendir(path)))
Emeric Brun50bcecc2013-04-22 13:05:23 +0200534 return ssl_sock_load_cert_file(path, bind_conf, curproxy, NULL, 0, err);
Emeric Brunfc0421f2012-09-07 17:30:07 +0200535
536 /* strip trailing slashes, including first one */
537 for (end = path + strlen(path) - 1; end >= path && *end == '/'; end--)
538 *end = 0;
539
Emeric Brunfc0421f2012-09-07 17:30:07 +0200540 while ((de = readdir(dir))) {
Willy Tarreauee2663b2012-12-06 11:36:59 +0100541 snprintf(fp, sizeof(fp), "%s/%s", path, de->d_name);
Emeric Brunfc0421f2012-09-07 17:30:07 +0200542 if (stat(fp, &buf) != 0) {
Willy Tarreaueb6cead2012-09-20 19:43:14 +0200543 memprintf(err, "%sunable to stat SSL certificate from file '%s' : %s.\n",
544 err && *err ? *err : "", fp, strerror(errno));
Emeric Brunfc0421f2012-09-07 17:30:07 +0200545 cfgerr++;
546 continue;
547 }
548 if (!S_ISREG(buf.st_mode))
549 continue;
Emeric Brun50bcecc2013-04-22 13:05:23 +0200550 cfgerr += ssl_sock_load_cert_file(fp, bind_conf, curproxy, NULL, 0, err);
Emeric Brunfc0421f2012-09-07 17:30:07 +0200551 }
Emeric Brunfc0421f2012-09-07 17:30:07 +0200552 closedir(dir);
553 return cfgerr;
554}
555
Thierry Fournier383085f2013-01-24 14:15:43 +0100556/* Make sure openssl opens /dev/urandom before the chroot. The work is only
557 * done once. Zero is returned if the operation fails. No error is returned
558 * if the random is said as not implemented, because we expect that openssl
559 * will use another method once needed.
560 */
561static int ssl_initialize_random()
562{
563 unsigned char random;
564 static int random_initialized = 0;
565
566 if (!random_initialized && RAND_bytes(&random, 1) != 0)
567 random_initialized = 1;
568
569 return random_initialized;
570}
571
Emmanuel Hocdetfe616562013-01-22 15:31:15 +0100572int ssl_sock_load_cert_list_file(char *file, struct bind_conf *bind_conf, struct proxy *curproxy, char **err)
573{
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +0200574 char thisline[LINESIZE];
Emmanuel Hocdetfe616562013-01-22 15:31:15 +0100575 FILE *f;
576 int linenum = 0;
577 int cfgerr = 0;
Emmanuel Hocdetfe616562013-01-22 15:31:15 +0100578
Willy Tarreauad1731d2013-04-02 17:35:58 +0200579 if ((f = fopen(file, "r")) == NULL) {
580 memprintf(err, "cannot open file '%s' : %s", file, strerror(errno));
Emmanuel Hocdetfe616562013-01-22 15:31:15 +0100581 return 1;
Willy Tarreauad1731d2013-04-02 17:35:58 +0200582 }
Emmanuel Hocdetfe616562013-01-22 15:31:15 +0100583
584 while (fgets(thisline, sizeof(thisline), f) != NULL) {
585 int arg;
Emeric Brun50bcecc2013-04-22 13:05:23 +0200586 int newarg;
Emmanuel Hocdetfe616562013-01-22 15:31:15 +0100587 char *end;
588 char *args[MAX_LINE_ARGS + 1];
589 char *line = thisline;
590
591 linenum++;
592 end = line + strlen(line);
593 if (end-line == sizeof(thisline)-1 && *(end-1) != '\n') {
594 /* Check if we reached the limit and the last char is not \n.
595 * Watch out for the last line without the terminating '\n'!
596 */
Willy Tarreauad1731d2013-04-02 17:35:58 +0200597 memprintf(err, "line %d too long in file '%s', limit is %d characters",
598 linenum, file, (int)sizeof(thisline)-1);
Emmanuel Hocdetfe616562013-01-22 15:31:15 +0100599 cfgerr = 1;
Willy Tarreauad1731d2013-04-02 17:35:58 +0200600 break;
Emmanuel Hocdetfe616562013-01-22 15:31:15 +0100601 }
602
Emmanuel Hocdetfe616562013-01-22 15:31:15 +0100603 arg = 0;
Emeric Brun50bcecc2013-04-22 13:05:23 +0200604 newarg = 1;
605 while (*line) {
Emmanuel Hocdetfe616562013-01-22 15:31:15 +0100606 if (*line == '#' || *line == '\n' || *line == '\r') {
607 /* end of string, end of loop */
608 *line = 0;
609 break;
610 }
611 else if (isspace(*line)) {
Emeric Brun50bcecc2013-04-22 13:05:23 +0200612 newarg = 1;
613 *line = 0;
Emmanuel Hocdetfe616562013-01-22 15:31:15 +0100614 }
Emeric Brun50bcecc2013-04-22 13:05:23 +0200615 else if (newarg) {
616 if (arg == MAX_LINE_ARGS) {
617 memprintf(err, "too many args on line %d in file '%s'.",
618 linenum, file);
619 cfgerr = 1;
620 break;
621 }
622 newarg = 0;
623 args[arg++] = line;
Emmanuel Hocdetfe616562013-01-22 15:31:15 +0100624 }
Emeric Brun50bcecc2013-04-22 13:05:23 +0200625 line++;
Emmanuel Hocdetfe616562013-01-22 15:31:15 +0100626 }
Emmanuel Hocdet7c41a1b2013-05-07 20:20:06 +0200627 if (cfgerr)
628 break;
Willy Tarreauad1731d2013-04-02 17:35:58 +0200629
Emmanuel Hocdetfe616562013-01-22 15:31:15 +0100630 /* empty line */
Emeric Brun50bcecc2013-04-22 13:05:23 +0200631 if (!arg)
Emmanuel Hocdetfe616562013-01-22 15:31:15 +0100632 continue;
Emmanuel Hocdetfe616562013-01-22 15:31:15 +0100633
Emeric Brun50bcecc2013-04-22 13:05:23 +0200634 cfgerr = ssl_sock_load_cert_file(args[0], bind_conf, curproxy, &args[1], arg-1, err);
Willy Tarreauad1731d2013-04-02 17:35:58 +0200635 if (cfgerr) {
636 memprintf(err, "error processing line %d in file '%s' : %s", linenum, file, *err);
Emmanuel Hocdetfe616562013-01-22 15:31:15 +0100637 break;
Willy Tarreauad1731d2013-04-02 17:35:58 +0200638 }
Emmanuel Hocdetfe616562013-01-22 15:31:15 +0100639 }
Emmanuel Hocdetfe616562013-01-22 15:31:15 +0100640 fclose(f);
641 return cfgerr;
642}
643
Emeric Brunfc0421f2012-09-07 17:30:07 +0200644#ifndef SSL_OP_CIPHER_SERVER_PREFERENCE /* needs OpenSSL >= 0.9.7 */
645#define SSL_OP_CIPHER_SERVER_PREFERENCE 0
646#endif
647
648#ifndef SSL_OP_NO_SESSION_RESUMPTION_ON_RENEGOTIATION /* needs OpenSSL >= 0.9.7 */
649#define SSL_OP_NO_SESSION_RESUMPTION_ON_RENEGOTIATION 0
Willy Tarreau7d588ee2012-11-26 18:47:31 +0100650#define SSL_renegotiate_pending(arg) 0
Emeric Brunfc0421f2012-09-07 17:30:07 +0200651#endif
Emeric Brun2b58d042012-09-20 17:10:03 +0200652#ifndef SSL_OP_SINGLE_ECDH_USE /* needs OpenSSL >= 0.9.8 */
653#define SSL_OP_SINGLE_ECDH_USE 0
654#endif
Emeric Brun2d0c4822012-10-02 13:45:20 +0200655#ifndef SSL_OP_NO_TICKET /* needs OpenSSL >= 0.9.8 */
656#define SSL_OP_NO_TICKET 0
657#endif
Emeric Brunfc0421f2012-09-07 17:30:07 +0200658#ifndef SSL_OP_NO_COMPRESSION /* needs OpenSSL >= 0.9.9 */
659#define SSL_OP_NO_COMPRESSION 0
660#endif
Emeric Brunc0ff4922012-09-28 19:37:02 +0200661#ifndef SSL_OP_NO_TLSv1_1 /* needs OpenSSL >= 1.0.1 */
662#define SSL_OP_NO_TLSv1_1 0
663#endif
664#ifndef SSL_OP_NO_TLSv1_2 /* needs OpenSSL >= 1.0.1 */
665#define SSL_OP_NO_TLSv1_2 0
666#endif
Emeric Bruna4bcd9a2012-09-20 16:19:02 +0200667#ifndef SSL_OP_SINGLE_DH_USE /* needs OpenSSL >= 0.9.6 */
668#define SSL_OP_SINGLE_DH_USE 0
669#endif
Emeric Brun2b58d042012-09-20 17:10:03 +0200670#ifndef SSL_OP_SINGLE_ECDH_USE /* needs OpenSSL >= 1.0.0 */
671#define SSL_OP_SINGLE_ECDH_USE 0
672#endif
Emeric Brunfc0421f2012-09-07 17:30:07 +0200673#ifndef SSL_MODE_RELEASE_BUFFERS /* needs OpenSSL >= 1.0.0 */
674#define SSL_MODE_RELEASE_BUFFERS 0
675#endif
Willy Tarreau2a65ff02012-09-13 17:54:29 +0200676int ssl_sock_prepare_ctx(struct bind_conf *bind_conf, SSL_CTX *ctx, struct proxy *curproxy)
Emeric Brunfc0421f2012-09-07 17:30:07 +0200677{
678 int cfgerr = 0;
Emeric Brun850efd52014-01-29 12:24:34 +0100679 int verify = SSL_VERIFY_NONE;
Emeric Brunfc0421f2012-09-07 17:30:07 +0200680 int ssloptions =
681 SSL_OP_ALL | /* all known workarounds for bugs */
682 SSL_OP_NO_SSLv2 |
683 SSL_OP_NO_COMPRESSION |
Emeric Bruna4bcd9a2012-09-20 16:19:02 +0200684 SSL_OP_SINGLE_DH_USE |
Emeric Brun2b58d042012-09-20 17:10:03 +0200685 SSL_OP_SINGLE_ECDH_USE |
Emeric Brun3c4bc6e2012-10-04 18:44:19 +0200686 SSL_OP_NO_SESSION_RESUMPTION_ON_RENEGOTIATION |
687 SSL_OP_CIPHER_SERVER_PREFERENCE;
Emeric Brunfc0421f2012-09-07 17:30:07 +0200688 int sslmode =
689 SSL_MODE_ENABLE_PARTIAL_WRITE |
690 SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER |
691 SSL_MODE_RELEASE_BUFFERS;
692
Thierry Fournier383085f2013-01-24 14:15:43 +0100693 /* Make sure openssl opens /dev/urandom before the chroot */
694 if (!ssl_initialize_random()) {
695 Alert("OpenSSL random data generator initialization failed.\n");
696 cfgerr++;
697 }
698
Emeric Brun89675492012-10-05 13:48:26 +0200699 if (bind_conf->ssl_options & BC_SSL_O_NO_SSLV3)
Emeric Brunfc0421f2012-09-07 17:30:07 +0200700 ssloptions |= SSL_OP_NO_SSLv3;
Emeric Brun89675492012-10-05 13:48:26 +0200701 if (bind_conf->ssl_options & BC_SSL_O_NO_TLSV10)
Emeric Brunfc0421f2012-09-07 17:30:07 +0200702 ssloptions |= SSL_OP_NO_TLSv1;
Emeric Brun89675492012-10-05 13:48:26 +0200703 if (bind_conf->ssl_options & BC_SSL_O_NO_TLSV11)
Emeric Brunc0ff4922012-09-28 19:37:02 +0200704 ssloptions |= SSL_OP_NO_TLSv1_1;
Emeric Brun89675492012-10-05 13:48:26 +0200705 if (bind_conf->ssl_options & BC_SSL_O_NO_TLSV12)
Emeric Brunc0ff4922012-09-28 19:37:02 +0200706 ssloptions |= SSL_OP_NO_TLSv1_2;
Emeric Brun89675492012-10-05 13:48:26 +0200707 if (bind_conf->ssl_options & BC_SSL_O_NO_TLS_TICKETS)
Emeric Brun2d0c4822012-10-02 13:45:20 +0200708 ssloptions |= SSL_OP_NO_TICKET;
Emeric Brun2cb7ae52012-10-05 14:14:21 +0200709 if (bind_conf->ssl_options & BC_SSL_O_USE_SSLV3)
710 SSL_CTX_set_ssl_version(ctx, SSLv3_server_method());
711 if (bind_conf->ssl_options & BC_SSL_O_USE_TLSV10)
712 SSL_CTX_set_ssl_version(ctx, TLSv1_server_method());
713#if SSL_OP_NO_TLSv1_1
714 if (bind_conf->ssl_options & BC_SSL_O_USE_TLSV11)
715 SSL_CTX_set_ssl_version(ctx, TLSv1_1_server_method());
716#endif
717#if SSL_OP_NO_TLSv1_2
718 if (bind_conf->ssl_options & BC_SSL_O_USE_TLSV12)
719 SSL_CTX_set_ssl_version(ctx, TLSv1_2_server_method());
720#endif
Emeric Brunfc0421f2012-09-07 17:30:07 +0200721
722 SSL_CTX_set_options(ctx, ssloptions);
723 SSL_CTX_set_mode(ctx, sslmode);
Emeric Brun850efd52014-01-29 12:24:34 +0100724 switch (bind_conf->verify) {
725 case SSL_SOCK_VERIFY_NONE:
726 verify = SSL_VERIFY_NONE;
727 break;
728 case SSL_SOCK_VERIFY_OPTIONAL:
729 verify = SSL_VERIFY_PEER;
730 break;
731 case SSL_SOCK_VERIFY_REQUIRED:
732 verify = SSL_VERIFY_PEER|SSL_VERIFY_FAIL_IF_NO_PEER_CERT;
733 break;
734 }
735 SSL_CTX_set_verify(ctx, verify, ssl_sock_bind_verifycbk);
736 if (verify & SSL_VERIFY_PEER) {
Emeric Brunfb510ea2012-10-05 12:00:26 +0200737 if (bind_conf->ca_file) {
Emeric Brund94b3fe2012-09-20 18:23:56 +0200738 /* load CAfile to verify */
Emeric Brunfb510ea2012-10-05 12:00:26 +0200739 if (!SSL_CTX_load_verify_locations(ctx, bind_conf->ca_file, NULL)) {
Emeric Brund94b3fe2012-09-20 18:23:56 +0200740 Alert("Proxy '%s': unable to load CA file '%s' for bind '%s' at [%s:%d].\n",
Emeric Brunfb510ea2012-10-05 12:00:26 +0200741 curproxy->id, bind_conf->ca_file, bind_conf->arg, bind_conf->file, bind_conf->line);
Emeric Brund94b3fe2012-09-20 18:23:56 +0200742 cfgerr++;
743 }
744 /* set CA names fo client cert request, function returns void */
Emeric Brunfb510ea2012-10-05 12:00:26 +0200745 SSL_CTX_set_client_CA_list(ctx, SSL_load_client_CA_file(bind_conf->ca_file));
Emeric Brund94b3fe2012-09-20 18:23:56 +0200746 }
Emeric Brun850efd52014-01-29 12:24:34 +0100747 else {
748 Alert("Proxy '%s': verify is enabled but no CA file specified for bind '%s' at [%s:%d].\n",
749 curproxy->id, bind_conf->arg, bind_conf->file, bind_conf->line);
750 cfgerr++;
751 }
Emeric Brun051cdab2012-10-02 19:25:50 +0200752#ifdef X509_V_FLAG_CRL_CHECK
Emeric Brunfb510ea2012-10-05 12:00:26 +0200753 if (bind_conf->crl_file) {
Emeric Brund94b3fe2012-09-20 18:23:56 +0200754 X509_STORE *store = SSL_CTX_get_cert_store(ctx);
755
Emeric Brunfb510ea2012-10-05 12:00:26 +0200756 if (!store || !X509_STORE_load_locations(store, bind_conf->crl_file, NULL)) {
Emeric Brund94b3fe2012-09-20 18:23:56 +0200757 Alert("Proxy '%s': unable to configure CRL file '%s' for bind '%s' at [%s:%d].\n",
Emeric Brunfb510ea2012-10-05 12:00:26 +0200758 curproxy->id, bind_conf->ca_file, bind_conf->arg, bind_conf->file, bind_conf->line);
Emeric Brund94b3fe2012-09-20 18:23:56 +0200759 cfgerr++;
760 }
Emeric Brun561e5742012-10-02 15:20:55 +0200761 else {
762 X509_STORE_set_flags(store, X509_V_FLAG_CRL_CHECK|X509_V_FLAG_CRL_CHECK_ALL);
763 }
Emeric Brund94b3fe2012-09-20 18:23:56 +0200764 }
Emeric Brun051cdab2012-10-02 19:25:50 +0200765#endif
Emeric Brun644cde02012-12-14 11:21:13 +0100766 ERR_clear_error();
Emeric Brund94b3fe2012-09-20 18:23:56 +0200767 }
Emeric Brunfc0421f2012-09-07 17:30:07 +0200768
Emeric Brun4f65bff2012-11-16 15:11:00 +0100769 if (global.tune.ssllifetime)
770 SSL_CTX_set_timeout(ctx, global.tune.ssllifetime);
771
Emeric Brunfc0421f2012-09-07 17:30:07 +0200772 shared_context_set_cache(ctx);
Willy Tarreau2a65ff02012-09-13 17:54:29 +0200773 if (bind_conf->ciphers &&
774 !SSL_CTX_set_cipher_list(ctx, bind_conf->ciphers)) {
Emeric Brunfc0421f2012-09-07 17:30:07 +0200775 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 +0200776 curproxy->id, bind_conf->ciphers, bind_conf->arg, bind_conf->file, bind_conf->line);
Emeric Brunfc0421f2012-09-07 17:30:07 +0200777 cfgerr++;
778 }
779
780 SSL_CTX_set_info_callback(ctx, ssl_sock_infocbk);
Willy Tarreau6c9a3d52012-10-18 18:57:14 +0200781#ifdef OPENSSL_NPN_NEGOTIATED
782 if (bind_conf->npn_str)
783 SSL_CTX_set_next_protos_advertised_cb(ctx, ssl_sock_advertise_npn_protos, bind_conf);
784#endif
Willy Tarreauab861d32013-04-02 02:30:41 +0200785#ifdef OPENSSL_ALPN_NEGOTIATED
786 if (bind_conf->alpn_str)
787 SSL_CTX_set_alpn_advertised_cb(ctx, ssl_sock_advertise_alpn_protos, bind_conf);
788#endif
Willy Tarreau6c9a3d52012-10-18 18:57:14 +0200789
Emeric Brunfc0421f2012-09-07 17:30:07 +0200790#ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME
791 SSL_CTX_set_tlsext_servername_callback(ctx, ssl_sock_switchctx_cbk);
Willy Tarreau2a65ff02012-09-13 17:54:29 +0200792 SSL_CTX_set_tlsext_servername_arg(ctx, bind_conf);
Emeric Brunfc0421f2012-09-07 17:30:07 +0200793#endif
Emeric Brun2b58d042012-09-20 17:10:03 +0200794#if defined(SSL_CTX_set_tmp_ecdh) && !defined(OPENSSL_NO_ECDH)
Emeric Brun6924ef82013-03-06 14:08:53 +0100795 {
Emeric Brun2b58d042012-09-20 17:10:03 +0200796 int i;
797 EC_KEY *ecdh;
798
Emeric Brun6924ef82013-03-06 14:08:53 +0100799 i = OBJ_sn2nid(bind_conf->ecdhe ? bind_conf->ecdhe : ECDHE_DEFAULT_CURVE);
Emeric Brun2b58d042012-09-20 17:10:03 +0200800 if (!i || ((ecdh = EC_KEY_new_by_curve_name(i)) == NULL)) {
801 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 +0100802 curproxy->id, bind_conf->ecdhe ? bind_conf->ecdhe : ECDHE_DEFAULT_CURVE,
803 bind_conf->arg, bind_conf->file, bind_conf->line);
Emeric Brun2b58d042012-09-20 17:10:03 +0200804 cfgerr++;
805 }
806 else {
807 SSL_CTX_set_tmp_ecdh(ctx, ecdh);
808 EC_KEY_free(ecdh);
809 }
810 }
811#endif
812
Emeric Brunfc0421f2012-09-07 17:30:07 +0200813 return cfgerr;
814}
815
Evan Broderbe554312013-06-27 00:05:25 -0700816static int ssl_sock_srv_hostcheck(const char *pattern, const char *hostname)
817{
818 const char *pattern_wildcard, *pattern_left_label_end, *hostname_left_label_end;
819 size_t prefixlen, suffixlen;
820
821 /* Trivial case */
822 if (strcmp(pattern, hostname) == 0)
823 return 1;
824
Evan Broderbe554312013-06-27 00:05:25 -0700825 /* The rest of this logic is based on RFC 6125, section 6.4.3
826 * (http://tools.ietf.org/html/rfc6125#section-6.4.3) */
827
Emeric Bruna848dae2013-10-08 11:27:28 +0200828 pattern_wildcard = NULL;
829 pattern_left_label_end = pattern;
830 while (*pattern_left_label_end != '.') {
831 switch (*pattern_left_label_end) {
832 case 0:
833 /* End of label not found */
834 return 0;
835 case '*':
836 /* If there is more than one wildcards */
837 if (pattern_wildcard)
838 return 0;
839 pattern_wildcard = pattern_left_label_end;
840 break;
841 }
842 pattern_left_label_end++;
843 }
844
845 /* If it's not trivial and there is no wildcard, it can't
846 * match */
847 if (!pattern_wildcard)
Evan Broderbe554312013-06-27 00:05:25 -0700848 return 0;
849
850 /* Make sure all labels match except the leftmost */
851 hostname_left_label_end = strchr(hostname, '.');
852 if (!hostname_left_label_end
853 || strcmp(pattern_left_label_end, hostname_left_label_end) != 0)
854 return 0;
855
856 /* Make sure the leftmost label of the hostname is long enough
857 * that the wildcard can match */
Emeric Brun369da852013-10-08 11:39:35 +0200858 if (hostname_left_label_end - hostname < (pattern_left_label_end - pattern) - 1)
Evan Broderbe554312013-06-27 00:05:25 -0700859 return 0;
860
861 /* Finally compare the string on either side of the
862 * wildcard */
863 prefixlen = pattern_wildcard - pattern;
864 suffixlen = pattern_left_label_end - (pattern_wildcard + 1);
Emeric Bruna848dae2013-10-08 11:27:28 +0200865 if ((prefixlen && (memcmp(pattern, hostname, prefixlen) != 0))
866 || (suffixlen && (memcmp(pattern_wildcard + 1, hostname_left_label_end - suffixlen, suffixlen) != 0)))
Evan Broderbe554312013-06-27 00:05:25 -0700867 return 0;
868
869 return 1;
870}
871
872static int ssl_sock_srv_verifycbk(int ok, X509_STORE_CTX *ctx)
873{
874 SSL *ssl;
875 struct connection *conn;
876 char *servername;
877
878 int depth;
879 X509 *cert;
880 STACK_OF(GENERAL_NAME) *alt_names;
881 int i;
882 X509_NAME *cert_subject;
883 char *str;
884
885 if (ok == 0)
886 return ok;
887
888 ssl = X509_STORE_CTX_get_ex_data(ctx, SSL_get_ex_data_X509_STORE_CTX_idx());
889 conn = (struct connection *)SSL_get_app_data(ssl);
890
891 servername = objt_server(conn->target)->ssl_ctx.verify_host;
892
893 /* We only need to verify the CN on the actual server cert,
894 * not the indirect CAs */
895 depth = X509_STORE_CTX_get_error_depth(ctx);
896 if (depth != 0)
897 return ok;
898
899 /* At this point, the cert is *not* OK unless we can find a
900 * hostname match */
901 ok = 0;
902
903 cert = X509_STORE_CTX_get_current_cert(ctx);
904 /* It seems like this might happen if verify peer isn't set */
905 if (!cert)
906 return ok;
907
908 alt_names = X509_get_ext_d2i(cert, NID_subject_alt_name, NULL, NULL);
909 if (alt_names) {
910 for (i = 0; !ok && i < sk_GENERAL_NAME_num(alt_names); i++) {
911 GENERAL_NAME *name = sk_GENERAL_NAME_value(alt_names, i);
912 if (name->type == GEN_DNS) {
Emeric Bruna33410c2013-09-17 15:47:48 +0200913#if OPENSSL_VERSION_NUMBER < 0x00907000L
914 if (ASN1_STRING_to_UTF8((unsigned char **)&str, name->d.ia5) >= 0) {
915#else
Evan Broderbe554312013-06-27 00:05:25 -0700916 if (ASN1_STRING_to_UTF8((unsigned char **)&str, name->d.dNSName) >= 0) {
Emeric Bruna33410c2013-09-17 15:47:48 +0200917#endif
Evan Broderbe554312013-06-27 00:05:25 -0700918 ok = ssl_sock_srv_hostcheck(str, servername);
919 OPENSSL_free(str);
920 }
921 }
922 }
Emeric Brun4ad50a42013-09-17 15:19:54 +0200923 sk_GENERAL_NAME_pop_free(alt_names, GENERAL_NAME_free);
Evan Broderbe554312013-06-27 00:05:25 -0700924 }
925
926 cert_subject = X509_get_subject_name(cert);
927 i = -1;
928 while (!ok && (i = X509_NAME_get_index_by_NID(cert_subject, NID_commonName, i)) != -1) {
929 X509_NAME_ENTRY *entry = X509_NAME_get_entry(cert_subject, i);
930 if (ASN1_STRING_to_UTF8((unsigned char **)&str, entry->value) >= 0) {
931 ok = ssl_sock_srv_hostcheck(str, servername);
932 OPENSSL_free(str);
933 }
934 }
935
936 return ok;
937}
938
Emeric Brun94324a42012-10-11 14:00:19 +0200939/* prepare ssl context from servers options. Returns an error count */
940int ssl_sock_prepare_srv_ctx(struct server *srv, struct proxy *curproxy)
941{
942 int cfgerr = 0;
943 int options =
944 SSL_OP_ALL | /* all known workarounds for bugs */
945 SSL_OP_NO_SSLv2 |
946 SSL_OP_NO_COMPRESSION;
947 int mode =
948 SSL_MODE_ENABLE_PARTIAL_WRITE |
949 SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER |
950 SSL_MODE_RELEASE_BUFFERS;
Emeric Brun850efd52014-01-29 12:24:34 +0100951 int verify = SSL_VERIFY_NONE;
Emeric Brun94324a42012-10-11 14:00:19 +0200952
Thierry Fournier383085f2013-01-24 14:15:43 +0100953 /* Make sure openssl opens /dev/urandom before the chroot */
954 if (!ssl_initialize_random()) {
955 Alert("OpenSSL random data generator initialization failed.\n");
956 cfgerr++;
957 }
958
Emeric Brun94324a42012-10-11 14:00:19 +0200959 /* Initiate SSL context for current server */
960 srv->ssl_ctx.reused_sess = NULL;
961 if (srv->use_ssl)
962 srv->xprt = &ssl_sock;
963 if (srv->check.use_ssl)
Simon Horman66183002013-02-23 10:16:43 +0900964 srv->check_common.xprt = &ssl_sock;
Emeric Brun94324a42012-10-11 14:00:19 +0200965
966 srv->ssl_ctx.ctx = SSL_CTX_new(SSLv23_client_method());
967 if (!srv->ssl_ctx.ctx) {
968 Alert("config : %s '%s', server '%s': unable to allocate ssl context.\n",
969 proxy_type_str(curproxy), curproxy->id,
970 srv->id);
971 cfgerr++;
972 return cfgerr;
973 }
Emeric Bruna7aa3092012-10-26 12:58:00 +0200974 if (srv->ssl_ctx.client_crt) {
975 if (SSL_CTX_use_PrivateKey_file(srv->ssl_ctx.ctx, srv->ssl_ctx.client_crt, SSL_FILETYPE_PEM) <= 0) {
976 Alert("config : %s '%s', server '%s': unable to load SSL private key from PEM file '%s'.\n",
977 proxy_type_str(curproxy), curproxy->id,
978 srv->id, srv->ssl_ctx.client_crt);
979 cfgerr++;
980 }
981 else if (SSL_CTX_use_certificate_chain_file(srv->ssl_ctx.ctx, srv->ssl_ctx.client_crt) <= 0) {
982 Alert("config : %s '%s', server '%s': unable to load ssl certificate 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_check_private_key(srv->ssl_ctx.ctx) <= 0) {
988 Alert("config : %s '%s', server '%s': inconsistencies between private key and certificate loaded from PEM file '%s'.\n",
989 proxy_type_str(curproxy), curproxy->id,
990 srv->id, srv->ssl_ctx.client_crt);
991 cfgerr++;
992 }
993 }
Emeric Brun94324a42012-10-11 14:00:19 +0200994
995 if (srv->ssl_ctx.options & SRV_SSL_O_NO_SSLV3)
996 options |= SSL_OP_NO_SSLv3;
997 if (srv->ssl_ctx.options & SRV_SSL_O_NO_TLSV10)
998 options |= SSL_OP_NO_TLSv1;
999 if (srv->ssl_ctx.options & SRV_SSL_O_NO_TLSV11)
1000 options |= SSL_OP_NO_TLSv1_1;
1001 if (srv->ssl_ctx.options & SRV_SSL_O_NO_TLSV12)
1002 options |= SSL_OP_NO_TLSv1_2;
Emeric Brunf9c5c472012-10-11 15:28:34 +02001003 if (srv->ssl_ctx.options & SRV_SSL_O_NO_TLS_TICKETS)
1004 options |= SSL_OP_NO_TICKET;
Emeric Brun94324a42012-10-11 14:00:19 +02001005 if (srv->ssl_ctx.options & SRV_SSL_O_USE_SSLV3)
1006 SSL_CTX_set_ssl_version(srv->ssl_ctx.ctx, SSLv3_client_method());
1007 if (srv->ssl_ctx.options & SRV_SSL_O_USE_TLSV10)
1008 SSL_CTX_set_ssl_version(srv->ssl_ctx.ctx, TLSv1_client_method());
1009#if SSL_OP_NO_TLSv1_1
1010 if (srv->ssl_ctx.options & SRV_SSL_O_USE_TLSV11)
1011 SSL_CTX_set_ssl_version(srv->ssl_ctx.ctx, TLSv1_1_client_method());
1012#endif
1013#if SSL_OP_NO_TLSv1_2
1014 if (srv->ssl_ctx.options & SRV_SSL_O_USE_TLSV12)
1015 SSL_CTX_set_ssl_version(srv->ssl_ctx.ctx, TLSv1_2_client_method());
1016#endif
1017
1018 SSL_CTX_set_options(srv->ssl_ctx.ctx, options);
1019 SSL_CTX_set_mode(srv->ssl_ctx.ctx, mode);
Emeric Brun850efd52014-01-29 12:24:34 +01001020
1021 if (global.ssl_server_verify == SSL_SERVER_VERIFY_REQUIRED)
1022 verify = SSL_VERIFY_PEER;
1023
1024 switch (srv->ssl_ctx.verify) {
1025 case SSL_SOCK_VERIFY_NONE:
1026 verify = SSL_VERIFY_NONE;
1027 break;
1028 case SSL_SOCK_VERIFY_REQUIRED:
1029 verify = SSL_VERIFY_PEER;
1030 break;
1031 }
Evan Broderbe554312013-06-27 00:05:25 -07001032 SSL_CTX_set_verify(srv->ssl_ctx.ctx,
Emeric Brun850efd52014-01-29 12:24:34 +01001033 verify,
Evan Broderbe554312013-06-27 00:05:25 -07001034 srv->ssl_ctx.verify_host ? ssl_sock_srv_verifycbk : NULL);
Emeric Brun850efd52014-01-29 12:24:34 +01001035 if (verify & SSL_VERIFY_PEER) {
Emeric Brunef42d922012-10-11 16:11:36 +02001036 if (srv->ssl_ctx.ca_file) {
1037 /* load CAfile to verify */
1038 if (!SSL_CTX_load_verify_locations(srv->ssl_ctx.ctx, srv->ssl_ctx.ca_file, NULL)) {
1039 Alert("Proxy '%s', server '%s' |%s:%d] unable to load CA file '%s'.\n",
1040 curproxy->id, srv->id,
1041 srv->conf.file, srv->conf.line, srv->ssl_ctx.ca_file);
1042 cfgerr++;
1043 }
1044 }
Emeric Brun850efd52014-01-29 12:24:34 +01001045 else {
1046 if (global.ssl_server_verify == SSL_SERVER_VERIFY_REQUIRED)
1047 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",
1048 curproxy->id, srv->id,
1049 srv->conf.file, srv->conf.line);
1050 else
1051 Alert("Proxy '%s', server '%s' |%s:%d] verify is enabled but no CA file specified.\n",
1052 curproxy->id, srv->id,
1053 srv->conf.file, srv->conf.line);
1054 cfgerr++;
1055 }
Emeric Brunef42d922012-10-11 16:11:36 +02001056#ifdef X509_V_FLAG_CRL_CHECK
1057 if (srv->ssl_ctx.crl_file) {
1058 X509_STORE *store = SSL_CTX_get_cert_store(srv->ssl_ctx.ctx);
1059
1060 if (!store || !X509_STORE_load_locations(store, srv->ssl_ctx.crl_file, NULL)) {
1061 Alert("Proxy '%s', server '%s' |%s:%d] unable to configure CRL file '%s'.\n",
1062 curproxy->id, srv->id,
1063 srv->conf.file, srv->conf.line, srv->ssl_ctx.crl_file);
1064 cfgerr++;
1065 }
1066 else {
1067 X509_STORE_set_flags(store, X509_V_FLAG_CRL_CHECK|X509_V_FLAG_CRL_CHECK_ALL);
1068 }
1069 }
1070#endif
1071 }
1072
Emeric Brun4f65bff2012-11-16 15:11:00 +01001073 if (global.tune.ssllifetime)
1074 SSL_CTX_set_timeout(srv->ssl_ctx.ctx, global.tune.ssllifetime);
1075
Emeric Brun94324a42012-10-11 14:00:19 +02001076 SSL_CTX_set_session_cache_mode(srv->ssl_ctx.ctx, SSL_SESS_CACHE_OFF);
1077 if (srv->ssl_ctx.ciphers &&
1078 !SSL_CTX_set_cipher_list(srv->ssl_ctx.ctx, srv->ssl_ctx.ciphers)) {
1079 Alert("Proxy '%s', server '%s' [%s:%d] : unable to set SSL cipher list to '%s'.\n",
1080 curproxy->id, srv->id,
1081 srv->conf.file, srv->conf.line, srv->ssl_ctx.ciphers);
1082 cfgerr++;
1083 }
1084
1085 return cfgerr;
1086}
1087
Willy Tarreau2a65ff02012-09-13 17:54:29 +02001088/* Walks down the two trees in bind_conf and prepares all certs. The pointer may
Emeric Brunfc0421f2012-09-07 17:30:07 +02001089 * be NULL, in which case nothing is done. Returns the number of errors
1090 * encountered.
1091 */
Willy Tarreau2a65ff02012-09-13 17:54:29 +02001092int ssl_sock_prepare_all_ctx(struct bind_conf *bind_conf, struct proxy *px)
Emeric Brunfc0421f2012-09-07 17:30:07 +02001093{
1094 struct ebmb_node *node;
1095 struct sni_ctx *sni;
1096 int err = 0;
1097
Willy Tarreau2a65ff02012-09-13 17:54:29 +02001098 if (!bind_conf || !bind_conf->is_ssl)
Emeric Brunfc0421f2012-09-07 17:30:07 +02001099 return 0;
1100
Willy Tarreau2a65ff02012-09-13 17:54:29 +02001101 node = ebmb_first(&bind_conf->sni_ctx);
Emeric Brunfc0421f2012-09-07 17:30:07 +02001102 while (node) {
1103 sni = ebmb_entry(node, struct sni_ctx, name);
1104 if (!sni->order) /* only initialize the CTX on its first occurrence */
Willy Tarreau2a65ff02012-09-13 17:54:29 +02001105 err += ssl_sock_prepare_ctx(bind_conf, sni->ctx, px);
Emeric Brunfc0421f2012-09-07 17:30:07 +02001106 node = ebmb_next(node);
1107 }
1108
Willy Tarreau2a65ff02012-09-13 17:54:29 +02001109 node = ebmb_first(&bind_conf->sni_w_ctx);
Emeric Brunfc0421f2012-09-07 17:30:07 +02001110 while (node) {
1111 sni = ebmb_entry(node, struct sni_ctx, name);
1112 if (!sni->order) /* only initialize the CTX on its first occurrence */
Willy Tarreau2a65ff02012-09-13 17:54:29 +02001113 err += ssl_sock_prepare_ctx(bind_conf, sni->ctx, px);
Emeric Brunfc0421f2012-09-07 17:30:07 +02001114 node = ebmb_next(node);
1115 }
1116 return err;
1117}
1118
Willy Tarreau2a65ff02012-09-13 17:54:29 +02001119/* Walks down the two trees in bind_conf and frees all the certs. The pointer may
Emeric Brunfc0421f2012-09-07 17:30:07 +02001120 * be NULL, in which case nothing is done. The default_ctx is nullified too.
1121 */
Willy Tarreau2a65ff02012-09-13 17:54:29 +02001122void ssl_sock_free_all_ctx(struct bind_conf *bind_conf)
Emeric Brunfc0421f2012-09-07 17:30:07 +02001123{
1124 struct ebmb_node *node, *back;
1125 struct sni_ctx *sni;
1126
Willy Tarreau2a65ff02012-09-13 17:54:29 +02001127 if (!bind_conf || !bind_conf->is_ssl)
Emeric Brunfc0421f2012-09-07 17:30:07 +02001128 return;
1129
Willy Tarreau2a65ff02012-09-13 17:54:29 +02001130 node = ebmb_first(&bind_conf->sni_ctx);
Emeric Brunfc0421f2012-09-07 17:30:07 +02001131 while (node) {
1132 sni = ebmb_entry(node, struct sni_ctx, name);
1133 back = ebmb_next(node);
1134 ebmb_delete(node);
1135 if (!sni->order) /* only free the CTX on its first occurrence */
1136 SSL_CTX_free(sni->ctx);
1137 free(sni);
1138 node = back;
1139 }
1140
Willy Tarreau2a65ff02012-09-13 17:54:29 +02001141 node = ebmb_first(&bind_conf->sni_w_ctx);
Emeric Brunfc0421f2012-09-07 17:30:07 +02001142 while (node) {
1143 sni = ebmb_entry(node, struct sni_ctx, name);
1144 back = ebmb_next(node);
1145 ebmb_delete(node);
1146 if (!sni->order) /* only free the CTX on its first occurrence */
1147 SSL_CTX_free(sni->ctx);
1148 free(sni);
1149 node = back;
1150 }
1151
Willy Tarreau2a65ff02012-09-13 17:54:29 +02001152 bind_conf->default_ctx = NULL;
Emeric Brune1f38db2012-09-03 20:36:47 +02001153}
1154
Emeric Brun46591952012-05-18 15:47:34 +02001155/*
1156 * This function is called if SSL * context is not yet allocated. The function
1157 * is designed to be called before any other data-layer operation and sets the
1158 * handshake flag on the connection. It is safe to call it multiple times.
1159 * It returns 0 on success and -1 in error case.
1160 */
1161static int ssl_sock_init(struct connection *conn)
1162{
1163 /* already initialized */
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02001164 if (conn->xprt_ctx)
Emeric Brun46591952012-05-18 15:47:34 +02001165 return 0;
1166
Willy Tarreau3c728722014-01-23 13:50:42 +01001167 if (!conn_ctrl_ready(conn))
Willy Tarreauf79c8172013-10-21 16:30:56 +02001168 return 0;
1169
Willy Tarreau20879a02012-12-03 16:32:10 +01001170 if (global.maxsslconn && sslconns >= global.maxsslconn) {
1171 conn->err_code = CO_ER_SSL_TOO_MANY;
Willy Tarreau403edff2012-09-06 11:58:37 +02001172 return -1;
Willy Tarreau20879a02012-12-03 16:32:10 +01001173 }
Willy Tarreau403edff2012-09-06 11:58:37 +02001174
Emeric Brun46591952012-05-18 15:47:34 +02001175 /* If it is in client mode initiate SSL session
1176 in connect state otherwise accept state */
Willy Tarreau3fdb3662012-11-12 00:42:33 +01001177 if (objt_server(conn->target)) {
Emeric Brun46591952012-05-18 15:47:34 +02001178 /* Alloc a new SSL session ctx */
Willy Tarreau3fdb3662012-11-12 00:42:33 +01001179 conn->xprt_ctx = SSL_new(objt_server(conn->target)->ssl_ctx.ctx);
Willy Tarreau20879a02012-12-03 16:32:10 +01001180 if (!conn->xprt_ctx) {
1181 conn->err_code = CO_ER_SSL_NO_MEM;
Emeric Brun46591952012-05-18 15:47:34 +02001182 return -1;
Willy Tarreau20879a02012-12-03 16:32:10 +01001183 }
Emeric Brun46591952012-05-18 15:47:34 +02001184
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02001185 SSL_set_connect_state(conn->xprt_ctx);
Willy Tarreau3fdb3662012-11-12 00:42:33 +01001186 if (objt_server(conn->target)->ssl_ctx.reused_sess)
1187 SSL_set_session(conn->xprt_ctx, objt_server(conn->target)->ssl_ctx.reused_sess);
Emeric Brun46591952012-05-18 15:47:34 +02001188
1189 /* set fd on SSL session context */
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02001190 SSL_set_fd(conn->xprt_ctx, conn->t.sock.fd);
Emeric Brun46591952012-05-18 15:47:34 +02001191
Evan Broderbe554312013-06-27 00:05:25 -07001192 /* set connection pointer */
1193 SSL_set_app_data(conn->xprt_ctx, conn);
1194
Emeric Brun46591952012-05-18 15:47:34 +02001195 /* leave init state and start handshake */
Willy Tarreau05737472012-09-04 08:03:39 +02001196 conn->flags |= CO_FL_SSL_WAIT_HS | CO_FL_WAIT_L6_CONN;
Willy Tarreau403edff2012-09-06 11:58:37 +02001197
1198 sslconns++;
Willy Tarreau71b734c2014-01-28 15:19:44 +01001199 totalsslconns++;
Emeric Brun46591952012-05-18 15:47:34 +02001200 return 0;
1201 }
Willy Tarreau3fdb3662012-11-12 00:42:33 +01001202 else if (objt_listener(conn->target)) {
Emeric Brun46591952012-05-18 15:47:34 +02001203 /* Alloc a new SSL session ctx */
Willy Tarreau3fdb3662012-11-12 00:42:33 +01001204 conn->xprt_ctx = SSL_new(objt_listener(conn->target)->bind_conf->default_ctx);
Willy Tarreau20879a02012-12-03 16:32:10 +01001205 if (!conn->xprt_ctx) {
1206 conn->err_code = CO_ER_SSL_NO_MEM;
Emeric Brun46591952012-05-18 15:47:34 +02001207 return -1;
Willy Tarreau20879a02012-12-03 16:32:10 +01001208 }
Emeric Brun46591952012-05-18 15:47:34 +02001209
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02001210 SSL_set_accept_state(conn->xprt_ctx);
Emeric Brun46591952012-05-18 15:47:34 +02001211
1212 /* set fd on SSL session context */
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02001213 SSL_set_fd(conn->xprt_ctx, conn->t.sock.fd);
Emeric Brun46591952012-05-18 15:47:34 +02001214
Emeric Brune1f38db2012-09-03 20:36:47 +02001215 /* set connection pointer */
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02001216 SSL_set_app_data(conn->xprt_ctx, conn);
Emeric Brune1f38db2012-09-03 20:36:47 +02001217
Emeric Brun46591952012-05-18 15:47:34 +02001218 /* leave init state and start handshake */
Willy Tarreau05737472012-09-04 08:03:39 +02001219 conn->flags |= CO_FL_SSL_WAIT_HS | CO_FL_WAIT_L6_CONN;
Willy Tarreau403edff2012-09-06 11:58:37 +02001220
1221 sslconns++;
Willy Tarreau71b734c2014-01-28 15:19:44 +01001222 totalsslconns++;
Emeric Brun46591952012-05-18 15:47:34 +02001223 return 0;
1224 }
1225 /* don't know how to handle such a target */
Willy Tarreau20879a02012-12-03 16:32:10 +01001226 conn->err_code = CO_ER_SSL_NO_TARGET;
Emeric Brun46591952012-05-18 15:47:34 +02001227 return -1;
1228}
1229
1230
1231/* This is the callback which is used when an SSL handshake is pending. It
1232 * updates the FD status if it wants some polling before being called again.
1233 * It returns 0 if it fails in a fatal way or needs to poll to go further,
1234 * otherwise it returns non-zero and removes itself from the connection's
1235 * flags (the bit is provided in <flag> by the caller).
1236 */
1237int ssl_sock_handshake(struct connection *conn, unsigned int flag)
1238{
1239 int ret;
1240
Willy Tarreau3c728722014-01-23 13:50:42 +01001241 if (!conn_ctrl_ready(conn))
Willy Tarreauf79c8172013-10-21 16:30:56 +02001242 return 0;
1243
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02001244 if (!conn->xprt_ctx)
Emeric Brun46591952012-05-18 15:47:34 +02001245 goto out_error;
1246
Emeric Brun674b7432012-11-08 19:21:55 +01001247 /* If we use SSL_do_handshake to process a reneg initiated by
1248 * the remote peer, it sometimes returns SSL_ERROR_SSL.
1249 * Usually SSL_write and SSL_read are used and process implicitly
1250 * the reneg handshake.
1251 * Here we use SSL_peek as a workaround for reneg.
1252 */
1253 if ((conn->flags & CO_FL_CONNECTED) && SSL_renegotiate_pending(conn->xprt_ctx)) {
1254 char c;
1255
1256 ret = SSL_peek(conn->xprt_ctx, &c, 1);
1257 if (ret <= 0) {
1258 /* handshake may have not been completed, let's find why */
1259 ret = SSL_get_error(conn->xprt_ctx, ret);
1260 if (ret == SSL_ERROR_WANT_WRITE) {
1261 /* SSL handshake needs to write, L4 connection may not be ready */
1262 __conn_sock_stop_recv(conn);
Willy Tarreaue1f50c42014-01-22 20:02:06 +01001263 __conn_sock_want_send(conn);
1264 fd_cant_send(conn->t.sock.fd);
Emeric Brun674b7432012-11-08 19:21:55 +01001265 return 0;
1266 }
1267 else if (ret == SSL_ERROR_WANT_READ) {
1268 /* handshake may have been completed but we have
1269 * no more data to read.
1270 */
1271 if (!SSL_renegotiate_pending(conn->xprt_ctx)) {
1272 ret = 1;
1273 goto reneg_ok;
1274 }
1275 /* SSL handshake needs to read, L4 connection is ready */
1276 if (conn->flags & CO_FL_WAIT_L4_CONN)
1277 conn->flags &= ~CO_FL_WAIT_L4_CONN;
1278 __conn_sock_stop_send(conn);
Willy Tarreaue1f50c42014-01-22 20:02:06 +01001279 __conn_sock_want_recv(conn);
1280 fd_cant_recv(conn->t.sock.fd);
Emeric Brun674b7432012-11-08 19:21:55 +01001281 return 0;
1282 }
1283 else if (ret == SSL_ERROR_SYSCALL) {
1284 /* if errno is null, then connection was successfully established */
1285 if (!errno && conn->flags & CO_FL_WAIT_L4_CONN)
1286 conn->flags &= ~CO_FL_WAIT_L4_CONN;
Willy Tarreau20879a02012-12-03 16:32:10 +01001287 if (!conn->err_code) {
1288 if (!((SSL *)conn->xprt_ctx)->packet_length)
1289 if (!errno)
1290 conn->err_code = CO_ER_SSL_EMPTY;
1291 else
1292 conn->err_code = CO_ER_SSL_ABORT;
1293 else
1294 conn->err_code = CO_ER_SSL_HANDSHAKE;
1295 }
Emeric Brun674b7432012-11-08 19:21:55 +01001296 goto out_error;
1297 }
1298 else {
1299 /* Fail on all other handshake errors */
1300 /* Note: OpenSSL may leave unread bytes in the socket's
1301 * buffer, causing an RST to be emitted upon close() on
1302 * TCP sockets. We first try to drain possibly pending
1303 * data to avoid this as much as possible.
1304 */
Willy Tarreau46be2e52014-01-20 12:10:52 +01001305 conn_drain(conn);
Willy Tarreau20879a02012-12-03 16:32:10 +01001306 if (!conn->err_code)
1307 conn->err_code = CO_ER_SSL_HANDSHAKE;
Emeric Brun674b7432012-11-08 19:21:55 +01001308 goto out_error;
1309 }
1310 }
1311 /* read some data: consider handshake completed */
1312 goto reneg_ok;
1313 }
1314
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02001315 ret = SSL_do_handshake(conn->xprt_ctx);
Emeric Brun46591952012-05-18 15:47:34 +02001316 if (ret != 1) {
1317 /* handshake did not complete, let's find why */
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02001318 ret = SSL_get_error(conn->xprt_ctx, ret);
Emeric Brun46591952012-05-18 15:47:34 +02001319
1320 if (ret == SSL_ERROR_WANT_WRITE) {
1321 /* SSL handshake needs to write, L4 connection may not be ready */
1322 __conn_sock_stop_recv(conn);
Willy Tarreaue1f50c42014-01-22 20:02:06 +01001323 __conn_sock_want_send(conn);
1324 fd_cant_send(conn->t.sock.fd);
Emeric Brun46591952012-05-18 15:47:34 +02001325 return 0;
1326 }
1327 else if (ret == SSL_ERROR_WANT_READ) {
1328 /* SSL handshake needs to read, L4 connection is ready */
1329 if (conn->flags & CO_FL_WAIT_L4_CONN)
1330 conn->flags &= ~CO_FL_WAIT_L4_CONN;
1331 __conn_sock_stop_send(conn);
Willy Tarreaue1f50c42014-01-22 20:02:06 +01001332 __conn_sock_want_recv(conn);
1333 fd_cant_recv(conn->t.sock.fd);
Emeric Brun46591952012-05-18 15:47:34 +02001334 return 0;
1335 }
Willy Tarreau89230192012-09-28 20:22:13 +02001336 else if (ret == SSL_ERROR_SYSCALL) {
1337 /* if errno is null, then connection was successfully established */
1338 if (!errno && conn->flags & CO_FL_WAIT_L4_CONN)
1339 conn->flags &= ~CO_FL_WAIT_L4_CONN;
Willy Tarreau20879a02012-12-03 16:32:10 +01001340
1341 if (!((SSL *)conn->xprt_ctx)->packet_length)
1342 if (!errno)
1343 conn->err_code = CO_ER_SSL_EMPTY;
1344 else
1345 conn->err_code = CO_ER_SSL_ABORT;
1346 else
1347 conn->err_code = CO_ER_SSL_HANDSHAKE;
Willy Tarreau89230192012-09-28 20:22:13 +02001348 goto out_error;
1349 }
Emeric Brun46591952012-05-18 15:47:34 +02001350 else {
1351 /* Fail on all other handshake errors */
Willy Tarreau566dc552012-10-19 20:52:18 +02001352 /* Note: OpenSSL may leave unread bytes in the socket's
1353 * buffer, causing an RST to be emitted upon close() on
1354 * TCP sockets. We first try to drain possibly pending
1355 * data to avoid this as much as possible.
1356 */
Willy Tarreau46be2e52014-01-20 12:10:52 +01001357 conn_drain(conn);
Willy Tarreau20879a02012-12-03 16:32:10 +01001358 if (!conn->err_code)
1359 conn->err_code = CO_ER_SSL_HANDSHAKE;
Emeric Brun46591952012-05-18 15:47:34 +02001360 goto out_error;
1361 }
1362 }
1363
Emeric Brun674b7432012-11-08 19:21:55 +01001364reneg_ok:
1365
Emeric Brun46591952012-05-18 15:47:34 +02001366 /* Handshake succeeded */
Willy Tarreau3fdb3662012-11-12 00:42:33 +01001367 if (objt_server(conn->target)) {
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02001368 if (!SSL_session_reused(conn->xprt_ctx)) {
Emeric Brun46591952012-05-18 15:47:34 +02001369 /* check if session was reused, if not store current session on server for reuse */
Willy Tarreau3fdb3662012-11-12 00:42:33 +01001370 if (objt_server(conn->target)->ssl_ctx.reused_sess)
1371 SSL_SESSION_free(objt_server(conn->target)->ssl_ctx.reused_sess);
Emeric Brun46591952012-05-18 15:47:34 +02001372
Willy Tarreau3fdb3662012-11-12 00:42:33 +01001373 objt_server(conn->target)->ssl_ctx.reused_sess = SSL_get1_session(conn->xprt_ctx);
Emeric Brun46591952012-05-18 15:47:34 +02001374 }
1375 }
1376
1377 /* The connection is now established at both layers, it's time to leave */
1378 conn->flags &= ~(flag | CO_FL_WAIT_L4_CONN | CO_FL_WAIT_L6_CONN);
1379 return 1;
1380
1381 out_error:
Emeric Brun644cde02012-12-14 11:21:13 +01001382 /* Clear openssl global errors stack */
1383 ERR_clear_error();
1384
Emeric Brun9fa89732012-10-04 17:09:56 +02001385 /* free resumed session if exists */
Willy Tarreau3fdb3662012-11-12 00:42:33 +01001386 if (objt_server(conn->target) && objt_server(conn->target)->ssl_ctx.reused_sess) {
1387 SSL_SESSION_free(objt_server(conn->target)->ssl_ctx.reused_sess);
1388 objt_server(conn->target)->ssl_ctx.reused_sess = NULL;
Emeric Brun9fa89732012-10-04 17:09:56 +02001389 }
1390
Emeric Brun46591952012-05-18 15:47:34 +02001391 /* Fail on all other handshake errors */
1392 conn->flags |= CO_FL_ERROR;
Willy Tarreau20879a02012-12-03 16:32:10 +01001393 if (!conn->err_code)
1394 conn->err_code = CO_ER_SSL_HANDSHAKE;
Emeric Brun46591952012-05-18 15:47:34 +02001395 return 0;
1396}
1397
1398/* Receive up to <count> bytes from connection <conn>'s socket and store them
Willy Tarreauabf08d92014-01-14 11:31:27 +01001399 * into buffer <buf>. Only one call to recv() is performed, unless the
Emeric Brun46591952012-05-18 15:47:34 +02001400 * buffer wraps, in which case a second call may be performed. The connection's
1401 * flags are updated with whatever special event is detected (error, read0,
1402 * empty). The caller is responsible for taking care of those events and
1403 * avoiding the call if inappropriate. The function does not call the
1404 * connection's polling update function, so the caller is responsible for this.
1405 */
1406static int ssl_sock_to_buf(struct connection *conn, struct buffer *buf, int count)
1407{
1408 int ret, done = 0;
Willy Tarreauabf08d92014-01-14 11:31:27 +01001409 int try;
Emeric Brun46591952012-05-18 15:47:34 +02001410
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02001411 if (!conn->xprt_ctx)
Emeric Brun46591952012-05-18 15:47:34 +02001412 goto out_error;
1413
1414 if (conn->flags & CO_FL_HANDSHAKE)
1415 /* a handshake was requested */
1416 return 0;
1417
Willy Tarreauabf08d92014-01-14 11:31:27 +01001418 /* let's realign the buffer to optimize I/O */
1419 if (buffer_empty(buf))
Emeric Brun46591952012-05-18 15:47:34 +02001420 buf->p = buf->data;
Emeric Brun46591952012-05-18 15:47:34 +02001421
1422 /* read the largest possible block. For this, we perform only one call
1423 * to recv() unless the buffer wraps and we exactly fill the first hunk,
1424 * in which case we accept to do it once again. A new attempt is made on
1425 * EINTR too.
1426 */
Willy Tarreau00b0fb92014-01-17 11:09:40 +01001427 while (count > 0) {
Willy Tarreauabf08d92014-01-14 11:31:27 +01001428 /* first check if we have some room after p+i */
1429 try = buf->data + buf->size - (buf->p + buf->i);
1430 /* otherwise continue between data and p-o */
1431 if (try <= 0) {
1432 try = buf->p - (buf->data + buf->o);
1433 if (try <= 0)
1434 break;
1435 }
1436 if (try > count)
1437 try = count;
1438
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02001439 ret = SSL_read(conn->xprt_ctx, bi_end(buf), try);
Emeric Brune1f38db2012-09-03 20:36:47 +02001440 if (conn->flags & CO_FL_ERROR) {
1441 /* CO_FL_ERROR may be set by ssl_sock_infocbk */
Emeric Brun644cde02012-12-14 11:21:13 +01001442 goto out_error;
Emeric Brune1f38db2012-09-03 20:36:47 +02001443 }
Emeric Brun46591952012-05-18 15:47:34 +02001444 if (ret > 0) {
1445 buf->i += ret;
1446 done += ret;
1447 if (ret < try)
1448 break;
1449 count -= ret;
Emeric Brun46591952012-05-18 15:47:34 +02001450 }
1451 else if (ret == 0) {
Emeric Brun644cde02012-12-14 11:21:13 +01001452 ret = SSL_get_error(conn->xprt_ctx, ret);
1453 if (ret != SSL_ERROR_ZERO_RETURN) {
Emeric Brun1c646862012-12-14 12:33:41 +01001454 /* error on protocol or underlying transport */
1455 if ((ret != SSL_ERROR_SYSCALL)
1456 || (errno && (errno != EAGAIN)))
1457 conn->flags |= CO_FL_ERROR;
1458
Emeric Brun644cde02012-12-14 11:21:13 +01001459 /* Clear openssl global errors stack */
1460 ERR_clear_error();
1461 }
Emeric Brun46591952012-05-18 15:47:34 +02001462 goto read0;
1463 }
1464 else {
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02001465 ret = SSL_get_error(conn->xprt_ctx, ret);
Emeric Brun46591952012-05-18 15:47:34 +02001466 if (ret == SSL_ERROR_WANT_WRITE) {
Emeric Brun8af8dd12012-11-08 17:56:20 +01001467 /* handshake is running, and it needs to enable write */
Emeric Brun46591952012-05-18 15:47:34 +02001468 conn->flags |= CO_FL_SSL_WAIT_HS;
Emeric Brun8af8dd12012-11-08 17:56:20 +01001469 __conn_sock_want_send(conn);
Emeric Brun46591952012-05-18 15:47:34 +02001470 break;
1471 }
1472 else if (ret == SSL_ERROR_WANT_READ) {
Emeric Brun282a76a2012-11-08 18:02:56 +01001473 if (SSL_renegotiate_pending(conn->xprt_ctx)) {
1474 /* handshake is running, and it may need to re-enable read */
1475 conn->flags |= CO_FL_SSL_WAIT_HS;
1476 __conn_sock_want_recv(conn);
1477 break;
1478 }
Emeric Brun46591952012-05-18 15:47:34 +02001479 /* we need to poll for retry a read later */
Willy Tarreaue1f50c42014-01-22 20:02:06 +01001480 fd_cant_recv(conn->t.sock.fd);
Emeric Brun46591952012-05-18 15:47:34 +02001481 break;
1482 }
1483 /* otherwise it's a real error */
1484 goto out_error;
1485 }
1486 }
1487 return done;
1488
1489 read0:
1490 conn_sock_read0(conn);
1491 return done;
1492 out_error:
Emeric Brun644cde02012-12-14 11:21:13 +01001493 /* Clear openssl global errors stack */
1494 ERR_clear_error();
1495
Emeric Brun46591952012-05-18 15:47:34 +02001496 conn->flags |= CO_FL_ERROR;
1497 return done;
1498}
1499
1500
1501/* Send all pending bytes from buffer <buf> to connection <conn>'s socket.
Willy Tarreau1049b1f2014-02-02 01:51:17 +01001502 * <flags> may contain some CO_SFL_* flags to hint the system about other
1503 * pending data for example, but this flag is ignored at the moment.
Emeric Brun46591952012-05-18 15:47:34 +02001504 * Only one call to send() is performed, unless the buffer wraps, in which case
1505 * a second call may be performed. The connection's flags are updated with
1506 * whatever special event is detected (error, empty). The caller is responsible
1507 * for taking care of those events and avoiding the call if inappropriate. The
1508 * function does not call the connection's polling update function, so the caller
1509 * is responsible for this.
1510 */
1511static int ssl_sock_from_buf(struct connection *conn, struct buffer *buf, int flags)
1512{
1513 int ret, try, done;
1514
1515 done = 0;
1516
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02001517 if (!conn->xprt_ctx)
Emeric Brun46591952012-05-18 15:47:34 +02001518 goto out_error;
1519
1520 if (conn->flags & CO_FL_HANDSHAKE)
1521 /* a handshake was requested */
1522 return 0;
1523
1524 /* send the largest possible block. For this we perform only one call
1525 * to send() unless the buffer wraps and we exactly fill the first hunk,
1526 * in which case we accept to do it once again.
1527 */
1528 while (buf->o) {
Kevin Hestercad82342013-05-30 15:12:41 -07001529 try = bo_contig_data(buf);
Willy Tarreaubfd59462013-02-21 07:46:09 +01001530
Willy Tarreau7bed9452014-02-02 02:00:24 +01001531 if (!(flags & CO_SFL_STREAMER) &&
1532 global.tune.ssl_max_record && try > global.tune.ssl_max_record)
Willy Tarreaubfd59462013-02-21 07:46:09 +01001533 try = global.tune.ssl_max_record;
1534
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02001535 ret = SSL_write(conn->xprt_ctx, bo_ptr(buf), try);
Emeric Brune1f38db2012-09-03 20:36:47 +02001536 if (conn->flags & CO_FL_ERROR) {
1537 /* CO_FL_ERROR may be set by ssl_sock_infocbk */
Emeric Brun644cde02012-12-14 11:21:13 +01001538 goto out_error;
Emeric Brune1f38db2012-09-03 20:36:47 +02001539 }
Emeric Brun46591952012-05-18 15:47:34 +02001540 if (ret > 0) {
1541 buf->o -= ret;
1542 done += ret;
1543
Willy Tarreau5fb38032012-12-16 19:39:09 +01001544 if (likely(buffer_empty(buf)))
Emeric Brun46591952012-05-18 15:47:34 +02001545 /* optimize data alignment in the buffer */
1546 buf->p = buf->data;
1547
1548 /* if the system buffer is full, don't insist */
1549 if (ret < try)
1550 break;
1551 }
1552 else {
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02001553 ret = SSL_get_error(conn->xprt_ctx, ret);
Emeric Brun46591952012-05-18 15:47:34 +02001554 if (ret == SSL_ERROR_WANT_WRITE) {
Emeric Brun282a76a2012-11-08 18:02:56 +01001555 if (SSL_renegotiate_pending(conn->xprt_ctx)) {
1556 /* handshake is running, and it may need to re-enable write */
1557 conn->flags |= CO_FL_SSL_WAIT_HS;
1558 __conn_sock_want_send(conn);
1559 break;
1560 }
Emeric Brun46591952012-05-18 15:47:34 +02001561 /* we need to poll to retry a write later */
Willy Tarreaue1f50c42014-01-22 20:02:06 +01001562 fd_cant_send(conn->t.sock.fd);
Emeric Brun46591952012-05-18 15:47:34 +02001563 break;
1564 }
1565 else if (ret == SSL_ERROR_WANT_READ) {
Emeric Brun8af8dd12012-11-08 17:56:20 +01001566 /* handshake is running, and it needs to enable read */
Emeric Brun46591952012-05-18 15:47:34 +02001567 conn->flags |= CO_FL_SSL_WAIT_HS;
Emeric Brun8af8dd12012-11-08 17:56:20 +01001568 __conn_sock_want_recv(conn);
Emeric Brun46591952012-05-18 15:47:34 +02001569 break;
1570 }
1571 goto out_error;
1572 }
1573 }
1574 return done;
1575
1576 out_error:
Emeric Brun644cde02012-12-14 11:21:13 +01001577 /* Clear openssl global errors stack */
1578 ERR_clear_error();
1579
Emeric Brun46591952012-05-18 15:47:34 +02001580 conn->flags |= CO_FL_ERROR;
1581 return done;
1582}
1583
Emeric Brun46591952012-05-18 15:47:34 +02001584static void ssl_sock_close(struct connection *conn) {
1585
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02001586 if (conn->xprt_ctx) {
1587 SSL_free(conn->xprt_ctx);
1588 conn->xprt_ctx = NULL;
Willy Tarreau403edff2012-09-06 11:58:37 +02001589 sslconns--;
Emeric Brun46591952012-05-18 15:47:34 +02001590 }
Emeric Brun46591952012-05-18 15:47:34 +02001591}
1592
1593/* This function tries to perform a clean shutdown on an SSL connection, and in
1594 * any case, flags the connection as reusable if no handshake was in progress.
1595 */
1596static void ssl_sock_shutw(struct connection *conn, int clean)
1597{
1598 if (conn->flags & CO_FL_HANDSHAKE)
1599 return;
1600 /* no handshake was in progress, try a clean ssl shutdown */
Emeric Brun644cde02012-12-14 11:21:13 +01001601 if (clean && (SSL_shutdown(conn->xprt_ctx) <= 0)) {
1602 /* Clear openssl global errors stack */
1603 ERR_clear_error();
1604 }
Emeric Brun46591952012-05-18 15:47:34 +02001605
1606 /* force flag on ssl to keep session in cache regardless shutdown result */
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02001607 SSL_set_shutdown(conn->xprt_ctx, SSL_SENT_SHUTDOWN);
Emeric Brun46591952012-05-18 15:47:34 +02001608}
1609
Willy Tarreauffc3fcd2012-10-12 20:17:54 +02001610/* used for logging, may be changed for a sample fetch later */
1611const char *ssl_sock_get_cipher_name(struct connection *conn)
1612{
1613 if (!conn->xprt && !conn->xprt_ctx)
1614 return NULL;
1615 return SSL_get_cipher_name(conn->xprt_ctx);
1616}
1617
1618/* used for logging, may be changed for a sample fetch later */
1619const char *ssl_sock_get_proto_version(struct connection *conn)
1620{
1621 if (!conn->xprt && !conn->xprt_ctx)
1622 return NULL;
1623 return SSL_get_version(conn->xprt_ctx);
1624}
1625
Willy Tarreau8d598402012-10-22 17:58:39 +02001626/* Extract a serial from a cert, and copy it to a chunk.
1627 * Returns 1 if serial is found and copied, 0 if no serial found and
1628 * -1 if output is not large enough.
1629 */
1630static int
1631ssl_sock_get_serial(X509 *crt, struct chunk *out)
1632{
1633 ASN1_INTEGER *serial;
1634
1635 serial = X509_get_serialNumber(crt);
1636 if (!serial)
1637 return 0;
1638
1639 if (out->size < serial->length)
1640 return -1;
1641
1642 memcpy(out->str, serial->data, serial->length);
1643 out->len = serial->length;
1644 return 1;
1645}
1646
Emeric Brunce5ad802012-10-22 14:11:22 +02001647
1648/* Copy Date in ASN1_UTCTIME format in struct chunk out.
1649 * Returns 1 if serial is found and copied, 0 if no valid time found
1650 * and -1 if output is not large enough.
1651 */
1652static int
1653ssl_sock_get_time(ASN1_TIME *tm, struct chunk *out)
1654{
1655 if (tm->type == V_ASN1_GENERALIZEDTIME) {
1656 ASN1_GENERALIZEDTIME *gentm = (ASN1_GENERALIZEDTIME *)tm;
1657
1658 if (gentm->length < 12)
1659 return 0;
1660 if (gentm->data[0] != 0x32 || gentm->data[1] != 0x30)
1661 return 0;
1662 if (out->size < gentm->length-2)
1663 return -1;
1664
1665 memcpy(out->str, gentm->data+2, gentm->length-2);
1666 out->len = gentm->length-2;
1667 return 1;
1668 }
1669 else if (tm->type == V_ASN1_UTCTIME) {
1670 ASN1_UTCTIME *utctm = (ASN1_UTCTIME *)tm;
1671
1672 if (utctm->length < 10)
1673 return 0;
1674 if (utctm->data[0] >= 0x35)
1675 return 0;
1676 if (out->size < utctm->length)
1677 return -1;
1678
1679 memcpy(out->str, utctm->data, utctm->length);
1680 out->len = utctm->length;
1681 return 1;
1682 }
1683
1684 return 0;
1685}
1686
Emeric Brun87855892012-10-17 17:39:35 +02001687/* Extract an entry from a X509_NAME and copy its value to an output chunk.
1688 * Returns 1 if entry found, 0 if entry not found, or -1 if output not large enough.
1689 */
1690static int
1691ssl_sock_get_dn_entry(X509_NAME *a, const struct chunk *entry, int pos, struct chunk *out)
1692{
1693 X509_NAME_ENTRY *ne;
1694 int i, j, n;
1695 int cur = 0;
1696 const char *s;
1697 char tmp[128];
1698
1699 out->len = 0;
1700 for (i = 0; i < sk_X509_NAME_ENTRY_num(a->entries); i++) {
1701 if (pos < 0)
1702 j = (sk_X509_NAME_ENTRY_num(a->entries)-1) - i;
1703 else
1704 j = i;
1705
1706 ne = sk_X509_NAME_ENTRY_value(a->entries, j);
1707 n = OBJ_obj2nid(ne->object);
1708 if ((n == NID_undef) || ((s = OBJ_nid2sn(n)) == NULL)) {
1709 i2t_ASN1_OBJECT(tmp, sizeof(tmp), ne->object);
1710 s = tmp;
1711 }
1712
1713 if (chunk_strcasecmp(entry, s) != 0)
1714 continue;
1715
1716 if (pos < 0)
1717 cur--;
1718 else
1719 cur++;
1720
1721 if (cur != pos)
1722 continue;
1723
1724 if (ne->value->length > out->size)
1725 return -1;
1726
1727 memcpy(out->str, ne->value->data, ne->value->length);
1728 out->len = ne->value->length;
1729 return 1;
1730 }
1731
1732 return 0;
1733
1734}
1735
1736/* Extract and format full DN from a X509_NAME and copy result into a chunk
1737 * Returns 1 if dn entries exits, 0 if no dn entry found or -1 if output is not large enough.
1738 */
1739static int
1740ssl_sock_get_dn_oneline(X509_NAME *a, struct chunk *out)
1741{
1742 X509_NAME_ENTRY *ne;
1743 int i, n, ln;
1744 int l = 0;
1745 const char *s;
1746 char *p;
1747 char tmp[128];
1748
1749 out->len = 0;
1750 p = out->str;
1751 for (i = 0; i < sk_X509_NAME_ENTRY_num(a->entries); i++) {
1752 ne = sk_X509_NAME_ENTRY_value(a->entries, i);
1753 n = OBJ_obj2nid(ne->object);
1754 if ((n == NID_undef) || ((s = OBJ_nid2sn(n)) == NULL)) {
1755 i2t_ASN1_OBJECT(tmp, sizeof(tmp), ne->object);
1756 s = tmp;
1757 }
1758 ln = strlen(s);
1759
1760 l += 1 + ln + 1 + ne->value->length;
1761 if (l > out->size)
1762 return -1;
1763 out->len = l;
1764
1765 *(p++)='/';
1766 memcpy(p, s, ln);
1767 p += ln;
1768 *(p++)='=';
1769 memcpy(p, ne->value->data, ne->value->length);
1770 p += ne->value->length;
1771 }
1772
1773 if (!out->len)
1774 return 0;
1775
1776 return 1;
1777}
1778
Willy Tarreau7875d092012-09-10 08:20:03 +02001779/***** Below are some sample fetching functions for ACL/patterns *****/
1780
Emeric Brune64aef12012-09-21 13:15:06 +02001781/* boolean, returns true if client cert was present */
1782static int
Emeric Brun2525b6b2012-10-18 15:59:43 +02001783smp_fetch_ssl_fc_has_crt(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
Willy Tarreauef38c392013-07-22 16:29:32 +02001784 const struct arg *args, struct sample *smp, const char *kw)
Emeric Brune64aef12012-09-21 13:15:06 +02001785{
Willy Tarreaub363a1f2013-10-01 10:45:07 +02001786 struct connection *conn;
1787
1788 if (!l4)
1789 return 0;
1790
1791 conn = objt_conn(l4->si[0].end);
1792 if (!conn || conn->xprt != &ssl_sock)
Emeric Brune64aef12012-09-21 13:15:06 +02001793 return 0;
1794
Willy Tarreaub363a1f2013-10-01 10:45:07 +02001795 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brune64aef12012-09-21 13:15:06 +02001796 smp->flags |= SMP_F_MAY_CHANGE;
1797 return 0;
1798 }
1799
1800 smp->flags = 0;
1801 smp->type = SMP_T_BOOL;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02001802 smp->data.uint = SSL_SOCK_ST_FL_VERIFY_DONE & conn->xprt_st ? 1 : 0;
Emeric Brune64aef12012-09-21 13:15:06 +02001803
1804 return 1;
1805}
1806
Willy Tarreau8d598402012-10-22 17:58:39 +02001807/* bin, returns serial in a binary chunk */
1808static int
1809smp_fetch_ssl_c_serial(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
Willy Tarreauef38c392013-07-22 16:29:32 +02001810 const struct arg *args, struct sample *smp, const char *kw)
Willy Tarreau8d598402012-10-22 17:58:39 +02001811{
1812 X509 *crt = NULL;
1813 int ret = 0;
1814 struct chunk *smp_trash;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02001815 struct connection *conn;
1816
1817 if (!l4)
1818 return 0;
Willy Tarreau8d598402012-10-22 17:58:39 +02001819
Willy Tarreaub363a1f2013-10-01 10:45:07 +02001820 conn = objt_conn(l4->si[0].end);
1821 if (!conn || conn->xprt != &ssl_sock)
Willy Tarreau8d598402012-10-22 17:58:39 +02001822 return 0;
1823
Willy Tarreaub363a1f2013-10-01 10:45:07 +02001824 if (!(conn->flags & CO_FL_CONNECTED)) {
Willy Tarreau8d598402012-10-22 17:58:39 +02001825 smp->flags |= SMP_F_MAY_CHANGE;
1826 return 0;
1827 }
1828
1829 /* SSL_get_peer_certificate, it increase X509 * ref count */
Willy Tarreaub363a1f2013-10-01 10:45:07 +02001830 crt = SSL_get_peer_certificate(conn->xprt_ctx);
Willy Tarreau8d598402012-10-22 17:58:39 +02001831 if (!crt)
1832 goto out;
1833
Willy Tarreau47ca5452012-12-23 20:22:19 +01001834 smp_trash = get_trash_chunk();
Willy Tarreau8d598402012-10-22 17:58:39 +02001835 if (ssl_sock_get_serial(crt, smp_trash) <= 0)
1836 goto out;
1837
1838 smp->data.str = *smp_trash;
1839 smp->type = SMP_T_BIN;
1840 ret = 1;
1841out:
1842 if (crt)
1843 X509_free(crt);
1844 return ret;
1845}
Emeric Brune64aef12012-09-21 13:15:06 +02001846
James Votha051b4a2013-05-14 20:37:59 +02001847/* bin, returns the client certificate's SHA-1 fingerprint (SHA-1 hash of DER-encoded certificate) in a binary chunk */
1848static int
1849smp_fetch_ssl_c_sha1(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
Willy Tarreauef38c392013-07-22 16:29:32 +02001850 const struct arg *args, struct sample *smp, const char *kw)
James Votha051b4a2013-05-14 20:37:59 +02001851{
1852 X509 *crt = NULL;
1853 const EVP_MD *digest;
1854 int ret = 0;
1855 struct chunk *smp_trash;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02001856 struct connection *conn;
James Votha051b4a2013-05-14 20:37:59 +02001857
Willy Tarreaub363a1f2013-10-01 10:45:07 +02001858 if (!l4)
James Votha051b4a2013-05-14 20:37:59 +02001859 return 0;
1860
Willy Tarreaub363a1f2013-10-01 10:45:07 +02001861 conn = objt_conn(l4->si[0].end);
1862 if (!conn || conn->xprt != &ssl_sock)
1863 return 0;
1864
1865 if (!(conn->flags & CO_FL_CONNECTED)) {
James Votha051b4a2013-05-14 20:37:59 +02001866 smp->flags |= SMP_F_MAY_CHANGE;
1867 return 0;
1868 }
1869
1870 /* SSL_get_peer_certificate, it increase X509 * ref count */
Willy Tarreaub363a1f2013-10-01 10:45:07 +02001871 crt = SSL_get_peer_certificate(conn->xprt_ctx);
James Votha051b4a2013-05-14 20:37:59 +02001872 if (!crt)
1873 goto out;
1874
1875 smp_trash = get_trash_chunk();
1876 digest = EVP_sha1();
1877 X509_digest(crt, digest, (unsigned char *)smp_trash->str, (unsigned int *)&smp_trash->len);
1878
1879 smp->data.str = *smp_trash;
1880 smp->type = SMP_T_BIN;
1881 ret = 1;
1882out:
1883 if (crt)
1884 X509_free(crt);
1885 return ret;
1886}
1887
Emeric Brunce5ad802012-10-22 14:11:22 +02001888/*str, returns notafter date in ASN1_UTCTIME format */
1889static int
1890smp_fetch_ssl_c_notafter(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
Willy Tarreauef38c392013-07-22 16:29:32 +02001891 const struct arg *args, struct sample *smp, const char *kw)
Emeric Brunce5ad802012-10-22 14:11:22 +02001892{
1893 X509 *crt = NULL;
1894 int ret = 0;
1895 struct chunk *smp_trash;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02001896 struct connection *conn;
Emeric Brunce5ad802012-10-22 14:11:22 +02001897
Willy Tarreaub363a1f2013-10-01 10:45:07 +02001898 if (!l4)
Emeric Brunce5ad802012-10-22 14:11:22 +02001899 return 0;
1900
Willy Tarreaub363a1f2013-10-01 10:45:07 +02001901 conn = objt_conn(l4->si[0].end);
1902 if (!conn || conn->xprt != &ssl_sock)
1903 return 0;
1904
1905 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brunce5ad802012-10-22 14:11:22 +02001906 smp->flags |= SMP_F_MAY_CHANGE;
1907 return 0;
1908 }
1909
1910 /* SSL_get_peer_certificate, it increase X509 * ref count */
Willy Tarreaub363a1f2013-10-01 10:45:07 +02001911 crt = SSL_get_peer_certificate(conn->xprt_ctx);
Emeric Brunce5ad802012-10-22 14:11:22 +02001912 if (!crt)
1913 goto out;
1914
Willy Tarreau47ca5452012-12-23 20:22:19 +01001915 smp_trash = get_trash_chunk();
Emeric Brunce5ad802012-10-22 14:11:22 +02001916 if (ssl_sock_get_time(X509_get_notAfter(crt), smp_trash) <= 0)
1917 goto out;
1918
1919 smp->data.str = *smp_trash;
1920 smp->type = SMP_T_STR;
1921 ret = 1;
1922out:
1923 if (crt)
1924 X509_free(crt);
1925 return ret;
1926}
1927
Emeric Brun87855892012-10-17 17:39:35 +02001928/* str, returns a string of a formatted full dn \C=..\O=..\OU=.. \CN=.. */
1929static int
1930smp_fetch_ssl_c_i_dn(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
Willy Tarreauef38c392013-07-22 16:29:32 +02001931 const struct arg *args, struct sample *smp, const char *kw)
Emeric Brun87855892012-10-17 17:39:35 +02001932{
1933 X509 *crt = NULL;
1934 X509_NAME *name;
1935 int ret = 0;
1936 struct chunk *smp_trash;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02001937 struct connection *conn;
Emeric Brun87855892012-10-17 17:39:35 +02001938
Willy Tarreaub363a1f2013-10-01 10:45:07 +02001939 if (!l4)
Emeric Brun87855892012-10-17 17:39:35 +02001940 return 0;
1941
Willy Tarreaub363a1f2013-10-01 10:45:07 +02001942 conn = objt_conn(l4->si[0].end);
1943 if (!conn || conn->xprt != &ssl_sock)
1944 return 0;
1945
1946 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brun87855892012-10-17 17:39:35 +02001947 smp->flags |= SMP_F_MAY_CHANGE;
1948 return 0;
1949 }
1950
1951 /* SSL_get_peer_certificate, it increase X509 * ref count */
Willy Tarreaub363a1f2013-10-01 10:45:07 +02001952 crt = SSL_get_peer_certificate(conn->xprt_ctx);
Emeric Brun87855892012-10-17 17:39:35 +02001953 if (!crt)
1954 goto out;
1955
1956 name = X509_get_issuer_name(crt);
1957 if (!name)
1958 goto out;
1959
Willy Tarreau47ca5452012-12-23 20:22:19 +01001960 smp_trash = get_trash_chunk();
Emeric Brun87855892012-10-17 17:39:35 +02001961 if (args && args[0].type == ARGT_STR) {
1962 int pos = 1;
1963
1964 if (args[1].type == ARGT_SINT)
1965 pos = args[1].data.sint;
1966 else if (args[1].type == ARGT_UINT)
1967 pos =(int)args[1].data.uint;
1968
1969 if (ssl_sock_get_dn_entry(name, &args[0].data.str, pos, smp_trash) <= 0)
1970 goto out;
1971 }
1972 else if (ssl_sock_get_dn_oneline(name, smp_trash) <= 0)
1973 goto out;
1974
1975 smp->type = SMP_T_STR;
1976 smp->data.str = *smp_trash;
1977 ret = 1;
1978out:
1979 if (crt)
1980 X509_free(crt);
1981 return ret;
1982}
1983
Emeric Brunce5ad802012-10-22 14:11:22 +02001984/*str, returns notbefore date in ASN1_UTCTIME format */
1985static int
1986smp_fetch_ssl_c_notbefore(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
Willy Tarreauef38c392013-07-22 16:29:32 +02001987 const struct arg *args, struct sample *smp, const char *kw)
Emeric Brunce5ad802012-10-22 14:11:22 +02001988{
1989 X509 *crt = NULL;
1990 int ret = 0;
1991 struct chunk *smp_trash;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02001992 struct connection *conn;
1993
1994 if (!l4)
1995 return 0;
Emeric Brunce5ad802012-10-22 14:11:22 +02001996
Willy Tarreaub363a1f2013-10-01 10:45:07 +02001997 conn = objt_conn(l4->si[0].end);
1998 if (!conn || conn->xprt != &ssl_sock)
Emeric Brunce5ad802012-10-22 14:11:22 +02001999 return 0;
2000
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002001 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brunce5ad802012-10-22 14:11:22 +02002002 smp->flags |= SMP_F_MAY_CHANGE;
2003 return 0;
2004 }
2005
2006 /* SSL_get_peer_certificate, it increase X509 * ref count */
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002007 crt = SSL_get_peer_certificate(conn->xprt_ctx);
Emeric Brunce5ad802012-10-22 14:11:22 +02002008 if (!crt)
2009 goto out;
2010
Willy Tarreau47ca5452012-12-23 20:22:19 +01002011 smp_trash = get_trash_chunk();
Emeric Brunce5ad802012-10-22 14:11:22 +02002012 if (ssl_sock_get_time(X509_get_notBefore(crt), smp_trash) <= 0)
2013 goto out;
2014
2015 smp->data.str = *smp_trash;
2016 smp->type = SMP_T_STR;
2017 ret = 1;
2018out:
2019 if (crt)
2020 X509_free(crt);
2021 return ret;
2022}
2023
Emeric Brun87855892012-10-17 17:39:35 +02002024/* str, returns a string of a formatted full dn \C=..\O=..\OU=.. \CN=.. */
2025static int
2026smp_fetch_ssl_c_s_dn(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
Willy Tarreauef38c392013-07-22 16:29:32 +02002027 const struct arg *args, struct sample *smp, const char *kw)
Emeric Brun87855892012-10-17 17:39:35 +02002028{
2029 X509 *crt = NULL;
2030 X509_NAME *name;
2031 int ret = 0;
2032 struct chunk *smp_trash;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002033 struct connection *conn;
Emeric Brun87855892012-10-17 17:39:35 +02002034
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002035 if (!l4)
Emeric Brun87855892012-10-17 17:39:35 +02002036 return 0;
2037
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002038 conn = objt_conn(l4->si[0].end);
2039 if (!conn || conn->xprt != &ssl_sock)
2040 return 0;
2041
2042 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brun87855892012-10-17 17:39:35 +02002043 smp->flags |= SMP_F_MAY_CHANGE;
2044 return 0;
2045 }
2046
2047 /* SSL_get_peer_certificate, it increase X509 * ref count */
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002048 crt = SSL_get_peer_certificate(conn->xprt_ctx);
Emeric Brun87855892012-10-17 17:39:35 +02002049 if (!crt)
2050 goto out;
2051
2052 name = X509_get_subject_name(crt);
2053 if (!name)
2054 goto out;
2055
Willy Tarreau47ca5452012-12-23 20:22:19 +01002056 smp_trash = get_trash_chunk();
Emeric Brun87855892012-10-17 17:39:35 +02002057 if (args && args[0].type == ARGT_STR) {
2058 int pos = 1;
2059
2060 if (args[1].type == ARGT_SINT)
2061 pos = args[1].data.sint;
2062 else if (args[1].type == ARGT_UINT)
2063 pos =(int)args[1].data.uint;
2064
2065 if (ssl_sock_get_dn_entry(name, &args[0].data.str, pos, smp_trash) <= 0)
2066 goto out;
2067 }
2068 else if (ssl_sock_get_dn_oneline(name, smp_trash) <= 0)
2069 goto out;
2070
2071 smp->type = SMP_T_STR;
2072 smp->data.str = *smp_trash;
2073 ret = 1;
2074out:
2075 if (crt)
2076 X509_free(crt);
2077 return ret;
2078}
Emeric Brun9143d372012-12-20 15:44:16 +01002079
2080/* integer, returns true if current session use a client certificate */
2081static int
2082smp_fetch_ssl_c_used(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
Willy Tarreauef38c392013-07-22 16:29:32 +02002083 const struct arg *args, struct sample *smp, const char *kw)
Emeric Brun9143d372012-12-20 15:44:16 +01002084{
2085 X509 *crt;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002086 struct connection *conn;
Emeric Brun9143d372012-12-20 15:44:16 +01002087
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002088 if (!l4)
Emeric Brun9143d372012-12-20 15:44:16 +01002089 return 0;
2090
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002091 conn = objt_conn(l4->si[0].end);
2092 if (!conn || conn->xprt != &ssl_sock)
2093 return 0;
2094
2095 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brun9143d372012-12-20 15:44:16 +01002096 smp->flags |= SMP_F_MAY_CHANGE;
2097 return 0;
2098 }
2099
2100 /* SSL_get_peer_certificate returns a ptr on allocated X509 struct */
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002101 crt = SSL_get_peer_certificate(conn->xprt_ctx);
Emeric Brun9143d372012-12-20 15:44:16 +01002102 if (crt) {
2103 X509_free(crt);
2104 }
2105
2106 smp->type = SMP_T_BOOL;
2107 smp->data.uint = (crt != NULL);
2108 return 1;
2109}
2110
Emeric Bruna7359fd2012-10-17 15:03:11 +02002111/* integer, returns the client certificate version */
2112static int
2113smp_fetch_ssl_c_version(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
Willy Tarreauef38c392013-07-22 16:29:32 +02002114 const struct arg *args, struct sample *smp, const char *kw)
Emeric Bruna7359fd2012-10-17 15:03:11 +02002115{
2116 X509 *crt;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002117 struct connection *conn;
2118
2119 if (!l4)
2120 return 0;
Emeric Bruna7359fd2012-10-17 15:03:11 +02002121
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002122 conn = objt_conn(l4->si[0].end);
2123 if (!conn || conn->xprt != &ssl_sock)
Emeric Bruna7359fd2012-10-17 15:03:11 +02002124 return 0;
2125
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002126 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Bruna7359fd2012-10-17 15:03:11 +02002127 smp->flags |= SMP_F_MAY_CHANGE;
2128 return 0;
2129 }
2130
2131 /* SSL_get_peer_certificate returns a ptr on allocated X509 struct */
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002132 crt = SSL_get_peer_certificate(conn->xprt_ctx);
Emeric Bruna7359fd2012-10-17 15:03:11 +02002133 if (!crt)
2134 return 0;
2135
2136 smp->data.uint = (unsigned int)(1 + X509_get_version(crt));
2137 X509_free(crt);
2138 smp->type = SMP_T_UINT;
2139
2140 return 1;
2141}
2142
Emeric Brun7f56e742012-10-19 18:15:40 +02002143/* str, returns the client certificate sig alg */
2144static int
2145smp_fetch_ssl_c_sig_alg(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
Willy Tarreauef38c392013-07-22 16:29:32 +02002146 const struct arg *args, struct sample *smp, const char *kw)
Emeric Brun7f56e742012-10-19 18:15:40 +02002147{
2148 X509 *crt;
2149 int nid;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002150 struct connection *conn;
Emeric Brun7f56e742012-10-19 18:15:40 +02002151
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002152 if (!l4)
Emeric Brun7f56e742012-10-19 18:15:40 +02002153 return 0;
2154
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002155 conn = objt_conn(l4->si[0].end);
2156 if (!conn || conn->xprt != &ssl_sock)
2157 return 0;
2158
2159 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brun7f56e742012-10-19 18:15:40 +02002160 smp->flags |= SMP_F_MAY_CHANGE;
2161 return 0;
2162 }
2163
2164 /* SSL_get_peer_certificate increase X509 * ref count */
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002165 crt = SSL_get_peer_certificate(conn->xprt_ctx);
Emeric Brun7f56e742012-10-19 18:15:40 +02002166 if (!crt)
2167 return 0;
2168
2169 nid = OBJ_obj2nid((ASN1_OBJECT *)(crt->cert_info->signature->algorithm));
2170
2171 smp->data.str.str = (char *)OBJ_nid2sn(nid);
Emeric Brun9bf3ba22013-10-07 14:31:44 +02002172 if (!smp->data.str.str) {
2173 X509_free(crt);
Emeric Brun7f56e742012-10-19 18:15:40 +02002174 return 0;
Emeric Brun9bf3ba22013-10-07 14:31:44 +02002175 }
Emeric Brun7f56e742012-10-19 18:15:40 +02002176
2177 smp->type = SMP_T_CSTR;
2178 smp->data.str.len = strlen(smp->data.str.str);
2179 X509_free(crt);
2180
2181 return 1;
2182}
2183
Emeric Brun521a0112012-10-22 12:22:55 +02002184/* str, returns the client certificate key alg */
2185static int
2186smp_fetch_ssl_c_key_alg(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
Willy Tarreauef38c392013-07-22 16:29:32 +02002187 const struct arg *args, struct sample *smp, const char *kw)
Emeric Brun521a0112012-10-22 12:22:55 +02002188{
2189 X509 *crt;
2190 int nid;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002191 struct connection *conn;
Emeric Brun521a0112012-10-22 12:22:55 +02002192
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002193 if (!l4)
Emeric Brun521a0112012-10-22 12:22:55 +02002194 return 0;
2195
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002196 conn = objt_conn(l4->si[0].end);
2197 if (!conn || conn->xprt != &ssl_sock)
2198 return 0;
2199
2200 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brun521a0112012-10-22 12:22:55 +02002201 smp->flags |= SMP_F_MAY_CHANGE;
2202 return 0;
2203 }
2204
2205 /* SSL_get_peer_certificate increase X509 * ref count */
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002206 crt = SSL_get_peer_certificate(conn->xprt_ctx);
Emeric Brun521a0112012-10-22 12:22:55 +02002207 if (!crt)
2208 return 0;
2209
2210 nid = OBJ_obj2nid((ASN1_OBJECT *)(crt->cert_info->key->algor->algorithm));
2211
2212 smp->data.str.str = (char *)OBJ_nid2sn(nid);
Emeric Brun9bf3ba22013-10-07 14:31:44 +02002213 if (!smp->data.str.str) {
2214 X509_free(crt);
Emeric Brun521a0112012-10-22 12:22:55 +02002215 return 0;
Emeric Brun9bf3ba22013-10-07 14:31:44 +02002216 }
Emeric Brun521a0112012-10-22 12:22:55 +02002217
2218 smp->type = SMP_T_CSTR;
2219 smp->data.str.len = strlen(smp->data.str.str);
2220 X509_free(crt);
2221
2222 return 1;
2223}
2224
Emeric Brun2525b6b2012-10-18 15:59:43 +02002225/* boolean, returns true if front conn. transport layer is SSL */
Willy Tarreau7875d092012-09-10 08:20:03 +02002226static int
Emeric Brun2525b6b2012-10-18 15:59:43 +02002227smp_fetch_ssl_fc(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
Willy Tarreauef38c392013-07-22 16:29:32 +02002228 const struct arg *args, struct sample *smp, const char *kw)
Willy Tarreau7875d092012-09-10 08:20:03 +02002229{
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002230 struct connection *conn = objt_conn(l4->si[0].end);
2231
Willy Tarreau7875d092012-09-10 08:20:03 +02002232 smp->type = SMP_T_BOOL;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002233 smp->data.uint = (conn && conn->xprt == &ssl_sock);
Willy Tarreau7875d092012-09-10 08:20:03 +02002234 return 1;
2235}
2236
Emeric Brun2525b6b2012-10-18 15:59:43 +02002237/* boolean, returns true if client present a SNI */
Willy Tarreau7875d092012-09-10 08:20:03 +02002238static int
Emeric Brun2525b6b2012-10-18 15:59:43 +02002239smp_fetch_ssl_fc_has_sni(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
Willy Tarreauef38c392013-07-22 16:29:32 +02002240 const struct arg *args, struct sample *smp, const char *kw)
Willy Tarreau7875d092012-09-10 08:20:03 +02002241{
2242#ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002243 struct connection *conn = objt_conn(l4->si[0].end);
2244
Willy Tarreau7875d092012-09-10 08:20:03 +02002245 smp->type = SMP_T_BOOL;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002246 smp->data.uint = (conn && conn->xprt == &ssl_sock) &&
2247 conn->xprt_ctx &&
2248 SSL_get_servername(conn->xprt_ctx, TLSEXT_NAMETYPE_host_name) != NULL;
Willy Tarreau7875d092012-09-10 08:20:03 +02002249 return 1;
2250#else
2251 return 0;
2252#endif
2253}
2254
Willy Tarreau8d598402012-10-22 17:58:39 +02002255/* bin, returns serial in a binary chunk */
2256static int
2257smp_fetch_ssl_f_serial(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
Willy Tarreauef38c392013-07-22 16:29:32 +02002258 const struct arg *args, struct sample *smp, const char *kw)
Willy Tarreau8d598402012-10-22 17:58:39 +02002259{
2260 X509 *crt = NULL;
2261 int ret = 0;
2262 struct chunk *smp_trash;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002263 struct connection *conn;
2264
2265 if (!l4)
2266 return 0;
Willy Tarreau8d598402012-10-22 17:58:39 +02002267
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002268 conn = objt_conn(l4->si[0].end);
2269 if (!conn || conn->xprt != &ssl_sock)
Willy Tarreau8d598402012-10-22 17:58:39 +02002270 return 0;
2271
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002272 if (!(conn->flags & CO_FL_CONNECTED)) {
Willy Tarreau8d598402012-10-22 17:58:39 +02002273 smp->flags |= SMP_F_MAY_CHANGE;
2274 return 0;
2275 }
2276
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002277 crt = SSL_get_certificate(conn->xprt_ctx);
Willy Tarreau8d598402012-10-22 17:58:39 +02002278 if (!crt)
2279 goto out;
2280
Willy Tarreau47ca5452012-12-23 20:22:19 +01002281 smp_trash = get_trash_chunk();
Willy Tarreau8d598402012-10-22 17:58:39 +02002282 if (ssl_sock_get_serial(crt, smp_trash) <= 0)
2283 goto out;
2284
2285 smp->data.str = *smp_trash;
2286 smp->type = SMP_T_BIN;
2287 ret = 1;
2288out:
2289 return ret;
2290}
Emeric Brunce5ad802012-10-22 14:11:22 +02002291/*str, returns notafter date in ASN1_UTCTIME format */
2292static int
2293smp_fetch_ssl_f_notafter(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
Willy Tarreauef38c392013-07-22 16:29:32 +02002294 const struct arg *args, struct sample *smp, const char *kw)
Emeric Brunce5ad802012-10-22 14:11:22 +02002295{
2296 X509 *crt = NULL;
2297 int ret = 0;
2298 struct chunk *smp_trash;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002299 struct connection *conn;
Emeric Brunce5ad802012-10-22 14:11:22 +02002300
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002301 if (!l4)
Emeric Brunce5ad802012-10-22 14:11:22 +02002302 return 0;
2303
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002304 conn = objt_conn(l4->si[0].end);
2305 if (!conn || conn->xprt != &ssl_sock)
2306 return 0;
2307
2308 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brunce5ad802012-10-22 14:11:22 +02002309 smp->flags |= SMP_F_MAY_CHANGE;
2310 return 0;
2311 }
2312
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002313 crt = SSL_get_certificate(conn->xprt_ctx);
Emeric Brunce5ad802012-10-22 14:11:22 +02002314 if (!crt)
2315 goto out;
2316
Willy Tarreau47ca5452012-12-23 20:22:19 +01002317 smp_trash = get_trash_chunk();
Emeric Brunce5ad802012-10-22 14:11:22 +02002318 if (ssl_sock_get_time(X509_get_notAfter(crt), smp_trash) <= 0)
2319 goto out;
2320
2321 smp->data.str = *smp_trash;
2322 smp->type = SMP_T_STR;
2323 ret = 1;
2324out:
2325 return ret;
2326}
2327
2328/*str, returns notbefore date in ASN1_UTCTIME format */
2329static int
2330smp_fetch_ssl_f_notbefore(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
Willy Tarreauef38c392013-07-22 16:29:32 +02002331 const struct arg *args, struct sample *smp, const char *kw)
Emeric Brunce5ad802012-10-22 14:11:22 +02002332{
2333 X509 *crt = NULL;
2334 int ret = 0;
2335 struct chunk *smp_trash;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002336 struct connection *conn;
Emeric Brunce5ad802012-10-22 14:11:22 +02002337
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002338 if (!l4)
Emeric Brunce5ad802012-10-22 14:11:22 +02002339 return 0;
2340
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002341 conn = objt_conn(l4->si[0].end);
2342 if (!conn || conn->xprt != &ssl_sock)
2343 return 0;
2344
2345 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brunce5ad802012-10-22 14:11:22 +02002346 smp->flags |= SMP_F_MAY_CHANGE;
2347 return 0;
2348 }
2349
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002350 crt = SSL_get_certificate(conn->xprt_ctx);
Emeric Brunce5ad802012-10-22 14:11:22 +02002351 if (!crt)
2352 goto out;
2353
Willy Tarreau47ca5452012-12-23 20:22:19 +01002354 smp_trash = get_trash_chunk();
Emeric Brunce5ad802012-10-22 14:11:22 +02002355 if (ssl_sock_get_time(X509_get_notBefore(crt), smp_trash) <= 0)
2356 goto out;
2357
2358 smp->data.str = *smp_trash;
2359 smp->type = SMP_T_STR;
2360 ret = 1;
2361out:
2362 return ret;
2363}
Willy Tarreau8d598402012-10-22 17:58:39 +02002364
Emeric Bruna7359fd2012-10-17 15:03:11 +02002365/* integer, returns the frontend certificate version */
2366static int
2367smp_fetch_ssl_f_version(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
Willy Tarreauef38c392013-07-22 16:29:32 +02002368 const struct arg *args, struct sample *smp, const char *kw)
Emeric Bruna7359fd2012-10-17 15:03:11 +02002369{
2370 X509 *crt;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002371 struct connection *conn;
Emeric Bruna7359fd2012-10-17 15:03:11 +02002372
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002373 if (!l4)
Emeric Bruna7359fd2012-10-17 15:03:11 +02002374 return 0;
2375
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002376 conn = objt_conn(l4->si[0].end);
2377 if (!conn || conn->xprt != &ssl_sock)
2378 return 0;
2379
2380 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Bruna7359fd2012-10-17 15:03:11 +02002381 smp->flags |= SMP_F_MAY_CHANGE;
2382 return 0;
2383 }
2384
2385 /* SSL_get_certificate returns a ptr on an SSL * internal sub struct */
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002386 crt = SSL_get_certificate(conn->xprt_ctx);
Emeric Bruna7359fd2012-10-17 15:03:11 +02002387 if (!crt)
2388 return 0;
2389
2390 smp->data.uint = (unsigned int)(1 + X509_get_version(crt));
2391 smp->type = SMP_T_UINT;
2392
2393 return 1;
2394}
2395
Emeric Brun7f56e742012-10-19 18:15:40 +02002396/* str, returns the client certificate sig alg */
2397static int
2398smp_fetch_ssl_f_sig_alg(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
Willy Tarreauef38c392013-07-22 16:29:32 +02002399 const struct arg *args, struct sample *smp, const char *kw)
Emeric Brun7f56e742012-10-19 18:15:40 +02002400{
2401 X509 *crt;
2402 int nid;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002403 struct connection *conn;
Emeric Brun7f56e742012-10-19 18:15:40 +02002404
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002405 if (!l4)
Emeric Brun7f56e742012-10-19 18:15:40 +02002406 return 0;
2407
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002408 conn = objt_conn(l4->si[0].end);
2409 if (!conn || conn->xprt != &ssl_sock)
2410 return 0;
2411
2412 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brun7f56e742012-10-19 18:15:40 +02002413 smp->flags |= SMP_F_MAY_CHANGE;
2414 return 0;
2415 }
2416
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002417 crt = SSL_get_certificate(conn->xprt_ctx);
Emeric Brun7f56e742012-10-19 18:15:40 +02002418 if (!crt)
2419 return 0;
2420
2421 nid = OBJ_obj2nid((ASN1_OBJECT *)(crt->cert_info->signature->algorithm));
2422
2423 smp->data.str.str = (char *)OBJ_nid2sn(nid);
2424 if (!smp->data.str.str)
2425 return 0;
2426
2427 smp->type = SMP_T_CSTR;
2428 smp->data.str.len = strlen(smp->data.str.str);
2429
2430 return 1;
2431}
2432
Emeric Brun521a0112012-10-22 12:22:55 +02002433/* str, returns the client certificate key alg */
2434static int
2435smp_fetch_ssl_f_key_alg(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
Willy Tarreauef38c392013-07-22 16:29:32 +02002436 const struct arg *args, struct sample *smp, const char *kw)
Emeric Brun521a0112012-10-22 12:22:55 +02002437{
2438 X509 *crt;
2439 int nid;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002440 struct connection *conn;
2441
2442 if (!l4)
2443 return 0;
Emeric Brun521a0112012-10-22 12:22:55 +02002444
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002445 conn = objt_conn(l4->si[0].end);
2446 if (!conn || conn->xprt != &ssl_sock)
Emeric Brun521a0112012-10-22 12:22:55 +02002447 return 0;
2448
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002449 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brun521a0112012-10-22 12:22:55 +02002450 smp->flags |= SMP_F_MAY_CHANGE;
2451 return 0;
2452 }
2453
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002454 crt = SSL_get_certificate(conn->xprt_ctx);
Emeric Brun521a0112012-10-22 12:22:55 +02002455 if (!crt)
2456 return 0;
2457
2458 nid = OBJ_obj2nid((ASN1_OBJECT *)(crt->cert_info->key->algor->algorithm));
2459
2460 smp->data.str.str = (char *)OBJ_nid2sn(nid);
2461 if (!smp->data.str.str)
2462 return 0;
2463
2464 smp->type = SMP_T_CSTR;
2465 smp->data.str.len = strlen(smp->data.str.str);
2466
2467 return 1;
2468}
2469
Emeric Brun87855892012-10-17 17:39:35 +02002470/* str, returns a string of a formatted full dn \C=..\O=..\OU=.. \CN=.. */
2471static int
2472smp_fetch_ssl_f_i_dn(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
Willy Tarreauef38c392013-07-22 16:29:32 +02002473 const struct arg *args, struct sample *smp, const char *kw)
Emeric Brun87855892012-10-17 17:39:35 +02002474{
2475 X509 *crt = NULL;
2476 X509_NAME *name;
2477 int ret = 0;
2478 struct chunk *smp_trash;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002479 struct connection *conn;
2480
2481 if (!l4)
2482 return 0;
Emeric Brun87855892012-10-17 17:39:35 +02002483
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002484 conn = objt_conn(l4->si[0].end);
2485 if (!conn || conn->xprt != &ssl_sock)
Emeric Brun87855892012-10-17 17:39:35 +02002486 return 0;
2487
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002488 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brun87855892012-10-17 17:39:35 +02002489 smp->flags |= SMP_F_MAY_CHANGE;
2490 return 0;
2491 }
2492
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002493 crt = SSL_get_certificate(conn->xprt_ctx);
Emeric Brun87855892012-10-17 17:39:35 +02002494 if (!crt)
2495 goto out;
2496
2497 name = X509_get_issuer_name(crt);
2498 if (!name)
2499 goto out;
2500
Willy Tarreau47ca5452012-12-23 20:22:19 +01002501 smp_trash = get_trash_chunk();
Emeric Brun87855892012-10-17 17:39:35 +02002502 if (args && args[0].type == ARGT_STR) {
2503 int pos = 1;
2504
2505 if (args[1].type == ARGT_SINT)
2506 pos = args[1].data.sint;
2507 else if (args[1].type == ARGT_UINT)
2508 pos =(int)args[1].data.uint;
2509
2510 if (ssl_sock_get_dn_entry(name, &args[0].data.str, pos, smp_trash) <= 0)
2511 goto out;
2512 }
2513 else if (ssl_sock_get_dn_oneline(name, smp_trash) <= 0)
2514 goto out;
2515
2516 smp->type = SMP_T_STR;
2517 smp->data.str = *smp_trash;
2518 ret = 1;
2519out:
2520 return ret;
2521}
2522
2523/* str, returns a string of a formatted full dn \C=..\O=..\OU=.. \CN=.. */
2524static int
2525smp_fetch_ssl_f_s_dn(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
Willy Tarreauef38c392013-07-22 16:29:32 +02002526 const struct arg *args, struct sample *smp, const char *kw)
Emeric Brun87855892012-10-17 17:39:35 +02002527{
2528 X509 *crt = NULL;
2529 X509_NAME *name;
2530 int ret = 0;
2531 struct chunk *smp_trash;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002532 struct connection *conn;
2533
2534 if (!l4)
2535 return 0;
Emeric Brun87855892012-10-17 17:39:35 +02002536
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002537 conn = objt_conn(l4->si[0].end);
2538 if (!conn || !conn->xprt_ctx || conn->xprt != &ssl_sock)
Emeric Brun87855892012-10-17 17:39:35 +02002539 return 0;
2540
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002541 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brun87855892012-10-17 17:39:35 +02002542 smp->flags |= SMP_F_MAY_CHANGE;
2543 return 0;
2544 }
2545
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002546 crt = SSL_get_certificate(conn->xprt_ctx);
Emeric Brun87855892012-10-17 17:39:35 +02002547 if (!crt)
2548 goto out;
2549
2550 name = X509_get_subject_name(crt);
2551 if (!name)
2552 goto out;
2553
Willy Tarreau47ca5452012-12-23 20:22:19 +01002554 smp_trash = get_trash_chunk();
Emeric Brun87855892012-10-17 17:39:35 +02002555 if (args && args[0].type == ARGT_STR) {
2556 int pos = 1;
2557
2558 if (args[1].type == ARGT_SINT)
2559 pos = args[1].data.sint;
2560 else if (args[1].type == ARGT_UINT)
2561 pos =(int)args[1].data.uint;
2562
2563 if (ssl_sock_get_dn_entry(name, &args[0].data.str, pos, smp_trash) <= 0)
2564 goto out;
2565 }
2566 else if (ssl_sock_get_dn_oneline(name, smp_trash) <= 0)
2567 goto out;
2568
2569 smp->type = SMP_T_STR;
2570 smp->data.str = *smp_trash;
2571 ret = 1;
2572out:
2573 return ret;
2574}
2575
Emeric Brun589fcad2012-10-16 14:13:26 +02002576static int
2577smp_fetch_ssl_fc_cipher(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
Willy Tarreauef38c392013-07-22 16:29:32 +02002578 const struct arg *args, struct sample *smp, const char *kw)
Emeric Brun589fcad2012-10-16 14:13:26 +02002579{
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002580 struct connection *conn;
2581
Emeric Brun589fcad2012-10-16 14:13:26 +02002582 smp->flags = 0;
2583
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002584 if (!l4)
2585 return 0;
2586
2587 conn = objt_conn(l4->si[0].end);
2588 if (!conn || !conn->xprt_ctx || conn->xprt != &ssl_sock)
Emeric Brun589fcad2012-10-16 14:13:26 +02002589 return 0;
2590
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002591 smp->data.str.str = (char *)SSL_get_cipher_name(conn->xprt_ctx);
Emeric Brun589fcad2012-10-16 14:13:26 +02002592 if (!smp->data.str.str)
2593 return 0;
2594
2595 smp->type = SMP_T_CSTR;
2596 smp->data.str.len = strlen(smp->data.str.str);
2597
2598 return 1;
2599}
2600
2601static int
2602smp_fetch_ssl_fc_alg_keysize(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
Willy Tarreauef38c392013-07-22 16:29:32 +02002603 const struct arg *args, struct sample *smp, const char *kw)
Emeric Brun589fcad2012-10-16 14:13:26 +02002604{
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002605 struct connection *conn;
2606
Emeric Brun589fcad2012-10-16 14:13:26 +02002607 smp->flags = 0;
2608
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002609 if (!l4)
Emeric Brun589fcad2012-10-16 14:13:26 +02002610 return 0;
2611
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002612 conn = objt_conn(l4->si[0].end);
2613 if (!conn || !conn->xprt_ctx || conn->xprt != &ssl_sock)
Emeric Brun589fcad2012-10-16 14:13:26 +02002614 return 0;
2615
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002616 if (!SSL_get_cipher_bits(conn->xprt_ctx, (int *)&smp->data.uint))
2617 return 0;
2618
Emeric Brun589fcad2012-10-16 14:13:26 +02002619 smp->type = SMP_T_UINT;
2620
2621 return 1;
2622}
2623
2624static int
2625smp_fetch_ssl_fc_use_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)
2637 return 0;
2638
2639 smp->data.uint = (unsigned int)SSL_get_cipher_bits(conn->xprt_ctx, NULL);
Emeric Brun589fcad2012-10-16 14:13:26 +02002640 if (!smp->data.uint)
2641 return 0;
2642
2643 smp->type = SMP_T_UINT;
2644
2645 return 1;
2646}
2647
Willy Tarreau6c9a3d52012-10-18 18:57:14 +02002648#ifdef OPENSSL_NPN_NEGOTIATED
Willy Tarreau7875d092012-09-10 08:20:03 +02002649static int
Emeric Brun2525b6b2012-10-18 15:59:43 +02002650smp_fetch_ssl_fc_npn(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
Willy Tarreauef38c392013-07-22 16:29:32 +02002651 const struct arg *args, struct sample *smp, const char *kw)
Willy Tarreaua33c6542012-10-15 13:19:06 +02002652{
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002653 struct connection *conn;
2654
Willy Tarreaua33c6542012-10-15 13:19:06 +02002655 smp->flags = 0;
2656 smp->type = SMP_T_CSTR;
2657
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002658 if (!l4)
Willy Tarreaua33c6542012-10-15 13:19:06 +02002659 return 0;
2660
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002661 conn = objt_conn(l4->si[0].end);
2662 if (!conn || !conn->xprt_ctx || conn->xprt != &ssl_sock)
2663 return 0;
2664
Willy Tarreaua33c6542012-10-15 13:19:06 +02002665 smp->data.str.str = NULL;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002666 SSL_get0_next_proto_negotiated(conn->xprt_ctx,
Willy Tarreaua33c6542012-10-15 13:19:06 +02002667 (const unsigned char **)&smp->data.str.str, (unsigned *)&smp->data.str.len);
2668
2669 if (!smp->data.str.str)
2670 return 0;
2671
2672 return 1;
Willy Tarreaua33c6542012-10-15 13:19:06 +02002673}
Willy Tarreau6c9a3d52012-10-18 18:57:14 +02002674#endif
Willy Tarreaua33c6542012-10-15 13:19:06 +02002675
Willy Tarreauab861d32013-04-02 02:30:41 +02002676#ifdef OPENSSL_ALPN_NEGOTIATED
2677static int
2678smp_fetch_ssl_fc_alpn(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
Willy Tarreauef38c392013-07-22 16:29:32 +02002679 const struct arg *args, struct sample *smp, const char *kw)
Willy Tarreauab861d32013-04-02 02:30:41 +02002680{
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002681 struct connection *conn;
2682
Willy Tarreauab861d32013-04-02 02:30:41 +02002683 smp->flags = 0;
2684 smp->type = SMP_T_CSTR;
2685
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002686 if (!l4)
2687 return 0;
2688
2689 conn = objt_conn(l4->si[0].end);
2690 if (!conn || !conn->xprt_ctx || conn->xprt != &ssl_sock)
Willy Tarreauab861d32013-04-02 02:30:41 +02002691 return 0;
2692
2693 smp->data.str.str = NULL;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002694 SSL_get0_alpn_negotiated(conn->xprt_ctx,
Willy Tarreauab861d32013-04-02 02:30:41 +02002695 (const unsigned char **)&smp->data.str.str, (unsigned *)&smp->data.str.len);
2696
2697 if (!smp->data.str.str)
2698 return 0;
2699
2700 return 1;
2701}
2702#endif
2703
Willy Tarreaua33c6542012-10-15 13:19:06 +02002704static int
Emeric Brun589fcad2012-10-16 14:13:26 +02002705smp_fetch_ssl_fc_protocol(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
Willy Tarreauef38c392013-07-22 16:29:32 +02002706 const struct arg *args, struct sample *smp, const char *kw)
Emeric Brun589fcad2012-10-16 14:13:26 +02002707{
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002708 struct connection *conn;
2709
Emeric Brun589fcad2012-10-16 14:13:26 +02002710 smp->flags = 0;
2711
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002712 if (!l4)
Emeric Brun589fcad2012-10-16 14:13:26 +02002713 return 0;
2714
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002715 conn = objt_conn(l4->si[0].end);
2716 if (!conn || !conn->xprt_ctx || conn->xprt != &ssl_sock)
2717 return 0;
2718
2719 smp->data.str.str = (char *)SSL_get_version(conn->xprt_ctx);
Emeric Brun589fcad2012-10-16 14:13:26 +02002720 if (!smp->data.str.str)
2721 return 0;
2722
2723 smp->type = SMP_T_CSTR;
2724 smp->data.str.len = strlen(smp->data.str.str);
2725
2726 return 1;
2727}
2728
2729static int
Emeric Brunfe68f682012-10-16 14:59:28 +02002730smp_fetch_ssl_fc_session_id(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
Willy Tarreauef38c392013-07-22 16:29:32 +02002731 const struct arg *args, struct sample *smp, const char *kw)
Emeric Brunfe68f682012-10-16 14:59:28 +02002732{
2733#if OPENSSL_VERSION_NUMBER > 0x0090800fL
2734 SSL_SESSION *sess;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002735 struct connection *conn;
Emeric Brunfe68f682012-10-16 14:59:28 +02002736
2737 smp->flags = 0;
2738 smp->type = SMP_T_CBIN;
2739
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002740 if (!l4)
Emeric Brunfe68f682012-10-16 14:59:28 +02002741 return 0;
2742
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002743 conn = objt_conn(l4->si[0].end);
2744 if (!conn || !conn->xprt_ctx || conn->xprt != &ssl_sock)
2745 return 0;
2746
2747 sess = SSL_get_session(conn->xprt_ctx);
Emeric Brunfe68f682012-10-16 14:59:28 +02002748 if (!sess)
2749 return 0;
2750
2751 smp->data.str.str = (char *)SSL_SESSION_get_id(sess, (unsigned int *)&smp->data.str.len);
2752 if (!smp->data.str.str || !&smp->data.str.len)
2753 return 0;
2754
2755 return 1;
2756#else
2757 return 0;
2758#endif
2759}
2760
2761static int
Emeric Brun2525b6b2012-10-18 15:59:43 +02002762smp_fetch_ssl_fc_sni(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
Willy Tarreauef38c392013-07-22 16:29:32 +02002763 const struct arg *args, struct sample *smp, const char *kw)
Willy Tarreau7875d092012-09-10 08:20:03 +02002764{
2765#ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002766 struct connection *conn;
2767
Willy Tarreau7875d092012-09-10 08:20:03 +02002768 smp->flags = 0;
2769 smp->type = SMP_T_CSTR;
2770
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002771 if (!l4)
Willy Tarreau7875d092012-09-10 08:20:03 +02002772 return 0;
2773
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002774 conn = objt_conn(l4->si[0].end);
2775 if (!conn || !conn->xprt_ctx || conn->xprt != &ssl_sock)
2776 return 0;
2777
2778 smp->data.str.str = (char *)SSL_get_servername(conn->xprt_ctx, TLSEXT_NAMETYPE_host_name);
Willy Tarreau3e394c92012-09-14 23:56:58 +02002779 if (!smp->data.str.str)
2780 return 0;
2781
Willy Tarreau7875d092012-09-10 08:20:03 +02002782 smp->data.str.len = strlen(smp->data.str.str);
2783 return 1;
2784#else
2785 return 0;
2786#endif
2787}
2788
Emeric Brun2525b6b2012-10-18 15:59:43 +02002789/* integer, returns the first verify error in CA chain of client certificate chain. */
Emeric Brunf282a812012-09-21 15:27:54 +02002790static int
Emeric Brun2525b6b2012-10-18 15:59:43 +02002791smp_fetch_ssl_c_ca_err(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
Willy Tarreauef38c392013-07-22 16:29:32 +02002792 const struct arg *args, struct sample *smp, const char *kw)
Emeric Brunf282a812012-09-21 15:27:54 +02002793{
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002794 struct connection *conn;
2795
2796 if (!l4)
Emeric Brunf282a812012-09-21 15:27:54 +02002797 return 0;
2798
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002799 conn = objt_conn(l4->si[0].end);
2800 if (!conn || conn->xprt != &ssl_sock)
2801 return 0;
2802
2803 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brunf282a812012-09-21 15:27:54 +02002804 smp->flags = SMP_F_MAY_CHANGE;
2805 return 0;
2806 }
2807
2808 smp->type = SMP_T_UINT;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002809 smp->data.uint = (unsigned int)SSL_SOCK_ST_TO_CA_ERROR(conn->xprt_st);
Emeric Brunf282a812012-09-21 15:27:54 +02002810 smp->flags = 0;
2811
2812 return 1;
2813}
2814
Emeric Brun2525b6b2012-10-18 15:59:43 +02002815/* integer, returns the depth of the first verify error in CA chain of client certificate chain. */
Emeric Brunf282a812012-09-21 15:27:54 +02002816static int
Emeric Brun2525b6b2012-10-18 15:59:43 +02002817smp_fetch_ssl_c_ca_err_depth(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
Willy Tarreauef38c392013-07-22 16:29:32 +02002818 const struct arg *args, struct sample *smp, const char *kw)
Emeric Brunf282a812012-09-21 15:27:54 +02002819{
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002820 struct connection *conn;
2821
2822 if (!l4)
2823 return 0;
2824
2825 conn = objt_conn(l4->si[0].end);
2826 if (!conn || conn->xprt != &ssl_sock)
Emeric Brunf282a812012-09-21 15:27:54 +02002827 return 0;
2828
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002829 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brunf282a812012-09-21 15:27:54 +02002830 smp->flags = SMP_F_MAY_CHANGE;
2831 return 0;
2832 }
2833
2834 smp->type = SMP_T_UINT;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002835 smp->data.uint = (unsigned int)SSL_SOCK_ST_TO_CAEDEPTH(conn->xprt_st);
Emeric Brunf282a812012-09-21 15:27:54 +02002836 smp->flags = 0;
2837
2838 return 1;
2839}
2840
Emeric Brun2525b6b2012-10-18 15:59:43 +02002841/* integer, returns the first verify error on client certificate */
Emeric Brunf282a812012-09-21 15:27:54 +02002842static int
Emeric Brun2525b6b2012-10-18 15:59:43 +02002843smp_fetch_ssl_c_err(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
Willy Tarreauef38c392013-07-22 16:29:32 +02002844 const struct arg *args, struct sample *smp, const char *kw)
Emeric Brunf282a812012-09-21 15:27:54 +02002845{
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002846 struct connection *conn;
2847
2848 if (!l4)
Emeric Brunf282a812012-09-21 15:27:54 +02002849 return 0;
2850
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002851 conn = objt_conn(l4->si[0].end);
2852 if (!conn || conn->xprt != &ssl_sock)
2853 return 0;
2854
2855 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brunf282a812012-09-21 15:27:54 +02002856 smp->flags = SMP_F_MAY_CHANGE;
2857 return 0;
2858 }
2859
2860 smp->type = SMP_T_UINT;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002861 smp->data.uint = (unsigned int)SSL_SOCK_ST_TO_CRTERROR(conn->xprt_st);
Emeric Brunf282a812012-09-21 15:27:54 +02002862 smp->flags = 0;
2863
2864 return 1;
2865}
2866
Emeric Brun2525b6b2012-10-18 15:59:43 +02002867/* integer, returns the verify result on client cert */
Emeric Brunbaf8ffb2012-09-21 15:27:20 +02002868static int
Emeric Brun2525b6b2012-10-18 15:59:43 +02002869smp_fetch_ssl_c_verify(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
Willy Tarreauef38c392013-07-22 16:29:32 +02002870 const struct arg *args, struct sample *smp, const char *kw)
Emeric Brunbaf8ffb2012-09-21 15:27:20 +02002871{
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002872 struct connection *conn;
2873
2874 if (!l4)
Emeric Brunbaf8ffb2012-09-21 15:27:20 +02002875 return 0;
2876
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002877 conn = objt_conn(l4->si[0].end);
2878 if (!conn || conn->xprt != &ssl_sock)
2879 return 0;
2880
2881 if (!(conn->flags & CO_FL_CONNECTED)) {
Emeric Brunbaf8ffb2012-09-21 15:27:20 +02002882 smp->flags = SMP_F_MAY_CHANGE;
2883 return 0;
2884 }
2885
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002886 if (!conn->xprt_ctx)
Emeric Brunbaf8ffb2012-09-21 15:27:20 +02002887 return 0;
2888
2889 smp->type = SMP_T_UINT;
Willy Tarreaub363a1f2013-10-01 10:45:07 +02002890 smp->data.uint = (unsigned int)SSL_get_verify_result(conn->xprt_ctx);
Emeric Brunbaf8ffb2012-09-21 15:27:20 +02002891 smp->flags = 0;
2892
2893 return 1;
2894}
2895
Emeric Brunfb510ea2012-10-05 12:00:26 +02002896/* parse the "ca-file" bind keyword */
2897static 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 +02002898{
2899 if (!*args[cur_arg + 1]) {
2900 if (err)
2901 memprintf(err, "'%s' : missing CAfile path", args[cur_arg]);
2902 return ERR_ALERT | ERR_FATAL;
2903 }
2904
Emeric Brunef42d922012-10-11 16:11:36 +02002905 if ((*args[cur_arg + 1] != '/') && global.ca_base)
2906 memprintf(&conf->ca_file, "%s/%s", global.ca_base, args[cur_arg + 1]);
2907 else
2908 memprintf(&conf->ca_file, "%s", args[cur_arg + 1]);
Emeric Brunc8e8d122012-10-02 18:42:10 +02002909
Emeric Brund94b3fe2012-09-20 18:23:56 +02002910 return 0;
2911}
2912
Willy Tarreau79eeafa2012-09-14 07:53:05 +02002913/* parse the "ciphers" bind keyword */
Willy Tarreau4348fad2012-09-20 16:48:07 +02002914static 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 +02002915{
2916 if (!*args[cur_arg + 1]) {
Willy Tarreaueb6cead2012-09-20 19:43:14 +02002917 memprintf(err, "'%s' : missing cipher suite", args[cur_arg]);
Willy Tarreau79eeafa2012-09-14 07:53:05 +02002918 return ERR_ALERT | ERR_FATAL;
2919 }
2920
Emeric Brun76d88952012-10-05 15:47:31 +02002921 free(conf->ciphers);
Willy Tarreau4348fad2012-09-20 16:48:07 +02002922 conf->ciphers = strdup(args[cur_arg + 1]);
Willy Tarreau79eeafa2012-09-14 07:53:05 +02002923 return 0;
2924}
2925
2926/* parse the "crt" bind keyword */
Willy Tarreau4348fad2012-09-20 16:48:07 +02002927static 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 +02002928{
Willy Tarreau38011032013-08-13 16:59:39 +02002929 char path[MAXPATHLEN];
Willy Tarreau79eeafa2012-09-14 07:53:05 +02002930 if (!*args[cur_arg + 1]) {
Willy Tarreaueb6cead2012-09-20 19:43:14 +02002931 memprintf(err, "'%s' : missing certificate location", args[cur_arg]);
Willy Tarreau79eeafa2012-09-14 07:53:05 +02002932 return ERR_ALERT | ERR_FATAL;
2933 }
2934
Emeric Brunc8e8d122012-10-02 18:42:10 +02002935 if ((*args[cur_arg + 1] != '/' ) && global.crt_base) {
Willy Tarreau38011032013-08-13 16:59:39 +02002936 if ((strlen(global.crt_base) + 1 + strlen(args[cur_arg + 1]) + 1) > MAXPATHLEN) {
Emeric Brunc8e8d122012-10-02 18:42:10 +02002937 memprintf(err, "'%s' : path too long", args[cur_arg]);
2938 return ERR_ALERT | ERR_FATAL;
2939 }
2940 sprintf(path, "%s/%s", global.crt_base, args[cur_arg + 1]);
2941 if (ssl_sock_load_cert(path, conf, px, err) > 0)
2942 return ERR_ALERT | ERR_FATAL;
2943
2944 return 0;
2945 }
2946
Willy Tarreau4348fad2012-09-20 16:48:07 +02002947 if (ssl_sock_load_cert(args[cur_arg + 1], conf, px, err) > 0)
Willy Tarreau79eeafa2012-09-14 07:53:05 +02002948 return ERR_ALERT | ERR_FATAL;
Emeric Brund94b3fe2012-09-20 18:23:56 +02002949
2950 return 0;
2951}
2952
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01002953/* parse the "crt-list" bind keyword */
2954static int bind_parse_crt_list(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
2955{
2956 if (!*args[cur_arg + 1]) {
2957 memprintf(err, "'%s' : missing certificate location", args[cur_arg]);
2958 return ERR_ALERT | ERR_FATAL;
2959 }
2960
Willy Tarreauad1731d2013-04-02 17:35:58 +02002961 if (ssl_sock_load_cert_list_file(args[cur_arg + 1], conf, px, err) > 0) {
2962 memprintf(err, "'%s' : %s", args[cur_arg], *err);
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01002963 return ERR_ALERT | ERR_FATAL;
Willy Tarreauad1731d2013-04-02 17:35:58 +02002964 }
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01002965
2966 return 0;
2967}
2968
Emeric Brunfb510ea2012-10-05 12:00:26 +02002969/* parse the "crl-file" bind keyword */
2970static 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 +02002971{
Emeric Brun051cdab2012-10-02 19:25:50 +02002972#ifndef X509_V_FLAG_CRL_CHECK
2973 if (err)
2974 memprintf(err, "'%s' : library does not support CRL verify", args[cur_arg]);
2975 return ERR_ALERT | ERR_FATAL;
2976#else
Emeric Brund94b3fe2012-09-20 18:23:56 +02002977 if (!*args[cur_arg + 1]) {
2978 if (err)
2979 memprintf(err, "'%s' : missing CRLfile path", args[cur_arg]);
2980 return ERR_ALERT | ERR_FATAL;
2981 }
Emeric Brun2b58d042012-09-20 17:10:03 +02002982
Emeric Brunef42d922012-10-11 16:11:36 +02002983 if ((*args[cur_arg + 1] != '/') && global.ca_base)
2984 memprintf(&conf->crl_file, "%s/%s", global.ca_base, args[cur_arg + 1]);
2985 else
2986 memprintf(&conf->crl_file, "%s", args[cur_arg + 1]);
Emeric Brunc8e8d122012-10-02 18:42:10 +02002987
Emeric Brun2b58d042012-09-20 17:10:03 +02002988 return 0;
Emeric Brun051cdab2012-10-02 19:25:50 +02002989#endif
Emeric Brun2b58d042012-09-20 17:10:03 +02002990}
2991
2992/* parse the "ecdhe" bind keyword keywords */
2993static int bind_parse_ecdhe(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
2994{
2995#if OPENSSL_VERSION_NUMBER < 0x0090800fL
2996 if (err)
2997 memprintf(err, "'%s' : library does not support elliptic curve Diffie-Hellman (too old)", args[cur_arg]);
2998 return ERR_ALERT | ERR_FATAL;
2999#elif defined(OPENSSL_NO_ECDH)
3000 if (err)
3001 memprintf(err, "'%s' : library does not support elliptic curve Diffie-Hellman (disabled via OPENSSL_NO_ECDH)", args[cur_arg]);
3002 return ERR_ALERT | ERR_FATAL;
3003#else
3004 if (!*args[cur_arg + 1]) {
3005 if (err)
3006 memprintf(err, "'%s' : missing named curve", args[cur_arg]);
3007 return ERR_ALERT | ERR_FATAL;
3008 }
3009
3010 conf->ecdhe = strdup(args[cur_arg + 1]);
Willy Tarreau79eeafa2012-09-14 07:53:05 +02003011
3012 return 0;
Emeric Brun2b58d042012-09-20 17:10:03 +02003013#endif
Willy Tarreau79eeafa2012-09-14 07:53:05 +02003014}
3015
Emeric Brun81c00f02012-09-21 14:31:21 +02003016/* parse the "crt_ignerr" and "ca_ignerr" bind keywords */
3017static int bind_parse_ignore_err(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
3018{
3019 int code;
3020 char *p = args[cur_arg + 1];
3021 unsigned long long *ignerr = &conf->crt_ignerr;
3022
3023 if (!*p) {
3024 if (err)
3025 memprintf(err, "'%s' : missing error IDs list", args[cur_arg]);
3026 return ERR_ALERT | ERR_FATAL;
3027 }
3028
3029 if (strcmp(args[cur_arg], "ca-ignore-err") == 0)
3030 ignerr = &conf->ca_ignerr;
3031
3032 if (strcmp(p, "all") == 0) {
3033 *ignerr = ~0ULL;
3034 return 0;
3035 }
3036
3037 while (p) {
3038 code = atoi(p);
3039 if ((code <= 0) || (code > 63)) {
3040 if (err)
3041 memprintf(err, "'%s' : ID '%d' out of range (1..63) in error IDs list '%s'",
3042 args[cur_arg], code, args[cur_arg + 1]);
3043 return ERR_ALERT | ERR_FATAL;
3044 }
3045 *ignerr |= 1ULL << code;
3046 p = strchr(p, ',');
3047 if (p)
3048 p++;
3049 }
3050
Emeric Brun2cb7ae52012-10-05 14:14:21 +02003051 return 0;
3052}
3053
3054/* parse the "force-sslv3" bind keyword */
3055static int bind_parse_force_sslv3(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
3056{
3057 conf->ssl_options |= BC_SSL_O_USE_SSLV3;
3058 return 0;
3059}
3060
3061/* parse the "force-tlsv10" bind keyword */
3062static int bind_parse_force_tlsv10(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
3063{
3064 conf->ssl_options |= BC_SSL_O_USE_TLSV10;
Emeric Brun2d0c4822012-10-02 13:45:20 +02003065 return 0;
3066}
3067
Emeric Brun2cb7ae52012-10-05 14:14:21 +02003068/* parse the "force-tlsv11" bind keyword */
3069static int bind_parse_force_tlsv11(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
3070{
3071#if SSL_OP_NO_TLSv1_1
3072 conf->ssl_options |= BC_SSL_O_USE_TLSV11;
3073 return 0;
3074#else
3075 if (err)
3076 memprintf(err, "'%s' : library does not support protocol TLSv1.1", args[cur_arg]);
3077 return ERR_ALERT | ERR_FATAL;
3078#endif
3079}
3080
3081/* parse the "force-tlsv12" bind keyword */
3082static int bind_parse_force_tlsv12(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
3083{
3084#if SSL_OP_NO_TLSv1_2
3085 conf->ssl_options |= BC_SSL_O_USE_TLSV12;
3086 return 0;
3087#else
3088 if (err)
3089 memprintf(err, "'%s' : library does not support protocol TLSv1.2", args[cur_arg]);
3090 return ERR_ALERT | ERR_FATAL;
3091#endif
3092}
3093
3094
Emeric Brun2d0c4822012-10-02 13:45:20 +02003095/* parse the "no-tls-tickets" bind keyword */
3096static int bind_parse_no_tls_tickets(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
3097{
Emeric Brun89675492012-10-05 13:48:26 +02003098 conf->ssl_options |= BC_SSL_O_NO_TLS_TICKETS;
Emeric Brun81c00f02012-09-21 14:31:21 +02003099 return 0;
3100}
3101
Emeric Brun2d0c4822012-10-02 13:45:20 +02003102
Emeric Brun9b3009b2012-10-05 11:55:06 +02003103/* parse the "no-sslv3" bind keyword */
3104static 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 +02003105{
Emeric Brun89675492012-10-05 13:48:26 +02003106 conf->ssl_options |= BC_SSL_O_NO_SSLV3;
Willy Tarreau79eeafa2012-09-14 07:53:05 +02003107 return 0;
3108}
3109
Emeric Brun9b3009b2012-10-05 11:55:06 +02003110/* parse the "no-tlsv10" bind keyword */
3111static 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 +02003112{
Emeric Brun89675492012-10-05 13:48:26 +02003113 conf->ssl_options |= BC_SSL_O_NO_TLSV10;
Emeric Brunc0ff4922012-09-28 19:37:02 +02003114 return 0;
3115}
3116
Emeric Brun9b3009b2012-10-05 11:55:06 +02003117/* parse the "no-tlsv11" bind keyword */
3118static 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 +02003119{
Emeric Brun89675492012-10-05 13:48:26 +02003120 conf->ssl_options |= BC_SSL_O_NO_TLSV11;
Emeric Brunc0ff4922012-09-28 19:37:02 +02003121 return 0;
3122}
3123
Emeric Brun9b3009b2012-10-05 11:55:06 +02003124/* parse the "no-tlsv12" bind keyword */
3125static 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 +02003126{
Emeric Brun89675492012-10-05 13:48:26 +02003127 conf->ssl_options |= BC_SSL_O_NO_TLSV12;
Willy Tarreau79eeafa2012-09-14 07:53:05 +02003128 return 0;
3129}
3130
Willy Tarreau6c9a3d52012-10-18 18:57:14 +02003131/* parse the "npn" bind keyword */
3132static int bind_parse_npn(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
3133{
3134#ifdef OPENSSL_NPN_NEGOTIATED
3135 char *p1, *p2;
3136
3137 if (!*args[cur_arg + 1]) {
3138 memprintf(err, "'%s' : missing the comma-delimited NPN protocol suite", args[cur_arg]);
3139 return ERR_ALERT | ERR_FATAL;
3140 }
3141
3142 free(conf->npn_str);
3143
3144 /* the NPN string is built as a suite of (<len> <name>)* */
3145 conf->npn_len = strlen(args[cur_arg + 1]) + 1;
3146 conf->npn_str = calloc(1, conf->npn_len);
3147 memcpy(conf->npn_str + 1, args[cur_arg + 1], conf->npn_len);
3148
3149 /* replace commas with the name length */
3150 p1 = conf->npn_str;
3151 p2 = p1 + 1;
3152 while (1) {
3153 p2 = memchr(p1 + 1, ',', conf->npn_str + conf->npn_len - (p1 + 1));
3154 if (!p2)
3155 p2 = p1 + 1 + strlen(p1 + 1);
3156
3157 if (p2 - (p1 + 1) > 255) {
3158 *p2 = '\0';
3159 memprintf(err, "'%s' : NPN protocol name too long : '%s'", args[cur_arg], p1 + 1);
3160 return ERR_ALERT | ERR_FATAL;
3161 }
3162
3163 *p1 = p2 - (p1 + 1);
3164 p1 = p2;
3165
3166 if (!*p2)
3167 break;
3168
3169 *(p2++) = '\0';
3170 }
3171 return 0;
3172#else
3173 if (err)
3174 memprintf(err, "'%s' : library does not support TLS NPN extension", args[cur_arg]);
3175 return ERR_ALERT | ERR_FATAL;
3176#endif
3177}
3178
Willy Tarreauab861d32013-04-02 02:30:41 +02003179/* parse the "alpn" bind keyword */
3180static int bind_parse_alpn(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
3181{
3182#ifdef OPENSSL_ALPN_NEGOTIATED
3183 char *p1, *p2;
3184
3185 if (!*args[cur_arg + 1]) {
3186 memprintf(err, "'%s' : missing the comma-delimited ALPN protocol suite", args[cur_arg]);
3187 return ERR_ALERT | ERR_FATAL;
3188 }
3189
3190 free(conf->alpn_str);
3191
3192 /* the ALPN string is built as a suite of (<len> <name>)* */
3193 conf->alpn_len = strlen(args[cur_arg + 1]) + 1;
3194 conf->alpn_str = calloc(1, conf->alpn_len);
3195 memcpy(conf->alpn_str + 1, args[cur_arg + 1], conf->alpn_len);
3196
3197 /* replace commas with the name length */
3198 p1 = conf->alpn_str;
3199 p2 = p1 + 1;
3200 while (1) {
3201 p2 = memchr(p1 + 1, ',', conf->alpn_str + conf->alpn_len - (p1 + 1));
3202 if (!p2)
3203 p2 = p1 + 1 + strlen(p1 + 1);
3204
3205 if (p2 - (p1 + 1) > 255) {
3206 *p2 = '\0';
3207 memprintf(err, "'%s' : ALPN protocol name too long : '%s'", args[cur_arg], p1 + 1);
3208 return ERR_ALERT | ERR_FATAL;
3209 }
3210
3211 *p1 = p2 - (p1 + 1);
3212 p1 = p2;
3213
3214 if (!*p2)
3215 break;
3216
3217 *(p2++) = '\0';
3218 }
3219 return 0;
3220#else
3221 if (err)
3222 memprintf(err, "'%s' : library does not support TLS ALPN extension", args[cur_arg]);
3223 return ERR_ALERT | ERR_FATAL;
3224#endif
3225}
3226
Willy Tarreau79eeafa2012-09-14 07:53:05 +02003227/* parse the "ssl" bind keyword */
Willy Tarreau4348fad2012-09-20 16:48:07 +02003228static 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 +02003229{
Willy Tarreau81796be2012-09-22 19:11:47 +02003230 struct listener *l;
3231
Willy Tarreau4348fad2012-09-20 16:48:07 +02003232 conf->is_ssl = 1;
Emeric Brun76d88952012-10-05 15:47:31 +02003233
3234 if (global.listen_default_ciphers && !conf->ciphers)
3235 conf->ciphers = strdup(global.listen_default_ciphers);
3236
Willy Tarreau81796be2012-09-22 19:11:47 +02003237 list_for_each_entry(l, &conf->listeners, by_bind)
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02003238 l->xprt = &ssl_sock;
Willy Tarreau81796be2012-09-22 19:11:47 +02003239
Willy Tarreau79eeafa2012-09-14 07:53:05 +02003240 return 0;
3241}
3242
Emmanuel Hocdet65623372013-01-24 17:17:15 +01003243/* parse the "strict-sni" bind keyword */
3244static int bind_parse_strict_sni(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
3245{
3246 conf->strict_sni = 1;
3247 return 0;
3248}
3249
Emeric Brund94b3fe2012-09-20 18:23:56 +02003250/* parse the "verify" bind keyword */
3251static int bind_parse_verify(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
3252{
3253 if (!*args[cur_arg + 1]) {
3254 if (err)
3255 memprintf(err, "'%s' : missing verify method", args[cur_arg]);
3256 return ERR_ALERT | ERR_FATAL;
3257 }
3258
3259 if (strcmp(args[cur_arg + 1], "none") == 0)
Emeric Brun850efd52014-01-29 12:24:34 +01003260 conf->verify = SSL_SOCK_VERIFY_NONE;
Emeric Brund94b3fe2012-09-20 18:23:56 +02003261 else if (strcmp(args[cur_arg + 1], "optional") == 0)
Emeric Brun850efd52014-01-29 12:24:34 +01003262 conf->verify = SSL_SOCK_VERIFY_OPTIONAL;
Emeric Brund94b3fe2012-09-20 18:23:56 +02003263 else if (strcmp(args[cur_arg + 1], "required") == 0)
Emeric Brun850efd52014-01-29 12:24:34 +01003264 conf->verify = SSL_SOCK_VERIFY_REQUIRED;
Emeric Brund94b3fe2012-09-20 18:23:56 +02003265 else {
3266 if (err)
3267 memprintf(err, "'%s' : unknown verify method '%s', only 'none', 'optional', and 'required' are supported\n",
3268 args[cur_arg], args[cur_arg + 1]);
3269 return ERR_ALERT | ERR_FATAL;
3270 }
3271
3272 return 0;
3273}
3274
Willy Tarreau92faadf2012-10-10 23:04:25 +02003275/************** "server" keywords ****************/
3276
Emeric Brunef42d922012-10-11 16:11:36 +02003277/* parse the "ca-file" server keyword */
3278static int srv_parse_ca_file(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
3279{
3280 if (!*args[*cur_arg + 1]) {
3281 if (err)
3282 memprintf(err, "'%s' : missing CAfile path", args[*cur_arg]);
3283 return ERR_ALERT | ERR_FATAL;
3284 }
3285
3286 if ((*args[*cur_arg + 1] != '/') && global.ca_base)
3287 memprintf(&newsrv->ssl_ctx.ca_file, "%s/%s", global.ca_base, args[*cur_arg + 1]);
3288 else
3289 memprintf(&newsrv->ssl_ctx.ca_file, "%s", args[*cur_arg + 1]);
3290
3291 return 0;
3292}
3293
Willy Tarreau92faadf2012-10-10 23:04:25 +02003294/* parse the "check-ssl" server keyword */
3295static int srv_parse_check_ssl(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
3296{
3297 newsrv->check.use_ssl = 1;
3298 if (global.connect_default_ciphers && !newsrv->ssl_ctx.ciphers)
3299 newsrv->ssl_ctx.ciphers = strdup(global.connect_default_ciphers);
3300 return 0;
3301}
3302
3303/* parse the "ciphers" server keyword */
3304static int srv_parse_ciphers(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
3305{
3306 if (!*args[*cur_arg + 1]) {
3307 memprintf(err, "'%s' : missing cipher suite", args[*cur_arg]);
3308 return ERR_ALERT | ERR_FATAL;
3309 }
3310
3311 free(newsrv->ssl_ctx.ciphers);
3312 newsrv->ssl_ctx.ciphers = strdup(args[*cur_arg + 1]);
3313 return 0;
3314}
3315
Emeric Brunef42d922012-10-11 16:11:36 +02003316/* parse the "crl-file" server keyword */
3317static int srv_parse_crl_file(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
3318{
3319#ifndef X509_V_FLAG_CRL_CHECK
3320 if (err)
3321 memprintf(err, "'%s' : library does not support CRL verify", args[*cur_arg]);
3322 return ERR_ALERT | ERR_FATAL;
3323#else
3324 if (!*args[*cur_arg + 1]) {
3325 if (err)
3326 memprintf(err, "'%s' : missing CRLfile path", args[*cur_arg]);
3327 return ERR_ALERT | ERR_FATAL;
3328 }
3329
3330 if ((*args[*cur_arg + 1] != '/') && global.ca_base)
3331 memprintf(&newsrv->ssl_ctx.crl_file, "%s/%s", global.ca_base, args[*cur_arg + 1]);
3332 else
3333 memprintf(&newsrv->ssl_ctx.crl_file, "%s", args[*cur_arg + 1]);
3334
3335 return 0;
3336#endif
3337}
3338
Emeric Bruna7aa3092012-10-26 12:58:00 +02003339/* parse the "crt" server keyword */
3340static int srv_parse_crt(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
3341{
3342 if (!*args[*cur_arg + 1]) {
3343 if (err)
3344 memprintf(err, "'%s' : missing certificate file path", args[*cur_arg]);
3345 return ERR_ALERT | ERR_FATAL;
3346 }
3347
3348 if ((*args[*cur_arg + 1] != '/') && global.crt_base)
3349 memprintf(&newsrv->ssl_ctx.client_crt, "%s/%s", global.ca_base, args[*cur_arg + 1]);
3350 else
3351 memprintf(&newsrv->ssl_ctx.client_crt, "%s", args[*cur_arg + 1]);
3352
3353 return 0;
3354}
Emeric Brunef42d922012-10-11 16:11:36 +02003355
Willy Tarreau92faadf2012-10-10 23:04:25 +02003356/* parse the "force-sslv3" server keyword */
3357static int srv_parse_force_sslv3(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
3358{
3359 newsrv->ssl_ctx.options |= SRV_SSL_O_USE_SSLV3;
3360 return 0;
3361}
3362
3363/* parse the "force-tlsv10" server keyword */
3364static int srv_parse_force_tlsv10(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
3365{
3366 newsrv->ssl_ctx.options |= SRV_SSL_O_USE_TLSV10;
3367 return 0;
3368}
3369
3370/* parse the "force-tlsv11" server keyword */
3371static int srv_parse_force_tlsv11(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
3372{
3373#if SSL_OP_NO_TLSv1_1
3374 newsrv->ssl_ctx.options |= SRV_SSL_O_USE_TLSV11;
3375 return 0;
3376#else
3377 if (err)
3378 memprintf(err, "'%s' : library does not support protocol TLSv1.1", args[*cur_arg]);
3379 return ERR_ALERT | ERR_FATAL;
3380#endif
3381}
3382
3383/* parse the "force-tlsv12" server keyword */
3384static int srv_parse_force_tlsv12(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
3385{
3386#if SSL_OP_NO_TLSv1_2
3387 newsrv->ssl_ctx.options |= SRV_SSL_O_USE_TLSV12;
3388 return 0;
3389#else
3390 if (err)
3391 memprintf(err, "'%s' : library does not support protocol TLSv1.2", args[*cur_arg]);
3392 return ERR_ALERT | ERR_FATAL;
3393#endif
3394}
3395
3396/* parse the "no-sslv3" server keyword */
3397static int srv_parse_no_sslv3(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
3398{
3399 newsrv->ssl_ctx.options |= SRV_SSL_O_NO_SSLV3;
3400 return 0;
3401}
3402
3403/* parse the "no-tlsv10" server keyword */
3404static int srv_parse_no_tlsv10(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
3405{
3406 newsrv->ssl_ctx.options |= SRV_SSL_O_NO_TLSV10;
3407 return 0;
3408}
3409
3410/* parse the "no-tlsv11" server keyword */
3411static int srv_parse_no_tlsv11(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
3412{
3413 newsrv->ssl_ctx.options |= SRV_SSL_O_NO_TLSV11;
3414 return 0;
3415}
3416
3417/* parse the "no-tlsv12" server keyword */
3418static int srv_parse_no_tlsv12(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
3419{
3420 newsrv->ssl_ctx.options |= SRV_SSL_O_NO_TLSV12;
3421 return 0;
3422}
3423
Emeric Brunf9c5c472012-10-11 15:28:34 +02003424/* parse the "no-tls-tickets" server keyword */
3425static int srv_parse_no_tls_tickets(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
3426{
3427 newsrv->ssl_ctx.options |= SRV_SSL_O_NO_TLS_TICKETS;
3428 return 0;
3429}
3430
Willy Tarreau92faadf2012-10-10 23:04:25 +02003431/* parse the "ssl" server keyword */
3432static int srv_parse_ssl(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
3433{
3434 newsrv->use_ssl = 1;
3435 if (global.connect_default_ciphers && !newsrv->ssl_ctx.ciphers)
3436 newsrv->ssl_ctx.ciphers = strdup(global.connect_default_ciphers);
3437 return 0;
3438}
3439
Emeric Brunef42d922012-10-11 16:11:36 +02003440/* parse the "verify" server keyword */
3441static int srv_parse_verify(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
3442{
3443 if (!*args[*cur_arg + 1]) {
3444 if (err)
3445 memprintf(err, "'%s' : missing verify method", args[*cur_arg]);
3446 return ERR_ALERT | ERR_FATAL;
3447 }
3448
3449 if (strcmp(args[*cur_arg + 1], "none") == 0)
Emeric Brun850efd52014-01-29 12:24:34 +01003450 newsrv->ssl_ctx.verify = SSL_SOCK_VERIFY_NONE;
Emeric Brunef42d922012-10-11 16:11:36 +02003451 else if (strcmp(args[*cur_arg + 1], "required") == 0)
Emeric Brun850efd52014-01-29 12:24:34 +01003452 newsrv->ssl_ctx.verify = SSL_SOCK_VERIFY_REQUIRED;
Emeric Brunef42d922012-10-11 16:11:36 +02003453 else {
3454 if (err)
3455 memprintf(err, "'%s' : unknown verify method '%s', only 'none' and 'required' are supported\n",
3456 args[*cur_arg], args[*cur_arg + 1]);
3457 return ERR_ALERT | ERR_FATAL;
3458 }
3459
Evan Broderbe554312013-06-27 00:05:25 -07003460 return 0;
3461}
3462
3463/* parse the "verifyhost" server keyword */
3464static int srv_parse_verifyhost(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
3465{
3466 if (!*args[*cur_arg + 1]) {
3467 if (err)
3468 memprintf(err, "'%s' : missing hostname to verify against", args[*cur_arg]);
3469 return ERR_ALERT | ERR_FATAL;
3470 }
3471
3472 newsrv->ssl_ctx.verify_host = strdup(args[*cur_arg + 1]);
3473
Emeric Brunef42d922012-10-11 16:11:36 +02003474 return 0;
3475}
3476
Willy Tarreau7875d092012-09-10 08:20:03 +02003477/* Note: must not be declared <const> as its list will be overwritten.
3478 * Please take care of keeping this list alphabetically sorted.
3479 */
Willy Tarreaudc13c112013-06-21 23:16:39 +02003480static struct sample_fetch_kw_list sample_fetch_keywords = {ILH, {
Willy Tarreau80aca902013-01-07 15:42:20 +01003481 { "ssl_c_ca_err", smp_fetch_ssl_c_ca_err, 0, NULL, SMP_T_UINT, SMP_USE_L5CLI },
3482 { "ssl_c_ca_err_depth", smp_fetch_ssl_c_ca_err_depth, 0, NULL, SMP_T_UINT, SMP_USE_L5CLI },
3483 { "ssl_c_err", smp_fetch_ssl_c_err, 0, NULL, SMP_T_UINT, SMP_USE_L5CLI },
3484 { "ssl_c_i_dn", smp_fetch_ssl_c_i_dn, ARG2(0,STR,SINT), NULL, SMP_T_STR, SMP_USE_L5CLI },
3485 { "ssl_c_key_alg", smp_fetch_ssl_c_key_alg, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
3486 { "ssl_c_notafter", smp_fetch_ssl_c_notafter, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
3487 { "ssl_c_notbefore", smp_fetch_ssl_c_notbefore, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
3488 { "ssl_c_sig_alg", smp_fetch_ssl_c_sig_alg, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
3489 { "ssl_c_s_dn", smp_fetch_ssl_c_s_dn, ARG2(0,STR,SINT), NULL, SMP_T_STR, SMP_USE_L5CLI },
3490 { "ssl_c_serial", smp_fetch_ssl_c_serial, 0, NULL, SMP_T_BIN, SMP_USE_L5CLI },
James Votha051b4a2013-05-14 20:37:59 +02003491 { "ssl_c_sha1", smp_fetch_ssl_c_sha1, 0, NULL, SMP_T_BIN, SMP_USE_L5CLI },
Willy Tarreau80aca902013-01-07 15:42:20 +01003492 { "ssl_c_used", smp_fetch_ssl_c_used, 0, NULL, SMP_T_BOOL, SMP_USE_L5CLI },
3493 { "ssl_c_verify", smp_fetch_ssl_c_verify, 0, NULL, SMP_T_UINT, SMP_USE_L5CLI },
3494 { "ssl_c_version", smp_fetch_ssl_c_version, 0, NULL, SMP_T_UINT, SMP_USE_L5CLI },
3495 { "ssl_f_i_dn", smp_fetch_ssl_f_i_dn, ARG2(0,STR,SINT), NULL, SMP_T_STR, SMP_USE_L5CLI },
3496 { "ssl_f_key_alg", smp_fetch_ssl_f_key_alg, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
3497 { "ssl_f_notafter", smp_fetch_ssl_f_notafter, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
3498 { "ssl_f_notbefore", smp_fetch_ssl_f_notbefore, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
3499 { "ssl_f_sig_alg", smp_fetch_ssl_f_sig_alg, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
3500 { "ssl_f_s_dn", smp_fetch_ssl_f_s_dn, ARG2(0,STR,SINT), NULL, SMP_T_STR, SMP_USE_L5CLI },
3501 { "ssl_f_serial", smp_fetch_ssl_f_serial, 0, NULL, SMP_T_BIN, SMP_USE_L5CLI },
3502 { "ssl_f_version", smp_fetch_ssl_f_version, 0, NULL, SMP_T_UINT, SMP_USE_L5CLI },
3503 { "ssl_fc", smp_fetch_ssl_fc, 0, NULL, SMP_T_BOOL, SMP_USE_L5CLI },
3504 { "ssl_fc_alg_keysize", smp_fetch_ssl_fc_alg_keysize, 0, NULL, SMP_T_UINT, SMP_USE_L5CLI },
3505 { "ssl_fc_cipher", smp_fetch_ssl_fc_cipher, 0, NULL, SMP_T_CSTR, SMP_USE_L5CLI },
3506 { "ssl_fc_has_crt", smp_fetch_ssl_fc_has_crt, 0, NULL, SMP_T_BOOL, SMP_USE_L5CLI },
3507 { "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 +02003508#ifdef OPENSSL_NPN_NEGOTIATED
Willy Tarreau80aca902013-01-07 15:42:20 +01003509 { "ssl_fc_npn", smp_fetch_ssl_fc_npn, 0, NULL, SMP_T_CSTR, SMP_USE_L5CLI },
Willy Tarreaua33c6542012-10-15 13:19:06 +02003510#endif
Willy Tarreauab861d32013-04-02 02:30:41 +02003511#ifdef OPENSSL_ALPN_NEGOTIATED
3512 { "ssl_fc_alpn", smp_fetch_ssl_fc_alpn, 0, NULL, SMP_T_CSTR, SMP_USE_L5CLI },
3513#endif
Willy Tarreau80aca902013-01-07 15:42:20 +01003514 { "ssl_fc_protocol", smp_fetch_ssl_fc_protocol, 0, NULL, SMP_T_CSTR, SMP_USE_L5CLI },
3515 { "ssl_fc_use_keysize", smp_fetch_ssl_fc_use_keysize, 0, NULL, SMP_T_UINT, SMP_USE_L5CLI },
3516 { "ssl_fc_session_id", smp_fetch_ssl_fc_session_id, 0, NULL, SMP_T_CBIN, SMP_USE_L5CLI },
3517 { "ssl_fc_sni", smp_fetch_ssl_fc_sni, 0, NULL, SMP_T_CSTR, SMP_USE_L5CLI },
Willy Tarreau7875d092012-09-10 08:20:03 +02003518 { NULL, NULL, 0, 0, 0 },
3519}};
3520
3521/* Note: must not be declared <const> as its list will be overwritten.
3522 * Please take care of keeping this list alphabetically sorted.
3523 */
Willy Tarreaudc13c112013-06-21 23:16:39 +02003524static struct acl_kw_list acl_kws = {ILH, {
Thierry FOURNIERa65b3432013-11-28 18:22:00 +01003525 { "ssl_c_i_dn", NULL, pat_parse_str, pat_match_str },
3526 { "ssl_c_key_alg", NULL, pat_parse_str, pat_match_str },
3527 { "ssl_c_notafter", NULL, pat_parse_str, pat_match_str },
3528 { "ssl_c_notbefore", NULL, pat_parse_str, pat_match_str },
3529 { "ssl_c_sig_alg", NULL, pat_parse_str, pat_match_str },
3530 { "ssl_c_s_dn", NULL, pat_parse_str, pat_match_str },
3531 { "ssl_c_serial", NULL, pat_parse_bin, pat_match_bin },
3532 { "ssl_f_i_dn", NULL, pat_parse_str, pat_match_str },
3533 { "ssl_f_key_alg", NULL, pat_parse_str, pat_match_str },
3534 { "ssl_f_notafter", NULL, pat_parse_str, pat_match_str },
3535 { "ssl_f_notbefore", NULL, pat_parse_str, pat_match_str },
3536 { "ssl_f_sig_alg", NULL, pat_parse_str, pat_match_str },
3537 { "ssl_f_s_dn", NULL, pat_parse_str, pat_match_str },
3538 { "ssl_f_serial", NULL, pat_parse_bin, pat_match_bin },
3539 { "ssl_fc_cipher", NULL, pat_parse_str, pat_match_str },
Willy Tarreaua33c6542012-10-15 13:19:06 +02003540#ifdef OPENSSL_NPN_NEGOTIATED
Thierry FOURNIERa65b3432013-11-28 18:22:00 +01003541 { "ssl_fc_npn", NULL, pat_parse_str, pat_match_str },
Willy Tarreaua33c6542012-10-15 13:19:06 +02003542#endif
Willy Tarreauab861d32013-04-02 02:30:41 +02003543#ifdef OPENSSL_ALPN_NEGOTIATED
Thierry FOURNIERa65b3432013-11-28 18:22:00 +01003544 { "ssl_fc_alpn", NULL, pat_parse_str, pat_match_str },
Willy Tarreauab861d32013-04-02 02:30:41 +02003545#endif
Thierry FOURNIERa65b3432013-11-28 18:22:00 +01003546 { "ssl_fc_protocol", NULL, pat_parse_str, pat_match_str },
3547 { "ssl_fc_sni", "ssl_fc_sni", pat_parse_str, pat_match_str },
3548 { "ssl_fc_sni_end", "ssl_fc_sni", pat_parse_str, pat_match_end },
3549 { "ssl_fc_sni_reg", "ssl_fc_sni", pat_parse_reg, pat_match_reg },
Willy Tarreau8ed669b2013-01-11 15:49:37 +01003550 { /* END */ },
Willy Tarreau7875d092012-09-10 08:20:03 +02003551}};
3552
Willy Tarreau79eeafa2012-09-14 07:53:05 +02003553/* Note: must not be declared <const> as its list will be overwritten.
3554 * Please take care of keeping this list alphabetically sorted, doing so helps
3555 * all code contributors.
3556 * Optional keywords are also declared with a NULL ->parse() function so that
3557 * the config parser can report an appropriate error when a known keyword was
3558 * not enabled.
3559 */
Willy Tarreau51fb7652012-09-18 18:24:39 +02003560static struct bind_kw_list bind_kws = { "SSL", { }, {
Willy Tarreauab861d32013-04-02 02:30:41 +02003561 { "alpn", bind_parse_alpn, 1 }, /* set ALPN supported protocols */
Emeric Brunfb510ea2012-10-05 12:00:26 +02003562 { "ca-file", bind_parse_ca_file, 1 }, /* set CAfile to process verify on client cert */
Emeric Brun2d0c4822012-10-02 13:45:20 +02003563 { "ca-ignore-err", bind_parse_ignore_err, 1 }, /* set error IDs to ignore on verify depth > 0 */
3564 { "ciphers", bind_parse_ciphers, 1 }, /* set SSL cipher suite */
Emeric Brunfb510ea2012-10-05 12:00:26 +02003565 { "crl-file", bind_parse_crl_file, 1 }, /* set certificat revocation list file use on client cert verify */
Emeric Brun2d0c4822012-10-02 13:45:20 +02003566 { "crt", bind_parse_crt, 1 }, /* load SSL certificates from this location */
3567 { "crt-ignore-err", bind_parse_ignore_err, 1 }, /* set error IDs to ingore on verify depth == 0 */
Emmanuel Hocdetfe616562013-01-22 15:31:15 +01003568 { "crt-list", bind_parse_crt_list, 1 }, /* load a list of crt from this location */
Emeric Brun2d0c4822012-10-02 13:45:20 +02003569 { "ecdhe", bind_parse_ecdhe, 1 }, /* defines named curve for elliptic curve Diffie-Hellman */
Emeric Brun2cb7ae52012-10-05 14:14:21 +02003570 { "force-sslv3", bind_parse_force_sslv3, 0 }, /* force SSLv3 */
3571 { "force-tlsv10", bind_parse_force_tlsv10, 0 }, /* force TLSv10 */
3572 { "force-tlsv11", bind_parse_force_tlsv11, 0 }, /* force TLSv11 */
3573 { "force-tlsv12", bind_parse_force_tlsv12, 0 }, /* force TLSv12 */
Emeric Brun9b3009b2012-10-05 11:55:06 +02003574 { "no-sslv3", bind_parse_no_sslv3, 0 }, /* disable SSLv3 */
3575 { "no-tlsv10", bind_parse_no_tlsv10, 0 }, /* disable TLSv10 */
3576 { "no-tlsv11", bind_parse_no_tlsv11, 0 }, /* disable TLSv11 */
3577 { "no-tlsv12", bind_parse_no_tlsv12, 0 }, /* disable TLSv12 */
Emeric Brun2d0c4822012-10-02 13:45:20 +02003578 { "no-tls-tickets", bind_parse_no_tls_tickets, 0 }, /* disable session resumption tickets */
Emeric Brun2d0c4822012-10-02 13:45:20 +02003579 { "ssl", bind_parse_ssl, 0 }, /* enable SSL processing */
Emmanuel Hocdet65623372013-01-24 17:17:15 +01003580 { "strict-sni", bind_parse_strict_sni, 0 }, /* refuse negotiation if sni doesn't match a certificate */
Emeric Brun2d0c4822012-10-02 13:45:20 +02003581 { "verify", bind_parse_verify, 1 }, /* set SSL verify method */
Willy Tarreau6c9a3d52012-10-18 18:57:14 +02003582 { "npn", bind_parse_npn, 1 }, /* set NPN supported protocols */
Willy Tarreau79eeafa2012-09-14 07:53:05 +02003583 { NULL, NULL, 0 },
3584}};
Emeric Brun46591952012-05-18 15:47:34 +02003585
Willy Tarreau92faadf2012-10-10 23:04:25 +02003586/* Note: must not be declared <const> as its list will be overwritten.
3587 * Please take care of keeping this list alphabetically sorted, doing so helps
3588 * all code contributors.
3589 * Optional keywords are also declared with a NULL ->parse() function so that
3590 * the config parser can report an appropriate error when a known keyword was
3591 * not enabled.
3592 */
3593static struct srv_kw_list srv_kws = { "SSL", { }, {
Emeric Brunef42d922012-10-11 16:11:36 +02003594 { "ca-file", srv_parse_ca_file, 1, 0 }, /* set CAfile to process verify server cert */
Emeric Brunecc91fe2012-10-11 15:05:10 +02003595 { "check-ssl", srv_parse_check_ssl, 0, 0 }, /* enable SSL for health checks */
3596 { "ciphers", srv_parse_ciphers, 1, 0 }, /* select the cipher suite */
Emeric Brunef42d922012-10-11 16:11:36 +02003597 { "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 +02003598 { "crt", srv_parse_crt, 1, 0 }, /* set client certificate */
Emeric Brunecc91fe2012-10-11 15:05:10 +02003599 { "force-sslv3", srv_parse_force_sslv3, 0, 0 }, /* force SSLv3 */
3600 { "force-tlsv10", srv_parse_force_tlsv10, 0, 0 }, /* force TLSv10 */
3601 { "force-tlsv11", srv_parse_force_tlsv11, 0, 0 }, /* force TLSv11 */
3602 { "force-tlsv12", srv_parse_force_tlsv12, 0, 0 }, /* force TLSv12 */
3603 { "no-sslv3", srv_parse_no_sslv3, 0, 0 }, /* disable SSLv3 */
3604 { "no-tlsv10", srv_parse_no_tlsv10, 0, 0 }, /* disable TLSv10 */
3605 { "no-tlsv11", srv_parse_no_tlsv11, 0, 0 }, /* disable TLSv11 */
3606 { "no-tlsv12", srv_parse_no_tlsv12, 0, 0 }, /* disable TLSv12 */
Emeric Brunf9c5c472012-10-11 15:28:34 +02003607 { "no-tls-tickets", srv_parse_no_tls_tickets, 0, 0 }, /* disable session resumption tickets */
Emeric Brunecc91fe2012-10-11 15:05:10 +02003608 { "ssl", srv_parse_ssl, 0, 0 }, /* enable SSL processing */
Emeric Brunef42d922012-10-11 16:11:36 +02003609 { "verify", srv_parse_verify, 1, 0 }, /* set SSL verify method */
Evan Broderbe554312013-06-27 00:05:25 -07003610 { "verifyhost", srv_parse_verifyhost, 1, 0 }, /* require that SSL cert verifies for hostname */
Willy Tarreau92faadf2012-10-10 23:04:25 +02003611 { NULL, NULL, 0, 0 },
3612}};
3613
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02003614/* transport-layer operations for SSL sockets */
3615struct xprt_ops ssl_sock = {
Emeric Brun46591952012-05-18 15:47:34 +02003616 .snd_buf = ssl_sock_from_buf,
3617 .rcv_buf = ssl_sock_to_buf,
3618 .rcv_pipe = NULL,
3619 .snd_pipe = NULL,
3620 .shutr = NULL,
3621 .shutw = ssl_sock_shutw,
3622 .close = ssl_sock_close,
3623 .init = ssl_sock_init,
3624};
3625
3626__attribute__((constructor))
Willy Tarreau92faadf2012-10-10 23:04:25 +02003627static void __ssl_sock_init(void)
3628{
Emeric Brun46591952012-05-18 15:47:34 +02003629 STACK_OF(SSL_COMP)* cm;
3630
3631 SSL_library_init();
3632 cm = SSL_COMP_get_compression_methods();
3633 sk_SSL_COMP_zero(cm);
Willy Tarreau7875d092012-09-10 08:20:03 +02003634 sample_register_fetches(&sample_fetch_keywords);
3635 acl_register_keywords(&acl_kws);
Willy Tarreau79eeafa2012-09-14 07:53:05 +02003636 bind_register_keywords(&bind_kws);
Willy Tarreau92faadf2012-10-10 23:04:25 +02003637 srv_register_keywords(&srv_kws);
Emeric Brun46591952012-05-18 15:47:34 +02003638}
3639
3640/*
3641 * Local variables:
3642 * c-indent-level: 8
3643 * c-basic-offset: 8
3644 * End:
3645 */