summaryrefslogtreecommitdiffstats
path: root/cmds/keystore/keymgmt.c
diff options
context:
space:
mode:
authorChia-chi Yeh <chiachi@android.com>2009-09-24 13:35:26 +0800
committerChia-chi Yeh <chiachi@android.com>2009-09-24 13:35:26 +0800
commit4424dd7dd5d3a0aea9b1a3375db5d65bc8675bb8 (patch)
treeeef7da401bf461b8cd366bf78c9cb252cabb0f3c /cmds/keystore/keymgmt.c
parent7b7c3c15154f95e693981f863f563fba41a7b993 (diff)
downloadframeworks_native-4424dd7dd5d3a0aea9b1a3375db5d65bc8675bb8.zip
frameworks_native-4424dd7dd5d3a0aea9b1a3375db5d65bc8675bb8.tar.gz
frameworks_native-4424dd7dd5d3a0aea9b1a3375db5d65bc8675bb8.tar.bz2
keystore: remove old implementation and test.
The new tests will be implemented in java.
Diffstat (limited to 'cmds/keystore/keymgmt.c')
-rw-r--r--cmds/keystore/keymgmt.c421
1 files changed, 0 insertions, 421 deletions
diff --git a/cmds/keystore/keymgmt.c b/cmds/keystore/keymgmt.c
deleted file mode 100644
index b5ace86..0000000
--- a/cmds/keystore/keymgmt.c
+++ /dev/null
@@ -1,421 +0,0 @@
-/*
-** 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.
-*/
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <sys/stat.h>
-#include <sys/types.h>
-#include <ctype.h>
-#include <fcntl.h>
-#include <dirent.h>
-#include <errno.h>
-#include <openssl/aes.h>
-#include <openssl/evp.h>
-#include <cutils/log.h>
-
-#include "common.h"
-#include "keymgmt.h"
-
-static int retry_count = 0;
-static unsigned char iv[IV_LEN];
-static KEYSTORE_STATE state = BOOTUP;
-static AES_KEY encryptKey, decryptKey;
-
-inline void unlock_keystore(unsigned char *master_key)
-{
- AES_set_encrypt_key(master_key, AES_KEY_LEN, &encryptKey);
- AES_set_decrypt_key(master_key, AES_KEY_LEN, &decryptKey);
- memset(master_key, 0, sizeof(master_key));
- state = UNLOCKED;
-}
-
-inline void lock_keystore()
-{
- memset(&encryptKey, 0 , sizeof(AES_KEY));
- memset(&decryptKey, 0 , sizeof(AES_KEY));
- state = LOCKED;
-}
-
-inline void get_encrypt_key(char *passwd, AES_KEY *key)
-{
- unsigned char user_key[USER_KEY_LEN];
- gen_key(passwd, user_key, USER_KEY_LEN);
- AES_set_encrypt_key(user_key, AES_KEY_LEN, key);
-}
-
-inline void get_decrypt_key(char *passwd, AES_KEY *key)
-{
- unsigned char user_key[USER_KEY_LEN];
- gen_key(passwd, user_key, USER_KEY_LEN);
- AES_set_decrypt_key(user_key, AES_KEY_LEN, key);
-}
-
-static int gen_random_blob(unsigned char *key, int size)
-{
- int ret = 0;
- int fd = open("/dev/urandom", O_RDONLY);
- if (fd == -1) return -1;
- if (read(fd, key, size) != size) ret = -1;
- close(fd);
- return ret;
-}
-
-static int encrypt_n_save(AES_KEY *enc_key, DATA_BLOB *blob,
- const char *keyfile)
-{
- int size, fd, ret = -1;
- unsigned char enc_blob[MAX_BLOB_LEN];
- char tmpfile[KEYFILE_LEN];
-
- if ((keyfile == NULL) || (strlen(keyfile) >= (KEYFILE_LEN - 4))) {
- LOGE("keyfile name is too long or null");
- return -1;
- }
- strcpy(tmpfile, keyfile);
- strcat(tmpfile, ".tmp");
-
- // prepare the blob
- if (IV_LEN > USER_KEY_LEN) {
- LOGE("iv length is too long.");
- return -1;
- }
- memcpy(blob->iv, iv, IV_LEN);
- blob->blob_size = get_blob_size(blob);
- if (blob->blob_size > MAX_BLOB_LEN) {
- LOGE("blob data size is too large.");
- return -1;
- }
- memcpy(enc_blob, blob->blob, blob->blob_size);
- AES_cbc_encrypt((unsigned char *)enc_blob, (unsigned char *)blob->blob,
- blob->blob_size, enc_key, iv, AES_ENCRYPT);
- // write to keyfile
- size = data_blob_size(blob);
- if ((fd = open(tmpfile, O_CREAT|O_RDWR)) == -1) return -1;
- if (write(fd, blob, size) == size) ret = 0;
- close(fd);
- if (!ret) {
- unlink(keyfile);
- rename(tmpfile, keyfile);
- chmod(keyfile, 0440);
- }
- return ret;
-}
-
-static int load_n_decrypt(const char *keyname, const char *keyfile,
- AES_KEY *key, DATA_BLOB *blob)
-{
- int fd, ret = -1;
- if ((fd = open(keyfile, O_RDONLY)) == -1) return -1;
- // get the encrypted blob and iv
- if ((read(fd, blob->iv, sizeof(blob->iv)) != sizeof(blob->iv)) ||
- (read(fd, &blob->blob_size, sizeof(uint32_t)) != sizeof(uint32_t)) ||
- (blob->blob_size > MAX_BLOB_LEN)) {
- goto err;
- } else {
- unsigned char enc_blob[MAX_BLOB_LEN];
- if (read(fd, enc_blob, blob->blob_size) !=
- (int) blob->blob_size) goto err;
- // decrypt the blob
- AES_cbc_encrypt((unsigned char *)enc_blob, (unsigned char*)blob->blob,
- blob->blob_size, key, blob->iv, AES_DECRYPT);
- if (strcmp(keyname, (char*)blob->keyname) == 0) ret = 0;
- }
-err:
- close(fd);
- return ret;
-}
-
-static int store_master_key(char *upasswd, unsigned char *master_key)
-{
- AES_KEY key;
- DATA_BLOB blob;
-
- // prepare the blob
- if (strlen(MASTER_KEY_TAG) >= USER_KEY_LEN) return -1;
- strlcpy(blob.keyname, MASTER_KEY_TAG, USER_KEY_LEN);
- blob.value_size = USER_KEY_LEN;
- if (USER_KEY_LEN > MAX_KEY_VALUE_LENGTH) {
- LOGE("master_key length is too long.");
- return -1;
- }
- memcpy((void*)blob.value, (const void*)master_key, USER_KEY_LEN);
-
- // generate the encryption key
- get_encrypt_key(upasswd, &key);
- return encrypt_n_save(&key, &blob, MASTER_KEY);
-}
-
-static int get_master_key(char *upasswd, unsigned char *master_key)
-{
- AES_KEY key;
- int size, ret = 0;
- DATA_BLOB blob;
-
- get_decrypt_key(upasswd, &key);
- ret = load_n_decrypt(MASTER_KEY_TAG, MASTER_KEY, &key, &blob);
- if (blob.value_size > USER_KEY_LEN) {
- LOGE("the blob's value size is too large");
- return -1;
- }
- if (!ret) memcpy(master_key, blob.value, blob.value_size);
- return ret;
-}
-
-static int create_master_key(char *upasswd)
-{
- int ret;
- unsigned char mpasswd[AES_KEY_LEN];
- unsigned char master_key[USER_KEY_LEN];
-
- gen_random_blob(mpasswd, AES_KEY_LEN);
- gen_key((char*)mpasswd, master_key, USER_KEY_LEN);
- if ((ret = store_master_key(upasswd, master_key)) == 0) {
- unlock_keystore(master_key);
- }
- memset(master_key, 0, USER_KEY_LEN);
- memset(mpasswd, 0, AES_KEY_LEN);
-
- return ret;
-}
-
-int change_passwd(char *old_pass, char *new_pass)
-{
- unsigned char master_key[USER_KEY_LEN];
- int ret;
-
- if (state == UNINITIALIZED) return -1;
- if ((strlen(old_pass) < MIN_PASSWD_LENGTH) ||
- (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;
- } else {
- ret = MAX_RETRY_COUNT - ++retry_count;
- if (ret == 0) {
- retry_count = 0;
- LOGE("passwd:reach max retry count, reset the keystore now.");
- reset_keystore();
- return -1;
- }
-
- }
- return ret;
-}
-
-int remove_key(const char *namespace, const char *keyname)
-{
- char keyfile[KEYFILE_LEN];
-
- if (state != UNLOCKED) return -state;
- if ((strlen(namespace) >= MAX_KEY_NAME_LENGTH) ||
- (strlen(keyname) >= MAX_KEY_NAME_LENGTH)) {
- LOGE("keyname is too long.");
- return -1;
- }
- sprintf(keyfile, KEYFILE_NAME, namespace, keyname);
- return unlink(keyfile);
-}
-
-int put_key(const char *namespace, const char *keyname,
- unsigned char *data, int size)
-{
- DATA_BLOB blob;
- uint32_t real_size;
- char keyfile[KEYFILE_LEN];
-
- if (state != UNLOCKED) {
- LOGE("Can not store key with current state %d\n", state);
- return -state;
- }
- if ((strlen(namespace) >= MAX_KEY_NAME_LENGTH) ||
- (strlen(keyname) >= MAX_KEY_NAME_LENGTH)) {
- LOGE("keyname is too long.");
- return -1;
- }
- sprintf(keyfile, KEYFILE_NAME, namespace, keyname);
- strcpy(blob.keyname, keyname);
- blob.value_size = size;
- if (size > MAX_KEY_VALUE_LENGTH) {
- LOGE("the data size is too large.");
- return -1;
- }
- memcpy(blob.value, data, size);
- return encrypt_n_save(&encryptKey, &blob, keyfile);
-}
-
-int get_key(const char *namespace, const char *keyname,
- unsigned char *data, int *size)
-{
- int ret;
- DATA_BLOB blob;
- uint32_t blob_size;
- char keyfile[KEYFILE_LEN];
-
- if (state != UNLOCKED) {
- LOGE("Can not retrieve key value with current state %d\n", state);
- return -state;
- }
- if ((strlen(namespace) >= MAX_KEY_NAME_LENGTH) ||
- (strlen(keyname) >= MAX_KEY_NAME_LENGTH)) {
- LOGE("keyname is too long.");
- return -1;
- }
- sprintf(keyfile, KEYFILE_NAME, namespace, keyname);
- ret = load_n_decrypt(keyname, keyfile, &decryptKey, &blob);
- if (!ret) {
- if ((blob.value_size > MAX_KEY_VALUE_LENGTH)) {
- LOGE("blob value size is too large.");
- ret = -1;
- } else {
- *size = blob.value_size;
- memcpy(data, blob.value, *size);
- }
- }
- return ret;
-}
-
-int list_keys(const char *namespace, char reply[BUFFER_MAX])
-{
- 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;
- }
-
- if (strlen(namespace) >= MAX_KEY_NAME_LENGTH) {
- LOGE("namespace is too long.");
- return -1;
- }
-
- reply[0] = 0;
- while ((de = readdir(d))) {
- char *prefix, *name, *keyfile = de->d_name;
- char *context = NULL;
-
- if (de->d_type != DT_REG) continue;
- if ((prefix = strtok_r(keyfile, NAME_DELIMITER, &context))
- == NULL) continue;
- if (strcmp(prefix, namespace)) continue;
- if ((name = strtok_r(NULL, NAME_DELIMITER, &context)) == NULL) continue;
- // append the key name into reply
- if (reply[0] != 0) strlcat(reply, " ", BUFFER_MAX);
- if (strlcat(reply, name, BUFFER_MAX) >= BUFFER_MAX) {
- LOGE("too many files under keystore directory\n");
- return -1;
- }
- }
- closedir(d);
- return 0;
-}
-
-int new_passwd(char *password)
-{
- int passwdlen = strlen(password);
-
- if ((state != UNINITIALIZED) || (passwdlen < MIN_PASSWD_LENGTH)) return -1;
- return create_master_key(password);
-}
-
-int lock()
-{
- switch(state) {
- case UNLOCKED:
- lock_keystore();
- case LOCKED:
- return 0;
- default:
- return -1;
- }
-}
-
-int unlock(char *passwd)
-{
- unsigned char master_key[USER_KEY_LEN];
- int ret = get_master_key(passwd, master_key);
- if (!ret) {
- unlock_keystore(master_key);
- retry_count = 0;
- } else {
- ret = MAX_RETRY_COUNT - ++retry_count;
- if (ret == 0) {
- retry_count = 0;
- LOGE("unlock:reach max retry count, reset the keystore now.");
- reset_keystore();
- return -1;
- }
- }
- return ret;
-}
-
-KEYSTORE_STATE get_state()
-{
- return state;
-}
-
-int reset_keystore()
-{
- int ret = 0;
- DIR *d;
- struct dirent *de;
-
- if ((d = opendir(".")) == NULL) {
- LOGE("cannot open keystore dir\n");
- return -1;
- }
- while ((de = readdir(d))) {
- char *dirname = de->d_name;
- if (strcmp(".", dirname) == 0) continue;
- if (strcmp("..", dirname) == 0) continue;
- if (unlink(dirname) != 0) ret = -1;
- }
- closedir(d);
- state = UNINITIALIZED;
- if (ret == 0) {
- LOGI("keystore is reset.");
- } else {
- LOGI("keystore can not be cleaned up entirely.");
- }
- return ret;
-}
-
-int init_keystore(const char *dir)
-{
- int fd;
-
- if (dir) mkdir(dir, 0770);
- if (!dir || chdir(dir)) {
- LOGE("Can not open/create the keystore directory %s\n",
- dir ? dir : "(null)");
- return -1;
- }
- gen_random_blob(iv, IV_LEN);
- if ((fd = open(MASTER_KEY, O_RDONLY)) == -1) {
- state = UNINITIALIZED;
- return 0;
- }
- close(fd);
- state = LOCKED;
- return 0;
-}