public Task PersistAsync(CertificateType persistenceType, IPersistableCertificate certificate)
        {
            switch (persistenceType)
            {
            case CertificateType.Account:
                _accountCertificate = (IKeyCertificate)certificate;
                break;

            case CertificateType.Site:
                _siteCertificate = certificate;
                break;

            default:
                throw new ArgumentException("Unhandled persistence type", nameof(persistenceType));
            }
            return(Task.CompletedTask);
        }
コード例 #2
0
        public async Task <CertificateRenewalResult> RenewCertificateIfNeeded(IAbstractCertificate current = null)
        {
            _logger.LogInformation("Checking to see if in-memory LetsEncrypt certificate needs renewal.");
            if (_certificateValidator.IsCertificateValid(current))
            {
                _logger.LogInformation("Current in-memory LetsEncrypt certificate is valid.");
                return(new CertificateRenewalResult(current, CertificateRenewalStatus.Unchanged));
            }

            _logger.LogInformation("Checking to see if existing LetsEncrypt certificate has been persisted and is valid.");
            var persistedSiteCertificate = await _persistenceService.GetPersistedSiteCertificateAsync();

            if (_certificateValidator.IsCertificateValid(persistedSiteCertificate))
            {
                _logger.LogInformation("A persisted non-expired LetsEncrypt certificate was found and will be used: {Thumbprint}", persistedSiteCertificate.Thumbprint);
                return(new CertificateRenewalResult(persistedSiteCertificate, CertificateRenewalStatus.LoadedFromStore));
            }

            _logger.LogInformation("No valid certificate was found. Requesting new certificate from LetsEncrypt.");
            var newCertificate = await RequestNewLetsEncryptCertificate();

            return(new CertificateRenewalResult(newCertificate, CertificateRenewalStatus.Renewed));
        }
        public bool IsCertificateValid(IAbstractCertificate certificate)
        {
            try
            {
                if (certificate == null)
                {
                    return(false);
                }

                var now = DateTime.Now;

                _logger.LogTrace("Validating cert UntilExpiry {UntilExpiry}, AfterIssue {AfterIssue} - {Certificate}",
                                 _options.TimeUntilExpiryBeforeRenewal, _options.TimeAfterIssueDateBeforeRenewal, certificate);

                if (_options.TimeUntilExpiryBeforeRenewal != null && certificate.NotAfter - now < _options.TimeUntilExpiryBeforeRenewal)
                {
                    return(false);
                }

                if (_options.TimeAfterIssueDateBeforeRenewal != null && now - certificate.NotBefore > _options.TimeAfterIssueDateBeforeRenewal)
                {
                    return(false);
                }

                if (certificate.NotBefore > now || certificate.NotAfter < now)
                {
                    return(false);
                }

                return(true);
            }
            catch (CryptographicException exc)
            {
                _logger.LogError(exc, "Exception occured during certificate validation");
                return(false);
            }
        }
        public async Task RunOnceAsync()
        {
            if (_semaphoreSlim.CurrentCount == 0)
            {
                return;
            }

            await _semaphoreSlim.WaitAsync();

            try
            {
                var result = await _certificateProvider.RenewCertificateIfNeeded(Certificate);

                if (result.Status != Unchanged)
                {
                    // Preload intermediate certs before exposing certificate to the Kestrel
                    using var chain = new X509Chain
                          {
                              ChainPolicy =
                              {
                                  RevocationMode = X509RevocationMode.NoCheck
                              }
                          };

                    if (result.Certificate is LetsEncryptX509Certificate x509cert)
                    {
                        if (chain.Build(x509cert.GetCertificate()))
                        {
                            _logger.LogInformation("Successfully built certificate chain");
                        }
                        else
                        {
                            _logger.LogWarning(
                                "Was not able to build certificate chain. This can cause an outage of your app.");
                        }
                    }
                }

                Certificate = result.Certificate;

                if (result.Status == Renewed)
                {
                    foreach (var lifecycleHook in _lifecycleHooks)
                    {
                        await lifecycleHook.OnRenewalSucceededAsync();
                    }
                }
            }
            catch (Exception ex)
            {
                foreach (var lifecycleHook in _lifecycleHooks)
                {
                    await lifecycleHook.OnExceptionAsync(ex);
                }

                throw;
            }
            finally
            {
                _semaphoreSlim.Release();
            }
        }
コード例 #5
0
 public CertificateRenewalResult(IAbstractCertificate certificate, CertificateRenewalStatus status)
 {
     Certificate = certificate;
     Status      = status;
 }