blob: 055bc6fe56eab4398de632afd84efccc624060d2 [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>
Emeric Brun46591952012-05-18 15:47:34 +020068#include <proto/log.h>
Emeric Brunfc0421f2012-09-07 17:30:07 +020069#include <proto/shctx.h>
Emeric Brun46591952012-05-18 15:47:34 +020070#include <proto/ssl_sock.h>
71#include <proto/task.h>
72
Emeric Brune64aef12012-09-21 13:15:06 +020073#define SSL_SOCK_ST_FL_VERIFY_DONE 0x00000001
Emeric Brunf282a812012-09-21 15:27:54 +020074/* bits 0xFFFF0000 are reserved to store verify errors */
75
76/* Verify errors macros */
77#define SSL_SOCK_CA_ERROR_TO_ST(e) (((e > 63) ? 63 : e) << (16))
78#define SSL_SOCK_CAEDEPTH_TO_ST(d) (((d > 15) ? 15 : d) << (6+16))
79#define SSL_SOCK_CRTERROR_TO_ST(e) (((e > 63) ? 63 : e) << (4+6+16))
80
81#define SSL_SOCK_ST_TO_CA_ERROR(s) ((s >> (16)) & 63)
82#define SSL_SOCK_ST_TO_CAEDEPTH(s) ((s >> (6+16)) & 15)
83#define SSL_SOCK_ST_TO_CRTERROR(s) ((s >> (4+6+16)) & 63)
Emeric Brune64aef12012-09-21 13:15:06 +020084
Willy Tarreau403edff2012-09-06 11:58:37 +020085static int sslconns = 0;
Emeric Brune1f38db2012-09-03 20:36:47 +020086
87void ssl_sock_infocbk(const SSL *ssl, int where, int ret)
88{
89 struct connection *conn = (struct connection *)SSL_get_app_data(ssl);
90 (void)ret; /* shut gcc stupid warning */
91
92 if (where & SSL_CB_HANDSHAKE_START) {
93 /* Disable renegotiation (CVE-2009-3555) */
94 if (conn->flags & CO_FL_CONNECTED)
95 conn->flags |= CO_FL_ERROR;
96 }
Emeric Brunfc0421f2012-09-07 17:30:07 +020097}
98
Emeric Brune64aef12012-09-21 13:15:06 +020099/* Callback is called for each certificate of the chain during a verify
100 ok is set to 1 if preverify detect no error on current certificate.
101 Returns 0 to break the handshake, 1 otherwise. */
102int ssl_sock_verifycbk(int ok, X509_STORE_CTX *x_store)
103{
104 SSL *ssl;
105 struct connection *conn;
Emeric Brun81c00f02012-09-21 14:31:21 +0200106 int err, depth;
Emeric Brune64aef12012-09-21 13:15:06 +0200107
108 ssl = X509_STORE_CTX_get_ex_data(x_store, SSL_get_ex_data_X509_STORE_CTX_idx());
109 conn = (struct connection *)SSL_get_app_data(ssl);
110
Willy Tarreauf7bc57c2012-10-03 00:19:48 +0200111 conn->xprt_st |= SSL_SOCK_ST_FL_VERIFY_DONE;
Emeric Brune64aef12012-09-21 13:15:06 +0200112
Emeric Brun81c00f02012-09-21 14:31:21 +0200113 if (ok) /* no errors */
114 return ok;
115
116 depth = X509_STORE_CTX_get_error_depth(x_store);
117 err = X509_STORE_CTX_get_error(x_store);
118
119 /* check if CA error needs to be ignored */
120 if (depth > 0) {
Willy Tarreauf7bc57c2012-10-03 00:19:48 +0200121 if (!SSL_SOCK_ST_TO_CA_ERROR(conn->xprt_st)) {
122 conn->xprt_st |= SSL_SOCK_CA_ERROR_TO_ST(err);
123 conn->xprt_st |= SSL_SOCK_CAEDEPTH_TO_ST(depth);
Emeric Brunf282a812012-09-21 15:27:54 +0200124 }
125
Emeric Brun81c00f02012-09-21 14:31:21 +0200126 if (target_client(&conn->target)->bind_conf->ca_ignerr & (1ULL << err))
127 return 1;
128
129 return 0;
130 }
131
Willy Tarreauf7bc57c2012-10-03 00:19:48 +0200132 if (!SSL_SOCK_ST_TO_CRTERROR(conn->xprt_st))
133 conn->xprt_st |= SSL_SOCK_CRTERROR_TO_ST(err);
Emeric Brunf282a812012-09-21 15:27:54 +0200134
Emeric Brun81c00f02012-09-21 14:31:21 +0200135 /* check if certificate error needs to be ignored */
136 if (target_client(&conn->target)->bind_conf->crt_ignerr & (1ULL << err))
137 return 1;
138
139 return 0;
Emeric Brune64aef12012-09-21 13:15:06 +0200140}
141
Emeric Brunfc0421f2012-09-07 17:30:07 +0200142#ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME
143/* Sets the SSL ctx of <ssl> to match the advertised server name. Returns a
144 * warning when no match is found, which implies the default (first) cert
145 * will keep being used.
146 */
Willy Tarreau2a65ff02012-09-13 17:54:29 +0200147static int ssl_sock_switchctx_cbk(SSL *ssl, int *al, struct bind_conf *s)
Emeric Brunfc0421f2012-09-07 17:30:07 +0200148{
149 const char *servername;
150 const char *wildp = NULL;
151 struct ebmb_node *node;
152 int i;
153 (void)al; /* shut gcc stupid warning */
154
155 servername = SSL_get_servername(ssl, TLSEXT_NAMETYPE_host_name);
156 if (!servername)
157 return SSL_TLSEXT_ERR_NOACK;
158
159 for (i = 0; i < trashlen; i++) {
160 if (!servername[i])
161 break;
162 trash[i] = tolower(servername[i]);
163 if (!wildp && (trash[i] == '.'))
164 wildp = &trash[i];
165 }
166 trash[i] = 0;
167
168 /* lookup in full qualified names */
169 node = ebst_lookup(&s->sni_ctx, trash);
170 if (!node) {
171 if (!wildp)
172 return SSL_TLSEXT_ERR_ALERT_WARNING;
173
174 /* lookup in full wildcards names */
175 node = ebst_lookup(&s->sni_w_ctx, wildp);
176 if (!node)
177 return SSL_TLSEXT_ERR_ALERT_WARNING;
178 }
179
180 /* switch ctx */
181 SSL_set_SSL_CTX(ssl, container_of(node, struct sni_ctx, name)->ctx);
182 return SSL_TLSEXT_ERR_OK;
183}
184#endif /* SSL_CTRL_SET_TLSEXT_HOSTNAME */
185
Emeric Bruna4bcd9a2012-09-20 16:19:02 +0200186#ifndef OPENSSL_NO_DH
187/* Loads Diffie-Hellman parameter from a file. Returns 1 if loaded, else -1
188 if an error occured, and 0 if parameter not found. */
189int ssl_sock_load_dh_params(SSL_CTX *ctx, const char *file)
190{
191 int ret = -1;
192 BIO *in;
193 DH *dh = NULL;
194
195 in = BIO_new(BIO_s_file());
196 if (in == NULL)
197 goto end;
198
199 if (BIO_read_filename(in, file) <= 0)
200 goto end;
201
202 dh = PEM_read_bio_DHparams(in, NULL, ctx->default_passwd_callback, ctx->default_passwd_callback_userdata);
203 if (dh) {
204 SSL_CTX_set_tmp_dh(ctx, dh);
205 ret = 1;
206 goto end;
207 }
208
209 ret = 0; /* DH params not found */
210end:
211 if (dh)
212 DH_free(dh);
213
214 if (in)
215 BIO_free(in);
216
217 return ret;
218}
219#endif
220
Emeric Brunfc0421f2012-09-07 17:30:07 +0200221/* Loads a certificate key and CA chain from a file. Returns 0 on error, -1 if
222 * an early error happens and the caller must call SSL_CTX_free() by itelf.
223 */
Willy Tarreau2a65ff02012-09-13 17:54:29 +0200224int ssl_sock_load_cert_chain_file(SSL_CTX *ctx, const char *file, struct bind_conf *s)
Emeric Brunfc0421f2012-09-07 17:30:07 +0200225{
226 BIO *in;
227 X509 *x = NULL, *ca;
228 int i, len, err;
229 int ret = -1;
230 int order = 0;
231 X509_NAME *xname;
232 char *str;
233 struct sni_ctx *sc;
234#ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME
235 STACK_OF(GENERAL_NAME) *names;
236#endif
237
238 in = BIO_new(BIO_s_file());
239 if (in == NULL)
240 goto end;
241
242 if (BIO_read_filename(in, file) <= 0)
243 goto end;
244
245 x = PEM_read_bio_X509_AUX(in, NULL, ctx->default_passwd_callback, ctx->default_passwd_callback_userdata);
246 if (x == NULL)
247 goto end;
248
249#ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME
250 names = X509_get_ext_d2i(x, NID_subject_alt_name, NULL, NULL);
251 if (names) {
252 for (i = 0; i < sk_GENERAL_NAME_num(names); i++) {
253 GENERAL_NAME *name = sk_GENERAL_NAME_value(names, i);
254 if (name->type == GEN_DNS) {
255 if (ASN1_STRING_to_UTF8((unsigned char **)&str, name->d.dNSName) >= 0) {
256 if ((len = strlen(str))) {
257 int j;
258
259 if (*str != '*') {
260 sc = malloc(sizeof(struct sni_ctx) + len + 1);
261 for (j = 0; j < len; j++)
262 sc->name.key[j] = tolower(str[j]);
263 sc->name.key[len] = 0;
264 sc->order = order++;
265 sc->ctx = ctx;
266 ebst_insert(&s->sni_ctx, &sc->name);
267 }
268 else {
269 sc = malloc(sizeof(struct sni_ctx) + len);
270 for (j = 1; j < len; j++)
271 sc->name.key[j-1] = tolower(str[j]);
272 sc->name.key[len-1] = 0;
273 sc->order = order++;
274 sc->ctx = ctx;
275 ebst_insert(&s->sni_w_ctx, &sc->name);
276 }
277 }
278 OPENSSL_free(str);
279 }
280 }
281 }
282 sk_GENERAL_NAME_pop_free(names, GENERAL_NAME_free);
283 }
284#endif /* SSL_CTRL_SET_TLSEXT_HOSTNAME */
285
286 xname = X509_get_subject_name(x);
287 i = -1;
288 while ((i = X509_NAME_get_index_by_NID(xname, NID_commonName, i)) != -1) {
289 X509_NAME_ENTRY *entry = X509_NAME_get_entry(xname, i);
290 if (ASN1_STRING_to_UTF8((unsigned char **)&str, entry->value) >= 0) {
291 if ((len = strlen(str))) {
292 int j;
293
294 if (*str != '*') {
295 sc = malloc(sizeof(struct sni_ctx) + len + 1);
296 for (j = 0; j < len; j++)
297 sc->name.key[j] = tolower(str[j]);
298 sc->name.key[len] = 0;
299 sc->order = order++;
300 sc->ctx = ctx;
301 ebst_insert(&s->sni_ctx, &sc->name);
302 }
303 else {
304 sc = malloc(sizeof(struct sni_ctx) + len);
305 for (j = 1; j < len; j++)
306 sc->name.key[j-1] = tolower(str[j]);
307 sc->name.key[len-1] = 0;
308 sc->order = order++;
309 sc->ctx = ctx;
310 ebst_insert(&s->sni_w_ctx, &sc->name);
311 }
312 }
313 OPENSSL_free(str);
314 }
315 }
316
317 ret = 0; /* the caller must not free the SSL_CTX argument anymore */
318 if (!SSL_CTX_use_certificate(ctx, x))
319 goto end;
320
321 if (ctx->extra_certs != NULL) {
322 sk_X509_pop_free(ctx->extra_certs, X509_free);
323 ctx->extra_certs = NULL;
324 }
325
326 while ((ca = PEM_read_bio_X509(in, NULL, ctx->default_passwd_callback, ctx->default_passwd_callback_userdata))) {
327 if (!SSL_CTX_add_extra_chain_cert(ctx, ca)) {
328 X509_free(ca);
329 goto end;
330 }
331 }
332
333 err = ERR_get_error();
334 if (!err || (ERR_GET_LIB(err) == ERR_LIB_PEM && ERR_GET_REASON(err) == PEM_R_NO_START_LINE)) {
335 /* we successfully reached the last cert in the file */
336 ret = 1;
337 }
338 ERR_clear_error();
339
340end:
341 if (x)
342 X509_free(x);
343
344 if (in)
345 BIO_free(in);
346
347 return ret;
348}
349
Willy Tarreau79eeafa2012-09-14 07:53:05 +0200350static 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 +0200351{
352 int ret;
353 SSL_CTX *ctx;
354
355 ctx = SSL_CTX_new(SSLv23_server_method());
356 if (!ctx) {
Willy Tarreaueb6cead2012-09-20 19:43:14 +0200357 memprintf(err, "%sunable to allocate SSL context for cert '%s'.\n",
358 err && *err ? *err : "", path);
Emeric Brunfc0421f2012-09-07 17:30:07 +0200359 return 1;
360 }
361
362 if (SSL_CTX_use_PrivateKey_file(ctx, path, SSL_FILETYPE_PEM) <= 0) {
Willy Tarreaueb6cead2012-09-20 19:43:14 +0200363 memprintf(err, "%sunable to load SSL private key from PEM file '%s'.\n",
364 err && *err ? *err : "", path);
Emeric Brunfc0421f2012-09-07 17:30:07 +0200365 SSL_CTX_free(ctx);
366 return 1;
367 }
368
Willy Tarreau2a65ff02012-09-13 17:54:29 +0200369 ret = ssl_sock_load_cert_chain_file(ctx, path, bind_conf);
Emeric Brunfc0421f2012-09-07 17:30:07 +0200370 if (ret <= 0) {
Willy Tarreaueb6cead2012-09-20 19:43:14 +0200371 memprintf(err, "%sunable to load SSL certificate from PEM file '%s'.\n",
372 err && *err ? *err : "", path);
Emeric Brunfc0421f2012-09-07 17:30:07 +0200373 if (ret < 0) /* serious error, must do that ourselves */
374 SSL_CTX_free(ctx);
375 return 1;
376 }
377 /* we must not free the SSL_CTX anymore below, since it's already in
378 * the tree, so it will be discovered and cleaned in time.
379 */
Emeric Bruna4bcd9a2012-09-20 16:19:02 +0200380#ifndef OPENSSL_NO_DH
381 ret = ssl_sock_load_dh_params(ctx, path);
382 if (ret < 0) {
383 if (err)
384 memprintf(err, "%sunable to load DH parameters from file '%s'.\n",
385 *err ? *err : "", path);
386 return 1;
387 }
388#endif
389
Emeric Brunfc0421f2012-09-07 17:30:07 +0200390#ifndef SSL_CTRL_SET_TLSEXT_HOSTNAME
Willy Tarreau2a65ff02012-09-13 17:54:29 +0200391 if (bind_conf->default_ctx) {
Willy Tarreaueb6cead2012-09-20 19:43:14 +0200392 memprintf(err, "%sthis version of openssl cannot load multiple SSL certificates.\n",
393 err && *err ? *err : "");
Emeric Brunfc0421f2012-09-07 17:30:07 +0200394 return 1;
395 }
396#endif
Willy Tarreau2a65ff02012-09-13 17:54:29 +0200397 if (!bind_conf->default_ctx)
398 bind_conf->default_ctx = ctx;
Emeric Brunfc0421f2012-09-07 17:30:07 +0200399
400 return 0;
401}
402
Willy Tarreau79eeafa2012-09-14 07:53:05 +0200403int ssl_sock_load_cert(char *path, struct bind_conf *bind_conf, struct proxy *curproxy, char **err)
Emeric Brunfc0421f2012-09-07 17:30:07 +0200404{
405 struct dirent *de;
406 DIR *dir;
407 struct stat buf;
408 int pathlen = 0;
409 char *end, *fp;
410 int cfgerr = 0;
411
412 if (!(dir = opendir(path)))
Willy Tarreau79eeafa2012-09-14 07:53:05 +0200413 return ssl_sock_load_cert_file(path, bind_conf, curproxy, err);
Emeric Brunfc0421f2012-09-07 17:30:07 +0200414
415 /* strip trailing slashes, including first one */
416 for (end = path + strlen(path) - 1; end >= path && *end == '/'; end--)
417 *end = 0;
418
419 if (end >= path)
420 pathlen = end + 1 - path;
421 fp = malloc(pathlen + 1 + NAME_MAX + 1);
422
423 while ((de = readdir(dir))) {
424 snprintf(fp, pathlen + 1 + NAME_MAX + 1, "%s/%s", path, de->d_name);
425 if (stat(fp, &buf) != 0) {
Willy Tarreaueb6cead2012-09-20 19:43:14 +0200426 memprintf(err, "%sunable to stat SSL certificate from file '%s' : %s.\n",
427 err && *err ? *err : "", fp, strerror(errno));
Emeric Brunfc0421f2012-09-07 17:30:07 +0200428 cfgerr++;
429 continue;
430 }
431 if (!S_ISREG(buf.st_mode))
432 continue;
Willy Tarreau79eeafa2012-09-14 07:53:05 +0200433 cfgerr += ssl_sock_load_cert_file(fp, bind_conf, curproxy, err);
Emeric Brunfc0421f2012-09-07 17:30:07 +0200434 }
435 free(fp);
436 closedir(dir);
437 return cfgerr;
438}
439
440#ifndef SSL_OP_CIPHER_SERVER_PREFERENCE /* needs OpenSSL >= 0.9.7 */
441#define SSL_OP_CIPHER_SERVER_PREFERENCE 0
442#endif
443
444#ifndef SSL_OP_NO_SESSION_RESUMPTION_ON_RENEGOTIATION /* needs OpenSSL >= 0.9.7 */
445#define SSL_OP_NO_SESSION_RESUMPTION_ON_RENEGOTIATION 0
446#endif
Emeric Brun2b58d042012-09-20 17:10:03 +0200447#ifndef SSL_OP_SINGLE_ECDH_USE /* needs OpenSSL >= 0.9.8 */
448#define SSL_OP_SINGLE_ECDH_USE 0
449#endif
Emeric Brun2d0c4822012-10-02 13:45:20 +0200450#ifndef SSL_OP_NO_TICKET /* needs OpenSSL >= 0.9.8 */
451#define SSL_OP_NO_TICKET 0
452#endif
Emeric Brunfc0421f2012-09-07 17:30:07 +0200453#ifndef SSL_OP_NO_COMPRESSION /* needs OpenSSL >= 0.9.9 */
454#define SSL_OP_NO_COMPRESSION 0
455#endif
Emeric Brunc0ff4922012-09-28 19:37:02 +0200456#ifndef SSL_OP_NO_TLSv1_1 /* needs OpenSSL >= 1.0.1 */
457#define SSL_OP_NO_TLSv1_1 0
458#endif
459#ifndef SSL_OP_NO_TLSv1_2 /* needs OpenSSL >= 1.0.1 */
460#define SSL_OP_NO_TLSv1_2 0
461#endif
Emeric Bruna4bcd9a2012-09-20 16:19:02 +0200462#ifndef SSL_OP_SINGLE_DH_USE /* needs OpenSSL >= 0.9.6 */
463#define SSL_OP_SINGLE_DH_USE 0
464#endif
Emeric Brun2b58d042012-09-20 17:10:03 +0200465#ifndef SSL_OP_SINGLE_ECDH_USE /* needs OpenSSL >= 1.0.0 */
466#define SSL_OP_SINGLE_ECDH_USE 0
467#endif
Emeric Brunfc0421f2012-09-07 17:30:07 +0200468#ifndef SSL_MODE_RELEASE_BUFFERS /* needs OpenSSL >= 1.0.0 */
469#define SSL_MODE_RELEASE_BUFFERS 0
470#endif
Willy Tarreau2a65ff02012-09-13 17:54:29 +0200471int ssl_sock_prepare_ctx(struct bind_conf *bind_conf, SSL_CTX *ctx, struct proxy *curproxy)
Emeric Brunfc0421f2012-09-07 17:30:07 +0200472{
473 int cfgerr = 0;
474 int ssloptions =
475 SSL_OP_ALL | /* all known workarounds for bugs */
476 SSL_OP_NO_SSLv2 |
477 SSL_OP_NO_COMPRESSION |
Emeric Bruna4bcd9a2012-09-20 16:19:02 +0200478 SSL_OP_SINGLE_DH_USE |
Emeric Brun2b58d042012-09-20 17:10:03 +0200479 SSL_OP_SINGLE_ECDH_USE |
Emeric Brun3c4bc6e2012-10-04 18:44:19 +0200480 SSL_OP_NO_SESSION_RESUMPTION_ON_RENEGOTIATION |
481 SSL_OP_CIPHER_SERVER_PREFERENCE;
Emeric Brunfc0421f2012-09-07 17:30:07 +0200482 int sslmode =
483 SSL_MODE_ENABLE_PARTIAL_WRITE |
484 SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER |
485 SSL_MODE_RELEASE_BUFFERS;
486
Emeric Brun89675492012-10-05 13:48:26 +0200487 if (bind_conf->ssl_options & BC_SSL_O_NO_SSLV3)
Emeric Brunfc0421f2012-09-07 17:30:07 +0200488 ssloptions |= SSL_OP_NO_SSLv3;
Emeric Brun89675492012-10-05 13:48:26 +0200489 if (bind_conf->ssl_options & BC_SSL_O_NO_TLSV10)
Emeric Brunfc0421f2012-09-07 17:30:07 +0200490 ssloptions |= SSL_OP_NO_TLSv1;
Emeric Brun89675492012-10-05 13:48:26 +0200491 if (bind_conf->ssl_options & BC_SSL_O_NO_TLSV11)
Emeric Brunc0ff4922012-09-28 19:37:02 +0200492 ssloptions |= SSL_OP_NO_TLSv1_1;
Emeric Brun89675492012-10-05 13:48:26 +0200493 if (bind_conf->ssl_options & BC_SSL_O_NO_TLSV12)
Emeric Brunc0ff4922012-09-28 19:37:02 +0200494 ssloptions |= SSL_OP_NO_TLSv1_2;
Emeric Brun89675492012-10-05 13:48:26 +0200495 if (bind_conf->ssl_options & BC_SSL_O_NO_TLS_TICKETS)
Emeric Brun2d0c4822012-10-02 13:45:20 +0200496 ssloptions |= SSL_OP_NO_TICKET;
Emeric Brun2cb7ae52012-10-05 14:14:21 +0200497 if (bind_conf->ssl_options & BC_SSL_O_USE_SSLV3)
498 SSL_CTX_set_ssl_version(ctx, SSLv3_server_method());
499 if (bind_conf->ssl_options & BC_SSL_O_USE_TLSV10)
500 SSL_CTX_set_ssl_version(ctx, TLSv1_server_method());
501#if SSL_OP_NO_TLSv1_1
502 if (bind_conf->ssl_options & BC_SSL_O_USE_TLSV11)
503 SSL_CTX_set_ssl_version(ctx, TLSv1_1_server_method());
504#endif
505#if SSL_OP_NO_TLSv1_2
506 if (bind_conf->ssl_options & BC_SSL_O_USE_TLSV12)
507 SSL_CTX_set_ssl_version(ctx, TLSv1_2_server_method());
508#endif
Emeric Brunfc0421f2012-09-07 17:30:07 +0200509
510 SSL_CTX_set_options(ctx, ssloptions);
511 SSL_CTX_set_mode(ctx, sslmode);
Emeric Brune64aef12012-09-21 13:15:06 +0200512 SSL_CTX_set_verify(ctx, bind_conf->verify ? bind_conf->verify : SSL_VERIFY_NONE, ssl_sock_verifycbk);
Emeric Brund94b3fe2012-09-20 18:23:56 +0200513 if (bind_conf->verify & SSL_VERIFY_PEER) {
Emeric Brunfb510ea2012-10-05 12:00:26 +0200514 if (bind_conf->ca_file) {
Emeric Brund94b3fe2012-09-20 18:23:56 +0200515 /* load CAfile to verify */
Emeric Brunfb510ea2012-10-05 12:00:26 +0200516 if (!SSL_CTX_load_verify_locations(ctx, bind_conf->ca_file, NULL)) {
Emeric Brund94b3fe2012-09-20 18:23:56 +0200517 Alert("Proxy '%s': unable to load CA file '%s' for bind '%s' at [%s:%d].\n",
Emeric Brunfb510ea2012-10-05 12:00:26 +0200518 curproxy->id, bind_conf->ca_file, bind_conf->arg, bind_conf->file, bind_conf->line);
Emeric Brund94b3fe2012-09-20 18:23:56 +0200519 cfgerr++;
520 }
521 /* set CA names fo client cert request, function returns void */
Emeric Brunfb510ea2012-10-05 12:00:26 +0200522 SSL_CTX_set_client_CA_list(ctx, SSL_load_client_CA_file(bind_conf->ca_file));
Emeric Brund94b3fe2012-09-20 18:23:56 +0200523 }
Emeric Brun051cdab2012-10-02 19:25:50 +0200524#ifdef X509_V_FLAG_CRL_CHECK
Emeric Brunfb510ea2012-10-05 12:00:26 +0200525 if (bind_conf->crl_file) {
Emeric Brund94b3fe2012-09-20 18:23:56 +0200526 X509_STORE *store = SSL_CTX_get_cert_store(ctx);
527
Emeric Brunfb510ea2012-10-05 12:00:26 +0200528 if (!store || !X509_STORE_load_locations(store, bind_conf->crl_file, NULL)) {
Emeric Brund94b3fe2012-09-20 18:23:56 +0200529 Alert("Proxy '%s': unable to configure CRL file '%s' for bind '%s' at [%s:%d].\n",
Emeric Brunfb510ea2012-10-05 12:00:26 +0200530 curproxy->id, bind_conf->ca_file, bind_conf->arg, bind_conf->file, bind_conf->line);
Emeric Brund94b3fe2012-09-20 18:23:56 +0200531 cfgerr++;
532 }
Emeric Brun561e5742012-10-02 15:20:55 +0200533 else {
534 X509_STORE_set_flags(store, X509_V_FLAG_CRL_CHECK|X509_V_FLAG_CRL_CHECK_ALL);
535 }
Emeric Brund94b3fe2012-09-20 18:23:56 +0200536 }
Emeric Brun051cdab2012-10-02 19:25:50 +0200537#endif
Emeric Brund94b3fe2012-09-20 18:23:56 +0200538 }
Emeric Brunfc0421f2012-09-07 17:30:07 +0200539
540 shared_context_set_cache(ctx);
Willy Tarreau2a65ff02012-09-13 17:54:29 +0200541 if (bind_conf->ciphers &&
542 !SSL_CTX_set_cipher_list(ctx, bind_conf->ciphers)) {
Emeric Brunfc0421f2012-09-07 17:30:07 +0200543 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 +0200544 curproxy->id, bind_conf->ciphers, bind_conf->arg, bind_conf->file, bind_conf->line);
Emeric Brunfc0421f2012-09-07 17:30:07 +0200545 cfgerr++;
546 }
547
548 SSL_CTX_set_info_callback(ctx, ssl_sock_infocbk);
549#ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME
550 SSL_CTX_set_tlsext_servername_callback(ctx, ssl_sock_switchctx_cbk);
Willy Tarreau2a65ff02012-09-13 17:54:29 +0200551 SSL_CTX_set_tlsext_servername_arg(ctx, bind_conf);
Emeric Brunfc0421f2012-09-07 17:30:07 +0200552#endif
Emeric Brun2b58d042012-09-20 17:10:03 +0200553#if defined(SSL_CTX_set_tmp_ecdh) && !defined(OPENSSL_NO_ECDH)
554 if (bind_conf->ecdhe) {
555 int i;
556 EC_KEY *ecdh;
557
558 i = OBJ_sn2nid(bind_conf->ecdhe);
559 if (!i || ((ecdh = EC_KEY_new_by_curve_name(i)) == NULL)) {
560 Alert("Proxy '%s': unable to set elliptic named curve to '%s' for bind '%s' at [%s:%d].\n",
561 curproxy->id, bind_conf->ecdhe, bind_conf->arg, bind_conf->file, bind_conf->line);
562 cfgerr++;
563 }
564 else {
565 SSL_CTX_set_tmp_ecdh(ctx, ecdh);
566 EC_KEY_free(ecdh);
567 }
568 }
569#endif
570
Emeric Brunfc0421f2012-09-07 17:30:07 +0200571 return cfgerr;
572}
573
Willy Tarreau2a65ff02012-09-13 17:54:29 +0200574/* Walks down the two trees in bind_conf and prepares all certs. The pointer may
Emeric Brunfc0421f2012-09-07 17:30:07 +0200575 * be NULL, in which case nothing is done. Returns the number of errors
576 * encountered.
577 */
Willy Tarreau2a65ff02012-09-13 17:54:29 +0200578int ssl_sock_prepare_all_ctx(struct bind_conf *bind_conf, struct proxy *px)
Emeric Brunfc0421f2012-09-07 17:30:07 +0200579{
580 struct ebmb_node *node;
581 struct sni_ctx *sni;
582 int err = 0;
583
Willy Tarreau2a65ff02012-09-13 17:54:29 +0200584 if (!bind_conf || !bind_conf->is_ssl)
Emeric Brunfc0421f2012-09-07 17:30:07 +0200585 return 0;
586
Willy Tarreau2a65ff02012-09-13 17:54:29 +0200587 node = ebmb_first(&bind_conf->sni_ctx);
Emeric Brunfc0421f2012-09-07 17:30:07 +0200588 while (node) {
589 sni = ebmb_entry(node, struct sni_ctx, name);
590 if (!sni->order) /* only initialize the CTX on its first occurrence */
Willy Tarreau2a65ff02012-09-13 17:54:29 +0200591 err += ssl_sock_prepare_ctx(bind_conf, sni->ctx, px);
Emeric Brunfc0421f2012-09-07 17:30:07 +0200592 node = ebmb_next(node);
593 }
594
Willy Tarreau2a65ff02012-09-13 17:54:29 +0200595 node = ebmb_first(&bind_conf->sni_w_ctx);
Emeric Brunfc0421f2012-09-07 17:30:07 +0200596 while (node) {
597 sni = ebmb_entry(node, struct sni_ctx, name);
598 if (!sni->order) /* only initialize the CTX on its first occurrence */
Willy Tarreau2a65ff02012-09-13 17:54:29 +0200599 err += ssl_sock_prepare_ctx(bind_conf, sni->ctx, px);
Emeric Brunfc0421f2012-09-07 17:30:07 +0200600 node = ebmb_next(node);
601 }
602 return err;
603}
604
Willy Tarreau2a65ff02012-09-13 17:54:29 +0200605/* Walks down the two trees in bind_conf and frees all the certs. The pointer may
Emeric Brunfc0421f2012-09-07 17:30:07 +0200606 * be NULL, in which case nothing is done. The default_ctx is nullified too.
607 */
Willy Tarreau2a65ff02012-09-13 17:54:29 +0200608void ssl_sock_free_all_ctx(struct bind_conf *bind_conf)
Emeric Brunfc0421f2012-09-07 17:30:07 +0200609{
610 struct ebmb_node *node, *back;
611 struct sni_ctx *sni;
612
Willy Tarreau2a65ff02012-09-13 17:54:29 +0200613 if (!bind_conf || !bind_conf->is_ssl)
Emeric Brunfc0421f2012-09-07 17:30:07 +0200614 return;
615
Willy Tarreau2a65ff02012-09-13 17:54:29 +0200616 node = ebmb_first(&bind_conf->sni_ctx);
Emeric Brunfc0421f2012-09-07 17:30:07 +0200617 while (node) {
618 sni = ebmb_entry(node, struct sni_ctx, name);
619 back = ebmb_next(node);
620 ebmb_delete(node);
621 if (!sni->order) /* only free the CTX on its first occurrence */
622 SSL_CTX_free(sni->ctx);
623 free(sni);
624 node = back;
625 }
626
Willy Tarreau2a65ff02012-09-13 17:54:29 +0200627 node = ebmb_first(&bind_conf->sni_w_ctx);
Emeric Brunfc0421f2012-09-07 17:30:07 +0200628 while (node) {
629 sni = ebmb_entry(node, struct sni_ctx, name);
630 back = ebmb_next(node);
631 ebmb_delete(node);
632 if (!sni->order) /* only free the CTX on its first occurrence */
633 SSL_CTX_free(sni->ctx);
634 free(sni);
635 node = back;
636 }
637
Willy Tarreau2a65ff02012-09-13 17:54:29 +0200638 bind_conf->default_ctx = NULL;
Emeric Brune1f38db2012-09-03 20:36:47 +0200639}
640
Emeric Brun46591952012-05-18 15:47:34 +0200641/*
642 * This function is called if SSL * context is not yet allocated. The function
643 * is designed to be called before any other data-layer operation and sets the
644 * handshake flag on the connection. It is safe to call it multiple times.
645 * It returns 0 on success and -1 in error case.
646 */
647static int ssl_sock_init(struct connection *conn)
648{
649 /* already initialized */
Willy Tarreauf7bc57c2012-10-03 00:19:48 +0200650 if (conn->xprt_ctx)
Emeric Brun46591952012-05-18 15:47:34 +0200651 return 0;
652
Willy Tarreau403edff2012-09-06 11:58:37 +0200653 if (global.maxsslconn && sslconns >= global.maxsslconn)
654 return -1;
655
Emeric Brun46591952012-05-18 15:47:34 +0200656 /* If it is in client mode initiate SSL session
657 in connect state otherwise accept state */
658 if (target_srv(&conn->target)) {
Emeric Brun46591952012-05-18 15:47:34 +0200659 /* Alloc a new SSL session ctx */
Willy Tarreauf7bc57c2012-10-03 00:19:48 +0200660 conn->xprt_ctx = SSL_new(target_srv(&conn->target)->ssl_ctx.ctx);
661 if (!conn->xprt_ctx)
Emeric Brun46591952012-05-18 15:47:34 +0200662 return -1;
663
Willy Tarreauf7bc57c2012-10-03 00:19:48 +0200664 SSL_set_connect_state(conn->xprt_ctx);
Emeric Brun46591952012-05-18 15:47:34 +0200665 if (target_srv(&conn->target)->ssl_ctx.reused_sess)
Willy Tarreauf7bc57c2012-10-03 00:19:48 +0200666 SSL_set_session(conn->xprt_ctx, target_srv(&conn->target)->ssl_ctx.reused_sess);
Emeric Brun46591952012-05-18 15:47:34 +0200667
668 /* set fd on SSL session context */
Willy Tarreauf7bc57c2012-10-03 00:19:48 +0200669 SSL_set_fd(conn->xprt_ctx, conn->t.sock.fd);
Emeric Brun46591952012-05-18 15:47:34 +0200670
671 /* leave init state and start handshake */
Willy Tarreau05737472012-09-04 08:03:39 +0200672 conn->flags |= CO_FL_SSL_WAIT_HS | CO_FL_WAIT_L6_CONN;
Willy Tarreau403edff2012-09-06 11:58:37 +0200673
674 sslconns++;
Emeric Brun46591952012-05-18 15:47:34 +0200675 return 0;
676 }
677 else if (target_client(&conn->target)) {
Emeric Brun46591952012-05-18 15:47:34 +0200678 /* Alloc a new SSL session ctx */
Willy Tarreauf7bc57c2012-10-03 00:19:48 +0200679 conn->xprt_ctx = SSL_new(target_client(&conn->target)->bind_conf->default_ctx);
680 if (!conn->xprt_ctx)
Emeric Brun46591952012-05-18 15:47:34 +0200681 return -1;
682
Willy Tarreauf7bc57c2012-10-03 00:19:48 +0200683 SSL_set_accept_state(conn->xprt_ctx);
Emeric Brun46591952012-05-18 15:47:34 +0200684
685 /* set fd on SSL session context */
Willy Tarreauf7bc57c2012-10-03 00:19:48 +0200686 SSL_set_fd(conn->xprt_ctx, conn->t.sock.fd);
Emeric Brun46591952012-05-18 15:47:34 +0200687
Emeric Brune1f38db2012-09-03 20:36:47 +0200688 /* set connection pointer */
Willy Tarreauf7bc57c2012-10-03 00:19:48 +0200689 SSL_set_app_data(conn->xprt_ctx, conn);
Emeric Brune1f38db2012-09-03 20:36:47 +0200690
Emeric Brun46591952012-05-18 15:47:34 +0200691 /* leave init state and start handshake */
Willy Tarreau05737472012-09-04 08:03:39 +0200692 conn->flags |= CO_FL_SSL_WAIT_HS | CO_FL_WAIT_L6_CONN;
Willy Tarreau403edff2012-09-06 11:58:37 +0200693
694 sslconns++;
Emeric Brun46591952012-05-18 15:47:34 +0200695 return 0;
696 }
697 /* don't know how to handle such a target */
698 return -1;
699}
700
701
702/* This is the callback which is used when an SSL handshake is pending. It
703 * updates the FD status if it wants some polling before being called again.
704 * It returns 0 if it fails in a fatal way or needs to poll to go further,
705 * otherwise it returns non-zero and removes itself from the connection's
706 * flags (the bit is provided in <flag> by the caller).
707 */
708int ssl_sock_handshake(struct connection *conn, unsigned int flag)
709{
710 int ret;
711
Willy Tarreauf7bc57c2012-10-03 00:19:48 +0200712 if (!conn->xprt_ctx)
Emeric Brun46591952012-05-18 15:47:34 +0200713 goto out_error;
714
Willy Tarreauf7bc57c2012-10-03 00:19:48 +0200715 ret = SSL_do_handshake(conn->xprt_ctx);
Emeric Brun46591952012-05-18 15:47:34 +0200716 if (ret != 1) {
717 /* handshake did not complete, let's find why */
Willy Tarreauf7bc57c2012-10-03 00:19:48 +0200718 ret = SSL_get_error(conn->xprt_ctx, ret);
Emeric Brun46591952012-05-18 15:47:34 +0200719
720 if (ret == SSL_ERROR_WANT_WRITE) {
721 /* SSL handshake needs to write, L4 connection may not be ready */
722 __conn_sock_stop_recv(conn);
723 __conn_sock_poll_send(conn);
724 return 0;
725 }
726 else if (ret == SSL_ERROR_WANT_READ) {
727 /* SSL handshake needs to read, L4 connection is ready */
728 if (conn->flags & CO_FL_WAIT_L4_CONN)
729 conn->flags &= ~CO_FL_WAIT_L4_CONN;
730 __conn_sock_stop_send(conn);
731 __conn_sock_poll_recv(conn);
732 return 0;
733 }
Willy Tarreau89230192012-09-28 20:22:13 +0200734 else if (ret == SSL_ERROR_SYSCALL) {
735 /* if errno is null, then connection was successfully established */
736 if (!errno && conn->flags & CO_FL_WAIT_L4_CONN)
737 conn->flags &= ~CO_FL_WAIT_L4_CONN;
738 goto out_error;
739 }
Emeric Brun46591952012-05-18 15:47:34 +0200740 else {
741 /* Fail on all other handshake errors */
742 goto out_error;
743 }
744 }
745
746 /* Handshake succeeded */
747 if (target_srv(&conn->target)) {
Willy Tarreauf7bc57c2012-10-03 00:19:48 +0200748 if (!SSL_session_reused(conn->xprt_ctx)) {
Emeric Brun46591952012-05-18 15:47:34 +0200749 /* check if session was reused, if not store current session on server for reuse */
750 if (target_srv(&conn->target)->ssl_ctx.reused_sess)
751 SSL_SESSION_free(target_srv(&conn->target)->ssl_ctx.reused_sess);
752
Willy Tarreauf7bc57c2012-10-03 00:19:48 +0200753 target_srv(&conn->target)->ssl_ctx.reused_sess = SSL_get1_session(conn->xprt_ctx);
Emeric Brun46591952012-05-18 15:47:34 +0200754 }
755 }
756
757 /* The connection is now established at both layers, it's time to leave */
758 conn->flags &= ~(flag | CO_FL_WAIT_L4_CONN | CO_FL_WAIT_L6_CONN);
759 return 1;
760
761 out_error:
Emeric Brun9fa89732012-10-04 17:09:56 +0200762 /* free resumed session if exists */
763 if (target_srv(&conn->target) && target_srv(&conn->target)->ssl_ctx.reused_sess) {
764 SSL_SESSION_free(target_srv(&conn->target)->ssl_ctx.reused_sess);
765 target_srv(&conn->target)->ssl_ctx.reused_sess = NULL;
766 }
767
Emeric Brun46591952012-05-18 15:47:34 +0200768 /* Fail on all other handshake errors */
769 conn->flags |= CO_FL_ERROR;
770 conn->flags &= ~flag;
771 return 0;
772}
773
774/* Receive up to <count> bytes from connection <conn>'s socket and store them
775 * into buffer <buf>. The caller must ensure that <count> is always smaller
776 * than the buffer's size. Only one call to recv() is performed, unless the
777 * buffer wraps, in which case a second call may be performed. The connection's
778 * flags are updated with whatever special event is detected (error, read0,
779 * empty). The caller is responsible for taking care of those events and
780 * avoiding the call if inappropriate. The function does not call the
781 * connection's polling update function, so the caller is responsible for this.
782 */
783static int ssl_sock_to_buf(struct connection *conn, struct buffer *buf, int count)
784{
785 int ret, done = 0;
786 int try = count;
787
Willy Tarreauf7bc57c2012-10-03 00:19:48 +0200788 if (!conn->xprt_ctx)
Emeric Brun46591952012-05-18 15:47:34 +0200789 goto out_error;
790
791 if (conn->flags & CO_FL_HANDSHAKE)
792 /* a handshake was requested */
793 return 0;
794
795 /* compute the maximum block size we can read at once. */
796 if (buffer_empty(buf)) {
797 /* let's realign the buffer to optimize I/O */
798 buf->p = buf->data;
799 }
800 else if (buf->data + buf->o < buf->p &&
801 buf->p + buf->i < buf->data + buf->size) {
802 /* remaining space wraps at the end, with a moving limit */
803 if (try > buf->data + buf->size - (buf->p + buf->i))
804 try = buf->data + buf->size - (buf->p + buf->i);
805 }
806
807 /* read the largest possible block. For this, we perform only one call
808 * to recv() unless the buffer wraps and we exactly fill the first hunk,
809 * in which case we accept to do it once again. A new attempt is made on
810 * EINTR too.
811 */
812 while (try) {
Willy Tarreauf7bc57c2012-10-03 00:19:48 +0200813 ret = SSL_read(conn->xprt_ctx, bi_end(buf), try);
Emeric Brune1f38db2012-09-03 20:36:47 +0200814 if (conn->flags & CO_FL_ERROR) {
815 /* CO_FL_ERROR may be set by ssl_sock_infocbk */
816 break;
817 }
Emeric Brun46591952012-05-18 15:47:34 +0200818 if (ret > 0) {
819 buf->i += ret;
820 done += ret;
821 if (ret < try)
822 break;
823 count -= ret;
824 try = count;
825 }
826 else if (ret == 0) {
827 goto read0;
828 }
829 else {
Willy Tarreauf7bc57c2012-10-03 00:19:48 +0200830 ret = SSL_get_error(conn->xprt_ctx, ret);
Emeric Brun46591952012-05-18 15:47:34 +0200831 if (ret == SSL_ERROR_WANT_WRITE) {
832 /* handshake is running, and it needs to poll for a write event */
833 conn->flags |= CO_FL_SSL_WAIT_HS;
834 __conn_sock_poll_send(conn);
835 break;
836 }
837 else if (ret == SSL_ERROR_WANT_READ) {
838 /* we need to poll for retry a read later */
839 __conn_data_poll_recv(conn);
840 break;
841 }
842 /* otherwise it's a real error */
843 goto out_error;
844 }
845 }
846 return done;
847
848 read0:
849 conn_sock_read0(conn);
850 return done;
851 out_error:
852 conn->flags |= CO_FL_ERROR;
853 return done;
854}
855
856
857/* Send all pending bytes from buffer <buf> to connection <conn>'s socket.
858 * <flags> may contain MSG_MORE to make the system hold on without sending
859 * data too fast, but this flag is ignored at the moment.
860 * Only one call to send() is performed, unless the buffer wraps, in which case
861 * a second call may be performed. The connection's flags are updated with
862 * whatever special event is detected (error, empty). The caller is responsible
863 * for taking care of those events and avoiding the call if inappropriate. The
864 * function does not call the connection's polling update function, so the caller
865 * is responsible for this.
866 */
867static int ssl_sock_from_buf(struct connection *conn, struct buffer *buf, int flags)
868{
869 int ret, try, done;
870
871 done = 0;
872
Willy Tarreauf7bc57c2012-10-03 00:19:48 +0200873 if (!conn->xprt_ctx)
Emeric Brun46591952012-05-18 15:47:34 +0200874 goto out_error;
875
876 if (conn->flags & CO_FL_HANDSHAKE)
877 /* a handshake was requested */
878 return 0;
879
880 /* send the largest possible block. For this we perform only one call
881 * to send() unless the buffer wraps and we exactly fill the first hunk,
882 * in which case we accept to do it once again.
883 */
884 while (buf->o) {
885 try = buf->o;
886 /* outgoing data may wrap at the end */
887 if (buf->data + try > buf->p)
888 try = buf->data + try - buf->p;
889
Willy Tarreauf7bc57c2012-10-03 00:19:48 +0200890 ret = SSL_write(conn->xprt_ctx, bo_ptr(buf), try);
Emeric Brune1f38db2012-09-03 20:36:47 +0200891 if (conn->flags & CO_FL_ERROR) {
892 /* CO_FL_ERROR may be set by ssl_sock_infocbk */
893 break;
894 }
Emeric Brun46591952012-05-18 15:47:34 +0200895 if (ret > 0) {
896 buf->o -= ret;
897 done += ret;
898
899 if (likely(!buffer_len(buf)))
900 /* optimize data alignment in the buffer */
901 buf->p = buf->data;
902
903 /* if the system buffer is full, don't insist */
904 if (ret < try)
905 break;
906 }
907 else {
Willy Tarreauf7bc57c2012-10-03 00:19:48 +0200908 ret = SSL_get_error(conn->xprt_ctx, ret);
Emeric Brun46591952012-05-18 15:47:34 +0200909 if (ret == SSL_ERROR_WANT_WRITE) {
910 /* we need to poll to retry a write later */
911 __conn_data_poll_send(conn);
912 break;
913 }
914 else if (ret == SSL_ERROR_WANT_READ) {
915 /* handshake is running, and
916 it needs to poll for a read event,
917 write polling must be disabled cause
918 we are sure we can't write anything more
919 before handshake re-performed */
920 conn->flags |= CO_FL_SSL_WAIT_HS;
921 __conn_sock_poll_recv(conn);
922 break;
923 }
924 goto out_error;
925 }
926 }
927 return done;
928
929 out_error:
930 conn->flags |= CO_FL_ERROR;
931 return done;
932}
933
934
935static void ssl_sock_close(struct connection *conn) {
936
Willy Tarreauf7bc57c2012-10-03 00:19:48 +0200937 if (conn->xprt_ctx) {
938 SSL_free(conn->xprt_ctx);
939 conn->xprt_ctx = NULL;
Willy Tarreau403edff2012-09-06 11:58:37 +0200940 sslconns--;
Emeric Brun46591952012-05-18 15:47:34 +0200941 }
Emeric Brun46591952012-05-18 15:47:34 +0200942}
943
944/* This function tries to perform a clean shutdown on an SSL connection, and in
945 * any case, flags the connection as reusable if no handshake was in progress.
946 */
947static void ssl_sock_shutw(struct connection *conn, int clean)
948{
949 if (conn->flags & CO_FL_HANDSHAKE)
950 return;
951 /* no handshake was in progress, try a clean ssl shutdown */
952 if (clean)
Willy Tarreauf7bc57c2012-10-03 00:19:48 +0200953 SSL_shutdown(conn->xprt_ctx);
Emeric Brun46591952012-05-18 15:47:34 +0200954
955 /* force flag on ssl to keep session in cache regardless shutdown result */
Willy Tarreauf7bc57c2012-10-03 00:19:48 +0200956 SSL_set_shutdown(conn->xprt_ctx, SSL_SENT_SHUTDOWN);
Emeric Brun46591952012-05-18 15:47:34 +0200957}
958
Willy Tarreau7875d092012-09-10 08:20:03 +0200959/***** Below are some sample fetching functions for ACL/patterns *****/
960
Emeric Brune64aef12012-09-21 13:15:06 +0200961/* boolean, returns true if client cert was present */
962static int
963smp_fetch_client_crt(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
964 const struct arg *args, struct sample *smp)
965{
Willy Tarreauf7bc57c2012-10-03 00:19:48 +0200966 if (!l4 || l4->si[0].conn.xprt != &ssl_sock)
Emeric Brune64aef12012-09-21 13:15:06 +0200967 return 0;
968
969 if (!(l4->si[0].conn.flags & CO_FL_CONNECTED)) {
970 smp->flags |= SMP_F_MAY_CHANGE;
971 return 0;
972 }
973
974 smp->flags = 0;
975 smp->type = SMP_T_BOOL;
Willy Tarreauf7bc57c2012-10-03 00:19:48 +0200976 smp->data.uint = SSL_SOCK_ST_FL_VERIFY_DONE & l4->si[0].conn.xprt_st ? 1 : 0;
Emeric Brune64aef12012-09-21 13:15:06 +0200977
978 return 1;
979}
980
981
Willy Tarreauf7bc57c2012-10-03 00:19:48 +0200982/* boolean, returns true if transport layer is SSL */
Willy Tarreau7875d092012-09-10 08:20:03 +0200983static int
984smp_fetch_is_ssl(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
985 const struct arg *args, struct sample *smp)
986{
987 smp->type = SMP_T_BOOL;
Willy Tarreauf7bc57c2012-10-03 00:19:48 +0200988 smp->data.uint = (l4->si[0].conn.xprt == &ssl_sock);
Willy Tarreau7875d092012-09-10 08:20:03 +0200989 return 1;
990}
991
Willy Tarreauf7bc57c2012-10-03 00:19:48 +0200992/* boolean, returns true if transport layer is SSL */
Willy Tarreau7875d092012-09-10 08:20:03 +0200993static int
994smp_fetch_has_sni(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
995 const struct arg *args, struct sample *smp)
996{
997#ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME
998 smp->type = SMP_T_BOOL;
Willy Tarreauf7bc57c2012-10-03 00:19:48 +0200999 smp->data.uint = (l4->si[0].conn.xprt == &ssl_sock) &&
1000 l4->si[0].conn.xprt_ctx &&
1001 SSL_get_servername(l4->si[0].conn.xprt_ctx, TLSEXT_NAMETYPE_host_name) != NULL;
Willy Tarreau7875d092012-09-10 08:20:03 +02001002 return 1;
1003#else
1004 return 0;
1005#endif
1006}
1007
1008static int
1009smp_fetch_ssl_sni(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
1010 const struct arg *args, struct sample *smp)
1011{
1012#ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME
1013 smp->flags = 0;
1014 smp->type = SMP_T_CSTR;
1015
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02001016 if (!l4 || !l4->si[0].conn.xprt_ctx || l4->si[0].conn.xprt != &ssl_sock)
Willy Tarreau7875d092012-09-10 08:20:03 +02001017 return 0;
1018
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02001019 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 +02001020 if (!smp->data.str.str)
1021 return 0;
1022
Willy Tarreau7875d092012-09-10 08:20:03 +02001023 smp->data.str.len = strlen(smp->data.str.str);
1024 return 1;
1025#else
1026 return 0;
1027#endif
1028}
1029
Emeric Brunf282a812012-09-21 15:27:54 +02001030/* integer, returns the first verify error ID in CA */
1031static int
1032smp_fetch_verify_caerr(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
1033 const struct arg *args, struct sample *smp)
1034{
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02001035 if (!l4 || l4->si[0].conn.xprt != &ssl_sock)
Emeric Brunf282a812012-09-21 15:27:54 +02001036 return 0;
1037
1038 if (!(l4->si[0].conn.flags & CO_FL_CONNECTED)) {
1039 smp->flags = SMP_F_MAY_CHANGE;
1040 return 0;
1041 }
1042
1043 smp->type = SMP_T_UINT;
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02001044 smp->data.uint = (unsigned int)SSL_SOCK_ST_TO_CA_ERROR(l4->si[0].conn.xprt_st);
Emeric Brunf282a812012-09-21 15:27:54 +02001045 smp->flags = 0;
1046
1047 return 1;
1048}
1049
1050/* integer, returns the depth of the first verify error in CA */
1051static int
1052smp_fetch_verify_caerr_depth(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
1053 const struct arg *args, struct sample *smp)
1054{
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02001055 if (!l4 || l4->si[0].conn.xprt != &ssl_sock)
Emeric Brunf282a812012-09-21 15:27:54 +02001056 return 0;
1057
1058 if (!(l4->si[0].conn.flags & CO_FL_CONNECTED)) {
1059 smp->flags = SMP_F_MAY_CHANGE;
1060 return 0;
1061 }
1062
1063 smp->type = SMP_T_UINT;
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02001064 smp->data.uint = (unsigned int)SSL_SOCK_ST_TO_CAEDEPTH(l4->si[0].conn.xprt_st);
Emeric Brunf282a812012-09-21 15:27:54 +02001065 smp->flags = 0;
1066
1067 return 1;
1068}
1069
1070/* integer, returns the depth of the first verify error in CA */
1071static int
1072smp_fetch_verify_crterr(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
1073 const struct arg *args, struct sample *smp)
1074{
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02001075 if (!l4 || l4->si[0].conn.xprt != &ssl_sock)
Emeric Brunf282a812012-09-21 15:27:54 +02001076 return 0;
1077
1078 if (!(l4->si[0].conn.flags & CO_FL_CONNECTED)) {
1079 smp->flags = SMP_F_MAY_CHANGE;
1080 return 0;
1081 }
1082
1083 smp->type = SMP_T_UINT;
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02001084 smp->data.uint = (unsigned int)SSL_SOCK_ST_TO_CRTERROR(l4->si[0].conn.xprt_st);
Emeric Brunf282a812012-09-21 15:27:54 +02001085 smp->flags = 0;
1086
1087 return 1;
1088}
1089
Emeric Brunbaf8ffb2012-09-21 15:27:20 +02001090/* integer, returns the verify result */
1091static int
1092smp_fetch_verify_result(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
1093 const struct arg *args, struct sample *smp)
1094{
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02001095 if (!l4 || l4->si[0].conn.xprt != &ssl_sock)
Emeric Brunbaf8ffb2012-09-21 15:27:20 +02001096 return 0;
1097
1098 if (!(l4->si[0].conn.flags & CO_FL_CONNECTED)) {
1099 smp->flags = SMP_F_MAY_CHANGE;
1100 return 0;
1101 }
1102
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02001103 if (!l4->si[0].conn.xprt_ctx)
Emeric Brunbaf8ffb2012-09-21 15:27:20 +02001104 return 0;
1105
1106 smp->type = SMP_T_UINT;
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02001107 smp->data.uint = (unsigned int)SSL_get_verify_result(l4->si[0].conn.xprt_ctx);
Emeric Brunbaf8ffb2012-09-21 15:27:20 +02001108 smp->flags = 0;
1109
1110 return 1;
1111}
1112
Emeric Brunfb510ea2012-10-05 12:00:26 +02001113/* parse the "ca-file" bind keyword */
1114static 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 +02001115{
1116 if (!*args[cur_arg + 1]) {
1117 if (err)
1118 memprintf(err, "'%s' : missing CAfile path", args[cur_arg]);
1119 return ERR_ALERT | ERR_FATAL;
1120 }
1121
Emeric Brunc8e8d122012-10-02 18:42:10 +02001122 if ((*args[cur_arg + 1] != '/') && global.ca_base) {
Emeric Brunfb510ea2012-10-05 12:00:26 +02001123 conf->ca_file = malloc(strlen(global.ca_base) + 1 + strlen(args[cur_arg + 1]) + 1);
1124 if (conf->ca_file)
1125 sprintf(conf->ca_file, "%s/%s", global.ca_base, args[cur_arg + 1]);
Emeric Brunc8e8d122012-10-02 18:42:10 +02001126 return 0;
1127 }
1128
Emeric Brunfb510ea2012-10-05 12:00:26 +02001129 conf->ca_file = strdup(args[cur_arg + 1]);
Emeric Brund94b3fe2012-09-20 18:23:56 +02001130 return 0;
1131}
1132
Willy Tarreau79eeafa2012-09-14 07:53:05 +02001133/* parse the "ciphers" bind keyword */
Willy Tarreau4348fad2012-09-20 16:48:07 +02001134static 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 +02001135{
1136 if (!*args[cur_arg + 1]) {
Willy Tarreaueb6cead2012-09-20 19:43:14 +02001137 memprintf(err, "'%s' : missing cipher suite", args[cur_arg]);
Willy Tarreau79eeafa2012-09-14 07:53:05 +02001138 return ERR_ALERT | ERR_FATAL;
1139 }
1140
Emeric Brun76d88952012-10-05 15:47:31 +02001141 free(conf->ciphers);
Willy Tarreau4348fad2012-09-20 16:48:07 +02001142 conf->ciphers = strdup(args[cur_arg + 1]);
Willy Tarreau79eeafa2012-09-14 07:53:05 +02001143 return 0;
1144}
1145
1146/* parse the "crt" bind keyword */
Willy Tarreau4348fad2012-09-20 16:48:07 +02001147static 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 +02001148{
Emeric Brunc8e8d122012-10-02 18:42:10 +02001149 char path[PATH_MAX];
Willy Tarreau79eeafa2012-09-14 07:53:05 +02001150 if (!*args[cur_arg + 1]) {
Willy Tarreaueb6cead2012-09-20 19:43:14 +02001151 memprintf(err, "'%s' : missing certificate location", args[cur_arg]);
Willy Tarreau79eeafa2012-09-14 07:53:05 +02001152 return ERR_ALERT | ERR_FATAL;
1153 }
1154
Emeric Brunc8e8d122012-10-02 18:42:10 +02001155 if ((*args[cur_arg + 1] != '/' ) && global.crt_base) {
1156 if ((strlen(global.crt_base) + 1 + strlen(args[cur_arg + 1]) + 1) > PATH_MAX) {
1157 memprintf(err, "'%s' : path too long", args[cur_arg]);
1158 return ERR_ALERT | ERR_FATAL;
1159 }
1160 sprintf(path, "%s/%s", global.crt_base, args[cur_arg + 1]);
1161 if (ssl_sock_load_cert(path, conf, px, err) > 0)
1162 return ERR_ALERT | ERR_FATAL;
1163
1164 return 0;
1165 }
1166
Willy Tarreau4348fad2012-09-20 16:48:07 +02001167 if (ssl_sock_load_cert(args[cur_arg + 1], conf, px, err) > 0)
Willy Tarreau79eeafa2012-09-14 07:53:05 +02001168 return ERR_ALERT | ERR_FATAL;
Emeric Brund94b3fe2012-09-20 18:23:56 +02001169
1170 return 0;
1171}
1172
Emeric Brunfb510ea2012-10-05 12:00:26 +02001173/* parse the "crl-file" bind keyword */
1174static 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 +02001175{
Emeric Brun051cdab2012-10-02 19:25:50 +02001176#ifndef X509_V_FLAG_CRL_CHECK
1177 if (err)
1178 memprintf(err, "'%s' : library does not support CRL verify", args[cur_arg]);
1179 return ERR_ALERT | ERR_FATAL;
1180#else
Emeric Brund94b3fe2012-09-20 18:23:56 +02001181 if (!*args[cur_arg + 1]) {
1182 if (err)
1183 memprintf(err, "'%s' : missing CRLfile path", args[cur_arg]);
1184 return ERR_ALERT | ERR_FATAL;
1185 }
Emeric Brun2b58d042012-09-20 17:10:03 +02001186
Emeric Brunc8e8d122012-10-02 18:42:10 +02001187 if ((*args[cur_arg + 1] != '/') && global.ca_base) {
Emeric Brunfb510ea2012-10-05 12:00:26 +02001188 conf->crl_file = malloc(strlen(global.ca_base) + 1 + strlen(args[cur_arg + 1]) + 1);
1189 if (conf->crl_file)
1190 sprintf(conf->crl_file, "%s/%s", global.ca_base, args[cur_arg + 1]);
Emeric Brunc8e8d122012-10-02 18:42:10 +02001191 return 0;
1192 }
1193
Emeric Brunfb510ea2012-10-05 12:00:26 +02001194 conf->crl_file = strdup(args[cur_arg + 1]);
Emeric Brun2b58d042012-09-20 17:10:03 +02001195 return 0;
Emeric Brun051cdab2012-10-02 19:25:50 +02001196#endif
Emeric Brun2b58d042012-09-20 17:10:03 +02001197}
1198
1199/* parse the "ecdhe" bind keyword keywords */
1200static int bind_parse_ecdhe(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
1201{
1202#if OPENSSL_VERSION_NUMBER < 0x0090800fL
1203 if (err)
1204 memprintf(err, "'%s' : library does not support elliptic curve Diffie-Hellman (too old)", args[cur_arg]);
1205 return ERR_ALERT | ERR_FATAL;
1206#elif defined(OPENSSL_NO_ECDH)
1207 if (err)
1208 memprintf(err, "'%s' : library does not support elliptic curve Diffie-Hellman (disabled via OPENSSL_NO_ECDH)", args[cur_arg]);
1209 return ERR_ALERT | ERR_FATAL;
1210#else
1211 if (!*args[cur_arg + 1]) {
1212 if (err)
1213 memprintf(err, "'%s' : missing named curve", args[cur_arg]);
1214 return ERR_ALERT | ERR_FATAL;
1215 }
1216
1217 conf->ecdhe = strdup(args[cur_arg + 1]);
Willy Tarreau79eeafa2012-09-14 07:53:05 +02001218
1219 return 0;
Emeric Brun2b58d042012-09-20 17:10:03 +02001220#endif
Willy Tarreau79eeafa2012-09-14 07:53:05 +02001221}
1222
Emeric Brun81c00f02012-09-21 14:31:21 +02001223/* parse the "crt_ignerr" and "ca_ignerr" bind keywords */
1224static int bind_parse_ignore_err(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
1225{
1226 int code;
1227 char *p = args[cur_arg + 1];
1228 unsigned long long *ignerr = &conf->crt_ignerr;
1229
1230 if (!*p) {
1231 if (err)
1232 memprintf(err, "'%s' : missing error IDs list", args[cur_arg]);
1233 return ERR_ALERT | ERR_FATAL;
1234 }
1235
1236 if (strcmp(args[cur_arg], "ca-ignore-err") == 0)
1237 ignerr = &conf->ca_ignerr;
1238
1239 if (strcmp(p, "all") == 0) {
1240 *ignerr = ~0ULL;
1241 return 0;
1242 }
1243
1244 while (p) {
1245 code = atoi(p);
1246 if ((code <= 0) || (code > 63)) {
1247 if (err)
1248 memprintf(err, "'%s' : ID '%d' out of range (1..63) in error IDs list '%s'",
1249 args[cur_arg], code, args[cur_arg + 1]);
1250 return ERR_ALERT | ERR_FATAL;
1251 }
1252 *ignerr |= 1ULL << code;
1253 p = strchr(p, ',');
1254 if (p)
1255 p++;
1256 }
1257
Emeric Brun2cb7ae52012-10-05 14:14:21 +02001258 return 0;
1259}
1260
1261/* parse the "force-sslv3" bind keyword */
1262static int bind_parse_force_sslv3(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
1263{
1264 conf->ssl_options |= BC_SSL_O_USE_SSLV3;
1265 return 0;
1266}
1267
1268/* parse the "force-tlsv10" bind keyword */
1269static int bind_parse_force_tlsv10(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
1270{
1271 conf->ssl_options |= BC_SSL_O_USE_TLSV10;
Emeric Brun2d0c4822012-10-02 13:45:20 +02001272 return 0;
1273}
1274
Emeric Brun2cb7ae52012-10-05 14:14:21 +02001275/* parse the "force-tlsv11" bind keyword */
1276static int bind_parse_force_tlsv11(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
1277{
1278#if SSL_OP_NO_TLSv1_1
1279 conf->ssl_options |= BC_SSL_O_USE_TLSV11;
1280 return 0;
1281#else
1282 if (err)
1283 memprintf(err, "'%s' : library does not support protocol TLSv1.1", args[cur_arg]);
1284 return ERR_ALERT | ERR_FATAL;
1285#endif
1286}
1287
1288/* parse the "force-tlsv12" bind keyword */
1289static int bind_parse_force_tlsv12(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
1290{
1291#if SSL_OP_NO_TLSv1_2
1292 conf->ssl_options |= BC_SSL_O_USE_TLSV12;
1293 return 0;
1294#else
1295 if (err)
1296 memprintf(err, "'%s' : library does not support protocol TLSv1.2", args[cur_arg]);
1297 return ERR_ALERT | ERR_FATAL;
1298#endif
1299}
1300
1301
Emeric Brun2d0c4822012-10-02 13:45:20 +02001302/* parse the "no-tls-tickets" bind keyword */
1303static int bind_parse_no_tls_tickets(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
1304{
Emeric Brun89675492012-10-05 13:48:26 +02001305 conf->ssl_options |= BC_SSL_O_NO_TLS_TICKETS;
Emeric Brun81c00f02012-09-21 14:31:21 +02001306 return 0;
1307}
1308
Emeric Brun2d0c4822012-10-02 13:45:20 +02001309
Emeric Brun9b3009b2012-10-05 11:55:06 +02001310/* parse the "no-sslv3" bind keyword */
1311static 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 +02001312{
Emeric Brun89675492012-10-05 13:48:26 +02001313 conf->ssl_options |= BC_SSL_O_NO_SSLV3;
Willy Tarreau79eeafa2012-09-14 07:53:05 +02001314 return 0;
1315}
1316
Emeric Brun9b3009b2012-10-05 11:55:06 +02001317/* parse the "no-tlsv10" bind keyword */
1318static 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 +02001319{
Emeric Brun89675492012-10-05 13:48:26 +02001320 conf->ssl_options |= BC_SSL_O_NO_TLSV10;
Emeric Brunc0ff4922012-09-28 19:37:02 +02001321 return 0;
1322}
1323
Emeric Brun9b3009b2012-10-05 11:55:06 +02001324/* parse the "no-tlsv11" bind keyword */
1325static 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 +02001326{
Emeric Brun89675492012-10-05 13:48:26 +02001327 conf->ssl_options |= BC_SSL_O_NO_TLSV11;
Emeric Brunc0ff4922012-09-28 19:37:02 +02001328 return 0;
1329}
1330
Emeric Brun9b3009b2012-10-05 11:55:06 +02001331/* parse the "no-tlsv12" bind keyword */
1332static 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 +02001333{
Emeric Brun89675492012-10-05 13:48:26 +02001334 conf->ssl_options |= BC_SSL_O_NO_TLSV12;
Willy Tarreau79eeafa2012-09-14 07:53:05 +02001335 return 0;
1336}
1337
Willy Tarreau79eeafa2012-09-14 07:53:05 +02001338/* parse the "ssl" bind keyword */
Willy Tarreau4348fad2012-09-20 16:48:07 +02001339static 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 +02001340{
Willy Tarreau81796be2012-09-22 19:11:47 +02001341 struct listener *l;
1342
Willy Tarreau4348fad2012-09-20 16:48:07 +02001343 conf->is_ssl = 1;
Emeric Brun76d88952012-10-05 15:47:31 +02001344
1345 if (global.listen_default_ciphers && !conf->ciphers)
1346 conf->ciphers = strdup(global.listen_default_ciphers);
1347
Willy Tarreau81796be2012-09-22 19:11:47 +02001348 list_for_each_entry(l, &conf->listeners, by_bind)
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02001349 l->xprt = &ssl_sock;
Willy Tarreau81796be2012-09-22 19:11:47 +02001350
Willy Tarreau79eeafa2012-09-14 07:53:05 +02001351 return 0;
1352}
1353
Emeric Brund94b3fe2012-09-20 18:23:56 +02001354/* parse the "verify" bind keyword */
1355static int bind_parse_verify(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
1356{
1357 if (!*args[cur_arg + 1]) {
1358 if (err)
1359 memprintf(err, "'%s' : missing verify method", args[cur_arg]);
1360 return ERR_ALERT | ERR_FATAL;
1361 }
1362
1363 if (strcmp(args[cur_arg + 1], "none") == 0)
1364 conf->verify = SSL_VERIFY_NONE;
1365 else if (strcmp(args[cur_arg + 1], "optional") == 0)
1366 conf->verify = SSL_VERIFY_PEER;
1367 else if (strcmp(args[cur_arg + 1], "required") == 0)
1368 conf->verify = SSL_VERIFY_PEER|SSL_VERIFY_FAIL_IF_NO_PEER_CERT;
1369 else {
1370 if (err)
1371 memprintf(err, "'%s' : unknown verify method '%s', only 'none', 'optional', and 'required' are supported\n",
1372 args[cur_arg], args[cur_arg + 1]);
1373 return ERR_ALERT | ERR_FATAL;
1374 }
1375
1376 return 0;
1377}
1378
Willy Tarreau7875d092012-09-10 08:20:03 +02001379/* Note: must not be declared <const> as its list will be overwritten.
1380 * Please take care of keeping this list alphabetically sorted.
1381 */
1382static struct sample_fetch_kw_list sample_fetch_keywords = {{ },{
Emeric Brunf282a812012-09-21 15:27:54 +02001383 { "client_crt", smp_fetch_client_crt, 0, NULL, SMP_T_BOOL, SMP_CAP_REQ|SMP_CAP_RES },
1384 { "is_ssl", smp_fetch_is_ssl, 0, NULL, SMP_T_BOOL, SMP_CAP_REQ|SMP_CAP_RES },
1385 { "ssl_has_sni", smp_fetch_has_sni, 0, NULL, SMP_T_BOOL, SMP_CAP_REQ|SMP_CAP_RES },
1386 { "ssl_sni", smp_fetch_ssl_sni, 0, NULL, SMP_T_CSTR, SMP_CAP_REQ|SMP_CAP_RES },
1387 { "ssl_verify_caerr", smp_fetch_verify_caerr, 0, NULL, SMP_T_UINT, SMP_CAP_REQ|SMP_CAP_RES },
1388 { "ssl_verify_caerr_depth", smp_fetch_verify_caerr_depth, 0, NULL, SMP_T_UINT, SMP_CAP_REQ|SMP_CAP_RES },
1389 { "ssl_verify_crterr", smp_fetch_verify_crterr, 0, NULL, SMP_T_UINT, SMP_CAP_REQ|SMP_CAP_RES },
1390 { "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 +02001391 { NULL, NULL, 0, 0, 0 },
1392}};
1393
1394/* Note: must not be declared <const> as its list will be overwritten.
1395 * Please take care of keeping this list alphabetically sorted.
1396 */
1397static struct acl_kw_list acl_kws = {{ },{
Emeric Brunf282a812012-09-21 15:27:54 +02001398 { "client_crt", acl_parse_int, smp_fetch_client_crt, acl_match_nothing, ACL_USE_L6REQ_PERMANENT|ACL_MAY_LOOKUP, 0 },
1399 { "is_ssl", acl_parse_int, smp_fetch_is_ssl, acl_match_nothing, ACL_USE_L6REQ_PERMANENT|ACL_MAY_LOOKUP, 0 },
1400 { "ssl_has_sni", acl_parse_int, smp_fetch_has_sni, acl_match_nothing, ACL_USE_L6REQ_PERMANENT, 0 },
1401 { "ssl_sni", acl_parse_str, smp_fetch_ssl_sni, acl_match_str, ACL_USE_L6REQ_PERMANENT|ACL_MAY_LOOKUP, 0 },
1402 { "ssl_sni_end", acl_parse_str, smp_fetch_ssl_sni, acl_match_end, ACL_USE_L6REQ_PERMANENT|ACL_MAY_LOOKUP, 0 },
1403 { "ssl_sni_reg", acl_parse_str, smp_fetch_ssl_sni, acl_match_reg, ACL_USE_L6REQ_PERMANENT|ACL_MAY_LOOKUP, 0 },
1404 { "ssl_verify_caerr", acl_parse_int, smp_fetch_verify_caerr, acl_match_int, ACL_USE_L6REQ_PERMANENT|ACL_MAY_LOOKUP, 0 },
1405 { "ssl_verify_caerr_depth", acl_parse_int, smp_fetch_verify_caerr_depth, acl_match_int, ACL_USE_L6REQ_PERMANENT|ACL_MAY_LOOKUP, 0 },
1406 { "ssl_verify_crterr", acl_parse_int, smp_fetch_verify_crterr, acl_match_int, ACL_USE_L6REQ_PERMANENT|ACL_MAY_LOOKUP, 0 },
1407 { "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 +02001408 { NULL, NULL, NULL, NULL },
1409}};
1410
Willy Tarreau79eeafa2012-09-14 07:53:05 +02001411/* Note: must not be declared <const> as its list will be overwritten.
1412 * Please take care of keeping this list alphabetically sorted, doing so helps
1413 * all code contributors.
1414 * Optional keywords are also declared with a NULL ->parse() function so that
1415 * the config parser can report an appropriate error when a known keyword was
1416 * not enabled.
1417 */
Willy Tarreau51fb7652012-09-18 18:24:39 +02001418static struct bind_kw_list bind_kws = { "SSL", { }, {
Emeric Brunfb510ea2012-10-05 12:00:26 +02001419 { "ca-file", bind_parse_ca_file, 1 }, /* set CAfile to process verify on client cert */
Emeric Brun2d0c4822012-10-02 13:45:20 +02001420 { "ca-ignore-err", bind_parse_ignore_err, 1 }, /* set error IDs to ignore on verify depth > 0 */
1421 { "ciphers", bind_parse_ciphers, 1 }, /* set SSL cipher suite */
Emeric Brunfb510ea2012-10-05 12:00:26 +02001422 { "crl-file", bind_parse_crl_file, 1 }, /* set certificat revocation list file use on client cert verify */
Emeric Brun2d0c4822012-10-02 13:45:20 +02001423 { "crt", bind_parse_crt, 1 }, /* load SSL certificates from this location */
1424 { "crt-ignore-err", bind_parse_ignore_err, 1 }, /* set error IDs to ingore on verify depth == 0 */
1425 { "ecdhe", bind_parse_ecdhe, 1 }, /* defines named curve for elliptic curve Diffie-Hellman */
Emeric Brun2cb7ae52012-10-05 14:14:21 +02001426 { "force-sslv3", bind_parse_force_sslv3, 0 }, /* force SSLv3 */
1427 { "force-tlsv10", bind_parse_force_tlsv10, 0 }, /* force TLSv10 */
1428 { "force-tlsv11", bind_parse_force_tlsv11, 0 }, /* force TLSv11 */
1429 { "force-tlsv12", bind_parse_force_tlsv12, 0 }, /* force TLSv12 */
Emeric Brun9b3009b2012-10-05 11:55:06 +02001430 { "no-sslv3", bind_parse_no_sslv3, 0 }, /* disable SSLv3 */
1431 { "no-tlsv10", bind_parse_no_tlsv10, 0 }, /* disable TLSv10 */
1432 { "no-tlsv11", bind_parse_no_tlsv11, 0 }, /* disable TLSv11 */
1433 { "no-tlsv12", bind_parse_no_tlsv12, 0 }, /* disable TLSv12 */
Emeric Brun2d0c4822012-10-02 13:45:20 +02001434 { "no-tls-tickets", bind_parse_no_tls_tickets, 0 }, /* disable session resumption tickets */
Emeric Brun2d0c4822012-10-02 13:45:20 +02001435 { "ssl", bind_parse_ssl, 0 }, /* enable SSL processing */
1436 { "verify", bind_parse_verify, 1 }, /* set SSL verify method */
Willy Tarreau79eeafa2012-09-14 07:53:05 +02001437 { NULL, NULL, 0 },
1438}};
Emeric Brun46591952012-05-18 15:47:34 +02001439
Willy Tarreauf7bc57c2012-10-03 00:19:48 +02001440/* transport-layer operations for SSL sockets */
1441struct xprt_ops ssl_sock = {
Emeric Brun46591952012-05-18 15:47:34 +02001442 .snd_buf = ssl_sock_from_buf,
1443 .rcv_buf = ssl_sock_to_buf,
1444 .rcv_pipe = NULL,
1445 .snd_pipe = NULL,
1446 .shutr = NULL,
1447 .shutw = ssl_sock_shutw,
1448 .close = ssl_sock_close,
1449 .init = ssl_sock_init,
1450};
1451
1452__attribute__((constructor))
1453static void __ssl_sock_init(void) {
1454 STACK_OF(SSL_COMP)* cm;
1455
1456 SSL_library_init();
1457 cm = SSL_COMP_get_compression_methods();
1458 sk_SSL_COMP_zero(cm);
Willy Tarreau7875d092012-09-10 08:20:03 +02001459 sample_register_fetches(&sample_fetch_keywords);
1460 acl_register_keywords(&acl_kws);
Willy Tarreau79eeafa2012-09-14 07:53:05 +02001461 bind_register_keywords(&bind_kws);
Emeric Brun46591952012-05-18 15:47:34 +02001462}
1463
1464/*
1465 * Local variables:
1466 * c-indent-level: 8
1467 * c-basic-offset: 8
1468 * End:
1469 */