mirror of
https://github.com/bookwyrm-social/bookwyrm.git
synced 2024-11-26 11:31:08 +00:00
Use correct keyId with legacy fallback
Bookwyrm keyIds are at `userpath/#main-key`, however when signing AP objects we have claimed in the headers that the keyId is at `userpath#main-key`. This is incorrect, and makes GoToSocial's strict checking break. Simply updating the signatures to use the correct KeyId breaks legacy Bookwyrm's signature checks, becuase it assumes that the keyId path is the same as the user path plus a fragment. This commit allows for either option, by sending the request a second time with the incorrect keyId if sending with the correct one causes an error.
This commit is contained in:
parent
c9dcd4f7ad
commit
03f21b0f35
3 changed files with 18 additions and 4 deletions
|
@ -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)
|
||||
|
|
|
@ -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"),
|
||||
|
|
|
@ -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)
|
||||
|
|
Loading…
Reference in a new issue