Skip to content

Use RetryHelper with AIA tests #55230

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 2 commits into from
Jul 9, 2021
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -29,22 +29,26 @@ public static void EmptyAiaResponseIsIgnored()
using (CertificateAuthority intermediate1 = intermediates[0])
using (CertificateAuthority intermediate2 = intermediates[1])
using (endEntity)
using (ChainHolder holder = new ChainHolder())
using (X509Certificate2 intermediate2Cert = intermediate2.CloneIssuerCert())
{
responder.RespondEmpty = true;

X509Chain chain = holder.Chain;
chain.ChainPolicy.ExtraStore.Add(intermediate2Cert);
chain.ChainPolicy.TrustMode = X509ChainTrustMode.CustomRootTrust;
chain.ChainPolicy.VerificationTime = endEntity.NotBefore.AddMinutes(1);
chain.ChainPolicy.UrlRetrievalTimeout = DynamicRevocationTests.s_urlRetrievalLimit;
chain.ChainPolicy.RevocationMode = X509RevocationMode.NoCheck;

Assert.False(chain.Build(endEntity));
X509ChainStatusFlags chainFlags = chain.AllStatusFlags();
Assert.True(chainFlags.HasFlag(X509ChainStatusFlags.PartialChain), $"expected partial chain flags, got {chainFlags}");
Assert.Equal(2, chain.ChainElements.Count);
RetryHelper.Execute(() => {
using (ChainHolder holder = new ChainHolder())
{
X509Chain chain = holder.Chain;
chain.ChainPolicy.ExtraStore.Add(intermediate2Cert);
chain.ChainPolicy.TrustMode = X509ChainTrustMode.CustomRootTrust;
chain.ChainPolicy.VerificationTime = endEntity.NotBefore.AddMinutes(1);
chain.ChainPolicy.UrlRetrievalTimeout = DynamicRevocationTests.s_urlRetrievalLimit;
chain.ChainPolicy.RevocationMode = X509RevocationMode.NoCheck;

Assert.False(chain.Build(endEntity));
X509ChainStatusFlags chainFlags = chain.AllStatusFlags();
Assert.True(chainFlags.HasFlag(X509ChainStatusFlags.PartialChain), $"expected partial chain flags, got {chainFlags}");
Assert.Equal(2, chain.ChainElements.Count);
}
});
}
}

Expand All @@ -65,72 +69,76 @@ public static void DisableAiaOptionWorks()
using (root)
using (intermediate)
using (endEntity)
using (ChainHolder holder = new ChainHolder())
using (X509Certificate2 rootCert = root.CloneIssuerCert())
using (X509Certificate2 intermediateCert = intermediate.CloneIssuerCert())
using (var cuCaStore = new X509Store(StoreName.CertificateAuthority, StoreLocation.CurrentUser))
{
cuCaStore.Open(OpenFlags.ReadWrite);

X509Chain chain = holder.Chain;
RetryHelper.Execute(() => {
using (ChainHolder holder = new ChainHolder())
using (var cuCaStore = new X509Store(StoreName.CertificateAuthority, StoreLocation.CurrentUser))
{
cuCaStore.Open(OpenFlags.ReadWrite);

// macOS combines revocation and AIA fetching in to a single flag. Both need to be disabled
// to prevent AIA fetches.
if (PlatformDetection.IsOSX)
{
chain.ChainPolicy.RevocationMode = X509RevocationMode.NoCheck;
}
X509Chain chain = holder.Chain;

chain.ChainPolicy.DisableCertificateDownloads = true;
chain.ChainPolicy.CustomTrustStore.Add(rootCert);
chain.ChainPolicy.TrustMode = X509ChainTrustMode.CustomRootTrust;
chain.ChainPolicy.VerificationTime = endEntity.NotBefore.AddMinutes(1);
chain.ChainPolicy.UrlRetrievalTimeout = DynamicRevocationTests.s_urlRetrievalLimit;
// macOS combines revocation and AIA fetching in to a single flag. Both need to be disabled
// to prevent AIA fetches.
if (PlatformDetection.IsOSX)
{
chain.ChainPolicy.RevocationMode = X509RevocationMode.NoCheck;
}

Assert.False(chain.Build(endEntity), "Chain build with no intermediate, AIA disabled");
chain.ChainPolicy.DisableCertificateDownloads = true;
chain.ChainPolicy.CustomTrustStore.Add(rootCert);
chain.ChainPolicy.TrustMode = X509ChainTrustMode.CustomRootTrust;
chain.ChainPolicy.VerificationTime = endEntity.NotBefore.AddMinutes(1);
chain.ChainPolicy.UrlRetrievalTimeout = DynamicRevocationTests.s_urlRetrievalLimit;

// If a previous run of this test leaves contamination in the CU\CA store on Windows
// the Windows chain engine will match the bad issuer and report NotSignatureValid instead
// of PartialChain.
X509ChainStatusFlags chainFlags = chain.AllStatusFlags();
Assert.False(chain.Build(endEntity), "Chain build with no intermediate, AIA disabled");

if (chainFlags.HasFlag(X509ChainStatusFlags.NotSignatureValid))
{
Assert.Equal(3, chain.ChainElements.Count);
// If a previous run of this test leaves contamination in the CU\CA store on Windows
// the Windows chain engine will match the bad issuer and report NotSignatureValid instead
// of PartialChain.
X509ChainStatusFlags chainFlags = chain.AllStatusFlags();

foreach (X509Certificate2 storeCert in cuCaStore.Certificates)
{
if (storeCert.Subject.Equals(intermediateCert.Subject))
if (chainFlags.HasFlag(X509ChainStatusFlags.NotSignatureValid))
{
cuCaStore.Remove(storeCert);
}
Assert.Equal(3, chain.ChainElements.Count);

storeCert.Dispose();
}
foreach (X509Certificate2 storeCert in cuCaStore.Certificates)
{
if (storeCert.Subject.Equals(intermediateCert.Subject))
{
cuCaStore.Remove(storeCert);
}

holder.DisposeChainElements();
storeCert.Dispose();
}

// Try again, with no caching side effect.
Assert.False(chain.Build(endEntity), "Chain build 2 with no intermediate, AIA disabled");
}
holder.DisposeChainElements();

Assert.Equal(1, chain.ChainElements.Count);
Assert.Contains(X509ChainStatusFlags.PartialChain, chain.ChainStatus.Select(s => s.Status));
holder.DisposeChainElements();
// Try again, with no caching side effect.
Assert.False(chain.Build(endEntity), "Chain build 2 with no intermediate, AIA disabled");
}

Assert.Equal(1, chain.ChainElements.Count);
Assert.Contains(X509ChainStatusFlags.PartialChain, chain.ChainStatus.Select(s => s.Status));
holder.DisposeChainElements();

chain.ChainPolicy.ExtraStore.Add(intermediateCert);
Assert.True(chain.Build(endEntity), "Chain build with intermediate, AIA disabled");
Assert.Equal(3, chain.ChainElements.Count);
Assert.Equal(X509ChainStatusFlags.NoError, chain.AllStatusFlags());
holder.DisposeChainElements();
chain.ChainPolicy.ExtraStore.Add(intermediateCert);
Assert.True(chain.Build(endEntity), "Chain build with intermediate, AIA disabled");
Assert.Equal(3, chain.ChainElements.Count);
Assert.Equal(X509ChainStatusFlags.NoError, chain.AllStatusFlags());
holder.DisposeChainElements();

chain.ChainPolicy.DisableCertificateDownloads = false;
chain.ChainPolicy.ExtraStore.Clear();
Assert.True(chain.Build(endEntity), "Chain build with no intermediate, AIA enabled");
Assert.Equal(3, chain.ChainElements.Count);
Assert.Equal(X509ChainStatusFlags.NoError, chain.AllStatusFlags());
chain.ChainPolicy.DisableCertificateDownloads = false;
chain.ChainPolicy.ExtraStore.Clear();
Assert.True(chain.Build(endEntity), "Chain build with no intermediate, AIA enabled");
Assert.Equal(3, chain.ChainElements.Count);
Assert.Equal(X509ChainStatusFlags.NoError, chain.AllStatusFlags());

cuCaStore.Remove(intermediateCert);
cuCaStore.Remove(intermediateCert);
}
});
}
}
}
Expand Down