xref: /aosp_15_r20/system/apex/apexd/apexd_brand_new_verifier.cpp (revision 33f3758387333dbd2962d7edbd98681940d895da)
1 /*
2  * Copyright (C) 2024 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 #include "apexd_brand_new_verifier.h"
18 
19 #include <optional>
20 #include <string>
21 
22 #include "android-base/logging.h"
23 #include "apex_constants.h"
24 #include "apex_file_repository.h"
25 
26 using android::base::Error;
27 using android::base::Result;
28 
29 namespace android::apex {
30 
VerifyBrandNewPackageAgainstPreinstalled(const ApexFile & apex)31 Result<ApexPartition> VerifyBrandNewPackageAgainstPreinstalled(
32     const ApexFile& apex) {
33   CHECK(ApexFileRepository::IsBrandNewApexEnabled())
34       << "Brand-new APEX must be enabled in order to do verification.";
35 
36   const std::string& name = apex.GetManifest().name();
37   const auto& file_repository = ApexFileRepository::GetInstance();
38   auto partition = file_repository.GetBrandNewApexPublicKeyPartition(
39       apex.GetBundledPublicKey());
40   if (!partition.has_value()) {
41     return Error()
42            << "No pre-installed public key found for the brand-new APEX: "
43            << name;
44   }
45 
46   if (apex.GetManifest().version() <=
47       file_repository.GetBrandNewApexBlockedVersion(partition.value(), name)) {
48     return Error() << "Brand-new APEX is blocked: " << name;
49   }
50 
51   return partition.value();
52 }
53 
VerifyBrandNewPackageAgainstActive(const ApexFile & apex)54 Result<void> VerifyBrandNewPackageAgainstActive(const ApexFile& apex) {
55   CHECK(ApexFileRepository::IsBrandNewApexEnabled())
56       << "Brand-new APEX must be enabled in order to do verification.";
57 
58   const std::string& name = apex.GetManifest().name();
59   const auto& file_repository = ApexFileRepository::GetInstance();
60 
61   if (file_repository.HasPreInstalledVersion(name)) {
62     return {};
63   }
64 
65   if (file_repository.HasDataVersion(name)) {
66     auto existing_package = file_repository.GetDataApex(name).get();
67     if (apex.GetBundledPublicKey() != existing_package.GetBundledPublicKey()) {
68       return Error()
69              << "Brand-new APEX public key doesn't match existing active APEX: "
70              << name;
71     }
72   }
73   return {};
74 }
75 
76 }  // namespace android::apex
77