blob: 8dce4e3562c4a992dc5ff76b99e0d07adefcc0ff [file] [log] [blame]
Max Biresf60987e2021-04-16 13:35:20 -07001/*
2 * Copyright 2021 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 <string>
18#include <vector>
19
20#include <aidl/android/hardware/security/keymint/IRemotelyProvisionedComponent.h>
21#include <android/binder_manager.h>
22#include <cppbor.h>
23#include <keymaster/cppcose/cppcose.h>
24#include <log/log.h>
Seth Moore6dfb02a2021-06-18 15:43:09 -070025#include <remote_prov/remote_prov_utils.h>
Max Biresf60987e2021-04-16 13:35:20 -070026#include <vintf/VintfObject.h>
27
28using std::set;
29using std::string;
30using std::vector;
31
32using aidl::android::hardware::security::keymint::DeviceInfo;
33using aidl::android::hardware::security::keymint::IRemotelyProvisionedComponent;
34using aidl::android::hardware::security::keymint::MacedPublicKey;
35using aidl::android::hardware::security::keymint::ProtectedData;
Seth Moore6dfb02a2021-06-18 15:43:09 -070036using aidl::android::hardware::security::keymint::remote_prov::generateEekChain;
Max Biresf60987e2021-04-16 13:35:20 -070037
38using android::vintf::HalManifest;
39using android::vintf::VintfObject;
40
41using namespace cppbor;
42using namespace cppcose;
43
44namespace {
45
46const string kPackage = "android.hardware.security.keymint";
47const string kInterface = "IRemotelyProvisionedComponent";
48const string kFormattedName = kPackage + "." + kInterface + "/";
49
Max Biresf60987e2021-04-16 13:35:20 -070050std::vector<uint8_t> getChallenge() {
51 return std::vector<uint8_t>(0);
52}
53
54std::vector<uint8_t> composeCertificateRequest(ProtectedData&& protectedData,
55 DeviceInfo&& deviceInfo) {
56 Array emptyMacedKeysToSign;
57 emptyMacedKeysToSign
58 .add(std::vector<uint8_t>(0)) // empty protected headers as bstr
59 .add(Map()) // empty unprotected headers
60 .add(Null()) // nil for the payload
61 .add(std::vector<uint8_t>(0)); // empty tag as bstr
62 Array certificateRequest;
63 certificateRequest.add(EncodedItem(std::move(deviceInfo.deviceInfo)))
64 .add(getChallenge()) // fake challenge
65 .add(EncodedItem(std::move(protectedData.protectedData)))
66 .add(std::move(emptyMacedKeysToSign));
67 return certificateRequest.encode();
68}
69
70int32_t errorMsg(string name) {
71 std::cerr << "Failed for rkp instance: " << name;
72 return -1;
73}
74
75} // namespace
76
77int main() {
78 std::shared_ptr<const HalManifest> manifest = VintfObject::GetDeviceHalManifest();
79 set<string> rkpNames = manifest->getAidlInstances(kPackage, kInterface);
80 for (auto name : rkpNames) {
81 string fullName = kFormattedName + name;
82 if (!AServiceManager_isDeclared(fullName.c_str())) {
83 ALOGE("Could not find the following instance declared in the manifest: %s\n",
84 fullName.c_str());
85 return errorMsg(name);
86 }
87 AIBinder* rkpAiBinder = AServiceManager_getService(fullName.c_str());
88 ::ndk::SpAIBinder rkp_binder(rkpAiBinder);
89 auto rkp_service = IRemotelyProvisionedComponent::fromBinder(rkp_binder);
90 std::vector<uint8_t> keysToSignMac;
91 std::vector<MacedPublicKey> emptyKeys;
92
93 // Replace this eek chain generation with the actual production GEEK
Seth Moore6dfb02a2021-06-18 15:43:09 -070094 const std::vector<uint8_t> kFakeEekId = {'f', 'a', 'k', 'e', 0};
95 auto eekOrErr = generateEekChain(3 /* chainlength */, kFakeEekId);
Max Biresf60987e2021-04-16 13:35:20 -070096 if (!eekOrErr) {
97 ALOGE("Failed to generate test EEK somehow: %s", eekOrErr.message().c_str());
98 return errorMsg(name);
99 }
100
Seth Moore6dfb02a2021-06-18 15:43:09 -0700101 auto [eek, pubkey, privkey] = eekOrErr.moveValue();
Max Biresf60987e2021-04-16 13:35:20 -0700102 DeviceInfo deviceInfo;
103 ProtectedData protectedData;
104 if (rkp_service) {
105 ALOGE("extracting bundle");
106 ::ndk::ScopedAStatus status = rkp_service->generateCertificateRequest(
107 true /* testMode */, emptyKeys, eek, getChallenge(), &deviceInfo, &protectedData,
108 &keysToSignMac);
109 if (!status.isOk()) {
110 ALOGE("Bundle extraction failed. Error code: %d", status.getServiceSpecificError());
111 return errorMsg(name);
112 }
Max Biresf60987e2021-04-16 13:35:20 -0700113 std::vector<uint8_t> certificateRequest =
114 composeCertificateRequest(std::move(protectedData), std::move(deviceInfo));
115 std::copy(certificateRequest.begin(), certificateRequest.end(),
116 std::ostream_iterator<char>(std::cout));
117 }
118 }
119}