DisposeChainElements() public method

public DisposeChainElements ( ) : void
return void
示例#1
0
        public static void TestResetMethod()
        {
            using (var sampleCert = new X509Certificate2(TestData.DssCer))
                using (var chainHolder = new ChainHolder())
                {
                    X509Chain chain = chainHolder.Chain;

                    chain.ChainPolicy.ExtraStore.Add(sampleCert);
                    bool valid = chain.Build(sampleCert);
                    Assert.False(valid);
                    chainHolder.DisposeChainElements();

                    chain.ChainPolicy.VerificationFlags = X509VerificationFlags.AllowUnknownCertificateAuthority;
                    chain.ChainPolicy.VerificationTime  = new DateTime(2015, 10, 15, 12, 01, 01, DateTimeKind.Local);
                    chain.ChainPolicy.RevocationMode    = X509RevocationMode.NoCheck;

                    valid = chain.Build(sampleCert);
                    Assert.True(valid, "Chain built validly");

                    Assert.Equal(1, chain.ChainElements.Count);
                    chainHolder.DisposeChainElements();

                    chain.Reset();
                    Assert.Equal(0, chain.ChainElements.Count);

                    // ChainPolicy did not reset (for desktop compat)
                    Assert.Equal(X509VerificationFlags.AllowUnknownCertificateAuthority, chain.ChainPolicy.VerificationFlags);

                    valid = chain.Build(sampleCert);
                    Assert.Equal(1, chain.ChainElements.Count);
                    // This succeeds because ChainPolicy did not reset
                    Assert.True(valid, "Chain built validly after reset");
                }
        }
        public static void VerifyCrlCache()
        {
            string crlDirectory = PersistedFiles.GetUserFeatureDirectory("cryptography", "crls");
            string crlFile      = Path.Combine(crlDirectory, MicrosoftDotComRootCrlFilename);

            Directory.CreateDirectory(crlDirectory);
            File.Delete(crlFile);

            using (var microsoftDotComIssuer = new X509Certificate2(TestData.MicrosoftDotComIssuerBytes))
                using (var microsoftDotComRoot = new X509Certificate2(TestData.MicrosoftDotComRootBytes))
                    using (var unrelated = new X509Certificate2(TestData.DssCer))
                        using (var chainHolder = new ChainHolder())
                        {
                            X509Chain chain = chainHolder.Chain;

                            chain.ChainPolicy.ExtraStore.Add(unrelated);
                            chain.ChainPolicy.ExtraStore.Add(microsoftDotComRoot);

                            // The very start of the CRL period.
                            chain.ChainPolicy.VerificationTime   = new DateTime(2015, 6, 17, 0, 0, 0, DateTimeKind.Utc);
                            chain.ChainPolicy.RevocationMode     = X509RevocationMode.NoCheck;
                            chain.ChainPolicy.RevocationFlag     = X509RevocationFlag.EndCertificateOnly;
                            chain.ChainPolicy.VerificationFlags |= X509VerificationFlags.AllowUnknownCertificateAuthority;

                            bool valid = chain.Build(microsoftDotComIssuer);
                            Assert.True(valid, "Precondition: Chain builds with no revocation checks");

                            int initialErrorCount = chain.ChainStatus.Length;
                            Assert.InRange(initialErrorCount, 0, 1);

                            X509ChainStatusFlags initialFlags = chain.AllStatusFlags();

                            if (initialFlags != X509ChainStatusFlags.NoError)
                            {
                                Assert.Equal(X509ChainStatusFlags.UntrustedRoot, initialFlags);
                            }

                            chainHolder.DisposeChainElements();

                            chain.ChainPolicy.RevocationMode = X509RevocationMode.Offline;

                            valid = chain.Build(microsoftDotComIssuer);
                            Assert.False(valid, "Chain should not build validly");

                            const X509ChainStatusFlags UnknownOffline =
                                X509ChainStatusFlags.RevocationStatusUnknown | X509ChainStatusFlags.OfflineRevocation;

                            Assert.Equal(initialFlags | UnknownOffline, chain.AllStatusFlags());

                            File.WriteAllText(crlFile, MicrosoftDotComRootCrlPem, Encoding.ASCII);

                            chainHolder.DisposeChainElements();

                            valid = chain.Build(microsoftDotComIssuer);
                            Assert.True(valid, "Chain should build validly now");
                            Assert.Equal(initialErrorCount, chain.ChainStatus.Length);
                        }
        }
示例#3
0
        public static void VerifyCrlCache()
        {
            string crlDirectory = PersistedFiles.GetUserFeatureDirectory("cryptography", "crls");
            string crlFile = Path.Combine(crlDirectory,MicrosoftDotComRootCrlFilename);

            Directory.CreateDirectory(crlDirectory);
            File.Delete(crlFile);

            using (var microsoftDotComIssuer = new X509Certificate2(TestData.MicrosoftDotComIssuerBytes))
            using (var microsoftDotComRoot = new X509Certificate2(TestData.MicrosoftDotComRootBytes))
            using (var unrelated = new X509Certificate2(TestData.DssCer))
            using (var chainHolder = new ChainHolder())
            {
                X509Chain chain = chainHolder.Chain;

                chain.ChainPolicy.ExtraStore.Add(unrelated);
                chain.ChainPolicy.ExtraStore.Add(microsoftDotComRoot);
                
                // The very start of the CRL period.
                chain.ChainPolicy.VerificationTime = new DateTime(2015, 6, 17, 0, 0, 0, DateTimeKind.Utc);
                chain.ChainPolicy.RevocationMode = X509RevocationMode.NoCheck;
                chain.ChainPolicy.RevocationFlag = X509RevocationFlag.EndCertificateOnly;
                chain.ChainPolicy.VerificationFlags |= X509VerificationFlags.AllowUnknownCertificateAuthority;

                bool valid = chain.Build(microsoftDotComIssuer);
                Assert.True(valid, "Precondition: Chain builds with no revocation checks");

                int initialErrorCount = chain.ChainStatus.Length;
                Assert.InRange(initialErrorCount, 0, 1);

                if (initialErrorCount > 0)
                {
                    Assert.Equal(X509ChainStatusFlags.UntrustedRoot, chain.ChainStatus[0].Status);
                }

                chainHolder.DisposeChainElements();

                chain.ChainPolicy.RevocationMode = X509RevocationMode.Offline;

                valid = chain.Build(microsoftDotComIssuer);
                Assert.False(valid, "Chain should not build validly");

                Assert.Equal(initialErrorCount + 1, chain.ChainStatus.Length);
                Assert.Equal(X509ChainStatusFlags.RevocationStatusUnknown, chain.ChainStatus[0].Status);

                File.WriteAllText(crlFile, MicrosoftDotComRootCrlPem, Encoding.ASCII);

                chainHolder.DisposeChainElements();

                valid = chain.Build(microsoftDotComIssuer);
                Assert.True(valid, "Chain should build validly now");
                Assert.Equal(initialErrorCount, chain.ChainStatus.Length);
            }
        }
示例#4
0
        public static void BuildInvalidSignatureTwice()
        {
            byte[] bytes = (byte[])TestData.MsCertificate.Clone();
            bytes[bytes.Length - 1] ^= 0xFF;

            using (X509Certificate2 cert = new X509Certificate2(bytes))
                using (ChainHolder chainHolder = new ChainHolder())
                {
                    X509Chain chain = chainHolder.Chain;
                    chain.ChainPolicy.VerificationTime  = cert.NotBefore.AddHours(2);
                    chain.ChainPolicy.VerificationFlags =
                        X509VerificationFlags.AllowUnknownCertificateAuthority;

                    chain.ChainPolicy.RevocationMode = X509RevocationMode.NoCheck;

                    int iter = 0;

                    void CheckChain()
                    {
                        iter++;
                        bool valid = chain.Build(cert);
                        X509ChainStatusFlags allFlags = chain.AllStatusFlags();

                        if (RuntimeInformation.IsOSPlatform(OSPlatform.OSX))
                        {
                            // OSX considers this to be valid because it doesn't report NotSignatureValid,
                            // just PartialChain ("I couldn't find an issuer that made the signature work"),
                            // and PartialChain + AllowUnknownCertificateAuthority == pass.
                            Assert.True(valid, $"Chain is valid on execution {iter}");

                            Assert.Equal(1, chain.ChainElements.Count);

                            Assert.Equal(
                                X509ChainStatusFlags.PartialChain,
                                allFlags);
                        }
                        else
                        {
                            Assert.False(valid, $"Chain is valid on execution {iter}");

                            Assert.Equal(3, chain.ChainElements.Count);

                            // Clear UntrustedRoot, if it happened.
                            allFlags &= ~X509ChainStatusFlags.UntrustedRoot;

                            Assert.Equal(
                                X509ChainStatusFlags.NotSignatureValid,
                                allFlags);
                        }

                        chainHolder.DisposeChainElements();
                    }

                    CheckChain();
                    CheckChain();
                }
        }
示例#5
0
        public static void BuildInvalidSignatureTwice(
            X509ChainStatusFlags endEntityErrors,
            X509ChainStatusFlags intermediateErrors,
            X509ChainStatusFlags rootErrors)
        {
            TestDataGenerator.MakeTestChain3(
                out X509Certificate2 endEntityCert,
                out X509Certificate2 intermediateCert,
                out X509Certificate2 rootCert);

            X509Certificate2 TamperIfNeeded(X509Certificate2 input, X509ChainStatusFlags flags)
            {
                if ((flags & X509ChainStatusFlags.NotSignatureValid) != 0)
                {
                    X509Certificate2 tampered = TamperSignature(input);
                    input.Dispose();
                    return(tampered);
                }

                return(input);
            }

            DateTime RewindIfNeeded(DateTime input, X509Certificate2 cert, X509ChainStatusFlags flags)
            {
                if ((flags & X509ChainStatusFlags.NotTimeValid) != 0)
                {
                    return(cert.NotBefore.AddMinutes(-1));
                }

                return(input);
            }

            int expectedCount = 3;

            DateTime verificationTime = endEntityCert.NotBefore.AddMinutes(1);

            verificationTime = RewindIfNeeded(verificationTime, endEntityCert, endEntityErrors);
            verificationTime = RewindIfNeeded(verificationTime, intermediateCert, intermediateErrors);
            verificationTime = RewindIfNeeded(verificationTime, rootCert, rootErrors);

            // Replace the certs for the scenario.
            endEntityCert    = TamperIfNeeded(endEntityCert, endEntityErrors);
            intermediateCert = TamperIfNeeded(intermediateCert, intermediateErrors);
            rootCert         = TamperIfNeeded(rootCert, rootErrors);

            if (RuntimeInformation.IsOSPlatform(OSPlatform.OSX))
            {
                // For the lower levels, turn NotSignatureValid into PartialChain,
                // and clear all errors at higher levels.

                if ((endEntityErrors & X509ChainStatusFlags.NotSignatureValid) != 0)
                {
                    expectedCount      = 1;
                    endEntityErrors   &= ~X509ChainStatusFlags.NotSignatureValid;
                    endEntityErrors   |= X509ChainStatusFlags.PartialChain;
                    intermediateErrors = X509ChainStatusFlags.NoError;
                    rootErrors         = X509ChainStatusFlags.NoError;
                }
                else if ((intermediateErrors & X509ChainStatusFlags.NotSignatureValid) != 0)
                {
                    expectedCount       = 2;
                    intermediateErrors &= ~X509ChainStatusFlags.NotSignatureValid;
                    intermediateErrors |= X509ChainStatusFlags.PartialChain;
                    rootErrors          = X509ChainStatusFlags.NoError;
                }
                else if ((rootErrors & X509ChainStatusFlags.NotSignatureValid) != 0)
                {
                    rootErrors &= ~X509ChainStatusFlags.NotSignatureValid;

                    // On 10.13+ it becomes PartialChain, and UntrustedRoot goes away.
                    if (PlatformDetection.IsOSX)
                    {
                        rootErrors &= ~X509ChainStatusFlags.UntrustedRoot;
                        rootErrors |= X509ChainStatusFlags.PartialChain;
                    }
                }
            }
            else if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
            {
                // Windows only reports NotTimeValid on the start-of-chain (end-entity in this case)
                // If it were possible in this suite to get only a higher-level cert as NotTimeValid
                // without the lower one, that would have resulted in NotTimeNested.
                intermediateErrors &= ~X509ChainStatusFlags.NotTimeValid;
                rootErrors         &= ~X509ChainStatusFlags.NotTimeValid;
            }

            X509ChainStatusFlags expectedAllErrors = endEntityErrors | intermediateErrors | rootErrors;

            // If PartialChain or UntrustedRoot are the only remaining errors, the chain will succeed.
            const X509ChainStatusFlags SuccessCodes =
                X509ChainStatusFlags.UntrustedRoot | X509ChainStatusFlags.PartialChain;

            bool expectSuccess = (expectedAllErrors & ~SuccessCodes) == 0;

            using (endEntityCert)
                using (intermediateCert)
                    using (rootCert)
                        using (ChainHolder chainHolder = new ChainHolder())
                        {
                            X509Chain chain = chainHolder.Chain;
                            chain.ChainPolicy.VerificationTime = verificationTime;
                            chain.ChainPolicy.RevocationMode   = X509RevocationMode.NoCheck;
                            chain.ChainPolicy.ExtraStore.Add(intermediateCert);
                            chain.ChainPolicy.ExtraStore.Add(rootCert);

                            chain.ChainPolicy.VerificationFlags |=
                                X509VerificationFlags.AllowUnknownCertificateAuthority;

                            int i = 0;

                            void CheckChain()
                            {
                                i++;

                                bool valid = chain.Build(endEntityCert);

                                if (expectSuccess)
                                {
                                    Assert.True(valid, $"Chain build on iteration {i}");
                                }
                                else
                                {
                                    Assert.False(valid, $"Chain build on iteration {i}");
                                }

                                Assert.Equal(expectedCount, chain.ChainElements.Count);
                                Assert.Equal(expectedAllErrors, chain.AllStatusFlags());

                                Assert.Equal(endEntityErrors, chain.ChainElements[0].AllStatusFlags());

                                if (expectedCount > 2)
                                {
                                    Assert.Equal(rootErrors, chain.ChainElements[2].AllStatusFlags());
                                }

                                if (expectedCount > 1)
                                {
                                    Assert.Equal(intermediateErrors, chain.ChainElements[1].AllStatusFlags());
                                }

                                chainHolder.DisposeChainElements();
                            }

                            CheckChain();
                            CheckChain();
                        }
        }