willc0de4food
Sending / receiving TCP requests with SSL certificate
Hello,
I’m attempting to communicate with the Verisign EPP server over a TCP / SSL connection. This connection requires an SSL certificate, but I’m having trouble with the SSL certificate. I am inexperienced in working with anything like this, in the past all I’ve done is use Req to send various requests of different verbs. So has anyone written a library to make this easier? Or can anyone assist in the correct configuration of including an SSL certificate, sending a request and listening for a response? Here’s what I have so far, just shooting in the dark:
def ssl_client() do
host = Application.get_env(:appname, :epp_host) |> String.to_charlist()
port = Application.get_env(:appname, :epp_port)
cert = File.cwd!() <> "/ssl/cert.chain.pem"
{:ok, connect_socket} =
:ssl.connect(host, port, [verify: :verify_none, cacertfile: cert, active: true], :infinity)
connect_socket
end
defp listen_ssl(socket) do
case :ssl.recv(socket, 0) do
{:ok, line} ->
IO.puts(~s(Client got: "#{String.trim(line)}"))
:ok = :ssl.close(socket)
{:error, :closed} ->
IO.puts("Server closed socket.")
{:error, :enotconn} ->
IO.puts("Server is not connected.")
{:error, reason} ->
IO.puts("Server errored with code: #{reason}")
end
end
def send_ssl_request(line) do
socket = ssl_client()
:ssl.send(socket, line)
listen_ssl(socket)
end
The response that I get when I attempt to call send_ssl_request() is:
TLS :client: In state :connection received SERVER ALERT: Fatal - Bad Certificate
Thanks!
Marked As Solved
willc0de4food
I finally found the right combination of options to get it working. What a pain! Somehow this ended up working:
def ssl_start() do
host = Application.get_env(:appname, :epp_host) |> String.to_charlist()
port = Application.get_env(:appname, :epp_port)
certs = File.cwd!() <> "/ssl/certs.pem"
key = File.cwd!() <> "/ssl/key.pem"
:public_key.cacerts_load(certs)
opts = [
cacerts: :public_key.cacerts_get(),
verify: :verify_none,
certfile: certs,
keyfile: key
]
:ssl.start()
case :ssl.connect(host, port, opts, 5000) do
{:ok, socket} ->
socket
{:error, err} ->
dbg(err)
nil
end
end
I received a file with 1 key & 3 certs. I tried separating each cert into it’s own file, but the working combination was to have the 3 certs in 1 file, and the key in another.
Also Liked
D4no0
On what are you running this server? It might be possible that you are missing the client certificates on your deployed system, the symptom usually is that it works on dev envs but fails on deployed server.
To check that fast, you can try adding castore to your project and use the provided certs by castore with: CAStore.file_path()
muelthe
A couple of things that have caught me out in the past, one being when using :public_key_cacerts_get() I didn’t have the certificate store configured correctly on my host machine.
Second, I’ve found that I also need to include the server_name_indication (SNI) in my ssl opts (some info here on SNI: https://www.cloudflare.com/learning/ssl/what-is-sni/).
Popular in Questions
Other popular topics
Categories:
Sub Categories:
Forums
Popular Tags
- #ecto
- #liveview
- #troubleshooting
- #learning-elixir
- #deployment
- #library
- #erlang
- #testing
- #genserver
- #mix
- #absinthe
- #remote-other
- #otp
- #plug
- #how-to-question
- #macros
- #postgres
- #channels
- #elixirconf
- #exunit
- #discussion
- #code-sync
- #javascript
- #podcasts
- #onsite
- #dialyzer
- #docker
- #authentication
- #umbrella
- #full-time-contract
- #podcasts-by-brainlid
- #ecto-query
- #elixir-ls
- #phoenix_html
- #iex
- #blog-post
- #graphql
- #genstage
- #ai
- #websockets
- #supervisor
- #elixirconf-us
- #advent-of-code
- #distillery
- #processes
- #forms
- #api
- #metaprogramming
- #security
- #hex









