blob: 6121b12847a5c88262628b2adafa871bcf5026dd [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>
Emeric Brun46591952012-05-18 15:47:34 +020046
47#include <common/buffer.h>
48#include <common/compat.h>
49#include <common/config.h>
50#include <common/debug.h>
Willy Tarreau79eeafa2012-09-14 07:53:05 +020051#include <common/errors.h>
Emeric Brun46591952012-05-18 15:47:34 +020052#include <common/standard.h>
53#include <common/ticks.h>
54#include <common/time.h>
55
Emeric Brunfc0421f2012-09-07 17:30:07 +020056#include <ebsttree.h>
57
58#include <types/global.h>
59#include <types/ssl_sock.h>
60
Willy Tarreau7875d092012-09-10 08:20:03 +020061#include <proto/acl.h>
62#include <proto/arg.h>
Emeric Brun46591952012-05-18 15:47:34 +020063#include <proto/connection.h>
64#include <proto/fd.h>
65#include <proto/freq_ctr.h>
66#include <proto/frontend.h>
Willy Tarreau79eeafa2012-09-14 07:53:05 +020067#include <proto/listener.h>
Willy Tarreau92faadf2012-10-10 23:04:25 +020068#include <proto/server.h>
Emeric Brun46591952012-05-18 15:47:34 +020069#include <proto/log.h>
Emeric Brun94324a42012-10-11 14:00:19 +020070#include <proto/proxy.h>
Emeric Brunfc0421f2012-09-07 17:30:07 +020071#include <proto/shctx.h>
Emeric Brun46591952012-05-18 15:47:34 +020072#include <proto/ssl_sock.h>
73#include <proto/task.h>
74
Emeric Brune64aef12012-09-21 13:15:06 +020075#define SSL_SOCK_ST_FL_VERIFY_DONE 0x00000001
Emeric Brunf282a812012-09-21 15:27:54 +020076/* bits 0xFFFF0000 are reserved to store verify errors */
77
78/* Verify errors macros */
79#define SSL_SOCK_CA_ERROR_TO_ST(e) (((e > 63) ? 63 : e) << (16))
80#define SSL_SOCK_CAEDEPTH_TO_ST(d) (((d > 15) ? 15 : d) << (6+16))
81#define SSL_SOCK_CRTERROR_TO_ST(e) (((e > 63) ? 63 : e) << (4+6+16))
82
83#define SSL_SOCK_ST_TO_CA_ERROR(s) ((s >> (16)) & 63)
84#define SSL_SOCK_ST_TO_CAEDEPTH(s) ((s >> (6+16)) & 15)
85#define SSL_SOCK_ST_TO_CRTERROR(s) ((s >> (4+6+16)) & 63)
Emeric Brune64aef12012-09-21 13:15:06 +020086
Willy Tarreau403edff2012-09-06 11:58:37 +020087static int sslconns = 0;
Emeric Brune1f38db2012-09-03 20:36:47 +020088
89void ssl_sock_infocbk(const SSL *ssl, int where, int ret)
90{
91 struct connection *conn = (struct connection *)SSL_get_app_data(ssl);
92 (void)ret; /* shut gcc stupid warning */
93
94 if (where & SSL_CB_HANDSHAKE_START) {
95 /* Disable renegotiation (CVE-2009-3555) */
96 if (conn->flags & CO_FL_CONNECTED)
97 conn->flags |= CO_FL_ERROR;
98 }
Emeric Brunfc0421f2012-09-07 17:30:07 +020099}
100
Emeric Brune64aef12012-09-21 13:15:06 +0200101/* Callback is called for each certificate of the chain during a verify
102 ok is set to 1 if preverify detect no error on current certificate.
103 Returns 0 to break the handshake, 1 otherwise. */
104int ssl_sock_verifycbk(int ok, X509_STORE_CTX *x_store)
105{
106 SSL *ssl;
107 struct connection *conn;
Emeric Brun81c00f02012-09-21 14:31:21 +0200108 int err, depth;
Emeric Brune64aef12012-09-21 13:15:06 +0200109
110 ssl = X509_STORE_CTX_get_ex_data(x_store, SSL_get_ex_data_X509_STORE_CTX_idx());
111 conn = (struct connection *)SSL_get_app_data(ssl);
112
Willy Tarreauf7bc57c2012-10-03 00:19:48 +0200113 conn->xprt_st |= SSL_SOCK_ST_FL_VERIFY_DONE;
Emeric Brune64aef12012-09-21 13:15:06 +0200114
Emeric Brun81c00f02012-09-21 14:31:21 +0200115 if (ok) /* no errors */
116 return ok;
117
118 depth = X509_STORE_CTX_get_error_depth(x_store);
119 err = X509_STORE_CTX_get_error(x_store);
120
121 /* check if CA error needs to be ignored */
122 if (depth > 0) {
Willy Tarreauf7bc57c2012-10-03 00:19:48 +0200123 if (!SSL_SOCK_ST_TO_CA_ERROR(conn->xprt_st)) {
124 conn->xprt_st |= SSL_SOCK_CA_ERROR_TO_ST(err);
125 conn->xprt_st |= SSL_SOCK_CAEDEPTH_TO_ST(depth);
Emeric Brunf282a812012-09-21 15:27:54 +0200126 }
127
Emeric Brun81c00f02012-09-21 14:31:21 +0200128 if (target_client(&conn->target)->bind_conf->ca_ignerr & (1ULL << err))
129 return 1;
130
131 return 0;
132 }
133
Willy Tarreauf7bc57c2012-10-03 00:19:48 +0200134 if (!SSL_SOCK_ST_TO_CRTERROR(conn->xprt_st))
135 conn->xprt_st |= SSL_SOCK_CRTERROR_TO_ST(err);
Emeric Brunf282a812012-09-21 15:27:54 +0200136
Emeric Brun81c00f02012-09-21 14:31:21 +0200137 /* check if certificate error needs to be ignored */
138 if (target_client(&conn->target)->bind_conf->crt_ignerr & (1ULL << err))
139 return 1;
140
141 return 0;
Emeric Brune64aef12012-09-21 13:15:06 +0200142}
143
Emeric Brunfc0421f2012-09-07 17:30:07 +0200144#ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME
145/* Sets the SSL ctx of <ssl> to match the advertised server name. Returns a
146 * warning when no match is found, which implies the default (first) cert
147 * will keep being used.
148 */
Willy Tarreau2a65ff02012-09-13 17:54:29 +0200149static int ssl_sock_switchctx_cbk(SSL *ssl, int *al, struct bind_conf *s)
Emeric Brunfc0421f2012-09-07 17:30:07 +0200150{
151 const char *servername;
152 const char *wildp = NULL;
153 struct ebmb_node *node;
154 int i;
155 (void)al; /* shut gcc stupid warning */
156
157 servername = SSL_get_servername(ssl, TLSEXT_NAMETYPE_host_name);
158 if (!servername)
159 return SSL_TLSEXT_ERR_NOACK;
160
161 for (i = 0; i < trashlen; i++) {
162 if (!servername[i])
163 break;
164 trash[i] = tolower(servername[i]);
165 if (!wildp && (trash[i] == '.'))
166 wildp = &trash[i];
167 }
168 trash[i] = 0;
169
170 /* lookup in full qualified names */
171 node = ebst_lookup(&s->sni_ctx, trash);
172 if (!node) {
173 if (!wildp)
174 return SSL_TLSEXT_ERR_ALERT_WARNING;
175
176 /* lookup in full wildcards names */
177 node = ebst_lookup(&s->sni_w_ctx, wildp);
178 if (!node)
179 return SSL_TLSEXT_ERR_ALERT_WARNING;
180 }
181
182 /* switch ctx */
183 SSL_set_SSL_CTX(ssl, container_of(node, struct sni_ctx, name)->ctx);
184 return SSL_TLSEXT_ERR_OK;
185}
186#endif /* SSL_CTRL_SET_TLSEXT_HOSTNAME */
187
Emeric Bruna4bcd9a2012-09-20 16:19:02 +0200188#ifndef OPENSSL_NO_DH
189/* Loads Diffie-Hellman parameter from a file. Returns 1 if loaded, else -1
190 if an error occured, and 0 if parameter not found. */
191int ssl_sock_load_dh_params(SSL_CTX *ctx, const char *file)
192{
193 int ret = -1;
194 BIO *in;
195 DH *dh = NULL;
196
197 in = BIO_new(BIO_s_file());
198 if (in == NULL)
199 goto end;
200
201 if (BIO_read_filename(in, file) <= 0)
202 goto end;
203
204 dh = PEM_read_bio_DHparams(in, NULL, ctx->default_passwd_callback, ctx->default_passwd_callback_userdata);
205 if (dh) {
206 SSL_CTX_set_tmp_dh(ctx, dh);
207 ret = 1;
208 goto end;
209 }
210
211 ret = 0; /* DH params not found */
212end:
213 if (dh)
214 DH_free(dh);
215
216 if (in)
217 BIO_free(in);
218
219 return ret;
220}
221#endif
222
Emeric Brunfc0421f2012-09-07 17:30:07 +0200223/* Loads a certificate key and CA chain from a file. Returns 0 on error, -1 if
224 * an early error happens and the caller must call SSL_CTX_free() by itelf.
225 */
Willy Tarreau2a65ff02012-09-13 17:54:29 +0200226int ssl_sock_load_cert_chain_file(SSL_CTX *ctx, const char *file, struct bind_conf *s)
Emeric Brunfc0421f2012-09-07 17:30:07 +0200227{
228 BIO *in;
229 X509 *x = NULL, *ca;
230 int i, len, err;
231 int ret = -1;
232 int order = 0;
233 X509_NAME *xname;
234 char *str;
235 struct sni_ctx *sc;
236#ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME
237 STACK_OF(GENERAL_NAME) *names;
238#endif
239
240 in = BIO_new(BIO_s_file());
241 if (in == NULL)
242 goto end;
243
244 if (BIO_read_filename(in, file) <= 0)
245 goto end;
246
247 x = PEM_read_bio_X509_AUX(in, NULL, ctx->default_passwd_callback, ctx->default_passwd_callback_userdata);
248 if (x == NULL)
249 goto end;
250
251#ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME
252 names = X509_get_ext_d2i(x, NID_subject_alt_name, NULL, NULL);
253 if (names) {
254 for (i = 0; i < sk_GENERAL_NAME_num(names); i++) {
255 GENERAL_NAME *name = sk_GENERAL_NAME_value(names, i);
256 if (name->type == GEN_DNS) {
257 if (ASN1_STRING_to_UTF8((unsigned char **)&str, name->d.dNSName) >= 0) {
258 if ((len = strlen(str))) {
259 int j;
260
261 if (*str != '*') {
262 sc = malloc(sizeof(struct sni_ctx) + len + 1);
263 for (j = 0; j < len; j++)
264 sc->name.key[j] = tolower(str[j]);
265 sc->name.key[len] = 0;
266 sc->order = order++;
267 sc->ctx = ctx;
268 ebst_insert(&s->sni_ctx, &sc->name);
269 }
270 else {
271 sc = malloc(sizeof(struct sni_ctx) + len);
272 for (j = 1; j < len; j++)
273 sc->name.key[j-1] = tolower(str[j]);
274 sc->name.key[len-1] = 0;
275 sc->order = order++;
276 sc->ctx = ctx;
277 ebst_insert(&s->sni_w_ctx, &sc->name);
278 }
279 }
280 OPENSSL_free(str);
281 }
282 }
283 }
284 sk_GENERAL_NAME_pop_free(names, GENERAL_NAME_free);
285 }
286#endif /* SSL_CTRL_SET_TLSEXT_HOSTNAME */
287
288 xname = X509_get_subject_name(x);
289 i = -1;
290 while ((i = X509_NAME_get_index_by_NID(xname, NID_commonName, i)) != -1) {
291 X509_NAME_ENTRY *entry = X509_NAME_get_entry(xname, i);
292 if (ASN1_STRING_to_UTF8((unsigned char **)&str, entry->value) >= 0) {
293 if ((len = strlen(str))) {
294 int j;
295
296 if (*str != '*') {
297 sc = malloc(sizeof(struct sni_ctx) + len + 1);
298 for (j = 0; j < len; j++)
299 sc->name.key[j] = tolower(str[j]);
300 sc->name.key[len] = 0;
301 sc->order = order++;
302 sc->ctx = ctx;
303 ebst_insert(&s->sni_ctx, &sc->name);
304 }
305 else {
306 sc = malloc(sizeof(struct sni_ctx) + len);
307 for (j = 1; j < len; j++)
308 sc->name.key[j-1] = tolower(str[j]);
309 sc->name.key[len-1] = 0;
310 sc->order = order++;
311 sc->ctx = ctx;
312 ebst_insert(&s->sni_w_ctx, &sc->name);
313 }
314 }
315 OPENSSL_free(str);
316 }
317 }
318
319 ret = 0; /* the caller must not free the SSL_CTX argument anymore */
320 if (!SSL_CTX_use_certificate(ctx, x))
321 goto end;
322
323 if (ctx->extra_certs != NULL) {
324 sk_X509_pop_free(ctx->extra_certs, X509_free);
325 ctx->extra_certs = NULL;
326 }
327
328 while ((ca = PEM_read_bio_X509(in, NULL, ctx->default_passwd_callback, ctx->default_passwd_callback_userdata))) {
329 if (!SSL_CTX_add_extra_chain_cert(ctx, ca)) {
330 X509_free(ca);
331 goto end;
332 }
333 }
334
335 err = ERR_get_error();
336 if (!err || (ERR_GET_LIB(err) == ERR_LIB_PEM && ERR_GET_REASON(err) == PEM_R_NO_START_LINE)) {
337 /* we successfully reached the last cert in the file */
338 ret = 1;
339 }
340 ERR_clear_error();
341
342end:
343 if (x)
344 X509_free(x);
345
346 if (in)
347 BIO_free(in);
348
349 return ret;
350}
351
Willy Tarreau79eeafa2012-09-14 07:53:05 +0200352static int ssl_sock_load_cert_file(const char *path, struct bind_conf *bind_conf, struct proxy *curproxy, char **err)
Emeric Brunfc0421f2012-09-07 17:30:07 +0200353{
354 int ret;
355 SSL_CTX *ctx;
356
357 ctx = SSL_CTX_new(SSLv23_server_method());
358 if (!ctx) {
Willy Tarreaueb6cead2012-09-20 19:43:14 +0200359 memprintf(err, "%sunable to allocate SSL context for cert '%s'.\n",
360 err && *err ? *err : "", path);
Emeric Brunfc0421f2012-09-07 17:30:07 +0200361 return 1;
362 }
363
364 if (SSL_CTX_use_PrivateKey_file(ctx, path, SSL_FILETYPE_PEM) <= 0) {
Willy Tarreaueb6cead2012-09-20 19:43:14 +0200365 memprintf(err, "%sunable to load SSL private key from PEM file '%s'.\n",
366 err && *err ? *err : "", path);
Emeric Brunfc0421f2012-09-07 17:30:07 +0200367 SSL_CTX_free(ctx);
368 return 1;
369 }
370
Willy Tarreau2a65ff02012-09-13 17:54:29 +0200371 ret = ssl_sock_load_cert_chain_file(ctx, path, bind_conf);
Emeric Brunfc0421f2012-09-07 17:30:07 +0200372 if (ret <= 0) {
Willy Tarreaueb6cead2012-09-20 19:43:14 +0200373 memprintf(err, "%sunable to load SSL certificate from PEM file '%s'.\n",
374 err && *err ? *err : "", path);
Emeric Brunfc0421f2012-09-07 17:30:07 +0200375 if (ret < 0) /* serious error, must do that ourselves */
376 SSL_CTX_free(ctx);
377 return 1;
378 }
379 /* we must not free the SSL_CTX anymore below, since it's already in
380 * the tree, so it will be discovered and cleaned in time.
381 */
Emeric Bruna4bcd9a2012-09-20 16:19:02 +0200382#ifndef OPENSSL_NO_DH
383 ret = ssl_sock_load_dh_params(ctx, path);
384 if (ret < 0) {
385 if (err)
386 memprintf(err, "%sunable to load DH parameters from file '%s'.\n",
387 *err ? *err : "", path);
388 return 1;
389 }
390#endif
391
Emeric Brunfc0421f2012-09-07 17:30:07 +0200392#ifndef SSL_CTRL_SET_TLSEXT_HOSTNAME
Willy Tarreau2a65ff02012-09-13 17:54:29 +0200393 if (bind_conf->default_ctx) {
Willy Tarreaueb6cead2012-09-20 19:43:14 +0200394 memprintf(err, "%sthis version of openssl cannot load multiple SSL certificates.\n",
395 err && *err ? *err : "");
Emeric Brunfc0421f2012-09-07 17:30:07 +0200396 return 1;
397 }
398#endif
Willy Tarreau2a65ff02012-09-13 17:54:29 +0200399 if (!bind_conf->default_ctx)
400 bind_conf->default_ctx = ctx;
Emeric Brunfc0421f2012-09-07 17:30:07 +0200401
402 return 0;
403}
404
Willy Tarreau79eeafa2012-09-14 07:53:05 +0200405int ssl_sock_load_cert(char *path, struct bind_conf *bind_conf, struct proxy *curproxy, char **err)
Emeric Brunfc0421f2012-09-07 17:30:07 +0200406{
407 struct dirent *de;
408 DIR *dir;
409 struct stat buf;
410 int pathlen = 0;
411 char *end, *fp;
412 int cfgerr = 0;
413
414 if (!(dir = opendir(path)))
Willy Tarreau79eeafa2012-09-14 07:53:05 +0200415 return ssl_sock_load_cert_file(path, bind_conf, curproxy, err);
Emeric Brunfc0421f2012-09-07 17:30:07 +0200416
417 /* strip trailing slashes, including first one */
418 for (end = path + strlen(path) - 1; end >= path && *end == '/'; end--)
419 *end = 0;
420
421 if (end >= path)
422 pathlen = end + 1 - path;
423 fp = malloc(pathlen + 1 + NAME_MAX + 1);
424
425 while ((de = readdir(dir))) {
426 snprintf(fp, pathlen + 1 + NAME_MAX + 1, "%s/%s", path, de->d_name);
427 if (stat(fp, &buf) != 0) {
Willy Tarreaueb6cead2012-09-20 19:43:14 +0200428 memprintf(err, "%sunable to stat SSL certificate from file '%s' : %s.\n",
429 err && *err ? *err : "", fp, strerror(errno));
Emeric Brunfc0421f2012-09-07 17:30:07 +0200430 cfgerr++;
431 continue;
432 }
433 if (!S_ISREG(buf.st_mode))
434 continue;
Willy Tarreau79eeafa2012-09-14 07:53:05 +0200435 cfgerr += ssl_sock_load_cert_file(fp, bind_conf, curproxy, err);
Emeric Brunfc0421f2012-09-07 17:30:07 +0200436 }
437 free(fp);
438 closedir(dir);
439 return cfgerr;
440}
441
442#ifndef SSL_OP_CIPHER_SERVER_PREFERENCE /* needs OpenSSL >= 0.9.7 */
443#define SSL_OP_CIPHER_SERVER_PREFERENCE 0
444#endif
445
446#ifndef SSL_OP_NO_SESSION_RESUMPTION_ON_RENEGOTIATION /* needs OpenSSL >= 0.9.7 */
447#define SSL_OP_NO_SESSION_RESUMPTION_ON_RENEGOTIATION 0
448#endif
Emeric Brun2b58d042012-09-20 17:10:03 +0200449#ifndef SSL_OP_SINGLE_ECDH_USE /* needs OpenSSL >= 0.9.8 */
450#define SSL_OP_SINGLE_ECDH_USE 0
451#endif
Emeric Brun2d0c4822012-10-02 13:45:20 +0200452#ifndef SSL_OP_NO_TICKET /* needs OpenSSL >= 0.9.8 */
453#define SSL_OP_NO_TICKET 0
454#endif
Emeric Brunfc0421f2012-09-07 17:30:07 +0200455#ifndef SSL_OP_NO_COMPRESSION /* needs OpenSSL >= 0.9.9 */
456#define SSL_OP_NO_COMPRESSION 0
457#endif
Emeric Brunc0ff4922012-09-28 19:37:02 +0200458#ifndef SSL_OP_NO_TLSv1_1 /* needs OpenSSL >= 1.0.1 */
459#define SSL_OP_NO_TLSv1_1 0
460#endif
461#ifndef SSL_OP_NO_TLSv1_2 /* needs OpenSSL >= 1.0.1 */
462#define SSL_OP_NO_TLSv1_2 0
463#endif
Emeric Bruna4bcd9a2012-09-20 16:19:02 +0200464#ifndef SSL_OP_SINGLE_DH_USE /* needs OpenSSL >= 0.9.6 */
465#define SSL_OP_SINGLE_DH_USE 0
466#endif
Emeric Brun2b58d042012-09-20 17:10:03 +0200467#ifndef SSL_OP_SINGLE_ECDH_USE /* needs OpenSSL >= 1.0.0 */
468#define SSL_OP_SINGLE_ECDH_USE 0
469#endif
Emeric Brunfc0421f2012-09-07 17:30:07 +0200470#ifndef SSL_MODE_RELEASE_BUFFERS /* needs OpenSSL >= 1.0.0 */
471#define SSL_MODE_RELEASE_BUFFERS 0
472#endif
Willy Tarreau2a65ff02012-09-13 17:54:29 +0200473int ssl_sock_prepare_ctx(struct bind_conf *bind_conf, SSL_CTX *ctx, struct proxy *curproxy)
Emeric Brunfc0421f2012-09-07 17:30:07 +0200474{
475 int cfgerr = 0;
476 int ssloptions =
477 SSL_OP_ALL | /* all known workarounds for bugs */
478 SSL_OP_NO_SSLv2 |
479 SSL_OP_NO_COMPRESSION |
Emeric Bruna4bcd9a2012-09-20 16:19:02 +0200480 SSL_OP_SINGLE_DH_USE |
Emeric Brun2b58d042012-09-20 17:10:03 +0200481 SSL_OP_SINGLE_ECDH_USE |
Emeric Brun3c4bc6e2012-10-04 18:44:19 +0200482 SSL_OP_NO_SESSION_RESUMPTION_ON_RENEGOTIATION |
483 SSL_OP_CIPHER_SERVER_PREFERENCE;
Emeric Brunfc0421f2012-09-07 17:30:07 +0200484 int sslmode =
485 SSL_MODE_ENABLE_PARTIAL_WRITE |
486 SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER |
487 SSL_MODE_RELEASE_BUFFERS;
488
Emeric Brun89675492012-10-05 13:48:26 +0200489 if (bind_conf->ssl_options & BC_SSL_O_NO_SSLV3)
Emeric Brunfc0421f2012-09-07 17:30:07 +0200490 ssloptions |= SSL_OP_NO_SSLv3;
Emeric Brun89675492012-10-05 13:48:26 +0200491 if (bind_conf->ssl_options & BC_SSL_O_NO_TLSV10)
Emeric Brunfc0421f2012-09-07 17:30:07 +0200492 ssloptions |= SSL_OP_NO_TLSv1;
Emeric Brun89675492012-10-05 13:48:26 +0200493 if (bind_conf->ssl_options & BC_SSL_O_NO_TLSV11)
Emeric Brunc0ff4922012-09-28 19:37:02 +0200494 ssloptions |= SSL_OP_NO_TLSv1_1;
Emeric Brun89675492012-10-05 13:48:26 +0200495 if (bind_conf->ssl_options & BC_SSL_O_NO_TLSV12)
Emeric Brunc0ff4922012-09-28 19:37:02 +0200496 ssloptions |= SSL_OP_NO_TLSv1_2;
Emeric Brun89675492012-10-05 13:48:26 +0200497 if (bind_conf->ssl_options & BC_SSL_O_NO_TLS_TICKETS)
Emeric Brun2d0c4822012-10-02 13:45:20 +0200498 ssloptions |= SSL_OP_NO_TICKET;
Emeric Brun2cb7ae52012-10-05 14:14:21 +0200499 if (bind_conf->ssl_options & BC_SSL_O_USE_SSLV3)
500 SSL_CTX_set_ssl_version(ctx, SSLv3_server_method());
501 if (bind_conf->ssl_options & BC_SSL_O_USE_TLSV10)
502 SSL_CTX_set_ssl_version(ctx, TLSv1_server_method());
503#if SSL_OP_NO_TLSv1_1
504 if (bind_conf->ssl_options & BC_SSL_O_USE_TLSV11)
505 SSL_CTX_set_ssl_version(ctx, TLSv1_1_server_method());
506#endif
507#if SSL_OP_NO_TLSv1_2
508 if (bind_conf->ssl_options & BC_SSL_O_USE_TLSV12)
509 SSL_CTX_set_ssl_version(ctx, TLSv1_2_server_method());
510#endif
Emeric Brunfc0421f2012-09-07 17:30:07 +0200511
512 SSL_CTX_set_options(ctx, ssloptions);
513 SSL_CTX_set_mode(ctx, sslmode);
Emeric Brune64aef12012-09-21 13:15:06 +0200514 SSL_CTX_set_verify(ctx, bind_conf->verify ? bind_conf->verify : SSL_VERIFY_NONE, ssl_sock_verifycbk);
Emeric Brund94b3fe2012-09-20 18:23:56 +0200515 if (bind_conf->verify & SSL_VERIFY_PEER) {
Emeric Brunfb510ea2012-10-05 12:00:26 +0200516 if (bind_conf->ca_file) {
Emeric Brund94b3fe2012-09-20 18:23:56 +0200517 /* load CAfile to verify */
Emeric Brunfb510ea2012-10-05 12:00:26 +0200518 if (!SSL_CTX_load_verify_locations(ctx, bind_conf->ca_file, NULL)) {
Emeric Brund94b3fe2012-09-20 18:23:56 +0200519 Alert("Proxy '%s': unable to load CA file '%s' for bind '%s' at [%s:%d].\n",
Emeric Brunfb510ea2012-10-05 12:00:26 +0200520 curproxy->id, bind_conf->ca_file, bind_conf->arg, bind_conf->file, bind_conf->line);
Emeric Brund94b3fe2012-09-20 18:23:56 +0200521 cfgerr++;
522 }
523 /* set CA names fo client cert request, function returns void */
Emeric Brunfb510ea2012-10-05 12:00:26 +0200524 SSL_CTX_set_client_CA_list(ctx, SSL_load_client_CA_file(bind_conf->ca_file));
Emeric Brund94b3fe2012-09-20 18:23:56 +0200525 }
Emeric Brun051cdab2012-10-02 19:25:50 +0200526#ifdef X509_V_FLAG_CRL_CHECK
Emeric Brunfb510ea2012-10-05 12:00:26 +0200527 if (bind_conf->crl_file) {
Emeric Brund94b3fe2012-09-20 18:23:56 +0200528 X509_STORE *store = SSL_CTX_get_cert_store(ctx);
529
Emeric Brunfb510ea2012-10-05 12:00:26 +0200530 if (!store || !X509_STORE_load_locations(store, bind_conf->crl_file, NULL)) {
Emeric Brund94b3fe2012-09-20 18:23:56 +0200531 Alert("Proxy '%s': unable to configure CRL file '%s' for bind '%s' at [%s:%d].\n",
Emeric Brunfb510ea2012-10-05 12:00:26 +0200532 curproxy->id, bind_conf->ca_file, bind_conf->arg, bind_conf->file, bind_conf->line);
Emeric Brund94b3fe2012-09-20 18:23:56 +0200533 cfgerr++;
534 }
Emeric Brun561e5742012-10-02 15:20:55 +0200535 else {
536 X509_STORE_set_flags(store, X509_V_FLAG_CRL_CHECK|X509_V_FLAG_CRL_CHECK_ALL);
537 }
Emeric Brund94b3fe2012-09-20 18:23:56 +0200538 }
Emeric Brun051cdab2012-10-02 19:25:50 +0200539#endif
Emeric Brund94b3fe2012-09-20 18:23:56 +0200540 }
Emeric Brunfc0421f2012-09-07 17:30:07 +0200541
542 shared_context_set_cache(ctx);
Willy Tarreau2a65ff02012-09-13 17:54:29 +0200543 if (bind_conf->ciphers &&
544 !SSL_CTX_set_cipher_list(ctx, bind_conf->ciphers)) {
Emeric Brunfc0421f2012-09-07 17:30:07 +0200545 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 +0200546 curproxy->id, bind_conf->ciphers, bind_conf->arg, bind_conf->file, bind_conf->line);
Emeric Brunfc0421f2012-09-07 17:30:07 +0200547 cfgerr++;
548 }
549
550 SSL_CTX_set_info_callback(ctx, ssl_sock_infocbk);
551#ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME
552 SSL_CTX_set_tlsext_servername_callback(ctx, ssl_sock_switchctx_cbk);
Willy Tarreau2a65ff02012-09-13 17:54:29 +0200553 SSL_CTX_set_tlsext_servername_arg(ctx, bind_conf);
Emeric Brunfc0421f2012-09-07 17:30:07 +0200554#endif
Emeric Brun2b58d042012-09-20 17:10:03 +0200555#if defined(SSL_CTX_set_tmp_ecdh) && !defined(OPENSSL_NO_ECDH)
556 if (bind_conf->ecdhe) {
557 int i;
558 EC_KEY *ecdh;
559
560 i = OBJ_sn2nid(bind_conf->ecdhe);
561 if (!i || ((ecdh = EC_KEY_new_by_curve_name(i)) == NULL)) {
562 Alert("Proxy '%s': unable to set elliptic named curve to '%s' for bind '%s' at [%s:%d].\n",
563 curproxy->id, bind_conf->ecdhe, bind_conf->arg, bind_conf->file, bind_conf->line);
564 cfgerr++;
565 }
566 else {
567 SSL_CTX_set_tmp_ecdh(ctx, ecdh);
568 EC_KEY_free(ecdh);
569 }
570 }
571#endif
572
Emeric Brunfc0421f2012-09-07 17:30:07 +0200573 return cfgerr;
574}
575
Emeric Brun94324a42012-10-11 14:00:19 +0200576/* prepare ssl context from servers options. Returns an error count */
577int ssl_sock_prepare_srv_ctx(struct server *srv, struct proxy *curproxy)
578{
579 int cfgerr = 0;
580 int options =
581 SSL_OP_ALL | /* all known workarounds for bugs */
582 SSL_OP_NO_SSLv2 |
583 SSL_OP_NO_COMPRESSION;
584 int mode =
585 SSL_MODE_ENABLE_PARTIAL_WRITE |
586 SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER |
587 SSL_MODE_RELEASE_BUFFERS;
588
589 /* Initiate SSL context for current server */
590 srv->ssl_ctx.reused_sess = NULL;
591 if (srv->use_ssl)
592 srv->xprt = &ssl_sock;
593 if (srv->check.use_ssl)
594 srv->check.xprt = &ssl_sock;
595
596 srv->ssl_ctx.ctx = SSL_CTX_new(SSLv23_client_method());
597 if (!srv->ssl_ctx.ctx) {
598 Alert("config : %s '%s', server '%s': unable to allocate ssl context.\n",
599 proxy_type_str(curproxy), curproxy->id,
600 srv->id);
601 cfgerr++;
602 return cfgerr;
603 }
604
605
606 if (srv->ssl_ctx.options & SRV_SSL_O_NO_SSLV3)
607 options |= SSL_OP_NO_SSLv3;
608 if (srv->ssl_ctx.options & SRV_SSL_O_NO_TLSV10)
609 options |= SSL_OP_NO_TLSv1;
610 if (srv->ssl_ctx.options & SRV_SSL_O_NO_TLSV11)
611 options |= SSL_OP_NO_TLSv1_1;
612 if (srv->ssl_ctx.options & SRV_SSL_O_NO_TLSV12)
613 options |= SSL_OP_NO_TLSv1_2;
Emeric Brunf9c5c472012-10-11 15:28:34 +0200614 if (srv->ssl_ctx.options & SRV_SSL_O_NO_TLS_TICKETS)
615 options |= SSL_OP_NO_TICKET;
Emeric Brun94324a42012-10-11 14:00:19 +0200616 if (srv->ssl_ctx.options & SRV_SSL_O_USE_SSLV3)
617 SSL_CTX_set_ssl_version(srv->ssl_ctx.ctx, SSLv3_client_method());
618 if (srv->ssl_ctx.options & SRV_SSL_O_USE_TLSV10)
619 SSL_CTX_set_ssl_version(srv->ssl_ctx.ctx, TLSv1_client_method());
620#if SSL_OP_NO_TLSv1_1
621 if (srv->ssl_ctx.options & SRV_SSL_O_USE_TLSV11)
622 SSL_CTX_set_ssl_version(srv->ssl_ctx.ctx, TLSv1_1_client_method());
623#endif
624#if SSL_OP_NO_TLSv1_2
625 if (srv->ssl_ctx.options & SRV_SSL_O_USE_TLSV12)
626 SSL_CTX_set_ssl_version(srv->ssl_ctx.ctx, TLSv1_2_client_method());
627#endif
628
629 SSL_CTX_set_options(srv->ssl_ctx.ctx, options);
630 SSL_CTX_set_mode(srv->ssl_ctx.ctx, mode);
Emeric Brunef42d922012-10-11 16:11:36 +0200631 SSL_CTX_set_verify(srv->ssl_ctx.ctx, srv->ssl_ctx.verify ? srv->ssl_ctx.verify : SSL_VERIFY_NONE, NULL);
632 if (srv->ssl_ctx.verify & SSL_VERIFY_PEER) {
633 if (srv->ssl_ctx.ca_file) {
634 /* load CAfile to verify */
635 if (!SSL_CTX_load_verify_locations(srv->ssl_ctx.ctx, srv->ssl_ctx.ca_file, NULL)) {
636 Alert("Proxy '%s', server '%s' |%s:%d] unable to load CA file '%s'.\n",
637 curproxy->id, srv->id,
638 srv->conf.file, srv->conf.line, srv->ssl_ctx.ca_file);
639 cfgerr++;
640 }
641 }
642#ifdef X509_V_FLAG_CRL_CHECK
643 if (srv->ssl_ctx.crl_file) {
644 X509_STORE *store = SSL_CTX_get_cert_store(srv->ssl_ctx.ctx);
645
646 if (!store || !X509_STORE_load_locations(store, srv->ssl_ctx.crl_file, NULL)) {
647 Alert("Proxy '%s', server '%s' |%s:%d] unable to configure CRL file '%s'.\n",
648 curproxy->id, srv->id,
649 srv->conf.file, srv->conf.line, srv->ssl_ctx.crl_file);
650 cfgerr++;
651 }
652 else {
653 X509_STORE_set_flags(store, X509_V_FLAG_CRL_CHECK|X509_V_FLAG_CRL_CHECK_ALL);
654 }
655 }
656#endif
657 }
658
Emeric Brun94324a42012-10-11 14:00:19 +0200659 SSL_CTX_set_session_cache_mode(srv->ssl_ctx.ctx, SSL_SESS_CACHE_OFF);
660 if (srv->ssl_ctx.ciphers &&
661 !SSL_CTX_set_cipher_list(srv->ssl_ctx.ctx, srv->ssl_ctx.ciphers)) {
662 Alert("Proxy '%s', server '%s' [%s:%d] : unable to set SSL cipher list to '%s'.\n",
663 curproxy->id, srv->id,
664 srv->conf.file, srv->conf.line, srv->ssl_ctx.ciphers);
665 cfgerr++;
666 }
667
668 return cfgerr;
669}
670
Willy Tarreau2a65ff02012-09-13 17:54:29 +0200671/* Walks down the two trees in bind_conf and prepares all certs. The pointer may
Emeric Brunfc0421f2012-09-07 17:30:07 +0200672 * be NULL, in which case nothing is done. Returns the number of errors
673 * encountered.
674 */
Willy Tarreau2a65ff02012-09-13 17:54:29 +0200675int ssl_sock_prepare_all_ctx(struct bind_conf *bind_conf, struct proxy *px)
Emeric Brunfc0421f2012-09-07 17:30:07 +0200676{
677 struct ebmb_node *node;
678 struct sni_ctx *sni;
679 int err = 0;
680
Willy Tarreau2a65ff02012-09-13 17:54:29 +0200681 if (!bind_conf || !bind_conf->is_ssl)
Emeric Brunfc0421f2012-09-07 17:30:07 +0200682 return 0;
683
Willy Tarreau2a65ff02012-09-13 17:54:29 +0200684 node = ebmb_first(&bind_conf->sni_ctx);
Emeric Brunfc0421f2012-09-07 17:30:07 +0200685 while (node) {
686 sni = ebmb_entry(node, struct sni_ctx, name);
687 if (!sni->order) /* only initialize the CTX on its first occurrence */
Willy Tarreau2a65ff02012-09-13 17:54:29 +0200688 err += ssl_sock_prepare_ctx(bind_conf, sni->ctx, px);
Emeric Brunfc0421f2012-09-07 17:30:07 +0200689 node = ebmb_next(node);
690 }
691
Willy Tarreau2a65ff02012-09-13 17:54:29 +0200692 node = ebmb_first(&bind_conf->sni_w_ctx);
Emeric Brunfc0421f2012-09-07 17:30:07 +0200693 while (node) {
694 sni = ebmb_entry(node, struct sni_ctx, name);
695 if (!sni->order) /* only initialize the CTX on its first occurrence */
Willy Tarreau2a65ff02012-09-13 17:54:29 +0200696 err += ssl_sock_prepare_ctx(bind_conf, sni->ctx, px);
Emeric Brunfc0421f2012-09-07 17:30:07 +0200697 node = ebmb_next(node);
698 }
699 return err;
700}
701
Willy Tarreau2a65ff02012-09-13 17:54:29 +0200702/* Walks down the two trees in bind_conf and frees all the certs. The pointer may
Emeric Brunfc0421f2012-09-07 17:30:07 +0200703 * be NULL, in which case nothing is done. The default_ctx is nullified too.
704 */
Willy Tarreau2a65ff02012-09-13 17:54:29 +0200705void ssl_sock_free_all_ctx(struct bind_conf *bind_conf)
Emeric Brunfc0421f2012-09-07 17:30:07 +0200706{
707 struct ebmb_node *node, *back;
708 struct sni_ctx *sni;
709
Willy Tarreau2a65ff02012-09-13 17:54:29 +0200710 if (!bind_conf || !bind_conf->is_ssl)
Emeric Brunfc0421f2012-09-07 17:30:07 +0200711 return;
712
Willy Tarreau2a65ff02012-09-13 17:54:29 +0200713 node = ebmb_first(&bind_conf->sni_ctx);
Emeric Brunfc0421f2012-09-07 17:30:07 +0200714 while (node) {
715 sni = ebmb_entry(node, struct sni_ctx, name);
716 back = ebmb_next(node);
717 ebmb_delete(node);
718 if (!sni->order) /* only free the CTX on its first occurrence */
719 SSL_CTX_free(sni->ctx);
720 free(sni);
721 node = back;
722 }
723
Willy Tarreau2a65ff02012-09-13 17:54:29 +0200724 node = ebmb_first(&bind_conf->sni_w_ctx);
Emeric Brunfc0421f2012-09-07 17:30:07 +0200725 while (node) {
726 sni = ebmb_entry(node, struct sni_ctx, name);
727 back = ebmb_next(node);
728 ebmb_delete(node);
729 if (!sni->order) /* only free the CTX on its first occurrence */
730 SSL_CTX_free(sni->ctx);
731 free(sni);
732 node = back;
733 }
734
Willy Tarreau2a65ff02012-09-13 17:54:29 +0200735 bind_conf->default_ctx = NULL;
Emeric Brune1f38db2012-09-03 20:36:47 +0200736}
737
Emeric Brun46591952012-05-18 15:47:34 +0200738/*
739 * This function is called if SSL * context is not yet allocated. The function
740 * is designed to be called before any other data-layer operation and sets the
741 * handshake flag on the connection. It is safe to call it multiple times.
742 * It returns 0 on success and -1 in error case.
743 */
744static int ssl_sock_init(struct connection *conn)
745{
746 /* already initialized */
Willy Tarreauf7bc57c2012-10-03 00:19:48 +0200747 if (conn->xprt_ctx)
Emeric Brun46591952012-05-18 15:47:34 +0200748 return 0;
749
Willy Tarreau403edff2012-09-06 11:58:37 +0200750 if (global.maxsslconn && sslconns >= global.maxsslconn)
751 return -1;
752
Emeric Brun46591952012-05-18 15:47:34 +0200753 /* If it is in client mode initiate SSL session
754 in connect state otherwise accept state */
755 if (target_srv(&conn->target)) {
Emeric Brun46591952012-05-18 15:47:34 +0200756 /* Alloc a new SSL session ctx */
Willy Tarreauf7bc57c2012-10-03 00:19:48 +0200757 conn->xprt_ctx = SSL_new(target_srv(&conn->target)->ssl_ctx.ctx);
758 if (!conn->xprt_ctx)
Emeric Brun46591952012-05-18 15:47:34 +0200759 return -1;
760
Willy Tarreauf7bc57c2012-10-03 00:19:48 +0200761 SSL_set_connect_state(conn->xprt_ctx);
Emeric Brun46591952012-05-18 15:47:34 +0200762 if (target_srv(&conn->target)->ssl_ctx.reused_sess)
Willy Tarreauf7bc57c2012-10-03 00:19:48 +0200763 SSL_set_session(conn->xprt_ctx, target_srv(&conn->target)->ssl_ctx.reused_sess);
Emeric Brun46591952012-05-18 15:47:34 +0200764
765 /* set fd on SSL session context */
Willy Tarreauf7bc57c2012-10-03 00:19:48 +0200766 SSL_set_fd(conn->xprt_ctx, conn->t.sock.fd);
Emeric Brun46591952012-05-18 15:47:34 +0200767
768 /* leave init state and start handshake */
Willy Tarreau05737472012-09-04 08:03:39 +0200769 conn->flags |= CO_FL_SSL_WAIT_HS | CO_FL_WAIT_L6_CONN;
Willy Tarreau403edff2012-09-06 11:58:37 +0200770
771 sslconns++;
Emeric Brun46591952012-05-18 15:47:34 +0200772 return 0;
773 }
774 else if (target_client(&conn->target)) {
Emeric Brun46591952012-05-18 15:47:34 +0200775 /* Alloc a new SSL session ctx */
Willy Tarreauf7bc57c2012-10-03 00:19:48 +0200776 conn->xprt_ctx = SSL_new(target_client(&conn->target)->bind_conf->default_ctx);
777 if (!conn->xprt_ctx)
Emeric Brun46591952012-05-18 15:47:34 +0200778 return -1;
779
Willy Tarreauf7bc57c2012-10-03 00:19:48 +0200780 SSL_set_accept_state(conn->xprt_ctx);
Emeric Brun46591952012-05-18 15:47:34 +0200781
782 /* set fd on SSL session context */
Willy Tarreauf7bc57c2012-10-03 00:19:48 +0200783 SSL_set_fd(conn->xprt_ctx, conn->t.sock.fd);
Emeric Brun46591952012-05-18 15:47:34 +0200784
Emeric Brune1f38db2012-09-03 20:36:47 +0200785 /* set connection pointer */
Willy Tarreauf7bc57c2012-10-03 00:19:48 +0200786 SSL_set_app_data(conn->xprt_ctx, conn);
Emeric Brune1f38db2012-09-03 20:36:47 +0200787
Emeric Brun46591952012-05-18 15:47:34 +0200788 /* leave init state and start handshake */
Willy Tarreau05737472012-09-04 08:03:39 +0200789 conn->flags |= CO_FL_SSL_WAIT_HS | CO_FL_WAIT_L6_CONN;
Willy Tarreau403edff2012-09-06 11:58:37 +0200790
791 sslconns++;
Emeric Brun46591952012-05-18 15:47:34 +0200792 return 0;
793 }
794 /* don't know how to handle such a target */
795 return -1;
796}
797
798
799/* This is the callback which is used when an SSL handshake is pending. It
800 * updates the FD status if it wants some polling before being called again.
801 * It returns 0 if it fails in a fatal way or needs to poll to go further,
802 * otherwise it returns non-zero and removes itself from the connection's
803 * flags (the bit is provided in <flag> by the caller).
804 */
805int ssl_sock_handshake(struct connection *conn, unsigned int flag)
806{
807 int ret;
808
Willy Tarreauf7bc57c2012-10-03 00:19:48 +0200809 if (!conn->xprt_ctx)
Emeric Brun46591952012-05-18 15:47:34 +0200810 goto out_error;
811
Willy Tarreauf7bc57c2012-10-03 00:19:48 +0200812 ret = SSL_do_handshake(conn->xprt_ctx);
Emeric Brun46591952012-05-18 15:47:34 +0200813 if (ret != 1) {
814 /* handshake did not complete, let's find why */
Willy Tarreauf7bc57c2012-10-03 00:19:48 +0200815 ret = SSL_get_error(conn->xprt_ctx, ret);
Emeric Brun46591952012-05-18 15:47:34 +0200816
817 if (ret == SSL_ERROR_WANT_WRITE) {
818 /* SSL handshake needs to write, L4 connection may not be ready */
819 __conn_sock_stop_recv(conn);
820 __conn_sock_poll_send(conn);
821 return 0;
822 }
823 else if (ret == SSL_ERROR_WANT_READ) {
824 /* SSL handshake needs to read, L4 connection is ready */
825 if (conn->flags & CO_FL_WAIT_L4_CONN)
826 conn->flags &= ~CO_FL_WAIT_L4_CONN;
827 __conn_sock_stop_send(conn);
828 __conn_sock_poll_recv(conn);
829 return 0;
830 }
Willy Tarreau89230192012-09-28 20:22:13 +0200831 else if (ret == SSL_ERROR_SYSCALL) {
832 /* if errno is null, then connection was successfully established */
833 if (!errno && conn->flags & CO_FL_WAIT_L4_CONN)
834 conn->flags &= ~CO_FL_WAIT_L4_CONN;
835 goto out_error;
836 }
Emeric Brun46591952012-05-18 15:47:34 +0200837 else {
838 /* Fail on all other handshake errors */
839 goto out_error;
840 }
841 }
842
843 /* Handshake succeeded */
844 if (target_srv(&conn->target)) {
Willy Tarreauf7bc57c2012-10-03 00:19:48 +0200845 if (!SSL_session_reused(conn->xprt_ctx)) {
Emeric Brun46591952012-05-18 15:47:34 +0200846 /* check if session was reused, if not store current session on server for reuse */
847 if (target_srv(&conn->target)->ssl_ctx.reused_sess)
848 SSL_SESSION_free(target_srv(&conn->target)->ssl_ctx.reused_sess);
849
Willy Tarreauf7bc57c2012-10-03 00:19:48 +0200850 target_srv(&conn->target)->ssl_ctx.reused_sess = SSL_get1_session(conn->xprt_ctx);
Emeric Brun46591952012-05-18 15:47:34 +0200851 }
852 }
853
854 /* The connection is now established at both layers, it's time to leave */
855 conn->flags &= ~(flag | CO_FL_WAIT_L4_CONN | CO_FL_WAIT_L6_CONN);
856 return 1;
857
858 out_error:
Emeric Brun9fa89732012-10-04 17:09:56 +0200859 /* free resumed session if exists */
860 if (target_srv(&conn->target) && target_srv(&conn->target)->ssl_ctx.reused_sess) {
861 SSL_SESSION_free(target_srv(&conn->target)->ssl_ctx.reused_sess);
862 target_srv(&conn->target)->ssl_ctx.reused_sess = NULL;
863 }
864
Emeric Brun46591952012-05-18 15:47:34 +0200865 /* Fail on all other handshake errors */
866 conn->flags |= CO_FL_ERROR;
867 conn->flags &= ~flag;
868 return 0;
869}
870
871/* Receive up to <count> bytes from connection <conn>'s socket and store them
872 * into buffer <buf>. The caller must ensure that <count> is always smaller
873 * than the buffer's size. Only one call to recv() is performed, unless the
874 * buffer wraps, in which case a second call may be performed. The connection's
875 * flags are updated with whatever special event is detected (error, read0,
876 * empty). The caller is responsible for taking care of those events and
877 * avoiding the call if inappropriate. The function does not call the
878 * connection's polling update function, so the caller is responsible for this.
879 */
880static int ssl_sock_to_buf(struct connection *conn, struct buffer *buf, int count)
881{
882 int ret, done = 0;
883 int try = count;
884
Willy Tarreauf7bc57c2012-10-03 00:19:48 +0200885 if (!conn->xprt_ctx)
Emeric Brun46591952012-05-18 15:47:34 +0200886 goto out_error;
887
888 if (conn->flags & CO_FL_HANDSHAKE)
889 /* a handshake was requested */
890 return 0;
891
892 /* compute the maximum block size we can read at once. */
893 if (buffer_empty(buf)) {
894 /* let's realign the buffer to optimize I/O */
895 buf->p = buf->data;
896 }
897 else if (buf->data + buf->o < buf->p &&
898 buf->p + buf->i < buf->data + buf->size) {
899 /* remaining space wraps at the end, with a moving limit */
900 if (try > buf->data + buf->size - (buf->p + buf->i))
901 try = buf->data + buf->size - (buf->p + buf->i);
902 }
903
904 /* read the largest possible block. For this, we perform only one call
905 * to recv() unless the buffer wraps and we exactly fill the first hunk,
906 * in which case we accept to do it once again. A new attempt is made on
907 * EINTR too.
908 */
909 while (try) {
Willy Tarreauf7bc57c2012-10-03 00:19:48 +0200910 ret = SSL_read(conn->xprt_ctx, bi_end(buf), try);
Emeric Brune1f38db2012-09-03 20:36:47 +0200911 if (conn->flags & CO_FL_ERROR) {
912 /* CO_FL_ERROR may be set by ssl_sock_infocbk */
913 break;
914 }
Emeric Brun46591952012-05-18 15:47:34 +0200915 if (ret > 0) {
916 buf->i += ret;
917 done += ret;
918 if (ret < try)
919 break;
920 count -= ret;
921 try = count;
922 }
923 else if (ret == 0) {
924 goto read0;
925 }
926 else {
Willy Tarreauf7bc57c2012-10-03 00:19:48 +0200927 ret = SSL_get_error(conn->xprt_ctx, ret);
Emeric Brun46591952012-05-18 15:47:34 +0200928 if (ret == SSL_ERROR_WANT_WRITE) {
929 /* handshake is running, and it needs to poll for a write event */
930 conn->flags |= CO_FL_SSL_WAIT_HS;
931 __conn_sock_poll_send(conn);
932 break;
933 }
934 else if (ret == SSL_ERROR_WANT_READ) {
935 /* we need to poll for retry a read later */
936 __conn_data_poll_recv(conn);
937 break;
938 }
939 /* otherwise it's a real error */
940 goto out_error;
941 }
942 }
943 return done;
944
945 read0:
946 conn_sock_read0(conn);
947 return done;
948 out_error:
949 conn->flags |= CO_FL_ERROR;
950 return done;
951}
952
953
954/* Send all pending bytes from buffer <buf> to connection <conn>'s socket.
955 * <flags> may contain MSG_MORE to make the system hold on without sending
956 * data too fast, but this flag is ignored at the moment.
957 * Only one call to send() is performed, unless the buffer wraps, in which case
958 * a second call may be performed. The connection's flags are updated with
959 * whatever special event is detected (error, empty). The caller is responsible
960 * for taking care of those events and avoiding the call if inappropriate. The
961 * function does not call the connection's polling update function, so the caller
962 * is responsible for this.
963 */
964static int ssl_sock_from_buf(struct connection *conn, struct buffer *buf, int flags)
965{
966 int ret, try, done;
967
968 done = 0;
969
Willy Tarreauf7bc57c2012-10-03 00:19:48 +0200970 if (!conn->xprt_ctx)
Emeric Brun46591952012-05-18 15:47:34 +0200971 goto out_error;
972
973 if (conn->flags & CO_FL_HANDSHAKE)
974 /* a handshake was requested */
975 return 0;
976
977 /* send the largest possible block. For this we perform only one call
978 * to send() unless the buffer wraps and we exactly fill the first hunk,
979 * in which case we accept to do it once again.
980 */
981 while (buf->o) {
982 try = buf->o;
983 /* outgoing data may wrap at the end */
984 if (buf->data + try > buf->p)
985 try = buf->data + try - buf->p;
986
Willy Tarreauf7bc57c2012-10-03 00:19:48 +0200987 ret = SSL_write(conn->xprt_ctx, bo_ptr(buf), try);
Emeric Brune1f38db2012-09-03 20:36:47 +0200988 if (conn->flags & CO_FL_ERROR) {
989 /* CO_FL_ERROR may be set by ssl_sock_infocbk */
990 break;
991 }
Emeric Brun46591952012-05-18 15:47:34 +0200992 if (ret > 0) {
993 buf->o -= ret;
994 done += ret;
995
996 if (likely(!buffer_len(buf)))
997 /* optimize data alignment in the buffer */
998 buf->p = buf->data;
999
1000 /* if the system buffer is full, don't insist */
1001 if (ret < try)
1002 break;
1003 }
1004 else {
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02001005 ret = SSL_get_error(conn->xprt_ctx, ret);
Emeric Brun46591952012-05-18 15:47:34 +02001006 if (ret == SSL_ERROR_WANT_WRITE) {
1007 /* we need to poll to retry a write later */
1008 __conn_data_poll_send(conn);
1009 break;
1010 }
1011 else if (ret == SSL_ERROR_WANT_READ) {
1012 /* handshake is running, and
1013 it needs to poll for a read event,
1014 write polling must be disabled cause
1015 we are sure we can't write anything more
1016 before handshake re-performed */
1017 conn->flags |= CO_FL_SSL_WAIT_HS;
1018 __conn_sock_poll_recv(conn);
1019 break;
1020 }
1021 goto out_error;
1022 }
1023 }
1024 return done;
1025
1026 out_error:
1027 conn->flags |= CO_FL_ERROR;
1028 return done;
1029}
1030
1031
1032static void ssl_sock_close(struct connection *conn) {
1033
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02001034 if (conn->xprt_ctx) {
1035 SSL_free(conn->xprt_ctx);
1036 conn->xprt_ctx = NULL;
Willy Tarreau403edff2012-09-06 11:58:37 +02001037 sslconns--;
Emeric Brun46591952012-05-18 15:47:34 +02001038 }
Emeric Brun46591952012-05-18 15:47:34 +02001039}
1040
1041/* This function tries to perform a clean shutdown on an SSL connection, and in
1042 * any case, flags the connection as reusable if no handshake was in progress.
1043 */
1044static void ssl_sock_shutw(struct connection *conn, int clean)
1045{
1046 if (conn->flags & CO_FL_HANDSHAKE)
1047 return;
1048 /* no handshake was in progress, try a clean ssl shutdown */
1049 if (clean)
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02001050 SSL_shutdown(conn->xprt_ctx);
Emeric Brun46591952012-05-18 15:47:34 +02001051
1052 /* force flag on ssl to keep session in cache regardless shutdown result */
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02001053 SSL_set_shutdown(conn->xprt_ctx, SSL_SENT_SHUTDOWN);
Emeric Brun46591952012-05-18 15:47:34 +02001054}
1055
Willy Tarreauffc3fcd2012-10-12 20:17:54 +02001056/* used for logging, may be changed for a sample fetch later */
1057const char *ssl_sock_get_cipher_name(struct connection *conn)
1058{
1059 if (!conn->xprt && !conn->xprt_ctx)
1060 return NULL;
1061 return SSL_get_cipher_name(conn->xprt_ctx);
1062}
1063
1064/* used for logging, may be changed for a sample fetch later */
1065const char *ssl_sock_get_proto_version(struct connection *conn)
1066{
1067 if (!conn->xprt && !conn->xprt_ctx)
1068 return NULL;
1069 return SSL_get_version(conn->xprt_ctx);
1070}
1071
Willy Tarreau7875d092012-09-10 08:20:03 +02001072/***** Below are some sample fetching functions for ACL/patterns *****/
1073
Emeric Brune64aef12012-09-21 13:15:06 +02001074/* boolean, returns true if client cert was present */
1075static int
1076smp_fetch_client_crt(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
1077 const struct arg *args, struct sample *smp)
1078{
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02001079 if (!l4 || l4->si[0].conn.xprt != &ssl_sock)
Emeric Brune64aef12012-09-21 13:15:06 +02001080 return 0;
1081
1082 if (!(l4->si[0].conn.flags & CO_FL_CONNECTED)) {
1083 smp->flags |= SMP_F_MAY_CHANGE;
1084 return 0;
1085 }
1086
1087 smp->flags = 0;
1088 smp->type = SMP_T_BOOL;
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02001089 smp->data.uint = SSL_SOCK_ST_FL_VERIFY_DONE & l4->si[0].conn.xprt_st ? 1 : 0;
Emeric Brune64aef12012-09-21 13:15:06 +02001090
1091 return 1;
1092}
1093
1094
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02001095/* boolean, returns true if transport layer is SSL */
Willy Tarreau7875d092012-09-10 08:20:03 +02001096static int
1097smp_fetch_is_ssl(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
1098 const struct arg *args, struct sample *smp)
1099{
1100 smp->type = SMP_T_BOOL;
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02001101 smp->data.uint = (l4->si[0].conn.xprt == &ssl_sock);
Willy Tarreau7875d092012-09-10 08:20:03 +02001102 return 1;
1103}
1104
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02001105/* boolean, returns true if transport layer is SSL */
Willy Tarreau7875d092012-09-10 08:20:03 +02001106static int
1107smp_fetch_has_sni(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
1108 const struct arg *args, struct sample *smp)
1109{
1110#ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME
1111 smp->type = SMP_T_BOOL;
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02001112 smp->data.uint = (l4->si[0].conn.xprt == &ssl_sock) &&
1113 l4->si[0].conn.xprt_ctx &&
1114 SSL_get_servername(l4->si[0].conn.xprt_ctx, TLSEXT_NAMETYPE_host_name) != NULL;
Willy Tarreau7875d092012-09-10 08:20:03 +02001115 return 1;
1116#else
1117 return 0;
1118#endif
1119}
1120
1121static int
Willy Tarreaua33c6542012-10-15 13:19:06 +02001122smp_fetch_ssl_npn(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
1123 const struct arg *args, struct sample *smp)
1124{
1125#ifdef OPENSSL_NPN_NEGOTIATED
1126 smp->flags = 0;
1127 smp->type = SMP_T_CSTR;
1128
1129 if (!l4 || !l4->si[0].conn.xprt_ctx || l4->si[0].conn.xprt != &ssl_sock)
1130 return 0;
1131
1132 smp->data.str.str = NULL;
1133 SSL_get0_next_proto_negotiated(l4->si[0].conn.xprt_ctx,
1134 (const unsigned char **)&smp->data.str.str, (unsigned *)&smp->data.str.len);
1135
1136 if (!smp->data.str.str)
1137 return 0;
1138
1139 return 1;
1140#else
1141 return 0;
1142#endif
1143}
1144
1145static int
Willy Tarreau7875d092012-09-10 08:20:03 +02001146smp_fetch_ssl_sni(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
1147 const struct arg *args, struct sample *smp)
1148{
1149#ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME
1150 smp->flags = 0;
1151 smp->type = SMP_T_CSTR;
1152
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02001153 if (!l4 || !l4->si[0].conn.xprt_ctx || l4->si[0].conn.xprt != &ssl_sock)
Willy Tarreau7875d092012-09-10 08:20:03 +02001154 return 0;
1155
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02001156 smp->data.str.str = (char *)SSL_get_servername(l4->si[0].conn.xprt_ctx, TLSEXT_NAMETYPE_host_name);
Willy Tarreau3e394c92012-09-14 23:56:58 +02001157 if (!smp->data.str.str)
1158 return 0;
1159
Willy Tarreau7875d092012-09-10 08:20:03 +02001160 smp->data.str.len = strlen(smp->data.str.str);
1161 return 1;
1162#else
1163 return 0;
1164#endif
1165}
1166
Emeric Brunf282a812012-09-21 15:27:54 +02001167/* integer, returns the first verify error ID in CA */
1168static int
1169smp_fetch_verify_caerr(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
1170 const struct arg *args, struct sample *smp)
1171{
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02001172 if (!l4 || l4->si[0].conn.xprt != &ssl_sock)
Emeric Brunf282a812012-09-21 15:27:54 +02001173 return 0;
1174
1175 if (!(l4->si[0].conn.flags & CO_FL_CONNECTED)) {
1176 smp->flags = SMP_F_MAY_CHANGE;
1177 return 0;
1178 }
1179
1180 smp->type = SMP_T_UINT;
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02001181 smp->data.uint = (unsigned int)SSL_SOCK_ST_TO_CA_ERROR(l4->si[0].conn.xprt_st);
Emeric Brunf282a812012-09-21 15:27:54 +02001182 smp->flags = 0;
1183
1184 return 1;
1185}
1186
1187/* integer, returns the depth of the first verify error in CA */
1188static int
1189smp_fetch_verify_caerr_depth(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
1190 const struct arg *args, struct sample *smp)
1191{
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02001192 if (!l4 || l4->si[0].conn.xprt != &ssl_sock)
Emeric Brunf282a812012-09-21 15:27:54 +02001193 return 0;
1194
1195 if (!(l4->si[0].conn.flags & CO_FL_CONNECTED)) {
1196 smp->flags = SMP_F_MAY_CHANGE;
1197 return 0;
1198 }
1199
1200 smp->type = SMP_T_UINT;
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02001201 smp->data.uint = (unsigned int)SSL_SOCK_ST_TO_CAEDEPTH(l4->si[0].conn.xprt_st);
Emeric Brunf282a812012-09-21 15:27:54 +02001202 smp->flags = 0;
1203
1204 return 1;
1205}
1206
1207/* integer, returns the depth of the first verify error in CA */
1208static int
1209smp_fetch_verify_crterr(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
1210 const struct arg *args, struct sample *smp)
1211{
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02001212 if (!l4 || l4->si[0].conn.xprt != &ssl_sock)
Emeric Brunf282a812012-09-21 15:27:54 +02001213 return 0;
1214
1215 if (!(l4->si[0].conn.flags & CO_FL_CONNECTED)) {
1216 smp->flags = SMP_F_MAY_CHANGE;
1217 return 0;
1218 }
1219
1220 smp->type = SMP_T_UINT;
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02001221 smp->data.uint = (unsigned int)SSL_SOCK_ST_TO_CRTERROR(l4->si[0].conn.xprt_st);
Emeric Brunf282a812012-09-21 15:27:54 +02001222 smp->flags = 0;
1223
1224 return 1;
1225}
1226
Emeric Brunbaf8ffb2012-09-21 15:27:20 +02001227/* integer, returns the verify result */
1228static int
1229smp_fetch_verify_result(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
1230 const struct arg *args, struct sample *smp)
1231{
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02001232 if (!l4 || l4->si[0].conn.xprt != &ssl_sock)
Emeric Brunbaf8ffb2012-09-21 15:27:20 +02001233 return 0;
1234
1235 if (!(l4->si[0].conn.flags & CO_FL_CONNECTED)) {
1236 smp->flags = SMP_F_MAY_CHANGE;
1237 return 0;
1238 }
1239
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02001240 if (!l4->si[0].conn.xprt_ctx)
Emeric Brunbaf8ffb2012-09-21 15:27:20 +02001241 return 0;
1242
1243 smp->type = SMP_T_UINT;
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02001244 smp->data.uint = (unsigned int)SSL_get_verify_result(l4->si[0].conn.xprt_ctx);
Emeric Brunbaf8ffb2012-09-21 15:27:20 +02001245 smp->flags = 0;
1246
1247 return 1;
1248}
1249
Emeric Brunfb510ea2012-10-05 12:00:26 +02001250/* parse the "ca-file" bind keyword */
1251static 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 +02001252{
1253 if (!*args[cur_arg + 1]) {
1254 if (err)
1255 memprintf(err, "'%s' : missing CAfile path", args[cur_arg]);
1256 return ERR_ALERT | ERR_FATAL;
1257 }
1258
Emeric Brunef42d922012-10-11 16:11:36 +02001259 if ((*args[cur_arg + 1] != '/') && global.ca_base)
1260 memprintf(&conf->ca_file, "%s/%s", global.ca_base, args[cur_arg + 1]);
1261 else
1262 memprintf(&conf->ca_file, "%s", args[cur_arg + 1]);
Emeric Brunc8e8d122012-10-02 18:42:10 +02001263
Emeric Brund94b3fe2012-09-20 18:23:56 +02001264 return 0;
1265}
1266
Willy Tarreau79eeafa2012-09-14 07:53:05 +02001267/* parse the "ciphers" bind keyword */
Willy Tarreau4348fad2012-09-20 16:48:07 +02001268static 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 +02001269{
1270 if (!*args[cur_arg + 1]) {
Willy Tarreaueb6cead2012-09-20 19:43:14 +02001271 memprintf(err, "'%s' : missing cipher suite", args[cur_arg]);
Willy Tarreau79eeafa2012-09-14 07:53:05 +02001272 return ERR_ALERT | ERR_FATAL;
1273 }
1274
Emeric Brun76d88952012-10-05 15:47:31 +02001275 free(conf->ciphers);
Willy Tarreau4348fad2012-09-20 16:48:07 +02001276 conf->ciphers = strdup(args[cur_arg + 1]);
Willy Tarreau79eeafa2012-09-14 07:53:05 +02001277 return 0;
1278}
1279
1280/* parse the "crt" bind keyword */
Willy Tarreau4348fad2012-09-20 16:48:07 +02001281static 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 +02001282{
Emeric Brunc8e8d122012-10-02 18:42:10 +02001283 char path[PATH_MAX];
Willy Tarreau79eeafa2012-09-14 07:53:05 +02001284 if (!*args[cur_arg + 1]) {
Willy Tarreaueb6cead2012-09-20 19:43:14 +02001285 memprintf(err, "'%s' : missing certificate location", args[cur_arg]);
Willy Tarreau79eeafa2012-09-14 07:53:05 +02001286 return ERR_ALERT | ERR_FATAL;
1287 }
1288
Emeric Brunc8e8d122012-10-02 18:42:10 +02001289 if ((*args[cur_arg + 1] != '/' ) && global.crt_base) {
1290 if ((strlen(global.crt_base) + 1 + strlen(args[cur_arg + 1]) + 1) > PATH_MAX) {
1291 memprintf(err, "'%s' : path too long", args[cur_arg]);
1292 return ERR_ALERT | ERR_FATAL;
1293 }
1294 sprintf(path, "%s/%s", global.crt_base, args[cur_arg + 1]);
1295 if (ssl_sock_load_cert(path, conf, px, err) > 0)
1296 return ERR_ALERT | ERR_FATAL;
1297
1298 return 0;
1299 }
1300
Willy Tarreau4348fad2012-09-20 16:48:07 +02001301 if (ssl_sock_load_cert(args[cur_arg + 1], conf, px, err) > 0)
Willy Tarreau79eeafa2012-09-14 07:53:05 +02001302 return ERR_ALERT | ERR_FATAL;
Emeric Brund94b3fe2012-09-20 18:23:56 +02001303
1304 return 0;
1305}
1306
Emeric Brunfb510ea2012-10-05 12:00:26 +02001307/* parse the "crl-file" bind keyword */
1308static 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 +02001309{
Emeric Brun051cdab2012-10-02 19:25:50 +02001310#ifndef X509_V_FLAG_CRL_CHECK
1311 if (err)
1312 memprintf(err, "'%s' : library does not support CRL verify", args[cur_arg]);
1313 return ERR_ALERT | ERR_FATAL;
1314#else
Emeric Brund94b3fe2012-09-20 18:23:56 +02001315 if (!*args[cur_arg + 1]) {
1316 if (err)
1317 memprintf(err, "'%s' : missing CRLfile path", args[cur_arg]);
1318 return ERR_ALERT | ERR_FATAL;
1319 }
Emeric Brun2b58d042012-09-20 17:10:03 +02001320
Emeric Brunef42d922012-10-11 16:11:36 +02001321 if ((*args[cur_arg + 1] != '/') && global.ca_base)
1322 memprintf(&conf->crl_file, "%s/%s", global.ca_base, args[cur_arg + 1]);
1323 else
1324 memprintf(&conf->crl_file, "%s", args[cur_arg + 1]);
Emeric Brunc8e8d122012-10-02 18:42:10 +02001325
Emeric Brun2b58d042012-09-20 17:10:03 +02001326 return 0;
Emeric Brun051cdab2012-10-02 19:25:50 +02001327#endif
Emeric Brun2b58d042012-09-20 17:10:03 +02001328}
1329
1330/* parse the "ecdhe" bind keyword keywords */
1331static int bind_parse_ecdhe(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
1332{
1333#if OPENSSL_VERSION_NUMBER < 0x0090800fL
1334 if (err)
1335 memprintf(err, "'%s' : library does not support elliptic curve Diffie-Hellman (too old)", args[cur_arg]);
1336 return ERR_ALERT | ERR_FATAL;
1337#elif defined(OPENSSL_NO_ECDH)
1338 if (err)
1339 memprintf(err, "'%s' : library does not support elliptic curve Diffie-Hellman (disabled via OPENSSL_NO_ECDH)", args[cur_arg]);
1340 return ERR_ALERT | ERR_FATAL;
1341#else
1342 if (!*args[cur_arg + 1]) {
1343 if (err)
1344 memprintf(err, "'%s' : missing named curve", args[cur_arg]);
1345 return ERR_ALERT | ERR_FATAL;
1346 }
1347
1348 conf->ecdhe = strdup(args[cur_arg + 1]);
Willy Tarreau79eeafa2012-09-14 07:53:05 +02001349
1350 return 0;
Emeric Brun2b58d042012-09-20 17:10:03 +02001351#endif
Willy Tarreau79eeafa2012-09-14 07:53:05 +02001352}
1353
Emeric Brun81c00f02012-09-21 14:31:21 +02001354/* parse the "crt_ignerr" and "ca_ignerr" bind keywords */
1355static int bind_parse_ignore_err(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
1356{
1357 int code;
1358 char *p = args[cur_arg + 1];
1359 unsigned long long *ignerr = &conf->crt_ignerr;
1360
1361 if (!*p) {
1362 if (err)
1363 memprintf(err, "'%s' : missing error IDs list", args[cur_arg]);
1364 return ERR_ALERT | ERR_FATAL;
1365 }
1366
1367 if (strcmp(args[cur_arg], "ca-ignore-err") == 0)
1368 ignerr = &conf->ca_ignerr;
1369
1370 if (strcmp(p, "all") == 0) {
1371 *ignerr = ~0ULL;
1372 return 0;
1373 }
1374
1375 while (p) {
1376 code = atoi(p);
1377 if ((code <= 0) || (code > 63)) {
1378 if (err)
1379 memprintf(err, "'%s' : ID '%d' out of range (1..63) in error IDs list '%s'",
1380 args[cur_arg], code, args[cur_arg + 1]);
1381 return ERR_ALERT | ERR_FATAL;
1382 }
1383 *ignerr |= 1ULL << code;
1384 p = strchr(p, ',');
1385 if (p)
1386 p++;
1387 }
1388
Emeric Brun2cb7ae52012-10-05 14:14:21 +02001389 return 0;
1390}
1391
1392/* parse the "force-sslv3" bind keyword */
1393static int bind_parse_force_sslv3(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
1394{
1395 conf->ssl_options |= BC_SSL_O_USE_SSLV3;
1396 return 0;
1397}
1398
1399/* parse the "force-tlsv10" bind keyword */
1400static int bind_parse_force_tlsv10(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
1401{
1402 conf->ssl_options |= BC_SSL_O_USE_TLSV10;
Emeric Brun2d0c4822012-10-02 13:45:20 +02001403 return 0;
1404}
1405
Emeric Brun2cb7ae52012-10-05 14:14:21 +02001406/* parse the "force-tlsv11" bind keyword */
1407static int bind_parse_force_tlsv11(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
1408{
1409#if SSL_OP_NO_TLSv1_1
1410 conf->ssl_options |= BC_SSL_O_USE_TLSV11;
1411 return 0;
1412#else
1413 if (err)
1414 memprintf(err, "'%s' : library does not support protocol TLSv1.1", args[cur_arg]);
1415 return ERR_ALERT | ERR_FATAL;
1416#endif
1417}
1418
1419/* parse the "force-tlsv12" bind keyword */
1420static int bind_parse_force_tlsv12(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
1421{
1422#if SSL_OP_NO_TLSv1_2
1423 conf->ssl_options |= BC_SSL_O_USE_TLSV12;
1424 return 0;
1425#else
1426 if (err)
1427 memprintf(err, "'%s' : library does not support protocol TLSv1.2", args[cur_arg]);
1428 return ERR_ALERT | ERR_FATAL;
1429#endif
1430}
1431
1432
Emeric Brun2d0c4822012-10-02 13:45:20 +02001433/* parse the "no-tls-tickets" bind keyword */
1434static int bind_parse_no_tls_tickets(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
1435{
Emeric Brun89675492012-10-05 13:48:26 +02001436 conf->ssl_options |= BC_SSL_O_NO_TLS_TICKETS;
Emeric Brun81c00f02012-09-21 14:31:21 +02001437 return 0;
1438}
1439
Emeric Brun2d0c4822012-10-02 13:45:20 +02001440
Emeric Brun9b3009b2012-10-05 11:55:06 +02001441/* parse the "no-sslv3" bind keyword */
1442static 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 +02001443{
Emeric Brun89675492012-10-05 13:48:26 +02001444 conf->ssl_options |= BC_SSL_O_NO_SSLV3;
Willy Tarreau79eeafa2012-09-14 07:53:05 +02001445 return 0;
1446}
1447
Emeric Brun9b3009b2012-10-05 11:55:06 +02001448/* parse the "no-tlsv10" bind keyword */
1449static 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 +02001450{
Emeric Brun89675492012-10-05 13:48:26 +02001451 conf->ssl_options |= BC_SSL_O_NO_TLSV10;
Emeric Brunc0ff4922012-09-28 19:37:02 +02001452 return 0;
1453}
1454
Emeric Brun9b3009b2012-10-05 11:55:06 +02001455/* parse the "no-tlsv11" bind keyword */
1456static 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 +02001457{
Emeric Brun89675492012-10-05 13:48:26 +02001458 conf->ssl_options |= BC_SSL_O_NO_TLSV11;
Emeric Brunc0ff4922012-09-28 19:37:02 +02001459 return 0;
1460}
1461
Emeric Brun9b3009b2012-10-05 11:55:06 +02001462/* parse the "no-tlsv12" bind keyword */
1463static 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 +02001464{
Emeric Brun89675492012-10-05 13:48:26 +02001465 conf->ssl_options |= BC_SSL_O_NO_TLSV12;
Willy Tarreau79eeafa2012-09-14 07:53:05 +02001466 return 0;
1467}
1468
Willy Tarreau79eeafa2012-09-14 07:53:05 +02001469/* parse the "ssl" bind keyword */
Willy Tarreau4348fad2012-09-20 16:48:07 +02001470static 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 +02001471{
Willy Tarreau81796be2012-09-22 19:11:47 +02001472 struct listener *l;
1473
Willy Tarreau4348fad2012-09-20 16:48:07 +02001474 conf->is_ssl = 1;
Emeric Brun76d88952012-10-05 15:47:31 +02001475
1476 if (global.listen_default_ciphers && !conf->ciphers)
1477 conf->ciphers = strdup(global.listen_default_ciphers);
1478
Willy Tarreau81796be2012-09-22 19:11:47 +02001479 list_for_each_entry(l, &conf->listeners, by_bind)
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02001480 l->xprt = &ssl_sock;
Willy Tarreau81796be2012-09-22 19:11:47 +02001481
Willy Tarreau79eeafa2012-09-14 07:53:05 +02001482 return 0;
1483}
1484
Emeric Brund94b3fe2012-09-20 18:23:56 +02001485/* parse the "verify" bind keyword */
1486static int bind_parse_verify(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
1487{
1488 if (!*args[cur_arg + 1]) {
1489 if (err)
1490 memprintf(err, "'%s' : missing verify method", args[cur_arg]);
1491 return ERR_ALERT | ERR_FATAL;
1492 }
1493
1494 if (strcmp(args[cur_arg + 1], "none") == 0)
1495 conf->verify = SSL_VERIFY_NONE;
1496 else if (strcmp(args[cur_arg + 1], "optional") == 0)
1497 conf->verify = SSL_VERIFY_PEER;
1498 else if (strcmp(args[cur_arg + 1], "required") == 0)
1499 conf->verify = SSL_VERIFY_PEER|SSL_VERIFY_FAIL_IF_NO_PEER_CERT;
1500 else {
1501 if (err)
1502 memprintf(err, "'%s' : unknown verify method '%s', only 'none', 'optional', and 'required' are supported\n",
1503 args[cur_arg], args[cur_arg + 1]);
1504 return ERR_ALERT | ERR_FATAL;
1505 }
1506
1507 return 0;
1508}
1509
Willy Tarreau92faadf2012-10-10 23:04:25 +02001510/************** "server" keywords ****************/
1511
Emeric Brunef42d922012-10-11 16:11:36 +02001512/* parse the "ca-file" server keyword */
1513static int srv_parse_ca_file(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
1514{
1515 if (!*args[*cur_arg + 1]) {
1516 if (err)
1517 memprintf(err, "'%s' : missing CAfile path", args[*cur_arg]);
1518 return ERR_ALERT | ERR_FATAL;
1519 }
1520
1521 if ((*args[*cur_arg + 1] != '/') && global.ca_base)
1522 memprintf(&newsrv->ssl_ctx.ca_file, "%s/%s", global.ca_base, args[*cur_arg + 1]);
1523 else
1524 memprintf(&newsrv->ssl_ctx.ca_file, "%s", args[*cur_arg + 1]);
1525
1526 return 0;
1527}
1528
Willy Tarreau92faadf2012-10-10 23:04:25 +02001529/* parse the "check-ssl" server keyword */
1530static int srv_parse_check_ssl(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
1531{
1532 newsrv->check.use_ssl = 1;
1533 if (global.connect_default_ciphers && !newsrv->ssl_ctx.ciphers)
1534 newsrv->ssl_ctx.ciphers = strdup(global.connect_default_ciphers);
1535 return 0;
1536}
1537
1538/* parse the "ciphers" server keyword */
1539static int srv_parse_ciphers(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
1540{
1541 if (!*args[*cur_arg + 1]) {
1542 memprintf(err, "'%s' : missing cipher suite", args[*cur_arg]);
1543 return ERR_ALERT | ERR_FATAL;
1544 }
1545
1546 free(newsrv->ssl_ctx.ciphers);
1547 newsrv->ssl_ctx.ciphers = strdup(args[*cur_arg + 1]);
1548 return 0;
1549}
1550
Emeric Brunef42d922012-10-11 16:11:36 +02001551/* parse the "crl-file" server keyword */
1552static int srv_parse_crl_file(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
1553{
1554#ifndef X509_V_FLAG_CRL_CHECK
1555 if (err)
1556 memprintf(err, "'%s' : library does not support CRL verify", args[*cur_arg]);
1557 return ERR_ALERT | ERR_FATAL;
1558#else
1559 if (!*args[*cur_arg + 1]) {
1560 if (err)
1561 memprintf(err, "'%s' : missing CRLfile path", args[*cur_arg]);
1562 return ERR_ALERT | ERR_FATAL;
1563 }
1564
1565 if ((*args[*cur_arg + 1] != '/') && global.ca_base)
1566 memprintf(&newsrv->ssl_ctx.crl_file, "%s/%s", global.ca_base, args[*cur_arg + 1]);
1567 else
1568 memprintf(&newsrv->ssl_ctx.crl_file, "%s", args[*cur_arg + 1]);
1569
1570 return 0;
1571#endif
1572}
1573
1574
Willy Tarreau92faadf2012-10-10 23:04:25 +02001575/* parse the "force-sslv3" server keyword */
1576static int srv_parse_force_sslv3(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
1577{
1578 newsrv->ssl_ctx.options |= SRV_SSL_O_USE_SSLV3;
1579 return 0;
1580}
1581
1582/* parse the "force-tlsv10" server keyword */
1583static int srv_parse_force_tlsv10(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
1584{
1585 newsrv->ssl_ctx.options |= SRV_SSL_O_USE_TLSV10;
1586 return 0;
1587}
1588
1589/* parse the "force-tlsv11" server keyword */
1590static int srv_parse_force_tlsv11(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
1591{
1592#if SSL_OP_NO_TLSv1_1
1593 newsrv->ssl_ctx.options |= SRV_SSL_O_USE_TLSV11;
1594 return 0;
1595#else
1596 if (err)
1597 memprintf(err, "'%s' : library does not support protocol TLSv1.1", args[*cur_arg]);
1598 return ERR_ALERT | ERR_FATAL;
1599#endif
1600}
1601
1602/* parse the "force-tlsv12" server keyword */
1603static int srv_parse_force_tlsv12(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
1604{
1605#if SSL_OP_NO_TLSv1_2
1606 newsrv->ssl_ctx.options |= SRV_SSL_O_USE_TLSV12;
1607 return 0;
1608#else
1609 if (err)
1610 memprintf(err, "'%s' : library does not support protocol TLSv1.2", args[*cur_arg]);
1611 return ERR_ALERT | ERR_FATAL;
1612#endif
1613}
1614
1615/* parse the "no-sslv3" server keyword */
1616static int srv_parse_no_sslv3(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
1617{
1618 newsrv->ssl_ctx.options |= SRV_SSL_O_NO_SSLV3;
1619 return 0;
1620}
1621
1622/* parse the "no-tlsv10" server keyword */
1623static int srv_parse_no_tlsv10(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
1624{
1625 newsrv->ssl_ctx.options |= SRV_SSL_O_NO_TLSV10;
1626 return 0;
1627}
1628
1629/* parse the "no-tlsv11" server keyword */
1630static int srv_parse_no_tlsv11(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
1631{
1632 newsrv->ssl_ctx.options |= SRV_SSL_O_NO_TLSV11;
1633 return 0;
1634}
1635
1636/* parse the "no-tlsv12" server keyword */
1637static int srv_parse_no_tlsv12(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
1638{
1639 newsrv->ssl_ctx.options |= SRV_SSL_O_NO_TLSV12;
1640 return 0;
1641}
1642
Emeric Brunf9c5c472012-10-11 15:28:34 +02001643/* parse the "no-tls-tickets" server keyword */
1644static int srv_parse_no_tls_tickets(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
1645{
1646 newsrv->ssl_ctx.options |= SRV_SSL_O_NO_TLS_TICKETS;
1647 return 0;
1648}
1649
Willy Tarreau92faadf2012-10-10 23:04:25 +02001650/* parse the "ssl" server keyword */
1651static int srv_parse_ssl(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
1652{
1653 newsrv->use_ssl = 1;
1654 if (global.connect_default_ciphers && !newsrv->ssl_ctx.ciphers)
1655 newsrv->ssl_ctx.ciphers = strdup(global.connect_default_ciphers);
1656 return 0;
1657}
1658
Emeric Brunef42d922012-10-11 16:11:36 +02001659/* parse the "verify" server keyword */
1660static int srv_parse_verify(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
1661{
1662 if (!*args[*cur_arg + 1]) {
1663 if (err)
1664 memprintf(err, "'%s' : missing verify method", args[*cur_arg]);
1665 return ERR_ALERT | ERR_FATAL;
1666 }
1667
1668 if (strcmp(args[*cur_arg + 1], "none") == 0)
1669 newsrv->ssl_ctx.verify = SSL_VERIFY_NONE;
1670 else if (strcmp(args[*cur_arg + 1], "required") == 0)
1671 newsrv->ssl_ctx.verify = SSL_VERIFY_PEER;
1672 else {
1673 if (err)
1674 memprintf(err, "'%s' : unknown verify method '%s', only 'none' and 'required' are supported\n",
1675 args[*cur_arg], args[*cur_arg + 1]);
1676 return ERR_ALERT | ERR_FATAL;
1677 }
1678
1679 return 0;
1680}
1681
Willy Tarreau7875d092012-09-10 08:20:03 +02001682/* Note: must not be declared <const> as its list will be overwritten.
1683 * Please take care of keeping this list alphabetically sorted.
1684 */
1685static struct sample_fetch_kw_list sample_fetch_keywords = {{ },{
Emeric Brunf282a812012-09-21 15:27:54 +02001686 { "client_crt", smp_fetch_client_crt, 0, NULL, SMP_T_BOOL, SMP_CAP_REQ|SMP_CAP_RES },
1687 { "is_ssl", smp_fetch_is_ssl, 0, NULL, SMP_T_BOOL, SMP_CAP_REQ|SMP_CAP_RES },
1688 { "ssl_has_sni", smp_fetch_has_sni, 0, NULL, SMP_T_BOOL, SMP_CAP_REQ|SMP_CAP_RES },
Willy Tarreaua33c6542012-10-15 13:19:06 +02001689#ifdef OPENSSL_NPN_NEGOTIATED
1690 { "ssl_npn", smp_fetch_ssl_npn, 0, NULL, SMP_T_CSTR, SMP_CAP_REQ|SMP_CAP_RES },
1691#endif
Emeric Brunf282a812012-09-21 15:27:54 +02001692 { "ssl_sni", smp_fetch_ssl_sni, 0, NULL, SMP_T_CSTR, SMP_CAP_REQ|SMP_CAP_RES },
1693 { "ssl_verify_caerr", smp_fetch_verify_caerr, 0, NULL, SMP_T_UINT, SMP_CAP_REQ|SMP_CAP_RES },
1694 { "ssl_verify_caerr_depth", smp_fetch_verify_caerr_depth, 0, NULL, SMP_T_UINT, SMP_CAP_REQ|SMP_CAP_RES },
1695 { "ssl_verify_crterr", smp_fetch_verify_crterr, 0, NULL, SMP_T_UINT, SMP_CAP_REQ|SMP_CAP_RES },
1696 { "ssl_verify_result", smp_fetch_verify_result, 0, NULL, SMP_T_UINT, SMP_CAP_REQ|SMP_CAP_RES },
Willy Tarreau7875d092012-09-10 08:20:03 +02001697 { NULL, NULL, 0, 0, 0 },
1698}};
1699
1700/* Note: must not be declared <const> as its list will be overwritten.
1701 * Please take care of keeping this list alphabetically sorted.
1702 */
1703static struct acl_kw_list acl_kws = {{ },{
Emeric Brunf282a812012-09-21 15:27:54 +02001704 { "client_crt", acl_parse_int, smp_fetch_client_crt, acl_match_nothing, ACL_USE_L6REQ_PERMANENT|ACL_MAY_LOOKUP, 0 },
1705 { "is_ssl", acl_parse_int, smp_fetch_is_ssl, acl_match_nothing, ACL_USE_L6REQ_PERMANENT|ACL_MAY_LOOKUP, 0 },
1706 { "ssl_has_sni", acl_parse_int, smp_fetch_has_sni, acl_match_nothing, ACL_USE_L6REQ_PERMANENT, 0 },
Willy Tarreaua33c6542012-10-15 13:19:06 +02001707#ifdef OPENSSL_NPN_NEGOTIATED
1708 { "ssl_npn", acl_parse_str, smp_fetch_ssl_npn, acl_match_str, ACL_USE_L6REQ_PERMANENT|ACL_MAY_LOOKUP, 0 },
1709#endif
Emeric Brunf282a812012-09-21 15:27:54 +02001710 { "ssl_sni", acl_parse_str, smp_fetch_ssl_sni, acl_match_str, ACL_USE_L6REQ_PERMANENT|ACL_MAY_LOOKUP, 0 },
1711 { "ssl_sni_end", acl_parse_str, smp_fetch_ssl_sni, acl_match_end, ACL_USE_L6REQ_PERMANENT|ACL_MAY_LOOKUP, 0 },
1712 { "ssl_sni_reg", acl_parse_str, smp_fetch_ssl_sni, acl_match_reg, ACL_USE_L6REQ_PERMANENT|ACL_MAY_LOOKUP, 0 },
1713 { "ssl_verify_caerr", acl_parse_int, smp_fetch_verify_caerr, acl_match_int, ACL_USE_L6REQ_PERMANENT|ACL_MAY_LOOKUP, 0 },
1714 { "ssl_verify_caerr_depth", acl_parse_int, smp_fetch_verify_caerr_depth, acl_match_int, ACL_USE_L6REQ_PERMANENT|ACL_MAY_LOOKUP, 0 },
1715 { "ssl_verify_crterr", acl_parse_int, smp_fetch_verify_crterr, acl_match_int, ACL_USE_L6REQ_PERMANENT|ACL_MAY_LOOKUP, 0 },
1716 { "ssl_verify_result", acl_parse_int, smp_fetch_verify_result, acl_match_int, ACL_USE_L6REQ_PERMANENT|ACL_MAY_LOOKUP, 0 },
Willy Tarreau7875d092012-09-10 08:20:03 +02001717 { NULL, NULL, NULL, NULL },
1718}};
1719
Willy Tarreau79eeafa2012-09-14 07:53:05 +02001720/* Note: must not be declared <const> as its list will be overwritten.
1721 * Please take care of keeping this list alphabetically sorted, doing so helps
1722 * all code contributors.
1723 * Optional keywords are also declared with a NULL ->parse() function so that
1724 * the config parser can report an appropriate error when a known keyword was
1725 * not enabled.
1726 */
Willy Tarreau51fb7652012-09-18 18:24:39 +02001727static struct bind_kw_list bind_kws = { "SSL", { }, {
Emeric Brunfb510ea2012-10-05 12:00:26 +02001728 { "ca-file", bind_parse_ca_file, 1 }, /* set CAfile to process verify on client cert */
Emeric Brun2d0c4822012-10-02 13:45:20 +02001729 { "ca-ignore-err", bind_parse_ignore_err, 1 }, /* set error IDs to ignore on verify depth > 0 */
1730 { "ciphers", bind_parse_ciphers, 1 }, /* set SSL cipher suite */
Emeric Brunfb510ea2012-10-05 12:00:26 +02001731 { "crl-file", bind_parse_crl_file, 1 }, /* set certificat revocation list file use on client cert verify */
Emeric Brun2d0c4822012-10-02 13:45:20 +02001732 { "crt", bind_parse_crt, 1 }, /* load SSL certificates from this location */
1733 { "crt-ignore-err", bind_parse_ignore_err, 1 }, /* set error IDs to ingore on verify depth == 0 */
1734 { "ecdhe", bind_parse_ecdhe, 1 }, /* defines named curve for elliptic curve Diffie-Hellman */
Emeric Brun2cb7ae52012-10-05 14:14:21 +02001735 { "force-sslv3", bind_parse_force_sslv3, 0 }, /* force SSLv3 */
1736 { "force-tlsv10", bind_parse_force_tlsv10, 0 }, /* force TLSv10 */
1737 { "force-tlsv11", bind_parse_force_tlsv11, 0 }, /* force TLSv11 */
1738 { "force-tlsv12", bind_parse_force_tlsv12, 0 }, /* force TLSv12 */
Emeric Brun9b3009b2012-10-05 11:55:06 +02001739 { "no-sslv3", bind_parse_no_sslv3, 0 }, /* disable SSLv3 */
1740 { "no-tlsv10", bind_parse_no_tlsv10, 0 }, /* disable TLSv10 */
1741 { "no-tlsv11", bind_parse_no_tlsv11, 0 }, /* disable TLSv11 */
1742 { "no-tlsv12", bind_parse_no_tlsv12, 0 }, /* disable TLSv12 */
Emeric Brun2d0c4822012-10-02 13:45:20 +02001743 { "no-tls-tickets", bind_parse_no_tls_tickets, 0 }, /* disable session resumption tickets */
Emeric Brun2d0c4822012-10-02 13:45:20 +02001744 { "ssl", bind_parse_ssl, 0 }, /* enable SSL processing */
1745 { "verify", bind_parse_verify, 1 }, /* set SSL verify method */
Willy Tarreau79eeafa2012-09-14 07:53:05 +02001746 { NULL, NULL, 0 },
1747}};
Emeric Brun46591952012-05-18 15:47:34 +02001748
Willy Tarreau92faadf2012-10-10 23:04:25 +02001749/* Note: must not be declared <const> as its list will be overwritten.
1750 * Please take care of keeping this list alphabetically sorted, doing so helps
1751 * all code contributors.
1752 * Optional keywords are also declared with a NULL ->parse() function so that
1753 * the config parser can report an appropriate error when a known keyword was
1754 * not enabled.
1755 */
1756static struct srv_kw_list srv_kws = { "SSL", { }, {
Emeric Brunef42d922012-10-11 16:11:36 +02001757 { "ca-file", srv_parse_ca_file, 1, 0 }, /* set CAfile to process verify server cert */
Emeric Brunecc91fe2012-10-11 15:05:10 +02001758 { "check-ssl", srv_parse_check_ssl, 0, 0 }, /* enable SSL for health checks */
1759 { "ciphers", srv_parse_ciphers, 1, 0 }, /* select the cipher suite */
Emeric Brunef42d922012-10-11 16:11:36 +02001760 { "crl-file", srv_parse_crl_file, 1, 0 }, /* set certificate revocation list file use on server cert verify */
Emeric Brunecc91fe2012-10-11 15:05:10 +02001761 { "force-sslv3", srv_parse_force_sslv3, 0, 0 }, /* force SSLv3 */
1762 { "force-tlsv10", srv_parse_force_tlsv10, 0, 0 }, /* force TLSv10 */
1763 { "force-tlsv11", srv_parse_force_tlsv11, 0, 0 }, /* force TLSv11 */
1764 { "force-tlsv12", srv_parse_force_tlsv12, 0, 0 }, /* force TLSv12 */
1765 { "no-sslv3", srv_parse_no_sslv3, 0, 0 }, /* disable SSLv3 */
1766 { "no-tlsv10", srv_parse_no_tlsv10, 0, 0 }, /* disable TLSv10 */
1767 { "no-tlsv11", srv_parse_no_tlsv11, 0, 0 }, /* disable TLSv11 */
1768 { "no-tlsv12", srv_parse_no_tlsv12, 0, 0 }, /* disable TLSv12 */
Emeric Brunf9c5c472012-10-11 15:28:34 +02001769 { "no-tls-tickets", srv_parse_no_tls_tickets, 0, 0 }, /* disable session resumption tickets */
Emeric Brunecc91fe2012-10-11 15:05:10 +02001770 { "ssl", srv_parse_ssl, 0, 0 }, /* enable SSL processing */
Emeric Brunef42d922012-10-11 16:11:36 +02001771 { "verify", srv_parse_verify, 1, 0 }, /* set SSL verify method */
Willy Tarreau92faadf2012-10-10 23:04:25 +02001772 { NULL, NULL, 0, 0 },
1773}};
1774
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02001775/* transport-layer operations for SSL sockets */
1776struct xprt_ops ssl_sock = {
Emeric Brun46591952012-05-18 15:47:34 +02001777 .snd_buf = ssl_sock_from_buf,
1778 .rcv_buf = ssl_sock_to_buf,
1779 .rcv_pipe = NULL,
1780 .snd_pipe = NULL,
1781 .shutr = NULL,
1782 .shutw = ssl_sock_shutw,
1783 .close = ssl_sock_close,
1784 .init = ssl_sock_init,
1785};
1786
1787__attribute__((constructor))
Willy Tarreau92faadf2012-10-10 23:04:25 +02001788static void __ssl_sock_init(void)
1789{
Emeric Brun46591952012-05-18 15:47:34 +02001790 STACK_OF(SSL_COMP)* cm;
1791
1792 SSL_library_init();
1793 cm = SSL_COMP_get_compression_methods();
1794 sk_SSL_COMP_zero(cm);
Willy Tarreau7875d092012-09-10 08:20:03 +02001795 sample_register_fetches(&sample_fetch_keywords);
1796 acl_register_keywords(&acl_kws);
Willy Tarreau79eeafa2012-09-14 07:53:05 +02001797 bind_register_keywords(&bind_kws);
Willy Tarreau92faadf2012-10-10 23:04:25 +02001798 srv_register_keywords(&srv_kws);
Emeric Brun46591952012-05-18 15:47:34 +02001799}
1800
1801/*
1802 * Local variables:
1803 * c-indent-level: 8
1804 * c-basic-offset: 8
1805 * End:
1806 */