MatthewKuKanich / FindMyFlipper

The FindMy Flipper app turns your FlipperZero into an AirTag or other tracking device, compatible with Apple AirTags and Samsung SmartTag and Tile Trackers. It uses the BLE beacon to broadcast, allowing users to clone existing tags, generate OpenHaystack key pairs for Apple's FindMy network, and customize beacon intervals and transmit power.
709 stars 31 forks source link

"Invalid public bytes for the given curve" after receiving 1000 position reports (Anisette server v3) #61

Open marcolucc opened 2 months ago

marcolucc commented 2 months ago

I encountered an error while testing the project. After receiving position reports, I came across the following issue:

Invalid public bytes for the given curve This error occurred after receiving approximately 1000 position reports.

Important details:

The Anisette server (version 3) is up and running:

CONTAINER ID  IMAGE                  COMMAND              CREATED     STATUS       PORTS                     NAMES
92348d2c177a  dadoum/anisette-v3-server:latest  "/opt/anisette-v3-se…"  2 days ago  Up 5 minutes  0.0.0.0:6969->6969/tcp, :::6969->6969/tcp  anisette-v3

All necessary files are present.

MatthewKuKanich commented 2 months ago

I encountered an error while testing the project. After receiving position reports, I came across the following issue:

Invalid public bytes for the given curve This error occurred after receiving approximately 1000 position reports.

Important details:

The Anisette server (version 3) is up and running:

CONTAINER ID  IMAGE                  COMMAND              CREATED     STATUS       PORTS                     NAMES
92348d2c177a  dadoum/anisette-v3-server:latest  "/opt/anisette-v3-se…"  2 days ago  Up 5 minutes  0.0.0.0:6969->6969/tcp, :::6969->6969/tcp  anisette-v3

All necessary files are present.

This is very interesting. I think I've seen one other report with a similar error. It's relating to an issue with the key I believe. I've received over 2500 reports in one query without issue in the past so I don't think that's the cause. I'll look into it more. Try deleting everything in your keys folder except for the current key. (backup all the files first)

marcolucc commented 2 months ago

You are correct, It's not caused by the number of reports. I've just tried to delete everything in the keys folder but one key.

ls keys 
test_d6d496f277c8.keys

And I got the same output

python3 request_reports.py

Apple ID: 
Password: 
pyprovision is not installed, querying http://localhost:6969 for an anisette server
/home/purple/.local/lib/python3.11/site-packages/urllib3/connectionpool.py:1099: InsecureRequestWarning: Unverified HTTPS request is being made to host 'gsa.apple.com'. Adding certificate verification is strongly advised. See: https://urllib3.readthedocs.io/en/latest/advanced-usage.html#tls-warnings
  warnings.warn(
pyprovision is not installed, querying http://localhost:6969 for an anisette server
/home/purple/.local/lib/python3.11/site-packages/urllib3/connectionpool.py:1099: InsecureRequestWarning: Unverified HTTPS request is being made to host 'gsa.apple.com'. Adding certificate verification is strongly advised. See: https://urllib3.readthedocs.io/en/latest/advanced-usage.html#tls-warnings
  warnings.warn(
pyprovision is not installed, querying http://localhost:6969 for an anisette server
/home/purple/.local/lib/python3.11/site-packages/urllib3/connectionpool.py:1099: InsecureRequestWarning: Unverified HTTPS request is being made to host 'setup.icloud.com'. Adding certificate verification is strongly advised. See: https://urllib3.readthedocs.io/en/latest/advanced-usage.html#tls-warnings
  warnings.warn(
pyprovision is not installed, querying http://localhost:6969 for an anisette server
200: 776 reports received.
Invalid public bytes for the given curve

Do you reckon it could be linked somehow to the account?

MatthewKuKanich commented 2 months ago

account

This seems to be relating to an issue communicating to the Auth servers. It's weird because it technically goes through (by the look of it). Try spinning up a new docker image / starting from scratch in a new folder but carry over the one key file you're using. You will need to stop the previous container

marcolucc commented 2 months ago

I've conducted further troubleshooting to investigate the "Invalid public bytes for the given curve" error. Here's a summary:

Attempted resets:

Unfortunately, none of these actions resolved the issue.

Given the lack of success, I suspect the issue might be related to the iCloud account. As a next step, I plan to create a new iCloud account to see if it resolves the error. This will help determine if the cause lies with the account itself. If you have any further suggestions into debugging this error, I'd greatly appreciate them.

MatthewKuKanich commented 2 months ago

I've conducted further troubleshooting to investigate the "Invalid public bytes for the given curve" error. Here's a summary:

Attempted resets:

* Deleted and recreated the Anisette server.

* Deleted the entire project folder and recreated the Anisette server.

* Generated a new key, installed it on the Flipper, re-downloaded the project, and recreated the Anisette server.

Unfortunately, none of these actions resolved the issue.

Given the lack of success, I suspect the issue might be related to the iCloud account. As a next step, I plan to create a new iCloud account to see if it resolves the error. This will help determine if the cause lies with the account itself. If you have any further suggestions into debugging this error, I'd greatly appreciate them.

Thank you for the comprehensive breakdown. When creating a new Apple account, do so via an Apple device. This will make it a “verified” account, which gives you access to the keyring/auth. Otherwise, you may get an issue like "Account rep too low".

c4pitalSteez commented 2 months ago

I've encountered the same issue and after completely restarting everything, besides the key, I get the same error. After auth information is saved, on following attempts I get a new error:

Expecting value: line 1 column 1 (char 0)

Running request_reports.py with the -r switch returns to the original error.

c4pitalSteez commented 2 months ago

After playing around with the code, I found that this error consistently occurs upon a decoded report payload that is one byte longer than the rest (89 instead of 88). I added the following adjustment to the data list index ranges on lines 118 to 124 of request_reports.py:

--> adj = len(data) - 88
118 eph_key = ec.EllipticCurvePublicKey.from_encoded_point(ec.SECP224R1(), data[5+adj:62+adj])
119 shared_key = ec.derive_private_key(priv, ec.SECP224R1(), default_backend()).exchange(ec.ECDH(), eph_key)
120 symmetric_key = sha256(shared_key + b'\x00\x00\x00\x01' + data[5+adj:62+adj])
121 decryption_key = symmetric_key[:16]
122 iv = symmetric_key[16:]
123 enc_data = data[62+adj:72+adj]
124 auth_tag = data[72+adj:]

This fixed the issue for me so it seems to be an issue with the length of bytes in the decoded payload data that are dedicated to the timestamp. I applied this fix to RequestReport&Map.py as well with the same success.

marcolucc commented 2 months ago

Thanks @c4pitalSteez! I'm happy to report that your solution resolved the "Invalid public bytes for the given curve" error.

I'm curious to understand why the payload initially worked without issue. What might have caused the extra byte to be added later?

Minor detail: when using @c4pitalSteez fix into "webserver.py" the variable enc_data there is called cipter_txt

c4pitalSteez commented 2 months ago

I'm curious as well, I printed out the extra bytes and they are all null bytes between where the timestamp ends and the rest of the payload begins. Not really sure why this would be as no data seems to be affected by the absence of these bytes.

MatthewKuKanich commented 2 months ago

After playing around with the code, I found that this error consistently occurs upon a decoded report payload that is one byte longer than the rest (89 instead of 88). I added the following adjustment to the data list index ranges on lines 118 to 124 of request_reports.py:

--> adj = len(data) - 88
118 eph_key = ec.EllipticCurvePublicKey.from_encoded_point(ec.SECP224R1(), data[5+adj:62+adj])
119 shared_key = ec.derive_private_key(priv, ec.SECP224R1(), default_backend()).exchange(ec.ECDH(), eph_key)
120 symmetric_key = sha256(shared_key + b'\x00\x00\x00\x01' + data[5+adj:62+adj])
121 decryption_key = symmetric_key[:16]
122 iv = symmetric_key[16:]
123 enc_data = data[62+adj:72+adj]
124 auth_tag = data[72+adj:]

This fixed the issue for me so it seems to be an issue with the length of bytes in the decoded payload data that are dedicated to the timestamp. I applied this fix to RequestReport&Map.py as well with the same success.

Thank's for the workaround! I've pushed it to the repo while I investigate further