FDH2 / UxPlay

AirPlay Unix mirroring server
GNU General Public License v3.0
1.35k stars 72 forks source link

Legacy pairing and pin-pair-start protocol (was Change the value of "SupportsLegacyPairing" from 1 to 0 results in the failure of decoding.) #176

Closed nenseso closed 1 year ago

nenseso commented 1 year ago

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:

/* dnssdint.h */
#define FEATURES_1 "0x5A7FFEE6" /* first 32 bits of features */

to:

/* dnssdint.h */
#define FEATURES_1 "0x527FFEE6" /* first 32 bits of features */

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?

❯ ./uxplay -n uxplay_test -d
UxPlay 1.61: An Open-Source AirPlay mirroring and audio-streaming server.
macOS detected: use -nc option as workaround for GStreamer problem
supported audio format 1: AAC-ELD 44100/2
supported audio format 2: ALAC 44100/16/2
GStreamer video pipeline will be:
"appsrc name=video_source ! queue ! h264parse ! decodebin ! videoconvert ! autovideosink name=video_sink sync=false"
Initialized GStreamer video renderer
using system MAC address 9a:1d:aa:55:b1:41
Initialized server socket(s)

(<unknown>:95141): GStreamer-Video-CRITICAL **: 10:30:11.618: gst_video_center_rect: assertion 'src->h != 0' failed

(<unknown>:95141): GStreamer-Video-CRITICAL **: 10:30:11.619: gst_video_center_rect: assertion 'src->h != 0' failed
Accepted IPv4 client on socket 27
Local: 169.254.88.93
Remote: 169.254.23.182
httpd receiving on socket 27
conn_request

GET /info RTSP/1.0
X-Apple-ProtocolVersion: 1
Content-Length: 70
Content-Type: application/x-apple-binary-plist
CSeq: 0
DACP-ID: 8187D50032A23CA6
Active-Remote: 3272830738
User-Agent: AirPlay/615.12.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>qualifier</key>
    <array>
        <string>txtAirPlay</string>
    </array>
</dict>
</plist>

Handling request GET with URL /info

RTSP/1.0 200 OK
CSeq: 0
Server: AirTunes/220.68
Content-Type: application/x-apple-binary-plist
Content-Length: 1093

<?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>txtAirPlay</key>
    <data>
    GmRldmljZWlkPTlhOjFkOmFhOjU1OmIxOjQxF2ZlYXR1cmVzPTB4NTI3RkZFRTYsMHgw
    CWZsYWdzPTB4NBBtb2RlbD1BcHBsZVRWMywyQ3BrPWIwNzcyN2Q2ZjZjZDZlMDhiNThl
    ZGU1MjVlYzNjZGVhYTI1MmFkOWY2ODNmZWIyMTJlZjhhMjA1MjQ2NTU0ZTcncGk9MmUz
    ODgwMDYtMTNiYS00MDQxLTlhNjctMjVkZDRhNDNkNTM2DnNyY3ZlcnM9MjIwLjY4BHZ2
    PTI=
    </data>
    <key>features</key>
    <integer>1384120038</integer>
    <key>name</key>
    <string>uxplay_test@zhouzihaodeMacBook-Pro.local</string>
    <key>audioFormats</key>
    <array>
        <dict>
            <key>type</key>
            <integer>100</integer>
            <key>audioInputFormats</key>
            <integer>67108860</integer>
            <key>audioOutputFormats</key>
            <integer>67108860</integer>
        </dict>
        <dict>
            <key>type</key>
            <integer>101</integer>
            <key>audioInputFormats</key>
            <integer>67108860</integer>
            <key>audioOutputFormats</key>
            <integer>67108860</integer>
        </dict>
    </array>
    <key>pi</key>
    <string>2e388006-13ba-4041-9a67-25dd4a43d536</string>
    <key>vv</key>
    <integer>2</integer>
    <key>statusFlags</key>
    <integer>68</integer>
    <key>keepAliveLowPower</key>
    <integer>1</integer>
    <key>sourceVersion</key>
    <string>220.68</string>
    <key>pk</key>
    <data>
    sHcn1vbNbgi1jt5SXsPN6qJSrZ9oP+shLviiBSRlVOc=
    </data>
    <key>keepAliveSendStatsAsBody</key>
    <integer>1</integer>
    <key>deviceID</key>
    <string>9a:1d:aa:55:b1:41</string>
    <key>audioLatencies</key>
    <array>
        <dict>
            <key>outputLatencyMicros</key>
            <false/>
            <key>type</key>
            <integer>100</integer>
            <key>audioType</key>
            <string>default</string>
            <key>inputLatencyMicros</key>
            <false/>
        </dict>
        <dict>
            <key>outputLatencyMicros</key>
            <false/>
            <key>type</key>
            <integer>101</integer>
            <key>audioType</key>
            <string>default</string>
            <key>inputLatencyMicros</key>
            <false/>
        </dict>
    </array>
    <key>model</key>
    <string>AppleTV3,2</string>
    <key>macAddress</key>
    <string>9a:1d:aa:55:b1:41</string>
    <key>displays</key>
    <array>
        <dict>
            <key>uuid</key>
            <string>e0ff8a27-6738-3d56-8a16-cc53aacee925</string>
            <key>widthPhysical</key>
            <false/>
            <key>heightPhysical</key>
            <false/>
            <key>width</key>
            <integer>1920</integer>
            <key>height</key>
            <integer>1080</integer>
            <key>widthPixels</key>
            <integer>1920</integer>
            <key>heightPixels</key>
            <integer>1080</integer>
            <key>rotation</key>
            <false/>
            <key>refreshRate</key>
            <integer>60</integer>
            <key>maxFPS</key>
            <integer>30</integer>
            <key>overscanned</key>
            <false/>
            <key>features</key>
            <integer>14</integer>
        </dict>
    </array>
</dict>
</plist>

httpd receiving on socket 27
conn_request

POST /fp-setup RTSP/1.0
X-Apple-ET: 32
Content-Length: 16
Content-Type: application/octet-stream
CSeq: 1
DACP-ID: 8187D50032A23CA6
Active-Remote: 3272830738
User-Agent: AirPlay/615.12.1

46 50 4c 59 03 01 01 00 00 00 00 04 02 00 03 bb

Handling request POST with URL /fp-setup

RTSP/1.0 200 OK
CSeq: 1
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 03 90 01
e1 72 7e 0f 57 f9 f5 88 0d b1 04 a6 25 7a 23 f5
cf ff 1a bb e1 e9 30 45 25 1a fb 97 eb 9f c0 01
1e be 0f 3a 81 df 5b 69 1d 76 ac b2 f7 a5 c7 08
e3 d3 28 f5 6b b3 9d bd e5 f2 9c 8a 17 f4 81 48
7e 3a e8 63 c6 78 32 54 22 e6 f7 8e 16 6d 18 aa
7f d6 36 25 8b ce 28 72 6f 66 1f 73 88 93 ce 44
31 1e 4b e6 c0 53 51 93 e5 ef 72 e8 68 62 33 72
9c 22 7d 82 0c 99 94 45 d8 92 46 c8 c3 59

httpd receiving on socket 27
conn_request

POST /fp-setup RTSP/1.0
X-Apple-ET: 32
Content-Length: 164
Content-Type: application/octet-stream
CSeq: 2
DACP-ID: 8187D50032A23CA6
Active-Remote: 3272830738
User-Agent: AirPlay/615.12.1

46 50 4c 59 03 01 03 00 00 00 00 98 03 8f 1a 9c
9b 1f c1 ab ad bf 38 b5 a5 7d 9b 77 28 0c 23 e3
57 be 09 69 92 49 b9 31 a4 2e fa 8a db 43 b7 d2
2e 63 ac 80 b6 73 c1 b1 22 1a 78 4c 49 f4 67 67
ff 31 35 76 89 a2 c6 ee 8e 79 a4 66 e0 cf 95 b0
1d 9a f2 30 8d a6 c6 7a e0 85 4c 64 3d af 33 6b
f9 5e 23 c6 63 b1 af e8 ad 9f 03 09 14 8c fa 95
4f a9 cd 82 70 e7 0c 91 6b 4a 3d b4 44 a9 11 6d
99 b2 73 2e 2b d8 49 32 7b d9 a3 5a e8 5a b8 ec
55 e3 93 e8 eb 2c 0d 12 44 0a e2 a6 9a 6e 00 b6
4d 28 c1 d3

Handling request POST with URL /fp-setup

RTSP/1.0 200 OK
CSeq: 2
Server: AirTunes/220.68
Content-Type: application/octet-stream
Content-Length: 32

46 50 4c 59 03 01 04 00 00 00 00 14 55 e3 93 e8
eb 2c 0d 12 44 0a e2 a6 9a 6e 00 b6 4d 28 c1 d3

httpd receiving on socket 27
conn_request

SETUP rtsp://169.254.88.93/7342205593126650935 RTSP/1.0
Content-Length: 586
Content-Type: application/x-apple-binary-plist
CSeq: 3
DACP-ID: 8187D50032A23CA6
Active-Remote: 3272830738
User-Agent: AirPlay/615.12.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>eiv</key>
    <data>
    BmJefEgFbanslvBSuOD49w==
    </data>
    <key>timingProtocol</key>
    <string>NTP</string>
    <key>sessionUUID</key>
    <string>65E4C116-1633-4437-B203-5341BAC602AA</string>
    <key>diagnosticsAndUsage</key>
    <true/>
    <key>osName</key>
    <string>iPhone OS</string>
    <key>osBuildVersion</key>
    <string>19F77</string>
    <key>sourceVersion</key>
    <string>615.12.1</string>
    <key>timingPort</key>
    <integer>61167</integer>
    <key>isScreenMirroringSession</key>
    <true/>
    <key>osVersion</key>
    <string>15.5</string>
    <key>ekey</key>
    <data>
    RlBMWQECAQAAAAA8AAAAAD/+Szp2s69LwoC53IMpBTIAAAAQHaiDw5V+80mQT32Q/Yvi
    pMg19tGnl7HZG7WzgIiA/qNDXDZV
    </data>
    <key>internalBuild</key>
    <false/>
    <key>deviceID</key>
    <string>CC:2D:B7:5D:00:12</string>
    <key>model</key>
    <string>iPhone10,2</string>
    <key>name</key>
    <string>zzh的 iPhone</string>
    <key>macAddress</key>
    <string>CE:2D:B7:5D:00:ED</string>
</dict>
</plist>

Handling request SETUP with URL rtsp://169.254.88.93/7342205593126650935
DACP-ID: 8187D50032A23CA6
Active-Remote: 3272830738
Transport: null
SETUP 1
eiv_len = 16
16 byte aesiv (needed for AES-CBC audio decryption iv):
06 62 5e 7c 48 05 6d a9 ec 96 f0 52 b8 e0 f8 f7

ekey_len = 72
ekey:
46 50 4c 59 01 02 01 00 00 00 00 3c 00 00 00 00
3f fe 4b 3a 76 b3 af 4b c2 80 b9 dc 83 29 05 32
00 00 00 10 1d a8 83 c3 95 7e f3 49 90 4f 7d 90
fd 8b e2 a4 c8 35 f6 d1 a7 97 b1 d9 1b b5 b3 80
88 80 fe a3 43 5c 36 55

fairplay_decrypt ret = 0
16 byte aeskey (fairplay-decrypted from ekey):
a3 77 d3 fe b6 e3 6e 39 14 b9 9a 8c 34 77 d7 98

32 byte shared ecdh_secret:
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00

Client identified as User-Agent: AirPlay/615.12.1
16 byte aeskey after sha-256 hash with ecdh_secret:
1d 19 24 a7 a6 1e 67 b8 5e 70 7f 0f 89 c7 dd 89

timing_rport = 61167
raop_ntp parse remote ip = 169.254.23.182
raop_ntp starting time
raop_ntp local timing port socket 29 port UDP 55912
raop_rtp parse remote ip = 169.254.23.182
raop_rtp_mirror parse remote ip = 169.254.23.182
eport = 61483, tport = 55912

RTSP/1.0 200 OK
CSeq: 3
Server: AirTunes/220.68
Content-Type: application/x-apple-binary-plist
Content-Length: 77

raop_ntp send_len = 32, now = 1675823435595447
<?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>timingPort</key>
    <integer>55912</integer>
    <key>eventPort</key>
    <integer>61483</integer>
</dict>
</plist>

raop_ntp receive time type_t=83 packetlen = 32
80 d3 00 07 00 00 00 00 e7 8d 87 cb 98 6f 36 ef
83 bc b8 51 be ff 16 84 83 bc b8 51 bf 06 9c 66

raop_ntp sync correction = -1674628985849604
Accepted IPv4 client on socket 30
Local: 169.254.88.93
Remote: 169.254.23.182
httpd receiving on socket 27
conn_request

GET /info RTSP/1.0
X-Apple-ProtocolVersion: 1
CSeq: 4
DACP-ID: 8187D50032A23CA6
Active-Remote: 3272830738
User-Agent: AirPlay/615.12.1

Handling request GET with URL /info

RTSP/1.0 200 OK
CSeq: 4
Server: AirTunes/220.68
Content-Type: application/x-apple-binary-plist
Content-Length: 1093

<?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>txtAirPlay</key>
    <data>
    GmRldmljZWlkPTlhOjFkOmFhOjU1OmIxOjQxF2ZlYXR1cmVzPTB4NTI3RkZFRTYsMHgw
    CWZsYWdzPTB4NBBtb2RlbD1BcHBsZVRWMywyQ3BrPWIwNzcyN2Q2ZjZjZDZlMDhiNThl
    ZGU1MjVlYzNjZGVhYTI1MmFkOWY2ODNmZWIyMTJlZjhhMjA1MjQ2NTU0ZTcncGk9MmUz
    ODgwMDYtMTNiYS00MDQxLTlhNjctMjVkZDRhNDNkNTM2DnNyY3ZlcnM9MjIwLjY4BHZ2
    PTI=
    </data>
    <key>features</key>
    <integer>1384120038</integer>
    <key>name</key>
    <string>uxplay_test@zhouzihaodeMacBook-Pro.local</string>
    <key>audioFormats</key>
    <array>
        <dict>
            <key>type</key>
            <integer>100</integer>
            <key>audioInputFormats</key>
            <integer>67108860</integer>
            <key>audioOutputFormats</key>
            <integer>67108860</integer>
        </dict>
        <dict>
            <key>type</key>
            <integer>101</integer>
            <key>audioInputFormats</key>
            <integer>67108860</integer>
            <key>audioOutputFormats</key>
            <integer>67108860</integer>
        </dict>
    </array>
    <key>pi</key>
    <string>2e388006-13ba-4041-9a67-25dd4a43d536</string>
    <key>vv</key>
    <integer>2</integer>
    <key>statusFlags</key>
    <integer>68</integer>
    <key>keepAliveLowPower</key>
    <integer>1</integer>
    <key>sourceVersion</key>
    <string>220.68</string>
    <key>pk</key>
    <data>
    sHcn1vbNbgi1jt5SXsPN6qJSrZ9oP+shLviiBSRlVOc=
    </data>
    <key>keepAliveSendStatsAsBody</key>
    <integer>1</integer>
    <key>deviceID</key>
    <string>9a:1d:aa:55:b1:41</string>
    <key>audioLatencies</key>
    <array>
        <dict>
            <key>outputLatencyMicros</key>
            <false/>
            <key>type</key>
            <integer>100</integer>
            <key>audioType</key>
            <string>default</string>
            <key>inputLatencyMicros</key>
            <false/>
        </dict>
        <dict>
            <key>outputLatencyMicros</key>
            <false/>
            <key>type</key>
            <integer>101</integer>
            <key>audioType</key>
            <string>default</string>
            <key>inputLatencyMicros</key>
            <false/>
        </dict>
    </array>
    <key>model</key>
    <string>AppleTV3,2</string>
    <key>macAddress</key>
    <string>9a:1d:aa:55:b1:41</string>
    <key>displays</key>
    <array>
        <dict>
            <key>uuid</key>
            <string>e0ff8a27-6738-3d56-8a16-cc53aacee925</string>
            <key>widthPhysical</key>
            <false/>
            <key>heightPhysical</key>
            <false/>
            <key>width</key>
            <integer>1920</integer>
            <key>height</key>
            <integer>1080</integer>
            <key>widthPixels</key>
            <integer>1920</integer>
            <key>heightPixels</key>
            <integer>1080</integer>
            <key>rotation</key>
            <false/>
            <key>refreshRate</key>
            <integer>60</integer>
            <key>maxFPS</key>
            <integer>30</integer>
            <key>overscanned</key>
            <false/>
            <key>features</key>
            <integer>14</integer>
        </dict>
    </array>
</dict>
</plist>

httpd receiving on socket 27
conn_request

GET_PARAMETER rtsp://169.254.88.93/7342205593126650935 RTSP/1.0
Content-Length: 8
Content-Type: text/parameters
CSeq: 5
DACP-ID: 8187D50032A23CA6
Active-Remote: 3272830738
User-Agent: AirPlay/615.12.1

volume

Handling request GET_PARAMETER with URL rtsp://169.254.88.93/7342205593126650935

RTSP/1.0 200 OK
CSeq: 5
Server: AirTunes/220.68
Content-Type: text/parameters
Content-Length: 13

volume: 0.0

httpd receiving on socket 27
conn_request

RECORD rtsp://169.254.88.93/7342205593126650935 RTSP/1.0
CSeq: 6
DACP-ID: 8187D50032A23CA6
Active-Remote: 3272830738
User-Agent: AirPlay/615.12.1

Handling request RECORD with URL rtsp://169.254.88.93/7342205593126650935
raop_handler_record

RTSP/1.0 200 OK
CSeq: 6
Server: AirTunes/220.68
Audio-Latency: 11025
Audio-Jack-Status: connected; type=analog

httpd receiving on socket 27
conn_request

SET_PARAMETER rtsp://169.254.88.93/7342205593126650935 RTSP/1.0
Content-Length: 20
Content-Type: text/parameters
CSeq: 7
DACP-ID: 8187D50032A23CA6
Active-Remote: 3272830738
User-Agent: AirPlay/615.12.1

volume: -20.000000

Handling request SET_PARAMETER with URL rtsp://169.254.88.93/7342205593126650935

RTSP/1.0 200 OK
CSeq: 7
Server: AirTunes/220.68

httpd receiving on socket 27
conn_request

SETUP rtsp://169.254.88.93/7342205593126650935 RTSP/1.0
Content-Length: 204
Content-Type: application/x-apple-binary-plist
CSeq: 8
DACP-ID: 8187D50032A23CA6
Active-Remote: 3272830738
User-Agent: AirPlay/615.12.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>streams</key>
    <array>
        <dict>
            <key>timestampInfo</key>
            <array>
                <dict>
                    <key>name</key>
                    <string>SubSu</string>
                </dict>
                <dict>
                    <key>name</key>
                    <string>BePxT</string>
                </dict>
                <dict>
                    <key>name</key>
                    <string>AfPxT</string>
                </dict>
                <dict>
                    <key>name</key>
                    <string>BefEn</string>
                </dict>
                <dict>
                    <key>name</key>
                    <string>EmEnc</string>
                </dict>
            </array>
            <key>latencyMs</key>
            <integer>40</integer>
            <key>type</key>
            <integer>110</integer>
            <key>streamConnectionID</key>
            <integer>1946811920699902152</integer>
        </dict>
    </array>
</dict>
</plist>

Handling request SETUP with URL rtsp://169.254.88.93/7342205593126650935
DACP-ID: 8187D50032A23CA6
Active-Remote: 3272830738
Transport: null
type = 110
streamConnectionID (needed for AES-CTR video decryption key and iv): 1946811920699902152
raop_rtp_mirror starting mirroring
raop_rtp_mirror local data port socket 31 port TCP 61563
Mirroring initialized successfully

RTSP/1.0 200 OK
CSeq: 8
Server: AirTunes/220.68
Content-Type: application/x-apple-binary-plist
Content-Length: 85

<?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>streams</key>
    <array>
        <dict>
            <key>dataPort</key>
            <integer>61563</integer>
            <key>type</key>
            <integer>110</integer>
        </dict>
    </array>
</dict>
</plist>

raop_rtp_mirror accepting client
raop_rtp_mirror: unidentified extra header data  656.000000, 0.000000
begin video stream wxh = 608x1080; source 608x1080
raop_rtp_mirror width_source = 608.000000 height_source = 1080.000000 width = 608.000000 height = 1080.000000
raop_rtp_mirror: sps/pps header size = 6
raop_rtp_mirror h264 sps/pps header:
01 64 00 20 ff e1

raop_rtp_mirror sps size = 17
raop_rtp_mirror h264 Sequence Parameter Set:
27 64 00 20 ac 13 14 50 26 02 27 e5 9b 80 80 80
81

raop_rtp_mirror pps size = 4
raop_rtp_mirror h264 Picture Parameter Set:
28 ee 3c b0

remainder size = 4
remainder of sps+pps packet:
02 00 00 00

raop_rtp video: now = 1675823435.727499, ntp = 1675823435.719129, latency = 0.008370
nalu_type = 17, nalu_size = 748119400,  processed bytes 748119404, payloadsize = 8826 nalus_count = 1
nalu marked as invalid
*** ERROR decryption of video packet failed
raop_rtp video: now = 1675823435.732293, ntp = 1675823435.735795, latency = -0.003502
nalu marked as invalid
*** ERROR decryption of video packet failed
raop_rtp video: now = 1675823435.744857, ntp = 1675823435.785804, latency = -0.040947
nalu_type = 5, nalu_size = 1425781468,  processed bytes 1425781472, payloadsize = 5870 nalus_count = 1
nalu marked as invalid
*** ERROR decryption of video packet failed
raop_rtp video: now = 1675823435.793351, ntp = 1675823435.835810, latency = -0.042459
nalu marked as invalid
*** ERROR decryption of video packet failed
raop_rtp video: now = 1675823435.827696, ntp = 1675823435.869147, latency = -0.041451
nalu_type = 14, nalu_size = 1319401868,  processed bytes 1319401872, payloadsize = 573 nalus_count = 1
nalu marked as invalid
*** ERROR decryption of video packet failed
raop_rtp video: now = 1675823435.862338, ntp = 1675823435.902485, latency = -0.040147
nalu_type = 11, nalu_size = 526419878,  processed bytes 526419882, payloadsize = 2935 nalus_count = 1
nalu marked as invalid
*** ERROR decryption of video packet failed
raop_rtp video: now = 1675823435.894049, ntp = 1675823435.935822, latency = -0.041773
nalu_type = 11, nalu_size = 1403516273,  processed bytes 1403516277, payloadsize = 3545 nalus_count = 1
nalu marked as invalid
*** ERROR decryption of video packet failed
raop_rtp video: now = 1675823435.928621, ntp = 1675823435.969159, latency = -0.040538
nalu marked as invalid
*** ERROR decryption of video packet failed
raop_rtp video: now = 1675823435.961878, ntp = 1675823436.002497, latency = -0.040619
nalu marked as invalid
*** ERROR decryption of video packet failed
raop_rtp video: now = 1675823435.995064, ntp = 1675823436.035834, latency = -0.040770
nalu_type = 4, nalu_size = 1023238659,  processed bytes 1023238663, payloadsize = 4164 nalus_count = 1
nalu marked as invalid
*** ERROR decryption of video packet failed
raop_rtp video: now = 1675823436.029416, ntp = 1675823436.069172, latency = -0.039756
nalu_type = 28, nalu_size = 1297298276,  processed bytes 1297298280, payloadsize = 5163 nalus_count = 1
nalu marked as invalid
*** ERROR decryption of video packet failed
raop_rtp video: now = 1675823436.062222, ntp = 1675823436.102509, latency = -0.040287
nalu_type = 19, nalu_size = 592418843,  processed bytes 592418847, payloadsize = 4618 nalus_count = 1
nalu marked as invalid
*** ERROR decryption of video packet failed
raop_rtp video: now = 1675823436.095691, ntp = 1675823436.135846, latency = -0.040155
nalu_type = 29, nalu_size = 429920952,  processed bytes 429920956, payloadsize = 3625 nalus_count = 1
nalu marked as invalid
*** ERROR decryption of video packet failed
raop_rtp video: now = 1675823436.128273, ntp = 1675823436.169184, latency = -0.040911
nalu marked as invalid
*** ERROR decryption of video packet failed
raop_rtp video: now = 1675823436.161626, ntp = 1675823436.202521, latency = -0.040895
nalu marked as invalid
*** ERROR decryption of video packet failed
raop_rtp video: now = 1675823436.195073, ntp = 1675823436.235859, latency = -0.040786
nalu_type = 17, nalu_size = 1229717987,  processed bytes 1229717991, payloadsize = 1918 nalus_count = 1
nalu marked as invalid
*** ERROR decryption of video packet failed
raop_rtp video: now = 1675823436.228676, ntp = 1675823436.269196, latency = -0.040520
nalu_type = 14, nalu_size = 652053930,  processed bytes 652053934, payloadsize = 847 nalus_count = 1
nalu marked as invalid
*** ERROR decryption of video packet failed
raop_rtp video: now = 1675823436.261509, ntp = 1675823436.302534, latency = -0.041025
nalu marked as invalid
*** ERROR decryption of video packet failed
raop_rtp video: now = 1675823436.295375, ntp = 1675823436.335871, latency = -0.040496
nalu marked as invalid
*** ERROR decryption of video packet failed
raop_rtp video: now = 1675823436.328345, ntp = 1675823436.369208, latency = -0.040863
nalu marked as invalid
*** ERROR decryption of video packet failed
raop_rtp video: now = 1675823436.362056, ntp = 1675823436.402546, latency = -0.040490
nalu_type = 30, nalu_size = 983958017,  processed bytes 983958021, payloadsize = 134 nalus_count = 1
nalu marked as invalid
*** ERROR decryption of video packet failed
raop_rtp video: now = 1675823436.395208, ntp = 1675823436.435883, latency = -0.040675
nalu_type = 22, nalu_size = 594471330,  processed bytes 594471334, payloadsize = 335 nalus_count = 1
nalu marked as invalid
*** ERROR decryption of video packet failed
raop_rtp video: now = 1675823436.428977, ntp = 1675823436.469221, latency = -0.040244
nalu marked as invalid
*** ERROR decryption of video packet failed
raop_rtp video: now = 1675823436.477683, ntp = 1675823436.519227, latency = -0.041544
nalu_type = 2, nalu_size = 1920500158,  processed bytes 1920500162, payloadsize = 340 nalus_count = 1
nalu marked as invalid
*** ERROR decryption of video packet failed
raop_rtp video: now = 1675823436.527819, ntp = 1675823436.569233, latency = -0.041414
nalu_type = 2, nalu_size = 464201315,  processed bytes 464201319, payloadsize = 286 nalus_count = 1
nalu marked as invalid
*** ERROR decryption of video packet failed
raop_rtp video: now = 1675823436.577700, ntp = 1675823436.619239, latency = -0.041539
nalu marked as invalid
*** ERROR decryption of video packet failed
raop_rtp video: now = 1675823436.627814, ntp = 1675823436.669245, latency = -0.041431
nalu_type = 8, nalu_size = 570113079,  processed bytes 570113083, payloadsize = 246 nalus_count = 1
nalu marked as invalid
*** ERROR decryption of video packet failed

Received video streaming performance info packet from client
raop_rtp video: now = 1675823436.677785, ntp = 1675823436.719251, latency = -0.041466
nalu marked as invalid
*** ERROR decryption of video packet failed
raop_rtp video: now = 1675823436.728197, ntp = 1675823436.769257, latency = -0.041060
nalu marked as invalid
*** ERROR decryption of video packet failed
raop_rtp video: now = 1675823436.777673, ntp = 1675823436.819264, latency = -0.041591
nalu marked as invalid
*** ERROR decryption of video packet failed
raop_rtp video: now = 1675823436.827772, ntp = 1675823436.869270, latency = -0.041498
nalu marked as invalid
*** ERROR decryption of video packet failed
raop_rtp video: now = 1675823436.877651, ntp = 1675823436.919276, latency = -0.041625
nalu_type = 21, nalu_size = 1112522391,  processed bytes 1112522395, payloadsize = 150 nalus_count = 1
nalu marked as invalid
*** ERROR decryption of video packet failed
raop_rtp video: now = 1675823436.928075, ntp = 1675823436.969282, latency = -0.041207
nalu marked as invalid
*** ERROR decryption of video packet failed
raop_rtp video: now = 1675823436.977691, ntp = 1675823437.019288, latency = -0.041597
nalu_type = 24, nalu_size = 1754311085,  processed bytes 1754311089, payloadsize = 227 nalus_count = 1
nalu marked as invalid
*** ERROR decryption of video packet failed
raop_rtp video: now = 1675823437.027688, ntp = 1675823437.069294, latency = -0.041606
nalu_type = 7, nalu_size = 980883999,  processed bytes 980884003, payloadsize = 249 nalus_count = 1
nalu marked as invalid
*** ERROR decryption of video packet failed
raop_rtp video: now = 1675823437.077377, ntp = 1675823437.119300, latency = -0.041923
nalu_type = 31, nalu_size = 42257309,  processed bytes 42257313, payloadsize = 270 nalus_count = 1
nalu marked as invalid
*** ERROR decryption of video packet failed
raop_rtp video: now = 1675823437.127634, ntp = 1675823437.169306, latency = -0.041672
nalu marked as invalid
*** ERROR decryption of video packet failed
raop_rtp video: now = 1675823437.178281, ntp = 1675823437.219313, latency = -0.041032
nalu marked as invalid
*** ERROR decryption of video packet failed
raop_rtp video: now = 1675823437.209574, ntp = 1675823437.252650, latency = -0.043076
nalu_type = 24, nalu_size = 558853868,  processed bytes 558853872, payloadsize = 1388 nalus_count = 1
nalu marked as invalid
*** ERROR decryption of video packet failed
raop_rtp video: now = 1675823437.242059, ntp = 1675823437.285987, latency = -0.043928
nalu_type = 11, nalu_size = 984624638,  processed bytes 984624642, payloadsize = 2300 nalus_count = 1
nalu marked as invalid
*** ERROR decryption of video packet failed
raop_rtp video: now = 1675823437.279668, ntp = 1675823437.319325, latency = -0.039657
nalu_type = 10, nalu_size = 2146034857,  processed bytes 2146034861, payloadsize = 2876 nalus_count = 1
nalu marked as invalid
*** ERROR decryption of video packet failed
raop_rtp video: now = 1675823437.309356, ntp = 1675823437.352662, latency = -0.043306
nalu marked as invalid
*** ERROR decryption of video packet failed
raop_rtp video: now = 1675823437.341632, ntp = 1675823437.386000, latency = -0.044368
nalu marked as invalid
*** ERROR decryption of video packet failed
raop_rtp video: now = 1675823437.379395, ntp = 1675823437.419337, latency = -0.039942
nalu marked as invalid
*** ERROR decryption of video packet failed
raop_rtp video: now = 1675823437.408217, ntp = 1675823437.452674, latency = -0.044457
nalu_type = 14, nalu_size = 2118686937,  processed bytes 2118686941, payloadsize = 2706 nalus_count = 1
nalu marked as invalid
*** ERROR decryption of video packet failed
raop_rtp video: now = 1675823437.441526, ntp = 1675823437.486012, latency = -0.044486
nalu_type = 3, nalu_size = 911337957,  processed bytes 911337961, payloadsize = 2027 nalus_count = 1
nalu marked as invalid
*** ERROR decryption of video packet failed
raop_rtp video: now = 1675823437.479521, ntp = 1675823437.519349, latency = -0.039828
nalu marked as invalid
*** ERROR decryption of video packet failed
raop_rtp video: now = 1675823437.527901, ntp = 1675823437.569355, latency = -0.041454
nalu marked as invalid
*** ERROR decryption of video packet failed
raop_rtp video: now = 1675823437.577906, ntp = 1675823437.619362, latency = -0.041456
nalu_type = 5, nalu_size = 303363718,  processed bytes 303363722, payloadsize = 386 nalus_count = 1
nalu marked as invalid
*** ERROR decryption of video packet failed
raop_rtp video: now = 1675823437.628323, ntp = 1675823437.669368, latency = -0.041045
httpd receiving on socket 27
nalu_type = 22, nalu_size = 198211114,  processed bytes 198211118, payloadsize = 334 nalus_count = 1
nalu marked as invalid
*** ERROR decryption of video packet failed
conn_request

POST /feedback RTSP/1.0
CSeq: 9
DACP-ID: 8187D50032A23CA6
Active-Remote: 3272830738
User-Agent: AirPlay/615.12.1

Handling request POST with URL /feedback
raop_handler_feedback

RTSP/1.0 200 OK
CSeq: 9
Server: AirTunes/220.68

Received video streaming performance info packet from client
raop_rtp video: now = 1675823437.659083, ntp = 1675823437.702705, latency = -0.043622
nalu marked as invalid
*** ERROR decryption of video packet failed
raop_rtp video: now = 1675823437.727970, ntp = 1675823437.769380, latency = -0.041410
nalu marked as invalid
*** ERROR decryption of video packet failed
raop_rtp video: now = 1675823437.777885, ntp = 1675823437.819386, latency = -0.041501
nalu_type = 25, nalu_size = 1572466074,  processed bytes 1572466078, payloadsize = 122 nalus_count = 1
nalu marked as invalid
*** ERROR decryption of video packet failed
raop_rtp video: now = 1675823437.828140, ntp = 1675823437.869392, latency = -0.041252
nalu marked as invalid
*** ERROR decryption of video packet failed
raop_rtp video: now = 1675823437.877934, ntp = 1675823437.919398, latency = -0.041464
nalu_type = 0, nalu_size = 359470841,  processed bytes 359470845, payloadsize = 160 nalus_count = 1
nalu marked as invalid
*** ERROR decryption of video packet failed
raop_rtp video: now = 1675823437.927985, ntp = 1675823437.969404, latency = -0.041419
nalu marked as invalid
*** ERROR decryption of video packet failed
raop_rtp video: now = 1675823437.977903, ntp = 1675823438.019410, latency = -0.041507
nalu_type = 9, nalu_size = 1422417826,  processed bytes 1422417830, payloadsize = 242 nalus_count = 1
nalu marked as invalid
*** ERROR decryption of video packet failed
raop_rtp video: now = 1675823438.028003, ntp = 1675823438.069417, latency = -0.041414
nalu marked as invalid
*** ERROR decryption of video packet failed
raop_rtp video: now = 1675823438.077599, ntp = 1675823438.119423, latency = -0.041824
nalu_type = 31, nalu_size = 1458180249,  processed bytes 1458180253, payloadsize = 238 nalus_count = 1
nalu marked as invalid
*** ERROR decryption of video packet failed
raop_rtp video: now = 1675823438.130542, ntp = 1675823438.169429, latency = -0.038887
nalu_type = 27, nalu_size = 306217286,  processed bytes 306217290, payloadsize = 1666 nalus_count = 1
nalu marked as invalid
*** ERROR decryption of video packet failed
raop_rtp video: now = 1675823438.177987, ntp = 1675823438.219435, latency = -0.041448
nalu marked as invalid
*** ERROR decryption of video packet failed
httpd receiving on socket 27
conn_request

SET_PARAMETER rtsp://169.254.88.93/7342205593126650935 RTSP/1.0
Content-Length: 20
Content-Type: text/parameters
CSeq: 10
DACP-ID: 8187D50032A23CA6
Active-Remote: 3272830738
User-Agent: AirPlay/615.12.1

volume: -30.000000

Handling request SET_PARAMETER with URL rtsp://169.254.88.93/7342205593126650935

RTSP/1.0 200 OK
CSeq: 10
Server: AirTunes/220.68

raop_rtp video: now = 1675823438.209324, ntp = 1675823438.252772, latency = -0.043448
nalu marked as invalid
*** ERROR decryption of video packet failed
raop_rtp_mirror tcp socket is closed, got 0 bytes of 128 byte header
httpd receiving on socket 27
conn_request

TEARDOWN rtsp://169.254.88.93/7342205593126650935 RTSP/1.0
Content-Length: 69
Content-Type: application/x-apple-binary-plist
CSeq: 11
DACP-ID: 8187D50032A23CA6
Active-Remote: 3272830738
User-Agent: AirPlay/615.12.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>streams</key>
    <array>
        <dict>
            <key>type</key>
            <integer>110</integer>
        </dict>
    </array>
</dict>
</plist>

Handling request TEARDOWN with URL rtsp://169.254.88.93/7342205593126650935
<?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>streams</key>
    <array>
        <dict>
            <key>type</key>
            <integer>110</integer>
        </dict>
    </array>
</dict>
</plist>

TEARDOWN request,  96=0, 110=1
raop_rtp_mirror error in select
raop_rtp_mirror exiting TCP thread

RTSP/1.0 200 OK
CSeq: 11
Server: AirTunes/220.68
Connection: close

httpd receiving on socket 27
conn_request

TEARDOWN rtsp://169.254.88.93/7342205593126650935 RTSP/1.0
Content-Length: 42
Content-Type: application/x-apple-binary-plist
CSeq: 12
DACP-ID: 8187D50032A23CA6
Active-Remote: 3272830738
User-Agent: AirPlay/615.12.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/>
</plist>

Handling request TEARDOWN with URL rtsp://169.254.88.93/7342205593126650935
<?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/>
</plist>

TEARDOWN request,  96=0, 110=0

RTSP/1.0 200 OK
CSeq: 12
Server: AirTunes/220.68
Connection: close

httpd receiving on socket 30
Connection closed for socket 30
Destroying connection
httpd receiving on socket 27
Connection closed for socket 27
Destroying connection
raop_ntp stopping time thread
raop_ntp exiting thread
raop_ntp stopped time thread
fduncanh commented 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

https://pyatv.dev/

fduncanh commented 1 year ago

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....

shuax commented 1 year ago

I tested that set old_protocol =true seems to be able to decrypt and a fast connection

fduncanh commented 1 year ago

@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?

shuax commented 1 year ago

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.

shuax commented 1 year ago

In short, don't use ecdh_secret for the key when using 0x527FFEE6

fduncanh commented 1 year ago

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?

shuax commented 1 year ago

I think AirMyPc ignores the features flag that it only uses one encryption method.

fduncanh commented 1 year ago

@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, ?

shuax commented 1 year ago

Yes, I am using my ipad for testing. I suggest not to use ecdh_secret when no pair message is received.

fduncanh commented 1 year ago

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 
shuax commented 1 year ago

When bit 27 is false, there seems not call /pair-setup.

fduncanh commented 1 year ago

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.

shuax commented 1 year ago

set bit 27 = 0 connection will be much faster, I recommend this

fduncanh commented 1 year ago

how much faster? Usually one just connects a few times at most?

fduncanh commented 1 year ago

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.

shuax commented 1 year ago

It will connect about 5 seconds before the modification, and it will connect 1 second after the modification.

fduncanh commented 1 year ago

Interesting. some option for "fast connection without pairing" could be added

fduncanh commented 1 year ago

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.

shuax commented 1 year ago

I just test SupportsLegacyPairing, and I don't know much about other knowledge.

fduncanh commented 1 year ago

@shuax It's great that you are discovering new things about the protocol!

thiccaxe commented 1 year ago

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.

fduncanh commented 1 year ago

@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.

fduncanh commented 1 year ago

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?

fduncanh commented 1 year ago

Updates to use @shuax 's find are tested and now in the github master branch, for a future UxPlay-1.65 release

fduncanh commented 9 months ago

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.

shuax commented 9 months ago

Are you trying to research pairing codes? This code may be useful.

https://github.com/phonegapX/AirPlay/blob/94ae91c35673df6e48b7ed743022d4528a6fbdce/AirplayLibrary/AirPlay/lib/raop.c#L1371

fduncanh commented 9 months ago

@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

fduncanh commented 9 months ago

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