diff options
| author | Dave McCloskey <dlm@google.com> | 2021-09-30 17:07:43 -0700 |
|---|---|---|
| committer | Dave McCloskey <dlm@google.com> | 2021-11-29 14:55:24 -0800 |
| commit | 2a548a596a5dc0f09eabbae3ea1fce1ca5a5a1ba (patch) | |
| tree | 62964127f18b68c0b5eb3e5fae13cdc41117cd3e /core/java/android | |
| parent | b9b25ef742df74ed6c1b62a3eecc06da97f461a1 (diff) | |
Create the system service for AVF & hook the manager to it.
Bug: 201696614
Change-Id: I4a7a830ba809ed59a030a87c4f479199685d8a42
Test: atest AttestationVerificationTest
Diffstat (limited to 'core/java/android')
5 files changed, 180 insertions, 4 deletions
diff --git a/core/java/android/app/SystemServiceRegistry.java b/core/java/android/app/SystemServiceRegistry.java index 04763070cded..089c2691a277 100644 --- a/core/java/android/app/SystemServiceRegistry.java +++ b/core/java/android/app/SystemServiceRegistry.java @@ -200,6 +200,8 @@ import android.safetycenter.SafetyCenterFrameworkInitializer; import android.scheduling.SchedulingFrameworkInitializer; import android.security.FileIntegrityManager; import android.security.IFileIntegrityService; +import android.security.attestationverification.AttestationVerificationManager; +import android.security.attestationverification.IAttestationVerificationManagerService; import android.service.oemlock.IOemLockService; import android.service.oemlock.OemLockManager; import android.service.persistentdata.IPersistentDataBlockService; @@ -1425,6 +1427,19 @@ public final class SystemServiceRegistry { return new FileIntegrityManager(ctx.getOuterContext(), IFileIntegrityService.Stub.asInterface(b)); }}); + + registerService(Context.ATTESTATION_VERIFICATION_SERVICE, + AttestationVerificationManager.class, + new CachedServiceFetcher<AttestationVerificationManager>() { + @Override + public AttestationVerificationManager createService(ContextImpl ctx) + throws ServiceNotFoundException { + IBinder b = ServiceManager.getServiceOrThrow( + Context.ATTESTATION_VERIFICATION_SERVICE); + return new AttestationVerificationManager(ctx.getOuterContext(), + IAttestationVerificationManagerService.Stub.asInterface(b)); + }}); + //CHECKSTYLE:ON IndentationCheck registerService(Context.APP_INTEGRITY_SERVICE, AppIntegrityManager.class, new CachedServiceFetcher<AppIntegrityManager>() { diff --git a/core/java/android/security/attestationverification/AttestationVerificationManager.java b/core/java/android/security/attestationverification/AttestationVerificationManager.java index 8ed5b20b085e..db783ceabcdb 100644 --- a/core/java/android/security/attestationverification/AttestationVerificationManager.java +++ b/core/java/android/security/attestationverification/AttestationVerificationManager.java @@ -26,12 +26,19 @@ import android.annotation.RequiresPermission; import android.annotation.SystemService; import android.content.Context; import android.os.Bundle; +import android.os.ParcelDuration; +import android.os.RemoteException; +import android.util.Log; + +import com.android.internal.infra.AndroidFuture; import java.lang.annotation.ElementType; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; +import java.time.Duration; import java.util.concurrent.Executor; +import java.util.concurrent.TimeUnit; import java.util.function.BiConsumer; /** @@ -43,6 +50,12 @@ import java.util.function.BiConsumer; @SystemService(Context.ATTESTATION_VERIFICATION_SERVICE) public class AttestationVerificationManager { + private static final String TAG = "AVF"; + private static final Duration MAX_TOKEN_AGE = Duration.ofHours(1); + + private final Context mContext; + private final IAttestationVerificationManagerService mService; + /** * Verifies that {@code attestation} describes a computing environment that meets the * requirements of {@code profile}, {@code localBindingType}, and {@code requirements}. @@ -96,7 +109,21 @@ public class AttestationVerificationManager { @NonNull byte[] attestation, @NonNull @CallbackExecutor Executor executor, @NonNull BiConsumer<@VerificationResult Integer, VerificationToken> callback) { - executor.execute(() -> callback.accept(RESULT_UNKNOWN, null)); + try { + AndroidFuture<IVerificationResult> resultCallback = new AndroidFuture<>(); + resultCallback.thenAccept(result -> { + Log.d(TAG, "verifyAttestation result: " + result.resultCode + " / " + result.token); + executor.execute(() -> { + callback.accept(result.resultCode, result.token); + }); + }); + + mService.verifyAttestation(profile, localBindingType, requirements, attestation, + resultCallback); + + } catch (RemoteException e) { + throw e.rethrowFromSystemServer(); + } } /** @@ -134,12 +161,38 @@ public class AttestationVerificationManager { @LocalBindingType int localBindingType, @NonNull Bundle requirements, @NonNull VerificationToken token, - @Nullable java.time.Duration maximumAge) { - return RESULT_UNKNOWN; + @Nullable Duration maximumAge) { + Duration usedMaximumAge; + if (maximumAge == null) { + usedMaximumAge = MAX_TOKEN_AGE; + } else { + if (maximumAge.compareTo(MAX_TOKEN_AGE) > 0) { + throw new IllegalArgumentException( + "maximumAge cannot be greater than " + MAX_TOKEN_AGE + "; was " + + maximumAge); + } + usedMaximumAge = maximumAge; + } + + try { + AndroidFuture<Integer> resultCallback = new AndroidFuture<>(); + resultCallback.orTimeout(5, TimeUnit.SECONDS); + + mService.verifyToken(token, new ParcelDuration(usedMaximumAge), resultCallback); + return resultCallback.get(); // block on result callback + } catch (RemoteException e) { + throw e.rethrowFromSystemServer(); + } catch (Throwable t) { + throw new RuntimeException("Error verifying token.", t); + } } /** @hide */ - public AttestationVerificationManager() { + public AttestationVerificationManager( + @NonNull Context context, + @NonNull IAttestationVerificationManagerService service) { + this.mContext = context; + this.mService = service; } /** @hide */ diff --git a/core/java/android/security/attestationverification/IAttestationVerificationManagerService.aidl b/core/java/android/security/attestationverification/IAttestationVerificationManagerService.aidl new file mode 100644 index 000000000000..2fb328c3e1fb --- /dev/null +++ b/core/java/android/security/attestationverification/IAttestationVerificationManagerService.aidl @@ -0,0 +1,43 @@ +/* + * Copyright 2021 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.attestationverification; + +import android.os.Bundle; +import android.os.ParcelDuration; +import android.security.attestationverification.AttestationProfile; +import android.security.attestationverification.VerificationToken; +import com.android.internal.infra.AndroidFuture; + + +/** + * Binder interface to communicate with AttestationVerificationManagerService. + * @hide + */ +oneway interface IAttestationVerificationManagerService { + + void verifyAttestation( + in AttestationProfile profile, + in int localBindingType, + in Bundle requirements, + in byte[] attestation, + in AndroidFuture resultCallback); + + void verifyToken( + in VerificationToken token, + in ParcelDuration maximumTokenAge, + in AndroidFuture resultCallback); +} diff --git a/core/java/android/security/attestationverification/IAttestationVerificationService.aidl b/core/java/android/security/attestationverification/IAttestationVerificationService.aidl new file mode 100644 index 000000000000..082ad3247ead --- /dev/null +++ b/core/java/android/security/attestationverification/IAttestationVerificationService.aidl @@ -0,0 +1,33 @@ +/* + * Copyright (C) 2021 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.attestationverification; + +import android.os.Bundle; +import com.android.internal.infra.AndroidFuture; + + +/** + * Binder interface for the system server to communicate with app implementations of + * AttestationVerificationService. + * @hide + */ +oneway interface IAttestationVerificationService { + void onVerifyAttestation( + in Bundle requirements, + in byte[] attestation, + in AndroidFuture callback); +} diff --git a/core/java/android/security/attestationverification/IVerificationResult.aidl b/core/java/android/security/attestationverification/IVerificationResult.aidl new file mode 100644 index 000000000000..f61c45697b31 --- /dev/null +++ b/core/java/android/security/attestationverification/IVerificationResult.aidl @@ -0,0 +1,32 @@ +/* + * Copyright (C) 2021 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.attestationverification; + +import android.security.attestationverification.VerificationToken; + + +/** + * The result of an attestation verification. + * + * {@hide} + */ +parcelable IVerificationResult { + /** The result code corresponding to @VerificationResult. */ + int resultCode; + /** The token for the verification or null. */ + VerificationToken token; +} |
