Unknown CA - Failed SSL client connection

I cannot connect to a remote server using SSL.
I’m trying to connect to an AMQP1.0 server using rabbitmq-server/deps/amqp10_client/src at main · rabbitmq/rabbitmq-server · GitHub

I can connect using Python + qpid-proton using a certificate. I can also establish a secure connection using the following command with the same certificate file:

$ openssl s_client -connect 7.7.7.7:7777 -CAfile key.crt.pem
...
Requested Signature Algorithms: ECDSA+SHA256:ECDSA+SHA384:ECDSA+SHA512:RSA-PSS+SHA256:RSA-P
SS+SHA384:RSA-PSS+SHA512:RSA-PSS+SHA256:RSA-PSS+SHA384:RSA-PSS+SHA512:RSA+SHA256:RSA+SHA384
:RSA+SHA512:DSA+SHA256:ECDSA+SHA224:RSA+SHA224:DSA+SHA224:ECDSA+SHA1:RSA+SHA1:DSA+SHA1
Shared Requested Signature Algorithms: ECDSA+SHA256:ECDSA+SHA384:ECDSA+SHA512:RSA-PSS+SHA25
6:RSA-PSS+SHA384:RSA-PSS+SHA512:RSA-PSS+SHA256:RSA-PSS+SHA384:RSA-PSS+SHA512:RSA+SHA256:RSA
+SHA384:RSA+SHA512:DSA+SHA256:ECDSA+SHA224:RSA+SHA224:DSA+SHA224
---
SSL handshake has read 11966 bytes and written 667 bytes
Verification: OK
---
New, TLSv1.2, Cipher is AES256-SHA256
Server public key is 2048 bit
Secure Renegotiation IS supported
Compression: NONE
Expansion: NONE
No ALPN negotiated
SSL-Session:
    Protocol  : TLSv1.2
    Cipher    : AES256-SHA256
    Session-ID: XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
    Session-ID-ctx: 
    Master-Key: XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
    PSK identity: None
    PSK identity hint: None
    SRP username: None
    Start Time: 1682342266
    Timeout   : 7200 (sec)
    Verify return code: 0 (ok)
    Extended master secret: yes
---

However, I cannot do the same with Erlang/Elixir. The simplest Elixir code I can create that replicate the error is the following:

opts = [
  cacertfile: './key.crt.pem',
  verify: :verify_peer,
  server_name_indication: :disable,
  ciphers: [:ssl.str_to_suite('AES256-SHA256')]
  # ciphers: [:ssl.str_to_suite('TLS_RSA_WITH_AES_256_CBC_SHA256')]
]

:ssl.connect({7, 7, 7, 7}, 7777, opts)

And I have the following error:

Connecting: {:error,
 {:shutdown,
  {:failed_to_start_child, :reader,
   {:tls_alert,
    {:unknown_ca,
     'TLS client: In state certify at ssl_handshake.erl:2111 generated CLIENT ALERT: Fatal 
- Unknown CA\n'}}}}}
** (MatchError) no match of right hand side value: {:error, {:shutdown, {:failed_to_start_c
hild, :reader, {:tls_alert, {:unknown_ca, 'TLS client: In state certify at ssl_handshake.er
l:2111 generated CLIENT ALERT: Fatal - Unknown CA\n'}}}}}

I’m using Erlang 25.3 (Elixir 1.14.3) but I tried other versions with similar results. I also tried TLS_RSA_WITH_AES_256_CBC_SHA256 cipher because it is the one that the Python client uses with similar results.

I don’t have any clue to solve this problem. Any idea?

I really appreciate any help you can provide.

1 Like

The filename ‘key.crt.pem’ makes me wonder if you are using the right files in the right place, I am not convinced you are using the file that contains the CA (I suspect this file is the private key of your server).

The contents should say ‘PUBLIC CERTIFICATE’ (iirc, on a phone at the moment, sorry) at the top and when you run the following it should output that the certificate purpose is a CA and also the subject and issuer are the same:

openssl x509 -noout -text -in CA.pem

The subject and issuer may be different, if there is a certificate chain, but I suspect you likely will be running a private CA and signing certs directly?

1 Like

Thanks for your response. I’m not an expert in certificates, so I’m unsure about my own responses. The file was given to me, so I don’t have too much control. The content is two concatenated certificates with:

-----BEGIN CERTIFICATE-----
...
-----END CERTIFICATE-----
-----BEGIN CERTIFICATE-----
...
-----END CERTIFICATE-----

The output of the command you shared is validates that the issuer and the subject are the same, and also it seems like a CA one:

            X509v3 Key Usage: critical
                Certificate Sign, CRL Sign
            X509v3 Basic Constraints: critical
                CA:TRUE

I’m able to connect forcing the version to:

tls_opts = [
  cacertfile: './key.crt.pem',
  verify: :verify_peer,
  # ciphers: [:ssl.str_to_suite('TLS_RSA_WITH_AES_256_CBC_SHA256')],
  server_name_indication: :disable,
  ciphers: [:ssl.str_to_suite('AES256-SHA256')],
  versions: [:"tlsv1.2"]
]

However, the AMQP 1.0 fails:

config = %{
  address: {7, 7, 7, 7},
  port: 7777,
  tls_opts: {:secure_port, tls_opts},
  notify: self(),
  sasl: :none,
  idle_time_out: 30_000
}

{:ok, conn} = :amqp10_client.open_connection(config)
receive do
  {:amqp10_event, {:connection, ^conn, :opened}} -> :ok
  msg -> raise "unexpected message received: #{inspect(msg)}"
after
  1000 -> raise "timeout"
end

----

12:17:26.059 [warning] AMQP 1.0 connection socket was closed, connection state: 'expecting_frame_header'
** (RuntimeError) unexpected message received: {:amqp10_event, {:connection, #PID<0.206.0>, {:closed, :function_clause}}}

Not sure if this error is still because the connection wasn’t made correctly, or should I open an issue in rabbit repo?

1 Like