diff --git a/keystore/java/android/security/CertTool.java b/keystore/java/android/security/CertTool.java
deleted file mode 100644
index 88d6e3d..0000000
--- a/keystore/java/android/security/CertTool.java
+++ /dev/null
@@ -1,357 +0,0 @@
-/*
- * Copyright (C) 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.
- */
-
-package android.security;
-
-import android.content.Context;
-import android.content.Intent;
-import android.security.Keystore;
-import android.text.TextUtils;
-import android.util.Log;
-
-import java.io.ByteArrayInputStream;
-import java.io.IOException;
-import java.security.cert.Certificate;
-import java.security.cert.CertificateException;
-import java.security.KeyStoreException;
-import java.security.NoSuchAlgorithmException;
-import java.security.UnrecoverableKeyException;
-import java.util.ArrayList;
-
-/**
- * The CertTool class provides the functions to list the certs/keys,
- * generate the certificate request(csr) and store certificates into
- * keystore.
- *
- * {@hide}
- */
-public class CertTool {
-    static {
-        System.loadLibrary("certtool_jni");
-    }
-
-    /** Keystore namespace for CA certificates. */
-    public static final String CA_CERTIFICATE = "CACERT";
-
-    /** Keystore namespace for user certificates. */
-    public static final String USER_CERTIFICATE = "USRCERT";
-
-    /** Keystore namespace for user private keys. */
-    public static final String USER_KEY = "USRKEY";
-
-    /** Action string for adding certificates to keystore. */
-    public static final String ACTION_ADD_CREDENTIAL =
-            "android.security.ADD_CREDENTIAL";
-
-    /** Action string for installing certificates to keystore from sdcard. */
-    public static final String ACTION_INSTALL_CERT_FROM_SDCARD =
-            "android.security.INSTALL_CERT_FROM_SDCARD";
-
-    /** Dialog title for adding a CA certificate. */
-    public static final String TITLE_CA_CERT = "CA Certificate";
-
-    /** Dialog title for adding a user certificate. */
-    public static final String TITLE_USER_CERT = "User Certificate";
-
-    /** Dialog title for adding a user private key. */
-    public static final String TITLE_PRIVATE_KEY = "Private Key";
-
-    /** Dialog title for adding a PKCS12 keystore. */
-    public static final String TITLE_PKCS12_KEYSTORE = "PKCS12 Keystore";
-
-    public static final int INCORRECT_PKCS12_PASSPHRASE = -100;
-
-    /**
-     * The builder class for building an add-credential-to-keystore intent.
-     */
-    public static class AddCredentialIntentBuilder {
-        private Intent mIntent;
-        private int mCount;
-
-        /**
-         * Creates a builder to build a add-credential-to-keystore intent.
-         *
-         * @param title title of the dialog for adding this credential
-         * @param descriptions description strings to show on the dialog
-         */
-        public AddCredentialIntentBuilder(String title,
-                String... descriptions) {
-            Intent intent = new Intent(ACTION_ADD_CREDENTIAL);
-            intent.putExtra(KEY_TITLE, title);
-
-            int i = 0;
-            for (String description : descriptions) {
-                intent.putExtra(KEY_DESCRIPTION + (i++), description);
-            }
-            mIntent = intent;
-        }
-
-        /**
-         * Adds credential data to the intent.
-         *
-         * @param namespace the namespace of the keystore to add the credential
-         *      data to
-         * @param data the credential data
-         * @return this builder
-         */
-        public AddCredentialIntentBuilder addCredential(String namespace,
-                byte[] data) {
-            mIntent.putExtra(KEY_NAMESPACE + mCount, namespace);
-            mIntent.putExtra(KEY_ITEM + mCount, data);
-            mCount++;
-            return this;
-        }
-
-        /** Returns the intent. */
-        public Intent build() {
-            return mIntent;
-        }
-    }
-
-    /**
-     * Request for adding credential data to keystore.
-     */
-    public static class AddCredentialRequest {
-        private Intent mIntent;
-
-        /**
-         * Creates an add-credential-data-to-keystore request.
-         *
-         * @param intent an add-credential-data-to-keystore intent
-         * @see AddCredentialIntentBuilder
-         */
-        public AddCredentialRequest(Intent intent) {
-            mIntent = intent;
-        }
-
-        /** Returns the dialog title. */
-        public String getTitle() {
-            return mIntent.getStringExtra(KEY_TITLE);
-        }
-
-        /**
-         * Returns the i'th credential data.
-         * @return the data or null if not exists
-         */
-        public byte[] getDataAt(int i) {
-            return mIntent.getByteArrayExtra(KEY_ITEM + i);
-        }
-
-        /**
-         * Returns the namespace of the i'th credential data.
-         * @return the namespace string or null if missing
-         */
-        public String getNamespaceAt(int i) {
-            return mIntent.getStringExtra(KEY_NAMESPACE + i);
-        }
-
-        /** Returns the descriptions of the credential data. */
-        public String[] getDescriptions() {
-            ArrayList<String> list = new ArrayList<String>();
-            for (int i = 0; ; i++) {
-                String s = mIntent.getStringExtra(KEY_DESCRIPTION + i);
-                if (s == null) break;
-                list.add(s);
-            }
-            return list.toArray(new String[list.size()]);
-        }
-    }
-
-    private static final String KEY_TITLE = "typeName";
-    private static final String KEY_ITEM = "item";
-    private static final String KEY_NAMESPACE = "namespace";
-    private static final String KEY_DESCRIPTION = "description";
-
-    private static final String TAG = "CertTool";
-    private static final String UNKNOWN = "Unknown";
-    private static final String ISSUER_NAME = "Issuer Name:";
-    private static final String DISTINCT_NAME = "Distinct Name:";
-
-    private static final String KEYNAME_DELIMITER = "_";
-    private static final Keystore sKeystore = Keystore.getInstance();
-
-    private native int getPkcs12Handle(byte[] data, String password);
-    private native String getPkcs12Certificate(int handle);
-    private native String getPkcs12PrivateKey(int handle);
-    private native String popPkcs12CertificateStack(int handle);
-    private native void freePkcs12Handle(int handle);
-    private native String generateCertificateRequest(int bits, String challenge);
-    private native boolean isPkcs12Keystore(byte[] data);
-    private native int generateX509Certificate(byte[] data);
-    private native boolean isCaCertificate(int handle);
-    private native String getIssuerDN(int handle);
-    private native String getCertificateDN(int handle);
-    private native String getPrivateKeyPEM(int handle);
-    private native void freeX509Certificate(int handle);
-
-    private static CertTool sSingleton = null;
-
-    private CertTool() { }
-
-    public static final CertTool getInstance() {
-        if (sSingleton == null) {
-            sSingleton = new CertTool();
-        }
-        return sSingleton;
-    }
-
-    /**
-     * Gets the full key to retrieve the user private key from the keystore.
-     * @see #getAllUserCertificateKeys()
-     */
-    public String getUserPrivateKey(String key) {
-        return USER_KEY + KEYNAME_DELIMITER + key;
-    }
-
-    /**
-     * Gets the full key to retrieve the user certificate from the keystore.
-     * @see #getAllUserCertificateKeys()
-     */
-    public String getUserCertificate(String key) {
-        return USER_CERTIFICATE + KEYNAME_DELIMITER + key;
-    }
-
-    /**
-     * Gets the full key to retrieve the CA certificate from the keystore.
-     * @see #getAllCaCertificateKeys()
-     */
-    public String getCaCertificate(String key) {
-        return CA_CERTIFICATE + KEYNAME_DELIMITER + key;
-    }
-
-    /**
-     * Gets all the keys to the user certificates/private keys stored in the
-     * keystore.
-     * @see #getUserCertificate(String)
-     * @see #getUserPrivateKey(String)
-     */
-    public String[] getAllUserCertificateKeys() {
-        return sKeystore.listKeys(USER_KEY);
-    }
-
-    /**
-     * Gets all the keys to the CA certificates stored in the keystore.
-     * @see #getCaCertificate(String)
-     */
-    public String[] getAllCaCertificateKeys() {
-        return sKeystore.listKeys(CA_CERTIFICATE);
-    }
-
-    public String[] getSupportedKeyStrenghs() {
-        return new String[] {"High Grade", "Medium Grade"};
-    }
-
-    private int getKeyLength(int index) {
-        if (index == 0) return 2048;
-        return 1024;
-    }
-
-    /**
-     * Generates a key pair.
-     *
-     * @param keyStrengthIndex index to the array of supported key strengths;
-     *      see {@link #getSupportedKeyStrenghs()}
-     * @param challenge the challenge string for generating the pair
-     * @param dirName (not used)
-     * @return a certificate request from the resulted public key
-     */
-    public String generateKeyPair(int keyStrengthIndex, String challenge,
-            String dirName) {
-        return generateCertificateRequest(getKeyLength(keyStrengthIndex),
-                challenge);
-    }
-
-    private int extractAndStoreKeysFromPkcs12(int handle, String keyname) {
-        int ret, i = 0;
-        String pemData;
-
-        if ((pemData = getPkcs12Certificate(handle)) != null) {
-            if ((ret = sKeystore.put(USER_CERTIFICATE, keyname, pemData)) != 0) {
-                return ret;
-            }
-        }
-        if ((pemData = getPkcs12PrivateKey(handle)) != null) {
-            if ((ret = sKeystore.put(USER_KEY, keyname, pemData)) != 0) {
-                return ret;
-            }
-        }
-        if ((pemData = this.popPkcs12CertificateStack(handle)) != null) {
-            if ((ret = sKeystore.put(CA_CERTIFICATE, keyname, pemData)) != 0) {
-                return ret;
-            }
-        }
-        return 0;
-    }
-
-    /** Adds a PKCS12 keystore to the keystore. */
-    public int addPkcs12Keystore(byte[] p12Data, String password,
-            String keyname) {
-        int handle, ret;
-        Log.i("CertTool", "addPkcs12Keystore()");
-
-        if ((handle = getPkcs12Handle(p12Data, password)) == 0) {
-            return INCORRECT_PKCS12_PASSPHRASE;
-        }
-        ret = extractAndStoreKeysFromPkcs12(handle, keyname);
-        freePkcs12Handle(handle);
-        return ret;
-    }
-
-    /**
-     * Adds a certificate to the keystore.
-     *
-     * @param data the certificate data
-     * @param context the context to send an add-credential-to-keystore intent
-     */
-    public synchronized void addCertificate(byte[] data, Context context) {
-        int handle;
-        Intent intent = null;
-
-        Log.i("CertTool", "addCertificate()");
-        if (isPkcs12Keystore(data)) {
-            intent = prepareIntent(TITLE_PKCS12_KEYSTORE, UNKNOWN, UNKNOWN)
-                    .addCredential(USER_KEY, data).build();
-        } else if ((handle = generateX509Certificate(data)) != 0) {
-            String issuer = getIssuerDN(handle);
-            String distinctName = getCertificateDN(handle);
-            String privateKeyPEM = getPrivateKeyPEM(handle);
-            if (isCaCertificate(handle)) {
-                intent = prepareIntent(TITLE_CA_CERT, issuer, distinctName)
-                        .addCredential(CA_CERTIFICATE, data).build();
-            } else {
-                AddCredentialIntentBuilder builder =
-                        prepareIntent(TITLE_USER_CERT, issuer, distinctName)
-                        .addCredential(USER_CERTIFICATE, data);
-                if (!TextUtils.isEmpty(privateKeyPEM)) {
-                    builder.addCredential(USER_KEY, privateKeyPEM.getBytes());
-                }
-                intent = builder.build();
-            }
-            freeX509Certificate(handle);
-        }
-        if (intent != null) {
-            context.startActivity(intent);
-        } else {
-            Log.w("CertTool", "incorrect data for addCertificate()");
-        }
-    }
-
-    private AddCredentialIntentBuilder prepareIntent(
-            String title, String issuer, String distinctName) {
-        return new AddCredentialIntentBuilder(title, ISSUER_NAME + issuer,
-                DISTINCT_NAME + distinctName);
-    }
-}
diff --git a/keystore/java/android/security/Keystore.java b/keystore/java/android/security/Keystore.java
deleted file mode 100644
index b47ae12..0000000
--- a/keystore/java/android/security/Keystore.java
+++ /dev/null
@@ -1,133 +0,0 @@
-/*
- * Copyright (C) 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.
- */
-
-package android.security;
-
-/**
- * The Keystore class provides the functions to list the certs/keys in keystore.
- * {@hide}
- */
-
-public abstract class Keystore {
-    /** Action to unlock (or initialize) the keystore. */
-    public static final String ACTION_UNLOCK_CREDENTIAL_STORAGE =
-            "android.security.UNLOCK_CREDENTIAL_STORAGE";
-
-    // Keystore States
-    public static final int BOOTUP = 0;
-    public static final int UNINITIALIZED = 1;
-    public static final int LOCKED = 2;
-    public static final int UNLOCKED = 3;
-
-    private static final String TAG = "Keystore";
-    private static final String[] NOTFOUND = new String[0];
-
-    public static Keystore getInstance() {
-        return new FileKeystore();
-    }
-
-    public abstract int lock();
-    public abstract int unlock(String password);
-    public abstract int getState();
-    public abstract int changePassword(String oldPassword, String newPassword);
-    public abstract int setPassword(String firstPassword);
-    public abstract String[] listKeys(String namespace);
-    public abstract int put(String namespace, String keyname, String value);
-    public abstract String get(String namespace, String keyname);
-    public abstract int remove(String namespace, String keyname);
-    public abstract int reset();
-
-    private static class FileKeystore extends Keystore {
-        private static final String SERVICE_NAME = "keystore";
-        private static final String CA_CERTIFICATE = "CaCertificate";
-        private static final String USER_CERTIFICATE = "UserCertificate";
-        private static final String USER_KEY = "UserPrivateKey";
-        private static final ServiceCommand mServiceCommand =
-                new ServiceCommand(SERVICE_NAME);
-
-        @Override
-        public int lock() {
-            Reply result = mServiceCommand.execute(ServiceCommand.LOCK);
-            return (result != null) ? result.returnCode : -1;
-        }
-
-        @Override
-        public int unlock(String password) {
-            Reply result = mServiceCommand.execute(ServiceCommand.UNLOCK,
-                    password);
-            return (result != null) ? result.returnCode : -1;
-        }
-
-        @Override
-        public int getState() {
-            Reply result = mServiceCommand.execute(ServiceCommand.GET_STATE);
-            return (result != null) ? result.returnCode : -1;
-        }
-
-        @Override
-        public int changePassword(String oldPassword, String newPassword) {
-            Reply result = mServiceCommand.execute(ServiceCommand.PASSWD,
-                    oldPassword, newPassword);
-            return (result != null) ? result.returnCode : -1;
-        }
-
-        @Override
-        public int setPassword(String firstPassword) {
-            Reply result = mServiceCommand.execute(ServiceCommand.PASSWD,
-                    firstPassword);
-            return (result != null) ? result.returnCode : -1;
-        }
-
-        @Override
-        public String[] listKeys(String namespace) {
-            Reply result = mServiceCommand.execute(ServiceCommand.LIST_KEYS,
-                    namespace);
-            if ((result == null) || (result.returnCode != 0) ||
-                    (result.len == 0)) {
-                return NOTFOUND;
-            }
-            return new String(result.data, 0, result.len).split("\\s+");
-        }
-
-        @Override
-        public int put(String namespace, String keyname, String value) {
-            Reply result = mServiceCommand.execute(ServiceCommand.PUT_KEY,
-                    namespace, keyname, value);
-            return (result != null) ? result.returnCode : -1;
-        }
-
-        @Override
-        public String get(String namespace, String keyname) {
-            Reply result = mServiceCommand.execute(ServiceCommand.GET_KEY,
-                    namespace, keyname);
-            return (result != null) ? ((result.returnCode != 0) ? null :
-                    new String(result.data, 0, result.len)) : null;
-        }
-
-        @Override
-        public int remove(String namespace, String keyname) {
-            Reply result = mServiceCommand.execute(ServiceCommand.REMOVE_KEY,
-                    namespace, keyname);
-            return (result != null) ? result.returnCode : -1;
-        }
-
-        @Override
-        public int reset() {
-            Reply result = mServiceCommand.execute(ServiceCommand.RESET);
-            return (result != null) ? result.returnCode : -1;
-        }
-    }
-}
diff --git a/keystore/jni/Android.mk b/keystore/jni/Android.mk
deleted file mode 100644
index 92c2d6d..0000000
--- a/keystore/jni/Android.mk
+++ /dev/null
@@ -1,31 +0,0 @@
-LOCAL_PATH:= $(call my-dir)
-include $(CLEAR_VARS)
-
-LOCAL_SRC_FILES:= \
-    cert.c certtool.c
-
-LOCAL_C_INCLUDES += \
-  $(JNI_H_INCLUDE) \
-  external/openssl/include
-
-LOCAL_SHARED_LIBRARIES := \
-  libcutils \
-  libnativehelper \
-  libutils \
-  libcrypto
-
-ifeq ($(TARGET_SIMULATOR),true)
-ifeq ($(TARGET_OS),linux)
-ifeq ($(TARGET_ARCH),x86)
-LOCAL_LDLIBS += -lpthread -ldl -lrt -lssl
-endif
-endif
-endif
-
-ifeq ($(WITH_MALLOC_LEAK_CHECK),true)
-  LOCAL_CFLAGS += -DMALLOC_LEAK_CHECK
-endif
-
-LOCAL_MODULE:= libcerttool_jni
-
-include $(BUILD_SHARED_LIBRARY)
diff --git a/keystore/jni/cert.c b/keystore/jni/cert.c
deleted file mode 100644
index 90f872e..0000000
--- a/keystore/jni/cert.c
+++ /dev/null
@@ -1,344 +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.
-*/
-
-#define LOG_TAG "CertTool"
-
-#include <stdio.h>
-#include <openssl/pem.h>
-#include <openssl/pkcs12.h>
-#include <openssl/rsa.h>
-#include <openssl/x509v3.h>
-#include <cutils/log.h>
-
-#include "cert.h"
-
-static PKEY_STORE pkey_store[KEYGEN_STORE_SIZE];
-static int store_index = 0;
-
-static char emsg[][30] = {
-    "",
-    STR(ERR_INVALID_KEY_LENGTH),
-    STR(ERR_CONSTRUCT_NEW_DATA),
-    STR(ERR_RSA_KEYGEN),
-    STR(ERR_X509_PROCESS),
-    STR(ERR_SPKAC_TOO_LONG),
-    STR(ERR_INVALID_ARGS),
-};
-
-static void save_in_store(EVP_PKEY *pkey)
-{
-    EVP_PKEY *newpkey = EVP_PKEY_new();
-    RSA *rsa = EVP_PKEY_get1_RSA(pkey);
-    EVP_PKEY_set1_RSA(newpkey, rsa);
-    PKEY_STORE_free(pkey_store[store_index]);
-    pkey_store[store_index].key_len = i2d_RSA_PUBKEY(rsa, &pkey_store[store_index].public_key);
-    pkey_store[store_index++].pkey = newpkey;
-    store_index %= KEYGEN_STORE_SIZE;
-    RSA_free(rsa);
-}
-
-static EVP_PKEY *get_pkey_from_store(X509 *cert)
-{
-    int i, key_len;
-    unsigned char *buf = NULL;
-    if ((key_len = i2d_X509_PUBKEY(X509_get_X509_PUBKEY(cert), &buf)) == 0) {
-        return NULL;
-    }
-    for (i = 0 ; i < KEYGEN_STORE_SIZE ; ++i) {
-        if ((key_len == pkey_store[i].key_len) &&
-            memcmp(buf, pkey_store[i].public_key, key_len) == 0) {
-            break;
-        }
-    }
-    free(buf);
-    return (i == KEYGEN_STORE_SIZE) ? NULL : pkey_store[i].pkey;
-}
-
-int gen_csr(int bits, const char *challenge, char reply[REPLY_MAX])
-{
-    int len, ret_code = 0;
-    BIGNUM *bn = NULL;
-    char *spkstr = NULL;
-    EVP_PKEY *pkey = NULL;
-    RSA *rsa = NULL;
-    NETSCAPE_SPKI *req = NULL;
-
-    if (challenge == NULL) {
-        ret_code = ERR_INVALID_ARGS;
-        goto err;
-    }
-
-    if ((bits != KEYLENGTH_MEDIUM) && (bits != KEYLENGTH_MAXIMUM)) {
-        ret_code = ERR_INVALID_KEY_LENGTH;
-        goto err;
-    }
-
-    if (((pkey = EVP_PKEY_new()) == NULL) ||
-        ((req = NETSCAPE_SPKI_new()) == NULL) ||
-        ((rsa = RSA_new()) == NULL) || ((bn = BN_new()) == NULL)) {
-        ret_code = ERR_CONSTRUCT_NEW_DATA;
-        goto err;
-    }
-
-    if (!BN_set_word(bn, RSA_F4) ||
-        !RSA_generate_key_ex(rsa, bits, bn, NULL) ||
-        !EVP_PKEY_assign_RSA(pkey, rsa)) {
-        ret_code = ERR_RSA_KEYGEN;
-        goto err;
-    }
-
-    rsa = NULL;
-    ASN1_STRING_set(req->spkac->challenge, challenge, (int)strlen(challenge));
-    NETSCAPE_SPKI_set_pubkey(req, pkey);
-    NETSCAPE_SPKI_sign(req, pkey, EVP_md5());
-    spkstr = NETSCAPE_SPKI_b64_encode(req);
-
-    if ((strlcpy(reply, spkstr, REPLY_MAX)) < REPLY_MAX) {
-        save_in_store(pkey);
-    } else {
-        ret_code = ERR_SPKAC_TOO_LONG;
-    }
-
-err:
-    if (rsa) RSA_free(rsa);
-    if (bn) BN_free(bn);
-    if (req) NETSCAPE_SPKI_free(req);
-    if (pkey) EVP_PKEY_free(pkey);
-    if (spkstr) OPENSSL_free(spkstr);
-    if ((ret_code > 0) && (ret_code < ERR_MAXIMUM)) LOGE(emsg[ret_code]);
-    return -ret_code;
-}
-
-PKCS12 *get_p12_handle(const char *buf, int bufLen)
-{
-    BIO *bp = NULL;
-    PKCS12  *p12 = NULL;
-
-    if (!buf || (bufLen < 1) || (buf[0] != 48)) goto err;
-
-    bp = BIO_new(BIO_s_mem());
-    if (!bp) goto err;
-
-    if (!BIO_write(bp, buf, bufLen)) goto err;
-
-    p12 = d2i_PKCS12_bio(bp, NULL);
-
-err:
-    if (bp) BIO_free(bp);
-    return p12;
-}
-
-PKCS12_KEYSTORE *get_pkcs12_keystore_handle(const char *buf, int bufLen,
-                                            const char *passwd)
-{
-    PKCS12_KEYSTORE *p12store = NULL;
-    EVP_PKEY *pkey = NULL;
-    X509 *cert = NULL;
-    STACK_OF(X509) *certs = NULL;
-    PKCS12  *p12 = get_p12_handle(buf, bufLen);
-
-    if (p12 == NULL) return NULL;
-    if (!PKCS12_parse(p12, passwd, &pkey, &cert, &certs)) {
-        LOGE("Can not parse PKCS12 content");
-        PKCS12_free(p12);
-        return NULL;
-    }
-    if ((p12store = malloc(sizeof(PKCS12_KEYSTORE))) == NULL) {
-        if (cert) X509_free(cert);
-        if (pkey) EVP_PKEY_free(pkey);
-        if (certs) sk_X509_free(certs);
-    }
-    p12store->p12 = p12;
-    p12store->pkey = pkey;
-    p12store->cert = cert;
-    p12store->certs = certs;
-    return p12store;
-}
-
-void free_pkcs12_keystore(PKCS12_KEYSTORE *p12store)
-{
-    if (p12store != NULL) {
-        if (p12store->cert) X509_free(p12store->cert);
-        if (p12store->pkey) EVP_PKEY_free(p12store->pkey);
-        if (p12store->certs) sk_X509_free(p12store->certs);
-        free(p12store);
-    }
-}
-
-int is_pkcs12(const char *buf, int bufLen)
-{
-    int ret = 0;
-    PKCS12  *p12 = get_p12_handle(buf, bufLen);
-    if (p12 != NULL) ret = 1;
-    PKCS12_free(p12);
-    return ret;
-}
-
-static int convert_to_pem(void *data, int is_cert, char *buf, int size)
-{
-    int len = 0;
-    BIO *bio = NULL;
-
-    if (data == NULL) return -1;
-
-    if ((bio = BIO_new(BIO_s_mem())) == NULL) goto err;
-    if (is_cert) {
-        if ((len = PEM_write_bio_X509(bio, (X509*)data)) == 0) {
-            goto err;
-        }
-    } else {
-        if ((len = PEM_write_bio_PrivateKey(bio, (EVP_PKEY *)data, NULL,
-                                            NULL, 0, NULL, NULL)) == 0) {
-            goto err;
-        }
-    }
-    if (len < size && (len = BIO_read(bio, buf, size - 1)) > 0) {
-        buf[len] = 0;
-    }
-err:
-    if (bio) BIO_free(bio);
-    return len;
-}
-
-int get_pkcs12_certificate(PKCS12_KEYSTORE *p12store, char *buf, int size)
-{
-    if ((p12store != NULL) && (p12store->cert != NULL)) {
-        int len = convert_to_pem((void*)p12store->cert, 1, buf, size);
-        return (len == 0) ? -1 : 0;
-    }
-    return -1;
-}
-
-int get_pkcs12_private_key(PKCS12_KEYSTORE *p12store, char *buf, int size)
-{
-    if ((p12store != NULL) && (p12store->pkey != NULL)) {
-        int len = convert_to_pem((void*)p12store->pkey, 0, buf, size);
-        return (len == 0) ? -1 : 0;
-    }
-    return -1;
-}
-
-int pop_pkcs12_certs_stack(PKCS12_KEYSTORE *p12store, char *buf, int size)
-{
-    X509 *cert = NULL;
-    int len = 0;
-
-    if ((p12store != NULL) && (p12store->certs != NULL)) {
-        while (((cert = sk_X509_pop(p12store->certs)) != NULL) && (len < size)) {
-            int s = convert_to_pem((void*)cert, 1, buf + len, size - len);
-            if (s == 0) {
-                LOGE("buffer size is too small. len=%d size=%d\n", len, size);
-                return -1;
-            }
-            len += s;
-            X509_free(cert);
-        }
-        return (len == 0) ? -1 : 0;
-    }
-    return -1;
-}
-
-X509* parse_cert(const char *buf, int bufLen)
-{
-    X509 *cert = NULL;
-    BIO *bp = NULL;
-
-    if(!buf || bufLen < 1)
-        return NULL;
-
-    bp = BIO_new(BIO_s_mem());
-    if (!bp) goto err;
-
-    if (!BIO_write(bp, buf, bufLen)) goto err;
-
-    cert = PEM_read_bio_X509(bp, NULL, NULL, NULL);
-    if (!cert) {
-        BIO_free(bp);
-        if((bp = BIO_new(BIO_s_mem())) == NULL) goto err;
-
-        if(!BIO_write(bp, (char *) buf, bufLen)) goto err;
-        cert = d2i_X509_bio(bp, NULL);
-   }
-
-err:
-    if (bp) BIO_free(bp);
-    return cert;
-}
-
-static int get_distinct_name(X509_NAME *dname, char *buf, int size)
-{
-   int i, len;
-   char *p, *name;
-
-   if (X509_NAME_oneline(dname, buf, size) == NULL) {
-      return -1;
-   }
-   name = strstr(buf, "/CN=");
-   p = name = name ? (name + 4) : buf;
-   while (*p != 0) {
-       if (*p == ' ') *p = '_';
-       if (*p == '/') {
-          *p = 0;
-          break;
-       }
-       ++p;
-   }
-   return 0;
-}
-
-int get_cert_name(X509 *cert, char *buf, int size)
-{
-   if (!cert) return -1;
-   return get_distinct_name(X509_get_subject_name(cert), buf, size);
-}
-
-int get_issuer_name(X509 *cert, char *buf, int size)
-{
-   if (!cert) return -1;
-   return get_distinct_name(X509_get_issuer_name(cert), buf, size);
-}
-
-int is_ca_cert(X509 *cert)
-{
-    int ret = 0;
-    BASIC_CONSTRAINTS *bs = (BASIC_CONSTRAINTS *)
-            X509_get_ext_d2i(cert, NID_basic_constraints, NULL, NULL);
-    if (bs != NULL) ret = bs->ca;
-    if (bs) BASIC_CONSTRAINTS_free(bs);
-    return ret;
-}
-
-int get_private_key_pem(X509 *cert, char *buf, int size)
-{
-    int len = 0;
-    BIO *bio = NULL;
-    EVP_PKEY *pkey = get_pkey_from_store(cert);
-
-    if (pkey == NULL) return -1;
-
-    bio = BIO_new(BIO_s_mem());
-    if ((bio = BIO_new(BIO_s_mem())) == NULL) goto err;
-    if (!PEM_write_bio_PrivateKey(bio, pkey, NULL,NULL,0,NULL, NULL)) {
-        goto err;
-    }
-    if ((len = BIO_read(bio, buf, size - 1)) > 0) {
-        buf[len] = 0;
-    }
-err:
-    if (bio) BIO_free(bio);
-    return (len == 0) ? -1 : 0;
-}
diff --git a/keystore/jni/cert.h b/keystore/jni/cert.h
deleted file mode 100644
index a9e1a9e..0000000
--- a/keystore/jni/cert.h
+++ /dev/null
@@ -1,73 +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.
-*/
-
-#ifndef __CERT_H__
-#define __CERT_H__
-
-#define ANDROID_KEYSTORE "Android Keystore"
-#define KEYGEN_STORE_SIZE     5
-#define KEYLENGTH_MEDIUM      1024
-#define KEYLENGTH_MAXIMUM     2048
-#define MAX_CERT_NAME_LEN     128
-#define MAX_PEM_LENGTH        4096
-#define REPLY_MAX             MAX_PEM_LENGTH
-
-
-#define STR(token) #token
-#define ERR_INVALID_KEY_LENGTH  1
-#define ERR_CONSTRUCT_NEW_DATA  2
-#define ERR_RSA_KEYGEN          3
-#define ERR_X509_PROCESS        4
-#define ERR_SPKAC_TOO_LONG      5
-#define ERR_INVALID_ARGS        6
-#define ERR_MAXIMUM             7
-
-typedef struct {
-    EVP_PKEY *pkey;
-    unsigned char *public_key;
-    int key_len;
-} PKEY_STORE;
-
-typedef struct {
-    PKCS12  *p12;
-    EVP_PKEY *pkey;
-    X509 *cert;
-    STACK_OF(X509) *certs;
-} PKCS12_KEYSTORE;
-
-#define PKEY_STORE_free(x) { \
-    if(x.pkey) EVP_PKEY_free(x.pkey); \
-    if(x.public_key) free(x.public_key); \
-}
-
-#define nelem(x) (sizeof (x) / sizeof *(x))
-
-int gen_csr(int bits, const char *organizations, char reply[REPLY_MAX]);
-PKCS12_KEYSTORE *get_pkcs12_keystore_handle(const char *buf, int bufLen,
-                                            const char *passwd);
-int get_pkcs12_certificate(PKCS12_KEYSTORE *p12store, char *buf, int size);
-int get_pkcs12_private_key(PKCS12_KEYSTORE *p12store, char *buf, int size);
-int pop_pkcs12_certs_stack(PKCS12_KEYSTORE *p12store, char *buf, int size);
-void free_pkcs12_keystore(PKCS12_KEYSTORE *p12store);
-int is_pkcs12(const char *buf, int bufLen);
-X509 *parse_cert(const char *buf, int bufLen);
-int get_cert_name(X509 *cert, char *buf, int size);
-int get_issuer_name(X509 *cert, char *buf, int size);
-int is_ca_cert(X509 *cert);
-int get_private_key_pem(X509 *cert, char *buf, int size);
-
-#endif
diff --git a/keystore/jni/certtool.c b/keystore/jni/certtool.c
deleted file mode 100644
index b36b34a..0000000
--- a/keystore/jni/certtool.c
+++ /dev/null
@@ -1,269 +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.
-*/
-#define LOG_TAG "CertTool"
-
-#include <string.h>
-#include <jni.h>
-#include <cutils/log.h>
-#include <openssl/pkcs12.h>
-#include <openssl/x509v3.h>
-
-#include "cert.h"
-
-typedef int PKCS12_KEYSTORE_FUNC(PKCS12_KEYSTORE *store, char *buf, int size);
-
-jstring
-android_security_CertTool_generateCertificateRequest(JNIEnv* env,
-                                                     jobject thiz,
-                                                     jint bits,
-                                                     jstring jChallenge)
-
-{
-    int ret = -1;
-    jboolean bIsCopy;
-    char csr[REPLY_MAX];
-    const char* challenge = (*env)->GetStringUTFChars(env, jChallenge, &bIsCopy);
-
-    ret = gen_csr(bits, challenge , csr);
-    (*env)->ReleaseStringUTFChars(env, jChallenge, challenge);
-    if (ret == 0) return (*env)->NewStringUTF(env, csr);
-    return NULL;
-}
-
-jboolean
-android_security_CertTool_isPkcs12Keystore(JNIEnv* env,
-                                           jobject thiz,
-                                           jbyteArray data)
-{
-    int len = (*env)->GetArrayLength(env, data);
-
-    if (len > 0) {
-        PKCS12 *handle = NULL;
-        char buf[len];
-
-        (*env)->GetByteArrayRegion(env, data, 0, len, (jbyte*)buf);
-        return (jboolean)is_pkcs12(buf, len);
-    } else {
-        return 0;
-    }
-}
-
-jint
-android_security_CertTool_getPkcs12Handle(JNIEnv* env,
-                                          jobject thiz,
-                                          jbyteArray data,
-                                          jstring jPassword)
-{
-    jboolean bIsCopy;
-    int len = (*env)->GetArrayLength(env, data);
-    const char* passwd = (*env)->GetStringUTFChars(env, jPassword , &bIsCopy);
-
-    if (len > 0) {
-        PKCS12_KEYSTORE *handle = NULL;
-        char buf[len];
-
-        (*env)->GetByteArrayRegion(env, data, 0, len, (jbyte*)buf);
-        handle = get_pkcs12_keystore_handle(buf, len, passwd);
-        (*env)->ReleaseStringUTFChars(env, jPassword, passwd);
-        return (jint)handle;
-    } else {
-        return 0;
-    }
-}
-
-jstring call_pkcs12_ks_func(PKCS12_KEYSTORE_FUNC *func,
-                            JNIEnv* env,
-                            jobject thiz,
-                            jint phandle)
-{
-    char buf[REPLY_MAX];
-
-    if (phandle == 0) return NULL;
-    if (func((PKCS12_KEYSTORE*)phandle, buf, sizeof(buf)) == 0) {
-        return (*env)->NewStringUTF(env, buf);
-    }
-    return NULL;
-}
-
-jstring
-android_security_CertTool_getPkcs12Certificate(JNIEnv* env,
-                                               jobject thiz,
-                                               jint phandle)
-{
-    return call_pkcs12_ks_func((PKCS12_KEYSTORE_FUNC *)get_pkcs12_certificate,
-                               env, thiz, phandle);
-}
-
-jstring
-android_security_CertTool_getPkcs12PrivateKey(JNIEnv* env,
-                                              jobject thiz,
-                                              jint phandle)
-{
-    return call_pkcs12_ks_func((PKCS12_KEYSTORE_FUNC *)get_pkcs12_private_key,
-                               env, thiz, phandle);
-}
-
-jstring
-android_security_CertTool_popPkcs12CertificateStack(JNIEnv* env,
-                                                    jobject thiz,
-                                                    jint phandle)
-{
-    return call_pkcs12_ks_func((PKCS12_KEYSTORE_FUNC *)pop_pkcs12_certs_stack,
-                               env, thiz, phandle);
-}
-
-void android_security_CertTool_freePkcs12Handle(JNIEnv* env,
-                                                jobject thiz,
-                                                jint handle)
-{
-    if (handle != 0) free_pkcs12_keystore((PKCS12_KEYSTORE*)handle);
-}
-
-jint
-android_security_CertTool_generateX509Certificate(JNIEnv* env,
-                                                  jobject thiz,
-                                                  jbyteArray data)
-{
-    char buf[REPLY_MAX];
-    int len = (*env)->GetArrayLength(env, data);
-
-    if (len > REPLY_MAX) return 0;
-    (*env)->GetByteArrayRegion(env, data, 0, len, (jbyte*)buf);
-    return (jint) parse_cert(buf, len);
-}
-
-jboolean android_security_CertTool_isCaCertificate(JNIEnv* env,
-                                                   jobject thiz,
-                                                   jint handle)
-{
-    return (handle == 0) ? (jboolean)0 : (jboolean) is_ca_cert((X509*)handle);
-}
-
-jstring android_security_CertTool_getIssuerDN(JNIEnv* env,
-                                              jobject thiz,
-                                              jint handle)
-{
-    char issuer[MAX_CERT_NAME_LEN];
-
-    if (handle == 0) return NULL;
-    if (get_issuer_name((X509*)handle, issuer, MAX_CERT_NAME_LEN)) return NULL;
-    return (*env)->NewStringUTF(env, issuer);
-}
-
-jstring android_security_CertTool_getCertificateDN(JNIEnv* env,
-                                                   jobject thiz,
-                                                   jint handle)
-{
-    char name[MAX_CERT_NAME_LEN];
-    if (handle == 0) return NULL;
-    if (get_cert_name((X509*)handle, name, MAX_CERT_NAME_LEN)) return NULL;
-    return (*env)->NewStringUTF(env, name);
-}
-
-jstring android_security_CertTool_getPrivateKeyPEM(JNIEnv* env,
-                                                   jobject thiz,
-                                                   jint handle)
-{
-    char pem[MAX_PEM_LENGTH];
-    if (handle == 0) return NULL;
-    if (get_private_key_pem((X509*)handle, pem, MAX_PEM_LENGTH)) return NULL;
-    return (*env)->NewStringUTF(env, pem);
-}
-
-void android_security_CertTool_freeX509Certificate(JNIEnv* env,
-                                                   jobject thiz,
-                                                   jint handle)
-{
-    if (handle != 0) X509_free((X509*)handle);
-}
-
-/*
- * Table of methods associated with the CertTool class.
- */
-static JNINativeMethod gCertToolMethods[] = {
-    /* name, signature, funcPtr */
-    {"generateCertificateRequest", "(ILjava/lang/String;)Ljava/lang/String;",
-        (void*)android_security_CertTool_generateCertificateRequest},
-    {"isPkcs12Keystore", "([B)Z",
-        (void*)android_security_CertTool_isPkcs12Keystore},
-    {"getPkcs12Handle", "([BLjava/lang/String;)I",
-        (void*)android_security_CertTool_getPkcs12Handle},
-    {"getPkcs12Certificate", "(I)Ljava/lang/String;",
-        (void*)android_security_CertTool_getPkcs12Certificate},
-    {"getPkcs12PrivateKey", "(I)Ljava/lang/String;",
-        (void*)android_security_CertTool_getPkcs12PrivateKey},
-    {"popPkcs12CertificateStack", "(I)Ljava/lang/String;",
-        (void*)android_security_CertTool_popPkcs12CertificateStack},
-    {"freePkcs12Handle", "(I)V",
-        (void*)android_security_CertTool_freePkcs12Handle},
-    {"generateX509Certificate", "([B)I",
-        (void*)android_security_CertTool_generateX509Certificate},
-    {"isCaCertificate", "(I)Z",
-        (void*)android_security_CertTool_isCaCertificate},
-    {"getIssuerDN", "(I)Ljava/lang/String;",
-        (void*)android_security_CertTool_getIssuerDN},
-    {"getCertificateDN", "(I)Ljava/lang/String;",
-        (void*)android_security_CertTool_getCertificateDN},
-    {"getPrivateKeyPEM", "(I)Ljava/lang/String;",
-        (void*)android_security_CertTool_getPrivateKeyPEM},
-    {"freeX509Certificate", "(I)V",
-        (void*)android_security_CertTool_freeX509Certificate},
-};
-
-/*
- * Register several native methods for one class.
- */
-static int registerNatives(JNIEnv* env, const char* className,
-                           JNINativeMethod* gMethods, int numMethods)
-{
-    jclass clazz;
-
-    clazz = (*env)->FindClass(env, className);
-    if (clazz == NULL) {
-        LOGE("Can not find class %s\n", className);
-        return JNI_FALSE;
-    }
-
-    if ((*env)->RegisterNatives(env, clazz, gMethods, numMethods) < 0) {
-        LOGE("Can not RegisterNatives\n");
-        return JNI_FALSE;
-    }
-
-    return JNI_TRUE;
-}
-
-jint JNI_OnLoad(JavaVM* vm, void* reserved)
-{
-    JNIEnv* env = NULL;
-    jint result = -1;
-
-
-    if ((*vm)->GetEnv(vm, (void**) &env, JNI_VERSION_1_4) != JNI_OK) {
-        goto bail;
-    }
-
-    if (!registerNatives(env, "android/security/CertTool",
-                         gCertToolMethods, nelem(gCertToolMethods))) {
-        goto bail;
-    }
-
-    /* success -- return valid version number */
-    result = JNI_VERSION_1_4;
-
-bail:
-    return result;
-}
