s_client SECLEVEL different in config file vs command line?

34 views
Skip to first unread message

Ian Pilcher

unread,
Sep 20, 2025, 11:16:32 AM (12 days ago) Sep 20
to openss...@openssl.org
I am trying to set up an Apache reverse proxy that will allow me to use
modern browsers to manage my old "smart" switches. These old switches
only support TLS 1.0 using the DHE-RSA-AES256-SHA cipher, which uses
SHA-1 digests. I'll ultimately need to create an Apache configuration,
but I'm working with openssl s_client right now, because baby steps.

I've noticed a behavior that I don't understand when setting the cipher
and SECLEVEL. In short, setting "CipherString = DHE-RSA-AES256-
SHA@SECLEVEL=0" in my configuration allows s_client to connect to one of
the old switches, but specifying "-cipher DHE-RSA-AES256-SHA@SECLEVEL=0"
on the command line does not have the same effect.

Here is the configuration file that I've created (INSECURE.cnf):

> HOME = .
> openssl_conf = openssl_init
> config_diagnostics = 1
>
> [openssl_init]
> providers = provider_sect
> ssl_conf = ssl_module
>
> [provider_sect]
> default = default_sect
>
> [default_sect]
> activate = 1
>
> [ssl_module]
> system_default = crypto_policy
>
> [crypto_policy]
> CipherString = DHE-RSA-AES256-SHA@SECLEVEL=0
> Options = UnsafeLegacyServerConnect

Using this file, s_client connects successfully.

> $ OPENSSL_CONF=./INSECURE.cnf openssl s_client -connect switch1.penurio.us:443
> Connecting to 172.31.4.1
> CONNECTED(00000003)
...
> ---
> SSL handshake has read 3026 bytes and written 489 bytes
> Verification: OK
> ---
> New, SSLv3, Cipher is DHE-RSA-AES256-SHA
> Server public key is 2048 bit
> Secure Renegotiation IS NOT supported
> Compression: NONE
> Expansion: NONE
> No ALPN negotiated
> SSL-Session:
> Protocol : TLSv1
> Cipher : DHE-RSA-AES256-SHA
> Session-ID:
> Session-ID-ctx:
> Master-Key: 6A299C2D5036546F6A64375F01E3F3F5CCDEA0FE3C1FA681C14647AC0DAA5BB0CD587346A62F3C1095F3CC8DAA69CC2D
> PSK identity: None
> PSK identity hint: None
> SRP username: None
> Start Time: 1758380946
> Timeout : 7200 (sec)
> Verify return code: 0 (ok)
> Extended master secret: no
> ---
> closed

But specifying the cipher and security level on the command line (along
with -tls1 and -legacy_renegotiation) doesn't work.

> $ openssl s_client -connect switch1.penurio.us:443 -legacy_renegotiation -cipher DHE-RSA-AES256-SHA@SECLEVEL=0 -tls1
> Connecting to 172.31.4.1
> CONNECTED(00000003)
> depth=1 O=PENURIO.US, CN=Certificate Authority
> verify return:1
> depth=0 O=PENURIO.US, CN=switch1.penurio.us
> verify return:1
> 40A75F54177F0000:error:03000098:digital envelope routines:do_sigver_init:invalid digest:crypto/evp/m_sigver.c:342:
> 40A75F54177F0000:error:0A080006:SSL routines:tls_process_key_exchange:EVP lib:ssl/statem/statem_clnt.c:2521:

I'm still getting an "invalid digest" error, presumably due to the SHA-1
digest algorithm.

Can anyone explain why these two methods of specifying the cipher are
behaving differently? (And what would I need to put on the command line
to allow SHA-1 digests?)

TIA!

(This is all done with OpenSSL 3.2.4 on Fedora 42.)

--
========================================================================
If your user interface is intuitive in retrospect ... it isn't intuitive
========================================================================

Viktor Dukhovni

unread,
Sep 21, 2025, 5:33:52 AM (11 days ago) Sep 21
to openss...@openssl.org
On Sat, Sep 20, 2025 at 10:16:24AM -0500, Ian Pilcher wrote:

> I am trying to set up an Apache reverse proxy that will allow me to use
> modern browsers to manage my old "smart" switches. These old switches
> only support TLS 1.0 using the DHE-RSA-AES256-SHA cipher, which uses
> SHA-1 digests. I'll ultimately need to create an Apache configuration,
> but I'm working with openssl s_client right now, because baby steps.
>
> I've noticed a behavior that I don't understand when setting the cipher
> and SECLEVEL. In short, setting "CipherString = DHE-RSA-AES256-
> SHA@SECLEVEL=0" in my configuration allows s_client to connect to one of
> the old switches, but specifying "-cipher DHE-RSA-AES256-SHA@SECLEVEL=0"
> on the command line does not have the same effect.

IIRC the expected. syntax is to use a ":" before "@SECLEVEL", though it
does appear to be "optional".

Looks like you're using OpenSSL on a RedHat or Fedora system. This is
then subject to RedHat's "crypto policies", which by default block the
use of SHA1. On my Fedora 41 system, with my own build of OpenSSL 3.2
(crypto policies aside, mostly similar 3.2 shipped in Fedora) I observe:

$ /opt/openssl/3.2/bin/openssl s_client -cipher DHE-RSA-AES256-SHA@SECLEVEL=0 -starttls smtp -tls1 -connect 127.0.0.1:25 -brief
Connecting to 127.0.0.1
Can't use SSL_get_servername
depth=1 C=US, O=Let's Encrypt, CN=R12
verify error:num=20:unable to get local issuer certificate
CONNECTION ESTABLISHED
Protocol version: TLSv1
Ciphersuite: DHE-RSA-AES256-SHA
Peer certificate: CN=[elided]
Hash used: MD5-SHA1
Signature type: RSA
Verification error: unable to get local issuer certificate
Server Temp Key: DH, 2048 bits
250 CHUNKING

$ /usr/bin/openssl s_client -cipher DHE-RSA-AES256-SHA@SECLEVEL=0 -starttls smtp -tls1 -connect 127.0.0.1:25 -brief
Connecting to 127.0.0.1
Can't use SSL_get_servername
409754D4617F0000:error:03000098:digital envelope routines:do_sigver_init:invalid digest:crypto/evp/m_sigver.c:342:
409754D4617F0000:error:0A080006:SSL routines:tls_process_key_exchange:EVP lib:ssl/statem/statem_clnt.c:2521:

As you can see, Fedora's OpenSSL does not want to negotiate the MD5-SHA1 TLS 1.0 digest.

> Here is the configuration file that I've created (INSECURE.cnf):
>
> > HOME = .
> > openssl_conf = openssl_init
> > config_diagnostics = 1
> >
> > [openssl_init]
> > providers = provider_sect
> > ssl_conf = ssl_module
> >
> > [provider_sect]
> > default = default_sect
> >
> > [default_sect]
> > activate = 1
> >
> > [ssl_module]
> > system_default = crypto_policy
> >
> > [crypto_policy]
> > CipherString = DHE-RSA-AES256-SHA@SECLEVEL=0
> > Options = UnsafeLegacyServerConnect

You're also overriding the default crypto policy,

/etc/pki/tls/openssl.cnf:
[crypto_policy]
.include = /etc/crypto-policies/back-ends/opensslcnf.config

/etc/crypto-policies/back-ends/opensslcnf.config:
CipherString = @SECLEVEL=2:kEECDH:kRSA:kEDH:kPSK:kDHEPSK:kECDHEPSK:kRSAPSK:-aDSS:-3DES:!DES:!RC4:!RC2:!IDEA:-SEED:!eNULL:!aNULL:!MD5:-SHA384:-CAMELLIA:-ARIA:-AESCCM8
Ciphersuites = TLS_AES_256_GCM_SHA384:TLS_CHACHA20_POLY1305_SHA256:TLS_AES_128_GCM_SHA256:TLS_AES_128_CCM_SHA256
TLS.MinProtocol = TLSv1.2
TLS.MaxProtocol = TLSv1.3
DTLS.MinProtocol = DTLSv1.2
DTLS.MaxProtocol = DTLSv1.2
SignatureAlgorithms = ECDSA+SHA256:ECDSA+SHA384:ECDSA+SHA512:ed25519:ed448:rsa_pss_pss_sha256:rsa_pss_pss_sha384:rsa_pss_pss_sha512:rsa_pss_rsae_sha256:rsa_pss_rsae_sha384:rsa_pss_rsae_sha512:RSA+SHA256:RSA+SHA384:RSA+SHA512:ECDSA+SHA224:RSA+SHA224
Groups = X25519:secp256r1:X448:secp521r1:secp384r1:ffdhe2048:ffdhe3072:ffdhe4096:ffdhe6144:ffdhe8192

[openssl_init]
alg_section = evp_properties

[evp_properties]
rh-allow-sha1-signatures = no

> Using this file, s_client connects successfully.

As expected.

> But specifying the cipher and security level on the command line (along
> with -tls1 and -legacy_renegotiation) doesn't work.

As expected.

> Can anyone explain why these two methods of specifying the cipher are
> behaving differently? (And what would I need to put on the command line
> to allow SHA-1 digests?)

See above.
>
> TIA!
>
> (This is all done with OpenSSL 3.2.4 on Fedora 42.)

As deduced from the reported symptoms and settings. This reminds me to
upgrade from Fedora 41 at some point. :-)

--
Viktor. 🇺🇦 Слава Україні!

Ian Pilcher

unread,
Sep 23, 2025, 5:08:22 PM (9 days ago) Sep 23
to openss...@openssl.org
On 9/21/25 4:33 AM, Viktor Dukhovni wrote:
> You're also overriding the default crypto policy,

And that's the key. /usr/share/crypto-policies/DEFAULT/opensslcnf.txt
specifically disables SHA-1 signatures.

[evp_properties]
rh-allow-sha1-signatures = no

So by not including that file (through its /etc/crypto-policies
symlink), I've allowed them. (This wouldn't work on RHEL or
derivatives, where 'rh-allow-sha1-signatures = yes' is required to
enable them.)

Annoyingly, it seems to be completely impossible to override this
setting from the command line, so a complete custom OpenSSL
configuration is required for every one-off test of an old server.

--
========================================================================
Google Where SkyNet meets Idiocracy
========================================================================

Viktor Dukhovni

unread,
Sep 24, 2025, 12:45:56 AM (8 days ago) Sep 24
to openss...@openssl.org
On Tue, Sep 23, 2025 at 04:07:59PM -0500, Ian Pilcher wrote:

> > You're also overriding the default crypto policy,
>
> And that's the key. /usr/share/crypto-policies/DEFAULT/opensslcnf.txt
> specifically disables SHA-1 signatures.
>
> [evp_properties]
> rh-allow-sha1-signatures = no
>
> So by not including that file (through its /etc/crypto-policies
> symlink), I've allowed them. (This wouldn't work on RHEL or
> derivatives, where 'rh-allow-sha1-signatures = yes' is required to
> enable them.)

Your configuration can do that too, of course.

> Annoyingly, it seems to be completely impossible to override this
> setting from the command line, so a complete custom OpenSSL
> configuration is required for every one-off test of an old server.

Setting the "OPENSSL_CONF" environment variant to a file that uses
a more liberal policy works from the command-line:

OPENSSL_CONF=/some/where/file.cnf cmd1 args ...
OPENSSL_CONF=/some/other/file.cnf cmd2 args ...

FWIW, the openssl-s_client(1) command also supports a "-ssl_config"
option, which can override *most* of the RedHat tweaks via configuration
files of the form:

/etc/pki/tls/openssl.cnf:
# top-level outside any [section] (a.k.a. default section)
...
openssl_conf = openssl_init
...
[openssl_init]
...
ssl_conf = ssl_module
...

# Redhat magic
[ssl_module]
system_default = crypto_policy
relaxed = [relaxed_ssl]

[ crypto_policy ]
.include = /etc/crypto-policies/back-ends/opensslcnf.config

# Ignore typically impractical attack vectors by overriding
# "crypto_policy" section settings in the above included file.
[relaxed_ssl]
# Note, s_client "-tls1*" and "-min_protocol" options override
# this, last one wins.
TLS.MinProtocol = TLSv1
...

$ openssl s_client -ssl_config relaxed ...

but, sadly, that cannot lift the SHA1 signature taboo, which happens at
a higher layer, because the above ".include" file also introduces
two additional sections:

[openssl_init]
alg_section = evp_properties

[evp_properties]
rh-allow-sha1-signatures = no

and the "alg_section" (i.e. "evp_properties") section is separate from
the "ssl_conf" (i.e. "crypto_policy") section, so you'd need to override
the application name ("openssl_init" by default) to avoid that.

So, indeed for s_server and s_client, if you want SHA1 support, you
need to resort to the "OPENSSL_CONF" environment variable.

Applications that take advantage of explicit non-default initialisation
can choose a different set of settings, see:

OPENSSL_INIT_new(3)
OPENSSL_INIT_set_config_file_flags(3)
OPENSSL_INIT_set_config_filename(3)
OPENSSL_INIT_set_config_appname(3)
OPENSSL_init_ssl(3)
SSL_CTX_config(3)

The last of these augments, but does not disable, the SSL_CTX
initialisation specified in "system_default", so any settings there that
you don't like need explicit overrides. The order of processing is:

- "system_default" section settings as part of SSL_CTX_new()
- any other application settings before any call to SSL_CTX_config(3)
- SSL_CTX_config(3) section settings
- any other settings after any call to SSL_CTX_config(3)

The processing of "-tls*" and "-min_protocol" in openssl-s_client(1)
is part of the last step above.

--
Viktor. 🇺🇦 Слава Україні!

Viktor Dukhovni

unread,
Sep 24, 2025, 1:38:50 AM (8 days ago) Sep 24
to openss...@openssl.org
On Wed, Sep 24, 2025 at 02:45:43PM +1000, Viktor Dukhovni wrote:

> [ssl_module]
> system_default = crypto_policy
> relaxed = [relaxed_ssl]

Correction, that should have been:

relaxed = relaxed_ssl

The "[]" only go around the section heading, and not when specifying a
section name in a property.

--
Viktor. 🇺🇦 Слава Україні!
Reply all
Reply to author
Forward
0 new messages