@@ -58,15 +58,56 @@ defmodule EasySSL do
5858 }
5959 }
6060 """
61- def parse_der ( certificate_der ) when is_binary ( certificate_der ) do
61+ def parse_der ( certificate_der , opts \\ [ all_domains: false , serialize: false ] ) when is_binary ( certificate_der ) do
6262 cert = :public_key . pkix_decode_cert ( certificate_der , :otp ) |> get_field ( :tbsCertificate )
6363
64- % { }
64+ serialized_certificate = % { }
6565 |> Map . put ( :fingerprint , certificate_der |> fingerprint_cert )
6666 |> Map . put ( :serial_number , cert |> get_field ( :serialNumber ) |> Integer . to_string ( 16 ) )
6767 |> Map . put ( :subject , cert |> parse_subject )
6868 |> Map . put ( :extensions , cert |> parse_extensions )
6969 |> Map . merge ( parse_expiry ( cert ) )
70+
71+ Enum . reduce ( opts , serialized_certificate , fn { option , flag } , serialized_certificate ->
72+ case option do
73+ :all_domains when flag == true ->
74+ serialized_certificate
75+ |> Map . put ( :all_domains , get_all_domain_names ( cert , serialized_certificate ) )
76+
77+ :serialize when flag == true ->
78+ serialized_certificate
79+ |> Map . put ( :as_der , Base . encode64 ( certificate_der ) )
80+ _ -> serialized_certificate
81+ end
82+ end )
83+ end
84+
85+ def get_all_domain_names ( cert , serialized_cert ) do
86+ domain_names = MapSet . new ( )
87+
88+ domain_names = case serialized_cert [ :subject ] [ :CN ] do
89+ nil -> domain_names
90+ _ -> MapSet . put ( domain_names , serialized_cert [ :subject ] [ :CN ] )
91+ end
92+
93+ extensions = cert |> get_field ( :extensions )
94+
95+ extensions
96+ |> Enum . reduce ( domain_names , fn extension , domain_names ->
97+ case extension do
98+ { :Extension , { 2 , 5 , 29 , 17 } , _critical , san_entries } ->
99+ san_entries
100+ |> Enum . reduce ( domain_names , fn entry , names ->
101+ case entry do
102+ { :dNSName , dns_name } -> MapSet . put ( names , dns_name |> to_string )
103+ _ -> names
104+ end
105+ end )
106+ :asn1_NOVALUE -> domain_names
107+ _ -> domain_names
108+ end
109+ end )
110+ |> MapSet . to_list
70111 end
71112
72113 @ doc """
@@ -104,7 +145,7 @@ defmodule EasySSL do
104145 }
105146"""
106147 def parse_pem ( cert_charlist ) when is_list ( cert_charlist ) do parse_pem ( cert_charlist |> to_string ) end
107- def parse_pem ( cert_pem ) do
148+ def parse_pem ( cert_pem , opts \\ [ all_domains: false , return_base64: false ] ) do
108149 cert_regex = ~r/ ^\- {5}BEGIN\s CERTIFICATE\- {5}\n (?<certificate>[^\- ]+)\- {5}END\s CERTIFICATE\- {5}/
109150 match = Regex . named_captures ( cert_regex , cert_pem )
110151
@@ -115,7 +156,7 @@ defmodule EasySSL do
115156 match [ "certificate" ]
116157 |> String . replace ( "\n " , "" )
117158 |> Base . decode64!
118- |> parse_der
159+ |> parse_der ( opts )
119160 end
120161
121162 defp get_field ( record , field ) do
@@ -284,7 +325,7 @@ defmodule EasySSL do
284325
285326 # Basically ignore those
286327 { :directoryName , _sequence } -> san_list
287- { :otherName , other_name } -> san_list
328+ { :otherName , _sequence } -> san_list
288329
289330 _ ->
290331 raise ( "Unhandled SAN entry type #{ inspect entry } " )
0 commit comments