Change the keystore APIs.

1. simplify the keypair selection in UI.
2. add the user certificate and key into the keystore for keygen feature.
diff --git a/cmds/keystore/commands.c b/cmds/keystore/commands.c
index e53cece..17dd060 100644
--- a/cmds/keystore/commands.c
+++ b/cmds/keystore/commands.c
@@ -1,5 +1,5 @@
 /*
-** Copyright 2008, The Android Open Source Project
+** Copyright 2009, The Android Open Source Project
 **
 ** Licensed under the Apache License, Version 2.0 (the "License");
 ** you may not use this file except in compliance with the License.
@@ -30,7 +30,8 @@
     return d;
 }
 
-static int list_files(const char *dir, char reply[REPLY_MAX]) {
+static int list_files(const char *dir, char reply[REPLY_MAX])
+{
     struct dirent *de;
     DIR *d;
 
@@ -39,7 +40,9 @@
     }
     reply[0]=0;
     while ((de = readdir(d))) {
-        if (de->d_type != DT_REG) continue;
+        if (de->d_type != DT_DIR) continue;
+        if ((strcmp(DOT, de->d_name) == 0) ||
+                (strcmp(DOTDOT, de->d_name) == 0)) continue;
         if (reply[0] != 0) strlcat(reply, " ", REPLY_MAX);
         if (strlcat(reply, de->d_name, REPLY_MAX) >= REPLY_MAX) {
             LOGE("reply is too long(too many files under '%s'\n", dir);
@@ -50,31 +53,25 @@
     return 0;
 }
 
-static int copy_keyfile(const char *keystore, const char *srcfile) {
-    int srcfd, dstfd;
-    int length;
-    char buf[2048];
-    char dstfile[KEYNAME_LENGTH];
-    const char *filename = strrchr(srcfile, '/');
+static int copy_keyfile(const char *src, int src_type, const char *dstfile) {
+    int srcfd = -1, dstfd;
+    char buf[REPLY_MAX];
 
-    strlcpy(dstfile, keystore, KEYNAME_LENGTH);
-    strlcat(dstfile, "/", KEYNAME_LENGTH);
-    if (strlcat(dstfile, filename ? filename + 1 : srcfile,
-                KEYNAME_LENGTH) >= KEYNAME_LENGTH) {
-        LOGE("keyname is too long '%s'\n", srcfile);
-        return -1;
-    }
-
-    if ((srcfd = open(srcfile, O_RDONLY)) == -1) {
-        LOGE("Cannot open the original file '%s'\n", srcfile);
+    if ((src_type == IS_FILE) && (srcfd = open(src, O_RDONLY)) == -1) {
+        LOGE("Cannot open the original file '%s'\n", src);
         return -1;
     }
     if ((dstfd = open(dstfile, O_CREAT|O_RDWR)) == -1) {
         LOGE("Cannot open the destination file '%s'\n", dstfile);
         return -1;
     }
-    while((length = read(srcfd, buf, 2048)) > 0) {
-        write(dstfd, buf, length);
+    if (src_type == IS_FILE) {
+        int length;
+        while((length = read(srcfd, buf, REPLY_MAX)) > 0) {
+            write(dstfd, buf, length);
+        }
+    } else {
+        write(dstfd, src, strlen(src));
     }
     close(srcfd);
     close(dstfd);
@@ -82,60 +79,149 @@
     return 0;
 }
 
-static int install_key(const char *dir, const char *keyfile)
+static int install_key(const char *path, const char *certname, const char *src,
+        int src_is_file, char *dstfile)
 {
     struct dirent *de;
+    char fullpath[KEYNAME_LENGTH];
     DIR *d;
 
-    if ((d = open_keystore(dir)) == NULL) {
+    if (snprintf(fullpath, sizeof(fullpath), "%s/%s/", path, certname)
+            >= KEYNAME_LENGTH) {
+        LOGE("cert name '%s' is too long.\n", certname);
         return -1;
     }
-    return copy_keyfile(dir, keyfile);
+
+    if ((d = open_keystore(fullpath)) == NULL) {
+        LOGE("Can not open the keystore '%s'\n", fullpath);
+        return -1;
+    }
+    closedir(d);
+    if (strlcat(fullpath, dstfile, KEYNAME_LENGTH) >= KEYNAME_LENGTH) {
+        LOGE("cert name '%s' is too long.\n", certname);
+        return -1;
+    }
+    return copy_keyfile(src, src_is_file, fullpath);
 }
 
-static int remove_key(const char *dir, const char *keyfile)
+static int get_key(const char *path, const char *keyname, const char *file,
+        char reply[REPLY_MAX])
 {
-    char dstfile[KEYNAME_LENGTH];
+    struct dirent *de;
+    char filename[KEYNAME_LENGTH];
+    int fd;
 
-    strlcpy(dstfile, dir, KEYNAME_LENGTH);
-    strlcat(dstfile, "/", KEYNAME_LENGTH);
-    if (strlcat(dstfile, keyfile, KEYNAME_LENGTH) >= KEYNAME_LENGTH) {
-        LOGE("keyname is too long '%s'\n", keyfile);
+    if (snprintf(filename, sizeof(filename), "%s/%s/%s", path, keyname, file)
+            >= KEYNAME_LENGTH) {
+        LOGE("cert name '%s' is too long.\n", keyname);
         return -1;
     }
-    if (unlink(dstfile)) {
-        LOGE("cannot delete '%s': %s\n", dstfile, strerror(errno));
+
+    if ((fd = open(filename, O_RDONLY)) == -1) {
+        return -1;
+    }
+    close(fd);
+    strlcpy(reply, filename, REPLY_MAX);
+    return 0;
+}
+
+static int remove_key(const char *dir, const char *key)
+{
+    char dstfile[KEYNAME_LENGTH];
+    char *keyfile[4] = { USER_KEY, USER_P12_CERT, USER_CERTIFICATE,
+            CA_CERTIFICATE };
+    int i, count = 0;
+
+    for ( i = 0 ; i < 4 ; i++) {
+        if (snprintf(dstfile, KEYNAME_LENGTH, "%s/%s/%s", dir, key, keyfile[i])
+                >= KEYNAME_LENGTH) {
+            LOGE("keyname is too long '%s'\n", key);
+            return -1;
+        }
+        if (unlink(dstfile) == 0) count++;
+    }
+
+    if (count == 0) {
+        LOGE("can not clean up '%s' keys or not exist\n", key);
+        return -1;
+    }
+
+    snprintf(dstfile, KEYNAME_LENGTH, "%s/%s", dir, key);
+    if (rmdir(dstfile)) {
+        LOGE("can not clean up '%s' directory\n", key);
         return -1;
     }
     return 0;
 }
 
-int list_certs(char reply[REPLY_MAX])
+int list_user_certs(char reply[REPLY_MAX])
 {
     return list_files(CERTS_DIR, reply);
 }
 
-int list_userkeys(char reply[REPLY_MAX])
+int list_ca_certs(char reply[REPLY_MAX])
 {
-    return list_files(USERKEYS_DIR, reply);
+    return list_files(CACERTS_DIR, reply);
 }
 
-int install_cert(const char *certfile)
+int install_user_cert(const char *keyname, const char *cert, const char *key)
 {
-    return install_key(CERTS_DIR, certfile);
+    if (install_key(CERTS_DIR, keyname, cert, IS_FILE, USER_CERTIFICATE) == 0) {
+        return install_key(CERTS_DIR, keyname, key, IS_FILE, USER_KEY);
+    }
+    return -1;
 }
 
-int install_userkey(const char *keyfile)
+int install_ca_cert(const char *keyname, const char *certfile)
 {
-    return install_key(USERKEYS_DIR, keyfile);
+    return install_key(CACERTS_DIR, keyname, certfile, IS_FILE, CA_CERTIFICATE);
 }
 
-int remove_cert(const char *certfile)
+int install_p12_cert(const char *keyname, const char *certfile)
 {
-    return remove_key(CERTS_DIR, certfile);
+    return install_key(CERTS_DIR, keyname, certfile, IS_FILE, USER_P12_CERT);
 }
 
-int remove_userkey(const char *keyfile)
+int add_ca_cert(const char *keyname, const char *certificate)
 {
-    return remove_key(USERKEYS_DIR, keyfile);
+    return install_key(CACERTS_DIR, keyname, certificate, IS_CONTENT,
+            CA_CERTIFICATE);
+}
+
+int add_user_cert(const char *keyname, const char *certificate)
+{
+    return install_key(CERTS_DIR, keyname, certificate, IS_CONTENT,
+            USER_CERTIFICATE);
+}
+
+int add_user_key(const char *keyname, const char *key)
+{
+    return install_key(CERTS_DIR, keyname, key, IS_CONTENT, USER_KEY);
+}
+
+int get_ca_cert(const char *keyname, char reply[REPLY_MAX])
+{
+    return get_key(CACERTS_DIR, keyname, CA_CERTIFICATE, reply);
+}
+
+int get_user_cert(const char *keyname, char reply[REPLY_MAX])
+{
+    return get_key(CERTS_DIR, keyname, USER_CERTIFICATE, reply);
+}
+
+int get_user_key(const char *keyname, char reply[REPLY_MAX])
+{
+    if(get_key(CERTS_DIR, keyname, USER_KEY, reply))
+        return get_key(CERTS_DIR, keyname, USER_P12_CERT, reply);
+    return 0;
+}
+
+int remove_user_cert(const char *key)
+{
+    return remove_key(CERTS_DIR, key);
+}
+
+int remove_ca_cert(const char *key)
+{
+    return remove_key(CACERTS_DIR, key);
 }