/// <summary> /// Returns an object that can be used to access the store. /// </summary> public static ICertificateStore CreateStore(string storeType) { ICertificateStore store = null; if (String.IsNullOrEmpty(storeType)) { return(new CertificateIdentifierCollection()); } #if !SILVERLIGHT switch (storeType) { case CertificateStoreType.Windows: { store = new WindowsCertificateStore(); break; } case CertificateStoreType.Directory: { store = new DirectoryCertificateStore(); break; } } #endif return(store); }
/// <summary> /// Returns an object that can be used to access the store. /// </summary> public static ICertificateStore CreateStore(string storeType) { ICertificateStore store = null; if (String.IsNullOrEmpty(storeType)) { return(new CertificateIdentifierCollection()); } switch (storeType) { case CertificateStoreType.X509Store: { store = new X509CertificateStore(); break; } case CertificateStoreType.Directory: { store = new DirectoryCertificateStore(); break; } } return(store); }
/// <summary> /// Returns an object that can be used to access the store. /// </summary> public static ICertificateStore CreateStore(string storeType) { ICertificateStore store = null; if (String.IsNullOrEmpty(storeType)) { return(new CertificateIdentifierCollection()); } switch (storeType) { case CertificateStoreType.X509Store: { store = new X509CertificateStore(); break; } case CertificateStoreType.Directory: { store = new DirectoryCertificateStore(); break; } default: { throw new ArgumentException($"Invalid store type name: {storeType}", nameof(storeType)); } } return(store); }
/// <summary> /// Loads the private key for the certificate with an optional password. /// </summary> public async Task <X509Certificate2> LoadPrivateKey(String password) { if (this.StoreType == CertificateStoreType.Directory) { using (DirectoryCertificateStore store = new DirectoryCertificateStore()) { store.Open(this.StorePath); m_certificate = store.LoadPrivateKey(this.Thumbprint, this.SubjectName, password); return(m_certificate); } } return(await Find(true)); }
/// <summary> /// Loads the private key for the certificate with an optional password. /// </summary> public X509Certificate2 LoadPrivateKey(System.Security.SecureString password) { #if !SILVERLIGHT if (this.StoreType == CertificateStoreType.Directory) { DirectoryCertificateStore store = new DirectoryCertificateStore(); store.Open(this.StorePath); m_certificate = store.LoadPrivateKey(this.Thumbprint, this.SubjectName, password); return(m_certificate); } #endif return(Find(true)); }
/// <summary> /// Loads the private key for the certificate with an optional password. /// </summary> public Task <X509Certificate2> LoadPrivateKeyEx(ICertificatePasswordProvider passwordProvider) { if (this.StoreType == CertificateStoreType.Directory) { using (DirectoryCertificateStore store = new DirectoryCertificateStore()) { store.Open(this.StorePath); string password = passwordProvider?.GetPassword(this); m_certificate = store.LoadPrivateKey(this.Thumbprint, this.SubjectName, password); return(Task.FromResult(m_certificate)); } } return(Find(true)); }
/// <summary> /// Creates a self signed application instance certificate. /// </summary> /// <param name="storeType">Type of certificate store (Directory) <see cref="CertificateStoreType"/>.</param> /// <param name="storePath">The store path (syntax depends on storeType).</param> /// <param name="password">The password to use to protect the certificate.</param> /// <param name="applicationUri">The application uri (created if not specified).</param> /// <param name="applicationName">Name of the application (optional if subjectName is specified).</param> /// <param name="subjectName">The subject used to create the certificate (optional if applicationName is specified).</param> /// <param name="domainNames">The domain names that can be used to access the server machine (defaults to local computer name if not specified).</param> /// <param name="keySize">Size of the key (1024, 2048 or 4096).</param> /// <param name="startTime">The start time.</param> /// <param name="lifetimeInMonths">The lifetime of the key in months.</param> /// <param name="hashSizeInBits">The hash size in bits.</param> /// <param name="isCA">if set to <c>true</c> then a CA certificate is created.</param> /// <param name="issuerCAKeyCert">The CA cert with the CA private key.</param> /// <returns>The certificate with a private key.</returns> public static X509Certificate2 CreateCertificate( string storeType, string storePath, string password, string applicationUri, string applicationName, string subjectName, IList <String> domainNames, ushort keySize, DateTime startTime, ushort lifetimeInMonths, ushort hashSizeInBits, bool isCA, X509Certificate2 issuerCAKeyCert) { if (!String.IsNullOrEmpty(storeType) && storeType != CertificateStoreType.Directory) { throw new NotSupportedException("Cannot create a certificate for a non directory store."); } if (issuerCAKeyCert != null) { if (!issuerCAKeyCert.HasPrivateKey) { throw new NotSupportedException("Cannot sign with a CA certificate without a private key."); } throw new NotSupportedException("Signing with an issuer CA certificate is currently unsupported."); } // set default values. SetSuitableDefaults( ref applicationUri, ref applicationName, ref subjectName, ref domainNames, ref keySize, ref lifetimeInMonths, isCA); // cert generators SecureRandom random = new SecureRandom(); X509V3CertificateGenerator cg = new X509V3CertificateGenerator(); // Serial Number BigInteger serialNumber = BigIntegers.CreateRandomInRange(BigInteger.One, BigInteger.ValueOf(Int64.MaxValue), random); cg.SetSerialNumber(serialNumber); // build name attributes var nameOids = new ArrayList(); nameOids.Add(X509Name.DC); nameOids.Add(X509Name.CN); var nameValues = new ArrayList(); nameValues.Add(domainNames[0]); nameValues.Add(applicationName); // self signed X509Name subjectDN = new X509Name(nameOids, nameValues); X509Name issuerDN = subjectDN; cg.SetIssuerDN(issuerDN); cg.SetSubjectDN(subjectDN); // valid for cg.SetNotBefore(startTime); cg.SetNotAfter(startTime.AddMonths(lifetimeInMonths)); // Private/Public Key AsymmetricCipherKeyPair subjectKeyPair; var keyGenerationParameters = new KeyGenerationParameters(random, keySize); var keyPairGenerator = new RsaKeyPairGenerator(); keyPairGenerator.Init(keyGenerationParameters); subjectKeyPair = keyPairGenerator.GenerateKeyPair(); cg.SetPublicKey(subjectKeyPair.Public); // add extensions // Subject key identifier cg.AddExtension(X509Extensions.SubjectKeyIdentifier.Id, false, new SubjectKeyIdentifier(SubjectPublicKeyInfoFactory.CreateSubjectPublicKeyInfo(subjectKeyPair.Public))); // Basic constraints cg.AddExtension(X509Extensions.BasicConstraints.Id, true, new BasicConstraints(isCA)); // Authority Key identifier var issuerKeyPair = subjectKeyPair; var issuerSerialNumber = serialNumber; cg.AddExtension(X509Extensions.AuthorityKeyIdentifier.Id, false, new AuthorityKeyIdentifier(SubjectPublicKeyInfoFactory.CreateSubjectPublicKeyInfo(subjectKeyPair.Public), new GeneralNames(new GeneralName(issuerDN)), issuerSerialNumber)); if (!isCA) { // Key usage cg.AddExtension(X509Extensions.KeyUsage, true, new KeyUsage(KeyUsage.DataEncipherment | KeyUsage.DigitalSignature | KeyUsage.NonRepudiation | KeyUsage.KeyCertSign | KeyUsage.KeyEncipherment)); // Extended Key usage cg.AddExtension(X509Extensions.ExtendedKeyUsage, true, new ExtendedKeyUsage(new List <DerObjectIdentifier>() { new DerObjectIdentifier("1.3.6.1.5.5.7.3.1"), // server auth new DerObjectIdentifier("1.3.6.1.5.5.7.3.2"), // client auth })); // subject alternate name cg.AddExtension(X509Extensions.SubjectAlternativeName, false, new GeneralNames(new GeneralName[] { new GeneralName(GeneralName.UniformResourceIdentifier, applicationUri), new GeneralName(GeneralName.DnsName, domainNames[0]) })); } else { // Key usage CA cg.AddExtension(X509Extensions.KeyUsage, true, new KeyUsage(KeyUsage.CrlSign | KeyUsage.DigitalSignature | KeyUsage.KeyCertSign)); } // sign certificate ISignatureFactory signatureFactory = new Asn1SignatureFactory((hashSizeInBits < 256) ? "SHA1WITHRSA" : "SHA256WITHRSA", subjectKeyPair.Private, random); Org.BouncyCastle.X509.X509Certificate x509 = cg.Generate(signatureFactory); // create pkcs12 store for cert and private key X509Certificate2 certificate = null; using (MemoryStream pfxData = new MemoryStream()) { Pkcs12Store pkcsStore = new Pkcs12StoreBuilder().Build(); X509CertificateEntry[] chain = new X509CertificateEntry[1]; string passcode = "passcode"; chain[0] = new X509CertificateEntry(x509); pkcsStore.SetKeyEntry(applicationName, new AsymmetricKeyEntry(subjectKeyPair.Private), chain); pkcsStore.Save(pfxData, passcode.ToCharArray(), random); // merge into X509Certificate2 certificate = CreateCertificateFromPKCS12(pfxData.ToArray(), passcode); } Utils.Trace(Utils.TraceMasks.Security, "Created new certificate: {0}", certificate.Thumbprint); // add cert to the store. if (!String.IsNullOrEmpty(storePath)) { ICertificateStore store = null; if (storeType == CertificateStoreType.Directory) { using (store = new DirectoryCertificateStore()) { store.Open(storePath); store.Add(certificate); store.Close(); } } } // note: this cert has a private key! return(certificate); }
/// <summary> /// Creates a self signed application instance certificate. /// </summary> /// <param name="storeType">Type of certificate store (Directory) <see cref="CertificateStoreType"/>.</param> /// <param name="storePath">The store path (syntax depends on storeType).</param> /// <param name="password">The password to use to protect the certificate.</param> /// <param name="applicationUri">The application uri (created if not specified).</param> /// <param name="applicationName">Name of the application (optional if subjectName is specified).</param> /// <param name="subjectName">The subject used to create the certificate (optional if applicationName is specified).</param> /// <param name="domainNames">The domain names that can be used to access the server machine (defaults to local computer name if not specified).</param> /// <param name="keySize">Size of the key (1024, 2048 or 4096).</param> /// <param name="startTime">The start time.</param> /// <param name="lifetimeInMonths">The lifetime of the key in months.</param> /// <param name="hashSizeInBits">The hash size in bits.</param> /// <param name="isCA">if set to <c>true</c> then a CA certificate is created.</param> /// <param name="issuerCAKeyCert">The CA cert with the CA private key.</param> /// <returns>The certificate with a private key.</returns> public static X509Certificate2 CreateCertificate( string storeType, string storePath, string password, string applicationUri, string applicationName, string subjectName, IList<String> domainNames, ushort keySize, DateTime startTime, ushort lifetimeInMonths, ushort hashSizeInBits, bool isCA, X509Certificate2 issuerCAKeyCert) { if (!String.IsNullOrEmpty(storeType) && storeType != CertificateStoreType.Directory) { throw new NotSupportedException("Cannot create a certificate for a non directory store."); } if (issuerCAKeyCert != null) { if (!issuerCAKeyCert.HasPrivateKey) { throw new NotSupportedException("Cannot sign with a CA certificate without a private key."); } throw new NotSupportedException("Signing with an issuer CA certificate is currently unsupported."); } // set default values. SetSuitableDefaults( ref applicationUri, ref applicationName, ref subjectName, ref domainNames, ref keySize, ref lifetimeInMonths, isCA); // cert generators SecureRandom random = new SecureRandom(); X509V3CertificateGenerator cg = new X509V3CertificateGenerator(); // Serial Number BigInteger serialNumber = BigIntegers.CreateRandomInRange(BigInteger.One, BigInteger.ValueOf(Int64.MaxValue), random); cg.SetSerialNumber(serialNumber); // build name attributes var nameOids = new ArrayList(); nameOids.Add(X509Name.DC); nameOids.Add(X509Name.CN); var nameValues = new ArrayList(); nameValues.Add(domainNames[0]); nameValues.Add(applicationName); // self signed X509Name subjectDN = new X509Name(nameOids, nameValues); X509Name issuerDN = subjectDN; cg.SetIssuerDN(issuerDN); cg.SetSubjectDN(subjectDN); // valid for cg.SetNotBefore(startTime); cg.SetNotAfter(startTime.AddMonths(lifetimeInMonths)); // Private/Public Key AsymmetricCipherKeyPair subjectKeyPair; var keyGenerationParameters = new KeyGenerationParameters(random, keySize); var keyPairGenerator = new RsaKeyPairGenerator(); keyPairGenerator.Init(keyGenerationParameters); subjectKeyPair = keyPairGenerator.GenerateKeyPair(); cg.SetPublicKey(subjectKeyPair.Public); // add extensions // Subject key identifier cg.AddExtension(X509Extensions.SubjectKeyIdentifier.Id, false, new SubjectKeyIdentifier(SubjectPublicKeyInfoFactory.CreateSubjectPublicKeyInfo(subjectKeyPair.Public))); // Basic constraints cg.AddExtension(X509Extensions.BasicConstraints.Id, true, new BasicConstraints(isCA)); // Authority Key identifier var issuerKeyPair = subjectKeyPair; var issuerSerialNumber = serialNumber; cg.AddExtension(X509Extensions.AuthorityKeyIdentifier.Id, false, new AuthorityKeyIdentifier(SubjectPublicKeyInfoFactory.CreateSubjectPublicKeyInfo(subjectKeyPair.Public), new GeneralNames(new GeneralName(issuerDN)), issuerSerialNumber)); if (!isCA) { // Key usage cg.AddExtension(X509Extensions.KeyUsage, true, new KeyUsage(KeyUsage.DataEncipherment | KeyUsage.DigitalSignature | KeyUsage.NonRepudiation | KeyUsage.KeyCertSign | KeyUsage.KeyEncipherment)); // Extended Key usage cg.AddExtension(X509Extensions.ExtendedKeyUsage, true, new ExtendedKeyUsage(new List<DerObjectIdentifier>() { new DerObjectIdentifier("1.3.6.1.5.5.7.3.1"), // server auth new DerObjectIdentifier("1.3.6.1.5.5.7.3.2"), // client auth })); // subject alternate name cg.AddExtension(X509Extensions.SubjectAlternativeName, false, new GeneralNames(new GeneralName[] { new GeneralName(GeneralName.UniformResourceIdentifier, applicationUri), new GeneralName(GeneralName.DnsName, domainNames[0])})); } else { // Key usage CA cg.AddExtension(X509Extensions.KeyUsage, true, new KeyUsage(KeyUsage.CrlSign | KeyUsage.DigitalSignature | KeyUsage.KeyCertSign)); } // sign certificate ISignatureFactory signatureFactory = new Asn1SignatureFactory((hashSizeInBits < 256) ? "SHA1WITHRSA" : "SHA256WITHRSA", subjectKeyPair.Private, random); Org.BouncyCastle.X509.X509Certificate x509 = cg.Generate(signatureFactory); // create pkcs12 store for cert and private key X509Certificate2 certificate = null; using (MemoryStream pfxData = new MemoryStream()) { Pkcs12Store pkcsStore = new Pkcs12StoreBuilder().Build(); X509CertificateEntry[] chain = new X509CertificateEntry[1]; string passcode = "passcode"; chain[0] = new X509CertificateEntry(x509); pkcsStore.SetKeyEntry(applicationName, new AsymmetricKeyEntry(subjectKeyPair.Private), chain); pkcsStore.Save(pfxData, passcode.ToCharArray(), random); // merge into X509Certificate2 certificate = CreateCertificateFromPKCS12(pfxData.ToArray(), passcode); } Utils.Trace(Utils.TraceMasks.Security, "Created new certificate: {0}", certificate.Thumbprint); // add cert to the store. if (!String.IsNullOrEmpty(storePath)) { ICertificateStore store = null; if (storeType == CertificateStoreType.Directory) { using (store = new DirectoryCertificateStore()) { store.Open(storePath); store.Add(certificate); store.Close(); } } } // note: this cert has a private key! return certificate; }
/// <summary> /// Returns an object that can be used to access the store. /// </summary> public static ICertificateStore CreateStore(string storeType) { ICertificateStore store = null; if (String.IsNullOrEmpty(storeType)) { return (ICertificateStore) new CertificateIdentifierCollection(); } switch (storeType) { case CertificateStoreType.Directory: { store = new DirectoryCertificateStore(); break; } } return store; }
/// <summary> /// Loads the private key for the certificate with an optional password. /// </summary> public async Task<X509Certificate2> LoadPrivateKey(String password) { if (this.StoreType == CertificateStoreType.Directory) { using (DirectoryCertificateStore store = new DirectoryCertificateStore()) { store.Open(this.StorePath); m_certificate = store.LoadPrivateKey(this.Thumbprint, this.SubjectName, password); return m_certificate; } } return await Find(true); }
/// <summary> /// Loads the private key for the certificate with an optional password. /// </summary> public X509Certificate2 LoadPrivateKey(System.Security.SecureString password) { #if !SILVERLIGHT if (this.StoreType == CertificateStoreType.Directory) { using (DirectoryCertificateStore store = new DirectoryCertificateStore()) { store.Open(this.StorePath); m_certificate = store.LoadPrivateKey(this.Thumbprint, this.SubjectName, password); return m_certificate; } } #endif return Find(true); }
/// <summary> /// Returns an object that can be used to access the store. /// </summary> public static ICertificateStore CreateStore(string storeType) { ICertificateStore store = null; if (String.IsNullOrEmpty(storeType)) { return new CertificateIdentifierCollection(); } #if !SILVERLIGHT switch (storeType) { case CertificateStoreType.Windows: { store = new WindowsCertificateStore(); break; } case CertificateStoreType.Directory: { store = new DirectoryCertificateStore(); break; } } #endif return store; }