comparison sat/plugins/plugin_comp_ap_gateway/__init__.py @ 3883:6da749bbf320

component AP gateway: fix headers case in signature: headers where not lower-cased in `headers` field of signature data, resulting in signature being rejected by Pleroma (but it was working with Mastodon). Also add `Content-Type` header. rel 371
author Goffi <goffi@goffi.org>
date Wed, 31 Aug 2022 17:07:03 +0200
parents 2e4a0f6050bd
children aa7197b67c26
comparison
equal deleted inserted replaced
3882:1bd44367337d 3883:6da749bbf320
931 # we have to use PKCS1v15 padding to be compatible with Mastodon 931 # we have to use PKCS1v15 padding to be compatible with Mastodon
932 padding.PKCS1v15(), # type: ignore 932 padding.PKCS1v15(), # type: ignore
933 hashes.SHA256() # type: ignore 933 hashes.SHA256() # type: ignore
934 ) 934 )
935 except InvalidSignature: 935 except InvalidSignature:
936 raise exceptions.EncryptionError("Invalid signature (using PKC0S1 v1.5 and SHA-256)") 936 raise exceptions.EncryptionError(
937 "Invalid signature (using PKC0S1 v1.5 and SHA-256)"
938 )
937 939
938 return actor_id 940 return actor_id
939 941
940 def getSignatureData( 942 def getSignatureData(
941 self, 943 self,
953 955
954 @return: headers and signature data 956 @return: headers and signature data
955 ``headers`` is an updated copy of ``headers`` arguments, with pseudo-headers 957 ``headers`` is an updated copy of ``headers`` arguments, with pseudo-headers
956 removed, and ``Signature`` added. 958 removed, and ``Signature`` added.
957 """ 959 """
958 to_sign = "\n".join(f"{k.lower()}: {v}" for k,v in headers.items()) 960 # headers must be lower case
961 l_headers: Dict[str, str] = {k.lower(): v for k, v in headers.items()}
962 to_sign = "\n".join(f"{k}: {v}" for k,v in l_headers.items())
959 signature = base64.b64encode(self.private_key.sign( 963 signature = base64.b64encode(self.private_key.sign(
960 to_sign.encode(), 964 to_sign.encode(),
961 # we have to use PKCS1v15 padding to be compatible with Mastodon 965 # we have to use PKCS1v15 padding to be compatible with Mastodon
962 padding.PKCS1v15(), # type: ignore 966 padding.PKCS1v15(), # type: ignore
963 hashes.SHA256() # type: ignore 967 hashes.SHA256() # type: ignore
964 )).decode() 968 )).decode()
965 sign_data = { 969 sign_data = {
966 "keyId": key_id, 970 "keyId": key_id,
967 "Algorithm": "rsa-sha256", 971 "Algorithm": "rsa-sha256",
968 "headers": " ".join(headers.keys()), 972 "headers": " ".join(l_headers.keys()),
969 "signature": signature 973 "signature": signature
970 } 974 }
971 new_headers = {k: v for k,v in headers.items() if not k.startswith("(")} 975 new_headers = {k: v for k,v in headers.items() if not k.startswith("(")}
972 new_headers["Signature"] = self.buildSignatureHeader(sign_data) 976 new_headers["Signature"] = self.buildSignatureHeader(sign_data)
973 return new_headers, sign_data 977 return new_headers, sign_data
1024 url_actor, ap_item = await self.apDeleteItem( 1028 url_actor, ap_item = await self.apDeleteItem(
1025 client.jid, node, item["id"] 1029 client.jid, node, item["id"]
1026 ) 1030 )
1027 else: 1031 else:
1028 raise exceptions.InternalError(f"unexpected element: {item.toXml()}") 1032 raise exceptions.InternalError(f"unexpected element: {item.toXml()}")
1029 resp = await self.signAndPost(inbox, url_actor, ap_item) 1033 await self.signAndPost(inbox, url_actor, ap_item)
1030 1034
1031 async def convertAndPostAttachments( 1035 async def convertAndPostAttachments(
1032 self, 1036 self,
1033 client: SatXMPPEntity, 1037 client: SatXMPPEntity,
1034 ap_account: str, 1038 ap_account: str,
1180 "(request-target)": f"post {p_url.path}", 1184 "(request-target)": f"post {p_url.path}",
1181 "Host": p_url.hostname, 1185 "Host": p_url.hostname,
1182 "Date": http.datetimeToString().decode(), 1186 "Date": http.datetimeToString().decode(),
1183 "Digest": digest 1187 "Digest": digest
1184 } 1188 }
1189 headers["Content-Type"] = (
1190 'application/activity+json'
1191 )
1185 headers, __ = self.getSignatureData(self.getKeyId(actor_id), headers) 1192 headers, __ = self.getSignatureData(self.getKeyId(actor_id), headers)
1186 1193
1187 if self.verbose: 1194 if self.verbose:
1188 if self.verbose>=3: 1195 if self.verbose>=3:
1189 h_to_log = "\n".join(f" {k}: {v}" for k,v in headers.items()) 1196 h_to_log = "\n".join(f" {k}: {v}" for k,v in headers.items())