6
6
using System . Linq ;
7
7
using System . Security . Cryptography . X509Certificates ;
8
8
using Microsoft . Extensions . Configuration ;
9
+ using Microsoft . Extensions . Logging ;
9
10
10
11
namespace Microsoft . AspNetCore
11
12
{
@@ -15,32 +16,53 @@ namespace Microsoft.AspNetCore
15
16
public class CertificateLoader
16
17
{
17
18
private readonly IConfiguration _certificatesConfiguration ;
19
+ private readonly string _environmentName ;
18
20
private readonly ICertificateFileLoader _certificateFileLoader ;
19
21
private readonly ICertificateStoreLoader _certificateStoreLoader ;
22
+ private readonly ILogger _logger ;
20
23
21
24
/// <summary>
22
- /// Creates a new instance of <see cref="CertificateLoader"/>.
25
+ /// Creates a new instance of <see cref="CertificateLoader"/> that can load certificate references from configuration .
23
26
/// </summary>
24
- public CertificateLoader ( )
25
- : this ( null )
27
+ /// <param name="certificatesConfiguration">An <see cref="IConfiguration"/> with information about certificates.</param>
28
+ public CertificateLoader ( IConfiguration certificatesConfiguration )
29
+ : this ( certificatesConfiguration , null , null )
26
30
{
27
31
}
28
32
29
33
/// <summary>
30
34
/// Creates a new instance of <see cref="CertificateLoader"/> that can load certificate references from configuration.
31
35
/// </summary>
32
36
/// <param name="certificatesConfiguration">An <see cref="IConfiguration"/> with information about certificates.</param>
33
- public CertificateLoader ( IConfiguration certificatesConfiguration )
34
- : this ( certificatesConfiguration , new CertificateFileLoader ( ) , new CertificateStoreLoader ( ) )
37
+ /// <param name="loggerFactory">An <see cref="ILoggerFactory"/> instance.</param>
38
+ public CertificateLoader ( IConfiguration certificatesConfiguration , ILoggerFactory loggerFactory )
39
+ : this ( certificatesConfiguration , loggerFactory , null )
35
40
{
36
- _certificatesConfiguration = certificatesConfiguration ;
37
41
}
38
42
39
- internal CertificateLoader ( IConfiguration certificatesConfiguration , ICertificateFileLoader certificateFileLoader , ICertificateStoreLoader certificateStoreLoader )
43
+ /// <summary>
44
+ /// Creates a new instance of <see cref="CertificateLoader"/> that can load certificate references from configuration.
45
+ /// </summary>
46
+ /// <param name="certificatesConfiguration">An <see cref="IConfiguration"/> with information about certificates.</param>
47
+ /// <param name="loggerFactory">An <see cref="ILoggerFactory"/> instance.</param>
48
+ /// <param name="environmentName">The name of the environment the application is running in.</param>
49
+ public CertificateLoader ( IConfiguration certificatesConfiguration , ILoggerFactory loggerFactory , string environmentName )
50
+ : this ( certificatesConfiguration , loggerFactory , environmentName , new CertificateFileLoader ( ) , new CertificateStoreLoader ( ) )
40
51
{
52
+ }
53
+
54
+ internal CertificateLoader (
55
+ IConfiguration certificatesConfiguration ,
56
+ ILoggerFactory loggerFactory ,
57
+ string environmentName ,
58
+ ICertificateFileLoader certificateFileLoader ,
59
+ ICertificateStoreLoader certificateStoreLoader )
60
+ {
61
+ _environmentName = environmentName ;
41
62
_certificatesConfiguration = certificatesConfiguration ;
42
63
_certificateFileLoader = certificateFileLoader ;
43
64
_certificateStoreLoader = certificateStoreLoader ;
65
+ _logger = loggerFactory ? . CreateLogger ( "Microsoft.AspNetCore.CertificateLoader" ) ;
44
66
}
45
67
46
68
/// <summary>
@@ -99,7 +121,8 @@ private X509Certificate2 LoadSingle(string certificateName)
99
121
100
122
if ( ! certificateConfiguration . Exists ( ) )
101
123
{
102
- throw new InvalidOperationException ( $ "No certificate named { certificateName } found in configuration") ;
124
+ var environmentName = _environmentName != null ? $ " ({ _environmentName } )" : "" ;
125
+ throw new KeyNotFoundException ( $ "No certificate named '{ certificateName } ' found in configuration for the current environment{ environmentName } .") ;
103
126
}
104
127
105
128
return LoadSingle ( certificateConfiguration ) ;
@@ -116,10 +139,10 @@ private X509Certificate2 LoadSingle(IConfigurationSection certificateConfigurati
116
139
certificateSource = new CertificateFileSource ( _certificateFileLoader ) ;
117
140
break ;
118
141
case "store" :
119
- certificateSource = new CertificateStoreSource ( _certificateStoreLoader ) ;
142
+ certificateSource = new CertificateStoreSource ( _certificateStoreLoader , _logger ) ;
120
143
break ;
121
144
default :
122
- throw new InvalidOperationException ( $ "Invalid certificate source kind: { sourceKind } ") ;
145
+ throw new InvalidOperationException ( $ "Invalid certificate source kind ' { sourceKind } '. ") ;
123
146
}
124
147
125
148
certificateConfiguration . Bind ( certificateSource ) ;
@@ -163,7 +186,7 @@ public override X509Certificate2 Load()
163
186
164
187
if ( error != null )
165
188
{
166
- throw error ;
189
+ throw new InvalidOperationException ( $ "Unable to load certificate from file ' { Path } '. Error details: ' { error . Message } '." , error ) ;
167
190
}
168
191
169
192
return certificate ;
@@ -188,10 +211,12 @@ private X509Certificate2 TryLoad(X509KeyStorageFlags flags, out Exception except
188
211
private class CertificateStoreSource : CertificateSource
189
212
{
190
213
private readonly ICertificateStoreLoader _certificateStoreLoader ;
214
+ private readonly ILogger _logger ;
191
215
192
- public CertificateStoreSource ( ICertificateStoreLoader certificateStoreLoader )
216
+ public CertificateStoreSource ( ICertificateStoreLoader certificateStoreLoader , ILogger logger )
193
217
{
194
218
_certificateStoreLoader = certificateStoreLoader ;
219
+ _logger = logger ;
195
220
}
196
221
197
222
public string Subject { get ; set ; }
@@ -203,10 +228,17 @@ public override X509Certificate2 Load()
203
228
{
204
229
if ( ! Enum . TryParse ( StoreLocation , ignoreCase : true , result : out StoreLocation storeLocation ) )
205
230
{
206
- throw new InvalidOperationException ( $ "Invalid store location: { StoreLocation } ") ;
231
+ throw new InvalidOperationException ( $ "The certificate store location '{ StoreLocation } ' is invalid.") ;
232
+ }
233
+
234
+ var certificate = _certificateStoreLoader . Load ( Subject , StoreName , storeLocation , ! AllowInvalid ) ;
235
+
236
+ if ( certificate == null )
237
+ {
238
+ _logger ? . LogWarning ( $ "Unable to find a matching certificate for subject '{ Subject } ' in store '{ StoreName } ' in '{ StoreLocation } '.") ;
207
239
}
208
240
209
- return _certificateStoreLoader . Load ( Subject , StoreName , storeLocation , ! AllowInvalid ) ;
241
+ return certificate ;
210
242
}
211
243
}
212
244
}
0 commit comments