XFE Git
XFE Studio Git
Git 首页 全局搜索
XFE 主站 文档 NuGet

XFESystem

【Rust】XFE系统,基于Rust和汇编

公开
关注 0 Fork 0 Star 0
UTF-8
using System.Security.Cryptography;
using XFESystem.Tls;

namespace XFESystem.NativeTls.Tests;

public sealed class TlsCertificateTests
{
    [Fact]
    public void ValidExplicitRootSanAndUtcAreAccepted()
    {
        using var fixture = new CertificateFixtures(); using var leaf = fixture.Leaf();
        var validated = new TlsCertificateValidator([fixture.RootBc]).Validate("TEST.XFE.INVALID", [leaf.RawData], fixture.Now);
        Assert.Equal(leaf.RawData, validated.GetEncoded());
    }

    [Theory]
    [InlineData("other.xfe.invalid")]
    [InlineData("sub.test.xfe.invalid")]
    [InlineData("test.xfe.invalid.attacker.invalid")]
    [InlineData("127.0.0.1")]
    public void WrongSubjectAlternativeNameIsRejected(string host)
    {
        using var fixture = new CertificateFixtures(); using var leaf = fixture.Leaf();
        Assert.Throws<InvalidOperationException>(() => new TlsCertificateValidator([fixture.RootBc]).Validate(host, [leaf.RawData], fixture.Now));
    }

    [Fact]
    public void UnknownRootIsRejected()
    {
        using var fixture = new CertificateFixtures(); using var stranger = new CertificateFixtures(); using var leaf = fixture.Leaf();
        Assert.ThrowsAny<Exception>(() => new TlsCertificateValidator([stranger.RootBc]).Validate("test.xfe.invalid", [leaf.RawData], fixture.Now));
    }

    [Fact]
    public void WrongSigningKeyIsRejectedEvenWhenIssuerNameMatchesTrustedRoot()
    {
        using var fixture = new CertificateFixtures(); using var wrongKey = ECDsa.Create(ECCurve.NamedCurves.nistP256);
        using var leaf = fixture.Leaf(signingKey: wrongKey);
        Assert.ThrowsAny<Exception>(() => new TlsCertificateValidator([fixture.RootBc]).Validate("test.xfe.invalid", [leaf.RawData], fixture.Now));
    }

    [Theory]
    [InlineData(-3, -2)]
    [InlineData(2, 3)]
    public void ExpiredAndNotYetValidCertificatesAreRejected(int before, int after)
    {
        using var fixture = new CertificateFixtures(); using var leaf = fixture.Leaf(before: fixture.Now.AddDays(before), after: fixture.Now.AddDays(after));
        Assert.ThrowsAny<Exception>(() => new TlsCertificateValidator([fixture.RootBc]).Validate("test.xfe.invalid", [leaf.RawData], fixture.Now));
    }

    [Fact]
    public void SubjectCommonNameDoesNotReplaceMissingSan()
    {
        using var fixture = new CertificateFixtures(); using var leaf = fixture.Leaf(dns: null);
        Assert.Throws<InvalidOperationException>(() => new TlsCertificateValidator([fixture.RootBc]).Validate("never-used-for-name-match.invalid", [leaf.RawData], fixture.Now));
    }

    [Theory]
    [InlineData(true, true, true)]
    [InlineData(false, false, true)]
    [InlineData(false, true, false)]
    public void CaLeafWrongExtendedUsageAndWrongSigningUsageAreRejected(bool ca, bool serverAuth, bool signingUsage)
    {
        using var fixture = new CertificateFixtures(); using var leaf = fixture.Leaf(ca: ca, serverAuth: serverAuth, signingUsage: signingUsage);
        Assert.ThrowsAny<Exception>(() => new TlsCertificateValidator([fixture.RootBc]).Validate("test.xfe.invalid", [leaf.RawData], fixture.Now));
    }

    [Fact]
    public void UnknownCriticalExtensionIsRejectedByPkix()
    {
        using var fixture = new CertificateFixtures(); using var leaf = fixture.Leaf(unknownCriticalExtension: true);
        Assert.ThrowsAny<Exception>(() => new TlsCertificateValidator([fixture.RootBc]).Validate("test.xfe.invalid", [leaf.RawData], fixture.Now));
    }

    [Theory]
    [InlineData("*.xfe.invalid", "test.xfe.invalid", true)]
    [InlineData("*.xfe.invalid", "nested.test.xfe.invalid", false)]
    [InlineData("*.xfe.invalid", "xfe.invalid", false)]
    [InlineData("*.invalid", "test.invalid", false)]
    [InlineData("*.xfe.invalid", "xn--test.xfe.invalid", false)]
    public void WildcardMatchesExactlyOneCompleteNonIdnaLabel(string name, string host, bool accepted)
    {
        using var fixture = new CertificateFixtures(); using var leaf = fixture.Leaf(dns: name);
        var validation = () => new TlsCertificateValidator([fixture.RootBc]).Validate(host, [leaf.RawData], fixture.Now);
        if (accepted) Assert.NotNull(validation()); else Assert.Throws<InvalidOperationException>(validation);
    }

    [Fact]
    public void IpIdentityRequiresIpSan()
    {
        using var fixture = new CertificateFixtures(); using var ipLeaf = fixture.Leaf(dns: null, ip: "127.0.0.1"); using var dnsLeaf = fixture.Leaf(dns: "127.0.0.1");
        var validator = new TlsCertificateValidator([fixture.RootBc]);
        Assert.NotNull(validator.Validate("127.0.0.1", [ipLeaf.RawData], fixture.Now));
        Assert.Throws<InvalidOperationException>(() => validator.Validate("127.0.0.1", [dnsLeaf.RawData], fixture.Now));
    }

    [Fact]
    public void BoundsEmptyTrustAndNonUtcInputsAreRejected()
    {
        using var fixture = new CertificateFixtures(); using var leaf = fixture.Leaf();
        Assert.Throws<ArgumentException>(() => new TlsCertificateValidator([]));
        var validator = new TlsCertificateValidator([fixture.RootBc]);
        Assert.Throws<InvalidOperationException>(() => validator.Validate("test.xfe.invalid", [], fixture.Now));
        Assert.Throws<InvalidOperationException>(() => validator.Validate("test.xfe.invalid", [new byte[131_073]], fixture.Now));
        Assert.Throws<ArgumentException>(() => validator.Validate("test.xfe.invalid", [leaf.RawData], DateTime.SpecifyKind(fixture.Now, DateTimeKind.Unspecified)));
    }

    [Fact]
    public void ExpiredTrustAnchorIsRejectedEvenWhenLeafIsStillValid()
    {
        using var fixture = new CertificateFixtures();
        using var leaf = fixture.Leaf(before: fixture.Now.AddDays(9), after: fixture.Now.AddDays(12));
        Assert.ThrowsAny<Exception>(() => new TlsCertificateValidator([fixture.RootBc]).Validate("test.xfe.invalid", [leaf.RawData], fixture.Now.AddDays(11)));
    }

    [Fact]
    public void PemRootBundleIsParsedWithoutHostCertificateStore()
    {
        using var fixture = new CertificateFixtures(); using var leaf = fixture.Leaf();
        var validator = TlsCertificateValidator.FromPem(fixture.Root.ExportCertificatePem());
        Assert.NotNull(validator.Validate("test.xfe.invalid", [leaf.RawData], fixture.Now));
    }
}