summaryrefslogtreecommitdiffstats
path: root/cmds
diff options
context:
space:
mode:
authorChung-yih Wang <cywang@google.com>2009-06-17 01:29:21 +0800
committerChung-yih Wang <cywang@google.com>2009-06-17 14:32:05 +0800
commit4c40420cd231b42a38b84577d6731ce8b0fa1269 (patch)
tree1d24eeef47ec6fc3eaa8b44a5c0323c3c44b7634 /cmds
parentb6d1e5b8ece3e79b606d8441edf89419acf38390 (diff)
downloadframeworks_native-4c40420cd231b42a38b84577d6731ce8b0fa1269.zip
frameworks_native-4c40420cd231b42a38b84577d6731ce8b0fa1269.tar.gz
frameworks_native-4c40420cd231b42a38b84577d6731ce8b0fa1269.tar.bz2
Change the keystore APIs.
1. simplify the keypair selection in UI. 2. add the user certificate and key into the keystore for keygen feature.
Diffstat (limited to 'cmds')
-rw-r--r--cmds/keystore/commands.c170
-rw-r--r--cmds/keystore/keystore.c100
-rw-r--r--cmds/keystore/keystore.h37
3 files changed, 235 insertions, 72 deletions
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 @@ static DIR *open_keystore(const char *dir)
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 @@ static int list_files(const char *dir, char reply[REPLY_MAX]) {
}
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 @@ static int list_files(const char *dir, char reply[REPLY_MAX]) {
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 @@ static int copy_keyfile(const char *keystore, const char *srcfile) {
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;
+ }
+
+ 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(dir, keyfile);
+ 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])
+{
+ struct dirent *de;
+ char filename[KEYNAME_LENGTH];
+ int fd;
+
+ 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 ((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++;
+ }
- 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 (count == 0) {
+ LOGE("can not clean up '%s' keys or not exist\n", key);
return -1;
}
- if (unlink(dstfile)) {
- LOGE("cannot delete '%s': %s\n", dstfile, strerror(errno));
+
+ 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 install_p12_cert(const char *keyname, const char *certfile)
+{
+ return install_key(CERTS_DIR, keyname, certfile, IS_FILE, USER_P12_CERT);
+}
+
+int add_ca_cert(const char *keyname, const char *certificate)
+{
+ 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_cert(const char *certfile)
+int remove_user_cert(const char *key)
{
- return remove_key(CERTS_DIR, certfile);
+ return remove_key(CERTS_DIR, key);
}
-int remove_userkey(const char *keyfile)
+int remove_ca_cert(const char *key)
{
- return remove_key(USERKEYS_DIR, keyfile);
+ return remove_key(CACERTS_DIR, key);
}
diff --git a/cmds/keystore/keystore.c b/cmds/keystore/keystore.c
index 5193b3d..df8d832 100644
--- a/cmds/keystore/keystore.c
+++ b/cmds/keystore/keystore.c
@@ -16,37 +16,89 @@
#include "keystore.h"
+static inline int has_whitespace(char *name)
+{
+ if((strrchr(name, ' ') != NULL)) {
+ LOGE("'%s' contains whitespace character\n", name);
+ return 1;
+ }
+ return 0;
+}
+
+static int do_list_user_certs(char **arg, char reply[REPLY_MAX])
+{
+ return list_user_certs(reply);
+}
+
+static int do_list_ca_certs(char **arg, char reply[REPLY_MAX])
+{
+ return list_ca_certs(reply);
+}
+
+static int do_install_user_cert(char **arg, char reply[REPLY_MAX])
+{
+ if (has_whitespace(arg[0])) return -1;
+ /* copy the certificate and key to keystore */
+ return install_user_cert(arg[0], arg[1], arg[2]);
+}
-static int do_list_certs(char **arg, char reply[REPLY_MAX])
+static int do_install_p12_cert(char **arg, char reply[REPLY_MAX])
{
- return list_certs(reply);
+ if (has_whitespace(arg[0])) return -1;
+ return install_p12_cert(arg[0], arg[1]);
}
-static int do_list_userkeys(char **arg, char reply[REPLY_MAX])
+static int do_install_ca_cert(char **arg, char reply[REPLY_MAX])
{
- return list_userkeys(reply);
+ if (has_whitespace(arg[0])) return -1;
+ /* copy the certificate and key to keystore */
+ return install_ca_cert(arg[0], arg[1]);
}
-static int do_install_cert(char **arg, char reply[REPLY_MAX])
+static int do_add_ca_cert(char **arg, char reply[REPLY_MAX])
{
- return install_cert(arg[0]); /* move the certificate to keystore */
+ if (has_whitespace(arg[0])) return -1;
+ return add_ca_cert(arg[0], arg[1]);
}
-static int do_remove_cert(char **arg, char reply[REPLY_MAX])
+static int do_add_user_cert(char **arg, char reply[REPLY_MAX])
{
- return remove_cert(arg[0]); /* certificate */
+ if (has_whitespace(arg[0])) return -1;
+ return add_user_cert(arg[0], arg[1]);
}
-static int do_install_userkey(char **arg, char reply[REPLY_MAX])
+static int do_add_user_key(char **arg, char reply[REPLY_MAX])
{
- return install_userkey(arg[0]); /* move the certificate to keystore */
+ if (has_whitespace(arg[0])) return -1;
+ return add_user_key(arg[0], arg[1]);
}
-static int do_remove_userkey(char **arg, char reply[REPLY_MAX])
+static int do_get_ca_cert(char **arg, char reply[REPLY_MAX])
{
- return remove_userkey(arg[0]); /* userkey */
+ return get_ca_cert(arg[0], reply);
}
+static int do_get_user_cert(char **arg, char reply[REPLY_MAX])
+{
+ return get_user_cert(arg[0], reply);
+}
+
+static int do_get_user_key(char **arg, char reply[REPLY_MAX])
+{
+ return get_user_key(arg[0], reply);
+}
+
+static int do_remove_user_cert(char **arg, char reply[REPLY_MAX])
+{
+ return remove_user_cert(arg[0]);
+}
+
+static int do_remove_ca_cert(char **arg, char reply[REPLY_MAX])
+{
+ return remove_ca_cert(arg[0]);
+}
+
+
struct cmdinfo {
const char *name;
unsigned numargs;
@@ -55,12 +107,19 @@ struct cmdinfo {
struct cmdinfo cmds[] = {
- { "listcerts", 0, do_list_certs },
- { "listuserkeys", 0, do_list_userkeys },
- { "installcert", 1, do_install_cert },
- { "removecert", 1, do_remove_cert },
- { "installuserkey", 1, do_install_userkey },
- { "removeuserkey", 1, do_remove_userkey },
+ { "listcacerts", 0, do_list_ca_certs },
+ { "listusercerts", 0, do_list_user_certs },
+ { "installusercert", 3, do_install_user_cert },
+ { "installcacert", 2, do_install_ca_cert },
+ { "installp12cert", 2, do_install_p12_cert },
+ { "addusercert", 2, do_add_user_cert },
+ { "adduserkey", 2, do_add_user_key },
+ { "addcacert", 2, do_add_ca_cert },
+ { "getusercert", 1, do_get_user_cert },
+ { "getuserkey", 1, do_get_user_key },
+ { "getcacert", 1, do_get_ca_cert },
+ { "removecacert", 1, do_remove_ca_cert },
+ { "removeusercert", 1, do_remove_user_cert },
};
static int readx(int s, void *_buf, int count)
@@ -121,7 +180,7 @@ static int execute(int s, char cmd[BUFFER_MAX])
/* n is number of args (not counting arg[0]) */
arg[0] = cmd;
while (*cmd) {
- if (isspace(*cmd)) {
+ if (*cmd == CMD_DELIMITER) {
*cmd++ = 0;
n++;
arg[n] = cmd;
@@ -167,6 +226,7 @@ int shell_command(const int argc, const char **argv)
int fd, i;
short ret;
unsigned short count;
+ char delimiter[2] = { CMD_DELIMITER, 0 };
char buf[BUFFER_MAX]="";
fd = socket_local_client(SOCKET_PATH,
@@ -177,7 +237,7 @@ int shell_command(const int argc, const char **argv)
exit(1);
}
for(i = 0; i < argc; i++) {
- if (i > 0) strlcat(buf, " ", BUFFER_MAX);
+ if (i > 0) strlcat(buf, delimiter, BUFFER_MAX);
if(strlcat(buf, argv[i], BUFFER_MAX) >= BUFFER_MAX) {
fprintf(stderr, "Arguments are too long\n");
exit(1);
diff --git a/cmds/keystore/keystore.h b/cmds/keystore/keystore.h
index 35acf0b..b9cb185 100644
--- a/cmds/keystore/keystore.h
+++ b/cmds/keystore/keystore.h
@@ -40,18 +40,35 @@
/* path of the keystore */
#define KEYSTORE_DIR_PREFIX "/data/misc/keystore"
-#define CERTS_DIR KEYSTORE_DIR_PREFIX "/certs"
-#define USERKEYS_DIR KEYSTORE_DIR_PREFIX "/userkeys"
+#define CERTS_DIR KEYSTORE_DIR_PREFIX "/keys"
+#define CACERTS_DIR KEYSTORE_DIR_PREFIX "/cacerts"
+#define CA_CERTIFICATE "ca.crt"
+#define USER_CERTIFICATE "user.crt"
+#define USER_P12_CERT "user.p12"
+#define USER_KEY "user.key"
+#define DOT "."
+#define DOTDOT ".."
-#define BUFFER_MAX 1024 /* input buffer for commands */
+#define BUFFER_MAX 4096 /* input buffer for commands */
#define TOKEN_MAX 8 /* max number of arguments in buffer */
-#define REPLY_MAX 1024 /* largest reply allowed */
+#define REPLY_MAX 4096 /* largest reply allowed */
+#define CMD_DELIMITER '\t'
#define KEYNAME_LENGTH 128
+#define IS_CONTENT 0
+#define IS_FILE 1
+
/* commands.c */
-int list_certs(char reply[REPLY_MAX]);
-int list_userkeys(char reply[REPLY_MAX]);
-int install_cert(const char *certfile);
-int install_userkey(const char *keyfile);
-int remove_cert(const char *certfile);
-int remove_userkey(const char *keyfile);
+int list_ca_certs(char reply[REPLY_MAX]);
+int list_user_certs(char reply[REPLY_MAX]);
+int install_user_cert(const char *certname, const char *cert, const char *key);
+int install_ca_cert(const char *certname, const char *cert);
+int install_p12_cert(const char *certname, const char *cert);
+int add_ca_cert(const char *certname, const char *content);
+int add_user_cert(const char *certname, const char *content);
+int add_user_key(const char *keyname, const char *content);
+int get_ca_cert(const char *keyname, char reply[REPLY_MAX]);
+int get_user_cert(const char *keyname, char reply[REPLY_MAX]);
+int get_user_key(const char *keyname, char reply[REPLY_MAX]);
+int remove_user_cert(const char *certname);
+int remove_ca_cert(const char *certname);