private async Task <T> ParsePayload <T>(HttpRequestMessage message) { var content = message.Content; Assert.Equal(JsonContentType, content.Headers.ContentType.MediaType); var json = await content.ReadAsStringAsync(); dynamic body = JObject.Parse(json); Assert.Equal("RS256", body.header?.alg?.Value); Assert.Equal("AQAB", body.header?.jwk?.e?.Value); Assert.Equal("RSA", body.header?.jwk?.kty?.Value); Assert.Equal("maeT6EsXTVHAdwuq3IlAl9uljXE5CnkRpr6uSw_Fk9nQshfZqKFdeZHkSBvIaLirE2ZidMEYy-rpS1O2j-viTG5U6bUSWo8aoeKoXwYfwbXNboEA-P4HgGCjD22XaXAkBHdhgyZ0UBX2z-jCx1smd7nucsi4h4RhC_2cEB1x_mE6XS5VlpvG91Hbcgml4cl0NZrWPtJ4DhFdPNUtQ8q3AYXkOr_OSFZgRKjesRaqfnSdJNABqlO_jEzAx0fgJfPZe1WlRWOfGRVBVopZ4_N5HpR_9lsNDzCZyidFsHwzvpkP6R6HbS8CMrNWgtkTbnz27EVqIhkYdiPVIN2Xkwj0BQ", body.header?.jwk?.n?.Value); var protectedBase64 = body.GetValue("protected").Value; var protectedJson = Encoding.UTF8.GetString(JwsConvert.FromBase64String(protectedBase64)); dynamic @protected = JObject.Parse(protectedJson); Assert.Equal(string.Format(NonceFormat, this.nonce), @protected.nonce?.Value); var payloadBase64 = body.GetValue("payload").Value; var payloadJson = Encoding.UTF8.GetString(JwsConvert.FromBase64String(payloadBase64)); var signature = $"{protectedBase64}.{payloadBase64}"; var signatureBytes = Encoding.ASCII.GetBytes(signature); var signedSignatureBytes = accountKey.SignData(signatureBytes); var signedSignatureEncoded = JwsConvert.ToBase64String(signedSignatureBytes); Assert.Equal(signedSignatureEncoded, body.GetValue("signature").Value); return(JsonConvert.DeserializeObject <T>(payloadJson, JsonUtil.CreateSettings())); }
private async Task <T> ParsePayload <T>(HttpRequestMessage message) { var accountKey = await Helper.LoadkeyV1(); var content = message.Content; Assert.Equal(JsonContentType, content.Headers.ContentType.MediaType); var json = await content.ReadAsStringAsync(); dynamic body = JObject.Parse(json); var protectedBase64 = body.GetValue("protected").Value; var protectedJson = Encoding.UTF8.GetString(JwsConvert.FromBase64String(protectedBase64)); dynamic @protected = JObject.Parse(protectedJson); Assert.Equal(string.Format(NonceFormat, this.nonce), @protected.nonce?.Value); var payloadBase64 = body.GetValue("payload").Value; var payloadJson = Encoding.UTF8.GetString(JwsConvert.FromBase64String(payloadBase64)); var signature = $"{protectedBase64}.{payloadBase64}"; var signatureBytes = Encoding.UTF8.GetBytes(signature); var signedSignatureBytes = accountKey.SignData(signatureBytes); var signedSignatureEncoded = JwsConvert.ToBase64String(signedSignatureBytes); Assert.Equal(signedSignatureEncoded, body.GetValue("signature").Value); return(JsonConvert.DeserializeObject <T>(payloadJson, JsonUtil.CreateSettings())); }
/// <summary> /// Post to the new account endpoint. /// </summary> /// <param name="context">The ACME context.</param> /// <param name="body">The payload.</param> /// <param name="ensureSuccessStatusCode">if set to <c>true</c>, throw exception if the request failed.</param> /// <param name="eabKeyId">Optional key identifier, if using external account binding.</param> /// <param name="eabKey">Optional EAB key, if using external account binding.</param> /// <param name="eabKeyAlg">Optional EAB key algorithm, if using external account binding, defaults to HS256 if not specified</param> /// <returns>The ACME response.</returns> internal static async Task <AcmeHttpResponse <Account> > NewAccount( IAcmeContext context, Account body, bool ensureSuccessStatusCode, string eabKeyId = null, string eabKey = null, string eabKeyAlg = null) { var endpoint = await context.GetResourceUri(d => d.NewAccount); var jws = new JwsSigner(context.AccountKey); if (eabKeyId != null && eabKey != null) { var header = new { alg = eabKeyAlg?.ToUpper() ?? "HS256", kid = eabKeyId, url = endpoint }; var headerJson = Newtonsoft.Json.JsonConvert.SerializeObject(header, Newtonsoft.Json.Formatting.None, JsonUtil.CreateSettings()); var protectedHeaderBase64 = JwsConvert.ToBase64String(System.Text.Encoding.UTF8.GetBytes(headerJson)); var accountKeyBase64 = JwsConvert.ToBase64String( System.Text.Encoding.UTF8.GetBytes( Newtonsoft.Json.JsonConvert.SerializeObject(context.AccountKey.JsonWebKey, Newtonsoft.Json.Formatting.None) ) ); var signingBytes = System.Text.Encoding.ASCII.GetBytes($"{protectedHeaderBase64}.{accountKeyBase64}"); // eab signature is the hash of the header and account key, using the eab key byte[] signatureHash; switch (header.alg) { case "HS512": using (var hs512 = new HMACSHA512(JwsConvert.FromBase64String(eabKey))) signatureHash = hs512.ComputeHash(signingBytes); break; case "HS384": using (var hs384 = new HMACSHA384(JwsConvert.FromBase64String(eabKey))) signatureHash = hs384.ComputeHash(signingBytes); break; default: using (var hs256 = new HMACSHA256(JwsConvert.FromBase64String(eabKey))) signatureHash = hs256.ComputeHash(signingBytes); break; } var signatureBase64 = JwsConvert.ToBase64String(signatureHash); body.ExternalAccountBinding = new { Protected = protectedHeaderBase64, Payload = accountKeyBase64, Signature = signatureBase64 }; } return(await context.HttpClient.Post <Account>(jws, endpoint, body, ensureSuccessStatusCode)); }