internal async Task ConfigureAcmeClient() { var httpClient = _proxyService.GetHttpClient(); httpClient.BaseAddress = _settings.BaseUri; _log.Verbose("Loading ACME account signer..."); IJwsTool?signer = null; var accountSigner = AccountSigner; if (accountSigner != null) { signer = accountSigner.JwsTool(); } _log.Verbose("Constructing ACME protocol client..."); try { _client = new AcmeProtocolClient( httpClient, signer: signer, usePostAsGet: _settings.Acme.PostAsGet); } catch (CryptographicException) { if (signer == null) { // There has been a problem generate a signer for the // new account, possibly because some EC curve is not // on available on the system? So we give it another // shot with a less fancy RSA signer _log.Verbose("First chance error generating new signer, retrying with RSA instead of ECC"); signer = new RSJwsTool { KeySize = _settings.Security.RSAKeyBits }; signer.Init(); _client = new AcmeProtocolClient( httpClient, signer: signer, usePostAsGet: _settings.Acme.PostAsGet); } else { throw; } } _client.BeforeHttpSend = (x, r) => _log.Debug("Send {method} request to {uri}", r.Method, r.RequestUri); _client.AfterHttpSend = (x, r) => _log.Verbose("Request completed with status {s}", r.StatusCode); _client.Directory = await _client.GetDirectoryAsync(); await _client.GetNonceAsync(); _client.Account = await LoadAccount(_client, signer); if (_client.Account == null) { throw new Exception("AcmeClient was unable to find or create an account"); } }
public IJwsTool JwsTool() { if (KeyType.StartsWith("ES")) { var tool = new ESJwsTool { HashSize = int.Parse(KeyType.Substring(2)) }; tool.Init(); tool.Import(KeyExport); return(tool); } if (KeyType.StartsWith("RS")) { var tool = new RSJwsTool { KeySize = int.Parse(KeyType.Substring(2)) }; tool.Init(); tool.Import(KeyExport); return(tool); } throw new Exception($"Unknown or unsupported KeyType [{KeyType}]"); }
public void SerDesRSA() { var rng = RandomNumberGenerator.Create(); for (var i = 0; i < 1000; i++) { var original = new RSJwsTool(); // Default for ISigner original.Init(); var rawX = new byte[8034]; rng.GetBytes(rawX); var sigX = original.Sign(rawX); var exported = original.Export(); var copy = new RSJwsTool(); copy.Init(); copy.Import(exported); var verified = copy.Verify(rawX, sigX); Assert.AreEqual(true, verified); } }
internal AcmeProtocolClient PrepareClient(HttpClient httpClient, IJwsTool?signer) { AcmeProtocolClient?client = null; _log.Verbose("Constructing ACME protocol client..."); try { client = new AcmeProtocolClient( httpClient, signer: signer, usePostAsGet: _settings.Acme.PostAsGet); } catch (CryptographicException) { if (signer == null) { // There has been a problem generate a signer for the // new account, possibly because some EC curve is not // on available on the system? So we give it another // shot with a less fancy RSA signer _log.Verbose("First chance error generating new signer, retrying with RSA instead of ECC"); signer = new RSJwsTool { KeySize = _settings.Security.RSAKeyBits }; signer.Init(); client = new AcmeProtocolClient( httpClient, signer: signer, usePostAsGet: _settings.Acme.PostAsGet); } else { throw; } } client.BeforeHttpSend = (x, r) => _log.Debug("Send {method} request to {uri}", r.Method, r.RequestUri); client.AfterHttpSend = (x, r) => _log.Verbose("Request completed with status {s}", r.StatusCode); return(client); }
internal AcmeProtocolClient PrepareClient(HttpClient httpClient, IJwsTool?signer) { _log.Verbose("Constructing ACME protocol client..."); AcmeProtocolClient?client; try { client = new AcmeProtocolClient( httpClient, signer: signer, usePostAsGet: _settings.Acme.PostAsGet); } catch (CryptographicException) { if (signer == null) { // There has been a problem generate a signer for the // new account, possibly because some EC curve is not // on available on the system? So we give it another // shot with a less fancy RSA signer _log.Verbose("First chance error generating new signer, retrying with RSA instead of ECC"); signer = new RSJwsTool { KeySize = _settings.Security.RSAKeyBits }; signer.Init(); client = new AcmeProtocolClient( httpClient, signer: signer, usePostAsGet: _settings.Acme.PostAsGet); } else { throw; } } return(client); }
void ValidateAccount(DbAccount acct, JwsSignedPayload signedPayload) { var ph = ExtractProtectedHeader(signedPayload); var jwk = JsonConvert.DeserializeObject <Dictionary <string, string> >(acct.Jwk); if (string.IsNullOrEmpty(ph.Alg)) { throw new Exception("invalid JWS header, missing 'alg'"); } if (string.IsNullOrEmpty(ph.Url)) { throw new Exception("invalid JWS header, missing 'url'"); } if (string.IsNullOrEmpty(ph.Nonce)) { throw new Exception("invalid JWS header, missing 'nonce'"); } IJwsTool tool = null; switch (ph.Alg) { case "RS256": tool = new RSJwsTool { HashSize = 256 }; ((RSJwsTool)tool).ImportJwk(acct.Jwk); break; case "RS384": tool = new RSJwsTool { HashSize = 384 }; ((RSJwsTool)tool).ImportJwk(acct.Jwk); break; case "RS512": tool = new RSJwsTool { HashSize = 512 }; ((RSJwsTool)tool).ImportJwk(acct.Jwk); break; case "ES256": tool = new ESJwsTool { HashSize = 256 }; break; case "ES384": tool = new ESJwsTool { HashSize = 384 }; break; case "ES512": tool = new ESJwsTool { HashSize = 512 }; break; default: throw new Exception("unknown or unsupported signature algorithm"); } var sig = CryptoHelper.Base64.UrlDecode(signedPayload.Signature); var pld = CryptoHelper.Base64.UrlDecode(signedPayload.Payload); var prt = CryptoHelper.Base64.UrlDecode(signedPayload.Protected); var sigInput = $"{signedPayload.Protected}.{signedPayload.Payload}"; var sigInputBytes = Encoding.ASCII.GetBytes(sigInput); if (!tool.Verify(sigInputBytes, sig)) { throw new Exception("account signature failure"); } }
private async Task <bool> ConfigureAcmeClient() { var httpClientHandler = new HttpClientHandler() { Proxy = _proxyService.GetWebProxy(), }; var httpClient = new HttpClient(httpClientHandler) { BaseAddress = new Uri(_arguments.MainArguments.GetBaseUri()) }; _log.Verbose("Loading ACME account signer..."); IJwsTool signer = null; var accountSigner = AccountSigner; if (accountSigner != null) { signer = accountSigner.JwsTool(); } _log.Verbose("Constructing ACME protocol client..."); try { _client = new AcmeProtocolClient(httpClient, signer: signer); } catch (CryptographicException) { if (signer == null) { // There has been a problem generate a signer for the // new account, possibly because some EC curve is not // on available on the system? So we give it another // shot with a less fancy RSA signer _log.Verbose("First chance error generating new signer, retrying with RSA instead of ECC"); signer = new RSJwsTool { KeySize = new Rsa(_log, new RsaOptions()).GetRsaKeyBits() }; signer.Init(); _client = new AcmeProtocolClient(httpClient, signer: signer); } else { throw; } } _client.BeforeHttpSend = (x, r) => { _log.Debug("Send {method} request to {uri}", r.Method, r.RequestUri); }; _client.AfterHttpSend = (x, r) => { _log.Verbose("Request completed with status {s}", r.StatusCode); }; _client.Directory = await _client.GetDirectoryAsync(); await _client.GetNonceAsync(); _client.Account = await LoadAccount(signer); if (_client.Account == null) { throw new Exception("AcmeClient was unable to find or create an account"); } return(true); }