Heyo all! I’ve been working on an activitypub server for a while now, and while it’s still not yet complete, recently I’ve reached a point where I realised that I’ve actually been sitting on some libraries that the community might benefit from, as the current ecosystem doesn’t seem to handle these things.
One such component that seemed to be in a state that was suitable to split off from was a small helper module to implement a particular http signature scheme that seems to be rather common in the activitypub scene.
In particular, the scheme I’m referring to is defined here: draft-cavage-http-signatures-12
Signing HTTP Messages
draft-cavage-http-signatures-12
Abstract
When communicating over the Internet using the HTTP protocol, it can
be desirable for a server or client to authenticate the sender of a
particular message. It can also be desirable to ensure that the
message was not tampered with during transit. This document
describes a way for servers and clients to simultaneously add
authentication and message integrity to HTTP messages by using a
digital signature.
I’ve written a small library that glues together some components in the OCaml ecosystem to somewhat handle the signing (I have been mainly working off an “implement-enough-to-make-the-system-work” process rather than directly transcribing the specification above):
(** [verify ~signed_string ~signature key] returns true iff
[signature] over [signed_string] is valid according to [key]. *)
val verify: signed_string:string -> signature:string -> X509.Public_key.t -> bool
(** [verify_request ~resolve_public_key req] verifies that a dream
request has been signed according to the HTTP signature scheme *)
val verify_request:
resolve_public_key:(string -> (X509.Public_key.t, 'a) Lwt_result.t) ->
Dream.request -> (bool, 'a) result Lwt.t
(** [build_signed_headers ~priv_key ~key_id ~headers ~body_str
~current_time ~method_ ~uri] returns a list of signed headers using
[priv_key] according to the HTTP signature scheme. [key_id] should
be a string that can be used to look up the public key associated
with [priv_key]. *)
val build_signed_headers:
priv_key:X509.Private_key.t ->
key_id:string ->
headers:string StringMap.t ->
body_str:string ->
current_time:Ptime.t -> method_:string -> uri:Uri.t -> (string * string) list
The library is currently published at GitHub - Gopiandcode/http_sig_ocaml: HTTP Signatures for OCaml under the LGPL, but I haven’t released it on opam.
Anyway, I was wondering if anyone else had interest in this kind of package, and whether it would be a good candidate for submission to opam - or if there are actually already existing libraries in the OCaml ecosystem that would actually already do this.