[PlatformSpecific(TestPlatforms.Windows | TestPlatforms.Linux)]
public static void RevocationCheckingDelayed(PkiOptions pkiOptions)
{
- CertificateAuthority.BuildPrivatePki(
- pkiOptions,
- out RevocationResponder responder,
- out CertificateAuthority rootAuthority,
- out CertificateAuthority intermediateAuthority,
- out X509Certificate2 endEntityCert,
- nameof(RevocationCheckingDelayed));
-
- using (responder)
- using (rootAuthority)
- using (intermediateAuthority)
- using (endEntityCert)
- using (ChainHolder holder = new ChainHolder())
- using (X509Certificate2 rootCert = rootAuthority.CloneIssuerCert())
- using (X509Certificate2 intermediateCert = intermediateAuthority.CloneIssuerCert())
- {
- TimeSpan delay = TimeSpan.FromSeconds(8);
-
- X509Chain chain = holder.Chain;
- responder.ResponseDelay = delay;
- responder.DelayedActions = RevocationResponder.DelayedActionsFlag.All;
-
- // This needs to be greater than delay, but less than 2x delay to ensure
- // that the time is a timeout for individual fetches, not a running total.
- chain.ChainPolicy.UrlRetrievalTimeout = TimeSpan.FromSeconds(15);
- chain.ChainPolicy.TrustMode = X509ChainTrustMode.CustomRootTrust;
- chain.ChainPolicy.CustomTrustStore.Add(rootCert);
- chain.ChainPolicy.ExtraStore.Add(intermediateCert);
- chain.ChainPolicy.RevocationMode = X509RevocationMode.Online;
- chain.ChainPolicy.RevocationFlag = X509RevocationFlag.ExcludeRoot;
-
- chain.ChainPolicy.DisableCertificateDownloads = true;
-
- Stopwatch watch = Stopwatch.StartNew();
- Assert.True(
- Retry(() =>
- {
- watch.Restart();
- return chain.Build(endEntityCert);
- }),
- $"chain.Build; Chain status: {chain.AllStatusFlags()}");
- watch.Stop();
-
- // There should be two network fetches, OCSP/CRL to intermediate to get leaf status,
- // OCSP/CRL to root to get intermediate statuses. It should take at least 2x the delay
- // plus other non-network time, so we can at least ensure it took as long as
- // the delay for each fetch.
- Assert.True(watch.Elapsed >= delay * 2, $"watch.Elapsed: {watch.Elapsed}");
- }
+ RetryHelper.Execute(() => {
+ CertificateAuthority.BuildPrivatePki(
+ pkiOptions,
+ out RevocationResponder responder,
+ out CertificateAuthority rootAuthority,
+ out CertificateAuthority intermediateAuthority,
+ out X509Certificate2 endEntityCert,
+ nameof(RevocationCheckingDelayed));
+
+ using (responder)
+ using (rootAuthority)
+ using (intermediateAuthority)
+ using (endEntityCert)
+ using (ChainHolder holder = new ChainHolder())
+ using (X509Certificate2 rootCert = rootAuthority.CloneIssuerCert())
+ using (X509Certificate2 intermediateCert = intermediateAuthority.CloneIssuerCert())
+ {
+ TimeSpan delay = TimeSpan.FromSeconds(8);
+
+ X509Chain chain = holder.Chain;
+ responder.ResponseDelay = delay;
+ responder.DelayedActions = RevocationResponder.DelayedActionsFlag.All;
+
+ // This needs to be greater than delay, but less than 2x delay to ensure
+ // that the time is a timeout for individual fetches, not a running total.
+ chain.ChainPolicy.UrlRetrievalTimeout = TimeSpan.FromSeconds(15);
+ chain.ChainPolicy.TrustMode = X509ChainTrustMode.CustomRootTrust;
+ chain.ChainPolicy.CustomTrustStore.Add(rootCert);
+ chain.ChainPolicy.ExtraStore.Add(intermediateCert);
+ chain.ChainPolicy.RevocationMode = X509RevocationMode.Online;
+ chain.ChainPolicy.RevocationFlag = X509RevocationFlag.ExcludeRoot;
+
+ chain.ChainPolicy.DisableCertificateDownloads = true;
+
+ Stopwatch watch = Stopwatch.StartNew();
+ Assert.True(chain.Build(endEntityCert), $"chain.Build; Chain status: {chain.AllStatusFlags()}");
+ watch.Stop();
+
+ // There should be two network fetches, OCSP/CRL to intermediate to get leaf status,
+ // OCSP/CRL to root to get intermediate statuses. It should take at least 2x the delay
+ // plus other non-network time, so we can at least ensure it took as long as
+ // the delay for each fetch.
+ Assert.True(watch.Elapsed >= delay * 2, $"watch.Elapsed: {watch.Elapsed}");
+ }
+ });
}
[Theory]
[PlatformSpecific(TestPlatforms.Windows | TestPlatforms.Linux)]
public static void RevocationCheckingNegativeTimeout(PkiOptions pkiOptions)
{
- CertificateAuthority.BuildPrivatePki(
- pkiOptions,
- out RevocationResponder responder,
- out CertificateAuthority rootAuthority,
- out CertificateAuthority intermediateAuthority,
- out X509Certificate2 endEntityCert,
- nameof(RevocationCheckingNegativeTimeout));
-
- using (responder)
- using (rootAuthority)
- using (intermediateAuthority)
- using (endEntityCert)
- using (ChainHolder holder = new ChainHolder())
- using (X509Certificate2 rootCert = rootAuthority.CloneIssuerCert())
- using (X509Certificate2 intermediateCert = intermediateAuthority.CloneIssuerCert())
- {
- // Delay is more than the 15 second default.
- TimeSpan delay = TimeSpan.FromSeconds(25);
+ RetryHelper.Execute(() => {
+ CertificateAuthority.BuildPrivatePki(
+ pkiOptions,
+ out RevocationResponder responder,
+ out CertificateAuthority rootAuthority,
+ out CertificateAuthority intermediateAuthority,
+ out X509Certificate2 endEntityCert,
+ nameof(RevocationCheckingNegativeTimeout));
+
+ using (responder)
+ using (rootAuthority)
+ using (intermediateAuthority)
+ using (endEntityCert)
+ using (ChainHolder holder = new ChainHolder())
+ using (X509Certificate2 rootCert = rootAuthority.CloneIssuerCert())
+ using (X509Certificate2 intermediateCert = intermediateAuthority.CloneIssuerCert())
+ {
+ // Delay is more than the 15 second default.
+ TimeSpan delay = TimeSpan.FromSeconds(25);
- X509Chain chain = holder.Chain;
- responder.ResponseDelay = delay;
- responder.DelayedActions = RevocationResponder.DelayedActionsFlag.All;
+ X509Chain chain = holder.Chain;
+ responder.ResponseDelay = delay;
+ responder.DelayedActions = RevocationResponder.DelayedActionsFlag.All;
- chain.ChainPolicy.UrlRetrievalTimeout = TimeSpan.FromMinutes(-1);
- chain.ChainPolicy.TrustMode = X509ChainTrustMode.CustomRootTrust;
- chain.ChainPolicy.CustomTrustStore.Add(rootCert);
- chain.ChainPolicy.ExtraStore.Add(intermediateCert);
- chain.ChainPolicy.RevocationMode = X509RevocationMode.Online;
- chain.ChainPolicy.RevocationFlag = X509RevocationFlag.EndCertificateOnly;
+ chain.ChainPolicy.UrlRetrievalTimeout = TimeSpan.FromMinutes(-1);
+ chain.ChainPolicy.TrustMode = X509ChainTrustMode.CustomRootTrust;
+ chain.ChainPolicy.CustomTrustStore.Add(rootCert);
+ chain.ChainPolicy.ExtraStore.Add(intermediateCert);
+ chain.ChainPolicy.RevocationMode = X509RevocationMode.Online;
+ chain.ChainPolicy.RevocationFlag = X509RevocationFlag.EndCertificateOnly;
- chain.ChainPolicy.DisableCertificateDownloads = true;
+ chain.ChainPolicy.DisableCertificateDownloads = true;
- Assert.True(Retry(() => chain.Build(endEntityCert)), $"chain.Build; Chain status: {chain.AllStatusFlags()}");
- }
+ Assert.True(chain.Build(endEntityCert), $"chain.Build; Chain status: {chain.AllStatusFlags()}");
+ }
+ });
}
[Fact]
[PlatformSpecific(TestPlatforms.Linux)]
public static void AiaFetchDelayed()
{
- CertificateAuthority.BuildPrivatePki(
- PkiOptions.OcspEverywhere,
- out RevocationResponder responder,
- out CertificateAuthority rootAuthority,
- out CertificateAuthority intermediateAuthority,
- out X509Certificate2 endEntityCert,
- nameof(AiaFetchDelayed));
+ RetryHelper.Execute(() => {
+ CertificateAuthority.BuildPrivatePki(
+ PkiOptions.OcspEverywhere,
+ out RevocationResponder responder,
+ out CertificateAuthority rootAuthority,
+ out CertificateAuthority intermediateAuthority,
+ out X509Certificate2 endEntityCert,
+ nameof(AiaFetchDelayed));
+
+ using (responder)
+ using (rootAuthority)
+ using (intermediateAuthority)
+ using (endEntityCert)
+ using (ChainHolder holder = new ChainHolder())
+ using (X509Certificate2 rootCert = rootAuthority.CloneIssuerCert())
+ using (X509Certificate2 intermediateCert = intermediateAuthority.CloneIssuerCert())
+ {
+ TimeSpan delay = TimeSpan.FromSeconds(1);
- using (responder)
- using (rootAuthority)
- using (intermediateAuthority)
- using (endEntityCert)
- using (ChainHolder holder = new ChainHolder())
- using (X509Certificate2 rootCert = rootAuthority.CloneIssuerCert())
- using (X509Certificate2 intermediateCert = intermediateAuthority.CloneIssuerCert())
- {
- TimeSpan delay = TimeSpan.FromSeconds(1);
+ X509Chain chain = holder.Chain;
+ responder.ResponseDelay = delay;
+ responder.DelayedActions = RevocationResponder.DelayedActionsFlag.All;
- X509Chain chain = holder.Chain;
- responder.ResponseDelay = delay;
- responder.DelayedActions = RevocationResponder.DelayedActionsFlag.All;
+ chain.ChainPolicy.UrlRetrievalTimeout = TimeSpan.FromSeconds(15);
+ chain.ChainPolicy.TrustMode = X509ChainTrustMode.CustomRootTrust;
+ chain.ChainPolicy.CustomTrustStore.Add(rootCert);
+ chain.ChainPolicy.RevocationMode = X509RevocationMode.NoCheck;
- chain.ChainPolicy.UrlRetrievalTimeout = TimeSpan.FromSeconds(15);
- chain.ChainPolicy.TrustMode = X509ChainTrustMode.CustomRootTrust;
- chain.ChainPolicy.CustomTrustStore.Add(rootCert);
- chain.ChainPolicy.RevocationMode = X509RevocationMode.NoCheck;
+ Stopwatch watch = Stopwatch.StartNew();
+ Assert.True(chain.Build(endEntityCert), GetFlags(chain, endEntityCert.Thumbprint).ToString());
+ watch.Stop();
- Stopwatch watch = Stopwatch.StartNew();
- Assert.True(
- Retry(() =>
- {
- watch.Restart();
- return chain.Build(endEntityCert);
- }),
- GetFlags(chain, endEntityCert.Thumbprint).ToString());
- watch.Stop();
-
- Assert.True(watch.Elapsed >= delay, $"watch.Elapsed: {watch.Elapsed}");
- }
+ Assert.True(watch.Elapsed >= delay, $"watch.Elapsed: {watch.Elapsed}");
+ }
+ });
}
[Fact]
chain.ChainElements.OfType<X509ChainElement>().
Single(e => e.Certificate.Thumbprint == thumbprint).
ChainElementStatus.Aggregate((X509ChainStatusFlags)0, (a, e) => a | e.Status);
-
- private static bool Retry(Func<bool> body, int times = 3)
- {
- for (int attempt = 0; attempt < times; attempt++)
- {
- if (body())
- {
- return true;
- }
- }
-
- return false;
- }
}
}