Example #1
0
        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));
        }
Example #2
0
        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");
            }
        }
Example #3
0
		/// <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);
			}
		}
Example #4
0
		/// <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);
		}
Example #5
0
		/// <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);
		}
Example #6
0
		/// <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.");
		}
Example #7
0
 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);
        }