protected virtual X509Certificate2 InstallCertificate(X509Store store, string certificateName)
        {
            if (_certificateCache.TryGetValue(certificateName, out X509Certificate2 certificate))
            {
                if (DateTime.Now >= certificate.NotAfter)
                {
                    _certificateCache.Remove(certificateName);
                }
                else
                {
                    return(certificate);
                }
            }
            lock (store)
            {
                try
                {
                    store.Open(OpenFlags.ReadWrite);
                    string subjectName = $"CN={certificateName}, O={Issuer}";

                    certificate = FindCertificates(store, subjectName)?[0];
                    if (certificate != null && DateTime.Now >= certificate.NotAfter)
                    {
                        if (Authority == null)
                        {
                            DestroyCertificates();
                            store.Open(OpenFlags.ReadWrite);
                        }
                        else
                        {
                            store.Remove(certificate);
                        }
                        certificate = null;
                    }

                    if (certificate == null)
                    {
                        certificate = CertificateEngine.CreateCertificate(subjectName, certificateName, Authority);
                        if (certificate != null)
                        {
                            if (store == RootStore || IsStoringPersonalCertificates)
                            {
                                store.Add(certificate);
                            }
                        }
                    }

                    return(certificate);
                }
                catch { return(certificate = null); }
                finally
                {
                    store.Close();
                    if (certificate != null && !_certificateCache.ContainsKey(certificateName))
                    {
                        _certificateCache.Add(certificateName, certificate);
                    }
                }
            }
        }
        internal CertificateManager(CertificateEngine engine,
                                    string issuer,
                                    string rootCertificateName,
                                    Action <Exception> exceptionFunc)
        {
            this.exceptionFunc = exceptionFunc;

            //For Mono only Bouncy Castle is supported
            if (RunTime.IsRunningOnMono() ||
                engine == CertificateEngine.BouncyCastle)
            {
                certEngine = new BCCertificateMaker();
            }
            else
            {
                certEngine = new WinCertificateMaker();
            }

            Issuer = issuer;
            RootCertificateName = rootCertificateName;

            certificateCache = new ConcurrentDictionary <string, CachedCertificate>();
        }