@@ -169,6 +169,7 @@ defmodule Plug.SSL do
169
169
|> check_for_missing_keys ( )
170
170
|> validate_ciphers ( )
171
171
|> normalize_ssl_files ( )
172
+ |> normalize_certs_keys_ssl_files ( )
172
173
|> convert_to_charlist ( )
173
174
|> set_secure_defaults ( )
174
175
|> configure_managed_tls ( )
@@ -179,24 +180,45 @@ defmodule Plug.SSL do
179
180
end
180
181
181
182
defp check_for_missing_keys ( options ) do
183
+ has_certs_keys? = List . keymember? ( options , :certs_keys , 0 )
182
184
has_sni? = List . keymember? ( options , :sni_hosts , 0 ) or List . keymember? ( options , :sni_fun , 0 )
183
185
has_key? = List . keymember? ( options , :key , 0 ) or List . keymember? ( options , :keyfile , 0 )
184
186
has_cert? = List . keymember? ( options , :cert , 0 ) or List . keymember? ( options , :certfile , 0 )
185
187
186
188
cond do
187
189
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 " )
190
192
true -> options
191
193
end
192
194
end
193
195
194
196
defp normalize_ssl_files ( options ) do
195
197
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 ] ) )
197
199
end
198
200
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
200
222
value = options [ key ]
201
223
202
224
cond do
@@ -207,7 +229,7 @@ defmodule Plug.SSL do
207
229
put_ssl_file ( options , key , value )
208
230
209
231
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 ) ) )
211
233
end
212
234
end
213
235
@@ -225,9 +247,9 @@ defmodule Plug.SSL do
225
247
List . keystore ( options , key , 0 , { key , value } )
226
248
end
227
249
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 )
231
253
else
232
254
fail ( "the :otp_app option is required when setting relative SSL certfiles" )
233
255
end
0 commit comments