Skip to content
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 @@ -220,26 +220,29 @@ public static void AiaIgnoresCertOverLimit()
[Fact]
public static void AiaCompletionHasLimits()
{
const int IntermediateCount = 6;
const int IntermediateCount = 8;
int iteration = 0;

CertificateAuthority.BuildPrivatePki(
PkiOptions.AllRevocation,
out RevocationResponder responder,
out CertificateAuthority root,
out CertificateAuthority[] intermediates,
out X509Certificate2 endEntity,
intermediateAuthorityCount: IntermediateCount,
pkiOptionsInSubject: false,
testName: nameof(AiaCompletionHasLimits));

using (responder)
using (root)
using (endEntity)
{
try
RetryHelper.Execute(
() =>
{
RetryHelper.Execute(
() =>
iteration++;

CertificateAuthority.BuildPrivatePki(
PkiOptions.AllRevocation,
out RevocationResponder responder,
out CertificateAuthority root,
out CertificateAuthority[] intermediates,
out X509Certificate2 endEntity,
intermediateAuthorityCount: IntermediateCount,
pkiOptionsInSubject: false,
testName: $"{nameof(AiaCompletionHasLimits)}_{iteration}");

using (responder)
using (root)
using (endEntity)
{
try
{
using (ChainHolder holder = new ChainHolder())
{
Expand All @@ -260,25 +263,60 @@ public static void AiaCompletionHasLimits()

// EE, intermediate0 (AIA), intermediate1 (ExtraStore), intermediate2 (AIA).
AssertExtensions.TrueExpression(chain.Build(endEntity));
Assert.Equal(4, chain.ChainElements.Count);
AssertExtensions.HasFlag(X509ChainStatusFlags.PartialChain, chain.AllStatusFlags());

CloneIntoExtraStore(chain, 1);
CloneIntoExtraStore(chain, 3);
holder.DisposeChainElements();

// Previous 4 plus intermediate3 and intermediate4.
AssertExtensions.TrueExpression(chain.Build(endEntity));
Assert.Equal(6, chain.ChainElements.Count);
AssertExtensions.HasFlag(X509ChainStatusFlags.PartialChain, chain.AllStatusFlags());

CloneIntoExtraStore(chain, 4);
CloneIntoExtraStore(chain, 5);
holder.DisposeChainElements();
// Current Windows only allows 2, by black box testing, but 3 does seem to happen
// on some builds. So, variant test for it being over-sized
if (chain.ChainElements.Count == 5)
{
// The ones described above, plus intermediate3(AIA).
AssertExtensions.HasFlag(X509ChainStatusFlags.PartialChain, chain.AllStatusFlags());

CloneIntoExtraStore(chain, 1);
CloneIntoExtraStore(chain, 3);
CloneIntoExtraStore(chain, 4);
holder.DisposeChainElements();

// Previous 5 plus intermediate4, intermediate5, and intermediate6.
AssertExtensions.TrueExpression(chain.Build(endEntity));
Assert.Equal(8, chain.ChainElements.Count);
AssertExtensions.HasFlag(X509ChainStatusFlags.PartialChain, chain.AllStatusFlags());

CloneIntoExtraStore(chain, 5);
CloneIntoExtraStore(chain, 6);
CloneIntoExtraStore(chain, 7);
holder.DisposeChainElements();
}
else
{
Assert.Equal(4, chain.ChainElements.Count);
Comment thread
bartonjs marked this conversation as resolved.
AssertExtensions.HasFlag(X509ChainStatusFlags.PartialChain, chain.AllStatusFlags());

CloneIntoExtraStore(chain, 1);
CloneIntoExtraStore(chain, 3);
holder.DisposeChainElements();

// Previous 4 plus intermediate3 and intermediate4.
AssertExtensions.TrueExpression(chain.Build(endEntity));
Assert.Equal(6, chain.ChainElements.Count);
AssertExtensions.HasFlag(X509ChainStatusFlags.PartialChain, chain.AllStatusFlags());

CloneIntoExtraStore(chain, 4);
CloneIntoExtraStore(chain, 5);
holder.DisposeChainElements();

// Previous 6 plus intermediate5 and intermediate6.
AssertExtensions.TrueExpression(chain.Build(endEntity));
Assert.Equal(8, chain.ChainElements.Count);
AssertExtensions.HasFlag(X509ChainStatusFlags.PartialChain, chain.AllStatusFlags());

CloneIntoExtraStore(chain, 6);
CloneIntoExtraStore(chain, 7);
holder.DisposeChainElements();
}

// AIA fetches intermediate5 and root, chain finishes.
// AIA fetches intermediate7 and root, chain finishes.
AssertExtensions.TrueExpression(chain.Build(endEntity));
Assert.Equal(8, chain.ChainElements.Count);
Assert.Equal(10, chain.ChainElements.Count);
Assert.Equal(X509ChainStatusFlags.UntrustedRoot, chain.AllStatusFlags());
Comment thread
bartonjs marked this conversation as resolved.
}
finally
Expand All @@ -289,22 +327,25 @@ public static void AiaCompletionHasLimits()
}
}
}
});
}
finally
{
foreach (CertificateAuthority intermediate in intermediates)
{
intermediate.Dispose();
}
finally
{
if (intermediates is not null)
{
foreach (CertificateAuthority intermediate in intermediates)
{
intermediate.Dispose();
}
}
}
}
}
});

static void CloneIntoExtraStore(X509Chain chain, int index)
{
ReadOnlySpan<byte> source = chain.ChainElements[index].Certificate.RawDataMemory.Span;
X509Certificate2 cert = X509CertificateLoader.LoadCertificate(source);
chain.ChainPolicy.ExtraStore.Add(cert);
}
static void CloneIntoExtraStore(X509Chain chain, int index)
{
ReadOnlySpan<byte> source = chain.ChainElements[index].Certificate.RawDataMemory.Span;
X509Certificate2 cert = X509CertificateLoader.LoadCertificate(source);
chain.ChainPolicy.ExtraStore.Add(cert);
}
}
}
Expand Down
Loading