@@ -169,6 +169,7 @@ defmodule Plug.SSL do
169169 |> check_for_missing_keys ( )
170170 |> validate_ciphers ( )
171171 |> normalize_ssl_files ( )
172+ |> normalize_certs_keys_ssl_files ( )
172173 |> convert_to_charlist ( )
173174 |> set_secure_defaults ( )
174175 |> configure_managed_tls ( )
@@ -179,24 +180,45 @@ defmodule Plug.SSL do
179180 end
180181
181182 defp check_for_missing_keys ( options ) do
183+ has_certs_keys? = List . keymember? ( options , :certs_keys , 0 )
182184 has_sni? = List . keymember? ( options , :sni_hosts , 0 ) or List . keymember? ( options , :sni_fun , 0 )
183185 has_key? = List . keymember? ( options , :key , 0 ) or List . keymember? ( options , :keyfile , 0 )
184186 has_cert? = List . keymember? ( options , :cert , 0 ) or List . keymember? ( options , :certfile , 0 )
185187
186188 cond do
187189 has_sni? -> options
188- not has_key? -> fail ( "missing option :key/:keyfile" )
189- not has_cert? -> fail ( "missing option :cert/:certfile" )
190+ not ( has_key? or has_certs_keys? ) -> fail ( "missing option :key/:keyfile/:certs_keys " )
191+ not ( has_cert? or has_certs_keys? ) -> fail ( "missing option :cert/:certfile/:certs_keys " )
190192 true -> options
191193 end
192194 end
193195
194196 defp normalize_ssl_files ( options ) do
195197 ssl_files = [ :keyfile , :certfile , :cacertfile , :dhfile ]
196- Enum . reduce ( ssl_files , options , & normalize_ssl_file ( & 1 , & 2 ) )
198+ Enum . reduce ( ssl_files , options , & normalize_ssl_file ( & 1 , & 2 , options [ :otp_app ] ) )
197199 end
198200
199- defp normalize_ssl_file ( key , options ) do
201+ defp normalize_certs_keys_ssl_files ( options ) do
202+ if certs_keys = options [ :certs_keys ] do
203+ ssl_files = [ :keyfile , :certfile ]
204+
205+ updated_certs_keys =
206+ Enum . map ( certs_keys , fn cert_key ->
207+ Enum . reduce (
208+ ssl_files ,
209+ Map . to_list ( cert_key ) ,
210+ & normalize_ssl_file ( & 1 , & 2 , options [ :otp_app ] )
211+ )
212+ |> Map . new ( )
213+ end )
214+
215+ List . keystore ( options , :certs_keys , 0 , { :certs_keys , updated_certs_keys } )
216+ else
217+ options
218+ end
219+ end
220+
221+ defp normalize_ssl_file ( key , options , otp_app ) do
200222 value = options [ key ]
201223
202224 cond do
@@ -207,7 +229,7 @@ defmodule Plug.SSL do
207229 put_ssl_file ( options , key , value )
208230
209231 true ->
210- put_ssl_file ( options , key , Path . expand ( value , otp_app ( options ) ) )
232+ put_ssl_file ( options , key , Path . expand ( value , resolve_otp_app ( otp_app ) ) )
211233 end
212234 end
213235
@@ -225,9 +247,9 @@ defmodule Plug.SSL do
225247 List . keystore ( options , key , 0 , { key , value } )
226248 end
227249
228- defp otp_app ( options ) do
229- if app = options [ : otp_app] do
230- Application . app_dir ( app )
250+ defp resolve_otp_app ( otp_app ) do
251+ if otp_app do
252+ Application . app_dir ( otp_app )
231253 else
232254 fail ( "the :otp_app option is required when setting relative SSL certfiles" )
233255 end
0 commit comments