Provides access to a simple file based certificate store.
Inheritance: ICertificateStore
コード例 #1
0
        /// <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);
        }
コード例 #2
0
        /// <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);
        }
コード例 #3
0
        /// <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);
        }
コード例 #4
0
        /// <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));
        }
コード例 #5
0
        /// <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));
        }
コード例 #6
0
        /// <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));
        }
コード例 #7
0
        /// <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);
        }
コード例 #8
0
        /// <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;
        }
コード例 #10
0
 /// <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);
 }
コード例 #11
0
        /// <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);
        }
コード例 #12
0
        /// <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;
        }