Rework API + verify metadata #2
Loading…
Add table
Add a link
Reference in a new issue
No description provided.
Delete branch "Oneric/http_signatures:api_rework"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
This patchset reworks the API into a clean basis suitable to expand on, with optional communication between API user and adapter, without leaking any internal details and adds new functionality. It will enable improvements to Akkoma.
The current API is an utter mess and by necessity leaks internal details and forces adapter implementations to reparse signature headers just to figure out which key they should actually look up. At the same time, current API does not allow passing any metadata between the caller of
verify/signatureand the adapter in neither direction. This however is important for akkoma to be able to e.g. exit early if:Furthermore the way pseudo headers are handled atm is very awkward, requiring explicit code for each pseudo header in both the lib and the API user! For example
(opaque)is apparently sometimes used, but has no explicit code yet and would thus always fail verification.Instead the new version now can handle any pseudo header during verification and explicit code only in the library is only needed to implement additional side-effects the pseudo header asks for, like e.g. checking a sender-determined expiry time (in addition to receiver-side signature age limits)
Speaking of expiry and time limits, so far the library never verified signature age or expiry, happily accepting a 100 year old signature even if it was explicitly marked as expiring 99 years ago. Now this is actually verified. Limits are configurable, by default max 2h old and a 40min clock skew leniency for future timestamps and expiry deadlines (since the latter might be affected by clock skew).
To avoid accepting vulnerable signatures and creating such ourselves, the presence of a minimal set of headers is now verified by the library.
Finally request-target aliases are now handled in the library which enables us to avoid attempting to refetch the key after each failed alias. Now a key is refetched at most once for one request, if and only if all request-target aliases failed to verify with the original key. Also alias can be lazily evaluated, allowing us to entirely skip database queries when objects are fetched by their canonical ID (the empirically most common case)
Further details in each commit. As usual this is best reviewed commit by commit.
2adf4c0214to9887ea6249i've glanced over it but will likely need some more time to look in depth
ezpz comment attached
@ -2,3 +2,3 @@# SPDX-License-Identifier: LGPL-3.0-onlyimage: elixir:1.7image: elixir:1.13you can probably drop this commit entirely (and remove the ci config file) since we don't use it
oh right it’s GitLab specific ;^^
now deleted
9887ea6249toc98a4df78bthing i noticed re: skew
@ -10,0 +9,4 @@config :http_signatures,adapter: HTTPSignatures.TestAdapter,# 20 years in seconds; to not just test our own signatures# the test suite contains signatures from other real-world implementationstypo typo implementations
potentially stupid question: what’s the typo?
If it’s about the plural
s, so far I’ve usually seen implementation used as a countable word when referring to distinct software projects following a common speci may be stupid
@ -97,0 +197,4 @@defp check_expiry(now, %{"(expires)" => expires_unix_seconds}) dowith {:ok, expires} <- unixstr_to_time(expires_unix_seconds),true <- DateTime.diff(expires, now) > -@max_clock_skew doyou probably could (and likelly should?) use
abshere to avoid the negative constant thing going on - this only allows one-way clock skewabs(DateTime.diff(expires, now)) < @max_clock_skewwould probably be okwon’t this end up rejecting signature whose expiry date is set further into the future than
now + max_clock_skew; i.e. rejecting signatures marked as still valid?@ -97,0 +210,4 @@defp check_created(now, %{"(created)" => created_unix_seconds}) dowith {:ok, created} <- unixstr_to_time(created_unix_seconds),diff <- DateTime.diff(now, created),{_, false} <- {:future, diff < -@max_clock_skew},same dealio here
clock skew should only limit dates set into the future; max_sig_age already restricts past dates. The latter has by default a higher leniency than future dates. If this was using
absboth future and past timestamps will be limited bymax_clock_skewandmax_sig_agewill be useless.