Esempio n. 1
0
        public async Task <FinalizeOutput> FinalizeOrder(FinalizeInput input, ILogger logger)
        {
            var context  = new AcmeContext(State.LetsEncryptEndpoint, KeyFactory.FromPem(State.Pem));
            var orderId  = string.Join("", input.Domains).ToMD5Hash();
            var orderCtx = context.Order(new Uri(State.Orders[orderId]));
            var order    = await orderCtx.Resource();

            if (order.Status == OrderStatus.Ready)
            {
                var certKey = KeyFactory.NewKey(KeyAlgorithm.ES256);

                order = await orderCtx.Finalize(
                    input.CsrInfo, certKey);

                if (order.Status == Certes.Acme.Resource.OrderStatus.Invalid)
                {
                    throw new Exception(order?.Error?.ToString() ?? $"{orderCtx} is invalid");
                }


                var certChain = await orderCtx.Download();

                var pfx  = certChain.ToPfx(certKey).Build("CN=" + input.Domains.First(), "");
                var cert = new X509Certificate2(pfx);
                return(new FinalizeOutput {
                    Pfx = pfx, Thumbprint = cert.Thumbprint
                });
            }

            throw new Exception(order?.Error?.ToString() ?? $"{orderCtx} is invalid");
        }
Esempio n. 2
0
        public static void TestHost(
            [Required(Description = "Host name")] string hostName,
            [Optional(null, "cfg", Description = "Custom configuration file name")] string cfgFileName,
            [Optional(false, Description = "Show verbose error messages")] bool verbose)
        {
            verboseMode = verbose;
            if (cfgStore == null)
            {
                LoadConfig(cfgFileName);
            }
            hostName = hostName.Trim().ToLower();

            var result = AcmeContext.TestAuthorization(hostName, CreateChallenge, CleanupChallenge);

            Trace.WriteLine(string.Empty);

            if (result)
            {
                Trace.WriteLine("Test authorization was successful. The real verification may still fail,");
                Trace.WriteLine("ie. when server is not accessible from outside.");
            }
            else
            {
                Trace.WriteLine("Test authorization failed. Examine the above to find out why.");
            }
        }
Esempio n. 3
0
        public static async Task <Client> Login(string mail, Func <HttpClient> httpClientGenerator, string dnsimpleToken, Account?account = null, bool production = true)
        {
            var acmeHttpClient = new AcmeHttpClient(GetServer(production), httpClientGenerator());

            AcmeContext acme;

            if (account == null)
            {
                acme = new AcmeContext(GetServer(production), null, acmeHttpClient);
                await acme.NewAccount(mail, true);

                account = new Account(acme.AccountKey);
            }
            else
            {
                acme = new AcmeContext(GetServer(production), account.Key, acmeHttpClient);
            }

            var client = new DNSimple.Client(httpClientGenerator());

            client.UseToken(dnsimpleToken);

            var dnsimple = await client.GetAccount(mail);

            return(new Client(acme, dnsimple, account));
        }
Esempio n. 4
0
        public async Task <AcmeContext> NewAcmeContextAsync(string serverAlias)
        {
            Uri acmeServerUri = GetAcmeServerUri(serverAlias);

            AcmeContext acmeCtx;

            var accountKey = await keyCache.GetAccountKey(serverAlias);

            if (accountKey != null)
            {
                acmeCtx = new AcmeContext(acmeServerUri, accountKey);
                await acmeCtx.Account();

                logger.LogInformation("Created ACME account from cached key, server: {serverUri}", acmeServerUri);
            }
            else
            {
                acmeCtx = new AcmeContext(acmeServerUri);
                await acmeCtx.NewAccount(settings.AcmeAccount.Email, true);

                await keyCache.SaveAccountKey(acmeCtx.AccountKey, serverAlias);

                logger.LogInformation("Created new ACME account, server: {serverUri}", acmeServerUri);
            }

            return(acmeCtx);
        }
Esempio n. 5
0
        public async Task <IActionResult> Delete([FromServices] AcmeContext context, [FromRoute] TKey id)
        {
            int next;

            lock (random)
            {
                next = random.Next(0, 2);
            }

            if (next == 0)
            {
                return(BadRequest(new Exception("BLEEE")));
            }
            else if (next == 1)
            {
                return(BadRequest("Reeee 2"));
            }

            var model = context.Set <T>().Find(id);

            context.Set <T>().Remove(model);
            await context.SaveChangesAsync();

            return(Ok());
        }
Esempio n. 6
0
        public async Task <string> InitWithNewAccountAsync(string emailId)
        {
            acmeContext = new AcmeContext(WellKnownServers.LetsEncryptV2);
            await acmeContext.NewAccount(emailId, true);

            return(acmeContext.AccountKey.ToPem());
        }
Esempio n. 7
0
        // This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
        public void Configure(IApplicationBuilder app, IWebHostEnvironment env, AcmeContext context)
        {
            if (env.IsDevelopment())
            {
                app.UseDeveloperExceptionPage();
            }

            context.Database.Migrate();

            // Enable middleware to serve generated Swagger as a JSON endpoint.
            app.UseSwagger();
            app.UseSwaggerUI(c =>
            {
                c.SwaggerEndpoint("/swagger/v1/swagger.json", "ACME Account Management V1");
                //c.RoutePrefix = string.Empty;
            });

            app.UseRouting();

            app.UseAuthorization();

            app.UseEndpoints(endpoints =>
            {
                endpoints.MapControllers();
            });
        }
        private async Task <IAcmeContext> GetContext()
        {
            if (_acme != null)
            {
                return(_acme);
            }

            var existingAccountKey = await _persistenceService.GetPersistedAccountCertificateAsync();

            if (existingAccountKey != null)
            {
                _logger.LogDebug("Using existing LetsEncrypt account.");
                var acme = new AcmeContext(_options.LetsEncryptUri, existingAccountKey);
                await acme.Account();

                return(_acme = acme);
            }
            else
            {
                _logger.LogDebug("Creating LetsEncrypt account with email {0}.", _options.Email);
                var acme = new AcmeContext(_options.LetsEncryptUri);
                await acme.NewAccount(_options.Email, true);

                await _persistenceService.PersistAccountCertificateAsync(acme.AccountKey);

                return(_acme = acme);
            }
        }
        public async Task RetryOnBadNonce()
        {
            var accountLoc = new Uri("https://acme.d/acct/1");
            var httpMock   = new Mock <IAcmeHttpClient>();

            httpMock.Setup(m => m.Get <Directory>(It.IsAny <Uri>()))
            .ReturnsAsync(new AcmeHttpResponse <Directory>(
                              accountLoc, MockDirectoryV2, null, null));
            httpMock.SetupSequence(
                m => m.Post <Account>(MockDirectoryV2.NewAccount, It.IsAny <object>()))
            .ReturnsAsync(new AcmeHttpResponse <Account>(
                              accountLoc, null, null, new AcmeError
            {
                Status = HttpStatusCode.BadRequest,
                Type   = "urn:ietf:params:acme:error:badNonce"
            }))
            .ReturnsAsync(new AcmeHttpResponse <Account>(
                              accountLoc, new Account
            {
                Status = AccountStatus.Valid
            }, null, null));

            var key = KeyFactory.NewKey(KeyAlgorithm.RS256);
            var ctx = new AcmeContext(
                WellKnownServers.LetsEncryptStagingV2,
                key,
                httpMock.Object);

            await ctx.NewAccount("", true);

            httpMock.Verify(m => m.Post <Account>(MockDirectoryV2.NewAccount, It.IsAny <object>()), Times.Exactly(2));
        }
Esempio n. 10
0
        private void ShowThumbprint(AcmeContext context)
        {
            var account    = new AccountKey(context.Account.Key);
            var thumbprint = JwsConvert.ToBase64String(account.GenerateThumbprint());

            ConsoleLogger.Info(thumbprint);
        }
Esempio n. 11
0
        private async Task <AcmeContext> UpdateAccount(AcmeContext context)
        {
            bool changed = false;
            var  account = context.Account;

            using (var client = new AcmeClient(Options.Server))
            {
                client.Use(account.Key);

                if (!string.IsNullOrWhiteSpace(Options.Email))
                {
                    account.Data.Contact = new[] { $"mailto:{Options.Email}" };
                    changed = true;
                }

                var currentTos = account.GetTermsOfServiceUri();
                if (Options.AgreeTos && account.Data.Agreement != currentTos)
                {
                    account.Data.Agreement = currentTos;
                    changed = true;
                }

                if (changed)
                {
                    account = await client.UpdateRegistration(account);
                }
            }

            ConsoleLogger.Info("Registration updated.");
            return(context);
        }
        static ContextAccountBundle GetNonStagingParameters()
        {
            Uri         server = WellKnownServers.LetsEncryptV2;
            AcmeContext ctx;

            if (File.Exists(ACC_LOC))
            {
                ctx = AccountHelper.GetContextWithAccount(ACC_LOC, server);
            }
            else
            {
                ctx = new AcmeContext(server);
            }
            IAccountContext account = AccountHelper.RetriveAccount(ctx);
            Account         accInfo = AccountHelper.RetriveAccountDetails(account);

            if (!accInfo.Status.HasValue)
            {
                throw new AcmeException("Account has not had its status set yet");
            }
            else if (accInfo.Status.Value == AccountStatus.Revoked || accInfo.Status.Value == AccountStatus.Deactivated)
            {
                throw new AcmeException("Account is either revoked or deactivated");
            }
            return(new ContextAccountBundle(ctx, account));
        }
        public static async Task InitAsync(ILogger logger, CertificateMode certificateMode)
        {
            _logger = logger;

            _logger.LogInformation($"Initializing LetsEncrypt bits");

            //ACCOUNT
            _logger.LogInformation("    Creating or Retrieving account");

            if (await AzureHelper.CheckIfFileExistsBlobStorageAsync(Constants.AccountKeyFileName))
            {
                _logger.LogInformation("        Retrieving existing account");

                // Load the saved account key
                var pemKey = await AzureHelper.ReadFileFromBlobStorageToStringAsync(Constants.AccountKeyFileName);

                var accountKey = KeyFactory.FromPem(pemKey);
                _acme = new AcmeContext(certificateMode == CertificateMode.Production ? WellKnownServers.LetsEncryptV2 : WellKnownServers.LetsEncryptStagingV2, accountKey);
                var account = await _acme.Account();
            }
            else
            {
                _logger.LogInformation("        Creating new account");
                _acme = new AcmeContext(certificateMode == CertificateMode.Production ? WellKnownServers.LetsEncryptV2 : WellKnownServers.LetsEncryptStagingV2);
                var account = await _acme.NewAccount(Settings.CertificateOwnerEmail, true);

                // Save the account key for later use
                var pemKey = _acme.AccountKey.ToPem();
                await AzureHelper.SaveFileToBlobStorageAsync(Constants.AccountKeyFileName, pemKey);
            }

            _logger.LogInformation("    Account set");
            _logger.LogInformation(Environment.NewLine);
        }
Esempio n. 14
0
        private async Task <AcmeContext> GetOrCreateAcmeContext(Uri acmeDirectoryUri, string email)
        {
            AcmeContext acme     = null;
            string      filename = $"account{email}--{acmeDirectoryUri.Host}";
            var         secret   = await this.certificateStore.GetSecret(filename);

            if (string.IsNullOrEmpty(secret))
            {
                acme = new AcmeContext(acmeDirectoryUri);
                var account = acme.NewAccount(email, true);

                // Save the account key for later use
                var pemKey = acme.AccountKey.ToPem();
                await certificateStore.SaveSecret(filename, pemKey);

                await Task.Delay(10000); //Wait a little before using the new account.

                acme = new AcmeContext(acmeDirectoryUri, acme.AccountKey, new AcmeHttpClient(acmeDirectoryUri, new HttpClient()));
            }
            else
            {
                var accountKey = KeyFactory.FromPem(secret);
                acme = new AcmeContext(acmeDirectoryUri, accountKey, new AcmeHttpClient(acmeDirectoryUri, new HttpClient()));
            }

            return(acme);
        }
        private static async Task <AcmeContext> LoadAccount()
        {
            AcmeContext acme;

            var server = _configuration.IsStaging ? WellKnownServers.LetsEncryptStagingV2 : WellKnownServers.LetsEncryptV2;

            Log($" 1. Setting Environment {server}...");

            if (String.IsNullOrEmpty(_configuration.AccountPem))
            {
                Log(" 2. Creating account...");
                acme = new AcmeContext(server);
                var account = await acme.NewAccount(_configuration.AccountEmail, true);

                _configuration.AccountPem = acme.AccountKey.ToPem();
            }
            else
            {
                Log(" 2. Using existing account...");
                var accountKey = KeyFactory.FromPem(_configuration.AccountPem);
                acme = new AcmeContext(server, accountKey);
            }

            return(acme);
        }
Esempio n. 16
0
        public override async Task <AcmeContext> Process(AcmeContext context)
        {
            if (context?.Account == null)
            {
                throw new Exception("Account not specified.");
            }

            var values = await GetAllValues();

            if (values.Length == 0)
            {
                throw new Exception("Value not specified.");
            }

            if (!string.IsNullOrWhiteSpace(Options.Complete))
            {
                await CompleteChallenge(context, values);
            }
            else if (!string.IsNullOrWhiteSpace(Options.KeyAuthentication))
            {
                ComputeKeyAuthorization(context, values);
            }
            else if (!string.IsNullOrWhiteSpace(Options.Refresh))
            {
                await RefreshAuthorization(context, values);
            }
            else
            {
                await NewAuthorization(context, values);
            }

            return(context);
        }
Esempio n. 17
0
        /// <summary>
        /// Register a new account with the ACME CA (Let's Encrypt), accepting terms and conditions
        /// </summary>
        /// <param name="log">  </param>
        /// <param name="email">  </param>
        /// <returns>  </returns>
        public async Task <bool> AddNewAccountAndAcceptTOS(ILog log, string email)
        {
            try
            {
                // start new account context, create new account
                _acme = new AcmeContext(_serviceUri);
                var account = await _acme.NewAccount(email, true);

                _settings.AccountEmail = email;

                //store account key
                SaveAccountKey(account);

                SaveSettings();

                log.Information($"Registering account {email} with certificate authority");

                // re-init provider based on new account key
                InitProvider();

                return(true);
            }
            catch (Exception exp)
            {
                log.Error($"Failed to register account {email} with certificate authority: {exp.Message}");
                return(false);
            }
        }
Esempio n. 18
0
        private void ComputeKeyAuthorization(AcmeContext context, string[] values)
        {
            var authorizations = context.Authorizations?.TryGet(Options.Type);

            using (var client = new AcmeClient(Options.Server))
            {
                client.Use(context.Account.Key);

                foreach (var name in values)
                {
                    var auth = authorizations?.TryGet(name);

                    var challenge = auth?
                                    .Data?
                                    .Challenges?
                                    .Where(c => c.Type == Options.KeyAuthentication)
                                    .FirstOrDefault();

                    if (challenge == null)
                    {
                        ConsoleLogger.Warn("{0} NotFound", name);
                    }
                    else
                    {
                        if (string.IsNullOrWhiteSpace(challenge.KeyAuthorization) || Options.Force)
                        {
                            challenge.KeyAuthorization = client.ComputeKeyAuthorization(challenge);
                        }

                        ConsoleLogger.Info("{0} {1}", name, challenge.KeyAuthorization);
                    }
                }
            }
        }
Esempio n. 19
0
        private async Task RefreshAuthorization(AcmeContext context, string[] values)
        {
            var authorizations = context.Authorizations?.TryGet(Options.Type);

            using (var client = new AcmeClient(Options.Server))
            {
                client.Use(context.Account.Key);

                foreach (var name in values)
                {
                    var auth = authorizations?.TryGet(name);
                    if (auth != null)
                    {
                        auth = authorizations[name] = await client.GetAuthorization(auth.Location);

                        var challenge = auth?
                                        .Data?
                                        .Challenges?
                                        .Where(c => c.Type == Options.Refresh)
                                        .FirstOrDefault();

                        ConsoleLogger.Info("{0} {1}", name, challenge.Status);
                    }
                }
            }
        }
Esempio n. 20
0
        private async Task <bool> HandleDns(AcmeContext acme, AcmeConfig config, IEnumerable <IChallengeContext> authorizations, List <INotifyConfig> notificationsList)
        {
            bool isValid = true;
            Dictionary <string, string> dnsValidation = new Dictionary <string, string>();
            var index = -1;

            foreach (var challenge in authorizations)
            {
                index++;
                var domainName = config.DNS.DomainNames[index].Replace("*.", "");
                var acmeDomain = "_acme-challenge." + domainName;
                var dnsText    = acme.AccountKey.DnsTxt(challenge.Token);
                dnsValidation.Add(acmeDomain, dnsText);
                _log.LogInfo($"Add TXT dns for {acmeDomain} to '{dnsText}'");
            }

            await AwaitDnsChanges(dnsValidation, notificationsList);

            Task.WaitAll(authorizations.Select(c => Task.Run(async() =>
            {
                var validation = await c.Validate();
                do
                {
                    if (validation.Status == Certes.Acme.Resource.ChallengeStatus.Pending)
                    {
                        System.Threading.Thread.Sleep(2000);
                        validation = await c.Resource();
                    }
                } while (validation.Status == Certes.Acme.Resource.ChallengeStatus.Pending);
                isValid = isValid && (validation.Status != Certes.Acme.Resource.ChallengeStatus.Invalid);
            })).ToArray());
            return(isValid);
        }
Esempio n. 21
0
        private async Task <AcmeContext> GetOrCreateAcmeContext(Uri acmeDirectoryUri, string email)
        {
            if (!Directory.Exists(configPath))
            {
                Directory.CreateDirectory(configPath);
            }

            AcmeContext acme     = null;
            string      filename = $"account{email}--{acmeDirectoryUri.Host}";
            var         filePath = Path.Combine(configPath, filename);

            if (!File.Exists(filePath) || string.IsNullOrEmpty(File.ReadAllText(filePath)))
            {
                acme = new AcmeContext(acmeDirectoryUri);
                var account = acme.NewAccount(email, true);

                // Save the account key for later use
                var pemKey = acme.AccountKey.ToPem();
                File.WriteAllText(filePath, pemKey);
                await Task.Delay(10000); //Wait a little before using the new account.

                acme = new AcmeContext(acmeDirectoryUri, acme.AccountKey, new AcmeHttpClient(acmeDirectoryUri, new HttpClient()));
            }
            else
            {
                var secret     = File.ReadAllText(filePath);
                var accountKey = KeyFactory.FromPem(secret);
                acme = new AcmeContext(acmeDirectoryUri, accountKey, new AcmeHttpClient(acmeDirectoryUri, new HttpClient()));
            }

            return(acme);
        }
Esempio n. 22
0
        private async Task <AcmeContext> GetOrCreateAcmeContext(Uri acmeDirectoryUri, string email)
        {
            AcmeContext acme     = null;
            string      filename = $"account{email}--{acmeDirectoryUri.Host}.pem";

            if (!await fileSystem.Exists(filename))
            {
                acme = new AcmeContext(acmeDirectoryUri);
                var account = acme.NewAccount(email, true);

                // Save the account key for later use
                var pemKey = acme.AccountKey.ToPem();
                await fileSystem.WriteAllText(filename, pemKey);

                await Task.Delay(10000); //Wait a little before using the new account.

                acme = new AcmeContext(acmeDirectoryUri, acme.AccountKey, new AcmeHttpClient(acmeDirectoryUri, new HttpClient()));
            }
            else
            {
                var pemKey = await fileSystem.ReadAllText(filename);

                var accountKey = KeyFactory.FromPem(pemKey);
                acme = new AcmeContext(acmeDirectoryUri, accountKey, new AcmeHttpClient(acmeDirectoryUri, new HttpClient()));
            }

            return(acme);
        }
Esempio n. 23
0
        public static async Task Main(string[] args)
        {
//            var acme = new AcmeContext(WellKnownServers.LetsEncryptV2);
//            var account = await acme.NewAccount("*****@*****.**", true);
//
//            // Save the account key for later use
//            var pemKey = acme.AccountKey.ToPem();
//            File.WriteAllText(@"C:\temp\letsencrypt\pem", pemKey);

            var accountKey = KeyFactory.FromPem(File.ReadAllText(@"C:\temp\letsencrypt\pem"));
            var acme       = new AcmeContext(WellKnownServers.LetsEncryptV2, accountKey);

            //var (uri, token, s) = await NewOrderHttp(acme, "peoplemeter.ru");
            await CheckOrderHttp(acme, "https://acme-v02.api.letsencrypt.org/acme/order/50945428/303515634");

            //            var newOrderLocation = newOrder.Location;
            //await CheckOrderDns(acme, "https://acme-v02.api.letsencrypt.org/acme/order/50945428/303477312");

//            if (validate.Status == ChallengeStatus.Valid)
//            {
//                var privateKey = KeyFactory.NewKey(KeyAlgorithm.ES256);
//                var cert = await order.Generate(new CsrInfo
//                {
//                    CountryName = "CA",
//                    State = "Ontario",
//                    Locality = "Toronto",
//                    Organization = "Certes",
//                    OrganizationUnit = "Dev",
//                    CommonName = "your.domain.name",
//                }, privateKey);
//            }
        }
Esempio n. 24
0
        public async Task <byte[]> GetCertificateAsync(Action <string> setDnsTxt)
        {
            IOrderContext order = await AcmeContext.NewOrder(new[] { Configuration.CertificateIdentifier });

            var authz        = (await order.Authorizations()).First();
            var dnsChallenge = await authz.Dns();

            var dnsTxt     = AcmeContext.AccountKey.DnsTxt(dnsChallenge.Token);
            var privateKey = KeyFactory.NewKey(KeyAlgorithm.ES256);

            setDnsTxt(dnsTxt);
            Challenge challenge = null;

            for (int i = 0; challenge?.Status != ChallengeStatus.Valid && i < 10; i++)
            {
                challenge = await dnsChallenge.Validate();

                if (challenge.Status == ChallengeStatus.Valid)
                {
                    break;
                }
                Thread.Sleep(1000);
            }
            var cert = await order.Generate(Configuration.CsrInfo, privateKey);

            var pfxBuilder = cert.ToPfx(privateKey);

            return(pfxBuilder.Build(Configuration.CertificateName, Configuration.CertificatePassword));
        }
Esempio n. 25
0
        public async Task <string> GetAccountKey()
        {
            if (!string.IsNullOrEmpty(_accountKey))
            {
                return(_accountKey);
            }

            _logger.LogInformation("Getting a new account key");

            var             acme = new AcmeContext(_options.AcmeServer);
            IAccountContext account;

            try
            {
                account = await acme.NewAccount(_options.EmailAddress, true);
            }
            catch (Exception e)
            {
                _logger.LogError(e.ToString());
                return(null);
            }

            var pemKey = acme.AccountKey.ToPem();

            if (!string.IsNullOrEmpty(_keyFile))
            {
                File.WriteAllText(_keyFile, pemKey);
            }

            return(pemKey);
        }
Esempio n. 26
0
        private static async Task RunAcmeRequestHandlerJob(
            HostBuilderContext hostBuilderContext,
            IServiceCollection services,
            string[] args)
        {
            services.AddTransient <IAcmeContext, AcmeContext>();
            services.AddTransient <IDnsManagementClient, DnsManagementClient>();
            services.AddTransient <IResourceManagementClient, ResourceManagementClient>();
            services.AddTransient <IWebSiteManagementClient, WebSiteManagementClient>();

            var acme    = new AcmeContext(WellKnownServers.LetsEncryptV2);
            var account = await acme.NewAccount("*****@*****.**", true);

            var pemKey = acme.AccountKey.ToPem();

            var order = await acme.NewOrder(new[] { "*.dev.xiaodong.world" });

            var authz        = (await order.Authorizations()).First();
            var dnsChallenge = await authz.Dns();

            var dnsText = acme.AccountKey.DnsTxt(dnsChallenge.Token);

            // TODO: add dns txt record to _acme-challenge.dev.xiaodong.world with dnsText value

            var httpChallenge = await authz.Http();

            var keyAuthz = httpChallenge.KeyAuthz;
        }
Esempio n. 27
0
        static async Task <CertRequest> CreateAccountAsync(bool staging)
        {
            Console.WriteLine("Creating letsencrypt account");

            var certRequest = ReadRequest("cert.json");

            var fileInfo = new FileInfo(certRequestFile);

            if (!fileInfo.Directory.Exists)
            {
                Directory.CreateDirectory(fileInfo.DirectoryName);
            }

            File.Copy("cert.json", certRequestFile);

            acmeContext = new AcmeContext(staging ? WellKnownServers.LetsEncryptStagingV2 : WellKnownServers.LetsEncryptV2);
            account     = await acmeContext.NewAccount(certRequest.Account, true);

            var pemKey = acmeContext.AccountKey.ToPem();
            var fi     = new FileInfo(accountFile);

            Directory.CreateDirectory(fi.DirectoryName);
            await File.WriteAllTextAsync(accountFile, pemKey);

            Console.WriteLine("Letsencrypt account created");
            return(certRequest);
        }
Esempio n. 28
0
        private async Task <AcmeContext> RegisterAccount(AcmeContext context)
        {
            if (context != null && !Options.Force)
            {
                throw new Exception($"A config exists at {Options.Path}, use a different path or --force option.");
            }

            using (var client = new AcmeClient(Options.Server))
            {
                var account = Options.NoEmail ?
                              await client.NewRegistraton() :
                              await client.NewRegistraton($"mailto:{Options.Email}");

                if (Options.AgreeTos)
                {
                    account.Data.Agreement = account.GetTermsOfServiceUri();
                    account = await client.UpdateRegistration(account);
                }

                context = new AcmeContext
                {
                    Account = account
                };
            }

            ConsoleLogger.Info("Registration created.");
            return(context);
        }
Esempio n. 29
0
        static async Task <int> Main(string[] args)
        {
            Args = CommandLineParser.ParseOrWriteUsageToConsole <CmdLine>(args);
            if (Args == null)
            {
                return(1);
            }

            var outputPath = Path.GetDirectoryName(Args.ConfigPath);
            var identifier = Path.GetFileNameWithoutExtension(Args.ConfigPath);
            var cfg        = Args.Config;

            Console.WriteLine($"This will create/renew a LetsEncrypt certificate for {cfg.Domain}");
            PressYToContinue();

            // https://community.letsencrypt.org/t/what-are-accounts-do-i-need-to-backup-them/21318/2
            // We won't try to preserve the account key, and will simply create a new one every time.
            var acme = new AcmeContext(WellKnownServers.LetsEncryptV2);
            await acme.NewAccount(cfg.NotifyEmail, true);

            var commonName = cfg.Domain;
            var order      = await acme.NewOrder(new[] { commonName });

            var authz     = (await order.Authorizations()).First();
            var challenge = await authz.Dns();

            Console.WriteLine();
            Console.WriteLine("DNS challenge required:");
            Console.WriteLine($"    update TXT record for _acme-challenge.{cfg.Domain.Replace("*.", "")}");
            Console.WriteLine($"    {acme.AccountKey.DnsTxt(challenge.Token)}");
            Console.WriteLine();
            PressYToContinue();
            await challenge.Validate();

            var privateKey = KeyFactory.NewKey(KeyAlgorithm.ES256);
            var cert       = await order.Generate(new CsrInfo
            {
                CountryName      = cfg.CountryName,
                State            = cfg.State,
                Locality         = cfg.Locality,
                Organization     = cfg.Domain.Replace("*.", ""),
                OrganizationUnit = "IT",
                CommonName       = commonName,
            }, privateKey);

            File.WriteAllText(Path.Combine(outputPath, $"{identifier}.ca-bundle"), string.Join("\r\n", cert.Issuers.Select(s => s.ToPem())));
            File.WriteAllText(Path.Combine(outputPath, $"{identifier}.crt"), cert.Certificate.ToPem());
            File.WriteAllText(Path.Combine(outputPath, $"{identifier}.private.key"), privateKey.ToPem());
            if (cfg.PfxPassword != null)
            {
                var pfxBuilder = cert.ToPfx(privateKey);
                var pfx        = pfxBuilder.Build(identifier, cfg.PfxPassword);
                File.WriteAllBytes(Path.Combine(outputPath, $"{identifier}.pfx"), pfx);
            }

            Console.WriteLine($"Certificate files saved to: {outputPath}\\{identifier}.*");

            return(0);
        }
Esempio n. 30
0
        /// <summary>
        /// Address repository constructor
        /// </summary>
        /// <param name="context">Acme DB context</param>
        public AddressRepository(AcmeContext context) : base(context)
        {
            // Set Country Entity
            countryEntity = _context.Set <Country>();

            // Set Postcode Entity
            postcodeEntity = _context.Set <Postcodes>();
        }