mirror of
https://github.com/Sneed-Group/pypush-plus-plus
synced 2025-01-09 17:33:47 +00:00
very messy experiments in facetime links
This commit is contained in:
parent
2960b7c63c
commit
7396445afe
5 changed files with 114 additions and 11 deletions
4
demo.py
4
demo.py
|
@ -6,6 +6,7 @@ from subprocess import PIPE, Popen
|
|||
from rich.logging import RichHandler
|
||||
|
||||
import apns
|
||||
import ids.facetime
|
||||
import ids
|
||||
import imessage
|
||||
|
||||
|
@ -80,6 +81,7 @@ async def main():
|
|||
CONFIG["id"] = {
|
||||
"key": user._id_keypair.key,
|
||||
"cert": user._id_keypair.cert,
|
||||
"ft_cert": user._facetime_cert,
|
||||
}
|
||||
CONFIG["auth"] = {
|
||||
"key": user._auth_keypair.key,
|
||||
|
@ -96,6 +98,8 @@ async def main():
|
|||
with open("config.json", "w") as f:
|
||||
json.dump(CONFIG, f, indent=4)
|
||||
|
||||
await ids.facetime.provision_alias(user)
|
||||
|
||||
im = imessage.iMessageUser(conn, user)
|
||||
|
||||
# Send a message to myself
|
||||
|
|
|
@ -66,7 +66,7 @@ class IDSUser:
|
|||
self.ec_key, self.rsa_key will be set to a randomly gnenerated EC and RSA keypair
|
||||
if they are not already set
|
||||
"""
|
||||
cert = identity.register(
|
||||
certs = identity.register(
|
||||
b64encode(self.push_connection.credentials.token),
|
||||
self.handles,
|
||||
self.user_id,
|
||||
|
@ -75,7 +75,8 @@ class IDSUser:
|
|||
self.encryption_identity,
|
||||
validation_data,
|
||||
)
|
||||
self._id_keypair = _helpers.KeyPair(self._auth_keypair.key, cert)
|
||||
self._id_keypair = _helpers.KeyPair(self._auth_keypair.key, certs["com.apple.madrid"])
|
||||
self._facetime_cert = certs["com.apple.private.alloy.facetime.multi"]
|
||||
|
||||
def restore_identity(self, id_keypair: _helpers.KeyPair):
|
||||
self._id_keypair = id_keypair
|
||||
|
@ -104,7 +105,8 @@ class IDSUser:
|
|||
(rsa_key := encryption.get("rsa_key")) and
|
||||
(signing_key := encryption.get("ec_key")) and
|
||||
(cert := id.get("cert")) and
|
||||
(key := id.get("key"))
|
||||
(key := id.get("key")) and
|
||||
(ft_cert := id.get("ft_cert"))
|
||||
):
|
||||
self.encryption_identity = identity.IDSIdentity(
|
||||
encryption_key=rsa_key,
|
||||
|
@ -113,6 +115,8 @@ class IDSUser:
|
|||
|
||||
id_keypair = _helpers.KeyPair(key, cert)
|
||||
self.restore_identity(id_keypair)
|
||||
|
||||
self._facetime_cert = ft_cert
|
||||
else:
|
||||
logging.info("Registering new identity...")
|
||||
import emulated.nac
|
||||
|
@ -124,4 +128,3 @@ class IDSUser:
|
|||
|
||||
async def lookup(self, uris: list[str], topic: str = "com.apple.madrid") -> Any:
|
||||
return await query.lookup(self.push_connection, self.current_handle, self._id_keypair, uris, topic)
|
||||
|
||||
|
|
62
ids/facetime.py
Normal file
62
ids/facetime.py
Normal file
|
@ -0,0 +1,62 @@
|
|||
from ids import IDSUser
|
||||
import logging
|
||||
logger = logging.getLogger("ids")
|
||||
import plistlib
|
||||
from ids._helpers import PROTOCOL_VERSION, KeyPair, parse_key, serialize_key
|
||||
from ids.signing import add_auth_signature, armour_cert, add_id_signature, add_push_signature
|
||||
import requests
|
||||
from base64 import b64decode, b64encode
|
||||
|
||||
async def provision_alias(user: IDSUser):
|
||||
# <?xml version="1.0" encoding="UTF-8"?>
|
||||
# <!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||
# <plist version="1.0">
|
||||
# <dict>
|
||||
# <key>attributes</key>
|
||||
# <dict>
|
||||
# <key>allowedServices</key>
|
||||
# <dict>
|
||||
# <key>com.apple.private.alloy.facetime.multi</key>
|
||||
# <array/>
|
||||
# </dict>
|
||||
# <key>expiry-epoch-seconds</key>
|
||||
# <real>1726418686.6028981</real>
|
||||
# <key>featureId</key>
|
||||
# <string>Gondola</string>
|
||||
# </dict>
|
||||
# <key>operation</key>
|
||||
# <string>create</string>
|
||||
# </dict>
|
||||
import time
|
||||
logger.debug(f"Adding new temp alias")
|
||||
body = {
|
||||
"attributes": {
|
||||
"allowedServices": {
|
||||
"com.apple.private.alloy.facetime.multi": []
|
||||
},
|
||||
# Unix timestamp in seconds, with decimal places, for 1 year from now
|
||||
"expiry-epoch-seconds": time.time() + 31536000,
|
||||
"featureId": "Gondola"
|
||||
},
|
||||
"operation": "create"
|
||||
}
|
||||
body = plistlib.dumps(body)
|
||||
|
||||
headers = {
|
||||
"x-protocol-version": PROTOCOL_VERSION,
|
||||
# "x-auth-user-id-0": user.user_id,
|
||||
"x-id-self-uri": "mailto:testu3@icloud.com"
|
||||
}
|
||||
#add_auth_signature(headers, body, "id-register", user._auth_keypair, user._push_keypair, b64encode(user.push_connection.credentials.token), 0)
|
||||
add_push_signature(headers, body, "id-provision-alias", user._push_keypair, b64encode(user.push_connection.credentials.token))
|
||||
add_id_signature(headers, body, "id-provision-alias", user._id_keypair, b64encode(user.push_connection.credentials.token))
|
||||
|
||||
r = requests.post(
|
||||
"https://identity.ess.apple.com/WebObjects/TDIdentityService.woa/wa/provisionAlias",
|
||||
headers=headers,
|
||||
data=body,
|
||||
verify=False,
|
||||
)
|
||||
r = plistlib.loads(r.content)
|
||||
|
||||
print(r)
|
|
@ -151,7 +151,28 @@ def register(
|
|||
"user-id": user_id,
|
||||
}
|
||||
],
|
||||
}
|
||||
},
|
||||
{
|
||||
"capabilities": [{"flags": 1, "name": "Invitation", "version": 1}],
|
||||
"service": "com.apple.private.alloy.facetime.multi",
|
||||
"sub-services": [],
|
||||
"users": [
|
||||
{
|
||||
"client-data": {
|
||||
"public-message-identity-key": identity.encode(),
|
||||
"public-message-identity-version": 2,
|
||||
"supports-avless": True,
|
||||
"supports-co": True,
|
||||
"supports-gft-calls": True,
|
||||
"supports-gft-errors": True,
|
||||
"supports-modern-gft": True,
|
||||
"supports-self-one-to-one-invites": True,
|
||||
},
|
||||
"uris": uris,
|
||||
"user-id": user_id,
|
||||
}
|
||||
],
|
||||
},
|
||||
],
|
||||
"validation-data": b64decode(validation_data),
|
||||
}
|
||||
|
@ -184,5 +205,10 @@ def register(
|
|||
raise Exception(f"No users in response: {r}")
|
||||
if not "cert" in r["services"][0]["users"][0]:
|
||||
raise Exception(f"No cert in response: {r}")
|
||||
|
||||
return {
|
||||
"com.apple.madrid": armour_cert(r["services"][0]["users"][0]["cert"]),
|
||||
"com.apple.private.alloy.facetime.multi": armour_cert(r["services"][1]["users"][0]["cert"])
|
||||
}
|
||||
|
||||
return armour_cert(r["services"][0]["users"][0]["cert"])
|
||||
#return armour_cert(r["services"][0]["users"][0]["cert"])
|
||||
|
|
|
@ -90,11 +90,7 @@ def add_auth_signature(
|
|||
push_token: str,
|
||||
auth_number=None,
|
||||
):
|
||||
push_sig, push_nonce = _sign_payload(push_key.key, bag_key, "", push_token, body)
|
||||
headers["x-push-sig"] = push_sig
|
||||
headers["x-push-nonce"] = b64encode(push_nonce)
|
||||
headers["x-push-cert"] = dearmour(push_key.cert)
|
||||
headers["x-push-token"] = push_token
|
||||
add_push_signature(headers, body, bag_key, push_key, push_token)
|
||||
|
||||
auth_sig, auth_nonce = _sign_payload(auth_key.key, bag_key, "", push_token, body)
|
||||
auth_postfix = "-" + str(auth_number) if auth_number is not None else ""
|
||||
|
@ -102,6 +98,18 @@ def add_auth_signature(
|
|||
headers["x-auth-nonce" + auth_postfix] = b64encode(auth_nonce)
|
||||
headers["x-auth-cert" + auth_postfix] = dearmour(auth_key.cert)
|
||||
|
||||
def add_push_signature(
|
||||
headers: dict,
|
||||
body: bytes,
|
||||
bag_key: str,
|
||||
push_key: KeyPair,
|
||||
push_token: str
|
||||
):
|
||||
push_sig, push_nonce = _sign_payload(push_key.key, bag_key, "", push_token, body)
|
||||
headers["x-push-sig"] = push_sig
|
||||
headers["x-push-nonce"] = b64encode(push_nonce)
|
||||
headers["x-push-cert"] = dearmour(push_key.cert)
|
||||
headers["x-push-token"] = push_token
|
||||
|
||||
def add_id_signature(
|
||||
headers: dict,
|
||||
|
|
Loading…
Reference in a new issue