Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

ios 9.3 POST /pair-setup,POST /pair-verify #61

Closed
Jack-lx opened this issue May 5, 2016 · 52 comments
Closed

ios 9.3 POST /pair-setup,POST /pair-verify #61

Jack-lx opened this issue May 5, 2016 · 52 comments

Comments

@Jack-lx
Copy link

Jack-lx commented May 5, 2016

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^X_ne:_|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

@yong253535551
Copy link

hi,if anybody known to deal with POST /pair-verify or /pair-setup session, please email to me
my email:yong253535551@163.com

@yong253535551
Copy link

@anhhna
Copy link

anhhna commented Sep 21, 2016

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

@jiam-marvell
Copy link

jiam-marvell commented Oct 8, 2016

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

@shahasachin
Copy link

shahasachin commented Dec 8, 2016

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.

@Jack-lx
Copy link
Author

Jack-lx commented Feb 7, 2017

@yong253535551 @anhhna @shahasachin @Derek0425 @vranki ,Did you fix this issue ?homekit can't resolve this!

@shahasachin
Copy link

@Jack-lx, Didn't get solution. Yes, configured homekit but didn't get any solution.

@msobiepanek-uz
Copy link

@Jack-lx have you found out how to handle setup and verify steps?

@ViktoriiaKh
Copy link

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.

@funtax
Copy link

funtax commented Jun 12, 2017

There's also an implementation available in Python & ObjectiveC and C.

@jvah
Copy link
Contributor

jvah commented Jun 13, 2017

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.

@Logical-sh
Copy link

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

@funtax
Copy link

funtax commented Jun 30, 2017

Hey @comwizz2, sadly not, I have only focused a this implementation (done by reverse-engineering another app) as this was required by mine.

@robertoandrade
Copy link

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

@funtax
Copy link

funtax commented Jul 27, 2017

@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);`

@robertoandrade
Copy link

robertoandrade commented Jul 27, 2017

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.

@robertoandrade
Copy link

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!

@funtax
Copy link

funtax commented Jul 30, 2017

I'm super-happy to read this @robertoandrade .
Really great news and good to know that my stuff has helped you :)

@htartisan
Copy link

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.

@funtax
Copy link

funtax commented Jul 31, 2017

Hey @htartisan, you mean the client-side that connects to the Apple TV/AirPlay-receiver?

@htartisan
Copy link

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.

@htartisan
Copy link

NOTE: AirPlay "server" device = a device that is connected to a monitor/TV, that can receive AirPlay streams.

@robertoandrade
Copy link

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?

@htartisan
Copy link

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.

@robertoandrade
Copy link

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 espes/Slave-in-the-Magic-Mirror#12

@htartisan
Copy link

I'll look there. Thanks!

@kcosmos4
Copy link

kcosmos4 commented Aug 30, 2017

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

@robertoandrade
Copy link

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?

@funtax
Copy link

funtax commented Oct 2, 2017

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

@gagakang
Copy link

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

@juhovh
Copy link
Owner

juhovh commented Mar 14, 2018

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.

@Jerzha
Copy link

Jerzha commented Mar 15, 2018

Got it, I found the different in curve25519_donna-c64. Replace this file with your code, I pass the pair-verify.

@juhovh 哈哈,是啊。中国人歪点子多。

@juhovh
Copy link
Owner

juhovh commented Mar 15, 2018

Just out of curiosity, do you mean the if (basepoint == NULL) basepoint = kCurve25519BasePoint; line when you say the difference in curve25519_donna-c64?

@Jerzha
Copy link

Jerzha commented Mar 15, 2018

Yep...

@ghost
Copy link

ghost commented Apr 11, 2018

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?

@robertoandrade
Copy link

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

@ghost
Copy link

ghost commented Apr 11, 2018

Hmm, I wonder why I don't get the second setup. Does your code work with ios 11.3?

@robertoandrade
Copy link

yep, but my codebase is not related to this project at all.

@ghost
Copy link

ghost commented Apr 11, 2018

Ok found the issue, i wasn't sending a 'name' and 'pk' in the info. Previously i had disabled pair-verify :) . Working now.

@ghost
Copy link

ghost commented Apr 11, 2018

Ok another issue. It seems on ios11.3 it does not connect back to the event port. It works fine on lower versions.

@ghost
Copy link

ghost commented Apr 11, 2018

Nevermind it's down to sending an error on my part.

@Jerzha
Copy link

Jerzha commented Apr 26, 2018

@382517366 是的,但是curve25519_donna这个函数跟你网上下到的有一点点小区别

@Jerzha
Copy link

Jerzha commented Apr 26, 2018

@382517366 我不是对着这个工程开发的。我是开发遇到问题点刚好看到这里在讨论才进来讨论的。你直接使用https://github.com/phonegapX/AirPlay 这套代码里的这个库就没问题的。

@Jerzha
Copy link

Jerzha commented Apr 28, 2018

@382517366 恩,对的,我们也是用64写的,没问题的。

Repository owner deleted a comment from notedit Jul 12, 2018
Repository owner deleted a comment from notedit Jul 12, 2018
Repository owner deleted a comment from Jerzha Jul 12, 2018
@juhovh
Copy link
Owner

juhovh commented Jul 12, 2018

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.

@juhovh
Copy link
Owner

juhovh commented Jul 21, 2018

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.

@juhovh
Copy link
Owner

juhovh commented Aug 2, 2018

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.

@juhovh juhovh closed this as completed Aug 2, 2018
@jmvermeulen
Copy link

The chinese guys above seem to have cracked it!
Trying to get their code running.

@tishion
Copy link

tishion commented Sep 4, 2018

@jmvermeulen lol, there are so many product working correctly in China, if you pay me 10 thousands i will give you the code.

Kidding.

@juhovh
Copy link
Owner

juhovh commented Sep 4, 2018

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

@tishion
Copy link

tishion commented Sep 4, 2018

hi @juhovh , I have some problem while i am implementing the AirServer, the first one is how to disable the FairPlay support? Is it achieved by change the Airplay feature flag?

@jmvermeulen
Copy link

@juhovh thanks!
My use case is very specific to Windows. I got one of the Chinese examples running but the critical part isn't open sourced by the development.

Will have a look at your code, when back at the office. Do you know if your application runs in Windows 10 Ubuntu?

@tishion I believe we are a open source community. Would be great if you could provide your code in GitHub ;-)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests