Support signature-validation of deleted actors

… and also signal a condition if fetching the
public key fails, otherwise!
This commit is contained in:
Jaidyn Ann 2025-01-14 22:40:43 -06:00
parent 1ae93b333b
commit aa982ead3d
Signed by: jadedctrl
GPG Key ID: FEF4FCF78B4BF019

View File

@ -174,9 +174,28 @@ https://swicg.github.io/activitypub-http-signature/"
(gethash "https://w3id.org/security#publicKeyPem" (signature-key signature-alist)) (gethash "https://w3id.org/security#publicKeyPem" (signature-key signature-alist))
signed-str signed-str
(cdr (assoc :signature signature-alist)))) (cdr (assoc :signature signature-alist))))
;; The special case of an actor being deleted, and so their key inaccessible.
;; https://swicg.github.io/activitypub-http-signature/#handling-deletes-of-actors
(fetch-error (err)
(or (deleting-object-p)
(signal 'invalid-signature-failed-fetch)))
;; The very normal case of the signature simply being invalid! :P
(invalid-signature (err) (invalid-signature (err)
(values nil err)))) (values nil err))))
(defun deleting-object-p (activity)
"Whether or not ACTIVITY is a DELETE and the OBJECT of the ACTIVITY purportedly,
what would be deleted is actually deleted. Fetching the object must, in which
case, return a 404 or a 410 HTTP error."
(when (typep activity 'as/v/a:delete)
(handler-case
(progn (as/u:http-get (as/v/a:object activity))
nil)
(as/u:http-get-error (err)
(let ((status (slot-value err 'as/u:status)))
(member status '(404 410)))))))
(defun matching-domains-p (signature-alist activity) (defun matching-domains-p (signature-alist activity)
"Returns whether or not the domain names within an ACTIVITY match, for ensuring "Returns whether or not the domain names within an ACTIVITY match, for ensuring
its signature is applicable: Those of the signature keys, the actors @ID, its signature is applicable: Those of the signature keys, the actors @ID,
@ -304,6 +323,12 @@ https://swicg.github.io/activitypub-http-signature/#how-to-obtain-a-signature-s-
Check the ID domain-names of the actor, the activity, and the signature-key.~&"))) Check the ID domain-names of the actor, the activity, and the signature-key.~&")))
(:documentation "Thrown during HTTP signature-validation, when it's noticed that domains-names for ID URIs don't match.")) (:documentation "Thrown during HTTP signature-validation, when it's noticed that domains-names for ID URIs don't match."))
(define-condition invalid-signature-failed-fetch (invalid-signature)
()
(:report (lambda (condition stream) (declare (ignore condition))
(format stream "We were unable to fetch the signatures public key. Either the server is napping, or the given keys address is a lie. We are agnostic.")))
(:documentation "Thrown during HTTP signature-validation, when the signatures public key couldnt be downloaded; and we have no cached version of it, either. And so, it is currently impossible to validate/invalidate the signature. We are agnostic."))
;;; Fetching public keys ;;; Fetching public keys