Merge change 6162 into donut

* changes:
  Hold a wakelock during backup/restore/clear operations
diff --git a/cmds/keystore/certtool.h b/cmds/keystore/certtool.h
index 7cd316b..aefad66 100644
--- a/cmds/keystore/certtool.h
+++ b/cmds/keystore/certtool.h
@@ -26,21 +26,29 @@
 #include "common.h"
 #include "netkeystore.h"
 
+#define CERT_NAME_LEN (2 * MAX_KEY_NAME_LENGTH + 2)
+
 /*
  * The specific function 'get_cert' is used in daemons to get the key value
  * from keystore. Caller should allocate the buffer and the length of the buffer
  * should be MAX_KEY_VALUE_LENGTH.
  */
-static inline int get_cert(char *certname, unsigned char *value, int *size)
+static inline int get_cert(const char *certname, unsigned char *value, int *size)
 {
     int count, fd, ret = -1;
     LPC_MARSHAL cmd;
     char delimiter[] = "_";
     char *namespace, *keyname;
     char *context = NULL;
+    char cname[CERT_NAME_LEN];
 
-    if (value == NULL) {
-        LOGE("get_cert: value is null\n");
+    if ((certname == NULL) || (value == NULL)) {
+        LOGE("get_cert: certname or value is null\n");
+        return -1;
+    }
+
+    if (strlcpy(cname, certname, CERT_NAME_LEN) >= CERT_NAME_LEN) {
+        LOGE("get_cert: keyname is too long\n");
         return -1;
     }
 
@@ -53,7 +61,7 @@
     }
 
     cmd.opcode = GET;
-    if (((namespace = strtok_r(certname, delimiter, &context)) == NULL) ||
+    if (((namespace = strtok_r(cname, delimiter, &context)) == NULL) ||
         ((keyname = strtok_r(NULL, delimiter, &context)) == NULL)) {
         goto err;
     }
diff --git a/cmds/keystore/keymgmt.c b/cmds/keystore/keymgmt.c
index e4102a9..66edd56 100644
--- a/cmds/keystore/keymgmt.c
+++ b/cmds/keystore/keymgmt.c
@@ -185,6 +185,7 @@
         p = strtok_r(NULL, delimiter, &context);
     }
     if (count != 2) return -1;
+    if (strlen(new_pass) < MIN_PASSWD_LENGTH) return -1;
     if ((ret = get_master_key(old_pass, master_key)) == 0) {
         ret = store_master_key(new_pass, master_key);
         retry_count = 0;
@@ -259,6 +260,11 @@
     DIR *d;
     struct dirent *de;
 
+    if (state != UNLOCKED) {
+        LOGE("Can not list key with current state %d\n", state);
+        return -1;
+    }
+
     if (!namespace || ((d = opendir("."))) == NULL) {
         LOGE("cannot open keystore dir or namespace is null\n");
         return -1;
@@ -287,6 +293,7 @@
 {
     if (state == UNINITIALIZED) {
         if (strchr(data, ' ')) return -1;
+        if (strlen(data) < MIN_PASSWD_LENGTH) return -1;
         return create_master_key(data);
     }
     return change_passwd(data);
diff --git a/cmds/keystore/keymgmt.h b/cmds/keystore/keymgmt.h
index 0f10570..0e928db 100644
--- a/cmds/keystore/keymgmt.h
+++ b/cmds/keystore/keymgmt.h
@@ -27,7 +27,8 @@
 #define AES_KEY_LEN     128
 #define USER_KEY_LEN    (AES_KEY_LEN/8)
 #define IV_LEN          USER_KEY_LEN
-#define MAX_RETRY_COUNT 6
+#define MAX_RETRY_COUNT   6
+#define MIN_PASSWD_LENGTH 8
 
 #define gen_key(passwd, key, len) \
                 PKCS5_PBKDF2_HMAC_SHA1(passwd, strlen(passwd), \
diff --git a/cmds/keystore/keystore_get.h b/cmds/keystore/keystore_get.h
new file mode 100644
index 0000000..a7fd9a5
--- /dev/null
+++ b/cmds/keystore/keystore_get.h
@@ -0,0 +1,53 @@
+/*
+**
+** 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.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+
+#ifndef __KEYSTORE_GET_H__
+#define __KEYSTORE_GET_H__
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "certtool.h"
+
+/* This function is provided to native components to get values from keystore.
+ * Users are required to link against libcutils. If something goes wrong, NULL
+ * is returned. Otherwise it returns the value in dynamically allocated memory
+ * and sets the size if the pointer is not NULL. One can release the memory by
+ * calling free(). */
+static char *keystore_get(char *key, int *size)
+{
+    char buffer[MAX_KEY_VALUE_LENGTH];
+    char *value;
+    int length;
+
+    if (get_cert(key, (unsigned char *)buffer, &length) != 0) {
+        return NULL;
+    }
+    value = malloc(length + 1);
+    if (!value) {
+        return NULL;
+    }
+    memcpy(value, buffer, length);
+    value[length] = 0;
+    if (size) {
+        *size = length;
+    }
+    return value;
+}
+
+#endif
diff --git a/cmds/keystore/netkeystore.c b/cmds/keystore/netkeystore.c
index e45e24f..eac455e 100644
--- a/cmds/keystore/netkeystore.c
+++ b/cmds/keystore/netkeystore.c
@@ -224,6 +224,7 @@
     }
     reply->retcode = reset_keystore();
 }
+
 static void execute(LPC_MARSHAL *cmd, LPC_MARSHAL *reply)
 {
     uint32_t cmd_max = sizeof(cmds)/sizeof(struct cmdinfo);