This means that when loading certificates from a directory, it is highly
recommended to load the default one first as a file or to ensure that it will
always be the first one in the directory. In order to chose multiple default
- certificates (1 rsa and 1 ecdsa), there are 2 options:
+ certificates (1 rsa and 1 ecdsa), there are 3 options:
- A multi-cert bundle can be configured as the first certificate
(`crt foobar.pem` in the configuration where the existing files
are `foobar.pem.ecdsa` and `foobar.pem.rsa`.
- Or a '*' filter for each certificate in a crt-list line.
+ - The 'default-crt' keyword can be used.
Note that the same cert may be loaded multiple times without side effects.
default.pem.rsa *
default.pem.ecdsa *
+default-crt <cert>
+ This option does the same as the "crt" option, with the difference that this
+ certificate will be used as a default one. It is possible to add multiple
+ default certificates to have an ECDSA and an RSA one, having more is not
+ really useful.
+
+ A default certificate is used when no "strict-sni" option is used on the bind
+ line. A default certificate is provided when the servername extension was not
+ used by the client, or when the servername does not match any configured
+ certificate.
+
+ Example:
+
+ bind *:443 default-crt foobar.pem.rsa default-crt foobar.pem.ecdsa crt website.pem.rsa
+
+ See also the "crt" keyword.
+
defer-accept
Is an optional keyword which is supported only on certain Linux kernels. It
states that a connection will only be accepted once some data arrive on it,
#endif
struct issuer_chain* ssl_get0_issuer_chain(X509 *cert);
int ssl_load_global_issuer_from_BIO(BIO *in, char *fp, char **err);
-int ssl_sock_load_cert(char *path, struct bind_conf *bind_conf, char **err);
+int ssl_sock_load_cert(char *path, struct bind_conf *bind_conf, int is_default, char **err);
int ssl_sock_load_srv_cert(char *path, struct server *server, int create_if_none, char **err);
void ssl_free_global_issuers(void);
int ssl_initialize_random(void);
static int bind_parse_crt(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
{
char path[MAXPATHLEN];
+ int default_crt = *args[cur_arg] == 'd' ? 1 : 0;
if (!*args[cur_arg + 1]) {
memprintf(err, "'%s' : missing certificate location", args[cur_arg]);
memprintf(err, "'%s' : path too long", args[cur_arg]);
return ERR_ALERT | ERR_FATAL;
}
- return ssl_sock_load_cert(path, conf, err);
+ return ssl_sock_load_cert(path, conf, default_crt, err);
}
- return ssl_sock_load_cert(args[cur_arg + 1], conf, err);
+ return ssl_sock_load_cert(args[cur_arg + 1], conf, default_crt, err);
}
/* parse the "crt-list" bind keyword. Returns a set of ERR_* flags possibly with an error in <err>. */
{ "crt-ignore-err", bind_parse_ignore_err, 1 }, /* set error IDs to ignore on verify depth == 0 */
{ "crt-list", bind_parse_crt_list, 1 }, /* load a list of crt from this location */
{ "curves", bind_parse_curves, 1 }, /* set SSL curve suite */
+ { "default-crt", bind_parse_crt, 1 }, /* load SSL certificates from this location */
{ "ecdhe", bind_parse_ecdhe, 1 }, /* defines named curve for elliptic curve Diffie-Hellman */
{ "force-sslv3", bind_parse_tls_method_options, 0 }, /* force SSLv3 */
{ "force-tlsv10", bind_parse_tls_method_options, 0 }, /* force TLSv10 */
}
/* Returns a set of ERR_* flags possibly with an error in <err>. */
-int ssl_sock_load_cert(char *path, struct bind_conf *bind_conf, char **err)
+int ssl_sock_load_cert(char *path, struct bind_conf *bind_conf, int is_default, char **err)
{
struct stat buf;
int cfgerr = 0;
struct ckch_store *ckchs;
struct ckch_inst *ckch_inst = NULL;
int found = 0; /* did we found a file to load ? */
- int is_default = 0;
/* if the SNI trees were empty the first "crt" become a default certificate,
* it can be applied on multiple certificates if it's a bundle */
- if (eb_is_empty(&bind_conf->sni_ctx) && eb_is_empty(&bind_conf->sni_w_ctx))
- is_default = 1;
+ if (is_default == 0) {
+ if (eb_is_empty(&bind_conf->sni_ctx) && eb_is_empty(&bind_conf->sni_w_ctx))
+ is_default = 1;
+ }
if ((ckchs = ckchs_lookup(path))) {
/* we found the ckchs in the tree, we can use it directly */