@@ -106,6 +106,7 @@ pub mod windows {
106106 use std:: sync:: Arc ;
107107
108108 use anyhow:: Context as _;
109+ use parking_lot:: Mutex ;
109110 use rustls_cng:: signer:: CngSigningKey ;
110111 use rustls_cng:: store:: { CertStore , CertStoreType } ;
111112 use tokio_rustls:: rustls:: pki_types:: CertificateDer ;
@@ -114,12 +115,21 @@ pub mod windows {
114115
115116 use crate :: config:: dto;
116117
118+ const CACHE_DURATION : time:: Duration = time:: Duration :: seconds ( 45 ) ;
119+
117120 #[ derive( Debug ) ]
118121 pub struct ServerCertResolver {
119122 machine_hostname : String ,
120123 subject_name : String ,
121124 store_type : CertStoreType ,
122125 store_name : String ,
126+ cached_key : Mutex < Option < KeyCache > > ,
127+ }
128+
129+ #[ derive( Debug ) ]
130+ struct KeyCache {
131+ key : Arc < CertifiedKey > ,
132+ expires_at : time:: OffsetDateTime ,
123133 }
124134
125135 impl ServerCertResolver {
@@ -140,6 +150,7 @@ pub mod windows {
140150 subject_name : cert_subject_name,
141151 store_type,
142152 store_name,
153+ cached_key : Mutex :: new ( None ) ,
143154 } )
144155 }
145156
@@ -170,10 +181,20 @@ pub mod windows {
170181 )
171182 }
172183
184+ let mut cache_guard = self . cached_key . lock ( ) ;
185+
186+ let now = time:: OffsetDateTime :: now_utc ( ) ;
187+
188+ if let Some ( cache) = cache_guard. as_ref ( ) {
189+ if now < cache. expires_at {
190+ trace ! ( "Used certified key from cache" ) ;
191+ return Ok ( Arc :: clone ( & cache. key ) ) ;
192+ }
193+ }
194+
173195 let store = CertStore :: open ( self . store_type , & self . store_name ) . context ( "open Windows certificate store" ) ?;
174196
175197 // Look up certificate by subject.
176- // TODO(perf): the resolution result could probably be cached.
177198 let contexts = store. find_by_subject_str ( & self . subject_name ) . with_context ( || {
178199 format ! (
179200 "failed to find server certificate for {} from system store" ,
@@ -189,7 +210,7 @@ pub mod windows {
189210
190211 trace ! ( subject_name = %self . subject_name, count = contexts. len( ) , "Found certificate contexts" ) ;
191212
192- let now = picky:: x509:: date:: UtcDate :: now ( ) ;
213+ let x509_date_now = picky:: x509:: date:: UtcDate :: from ( now ) ;
193214
194215 // Initial processing and filtering of the available candidates.
195216 let mut contexts: Vec < CertHandleCtx > = contexts
@@ -212,7 +233,7 @@ pub mod windows {
212233
213234 trace ! ( %idx, %serial_number, %subject, %issuer, %not_before, %not_after, "Parsed store certificate" ) ;
214235
215- if now < not_before {
236+ if x509_date_now < not_before {
216237 debug ! (
217238 %idx, %serial_number, %not_before, "Filtered out certificate based on not before validity date"
218239 ) ;
@@ -284,12 +305,20 @@ pub mod windows {
284305 . context ( "certification chain is not available for this certificate" ) ?;
285306 let certs = chain. into_iter ( ) . map ( CertificateDer :: from) . collect ( ) ;
286307
287- // Return CertifiedKey instance.
288- return Ok ( Arc :: new ( CertifiedKey {
308+ let key = Arc :: new ( CertifiedKey {
289309 cert : certs,
290310 key : Arc :: new ( key) ,
291311 ocsp : None ,
292- } ) ) ;
312+ } ) ;
313+
314+ * cache_guard = Some ( KeyCache {
315+ key : key. clone ( ) ,
316+ expires_at : now + CACHE_DURATION ,
317+ } ) ;
318+ trace ! ( "Cached certified key" ) ;
319+
320+ // Return CertifiedKey instance.
321+ return Ok ( key) ;
293322
294323 struct CertHandleCtx {
295324 idx : usize ,
0 commit comments