Reputation: 327
Using Elixir and Brod (which relies on Erlang's ssl
module), I'm trying to connect to a SSL-enabled Kafka broker. This works if, and only if, the private key of the client certificate is not password-protected.
The certificate is created using openssl
:
$ openssl req -newkey rsa:2048 -sha256 -passout pass:test1234 -keyout client.key -out client.csr -days $DAYS -subj "$SUBJ"
$ openssl x509 -req -CA ca.crt -CAkey ca.key -in client.csr -out client.crt -days $DAYS -CAserial ca.sr
I verify that the password is set using openssl rsa -noout -text -in certs/client.key
.
After that, client.key
looks like this:
-----BEGIN ENCRYPTED PRIVATE KEY-----
MIIFHzBJBgkqhkiG9w0BBQ0wPDAbBgkqhkiG9w0BBQwwDgQIttCU1ZmyY2ACAggA
...
6C/BxoJnc6SQODqj+eiZHsCTKQ==
-----END ENCRYPTED PRIVATE KEY-----
..which I suppose is in PEM format, suitable for Erlang's ssl
module.
Brod passes the SSL options down to Erlang's ssl:connect
. I'm passing these options (Elixir syntax):
[
certfile: "client.crt",
keyfile: "client.key",
password: String.to_charlist("test1234"),
cacertfile: "ca.crt"
]
** (stop) {{{:failed_to_upgrade_to_ssl, {:keyfile, :function_clause}}, [{:brod_sock, :maybe_upgrade_to_ssl, 4, [file: 'src/brod_sock.erl', line: 278]}, {:brod_sock, :do_init, 4, [file: 'src/brod_sock.erl', line: 204]}, {:brod_sock, :init, 5, [file: 'src/brod_sock.erl', line: 176]}, {:proc_lib, :init_p_do_apply, 3, [file: 'proc_lib.erl', line: 247]}]}, [localhost: 9193]}
(brod) src/brod_client.erl:708: :brod_client.start_metadata_socket/5
(brod) src/brod_client.erl:301: :brod_client.handle_info/2
(stdlib) gen_server.erl:616: :gen_server.try_dispatch/4
(stdlib) gen_server.erl:686: :gen_server.handle_msg/6
(stdlib) proc_lib.erl:247: :proc_lib.init_p_do_apply/3
According to The Internet this error means that the private key file could not be parsed/loaded/used. I've tried using a wrong password and it's the exact same message. As noted above, when using a secret key that's not password protected, it works fine.
client.key
's formatting?Currently studying the OTP sources, but no luck so far.
Upvotes: 2
Views: 1040
Reputation: 435
I had similar problem. It turned out that the private key was encoded using AES-256-CBC
, but the public_key
library in Erlang/OTP doesn't support it. This is the function call that fails:
** exception error: no function clause matching pubkey_pbe:decode(...,
"password","AES-256-CBC", ...) (pubkey_pbe.erl, line 59)
in function public_key:do_pem_entry_decode/2 (public_key.erl, line 976)
The actual code in Erlang/OTP is at github and we can see that "AES-256-CBC" is not handled.
Upvotes: 2
Reputation: 327
After investigating some more I found out that the Erlang ssl implementation doesn't play well with the private key created by openssl req -newkey. In the openssl documentation I couldn't find the exact algorithm used by -newkey, but creating the private key beforehand using openssl genrsa -des3 did the trick, so I think the default algorithm is something not supported by Erlang's ssl.
I'm posting this as an answer as it solves my problem, but I'd very much appreciate any additional insights.
Upvotes: 1
Reputation: 163
This is just a suggestion. I do not have enough reps to provide this in comments. Try giving the password as binary string.
Upvotes: 0