/// <summary> /// Request a certificate. /// </summary> /// <param name="order">A previously completed order.</param> /// <param name="key">The private key to sign the certificate request with.</param> /// <param name="cancellationToken">Cancellation token for the async request.</param> /// <returns>An updated <see cref="Order"/> object.</returns> /// <remarks>The subjectname for the request is the first identifier in <paramref name="order"/>. Subsequent identifiers are added as alternative names.</remarks> public async Task <Order> RequestCertificateAsync(Order order, RSACryptoServiceProvider key, CancellationToken cancellationToken = default) { var csr = new CertificateRequest("CN=" + order.Identifiers[0].Value, key, HashAlgorithmName.SHA256, RSASignaturePadding.Pkcs1); var san = new SubjectAlternativeNameBuilder(); foreach (var identifier in order.Identifiers.Skip(1)) { san.AddDnsName(identifier.Value); } csr.CertificateExtensions.Add(san.Build()); var message = new FinalizeRequest { CSR = Jws.Base64UrlEncoded(csr.CreateSigningRequest()) }; var(result, responseText) = await client.PostAsync <Order>(order.Finalize, message, cancellationToken); if (result is Order acmeOrder) { return(acmeOrder); } throw new InvalidServerResponse("Invalid response from server during RequestCertificate.", responseText, order.Finalize.ToString()); }
public LetsEncryptClient(string url) { _url = url ?? throw new ArgumentNullException(nameof(url)); var home = Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData, Environment.SpecialFolderOption.Create); var hash = SHA256.Create().ComputeHash(Encoding.UTF8.GetBytes(url)); var file = Jws.Base64UrlEncoded(hash) + ".lets-encrypt.cache.json"; _path = Path.Combine(home, file); }
public async Task <string> GetDnsChallenge(string hostname, CancellationToken token = default(CancellationToken)) { _hosts.Add(hostname); var challenge = await _client.NewDnsAuthorizationAsync(hostname, token); var dnsChallenge = challenge.Challenges.First(x => x.Type == "dns-01"); var keyToken = _client.GetKeyAuthorization(dnsChallenge.Token); var computedDns = Jws.Base64UrlEncoded(SHA256.Create().ComputeHash(Encoding.UTF8.GetBytes(keyToken))); _challenges.Add(dnsChallenge); return(computedDns); }
public async Task <CertificateResponse> NewCertificateRequestAsync(byte[] csr, CancellationToken token = default(CancellationToken)) { await EnsureDirectoryAsync().ConfigureAwait(false); var request = new AcmeCertificateRequest { Csr = Jws.Base64UrlEncoded(csr) }; var response = await PostAsync <CertificateResponse>( _directory.NewCertificate, request, token ).ConfigureAwait(false); return(response); }