protected void ProcessOrders(AcmeResponse response) { if (response.Content is Protocol.OrderList orderList) { orderList.Orders = orderList.Orders.Select(o => $"{BaseUri}order/{o}").ToArray(); } }
protected ActionResult CreateActionResult(AcmeResponse response) { // TODO NewNoce must return 200 status for HEAD request ActionResult result = response.Content == null ? new NoContentResult() : (ActionResult) new OkObjectResult(response.Content) { StatusCode = response.StatusCode, }; #region Add headers foreach (var header in response.Headers.AllKeys) { Response.Headers.Add(header, response.Headers.Get(header)); } #endregion #region Add Content-Type for Error if (response.Content is Error) { Response.Headers.Add("Content-Type", new string[] { "application/problem+json" }); } #endregion return(result); }
private void ThrowIfError <T>(AcmeResponse <T> response) { if (response.Error != null) { throw new Exception($"{response.Error.Type}: {response.Error.Detail} ({response.Error.Status})"); } }
public void POST_Nonce_Empty() { AcmeResponse response = null; using var provider = Application.CreateProvider(); IAcmeController controller = (IAcmeController)provider.GetService(typeof(IAcmeController)); var accountKey = RSA.Create(2048); var token = new JsonWebSignature(); token.SetProtected(new JsonWebSignatureProtected { Url = $"{Application.BaseAddress}new-acct", Algorithm = AlgorithmsEnum.RS256, Key = new JsonWebKey(accountKey), }); token.Sign(accountKey); response = controller.CreateAccount(new AcmeRequest { Path = $"{Application.BaseAddress}new-acct", Method = "POST", Token = token, }); Assert.Equal(400, response.StatusCode); var content = response.GetContent <Protocol.Error>(); Assert.Equal(Protocol.ErrorType.Malformed, content.Type); Assert.NotNull(content.Detail); }
/// <summary> /// Deactivates an authorization. /// </summary> /// <param name="AccountLocation">Account location.</param> /// <param name="AuthorizationLocation">Authorization location</param> /// <returns>New authorization object.</returns> public async Task <AcmeAuthorization> DeactivateAuthorization(Uri AccountLocation, Uri AuthorizationLocation) { AcmeResponse Response = await this.POST(AuthorizationLocation, AccountLocation, new KeyValuePair <string, object>("status", "deactivated")); return(new AcmeAuthorization(this, AccountLocation, Response.Location, Response.Payload)); }
/// <summary> /// Finalize order. /// </summary> /// <param name="AccountLocation">Account location.</param> /// <param name="FinalizeLocation">Finalize location.</param> /// <param name="CertificateRequest">Certificate request.</param> /// <returns>New order object.</returns> public async Task <AcmeOrder> FinalizeOrder(Uri AccountLocation, Uri FinalizeLocation, CertificateRequest CertificateRequest) { byte[] CSR = CertificateRequest.BuildCSR(); AcmeResponse Response = await this.POST(FinalizeLocation, AccountLocation, new KeyValuePair <string, object>("csr", Base64Url.Encode(CSR))); return(new AcmeOrder(this, AccountLocation, Response.Location, Response.Payload, Response.ResponseMessage)); }
private void ThrowIfError <T>(AcmeResponse <T> response, Uri uri) { if (response.Error != null) { throw new AcmeRequestException( string.Format(Strings.ErrorFetchResource, uri), response.Error); } }
/// <summary> /// Creates <see cref="AcmeResponse"/> with headers /// </summary> /// <returns></returns> public AcmeResponse CreateResponse() { var resp = new AcmeResponse { StatusCode = 200, // OK }; resp.Headers.Link.Add(new LinkHeader($"{Options.BaseAddress}directory", new LinkHeaderItem("rel", "index", true))); resp.Headers.ReplayNonce = NonceService.Create(); return(resp); }
/// <summary> /// Updates an account. /// </summary> /// <param name="AccountLocation">Account location.</param> /// <param name="Contact">New contact information.</param> /// <returns>New account object.</returns> public async Task <AcmeAccount> UpdateAccount(Uri AccountLocation, string[] Contact) { if (this.directory == null) { await this.GetDirectory(); } AcmeResponse Response = await this.POST(AccountLocation, AccountLocation, new KeyValuePair <string, object>("contact", Contact)); return(new AcmeAccount(this, Response.Location, Response.Payload)); }
/// <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")); return(new AcmeAccount(this, Response.Location, Response.Payload)); }
internal async Task <AcmeResponse> POST(Uri URL, Uri KeyID, params KeyValuePair <string, object>[] Payload) { HttpResponseMessage Response = await this.HttpPost(URL, KeyID, null, Payload); byte[] Bin = await Response.Content.ReadAsByteArrayAsync(); string CharSet = Response.Content.Headers.ContentType?.CharSet; Encoding Encoding; if (string.IsNullOrEmpty(CharSet)) { Encoding = Encoding.UTF8; } else { Encoding = InternetContent.GetEncoding(CharSet); } AcmeResponse AcmeResponse = new AcmeResponse() { Json = Encoding.GetString(Bin), Location = URL, ResponseMessage = Response, Payload = null }; if (Response.Headers.TryGetValues("Location", out IEnumerable <string> Values)) { foreach (string s in Values) { AcmeResponse.Location = new Uri(s); break; } } if (string.IsNullOrEmpty(AcmeResponse.Json)) { AcmeResponse.Payload = null; } else if ((AcmeResponse.Payload = JSON.Parse(AcmeResponse.Json) as IEnumerable <KeyValuePair <string, object> >) is null) { throw new Exception("Unexpected response returned."); } if (Response.IsSuccessStatusCode) { return(AcmeResponse); } else { throw CreateException(AcmeResponse.Payload, Response); } }
/// <summary> /// Creates an account on the ACME server. /// </summary> /// <param name="ContactURLs">URLs for contacting the account holder.</param> /// <param name="TermsOfServiceAgreed">If the terms of service have been accepted.</param> /// <returns>ACME account object.</returns> public async Task <AcmeAccount> CreateAccount(string[] ContactURLs, bool TermsOfServiceAgreed) { if (this.directory == null) { await this.GetDirectory(); } AcmeResponse Response = await this.POST(this.directory.NewAccount, null, new KeyValuePair <string, object>("termsOfServiceAgreed", TermsOfServiceAgreed), new KeyValuePair <string, object>("contact", ContactURLs)); AcmeAccount Account; if (Response.Payload == null) { Response = await this.POST(Response.Location, Response.Location); Account = new AcmeAccount(this, Response.Location, Response.Payload); bool ContactsDifferent = false; int i, c = ContactURLs.Length; if (c != Account.Contact.Length) { ContactsDifferent = true; } else { for (i = 0; i < c; i++) { if (ContactURLs[i] != Account.Contact[i]) { ContactsDifferent = true; break; } } } if (ContactsDifferent) { Account = await this.UpdateAccount(Account.Location, ContactURLs); } } else { Account = new AcmeAccount(this, Response.Location, Response.Payload); } return(Account); }
public void Account_New_TermsOfService_Enabled_TermsOfServiceAgreed_False() { AcmeResponse response = null; using var provider = Application.CreateProvider(o => { o.TermsOfService = "https://some.com/acme/terms.pdf"; }); IAcmeController controller = (IAcmeController)provider.GetService(typeof(IAcmeController)); // Get nonce response = controller.GetNonce(new AcmeRequest { Path = $"{Application.BaseAddress}new-nonce", Method = "HEAD", }); // Create token var accountKey = RSA.Create(2048); var token = new JsonWebSignature(); token.SetProtected(new JsonWebSignatureProtected { Url = $"{Application.BaseAddress}new-acct", Algorithm = AlgorithmsEnum.RS256, Key = new JsonWebKey(accountKey), Nonce = response.Headers.ReplayNonce, }); token.SetPayload(new NewAccount { Contacts = new string[] { "mailto:[email protected]" }, TermsOfServiceAgreed = false, }); token.Sign(accountKey); // Create account response = controller.CreateAccount(new AcmeRequest { Path = $"{Application.BaseAddress}new-acct", Method = "POST", Token = token, }); Assert.Equal(400, response.StatusCode); var content = response.GetContent <Protocol.Error>(); Assert.Equal(Protocol.ErrorType.Malformed, content.Type); Assert.NotNull(content.Detail); }
/// <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(); } }
public void Account_New_TermsOfService_Disabled() { AcmeResponse response = null; using var provider = Application.CreateProvider(); IAcmeController controller = (IAcmeController)provider.GetService(typeof(IAcmeController)); // Get nonce response = controller.GetNonce(new AcmeRequest { Path = $"{Application.BaseAddress}new-nonce", Method = "HEAD", }); // Create token var accountKey = RSA.Create(2048); var token = new JsonWebSignature(); token.SetProtected(new JsonWebSignatureProtected { Url = $"{Application.BaseAddress}new-acct", Algorithm = AlgorithmsEnum.RS256, Key = new JsonWebKey(accountKey), Nonce = response.Headers.ReplayNonce, }); token.SetPayload(new NewAccount { Contacts = new string[] { "mailto:[email protected]" }, }); token.Sign(accountKey); // Create account response = controller.CreateAccount(new AcmeRequest { Path = $"{Application.BaseAddress}new-acct", Method = "POST", Token = token, }); Assert.Equal(201, response.StatusCode); var content = response.GetContent <Protocol.Account>(); Assert.Single(response.Headers.Link); Assert.Equal("https://test.server.com/acme/acct/1", response.Headers.Location); Assert.NotNull(content); Assert.NotNull(content.Key); Assert.Null(content.TermsOfServiceAgreed); }
/// <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> /// Gets the account object from the ACME server. /// </summary> /// <returns>ACME account object.</returns> public async Task <AcmeAccount> GetAccount() { if (this.directory == null) { await this.GetDirectory(); } AcmeResponse Response = await this.POST(this.directory.NewAccount, null, new KeyValuePair <string, object>("onlyReturnExisting", true)); if (Response.Payload == null) { Response = await this.POST(Response.Location, Response.Location); } return(new AcmeAccount(this, Response.Location, Response.Payload)); }
/// <summary> /// Download the issued certificate. /// </summary> /// <see cref="https://tools.ietf.org/html/rfc8555#section-7.4.2"/> public async Task <AcmeResponse <X509Certificate2Collection> > OrderCertificateGetAsync(string certificateUrl) { Logger.Info("Getting an ACME certificate list. Params:{@params}", certificateUrl); var response = await Request(certificateUrl, new RequestParams { Method = HttpMethod.Post, Payload = "" }); var chain = new X509Certificate2Collection(); var mediaContnet = (MediaTypeContent)response.Content; var rawData = mediaContnet.ToArray(); switch (mediaContnet.Type) { case "application/pkix-cert": chain.Add(new X509Certificate2(rawData)); break; case "application/pem-certificate-chain": var dec = Encoding.UTF8.GetString(rawData); chain.AddRange(PemConverter.Decode(dec).Select(o => new X509Certificate2(o)).ToArray()); break; case "application/pkcs7-mime": chain.Import(rawData); break; default: throw new Exception("Wrong Content type"); } var resp = new AcmeResponse <X509Certificate2Collection>() { StatusCode = (int)response.StatusCode, // todo need upgrade //ReplayNonce = replayNonceValues?.FirstOrDefault(), //Location = locationValues?.FirstOrDefault(), //Links = linksValues != null ? new LinkHeaderCollection(linksValues.ToArray()) : null, Content = chain, }; return(resp); }
public void POST_Url_WrongTargetUrl() { /// The value of the "url" header /// parameter MUST be a string representing the target URL AcmeResponse response = null; using var provider = Application.CreateProvider(); IAcmeController controller = (IAcmeController)provider.GetService(typeof(IAcmeController)); // Get nonce response = controller.GetNonce(new AcmeRequest { Path = $"{Application.BaseAddress}new-nonce", Method = "HEAD", }); var accountKey = RSA.Create(2048); var token = new JsonWebSignature(); token.SetProtected(new JsonWebSignatureProtected { Url = "https://wrong.com/acme/new-account", Nonce = response.Headers.ReplayNonce, Algorithm = AlgorithmsEnum.RS256, Key = new JsonWebKey(accountKey), }); token.Sign(accountKey); response = controller.CreateAccount(new AcmeRequest { Path = $"{Application.BaseAddress}new-acct", Method = "POST", Token = token, }); Assert.Equal(400, response.StatusCode); var content = response.GetContent <Protocol.Error>(); Assert.Equal(Protocol.ErrorType.Malformed, content.Type); Assert.NotNull(content.Detail); }
/// <summary> /// Orders certificate. /// </summary> /// <param name="AccountLocation">Account resource location.</param> /// <param name="Identifiers">Identifiers to include in the certificate.</param> /// <param name="NotBefore">If provided, certificate is not valid before this point in time.</param> /// <param name="NotAfter">If provided, certificate is not valid after this point in time.</param> /// <returns>ACME order object.</returns> public async Task <AcmeOrder> OrderCertificate(Uri AccountLocation, AcmeIdentifier[] Identifiers, DateTime?NotBefore, DateTime?NotAfter) { if (this.directory == null) { await this.GetDirectory(); } int i, c = Identifiers.Length; IEnumerable <KeyValuePair <string, object> >[] Identifiers2 = new IEnumerable <KeyValuePair <string, object> > [c]; for (i = 0; i < c; i++) { Identifiers2[i] = new KeyValuePair <string, object>[] { new KeyValuePair <string, object>("type", Identifiers[i].Type), new KeyValuePair <string, object>("value", Identifiers[i].Value) }; } List <KeyValuePair <string, object> > Payload = new List <KeyValuePair <string, object> >() { new KeyValuePair <string, object>("identifiers", Identifiers2) }; if (NotBefore.HasValue) { Payload.Add(new KeyValuePair <string, object>("notBefore", NotBefore.Value)); } if (NotAfter.HasValue) { Payload.Add(new KeyValuePair <string, object>("notAfter", NotAfter.Value)); } AcmeResponse Response = await this.POST(this.directory.NewOrder, AccountLocation, Payload.ToArray()); return(new AcmeOrder(this, AccountLocation, Response.Location, Response.Payload, Response.ResponseMessage)); }
protected HttpResponseMessage CreateHttpResponseMessage(AcmeResponse response) { HttpResponseMessage result; if (response.Content != null) { if (response.Content is MediaTypeContent content) { result = Request.CreateResponse((HttpStatusCode)response.StatusCode); var streamContent = new StreamContent(content.Content); streamContent.Headers.Add("Content-Type", content.Type); result.Content = streamContent; } else { result = Request.CreateResponse((HttpStatusCode)response.StatusCode); result.Content = new StringContent( JsonConvert.SerializeObject(response.Content), Encoding.UTF8, response.Content is Error ? "application/problem+json" : "application/json"); } } else { result = Request.CreateResponse(response.StatusCode); } #region Add headers foreach (var header in response.Headers.AllKeys) { result.Headers.Add(header, response.Headers.Get(header)); } #endregion return(result); }
public void POST_Nonce_WrongEncoding() { AcmeResponse response = null; using var provider = Application.CreateProvider(); IAcmeController controller = (IAcmeController)provider.GetService(typeof(IAcmeController)); var accountKey = RSA.Create(2048); var token = new JsonWebSignature(); token.SetProtected(new JsonWebSignatureProtected { Url = $"{Application.BaseAddress}new-acct", Algorithm = AlgorithmsEnum.RS256, Key = new JsonWebKey(accountKey), Nonce = "Wrong encoded nonce" }); token.Sign(accountKey); response = controller.CreateAccount(new AcmeRequest { Path = $"{Application.BaseAddress}new-acct", Method = "POST", Token = token, }); // If the value of a "nonce" header parameter is not valid // according to this encoding, then the verifier MUST reject the JWS as // malformed. Assert.Equal(400, response.StatusCode); var content = response.GetContent <Protocol.Error>(); Assert.Equal(Protocol.ErrorType.Malformed, content.Type); Assert.NotNull(content.Detail); }
/// <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(); } }
internal async Task <AcmeResponse> POST(Uri URL, Uri KeyID, params KeyValuePair <string, object>[] Payload) { string HeaderString; string PayloadString; string Signature; if (KeyID == null) { this.jws.Sign(new KeyValuePair <string, object>[] { new KeyValuePair <string, object>("nonce", await this.NextNonce()), new KeyValuePair <string, object>("url", URL.ToString()) }, Payload, out HeaderString, out PayloadString, out Signature); } else { this.jws.Sign(new KeyValuePair <string, object>[] { new KeyValuePair <string, object>("kid", KeyID.ToString()), new KeyValuePair <string, object>("nonce", await this.NextNonce()), new KeyValuePair <string, object>("url", URL.ToString()) }, Payload, out HeaderString, out PayloadString, out Signature); } string Json = JSON.Encode(new KeyValuePair <string, object>[] { new KeyValuePair <string, object>("protected", HeaderString), new KeyValuePair <string, object>("payload", PayloadString), new KeyValuePair <string, object>("signature", Signature) }, null); HttpContent Content = new ByteArrayContent(System.Text.Encoding.ASCII.GetBytes(Json)); Content.Headers.Add("Content-Type", JwsAlgorithm.JwsContentType); HttpResponseMessage Response = await this.httpClient.PostAsync(URL, Content); this.GetNextNonce(Response); Stream Stream = await Response.Content.ReadAsStreamAsync(); byte[] Bin = await Response.Content.ReadAsByteArrayAsync(); string CharSet = Response.Content.Headers.ContentType?.CharSet; Encoding Encoding; if (string.IsNullOrEmpty(CharSet)) { Encoding = Encoding.UTF8; } else { Encoding = System.Text.Encoding.GetEncoding(CharSet); } AcmeResponse AcmeResponse = new AcmeResponse() { Json = Encoding.GetString(Bin), Location = URL, ResponseMessage = Response, Payload = null }; if (Response.Headers.TryGetValues("Location", out IEnumerable <string> Values)) { foreach (string s in Values) { AcmeResponse.Location = new Uri(s); break; } } if (string.IsNullOrEmpty(AcmeResponse.Json)) { AcmeResponse.Payload = null; } else if ((AcmeResponse.Payload = JSON.Parse(AcmeResponse.Json) as IEnumerable <KeyValuePair <string, object> >) == null) { throw new Exception("Unexpected response returned."); } if (Response.IsSuccessStatusCode) { return(AcmeResponse); } else { throw CreateException(AcmeResponse.Payload, Response); } }
public void Account_ChangeKey_DuplicateKey() { AcmeResponse response = null; using var provider = Application.CreateProvider(); IAcmeController controller = (IAcmeController)provider.GetService(typeof(IAcmeController)); // Get nonce response = controller.GetNonce(new AcmeRequest { Path = $"{Application.BaseAddress}new-nonce", Method = "HEAD", }); // Create token var accountKey = RSA.Create(2048); var token = new JsonWebSignature(); token.SetProtected(new JsonWebSignatureProtected { Url = $"{Application.BaseAddress}new-acct", Algorithm = AlgorithmsEnum.RS256, Key = new JsonWebKey(accountKey), Nonce = response.Headers.ReplayNonce, }); token.SetPayload(new NewAccount { Contacts = new string[] { "mailto:[email protected]" }, }); token.Sign(accountKey); // Create account response = controller.CreateAccount(new AcmeRequest { Path = $"{Application.BaseAddress}new-acct", Method = "POST", Token = token, }); Assert.Equal(201, response.StatusCode); // Create token var duplicateKey = RSA.Create(2048); token = new JsonWebSignature(); token.SetProtected(new JsonWebSignatureProtected { Url = $"{Application.BaseAddress}new-acct", Algorithm = AlgorithmsEnum.RS256, Key = new JsonWebKey(duplicateKey), Nonce = response.Headers.ReplayNonce, }); token.SetPayload(new NewAccount { Contacts = new string[] { "mailto:[email protected]" }, }); token.Sign(duplicateKey); // Create account response = controller.CreateAccount(new AcmeRequest { Path = $"{Application.BaseAddress}new-acct", Method = "POST", Token = token, }); Assert.Equal(201, response.StatusCode); token = new JsonWebSignature(); token.SetProtected(new JsonWebSignatureProtected { Url = $"{Application.BaseAddress}key-change", Algorithm = AlgorithmsEnum.RS256, KeyID = $"{Application.BaseAddress}acct/1", Nonce = response.Headers.ReplayNonce, }); #region New key var newKeyToken = new JsonWebSignature(); newKeyToken.SetProtected(new JsonWebSignatureProtected { Url = $"{Application.BaseAddress}key-change", Algorithm = AlgorithmsEnum.RS256, Key = new JsonWebKey(duplicateKey), }); newKeyToken.SetPayload(new ChangeKey { Account = $"{Application.BaseAddress}acct/1", Key = new JsonWebKey(accountKey), }); newKeyToken.Sign(duplicateKey); #endregion token.SetPayload(newKeyToken); token.Sign(accountKey); // Update account response = controller.ChangeKey(new AcmeRequest { Path = $"{Application.BaseAddress}key-change", Method = "POST", Token = token, }); Assert.Equal(409, response.StatusCode); Assert.Equal($"{Application.BaseAddress}acct/2", response.Headers.Location); var content = response.GetContent <Protocol.Error>(); Assert.Equal(Protocol.ErrorType.Malformed, content.Type); Assert.NotNull(content.Detail); }
/// <summary> /// Acknowledges a challenge from the server. /// </summary> /// <param name="AccountLocation">Account location.</param> /// <param name="ChallengeLocation">Challenge location.</param> /// <returns>Acknowledged challenge object.</returns> public async Task <AcmeChallenge> AcknowledgeChallenge(Uri AccountLocation, Uri ChallengeLocation) { AcmeResponse Response = await this.POST(ChallengeLocation, AccountLocation); return(this.CreateChallenge(AccountLocation, Response.Payload)); }
/// <summary> /// Gets the state of an authorization. /// </summary> /// <param name="AccountLocation">URI of account.</param> /// <param name="AuthorizationLocation">URI of authorization.</param> /// <returns>ACME authorization object.</returns> public async Task <AcmeAuthorization> GetAuthorization(Uri AccountLocation, Uri AuthorizationLocation) { AcmeResponse Response = await this.GET(AuthorizationLocation); return(new AcmeAuthorization(this, AccountLocation, AuthorizationLocation, Response.Payload)); }
/// <summary> /// Gets the list of current orders for an account. /// </summary> /// <param name="AccountLocation">URI of account.</param> /// <param name="OrdersLocation">URI of orders.</param> /// <returns>ACME order object.</returns> public async Task <AcmeOrder[]> GetOrders(Uri AccountLocation, Uri OrdersLocation) { AcmeResponse Response = await this.GET(OrdersLocation); return(null); }
/// <summary> /// Gets the state of an order. /// </summary> /// <param name="AccountLocation">URI of account.</param> /// <param name="OrderLocation">URI of order.</param> /// <returns>ACME order object.</returns> public async Task <AcmeOrder> GetOrder(Uri AccountLocation, Uri OrderLocation) { AcmeResponse Response = await this.GET(OrderLocation); return(new AcmeOrder(this, AccountLocation, OrderLocation, Response.Payload, Response.ResponseMessage)); }
/// <summary> /// Gets the list of current orders for an account. /// </summary> /// <param name="AccountLocation">URI of account.</param> /// <param name="OrdersLocation">URI of orders.</param> /// <returns>ACME order object.</returns> public async Task <AcmeOrder[]> GetOrders(Uri AccountLocation, Uri OrdersLocation) { AcmeResponse _ = await this.GET(OrdersLocation); throw new NotImplementedException("Method not implemented."); }