Shared publicly  - 
 
Technical Details on +CyanogenMod Device Finder

The new +CyanogenMod Device Finding service creates a secure connection between your browser (javascript) and your phone.

The server never has your password. Your authentication is a derived password.
A public key is generated in the browser, and hmac'd with the actual password (unavailable to the server).
On a device find request, the Android device receives this public key, and validates it is authentic, as the Android device also has the same, underived/original, password.
The Android device sends back an encrypted symmetric key using the public key.
The server can not decrypt the symmetric key, as it does not have the private key.
The browser receives the encrypted payload, and decrypts the symmetric key.

The browser and phone at this point have a secure communication channel, and both sides have authenticated each other. The server is not capable of listening in. It merely provides a transport.

The browser then requests the device location (or requests a wipe) through this secure channel.

The result? As seen in firebug below, the data sent through the server is completely opaque.

This is how device finding should be done. You can not trust that a service will never be compromised. You can never trust that a service provider will not be subject to the will of a government request.

You can only trust that your data was secure from the service itself.

The Android code is up on github, and a review from outside parties is highly encouraged. The website code... right click + view source; it's not obfuscated.
487
263
සසංක lakpriya's profile photoBrett Daugherty's profile photoChi Tung Li's profile photoNipun Ahuja's profile photo
81 comments
 
Well done! You should get a Yacht for this! :)
 
You and the cm team should get a kick starter together to make your own phones. Your features and security are better than any company out there.
 
Very awesome. I love it and will be using it as soon as I can.
 
Thanks for the explanation
 
+Koushik Dutta tell the truth, you are an android from the future trying to prevent the apple uprising and the machine war
 

As always, leading the aftermarket ROM community with viable security options. Thanks!
 
I'll check this out when I get off work. Also, what's the story with the yacht?
 
Superb. And I'd love to fund a CM phone but if Ubuntu can't pull off a very naive 32 million in cash, how is CM going to do it?
 
Awesome work and respectful implementation!
 
The CMAccount Android sources are on GitHub - what about the server/web side?
 
+Guillaume Lesniak the web side can be viewed as source on the webpage. none of the javascript managing the encryption is obfuscated.

The static pages will be released for translations as well.
 
+Koushik Dutta - Will there be a an app available that can run on any device... for example my wife's stock Galaxy S4? 
 
I like the idea! Security is at high stakes today. However, what happens if the server itself is compromised, and delivers a different JavaScript? Which logs the password directly? Aww, snap… ;)
 
+Derek Reynolds I think koush explained it this way because ADM from Google does not perform in this manner. 
 
Shouldn't you all be using a federated credentials? ;-)
 
+Marc Reichelt We thought about that. It's up to you to see what code the server is running on your browser of course :)

This design reduces the attack surface to only when you enter your password. Right now on other services, if the server is compromised everyone can be tracked, full stop.

If our server gets compromised to deliver new javascript, then users are still safe, until they enter the password into the website at some point. At which point, that single user is compromised.
 
+Christian Ketterer I agree. It's not a perfect solution. But it is a better solution if the server gets compromised. Companies providing this service can do better, and this is our attempt.

Obvious next step would be to provide a standalone app or extension, so the server never serves the client side code beyond initial delivery.
 
+Koushik Dutta seems like a Chrome of Firefox extension would greatly reduce that risk with great compatibility and reasonable implementation time.

So +1 for that idea.
 
Created my account. Be glad when I can add it to my device and use those kick ass new tracking features. 
 
outside of this being a great commercialization feature for CM, in your ToS (http://www.cyanogenmod.org/docs/privacy) you state: 

"We may share aggregated, non-personally identifiable information publicly and with our partners. For example, we may share information publicly to show trends about the use of our services."

Who are these partners? From the cmid you end up having my email, name, phone and carrier. It's great to open up and say you welcome review from outside parties, but do you disclose who these partners are that are receiving this information?
 
Commercialization being the key word here
 
+Jeremy Meiss The shared information, as stated, is aggregated, not personally identifiable (your number, which is necessary for sms push, and email, which is necessary for login, are personally identifiable), and is available to our partners, aka the entire internet.

http://stats.cyanogenmod.com/
 
Can't we avoid nsa for once? Tor networking doesn't work, they also use it
 
I'm not sure people appreciate the awesome. Besides how cool it is, it's open source; the provider on your phone could be configured to hit your own server. So if you have concerns you could start get to writing a First Time Setup app that allows you to login to your CM Account or [advanced] and login to your own. Heh, unless this is in the works already.
 
+Koushik Dutta Have any idea if WebRTC DataChannels were considered for this? - it would allow for nat negotiated p2p  connections, you would only need to run a TURN server for the very few clients that are (both) behind full nat cone routers, and they get an encrypted connection for free.

[downside, I've seen a couple av samples, haven't stumbled upon a datachannels one yet]
 
+Koushik Dutta Google api includes it under the experimental settings, to enable in the browser just go to chrome://flags
 
Oh dear, I'd massively over estimated the implementation availability of that API, :(
Obby Tt
 
want the option back to disable the incredibly annoying button backlights on the soft keys
 
Why are all these things coming out , just when I bought Cerberus !
 
Thanks for the answer +Koushik Dutta - the question then becomes, if you're only aggregating the shared data for your partners (i.e. the Internet...) what is happening to our actual personal, identifiable information (email address, name, phone, carrier)? Who sees that? How is it stored? What are you SMS pushing to me? And what am I logging into? Are you saying that this new feature is what is now using that information? How long have you been grabbing this information without using it? 
 
You guys are awesome! Just one question about the security protocol. What about device authentication? It seems only the device authenticates the browser but not the other way round. Therefore, there is a potential for device location spoofing. Is that something that was left out by design to simplify the protocol?
 
+Jeremy Meiss There's two ways to signal a phone on find/wipe. Using GCM or using a text/binary sms. We don't want a dependency on Google (and neither do many of our users), so we are planning fall back to SMS delivery. Which is why the phone number is necessary. The carrier information helps us with routing in other countries like China (using Twilio vs Tropo, etc). We actually have talks with Twilio right now to sponsor CM. Sending text messages is not cheap. You'll hear more on that later.

The personally identifiable information (email, you can use a throwaway, and phone) which is necessary for this to even work is stored on our servers (App Engine). Where else would it be stored?

The phone number is also going to be used by SecureSMS which is under development in partnership with TextSecure/WhisperSystems.

No new information is collected over CM Stats (also opt in). The rest of your questions don't make any sense, and are basically inflammatory:
 * Are you saying that this new feature is what is now using that information? No, you are saying that.
 * How long have you been grabbing this information without using it? We've always been using it. Where do you think http://stats.cyanogenmod.com/ comes from? That is the front end for stats collection.

If you have issues with the data collection (which is necessary for the app to even function), don't use it. It is opt in.
 
You guys really do great work!
 
Could the whole browser code exist in a git repo locally? Then you could vet the code once and track the diffs. Even better, a single saveable html file. 
 
+Joe Taber Yeah, we're gonna ship it as a standalone app of some sort. What you suggest works.
 
Perfect. Love it when devs are willing to support the paranoids. My cryptocd thanks you. 
 
At first its an awesome implementation... Koush you rock...
 
Its HTC One not htc One, I'm sorry, your service sucks.
 
Gvvvln in thi k.jvvvv, kk
s wi ..g. MV in. in.ñu u u ubub kijkkkkkkkikkkk....
 
Created an account but how do I login to my device with my CM password? I'm on the latest nightly for Mako btw...
 
While being open, why don't you use some open maps, i.e. open street map (http://osm.org)? Mapbox provides nice looking maps based on osm, maybe you could talk about sponsorship with them. ~Chris
 
Gotta say I really like where CyanogenMod is slowly going; Android WITH the features, WITHOUT your data in the hands of people you don't want. Android is sooo convenient, but Google freaks the hell out of me sometimes.
 
+Koushik Dutta  Loving the new security-oriented features lately. Hopefully that secure messaging solution will be coming out soon, too, although if I were you I'd wait to see what KLP is all about. They might change a ton of things in it, and better to wait and adapt to that before releasing it, and make sure it's really secure, too (preferably with perfect forward secrecy and some kind of P2P decentralization built-in).
 
Very clean & instructive code, good job guys.
 
+Koushik Dutta  thank you for your work...... I look forward your system could save our freedom once = the major mobile OS for everyone completely open source after the day we all realize we are all trapped in the US gov (NSA) spiderweb.....

but unfortunately it needs open HW drivers that will be banned soon because of US gov by blackmailing manufacturers like Lavabit (email of Snowden) was shut down by the US blackmailing

So you need to produce your own phone soon.....and I would definitely buy that even with 50 % margin for you for freedom!!! :)
 
Would be perfect...if the server side was open-sourced as well.
 
Wow. I am waiting for such a service for a long time.
 
Why store the plain password hash in the first place?  Trivial to reveal the password. Also, single hash round, not a good way to derive an HMAC key (or any key really). 
 
+Nikolay Elenkov Yep, I have already an open issue on the HMAC bit to use a key derivation function on the password.

Password is actually double hashed and sent to the server, but that's not much better. We've been talking about sending a device side salted hash, but that makes authentication trickier, as it will require a back and forth.

Thoughts?
 
bloops, commenting from my actual G+ account...

+Nikolay Elenkov +Koushik Dutta  We actually do send the single hashed password to the server, but it is never stored.  We send it to the server because the server acts as a transport between the browser and device.

Sure, revealing a password that is only hashed once and not salted may be "trivial", if the password is a common word or happens to be in someones rainbow tables.  Secure passwords are the answer here, though, I still think we can make an improvement.
 
'Trivial' as in 'paste hash into Google'. You could enforce password rules, but when has that ever worked? 

So my understanding of this is that the main protection against getting requests from a rogue server is the HMAC key (currently SHA512 of password). With that in mind, it would be a good idea for it to be unpredictable and hard to derive, otherwise an attacker could simply take a password list, calculate hashes of top passwords and try to find devices with weak passwords. For this using something like PBKDF2 with a good number of iterations should work. As for the salt, you could either generate at server and send in the PublicKeyMessage or derive from the password, the former is probably better.

Also, secure messages (EncryptedMessage) need an HMAC as well, since encryption does not protect from modification. Since you already have an HMAC key, this should be easy to add, over the encrypted text (encrypt-then-mac). 

Ideally, the session AES key should use randomness from both server and client, so that you don't end up generating weak keys if one is compromised (right now, SecureRandom on Android, need to add the 'manual seed' workaround as well), also helps against replay. Cf. Pre-master secret in SSL/TLS. That would add more round trips, but should be doable. Even better, you should have different encrypt/HMAC keys for each direction (server->client and client->server). Since the client talks to the server over TLS, you could probably get away without it. 

Other random things: 

 * what is the OAuth? token and how is it managed? Seems to be 32 bytes, so I assume it's saved in on the server.
 * how does the server handle authentication Seems to be matching password hash with what's stored on server?
 * is there really a need to save session keys in the DB? On memory should be better, to decrease the chance of leaking keys. 
  * Do you have any idea how secure is GCM in general? I.e., how easy/hard is it for a third party to send messages to CM devices?

And, of course, get this reviewed by someone who actually designs secure protocols for a living :)
 
+Nikolay Elenkov Yep, which is why he is doing the secure messaging for us. Basically embedding textsecure into the messaging app seamlessly.

But what Moxie is doing there doesn't fit our use case for find/wipe.
 
+Nikolay Elenkov Here's what I just deployed:

HMAC secret is now derived from your password hash (sha512) and a "device salt", using PBKDF2 with 1024 iterations.  The salt is generated randomly on the device, and stored on the server.  As of right now, the salt is only generated and stored once.  I'll revisit regenerating that salt in the future, trying to avoid the back-and-forth right now.

I do like the idea of generating the salt on the server and sending it in the PublicKeyMessage, however, that means we would have to send the sha512 hash of the password up to the server so it can derive the HMAC key.  We are trying to avoid ever sending the unsalted hashed password, which is why the salt is generated on the device and sent to the browser.

I'll see about adding HMAC with the AES encrypted message exchange, should be dead simple.  I'm not sure we need separate keys for each direction, as we are using AES CBC and generating a random initialization vector for each message, which I understand helps prevent replay attacks.  These sessions are very short lived anyway, though I do have a TODO to expire the AES keys on the device, so that is moot until that is done.

Agreed that it would be a good move to generate some random bytes on the server and client (web/android) and use a combination of both.

Random things:

- The OAuth token is exactly that.  It is an OAuth token.  It is saved on the server, and they expire after 1h.  I meant to change this to 15m, but it seems I totally forgot to do that.  I'll deploy a change here in a few minutes.  If you get ahold of my OAuth token, you can impersonate me when making API requests, so an hour is a bit too long.  The access token is a hex UUID4.

- The server matches password hash with the hash that is stored on the server, correct.  The hash that we store is salted a server salt, as well as a per-user salt before it is stored.   Note that we never send your plaintext password, so we are just salting the hash that is sent to us.

-  RE: session keys in the DB.  I'm not an Android framework/app expert by any means, but my understanding is that an Android process can go away at any time.  Storing the key in memory is risky, as the process may not actually be running after the key exchange is done, and before the "begin_locate" message comes in, causing the key to disappear.

- GCM is something that I would like to get rid of eventually.  We shouldn't need to rely on Google for this, however, for right now this is the best solution without engineering something completely new from the ground up.  GCM requires an API key to send messages.  A third party could send messages to our devices if they have our API key the registration ID for a device.

Thanks for your input, really appreciate it.  I'm bad at G+, so if you want to take this discussion offline, please feel free to email me at ctso@cyanogenmod.org.

Changes: 

https://github.com/CyanogenMod/android_packages_apps_CMAccount/commit/4af16e362c982ba43040e8c239455ac7afe04a3e
https://github.com/CyanogenMod/CMAccountWebsite/commit/05d8fe15e571359e8f60862497b83d751aa8c47d
 
Thanks, I'll have a look and if my AOSP VM recovers, I might even try it :)

* Re: HMAC: make sure you cover the IV with the HMAC as well (HMAC(IV||encrypted data)). Random IV is a requirement for CBC, it doesn't prevent replays by itself. 
* Re: keys in DB: yes the process can be killed, but you could restart the whole sequence in that case. It can also be killed right before you clear the keys from DB, leaving old keys behind. Some sort of GC (delete old keys) could be useful. Are delays with GCM common? 

Switching to email will loose some context, but if that works for you, will do.
 
Following G+ threads is a nuisance when it comes to long discussions like this, for me at least.  Once we are comfortable with the security around this set of features, myself or Koush will do another post to inform the community on how we have improved it.
Add a comment...