/// <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); }
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)); }
/// <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)); } }
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)); }
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); }
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); }
/// <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); }