4

I have to use a service that uses self-signed certificate (from Ubuntu). I have added the company's CA to the trusted list (Ubuntu). After that "self signed certificate in chain" error is gone but now I get "CA certificate too weak" error. E.g.

curl -vvv https://someservicehost.net
 *   Trying 93.184.216.34:443...
 * TCP_NODELAY set
 * Connected to someservicehost.net (93.184.216.34) port 443 (#0)
 * ALPN, offering h2
 * ALPN, offering http/1.1
 * successfully set certificate verify locations:
 *   CAfile: /etc/ssl/certs/ca-certificates.crt
  CApath: /etc/ssl/certs
 * TLSv1.3 (OUT), TLS handshake, Client hello (1):
 * TLSv1.3 (IN), TLS handshake, Server hello (2):
 * TLSv1.2 (IN), TLS handshake, Certificate (11):
 * TLSv1.2 (OUT), TLS alert, bad certificate (554):
 * SSL certificate problem: CA certificate key too weak
 * Closing connection 0
curl: (60) SSL certificate problem: CA certificate key too weak

I tried to search it but there is surprisingly little information on this. So I have 2 questions

  • How do I find exactly which properties of this certificate make it "weak"? Is it hash, key length, something else? I deliberately omitted the certificate details as I want to know how do I diagnose the problem not the problem with this particular certificate.
  • How do I force client software to trust it? I think I do not have a choice of upgrading the CA cert.
Petr Gladkikh
  • 183
  • 1
  • 1
  • 9
  • 3
    Contact the people in your company who are responsible for this proxy. It is a problem they have to solve (and should have solved before it actually occured) – Gerald Schneider Sep 10 '20 at 13:06
  • 1
    `key too weak` tells you it's the key; if it were the message digest aka digest aka hash, it would say 'md too weak' (but note the CA key is the one in the CA cert, while the CA _hash_ is the one in the _child_ = EE cert because it was _signed by_ the CA) – dave_thompson_085 Sep 11 '20 at 03:31

1 Answers1

13

At the time of writing this, example.net used a certificate signed by the DigiCert SHA2 Secure Server CA intermediate CA, which in turn is signed by the DigiCert Global Root CA root CA. Both CA certificates use a 2048-bit RSA key. However, if you are behind a corporate TLS proxy, the actual CA might only use a 1024-bit key (you didn't provide any details on it), so adapt the rest of the answer according to the key size of that CA certificate. If you can't avoid the proxy, a better approach, than what's described below, would be to inquire whether a CA certificate with a stronger key could be employed on it.

When OpenSSL verifies the certificate chain, it checks the key size against the configured security level. According to the documentation, level 1 corresponds to a minimum of 80 bits of security, level 2 to 112 bits, level 3 to 128 bits, level 4 to 192 bits and level 5 to 256 bits.

RSA 2048-bit keys are currently deemed to have 112 bits of security, so if the above level is 3 or higher, the key is rejected as too weak. So to accept such a certificate, you'd have to reduce the security level to 2 or lower.

The level can be configured at compile time or via configuration (it can also be changed by the program that links libssl/libcrypto, but it looks like curl doesn't do so). The default level is 1 according to the documentation linked above.

So first check the compile options (openssl version -f) and then the default openssl.cnf file on your system (the directory where it's located can be determined via openssl version -d). There might be a setting called CipherSuites that sets SECLEVEL (e.g. CipherString = DEFAULT@SECLEVEL=3 would set it to level 3).

To override the level, either change the default config file, or use a custom file via OPENSSL_CONF environment variable. For instance, the following file sets the default security level to 2 (see the documentation for details):

openssl_conf = openssl_conf_sect

[openssl_conf_sect]
ssl_conf = ssl_sect

[ssl_sect]
system_default = system_default_sect

[system_default_sect]
CipherString = DEFAULT@SECLEVEL=2

It may be used e.g. with OPENSSL_CONF=/path/to/this.cnf curl -vvv https://example.net.

As pointed out in the comments by @dave_thompson_085, curl allows configuring the cipher suites on the command line. So instead of fiddling with the configuration, you may simply change the security level via --ciphers option:

curl -vvv --ciphers DEFAULT@SECLEVEL=2 https://example.net
ecdsa
  • 3,973
  • 15
  • 29
  • 1
    Well, look at the certificate (e.g. in your browser or if you have it as a file with `openssl x509 -text`), then you don't have to guess :) – ecdsa Sep 10 '20 at 14:33
  • Yes, the certificate of example.com is irrelevant. The one I see is internal CA provided by the company. I probably should clarify the question. The question was - is there a way to, say, print the diagnostics: "the cert is weak because..." without resorting to guessing. I just checked CA cert: 'Signature Algorithm: sha256WithRSAEncryption" - so it is probably not a hash function, the key size is 4096 bits - also looks OK. – Petr Gladkikh Sep 10 '20 at 14:38
  • I know which certificate is used so no need to guess. I would like to see which property of it is considered "weak" - as far as I know that may be hash algorithm, key size, something else? Or "weak" always refers to key size? In my case the message complains about CA - but that one is 4096 bits. – Petr Gladkikh Sep 10 '20 at 14:42
  • 1
    OK, lowering DEFAULT@SECLEVEL to 1 helped. Probably I should use that... Thanks! – Petr Gladkikh Sep 10 '20 at 14:46
  • @PetrGladkikh If going to SECLEVEL=1 worked and 2 did not, then the cert probably truly is too weak to still be in use and should have been retired many years ago. As this is a potentially serious security issue for your organization, you should have a chat with whoever manages the CA. Even 2 is now too weak if your threats include organized crime or nation-states. – Michael Hampton Sep 10 '20 at 20:45
  • Thanks, the problem is that it is not obvious what exactly is off there: both algorithms and key length look OK. – Petr Gladkikh Sep 10 '20 at 22:32
  • 2
    `curl --ciphers DEFAULT:@SECLEVEL=$n ...` sets it without fiddling the config (which can affect other programs, or users if any) – dave_thompson_085 Sep 11 '20 at 03:37
  • if you use `openssl s_client`, add `--cipher DEFAULT@SECLEVEL=1` – quant2016 Mar 29 '23 at 13:16