-
Notifications
You must be signed in to change notification settings - Fork 14
/
socket.ex
68 lines (53 loc) · 1.7 KB
/
socket.ex
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
defmodule NervesHub.Socket do
alias NervesHub.Certificate
@cert "nerves_hub_cert"
@key "nerves_hub_key"
def opts(nil), do: opts([])
def opts(user_config) when is_list(user_config) do
ca_certs = user_config[:cacerts] || Certificate.ca_certs()
{cert_key, cert_value} = cert(user_config)
{key_key, key_value} = key(user_config)
server_name = Application.get_env(:nerves_hub, :device_api_host)
server_port = Application.get_env(:nerves_hub, :device_api_port)
sni = Application.get_env(:nerves_hub, :device_api_sni)
url = "wss://#{server_name}:#{server_port}/socket/websocket"
socket_opts =
[
cacerts: ca_certs,
server_name_indication: to_charlist(sni)
]
|> Keyword.put(cert_key, cert_value)
|> Keyword.put(key_key, key_value)
default_config = [
url: url,
serializer: Jason,
ssl_verify: :verify_peer,
transport_opts: [socket_opts: socket_opts]
]
Keyword.merge(default_config, user_config)
end
def cert(opts) do
cond do
opts[:certfile] != nil -> {:certfile, opts[:certfile]}
opts[:cert] != nil -> {:cert, opts[:cert]}
true -> {:cert, Nerves.Runtime.KV.get(@cert) |> Certificate.pem_to_der()}
end
end
def key(opts) do
cond do
opts[:keyfile] != nil ->
{:keyfile, opts[:keyfile]}
opts[:key] != nil ->
{:key, opts[:key]}
true ->
{:key, {:ECPrivateKey, Nerves.Runtime.KV.get(@key) |> key_pem_to_der()}}
end
end
defp key_pem_to_der(nil), do: <<>>
defp key_pem_to_der(pem) do
case X509.PrivateKey.from_pem(pem) do
{:error, :not_found} -> <<>>
{:ok, decoded} -> X509.PrivateKey.to_der(decoded)
end
end
end