/// <summary> /// Opens the store. /// </summary> /// <param name="path">The path.</param> /// <returns>The store.</returns> public static ICertificateStore OpenStore(string path) { ICertificateStore store = CertificateStoreIdentifier.CreateStore(CertificateStoreIdentifier.DetermineStoreType(path)); store.Open(path); return(store); }
/// <summary> /// Returns an object that can be used to access the store containing the certificate. /// </summary> /// <returns>An instance of the <see cref="ICertificateStore"/> poined out by the current value of </returns> public ICertificateStore OpenStore() { ICertificateStore store = CertificateStoreIdentifier.CreateStore(this.StoreType); store.Open(this.StorePath); return(store); }
/// <summary> /// Returns an object to access the store containing the certificates. /// </summary> /// <remarks> /// Opens an instance of the store which contains public keys. /// </remarks> /// <returns>A disposable instance of the <see cref="ICertificateStore"/>.</returns> public virtual ICertificateStore OpenStore() { ICertificateStore store = CreateStore(this.StoreType); store.Open(this.StorePath); return(store); }
/// <summary> /// Finds a certificate in a store. /// </summary> /// <param name="needPrivateKey">if set to <c>true</c> the returned certificate must contain the private key.</param> /// <returns>An instance of the <see cref="X509Certificate2"/> that is emebeded by this instance or find it in /// the selected strore pointed out by the <see cref="StorePath"/> using selected <see cref="SubjectName"/>.</returns> public async Task <X509Certificate2> Find(bool needPrivateKey) { X509Certificate2 certificate = null; // check if the entire certificate has been specified. if (m_certificate != null && (!needPrivateKey || m_certificate.HasPrivateKey)) { certificate = m_certificate; } else { // open store. using (ICertificateStore store = CertificateStoreIdentifier.CreateStore(StoreType)) { store.Open(StorePath); X509Certificate2Collection collection = await store.Enumerate(); certificate = Find(collection, m_thumbprint, m_subjectName, needPrivateKey); if (certificate != null) { m_certificate = certificate; } } } // use the single instance in the certificate cache. if (needPrivateKey) { certificate = m_certificate = CertificateFactory.Load(certificate, true); } return(certificate); }
private ICertificateStore CreateStore(string storePath) { ICertificateStore store = CertificateStoreIdentifier.CreateStore(CertificateStoreIdentifier.DetermineStoreType(storePath)); store.Open(storePath); return(store); }
/// <summary> /// Finds a certificate in a store. /// </summary> /// <param name="needPrivateKey">if set to <c>true</c> the returned certificate must contain the private key.</param> /// <returns>An instance of the <see cref="X509Certificate2"/> that is emebeded by this instance or find it in /// the selected strore pointed out by the <see cref="StorePath"/> using selected <see cref="SubjectName"/>.</returns> public async Task <X509Certificate2> Find(bool needPrivateKey) { X509Certificate2 certificate = null; // check if the entire certificate has been specified. if (m_certificate != null) { certificate = m_certificate; } else { // open store. ICertificateStore store = CertificateStoreIdentifier.PickStore(StoreType); store.Open(StorePath); X509Certificate2Collection collection = await store.Enumerate(); certificate = Find(collection, m_thumbprint, m_subjectName, needPrivateKey); if (certificate != null) { m_certificate = certificate; } } return(certificate); }
/// <summary> /// Returns an object that can be used to access the store. /// </summary> public ICertificateStore OpenStore() { ICertificateStore store = PickStore(this.StoreType); store.Open(this.StorePath); return(store); }
/// <summary> /// Returns an object that can be used to access the store. /// </summary> public ICertificateStore OpenStore() { ICertificateStore store = CreateStore(this.StoreType); Task t = Task.Run(() => store.Open(this.StorePath)); t.Wait(); return(store); }
public async Task <X509CertificateCollection> KeyVaultSigningRequestAsync() { Skip.If(!_fixture.KeyVaultInitOk); X509CertificateCollection certCollection = new X509CertificateCollection(); string[] groups = await _keyVault.GetCertificateGroupIds(); foreach (string group in groups) { var certificateGroupConfiguration = await _keyVault.GetCertificateGroupConfiguration(group); ApplicationTestData randomApp = _fixture.RandomGenerator.RandomApplicationTestData(); X509Certificate2 csrCertificate = CertificateFactory.CreateCertificate( null, null, null, randomApp.ApplicationRecord.ApplicationUri, null, randomApp.Subject, randomApp.DomainNames.ToArray(), certificateGroupConfiguration.DefaultCertificateKeySize, DateTime.UtcNow.AddDays(-10), certificateGroupConfiguration.DefaultCertificateLifetime, certificateGroupConfiguration.DefaultCertificateHashSize ); byte[] certificateRequest = CertificateFactory.CreateSigningRequest(csrCertificate, randomApp.DomainNames); X509Certificate2 newCert = await _keyVault.SigningRequestAsync( group, randomApp.ApplicationRecord.ApplicationUri, certificateRequest); // get issuer cert used for signing X509Certificate2Collection issuerCerts = await _keyVault.GetIssuerCACertificateChainAsync(group); #if WRITECERT // save cert for debugging using (ICertificateStore store = CertificateStoreIdentifier.CreateStore(CertificateStoreType.Directory)) { Assert.NotNull(store); store.Open("d:\\unittest"); await store.Add(newCert); foreach (var cert in issuerCerts) { await store.Add(cert); } } #endif Assert.NotNull(issuerCerts); Assert.True(issuerCerts.Count >= 1); X509TestUtils.VerifySignedApplicationCert(randomApp, newCert, issuerCerts); certCollection.Add(newCert); } return(certCollection); }
/// <summary> /// Loads the private key for the certificate with an optional password. /// </summary> public async Task <X509Certificate2> LoadPrivateKeyEx(ICertificatePasswordProvider passwordProvider) { if (this.StoreType != CertificateStoreType.X509Store) { using (ICertificateStore store = CertificateStoreIdentifier.CreateStore(StoreType)) { if (store.SupportsLoadPrivateKey) { store.Open(this.StorePath, false); string password = passwordProvider?.GetPassword(this); m_certificate = await store.LoadPrivateKey(this.Thumbprint, this.SubjectName, password).ConfigureAwait(false); return(m_certificate); } } } return(await Find(true).ConfigureAwait(false)); }
/// <summary> /// Gets the private key file path. /// </summary> public string GetPrivateKeyFilePath() { X509Certificate2 certificate = Find(false); if (certificate == null) { return(null); } ICertificateStore store = CertificateStoreIdentifier.CreateStore(this.StoreType); try { store.Open(this.StorePath); return(store.GetPrivateKeyFilePath(certificate.Thumbprint)); } finally { store.Close(); } }
/// <summary> /// Finds a certificate in a store. /// </summary> /// <param name="needPrivateKey">if set to <c>true</c> the returned certificate must contain the private key.</param> /// <returns>An instance of the <see cref="X509Certificate2"/> that is embedded by this instance or find it in /// the selected store pointed out by the <see cref="StorePath"/> using selected <see cref="SubjectName"/>.</returns> public async Task <X509Certificate2> Find(bool needPrivateKey) { X509Certificate2 certificate = null; // check if the entire certificate has been specified. if (m_certificate != null && (!needPrivateKey || m_certificate.HasPrivateKey)) { certificate = m_certificate; } else { // open store. using (ICertificateStore store = CertificateStoreIdentifier.CreateStore(StoreType)) { store.Open(StorePath, false); X509Certificate2Collection collection = await store.Enumerate().ConfigureAwait(false); certificate = Find(collection, m_thumbprint, m_subjectName, needPrivateKey); if (certificate != null) { if (needPrivateKey && store.SupportsLoadPrivateKey) { var message = new StringBuilder(); message.AppendLine("Loaded a certificate with private key from store {0}."); message.AppendLine("Ensure to call LoadPrivateKeyEx with password provider before calling Find(true)."); Utils.LogWarning(message.ToString(), StoreType); } m_certificate = certificate; } } } // use the single instance in the certificate cache. if (needPrivateKey) { certificate = m_certificate = CertificateFactory.Load(certificate, true); } return(certificate); }
/// <summary> /// Extension to add a certificate to a <see cref="ICertificateStore"/>. /// </summary> /// <remarks> /// Saves also the private key, if available. /// If written to a Pfx file, the password is used for protection. /// </remarks> /// <param name="certificate">The certificate to store.</param> /// <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> /// <returns></returns> public static X509Certificate2 AddToStore( this X509Certificate2 certificate, string storeType, string storePath, string password = null) { // add cert to the store. if (!String.IsNullOrEmpty(storePath) && !String.IsNullOrEmpty(storeType)) { using (ICertificateStore store = Opc.Ua.CertificateStoreIdentifier.CreateStore(storeType)) { if (store == null) { throw new ArgumentException("Invalid store type"); } store.Open(storePath); store.Add(certificate, password).Wait(); store.Close(); } } 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 = false, X509Certificate2 issuerCAKeyCert = null, byte[] publicKey = null) { if (issuerCAKeyCert != null) { if (!issuerCAKeyCert.HasPrivateKey) { throw new NotSupportedException("Cannot sign with a CA certificate without a private key."); } } if (publicKey != null && issuerCAKeyCert == null) { throw new NotSupportedException("Cannot use a public key without a CA certificate with a private key."); } // set default values. X509Name subjectDN = SetSuitableDefaults( ref applicationUri, ref applicationName, ref subjectName, ref domainNames, ref keySize, ref lifetimeInMonths); using (var cfrg = new CertificateFactoryRandomGenerator()) { // cert generators SecureRandom random = new SecureRandom(cfrg); X509V3CertificateGenerator cg = new X509V3CertificateGenerator(); // Serial Number BigInteger serialNumber = BigIntegers.CreateRandomInRange(BigInteger.One, BigInteger.ValueOf(Int64.MaxValue), random); cg.SetSerialNumber(serialNumber); // subject and issuer DN X509Name issuerDN = null; if (issuerCAKeyCert != null) { issuerDN = new CertificateFactoryX509Name(issuerCAKeyCert.Subject); } else { // self signed issuerDN = subjectDN; } cg.SetIssuerDN(issuerDN); cg.SetSubjectDN(subjectDN); // valid for cg.SetNotBefore(startTime); cg.SetNotAfter(startTime.AddMonths(lifetimeInMonths)); // set Private/Public Key AsymmetricKeyParameter subjectPublicKey; AsymmetricKeyParameter subjectPrivateKey; if (publicKey == null) { var keyGenerationParameters = new KeyGenerationParameters(random, keySize); var keyPairGenerator = new RsaKeyPairGenerator(); keyPairGenerator.Init(keyGenerationParameters); AsymmetricCipherKeyPair subjectKeyPair = keyPairGenerator.GenerateKeyPair(); subjectPublicKey = subjectKeyPair.Public; subjectPrivateKey = subjectKeyPair.Private; } else { // special case, if a cert is signed by CA, the private key of the cert is not needed subjectPublicKey = PublicKeyFactory.CreateKey(publicKey); subjectPrivateKey = null; } cg.SetPublicKey(subjectPublicKey); // add extensions // Subject key identifier cg.AddExtension(X509Extensions.SubjectKeyIdentifier.Id, false, new SubjectKeyIdentifier(SubjectPublicKeyInfoFactory.CreateSubjectPublicKeyInfo(subjectPublicKey))); // Basic constraints cg.AddExtension(X509Extensions.BasicConstraints.Id, true, new BasicConstraints(isCA)); // Authority Key identifier references the issuer cert or itself when self signed AsymmetricKeyParameter issuerPublicKey; BigInteger issuerSerialNumber; if (issuerCAKeyCert != null) { issuerPublicKey = GetPublicKeyParameter(issuerCAKeyCert); issuerSerialNumber = GetSerialNumber(issuerCAKeyCert); } else { issuerPublicKey = subjectPublicKey; issuerSerialNumber = serialNumber; } cg.AddExtension(X509Extensions.AuthorityKeyIdentifier.Id, false, new AuthorityKeyIdentifier(SubjectPublicKeyInfoFactory.CreateSubjectPublicKeyInfo(issuerPublicKey), 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 List <GeneralName> generalNames = new List <GeneralName>(); generalNames.Add(new GeneralName(GeneralName.UniformResourceIdentifier, applicationUri)); generalNames.AddRange(CreateSubjectAlternateNameDomains(domainNames)); cg.AddExtension(X509Extensions.SubjectAlternativeName, false, new GeneralNames(generalNames.ToArray())); } else { // Key usage CA cg.AddExtension(X509Extensions.KeyUsage, true, new KeyUsage(KeyUsage.CrlSign | KeyUsage.DigitalSignature | KeyUsage.KeyCertSign)); } // sign certificate AsymmetricKeyParameter signingKey; if (issuerCAKeyCert != null) { // signed by issuer signingKey = GetPrivateKeyParameter(issuerCAKeyCert); } else { // self signed signingKey = subjectPrivateKey; } ISignatureFactory signatureFactory = new Asn1SignatureFactory(GetRSAHashAlgorithm(hashSizeInBits), signingKey, random); Org.BouncyCastle.X509.X509Certificate x509 = cg.Generate(signatureFactory); // convert to X509Certificate2 X509Certificate2 certificate = null; if (subjectPrivateKey == null) { // create the cert without the private key certificate = new X509Certificate2(x509.GetEncoded()); } else { // note: this cert has a private key! certificate = CreateCertificateWithPrivateKey(x509, null, subjectPrivateKey, random); } Utils.Trace(Utils.TraceMasks.Security, "Created new certificate: {0}", certificate.Thumbprint); // add cert to the store. if (!String.IsNullOrEmpty(storePath) && !String.IsNullOrEmpty(storeType)) { using (ICertificateStore store = CertificateStoreIdentifier.CreateStore(storeType)) { if (store == null) { throw new ArgumentException("Invalid store type"); } store.Open(storePath); store.Add(certificate, password).Wait(); store.Close(); } } return(certificate); } }
public async Task VerifyAppCertDirectoryStore() { var appCertificate = GetTestCert(); Assert.NotNull(appCertificate); Assert.True(appCertificate.HasPrivateKey); string password = Guid.NewGuid().ToString(); // pki directory root for app cert var pkiRoot = Path.GetTempPath() + Path.GetRandomFileName() + Path.DirectorySeparatorChar; var storePath = pkiRoot + "own"; var storeType = CertificateStoreType.Directory; appCertificate.AddToStore( storeType, storePath, password ); using (var publicKey = new X509Certificate2(appCertificate.RawData)) { Assert.NotNull(publicKey); Assert.False(publicKey.HasPrivateKey); var id = new CertificateIdentifier() { Thumbprint = publicKey.Thumbprint, StorePath = storePath, StoreType = storeType }; { // check no password fails to load var nullKey = await id.LoadPrivateKey(null).ConfigureAwait(false); Assert.IsNull(nullKey); } { // check invalid password fails to load var nullKey = await id.LoadPrivateKey("123").ConfigureAwait(false); Assert.IsNull(nullKey); } { // check invalid password fails to load var nullKey = await id.LoadPrivateKeyEx(new CertificatePasswordProvider("123")).ConfigureAwait(false); Assert.IsNull(nullKey); } var privateKey = await id.LoadPrivateKeyEx(new CertificatePasswordProvider(password)).ConfigureAwait(false); Assert.NotNull(privateKey); Assert.True(privateKey.HasPrivateKey); X509Utils.VerifyRSAKeyPair(publicKey, privateKey, true); using (ICertificateStore store = Opc.Ua.CertificateStoreIdentifier.CreateStore(storeType)) { store.Open(storePath); await store.Delete(publicKey.Thumbprint).ConfigureAwait(false); } } }
/// <summary> /// Returns an object that can be used to access the store. /// </summary> public ICertificateStore OpenStore() { ICertificateStore store = CreateStore(this.StoreType); store.Open(this.StorePath); return store; }