Skip to content
Open
Show file tree
Hide file tree
Changes from 2 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 @@ -196,7 +196,7 @@ private void ReadPolicies(List<X509Certificate2> chain)
}
else
{
inhibitAnyPolicyDepth--;
inhibitPolicyMappingDepth--;
}

if (explicitPolicyDepth <= 0)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1039,6 +1039,58 @@ public static void PolicyConstraints_Mapped()
}
}

[Fact]
[SkipOnPlatform(TestPlatforms.Linux, "Not supported on Linux.")]
public static void PolicyConstraints_AnyPolicyInhibited_Success()
{
X509Extension[] intermediate1Extensions = new[]
{
BasicConstraintsCA,
BuildPolicyMappings(("1.2.3.5", "1.2.3.6")),
};

X509Extension[] intermediate2Extensions = new[]
{
BasicConstraintsCA,
BuildPolicyMappings(("1.2.3.7", "1.2.3.8")),
};

X509Extension[] endEntityExtensions = new[]
{
BasicConstraintsEndEntity,
BuildPolicyByIdentifiers("1.2.3.4"),
};

TestDataGenerator.MakeTestChain4(
out X509Certificate2 endEntityCert,
out X509Certificate2 intermediateCert1,
out X509Certificate2 intermediateCert2,
out X509Certificate2 rootCert,
endEntityExtensions,
intermediate1Extensions,
intermediate2Extensions,
rootExtensions: null);

using (endEntityCert)
using (intermediateCert1)
using (intermediateCert2)
using (rootCert)
using (ChainHolder chainHolder = new ChainHolder())
{
X509Chain chain = chainHolder.Chain;
chain.ChainPolicy.TrustMode = X509ChainTrustMode.CustomRootTrust;
chain.ChainPolicy.CustomTrustStore.Add(rootCert);
chain.ChainPolicy.ExtraStore.Add(intermediateCert1);
chain.ChainPolicy.ExtraStore.Add(intermediateCert2);
chain.ChainPolicy.VerificationTime = endEntityCert.NotBefore.AddSeconds(1);
chain.ChainPolicy.RevocationMode = X509RevocationMode.NoCheck;
chain.ChainPolicy.CertificatePolicy.Add(new Oid("1.2.3.4"));

bool result = chain.Build(endEntityCert);
AssertExtensions.TrueExpression(result);
}
}

public enum BuildChainWithNotSignatureValidTest : int
{
TrustedRoot,
Expand Down Expand Up @@ -1345,6 +1397,15 @@ private static X509Extension BuildPolicyMappings(
return new X509Extension("2.5.29.33", writer.Encode(), critical: true);
}

private static X509Extension BuildInhibitAnyPolicy(int skipCerts)
{
// InhibitAnyPolicy ::= SkipCerts
// SkipCerts ::= INTEGER (0..MAX)
AsnWriter writer = new AsnWriter(AsnEncodingRules.DER);
writer.WriteInteger(skipCerts);
return new X509Extension("2.5.29.54", writer.Encode(), critical: true);
}

private static void TestChain3(
X509Certificate2 rootCertificate,
X509Certificate2 intermediateCertificate,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,149 @@ internal static void MakeTestChain4(
}
}

internal static void MakeTestChain4(
out X509Certificate2 endEntityCert,
out X509Certificate2 intermediateCert1,
out X509Certificate2 intermediateCert2,
out X509Certificate2 rootCert,
IEnumerable<X509Extension> endEntityExtensions,
IEnumerable<X509Extension> intermediate1Extensions,
IEnumerable<X509Extension> intermediate2Extensions,
IEnumerable<X509Extension> rootExtensions,
[CallerMemberName] string testName = null)
{
using (RSA rootKey = RSA.Create())
using (RSA intermediateKey1 = RSA.Create())
using (RSA intermediateKey2 = RSA.Create())
using (RSA endEntityKey = RSA.Create())
{
ReadOnlySpan<RSA> keys = new[]
{
rootKey,
intermediateKey1,
intermediateKey2,
endEntityKey,
};

Span<X509Certificate2> certs = new X509Certificate2[keys.Length];

// Build root
HashAlgorithmName hashAlgorithm = HashAlgorithmName.SHA256;
RSASignaturePadding signaturePadding = RSASignaturePadding.Pkcs1;
int rootIndex = keys.Length - 1;
DateTimeOffset eeStart = DateTimeOffset.UtcNow.AddDays(-7);
DateTimeOffset eeEnd = eeStart.AddDays(45);
TimeSpan notBeforeInterval = TimeSpan.FromDays(30);
TimeSpan notAfterInterval = TimeSpan.FromDays(90);

CertificateRequest rootReq = new CertificateRequest(
$"CN=Test Root, O=\"{testName}\"",
keys[rootIndex],
hashAlgorithm,
signaturePadding);

rootExtensions ??= new X509Extension[] {
new X509BasicConstraintsExtension(true, false, 0, true),
new X509KeyUsageExtension(
X509KeyUsageFlags.CrlSign |
X509KeyUsageFlags.KeyCertSign |
X509KeyUsageFlags.DigitalSignature,
false)
};

foreach (X509Extension ext in rootExtensions)
{
rootReq.CertificateExtensions.Add(ext);
}

X509SignatureGenerator lastGenerator = X509SignatureGenerator.CreateForRSA(keys[rootIndex], RSASignaturePadding.Pkcs1);
X500DistinguishedName lastSubject = rootReq.SubjectName;

certs[rootIndex] = rootReq.Create(
lastSubject,
lastGenerator,
eeStart - (notBeforeInterval * rootIndex),
eeEnd + (notAfterInterval * rootIndex),
CreateSerial());

CertificateRequest int2Req = new CertificateRequest(
$"CN=Intermediate Layer 2, O=\"{testName}\"",
keys[2],
hashAlgorithm,
signaturePadding);
intermediate2Extensions ??= new X509Extension[] {
new X509BasicConstraintsExtension(true, false, 0, true),
new X509KeyUsageExtension(
X509KeyUsageFlags.CrlSign |
X509KeyUsageFlags.KeyCertSign |
X509KeyUsageFlags.DigitalSignature,
false)
};
foreach (X509Extension ext in intermediate2Extensions)
{
int2Req.CertificateExtensions.Add(ext);
}
certs[2] = int2Req.Create(
lastSubject,
lastGenerator,
eeStart - (notBeforeInterval * 2),
eeEnd + (notAfterInterval * 2),
CreateSerial());
lastSubject = int2Req.SubjectName;
lastGenerator = X509SignatureGenerator.CreateForRSA(keys[2], RSASignaturePadding.Pkcs1);

CertificateRequest int1Req = new CertificateRequest(
$"CN=Intermediate Layer 1, O=\"{testName}\"",
keys[1],
hashAlgorithm,
signaturePadding);
intermediate1Extensions ??= new X509Extension[] {
new X509BasicConstraintsExtension(true, false, 0, true),
new X509KeyUsageExtension(
X509KeyUsageFlags.CrlSign |
X509KeyUsageFlags.KeyCertSign |
X509KeyUsageFlags.DigitalSignature,
false)
};
foreach (X509Extension ext in intermediate1Extensions)
{
int1Req.CertificateExtensions.Add(ext);
}
certs[1] = int1Req.Create(
lastSubject,
lastGenerator,
eeStart - (notBeforeInterval * 1),
eeEnd + (notAfterInterval * 1),
CreateSerial());
lastSubject = int1Req.SubjectName;
lastGenerator = X509SignatureGenerator.CreateForRSA(keys[1], RSASignaturePadding.Pkcs1);

CertificateRequest eeReq = new CertificateRequest(
$"CN=End-Entity, O=\"{testName}\"",
keys[0],
hashAlgorithm,
signaturePadding);
endEntityExtensions ??= new X509Extension[] {
new X509BasicConstraintsExtension(false, false, 0, true),
new X509KeyUsageExtension(
X509KeyUsageFlags.DigitalSignature |
X509KeyUsageFlags.NonRepudiation |
X509KeyUsageFlags.KeyEncipherment,
false)
};
foreach (X509Extension ext in endEntityExtensions)
{
eeReq.CertificateExtensions.Add(ext);
}
certs[0] = eeReq.Create(lastSubject, lastGenerator, eeStart, eeEnd, CreateSerial());

endEntityCert = certs[0];
intermediateCert1 = certs[1];
intermediateCert2 = certs[2];
rootCert = certs[3];
}
}

internal static void MakeTestChain(
ReadOnlySpan<RSA> keys,
Span<X509Certificate2> certs,
Expand Down
Loading