Exemple #1
0
        /// <summary>
        /// Generates a list of certificates representing a chain of certificates.
        /// The first certificate is the root certificate stored in StoreName.Root and StoreLocation.LocalMachine.
        /// The last certificate is the leaf certificate stored in StoreName.TrustedPeople and StoreLocation.LocalMachine.
        /// Please dispose all the certificates in the list after use.
        /// </summary>
        /// <param name="length">Length of the chain.</param>
        /// <param name="crlServerUri">Uri for crl server</param>
        /// <param name="crlLocalUri">Uri for crl local</param>
        /// <param name="configureLeafCrl">Indicates if leaf crl should be configured</param>
        /// <param name="leafCertificateActionGenerator">Specify actionGenerator for the leaf certificate of the chain</param>
        /// <returns>List of certificates representing a chain of certificates.</returns>
        public static IList <TrustedTestCert <TestCertificate> > GenerateCertificateChain(int length, string crlServerUri, string crlLocalUri, bool configureLeafCrl = true, Action <TestCertificateGenerator> leafCertificateActionGenerator = null)
        {
            var certChain       = new List <TrustedTestCert <TestCertificate> >();
            var actionGenerator = CertificateModificationGeneratorForCodeSigningEkuCert;
            var leafGenerator   = leafCertificateActionGenerator ?? actionGenerator;
            TrustedTestCert <TestCertificate> issuer = null;
            TrustedTestCert <TestCertificate> cert   = null;

            for (var i = 0; i < length; i++)
            {
                if (i == 0) // root CA cert
                {
                    var chainCertificateRequest = new ChainCertificateRequest()
                    {
                        ConfigureCrl     = true,
                        CrlLocalBaseUri  = crlLocalUri,
                        CrlServerBaseUri = crlServerUri,
                        IsCA             = true
                    };

                    cert   = TestCertificate.Generate(actionGenerator, chainCertificateRequest).WithPrivateKeyAndTrust(StoreName.Root);
                    issuer = cert;
                }
                else if (i < length - 1) // intermediate CA cert
                {
                    var chainCertificateRequest = new ChainCertificateRequest()
                    {
                        ConfigureCrl     = true,
                        CrlLocalBaseUri  = crlLocalUri,
                        CrlServerBaseUri = crlServerUri,
                        IsCA             = true,
                        Issuer           = issuer.Source.Cert
                    };

                    cert   = TestCertificate.Generate(actionGenerator, chainCertificateRequest).WithPrivateKeyAndTrustForIntermediateCertificateAuthority();
                    issuer = cert;
                }
                else // leaf cert
                {
                    var chainCertificateRequest = new ChainCertificateRequest()
                    {
                        CrlLocalBaseUri  = crlLocalUri,
                        CrlServerBaseUri = crlServerUri,
                        IsCA             = false,
                        ConfigureCrl     = configureLeafCrl,
                        Issuer           = issuer.Source.Cert
                    };

                    cert = TestCertificate.Generate(leafGenerator, chainCertificateRequest).WithPrivateKeyAndTrustForLeafOrSelfIssued();
                }

                certChain.Add(cert);
            }

            return(certChain);
        }
Exemple #2
0
        public static X509CertificateWithKeyInfo GenerateCertificateWithKeyInfo(
            string subjectName,
            Action <TestCertificateGenerator> modifyGenerator,
            NuGet.Common.HashAlgorithmName hashAlgorithm = NuGet.Common.HashAlgorithmName.SHA256,
            RSASignaturePaddingMode paddingMode          = RSASignaturePaddingMode.Pkcs1,
            int publicKeyLength = 2048,
            ChainCertificateRequest chainCertificateRequest = null)
        {
            var rsa  = RSA.Create(publicKeyLength);
            var cert = GenerateCertificate(subjectName, modifyGenerator, rsa, hashAlgorithm, paddingMode, chainCertificateRequest);

            return(new X509CertificateWithKeyInfo(cert, rsa));
        }
Exemple #3
0
        /// <summary>
        /// Create a self signed certificate with bouncy castle.
        /// </summary>
        public static X509Certificate2 GenerateCertificate(
            string subjectName,
            Action <TestCertificateGenerator> modifyGenerator,
            NuGet.Common.HashAlgorithmName hashAlgorithm = NuGet.Common.HashAlgorithmName.SHA256,
            RSASignaturePaddingMode paddingMode          = RSASignaturePaddingMode.Pkcs1,
            int publicKeyLength = 2048,
            ChainCertificateRequest chainCertificateRequest = null)
        {
            chainCertificateRequest = chainCertificateRequest ?? new ChainCertificateRequest()
            {
                IsCA = true
            };

            using (var rsa = RSA.Create(publicKeyLength))
            {
                return(GenerateCertificate(subjectName, modifyGenerator, rsa, hashAlgorithm, paddingMode, chainCertificateRequest));
            }
        }
Exemple #4
0
        private static X509Certificate2 GenerateCertificate(
            string subjectName,
            Action <TestCertificateGenerator> modifyGenerator,
            RSA rsa,
            NuGet.Common.HashAlgorithmName hashAlgorithm,
            RSASignaturePaddingMode paddingMode,
            ChainCertificateRequest chainCertificateRequest)
        {
            if (string.IsNullOrEmpty(subjectName))
            {
                subjectName = "NuGetTest";
            }

            // Create cert
            var subjectDN = $"CN={subjectName}";
            var certGen   = new TestCertificateGenerator();

            var isSelfSigned          = true;
            X509Certificate2 issuer   = null;
            DateTimeOffset?  notAfter = null;

            var keyUsage = X509KeyUsageFlags.DigitalSignature;

            if (chainCertificateRequest == null)
            {
                // Self-signed certificates should have this flag set.
                keyUsage |= X509KeyUsageFlags.KeyCertSign;
            }
            else
            {
                if (chainCertificateRequest.Issuer != null)
                {
                    isSelfSigned = false;
                    // for a certificate with an issuer assign Authority Key Identifier
                    issuer = chainCertificateRequest?.Issuer;

                    notAfter = issuer.NotAfter.Subtract(TimeSpan.FromMinutes(5));
                    var publicKey = DotNetUtilities.GetRsaPublicKey(issuer.GetRSAPublicKey());

                    certGen.Extensions.Add(
                        new X509Extension(
                            Oids.AuthorityKeyIdentifier,
                            new AuthorityKeyIdentifierStructure(publicKey).GetEncoded(),
                            critical: false));
                }

                if (chainCertificateRequest.ConfigureCrl)
                {
                    // for a certificate in a chain create CRL distribution point extension
                    var issuerDN      = chainCertificateRequest?.Issuer?.Subject ?? subjectDN;
                    var crlServerUri  = $"{chainCertificateRequest.CrlServerBaseUri}{issuerDN}.crl";
                    var generalName   = new Org.BouncyCastle.Asn1.X509.GeneralName(Org.BouncyCastle.Asn1.X509.GeneralName.UniformResourceIdentifier, new DerIA5String(crlServerUri));
                    var distPointName = new DistributionPointName(new GeneralNames(generalName));
                    var distPoint     = new DistributionPoint(distPointName, null, null);

                    certGen.Extensions.Add(
                        new X509Extension(
                            TestOids.CrlDistributionPoints,
                            new DerSequence(distPoint).GetDerEncoded(),
                            critical: false));
                }

                if (chainCertificateRequest.IsCA)
                {
                    // update key usage with CA cert sign and crl sign attributes
                    keyUsage |= X509KeyUsageFlags.CrlSign | X509KeyUsageFlags.KeyCertSign;
                }
            }

            var  padding = paddingMode.ToPadding();
            var  request = new CertificateRequest(subjectDN, rsa, hashAlgorithm.ConvertToSystemSecurityHashAlgorithmName(), padding);
            bool isCa    = isSelfSigned ? true : (chainCertificateRequest?.IsCA ?? false);

            certGen.NotAfter  = notAfter ?? DateTime.UtcNow.Add(TimeSpan.FromMinutes(30));
            certGen.NotBefore = DateTime.UtcNow.Subtract(TimeSpan.FromMinutes(30));

            var random       = new Random();
            var serial       = random.Next();
            var serialNumber = BitConverter.GetBytes(serial);

            Array.Reverse(serialNumber);
            certGen.SetSerialNumber(serialNumber);

            certGen.Extensions.Add(
                new X509SubjectKeyIdentifierExtension(request.PublicKey, critical: false));
            certGen.Extensions.Add(
                new X509KeyUsageExtension(keyUsage, critical: false));
            certGen.Extensions.Add(
                new X509BasicConstraintsExtension(certificateAuthority: isCa, hasPathLengthConstraint: false, pathLengthConstraint: 0, critical: true));

            // Allow changes
            modifyGenerator?.Invoke(certGen);

            foreach (var extension in certGen.Extensions)
            {
                request.CertificateExtensions.Add(extension);
            }

            X509Certificate2 certResult;

            if (isSelfSigned)
            {
                certResult = request.CreateSelfSigned(certGen.NotBefore, certGen.NotAfter);
            }
            else
            {
                using (var temp = request.Create(issuer, certGen.NotBefore, certGen.NotAfter, certGen.SerialNumber))
                {
                    certResult = temp.CopyWithPrivateKey(rsa);
                }
            }

            return(new X509Certificate2(certResult.Export(X509ContentType.Pkcs12), password: (string)null, keyStorageFlags: X509KeyStorageFlags.Exportable));
        }
Exemple #5
0
        public static IX509CertificateChain GenerateCertificateChainWithoutTrust(
            int length,
            string crlServerUri,
            string crlLocalUri,
            bool configureLeafCrl = true,
            Action <TestCertificateGenerator> leafCertificateActionGenerator = null,
            bool revokeEndCertificate = false)
        {
            List <TestCertificate>            testCertificates = new();
            X509CertificateChain              certificateChain = new();
            Action <TestCertificateGenerator> actionGenerator  = CertificateModificationGeneratorForCodeSigningEkuCert;
            Action <TestCertificateGenerator> leafGenerator    = leafCertificateActionGenerator ?? actionGenerator;
            X509Certificate2          issuer      = null;
            X509Certificate2          certificate = null;
            CertificateRevocationList crl         = null;

            for (var i = 0; i < length; i++)
            {
                TestCertificate testCertificate;

                if (i == 0) // root CA cert
                {
                    ChainCertificateRequest chainCertificateRequest = new()
                    {
                        ConfigureCrl     = true,
                        CrlLocalBaseUri  = crlLocalUri,
                        CrlServerBaseUri = crlServerUri,
                        IsCA             = true
                    };

                    testCertificate = TestCertificate.Generate(actionGenerator, chainCertificateRequest);

                    testCertificates.Add(testCertificate);

                    issuer = certificate = testCertificate.PublicCertWithPrivateKey;
                }
                else if (i < length - 1) // intermediate CA cert
                {
                    ChainCertificateRequest chainCertificateRequest = new ChainCertificateRequest()
                    {
                        ConfigureCrl     = true,
                        CrlLocalBaseUri  = crlLocalUri,
                        CrlServerBaseUri = crlServerUri,
                        IsCA             = true,
                        Issuer           = issuer
                    };

                    testCertificate = TestCertificate.Generate(actionGenerator, chainCertificateRequest);

                    testCertificates.Add(testCertificate);

                    issuer = certificate = testCertificate.PublicCertWithPrivateKey;

                    if (revokeEndCertificate)
                    {
                        crl = testCertificate.Crl;
                    }
                }
                else // leaf cert
                {
                    ChainCertificateRequest chainCertificateRequest = new()
                    {
                        CrlLocalBaseUri  = crlLocalUri,
                        CrlServerBaseUri = crlServerUri,
                        IsCA             = false,
                        ConfigureCrl     = configureLeafCrl,
                        Issuer           = issuer
                    };

                    testCertificate = TestCertificate.Generate(leafGenerator, chainCertificateRequest);

                    certificate = testCertificate.PublicCertWithPrivateKey;

                    if (revokeEndCertificate)
                    {
                        testCertificates[testCertificates.Count - 1].Crl.RevokeCertificate(certificate);
                    }

                    testCertificates.Add(testCertificate);
                }

                certificateChain.Insert(index: 0, certificate);
            }

            foreach (TestCertificate testCertificate in testCertificates)
            {
                testCertificate.Cert.Dispose();
            }

            return(certificateChain);
        }
Exemple #6
0
        public static TestCertificate Generate(Action <X509V3CertificateGenerator> modifyGenerator = null, ChainCertificateRequest chainCertificateRequest = null)
        {
            var certName = GenerateCertificateName();
            var cert     = SigningTestUtility.GenerateCertificate(certName, modifyGenerator, chainCertificateRequest: chainCertificateRequest);
            CertificateRevocationList crl = null;

            // create a crl only if the certificate is part of a chain and it is a CA
            if (chainCertificateRequest != null && chainCertificateRequest.IsCA)
            {
                crl = CertificateRevocationList.CreateCrl(cert, chainCertificateRequest.CrlLocalBaseUri);
            }

            var testCertificate = new TestCertificate
            {
                Cert = cert,
                Crl  = crl
            };

            return(testCertificate);
        }
Exemple #7
0
        /// <summary>
        /// Create a self signed certificate with bouncy castle.
        /// </summary>
        public static X509Certificate2 GenerateCertificate(
            string subjectName,
            Action <X509V3CertificateGenerator> modifyGenerator,
            string signatureAlgorithm = "SHA256WITHRSA",
            int publicKeyLength       = 2048,
            ChainCertificateRequest chainCertificateRequest = null)
        {
            if (string.IsNullOrEmpty(subjectName))
            {
                subjectName = "NuGetTest";
            }

            var random  = new SecureRandom();
            var keyPair = GenerateKeyPair(publicKeyLength);

            // Create cert
            var subjectDN = $"CN={subjectName}";
            var certGen   = new X509V3CertificateGenerator();

            certGen.SetSubjectDN(new X509Name(subjectDN));

            // default to new key pair
            var issuerPrivateKey = keyPair.Private;
            var keyUsage         = KeyUsage.DigitalSignature;
            var issuerDN         = chainCertificateRequest?.IssuerDN ?? subjectDN;

            certGen.SetIssuerDN(new X509Name(issuerDN));

#if IS_DESKTOP
            if (chainCertificateRequest != null)
            {
                if (chainCertificateRequest.Issuer != null)
                {
                    // for a certificate with an issuer assign Authority Key Identifier
                    var issuer   = chainCertificateRequest?.Issuer;
                    var bcIssuer = DotNetUtilities.FromX509Certificate(issuer);
                    var authorityKeyIdentifier = new AuthorityKeyIdentifierStructure(bcIssuer);
                    issuerPrivateKey = DotNetUtilities.GetKeyPair(issuer.PrivateKey).Private;
                    certGen.AddExtension(X509Extensions.AuthorityKeyIdentifier.Id, false, authorityKeyIdentifier);
                }

                if (chainCertificateRequest.ConfigureCrl)
                {
                    // for a certificate in a chain create CRL distribution point extension
                    var crlServerUri  = $"{chainCertificateRequest.CrlServerBaseUri}{issuerDN}.crl";
                    var generalName   = new Org.BouncyCastle.Asn1.X509.GeneralName(Org.BouncyCastle.Asn1.X509.GeneralName.UniformResourceIdentifier, new DerIA5String(crlServerUri));
                    var distPointName = new DistributionPointName(new GeneralNames(generalName));
                    var distPoint     = new DistributionPoint(distPointName, null, null);

                    certGen.AddExtension(X509Extensions.CrlDistributionPoints, critical: false, extensionValue: new DerSequence(distPoint));
                }

                if (chainCertificateRequest.IsCA)
                {
                    // update key usage with CA cert sign and crl sign attributes
                    keyUsage |= KeyUsage.CrlSign | KeyUsage.KeyCertSign;
                }
            }
#endif
            certGen.SetNotAfter(DateTime.UtcNow.Add(TimeSpan.FromHours(1)));
            certGen.SetNotBefore(DateTime.UtcNow.Subtract(TimeSpan.FromHours(1)));
            certGen.SetPublicKey(keyPair.Public);

            var serialNumber = BigIntegers.CreateRandomInRange(BigInteger.One, BigInteger.ValueOf(long.MaxValue), random);
            certGen.SetSerialNumber(serialNumber);

            var subjectKeyIdentifier = new SubjectKeyIdentifier(SubjectPublicKeyInfoFactory.CreateSubjectPublicKeyInfo(keyPair.Public));
            certGen.AddExtension(X509Extensions.SubjectKeyIdentifier.Id, false, subjectKeyIdentifier);

            certGen.AddExtension(X509Extensions.KeyUsage.Id, false, new KeyUsage(keyUsage));
            certGen.AddExtension(X509Extensions.BasicConstraints.Id, true, new BasicConstraints(chainCertificateRequest?.IsCA ?? false));

            // Allow changes
            modifyGenerator?.Invoke(certGen);

            var signatureFactory = new Asn1SignatureFactory(signatureAlgorithm, issuerPrivateKey, random);
            var certificate      = certGen.Generate(signatureFactory);
            var certResult       = new X509Certificate2(certificate.GetEncoded());

#if IS_DESKTOP
            certResult.PrivateKey = DotNetUtilities.ToRSA(keyPair.Private as RsaPrivateCrtKeyParameters);
#endif

            return(certResult);
        }