Пример #1
0
 public AcmeClient(IDnsProvider dnsProvider, DnsLookupService dnsLookupService, ICertificateStore certifcateStore, ILogger <AcmeClient> logger = null)
 {
     this.dnsProvider      = dnsProvider;
     this.dnsLookupService = dnsLookupService;
     this.certificateStore = certifcateStore;
     this.logger           = logger ?? NullLogger <AcmeClient> .Instance;
 }
Пример #2
0
 public AcmeClient(IDnsProvider dnsProvider, DnsLookupService dnsLookupService, IFileSystem fileSystem = null, ILogger <AcmeClient> logger = null)
 {
     this.dnsProvider      = dnsProvider;
     this.dnsLookupService = dnsLookupService;
     this.fileSystem       = fileSystem ?? new FileSystem();
     this.logger           = logger ?? NullLogger <AcmeClient> .Instance;
 }
Пример #3
0
        /// <summary>
        /// Request a certificate from lets encrypt using the DNS challenge, placing the challenge record in Azure DNS.
        /// The certifiacte is not assigned, but just returned.
        /// </summary>
        /// <param name="azureDnsEnvironment"></param>
        /// <param name="acmeConfig"></param>
        /// <returns></returns>
        public async Task <CertificateInstallModel> RequestDnsChallengeCertificate(IAcmeDnsRequest acmeConfig)
        {
            logger.LogInformation("Starting request DNS Challenge certificate for {AcmeEnvironment} and {Email}", acmeConfig.AcmeEnvironment.BaseUri, acmeConfig.RegistrationEmail);
            var acmeContext = await GetOrCreateAcmeContext(acmeConfig.AcmeEnvironment.BaseUri, acmeConfig.RegistrationEmail);

            var idn = new IdnMapping();

            var order = await acmeContext.NewOrder(new[] { "*." + idn.GetAscii(acmeConfig.Host.Substring(2)) });

            var a = await order.Authorizations();

            var authz     = a.First();
            var challenge = await authz.Dns();

            var dnsTxt = acmeContext.AccountKey.DnsTxt(challenge.Token);

            logger.LogInformation("Got DNS challenge token {Token}", dnsTxt);

            ///add dns entry
            await this.dnsProvider.PersistChallenge(String.Concat("_acme-challenge.", DnsLookupService.GetNoneWildcardSubdomain(acmeConfig.Host)), dnsTxt);

            if (!(await this.dnsLookupService.Exists(acmeConfig.Host, dnsTxt, this.dnsProvider.MinimumTtl)))
            {
                throw new TimeoutException($"Unable to validate that _acme-challenge was stored in txt _acme-challenge record after {this.dnsProvider.MinimumTtl} seconds");
            }


            Challenge chalResp = await challenge.Validate();

            while (chalResp.Status == ChallengeStatus.Pending || chalResp.Status == ChallengeStatus.Processing)
            {
                logger.LogInformation("Dns challenge response status {ChallengeStatus} more info at {ChallengeStatusUrl} retrying in 5 sec", chalResp.Status, chalResp.Url.ToString());
                await Task.Delay(5000);

                chalResp = await challenge.Resource();
            }

            logger.LogInformation("Finished validating dns challenge token, response was {ChallengeStatus} more info at {ChallengeStatusUrl}", chalResp.Status, chalResp.Url);

            var privateKey = await GetOrCreateKey(acmeConfig.AcmeEnvironment.BaseUri, acmeConfig.Host);

            var cert = await order.Generate(new Certes.CsrInfo
            {
                CountryName      = acmeConfig.CsrInfo.CountryName,
                State            = acmeConfig.CsrInfo.State,
                Locality         = acmeConfig.CsrInfo.Locality,
                Organization     = acmeConfig.CsrInfo.Organization,
                OrganizationUnit = acmeConfig.CsrInfo.OrganizationUnit,
                CommonName       = acmeConfig.CsrInfo.CommonName,
            }, privateKey);

            var certPem = cert.ToPem();

            var pfxBuilder = cert.ToPfx(privateKey);
            var pfx        = pfxBuilder.Build(acmeConfig.Host, acmeConfig.PFXPassword);

            await this.dnsProvider.Cleanup(dnsTxt);

            return(new CertificateInstallModel()
            {
                CertificateInfo = new CertificateInfo()
                {
                    Certificate = new X509Certificate2(pfx, acmeConfig.PFXPassword, X509KeyStorageFlags.DefaultKeySet | X509KeyStorageFlags.PersistKeySet | X509KeyStorageFlags.Exportable),
                    Name = $"{acmeConfig.Host} {DateTime.Now}",
                    Password = acmeConfig.PFXPassword,
                    PfxCertificate = pfx
                },
                Host = acmeConfig.Host
            });
        }