551 Commits

Author SHA1 Message Date
Emmanuel Hocdet
e38047423d MINOR: ssl: improved cipherlist captures
Alloc capture buffer later (when filling), parse client-hello after
heartbeat check and remove capture->conn (unused).
2017-03-08 15:04:43 +01:00
Emmanuel Hocdet
aaee75088a BUG/MINOR: ssl: fix cipherlist captures with sustainable SSL calls
Use SSL_set_ex_data/SSL_get_ex_data standard API call to store capture.
We need to avoid internal structures/undocumented calls usage to try to
control the beast and limit painful compatibilities.
2017-03-08 15:04:25 +01:00
Emmanuel Hocdet
f6b37c67be BUG/MEDIUM: ssl: in bind line, ssl-options after 'crt' are ignored.
Bug introduced with "removes SSL_CTX_set_ssl_version call and cleanup CTX
creation": ssl_sock_new_ctx is called before all the bind line is parsed.
The fix consists of separating the use of default_ctx as the initialization
context of the SSL connection via bind_conf->initial_ctx. Initial_ctx contains
all the necessary parameters before performing the selection of the CTX:
default_ctx is processed as others ctx without unnecessary parameters.
2017-03-07 10:42:43 +01:00
Emmanuel Hocdet
4608ed9511 MEDIUM: ssl: remove ssl-options from crt-list
ssl-options are link to the initial negotiation environnement worn
by default_ctx.
Remove it from crt-list to avoid any confusion.
2017-03-07 10:33:16 +01:00
Thierry FOURNIER
5bf77329b6 MEDIUM: ssl: add new sample-fetch which captures the cipherlist
This new sample-fetches captures the cipher list offer by the client
SSL connection during the client-hello phase. This is useful for
fingerprint the SSL connection.
2017-03-06 21:40:23 +01:00
Emmanuel Hocdet
cc6c2a2cb7 BUILD: ssl: fix build with -DOPENSSL_NO_DH 2017-03-06 10:20:28 +01:00
Emmanuel Hocdet
4de1ff1fd6 MINOR: ssl: removes SSL_CTX_set_ssl_version call and cleanup CTX creation.
BoringSSL doesn't support SSL_CTX_set_ssl_version. To remove this call, the
CTX creation is cleanup to clarify what is happening. SSL_CTX_new is used to
match the original behavior, in order: force-<method> according the method
version then the default method with no-<method> options.
OPENSSL_NO_SSL3 error message is now in force-sslv3 parsing (as force-tls*).
For CTX creation in bind environement, all CTX set related to the initial ctx
are aggregate to ssl_sock_new_ctx function for clarity.

Tests with crt-list have shown that server_method, options and mode are
linked to the initial CTX (default_ctx): all ssl-options are link to each
bind line and must be removed from crt-list.
2017-03-06 10:20:20 +01:00
Emmanuel Hocdet
d385060393 BUG/MEDIUM: ssl: switchctx should not return SSL_TLSEXT_ERR_ALERT_WARNING
Extract from RFC 6066:
"If the server understood the ClientHello extension but does not recognize
the server name, the server SHOULD take one of two actions: either abort the
handshake by sending a fatal-level unrecognized_name(112) alert or continue the
handshake. It is NOT RECOMMENDED to send a warning-level unrecognized_name(112)
alert, because the client's behavior in response to warning-level alerts is
unpredictable. If there is a mismatch between the server name used by the
client application and the server name of the credential chosen by the server,
this mismatch will become apparent when the client application performs the
server endpoint identification, at which point the client application will have
to decide whether to proceed with the communication."

Thanks Roberto Guimaraes for the bug repport, spotted with openssl-1.1.0.
This fix must be backported.
2017-03-06 10:10:49 +01:00
Emmanuel Hocdet
530141f747 BUG/MEDIUM: ssl: fix verify/ca-file per certificate
SSL verify and client_CA inherits from the initial ctx (default_ctx).
When a certificate is found, the SSL connection environment must be replaced by
the certificate configuration (via SSL_set_verify and SSL_set_client_CA_list).
2017-03-02 18:31:51 +01:00
Emmanuel Hocdet
0594211987 MEDIUM: boringssl: support native multi-cert selection without bundling
This patch used boringssl's callback to analyse CLientHello before any
handshake to extract key signature capabilities.
Certificat with better signature (ECDSA before RSA) is choosed
transparenty, if client can support it. RSA and ECDSA certificates can
be declare in a row (without order). This makes it possible to set
different ssl and filter parameter with crt-list.
2017-03-02 18:31:05 +01:00
Willy Tarreau
e3cc3a3026 BUG/MAJOR: ssl: fix a regression in ssl_sock_shutw()
Commit 405ff31 ("BUG/MINOR: ssl: assert on SSL_set_shutdown with BoringSSL")
introduced a regression causing some random crashes apparently due to
memory corruption. The issue is the use of SSL_CTX_set_quiet_shutdown()
instead of SSL_set_quiet_shutdown(), making it use a different structure
and causing the flag to be put who-knows-where.

Many thanks to Jarno Huuskonen who reported this bug early and who
bisected the issue to spot this patch. No backport is needed, this
is 1.8-specific.
2017-02-13 11:15:13 +01:00
Willy Tarreau
e3e326d9f0 BUILD: ssl: kill a build warning introduced by BoringSSL compatibility
A recent patch to support BoringSSL caused this warning to appear on
OpenSSL 1.1.0 :
   src/ssl_sock.c:3062:4: warning: statement with no effect [-Wunused-value]

It's caused by SSL_CTX_set_ecdh_auto() which is now only a macro testing
that the last argument is zero, and the result is not used here. Let's
just kill it for both versions.

Tested with 0.9.8, 1.0.0, 1.0.1, 1.0.2, 1.1.0. This fix may be backported
to 1.7 if the boringssl fix is as well.
2017-01-19 17:56:20 +01:00
Emmanuel Hocdet
fdec7897fd BUILD: ssl: fix to build (again) with boringssl
Limitations:
. disable force-ssl/tls (need more work)
should be set earlier with SSL_CTX_new (SSL_CTX_set_ssl_version is removed)
. disable generate-certificates (need more work)
introduce SSL_NO_GENERATE_CERTIFICATES to disable generate-certificates.

Cleanup some #ifdef and type related to boringssl env.
2017-01-16 12:40:35 +01:00
Emmanuel Hocdet
e7f2b7301c MINOR: ssl: add curve suite for ECDHE negotiation
Add 'curves' parameter on 'bind' and for 'crt-list' to set curve suite.
(ex: curves X25519:P-256)
2017-01-13 11:41:01 +01:00
Emmanuel Hocdet
98263291cc MAJOR: ssl: bind configuration per certificat
crt-list is extend to support ssl configuration. You can now have
such line in crt-list <file>:
mycert.pem [npn h2,http/1.1]

Support include "npn", "alpn", "verify", "ca_file", "crl_file",
"ecdhe", "ciphers" configuration and ssl options.

"crt-base" is also supported to fetch certificates.
2017-01-13 11:40:34 +01:00
Lukas Tribus
3eb5b3fdd3 MINOR: ssl: don't show prefer-server-ciphers output
The output of whether prefer-server-ciphers is supported by OpenSSL
actually always show yes in 1.8, because SSL_OP_CIPHER_SERVER_PREFERENCE
is redefined before the actual check in src/ssl_sock.c, since it was
moved from here from src/haproxy.c.

Since this is not really relevant anymore as we don't support OpenSSL
< 0.9.7 anyway, this change just removes this output.
2017-01-12 07:45:45 +01:00
Emmanuel Hocdet
405ff31e31 BUG/MINOR: ssl: assert on SSL_set_shutdown with BoringSSL
With BoringSSL:
SSL_set_shutdown: Assertion `(SSL_get_shutdown(ssl) & mode) == SSL_get_shutdown(ssl)' failed.

"SSL_set_shutdown causes ssl to behave as if the shutdown bitmask (see SSL_get_shutdown)
were mode. This may be used to skip sending or receiving close_notify in SSL_shutdown by
causing the implementation to believe the events already happened.
It is an error to use SSL_set_shutdown to unset a bit that has already been set.
Doing so will trigger an assert in debug builds and otherwise be ignored.
Use SSL_CTX_set_quiet_shutdown instead."

Change logic to not notify on SSL_shutdown when connection is not clean.
2017-01-11 12:44:40 +01:00
Emmanuel Hocdet
b7a4c34aac BUG/MINOR: ssl: EVP_PKEY must be freed after X509_get_pubkey usage
"X509_get_pubkey() attempts to decode the public key for certificate x.
If successful it returns the public key as an EVP_PKEY pointer with its
reference count incremented: this means the returned key must be freed
up after use."
2017-01-11 12:44:40 +01:00
Willy Tarreau
119a4084bf BUG/MEDIUM: ssl: for a handshake when server-side SNI changes
Calling SSL_set_tlsext_host_name() on the current SSL ctx has no effect
if the session is being resumed because the hostname is already stored
in the session and is not advertised again in subsequent connections.
It's visible when enabling SNI and health checks at the same time because
checks do not send an SNI and regular traffic reuses the same connection,
resulting in no SNI being sent.

The only short-term solution is to reset the reused session when the
SNI changes compared to the previous one. It can make the server-side
performance suffer when SNIs are interleaved but it will work. A better
long-term solution would be to keep a small cache of a few contexts for
a few SNIs.

Now with SSL_set_session(ctx, NULL) it works. This needs to be double-
checked though. The man says that SSL_set_session() frees any previously
existing context. Some people report a bit of breakage when calling
SSL_set_session(NULL) on openssl 1.1.0a (freed session not reusable at
all though it's not an issue for now).

This needs to be backported to 1.7 and 1.6.
2016-12-23 16:21:40 +01:00
Willy Tarreau
ef934603c0 CLEANUP: ssl: move most ssl-specific global settings to ssl_sock.c
Historically a lot of SSL global settings were stored into the global
struct, but we've reached a point where there are 3 ifdefs in it just
for this, and others in haproxy.c to initialize it.

This patch moves all the private fields to a new struct "global_ssl"
stored in ssl_sock.c. This includes :

       char *crt_base;
       char *ca_base;
       char *listen_default_ciphers;
       char *connect_default_ciphers;
       int listen_default_ssloptions;
       int connect_default_ssloptions;
       int tune.sslprivatecache; /* Force to use a private session cache even if nbproc > 1 */
       unsigned int tune.ssllifetime;   /* SSL session lifetime in seconds */
       unsigned int tune.ssl_max_record; /* SSL max record size */
       unsigned int tune.ssl_default_dh_param; /* SSL maximum DH parameter size */
       int tune.ssl_ctx_cache; /* max number of entries in the ssl_ctx cache. */

The "tune" part was removed (useless here) and the occasional "ssl"
prefixes were removed as well. Thus for example instead of

       global.tune.ssl_default_dh_param

we now have :

       global_ssl.default_dh_param

A few initializers were present in the constructor, they could be brought
back to the structure declaration.

A few other entries had to stay in global for now. They concern memory
calculationn (used in haproxy.c) and stats (used in stats.c).

The code is already much cleaner now, especially for global.h and haproxy.c
which become readable.
2016-12-22 23:26:38 +01:00
Willy Tarreau
d1c5750370 CLEANUP: ssl: move tlskeys_finalize_config() to a post_check callback
tlskeys_finalize_config() was the only reason for haproxy.c to still
require ifdef and includes for ssl_sock. This one fits perfectly well
in the late initializers so it was changed to be registered with
hap_register_post_check().
2016-12-22 23:26:38 +01:00
Willy Tarreau
17d4538044 MINOR: ssl_sock: implement and use prepare_srv()/destroy_srv()
Now we can simply check the transport layer at run time and decide
whether or not to initialize or destroy these entries. This removes
other ifdefs and includes from cfgparse.c, haproxy.c and hlua.c.
2016-12-22 23:26:38 +01:00
Willy Tarreau
d9f5cca3d5 CLEANUP: connection: unexport raw_sock and ssl_sock
This way we're sure not to reuse them by accident.
2016-12-22 23:26:38 +01:00
Willy Tarreau
13e1410f8a MINOR: connection: add a minimal transport layer registration system
There are still a lot of #ifdef USE_OPENSSL in the code (still 43
occurences) because we never know if we can directly access ssl_sock
or not. This patch attacks the problem differently by providing a
way for transport layers to register themselves and for users to
retrieve the pointer. Unregistered transport layers will point to NULL
so it will be easy to check if SSL is registered or not. The mechanism
is very inexpensive as it relies on a two-entries array of pointers,
so the performance will not be affected.
2016-12-22 23:26:38 +01:00
Willy Tarreau
795cdabb57 MINOR: ssl_sock: implement ssl_sock_destroy_bind_conf()
Instead of hard-coding all SSL destruction in cfgparse.c and haproxy.c,
we now register this new function as the transport layer's destroy_bind_conf()
and call it only when defined. This removes some non-obvious SSL-specific
code and #ifdefs from cfgparse.c and haproxy.c
2016-12-22 23:26:38 +01:00
Willy Tarreau
55d3791b46 MEDIUM: ssl_sock: implement ssl_sock_prepare_bind_conf()
Instead of hard-coding all SSL preparation in cfgparse.c, we now register
this new function as the transport layer's prepare_bind_conf() and call it
only when definied. This removes some non-obvious SSL-specific code from
cfgparse.c as well as a #ifdef.
2016-12-22 23:26:38 +01:00
Willy Tarreau
0320934f7e MEDIUM: ssl: remote the proxy argument from most functions
Most of the SSL functions used to have a proxy argument which was mostly
used to be able to emit clean errors using Alert(). First, many of them
were converted to memprintf() and don't require this pointer anymore.
Second, the rare which still need it also have either a bind_conf argument
or a server argument, both of which carry a pointer to the relevant proxy.

So let's now get rid of it, it needlessly complicates the API and certain
functions already have many arguments.
2016-12-22 23:26:38 +01:00
Willy Tarreau
71a8c7c49e MINOR: listener: move the transport layer pointer to the bind_conf
A mistake was made when the socket layer was cut into proto and
transport, the transport was attached to the listener while all
listeners in a single "bind" line always have exactly the same
transport. It doesn't seem obvious but this is the reason why there
are so many #ifdefs USE_OPENSSL in cfgparse : a lot of operations
have to be open-coded because cfgparse only manipulates bind_conf
and we don't have the information of the transport layer here.

Very little code makes use of the transport layer, mainly session
setup and log. These places can afford an extra pointer indirection
(the listener points to the bind_conf). This change is thus very small,
it saves a little bit of memory (8B per listener) and makes the code
more flexible.
2016-12-22 23:26:37 +01:00
Willy Tarreau
94ff03af84 BUG/MEDIUM: ssl: avoid double free when releasing bind_confs
ssl_sock functions don't mark pointers as NULL after freeing them. So
if a "bind" line specifies some SSL settings without the "ssl" keyword,
they will get freed at the end of check_config_validity(), then freed
a second time on exit. Simply mark the pointers as NULL to fix this.
This fix needs to be backported to 1.7 and 1.6.
2016-12-22 22:07:36 +01:00
Willy Tarreau
30fd4bd844 BUG/MEDIUM: ssl: properly reset the reused_sess during a forced handshake
We have a bug when SSL reuse is disabled on the server side : we reset
the context but do not set it to NULL, causing a multiple free of the
same entry. It seems like this bug cannot appear as-is with the current
code (or the conditions to get it are not obvious) but it did definitely
strike when trying to fix another bug with the SNI which forced a new
handshake.

This fix should be backported to 1.7, 1.6 and 1.5.
2016-12-22 21:54:21 +01:00
Willy Tarreau
14e36a101c MEDIUM: cfgparse: move ssl-dh-param-file parsing to ssl_sock
This one was missing an arg count check which was added in the operation.
2016-12-21 23:39:26 +01:00
Willy Tarreau
f22e9683e9 MINOR: cfgparse: move parsing of ssl-default-{bind,server}-ciphers to ssl_sock
These ones are pretty similar, just an strdup. Contrary to ca-base
and crt-base they support being changed.
2016-12-21 23:39:26 +01:00
Willy Tarreau
0bea58d641 MEDIUM: cfgparse: move maxsslconn parsing to ssl_sock
This one simply reuses the existing integer parser. It implicitly
adds a control against negative numbers.
2016-12-21 23:39:26 +01:00
Willy Tarreau
9ceda384e9 MEDIUM: cfgparse: move all tune.ssl.* keywords to ssl_sock
The following keywords were still parsed in cfgparse and were moved
to ssl_sock to remove some #ifdefs :

"tune.ssl.cachesize", "tune.ssl.default-dh-param", "tune.ssl.force-private-cache",
"tune.ssl.lifetime", "tune.ssl.maxrecord", "tune.ssl.ssl-ctx-cache-size".

It's worth mentionning that some of them used to have incorrect sign
checks possibly resulting in some negative values being used. All of
them are now checked for being positive.
2016-12-21 23:39:26 +01:00
Willy Tarreau
8c3b0fd273 MINOR: cfgparse: move parsing of "ca-base" and "crt-base" to ssl_sock
This removes 2 #ifdefs and makes the code much cleaner. The controls
are still there and the two parsers have been merged into a single
function ssl_parse_global_ca_crt_base().

It's worth noting that there's still a check to prevent a change when
the value was already specified. This test seems useless and possibly
counter-productive, it may have to be revisited later, but for now it
was implemented identically.
2016-12-21 23:39:26 +01:00
Willy Tarreau
c2c0b61274 CLEANUP: ssl: use the build options list to report the SSL details
This removes 7 #ifdef from haproxy.c. The message indicating that
openssl is *not* enabled is not there anymore.
2016-12-21 21:30:54 +01:00
Willy Tarreau
f5f26e824a MINOR: appctx/cli: remove the "tlskeys" entry from the appctx union
This one now migrates to the general purpose cli.p0 for the ref pointer,
cli.i0 for the dump_all flag and cli.i1 for the dump_keys_index. A few
comments were added.

The applet.h file doesn't depend on openssl anymore. It's worth noting
that the previous dependency was accidental and only used to work because
all files including this one used to have openssl included prior to
loading this file.
2016-12-16 19:40:14 +01:00
Luca Pizzamiglio
578b169dcb BUILD/MEDIUM: Fixing the build using LibreSSL
Fixing the build using LibreSSL as OpenSSL implementation.
Currently, LibreSSL 2.4.4 provides the same API of OpenSSL 1.0.1x,
but it redefine the OpenSSL version number as 2.0.x, breaking all
checks with OpenSSL 1.1.x.
The patch solves the issue checking the definition of the symbol
LIBRESSL_VERSION_NUMBER when Openssl 1.1.x features are requested.
2016-12-12 22:57:04 +01:00
Willy Tarreau
3067bfa815 BUG/MEDIUM: cli: fix "show stat resolvers" and "show tls-keys"
The recent CLI reorganization managed to break these two commands
by having their parser return 1 (indicating an end of processing)
instead of 0 to indicate new calls to the io handler were needed.

Namely the faulty commits are :
  69e9644 ("REORG: cli: move show stat resolvers to dns.c")
  32af203 ("REORG: cli: move ssl CLI functions to ssl_sock.c")

The fix is trivial and there is no other loss of functionality. Thanks
to Dragan Dosen for reporting the issue and the faulty commits. The
backport is needed in 1.7.
2016-12-05 14:53:37 +01:00
Willy Tarreau
30e5e18bbb CLEANUP: cli: remove assignments to st0 and st2 in keyword parsers
Now it's not needed anymore to set STAT_ST_INIT nor CLI_ST_CALLBACK
in the parsers, remove it in the various places.
2016-11-24 16:59:28 +01:00
Willy Tarreau
3b6e547be8 CLEANUP: cli: rename STAT_CLI_* to CLI_ST_*
These are in CLI states, not stats states anymore. STAT_CLI_O_CUSTOM
was more appropriately renamed CLI_ST_CALLBACK.
2016-11-24 16:59:28 +01:00
William Lallemand
32af203b75 REORG: cli: move ssl CLI functions to ssl_sock.c
Move ssl CLI functions to ssl_sock.c and use the cli keyword API to
register ssl actions on the CLI.
2016-11-24 16:59:27 +01:00
Willy Tarreau
8e0bb0ae16 MINOR: connection: add names for transport and data layers
This makes debugging easier and avoids having to put ugly checks
against certain well-known internal struct pointers.
2016-11-24 16:58:12 +01:00
Bertrand Jacquin
ff13c06a17 CLEANUP: ssl: Fix bind keywords name in comments
Along with a whitespace cleanup and a grammar typo
2016-11-14 18:15:20 +01:00
Bertrand Jacquin
5424ee08de BUG/MINOR: ssl: Print correct filename when error occurs reading OCSP
When Multi-Cert bundle are used, error is throwned regarding certificate
filename without including certifcate type extension.
2016-11-14 18:15:20 +01:00
Bertrand Jacquin
3342309572 BUG/MEDIUM: ssl: Store certificate filename in a variable
Before this change, trash is being used to create certificate filename
to read in care Mutli-Cert are in used. But then ssl_sock_load_ocsp()
modify trash leading to potential wrong information given in later error
message.

This also blocks any further use of certificate filename for other
usage, like ongoing patch to support Certificate Transparency handling
in Multi-Cert bundle.
2016-11-14 18:15:20 +01:00
Dirkjan Bussink
1866d6d8f1 MEDIUM: ssl: Add support for OpenSSL 1.1.0
In the last release a lot of the structures have become opaque for an
end user. This means the code using these needs to be changed to use the
proper functions to interact with these structures instead of trying to
manipulate them directly.

This does not fix any deprecations yet that are part of 1.1.0, it only
ensures that it can be compiled against that version and is still
compatible with older ones.

[wt: openssl-0.9.8 doesn't build with it, there are conflicts on certain
     function prototypes which we declare as inline here and which are
     defined differently there. But openssl-0.9.8 is not supported anymore
     so probably it's OK to go without it for now and we'll see later if
     some users still need it. Emeric has reviewed this change and didn't
     spot anything obvious which requires special care. Let's try it for
     real now]
2016-11-08 20:54:41 +01:00
Thierry FOURNIER / OZON.IO
07c3d78c2c BUG/MINOR: ssl: prevent multiple entries for the same certificate
Today, the certificate are indexed int he SNI tree using their CN and the
list of thier AltNames. So, Some certificates have the same names in the
CN and one of the AltNames entries.

Typically Let's Encrypt duplicate the the DNS name in the CN and the
AltName.

This patch prevents the creation of identical entries in the trees. It
checks the same DNS name and the same SSL context.

If the same certificate is registered two time it will be duplicated.

This patch should be backported in the 1.6 and 1.5 version.
2016-10-24 19:13:12 +02:00
Thierry FOURNIER / OZON.IO
7a3bd3b9dc BUG/MINOR: ssl: Check malloc return code
If malloc() can't allocate memory and return NULL, a segfaut will raises.

This patch should be backported in the 1.6 and 1.5 version.
2016-10-24 19:13:12 +02:00
Thierry FOURNIER / OZON.IO
d44ea3f77c BUILD/CLEANUP: ssl: Check BIO_reset() return code
The BIO_reset function can fails, and the error is not processed.
This patch just take in account the return code of the BIO_reset()
function.
2016-10-24 19:13:12 +02:00