Support cross-UID access from AndroidKeyStore.
This is meant for exposing the pre-existing cross-UID access to keys
backed by the keystore service via higher-level JCA API. For example,
this lets system_server use Wi-Fi or VPN UID keys via JCA API.
To obtain a JCA AndroidKeyStore KeyStore for another UID, use the
hidden system API AndroidKeyStoreProvider.getKeyStoreForUid(uid).
To generate a key owned by another UID, invoke setUid(uid) on
KeyGenParameterSpec.Builder.
This CL does not change the security policy, such as which UID can
access/modify which UIDs' keys. The policy is that only certain system
UIDs are permitted to access keys of certain other system UIDs.
Bug: 23978113
Change-Id: Ie381530f41dc41c50d52f675fb9e68bc87c006de
diff --git a/keystore/java/android/security/Credentials.java b/keystore/java/android/security/Credentials.java
index 5d777b0..c8333c8 100644
--- a/keystore/java/android/security/Credentials.java
+++ b/keystore/java/android/security/Credentials.java
@@ -217,13 +217,22 @@
* Returns {@code true} if there was at least one of those types.
*/
public static boolean deleteAllTypesForAlias(KeyStore keystore, String alias) {
+ return deleteAllTypesForAlias(keystore, alias, KeyStore.UID_SELF);
+ }
+
+ /**
+ * Delete all types (private key, certificate, CA certificate) for a
+ * particular {@code alias}. All three can exist for any given alias.
+ * Returns {@code true} if there was at least one of those types.
+ */
+ public static boolean deleteAllTypesForAlias(KeyStore keystore, String alias, int uid) {
/*
* Make sure every type is deleted. There can be all three types, so
* don't use a conditional here.
*/
- return keystore.delete(Credentials.USER_PRIVATE_KEY + alias)
- | keystore.delete(Credentials.USER_SECRET_KEY + alias)
- | deleteCertificateTypesForAlias(keystore, alias);
+ return keystore.delete(Credentials.USER_PRIVATE_KEY + alias, uid)
+ | keystore.delete(Credentials.USER_SECRET_KEY + alias, uid)
+ | deleteCertificateTypesForAlias(keystore, alias, uid);
}
/**
@@ -232,12 +241,21 @@
* Returns {@code true} if there was at least one of those types.
*/
public static boolean deleteCertificateTypesForAlias(KeyStore keystore, String alias) {
+ return deleteCertificateTypesForAlias(keystore, alias, KeyStore.UID_SELF);
+ }
+
+ /**
+ * Delete all types (private key, certificate, CA certificate) for a
+ * particular {@code alias}. All three can exist for any given alias.
+ * Returns {@code true} if there was at least one of those types.
+ */
+ public static boolean deleteCertificateTypesForAlias(KeyStore keystore, String alias, int uid) {
/*
* Make sure every certificate type is deleted. There can be two types,
* so don't use a conditional here.
*/
- return keystore.delete(Credentials.USER_CERTIFICATE + alias)
- | keystore.delete(Credentials.CA_CERTIFICATE + alias);
+ return keystore.delete(Credentials.USER_CERTIFICATE + alias, uid)
+ | keystore.delete(Credentials.CA_CERTIFICATE + alias, uid);
}
/**
@@ -245,7 +263,15 @@
* Returns {@code true} if an entry was was deleted.
*/
static boolean deletePrivateKeyTypeForAlias(KeyStore keystore, String alias) {
- return keystore.delete(Credentials.USER_PRIVATE_KEY + alias);
+ return deletePrivateKeyTypeForAlias(keystore, alias, KeyStore.UID_SELF);
+ }
+
+ /**
+ * Delete private key for a particular {@code alias}.
+ * Returns {@code true} if an entry was was deleted.
+ */
+ static boolean deletePrivateKeyTypeForAlias(KeyStore keystore, String alias, int uid) {
+ return keystore.delete(Credentials.USER_PRIVATE_KEY + alias, uid);
}
/**
@@ -253,6 +279,14 @@
* Returns {@code true} if an entry was was deleted.
*/
public static boolean deleteSecretKeyTypeForAlias(KeyStore keystore, String alias) {
- return keystore.delete(Credentials.USER_SECRET_KEY + alias);
+ return deleteSecretKeyTypeForAlias(keystore, alias, KeyStore.UID_SELF);
+ }
+
+ /**
+ * Delete secret key for a particular {@code alias}.
+ * Returns {@code true} if an entry was was deleted.
+ */
+ public static boolean deleteSecretKeyTypeForAlias(KeyStore keystore, String alias, int uid) {
+ return keystore.delete(Credentials.USER_SECRET_KEY + alias, uid);
}
}