diff options
Diffstat (limited to 'keystore/java/android/security')
-rw-r--r-- | keystore/java/android/security/CertTool.java | 68 | ||||
-rw-r--r-- | keystore/java/android/security/Keystore.java | 106 |
2 files changed, 62 insertions, 112 deletions
diff --git a/keystore/java/android/security/CertTool.java b/keystore/java/android/security/CertTool.java index 26d22ae..79418bd 100644 --- a/keystore/java/android/security/CertTool.java +++ b/keystore/java/android/security/CertTool.java @@ -16,11 +16,19 @@ package android.security; +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 android.content.Context; import android.content.Intent; import android.security.Keystore; import android.text.TextUtils; - +import android.util.Log; /** * The CertTool class provides the functions to list the certs/keys, @@ -41,12 +49,13 @@ public class CertTool { public static final String KEY_NAMESPACE = "namespace"; public static final String KEY_DESCRIPTION = "description"; - private static final String TAG = "CertTool"; + public static final String TITLE_CA_CERT = "CA Certificate"; + public static final String TITLE_USER_CERT = "User Certificate"; + public static final String TITLE_PKCS12_KEYSTORE = "PKCS12 Keystore"; + public static final String TITLE_PRIVATE_KEY = "Private Key"; + public static final int INCORRECT_PKCS12_PASSPHRASE = -100; - private static final String TITLE_CA_CERT = "CA Certificate"; - private static final String TITLE_USER_CERT = "User Certificate"; - private static final String TITLE_PKCS12_KEYSTORE = "PKCS12 Keystore"; - private static final String TITLE_PRIVATE_KEY = "Private Key"; + 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:"; @@ -58,6 +67,11 @@ public class CertTool { 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 subject); private native boolean isPkcs12Keystore(byte[] data); private native int generateX509Certificate(byte[] data); @@ -130,10 +144,52 @@ public class CertTool { intent.putExtra(KEY_NAMESPACE + "1", namespace); } + 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; + } + } + while ((pemData = this.popPkcs12CertificateStack(handle)) != null) { + if (i++ > 0) { + if ((ret = sKeystore.put(CA_CERTIFICATE, keyname + i, pemData)) != 0) { + return ret; + } + } else { + if ((ret = sKeystore.put(CA_CERTIFICATE, keyname, pemData)) != 0) { + return ret; + } + } + } + return 0; + } + + 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; + } + 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, data, USER_KEY, UNKNOWN, UNKNOWN); diff --git a/keystore/java/android/security/Keystore.java b/keystore/java/android/security/Keystore.java index 1f14da7..a6cfbca 100644 --- a/keystore/java/android/security/Keystore.java +++ b/keystore/java/android/security/Keystore.java @@ -48,49 +48,6 @@ public abstract class Keystore { public abstract int remove(String namespace, String keyname); public abstract int reset(); - // TODO: for migrating to the mini-keystore, clean up from here - /** - */ - public abstract String getCaCertificate(String key); - - /** - */ - public abstract String getUserCertificate(String key); - - /** - */ - public abstract String getUserPrivateKey(String key); - - /** - * Returns the array of the certificate keynames in keystore if successful. - * Or return an empty array if error. - * - * @return array of the certificate keynames - */ - public abstract String[] getAllUserCertificateKeys(); - - /** - */ - public abstract String[] getAllCaCertificateKeys(); - - /** - */ - public abstract String[] getSupportedKeyStrenghs(); - - /** - * Generates a key pair and returns the certificate request. - * @param keyStrengthIndex index to the array of supported key strengths - * @param challenge the challenge message in the keygen tag - * @param organizations the organization string, e.g., - * "/C=US/ST={state}/L={city}/O={company}/OU={app}/CN={hostname}" - * @return the certificate request - */ - public abstract String generateKeyPair( - int keyStrengthIndex, String challenge, String organizations); - - public abstract void addCertificate(byte[] cert); - // to here - private static class FileKeystore extends Keystore { private static final String SERVICE_NAME = "keystore"; private static final String CA_CERTIFICATE = "CaCertificate"; @@ -100,69 +57,6 @@ public abstract class Keystore { private static final ServiceCommand mServiceCommand = new ServiceCommand(SERVICE_NAME); - // TODO: for migrating to the mini-keystore, start from here - @Override - public String getUserPrivateKey(String key) { - return ""; - } - - @Override - public String getUserCertificate(String key) { - return ""; - } - - @Override - public String getCaCertificate(String key) { - return ""; - } - - @Override - public String[] getAllUserCertificateKeys() { - return new String[0]; - } - - @Override - public String[] getAllCaCertificateKeys() { - return new String[0]; - } - - @Override - public String[] getSupportedKeyStrenghs() { - // TODO: real implementation - return new String[] {"High Grade", "Medium Grade"}; - } - - @Override - public String generateKeyPair(int keyStrengthIndex, String challenge, - String organizations) { - // TODO: real implementation - return "-----BEGIN CERTIFICATE REQUEST-----" - + "\nMIICzjCCAbYCAQAwgYgxCzAJBgNVBAYTAlVTMRMwEQYDVQQIEwpDYWxpZm9ybmlh" - + "\nMRYwFAYDVQQHEw1Nb3VudGFpbiBWaWV3MRMwEQYDVQQKEwpHb29nbGUgSW5jMRYw" - + "\nFAYDVQQLEw1SZW1vdGUgQWNjZXNzMRAwDgYDVQQLEwdHbGFwdG9wMQ0wCwYDVQQD" - + "\nEwR0ZXN0MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAznwy7a16O35u" - + "\nODLQOw6yHAxozrrX1J+c0reiIh8GYohwKrBedFnQ/FnTls6bxY4fNHD+SZvFFgvU" - + "\nECBFOfRmRm7AFo51qT0t2a8qgvDLM6L1qGkmy94W28Q3OlcpF2QianHYdjyGT+Ac" - + "\nYDek1Zi/E/mdPzuVM/K8tkB7n8ktC0PTm1ZtdMRauE5R0WrEhWuF6In/2gy1Q/Zh" - + "\noy7/zQqpbPl2ouulvkx1Y3OXHM6XPNFLoHS1gH0HyAuBUokO0QmetRn6ngJSvz7e" - + "\nVD7QYRppGp+g4BxqaV9XSxhaaKrMs4PAld9enV51X9qjvjCRBve2QxtuJgMfGJdU" - + "\njGr/JweZoQIDAQABoAAwDQYJKoZIhvcNAQEFBQADggEBADtxOtEseoLOVYh6sh4b" - + "\nWCdngK87uHn2bdGipFwKdNTxQDdxNQLAKdoGYIfbVsC1cDgFiufeNwVukxxymdnm" - + "\nk0GGK+0O0tZKENv8ysgfbgEsHpJH9FoR5Y5XEq1etejkcgCp59dyhrSk0DLyVm0D" - + "\nIfTC/nsK95H7AAGOkbbDFo2otyLNNrthYncQ9diAG0UzzLacA+86JXZmD3HyC48u" - + "\nI9hsivVnTTfl9afcfVAhfxbQ6HgkhZZjbjFjfABSd4v8wKlAAqK58VxCajNVOVcV" - + "\ncCzOWf6NpE7xEHCf32i8bWDP6hi0WgQcdpQwnZNKhhTLGNb23Uty6HYlJhbxexC7" - + "\nUoM=" - + "\n-----END CERTIFICATE REQUEST-----"; - } - - @Override - public void addCertificate(byte[] cert) { - // TODO: real implementation - } - - // to here - @Override public int lock() { Reply result = mServiceCommand.execute(ServiceCommand.LOCK, null); |