public static X509Certificate2 CreateCertificate(string password, string issuer = "CN=Microsoft Azure Powershell Test", string friendlyName = "PSTest") { var keyCreationParameters = new CngKeyCreationParameters { ExportPolicy = CngExportPolicies.AllowExport, KeyCreationOptions = CngKeyCreationOptions.None, KeyUsage = CngKeyUsages.AllUsages, Provider = CngProvider.MicrosoftSoftwareKeyStorageProvider }; keyCreationParameters.Parameters.Add(new CngProperty("Length", BitConverter.GetBytes(2048), CngPropertyOptions.None)); CngKey key = CngKey.Create(CngAlgorithm2.Rsa, null, keyCreationParameters); var creationParams = new X509CertificateCreationParameters(new X500DistinguishedName(issuer)) { TakeOwnershipOfKey = true }; X509Certificate2 cert = key.CreateSelfSignedCertificate(creationParams); key = null; cert.FriendlyName = friendlyName; byte[] bytes = cert.Export(X509ContentType.Pfx, password); X509Certificate2 returnCert = new X509Certificate2(); returnCert.Import(bytes, password, X509KeyStorageFlags.PersistKeySet | X509KeyStorageFlags.Exportable); return(returnCert); }
public void Create2048RsaCertificate() { CngKeyCreationParameters keyCreationParameters = new CngKeyCreationParameters(); keyCreationParameters.ExportPolicy = CngExportPolicies.AllowExport; keyCreationParameters.KeyCreationOptions = CngKeyCreationOptions.None; keyCreationParameters.KeyUsage = CngKeyUsages.AllUsages; keyCreationParameters.Provider = CngProvider.MicrosoftSoftwareKeyStorageProvider; int keySize = 2048; keyCreationParameters.Parameters.Add(new CngProperty("Length", BitConverter.GetBytes(keySize), CngPropertyOptions.None)); byte[] pfx = null; using (CngKey key = CngKey.Create(CngAlgorithm2.Rsa, null, keyCreationParameters)) { X509Certificate2 cert = key.CreateSelfSignedCertificate(new X500DistinguishedName("CN=TestRSAKey")); pfx = cert.Export(X509ContentType.Pfx, "TestPassword"); Assert.IsTrue(cert.HasPrivateKey); Assert.IsTrue(cert.HasCngKey()); } X509Certificate2 rtCert = new X509Certificate2(pfx, "TestPassword"); Assert.IsTrue(rtCert.HasPrivateKey); Assert.IsTrue(rtCert.HasCngKey()); using (CngKey rtKey = rtCert.GetCngPrivateKey()) { Assert.AreEqual(CngAlgorithm2.Rsa, rtKey.Algorithm); Assert.AreEqual(2048, rtKey.KeySize); } }
public void CreateECDsaCertificate() { byte[] pfx = null; CngKeyCreationParameters keyCreationParameters = new CngKeyCreationParameters(); keyCreationParameters.ExportPolicy = CngExportPolicies.AllowExport; keyCreationParameters.KeyUsage = CngKeyUsages.Signing; using (CngKey key = CngKey.Create(CngAlgorithm.ECDsaP256, null, keyCreationParameters)) { X509CertificateCreationParameters creationParams = new X509CertificateCreationParameters(new X500DistinguishedName("CN=TestECDSACert")); creationParams.SignatureAlgorithm = X509CertificateSignatureAlgorithm.ECDsaSha256; X509Certificate2 cert = key.CreateSelfSignedCertificate(creationParams); pfx = cert.Export(X509ContentType.Pfx, "TestPassword"); Assert.IsTrue(cert.HasPrivateKey); Assert.IsTrue(cert.HasCngKey()); } X509Certificate2 rtCert = new X509Certificate2(pfx, "TestPassword"); Assert.IsTrue(rtCert.HasPrivateKey); Assert.IsTrue(rtCert.HasCngKey()); using (CngKey rtKey = rtCert.GetCngPrivateKey()) { Assert.AreEqual(CngAlgorithmGroup.ECDsa, rtKey.AlgorithmGroup); Assert.AreEqual(256, rtKey.KeySize); } }
public X509Certificate2 CreateNamedKeyCertificate(CertData data) { try { CngKeyCreationParameters keyCreationParameters = new CngKeyCreationParameters { ExportPolicy = CngExportPolicies.AllowExport | CngExportPolicies.AllowPlaintextExport | CngExportPolicies.AllowPlaintextArchiving | CngExportPolicies.AllowArchiving, KeyUsage = CngKeyUsages.AllUsages }; X509Certificate2 cert; X509CertificateCreationParameters configCreate = new X509CertificateCreationParameters(new X500DistinguishedName(data.DistinguishedName)) { EndTime = DateTime.Parse("01/01/2020", System.Globalization. DateTimeFormatInfo. InvariantInfo), StartTime = DateTime.Parse("01/01/2010", System.Globalization. DateTimeFormatInfo. InvariantInfo) }; using (CngKey namedKey = CngKey.Create(CngAlgorithm2.Rsa, data.Key, keyCreationParameters)) { cert = namedKey.CreateSelfSignedCertificate(configCreate); cert.FriendlyName = data.Friendlyname; Assert.True(cert.HasPrivateKey); Assert.True(cert.HasCngKey()); using (CngKey certKey = cert.GetCngPrivateKey()) { Assert.Equal(CngAlgorithm2.Rsa, certKey.Algorithm); } } return(cert); } finally { if (CngKey.Exists(data.Key)) { using (CngKey key = CngKey.Open(data.Key)) { key.Delete(); } } } }
public void CreateCertificateReuseKey() { CngKeyCreationParameters keyCreationParameters = new CngKeyCreationParameters(); keyCreationParameters.ExportPolicy = CngExportPolicies.AllowExport; using (CngKey key = CngKey.Create(CngAlgorithm2.Rsa, null, keyCreationParameters)) { key.CreateSelfSignedCertificate(new X500DistinguishedName("CN=TestCert")); CngAlgorithm algorithm = key.Algorithm; } }
public void OpenSubscriber() { try { if (IsListening()) { return; } log.InfoFormat("Opening subscriber endpoint at {0}", netTcpAddress); log.InfoFormat("Opening http subscriber endpoint at {0}", httpAddress); NotificationSubscriber notificationSubscriber = new NotificationSubscriber(); notificationSubscriber.IndicationReceived += OnIndication; CngKeyCreationParameters keyCreationParameters = new CngKeyCreationParameters(); keyCreationParameters.ExportPolicy = CngExportPolicies.AllowExport | CngExportPolicies.AllowPlaintextExport | CngExportPolicies.AllowPlaintextArchiving | CngExportPolicies.AllowArchiving; keyCreationParameters.KeyUsage = CngKeyUsages.AllUsages; X509CertificateCreationParameters configCreate = new X509CertificateCreationParameters(new X500DistinguishedName("CN=SolarWinds-SwqlStudio")); configCreate.EndTime = DateTime.Now.AddYears(1); configCreate.StartTime = DateTime.Now; using (CngKey cngKey = CngKey.Create(CngAlgorithm2.Rsa)) { X509Certificate2 certificate = cngKey.CreateSelfSignedCertificate(configCreate); ServiceHost host = new ServiceHost(notificationSubscriber, new Uri(netTcpAddress), new Uri(httpAddress)); host.Credentials.ServiceCertificate.Certificate = certificate; // SetCertificate(StoreLocation.LocalMachine, StoreName.My, X509FindType.FindBySubjectDistinguishedName, "CN=SolarWinds-Orion"); host.Open(); subscriberHosts.Add(host); } log.Info("Http Subscriber endpoint opened"); } catch (Exception ex) { log.ErrorFormat("Exception opening subscriber host with address {0}.\n{1}", httpAddress, ex); } foreach (ServiceHost serviceHost in subscriberHosts) { foreach (ChannelDispatcherBase channelDispatcher in serviceHost.ChannelDispatchers) { log.InfoFormat("Listening on {0}", channelDispatcher.Listener.Uri.AbsoluteUri); } } ListenerOpened?.Invoke(); }
public void GetCngPrivateKeyTest() { // The known Microsoft cert does not have a CNG private key Assert.IsNull(s_microsoftCert.GetCngPrivateKey()); const string keyName = "Microsoft.Security.Cryptography.X509Certificates.Test.X509Certificate2Tests.GetCngPrivateKeyTest.RSA1"; try { // Create a cert for a persisted CNG key CngKeyCreationParameters keyCreationParams = new CngKeyCreationParameters(); keyCreationParams.ExportPolicy = CngExportPolicies.AllowExport | CngExportPolicies.AllowPlaintextExport; using (CngKey key = CngKey.Create(CngAlgorithm2.Rsa, keyName, keyCreationParams)) { X509CertificateCreationParameters creationParams = new X509CertificateCreationParameters(new X500DistinguishedName("CN=CngCert")); creationParams.CertificateCreationOptions = X509CertificateCreationOptions.None; creationParams.TakeOwnershipOfKey = false; // A CNG certificate using a named key which is linked to the cert itself should return true X509Certificate2 cngFullCert = key.CreateSelfSignedCertificate(creationParams); using (CngKey certKey = cngFullCert.GetCngPrivateKey()) { Assert.AreEqual(keyName, certKey.KeyName); } // Create a cert with just the public key - there should be no access to the private key byte[] publicCertData = cngFullCert.Export(X509ContentType.Cert); X509Certificate2 cngPublicCert = new X509Certificate2(publicCertData); Assert.IsFalse(cngPublicCert.HasPrivateKey); Assert.IsNull(cngPublicCert.GetCngPrivateKey()); key.Delete(); } } finally { // Make sure to delete the persisted key so we're clean for the next run. if (CngKey.Exists(keyName)) { using (CngKey key = CngKey.Open(keyName)) { key.Delete(); } } } }
public void CreateNamedKeyCertificate() { string keyName = "NamedKey_" + Guid.NewGuid().ToString(); try { CngKeyCreationParameters keyCreationParameters = new CngKeyCreationParameters(); keyCreationParameters.ExportPolicy = CngExportPolicies.AllowExport; X509Certificate2 cert = null; byte[] pfx = null; using (CngKey namedKey = CngKey.Create(CngAlgorithm2.Rsa, keyName, keyCreationParameters)) { cert = namedKey.CreateSelfSignedCertificate(new X500DistinguishedName("CN=TestNamedRSAKey")); pfx = cert.Export(X509ContentType.Pfx, "TestPassword"); Assert.IsTrue(cert.HasPrivateKey); Assert.IsTrue(cert.HasCngKey()); using (CngKey certKey = cert.GetCngPrivateKey()) { Assert.AreEqual(CngAlgorithm2.Rsa, certKey.Algorithm); } } GC.KeepAlive(cert); X509Certificate2 rtCert = new X509Certificate2(pfx, "TestPassword"); Assert.IsTrue(rtCert.HasPrivateKey); Assert.IsTrue(rtCert.HasCngKey()); using (CngKey rtKey = rtCert.GetCngPrivateKey()) { Assert.AreEqual(CngAlgorithm2.Rsa, rtKey.Algorithm); } } finally { if (CngKey.Exists(keyName)) { using (CngKey key = CngKey.Open(keyName)) { key.Delete(); } } } }
public void CreateDefaultCertificate() { DateTime preCreationTime = DateTime.UtcNow; DateTime postCreationTime = DateTime.UtcNow; byte[] pfx = null; CngKeyCreationParameters keyCreationParameters = new CngKeyCreationParameters(); keyCreationParameters.ExportPolicy = CngExportPolicies.AllowExport; using (CngKey key = CngKey.Create(CngAlgorithm2.Rsa, null, keyCreationParameters)) { preCreationTime = DateTime.UtcNow; X509Certificate2 cert = key.CreateSelfSignedCertificate(new X500DistinguishedName("CN=TestCert")); postCreationTime = DateTime.UtcNow; Assert.AreEqual("TestCert", cert.GetNameInfo(X509NameType.SimpleName, true)); Assert.AreEqual("TestCert", cert.GetNameInfo(X509NameType.SimpleName, false)); Assert.IsTrue(cert.NotBefore.ToUniversalTime().Date.Equals(preCreationTime.Date) || cert.NotBefore.ToUniversalTime().Date.Equals(postCreationTime.Date)); Assert.IsTrue(cert.NotAfter.ToUniversalTime().Date.Equals(preCreationTime.Date.AddYears(1)) || cert.NotAfter.ToUniversalTime().Date.Equals(postCreationTime.Date.AddYears(1))); Assert.IsTrue(cert.HasCngKey()); Assert.IsTrue(cert.HasPrivateKey); // Try to round trip through PFX pfx = cert.Export(X509ContentType.Pfx, "TestPassword"); } // Make sure we can read back the PFX file even after the original key is gone X509Certificate2 rtCert = new X509Certificate2(pfx, "TestPassword"); Assert.AreEqual("TestCert", rtCert.GetNameInfo(X509NameType.SimpleName, true)); Assert.AreEqual("TestCert", rtCert.GetNameInfo(X509NameType.SimpleName, false)); Assert.IsTrue(rtCert.NotBefore.ToUniversalTime().Date.Equals(preCreationTime.Date) || rtCert.NotBefore.ToUniversalTime().Date.Equals(postCreationTime.Date)); Assert.IsTrue(rtCert.NotAfter.ToUniversalTime().Date.Equals(preCreationTime.Date.AddYears(1)) || rtCert.NotAfter.ToUniversalTime().Date.Equals(postCreationTime.Date.AddYears(1))); Assert.IsTrue(rtCert.HasCngKey()); Assert.IsTrue(rtCert.HasPrivateKey); }
public void HasCngKeyTestCngCertTest() { const string keyName = "Microsoft.Security.Cryptography.X509Certificates.Test.X509Certificate2Tests.HasCngKeyTest.RSA1"; try { // Create a cert for a persisted CNG key CngKeyCreationParameters keyCreationParams = new CngKeyCreationParameters(); keyCreationParams.ExportPolicy = CngExportPolicies.AllowExport | CngExportPolicies.AllowPlaintextExport; using (CngKey key = CngKey.Create(CngAlgorithm2.Rsa, keyName, keyCreationParams)) { X509CertificateCreationParameters creationParams = new X509CertificateCreationParameters(new X500DistinguishedName("CN=CngCert")); creationParams.CertificateCreationOptions = X509CertificateCreationOptions.None; creationParams.TakeOwnershipOfKey = false; // A CNG certificate using a named key which is linked to the cert itself should return true X509Certificate2 cngCert = key.CreateSelfSignedCertificate(creationParams); Assert.IsTrue(cngCert.HasCngKey()); // A CNG cert exported and then re-imported should also return true byte[] pfx = cngCert.Export(X509ContentType.Pfx, "CngCertPassword"); X509Certificate2 cngCertImport = new X509Certificate2(pfx, "CngCertPassword"); Assert.IsTrue(cngCertImport.HasCngKey()); key.Delete(); } using (CngKey key = CngKey.Create(CngAlgorithm2.Rsa)) { X509Certificate2 ephemeralCert = key.CreateSelfSignedCertificate(new X500DistinguishedName("CN=EphemeralCngCert")); Assert.IsTrue(ephemeralCert.HasCngKey()); } } finally { // Make sure to delete the persisted key so we're clean for the next run. if (CngKey.Exists(keyName)) { using (CngKey key = CngKey.Open(keyName)) { key.Delete(); } } } }
private void WritePrivateKey(CngKey key) { var creationParams = new X509CertificateCreationParameters(new X500DistinguishedName("CN=" + key.KeyName)) { CertificateCreationOptions = X509CertificateCreationOptions.None, SignatureAlgorithm = X509CertificateSignatureAlgorithm.ECDsaSha512, TakeOwnershipOfKey = false }; var cert = key.CreateSelfSignedCertificate(creationParams); byte[] pfx = string.IsNullOrEmpty(Password) ? cert.Export(X509ContentType.Pfx) : cert.Export(X509ContentType.Pfx, Password); using (var fs = File.OpenWrite(OutputPath)) { fs.Write(pfx, 0, pfx.Length); } }
public void CreateCertificateNoOwnershipChangeReuseKey() { CngKeyCreationParameters keyCreationParameters = new CngKeyCreationParameters(); keyCreationParameters.ExportPolicy = CngExportPolicies.AllowExport; using (CngKey key = CngKey.Create(CngAlgorithm2.Rsa, null, keyCreationParameters)) { X509CertificateCreationParameters certCreationParameters = new X509CertificateCreationParameters(new X500DistinguishedName("CN=TestCert")); certCreationParameters.TakeOwnershipOfKey = false; key.CreateSelfSignedCertificate(certCreationParameters); // Make sure the X509Certificate has been destroyed GC.Collect(); GC.WaitForPendingFinalizers(); GC.Collect(); GC.WaitForPendingFinalizers(); Assert.AreEqual(CngAlgorithm2.Rsa, key.Algorithm); } }
/// <summary> /// Create a ECDSA based certificate with the given options /// </summary> /// <param name="buildOptions">Allows for more advanced configuration</param> /// <returns>An exportable X509Certificate2 object (with private key)</returns> public static X509Certificate2 CreateNewSigningCertificate(ECCertificateBuilderOptions buildOptions) { if (buildOptions == null) { throw new ArgumentNullException("buildOptions"); } string keyName = buildOptions.ECKeyName ?? "ECDSAKey"; CngKey objCngKey = null; if (CngKey.Exists(keyName)) { objCngKey = CngKey.Open(keyName); objCngKey.Delete(); } var creationParameters = new CngKeyCreationParameters(); creationParameters.ExportPolicy = CngExportPolicies.AllowExport; creationParameters.KeyUsage = CngKeyUsages.Signing; CngAlgorithm keyAlg; switch (buildOptions.ECCurve ?? ECNamedCurves.P521) { case ECNamedCurves.P521: keyAlg = CngAlgorithm.ECDsaP521; break; case ECNamedCurves.P384: keyAlg = CngAlgorithm.ECDsaP384; break; case ECNamedCurves.P256: keyAlg = CngAlgorithm.ECDsaP256; break; default: throw new InvalidOperationException("Selected curve is not supported"); } objCngKey = CngKey.Create(keyAlg, keyName, creationParameters); var name = new X500DistinguishedName(buildOptions.FullSubjectName); X509CertificateSignatureAlgorithm certAlg; switch (buildOptions.HashingMethod ?? HashingMethods.Sha256) { case HashingMethods.Sha1: certAlg = X509CertificateSignatureAlgorithm.ECDsaSha1; break; case HashingMethods.Sha256: certAlg = X509CertificateSignatureAlgorithm.ECDsaSha256; break; case HashingMethods.Sha384: certAlg = X509CertificateSignatureAlgorithm.ECDsaSha384; break; case HashingMethods.Sha512: certAlg = X509CertificateSignatureAlgorithm.ECDsaSha512; break; default: throw new InvalidOperationException("Selected hashing method is not supported"); } var options = new X509CertificateCreationParameters(name) { SignatureAlgorithm = certAlg, TakeOwnershipOfKey = true }; return(objCngKey.CreateSelfSignedCertificate(options)); }
private void OpenSubscriber() { string ipAddress; try { // Instance should run on a different machine (i.e. where the additional poller is), so in that case must be subscription done via IP instead of relative localhost ipAddress = ResolveLocalIPAddress(); } catch (Exception ex) { log.ErrorFormat("Unable to retrieve ip address", ex); return; } string address = string.Format("net.tcp://{0}:17777/SolarWinds/SwqlStudio/{1}/Subscriber", ipAddress, Process.GetCurrentProcess().Id); try { log.InfoFormat("Opening subscriber endpoint at {0}", address); ServiceHost host = new ServiceHost(this); host.AddServiceEndpoint(typeof(INotificationSubscriber), new NetTcpBinding("NotificationSubscriber"), address); host.Open(); subscriberHosts.Add(host); log.Info("Subscriber endpoint opened"); subscriberInfo = new SubscriberInfo { EndpointAddress = address, OpenedSuccessfully = true, Binding = "NetTcp", DataFormat = "Xml", CredentialType = "Certificate" }; } catch (Exception ex) { log.ErrorFormat("Exception opening subscriber host with address {0}.\n{1}", address, ex); subscriberInfo = new SubscriberInfo { OpenedSuccessfully = false, ErrorMessage = ex.Message }; } string httpAddress = string.Format("https://{0}:17778/SolarWinds/SwqlStudio/{1}", Utility.GetFqdn(), Process.GetCurrentProcess().Id); try { log.InfoFormat("Opening http subscriber endpoint at {0}", httpAddress); NotificationSubscriber notificationSubscriber = new NotificationSubscriber(); notificationSubscriber.IndicationReceived += OnIndication; CngKeyCreationParameters keyCreationParameters = new CngKeyCreationParameters(); keyCreationParameters.ExportPolicy = CngExportPolicies.AllowExport | CngExportPolicies.AllowPlaintextExport | CngExportPolicies.AllowPlaintextArchiving | CngExportPolicies.AllowArchiving; keyCreationParameters.KeyUsage = CngKeyUsages.AllUsages; X509CertificateCreationParameters configCreate = new X509CertificateCreationParameters(new X500DistinguishedName("CN=SolarWinds-SwqlStudio")); configCreate.EndTime = DateTime.Now.AddYears(1); configCreate.StartTime = DateTime.Now; using (CngKey cngKey = CngKey.Create(CngAlgorithm2.Rsa)) { X509Certificate2 certificate = cngKey.CreateSelfSignedCertificate(configCreate); ServiceHost host = new ServiceHost(notificationSubscriber, new Uri(httpAddress)); host.Credentials.ServiceCertificate.Certificate = certificate; // SetCertificate(StoreLocation.LocalMachine, StoreName.My, X509FindType.FindBySubjectDistinguishedName, "CN=SolarWinds-Orion"); host.Open(); subscriberHosts.Add(host); } log.Info("Http Subscriber endpoint opened"); httpSubscriberInfo = new SubscriberInfo { EndpointAddress = httpAddress + "/Subscriber", OpenedSuccessfully = true, DataFormat = "Xml", Binding = "Soap1_1", CredentialType = "Username" }; } catch (Exception ex) { log.ErrorFormat("Exception opening subscriber host with address {0}.\n{1}", address, ex); httpSubscriberInfo = new SubscriberInfo { OpenedSuccessfully = false, ErrorMessage = ex.Message }; } foreach (ServiceHost serviceHost in subscriberHosts) { foreach (ChannelDispatcherBase channelDispatcher in serviceHost.ChannelDispatchers) { log.InfoFormat("Listening on {0}", channelDispatcher.Listener.Uri.AbsoluteUri); } } subscriberHostOpened.Set(); }
public void CreateCertificateWithExtensions() { byte[] pfx = null; X509CertificateCreationParameters creationParams = new X509CertificateCreationParameters(new X500DistinguishedName("CN=TestCertWithExtensions")); creationParams.SignatureAlgorithm = X509CertificateSignatureAlgorithm.RsaSha512; creationParams.Extensions.Add(new X509KeyUsageExtension(X509KeyUsageFlags.DigitalSignature, true)); creationParams.Extensions.Add(new X509BasicConstraintsExtension(false, true, 5, false)); CngKeyCreationParameters keyCreationParameters = new CngKeyCreationParameters(); keyCreationParameters.ExportPolicy = CngExportPolicies.AllowExport; using (CngKey key = CngKey.Create(CngAlgorithm2.Rsa, null, keyCreationParameters)) { X509Certificate2 cert = key.CreateSelfSignedCertificate(creationParams); bool foundKeyUsageExtension = false; bool foundBasicConstraintExtension = false; foreach (X509Extension extension in cert.Extensions) { X509KeyUsageExtension keyUsageExtension = extension as X509KeyUsageExtension; X509BasicConstraintsExtension basicConstraintsExtension = extension as X509BasicConstraintsExtension; if (keyUsageExtension != null) { foundKeyUsageExtension = true; Assert.AreEqual(X509KeyUsageFlags.DigitalSignature, keyUsageExtension.KeyUsages); Assert.IsTrue(keyUsageExtension.Critical); } else if (basicConstraintsExtension != null) { foundBasicConstraintExtension = true; Assert.IsFalse(basicConstraintsExtension.CertificateAuthority); Assert.IsTrue(basicConstraintsExtension.HasPathLengthConstraint); Assert.AreEqual(5, basicConstraintsExtension.PathLengthConstraint); Assert.IsFalse(basicConstraintsExtension.Critical); } } Assert.IsTrue(foundKeyUsageExtension); Assert.IsTrue(foundBasicConstraintExtension); pfx = cert.Export(X509ContentType.Pfx, "TestPassword"); } X509Certificate2 rtCert = new X509Certificate2(pfx, "TestPassword"); bool foundRTKeyUsageExtension = false; bool foundRTBasicConstraintExtension = false; foreach (X509Extension extension in rtCert.Extensions) { X509KeyUsageExtension keyUsageExtension = extension as X509KeyUsageExtension; X509BasicConstraintsExtension basicConstraintsExtension = extension as X509BasicConstraintsExtension; if (keyUsageExtension != null) { foundRTKeyUsageExtension = true; Assert.AreEqual(X509KeyUsageFlags.DigitalSignature, keyUsageExtension.KeyUsages); Assert.IsTrue(keyUsageExtension.Critical); } else if (basicConstraintsExtension != null) { foundRTBasicConstraintExtension = true; Assert.IsFalse(basicConstraintsExtension.CertificateAuthority); Assert.IsTrue(basicConstraintsExtension.HasPathLengthConstraint); Assert.AreEqual(5, basicConstraintsExtension.PathLengthConstraint); Assert.IsFalse(basicConstraintsExtension.Critical); } } Assert.IsTrue(foundRTKeyUsageExtension); Assert.IsTrue(foundRTBasicConstraintExtension); }
/// <summary> /// Create a RSA based certificate (to be used with encryption) with the given options /// </summary> /// <param name="buildOptions">Allows for more advanced configuration</param> /// <returns>An exportable X509Certificate2 object (with private key)</returns> public static X509Certificate2 CreateNewCertificate(RSACertificateBuilderOptions buildOptions) { if (buildOptions == null) { throw new ArgumentNullException("buildOptions"); } string keyName = buildOptions.RSAKeyName ?? "RSAKey"; CngKey objCngKey = null; if (CngKey.Exists(keyName)) { objCngKey = CngKey.Open(keyName); objCngKey.Delete(); } var creationParameters = new CngKeyCreationParameters(); creationParameters.ExportPolicy = CngExportPolicies.AllowExport; creationParameters.KeyUsage = CngKeyUsages.AllUsages; creationParameters.Provider = CngProvider.MicrosoftSoftwareKeyStorageProvider; var keySizeProperty = new CngProperty("Length", BitConverter.GetBytes(buildOptions.KeySize ?? 4096), CngPropertyOptions.None); creationParameters.Parameters.Add(keySizeProperty); objCngKey = CngKey.Create(CngAlgorithm2.Rsa, keyName, creationParameters); var name = new X500DistinguishedName(buildOptions.FullSubjectName); X509CertificateSignatureAlgorithm certAlg; switch (buildOptions.HashingMethod ?? HashingMethods.Sha256) { case HashingMethods.Sha1: certAlg = X509CertificateSignatureAlgorithm.RsaSha1; break; case HashingMethods.Sha256: certAlg = X509CertificateSignatureAlgorithm.RsaSha256; break; case HashingMethods.Sha384: certAlg = X509CertificateSignatureAlgorithm.RsaSha384; break; case HashingMethods.Sha512: certAlg = X509CertificateSignatureAlgorithm.RsaSha512; break; default: throw new InvalidOperationException("Selected hashing method is not supported"); } var options = new X509CertificateCreationParameters(name) { SignatureAlgorithm = certAlg, TakeOwnershipOfKey = true }; return(objCngKey.CreateSelfSignedCertificate(options)); }