1259 Commits

Author SHA1 Message Date
Emmanuel Hocdet
4fed93eb72 MINOR: ssl: rework add cert chain to CTX to be libssl independent
SSL_CTX_set1_chain is used for openssl >= 1.0.2 and a loop with
SSL_CTX_add_extra_chain_cert for openssl < 1.0.2.
SSL_CTX_add_extra_chain_cert exist with openssl >= 1.0.2 and can be
used for all openssl version (is new name is SSL_CTX_add0_chain_cert).
This patch use SSL_CTX_add_extra_chain_cert to remove any #ifdef for
compatibilty. In addition sk_X509_num()/sk_X509_value() replace
sk_X509_shift() to extract CA from chain, as it is used in others part
of the code.
2020-03-24 14:46:01 +01:00
Emmanuel Hocdet
ef87e0a3da CLEANUP: ssl: rename ssl_get_issuer_chain to ssl_get0_issuer_chain
Rename ssl_get_issuer_chain to ssl_get0_issuer_chain to be consistent
with openssl >= 1.0.2 API.
2020-03-23 15:35:39 +01:00
Emmanuel Hocdet
f4f14eacd3 BUG/MINOR: ssl: memory leak when find_chain is NULL
This bug was introduced by 85888573 "BUG/MEDIUM: ssl: chain must be
initialized with sk_X509_new_null()". No need to set find_chain with
sk_X509_new_null(), use find_chain conditionally to fix issue #516.

This bug was referenced by issue #559.

[wla: fix some alignment/indentation issue]
2020-03-23 13:10:10 +01:00
William Lallemand
18eeb8e815 BUG/MINOR: ssl/cli: fix a potential NULL dereference
Fix a potential NULL dereference in "show ssl cert" when we can't
allocate the <out> trash buffer.

This patch creates a new label so we could jump without trying to do the
ci_putchk in this case.

This bug was introduced by ea987ed ("MINOR: ssl/cli: 'new ssl cert'
command"). 2.2 only.

This bug was referenced by issue #556.
2020-03-20 14:49:25 +01:00
William Lallemand
67b991d370 BUG/MINOR: ssl/cli: free BIO upon error in 'show ssl cert'
Fix a memory leak that could happen upon a "show ssl cert" if notBefore:
or notAfter: failed to extract its ASN1 string.

Introduced by d4f946c ("MINOR: ssl/cli: 'show ssl cert' give information
on the certificates"). 2.2 only.
2020-03-20 14:22:35 +01:00
William Lallemand
3c516fc989 BUG/MINOR: ssl: crtlist_dup_filters() must return NULL with fcount == 0
crtlist_dup_filters() must return a NULL ptr if the fcount number is 0.

This bug was introduced by 2954c47 ("MEDIUM: ssl: allow crt-list caching").
2020-03-20 10:10:25 +01:00
Tim Duesterhus
2445f8d4ec BUG/MINOR: ssl: Correctly add the 1 for the sentinel to the number of elements
In `crtlist_dup_filters()` add the `1` to the number of elements instead of
the size of a single element.

This bug was introduced in commit 2954c478ebab019b814b97cbaec4653af7f03f34,
which is 2.2+. No backport needed.
2020-03-20 09:43:53 +01:00
Tim Duesterhus
8c12025a7d BUG/MINOR: ssl: Do not free garbage pointers on memory allocation failure
In `ckch_inst_sni_ctx_to_sni_filters` use `calloc()` to allocate the filter
array. When the function fails to allocate memory for a single entry the
whole array will be `free()`d using free_sni_filters(). With the previous
`malloc()` the pointers for entries after the failing allocation could
possibly be a garbage value.

This bug was introduced in commit 38df1c8006a2adf97f4ad5a183f80cfdcba3da8a,
which is 2.2+. No backport needed.
2020-03-20 09:36:20 +01:00
William Lallemand
59c16fc2cb MINOR: ssl/cli: show certificate status in 'show ssl cert'
Display the status of the certificate in 'show ssl cert'.

Example:

  Status: Empty
  Status: Unused
  Status: Used
2020-03-19 20:36:13 +01:00
William Lallemand
ea987ed78a MINOR: ssl/cli: 'new ssl cert' command
The CLI command "new ssl cert" allows one to create a new certificate
store in memory. It can be filed with "set ssl cert" and "commit ssl
cert".

This patch also made a small change in "show ssl cert" to handle an
empty certificate store.

Multi-certificate bundles are not supported since they will probably be
removed soon.

This feature alone is useless since there is no way to associate the
store to a crt-list yet.

Example:

  $ echo "new ssl cert foobar.pem" | socat /tmp/sock1 -
  New empty certificate store 'foobar.pem'!
  $ printf "set ssl cert foobar.pem <<\n$(cat localhost.pem.rsa)\n\n" | socat /tmp/sock1 -
  Transaction created for certificate foobar.pem!
  $ echo "commit ssl cert foobar.pem" | socat /tmp/sock1 -
  Committing foobar.pem
  Success!
  $ echo "show ssl cert foobar.pem" | socat /tmp/sock1 -
  Filename: foobar.pem
  [...]
2020-03-19 17:44:41 +01:00
William Lallemand
a64593c80d BUG/MINOR: ssl: memleak of struct crtlist_entry
There is a memleak of the entry structure in crtlist_load_cert_dir(), in
the case we can't stat the file, or this is not a regular file. Let's
move the entry allocation so it's done after these tests.

Fix issue #551.
2020-03-17 20:28:06 +01:00
William Lallemand
909086ea61 BUG/MINOR: ssl: memory leak in crtlist_parse_file()
A memory leak happens in an error case when ckchs_load_cert_file()
returns NULL in crtlist_parse_file().

This bug was introduced by commit 2954c47 ("MEDIUM: ssl: allow crt-list caching")

This patch fixes bug #551.
2020-03-17 16:57:34 +01:00
William Lallemand
2ea1b49832 BUG/MINOR: ssl/cli: free the trash chunk in dump_crtlist
Free the trash chunk after dumping the crt-lists.

Introduced by a6ffd5b ("MINOR: ssl/cli: show/dump ssl crt-list").
2020-03-17 15:30:05 +01:00
William Lallemand
a6ffd5bf8a MINOR: ssl/cli: show/dump ssl crt-list
Implement 2 new commands on the CLI:

show ssl crt-list [<filename>]: Without a specified filename, display
the list of crt-lists used by the configuration. If a filename is
specified, it will displays the content of this crt-list, with a line
identifier at the beginning of each line. This output must not be used
as a crt-list file.

dump ssl crt-list <filename>: Dump the content of a crt-list, the output
can be used as a crt-list file.

Note: It currently displays the default ssl-min-ver and ssl-max-ver
which are potentialy not in the original file.
2020-03-17 14:59:37 +01:00
William Lallemand
83918e2ef1 BUG/MINOR: ssl: can't open directories anymore
The commit 6be66ec ("MINOR: ssl: directories are loaded like crt-list")
broke the directory loading of the certificates. The <crtlist> wasn't
filled by the crtlist_load_cert_dir() function. And the entries were
not correctly initialized. Leading to a segfault during startup.
2020-03-16 17:29:10 +01:00
William Lallemand
6be66ec7a9 MINOR: ssl: directories are loaded like crt-list
Generate a directory cache with the crtlist and crtlist_entry structures.

With this new model, directories are a special case of the crt-lists.
A directory is a crt-list which allows only one occurence of each file,
without SSL configuration (ssl_bind_conf) and without filters.
2020-03-16 16:23:44 +01:00
William Lallemand
2954c478eb MEDIUM: ssl: allow crt-list caching
The crtlist structure defines a crt-list in the HAProxy configuration.
It contains crtlist_entry structures which are the lines in a crt-list
file.

crt-list are now loaded in memory using crtlist and crtlist_entry
structures. The file is read only once. The generation algorithm changed
a little bit, new ckch instances are generated from the crtlist
structures, instead of being generated during the file loading.

The loading function was split in two, one that loads and caches the
crt-list and certificates, and one that looks for a crt-list and creates
the ckch instances.

Filters are also stored in crtlist_entry->filters as a char ** so we can
generate the sni_ctx again if needed. I won't be needed anymore to parse
the sni_ctx to do that.

A crtlist_entry stores the list of all ckch_inst that were generated
from this entry.
2020-03-16 16:18:49 +01:00
William Lallemand
24bde43eab MINOR: ssl: pass ckch_inst to ssl_sock_load_ckchs()
Pass a pointer to the struct ckch_inst to the ssl_sock_load_ckchs()
function so we can manipulate the ckch_inst from
ssl_sock_load_cert_list_file() and ssl_sock_load_cert().
2020-03-16 16:18:49 +01:00
William Lallemand
06b22a8fba REORG: ssl: move ssl_sock_load_cert()
Move the ssl_sock_load_cert() at the right place.
2020-03-16 16:18:49 +01:00
Ilya Shipitsin
77e3b4a2c4 CLEANUP: assorted typo fixes in the code and comments
These are mostly comments in the code. A few error messages were fixed
and are of low enough importance not to deserve a backport. Some regtests
were also fixed.
2020-03-14 09:42:07 +01:00
William Lallemand
2d232c2131 CLEANUP: ssl: separate the directory loading in a new function
In order to store and cache the directory loading, the directory loading
was separated from ssl_sock_load_cert() and put in a new function
ssl_sock_load_cert_dir() to be more readable.

This patch only splits the function in two.
2020-03-10 15:55:22 +01:00
William Lallemand
6763016866 BUG/MINOR: ssl/cli: sni_ctx' mustn't always be used as filters
Since commit 244b070 ("MINOR: ssl/cli: support crt-list filters"),
HAProxy generates a list of filters based on the sni_ctx in memory.
However it's not always relevant, sometimes no filters were configured
and the CN/SAN in the new certificate are not the same.

This patch fixes the issue by using a flag filters in the ckch_inst, so
we are able to know if there were filters or not. In the late case it
uses the CN/SAN of the new certificate to generate the sni_ctx.

note: filters are still only used in the crt-list atm.
2020-03-09 17:32:04 +01:00
Willy Tarreau
d04a2a6654 BUG/MINOR: ssl-sock: do not return an uninitialized pointer in ckch_inst_sni_ctx_to_sni_filters
There's a build error reported here:
   c9c6cdbf9c/checks

It's just caused by an inconditional assignment of tmp_filter to
*sni_filter without having been initialized, though it's harmless because
this return pointer is not used when fcount is NULL, which is the only
case where this happens.

No backport is needed as this was brought today by commit 38df1c8006
("MINOR: ssl/cli: support crt-list filters").
2020-03-05 16:26:12 +01:00
William Lallemand
cfca1422c7 MINOR: ssl: reach a ckch_store from a sni_ctx
It was only possible to go down from the ckch_store to the sni_ctx but
not to go up from the sni_ctx to the ckch_store.

To allow that, 2 pointers were added:

- a ckch_inst pointer in the struct sni_ctx
- a ckckh_store pointer in the struct ckch_inst
2020-03-05 11:28:42 +01:00
William Lallemand
38df1c8006 MINOR: ssl/cli: support crt-list filters
Generate a list of the previous filters when updating a certificate
which use filters in crt-list. Then pass this list to the function
generating the sni_ctx during the commit.

This feature allows the update of the crt-list certificates which uses
the filters with "set ssl cert".

This function could be probably replaced by creating a new
ckch_inst_new_load_store() function which take the previous sni_ctx list as
an argument instead of the char **sni_filter, avoiding the
allocation/copy during runtime for each filter. But since are still
handling the multi-cert bundles, it's better this way to avoid code
duplication.
2020-03-05 11:27:53 +01:00
Willy Tarreau
f4629a5346 BUG/MINOR: connection/debug: do not enforce !event_type on subscribe() anymore
When building with DEBUG_STRICT, there are still some BUG_ON(events&event_type)
in the subscribe() code which are not welcome anymore since we explicitly
permit to wake the caller up on readiness. This causes some regtests to fail
since 2c1f37d353 ("OPTIM: mux-h1: subscribe rather than waking up at a few
other places") when built with this option.

No backport is needed, this is 2.2-dev.
2020-03-05 07:46:33 +01:00
Emmanuel Hocdet
842e94ee06 MINOR: ssl: add "ca-verify-file" directive
It's only available for bind line. "ca-verify-file" allows to separate
CA certificates from "ca-file". CA names sent in server hello message is
only compute from "ca-file". Typically, "ca-file" must be defined with
intermediate certificates and "ca-verify-file" with certificates to
ending the chain, like root CA.

Fix issue #404.
2020-03-04 11:53:11 +01:00
William Lallemand
858885737c BUG/MEDIUM: ssl: chain must be initialized with sk_X509_new_null()
Even when there isn't a chain, it must be initialized to a empty X509
structure with sk_X509_new_null().

This patch fixes a segfault which appears with older versions of the SSL
libs (openssl 0.9.8, libressl 2.8.3...) because X509_chain_up_ref() does
not check the pointer.

This bug was introduced by b90d2cb ("MINOR: ssl: resolve issuers chain
later").

Should fix issue #516.
2020-02-27 14:48:35 +01:00
Emmanuel Hocdet
cf8cf6c5cd MINOR: ssl/cli: "show ssl cert" command should print the "Chain Filename:"
When the issuers chain of a certificate is picked from
the "issuers-chain-path" tree, "ssl show cert" prints it.
2020-02-26 13:11:59 +01:00
Emmanuel Hocdet
6f507c7c5d MINOR: ssl: resolve ocsp_issuer later
The goal is to use the ckch to store data from PEM files or <payload> and
only for that. This patch adresses the ckch->ocsp_issuer case. It finds
issuers chain if no chain is present in the ckch in ssl_sock_put_ckch_into_ctx(),
filling the ocsp_issuer from the chain must be done after.
It changes the way '.issuer' is managed: it tries to load '.issuer' in
ckch->ocsp_issuer first and then look for the issuer in the chain later
(in ssl_sock_load_ocsp() ). "ssl-load-extra-files" without the "issuer"
parameter can negate extra '.issuer' file check.
2020-02-26 13:11:59 +01:00
Emmanuel Hocdet
b90d2cbc42 MINOR: ssl: resolve issuers chain later
The goal is to use the ckch to store data from a loaded PEM file or a
<payload> and only for that. This patch addresses the ckch->chain case.
Looking for the issuers chain, if no chain is present in the ckch, can
be done in ssl_sock_put_ckch_into_ctx(). This way it is possible to know
the origin of the certificate chain without an extra state.
2020-02-26 13:06:04 +01:00
Emmanuel Hocdet
75a7aa13da MINOR: ssl: move find certificate chain code to its own function
New function ssl_get_issuer_chain(cert) to find an issuer_chain entry
from "issers-chain-path" tree.
2020-02-26 12:48:47 +01:00
William Lallemand
e0f3fd5b4c CLEANUP: ssl: move issuer_chain tree and definition
Move the cert_issuer_tree outside the global_ssl structure since it's
not a configuration variable. And move the declaration of the
issuer_chain structure in types/ssl_sock.h
2020-02-25 15:06:40 +01:00
William Lallemand
a90e593a7a MINOR: ssl/cli: reorder 'show ssl cert' output
Reorder the 'show ssl cert' output so it's easier to see if the whole
chain is correct.

For a chain to be correct, an "Issuer" line must have the same
content as the next "Subject" line.

Example:

  Subject: /C=FR/ST=Paris/O=HAProxy Test Certificate/CN=test.haproxy.local
  Issuer: /C=FR/ST=Paris/O=HAProxy Test Intermediate CA 2/CN=ca2.haproxy.local
  Chain Subject: /C=FR/ST=Paris/O=HAProxy Test Intermediate CA 2/CN=ca2.haproxy.local
  Chain Issuer: /C=FR/ST=Paris/O=HAProxy Test Intermediate CA 1/CN=ca1.haproxy.local
  Chain Subject: /C=FR/ST=Paris/O=HAProxy Test Intermediate CA 1/CN=ca1.haproxy.local
  Chain Issuer: /C=FR/ST=Paris/O=HAProxy Test Root CA/CN=root.haproxy.local
2020-02-25 14:17:50 +01:00
William Lallemand
bb7288a9f5 MINOR: ssl/cli: 'show ssl cert'displays the issuer in the chain
For each certificate in the chain, displays the issuer, so it's easy to
know if the chain is right.

Also rename "Chain" to "Chain Subject".

Example:

  Chain Subject: /C=FR/ST=Paris/O=HAProxy Test Intermediate CA 2/CN=ca2.haproxy.local
  Chain Issuer: /C=FR/ST=Paris/O=HAProxy Test Intermediate CA 1/CN=ca1.haproxy.local
  Chain Subject: /C=FR/ST=Paris/O=HAProxy Test Intermediate CA 1/CN=ca1.haproxy.local
  Chain Issuer: /C=FR/ST=Paris/O=HAProxy Test Root CA/CN=root.haproxy.local
2020-02-25 14:17:44 +01:00
William Lallemand
35f4a9dd8c MINOR: ssl/cli: 'show ssl cert' displays the chain
Display the subject of each certificate contained in the chain in the
output of "show ssl cert <filename>".
Each subjects are on a unique line prefixed by "Chain: "

Example:

Chain: /C=FR/ST=Paris/O=HAProxy Test Intermediate CA 2/CN=ca2.haproxy.local
Chain: /C=FR/ST=Paris/O=HAProxy Test Intermediate CA 1/CN=ca1.haproxy.local
2020-02-25 12:02:51 +01:00
Willy Tarreau
105599c1ba BUG/MEDIUM: ssl: fix several bad pointer aliases in a few sample fetch functions
Sample fetch functions ssl_x_sha1(), ssl_fc_npn(), ssl_fc_alpn(),
ssl_fc_session_id(), as well as the CLI's "show cert details" handler
used to dereference the output buffer's <data> field by casting it to
"unsigned *". But while doing this could work before 1.9, it broke
starting with commit 843b7cbe9d ("MEDIUM: chunks: make the chunk struct's
fields match the buffer struct") which merged chunks and buffers, causing
the <data> field to become a size_t. The impact is only on 64-bit platform
and depends on the endianness: on little endian, there should never be any
non-zero bits in the field as it is supposed to have been zeroed before the
call, so it shouldbe harmless; on big endian, the high part of the value
only is written instead of the lower one, often making the result appear
4 billion times larger, and making such values dropped everywhere due to
being larger than a buffer.

It seems that it would be wise to try to re-enable strict-aliasing to
catch such errors.

This must be backported till 1.9.
2020-02-25 08:59:23 +01:00
Willy Tarreau
ded15b7564 BUILD: ssl: only pass unsigned chars to isspace()
A build failure on cygwin was reported on github actions here:

  https://github.com/haproxy/haproxy/runs/466507874

It's caused by a signed char being passed to isspace(), and this one
being implemented as a macro instead of a function as the man page
suggests. It's the same issue that regularly pops up on Solaris. This
comes from commit 98263291cc3 which was merged in 1.8-dev1. A backport
is possible though not incredibly useful.
2020-02-25 07:51:59 +01:00
William Lallemand
3f25ae31bd BUG/MINOR: ssl: load .key in a directory only after PEM
Don't try to load a .key in a directory without loading its associated
certificate file.

This patch ignores the .key files when iterating over the files in a
directory.

Introduced by 4c5adbf ("MINOR: ssl: load the key from a dedicated
file").
2020-02-24 16:34:16 +01:00
William Lallemand
4c5adbf595 MINOR: ssl: load the key from a dedicated file
For a certificate on a bind line, if the private key was not found in
the PEM file, look for a .key and load it.

This default behavior can be changed by using the ssl-load-extra-files
directive in the global section

This feature was mentionned in the issue #221.
2020-02-24 15:39:53 +01:00
Tim Duesterhus
e8aa5f24d6 BUG/MINOR: ssl: Stop passing dynamic strings as format arguments
gcc complains rightfully:

src/ssl_sock.c: In function ‘ssl_load_global_issuers_from_path’:
src/ssl_sock.c:9860:4: warning: format not a string literal and no format arguments [-Wformat-security]
    ha_warning(warn);
    ^

Introduced in 70df7bf19cebd5593c0abb01923e6c9f72961da6.
2020-02-19 11:46:18 +01:00
Emmanuel Hocdet
70df7bf19c MINOR: ssl: add "issuers-chain-path" directive.
Certificates loaded with "crt" and "crt-list" commonly share the same
intermediate certificate in PEM file. "issuers-chain-path" is a global
directive to share intermediate chain certificates in a directory. If
certificates chain is not included in certificate PEM file, haproxy
will complete chain if issuer match the first certificate of the chain
stored via "issuers-chain-path" directive. Such chains will be shared
in memory.
2020-02-18 14:33:05 +01:00
William Lallemand
696f317f13 BUG/MEDIUM: ssl/cli: 'commit ssl cert' wrong SSL_CTX init
The code which is supposed to apply the bind_conf configuration on the
SSL_CTX was not called correctly. Indeed it was called with the previous
SSL_CTX so the new ones were left with default settings. For example the
ciphers were not changed.

This patch fixes #429.

Must be backported in 2.1.
2020-02-07 20:55:35 +01:00
William Lallemand
4dd145a888 BUG/MINOR: ssl: clear the SSL errors on DH loading failure
In ssl_sock_load_dh_params(), if haproxy failed to apply the dhparam
with SSL_CTX_set_tmp_dh(), it will apply the DH with
SSL_CTX_set_dh_auto().

The problem is that we don't clean the OpenSSL errors when leaving this
function so it could fail to load the certificate, even if it's only a
warning.

Fixes bug #483.

Must be backported in 2.1.
2020-02-05 15:32:24 +01:00
Willy Tarreau
731248f0db BUG/MINOR: ssl: we may only ignore the first 64 errors
We have the ability per bind option to ignore certain errors (CA, crt, ...),
and for this we use a 64-bit field. In issue #479 coverity reports a risk of
too large a left shift. For now as of OpenSSL 1.1.1 the highest error value
that may be reported by X509_STORE_CTX_get_error() seems to be around 50 so
there should be no risk yet, but it's enough of a warning to add a check so
that we don't accidently hide random errors in the future.

This may be backported to relevant stable branches.
2020-02-04 14:04:36 +01:00
William Lallemand
3af48e706c MINOR: ssl: ssl-load-extra-files configure loading of files
This new setting in the global section alters the way HAProxy will look
for unspecified files (.ocsp, .sctl, .issuer, bundles) during the
loading of the SSL certificates.

By default, HAProxy discovers automatically a lot of files not specified
in the configuration, and you may want to disable this behavior if you
want to optimize the startup time.

This patch sets flags in global_ssl.extra_files and then check them
before trying to load an extra file.
2020-02-03 17:50:26 +01:00
William Lallemand
a25a19fdee BUG/MINOR: ssl/cli: fix unused variable with openssl < 1.0.2
src/ssl_sock.c: In function ‘cli_io_handler_show_cert’:
src/ssl_sock.c:10214:6: warning: unused variable ‘n’ [-Wunused-variable]
  int n;
      ^
Fix this problem in the io handler of the "show ssl cert" function.
2020-01-29 00:08:10 +01:00
Olivier Houchard
efe5e8e998 BUG/MEDIUM: ssl: Don't forget to free ctx->ssl on failure.
In ssl_sock_init(), if we fail to allocate the BIO, don't forget to free
the SSL *, or we'd end up with a memory leak.

This should be backported to 2.1 and 2.0.
2020-01-24 15:17:38 +01:00
Olivier Houchard
6d53cd6978 MINOR: ssl: Remove dead code.
Now that we don't call the handshake function directly, but merely wake
the tasklet, we can no longer have CO_FL_ERR, so don't bother checking it.
2020-01-24 15:13:57 +01:00
Frédéric Lécaille
3139c1b198 BUG/MINOR: ssl: Possible memleak when allowing the 0RTT data buffer.
​
As the server early data buffer is allocated in the middle of the loop
used to allocate the SSL session without being freed before retrying,
this leads to a memory leak.
​
To fix this we move the section of code responsible of this early data buffer
alloction after the one reponsible of allocating the SSL session.
​
Must be backported to 2.1 and 2.0.
2020-01-24 15:12:21 +01:00