nerves-hub / nerves_hub

NervesHub client for devices
70 stars 14 forks source link

EC private keys cause devices' non-socket NervesHub requests to fail from v0.4.0 #76

Closed danielspofford closed 5 years ago

danielspofford commented 5 years ago

Reproduction:

  1. have a device with an ec private key
  2. on the device: NervesHub.update/0

Explanation

The root of the issue is here https://github.com/nerves-hub/nerves_hub/blob/v0.4.0/lib/nerves_hub/http_client.ex#L47

We pass the private key to Certificate.pem_to_der() here: https://github.com/nerves-hub/nerves_hub/blob/v0.4.0/lib/nerves_hub/certificate.ex#L25

which uses X509.Certificate.from_pem/1 in all cases, even though as in this case it is possible it will be called with a key, not a cert.

Solution

In this case, we should be calling X509.PrivateKey.from_pem/1 like Socket does here: https://github.com/nerves-hub/nerves_hub/blob/v0.4.0/lib/nerves_hub/socket.ex#L63

--

Edit: In the wild this leads to a relatively cryptic error message:

** (exit) exited in: :gen_statem.call(#PID<0.1835.0>, {:start, 8000}, :infinity)
    ** (EXIT) an exception was raised:
        ** (MatchError) no match of right hand side value: {:error, {:asn1, {{:invalid_value, 0}, [{:asn1rt_nif, :decode_ber_tlv, 1, [file: 'asn1rt_nif.erl', line: 85]}, {:"OTP-PUB-KEY", :decode, 2, [file: 'OTP-PUB-KEY.erl', line: 1109]}, {:public_key, :der_decode, 2, [file: 'public_key.erl', line: 280]}, {:ssl_config, :init_private_key, 5, [file: 'ssl_config.erl', line: 121]}, {:ssl_config, :init, 2, [file: 'ssl_config.erl', line: 38]}, {:ssl_connection, :ssl_config, 4, [file: 'ssl_connection.erl', line: 602]}, {:tls_connection, :init, 1, [file: 'tls_connection.erl', line: 132]}, {:proc_lib, :init_p_do_apply, 3, [file: 'proc_lib.erl', line: 249]}]}}}
            (public_key) public_key.erl:284: :public_key.der_decode/2
            (ssl) ssl_config.erl:121: :ssl_config.init_private_key/5
            (ssl) ssl_config.erl:38: :ssl_config.init/2
            (ssl) ssl_connection.erl:602: :ssl_connection.ssl_config/4
            (ssl) tls_connection.erl:132: :tls_connection.init/1
            (stdlib) proc_lib.erl:249: :proc_lib.init_p_do_apply/3
    (stdlib) gen.erl:177: :gen.do_call/4
    (stdlib) gen_statem.erl:598: :gen_statem.call_dirty/4
    (ssl) ssl_connection.erl:2202: :ssl_connection.call/2
    (ssl) ssl_connection.erl:122: :ssl_connection.handshake/2
    (ssl) tls_connection.erl:90: :tls_connection.start_fsm/8
    (ssl) ssl_connection.erl:91: :ssl_connection.connect/8
    (ssl) ssl.erl:125: :ssl.connect/4
    (hackney) /Users/daniel/dev/git/very-possible/some_client/some_repo_name/deps/hackney/src/hackney_connect.erl:279: :hackney_connect.do_connect/5
fhunleth commented 5 years ago

Sounds good. Could you send a PR?

danielspofford commented 5 years ago

It's on the list of todos for sure! This is a crazy week leading up to a company retreat so it's a bit hectic ATM :)

fhunleth commented 5 years ago

Fixed in 4469e7684df763c922b6921eba45c8c8fa493f48.