hs2019 signatures hashed with SHA-512, and SHA-512 digests
A draft-cavage hs2019 signature leaves the hash to the key: with an RSA key it is tried with SHA-256, as nearly everyone signs, then with SHA-512, as some do; rsa-sha256 stays SHA-256 only. A Digest of SHA-512= is checked as SHA-256= is. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01LsXgEaXee4GCU1hwYgPJXw
This commit is contained in:
1 parent
0310bbe0f9
commit
e708f1ad2e
5 files changed
+39
-7
No files matched your search
@@ -101,6 +101,33 @@ namespace PrivaPub.Tests.Federation
|
||||
Assert.Equal("the signature has expired",
|
||||
Check(MastodonRequest(extra: $",expires=\"{Now.AddMinutes(-20).ToUnixTimeSeconds()}\"")));
|
||||
|
||||
// hs2019 leaves the hash to the key: some sign RSA with SHA-512, which rsa-sha256 does not allow; and a SHA-512 digest
|
||||
[Fact]
|
||||
public void Accepts_hs2019_hashed_with_sha512_and_a_sha512_digest()
|
||||
{
|
||||
var context = new DefaultHttpContext();
|
||||
context.Request.Method = "POST";
|
||||
context.Request.Host = new HostString(Host);
|
||||
context.Request.Path = "/peasants/bob/mouth";
|
||||
context.Features.Get<IHttpRequestFeature>().RawTarget = "/peasants/bob/mouth";
|
||||
var date = Now.ToString("r", CultureInfo.InvariantCulture);
|
||||
var digest = "SHA-512=" + Convert.ToBase64String(SHA512.HashData(Body));
|
||||
context.Request.Headers["Date"] = date;
|
||||
context.Request.Headers["Digest"] = digest;
|
||||
var signingString = $"(request-target): post /peasants/bob/mouth\nhost: {Host}\ndate: {date}\ndigest: {digest}";
|
||||
var signature = Convert.ToBase64String(_key.SignData(Encoding.UTF8.GetBytes(signingString), HashAlgorithmName.SHA512, RSASignaturePadding.Pkcs1));
|
||||
string Signed(string algorithm) => $"keyId=\"{KeyId}\",algorithm=\"{algorithm}\",headers=\"(request-target) host date digest\",signature=\"{signature}\"";
|
||||
|
||||
context.Request.Headers["Signature"] = Signed("hs2019");
|
||||
var parameters = HttpSignatures.Parse(context.Request.Headers["Signature"].ToString());
|
||||
Assert.Null(HttpSignatures.CheckRequest(context.Request, parameters, Body, Now));
|
||||
Assert.True(HttpSignatures.Verify(PublicKey, HttpSignatures.SigningString(context.Request, parameters), parameters.Signature, parameters.Algorithm));
|
||||
|
||||
context.Request.Headers["Signature"] = Signed("rsa-sha256");
|
||||
parameters = HttpSignatures.Parse(context.Request.Headers["Signature"].ToString());
|
||||
Assert.False(HttpSignatures.Verify(PublicKey, HttpSignatures.SigningString(context.Request, parameters), parameters.Signature, parameters.Algorithm));
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Signs_with_the_raw_request_target()
|
||||
{
|
||||
|
||||
Reference in new issue
Block a user