diff --git a/bookwyrm/models/activitypub_mixin.py b/bookwyrm/models/activitypub_mixin.py index 83ca90b0a..83a7dd998 100644 --- a/bookwyrm/models/activitypub_mixin.py +++ b/bookwyrm/models/activitypub_mixin.py @@ -540,10 +540,11 @@ async def sign_and_send( digest = make_digest(data) + headers = { "Date": now, "Digest": digest, - "Signature": make_signature("post", sender, destination, now, digest), + "Signature": make_signature("post", sender, destination, now, digest, False), "Content-Type": "application/activity+json; charset=utf-8", "User-Agent": USER_AGENT, } @@ -554,6 +555,16 @@ async def sign_and_send( logger.exception( "Failed to send broadcast to %s: %s", destination, response.reason ) + logger.info("Trying again with legacy keyId") + # try with incorrect keyId to enable communication with legacy Bookwyrm servers + legacy_signature = make_signature("post", sender, destination, now, digest, True) + headers["Signature"] = legacy_signature + async with session.post(destination, data=data, headers=headers) as response: + if not response.ok: + logger.exception( + "Failed to send broadcast with legacy keyId to %s: %s", destination, response.reason + ) + return response except asyncio.TimeoutError: logger.info("Connection timed out for url: %s", destination) diff --git a/bookwyrm/signatures.py b/bookwyrm/signatures.py index 3dfde4cb1..2a1f2e72a 100644 --- a/bookwyrm/signatures.py +++ b/bookwyrm/signatures.py @@ -22,7 +22,7 @@ def create_key_pair(): return private_key, public_key -def make_signature(method, sender, destination, date, digest=None): +def make_signature(method, sender, destination, date, digest=None, use_legacy_key=False): """uses a private key to sign an outgoing message""" inbox_parts = urlparse(destination) signature_headers = [ @@ -38,8 +38,10 @@ def make_signature(method, sender, destination, date, digest=None): message_to_sign = "\n".join(signature_headers) signer = pkcs1_15.new(RSA.import_key(sender.key_pair.private_key)) signed_message = signer.sign(SHA256.new(message_to_sign.encode("utf8"))) + # For legacy reasons we need to use an incorrect keyId for older Bookwyrm versions + key_id = f"{sender.remote_id}#main-key" if use_legacy_key else f"{sender.remote_id}/#main-key" signature = { - "keyId": f"{sender.remote_id}/#main-key", + "keyId": key_id, "algorithm": "rsa-sha256", "headers": headers, "signature": b64encode(signed_message).decode("utf8"), diff --git a/bookwyrm/views/inbox.py b/bookwyrm/views/inbox.py index da32ebdb0..9eef6792f 100644 --- a/bookwyrm/views/inbox.py +++ b/bookwyrm/views/inbox.py @@ -137,7 +137,8 @@ def has_valid_signature(request, activity): return False if signature.key_id != remote_user.key_pair.remote_id: - raise ValueError("Wrong actor created signature.") + if signature.key_id != f"{remote_user.remote_id}#main-key": # legacy Bookwyrm + raise ValueError("Wrong actor created signature.") try: signature.verify(remote_user.key_pair.public_key, request)