Allows DPM.generateKeyPair() to be called from PO of affiliated user.

If the key is used by device attestation, it can only be used by the
user that generated it, as it's not parcelable. Hence, on devices
running with Headless System User Mode (HSUM), the key must be
generated by the "real" user's PO, not the DO (which runs on system
user).

Test: atest com.android.cts.devicepolicy.MixedProfileOwnerTest#testDelegatedCertInstallerDeviceIdAttestation # on phone
Test: manual verification with TestDpc on automotive
Bug: 213388897

Change-Id: I58623f5c1a1d60af7743f5a815a491ebbad9b9fe
This commit is contained in:
Felipe Leme
2022-02-10 12:54:31 -08:00
parent 7ac3a06942
commit e8caa07e9f
2 changed files with 23 additions and 12 deletions

View File

@@ -6388,10 +6388,10 @@ public class DevicePolicyManager {
* management app can use {@link #ID_TYPE_BASE_INFO} to request inclusion of the general device * management app can use {@link #ID_TYPE_BASE_INFO} to request inclusion of the general device
* information including manufacturer, model, brand, device and product in the attestation * information including manufacturer, model, brand, device and product in the attestation
* record. * record.
* Only device owner, profile owner on an organization-owned device and their delegated * Only device owner, profile owner on an organization-owned device or affiliated user, and
* certificate installers can use {@link #ID_TYPE_SERIAL}, {@link #ID_TYPE_IMEI} and * their delegated certificate installers can use {@link #ID_TYPE_SERIAL}, {@link #ID_TYPE_IMEI}
* {@link #ID_TYPE_MEID} to request unique device identifiers to be attested (the serial number, * and {@link #ID_TYPE_MEID} to request unique device identifiers to be attested (the serial
* IMEI and MEID correspondingly), if supported by the device * number, IMEI and MEID correspondingly), if supported by the device
* (see {@link #isDeviceIdAttestationSupported()}). * (see {@link #isDeviceIdAttestationSupported()}).
* Additionally, device owner, profile owner on an organization-owned device and their delegated * Additionally, device owner, profile owner on an organization-owned device and their delegated
* certificate installers can also request the attestation record to be signed using an * certificate installers can also request the attestation record to be signed using an

View File

@@ -5894,6 +5894,7 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager {
* (1.1) The caller is the Device Owner * (1.1) The caller is the Device Owner
* (1.2) The caller is another app in the same user as the device owner, AND * (1.2) The caller is another app in the same user as the device owner, AND
* The caller is the delegated certificate installer. * The caller is the delegated certificate installer.
* (1.3) The caller is a Profile Owner and the calling user is affiliated.
* (2) The user has a profile owner, AND: * (2) The user has a profile owner, AND:
* (2.1) The profile owner has been granted access to Device IDs and one of the following * (2.1) The profile owner has been granted access to Device IDs and one of the following
* holds: * holds:
@@ -5919,12 +5920,14 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager {
* If the caller is from the work profile, then it must be the PO or the delegate, and * If the caller is from the work profile, then it must be the PO or the delegate, and
* it must have the right permission to access device identifiers. * it must have the right permission to access device identifiers.
*/ */
if (hasProfileOwner(caller.getUserId())) { int callerUserId = caller.getUserId();
if (hasProfileOwner(callerUserId)) {
// Make sure that the caller is the profile owner or delegate. // Make sure that the caller is the profile owner or delegate.
Preconditions.checkCallAuthorization(canInstallCertificates(caller)); Preconditions.checkCallAuthorization(canInstallCertificates(caller));
// Verify that the managed profile is on an organization-owned device and as such // Verify that the managed profile is on an organization-owned device (or is affiliated
// the profile owner can access Device IDs. // with the device owner user) and as such the profile owner can access Device IDs.
if (isProfileOwnerOfOrganizationOwnedDevice(caller.getUserId())) { if (isProfileOwnerOfOrganizationOwnedDevice(callerUserId)
|| isUserAffiliatedWithDevice(callerUserId)) {
return; return;
} }
throw new SecurityException( throw new SecurityException(
@@ -9305,10 +9308,11 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager {
return false; return false;
} }
// Allow access to the device owner or delegate cert installer. // Allow access to the device owner or delegate cert installer or profile owner of an
// affiliated user
ComponentName deviceOwner = getDeviceOwnerComponent(true); ComponentName deviceOwner = getDeviceOwnerComponent(true);
if (deviceOwner != null && (deviceOwner.getPackageName().equals(packageName) if (deviceOwner != null && (deviceOwner.getPackageName().equals(packageName)
|| isCallerDelegate(packageName, uid, DELEGATION_CERT_INSTALL))) { || isCallerDelegate(packageName, uid, DELEGATION_CERT_INSTALL))) {
return true; return true;
} }
final int userId = UserHandle.getUserId(uid); final int userId = UserHandle.getUserId(uid);
@@ -9318,7 +9322,8 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager {
final boolean isCallerProfileOwnerOrDelegate = profileOwner != null final boolean isCallerProfileOwnerOrDelegate = profileOwner != null
&& (profileOwner.getPackageName().equals(packageName) && (profileOwner.getPackageName().equals(packageName)
|| isCallerDelegate(packageName, uid, DELEGATION_CERT_INSTALL)); || isCallerDelegate(packageName, uid, DELEGATION_CERT_INSTALL));
if (isCallerProfileOwnerOrDelegate && isProfileOwnerOfOrganizationOwnedDevice(userId)) { if (isCallerProfileOwnerOrDelegate && (isProfileOwnerOfOrganizationOwnedDevice(userId)
|| isUserAffiliatedWithDevice(userId))) {
return true; return true;
} }
@@ -14602,7 +14607,13 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager {
final CallerIdentity caller = getCallerIdentity(); final CallerIdentity caller = getCallerIdentity();
Preconditions.checkCallAuthorization(hasCrossUsersPermission(caller, userId)); Preconditions.checkCallAuthorization(hasCrossUsersPermission(caller, userId));
return isUserAffiliatedWithDeviceLocked(userId); return isUserAffiliatedWithDevice(userId);
}
private boolean isUserAffiliatedWithDevice(@UserIdInt int userId) {
synchronized (getLockObject()) {
return isUserAffiliatedWithDeviceLocked(userId);
}
} }
private boolean isUserAffiliatedWithDeviceLocked(@UserIdInt int userId) { private boolean isUserAffiliatedWithDeviceLocked(@UserIdInt int userId) {