Hi,

Last time I saw this error it involved TLS decryption by firewalls that didn't 
support RSA-PSS. Why they blow up
when the new, more secure RSA-PSS signature algorithms are used beats me, but 
it's principally _on them_ for not supporting the latest IETF standards.

Attached is a patch that reorders the signature algorithms
in openssl 1.1.1 so that the pkcs1 ones are first. Also,
the test/recipes/80-test_ssl_new.t test needs to be thrown out for this to 
work. I would recommend trying to get this to work without docker and 
kubernetes first, and using the -d haproxy option to get more detailed OpenSSL 
logging.

It is also likely you will need to set ssl-default-bind-curves since the 
firewalls in question do not support curve x25519 either. This is a HAProxy 2.2 
option (https://www.haproxy.com/blog/announcing-haproxy-2-2/). 
ssl-default-bind-curves P-256 should/could the trick, although tuning this to 
include all supported curves should be done for production traffic.

As for implementing this in HAProxy, SSL_CTX_set1_sigalgs_list could be used in 
the part of the code that initializes the TLS connection, but it seems that 
somewhere in the handshake code the signature algorithms get renegotiated.
I haven't had any luck in identifying where exactly this renegotiation happens. 
Someone else might have more luck in writing up a patch that adds a "sigalgs" 
or similarly named option to adjust the signature algorithms.

Regards,

Bruno

‐‐‐‐‐‐‐ Original Message ‐‐‐‐‐‐‐
On Tuesday, September 15, 2020 1:45 PM, vcjouni <[email protected]> 
wrote:

> Hi!
>
> We can not get haproxy-ingress to work with TLS authentication. Only
> option to get this work is by using force-tlsv12 and then only Chrome
> works. Problem is TLS handshake decrypt error when using RSA-PSS
> signature algorithm, handshake fails every time. When we use
> force-tlsv12, only Chrome will change signature back to pkcs1 and then
> session is ok. Safari, Edge or IE does not work with any option and they
> keep offering RSA-PSS signature.
>
> This same CA bundle and cards has been used before with citrix netscaler
> ingress controller without problems (TLSv1.2). Smart cards are
> government provided FINEID cards, so we can't test them command line,
> only by using those cards with browser.
>
> I already discussed with haproxy-ingress builder jcmoraisjr and he
> suggested us to ask from haproxy mailing list.
>
> Docker image: image: quay.io/jcmoraisjr/haproxy-ingress
>
> haproxy -vv
>
> ============
>
> HA-Proxy version 2.0.17 2020/07/31 - https://haproxy.org/
> Build options :
>   TARGET  = linux-glibc
>   CPU     = generic
>   CC      = gcc
>   CFLAGS  = -O2 -g -fno-strict-aliasing -Wdeclaration-after-statement
> -fwrapv -Wno-address-of-packed-member -Wno-unused-label
> -Wno-sign-compare -Wno-unused-parameter -Wno-old-style-declaration
> -Wno-ignored-qualifiers -Wno-clobbered -Wno-missing-field-initializers
> -Wno-implicit-fallthrough -Wno-stringop-overflow -Wno-cast-function-type
> -Wtype-limits -Wshift-negative-value -Wshift-overflow=2
> -Wduplicated-cond -Wnull-dereference
>   OPTIONS = USE_PCRE2=1 USE_PCRE2_JIT=1 USE_GETADDRINFO=1 USE_OPENSSL=1
> USE_LUA=1 USE_ZLIB=1
>
> Feature list : +EPOLL -KQUEUE -MY_EPOLL -MY_SPLICE +NETFILTER -PCRE
> -PCRE_JIT +PCRE2 +PCRE2_JIT +POLL -PRIVATE_CACHE +THREAD
> -PTHREAD_PSHARED -REGPARM -STATIC_PCRE -STATIC_PCRE2 +TPROXY
> +LINUX_TPROXY +LINUX_SPLICE +LIBCRYPT +CRYPT_H -VSYSCALL +GETADDRINFO
> +OPENSSL +LUA +FUTEX +ACCEPT4 -MY_ACCEPT4 +ZLIB -SLZ +CPU_AFFINITY +TFO
> +NS +DL +RT -DEVICEATLAS -51DEGREES -WURFL -SYSTEMD -OBSOLETE_LINKER
> +PRCTL +THREAD_DUMP -EVPORTS
>
> Default settings :
>   bufsize = 16384, maxrewrite = 1024, maxpollevents = 200
>
> Built with multi-threading support (MAX_THREADS=64, default=2).
> Built with OpenSSL version : OpenSSL 1.1.1g  21 Apr 2020
> Running on OpenSSL version : OpenSSL 1.1.1g  21 Apr 2020
> OpenSSL library supports TLS extensions : yes
> OpenSSL library supports SNI : yes
> OpenSSL library supports : TLSv1.0 TLSv1.1 TLSv1.2 TLSv1.3
> Built with Lua version : Lua 5.3.5
> Built with network namespace support.
> Built with transparent proxy support using: IP_TRANSPARENT
> IPV6_TRANSPARENT IP_FREEBIND
> Built with zlib version : 1.2.11
> Running on zlib version : 1.2.11
> Compression algorithms supported : identity("identity"),
> deflate("deflate"), raw-deflate("deflate"), gzip("gzip")
> Built with PCRE2 version : 10.35 2020-05-09
> PCRE2 library supports JIT : yes
> Encrypted password support via crypt(3): yes
> Built with the Prometheus exporter as a service
>
> Available polling systems :
>       epoll : pref=300,  test result OK
>        poll : pref=200,  test result OK
>      select : pref=150,  test result OK
> Total: 3 (3 usable), will use epoll.
>
> Available multiplexer protocols :
> (protocols marked as <default> cannot be specified using 'proto' keyword)
> h2 : mode=HTX        side=FE|BE     mux=H2
>               h2 : mode=HTTP       side=FE        mux=H2
>        <default> : mode=HTX        side=FE|BE     mux=H1
> <default> : mode=TCP|HTTP   side=FE|BE     mux=PASS
>
> Available services :
>     prometheus-exporter
>
> Available filters :
>     [SPOE] spoe
>     [COMP] compression
>     [CACHE] cache
>     [TRACE] trace
>
> haproxy configmap:
>
> apiVersion: v1
> kind: ConfigMap
> metadata:
>   name: haproxy-ingress
>   namespace: ingress-controller
> data:
>   ssl-headers-prefix: HTTP_X_SSL
>   max-connections: "10000"
> #  ssl-options: ssl-min-ver TLSv1.2 no-tls-tickets
> #  ssl-options: force-tlsv12 no-tls-tickets
>   ssl-options: no-sslv3 no-tlsv10 no-tlsv11 no-tls-tickets
>   ssl-cipher-suites:
> TLS_AES_128_GCM_SHA256:TLS_AES_256_GCM_SHA384:TLS_CHACHA20_POLY1305_SHA256
>   #  ssl-ciphers:
> ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384
>
> #  ssl-ciphers:
> RSA+SHA256:RSA+SHA512:RSA+SHA384:ECDSA+SHA256:ECDSA+SHA512:ECDSA+SHA384
>   ssl-ciphers:
> ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384
>   ssl-dh-default-max-size: "2048"
>   syslog-endpoint: "10.32.121.202:514"
>   syslog-length: "2048"
>   http-log-format: "%ci:%cp\\ [%t]\\ %ft\\ %b/%s\\
> %Tq/%Tw/%Tc/%Tr/%Tt\\ %ST\\ %B\\ %CC\\ \\ %CS\\ %tsc\\
> %ac/%fc/%bc/%sc/%rc\\ %sq/%bq\\ %hr\\ %hs\\ %{+Q}r\\ ssl_version=%sslv\\
> ssl_cypher=%sslc}\\ C_VERIFY=%{+Q}[ssl_c_verify]\\
> C_ERR=%{+Q}[ssl_c_err]\\ C_S_DN=%{+Q}[ssl_c_s_dn]\\
> C_i_DN=%{+Q}[ssl_c_i_dn]\\ C_key_Alg=%{+Q}[ssl_c_key_alg]\\
> C_USED_Bool=%{+Q}[ssl_c_used]\\ C_VERSION=%{+Q}[ssl_c_version]\\
> F_i_DN=%{+Q}[ssl_f_i_dn]\\ F_KEY_ALG=%{+Q}[ssl_f_key_alg]\\
> F_S_DN=%{+Q}[ssl_f_s_dn]\\ F_SIG_ALG=%{+Q}[ssl_f_sig_alg]\\
> F_VERSION=%{+Q}[ssl_f_version]\\ FC=%{+Q}[ssl_fc]\\
> FC_ALPN=%{+Q}[ssl_fc_alpn]\\ FC_CIPHER=%{+Q}[ssl_fc_cipher]\\
> CIPHERLIST=%{+Q}[ssl_fc_cipherlist_str]\\
> FC_HAS_CRT=%{+Q}[ssl_fc_has_crt]\\
> FC_HAS_EARLY_Bool=%{+Q}[ssl_fc_has_early]\\
> FC_HAS_SNI=%{+Q}[ssl_fc_has_sni]\\
> FC_IS_RESUMED_Bool=%{+Q}[ssl_fc_is_resumed]\\ FC_NPN=%{+Q}[ssl_fc_npn]\\
> FC_PROTOCOL=%{+Q}[ssl_fc_protocol]\\ FC_SNI=%{+Q}[ssl_fc_sni]\\
> C_CA_ERR=%[capture.req.hdr(2)]\\ C_CA_ERR_DEPTH=%[capture.req.hdr(3)]\\
> FC_CIPHER=%[capture.req.hdr(4)]"
>   https-log-format: "%ci:%cp\\ [%t]\\ %ft\\ %b/%s\\ %ST\\ %B\\ %tsc\\
> %ac/%fc/%bc/%sc/%rc\\ %sq/%bq\\ %hr\\ %hs"
>   config-global: |
>   config-frontend: |
>     capture request header Host len 100
>     capture request header User-Agent len 200
>     http-request capture ssl_c_ca_err len 2
>     http-request capture ssl_c_ca_err_depth len 2
>     http-request capture ssl_fc_cipher len 64
>
>   config-backend: |
>     http-request set-header X_SSL_CLIENT_VERIFY %[ssl_c_verify]
>     http-request set-header X_SSL_CLIENT_DN %{+Q}[ssl_c_s_dn]
>     http-request set-header X_SSL_ISSUER_DN %{+Q}[ssl_c_i_dn]
>
> Ingress:
> annotations:
>     kubernetes.io/ingress.class: haproxy
>     ingress.kubernetes.io/auth-tls-secret:
> default/staging-client-certificate-ca
>     ingress.kubernetes.io/auth-tls-verify-client: optional
>
> Any help?
>
> Br,
> Jouni

diff -ur a/ssl/t1_lib.c b/ssl/t1_lib.c
--- a/ssl/t1_lib.c      2020-08-18 13:47:55.000000000 +0000
+++ b/ssl/t1_lib.c      2020-08-18 13:45:56.434154734 +0000
@@ -643,18 +643,12 @@
     TLSEXT_SIGALG_ed25519,
     TLSEXT_SIGALG_ed448,
 #endif
-
     TLSEXT_SIGALG_rsa_pss_pss_sha256,
     TLSEXT_SIGALG_rsa_pss_pss_sha384,
     TLSEXT_SIGALG_rsa_pss_pss_sha512,
-    TLSEXT_SIGALG_rsa_pss_rsae_sha256,
-    TLSEXT_SIGALG_rsa_pss_rsae_sha384,
-    TLSEXT_SIGALG_rsa_pss_rsae_sha512,
-
     TLSEXT_SIGALG_rsa_pkcs1_sha256,
     TLSEXT_SIGALG_rsa_pkcs1_sha384,
     TLSEXT_SIGALG_rsa_pkcs1_sha512,
-
 #ifndef OPENSSL_NO_EC
     TLSEXT_SIGALG_ecdsa_sha224,
     TLSEXT_SIGALG_ecdsa_sha1,
@@ -674,6 +668,9 @@
     TLSEXT_SIGALG_gostr34102012_512_gostr34112012_512,
     TLSEXT_SIGALG_gostr34102001_gostr3411,
 #endif
+    TLSEXT_SIGALG_rsa_pss_rsae_sha256,
+    TLSEXT_SIGALG_rsa_pss_rsae_sha384,
+    TLSEXT_SIGALG_rsa_pss_rsae_sha512,
 };
 
 #ifndef OPENSSL_NO_EC

Reply via email to