OrlandoLabao43 / sandrob

Automatically exported from code.google.com/p/sandrob
2 stars 0 forks source link

No obvious means of importing client cert in version in Android Market #10

Closed GoogleCodeExporter closed 8 years ago

GoogleCodeExporter commented 8 years ago
What steps will reproduce the problem?
1. Search for and install SandroB from Android Market (version 0.9.4)
2. Tap Menu, then More
3. Tap Settings
4. No option available for importing client certificate

What is the expected output? What do you see instead?
I expected to find some sort of UI setting for importing client certs. I read 
somewhere about an option called "SandroB Specific Settings" but can't find it. 
There are no instructions or UI that I can find for importing a certificate.

What version of the product are you using? On what operating system?
The version in the Android Market, 0.9.4, running on an original Motorola Droid 
running stock Android 2.2.2 (FRG83G)

Please provide any additional information below.
Attempted to download and install beta from downloads page 
(sandrob_xxjvk_0_9_5_8.apk) but it won't install; see Issue 9.

Original issue reported on code.google.com by jeff.darlington@gmail.com on 16 Apr 2011 at 11:02

GoogleCodeExporter commented 8 years ago

There is no import. 
On the first https request pop-up appears asking where is certfile and what is 
the password for it.
There will be an option to store whole file in browser database (as a blob), 
but is not implemented yet. 
http://code.google.com/p/sandrob/issues/detail?id=8

sandrob_xxjvk_0_9_5_8.apk is meant to work on 2.3.3 stock androids
as is described in 
http://code.google.com/p/sandrob/issues/detail?id=4

Original comment by supp.san...@gmail.com on 16 Apr 2011 at 11:27

GoogleCodeExporter commented 8 years ago

Original comment by supp.san...@gmail.com on 17 Apr 2011 at 9:15

GoogleCodeExporter commented 8 years ago

Original comment by supp.san...@gmail.com on 17 Apr 2011 at 11:34

GoogleCodeExporter commented 8 years ago
Jeff,

Did you manage to make it work?
Maybe I should put some tutorial on site for quick start with application...

Original comment by supp.san...@gmail.com on 19 Apr 2011 at 5:55

GoogleCodeExporter commented 8 years ago
I eventually got it to work. However, I ran into a new problem. I deleted the 
cert file from the SD card after the first successful connection, as per your 
(wise) recommendation. After I updated to the new version just pushed to the 
Market, however, it seemed to "forget" the certificate and now I need to 
re-import it. Since I do not have the cert file with me, I'll have to wait 
until later to try again.

Yes, there absolutely needs to be some sort of tutorial or instructions, 
preferably on the device itself. If not in the app, at least have some menu 
option that sends the user to the site for help. I consider myself a very 
technical person; I am a professional software developer, code my own Android 
apps, and use my own certificate authority to secure access to my various 
websites. That said, it was not obvious that I was supposed to just go to an 
HTTPS site and I'd be prompted for a certificate. As stated above, the first 
thing I did was look for instructions or SandroB-specific settings and didn't 
find any. Less technical users won't think to go looking for a wiki at 
code.google.com, especially if there's no link there within the app to follow. 
While it could be argued that less technical users wouldn't be using client 
cert authentication, there are a lot of corporate sites that use client certs, 
and not all of their users are going to be coders or IT staff.

Since users will likely be coming to SandroB specifically for the client cert 
capability, it might be nice to include a dedicated UI for importing certs 
before the user starts trying to access the site. Then they can pre-load the 
certs they need in one batch. If they need to select which cert to use from the 
list currently stored certs when they first access the site, that's fine. You 
can also keep the ability to import the cert upon first access, and have the 
choice between selecting a pre-loaded cert and importing a cert an option.

It might be nice to also let the user browse a list of files rather than typing 
in the path. A lot of users will likely be used to scrolling through folders 
and tapping on file names, rather than typing in UNIX path names. If you don't 
want to write your own file browser (I know I didn't), you can pass a file 
selection intent to one of the many file manager apps in the Market and let the 
user pick one that way.

It took me a couple tries (including uninstalling and reinstalling SandroB to 
make it "forget" my failed connection attempts) before I realized that I needed 
to include the "/sdcard/" path to the cert file. I had assumed that since the 
file was supposed to be on the SD card, the app would prepend that path.

Oh, and that's another thing, which I don't know if this needs to go into a 
separate issue or not. As mentioned above, when I upgraded with the latest 
version from the market, the app "forgot" my installed certificate. It's as if 
it stored the cert after the initial import, but the upgrade blew away the 
database so when I attempted to access the secured site afterward, it wanted me 
to import the cert file again. Since I had assumed the cert had been imported 
an stored, I deleted the file from the SD card, so I no longer had it available 
to re-import it. An app should remember the user's data and settings between 
upgrades, and if the database structure must change dramatically, it should 
transparently convert the old data into the new format without the user even 
knowing. As it stands now, it will be several hours before I can get back to my 
computer where the cert file is currently stored and try testing again.

Original comment by jeff.darlington@gmail.com on 19 Apr 2011 at 1:11

GoogleCodeExporter commented 8 years ago
I'm glad that you make it work.
I write some facts that will clarify/answer your post.

- There is already sqllite database that comes with stock browser 
  and also one SandroB specific table that I created
  but only url and filename are stored now. Password will never be.
  So when you input https url, it checks database, and if it find match,
  it fills cert filename input box.

        if (justHttpsClientTable){
            mDatabase.execSQL("CREATE TABLE " + mTableNames[TABLE_HTTPSCLIENT_ID]
                    + " (" + ID_COL + " INTEGER PRIMARY KEY, " +
                    HTTPSCLIENT_URL_COL      + " TEXT, " +  
                    HTTPSCLIENT_DATA_COL     + " BLOB DEFAULT NULL , " +  
                    HTTPSCLIENT_FILENAME_COL + " TEXT, " +  
                    HTTPSCLIENT_PASSWORD_COL + " TEXT" + 
                    ");");
        }

  I feel very uncomfortable storing also file data. 
  Recently I am investigating maybe to use android keystore like it is used for VPN.
  But if I failed on this, import to database will be implemented.

- It seems to me that when you uninstall android app it deletes all data.
  This makes sense also for SandroB. So the user has the power to delete all.
  Nothing remains waiting for manual clean-up.
  But when just upgrade is performed, data (sqllite database) remains the same.
  I tested it and it is working ok.

- There are SandroB specific settings. But just to configure proxy.
  Menu->Settings->Enable Proxy
- There is Clear feature (Menu->Clear). Among other it also invalidate 
sslcontext.
- tutorial/wiki ... yes. After I resolve this cert store issue I write one.

Original comment by supp.san...@gmail.com on 19 Apr 2011 at 8:35

GoogleCodeExporter commented 8 years ago
From what I read in the Android issue list (#11231):

https://code.google.com/p/android/issues/detail?id=11231

it sounds unlikely that you'll be able to store client certs in the official 
system key store unless Google opens up access to it. We know users can import 
certs for use with WiFi or VPN (both of which are managed directly by the OS), 
but I have no idea if any old application will be able read or write to the 
store. I haven't looked into that myself, so I have no idea. Good luck with 
that, though; that would certainly be a good place to store it. Some certs, 
like those on the U.S. DoD CAC ID card, are used for many different forms of 
authentication, so they could be used for websites, VPNs, etc. Having a common 
store would certainly be convenient.

When I suggested importing the cert into the database, what I meant was that 
you could store the raw cert data or serialize the Java object that contains it 
and store that as a binary blob keyed to a unique identifier. Then you could 
modify your existing table to store the ID from the cert table rather than the 
file name. Join on this ID and you can easily retrieve the cert for a given 
URL. The added benefit would be that, as previously suggested, you could 
theoretically use the same cert for multiple URLs; just insert a new row into 
the URL table with the same cert ID.

As for the security of storing the cert in the database, it's a whole lot safer 
than storing it as a file on the SD card. Each Android app has its own user ID 
in the OS and cannot read data across app boundaries unless the developer 
expressly gives two or more apps the same user ID, or if they provide a content 
API where the data can be accessed via intent. At that point, SandroB will have 
its own key store database all to itself, so your app should be the only one 
that can read or write to it. The only exploit around this that I know of would 
be if the user roots the device, at which point they've bypassed the built-in 
security mechanisms and taken their data security into their own hands. 
Encrypting the data stored in the table would be a good protection against 
that, but at this point it's up to the user rather than you to keep the device 
secure. You could generate a random "seed" and store that somewhere, then 
generate the actual encryption key by using multiple iterations of a 
cryptographic hash. That way, the actual encryption key is never stored.

To clarify my comments about uninstalling and reinstalling SandroB, here's the 
sequence of events:
1) I installed SandroB (the previous version that was in the Market) and copied 
the cert file to my SD card.
2) I attempted to access my secure site using SandroB. Since I didn't know I 
needed to specify the full path to the file (/sdcard/filename.p12), I put in 
the wrong path name.
3) SandroB naturally could not find the file and thus could not establish a 
connection. It attempted to connect via HTTPS without the client cert and 
correctly gave me connection failure error.
4) I closed and restarted SandroB, attempting to reconnect to the same secure 
URL. From this point, SandroB remembered the previous sequence events and 
didn't bother asking for the cert file. It simply tried to connect without the 
client cert and failed. Repeatedly closing and restarting the app had the same 
effect. I'm not sure if I didn't wait "long enough" for it to forget this, or 
if there is any mechanism in place to clear this type of error without clearing 
out the database, but that seemed to be the only option available at the time.
5) In an attempt to clear out the database, I uninstalled and reinstalled 
SandroB.
6) I repeated Step 2, this time with the correct cert file path. SandroB found 
the file, unlocked it with the password, and successfully connected to the 
secure site. At this point, I had assumed SandroB had imported and stored the 
certificate and that the file was no longer needed. I deleted the cert file 
from the SD card.
7) The next day, you pushed out a new version of SandroB to the Market. I used 
the Market update procedure to update the app.
8) With the new version installed, I attempted to access the same secure URL as 
before. SandroB prompted me for the file name and password. I assumed that the 
cert data had been imported during the previous successfully connection, so I 
was surprised to be prompted for the file name again. Since I had already 
deleted the file, it was no longer present and thus SandroB could not find it. 
The connection failed.

So this was a invalid assumption on my part. I had assumed the cert was 
imported and stored in the database, rather than being read from the SD card 
each time it was needed. The other app settings may have been preserved, but 
since the cert was not found and I could not connect, I assumed the cert data 
had been cleared during the upgrade. My mistake.

The only reason I keep harping on importing and storing the cert is that this 
seems to be a reasonable expectation most Android users would have. It makes 
sense to prompt the user for the password every time, but selecting a cert for 
a given URL is something that realistically will only need to be done rarely, 
mostly likely occurring whenever the cert expires. For example, in Firefox I 
import a new client cert once a year, right before the old one expires. FF can 
be configured to prompt you for which cert to use for each new session, but it 
usually makes a good guess on its own. (I think the server may actually tell it 
which cert chain is acceptable.) I don't have to tell FF to look for the cert 
in a certain place every time; it "just knows" because the cert has been stored 
in the key store. Whether or not to store the unencrypted cert or to prompt for 
the password every time are good debating points for another time, but the 
"import it and forget it" expectation is one many users will have. They want it 
to "just work", and the fewer messy mechanics they have to deal with, the 
better.

I'm not sure where you're planning to go with SandroB. Is it still just an 
experiment to prove to Google that it can be done, or are you trying to build a 
long-term project that you plan to maintain over time? I'm looking at it from 
the perspective of a potential user who has a need that must be fulfilled, and 
SandroB is the only option at the moment that does so satisfactorily. (Firefox 
Mobile is no longer an option for me since they deemed my device to have not 
enough horsepower to support.) As such, I hope I'm offering suggestions that 
will help improve the overall user experience. If you disagree, I'll quietly go 
away and look for another solution to my own needs. If you find my suggestions 
helpful, I'll attempt to make them as clear and concise as I can (although at 
this point I think I can safely say "concise" is no longer descriptive :D ).

Good luck.

Original comment by jeff.darlington@gmail.com on 20 Apr 2011 at 2:00

GoogleCodeExporter commented 8 years ago
Jeff, 

I appreciate any suggestions and I'm glad that you have interest for SandroB.
I will try to implement as you suggest but you must understand that...
I'm just a poor guy who brings cold water to machine guns :)

Just quick note about using keystore.
I checked android keystore sources and there is checking for uid of process.
Only few process id's has rights to get keys out.
So without root-ed phone there is no way to access it.

It looks that I will put files/certs in the database blob after all.
But it will be user choice to have it that way.

If you agree, I will close your issues an we can discuss on another ones.

// SandroB; extract from keystore.c file
static struct user {
    uid_t uid;
    uid_t euid;
    uint32_t perms;
} users[] = {
    {AID_SYSTEM,   ~0,         ~GET},
    {AID_VPN,      AID_SYSTEM, GET},
    {AID_WIFI,     AID_SYSTEM, GET},
    {AID_ROOT,     AID_SYSTEM, GET},
    {~0,           ~0,         TEST | GET | INSERT | DELETE | EXIST | SAW},
};

// SandroB; extract from core/include/private/android_filesystem_config.h
/* This is the master Users and Groups config for the platform.
** DO NOT EVER RENUMBER.
*/

#define AID_ROOT             0  /* traditional unix root user */

#define AID_SYSTEM        1000  /* system server */

#define AID_RADIO         1001  /* telephony subsystem, RIL */
#define AID_BLUETOOTH     1002  /* bluetooth subsystem */
#define AID_GRAPHICS      1003  /* graphics devices */
#define AID_INPUT         1004  /* input devices */
#define AID_AUDIO         1005  /* audio devices */
#define AID_CAMERA        1006  /* camera devices */
#define AID_LOG           1007  /* log devices */
#define AID_COMPASS       1008  /* compass device */
#define AID_MOUNT         1009  /* mountd socket */
#define AID_WIFI          1010  /* wifi subsystem */
#define AID_ADB           1011  /* android debug bridge (adbd) */
#define AID_INSTALL       1012  /* group for installing packages */
#define AID_MEDIA         1013  /* mediaserver process */
#define AID_DHCP          1014  /* dhcp client */
#define AID_SDCARD_RW     1015  /* external storage write access */
#define AID_VPN           1016  /* vpn system */
#define AID_KEYSTORE      1017  /* keystore subsystem */

#define AID_SHELL         2000  /* adb and debug shell user */
#define AID_CACHE         2001  /* cache access */
#define AID_DIAG          2002  /* access to diagnostic resources */

/* The 3000 series are intended for use as supplemental group id's only.
 * They indicate special Android capabilities that the kernel is aware of. */
#define AID_NET_BT_ADMIN  3001  /* bluetooth: create any socket */
#define AID_NET_BT        3002  /* bluetooth: create sco, rfcomm or l2cap 
sockets */
#define AID_INET          3003  /* can create AF_INET and AF_INET6 sockets */
#define AID_NET_RAW       3004  /* can create raw INET sockets */
#define AID_NET_ADMIN     3005  /* can configure interfaces and routing tables. 
*/

#define AID_MISC          9998  /* access to misc storage */
#define AID_NOBODY        9999

Original comment by supp.san...@gmail.com on 20 Apr 2011 at 8:25

GoogleCodeExporter commented 8 years ago

Original comment by supp.san...@gmail.com on 3 May 2011 at 9:39