64 lines
1.9 KiB
Elixir
64 lines
1.9 KiB
Elixir
|
defmodule ChronoscopeWeb.API.NTS.KeyExchangeController do
|
||
|
use ChronoscopeWeb, :controller
|
||
|
|
||
|
require Logger
|
||
|
|
||
|
@default_port "4460"
|
||
|
@timeout_in_milliseconds 3000
|
||
|
|
||
|
def get(conn, params) do
|
||
|
host = to_charlist(params["host"])
|
||
|
port = String.to_integer(params["port"] || @default_port)
|
||
|
|
||
|
tls_options = :tls_certificate_check.options(host) ++ [alpn_advertised_protocols: ["ntse/1"]]
|
||
|
|
||
|
case :ssl.connect(host, port, tls_options, @timeout_in_milliseconds) do
|
||
|
{:ok, socket} ->
|
||
|
key_exchange_request =
|
||
|
<<0x80, 0x01, 0x00, 0x02, 0x00, 0x00, 0x80, 0x04, 0x00, 0x04, 0x00, 0x1E, 0x00, 0x0F,
|
||
|
0x80, 0x00, 0x00, 0x00>>
|
||
|
|
||
|
:ok = :ssl.send(socket, key_exchange_request)
|
||
|
|
||
|
receive do
|
||
|
{:ssl, _socket, data} ->
|
||
|
:ssl.close(socket)
|
||
|
ok_response(conn, %{status: :ok, response: parse_response(data)})
|
||
|
|
||
|
msg ->
|
||
|
:ssl.close(socket)
|
||
|
Logger.error("received unexpected message: #{inspect(msg)}")
|
||
|
ok_response(conn, %{status: :error, reason: :no_response})
|
||
|
after
|
||
|
@timeout_in_milliseconds ->
|
||
|
:ssl.close(socket)
|
||
|
Logger.error("timed out waiting for response")
|
||
|
ok_response(conn, %{status: :error, reason: :timeout})
|
||
|
end
|
||
|
|
||
|
{:error, {:tls_alert, {:handshake_failure, error}}} ->
|
||
|
ok_response(conn, %{status: :error, reason: to_string(error)})
|
||
|
|
||
|
{:error, error} ->
|
||
|
ok_response(conn, %{status: :error, reason: inspect(error)})
|
||
|
|
||
|
error ->
|
||
|
ok_response(conn, %{status: :error, reason: inspect(error)})
|
||
|
end
|
||
|
end
|
||
|
|
||
|
defp parse_response([0x80 | _] = _data) do
|
||
|
"success"
|
||
|
end
|
||
|
|
||
|
defp parse_response(_data) do
|
||
|
"failure"
|
||
|
end
|
||
|
|
||
|
defp ok_response(conn, body) do
|
||
|
conn
|
||
|
|> Plug.Conn.put_resp_content_type("application/json")
|
||
|
|> Plug.Conn.send_resp(:ok, Jason.encode!(body))
|
||
|
end
|
||
|
end
|