Merge "Add remote_provisioning system service" am: 222a476ac5 am: 9430c5fed0

Original change: https://android-review.googlesource.com/c/platform/frameworks/base/+/2263722

Change-Id: Id71268d27836111005aa1678c180c4a9081363a3
Signed-off-by: Automerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com>
This commit is contained in:
Seth Moore
2022-12-08 16:11:30 +00:00
committed by Automerger Merge Worker
14 changed files with 459 additions and 1 deletions

View File

@@ -116,6 +116,7 @@ combined_apis {
system_server_classpath: [
"service-media-s",
"service-permission",
"service-rkp",
"service-sdksandbox",
],
}

View File

@@ -376,6 +376,20 @@ aidl_interface {
},
}
// Build Rust bindings for remote provisioning. Needed by keystore2.
aidl_interface {
name: "android.security.rkp_aidl",
unstable: true,
srcs: [
"android/security/rkp/*.aidl",
],
backend: {
rust: {
enabled: true,
},
},
}
aidl_interface {
name: "android.debug_aidl",
unstable: true,

View File

@@ -5918,6 +5918,14 @@ public abstract class Context {
*/
public static final String FILE_INTEGRITY_SERVICE = "file_integrity";
/**
* Binder service for remote key provisioning.
*
* @see android.frameworks.rkp.IRemoteProvisioning
* @hide
*/
public static final String REMOTE_PROVISIONING_SERVICE = "remote_provisioning";
/**
* Use with {@link #getSystemService(String)} to retrieve a
* {@link android.hardware.lights.LightsManager} for controlling device lights.

View File

@@ -0,0 +1,49 @@
/*
* Copyright (C) 2022 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.rkp;
import android.security.rkp.RemotelyProvisionedKey;
/**
* Callback interface for receiving remotely provisioned keys from a
* {@link IRegistration}.
*
* @hide
*/
oneway interface IGetKeyCallback {
/**
* Called in response to {@link IRegistration.getKey}, indicating
* a remotely-provisioned key is available.
*
* @param key The key that was received from the remote provisioning service.
*/
void onSuccess(in RemotelyProvisionedKey key);
/**
* Called when the key request has been successfully cancelled.
* @see IRegistration.cancelGetKey
*/
void onCancel();
/**
* Called when an error has occurred while trying to get a remotely provisioned key.
*
* @param error A description of what failed, suitable for logging.
*/
void onError(String error);
}

View File

@@ -0,0 +1,49 @@
/*
* Copyright (C) 2022 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.rkp;
import android.security.rkp.IRegistration;
/**
* Callback interface for receiving a remote provisioning registration.
* {@link IRegistration}.
*
* @hide
*/
oneway interface IGetRegistrationCallback {
/**
* Called in response to {@link IRemoteProvisioning.getRegistration}.
*
* @param registration an IRegistration that is used to fetch remotely
* provisioned keys for the given IRemotelyProvisionedComponent.
*/
void onSuccess(in IRegistration registration);
/**
* Called when the get registration request has been successfully cancelled.
* @see IRemoteProvisioning.cancelGetRegistration
*/
void onCancel();
/**
* Called when an error has occurred while trying to get a registration.
*
* @param error A description of what failed, suitable for logging.
*/
void onError(String error);
}

View File

@@ -0,0 +1,85 @@
/*
* Copyright (C) 2022 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.rkp;
import android.security.rkp.IGetKeyCallback;
/**
* This interface is associated with the registration of an
* IRemotelyProvisionedComponent. Each component has a unique set of keys
* and certificates that are provisioned to the device for attestation. An
* IRegistration binder is created by calling
* {@link IRemoteProvisioning#getRegistration()}.
*
* This interface is used to query for available keys and certificates for the
* registered component.
*
* @hide
*/
oneway interface IRegistration {
/**
* Fetch a remotely provisioned key for the given keyId. Keys are unique
* per caller/keyId/registration tuple. This ensures that no two
* applications are able to correlate keys to uniquely identify a
* device/user. Callers receive their key via {@code callback}.
*
* If a key is available, this call immediately invokes {@code callback}.
*
* If no keys are immediately available, then this function contacts the
* remote provisioning server to provision a key. After provisioning is
* completed, the key is passed to {@code callback}.
*
* @param keyId This is a client-chosen key identifier, used to
* differentiate between keys for varying client-specific use-cases. For
* example, keystore2 passes the UID of the applications that call it as
* the keyId value here, so that each of keystore2's clients gets a unique
* key.
* @param callback Receives the result of the call. A callback must only
* be used with one {@code getKey} call at a time.
*/
void getKey(int keyId, IGetKeyCallback callback);
/**
* Cancel an active request for a remotely provisioned key, as initiated via
* {@link getKey}. Upon cancellation, {@code callback.onCancel} will be invoked.
*/
void cancelGetKey(IGetKeyCallback callback);
/**
* Replace an obsolete key blob with an upgraded key blob.
* In certain cases, such as security patch level upgrade, keys become "old".
* In these cases, the component which supports operations with the remotely
* provisioned key blobs must support upgrading the blobs to make them "new"
* and usable on the updated system.
*
* For an example of a remotely provisioned component that has an upgrade
* mechanism, see the documentation for IKeyMintDevice.upgradeKey.
*
* Once a key has been upgraded, the IRegistration where the key is stored
* needs to be told about the new blob. After calling storeUpgradedKey,
* getKey will return the new key blob instead of the old one.
*
* Note that this function does NOT extend the lifetime of key blobs. The
* certificate for the key is unchanged, and the key will still expire at
* the same time it would have if storeUpgradedKey had never been called.
*
* @param oldKeyBlob The old key blob to be replaced by {@code newKeyBlob}.
*
* @param newKeyblob The new blob to replace {@code oldKeyBlob}.
*/
void storeUpgradedKey(in byte[] oldKeyBlob, in byte[] newKeyBlob);
}

View File

@@ -0,0 +1,68 @@
/*
* Copyright (C) 2022 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.rkp;
import android.security.rkp.IRegistration;
import android.security.rkp.IGetRegistrationCallback;
/**
* {@link IRemoteProvisioning} is the interface provided to use the remote key
* provisioning functionality from the Remote Key Provisioning Daemon (RKPD).
* This would be the first service that RKPD clients would interact with. The
* intent is for the clients to get the {@link IRegistration} object from this
* interface and use it for actual remote provisioning work.
*
* @hide
*/
oneway interface IRemoteProvisioning {
/**
* Takes a remotely provisioned component service name and gets a
* registration bound to that service and the caller's UID.
*
* @param irpcName The name of the {@code IRemotelyProvisionedComponent}
* for which remotely provisioned keys should be managed.
* @param callback Receives the result of the call. A callback must only
* be used with one {@code getRegistration} call at a time.
*
* Notes:
* - This function will attempt to get the service named by irpcName. This
* implies that a lazy/dynamic aidl service will be instantiated, and this
* function blocks until the service is up. Upon return, any binder tokens
* are dropped, allowing the lazy/dynamic service to shutdown.
* - The created registration object is unique per caller. If two different
* UIDs call getRegistration with the same irpcName, they will receive
* different registrations. This prevents two different applications from
* being able to see the same keys.
* - This function is idempotent per calling UID. Additional calls to
* getRegistration with the same parameters, from the same caller, will have
* no side effects.
* - A callback may only be associated with one getRegistration call at a time.
* If the callback is used multiple times, this API will return an error.
*
* @see IRegistration#getKey()
* @see IRemotelyProvisionedComponent
*
*/
void getRegistration(String irpcName, IGetRegistrationCallback callback);
/**
* Cancel any active {@link getRegistration} call associated with the given
* callback. If no getRegistration call is currently active, this function is
* a noop.
*/
void cancelGetRegistration(IGetRegistrationCallback callback);
}

View File

@@ -0,0 +1,5 @@
# Bug component: 1084908
jbires@google.com
sethmo@google.com
vikramgaur@google.com

View File

@@ -0,0 +1,44 @@
/*
* Copyright 2022, 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.rkp;
/**
* A {@link RemotelyProvisionedKey} holds an attestation key and the
* corresponding remotely provisioned certificate chain.
*
* @hide
*/
@RustDerive(Eq=true, PartialEq=true)
parcelable RemotelyProvisionedKey {
/**
* The remotely-provisioned key that may be used to sign attestations. The
* format of this key is opaque, and need only be understood by the
* IRemotelyProvisionedComponent that generated it.
*
* Any private key material contained within this blob must be encrypted.
*
* @see IRemotelyProvisionedComponent
*/
byte[] keyBlob;
/**
* Sequence of DER-encoded X.509 certificates that make up the attestation
* key's certificate chain. This is the binary encoding for a chain that is
* supported by Java's CertificateFactory.generateCertificates API.
*/
byte[] encodedCertChain;
}

View File

@@ -174,6 +174,7 @@ java_library {
"framework-tethering.stubs.module_lib",
"service-art.stubs.system_server",
"service-permission.stubs.system_server",
"service-rkp.stubs.system_server",
"service-sdksandbox.stubs.system_server",
],

View File

@@ -131,6 +131,7 @@ java_library_static {
"app-compat-annotations",
"framework-tethering.stubs.module_lib",
"service-permission.stubs.system_server",
"service-rkp.stubs.system_server",
"service-sdksandbox.stubs.system_server",
],

View File

@@ -0,0 +1 @@
file:platform/frameworks/base:master:/core/java/android/security/rkp/OWNERS

View File

@@ -0,0 +1,126 @@
/*
* Copyright (C) 2022 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 com.android.server.security.rkp;
import android.content.Context;
import android.os.Binder;
import android.os.OutcomeReceiver;
import android.os.RemoteException;
import android.security.rkp.IGetKeyCallback;
import android.security.rkp.IGetRegistrationCallback;
import android.security.rkp.IRegistration;
import android.security.rkp.IRemoteProvisioning;
import android.security.rkp.service.RegistrationProxy;
import android.util.Log;
import com.android.server.SystemService;
import java.time.Duration;
/**
* Implements the remote provisioning system service. This service is backed by a mainline
* module, allowing the underlying implementation to be updated. The code here is a thin
* proxy for the code in android.security.rkp.service.
*
* @hide
*/
public class RemoteProvisioningService extends SystemService {
public static final String TAG = "RemoteProvisionSysSvc";
private static final Duration CREATE_REGISTRATION_TIMEOUT = Duration.ofSeconds(10);
private final RemoteProvisioningImpl mBinderImpl = new RemoteProvisioningImpl();
/** @hide */
public RemoteProvisioningService(Context context) {
super(context);
}
@Override
public void onStart() {
publishBinderService(Context.REMOTE_PROVISIONING_SERVICE, mBinderImpl);
}
private final class RemoteProvisioningImpl extends IRemoteProvisioning.Stub {
final class RegistrationBinder extends IRegistration.Stub {
static final String TAG = RemoteProvisioningService.TAG;
private final RegistrationProxy mRegistration;
RegistrationBinder(RegistrationProxy registration) {
mRegistration = registration;
}
@Override
public void getKey(int keyId, IGetKeyCallback callback) {
Log.e(TAG, "RegistrationBinder.getKey NOT YET IMPLEMENTED");
}
@Override
public void cancelGetKey(IGetKeyCallback callback) {
Log.e(TAG, "RegistrationBinder.cancelGetKey NOT YET IMPLEMENTED");
}
@Override
public void storeUpgradedKey(byte[] oldKeyBlob, byte[] newKeyBlob) {
Log.e(TAG, "RegistrationBinder.storeUpgradedKey NOT YET IMPLEMENTED");
}
}
@Override
public void getRegistration(String irpcName, IGetRegistrationCallback callback)
throws RemoteException {
final int callerUid = Binder.getCallingUidOrThrow();
final long callingIdentity = Binder.clearCallingIdentity();
try {
Log.i(TAG, "getRegistration(" + irpcName + ")");
RegistrationProxy.createAsync(
getContext(),
callerUid,
irpcName,
CREATE_REGISTRATION_TIMEOUT,
getContext().getMainExecutor(),
new OutcomeReceiver<>() {
@Override
public void onResult(RegistrationProxy registration) {
try {
callback.onSuccess(new RegistrationBinder(registration));
} catch (RemoteException e) {
Log.e(TAG, "Error calling success callback", e);
}
}
@Override
public void onError(Exception error) {
try {
callback.onError(error.toString());
} catch (RemoteException e) {
Log.e(TAG, "Error calling error callback", e);
}
}
});
} finally {
Binder.restoreCallingIdentity(callingIdentity);
}
}
@Override
public void cancelGetRegistration(IGetRegistrationCallback callback)
throws RemoteException {
Log.i(TAG, "cancelGetRegistration()");
callback.onError("cancelGetRegistration not yet implemented");
}
}
}

View File

@@ -186,6 +186,7 @@ import com.android.server.security.AttestationVerificationManagerService;
import com.android.server.security.FileIntegrityService;
import com.android.server.security.KeyAttestationApplicationIdProviderService;
import com.android.server.security.KeyChainSystemService;
import com.android.server.security.rkp.RemoteProvisioningService;
import com.android.server.sensorprivacy.SensorPrivacyService;
import com.android.server.sensors.SensorService;
import com.android.server.signedconfig.SignedConfigService;
@@ -1390,11 +1391,16 @@ public final class SystemServer implements Dumpable {
mSystemServiceManager.startService(BugreportManagerService.class);
t.traceEnd();
// Serivce for GPU and GPU driver.
// Service for GPU and GPU driver.
t.traceBegin("GpuService");
mSystemServiceManager.startService(GpuService.class);
t.traceEnd();
// Handles system process requests for remotely provisioned keys & data.
t.traceBegin("StartRemoteProvisioningService");
mSystemServiceManager.startService(RemoteProvisioningService.class);
t.traceEnd();
t.traceEnd(); // startCoreServices
}