CaliDog / EasySSL

SSL certificate parsing for humans
MIT License
36 stars 19 forks source link

MatchError in parse extensions when anything other than :AccessDescription is present when parsing :authorityInfoAccess extensions. #8

Closed toddholmberg closed 4 years ago

toddholmberg commented 4 years ago

I ran into an error recently when parsing a certificate:

10:37:26.790 [error] ** (MatchError) no match of right hand side value: {:AccessDescription, {1, 3, 6, 1, 5, 5, 7, 48, 2}, {:directoryName, {:rdnSequence, [[{:AttributeTypeAndValue, {2, 5, 4, 10}, <<19, 6, 104, 112, 46, 99, 111, 109>>}], [{:AttributeTypeAndValue, {2, 5, 4, 11}, <<19, 17, 73, 84, 32, 73, 110, 102, 114, 97, 115, 116, 114, 117, 99, 116, 117, 114, 101>>}], [{:AttributeTypeAndValue, {2, 5, 4, 6}, <<19, 2, 85, 83>>}], [{:AttributeTypeAndValue, {2, 5, 4, 10}, <<19, 23, 72, 101, 119, 108, 101, 116, 116, 45, 80, 97, 99, 107, 97, 114, 100, 32, 67, 111, 109, 112, 97, 110, 121>>}], [{:AttributeTypeAndValue, {2, 5, 4, 3}, <<19, 55, 72, 101, 119, 108, 101, 116, 116, 45, 80, 97, 99, 107, 97, 114, 100, 32, 80, 114, 105, 118, 97, 116, 101, 32, 67, 108, 97, 115, 115, 32, 50, 32, ...>>}]]}}}
    (easy_ssl 1.1.2) lib/easy_ssl.ex:292: anonymous fn/2 in EasySSL.parse_extensions/1
    (elixir 1.10.1) lib/enum.ex:2111: Enum."-reduce/3-lists^foldl/2-0-"/3
    (easy_ssl 1.1.2) lib/easy_ssl.ex:291: anonymous fn/2 in EasySSL.parse_extensions/1
    (elixir 1.10.1) lib/enum.ex:2111: Enum."-reduce/3-lists^foldl/2-0-"/3
    (easy_ssl 1.1.2) lib/easy_ssl.ex:70: EasySSL.parse_der/2
    (tls_worker 0.1.0) lib/tls_worker/certificate.ex:140: TLSWorker.Certificate.process_certificate/4
    (tls_worker 0.1.0) lib/tls_worker.ex:35: TLSWorker.run_scan/2
    (tls_worker 0.1.0) lib/tls_worker/broadway.ex:135: TLSWorker.Broadway.process_message/1

This occurs because the match on line 292 is too restrictive and causes the above match error.

Current code:

{:Extension, {1, 3, 6, 1, 5, 5, 7, 1, 1}, _critical, authority_info_access} ->
              Map.put(
                extension_map,
                :authorityInfoAccess,
                authority_info_access
                |> Enum.reduce([], fn match, entries ->
                  {:AccessDescription, oid, {:uniformResourceIdentifier, url}} = match
                  ["#{@authority_info_access_oids[oid]}:#{url}" | entries]
                end)
                |> Enum.join("\n")
                |> String.replace_suffix("", "\n")
              )

I propose adding a case clause and ignoring anything that does not fit the first case clause:

{:Extension, {1, 3, 6, 1, 5, 5, 7, 1, 1}, _critical, authority_info_access} ->
              Map.put(
                extension_map,
                :authorityInfoAccess,
                authority_info_access
                |> Enum.reduce([], fn match, entries ->
                  case match do
                    {:AccessDescription, oid, {:uniformResourceIdentifier, url}} -> ["#{@authority_info_access_oids[oid]}:#{url}" | entries]
                    _ -> entries
                  end
                end)
                |> Enum.join("\n")
                |> String.replace_suffix("", "\n")
              )

I have a branch ready for a pull request.

Fitblip commented 4 years ago

This is merged!