src/System.Private.ServiceModel/tools/CertificateGenerator/Program.cs (176 lines of code) (raw):

// Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Security.Cryptography; using System.Security.Cryptography.X509Certificates; using System.Threading.Tasks; using WcfTestCommon; using X509Certificate2 = System.Security.Cryptography.X509Certificates.X509Certificate2; using X509KeyStorageFlags = System.Security.Cryptography.X509Certificates.X509KeyStorageFlags; using System.IO; using System.Net; using System.Configuration; namespace CertUtil { internal class Program { private const string ClientCertificateSubject = "WCF Client Certificate"; private const string CertificateIssuer = "DO_NOT_TRUST_WcfBridgeRootCA"; private static string s_fqdn = Dns.GetHostEntry("127.0.0.1").HostName; private static string s_hostname = Dns.GetHostEntry("127.0.0.1").HostName.Split('.')[0]; private static string s_testserverbase = string.Empty; private static string s_CrlFileLocation = string.Empty; private static TimeSpan s_ValidatePeriod; private static void RemoveCertificatesFromStore(StoreName storeName, StoreLocation storeLocation) { Console.WriteLine(" Checking StoreName '{0}', StoreLocation '{1}'", storeName, storeLocation); X509Store store = new X509Store(storeName, storeLocation); { store.Open(OpenFlags.ReadWrite | OpenFlags.IncludeArchived); foreach (var cert in store.Certificates.Find(X509FindType.FindByIssuerName, CertificateIssuer, false)) { Console.Write(" {0}. Subject: '{1}'", cert.Thumbprint, cert.SubjectName.Name); store.Remove(cert); Console.Write(" ... removed"); } } Console.WriteLine(); } private static void UninstallAllCerts() { RemoveCertificatesFromStore(StoreName.My, StoreLocation.CurrentUser); RemoveCertificatesFromStore(StoreName.My, StoreLocation.LocalMachine); RemoveCertificatesFromStore(StoreName.Root, StoreLocation.LocalMachine); RemoveCertificatesFromStore(StoreName.Root, StoreLocation.CurrentUser); RemoveCertificatesFromStore(StoreName.TrustedPeople, StoreLocation.LocalMachine); RemoveCertificatesFromStore(StoreName.TrustedPeople, StoreLocation.CurrentUser); } private static void Usage() { Console.WriteLine("Supported argument is -Uninstall"); Console.WriteLine(" -help"); } private static int Main(string[] args) { ApplyAppSettings(); if (args.Length > 0) { if (string.Compare(args[0], "-Uninstall", true) == 0) { UninstallAllCerts(); return 0; } else if (string.Compare(args[0], "-help", true) == 0) { Usage(); return 0; } else { Usage(); return 1; } } UninstallAllCerts(); CertificateGenerator certificateGenerate = new CertificateGenerator(); certificateGenerate.CertificatePassword = "test"; certificateGenerate.CrlServiceUri = s_fqdn; certificateGenerate.ValidityPeriod = s_ValidatePeriod; if (!string.IsNullOrEmpty(s_testserverbase)) { certificateGenerate.CrlUriRelativePath += "/" + s_testserverbase; } certificateGenerate.CrlUriRelativePath += "/TestHost.svc/Crl"; //Create and install root and server cert CertificateManager.CreateAndInstallLocalMachineCertificates(certificateGenerate); //Create and Install expired cert CertificateCreationSettings certificateCreationSettings = new CertificateCreationSettings() { FriendlyName = "WCF Bridge - TcpExpiredServerCertResource", ValidityType = CertificateValidityType.Expired, ValidityNotBefore = DateTime.UtcNow - TimeSpan.FromDays(4), ValidityNotAfter = DateTime.UtcNow - TimeSpan.FromDays(2), //If you specify multiple subjects, the first one becomes the subject, and all of them become Subject Alt Names. //In this case, the certificate subject is CN=fqdn, OU=..., O=... , and SANs will be fqdn, hostname, localhost //We do this so that a single WCF service setup can deal with all the possible addresses that a client might use. Subject = s_fqdn, SubjectAlternativeNames = new string[] { s_fqdn, s_hostname, "localhost" } }; CreateAndInstallMachineCertificate(certificateGenerate, certificateCreationSettings); //Create and Install TcpCertificateWithServerAltName certificateCreationSettings = new CertificateCreationSettings() { FriendlyName = "WCF Bridge - TcpCertificateWithServerAltNameResource", Subject = "not-real-subject-name", SubjectAlternativeNames = new string[] { "not-real-subject-name", "not-real-subject-name.example.com", s_fqdn, s_hostname, "localhost" } }; CreateAndInstallMachineCertificate(certificateGenerate, certificateCreationSettings); //TcpCertificateWithSubjectCanonicalNameDomainName certificateCreationSettings = new CertificateCreationSettings() { FriendlyName = "WCF Bridge - TcpCertificateWithSubjectCanonicalNameDomainNameResource", Subject = s_hostname, SubjectAlternativeNames = new string[0], ValidityType = CertificateValidityType.NonAuthoritativeForMachine }; CreateAndInstallMachineCertificate(certificateGenerate, certificateCreationSettings); //WCF Bridge - TcpCertificateWithSubjectCanonicalNameFqdn certificateCreationSettings = new CertificateCreationSettings() { FriendlyName = "WCF Bridge - TcpCertificateWithSubjectCanonicalNameFqdnResource", Subject = s_fqdn, SubjectAlternativeNames = new string[0], ValidityType = CertificateValidityType.NonAuthoritativeForMachine }; CreateAndInstallMachineCertificate(certificateGenerate, certificateCreationSettings); //TcpCertificateWithSubjectCanonicalNameLocalhost certificateCreationSettings = new CertificateCreationSettings() { FriendlyName = "WCF Bridge - TcpCertificateWithSubjectCanonicalNameLocalhostResource", Subject = "localhost", SubjectAlternativeNames = new string[0], ValidityType = CertificateValidityType.NonAuthoritativeForMachine }; CreateAndInstallMachineCertificate(certificateGenerate, certificateCreationSettings); //TcpRevokedServerCert certificateCreationSettings = new CertificateCreationSettings() { FriendlyName = "WCF Bridge - TcpRevokedServerCertResource", ValidityType = CertificateValidityType.Revoked, Subject = s_fqdn, SubjectAlternativeNames = new string[] { s_fqdn, s_hostname, "localhost" } }; CreateAndInstallMachineCertificate(certificateGenerate, certificateCreationSettings); //TcpInvalidEkuServerCert certificateCreationSettings = new CertificateCreationSettings() { FriendlyName = "WCF Bridge - TcpInvalidEkuServerCert", ValidityType = CertificateValidityType.Valid, Subject = s_fqdn, SubjectAlternativeNames = new string[] { s_fqdn, s_hostname, "localhost" }, EKU = new List<Org.BouncyCastle.Asn1.X509.KeyPurposeID> { Org.BouncyCastle.Asn1.X509.KeyPurposeID.IdKPClientAuth } }; CreateAndInstallMachineCertificate(certificateGenerate, certificateCreationSettings); //STSMetaData certificateCreationSettings = new CertificateCreationSettings() { FriendlyName = "WCF Bridge - STSMetaData", ValidityType = CertificateValidityType.Valid, Subject = "STSMetaData", EKU = new List<Org.BouncyCastle.Asn1.X509.KeyPurposeID>() }; CreateAndInstallMachineCertificate(certificateGenerate, certificateCreationSettings); //Create and install client cert certificateCreationSettings = new CertificateCreationSettings() { FriendlyName = "WCF Bridge - UserCertificateResource", Subject = "WCF Client Certificate", }; X509Certificate2 certificate = certificateGenerate.CreateUserCertificate(certificateCreationSettings).Certificate; CertificateManager.AddToStoreIfNeeded(StoreName.My, StoreLocation.LocalMachine, certificate); //Create CRL and save it File.WriteAllBytes(s_CrlFileLocation, certificateGenerate.CrlEncoded); return 0; } private static void ApplyAppSettings() { var appSettings = ConfigurationManager.AppSettings; s_testserverbase = appSettings["testserverbase"] ?? string.Empty; s_ValidatePeriod = TimeSpan.FromDays(int.Parse(appSettings["CertExpirationInDay"])); s_CrlFileLocation = appSettings["CrlFileLocation"]; } private static void CreateAndInstallMachineCertificate(CertificateGenerator certificateGenerate, CertificateCreationSettings certificateCreationSettings) { X509Certificate2 certificate = certificateGenerate.CreateMachineCertificate(certificateCreationSettings).Certificate; CertificateManager.AddToStoreIfNeeded(StoreName.My, StoreLocation.LocalMachine, certificate); } } }