It always amazes me which posts of mine tend to generate the most traffic. Not that my blog gets a ton of traffic, but once in a while I get spikes of traffic to a specific post and it surprises me a little. My previous post on KitKat seems to be one of those that has caused a bit of a spike. So, I figured a follow up might be interesting.
A couple of hours ago, a coworker sent me a link to Android issue 62076. Gotta say, I was quite surprised to see a link to my blog as supporting evidence! I was equally surprised to see that the bug was marked "Works as Intended" and closed. I read through the statements on how it is intended to work, and came to the conclusion that if it does indeed work that way, this may not be as big a deal as I thought. But, what was being claimed didn't seem to match up with my experience using KitKat.
For those who don't want to sift through the bug chatter, here is a snip of the response from one of the Android team members :
The "User" portion of the trusted credential store is non-system CA certificates that have been installed and are trusted by the browser and other things that use the system Trusted Certificate Store. This warning is about protecting the user of the device. Note that EAP-TLS and other Wi-Fi modes do not need to install a CA certificate to the Trusted Certificate Store. If you include your CA certificate in a PKCS#12 bundle when installing the credentials and select "Wi-Fi" as the destination for those credentials, you will not get this warning. You can also create a program that adds Wi-Fi credentials and configurations programmatically using the new WifiEnterpriseConfig API (see http://developer.android.com/reference/android/net/wifi/WifiEnterpriseConfig.html). Asking for exceptions does not make sense. There is a process for getting a CA into the trusted list of browsers and operating systems. Please see http://www.mozilla.org/projects/security/certs/policy/ for an example of the process that needs to be followed.
This all seems pretty reasonable, although arguing that you can write an app to install certificates in a way that doesn't cause scary messages seems to be a bit of a stretch for most people. But, lets run with the claim for the PKCS#12 bundle for installing the certificates for a second.
Lets start with a little test. First, go download a root CA certificate from a known CA provider. You might need to search around a bit to find one, or you can just use the GeoTrust certificate that I will be using as I run through this test. I used the first certificate on the list, which is the "Equifax Secure Certificate Authority" certificate. Next, lets convert that certificate to a PKCS#12 bundle so that we can attempt to install it. You can either try to figure out the magical incantations to do it using OpenSSL, or you could just hop over to the SSL Shopper.com converter that I will be using.
Whoops. You mean we have to have a private key to create the bundle that we need to install a root CA in a way that doesn't trigger that scary warning message?! Awww, c'mon!
A little bit of searching will quickly turn up that a PKCS#12 bundle is intended to store a user certificate and any supporting CA certificates it may need. Further, even if you could get a PKCS#12 file with just the CA certificates in it, the code in the Android certificate installer would prevent you from using it. (I have spent FAR too much time digging around in that code. So you may have to trust me on this one.)
Okay, so lets assume for a second that we are using an EAP-TLS network, and so we can create a PKCS#12 bundle that contains a user certificate and private key. According to the statement from the bug, we should be able to do this, and as long as we select the "Wi-Fi" store, we should be good to go. As I happened to have a small home grown CA set up on a Linux box, I tried this method. After going through the install, I still saw the scary icon in the shade. But, how could that be? If the bug was closed because it works as intended, and someone with an @android.com e-mail address says the way it is intended to work shouldn't be showing that scary icon, we must have done something wrong. Did I maybe forget to select "Wi-Fi" for the target store? So, I decided to try again. The first thing I would do is go an clear the "Credential Store" by going to Settings->Security->Clear Credentials. Then, I tried it again, and again got the icon for the scary warning. But this time, I made extra sure that I had selected the "Wi-Fi" store like the bug resolution said to. Interesting...
While poking around with KitKat, I remembered coming across another location that I could use to install certificates. If you go to Settings->WiFi, select the menu button at the bottom and select "Advanced" there is another option in that menu to install certificates. But, before we do that, we need to clear out the certificates we had already installed. So, we go to Settings->Security->Clear Credentials, but the option to clear the credentials isn't available. Does this mean that the certificates weren't installed? If you tap on "Trusted Credentials" and then select the "User" tab, you would find that the certificates you had installed are actually listed. So, either the "Clear Credentials" option has a bug that prevents it from being used when a user has installed certificates to the "Wi-Fi" store, or the certificates are installed someplace other than the "normal" user key store. The response to the bug indicated they were installed elsewhere, so lets assume that is the case. (A quick aside. They are actually stored in the same place as they always were, but they are flagged with a different user ID. So, it could easily be argued that we are dealing with a bug. Exactly what the bug is would depend on your view of how things should work, but the fact that historically using "Clear Credentials" has cleared all of the certificates that were installed on the "User" tab would seem to indicate that the same should continue to be true.)
Okay, so the only way to get rid of them appears to be to tap each certificate listed, scroll down and tap the "Remove" button. Fair enough, lets do that. Now, we are ready to install certificates using the installed option located in the advanced section of the WiFi settings. Doing so acts almost the same as installing them through the security menu. The only difference is that you are not given the option to install to the "Wi-Fi" store. So, I guess we have to assume that it is going there by default when you install this way. (Another aside, testing this on the emulator shows that it does go in to the "Wi-Fi store".)
But, look at that, the scary warning is showing up again!
Well crap. Now what? Lets try the other option outlined. Let's write our own code. But first, lets take a look at this bug. Uh oh. Looks like that isn't an option either. And I won't even bother to point out that the API doesn't allow for certificate chaining. So, even if it DID work, most people would be outta luck using it anyway.
So there you have it. This is not a bug. It works as intended. Which means that you have *NO* way to access an authenticated wireless network without seeing a scary warning that someone might be monitoring your traffic.
But, before I go, let me relate a story that happened to me a few years ago that, while tangentially related seems like it makes a good warning. Several years ago, I was on a conference call with a large mobile phone provider from the UK, and higher-ups at a phone manufacturer that had significant market share at the time. I'm leaving out names because I suspect neither party would be overly happy to be identified publicly. During this call, the mobile phone provider was asking the manufacturer for APIs to support a product they wanted to deploy. No matter how they asked, or how they threatened, the manufacturer kept telling the provider that they didn't need those APIs because the product they wanted to use would be obsoleted by something they were working on. After getting off the call, I talked to my boss (who was also on the call) and said, "Ignoring what your customers want seems to be a good way to kill a company." In the years since that call, the manufacturer ignored more of what its customers wanted, and its market share has declined to a point that is shameful. It doesn't matter how big your company is, or how your market share is today, if you ignore what your customers want, you will eventually die.
Since there seems to be some interest in how the wireless authentication all fits together on Android, I plan to post additional information here. If you want to know far more about the certificate internals of Android than any reasonable person would, you might want to check back.
If I'm a Linux guy, used to working with OpenSSL, command line, PKI and certificates in general, is there a way to either a) manually install your own CA behind the scenes in the CA bundle, circumventing the "user" tab and scary security message or b) manually make that message go away forever? It's super annoying. 20+ years of open source work, I've gotta imagine there has to be a way to make this work.... Heck, my locked down iPhone lets me load a trusted CA in a profile no problem, no errors.
ReplyDeleteAs long as you are using KitKat 4.4.2 or higher, you can install certificates for a specific wifi profile without the scary warning. If you look at the android.net.wifi.WifiEnterpriseConfig class, you will find some "set" calls that will allow you to install the CA, user cert, and private key.
DeleteHowever, if you are looking to install a CA that you want to use with a web browser, that method won't work. Starting with Android 4.3 the keystore is logically segmented in to a keystore for use with wifi certificates, and a keystore for use with everything else. The only time to install a CA certificate in the "everything else" system keystore is to use the certificate install intent. (You can find more info in documentation for the KeyChain class.) Any time you put a CA certificate in the system's "everything else" store using this method, you will trigger the warning message. (Note : I have not tried installing a certificate in to the app specific keystore, but I would hope that doesn't trigger the warning since it shouldn't be used by a browser.) That said, I do believe that if you could figure out how to get ahold of a keystore binder with system privileges you could install one without the warning. However, that would be considered a security hole and would probably be fixed eventually.
If you want to get a better handle on the keystore, I recommend this article, along with the rest of the blog. http://nelenkov.blogspot.com/2013/08/credential-storage-enhancements-android-43.html?view=classic If you dig around in the articles you can find some really great deconstructions about how the keystore works at a really low level.
BTW - If you do find a way to install certs without the warning, I would love to hear about it!
I understand, to some extent, what Google is trying to do by putting this warning up. They hope to increase security by making people aware that when they install a new CA in the "everything store" that it can be used to basically man-in-the-middle their sessions and monitor traffic that a user reasonably believes is encrypted. Because of my day job, I know that this type of activity is more common that most of us would believe. A lot of different organizations want to know what people are doing on their networks. In some cases, this type of system may even be required by law. However, trusting the data in my SSL sessions to a network admin that I don't know (or even one I do know for that matter) doesn't make me feel good. Things like bank account numbers or other information that would be useful to a bad actor could easily be had. Worse, in most of these systems the data is stored somewhere, usually unencrypted.
So, I applaud Google for trying to increase awareness of these devices and the issues they represent. However, I wish there was a better way to get the word out. Unfortunately, I don't know of any better way. But, on the off chance someone from Google reads this, it would be nice to have an option to turn the warning off. Warning me once is an okay idea, bugging the crap out of me from then on is annoying.