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

How does Device Authentication work ? #2

Open
thibauts opened this issue Jun 8, 2014 · 67 comments
Open

How does Device Authentication work ? #2

thibauts opened this issue Jun 8, 2014 · 67 comments

Comments

@thibauts
Copy link
Owner

@thibauts thibauts commented Jun 8, 2014

I'm trying to understand device authentication right now and will post progress in this issue.

@thibauts

This comment has been minimized.

Copy link
Owner Author

@thibauts thibauts commented Jun 8, 2014

The culprit is the VerifyCredentials function in cast_auth_util_nss.cc.

The Chromecast uses 2 certificates. The first one is used for the TLS connection, is self-signed and expires every 24 hours (let's call it the peer certificate). The second one is used to validate the first in the device authentication process (let's call it the platform certificate).

I added a few tools in the bin directory to help dumping and inspecting the various files.

The process seems to go as follows.

  1. Every 24 hours the dongle generates a new self-signed TLS peer certificate.
  2. A client sends a DeviceAuth challenge.
  3. The dongle generates a signature of its current peer certificate using the platform certificate private key and returns both the platform certificate and the signature to the client.
  4. First the client verifies that the platform certificate is signed by a trusted CA using its embedded public key (kCAPublicKeyDER)
  5. The client then extracts the platform certificate public key and uses it to check that the returned signature matches the peer certificate signed with the platform certificate.

Long story short, I'm not an expert in cryptography but it seems that without the platform certificate private key used to produce the signature, not much can be done.

@luke

This comment has been minimized.

Copy link

@luke luke commented Aug 25, 2014

I stumbled across this repo. It seems to have tools related to the certs on the chromecast. Thought it migth be of some help. https://github.com/EiNSTeiN-/chromecast-widevine-tools

@thibauts

This comment has been minimized.

Copy link
Owner Author

@thibauts thibauts commented Aug 25, 2014

Looks good indeed. Thanks a lot !

@leo-labs

This comment has been minimized.

Copy link

@leo-labs leo-labs commented Nov 19, 2014

Are there some updates on this? :)

@thibauts

This comment has been minimized.

Copy link
Owner Author

@thibauts thibauts commented Nov 23, 2014

Nothing yet. I don't have time nor interest in searching this direction but I'll help if I can.

@leo-labs

This comment has been minimized.

Copy link

@leo-labs leo-labs commented Nov 24, 2014

Am I rigth that the only way to get authentiation is work is buying a chromecast and root it?

@thibauts

This comment has been minimized.

Copy link
Owner Author

@thibauts thibauts commented Nov 24, 2014

I can't say for sure. A first step would be understanding the auth scheme and looking at the chromium source code.

@emersion

This comment has been minimized.

Copy link

@emersion emersion commented Dec 10, 2014

Somme guys managed to make it work in a Python project: https://github.com/dz0ny/leapcast
I will try to add this to node-castv2 soon :-)

@thibauts

This comment has been minimized.

Copy link
Owner Author

@thibauts thibauts commented Dec 10, 2014

Hmm, where exactly is the code that does it ?

@emersion

This comment has been minimized.

Copy link

@emersion emersion commented Dec 10, 2014

@leo-labs

This comment has been minimized.

Copy link

@leo-labs leo-labs commented Dec 11, 2014

I do not think, that this is related to chromecast v2 protocol;

@thibauts

This comment has been minimized.

Copy link
Owner Author

@thibauts thibauts commented Dec 11, 2014

I think @leo-labs is right, it doesn't look like the same process at all. Probably only relevant to the DIAL protocol.

@Afterster

This comment has been minimized.

Copy link

@Afterster Afterster commented Jan 2, 2015

The chromecast protocol is new to me so sorry if this is a dummy question :).
If the 24h-generated certificate is only used for Chromecast device legacy authentication, an "authentication proxy" replaying the authentication request to a real Chromecast should work isn't it?

@thibauts

This comment has been minimized.

Copy link
Owner Author

@thibauts thibauts commented Jan 2, 2015

This looks like it should work in principle, but in effect I fear the Chrome browser will be too sensitive. During discovery the browser does an mDNS lookup and immediately connects to and authenticates the devices it found. I'm not sure two devices with the same credentials will be accepted.

I may even have tried this and failed, can't remember exactly. I may have messed something up during my tests, too.

@JumpLink

This comment has been minimized.

Copy link

@JumpLink JumpLink commented Jan 10, 2015

Did someone just ask google to get an certificate for custom applications? Google seems to allow chromecast devices from other manufacturers, like smartTV's or speakers, for example this: http://www.xperiablog.net/2015/01/07/sony-announces-speakers-with-google-cast-for-audio-support/ Maybe this is not as problematic as we think?

@thibauts

This comment has been minimized.

Copy link
Owner Author

@thibauts thibauts commented Jan 10, 2015

I doubt they took the burden of creating an auth system only to deliver free keys later. But well, you should ask !

@JumpLink

This comment has been minimized.

@HomerSp

This comment has been minimized.

Copy link
Contributor

@HomerSp HomerSp commented Jan 14, 2015

I've done some looking into this, and noticed that the AuthResponse structure of cast_channel.proto is slightly wrong. There is an additional repeated field at index 3 that contains the CA certificates that's used for verifying the client_auth_certificate on the client-side (on Android it's done through CertPathValidator).
So the correct struct would look like this:
message AuthResponse {
required bytes signature = 1;
required bytes client_auth_certificate = 2;
repeated bytes ca_certs = 3;
}

@thibauts

This comment has been minimized.

Copy link
Owner Author

@thibauts thibauts commented Jan 14, 2015

Interesting. I have no immediate interest in pursuing that but I'll gladly accept PRs.

@friscoMad

This comment has been minimized.

Copy link

@friscoMad friscoMad commented Apr 29, 2015

Checking the last version of the sources it is clear that there are several CAs and that now that field is repeated as a CA chain can be sent.
The legacy flow (only one CA) just checks agains the same CA public key and if a chain is sent then it seeks for the CA cert hast and check against the proper certificate (¿kPublicKeyICA1 and kPublicKeyICA2 are the same cert with different hash?) .

So to make all this work we need a device cert signed with one of those CAs or use a Chrome client that skips that validation. I am no aware of anyone but it should be simple to create one.

Probably there is one CA cert for every vendor, so they have to pay the fees to be included in the SDK and future ChromeCast clients.
Rooting any authorized device will provide us a valid cert, and unless they want to disable a lot of official devices they will not be able to revoke that cert, so that seems the only way to go if Google don't want to give a cert to the public and we want a server that works with any client.

@emersion

This comment has been minimized.

Copy link

@emersion emersion commented May 2, 2015

Has anyone tried to install this XPosed module to be able to skip Device Authentication?

https://github.com/HomerSp/XposedCastClientFix

(Source: http://forum.xda-developers.com/hardware-hacking/chromecast/app-cast-receiver-app-android-t2900726)

@katlogic

This comment has been minimized.

Copy link

@katlogic katlogic commented May 3, 2015

@Afterster Indeed that appears to be the case. Simplest course of action would be to expose public internet service providing signatures via libGtvCa (ie everyone would essentialy see the very same device) running on a rooted dongle.

This is both simplest implementation and works against the worst case when signatures are provided by DRM hardware in the dongle (ie extracting root key will be very difficult).

EDIT: According to XDA, v2 proto seems to use widevine hardware DRM for key provisioning. Hey google, you promised to not be evil :/

@leo-labs

This comment has been minimized.

Copy link

@leo-labs leo-labs commented May 8, 2015

@friscoMad

This comment has been minimized.

Copy link

@friscoMad friscoMad commented Sep 23, 2015

It seems Google does not want receivers outside the oficial one
A XDA Developer managed to get a receiver working but Google sent a Cease & Desist
http://forum.xda-developers.com/hardware-hacking/chromecast/app-youmap-chromecast-receiver-android-t316185

@xmikos

This comment has been minimized.

Copy link

@xmikos xmikos commented Sep 23, 2015

@frisco82 I have looked into YouMap Receiver apk and I don't blame Google for this Cease & Desist too much. That apk included big parts of proprietary Google Cast Receiver apk (and it was paid app on Google Play! Very daring and reckless...).

Also there was no magic, there has been only drm.json file in the apk full of pregenerated daily Chromecast V2 protocol keys (for one month period). I think author of YouMap Receiver just pregenerated them on rooted Chromecast. Maybe this can be solution for opensource implementation - someone with rooted Chromecast can pregenerate daily keys for a long period (something like many many years) and publish them anonymously on net.

@JumpLink

This comment has been minimized.

Copy link

@JumpLink JumpLink commented Oct 6, 2015

@leo-labs thank you!

@sorryusernameisalreadytaken

This comment has been minimized.

Copy link

@sorryusernameisalreadytaken sorryusernameisalreadytaken commented Mar 19, 2018

I can get a gen1 g-cast stick, never used, buyed middle of 2015....

@sashahilton00

This comment has been minimized.

Copy link

@sashahilton00 sashahilton00 commented Mar 19, 2018

up to you. I've no experience with libgtvca and all that, but my guess is that it's just an interface to trustzone?

@cretz

This comment has been minimized.

Copy link

@cretz cretz commented Jun 14, 2018

I wrote a toy server impl in Go that does the auth if it helps anyone. Of course, it fails here (I think based on debug cert fail event count in chrome logs) because the auth cert wasn't gen'd from Google's CA key. I am unsure if I got everything right of course, and I didn't include the gen'd protobuf files, but I figure it could be good reading for anyone landing here.

@sashahilton00

This comment has been minimized.

Copy link

@sashahilton00 sashahilton00 commented Jul 10, 2018

@cretz you might be able to give the keys @fghfghff posted a go, just manually set your time back to when the certs were valid

@cretz

This comment has been minimized.

Copy link

@cretz cretz commented Jul 10, 2018

@sashahilton00 - Oh, I have a full blown auth'd impl now at https://github.com/cretz/owncast. I actually patch a chrome binary to put my own CA in there so it auths with mine. I create the needed intermediate cert, solve the auth request w/ signature and everything, but casting using the cast v2 protocol is not yet implemented in Chrome. I don't have anything documented, and I won't resume work until https://bugs.chromium.org/p/chromium/issues/detail?id=809249 is complete (it's coming along).

@forlayo

This comment has been minimized.

Copy link

@forlayo forlayo commented Oct 17, 2018

@cretz can you guide me on how to set Chrome to expose the log which says the cert have failed? I'm doing tests trying to get a valid certificate and this can be a really good point for validate :)

@cretz

This comment has been minimized.

Copy link

@cretz cretz commented Oct 17, 2018

@forlayo - This worked for me: https://www.chromium.org/for-testers/enable-logging. You'll have to turn that v number up high (there's lots of noise) and may want to use canary w/ better cast support. Note, even with cast auth succeeding, cast protocol is not implemented completely in Chrome yet. But w/ the Chrome CA patched, I can get my device to appear in the list of Chromecast devices in the browser.

@forlayo

This comment has been minimized.

Copy link

@forlayo forlayo commented Oct 17, 2018

Thanks a lot, I've been doing
google-chrome --enable-logging=stderr --v=1

I'm playing a bit around, as should be a way to avoid or to fake ( or to provide a valid one ) with the authentication.

I've seen that demo application of Reflector 3 (http://www.airsquirrels.com/reflector/) and AirServer (http://www.airserver.com/) supports doing it, and it works :/

@sashahilton00

This comment has been minimized.

Copy link

@sashahilton00 sashahilton00 commented Nov 5, 2018

@forlayo any further progress on this? I'm guessing you have a Gen 1 and were looking to just create a signing service for peer certificates?

@treblam

This comment has been minimized.

Copy link

@treblam treblam commented Nov 29, 2018

@forlayo Have you succeed in faking with the authentication?

@forlayo

This comment has been minimized.

Copy link

@forlayo forlayo commented Dec 4, 2018

I've been able to extract the certificates they use to authenticate but not the primary key which is needed; by the way I am not working on this at the minute and I am unsure if going to work again in the future.

If I've a couple of hours at home I will try again, if success I will share here. I am pretty sure that someone with experience doing reversing can do this authentication bit :/

@sashahilton00

This comment has been minimized.

Copy link

@sashahilton00 sashahilton00 commented Dec 4, 2018

Fair enough. Extracting the device certificate is not practical in all likelihood; i can't remember whether it uses a coprocessor to do the crypto stuff, or if it is a TrustZone implementation, either way, it's unlikely that we'll be able to pull the keys out, short of someone exploiting TrustZone (though it has been done before). IIRC, the device key is burned in via UART during manufacture then the device is sealed.

The optimum solution is likely a lightweight API server that runs directly on a rooted chromecast, whereby one feeds in parameters/signing requests, and the Chromecast returns signed certificates. One could then create a batch of signed certificates for the next 5 years or something, write a simple API of the form /certificate/latest, which would return the presigned certificates, the valid from/valid to dates, which people could use in various open source projects.

@forlayo

This comment has been minimized.

Copy link

@forlayo forlayo commented Dec 4, 2018

The weird thing is these applications I'm talking about (reflector and airserver) works even being installed on a computer without access to internet (I've tried that, and I've tried installing the application that I've downloaded few days ago).

So, or they've a bunch of these certificates you're talking about somehow into. Or they've the primary key of certificate somehow into..

I've been able to get the certificates used, but not the primary key that's obviously needed for sign the challenge

@Xebozone

This comment has been minimized.

Copy link

@Xebozone Xebozone commented Dec 6, 2018

@forlayo those applications just do screen mirroring though? It won't work with casting apps like YouTube, etc

@forlayo

This comment has been minimized.

Copy link

@forlayo forlayo commented Dec 6, 2018

I've just checked screen mirroring functionality that's in which I were interested; and it works perfectly.

@sashahilton00

This comment has been minimized.

Copy link

@sashahilton00 sashahilton00 commented Dec 6, 2018

@forlayo airserver is cast v1. only chrome uses cast v1. anything using Cast SDK is v2 (e.g. Youtube) and won't work.

@forlayo

This comment has been minimized.

Copy link

@forlayo forlayo commented Dec 6, 2018

@sashahilton00

This comment has been minimized.

Copy link

@sashahilton00 sashahilton00 commented Dec 6, 2018

Not sure, but have a look at the AirServer docs. They don't support a bunch of Cast Senders, which suggests that they haven't solved the auth problem. My guess is they're using an old implementation which is compatible with some senders. https://support.airserver.com/customer/portal/articles/2518775-google-cast-compatible-sending-devices

@forlayo

This comment has been minimized.

Copy link

@forlayo forlayo commented Dec 6, 2018

As I said, I've tested that you can do screen mirroring from chrome to airserver, and I can see on chrome logs the authentication going successful.

So, maybe they're not supporting some of cast applications; which is different from having the authentication solved.

However my comments are based on facts of my personal tests, and not guessing. You can check it by yourself, the demo is free for download.

@sashahilton00

This comment has been minimized.

Copy link

@sashahilton00 sashahilton00 commented Dec 6, 2018

I did try to download it, but the demo won't run in trial mode on mine for some reason. Regardless of whether the authentication is there or not, they haven't sorted everything clearly as it doesn't show up on iOS devices

@dougmoscrop

This comment has been minimized.

Copy link

@dougmoscrop dougmoscrop commented Dec 16, 2018

I ran the trial of AirServer on my macbook and while it worked for screen mirroring, it showed up in the list of cast destinations for Google Play Music but it did not actually play music.

I'm looking to implement custom/virtual cast receivers and the only support I need is from Google Play Music - not all casting support. Has anyone poked around to see if Google Play Music is using v2 or also supports DIAL or doesn't care about auth?

@treblam

This comment has been minimized.

Copy link

@treblam treblam commented Dec 17, 2018

@sashahilton00 - Oh, I have a full blown auth'd impl now at https://github.com/cretz/owncast. I actually patch a chrome binary to put my own CA in there so it auths with mine. I create the needed intermediate cert, solve the auth request w/ signature and everything, but casting using the cast v2 protocol is not yet implemented in Chrome. I don't have anything documented, and I won't resume work until https://bugs.chromium.org/p/chromium/issues/detail?id=809249 is complete (it's coming along).

@cretz Why don't you implement a full screen mirroring receiver? Chromium can do screen mirroring, if you make your project to be a full screen mirroring receiver, it's more meaningful.

@Bkucera

This comment has been minimized.

Copy link

@Bkucera Bkucera commented Jan 6, 2019

What evidence do we have that the 24hr generated key (for v2) is the same across all chromecasts? Why would it not use timestamp + IP to ensure it's unique for that specific connection, making so you can't just host a single key that changes every 24hrs (or generate 5 yrs of keys for everyone)?

@sashahilton00

This comment has been minimized.

Copy link

@sashahilton00 sashahilton00 commented Jan 6, 2019

Because the device generates the cert, then sends the CSR to trustzone for signing via the device key. You can inspect the 24 hour cert, there is no IP address or anything like that in there.

@luojiaxiong

This comment has been minimized.

Copy link

@luojiaxiong luojiaxiong commented Mar 6, 2019

The culprit is the VerifyCredentials function in cast_auth_util_nss.cc.

The Chromecast uses 2 certificates. The first one is used for the TLS connection, is self-signed and expires every 24 hours (let's call it the peer certificate). The second one is used to validate the first in the device authentication process (let's call it the platform certificate).

I added a few tools in the bin directory to help dumping and inspecting the various files.

The process seems to go as follows.

  1. Every 24 hours the dongle generates a new self-signed TLS peer certificate.
  2. A client sends a DeviceAuth challenge.
  3. The dongle generates a signature of its current peer certificate using the platform certificate private key and returns both the platform certificate and the signature to the client.
  4. First the client verifies that the platform certificate is signed by a trusted CA using its embedded public key (kCAPublicKeyDER)
  5. The client then extracts the platform certificate public key and uses it to check that the returned signature matches the peer certificate signed with the platform certificate.

Long story short, I'm not an expert in cryptography but it seems that without the platform certificate private key used to produce the signature, not much can be done.

@thibauts hi thibauts, I don't really understand how chromecast works. I don't even know how to add chromecast to Android tv. I want to know how to get Chroomecast to work on Android tv. I want to know how to get "let's call it the platform certificate"? Thank you for your answer.

@tishion

This comment has been minimized.

Copy link

@tishion tishion commented Mar 14, 2019

Any progress on this issue?

@rlbartle

This comment has been minimized.

Copy link

@rlbartle rlbartle commented Sep 11, 2019

I'm willing to look into this but I would need a rooted chromecast to work with. Anyone willing to sell me one? I'd like to generate a tonne of peer certificates for a project I'm working on and I'd happily make public the results in order to provide a working solution here. It would be easy for me to provide a web endpoint to retrieve the daily certificate. In my case I'd like to embed them in my project.

@sashahilton00

This comment has been minimized.

Copy link

@sashahilton00 sashahilton00 commented Sep 12, 2019

I bought one recently and have been playing around with it. Where are you based?

@rlbartle

This comment has been minimized.

Copy link

@rlbartle rlbartle commented Sep 12, 2019

I'm in New Zealand, an also have an available shipping service in the US and UK. I've been browsing around and I've found a couple potential hits on ebay. I'm asking the sellers for more info about the serial number to ascertain if they are likely to have an old firmware that can be rooted.

@RunasSudo

This comment has been minimized.

Copy link

@RunasSudo RunasSudo commented Dec 20, 2019

For anyone interested in using node-castv2 with a stock client, I've described how to bypass device authentication on a rooted Android smartphone at https://yingtongli.me/blog/2019/12/20/gcast-auth.html / https://yingtongli.me/git/GCastNoDeviceAuth/.

On a desktop, Chrome binaries can be patched (as described in #2 (comment)), or the relevant tests could be commented out in the Chromium source code.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
You can’t perform that action at this time.