namespace PrivaPub.Federation.Signing { // What signed a request: an RFC 9421 message signature when it carries Signature-Input, else a draft-cavage Signature; // the inbox and signed fetches check either the same way. public sealed class RequestSignature { readonly SignatureParameters _cavage; readonly MessageSignature _message; RequestSignature(SignatureParameters cavage, MessageSignature message) { _cavage = cavage; _message = message; } public string KeyId => _message?.KeyId ?? _cavage.KeyId; public string Algorithm => _message != default ? _message.Algorithm ?? "rsa-v1_5-sha256" : _cavage.Algorithm; // how the ledger names it: "cavage:rsa-sha256", "rfc9421:rsa-v1_5-sha256" public string Scheme => _message != default ? "rfc9421:" + Algorithm : "cavage:" + Algorithm; public string[] Covered => _message?.Components ?? _cavage.Headers; // the request's signature, or null when it has none it can read public static RequestSignature Of(HttpRequest request) { if (MessageSignatures.Present(request)) { var message = MessageSignatures.Parse(request.Headers["Signature-Input"].ToString(), request.Headers["Signature"].ToString()); return message == default ? default : new RequestSignature(default, message); } var cavage = HttpSignatures.Parse(request.Headers["Signature"].ToString()); return cavage == default ? default : new RequestSignature(cavage, default); } // what is wrong with the request as signed (unsigned target or digest, a stale date...), or null public string Problem(HttpRequest request, byte[] body) => _message != default ? MessageSignatures.CheckRequest(request, _message, body) : HttpSignatures.CheckRequest(request, _cavage, body); // the string the signature is over: the signing string, or RFC 9421's signature base against our public address public string Signed(HttpRequest request, string baseAddress) => _message != default ? MessageSignatures.Base(request, _message, baseAddress) : HttpSignatures.SigningString(request, _cavage); public bool VerifiedBy(string publicKeyPem, string signed) => _message != default ? MessageSignatures.Verify(publicKeyPem, _message, signed) : HttpSignatures.Verify(publicKeyPem, signed, _cavage.Signature, _cavage.Algorithm); } }