18ff1e193acc1d9946f877332547c7706cfcf12f4Janis Danisevskis/*
28ff1e193acc1d9946f877332547c7706cfcf12f4Janis Danisevskis * Copyright (C) 2016 The Android Open Source Project
38ff1e193acc1d9946f877332547c7706cfcf12f4Janis Danisevskis *
48ff1e193acc1d9946f877332547c7706cfcf12f4Janis Danisevskis * Licensed under the Apache License, Version 2.0 (the "License");
58ff1e193acc1d9946f877332547c7706cfcf12f4Janis Danisevskis * you may not use this file except in compliance with the License.
68ff1e193acc1d9946f877332547c7706cfcf12f4Janis Danisevskis * You may obtain a copy of the License at
78ff1e193acc1d9946f877332547c7706cfcf12f4Janis Danisevskis *
88ff1e193acc1d9946f877332547c7706cfcf12f4Janis Danisevskis *      http://www.apache.org/licenses/LICENSE-2.0
98ff1e193acc1d9946f877332547c7706cfcf12f4Janis Danisevskis *
108ff1e193acc1d9946f877332547c7706cfcf12f4Janis Danisevskis * Unless required by applicable law or agreed to in writing, software
118ff1e193acc1d9946f877332547c7706cfcf12f4Janis Danisevskis * distributed under the License is distributed on an "AS IS" BASIS,
128ff1e193acc1d9946f877332547c7706cfcf12f4Janis Danisevskis * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
138ff1e193acc1d9946f877332547c7706cfcf12f4Janis Danisevskis * See the License for the specific language governing permissions and
148ff1e193acc1d9946f877332547c7706cfcf12f4Janis Danisevskis * limitations under the License.
158ff1e193acc1d9946f877332547c7706cfcf12f4Janis Danisevskis */
168ff1e193acc1d9946f877332547c7706cfcf12f4Janis Danisevskis
178ff1e193acc1d9946f877332547c7706cfcf12f4Janis Danisevskis
188ff1e193acc1d9946f877332547c7706cfcf12f4Janis Danisevskispackage com.android.server.security;
198ff1e193acc1d9946f877332547c7706cfcf12f4Janis Danisevskis
208ff1e193acc1d9946f877332547c7706cfcf12f4Janis Danisevskisimport android.content.Context;
218ff1e193acc1d9946f877332547c7706cfcf12f4Janis Danisevskisimport android.content.pm.PackageInfo;
228ff1e193acc1d9946f877332547c7706cfcf12f4Janis Danisevskisimport android.content.pm.PackageManager;
238ff1e193acc1d9946f877332547c7706cfcf12f4Janis Danisevskisimport android.content.pm.PackageManager.NameNotFoundException;
246ab9bb68bafaa2b9a10924f3a7c3a1d164dda752Janis Danisevskisimport android.os.Binder;
258ff1e193acc1d9946f877332547c7706cfcf12f4Janis Danisevskisimport android.os.RemoteException;
268ff1e193acc1d9946f877332547c7706cfcf12f4Janis Danisevskisimport android.os.UserHandle;
278ff1e193acc1d9946f877332547c7706cfcf12f4Janis Danisevskisimport android.security.keymaster.KeyAttestationPackageInfo;
288ff1e193acc1d9946f877332547c7706cfcf12f4Janis Danisevskisimport android.security.keymaster.KeyAttestationApplicationId;
298ff1e193acc1d9946f877332547c7706cfcf12f4Janis Danisevskisimport android.security.keymaster.IKeyAttestationApplicationIdProvider;
308ff1e193acc1d9946f877332547c7706cfcf12f4Janis Danisevskis
318ff1e193acc1d9946f877332547c7706cfcf12f4Janis Danisevskis/**
328ff1e193acc1d9946f877332547c7706cfcf12f4Janis Danisevskis * @hide
338ff1e193acc1d9946f877332547c7706cfcf12f4Janis Danisevskis * The KeyAttestationApplicationIdProviderService provides information describing the possible
348ff1e193acc1d9946f877332547c7706cfcf12f4Janis Danisevskis * applications identified by a UID. Due to UID sharing, this KeyAttestationApplicationId can
358ff1e193acc1d9946f877332547c7706cfcf12f4Janis Danisevskis * comprise information about multiple packages. The Information is used by keystore to describe
368ff1e193acc1d9946f877332547c7706cfcf12f4Janis Danisevskis * the initiating application of a key attestation procedure.
378ff1e193acc1d9946f877332547c7706cfcf12f4Janis Danisevskis */
388ff1e193acc1d9946f877332547c7706cfcf12f4Janis Danisevskispublic class KeyAttestationApplicationIdProviderService
398ff1e193acc1d9946f877332547c7706cfcf12f4Janis Danisevskis        extends IKeyAttestationApplicationIdProvider.Stub {
408ff1e193acc1d9946f877332547c7706cfcf12f4Janis Danisevskis
418ff1e193acc1d9946f877332547c7706cfcf12f4Janis Danisevskis    public KeyAttestationApplicationIdProviderService(Context context) {
428ff1e193acc1d9946f877332547c7706cfcf12f4Janis Danisevskis        mPackageManager = context.getPackageManager();
438ff1e193acc1d9946f877332547c7706cfcf12f4Janis Danisevskis    }
448ff1e193acc1d9946f877332547c7706cfcf12f4Janis Danisevskis
458ff1e193acc1d9946f877332547c7706cfcf12f4Janis Danisevskis    private PackageManager mPackageManager;
468ff1e193acc1d9946f877332547c7706cfcf12f4Janis Danisevskis
478ff1e193acc1d9946f877332547c7706cfcf12f4Janis Danisevskis    public KeyAttestationApplicationId getKeyAttestationApplicationId(int uid)
488ff1e193acc1d9946f877332547c7706cfcf12f4Janis Danisevskis            throws RemoteException {
496ab9bb68bafaa2b9a10924f3a7c3a1d164dda752Janis Danisevskis        if (Binder.getCallingUid() != android.os.Process.KEYSTORE_UID) {
506ab9bb68bafaa2b9a10924f3a7c3a1d164dda752Janis Danisevskis            throw new SecurityException("This service can only be used by Keystore");
518ff1e193acc1d9946f877332547c7706cfcf12f4Janis Danisevskis        }
526ab9bb68bafaa2b9a10924f3a7c3a1d164dda752Janis Danisevskis        KeyAttestationPackageInfo[] keyAttestationPackageInfos = null;
536ab9bb68bafaa2b9a10924f3a7c3a1d164dda752Janis Danisevskis        final long token = Binder.clearCallingIdentity();
548ff1e193acc1d9946f877332547c7706cfcf12f4Janis Danisevskis        try {
556ab9bb68bafaa2b9a10924f3a7c3a1d164dda752Janis Danisevskis            String[] packageNames = mPackageManager.getPackagesForUid(uid);
566ab9bb68bafaa2b9a10924f3a7c3a1d164dda752Janis Danisevskis            if (packageNames == null) {
576ab9bb68bafaa2b9a10924f3a7c3a1d164dda752Janis Danisevskis                throw new RemoteException("No packages for uid");
586ab9bb68bafaa2b9a10924f3a7c3a1d164dda752Janis Danisevskis            }
596ab9bb68bafaa2b9a10924f3a7c3a1d164dda752Janis Danisevskis            int userId = UserHandle.getUserId(uid);
606ab9bb68bafaa2b9a10924f3a7c3a1d164dda752Janis Danisevskis            keyAttestationPackageInfos = new KeyAttestationPackageInfo[packageNames.length];
616ab9bb68bafaa2b9a10924f3a7c3a1d164dda752Janis Danisevskis
628ff1e193acc1d9946f877332547c7706cfcf12f4Janis Danisevskis            for (int i = 0; i < packageNames.length; ++i) {
638ff1e193acc1d9946f877332547c7706cfcf12f4Janis Danisevskis                PackageInfo packageInfo = mPackageManager.getPackageInfoAsUser(packageNames[i],
648ff1e193acc1d9946f877332547c7706cfcf12f4Janis Danisevskis                        PackageManager.GET_SIGNATURES, userId);
658ff1e193acc1d9946f877332547c7706cfcf12f4Janis Danisevskis                keyAttestationPackageInfos[i] = new KeyAttestationPackageInfo(packageNames[i],
668ff1e193acc1d9946f877332547c7706cfcf12f4Janis Danisevskis                        packageInfo.versionCode, packageInfo.signatures);
678ff1e193acc1d9946f877332547c7706cfcf12f4Janis Danisevskis            }
688ff1e193acc1d9946f877332547c7706cfcf12f4Janis Danisevskis        } catch (NameNotFoundException nnfe) {
698ff1e193acc1d9946f877332547c7706cfcf12f4Janis Danisevskis            throw new RemoteException(nnfe.getMessage());
706ab9bb68bafaa2b9a10924f3a7c3a1d164dda752Janis Danisevskis        } finally {
716ab9bb68bafaa2b9a10924f3a7c3a1d164dda752Janis Danisevskis            Binder.restoreCallingIdentity(token);
728ff1e193acc1d9946f877332547c7706cfcf12f4Janis Danisevskis        }
738ff1e193acc1d9946f877332547c7706cfcf12f4Janis Danisevskis        return new KeyAttestationApplicationId(keyAttestationPackageInfos);
748ff1e193acc1d9946f877332547c7706cfcf12f4Janis Danisevskis    }
758ff1e193acc1d9946f877332547c7706cfcf12f4Janis Danisevskis}
76