예제 #1
0
        public async Task Should_POST_to_get_registration_details_if_the_registration_already_exists()
        {
            // Arrange
            var http = new FakeHttpMessageHandler("http://baseaddress/");
            var directory = new Directory() { NewRegistration = new Uri("http://baseaddress/registration") };
            var registration = new RegistrationResponse();

            var client =
                http.RequestTo("directory").Returns(directory).WithNonce("nonce").
                RequestTo("registration").Returns(new Problem(), "application/problem+json").HasStatusCode(HttpStatusCode.Conflict).WithHeader("Location", "http://baseaddress/existingreguri").WithNonce("nonce").
                RequestTo("existingreguri").Returns(registration).WithNonce("nonce").
                GetHttpClient();

            var sut = new AcmeClient(client, new RSACryptoServiceProvider());

            // Act
            var registrationResponse = await sut.RegisterAsync("agreementUri", new[] { "mailto:[email protected]" });

            // Assert
            registrationResponse.Should().NotBeNull();
            http.ReceivedRequestsTo("directory").Single().HasMethod(HttpMethod.Get);
            http.ReceivedRequestsTo("registration").Single().HasMethod(HttpMethod.Post).HasJwsPayload<NewRegistrationRequest>(r =>
            {
                r.Agreement.Should().Be("agreementUri");
                r.Contact.Should().Contain("mailto:[email protected]");
            });
            http.ReceivedRequestsTo("existingreguri").Single().HasMethod(HttpMethod.Post).HasJwsPayload<UpdateRegistrationRequest>(r =>
            {
                r.Agreement.Should().BeNull();
                r.Contact.Should().BeNull();
            });
        }
예제 #2
0
        public async Task Should_post_a_valid_Registration_message()
        {
            // Arrange
            var http = new FakeHttpMessageHandler("http://baseaddress/");
            var directory = new Directory() { NewRegistration = new Uri("http://baseaddress/registration")};
            var registration = new RegistrationResponse();

            var client = 
                http.RequestTo("directory").Returns(directory).WithNonce("nonce").
                RequestTo("registration").Returns(registration).WithNonce("nonce").
                GetHttpClient();
            
            var sut = new AcmeClient(client, new RSACryptoServiceProvider());

            // Act
            var registrationResponse =  await sut.RegisterAsync("agreementUri", new []{ "mailto:[email protected]"});

            // Assert
            registrationResponse.Should().NotBeNull();
            http.ReceivedRequestsTo("directory").Single().HasMethod(HttpMethod.Get);
            http.ReceivedRequestsTo("registration").Single().HasMethod(HttpMethod.Post).HasJwsPayload<NewRegistrationRequest>(r =>
            {
                r.Agreement.Should().Be("agreementUri");               
                r.Contact.Should().Contain("mailto:[email protected]");
            });
        }
예제 #3
0
        public static async Task RequestSslCertificate(Options options)
        {
            Log.Level = Oocx.Acme.Services.LogLevel.Info;

            if (!Directory.Exists(options.StoreDirectory))
            {
                Directory.CreateDirectory(options.StoreDirectory);
            }

            IKeyStore keyStore = new FileKeyStore(options.StoreDirectory);

            IAcmeClient client = new AcmeClient(
                options.AcmeServer,
                options.AccountKeyName,
                keyStore
                );

            var challenge = new AzureStorageChallengeProvider(
                options,
                client
                );

            IServerConfigurationProvider server = new ConfigureToFiles(options);

            var acmep = new AcmeProcess(
                options,
                challenge,
                server,
                client
                );

            await acmep.StartAsync();

            await challenge.CleanupUsedChallengeFilesAsync();
        }
예제 #4
0
        public void TestInitialize()
        {
            RSAParameters Parameters;

            try
            {
                CspParameters CspParams = new CspParameters()
                {
                    Flags            = CspProviderFlags.UseMachineKeyStore,
                    KeyContainerName = directory
                };

                /*using (RSACryptoServiceProvider RSA = new RSACryptoServiceProvider(4096, CspParams))
                 * {
                 *      RSA.PersistKeyInCsp = false;
                 *      RSA.Clear();
                 * }*/

                using (RSACryptoServiceProvider RSA = new RSACryptoServiceProvider(4096, CspParams))
                {
                    Parameters = RSA.ExportParameters(true);
                }
            }
            catch (CryptographicException ex)
            {
                throw new CryptographicException("Unable to get access to cryptographic key. Was application initially run using another user?", ex);
            }

            this.client = new AcmeClient(new Uri(directory), Parameters);
        }
        public async Task TestEndToEndUnoEuro()
        {
            var dnsProvider = TestHelper.UnoEuroDnsProvider;

            var manager = new AcmeClient(dnsProvider, new DnsLookupService(), new NullCertificateStore());

            var dnsRequest = new AcmeDnsRequest()
            {
                Host              = "*.tiimo.dk",
                PFXPassword       = "******",
                RegistrationEmail = "*****@*****.**",
                AcmeEnvironment   = new LetsEncryptStagingV2(),
                CsrInfo           = new CsrInfo()
                {
                    CountryName      = "DK",
                    Locality         = "Copenhagen",
                    Organization     = "tiimo ApS",
                    OrganizationUnit = "",
                    State            = "DK"
                }
            };

            var res = await manager.RequestDnsChallengeCertificate(dnsRequest);

            Assert.IsNotNull(res);

            File.WriteAllBytes($"{dnsRequest.Host.Substring(2)}.pfx", res.CertificateInfo.PfxCertificate);
        }
예제 #6
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);
                    }
                }
            }
        }
예제 #7
0
        public async Task Should_post_a_valid_Registration_message()
        {
            // Arrange
            var http      = new FakeHttpMessageHandler("http://baseaddress/");
            var directory = new Directory {
                NewRegistration = new Uri("http://baseaddress/registration")
            };
            var registration = new RegistrationResponse();

            var client =
                http.RequestTo("directory").Returns(directory).WithNonce("nonce").
                RequestTo("registration").Returns(registration).WithNonce("nonce").
                GetHttpClient();

            var sut = new AcmeClient(client, new RSACryptoServiceProvider());

            // Act
            var registrationResponse = await sut.RegisterAsync("agreementUri", new [] { "mailto:[email protected]" });

            // Assert
            registrationResponse.Should().NotBeNull();
            http.ReceivedRequestsTo("directory").Single().HasMethod(HttpMethod.Get);
            http.ReceivedRequestsTo("registration").Single().HasMethod(HttpMethod.Post).HasJwsPayload <NewRegistrationRequest>(r =>
            {
                r.Agreement.Should().Be("agreementUri");
                r.Contact.Should().Contain("mailto:[email protected]");
            });
        }
        public static IssuedCertificate RequestCertificate(AcmeClient client, CertificateProvider certProvider, string hostName, List <string> alternativeNames = null)
        {
            if (alternativeNames == null)
            {
                alternativeNames = new List <string>();
            }

            PrivateKey pk;
            var        csr = GenerateCSR(certProvider, hostName, alternativeNames, out pk);

            var certRequest = client.RequestCertificate(JwsHelper.Base64UrlEncode(csr));

            if (certRequest.StatusCode != HttpStatusCode.Created)
            {
                throw new CertificateApplicationException(certRequest, hostName, alternativeNames.ToArray());
            }

            Crt crt;

            using (var ms = new MemoryStream())
            {
                certRequest.SaveCertificate(ms);

                ms.Seek(0, SeekOrigin.Begin);
                crt = certProvider.ImportCertificate(EncodingFormat.DER, ms);
            }
            var caCrt = GetCACertificate(certProvider, certRequest);

            return(new IssuedCertificate {
                PublicKey = crt, PrivateKey = pk, CAPublicKey = caCrt
            });
        }
예제 #9
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);
                    }
                }
            }
        }
예제 #10
0
        static void RetrieveCertificates(AcmeClient client, string api, string domain, string certificatesFolder, int certBits)
        {
            var cp     = CertificateProvider.GetProvider();
            var rsaPkp = new RsaPrivateKeyParams()
            {
                NumBits = certBits
            };

            var rsaKeys   = cp.GeneratePrivateKey(rsaPkp);
            var csrParams = new CsrParams
            {
                Details = new CsrDetails {
                    CommonName = domain
                }
            };

            var derRaw = default(byte[]);
            var csr    = cp.GenerateCsr(csrParams, rsaKeys, Crt.MessageDigest.SHA256);

            using (var bs = new MemoryStream())
            {
                cp.ExportCsr(csr, EncodingFormat.DER, bs);
                derRaw = bs.ToArray();
            }

            var derB64U  = JwsHelper.Base64UrlEncode(derRaw);
            var certRequ = client.RequestCertificate(derB64U);

            if (certRequ.StatusCode == HttpStatusCode.Created)
            {
                GenerateCertFiles(cp, rsaKeys, csr, certRequ, certificatesFolder, domain);
            }
        }
예제 #11
0
        public async Task TestEndToEndGoDaddy()
        {
            var dnsProvider = new GoDaddyDnsProviderTest().DnsService;

            var manager = new AcmeClient(dnsProvider, new DnsLookupService(), new NullCertificateStore());

            var dnsRequest = new AcmeDnsRequest()
            {
                Host              = "*.åbningstider.info",
                PFXPassword       = "******",
                RegistrationEmail = "*****@*****.**",
                AcmeEnvironment   = new LetsEncryptStagingV2(),
                CsrInfo           = new CsrInfo()
                {
                    CountryName      = "DK",
                    Locality         = "Copenhagen",
                    Organization     = "Sjkp",
                    OrganizationUnit = "",
                    State            = "DK"
                }
            };

            var res = await manager.RequestDnsChallengeCertificate(dnsRequest);

            Assert.IsNotNull(res);

            File.WriteAllBytes($"{dnsRequest.Host.Substring(2)}.pfx", res.CertificateInfo.PfxCertificate);

            var certService = new AzureWebAppService(new[] { TestHelper.AzureWebAppSettings });

            await certService.Install(res);
        }
예제 #12
0
        public async Task Should_POST_to_get_registration_details_if_the_registration_already_exists()
        {
            // Arrange
            var http      = new FakeHttpMessageHandler("http://baseaddress/");
            var directory = new Directory {
                NewRegistration = new Uri("http://baseaddress/registration")
            };
            var registration = new RegistrationResponse();

            var client =
                http.RequestTo("directory").Returns(directory).WithNonce("nonce").
                RequestTo("registration").Returns(new Problem(), "application/problem+json").HasStatusCode(HttpStatusCode.Conflict).WithHeader("Location", "http://baseaddress/existingreguri").WithNonce("nonce").
                RequestTo("existingreguri").Returns(registration).WithNonce("nonce").
                GetHttpClient();

            var sut = new AcmeClient(client, new RSACryptoServiceProvider());

            // Act
            var registrationResponse = await sut.RegisterAsync("agreementUri", new[] { "mailto:[email protected]" });

            // Assert
            registrationResponse.Should().NotBeNull();
            http.ReceivedRequestsTo("directory").Single().HasMethod(HttpMethod.Get);
            http.ReceivedRequestsTo("registration").Single().HasMethod(HttpMethod.Post).HasJwsPayload <NewRegistrationRequest>(r =>
            {
                r.Agreement.Should().Be("agreementUri");
                r.Contact.Should().Contain("mailto:[email protected]");
            });
            http.ReceivedRequestsTo("existingreguri").Single().HasMethod(HttpMethod.Post).HasJwsPayload <UpdateRegistrationRequest>(r =>
            {
                r.Agreement.Should().BeNull();
                r.Contact.Should().BeNull();
            });
        }
예제 #13
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);
        }
예제 #14
0
 public App(AcmeClient acmeClient, ICertificateStore certificateStore, AzureWebAppService azureWebAppService, ILogger <App> logger = null)
 {
     this.acmeClient         = acmeClient;
     this.certificateStore   = certificateStore;
     this.azureWebAppService = azureWebAppService;
     this.logger             = logger ?? NullLogger <App> .Instance;
 }
예제 #15
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);
        }
예제 #16
0
        public static void Init(VaultConfig config, AcmeClient client)
        {
            client.Init();

            if (config.GetInitialDirectory)
                client.GetDirectory(config.UseRelativeInitialDirectory);
        }
        private bool disposedValue = false; // To detect redundant calls

        protected virtual void Dispose(bool disposing)
        {
            if (!disposedValue)
            {
                if (disposing)
                {
                    // dispose managed state (managed objects).
                    if (_Client != null)
                    {
                        _Client.Dispose();
                        _Client = null;
                    }
                    if (_Signer != null)
                    {
                        _Signer.Dispose();
                        _Signer = null;
                    }
                }

                // free unmanaged resources (unmanaged objects) and override a finalizer below.
                // set large fields to null.

                disposedValue = true;
            }
        }
예제 #18
0
        public async Task AccountCreation()
        {
            var acmeClient = new AcmeClient(EnviromentUri);
            var account    = await acmeClient.CreateNewAccountAsync(ContactEmail);

            Assert.IsNotNull(account);
        }
예제 #19
0
        private async void loadToolStripMenuItem_Click(object sender, EventArgs e)
        {
            var account = cmbAccounts.SelectedItem as Account;

            if (account == null)
            {
                log.Error("not account.");
                await Task.FromResult(0);

                return;
            }

            RS256Signer signer = null;
            AcmeClient  client = null;

            try
            {
                signer = account.Signer;

                client = new AcmeClient(new Uri(account.uri), new AcmeServerDirectory(), signer);
                client.Init();
                log.Info("\nGetting AcmeServerDirectory");
                client.GetDirectory(true);

                client.Registration = account.Registration;

                this.client  = client;
                this.account = account;
                log.Info("load done.");
                labInfo.Text = account.ToString();
                btnRefreshDomains.PerformClick();
            }
            catch (Exception ex)
            {
                if (client != null)
                {
                    client.Dispose();
                    client = null;
                }

                if (signer != null)
                {
                    signer.Dispose();
                    signer = null;
                }

                var acmeWebException = ex as AcmeClient.AcmeWebException;
                if (acmeWebException != null)
                {
                    log.Error(acmeWebException.Message);
                    log.Error("ACME Server Returned:");
                    log.Error(acmeWebException.Response.ContentAsString);
                }
                else
                {
                    log.Error(ex);
                }
            }
        }
예제 #20
0
 public CertificateService(Options options, ILogService log, AcmeClient client, string configPath)
 {
     _log        = log;
     _options    = options;
     _client     = client;
     _configPath = configPath;
     InitCertificatePath();
 }
예제 #21
0
 public void TestCleanup()
 {
     if (this.client != null)
     {
         this.client.Dispose();
         this.client = null;
     }
 }
예제 #22
0
 public AcmeContext(Uri serverAddress)
 {
     if (serverAddress == null)
     {
         throw new ArgumentNullException(nameof(serverAddress));
     }
     this.client = new AcmeClient(serverAddress);
 }
예제 #23
0
 public DefaultPlugin(ILogger logger, IAcmeClientService acmeClientService,
                      AcmeClient acmeClient, ICertificateService certificateService)
 {
     _logger             = logger;
     _acmeClientService  = acmeClientService;
     _acmeClient         = acmeClient;
     _certificateService = certificateService;
 }
        public static AcmeRegistration CreateNew(AcmeClient client, string contactEmail)
        {
            var contacts     = new[] { "mailto:" + contactEmail };
            var registration = client.Register(contacts);

            client.UpdateRegistration(true, true);

            return(registration);
        }
예제 #25
0
파일: Helpers.cs 프로젝트: timnboys/certify
        public static void Init(VaultInfo config, AcmeClient client)
        {
            client.Init();

            if (config.GetInitialDirectory)
            {
                client.GetDirectory(config.UseRelativeInitialDirectory);
            }
        }
예제 #26
0
        static Tuple <AuthorizeChallenge, AuthorizationState> RequestChallengeFile(
            AcmeClient client, string domain)
        {
            var state         = client.AuthorizeIdentifier(domain);
            var challenge     = client.DecodeChallenge(state, AcmeProtocol.CHALLENGE_TYPE_HTTP);
            var httpChallenge = challenge.Challenge as HttpChallenge;

            return(new Tuple <AuthorizeChallenge, AuthorizationState>(challenge, state));
        }
예제 #27
0
 public CertificateFactory(IOptions <LetsEncryptOptions> options,
                           IHttpChallengeResponseStore challengeStore,
                           ILogger logger)
 {
     _options        = options;
     _challengeStore = challengeStore;
     _logger         = logger;
     _client         = new AcmeClient(_options.Value.AcmeServer);
 }
예제 #28
0
        public async Task Init(string email, CancellationToken token = default(CancellationToken))
        {
            _accountKey = new RSACryptoServiceProvider(4096);

            if (File.Exists(_path))
            {
                bool success;
                try
                {
                    lock (Locker)
                    {
                        _cache = JsonConvert.DeserializeObject <RegistrationCache>(File.ReadAllText(_path));
                    }

                    _accountKey.ImportCspBlob(_cache.AccountKey);

                    success = true;
                }
                catch
                {
                    success = false;
                    // if we failed for any reason, we'll just
                    // generate a new registration
                }

                if (success)
                {
                    _client = new AcmeClient(GetCachedClient(_url), _accountKey);

                    return;
                }
            }

            // need to generate new account
            _client = new AcmeClient(new HttpClient
            {
                BaseAddress = new Uri(_url)
            }, _accountKey);
            var registration = await _client.RegisterAsync(new NewRegistrationRequest
            {
                Contact = new[] { "mailto:" + email }
            }, token);

            lock (Locker)
            {
                _cache = new RegistrationCache
                {
                    Location   = registration.Location,
                    Id         = registration.Id,
                    Key        = registration.Key,
                    AccountKey = _accountKey.ExportCspBlob(true)
                };
                File.WriteAllText(_path,
                                  JsonConvert.SerializeObject(_cache, Formatting.Indented));
            }
        }
예제 #29
0
        public static void Authorize(AcmeClient client, IDnsProvider dnsProvider, string hostName, List <string> alternativeNames = null)
        {
            var dnsIdentifiers = new List <string>()
            {
                hostName
            };

            if (alternativeNames != null)
            {
                dnsIdentifiers.AddRange(alternativeNames);
            }

            var authResults = new List <AuthorizationState>();

            foreach (var dnsIdentifier in dnsIdentifiers)
            {
                var authzState = client.AuthorizeIdentifier(dnsIdentifier);
                var challenge  = client.DecodeChallenge(authzState, AcmeProtocol.CHALLENGE_TYPE_DNS);

                var dnsChallenge = challenge.Challenge as DnsChallenge;
                var dnsRecordRef = AddRecordToDNS(dnsProvider, dnsChallenge);
                Thread.Sleep(3 * 1000); //  wait for the newly created TXT record to take effect

                try
                {
                    authzState.Challenges = new AuthorizeChallenge[] { challenge };
                    client.SubmitChallengeAnswer(authzState, AcmeProtocol.CHALLENGE_TYPE_DNS, true);

                    // have to loop to wait for server to stop being pending.
                    // todo: put timeout/retry limit in this loop
                    while (authzState.Status == "pending")
                    {
                        Thread.Sleep(3 * 1000); // this has to be here to give ACME server a chance to think
                        var newAuthzState = client.RefreshIdentifierAuthorization(authzState);
                        if (newAuthzState.Status != "pending")
                        {
                            authzState = newAuthzState;
                        }
                    }

                    authResults.Add(authzState);
                }
                finally
                {
                    if (!string.IsNullOrEmpty(dnsRecordRef))
                    {
                        dnsProvider.RemoveTxtRecord(dnsRecordRef);
                    }
                }
            }

            if (authResults.Any(result => result.Status != "valid"))
            {
                throw new AuthorizationFailedException(authResults);
            }
        }
예제 #30
0
파일: ClientTests.cs 프로젝트: carbon/Acme
        // [Fact]
        public async Task D()
        {
            var privateKey = RSA.Create(RSAPrivateKey.Decode(TestData.PrivateRSA256KeyText));

            var client = new AcmeClient(privateKey, directoryUrl: "https://acme-staging-v02.api.letsencrypt.org/directory");

            var accountUrl = await client.GetAccountUrlAsync();

            throw new Exception(JsonObject.FromObject(new { accountUrl }).ToString());
        }
예제 #31
0
        public async Task ExecAsync()
        {
            var configBuilder = new ConfigurationBuilder();

            if (_options.AzureKeyVaultUrl != null)
            {
                configBuilder.AddAzureKeyVault(_options.AzureKeyVaultUrl);
            }

            var config = configBuilder.Build();

            _services.AddLogging((builder => { builder.AddConsole(); }));
            _services.AddSingleton <IConfiguration>(config);

            switch (_options.StorageType)
            {
            case StorageType.AzureBlob:
                SetupAzureBlobStore();
                break;

            case StorageType.LocalFs:
                SetupLocalFsStore();
                break;

            default:
                throw new ArgumentException($"Invalid storage type {_options.StorageType}");
            }

            _services.AddSingleton <IAccountStore, FileSystemAccountStore>();
            _services.AddSingleton <IChallengeStore, FileSystemChallengeStore>();
            _services.AddSingleton <ICertStore, FileSystemCertStore>();
            _services.AddSingleton <ICertReader, FileSystemCertStore>();
            _services.AddSingleton <IClientStateStore, DelegatedClientStateStore>();
            _services.AddSingleton((provider) =>
            {
                var client = new AcmeClient(_options.CaUrl, CreateLogger <AcmeClient>(provider));
                client.InitAsync().Wait();
                return(client);
            });
            _services.AddSingleton((provider) => new AcmeOptions
            {
                AcceptTermsOfService = true,
                AccountContactEmails = _options.AccountContactEmails,
                DnsNames             = _options.DnsNames,
                CertificateKeyAlgor  = "rsa"
            });
            _services.AddSingleton <ACMEWorker>();

            var serviceProvider = _services.BuildServiceProvider();
            var worker          = serviceProvider.GetService(typeof(ACMEWorker)) as ACMEWorker;

            await worker.WorkAsync();

            await serviceProvider.DisposeAsync();
        }
예제 #32
0
        private bool TryLoad(bool force = false)
        {
            if (force == false && this.client != null)
            {
                return(true);
            }

            RS256Signer signer = null;
            AcmeClient  client = null;

            try
            {
                signer = account.Signer;

                client = new AcmeClient(new Uri(account.uri), new AcmeServerDirectory(), signer);
                client.Init();
                log.Info("\nGetting AcmeServerDirectory");
                client.GetDirectory(true);

                client.Registration = account.Registration;

                this.client = client;
                log.Info("load done.");
                labInfo.Text = account.ToString();
                //
                return(true);
            }
            catch (Exception ex)
            {
                if (client != null)
                {
                    client.Dispose();
                    client = null;
                }

                if (signer != null)
                {
                    signer.Dispose();
                    signer = null;
                }

                var acmeWebException = ex as AcmeClient.AcmeWebException;
                if (acmeWebException != null)
                {
                    log.Error(acmeWebException.Message);
                    log.Error("ACME Server Returned:");
                    log.Error(acmeWebException.Response.ContentAsString);
                }
                else
                {
                    log.Error(ex);
                }
            }
            return(false);
        }
예제 #33
0
        public async Task Run()
        {
            // Create client alias core object + specify which environment you want to use
            var acmeClient = new AcmeClient(EnviromentUri);

            // Create new Account
            var account = await acmeClient.CreateNewAccountAsync(ContactEmail);

            // Create new Order
            var order = await acmeClient.NewOrderAsync(account, Identifiers);

            // Create DNS challenge (DNS is required for wildcard certificate)
            var challenges = await acmeClient.GetDnsChallenges(account, order);

            // Creation of all DNS entries
            foreach (var challenge in challenges)
            {
                var dnsKey  = challenge.VerificationKey;
                var dnsText = challenge.VerificationValue;
                // value can be e.g.: eBAdFvukOz4Qq8nIVFPmNrMKPNlO8D1cr9bl8VFFsJM

                // Create DNS TXT record e.g.:
                // key: _acme-challenge.your.domain.com
                // value: eBAdFvukOz4Qq8nIVFPmNrMKPNlO8D1cr9bl8VFFsJM
            }

            // Validation of all DNS entries
            foreach (var challenge in challenges)
            {
                await acmeClient.ValidateChallengeAsync(account, challenge);

                // Verify status of challenge
                var freshChallenge = await acmeClient.GetChallengeAsync(account, challenge);

                if (freshChallenge.Status == ChallengeStatus.Invalid)
                {
                    throw new Exception("Something is wrong with your DNS TXT record(s)!");
                }
            }

            // Generate certificate
            var certificate = await acmeClient.GenerateCertificateAsync(account, order, "Suppo.biz");

            // Save files locally
            var password = "******";
            await LocalFileHandler.WriteAsync("Suppo.biz.pfx", certificate.GeneratePfx(password));

            await LocalFileHandler.WriteAsync("Suppo.biz.crt", certificate.GenerateCrt(password));

            await LocalFileHandler.WriteAsync("Suppo.biz.crt.pem", certificate.GenerateCrtPem(password));

            await LocalFileHandler.WriteAsync("Suppo.biz.key.pem", certificate.GenerateKeyPem());

            Assert.Pass();
        }
예제 #34
0
        public static AcmeClient GetClient(VaultConfig Config)
        {
            var p = Config.Proxy;
            var _Client = new AcmeClient();

            _Client.RootUrl = new Uri(Config.BaseURI);
            _Client.Directory = Config.ServerDirectory;

            if (Config.Proxy != null)
                _Client.Proxy = Config.Proxy.GetWebProxy();

            return _Client;
        }
예제 #35
0
 public override async Task Context()
 {
     RestClient = A.Fake<IRestClient>();
     A.CallTo(
         () =>
             RestClient.RequestJson("https://acme-staging.api.letsencrypt.org/directory", HttpMethod.Get, null,
                 null))
         .Returns(new HttpResponseMessage(HttpStatusCode.OK)
         {
             Content = new StringContent(DirectoryJson),
             Headers = {{"Replay-Nonce", "noncey"}}
         });
     
     ClassUnderTest = new AcmeClient(RestClient, new JwsBuilder(),  "https://acme-staging.api.letsencrypt.org/directory");
 }
예제 #36
0
        public async Task Should_get_a_Directory_object_from_the_default_endpoint()
        {
            // Arrange
            var http = new FakeHttpMessageHandler("http://baseaddress/");
            var directory = new Directory();

            var client = 
                http.RequestTo("directory").Returns(directory).WithNonce("nonce")
                .GetHttpClient();

            var sut = new AcmeClient(client, new RSACryptoServiceProvider());

            // Act
            var discoverResponse = await sut.DiscoverAsync();

            // Assert
            discoverResponse.Should().NotBeNull();
        }
예제 #37
0
        static void Main(string[] args)
        {
            var commandLineParseResult = Parser.Default.ParseArguments<Options>(args);
            var parsed = commandLineParseResult as Parsed<Options>;
            if (parsed == null)
            {
#if DEBUG
                Console.WriteLine("Press enter to continue.");
                Console.ReadLine();
#endif
                return; // not parsed
            }
            Options = parsed.Value;

            Console.WriteLine("Let's Encrypt (Simple Windows ACME Client)");

            BaseURI = Options.BaseURI;
            if (Options.Test)
                BaseURI = "https://acme-staging.api.letsencrypt.org/";

            //Console.Write("\nUse production Let's Encrypt server? (Y/N) ");
            //if (PromptYesNo())
            //    BaseURI = ProductionBaseURI;

            Console.WriteLine($"\nACME Server: {BaseURI}");

            settings = new Settings(clientName, BaseURI);

            configPath = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData), clientName, CleanFileName(BaseURI));
            Console.WriteLine("Config Folder: " + configPath);
            Directory.CreateDirectory(configPath);

            try
            {
                using (var signer = new RS256Signer())
                {
                    signer.Init();

                    var signerPath = Path.Combine(configPath, "Signer");
                    if (File.Exists(signerPath))
                    {
                        Console.WriteLine($"Loading Signer from {signerPath}");
                        using (var signerStream = File.OpenRead(signerPath))
                            signer.Load(signerStream);
                    }

                    using (client = new AcmeClient(new Uri(BaseURI), new AcmeServerDirectory(), signer))
                    {
                        client.Init();
                        Console.WriteLine("\nGetting AcmeServerDirectory");
                        client.GetDirectory(true);

                        var registrationPath = Path.Combine(configPath, "Registration");
                        if (File.Exists(registrationPath))
                        {
                            Console.WriteLine($"Loading Registration from {registrationPath}");
                            using (var registrationStream = File.OpenRead(registrationPath))
                                client.Registration = AcmeRegistration.Load(registrationStream);
                        }
                        else
                        {
                            Console.WriteLine("Calling Register");
                            var registration = client.Register(new string[] { });

                            if (!Options.AcceptTOS && !Options.Renew)
                            {
                                Console.WriteLine($"Do you agree to {registration.TosLinkUri}? (Y/N) ");
                                if (!PromptYesNo())
                                    return;
                            }

                            Console.WriteLine("Updating Registration");
                            client.UpdateRegistration(true, true);

                            Console.WriteLine("Saving Registration");
                            using (var registrationStream = File.OpenWrite(registrationPath))
                                client.Registration.Save(registrationStream);

                            Console.WriteLine("Saving Signer");
                            using (var signerStream = File.OpenWrite(signerPath))
                                signer.Save(signerStream);
                        }

                        if (Options.Renew)
                        {
                            CheckRenewals();
#if DEBUG
                            Console.WriteLine("Press enter to continue.");
                            Console.ReadLine();
#endif
                            return;
                        }

                        var targets = new List<Target>();
                        foreach (var plugin in Target.Plugins.Values)
                        {
                            targets.AddRange(plugin.GetTargets());
                        }

                        if (targets.Count == 0)
                        {
                            Console.WriteLine("No targets found.");
                        }
                        else
                        {
                            var count = 1;
                            foreach (var binding in targets)
                            {
                                Console.WriteLine($" {count}: {binding}");
                                count++;
                            }
                        }

                        Console.WriteLine();
                        foreach (var plugin in Target.Plugins.Values)
                        {
                            plugin.PrintMenu();
                        }

                        Console.WriteLine(" A: Get certificates for all hosts");
                        Console.WriteLine(" Q: Quit");
                        Console.Write("Which host do you want to get a certificate for: ");
                        var response = Console.ReadLine().ToLowerInvariant();
                        switch (response)
                        {
                            case "a":
                                foreach (var target in targets)
                                {
                                    Auto(target);
                                }
                                break;
                            case "q":
                                return;
                            default:
                                var targetId = 0;
                                if (Int32.TryParse(response, out targetId))
                                {
                                    targetId--;
                                    if (targetId >= 0 && targetId < targets.Count)
                                    {
                                        var binding = targets[targetId];
                                        Auto(binding);
                                    }
                                }
                                else
                                {
                                    foreach (var plugin in Target.Plugins.Values)
                                    {
                                        plugin.HandleMenuResponse(response, targets);
                                    }
                                }
                                break;
                        }
                    }
                }
            }
            catch (Exception e)
            {
                Console.ForegroundColor = ConsoleColor.Red;
                var acmeWebException = e as AcmeClient.AcmeWebException;
                if (acmeWebException != null)
                {
                    Console.WriteLine(acmeWebException.Message);
                    Console.WriteLine("ACME Server Returned:");
                    Console.WriteLine(acmeWebException.Response.ContentAsString);
                }
                else
                {
                    Console.WriteLine(e);
                }
                Console.ResetColor();
            }

#if DEBUG
            Console.WriteLine("Press enter to continue.");
            Console.ReadLine();
#endif
        }
예제 #38
0
        static void Main(string[] args)
        {
            var commandLineParseResult = Parser.Default.ParseArguments<Options>(args);
            var parsed = commandLineParseResult as Parsed<Options>;
            if (parsed == null)
            {
#if DEBUG
                Console.WriteLine("Press enter to continue.");
                Console.ReadLine();
#endif
                return; // not parsed
            }
            options = parsed.Value;

            Console.WriteLine("Let's Encrypt (Simple Windows ACME Client)");

            BaseURI = options.BaseURI;
            if (options.Test)
                BaseURI = "https://acme-staging.api.letsencrypt.org/";

            //Console.Write("\nUse production Let's Encrypt server? (Y/N) ");
            //if (PromptYesNo())
            //    BaseURI = ProductionBaseURI;

            Console.WriteLine($"\nACME Server: {BaseURI}");

            settings = new Settings(clientName, BaseURI);

            configPath = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData), clientName, CleanFileName(BaseURI));
            Console.WriteLine("Config Folder: " + configPath);
            Directory.CreateDirectory(configPath);

            using (var signer = new RS256Signer())
            {
                signer.Init();

                var signerPath = Path.Combine(configPath, "Signer");
                if (File.Exists(signerPath))
                {
                    Console.WriteLine($"Loading Signer from {signerPath}");
                    using (var signerStream = File.OpenRead(signerPath))
                        signer.Load(signerStream);
                }

                using (client = new AcmeClient(new Uri(BaseURI), new AcmeServerDirectory(), signer))
                {
                    client.Init();
                    Console.WriteLine("\nGetting AcmeServerDirectory");
                    client.GetDirectory(true);

                    var registrationPath = Path.Combine(configPath, "Registration");
                    if (File.Exists(registrationPath))
                    {
                        Console.WriteLine($"Loading Registration from {registrationPath}");
                        using (var registrationStream = File.OpenRead(registrationPath))
                            client.Registration = AcmeRegistration.Load(registrationStream);
                    }
                    else
                    {
                        Console.WriteLine("Calling Register");
                        var registration = client.Register(new string[] { });

                        if (!options.AcceptTOS && !options.Renew)
                        {
                            Console.WriteLine($"Do you agree to {registration.TosLinkUri}? (Y/N) ");
                            if (!PromptYesNo())
                                return;
                        }

                        Console.WriteLine("Updating Registration");
                        client.UpdateRegistration(true, true);

                        Console.WriteLine("Saving Registration");
                        using (var registrationStream = File.OpenWrite(registrationPath))
                            client.Registration.Save(registrationStream);

                        Console.WriteLine("Saving Signer");
                        using (var signerStream = File.OpenWrite(signerPath))
                            signer.Save(signerStream);
                    }

                    if (options.Renew)
                    {
                        CheckRenewals();
#if DEBUG
                        Console.WriteLine("Press enter to continue.");
                        Console.ReadLine();
#endif
                        return;
                    }

                    Console.WriteLine("\nScanning IIS 7 Site Bindings for Hosts (Elevated Permissions Required)");
                    if (!IsElevated)
                    {
                        Console.WriteLine("Elevated Permissions Required. Please run under an administrator console.");
#if DEBUG
                        Console.WriteLine("Press enter to continue.");
                        Console.ReadLine();
#endif
                        return;
                    }


                    var bindings = GetHostNames();
                    if (bindings.Count == 0)
                    {
                        Console.WriteLine("No IIS bindings with host names were found. Please add one using IIS Manager. A host name and site path are required to verify domain ownership.");
                        return;
                    }

                    Console.WriteLine("IIS Bindings");
                    var count = 1;
                    foreach (var binding in bindings)
                    {
                        Console.WriteLine($" {count}: {binding}");
                        count++;
                    }

                    Console.WriteLine();
                    Console.WriteLine(" A: Get Certificates for All Bindings");
                    Console.WriteLine(" Q: Quit");
                    Console.Write("Which binding do you want to get a cert for: ");
                    var response = Console.ReadLine();
                    switch (response.ToLowerInvariant())
                    {
                        case "a":
                            foreach (var binding in bindings)
                            {
                                Auto(binding);
                            }
                            break;
                        case "q":
                            return;
                        default:
                            var bindingId = 0;
                            if (Int32.TryParse(response, out bindingId))
                            {
                                bindingId--;
                                if (bindingId >= 0 && bindingId < bindings.Count)
                                {
                                    var binding = bindings[bindingId];
                                    Auto(binding);
                                }
                            }
                            break;
                    }
                }
            }

#if DEBUG
            Console.WriteLine("Press enter to continue.");
            Console.ReadLine();
#endif
        }