Closed nenseso closed 1 year ago
Sorry, we dont know how to do non-legacy pairing. UxPlay only supports Legacy pairing.
pyatv seems to have made some progress in the direction of understanding the AirPlay 2 protocols
Closing because this is a feature not a bug ....
It would be great if the more recent protocols could be supported, because Apple could withdraw support for "Legacy paring" at any time there is a major update of iOS.
The difficulty is all the cryptography involved....
I tested that set old_protocol =true seems to be able to decrypt and a fast connection
@shuax
can you describe in more details what you managed to do? "old _protocol=true" skips an extra sha-256 hash after fairplay decryption of the audio aeskey with ecdh_secret
I discovered that this had to be skipped for a windows airplay emulator AirMyPc to work (a teacher was teaching a class where some pupils had iPad, others had microsoft surface devices with AirMyPc on those.)
I always wondered why this worked. Are you reporting that if "supports legacy pairing" (features bit 27) is switched off and "old_protocol"=true, that UxPlay still works?
My English is not good, hope you can understand. Because I found that some software connects quickly, and it uses 0x527FFEE6. Then I try to set UxPlay to 0x527FFEE6, obviously the decryption will fail. Then I found that old_protocol will change the decryption process, so I tried to force it to open, and it seemed to work normally.
In short, don't use ecdh_secret for the key when using 0x527FFEE6
How do we know when to use 0x527FFEE6 instead of 0x5A7FFEE6 (bit 27 = 0) for "features"?
Which software (other than AirMyPc) wants this? How does it tell this to UxPlay?
I think AirMyPc ignores the features flag that it only uses one encryption method.
@shuax are you suggesting that if bit 27 is switched off, and "old_protocol"=true, UxPlay will still always work with iOS and macOS clients, ?
Yes, I am using my ipad for testing. I suggest not to use ecdh_secret when no pair message is received.
which pair message do you mean?
httpd receiving on socket 24
conn_request
POST /pair-setup RTSP/1.0
Content-Length: 32
Content-Type: application/octet-stream
CSeq: 1
DACP-ID: 2A28BF33CA9E193
Active-Remote: 3717414016
User-Agent: AirPlay/665.13.1
f4 b9 c1 ce 30 36 45 b5 3e 52 d6 ab e3 50 dc 29
40 34 c0 6b 1d 83 49 d6 98 48 10 61 d4 88 ad 82
Handling request POST with URL /pair-setup
RTSP/1.0 200 OK
CSeq: 1
Server: AirTunes/220.68
Content-Type: application/octet-stream
Content-Length: 32
5a 64 e5 af 91 fb d5 c9 89 e3 77 63 60 bf 05 95
3c 60 c9 b3 52 5e 03 5a 45 6f bf 40 6b cb 84 45
httpd receiving on socket 24
conn_request
POST /pair-verify RTSP/1.0
X-Apple-PD: 1
X-Apple-AbsoluteTime: 692578708
Content-Length: 68
Content-Type: application/octet-stream
CSeq: 2
DACP-ID: 2A28BF33CA9E193
Active-Remote: 3717414016
User-Agent: AirPlay/665.13.1
01 00 00 00 0c 71 cb 1b cd 02 ed 9b fb 69 41 1b
c9 8b 09 b3 c3 a7 a9 f2 30 43 38 b8 67 b2 89 2c
42 92 af 65 f4 b9 c1 ce 30 36 45 b5 3e 52 d6 ab
e3 50 dc 29 40 34 c0 6b 1d 83 49 d6 98 48 10 61
d4 88 ad 82
Handling request POST with URL /pair-verify
RTSP/1.0 200 OK
CSeq: 2
Server: AirTunes/220.68
Content-Type: application/octet-stream
Content-Length: 96
7c f2 16 3a 06 ad 2a d6 96 f2 a7 8e de c3 3c 87
a6 e9 77 31 cb 54 13 9a 44 24 8b a5 42 94 f0 1a
6c dc e3 8e a9 03 f9 5a b5 f7 9e 3f 7e 46 28 b8
44 66 90 b4 c8 bb 78 ae 48 d1 29 ce d5 94 75 88
cf cc 0e 1c 08 7a ec a7 35 31 37 85 fa 55 08 cb
a9 87 21 24 1c 61 78 bf e0 f6 98 6a cd 6b 14 48
httpd receiving on socket 24
conn_request
POST /pair-verify RTSP/1.0
X-Apple-PD: 1
X-Apple-AbsoluteTime: 692578708
Content-Length: 68
Content-Type: application/octet-stream
CSeq: 3
DACP-ID: 2A28BF33CA9E193
Active-Remote: 3717414016
User-Agent: AirPlay/665.13.1
00 00 00 00 84 1e 81 ed eb 3c c5 c4 f8 8d 6f 89
e5 ef f7 9d 87 ae 62 26 7f be 06 d5 c5 36 eb 45
4a 2b f7 3b f5 83 03 91 55 b7 ef b1 fa 66 1e 4a
72 48 cf 77 62 1a 2e d5 34 7b 5a a7 d8 1c fd b6
2b 0f 90 18
Handling request POST with URL /pair-verify
2nd pair-verify step: checking signature
pair-verify: signature is verified
RTSP/1.0 200 OK
CSeq: 3
Server: AirTunes/220.68
Content-Type: application/octet-stream
httpd receiving on socket 24
conn_request
POST /fp-setup RTSP/1.0
X-Apple-ET: 32
Content-Length: 16
Content-Type: application/octet-stream
CSeq: 4
DACP-ID: 2A28BF33CA9E193
Active-Remote: 3717414016
User-Agent: AirPlay/665.13.1
46 50 4c 59 03 01 01 00 00 00 00 04 02 00 01 bb
Handling request POST with URL /fp-setup
RTSP/1.0 200 OK
CSeq: 4
Server: AirTunes/220.68
Content-Type: application/octet-stream
Content-Length: 142
46 50 4c 59 03 01 02 00 00 00 00 82 02 01 cf 32
a2 57 14 b2 52 4f 8a a0 ad 7a f1 64 e3 7b cf 44
24 e2 00 04 7e fc 0a d6 7a fc d9 5d ed 1c 27 30
bb 59 1b 96 2e d6 3a 9c 4d ed 88 ba 8f c7 8d e6
4d 91 cc fd 5c 7b 56 da 88 e3 1f 5c ce af c7 43
19 95 a0 16 65 a5 4e 19 39 d2 5b 94 db 64 b9 e4
5d 8d 06 3e 1e 6a f0 7e 96 56 16 2b 0e fa 40 42
75 ea 5a 44 d9 59 1c 72 56 b9 fb e6 51 38 98 b8
02 27 72 19 88 57 16 50 94 2a d9 46 68 8a
httpd receiving on socket 24
conn_request
POST /fp-setup RTSP/1.0
X-Apple-ET: 32
Content-Length: 164
Content-Type: application/octet-stream
CSeq: 5
DACP-ID: 2A28BF33CA9E193
Active-Remote: 3717414016
User-Agent: AirPlay/665.13.1
46 50 4c 59 03 01 03 00 00 00 00 98 01 8f 1a 9c
4e 23 16 d8 b2 88 55 d5 e7 11 e3 03 ea f1 76 c2
45 ab ad 70 cb 12 af cd cd 43 9e 1d 33 7d af 12
9d ba 1e 8e 63 7b ae 03 99 1e 97 d8 cd 84 6f 9d
89 b4 f8 e2 2e 48 6a 86 da dc 8f c8 4e 55 86 29
7f 8e 90 fe cc e2 f2 52 83 a3 cc f8 be 11 7f 54
29 f9 23 53 c6 34 6e 79 2a 99 4d cd ab c6 76 e8
1c 60 4f 37 5b 9f b4 cd 00 50 4d 81 c9 66 11 c9
21 30 4f 19 d8 e8 c2 c9 a6 bc 81 d1 52 ab 9d 6b
a9 4f 87 01 2f 01 39 d4 41 36 79 b7 88 2b df ee
34 08 bf 95
Handling request POST with URL /fp-setup
RTSP/1.0 200 OK
CSeq: 5
Server: AirTunes/220.68
Content-Type: application/octet-stream
Content-Length: 32
46 50 4c 59 03 01 04 00 00 00 00 14 a9 4f 87 01
2f 01 39 d4 41 36 79 b7 88 2b df ee 34 08 bf 95
httpd receiving on socket 24
conn_request
SETUP rtsp://192.168.1.54/14915512193180388723 RTSP/1.0
Content-Length: 687
Content-Type: application/x-apple-binary-plist
CSeq: 6
DACP-ID: 2A28BF33CA9E193
Active-Remote: 3717414016
User-Agent: AirPlay/665.13.1
<?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>et</key>
<integer>32</integer>
<key>statsCollectionEnabled</key>
<false/>
<key>eiv</key>
<data>
sjpLqD6E9/DaQkeEtPnqZQ==
</data>
<key>sessionUUID</key>
<string>CEFE8B50-5D86-4D73-87D7-E1FD04E0BCC2</string>
<key>timingProtocol</key>
<string>NTP</string>
<key>diagnosticsAndUsage</key>
<true/>
<key>osName</key>
<string>iPhone OS</string>
<key>osBuildVersion</key>
<string>20B101</string>
<key>sourceVersion</key>
<string>665.13.1</string>
<key>timingPort</key>
<integer>60512</integer>
<key>isScreenMirroringSession</key>
<true/>
<key>osVersion</key>
<string>16.1.1</string>
<key>ekey</key>
<data>
RlBMWQECAQAAAAA8AAAAAJDMkIOALm9kJ4isoybax7AAAAAQbeD5thy49pwbQg3aijpH
GS3DbyL7xdTBAL/W7/raAOiWzhDl
</data>
<key>sessionCorrelationUUID</key>
<string>A4746968-6424-4BE4-BFC6-5184C798593E</string>
<key>internalBuild</key>
<false/>
<key>deviceID</key>
<string>60:8B:1F:43:B2:F6</string>
<key>model</key>
<string>iPad7,11</string>
<key>name</key>
<string>Someone’s iPad</string>
<key>macAddress</key>
<string>C2:2A:DE:2B:81:21</string>
</dict>
</plist>
Handling request SETUP with URL rtsp://192.168.1.54/14915512193180388723
DACP-ID: 2A28BF33CA9E193
Active-Remote: 3717414016
Transport: null
SETUP 1
eiv_len = 16
16 byte aesiv (needed for AES-CBC audio decryption iv):
b2 3a 4b a8 3e 84 f7 f0 da 42 47 84 b4 f9 ea 65
ekey_len = 72
ekey:
46 50 4c 59 01 02 01 00 00 00 00 3c 00 00 00 00
90 cc 90 83 80 2e 6f 64 27 88 ac a3 26 da c7 b0
00 00 00 10 6d e0 f9 b6 1c b8 f6 9c 1b 42 0d da
8a 3a 47 19 2d c3 6f 22 fb c5 d4 c1 00 bf d6 ef
fa da 00 e8 96 ce 10 e5
fairplay_decrypt ret = 0
16 byte aeskey (fairplay-decrypted from ekey):
72 6d 52 07 b7 7a 91 6a 98 26 90 62 4a 4c e2 fb
32 byte shared ecdh_secret:
b1 d3 49 6a 1c 68 e8 cd 9f 60 0b 18 14 d7 0c 19
b9 80 76 76 f4 92 d7 40 ed fd f3 76 0e 42 56 55
Client identified as User-Agent: AirPlay/665.13.1
16 byte aeskey after sha-256 hash with ecdh_secret:
7f a1 9e a9 f8 c6 f9 5b 36 ac 3c 50 8e c6 5c d3
When bit 27 is false, there seems not call /pair-setup.
I am testing and I agree with you so far. Very interesting
But since things are working , is there any reason to change uxplay to use bit 27 = 0 ? The only problem case was the AirMyPC client, and that is fixed.
set bit 27 = 0 connection will be much faster, I recommend this
how much faster? Usually one just connects a few times at most?
any easy initial thing would be to add code to test whether bit 27 was set, and switch off the hashing step if it is not.
EDIT: I see the missing pair setup when bit 27 is not set. You are probably right to test for that.
It will connect about 5 seconds before the modification, and it will connect 1 second after the modification.
Interesting. some option for "fast connection without pairing" could be added
In principle, pairing is supposed to allow multiple clients (up to 16) to connect simultaneously to AppleTv, each with a unique SessionID created in pair setup but we dont have the details for setting this and dont allow it.
I just test SupportsLegacyPairing, and I don't know much about other knowledge.
@shuax It's great that you are discovering new things about the protocol!
I can corroborate that this works.
In regard to "It will connect about 5 seconds before the modification, and it will connect 1 second after the modification."
As we can see from wireshark recordings, the ios device doesn't actually send any messages to the server (apart from a possible mdns query?) for several seconds, until it finally makes the connection.
If we change the FEATURES flags as shuax described, this delay is entirely gone.
I think that the ios device must be generating some sort of encryption keys... but this shouldn't take 3-4 seconds.
Possible hypothesis are that the fun "apple way" connecting all your devices together - it will attempt to use the internet to reach your other apple devices / icloud to see if there is a valid pairing key out there. Using MITMProxy it doesn't appear to be doing this, but I can't be sure.
Someone with most likely an apple tv 2 (or 1?) will need to see if this delay exists on first pair.
@thiccaxe
Yes I've tested. In the test I add (bool) comm->pairing_request_received initially false, and set it true if pair_setup takes place, to decide whether to do the hash.
I can make this change for now, and decide later whether to change the features flag, or make some option for doing that. or for setting it. But nothing seems to break when the flag is off.
latest github is updated so bit27 can be switched off by uncommenting a line in lib/dnssdint.h (and commenting out the line above)
Before making the final switch bit27 = OFF, I am thinking about whether to make another option to restore previous behavior. any thoughts on this?
Updates to use @shuax 's find are tested and now in the github master branch, for a future UxPlay-1.65 release
The choice to reset features bit 27 to "on" is now provided by an option "-pair" in the "testing" branch of UxPlay. (the changes would allow any bit in "features" to be changed as a UxPlay option).
This will probably be in UxPlay-1.67 when it is released, and might be useful if some newer protocols described in pyatv ever get implemented, like displaying a code on the screen, which need pairing.
Are you trying to research pairing codes? This code may be useful.
@shuax thanks! will take a look when I have time to see if any new features are in that code variant.
I have now merged the "testing" branch into master UxPlay
Possible sources of info for pin-pair-start protocol seem to be:
https://github.com/serezhka/java-airplay-server/issues/5
https://github.com/warren-bank/Java-AirPlay2-Receiver
https://github.com/openairplay/AirPlayAuth
Added (notes from Warren Bank ): https://github.com/warren-bank/Java-AirPlay2-Receiver/blob/246800d0d5d2cc900f43ecd507a612e703331ce0/etc/notes/AirPlay2%20initial%203-step%20pairing%20handshake.txt
I recently altered the 27th bit of the features field by modifying the value of "SupportsLegacyPairing" from 1 to 0. I achieved this by changing the following code:
to:
However, this modification resulted in the failure of decryption. I am seeking guidance on how to modify the code in order to ensure successful decryption. Can you please help me with this issue?