コード例 #1
0
        public static void ChainCertRequirements(bool useIntermed, bool?isCA, X509KeyUsageFlags keyUsage, bool expectSuccess)
        {
            HashAlgorithmName hashAlgorithm = HashAlgorithmName.SHA384;

            ECDsa rootKey     = null;
            ECDsa intermedKey = null;
            ECDsa leafKey     = null;

            X509Certificate2 rootCert     = null;
            X509Certificate2 intermedCert = null;
            X509Certificate2 leafCert     = null;

            try
            {
                rootKey = ECDsa.Create(ECCurve.NamedCurves.nistP384);

                var request = new CertificateRequest("CN=Root", rootKey, hashAlgorithm);

                if (useIntermed || isCA.HasValue)
                {
                    request.CertificateExtensions.Add(
                        new X509BasicConstraintsExtension(useIntermed || isCA.Value, false, 0, true));
                }

                X509KeyUsageFlags rootFlags = useIntermed ? X509KeyUsageFlags.KeyCertSign : keyUsage;

                if (rootFlags != X509KeyUsageFlags.None)
                {
                    request.CertificateExtensions.Add(new X509KeyUsageExtension(rootFlags, true));
                }

                DateTimeOffset start = DateTimeOffset.UtcNow.AddHours(-1);
                DateTimeOffset end   = start.AddHours(2);

                rootCert = request.CreateSelfSigned(start, end);

                X509Certificate2 signerCert = rootCert;

                if (useIntermed)
                {
                    intermedKey = ECDsa.Create(ECCurve.NamedCurves.nistP384);
                    request     = new CertificateRequest("CN=Intermediate", intermedKey, hashAlgorithm);

                    if (isCA.HasValue)
                    {
                        request.CertificateExtensions.Add(
                            new X509BasicConstraintsExtension(isCA.Value, false, 0, true));
                    }

                    if (keyUsage != X509KeyUsageFlags.None)
                    {
                        request.CertificateExtensions.Add(new X509KeyUsageExtension(keyUsage, true));
                    }

                    using (X509Certificate2 tmp = request.Create(rootCert, start, end, new byte[] { 6, 0, 2, 2, 10, 23 }))
                    {
                        intermedCert = tmp.CopyWithPrivateKey(intermedKey);
                    }

                    signerCert = intermedCert;
                }

                leafKey = ECDsa.Create(ECCurve.NamedCurves.nistP256);
                request = new CertificateRequest("CN=Leaf", leafKey, hashAlgorithm);

                byte[] leafSerialNumber = { 2, 4, 6, 0, 1 };

                if (!expectSuccess)
                {
                    AssertExtensions.Throws <ArgumentException>(
                        "issuerCertificate",
                        () =>
                    {
                        request.Create(signerCert, start, end, leafSerialNumber)?.Dispose();
                    });

                    return;
                }

                leafCert = request.Create(signerCert, start, end, leafSerialNumber);

                using (X509Chain chain = new X509Chain())
                {
                    chain.ChainPolicy.RevocationMode = X509RevocationMode.NoCheck;
                    chain.ChainPolicy.ExtraStore.Add(rootCert);
                    chain.ChainPolicy.VerificationTime = start.UtcDateTime;
                    chain.AllowUnknownAuthorityOrAddSelfSignedToCustomTrust(rootCert);

                    if (useIntermed)
                    {
                        chain.ChainPolicy.ExtraStore.Add(intermedCert);
                    }

                    RunChain(chain, leafCert, true, "Chain verification");
                    DisposeChainCerts(chain);
                }
            }
            finally
            {
                leafCert?.Dispose();
                leafKey?.Dispose();
                intermedCert?.Dispose();
                intermedKey?.Dispose();
                rootCert?.Dispose();
                rootKey?.Dispose();
            }
        }