public async Task <List <PersonalCertificate> > GetCertificatesFromStore(CertificateStoreType certificateStoreType, bool onlyValid = true, CancellationToken cancellationToken = default, IProgress <ProgressData> progress = null) { var manager = await this.managerFactory.GetProxyFor(SelfElevationLevel.AsInvoker, cancellationToken).ConfigureAwait(false); cancellationToken.ThrowIfCancellationRequested(); return(await manager.GetCertificatesFromStore(certificateStoreType, onlyValid, cancellationToken, progress).ConfigureAwait(false)); }
static ICertificateStore CreateCertificateStore(CertificateStoreType type) { switch (type) { case CertificateStoreType.File: { var storename = ConfigurationManager.AppSettings.Get("CertificateStoreId"); var clientConfig = ((AuthorisedClientsSection)ConfigurationManager.GetSection("AuthorisedClients")).AuthorisedClientElement(storename); return(new FileCertificateStore(clientConfig)); } case CertificateStoreType.MSCert: return(new MsCertificateStore()); case CertificateStoreType.AzureKeyVault: { var authorisedClientIdentifier = ConfigurationManager.AppSettings["AuthorisedClientId"]; var clientConfig = ((AuthorisedClientsSection)ConfigurationManager.GetSection("AuthorisedClients")).AuthorisedClientElement(authorisedClientIdentifier); var keyVaultUrl = ConfigurationManager.AppSettings["Key Vault URL"]; var adClientId = ConfigurationManager.AppSettings["Azure AD client identifier"]; var adClientSecret = ConfigurationManager.AppSettings["Azure AD client secret"]; var inMemLifeSpanInMinutes = int.Parse(ConfigurationManager.AppSettings["In-memory certificate life span (minutes)"]); var keyVaultClient = new KeyVaultClient(async(authority, resource, scope) => { var authContext = new AuthenticationContext(authority); var clientCredential = new ClientCredential(adClientId, adClientSecret); var authenticationResult = await authContext.AcquireTokenAsync(resource, clientCredential); if (authenticationResult == null) { throw new InvalidOperationException("failed to obtain JWT token"); } return(authenticationResult.AccessToken); }); var clientEncryptionCertProvider = CreateCertificateProvider(clientConfig, Owner.Client, Usage.ContentEncryption, keyVaultUrl, keyVaultClient); var clientSignatureCertProvider = CreateCertificateProvider(clientConfig, Owner.Client, Usage.Signature, keyVaultUrl, keyVaultClient); var bankEncryptionCertProvider = CreateCertificateProvider(clientConfig, Owner.DB, Usage.ContentEncryption, keyVaultUrl, keyVaultClient); var bankSignatureCertProvider = CreateCertificateProvider(clientConfig, Owner.DB, Usage.Signature, keyVaultUrl, keyVaultClient); var timeProvider = new SystemTimeProvider(); return(new AzureKeyVaultCertificateStore( clientEncryptionCertProvider, clientSignatureCertProvider, bankEncryptionCertProvider, bankSignatureCertProvider, timeProvider, new TimeSpan(0, inMemLifeSpanInMinutes, 0))); } default: throw new Exception("Unknown certificatestore type"); } }
/// <summary> /// Returns the byte representation of the serialized store. /// </summary> /// <param name="type">One of the <see cref="CertificateStoreType"/> values.</param> /// <returns>An array of bytes that represents the encoded store.</returns> /// <exception cref="CertificateException">An error occurs while saving the store to the memory buffer.</exception> private byte[] GetCerBuffer(CertificateStoreType type) { DataBlob data = new DataBlob(); try { data.cbData = 0; data.pbData = IntPtr.Zero; if (SspiProvider.CertSaveStore(this.Handle, SecurityConstants.X509_ASN_ENCODING | SecurityConstants.PKCS_7_ASN_ENCODING, (int)type, SecurityConstants.CERT_STORE_SAVE_TO_MEMORY, ref data, 0) == 0) throw new CertificateException("Unable to get the certificate data."); data.pbData = Marshal.AllocHGlobal(data.cbData); if (SspiProvider.CertSaveStore(this.Handle, SecurityConstants.X509_ASN_ENCODING | SecurityConstants.PKCS_7_ASN_ENCODING, (int)type, SecurityConstants.CERT_STORE_SAVE_TO_MEMORY, ref data, 0) == 0) throw new CertificateException("Unable to get the certificate data."); byte[] ret = new byte[data.cbData]; Marshal.Copy(data.pbData, ret, 0, data.cbData); return ret; } finally { if (data.pbData != IntPtr.Zero) Marshal.FreeHGlobal(data.pbData); } }
/// <summary> /// Saves the <see cref="CertificateStore"/> in a buffer. /// </summary> /// <param name="type">One of the <see cref="CertificateStoreType"/> values.</param> /// <returns>An array of bytes that represents the encoded store.</returns> /// <exception cref="CertificateException">An error occurs while saving the store to the memory buffer.</exception> public byte[] ToCerBuffer(CertificateStoreType type) { return GetCerBuffer(type); }
/// <summary> /// Saves the <see cref="CertificateStore"/> in a file. /// </summary> /// <param name="filename">The filename of the serialized store.</param> /// <param name="type">One of the <see cref="CertificateStoreType"/> values.</param> /// <exception cref="ArgumentNullException"><paramref name="filename"/> is a null reference (<b>Nothing</b> in Visual Basic).</exception> /// <exception cref="CertificateException">An error occurs while saving the store to the memory buffer.</exception> /// <exception cref="IOException">An error occurs while writing the data.</exception> public void ToCerFile(string filename, CertificateStoreType type) { SaveToFile(GetCerBuffer(type), filename); }
/// <summary> /// Opens a serialized certificate store or a certificate store with signed PKCS7 messages. /// </summary> /// <param name="buffer">The bytes of the store to open.</param> /// <param name="type">One of the <see cref="CertificateStoreType"/> values.</param> /// <exception cref="ArgumentNullException"><paramref name="buffer"/> is a null reference (<b>Nothing</b> in Visual Basic).</exception> /// <exception cref="CertificateException">An error occurs while opening the store.</exception> public CertificateStore(byte[] buffer, CertificateStoreType type) { if (buffer == null) throw new ArgumentNullException(); DataBlob data = new DataBlob(); data.cbData = buffer.Length; data.pbData = Marshal.AllocHGlobal(data.cbData); Marshal.Copy(buffer, 0, data.pbData, buffer.Length); IntPtr provider; if (type == CertificateStoreType.Pkcs7Message) provider = new IntPtr(SecurityConstants.CERT_STORE_PROV_PKCS7); else provider = new IntPtr(SecurityConstants.CERT_STORE_PROV_SERIALIZED); m_Handle = SspiProvider.CertOpenStoreData(provider, SecurityConstants.X509_ASN_ENCODING | SecurityConstants.PKCS_7_ASN_ENCODING, IntPtr.Zero, 0, ref data); Marshal.FreeHGlobal(data.pbData); if (m_Handle == IntPtr.Zero) throw new CertificateException("An error occurs while opening the store."); }
protected void OneTimeSetUp() { CertificateStoreType.RegisterCertificateStoreType("testStoreType", new TestStoreType()); }
private static PersonalCertificate CreateFromX509(X509Certificate certificate, CertificateStoreType certStoreType) { var parser = new X509CertificateParser(); var read = parser.ReadCertificate(certificate.GetRawCertData()); var cert = new PersonalCertificate { Issuer = certificate.Issuer, Thumbprint = certificate.GetCertHashString(), Subject = certificate.Subject, DigestAlgorithm = (read.SigAlgName.EndsWith("withRSA", StringComparison.OrdinalIgnoreCase) ? read.SigAlgName.Substring(0, read.SigAlgName.Length - "withRSA".Length) : read.SigAlgName).Replace("-", string.Empty), StoreType = certStoreType }; var list = read.SubjectDN.GetValueList(); if (list?.Count > 0) { // ReSharper disable once PossibleNullReferenceException cert.DisplayName = list[^ 1].ToString();
private static PersonalCertificate CreateFromX509(X509Certificate2 certificate, CertificateStoreType certStoreType) { var cert = new PersonalCertificate { DisplayName = certificate.FriendlyName, Date = certificate.NotAfter, Issuer = certificate.Issuer, Subject = certificate.Subject, Thumbprint = certificate.Thumbprint, DigestAlgorithm = certificate.SignatureAlgorithm.FriendlyName, StoreType = certStoreType }; return(cert); }
public async Task <List <PersonalCertificate> > GetCertificatesFromStore(CertificateStoreType certStoreType, bool onlyValid = true, CancellationToken cancellationToken = default, IProgress <ProgressData> progress = null) { StoreLocation loc; switch (certStoreType) { case CertificateStoreType.User: loc = StoreLocation.CurrentUser; break; case CertificateStoreType.Machine: loc = StoreLocation.LocalMachine; break; case CertificateStoreType.MachineUser: var list1 = await this.GetCertificatesFromStore(CertificateStoreType.User, onlyValid, cancellationToken, progress).ConfigureAwait(false); var list2 = await this.GetCertificatesFromStore(CertificateStoreType.Machine, onlyValid, cancellationToken, progress).ConfigureAwait(false); // Remove duplicated certificates for (var index = list2.Count - 1; index >= 0; index--) { var item = list2[index]; if (list1.Any(otherItem => item.Thumbprint == otherItem.Thumbprint)) { list2.RemoveAt(index); } } return(list1.Concat(list2).ToList()); default: throw new ArgumentOutOfRangeException(nameof(certStoreType), certStoreType, null); } Logger.Info($"Getting the list of certificates from {loc} containing a private key and in a valid time range."); using var store = new X509Store(StoreName.My, loc); store.Open(OpenFlags.ReadOnly | OpenFlags.OpenExistingOnly); var list = new List <PersonalCertificate>(); X509Certificate2Collection col; if (onlyValid) { col = store.Certificates.Find(X509FindType.FindByKeyUsage, X509KeyUsageFlags.DigitalSignature, true); } else { col = store.Certificates; } foreach (var certificate in col) { Logger.Debug("Processing certificate {0}...", certificate); cancellationToken.ThrowIfCancellationRequested(); list.Add(CreateFromX509(certificate, certStoreType)); } store.Close(); return(list); }