Skip to content
Open
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ private static bool TrustsMicrosoftDotComRoot
using (var chainHolder = new ChainHolder())
{
X509Chain chain = chainHolder.Chain;
chain.ChainPolicy.VerificationTime = new DateTime(2021, 02, 26, 12, 01, 01, DateTimeKind.Local);
chain.ChainPolicy.VerificationTime = new DateTime(2025, 12, 25, 12, 01, 01, DateTimeKind.Local);
chain.ChainPolicy.RevocationMode = X509RevocationMode.NoCheck;

return chain.Build(microsoftDotCom);
Expand All @@ -50,7 +50,7 @@ public static void BuildChain()

// Halfway between microsoftDotCom's NotBefore and NotAfter
// This isn't a boundary condition test.
chain.ChainPolicy.VerificationTime = new DateTime(2021, 02, 26, 12, 01, 01, DateTimeKind.Local);
chain.ChainPolicy.VerificationTime = new DateTime(2025, 12, 25, 12, 01, 01, DateTimeKind.Local);
chain.ChainPolicy.RevocationMode = X509RevocationMode.NoCheck;

bool valid = chain.Build(microsoftDotCom);
Expand Down Expand Up @@ -82,7 +82,7 @@ public static void VerifyChainFromHandle()
chain.ChainPolicy.ExtraStore.Add(microsoftDotComRoot);
chain.ChainPolicy.ExtraStore.Add(microsoftDotComIssuer);
chain.ChainPolicy.VerificationFlags = X509VerificationFlags.AllowUnknownCertificateAuthority;
chain.ChainPolicy.VerificationTime = new DateTime(2021, 02, 26, 12, 01, 01, DateTimeKind.Local);
chain.ChainPolicy.VerificationTime = new DateTime(2025, 12, 25, 12, 01, 01, DateTimeKind.Local);
chain.ChainPolicy.RevocationMode = X509RevocationMode.NoCheck;

bool valid = chain.Build(microsoftDotCom);
Expand Down Expand Up @@ -113,7 +113,7 @@ public static void VerifyChainFromHandle()

// Re-set the ChainPolicy properties
chain2.ChainPolicy.VerificationFlags = X509VerificationFlags.AllowUnknownCertificateAuthority;
chain2.ChainPolicy.VerificationTime = new DateTime(2021, 02, 26, 12, 01, 01, DateTimeKind.Local);
chain2.ChainPolicy.VerificationTime = new DateTime(2025, 12, 25, 12, 01, 01, DateTimeKind.Local);
chain2.ChainPolicy.RevocationMode = X509RevocationMode.NoCheck;

valid = chain2.Build(microsoftDotCom);
Expand All @@ -137,7 +137,7 @@ public static void VerifyChainFromHandle_Unix()
chain.ChainPolicy.ExtraStore.Add(microsoftDotComIssuer);
chain.ChainPolicy.VerificationFlags = X509VerificationFlags.AllowUnknownCertificateAuthority;

chain.ChainPolicy.VerificationTime = new DateTime(2021, 02, 26, 12, 01, 01, DateTimeKind.Local);
chain.ChainPolicy.VerificationTime = new DateTime(2025, 12, 25, 12, 01, 01, DateTimeKind.Local);
chain.ChainPolicy.RevocationMode = X509RevocationMode.NoCheck;

bool valid = chain.Build(microsoftDotCom);
Expand All @@ -159,7 +159,7 @@ public static void TestDispose()
{
chain = chainHolder.Chain;
chain.ChainPolicy.VerificationFlags = X509VerificationFlags.AllowUnknownCertificateAuthority;
chain.ChainPolicy.VerificationTime = new DateTime(2021, 02, 26, 12, 01, 01, DateTimeKind.Local);
chain.ChainPolicy.VerificationTime = new DateTime(2025, 12, 25, 12, 01, 01, DateTimeKind.Local);
chain.ChainPolicy.RevocationMode = X509RevocationMode.NoCheck;
chain.Build(microsoftDotCom);

Expand Down Expand Up @@ -288,11 +288,7 @@ public static void SystemTrustCertificateWithCustomRootTrust(bool addCertificate

// Check some known conditions.

if (OperatingSystem.IsLinux() || PlatformDetection.IsApplePlatform26OrLater)
{
Assert.Equal(2, chain.ChainElements.Count);
}
else if (PlatformDetection.IsOSXLike)
if (OperatingSystem.IsLinux() || PlatformDetection.UsesAppleCrypto)
{
Assert.Equal(3, chain.ChainElements.Count);
}
Expand All @@ -314,10 +310,6 @@ public static IEnumerable<object[]> BuildChainCustomTrustStoreData()
{
// Android doesn't support an empty custom root
X509ChainStatusFlags flags = X509ChainStatusFlags.UntrustedRoot;
if (!SignatureSupport.SupportsX509Sha1Signatures)
{
flags |= X509ChainStatusFlags.NotSignatureValid;
}
yield return new object[] { false, flags, BuildChainCustomTrustStoreTestArguments.TrustedIntermediateUntrustedRoot };
}

Expand Down Expand Up @@ -427,30 +419,24 @@ public static void Invalidx509ChainTrustMode(int trustMode)
public static IEnumerable<object[]> VerifyExpirationData()
{
// The test will be using the chain for TestData.MicrosoftDotComSslCertBytes
// The leaf cert (microsoft.com) is valid from 2020-08-28 22:17:02Z to 2021-08-28 22:17:02Z
DateTime[] validTimes =
{
// The NotBefore value
new DateTime(2020, 08, 28, 22, 17, 02, DateTimeKind.Utc),

// One second before the NotAfter value
new DateTime(2021, 08, 28, 22, 17, 01, DateTimeKind.Utc),
};
DateTime notBefore = new DateTime(2025, 10, 01, 05, 17, 14, DateTimeKind.Utc);
DateTime notAfter = new DateTime(2026, 03, 30, 05, 17, 14, DateTimeKind.Utc);

// The NotAfter value as a boundary condition differs on Windows and OpenSSL.
// Windows considers it valid (<= NotAfter).
// OpenSSL considers it invalid (< NotAfter), with a comment along the lines of
// "it'll be invalid in a millisecond, why bother with the <="
// So that boundary condition is not being tested.
DateTime[] validTimes = [notBefore, notAfter.AddSeconds(-1)];

DateTime[] invalidTimes =
{
[
// One second before the NotBefore time
new DateTime(2020, 08, 28, 22, 17, 01, DateTimeKind.Utc),
notBefore.AddSeconds(-1),

// One second after the NotAfter time
new DateTime(2021, 08, 28, 22, 17, 03, DateTimeKind.Utc),
};
notAfter.AddSeconds(1)
];

List<object[]> testCases = new List<object[]>((validTimes.Length + invalidTimes.Length) * 3);

Expand Down Expand Up @@ -502,7 +488,10 @@ public static void VerifyExpiration_LocalTime(DateTime verificationTime, bool sh

bool builtSuccessfully = chain.Build(microsoftDotCom);

Assert.Equal(shouldBeValid, builtSuccessfully);
if (shouldBeValid != builtSuccessfully)
{
Assert.Fail($"Expected chain validity to be '{shouldBeValid}' but was '{builtSuccessfully}'. Chain flags: '{chain.AllStatusFlags()}'.");
}

// If we failed to build the chain, validate the chain status
if (!shouldBeValid)
Expand Down Expand Up @@ -656,11 +645,14 @@ public static void BuildChain_FailOnlyApplicationPolicy()
X509ChainStatusFlags.NoError,
(a, status) => a | status.Status));

Assert.Equal(
X509ChainStatusFlags.NotValidForUsage,
holder.Chain.ChainElements[2].ChainElementStatus.Aggregate(
X509ChainStatusFlags.NoError,
(a, status) => a | status.Status));
if (!PlatformDetection.IsWindows)
{
Assert.Equal(
X509ChainStatusFlags.NotValidForUsage,
holder.Chain.ChainElements[2].ChainElementStatus.Aggregate(
X509ChainStatusFlags.NoError,
(a, status) => a | status.Status));
}
}
}

Expand Down Expand Up @@ -748,7 +740,7 @@ public static void BuildChain_MicrosoftDotCom_WithRootCertInUserAndSystemRootCer
}

X509Chain chainValidator = chainHolder.Chain;
chainValidator.ChainPolicy.VerificationTime = new DateTime(2021, 02, 26, 12, 01, 01, DateTimeKind.Local);
chainValidator.ChainPolicy.VerificationTime = new DateTime(2025, 12, 25, 12, 01, 01, DateTimeKind.Local);
chainValidator.ChainPolicy.RevocationMode = X509RevocationMode.NoCheck;

bool chainBuildResult = chainValidator.Build(microsoftDotCom);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -903,7 +903,7 @@ public static void X509ChainElementCollection_CopyTo_NonZeroLowerBound_ThrowsInd

// Halfway between microsoftDotCom's NotBefore and NotAfter
// This isn't a boundary condition test.
chain.ChainPolicy.VerificationTime = new DateTime(2021, 02, 26, 12, 01, 01, DateTimeKind.Local);
chain.ChainPolicy.VerificationTime = new DateTime(2025, 12, 25, 12, 01, 01, DateTimeKind.Local);

bool valid = chain.Build(microsoftDotCom);
Assert.True(valid, "Precondition: Chain built validly");
Expand Down Expand Up @@ -1317,7 +1317,7 @@ public static void X509ChainElementCollection_IndexerVsEnumerator()

// Halfway between microsoftDotCom's NotBefore and NotAfter
// This isn't a boundary condition test.
chain.ChainPolicy.VerificationTime = new DateTime(2021, 02, 26, 12, 01, 01, DateTimeKind.Local);
chain.ChainPolicy.VerificationTime = new DateTime(2025, 12, 25, 12, 01, 01, DateTimeKind.Local);
chain.ChainPolicy.RevocationMode = X509RevocationMode.NoCheck;

bool valid = chain.Build(microsoftDotCom);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -91,14 +91,14 @@ public static void CreateKeyIdOnlyFromCertificate()
}

Assert.False(akid.Critical, "akid.Critical");
Assert.Equal("30168014B5760C3011CEC792424D4CC75C2CC8A90CE80B64", akid.RawData.ByteArrayToHex());
Assert.Equal("30168014F67E2FBD80A34AB2705BEBDF9A1FD8EDCA618007", akid.RawData.ByteArrayToHex());
Assert.False(akid.RawIssuer.HasValue, "akid.RawIssuer.HasValue");
Assert.Null(akid.NamedIssuer);
Assert.False(akid.SerialNumber.HasValue, "akid.SerialNumber.HasValue");
Assert.True(akid.KeyIdentifier.HasValue, "akid.KeyIdentifier.HasValue");

Assert.Equal(
"B5760C3011CEC792424D4CC75C2CC8A90CE80B64",
"F67E2FBD80A34AB2705BEBDF9A1FD8EDCA618007",
akid.KeyIdentifier.GetValueOrDefault().ByteArrayToHex());
}

Expand Down Expand Up @@ -128,10 +128,10 @@ public static void CreateIssuerAndSerialFromCertificate()
Assert.False(akid.KeyIdentifier.HasValue, "akid.KeyIdentifier.HasValue");

const string ExpectedHex =
"3072A15EA45C305A310B300906035504061302494531123010060355040A1309" +
"42616C74696D6F726531133011060355040B130A437962657254727573743122" +
"30200603550403131942616C74696D6F7265204379626572547275737420526F" +
"6F7482100F14965F202069994FD5C7AC788941E2";
"3079A165A4633061310B300906035504061302555331153013060355040A130C" +
"446967694365727420496E6331193017060355040B13107777772E6469676963" +
"6572742E636F6D3120301E06035504031317446967694365727420476C6F6261" +
"6C20526F6F7420473282100EFB7E547EDF0FF1069AEE57696D7BA0";

Assert.Equal(ExpectedHex, akid.RawData.ByteArrayToHex());
}
Expand Down Expand Up @@ -162,15 +162,15 @@ public static void CreateFullFromCertificate()
Assert.True(akid.KeyIdentifier.HasValue, "akid.KeyIdentifier.HasValue");

Assert.Equal(
"B5760C3011CEC792424D4CC75C2CC8A90CE80B64",
"F67E2FBD80A34AB2705BEBDF9A1FD8EDCA618007",
akid.KeyIdentifier.GetValueOrDefault().ByteArrayToHex());

const string ExpectedHex =
"3081888014B5760C3011CEC792424D4CC75C2CC8A90CE80B64A15EA45C305A31" +
"0B300906035504061302494531123010060355040A130942616C74696D6F7265" +
"31133011060355040B130A437962657254727573743122302006035504031319" +
"42616C74696D6F7265204379626572547275737420526F6F7482100F14965F20" +
"2069994FD5C7AC788941E2";
"30818F8014F67E2FBD80A34AB2705BEBDF9A1FD8EDCA618007A165A463306131" +
"0B300906035504061302555331153013060355040A130C446967694365727420" +
"496E6331193017060355040B13107777772E64696769636572742E636F6D3120" +
"301E06035504031317446967694365727420476C6F62616C20526F6F74204732" +
"82100EFB7E547EDF0FF1069AEE57696D7BA0";

Assert.Equal(ExpectedHex, akid.RawData.ByteArrayToHex());
}
Expand Down Expand Up @@ -517,10 +517,10 @@ public static void CreateIssuerAndSerial(bool fromArray)
Assert.False(akid.KeyIdentifier.HasValue, "akid.KeyIdentifier.HasValue");

const string ExpectedHex =
"3072A15EA45C305A310B300906035504061302494531123010060355040A1309" +
"42616C74696D6F726531133011060355040B130A437962657254727573743122" +
"30200603550403131942616C74696D6F7265204379626572547275737420526F" +
"6F7482100F14965F202069994FD5C7AC788941E2";
"3079A165A4633061310B300906035504061302555331153013060355040A130C" +
"446967694365727420496E6331193017060355040B13107777772E6469676963" +
"6572742E636F6D3120301E06035504031317446967694365727420476C6F6261" +
"6C20526F6F7420473282100EFB7E547EDF0FF1069AEE57696D7BA0";

Assert.Equal(ExpectedHex, akid.RawData.ByteArrayToHex());
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,17 +15,17 @@ public static class MatchesHostnameTests
[InlineData("fruit.example", false)]
[InlineData("127.0.0.1", false)]
[InlineData("microsoft.com", true)]
[InlineData("www.microsoft.com", true)]
[InlineData("wwwqa.microsoft.com", true)]
[InlineData("www.microsoft.com.au", true)]
[InlineData("copilot.ai", true)]
[InlineData("wwwqa2.microsoft.com", false)]
[InlineData("staticview.microsoft.com", true)]
[InlineData("c.s-microsoft.com", true)]
[InlineData("i.s-microsoft.com", true)]
[InlineData("j.s-microsoft.com", false)]
[InlineData("yarp.dot.net", true)]
[InlineData("explore-smb.microsoft.com", true)]
[InlineData("real-stories.microsoft.com", true)]
[InlineData("ghost-stories.microsoft.com", false)]
[InlineData("s-microsoft.com", false)]
[InlineData("privacy.microsoft.com", true)]
[InlineData("more.privacy.microsoft.com", false)]
[InlineData("moreprivacy.microsoft.com", false)]
[InlineData("discover.copilot.com", true)]
[InlineData("more.discover.copilot.com", false)]
[InlineData("morediscover.copilot.com", false)]
public static void MicrosoftDotComSslMatchesHostname(string candidate, bool expected)
{
using (X509Certificate2 cert = new X509Certificate2(TestData.MicrosoftDotComSslCertBytes))
Expand Down
Loading
Loading