Merge "Add remote_provisioning system service"
This commit is contained in:
@@ -116,6 +116,7 @@ combined_apis {
|
||||
system_server_classpath: [
|
||||
"service-media-s",
|
||||
"service-permission",
|
||||
"service-rkp",
|
||||
"service-sdksandbox",
|
||||
],
|
||||
}
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -5906,6 +5906,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.
|
||||
|
||||
49
core/java/android/security/rkp/IGetKeyCallback.aidl
Normal file
49
core/java/android/security/rkp/IGetKeyCallback.aidl
Normal 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);
|
||||
}
|
||||
|
||||
49
core/java/android/security/rkp/IGetRegistrationCallback.aidl
Normal file
49
core/java/android/security/rkp/IGetRegistrationCallback.aidl
Normal 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);
|
||||
}
|
||||
|
||||
85
core/java/android/security/rkp/IRegistration.aidl
Normal file
85
core/java/android/security/rkp/IRegistration.aidl
Normal 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);
|
||||
}
|
||||
68
core/java/android/security/rkp/IRemoteProvisioning.aidl
Normal file
68
core/java/android/security/rkp/IRemoteProvisioning.aidl
Normal 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);
|
||||
}
|
||||
5
core/java/android/security/rkp/OWNERS
Normal file
5
core/java/android/security/rkp/OWNERS
Normal file
@@ -0,0 +1,5 @@
|
||||
# Bug component: 1084908
|
||||
|
||||
jbires@google.com
|
||||
sethmo@google.com
|
||||
vikramgaur@google.com
|
||||
44
core/java/android/security/rkp/RemotelyProvisionedKey.aidl
Normal file
44
core/java/android/security/rkp/RemotelyProvisionedKey.aidl
Normal 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;
|
||||
}
|
||||
@@ -176,6 +176,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",
|
||||
],
|
||||
|
||||
|
||||
@@ -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",
|
||||
],
|
||||
|
||||
|
||||
@@ -0,0 +1 @@
|
||||
file:platform/frameworks/base:master:/core/java/android/security/rkp/OWNERS
|
||||
@@ -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");
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
@@ -1392,11 +1393,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
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user