public async Task PostAddsProperHeader() { HttpRequestMessage httpRequestMessage = null; Mock <HttpMessageHandler> messageHandlerMock = new Mock <HttpMessageHandler>(MockBehavior.Strict) .AddDirectoryResponse() .AddNonce(); messageHandlerMock.Protected() .Setup <Task <HttpResponseMessage> >("SendAsync", ItExpr.Is <HttpRequestMessage>(x => x.RequestUri == TestHelpers.AcmeDirectory.NewAccount), ItExpr.IsAny <CancellationToken>()) .Returns((HttpRequestMessage request, CancellationToken token) => { httpRequestMessage = request; return(Task.FromResult(new HttpResponseMessage())); }) .Verifiable(); var httpClient = new HttpClient(messageHandlerMock.Object); var rsaKey = RSA.Create(); var acmeClient = new ACMEClient(TestHelpers.BaseUri, rsaKey, httpClient); await acmeClient.RegisterAsync(new[] { "*****@*****.**" }); // assert httpRequestMessage.Content.Headers.ContentType.MediaType.Should().Be("application/jose+json"); httpRequestMessage.Content.Headers.ContentType.CharSet.Should().BeNull(); }
public async Task ValidateACMEConnection() { acmeDirectory = await acmeClient.InitializeAsync(); Kenc.ACMELib.ACMEObjects.Account account = null; if (!string.IsNullOrEmpty(options.Key)) { Console.WriteLine("Validating if user exists with existing key"); try { account = await acmeClient.GetAccountAsync(); } catch (AccountDoesNotExistException exception) { Program.LogLine(exception.Message); } if (account != null) { Program.LogLine($"Using previously created account {account.Id}"); } else { Program.LogLine("Couldn't retrieve existing account. Creating new account."); } } if (account == null) { Program.LogLine("Creating user.."); Program.LogLine($"By creating this user, you acknowledge the terms of service: {acmeDirectory.Meta.TermsOfService}"); Program.Log("Enter email address for user: "******"mailto:" + userContact }); } catch (Exception ex) { Program.LogLine($"An error occured while registering user. {ex.Message}"); throw; } } }
public async Task GetsANonceIfNoneIsPresent() { Mock <HttpMessageHandler> messageHandlerMock = new Mock <HttpMessageHandler>(MockBehavior.Strict) .AddDirectoryResponse() .AddNonce(); messageHandlerMock.Protected() .Setup <Task <HttpResponseMessage> >("SendAsync", ItExpr.Is <HttpRequestMessage>(x => x.RequestUri == TestHelpers.AcmeDirectory.NewAccount), ItExpr.IsAny <CancellationToken>()) .Returns((HttpRequestMessage request, CancellationToken token) => Task.FromResult(new HttpResponseMessage())) .Verifiable(); var httpClient = new HttpClient(messageHandlerMock.Object); var rsaKey = RSA.Create(); var acmeClient = new ACMEClient(TestHelpers.BaseUri, rsaKey, httpClient); await acmeClient.RegisterAsync(new[] { "*****@*****.**" }); messageHandlerMock.VerifyAll(); }
static async Task Main(string[] args) { Console.WriteLine("Kenc.ACMEClient example"); Console.WriteLine("USE AT OWN RISK"); Console.WriteLine("This program uses the LetsEncrypt STAGING environment by default"); Console.WriteLine("WARNING: Encryption key is stored UNPROTECTED in bin folder"); Console.WriteLine("============================================================\n\n"); // RSA service provider var rsaCryptoServiceProvider = new RSACryptoServiceProvider(2048); Console.WriteLine($"Looking for key {keyPath}"); var existingKey = File.Exists(keyPath); if (!existingKey) { Console.WriteLine("Key not found - generating"); var exportKey = rsaCryptoServiceProvider.ExportCspBlob(true); var strKey = Convert.ToBase64String(exportKey); File.WriteAllText(keyPath, strKey); } var key = Convert.FromBase64String(File.ReadAllText(keyPath)); rsaCryptoServiceProvider.ImportCspBlob(key); var rsaKey = RSA.Create(rsaCryptoServiceProvider.ExportParameters(true)); var acmeClient = new ACMEClient(ACMEEnvironment.StagingV2, rsaKey, string.Empty, new RestClientFactory()); var directory = await acmeClient.InitializeAsync(); Account account = null; if (existingKey) { Console.WriteLine("Validating if user exists with existing key"); try { account = await acmeClient.GetAccountAsync(); } catch (AccountDoesNotExistException exception) { Console.WriteLine(exception.Message); } catch (Exception exception) { Console.WriteLine($"Exception encounted while looking up client: {exception.Message}"); } if (account != null) { Console.WriteLine($"Using previously created account {account.Id}"); } else { Console.WriteLine("Couldn't retrieve existing account. Creating new account."); } } if (account == null) { Console.WriteLine("Creating user.."); Console.WriteLine("By creating this user, you acknowledge the terms of service: {0}", directory.Meta.TermsOfService); Console.Write("Enter email address for user: "******"mailto:" + userContact }); } catch (Exception ex) { Console.WriteLine("An error occured while registering user. {0}", ex.Message); throw; } } Console.WriteLine("Enter domain to validate and request certificate for:"); var domainName = Console.ReadLine(); if (string.IsNullOrWhiteSpace(domainName)) { Console.WriteLine("Invalid domain aborting."); return; } var domainTask = OrderDomains(acmeClient, domainName); domainTask.Wait(); }
private static async Task Main() { Console.WriteLine("Kenc.ACMEClient example"); Console.WriteLine("USE AT OWN RISK"); Console.WriteLine("This program uses the LetsEncrypt STAGING environment by default"); Console.WriteLine("WARNING: Encryption key is stored UNPROTECTED in bin folder"); Console.WriteLine("============================================================\n\n"); // RSA service provider var rsaCryptoServiceProvider = new RSACryptoServiceProvider(2048); Console.WriteLine($"Looking for key {keyPath}"); var existingKey = File.Exists(keyPath); if (!existingKey) { Console.WriteLine("Key not found - generating"); var exportKey = rsaCryptoServiceProvider.ExportCspBlob(true); var strKey = Convert.ToBase64String(exportKey); File.WriteAllText(keyPath, strKey); } var key = Convert.FromBase64String(File.ReadAllText(keyPath)); rsaCryptoServiceProvider.ImportCspBlob(key); var rsaKey = RSA.Create(rsaCryptoServiceProvider.ExportParameters(true)); var acmeClient = new ACMEClient(new Uri(ACMEEnvironment.StagingV2), rsaKey, new HttpClient()); ACMEDirectory directory = await acmeClient.InitializeAsync(); Account account = null; if (existingKey) { Console.WriteLine("Validating if user exists with existing key"); try { account = await acmeClient.GetAccountAsync(); } catch (AccountDoesNotExistException exception) { Console.WriteLine(exception.Message); } catch (Exception exception) { Console.WriteLine($"Exception encounted while looking up client: {exception.Message}"); } if (account != null) { Console.WriteLine($"Using previously created account {account.Id}"); } else { Console.WriteLine("Couldn't retrieve existing account. Creating new account."); } } if (account == null) { Console.WriteLine("Creating user.."); Console.WriteLine("By creating this user, you acknowledge the terms of service: {0}", directory.Meta.TermsOfService); Console.Write("Enter email address for user: "******"mailto:" + userContact }); } catch (Exception ex) { Console.WriteLine("An error occured while registering user. {0}", ex.Message); throw; } } Console.WriteLine("Enter domain(s) to validate and request certificate(s) for (wildcard? add wildcard and tld comma separated):"); var domainNames = Console.ReadLine().Split(',').Where(s => !string.IsNullOrWhiteSpace(s)).ToArray(); if (!domainNames.Any()) { Console.WriteLine("Invalid domain aborting."); return; } Task domainTask = OrderDomains(acmeClient, domainNames); domainTask.Wait(); // enumerate all certs var certificateFiles = Directory.EnumerateFiles(Directory.GetCurrentDirectory(), "*.crt").ToList(); Console.WriteLine($"Revoking certificates: {string.Join(',', certificateFiles)}"); var foo = HandleConsoleInput("Continue?", new[] { "y", "yes", "n", "no" }, false).ToLower(); if (foo == "y" || foo == "yes") { IEnumerable <X509Certificate> certificates = certificateFiles.Select(path => X509Certificate2.CreateFromCertFile(path)); foreach (X509Certificate certificate in certificates) { try { await acmeClient.RevokeCertificateAsync(certificate, RevocationReason.Superseded); Console.WriteLine($"{certificate.Subject} revoked."); } catch (ACMEException exception) when(exception.Descriptor == "urn:ietf:params:acme:error:alreadyRevoked") { Console.WriteLine(exception.Message); } catch (ACMEException exception) { Console.WriteLine(exception.Message); throw; } } Console.WriteLine("Completed"); } }