@@ -15,12 +15,14 @@ namespace System.Security.Cryptography
1515 /// </summary>
1616 public sealed partial class CngKey : IDisposable
1717 {
18- //
19- // Key properties
20- //
21-
2218 private const int CachedKeySizeUninitializedSentinel = - 1 ;
23- private int _cachedKeySize = CachedKeySizeUninitializedSentinel ;
19+ private volatile int _cachedKeySize = CachedKeySizeUninitializedSentinel ;
20+
21+ private volatile CngAlgorithm ? _cachedAlgorithm ;
22+ private volatile bool _hasCachedAlgorithmGroup ;
23+ private volatile CngAlgorithmGroup ? _cachedAlgorithmGroup ;
24+ private volatile bool _hasCachedProvider ;
25+ private volatile CngProvider ? _cachedProvider ;
2426
2527 /// <summary>
2628 /// Algorithm group this key can be used with
@@ -29,25 +31,38 @@ public CngAlgorithm Algorithm
2931 {
3032 get
3133 {
32- string algorithm = _keyHandle . GetPropertyAsString ( KeyPropertyName . Algorithm , CngPropertyOptions . None ) ! ;
33- // .NET Framework compat: Don't check for null. Just let CngAlgorithm handle it.
34- return new CngAlgorithm ( algorithm ) ;
35- }
34+ if ( _cachedAlgorithm is null || _keyHandle . IsClosed )
35+ {
36+ string algorithm = _keyHandle . GetPropertyAsString ( KeyPropertyName . Algorithm , CngPropertyOptions . None ) ! ;
3637
38+ // .NET Framework compat: Don't check for null. Just let CngAlgorithm handle it.
39+ _cachedAlgorithm = new CngAlgorithm ( algorithm ) ;
40+ }
41+
42+ return _cachedAlgorithm ;
43+ }
3744 }
3845
3946 /// <summary>
4047 /// Name of the algorithm this key can be used with
4148 /// </summary>
4249 public CngAlgorithmGroup ? AlgorithmGroup
43-
4450 {
4551 get
4652 {
47- string ? algorithmGroup = _keyHandle . GetPropertyAsString ( KeyPropertyName . AlgorithmGroup , CngPropertyOptions . None ) ;
48- if ( algorithmGroup == null )
49- return null ;
50- return new CngAlgorithmGroup ( algorithmGroup ) ;
53+ if ( ! _hasCachedAlgorithmGroup || _keyHandle . IsClosed )
54+ {
55+ string ? algorithmGroup = _keyHandle . GetPropertyAsString ( KeyPropertyName . AlgorithmGroup , CngPropertyOptions . None ) ;
56+
57+ if ( algorithmGroup is not null )
58+ {
59+ _cachedAlgorithmGroup = new CngAlgorithmGroup ( algorithmGroup ) ;
60+ }
61+
62+ _hasCachedAlgorithmGroup = true ;
63+ }
64+
65+ return _cachedAlgorithmGroup ;
5166 }
5267 }
5368
@@ -242,7 +257,6 @@ int ComputeKeySize()
242257 /// Usage restrictions on the key
243258 /// </summary>
244259 public CngKeyUsages KeyUsage
245-
246260 {
247261 get
248262 {
@@ -279,10 +293,19 @@ public CngProvider? Provider
279293 {
280294 get
281295 {
282- string ? provider = _providerHandle . GetPropertyAsString ( ProviderPropertyName . Name , CngPropertyOptions . None ) ;
283- if ( provider == null )
284- return null ;
285- return new CngProvider ( provider ) ;
296+ if ( ! _hasCachedProvider || _providerHandle . IsClosed )
297+ {
298+ string ? provider = _providerHandle . GetPropertyAsString ( ProviderPropertyName . Name , CngPropertyOptions . None ) ;
299+
300+ if ( provider is not null )
301+ {
302+ _cachedProvider = new CngProvider ( provider ) ;
303+ }
304+
305+ _hasCachedProvider = true ;
306+ }
307+
308+ return _cachedProvider ;
286309 }
287310 }
288311
0 commit comments