/// <summary> /// <see cref="IDisposable.Dispose"/> /// </summary> public void Dispose() { if (!(this.httpClient is null)) { this.httpClient.Dispose(); this.httpClient = null; } if (!(this.jws is null)) { this.jws.Dispose(); this.jws = null; } }
/// <summary> /// <see cref="IDisposable.Dispose"/> /// </summary> public void Dispose() { if (this.httpClient != null) { this.httpClient.Dispose(); this.httpClient = null; } if (this.jws != null) { this.jws.Dispose(); this.jws = null; } }
/// <summary> /// Generates a new key for the account. (Account keys are managed by the CSP.) /// </summary> /// <param name="AccountLocation">URL of the account resource.</param> public async Task <AcmeAccount> NewKey(Uri AccountLocation) { if (this.directory == null) { await this.GetDirectory(); } RSA NewKey = RSA.Create(); NewKey.KeySize = KeySize; if (NewKey.KeySize != KeySize) // Happens when using library from traditioanl .NET FW { Type T = Runtime.Inventory.Types.GetType("System.Security.Cryptography.RSACryptoServiceProvider"); if (T == null) { throw new Exception("Unable to set RSA key size to anything but default (" + NewKey.KeySize.ToString() + " bits)."); } NewKey = Activator.CreateInstance(T, KeySize) as RSA; } RsaSsaPkcsSha256 Jws2 = new RsaSsaPkcsSha256(NewKey); try { Jws2.Sign(new KeyValuePair <string, object>[] { new KeyValuePair <string, object>("url", this.directory.KeyChange.ToString()) }, new KeyValuePair <string, object>[] { new KeyValuePair <string, object>("account", AccountLocation.ToString()), new KeyValuePair <string, object>("oldkey", this.jws.PublicWebKey), }, out string Header, out string Payload, out string Signature); AcmeResponse Response = await this.POST(this.directory.KeyChange, AccountLocation, new KeyValuePair <string, object>("protected", Header), new KeyValuePair <string, object>("payload", Payload), new KeyValuePair <string, object>("signature", Signature)); this.jwkThumbprint = null; this.jws.ImportKey(NewKey); return(new AcmeAccount(this, Response.Location, Response.Payload)); } finally { Jws2.Dispose(); } }
/// <summary> /// Deactivates an account. /// </summary> /// <param name="AccountLocation">Account location.</param> /// <returns>New account object.</returns> public async Task <AcmeAccount> DeactivateAccount(Uri AccountLocation) { if (this.directory == null) { await this.GetDirectory(); } AcmeResponse Response = await this.POST(AccountLocation, AccountLocation, new KeyValuePair <string, object>("status", "deactivated")); this.jws.DeleteRsaKeyFromCsp(); this.jws = null; this.jws = new RsaSsaPkcsSha256(KeySize, this.directoryEndpoint.ToString()); return(new AcmeAccount(this, Response.Location, Response.Payload)); }
/// <summary> /// Implements an ACME client for the generation of certificates using ACME-compliant certificate servers. /// </summary> /// <param name="DirectoryEndpoint">HTTP endpoint for the ACME directory resource.</param> public AcmeClient(Uri DirectoryEndpoint) { this.directoryEndpoint = DirectoryEndpoint; this.jws = new RsaSsaPkcsSha256(KeySize, DirectoryEndpoint.ToString()); this.httpClient = new HttpClient(new HttpClientHandler() { AllowAutoRedirect = true, AutomaticDecompression = DecompressionMethods.Deflate | DecompressionMethods.GZip, CheckCertificateRevocationList = true, SslProtocols = SslProtocols.Tls | SslProtocols.Tls11 | SslProtocols.Tls12 }, true); this.httpClient.DefaultRequestHeaders.Add("User-Agent", typeof(AcmeClient).Namespace); this.httpClient.DefaultRequestHeaders.Add("Accept", JwsAlgorithm.JwsContentType); this.httpClient.DefaultRequestHeaders.Add("Accept-Language", "en"); }
/// <summary> /// Implements an ACME client for the generation of certificates using ACME-compliant certificate servers. /// </summary> /// <param name="DirectoryEndpoint">HTTP endpoint for the ACME directory resource.</param> /// <param name="Parameters">RSA key parameters.</param> public AcmeClient(Uri DirectoryEndpoint, RSAParameters Parameters) { this.directoryEndpoint = DirectoryEndpoint; this.jws = new RsaSsaPkcsSha256(Parameters); try { this.httpClient = new HttpClient(new HttpClientHandler() { AllowAutoRedirect = true, AutomaticDecompression = DecompressionMethods.Deflate | DecompressionMethods.GZip, CheckCertificateRevocationList = true, SslProtocols = SslProtocols.Tls | SslProtocols.Tls11 | SslProtocols.Tls12 }, true); } catch (PlatformNotSupportedException) { this.httpClient = new HttpClient(new HttpClientHandler() { AllowAutoRedirect = true }, true); } Type T = typeof(AcmeClient); Version Version = T.GetTypeInfo().Assembly.GetName().Version; StringBuilder UserAgent = new StringBuilder(); UserAgent.Append(T.Namespace); UserAgent.Append('/'); UserAgent.Append(Version.Major.ToString()); UserAgent.Append('.'); UserAgent.Append(Version.Minor.ToString()); UserAgent.Append('.'); UserAgent.Append(Version.Build.ToString()); this.httpClient.DefaultRequestHeaders.Add("User-Agent", UserAgent.ToString()); this.httpClient.DefaultRequestHeaders.Add("Accept", JwsAlgorithm.JwsContentType); this.httpClient.DefaultRequestHeaders.Add("Accept-Language", "en"); }
/// <summary> /// Generates a new key for the account. (Account keys are managed by the CSP.) /// </summary> /// <param name="AccountLocation">URL of the account resource.</param> public async Task <AcmeAccount> NewKey(Uri AccountLocation) { if (this.directory == null) { await this.GetDirectory(); } RSACryptoServiceProvider NewKey = new RSACryptoServiceProvider(KeySize); RsaSsaPkcsSha256 Jws2 = new RsaSsaPkcsSha256(NewKey); try { Jws2.Sign(new KeyValuePair <string, object>[] { new KeyValuePair <string, object>("url", this.directory.KeyChange.ToString()) }, new KeyValuePair <string, object>[] { new KeyValuePair <string, object>("account", AccountLocation.ToString()), new KeyValuePair <string, object>("newkey", Jws2.PublicWebKey) }, out string Header, out string Payload, out string Signature); AcmeResponse Response = await this.POST(this.directory.KeyChange, AccountLocation, new KeyValuePair <string, object>("protected", Header), new KeyValuePair <string, object>("payload", Payload), new KeyValuePair <string, object>("signature", Signature)); this.jwkThumbprint = null; this.jws.ImportKey(NewKey); return(new AcmeAccount(this, Response.Location, Response.Payload)); } finally { Jws2.Dispose(); } }