Closed odarriba closed 2 months ago
I've pushed docs update to main, if passing :cacertfile is not enough, please lmk!
Thanks for the quick response!
As fas as I know, CA certificates are used to validate that server certificate is emitted by a trusted authority, works as authenticating the server on the client side.
However, client certificates works the opposite: they are used to authenticate the client against the server, and the server is the one that have a CA that matches the client certificate. it is like having a two-way certificate communication (here some documentation).
In other libraries (docs), it can be done passing ssl
options, but I'm not sure if that can be done or how.
Right, replace:
options = [ssl: [certfile: "certs/client.crt"]]
{:ok, response} = HTTPoison.post(url, [], options)
with
options = [connect_options: [transport_opts: [cacertfile: "certs.pem"]]]
Req.get!(url, options)
and you should be good to go. Transport options are documented here: https://hexdocs.pm/mint/Mint.HTTP.html#connect/4-transport-options
Hi!
I'm trying to make the requests as you mention but I'm getting the following error:
iex(15)> req_options = [connect_options: [transport_opts: [cacertfile: cert_path]]]
[connect_options: [transport_opts: [cacertfile: "cert.pfx"]]]
iex(16)> Req.get!(url, req_options)
[notice] TLS :client: In state :certify at ssl_handshake.erl:2174 generated CLIENT ALERT: Fatal - Unknown CA
** (Req.TransportError) TLS client: In state certify at ssl_handshake.erl:2174 generated CLIENT ALERT: Fatal - Unknown CA
(req 0.5.6) lib/req.ex:1092: Req.request!/2
iex:16: (file)
I don't know if .pfx
is a valid certificate for that purpose. It's what I'm using in Postman and it's working properly.
I've tried to convert that .pfx
to .pem
with openssl
if possible because of this doc:
:cacertfile - path to a file containing PEM-encoded CA certificates. See the :cacerts option for the defaults to this value.
with same result.
is that .pfx working with httpoison that you mentioned prior?
It's NOT with .pfx
but It's working with converted .pem
.
In Req
is not working with .pfx
nor converted .pem
I think the reason is that CA certificate is used to validate the server certificate, and the client certificate is a different thing: it is sent to the server.
what happens when in httpoison you additionally set cacertfile: ..., verify: :verify_peer
? Do you get the same error?
You can disable server verification with cacertfile: ..., verify: :verify_none
.
Responses with HTTPoison: {:ok, response} = HTTPoison.get(url, [], options)
options = [ssl: [certfile: cert_path]]
Result: Successoptions = [ssl: [cacertfile: cert_path]]
Result: [notice] TLS :client: In state :certify at ssl_handshake.erl:2174 generated CLIENT ALERT: Fatal - Unknown CA
** (MatchError) no match of right hand side value: {:error, %HTTPoison.Error{reason: {:tls_alert, {:unknown_ca, ~c"TLS client: In state certify at ssl_handshake.erl:2174 generated CLIENT ALERT: Fatal - Unknown CA\n"}}, id: nil}}
(stdlib 6.0) erl_eval.erl:652: :erl_eval.expr/6
iex:50: (file)
options = [ssl: [cacertfile: cert_path, verify: :verify_peer]]
Result: [notice] TLS :client: In state :certify at ssl_handshake.erl:2174 generated CLIENT ALERT: Fatal - Unknown CA
** (MatchError) no match of right hand side value: {:error, %HTTPoison.Error{reason: {:tls_alert, {:unknown_ca, ~c"TLS client: In state certify at ssl_handshake.erl:2174 generated CLIENT ALERT: Fatal - Unknown CA\n"}}, id: nil}}
(stdlib 6.0) erl_eval.erl:652: :erl_eval.expr/6
iex:50: (file)
options = [ssl: [cacertfile: cert_path, verify: :verify_none]]
Result: Doesn't response with an error. But endpoint raises a 403 error. Same response as no cert provided.Thanks for following up. The best way to figure this out is to reproduce with Mint so we remove extra layers like Finch and Req. With Mint this should work:
{:ok, conn} =
Mint.HTTP.connect(
:https,
"example.com",
443,
transport_opts: …
)
My recommendation is to first of all take this snippet and make sure it works (eg without cert, to a regular host), modify it in a way that should work and when it doesn’t, ask people on ElixirForum etc, the question will have more visibility and broader community could help. Sorry I couldn’t be more helpful.
I've just made Req works with this params: [connect_options: [transport_opts: [certfile: "cert.pem"]]]
instead of: [connect_options: [transport_opts: [cacertfile: "cert.pem"]]]
I've tried with this options just because is the name in HTTPoison and... it worked 😂
Oh, wow, good to know.
Hello,
Thanks a lot for building Req, it's really a life saver 🚀
I'm trying to use Req to communicate with an external service that uses Mutual TLS (client certificates) as authentication.
Is it possible to use Req for this? I have been looking for documentation on Mint but no luck so far. I found a thread in ElixirForum talking about an option which is no longer in the docs or in the source code, so I'm not sure it will work anymore.
Is there any known way of using client certificates to do requests with Req?
Thanks