コード例 #1
0
        /// <summary>
        /// Checks if we have to renew the specific certificate just yet.
        /// </summary>
        /// <param name="options"></param>
        /// <param name="cfg"></param>
        /// <param name="cancellationToken"></param>
        /// <returns>The cert if it is still valid according to rules in config. False otherwise.</returns>
        private async Task <ICertificate> GetExistingCertificateAsync(
            IAcmeOptions options,
            CertificateRenewalOptions cfg,
            CancellationToken cancellationToken)
        {
            if (cfg.Overrides.NewCertificate)
            {
                // ignore existing certificate
                _log.LogWarning($"Override '{nameof(cfg.Overrides.NewCertificate)}' is enabled, forcing certificate renewal.");
                return(null);
            }

            var certStore = _renewalOptionParser.ParseCertificateStore(cfg);

            // determine if renewal is needed based on existing cert
            var existingCert = await certStore.GetCertificateAsync(cancellationToken);

            // check if cert exists and that it is valid right now
            if (existingCert != null)
            {
                // handle cases of manually uploaded certificates
                if (!existingCert.Expires.HasValue)
                {
                    throw new NotSupportedException($"Missing expiration value on certificate {existingCert.Name} (provider: {certStore.Type}). " +
                                                    "Must be set to expiration date of the certificate.");
                }

                var now = DateTime.UtcNow;
                // must be valid now and some day in the future based on config expiration rule
                var isValidAlready = !existingCert.NotBefore.HasValue || existingCert.NotBefore.Value < now;
                var isStillValid   = existingCert.Expires.Value.Date.AddDays(-options.RenewXDaysBeforeExpiry) >= now;
                if (isValidAlready && isStillValid)
                {
                    _log.LogInformation($"Certificate {existingCert.Name} (from source: {certStore.Name}) is still valid until {existingCert.Expires.Value}. " +
                                        $"Will be renewed in {(int)(existingCert.Expires.Value - now).TotalDays - options.RenewXDaysBeforeExpiry} days. Skipping renewal.");
                    return(existingCert);
                }
                var reason = !isValidAlready ?
                             $"certificate won't be valid until {existingCert.NotBefore}" :
                             $"renewal is demanded {options.RenewXDaysBeforeExpiry} days before expiry and it is currently {(int)(existingCert.Expires.Value - now).TotalDays} days before expiry";

                _log.LogInformation($"Certificate {existingCert.Name} (from source: {certStore.Name}) is no longer up to date ({reason}).");
            }
            // either no cert or expired
            return(null);
        }
コード例 #2
0
        /// <summary>
        /// Checks if we have to renew the specific certificate just yet.
        /// </summary>
        /// <param name="options"></param>
        /// <param name="cfg"></param>
        /// <param name="cancellationToken"></param>
        /// <returns>The cert if it is still valid according to rules in config. False otherwise.</returns>
        private async Task <ICertificate> GetExistingCertificateAsync(
            IAcmeOptions options,
            CertificateRenewalOptions cfg,
            CancellationToken cancellationToken)
        {
            if (cfg.Overrides.ForceNewCertificates)
            {
                // if overrides contain domain whitelist then only ignore existing certificate if it is not matched
                if (cfg.Overrides.DomainsToUpdate.Any())
                {
                    if (cfg.Overrides.DomainsToUpdate.Any(domain => cfg.HostNames.Contains(domain, StringComparison.OrdinalIgnoreCase)))
                    {
                        _logger.LogWarning($"Override '{nameof(cfg.Overrides.ForceNewCertificates)}' is enabled, forcing certificate renewal.");
                        return(null);
                    }
                    _logger.LogWarning($"Override '{nameof(cfg.Overrides.ForceNewCertificates)}' is enabled but certificate does not match any of the hostnames -> force renewal is not applied to this certificate.");
                }
                else
                {
                    // ignore existing certificate
                    _logger.LogWarning($"Override '{nameof(cfg.Overrides.ForceNewCertificates)}' is enabled, forcing certificate renewal.");
                    return(null);
                }
            }

            var certStore = _renewalOptionParser.ParseCertificateStore(cfg);

            // determine if renewal is needed based on existing cert
            var existingCert = await certStore.GetCertificateAsync(cancellationToken);

            // check if cert exists and that it is valid right now
            if (existingCert != null)
            {
                // handle cases of manually uploaded certificates
                if (!existingCert.Expires.HasValue)
                {
                    throw new NotSupportedException($"Missing expiration value on certificate {existingCert.Name} (provider: {certStore.Type}). " +
                                                    "Must be set to expiration date of the certificate.");
                }

                var now = DateTime.UtcNow;
                // must be valid now and some day in the future based on config expiration rule
                var isValidAlready = !existingCert.NotBefore.HasValue || existingCert.NotBefore.Value < now;
                var isStillValid   = existingCert.Expires.Value.Date.AddDays(-options.RenewXDaysBeforeExpiry) >= now;
                if (isValidAlready && isStillValid)
                {
                    _logger.LogInformation($"Certificate {existingCert.Name} (from source: {certStore.Name}) is still valid until {existingCert.Expires.Value}. " +
                                           $"Will be renewed in {(int)(existingCert.Expires.Value - now).TotalDays - options.RenewXDaysBeforeExpiry} days. Skipping renewal.");

                    // ensure cert covers all requested domains exactly (order doesn't matter, but one cert more or less does)
                    var requestedDomains = cfg.HostNames
                                           .Select(s => s.ToLowerInvariant())
                                           .OrderBy(s => s)
                                           .ToArray();
                    var certDomains = existingCert.HostNames
                                      .Select(s => s.ToLowerInvariant())
                                      .OrderBy(s => s)
                                      .ToArray();
                    if (!requestedDomains.SequenceEqual(certDomains))
                    {
                        // if not exact domains as requested consider invalid and issue a new cert
                        return(null);
                    }
                    return(existingCert);
                }
                var reason = !isValidAlready ?
                             $"certificate won't be valid until {existingCert.NotBefore}" :
                             $"renewal is demanded {options.RenewXDaysBeforeExpiry} days before expiry and it is currently {(int)(existingCert.Expires.Value - now).TotalDays} days before expiry";

                _logger.LogInformation($"Certificate {existingCert.Name} (from source: {certStore.Name}) is no longer up to date ({reason}).");
            }
            // either no cert or expired
            return(null);
        }