Closed Jack-lx closed 6 years ago
hi,if anybody known to deal with POST /pair-verify or /pair-setup session, please email to me my email:yong253535551@163.com
hi, i find code that can deal with pair-setup https://github.com/AlfredHunter/WifiAirCleaner/tree/6b03b730aaa72d817cff426d2237966ce984d801/Demos/COM.Apple.HomeKit
hi, im reseaching on AirPlay, I found when I publish AirPlay service with:
txt.append(26); txt.append("deviceid="); txt.append(GetMacAddress()); // supposed to be: 0: video, 1:Phone, 3: Volume Control, 4: HLS // 9: Audio, 10: ? (but important without it it fails) 11: Audio redundant txt.append(24); txt.append("features=0x5A7FFFF7,0x1E"); txt.append(10); txt.append("flags=0x44"); txt.append(17); txt.append("model=AppleTV3,2C"); txt.append(36); txt.append("pk=7f2f132f6f6f64fff4ff6f2fff3f42f51"); txt.append(14); txt.append("srcvers="AIRPLAY_SERVER_VERSION_STR); txt.append(4); txt.append("ch=2");
notice that the pk=7f2f132f6f6f64fff4ff6f2fff3f42f51. I guess it is the private key, with this key at the pair-verify step, iPhone send to my App the hex string (this hex string changed every the iPhone send to App): (1) 01000000418cd3e6d6d01e6f01259e2411e9a8aff4849bac4abcb9a005b4d637ee4d1122d192b65eac6e37b1465038f7d23ee1ad1728cad406d41f118d4005bf1c15fd55
and we need to send back the hex string: (2) 78ef4d6f63eb73c40781ab621a392b53c2d607c650eb0f52f81ab685d096a400f0610341a6dd4c59cc8f53dcf04305e691aa86ba1a658a0bc5df06b45ba3d7d9bfbd0275cfb0797838e0ee2bec882c8519b89d7518ec7318653ab64c372f9e25
but I dont know how to Decode (1) string iPhone send to app to (2) string, did you find the way to deal with the pair-verify session, plz share to me, thank you so much
@yong253535551 @anhhna I check the HomeKit stuff. It only deal with application/x-tlv8. Nothing about application/octet-stream. I have same issue which you mentioned above. And I don't know how to do next. Did you fix your issue ?
I am facing same issue, if anybody know the solution for how to decode or what string should we pass please let me know. Thank you in advance.
@yong253535551 @anhhna @shahasachin @Derek0425 @vranki ,Did you fix this issue ?homekit can't resolve this!
@Jack-lx, Didn't get solution. Yes, configured homekit but didn't get any solution.
@Jack-lx have you found out how to handle setup and verify steps?
Hello everyone! @funtax has reverse-engineered the Apple TV Device Verification. Here is the link to his Java-library: AirPlayAuth. I believe this will help you to solve this issue.
There's also an implementation available in Python & ObjectiveC and C.
Thank you @ViktoriiaKh for letting me know, and huge thanks for @funtax for the work! It's a bit hectic right now but I'll try to find some time for this.
@funtax It looks like your implementation is only for /setup-pair-pin | binary-plist which is not the requests servers seem to get from Mac OS X. Have you figured out anything about the /pair-setup with a content type of octetstream?
Hey @comwizz2, sadly not, I have only focused a this implementation (done by reverse-engineering another app) as this was required by mine.
@funtax implementation's seems to do the client-side of the /pair-verify
step, even though it doesn't handle the /pair-setup
, I notice that responding with random 32 bytes (or echoing back the same input) gets you to the next step, which is the verify one. Given the data it sends on the setup is also sent on the verify (ie: last 32 bytes) I'm wondering what the response from the first is used for if at all, given the request for verify doesn't seem to use it (unless it's using that as the edDSA Auth Key).
Any clues as to what the official client checks on the response for the first pair-verify call (it looks like from that code it's expecting the first 32 bytes to be the server public key and the last 64 just some random blob used for the signature that is sent on the 3rd step, but how does it verify that either the public key or the signature blob have anything to do with either the response from /pair-setup
or even the pk
entry on the mDNS broadcast I'm still puzzled to find out.
@robertoandrade I sadly removed the part where the verification of the mDNS "pk"-value as it wasn't mandatory for my case. Renaming the library and moving code broke the history in IntelliJ. The code I reverse-engineered was developed in scrambled Javascript.
I tried to re-code it a bit into Java.. it won't compile but might help:
` // line 235 in https://github.com/funtax/AirPlayAuth/blob/master/src/main/java/eu/airaudio/airplay/auth/AirPlayAuth.java
Cipher aesCtr128Encrypt = Cipher.getInstance("AES/CTR/NoPadding");
aesCtr128Encrypt.init(Cipher.ENCRYPT_MODE, new SecretKeySpec(sharedSecretSha512AesKey, "AES"), new IvParameterSpec(sharedSecretSha512AesIV));
// start edit
EdDSAEngine edDSAEngine = new EdDSAEngine();
byte[] signatureForVerify = aesCtr128Encrypt.update(Arrays.copyOfRange(pairVerify1Response, 32, pairVerify1Response.length));
byte[] messageToVerify = AuthUtils.concatByteArrays(atvPublicKey, randomPublicKey);
byte[] thePKFromMdns = new byte[32]; // I think was from Base64 mdns[extras][pk]
edDSAEngine.initVerify(thePKFromMdns);
if (edDSAEngine.verifyOneShot(messageToVerify, signatureForVerify)) {
System.out.println("Signature verification successful!");
}
// end edit
edDSAEngine = new EdDSAEngine();
edDSAEngine.initSign(authKey);`
Ok, awesome @funtax thanks for sharing this.
I'm trying to decipher what are the last 64 bytes of that 96 byte response from the first pair-verify
, but from your client code it's not clear if if it's the simple concatenation of the server public key with the client public key given they try to verify that was the message signed via the PK (assuming another Public Key) in the mDNS record.
Ok, I figured it out, just needed to do the inverse on the server, sign the server curve public key + client curve public key with the EdDSA private key and decrypt it with the derived AES key from the shared secret composed from the server curve private key and the client curve public key.
Thanks a bunch @funtax for the information, this was a lifesaver!
I'm super-happy to read this @robertoandrade . Really great news and good to know that my stuff has helped you :)
Anyone know of any example c/c++ code for handling /pair-setup and /pair-verify messages sent to the AirPlay server by a connected device??? (or if not, perhaps some sudo-code?)
I see some mention of Java code above, but I'm not fluent in Java, and not good at deciphering the logic.
Hey @htartisan, you mean the client-side that connects to the Apple TV/AirPlay-receiver?
No. I am trying to write write code for an AirPlay "server" device, that would support AirPlay mirroring. I can't find any documentation on how to do this (even from Apple), or any example code.
So far, I have successfully created the Bonjour server entry, and I can see the data from the "/pair-setup" message coming into my server code. I do not know how to interpret the "octec-stream" data that is being sent, or how to create the appropriate response. Beyond that, I know that I need to handle the "/pair-verify" message (interpret it's data) and create the appropriate response to that as well.
I would be very helpful for any help that anyone can offer.
NOTE: AirPlay "server" device = a device that is connected to a monitor/TV, that can receive AirPlay streams.
Depending on what kind of streams you want to process on your AirPlay "server" (aka receiver in Apple's lingo), you don't need to handle the pairing requests @htartisan, are you trying to handle Screen Mirroring, Audio, Remote Media or all of those?
Initially, I am just trying to get Screen Mirroring to work. I will probably want to get audio, and perhaps even video to work in the future, but if I can just get the Screen Mirroring to work, that would be a big victory.
Yeah for that you don't need to handle the pair-setup/pair-verify calls (with the proper mDNS broadcast), you'll only need to do that for sure to handle remote video streams.
You may wanna take a look at the long discussion we've had on https://github.com/espes/Slave-in-the-Magic-Mirror/issues/12
I'll look there. Thanks!
@robertoandrade @funtax Thank you.
I received a lot of help.
Starting with golang's Airplay mirroring server related code ... Https://github.com/Vluxe/nighthawk Https://github.com/philippe44/RAOP-Player Https://github.com/funtax/AirPlayAuth Https://github.com/espes/Slave-in-the-Magic-Mirror Https://github.com/robertoandrade/playfair
I succeeded in protocol processing and mirroring data decryption in iOS 7 and 8. In iOS 10.3.3, pair-verify succeeds, but does not solve the mirroring data decryption key problem. (If features are given as 0x2beff7, you can go to the next step, fp-setup, without pair-verify.)
Did you solve the key problem?
heya @funtax I was looking at using advertise mode 0x5A7FFFF7 instead of 0x527FFFF7 which forces the pairing to occur and I noticed the AES Key the clients use to encrypt the data (mirroring/audio) is different than the one they use it without pairing.
I was wondering if in your AirAudio implementation (which doesn't seem to be open source from what I could tell) you had any hints as to how the shared secret using during the pairing is used later on to derive the AES Key to be used to encrypt the actual streams?
Hey @robertoandrade, I am sorry but I have no more knowledge about the usage of the encryption-keys. AirAudio + AirSpot do audio-transmission via the AirPlay/AirTunes-protocol and this uses a key that is used within all clients/servers: https://www.theiphonewiki.com/wiki/AirPlay#Encryption
@kcosmos4 hi, i noticed that you have In iOS 10.3.3, pair-verify succeeds,can you tell me the detail information?thank u so much.
To be more specific, the relevant code seems to be at https://github.com/phonegapX/AirPlay/blob/master/AirplayLibrary/AirPlay/lib/raop.c#L1288
I have been too preoccupied by other stuff lately, but I'm hoping I would have time to at least do some initial tests of integrating this to the main codebase.
Got it, I found the different in curve25519_donna-c64. Replace this file with your code, I pass the pair-verify.
@juhovh 哈哈,是啊。中国人歪点子多。
Just out of curiosity, do you mean the if (basepoint == NULL) basepoint = kCurve25519BasePoint;
line when you say the difference in curve25519_donna-c64?
Yep...
Hey guys,
Having issues on ios 11.3.
In airserver I see:
INFO pair-setup/pair-verify 0/pairverify 1 fp-setup 1 fp-setup 2 SETUP (no streams) INFO RECORD GET/SET PARAMETER (volume) SETUP (with streams)
My code works fine until the last setup. I don't get any second setup message at all. Do you have your code working on ios 11.3? Can you confirm the flow you see?
@kam187 last I checked the flow is the same in 11.3, depending on what you're playing on the sender, you may even get a 3rd SETUP call (one for screen and one for audio).
Hmm, I wonder why I don't get the second setup. Does your code work with ios 11.3?
yep, but my codebase is not related to this project at all.
Ok found the issue, i wasn't sending a 'name' and 'pk' in the info. Previously i had disabled pair-verify :) . Working now.
Ok another issue. It seems on ios11.3 it does not connect back to the event port. It works fine on lower versions.
Nevermind it's down to sending an error on my part.
@382517366 是的,但是curve25519_donna这个函数跟你网上下到的有一点点小区别
@382517366 我不是对着这个工程开发的。我是开发遇到问题点刚好看到这里在讨论才进来讨论的。你直接使用https://github.com/phonegapX/AirPlay 这套代码里的这个库就没问题的。
@382517366 恩,对的,我们也是用64写的,没问题的。
Just to let you know, I have removed comments from notedit and modified references to his repo to point to phonegapX repo instead. It turns out the only reason notedit joined this discussion and cloned phonegapX's repository was to promote his proprietary SDK he is trying to sell, he has done no open source work on airplay protocol whatsoever.
Just to let you all know again, I have just pushed to master the code that is able to handle POST /pair-setup
and POST /pair-verify
requests successfully, fp-setup is still not handled but I guess I'll throw in some similar solution to that than what foxsen had but with a bit different implementation.
I have now committed a version of shairplay to master that allows receiving audio from iOS with the full /pair-setup
, /pair-verify
and /fp-setup
handshake. It is using https://github.com/EstebanKubata/playfair library and is only enabled with --with-playfair
configure flag, because the legal status of that library is unclear and it is GPLv3 therefore tainting the whole shairplay code. I have tested it to work with iOS 11.4.1 but it unfortunately does not work with iTunes because it uses a different version of fairplay. Hope this is helpful and have fun playing with it, closing this issue.
The chinese guys above seem to have cracked it! Trying to get their code running.
@jmvermeulen lol, there are so many product working correctly in China, if you pay me 10 thousands i will give you the code.
Kidding.
@tishion thanks for the edit, without it your comment was a bit too close to reality to be funny
@jmvermeulen the code in the phonegapX repository is very Windows specific, I've already ported the key exchange and fairplay decryption parts, and shairplay compiled with --with-playfair
is able to get working decryption keys for both screen mirroring and audio, just haven't got time to write the rest of it yet.
POST /pair-verify or /pair-setup,how to handle these seesion?
POST /pair-setup RTSP/1.0 Content-Length: 32 Content-Type: application/octet-stream CSeq: 0 DACP-ID: 82F0F5B508E73AF1 Active-Remote: 3453826074 User-Agent: AirPlay/280.32.2
-k8hS( aG
RTSP/1.0 200 OK CSeq: 0 Content-Length: 32 Audio-Jack-Status: connected; type=analog Server: AirTunes/230.33
y|XT^{W7zVSsoFzGt
POST /pair-verify RTSP/1.0 X-Apple-AbsoluteTime: 481732246 X-Apple-PD: 1 Content-Length: 68 Content-Type: application/octet-stream CSeq: 1 DACP-ID: 82F0F5B508E73AF1 Active-Remote: 3453826074 User-Agent: AirPlay/280.32.2
P(XGd^+a;5lmpH^-k8hS( aG
RTSP/1.0 200 OK CSeq: 1 Content-Length: 96 Audio-Jack-Status: connected; type=analog Server: AirTunes/230.33
^Ns`>shrPbg1xYy=L^Xne:|6OB#hi^9m-^O/S^lb
POST /pair-verify RTSP/1.0 X-Apple-AbsoluteTime: 481732247 X-Apple-PD: 1 Content-Length: 68 Content-Type: application/octet-stream CSeq: 2 DACP-ID: 82F0F5B508E73AF1 Active-Remote: 3453826074 User-Agent: AirPlay/280.32.2
j8~oY6>J?[X|2U|iWn
RTSP/1.0 200 OK CSeq: 2 Content-Length: 0 Audio-Jack-Status: connected; type=analog Server: AirTunes/230.33