Open ghost opened 8 years ago
You're doing something slightly different as you're emulating the sender and sending to an Apple receiver (i.e.: the Apple TV), we are mostly discussing here the receiver side so we are always receiving steams from Apple senders and we are emulating what the Apple receivers do.
From what I know you don't need to do anything special with the IV in older versions, just encrypt the data with the same key/IV you pass in, but on older versions the key/IV used to be passed as a plist to the POST /stream call as param1/param2 inline with the h264 encoded/encrypted stream.
Once they changed it in iOS 9 to send it as part of the SETUP payload as ekey/eiv is when the derivation by hashing it with the streamCnnectionId that was sent on the subsequent SETUP call started being needed.
On Tue, Jun 6, 2017 at 6:39 PM bobj1212 notifications@github.com wrote:
i meant to the appletv software. on atv2 the latest one is 6.2.1 so no as said, i am checking on atv2. so i use the generated aes key and iv. Maybe it will help if you can let me know which lib you use for the aes_ctr encryption. and as said, if i need to do something special with the iv on each call to the encryption function.
Thanks.
— You are receiving this because you were mentioned. Reply to this email directly, view it on GitHub https://github.com/espes/Slave-in-the-Magic-Mirror/issues/12#issuecomment-306637602, or mute the thread https://github.com/notifications/unsubscribe-auth/AATd-VYb3-4gaNcnbHbmS6onpoY3JfLiks5sBdUigaJpZM4GRiD8 .
Check the POST /stream
bplist described here @bobj1212 .
I did, didn't have time to look at it yet, Will let you know if I spot something. On Thu, Jun 8, 2017 at 8:03 AM bobj1212 notifications@github.com wrote:
Hi @robertoandrade https://github.com/robertoandrade. I have send you an email yesterday with my hash function. and some key output example. Just wonder if you got my email or it went to your spam. Thanks!
— You are receiving this because you were mentioned. Reply to this email directly, view it on GitHub https://github.com/espes/Slave-in-the-Magic-Mirror/issues/12#issuecomment-307083268, or mute the thread https://github.com/notifications/unsubscribe-auth/AATd-a3K4WK_rxg_vyNHwg4mBrTrY0qkks5sB-MigaJpZM4GRiD8 .
Really hope you will find the error because i stuck on this for days ... Thanks!
@robertoandrade I can only receive the data with type 5 every one second , do you know why?
I set the feature to 0x527FFFF7
@carryinfo what data do you return in GET /info and in second SETUP message?
@maciejjj the return, for info:
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>audioFormat</key>
<array>
<dict>
<key>audioInputFormats</key>
<integer>67108860</integer>
<key>audioOutputFormats</key>
<integer>67108860</integer>
<key>type</key>
<integer>100</integer>
</dict>
<dict>
<key>audioInputFormats</key>
<integer>67108860</integer>
<key>audioOutputFormats</key>
<integer>67108860</integer>
<key>type</key>
<integer>101</integer>
</dict>
</array>
<key>audioLatencies</key>
<array>
<dict>
<key>outputLatencyMicros</key>
<integer>0</integer>
<key>inputLatencyMicros</key>
<integer>0</integer>
<key>type</key>
<integer>100</integer>
<key>audioType</key>
<string>default</string>
</dict>
<dict>
<key>outputLatencyMicros</key>
<integer>0</integer>
<key>inputLatencyMicros</key>
<integer>0</integer>
<key>type</key>
<integer>101</integer>
<key>audioType</key>
<string>default</string>
</dict>
</array>
<key>displays</key>
<array>
<dict>
<key>rotation</key>
<false/>
<key>overscanned</key>
<true/>
<key>uuid</key>
<string>e5f7a68d-7b0f-4305-984b-974f677a150b</string>
<key>feature</key>
<integer>14</integer>
<key>width</key>
<integer>1280</integer>
<key>widthPixels</key>
<integer>1280</integer>
<key>height</key>
<integer>720</integer>
</dict>
</array>
<key>sourceVersion</key>
<string>220.00</string>
<key>keepAliveLowPower</key>
<true/>
<key>model</key>
<string>AppleTV3,2</string>
<key>name</key>
<string>Airplay Receiver</string>
<key>features</key>
<integer>1518338039</integer>
<key>vv</key>
<integer>2</integer>
<key>keepAliveSendStatsAsBody</key>
<false/>
<key>statusFlags</key>
<integer>68</integer>
</dict>
</plist>
for the second setup
<!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>
<key>dataPort</key>
<integer>53758</integer>
</dict>
</array>
</dict>
</plist>
is there any problem ?
@carryinfo it seems you're missing couple of fields, take a look (also notice that you need to set pk ). And your features in service doesn't match the one in info.
<?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>audioFormats</key>
<array>
<dict>
<key>audioInputFormats</key>
<integer>67108860</integer>
<key>audioOutputFormats</key>
<integer>67108860</integer>
<key>type</key>
<integer>100</integer>
</dict>
<dict>
<key>audioInputFormats</key>
<integer>67108860</integer>
<key>audioOutputFormats</key>
<integer>67108860</integer>
<key>type</key>
<integer>101</integer>
</dict>
</array>
<key>audioLatencies</key>
<array>
<dict>
<key>audioType</key>
<string>default</string>
<key>inputLatencyMicros</key>
<integer>0</integer>
<key>outputLatencyMicros</key>
<integer>0</integer>
<key>type</key>
<integer>100</integer>
</dict>
<dict>
<key>audioType</key>
<string>default</string>
<key>inputLatencyMicros</key>
<integer>0</integer>
<key>outputLatencyMicros</key>
<integer>0</integer>
<key>type</key>
<integer>101</integer>
</dict>
</array>
<key>deviceID</key>
<string>00:00:00:00:00:00</string>
<key>displays</key>
<array>
<dict>
<key>features</key>
<integer>14</integer>
<key>height</key>
<integer>1080</integer>
<key>heightPhysical</key>
<integer>0</integer>
<key>heightPixels</key>
<integer>1080</integer>
<key>overscanned</key>
<integer>0</integer>
<key>refreshRate</key>
<integer>60</integer>
<key>rotation</key>
<integer>1</integer>
<key>uuid</key>
<string>e5f7a68d-7b0f-4305-984b-974f677a150b</string>
<key>width</key>
<integer>1080</integer>
<key>widthPhysical</key>
<integer>0</integer>
<key>widthPixels</key>
<integer>1080</integer>
</dict>
</array>
<key>features</key>
<integer>130233139191</integer>
<key>keepAliveLowPower</key>
<integer>1</integer>
<key>keepAliveSendStatsAsBody</key>
<integer>1</integer>
<key>macAddress</key>
<string>00:00:00:00:00:00</string>
<key>model</key>
<string>AppleTV3,2</string>
<key>name</key>
<string>Apple TV</string>
<key>pi</key>
<string>5e66cf9b-0a39-4e0c-9d32-081a8ce63231</string>
<key>pk</key>
<data>
44 bytes of random data?
</data>
<key>sourceVersion</key>
<string>220.68</string>
<key>statusFlags</key>
<integer>68</integer>
<key>vv</key>
<integer>1</integer>
</dict>
</plist>
@maciejjj thanks for your help
now i can successfully get the video data
another issue,do you known how to set the video fps and bitrate ? I tried refreshRate for fps, but failed 😱
@maciejjj have you figured out the artifacts vs payload type 5 enigma?
@robertoandrade use /info I pasted above to get rid of artifacts. So I don't use payload 5 at all, but I'm really curious what is it:)
@carryinfo I tried to modify video settings but was unsuccessful, so if you come up with anything please let me know!
Thanks @maciejjj frrom what I could test and confirm the main difference is setting displays[0].overscanned = false
instead of true
like I had to avoid the payload type 5 and artifacts coming through.
Has anyone on the list figured out the exact logic of the pair-setup
and pair-verify
requests? I've been taking notes and examining the contents of both requests and responses and have an overall idea but was just wondering if anyone was further along in understanding them.
FYI, screen recorder has been supported on iOS11 beta.
@cbangchen yeah working just fine here on iOS11 beta as well. Still looking for an alternative implementation of the FairPlay handshake code as well as the pair-setup/pair-verify
sequence.
Experimenting with playfair but not getting the results I expected from decryption of the AES key after sending in the fp-setup
calls.
I am trying to create a server that will support (initially) AirPlay mirroring. I have gotten the Bonjour configuration setup so that an iPad/iPhone identifies my server as an Airplay device that supports mirroring.
I am now trying to handle the "/fp-setup" messages. Does anyone have any documentation/sudo-code that documents how to properly create the "FPLY302" and "FPLY304" messages to reply to "fp-setup"???
NOTE: I have tried looking at the "AirSpeaker", and "Slave-in-the-Magic-Mirror" source code, but I'm a C/C++ programmer, and not good at deciphering Python/Go/Java source code.
Thanks in advance for any help you can offer.
Check my fork of playfair. On Tue, Aug 1, 2017 at 5:04 PM MediaWiz notifications@github.com wrote:
I am trying to create a server that will support (initially) AirPlay mirroring. I have gotten the Bonjour configuration setup so that an iPad/iPhone identifies my server as an Airplay device that supports mirroring.
I am now trying to handle the "/fp-setup" messages. Does anyone have any documentation/sudo-code that documents how to properly create the "FPLY302" and "FPLY304" messages to reply to "fp-setup"???
NOTE: I have tried looking at the "AirSpeaker", and "Slave-in-the-Magic-Mirror" source code, but I'm a C/C++ programmer, and not good at deciphering Python/Go/Java source code.
Thanks in advance for any help you can offer.
— You are receiving this because you were mentioned. Reply to this email directly, view it on GitHub https://github.com/espes/Slave-in-the-Magic-Mirror/issues/12#issuecomment-319496575, or mute the thread https://github.com/notifications/unsubscribe-auth/AATd-SWS6tLcBjaNkv01mQDwgo_iTzduks5sT5LxgaJpZM4GRiD8 .
Hello @robertoandrade , Thank you for your source code. I have got your source code of playfair , and build in centos successfully. These are some trouble with me, and could you help me ? 1, The http listen port is alway no change , but I know the port of Airplay is different every time , so It is mean I need get the listen port first ? and how can I get those port ? 2, Before http listen , Airplay must has a mDNS first , and how to analy those packetage ? 3, Is it could be no reply when receive like "/pair-set" ? I have no find any option for this string in the code .
Thanks all, really a great help!
From discussion above, I start from Playfair, Skip /pair-setup /pair-verify and Get vidoe encrypted data. Following your instruction
hashes it with a predefined set of strings (ie: AirPlayStreamKey/AirPlayStreamIV) as well as the streamConnectionID of each stream ".
I write function DoHashKey(), where conn is a context holding Decrypted key from Fairplay. pConnSetupInfo contains connection stream ID ( video ) I tried big and little endian conn ID byte order and even convert to long. neither does work. `
void CRaopServer::DoHashKey( CRaopContext& conn, LP_BPSetupInfo_t pConnSetupInfo, BOOL bReorderID, BOOL bConvertIDlong ) { SHA512_CTX sha512cxt; unsigned char szSha[64];
LONGLONG hnRawOrder;
if ( bReorderID )
{
hnRawOrder = 0;
for ( int k = 0; k <8; k ++ )
{
hnRawOrder = (hnRawOrder<<8) | *((BYTE *)&pConnSetupInfo->hiVideoConnID + k );
}
}
else
{
hnRawOrder = pConnSetupInfo->hiVideoConnID;
}
memset( szSha, 0, sizeof(szSha) );
SHA512_Init( &sha512cxt );
SHA512_Update( &sha512cxt, "AirPlayStreamIV", strlen("AirPlayStreamIV") );
if ( bConvertIDlong )
{
SHA512_Update( &sha512cxt, &hnRawOrder, sizeof(long) );
}
else
{
SHA512_Update( &sha512cxt, &hnRawOrder, sizeof(hnRawOrder) );
}
SHA512_Update( &sha512cxt, conn.GetDecAesKey(), conn.GetDecAesKeyLen() );
SHA512_Final( szSha, & sha512cxt );
OPENSSL_cleanse(&sha512cxt, sizeof(sha512cxt));
conn.CopyEiv( szSha, 16 ); //save the real decryt IV
memset( szSha, 0, sizeof(szSha) );
SHA512_Init( &sha512cxt );
SHA512_Update( &sha512cxt, "AirPlayStreamKey", strlen("AirPlayStreamKey") );
if ( bConvertIDlong )
{
SHA512_Update( &sha512cxt, &hnRawOrder, sizeof(long) );
}
else
{
SHA512_Update( &sha512cxt, &hnRawOrder, sizeof(hnRawOrder) );
}
SHA512_Update( &sha512cxt, conn.GetDecAesKey(), conn.GetDecAesKeyLen() );
SHA512_Final( szSha, & sha512cxt );
OPENSSL_cleanse(&sha512cxt, sizeof(sha512cxt));
conn.CopyDecAesKey( szSha, 16 ); //save the real decryt code
} `
decryption data applied to 4096 as well as type 0. AES state extend frame or session. neither do work.
`
if ( m_bAesLifeSession )
{
AES_ctr128_encrypt(pInSrc, pDestDecrypt, iDataLen, &m_AesCxt, m_daIv, m_daAesCount, &m_nAesNum );
}
else
{
if ( bFirstSegInPacket )
{
Log( "FirstSetInPacket: Len: %d ", iDataLen );
m_nAesRunningNum = 0;
memcpy( m_daRunningIv ,m_daIv, sizeof(iv) );
memset( m_daAesRuningCount, 0, sizeof(ecount) );
}
else
{
Log( " After first Len: %d ", iDataLen );
}
AES_ctr128_encrypt(pInSrc, pDestDecrypt, iDataLen, &m_AesCxt, m_daRunningIv, m_daAesRuningCount, &m_nAesRunningNum );
}
`
any comments would be highly appreciated!
I have been using all your advice here to get video decoding working! Now I run into the problem that I do not know how to decode the audio? In this newer protocol, how is the audio encoded? I get the stream but the bytes don't seem right and ffmpeg complains they are not valid acc-eld data
In /info I see:
<array>
<dict>
<key>audioInputFormats</key>
<integer>67108860</integer>
Question: What is 67108860? Is it Apple Lossless codec? AAC? AAC-ELD? Is there table for these formats codes?
Thanks.
I believe all clients I've tested so far return the same constant which is indicative of the formats it supports (either AAC or ALAC). The client is the one that tells the server what format the stream it's sending is via the SETUP call.
they have an audioFormat plist property there which I've seen come in with either:
ALAC = 0x40000
AAC = 0x1000000
Does anyone know how the audio is encrypted?
with the AES Key/IV that is provided (FP encrypted) on the SETUP call?
Well for video its First 16 of SHAHash("AirPlayStream{the string 'Key' or 'IV'}{StreamConnectionID}{FairplayMasterKey}") In AES/CTR 128
But audio doesn't have a streamId so Im not sure what cipher or key/iv to use.
It’s the original AES key and IV sent on SETUP. On Sat, Sep 30, 2017 at 11:47 AM Michael Rogers notifications@github.com wrote:
Well for video its First 16 of SHAHash("AirPlayStream{the string 'Key' or 'IV'}{StreamConnectionID}{FairplayMasterKey}") In AES/CTR 128
But audio doesn't have a streamId so Im not sure what cipher or key/iv to use.
— You are receiving this because you were mentioned. Reply to this email directly, view it on GitHub https://github.com/espes/Slave-in-the-Magic-Mirror/issues/12#issuecomment-333316976, or mute the thread https://github.com/notifications/unsubscribe-auth/AATd-cLnb6t32E4lFZWYld7GtamtxZ0pks5snmKNgaJpZM4GRiD8 .
@robertoandrade Audio is encrypted in CBC mode ? or CTR ?
CBC I believe. I still have issues once I get The properly decrypted ALAC frames on putting them back together for playback, something weird regarding the playback rate (even though I have it with the 352 frames per sample, 16 bit, 2 channel settings) when wrapping it in an MP4 container with the ALAC magic cookie it still seems to be playing faster than the original (checked the frame duration headers and all) and with a few hiccups or audio artifacts here and there. Would appreciate if anyone has got any experience with the decoding part of the ALAC stream since it seems like decryption is working fine. On Tue, Oct 10, 2017 at 6:15 AM vitiluck notifications@github.com wrote:
@robertoandrade https://github.com/robertoandrade Audio is encrypted in CBC mode ? or CTR ?
— You are receiving this because you were mentioned. Reply to this email directly, view it on GitHub https://github.com/espes/Slave-in-the-Magic-Mirror/issues/12#issuecomment-335427275, or mute the thread https://github.com/notifications/unsubscribe-auth/AATd-XnPJ0CjnKewKzUnHZfCnMb_prQHks5sq0OqgaJpZM4GRiD8 .
@comwizz2 How to get the 'FairplayMasterKey'? Can you give me some advice?
SHAHash("AirPlayStream{the string 'Key' or 'IV'}{StreamConnectionID}{FairplayMasterKey}")
@suiye223 You get it through the /fp-setup calls. I did not write that code in my project, I received it from another developer and do not have rights to share it.
@robertoandrade aes cbc 128? The only key and IV I get sent during setup are "ekay" and "eiv" and they are 72 bytes and 16 bytes respectively, which means the key is the wrong size? Is it a subset of that blob? Sorry if I am bugging you, just information on this is sparce!
The ekey is an encrypted key (using FairPlay) so once you decrypt it you get 16 bytes which is the AES 128 bit key. On Wed, Oct 11, 2017 at 3:57 PM Michael Rogers notifications@github.com wrote:
@robertoandrade https://github.com/robertoandrade aes cbc 128? The only key and IV I get sent during setup are "ekay" and "eiv" and they are 72 bytes and 16 bytes respectively, which means the key is the wrong size? Is it a subset of that blob? Sorry if I am bugging you, just information on this is sparce!
— You are receiving this because you were mentioned. Reply to this email directly, view it on GitHub https://github.com/espes/Slave-in-the-Magic-Mirror/issues/12#issuecomment-335929482, or mute the thread https://github.com/notifications/unsubscribe-auth/AATd-Ye10CRSdkQog4oB950PeUvoILPhks5srR2qgaJpZM4GRiD8 .
when pair-setup/verify is skipped. key/iv from FairPlay,then do SHA512 AirPlayStream Key,IV and streamID. decode video is fine. when pair-setup/verify is enabled. former video decoding ---- invalid . pair-verify is authentication method to verify device identity. does it affect video data decoding process?
@robertoandrade Did you use the key provided when you were doing pair verify? Or did you skip pair verify?
@vitiluck @robertoandrade when capture mirror data, I have the following problems. My iphone version is 10.0. After the second fp-setup, client will send SETUP method data package as following,
SETUP rtsp://192.168.123.47/6108990559123033009 RTSP/1.0 Content-Length: 425 Content-Type: application/x-apple-binary-plist CSeq: 5 DACP-ID: E28CCF9054EDE3B9 Active-Remote: 3016615115 User-Agent: AirPlay/320.20
bplist00.......... .. .........RetTname]sourceVersionZtimingPortXdeviceIDUmodelZmacAddress^osBuildVersion[sessionUUIDTekeySeiv. ..GrandStream-6plusV320.20..&..D8:BB:2C:1F:28:94YiPhone7,1..D8:BB:2C:1F:28:92U14G60.$54C77E8B-F4BE-4BB1-A9D7-D246D6672D8BO.HFPLY.......<....?z.(...K`.....}.....'......W...B...6j..w.{^..d...,...!.O..Ds*..i#6...D.T.!.....".'.5.@.I.O.Z.i.u.z.~...................H...............................[ RTSP/1.0 200 OK Date: Thu, 19 Oct 2017 02:16:37 GMT CSeq: 5 Server: AirTunes/220.68 Content-Length: 284
<?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">
The x-apple-binary-plist format data was parsed as following: <?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">
and the return package should as following:
When my iphone connet to android receiver, iphone will promt the message 'cann't connect to xxx' How can I deal with eventPort and timingPort?
Some body can help me?
i just crack pair-setup/verify and solve the video/audio decode issue. and build our airplay mirror sdk for android/iOS/linux/windows.
we provide commercial support.
sorry for the bother.
The GET /info "pk" field is the Curve25519 public key. Create at PairSetup step. audioFormat ALAC = 0x40000 spf = 352 AAC = 0x400000 AAC-ELD = 0x1000000 spf = 480 I found standalone audio stream use ALAC, screen mirroring audio stream use AAC-ELD. Any one known the "ct" field means?
Anyone here familiar with what the PI field is supposed to be in the bonjour record?
@comwizz2 pi field just a guid string.
Anyone figured out the /fp-setup2 call yet? Seems this is needed for fairplay airplay streams (such as youtube video.)
I believe the default is replying with a 0 byte response, the data itself is not used from what I gathered in decrypting data since the Youtube sends a custom HLS URL that points to "localhost" for streaming the content. Haven't figured out how to crack that part yet.
So from reading a working stream, it seems if you respond to /fp-setup2 correctly, all communications become encrypted. Part of this I have observed is that if there are certain headers (x-apple-session I believe) you respond with HTTP/1.1 instead of RTSP/1.0, this is the only way I get the fp-setup2 call.
I've noticed that as well, responding to the GET /server-info with a features=0x0 also makes is so that it falls back to the older PTTH/1.0 protocol to send in the remote commands and state for playback after the fp-setup2.
From what I have seen of a working connection, I'm pretty sure that this fp-setup2 may be the key to fixing YouTube streams, because as you have said, other paths cause that useless localhost url path. The problem is figuring out what exact type of encryption and how to derive the key...
On Thu, Apr 19, 2018 at 11:26 AM Roberto Andrade notifications@github.com wrote:
I've noticed that as well, responding to the GET /server-info with a features=0x0 also makes is so that it falls back to the older PTTH/1.0 protocol to send in the remote commands and state for playback after the fp-setup2.
— You are receiving this because you were mentioned. Reply to this email directly, view it on GitHub https://github.com/espes/Slave-in-the-Magic-Mirror/issues/12#issuecomment-382798099, or mute the thread https://github.com/notifications/unsubscribe-auth/AFidfkzuJm5s7D7uipLiqA43LcFiYORnks5tqLrAgaJpZM4GRiD8 .
Thanks all of you guys.
I've tried your project but if you want to simulator x86 ,even arm instrument unicorn is a good choice @Hay187. I've make ios app with arm instruction running on Mac successfully.
I've tried your project but if you want to simulator x86 ,even arm instrument unicorn is a good choice @Hay187. I've make ios app with arm instruction running on Mac successfully.
HI. I find someone had implemented the mirror function in ios12 based on shairplay. https://github.com/dsafa22/AirplayServer. But it is for android system.
I combine two pieces of code in https://github.com/561546441/shairplay the mirroring handshake seem to be success。 But I can not find the mirroring stream from client. Can you spend on a little of time to see why?
@robertoandrade @espes
So i've managed to get iOS9 to negotiate and start sending data. The config record looks correct (non encrypted). But the video data makes no sense once decrypted.
It appears that the key must have changed.
I tried to find a decrypted version of the newest formware for apple TV but I can't seem to find one. Emulating thumb is not a problem if i can find the firmware.
Any ideas