public async Task SslStream_ClientCertificate_SendsChain()
{
List<SslStream> streams = new List<SslStream>();
- TestHelper.CleanupCertificates("SslStream_ClinetCertificate_SendsChain");
+ TestHelper.CleanupCertificates();
(X509Certificate2 clientCertificate, X509Certificate2Collection clientChain) = TestHelper.GenerateCertificates("SslStream_ClinetCertificate_SendsChain", serverCertificate: false);
using (X509Store store = new X509Store(StoreName.CertificateAuthority, StoreLocation.CurrentUser))
{
store.Close();
}
- // There is race between adding certificate to the store and building chain
- // Make sure we can build chain before proceeding to ssl handshale
using (var chain = new X509Chain())
{
- int count = 25;
chain.ChainPolicy.VerificationFlags = X509VerificationFlags.AllFlags;
chain.ChainPolicy.RevocationMode = X509RevocationMode.NoCheck;
chain.ChainPolicy.DisableCertificateDownloads = false;
bool chainStatus = chain.Build(clientCertificate);
- while (chain.ChainElements.Count != (clientChain.Count + 1) && count > 0)
- {
- Thread.Sleep(100);
- count--;
- chainStatus = chain.Build(clientCertificate);
- }
-
// Verify we can construct full chain
- Assert.True(chain.ChainElements.Count > clientChain.Count, "chain cannot be built");
+ Assert.True(chain.ChainElements.Count >= clientChain.Count, "chain cannot be built");
}
var clientOptions = new SslClientAuthenticationOptions() { TargetHost = "localhost", };
streams.Add(server);
}
- TestHelper.CleanupCertificates("SslStream_ClinetCertificate_SendsChain");
+ TestHelper.CleanupCertificates();
clientCertificate.Dispose();
foreach (X509Certificate c in clientChain)
{
private SafeX509StackHandle? _nativeCollection;
private DateTime _loadLastWrite;
+ private bool _forceRefresh;
internal CachedDirectoryStoreProvider(string storeName)
{
_storeDirectoryInfo = new DirectoryInfo(storePath);
}
+ internal void DoRefresh()
+ {
+ _forceRefresh = true;
+ }
+
internal SafeX509StackHandle GetNativeCollection()
{
SafeX509StackHandle? ret = _nativeCollection;
TimeSpan elapsed = _recheckStopwatch.Elapsed;
- if (ret == null || elapsed >= s_lastWriteRecheckInterval)
+ if (ret == null || elapsed >= s_lastWriteRecheckInterval || _forceRefresh)
{
lock (_recheckStopwatch)
{
DirectoryInfo info = _storeDirectoryInfo;
if (ret == null ||
+ _forceRefresh ||
elapsed >= s_assumeInvalidInterval ||
(info.Exists && info.LastWriteTimeUtc != _loadLastWrite))
{
ret = newColl;
_nativeCollection = newColl;
_recheckStopwatch.Restart();
+ _forceRefresh = false;
}
}
}
Interop.Crypto.X509StoreCtxCommitToChain(_storeCtx);
}
+ internal static void FlushStores()
+ {
+ s_userRootStore.DoRefresh();
+ s_userPersonalStore.DoRefresh();
+ s_userIntermediateStore.DoRefresh();
+ }
+
internal void ProcessRevocation(
X509RevocationMode revocationMode,
X509RevocationFlag revocationFlag)